Bug 1615016 - Store isAtomsZone and isSelfHostingZone flags on the Zone r=sfink

Remove some dependencies on JSRuntime by storing flags on the Zone to indicate whether a zone is the atoms zone or the self hosting zone.

Differential Revision: https://phabricator.services.mozilla.com/D62620

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jon Coppeard 2020-02-13 14:25:48 +00:00
Родитель b201f42e88
Коммит c5e9e5c6e8
17 изменённых файлов: 81 добавлений и 37 удалений

Просмотреть файл

@ -13,6 +13,7 @@
#include "mozilla/Maybe.h"
#include "gc/Zone.h"
#include "vm/Runtime.h"
#include "gc/ArenaList-inl.h"

Просмотреть файл

@ -3954,7 +3954,7 @@ void GCRuntime::purgeSourceURLsForShrinkingGC() {
gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::PURGE_SOURCE_URLS);
for (GCZonesIter zone(this); !zone.done(); zone.next()) {
// URLs are not tracked for realms in the system zone.
if (!canRelocateZone(zone) || zone->isSystem) {
if (!canRelocateZone(zone) || zone->isSystemZone()) {
continue;
}
for (CompartmentsInZoneIter comp(zone); !comp.done(); comp.next()) {
@ -7527,16 +7527,15 @@ Realm* js::NewRealm(JSContext* cx, JSPrincipals* principals,
if (!zone) {
zoneHolder = MakeUnique<Zone>(cx->runtime());
if (!zoneHolder) {
if (!zoneHolder || !zoneHolder->init()) {
ReportOutOfMemory(cx);
return nullptr;
}
const JSPrincipals* trusted = rt->trustedPrincipals();
bool isSystem = principals && principals == trusted;
if (!zoneHolder->init(isSystem)) {
ReportOutOfMemory(cx);
return nullptr;
if (isSystem) {
zoneHolder->setIsSystemZone();
}
zone = zoneHolder.get();
@ -7589,11 +7588,11 @@ Realm* js::NewRealm(JSContext* cx, JSPrincipals* principals,
if (zoneHolder) {
rt->gc.zones().infallibleAppend(zoneHolder.release());
// Lazily set the runtime's sytem zone.
// Lazily set the runtime's system zone.
if (compSpec == JS::CompartmentSpecifier::NewCompartmentInSystemZone) {
MOZ_RELEASE_ASSERT(!rt->gc.systemZone);
rt->gc.systemZone = zone;
zone->isSystem = true;
zone->setIsSystemZone();
}
}

Просмотреть файл

@ -15,6 +15,8 @@
#include "js/TracingAPI.h"
#include "js/TypeDecls.h"
class JSRope;
namespace js {
class AutoAccessAtomsZone;

Просмотреть файл

@ -12,6 +12,7 @@
#include "gc/StoreBuffer.h"
#include "gc/Zone.h"
#include "util/Poison.h"
#include "vm/Runtime.h"
inline void js::gc::Arena::init(JS::Zone* zoneArg, AllocKind kind,
const AutoLockGC& lock) {

Просмотреть файл

@ -17,6 +17,7 @@
#include "gc/GCRuntime.h"
#include "gc/Zone.h"
#include "vm/Compartment.h"
#include "vm/Runtime.h"
struct JSRuntime;

Просмотреть файл

@ -478,6 +478,7 @@ void js::gc::GCRuntime::finishRoots() {
rt->finishPersistentRoots();
rt->finishSelfHosting();
selfHostingZoneFrozen = false;
for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
zone->finishRoots();

Просмотреть файл

@ -9,6 +9,8 @@
#include "gc/Zone.h"
#include "vm/Runtime.h"
/* static */ inline js::HashNumber JS::Zone::UniqueIdToHash(uint64_t uid) {
return mozilla::HashGeneric(uid);
}

Просмотреть файл

@ -36,8 +36,6 @@ ZoneAllocator::ZoneAllocator(JSRuntime* rt)
mallocHeapSize(nullptr),
jitHeapSize(nullptr),
jitHeapThreshold(jit::MaxCodeBytesPerProcess * 0.8) {
AutoLockGC lock(rt);
updateGCThresholds(rt->gc, GC_NORMAL, lock);
}
ZoneAllocator::~ZoneAllocator() {
@ -143,7 +141,6 @@ JS::Zone::Zone(JSRuntime* rt)
tenuredBigInts(this, 0),
allocNurseryStrings(this, true),
allocNurseryBigInts(this, true),
isSystem(this, false),
suppressAllocationMetadataBuilder(this, false),
uniqueIds_(this),
tenuredAllocsSinceMinorGC_(0),
@ -179,7 +176,10 @@ JS::Zone::Zone(JSRuntime* rt)
/* Ensure that there are no vtables to mess us up here. */
MOZ_ASSERT(reinterpret_cast<JS::shadow::Zone*>(this) ==
static_cast<JS::shadow::Zone*>(this));
MOZ_ASSERT(gcSweepGroupIndex == 0);
// We can't call updateGCThresholds until the Zone has been constructed.
AutoLockGC lock(rt);
updateGCThresholds(rt->gc, GC_NORMAL, lock);
}
Zone::~Zone() {
@ -189,18 +189,37 @@ Zone::~Zone() {
JSRuntime* rt = runtimeFromAnyThread();
if (this == rt->gc.systemZone) {
MOZ_ASSERT(isSystemZone());
rt->gc.systemZone = nullptr;
}
js_delete(jitZone_.ref());
}
bool Zone::init(bool isSystemArg) {
isSystem = isSystemArg;
bool Zone::init() {
regExps_.ref() = make_unique<RegExpZone>(this);
return regExps_.ref() && gcWeakKeys().init() && gcNurseryWeakKeys().init();
}
void Zone::setIsAtomsZone() {
MOZ_ASSERT(!isAtomsZone_);
MOZ_ASSERT(runtimeFromAnyThread()->isAtomsZone(this));
isAtomsZone_ = true;
setIsSystemZone();
}
void Zone::setIsSelfHostingZone() {
MOZ_ASSERT(!isSelfHostingZone_);
MOZ_ASSERT(runtimeFromAnyThread()->isSelfHostingZone(this));
isSelfHostingZone_ = true;
setIsSystemZone();
}
void Zone::setIsSystemZone() {
MOZ_ASSERT(!isSystemZone_);
isSystemZone_ = true;
}
void Zone::setNeedsIncrementalBarrier(bool needs) {
needsIncrementalBarrier_ = needs;
}

Просмотреть файл

@ -11,18 +11,20 @@
#include "mozilla/HashFunctions.h"
#include "mozilla/SegmentedVector.h"
#include "ds/Bitmap.h"
#include "gc/ArenaList.h"
#include "gc/Barrier.h"
#include "gc/FindSCCs.h"
#include "gc/GCMarker.h"
#include "gc/NurseryAwareHashMap.h"
#include "gc/ZoneAllocator.h"
#include "js/GCHashTable.h"
#include "vm/MallocProvider.h"
#include "vm/Runtime.h"
#include "vm/AtomsTable.h"
#include "vm/JSScript.h"
#include "vm/TypeInference.h"
namespace js {
class Debugger;
class RegExpZone;
class WeakRefObject;
@ -32,6 +34,8 @@ class JitZone;
namespace gc {
class ZoneList;
using ZoneComponentFinder = ComponentFinder<JS::Zone>;
struct UniqueIdGCPolicy {
@ -171,6 +175,10 @@ namespace JS {
// to delete the last compartment in a live zone.
class Zone : public js::ZoneAllocator, public js::gc::GraphNodeBase<JS::Zone> {
private:
js::WriteOnceData<bool> isAtomsZone_;
js::WriteOnceData<bool> isSelfHostingZone_;
js::WriteOnceData<bool> isSystemZone_;
enum class HelperThreadUse : uint32_t { None, Pending, Active };
mozilla::Atomic<HelperThreadUse, mozilla::SequentiallyConsistent,
mozilla::recordreplay::Behavior::DontPreserve>
@ -194,8 +202,6 @@ class Zone : public js::ZoneAllocator, public js::gc::GraphNodeBase<JS::Zone> {
js::ZoneData<bool> allocNurseryStrings;
js::ZoneData<bool> allocNurseryBigInts;
js::ZoneData<bool> isSystem;
// When true, skip calling the metadata callback. We use this:
// - to avoid invoking the callback recursively;
// - to avoid observing lazy prototype setup (which confuses callbacks that
@ -353,7 +359,7 @@ class Zone : public js::ZoneAllocator, public js::gc::GraphNodeBase<JS::Zone> {
explicit Zone(JSRuntime* rt);
~Zone();
MOZ_MUST_USE bool init(bool isSystem);
MOZ_MUST_USE bool init();
void destroy(JSFreeOp* fop);
@ -485,10 +491,13 @@ class Zone : public js::ZoneAllocator, public js::gc::GraphNodeBase<JS::Zone> {
}
js::jit::JitZone* jitZone() { return jitZone_; }
bool isAtomsZone() const { return runtimeFromAnyThread()->isAtomsZone(this); }
bool isSelfHostingZone() const {
return runtimeFromAnyThread()->isSelfHostingZone(this);
}
bool isAtomsZone() const { return isAtomsZone_; }
bool isSelfHostingZone() const { return isSelfHostingZone_; }
bool isSystemZone() const { return isSystemZone_; }
void setIsAtomsZone();
void setIsSelfHostingZone();
void setIsSystemZone();
void prepareForCompacting();

Просмотреть файл

@ -337,10 +337,10 @@ JS_FRIEND_API bool js::IsSystemRealm(JS::Realm* realm) {
return realm->isSystem();
}
JS_FRIEND_API bool js::IsSystemZone(Zone* zone) { return zone->isSystem; }
JS_FRIEND_API bool js::IsSystemZone(Zone* zone) { return zone->isSystemZone(); }
JS_FRIEND_API bool js::IsAtomsZone(JS::Zone* zone) {
return zone->runtimeFromAnyThread()->isAtomsZone(zone);
return zone->isAtomsZone();
}
JS_FRIEND_API bool js::IsFunctionObject(JSObject* obj) {

Просмотреть файл

@ -10,6 +10,7 @@
#include "js/Wrapper.h"
#include "proxy/DeadObjectProxy.h"
#include "vm/Iteration.h"
#include "vm/Runtime.h"
#include "vm/WrapperObject.h"
#include "gc/Nursery-inl.h"

Просмотреть файл

@ -199,8 +199,8 @@ bool Compartment::getNonWrapperObjectForCurrentCompartment(
// associated with the self-hosting zone. We don't want to create
// wrappers for objects in other runtimes, which may be the case for the
// self-hosting zone.
MOZ_ASSERT(!cx->runtime()->isSelfHostingZone(cx->zone()));
MOZ_ASSERT(!cx->runtime()->isSelfHostingZone(obj->zone()));
MOZ_ASSERT(!cx->zone()->isSelfHostingZone());
MOZ_ASSERT(!obj->zone()->isSelfHostingZone());
// The object is already in the right compartment. Normally same-
// compartment returns the object itself, however, windows are always

Просмотреть файл

@ -114,6 +114,13 @@ bool Realm::init(JSContext* cx, JSPrincipals* principals) {
return true;
}
void Realm::setIsSelfHostingRealm() {
MOZ_ASSERT(!isSelfHostingRealm_);
MOZ_ASSERT(zone()->isSelfHostingZone());
isSelfHostingRealm_ = true;
isSystem_ = true;
}
bool JSRuntime::createJitRuntime(JSContext* cx) {
using namespace js::jit;

Просмотреть файл

@ -512,10 +512,7 @@ class JS::Realm : public JS::shadow::Realm {
bool preserveJitCode() { return creationOptions_.preserveJitCode(); }
bool isSelfHostingRealm() const { return isSelfHostingRealm_; }
void setIsSelfHostingRealm() {
isSelfHostingRealm_ = true;
isSystem_ = true;
}
void setIsSelfHostingRealm();
/* The global object for this realm.
*

Просмотреть файл

@ -210,11 +210,12 @@ bool JSRuntime::init(JSContext* cx, uint32_t maxbytes) {
}
UniquePtr<Zone> atomsZone = MakeUnique<Zone>(this);
if (!atomsZone || !atomsZone->init(true)) {
if (!atomsZone || !atomsZone->init()) {
return false;
}
gc.atomsZone = atomsZone.release();
gc.atomsZone->setIsAtomsZone();
// The garbage collector depends on everything before this point being
// initialized.

Просмотреть файл

@ -628,7 +628,6 @@ struct JSRuntime {
bool isSelfHostingGlobal(JSObject* global) {
return global == selfHostingGlobal_;
}
bool isSelfHostingZone(const JS::Zone* zone) const;
bool createLazySelfHostedFunctionClone(JSContext* cx,
js::HandlePropertyName selfHostedName,
js::HandleAtom name, unsigned nargs,
@ -642,6 +641,11 @@ struct JSRuntime {
js::MutableHandleValue vp);
void assertSelfHostedFunctionHasCanonicalName(JSContext* cx,
js::HandlePropertyName name);
#if DEBUG
bool isSelfHostingZone(const JS::Zone* zone) const {
return selfHostingGlobal_ && selfHostingGlobal_->zone() == zone;
}
#endif
//-------------------------------------------------------------------------
// Locale information
@ -763,7 +767,9 @@ struct JSRuntime {
}
JS::Zone* unsafeAtomsZone() { return gc.atomsZone; }
#ifdef DEBUG
bool isAtomsZone(const JS::Zone* zone) const { return zone == gc.atomsZone; }
#endif
bool activeGCInAtomsZone();

Просмотреть файл

@ -2621,6 +2621,7 @@ GlobalObject* JSRuntime::createSelfHostingGlobal(JSContext* cx) {
}
cx->runtime()->selfHostingGlobal_ = shg;
realm->zone()->setIsSelfHostingZone();
realm->setIsSelfHostingRealm();
if (!GlobalObject::initSelfHostingBuiltins(cx, shg, intrinsic_functions)) {
@ -2785,10 +2786,6 @@ void JSRuntime::traceSelfHostingGlobal(JSTracer* trc) {
}
}
bool JSRuntime::isSelfHostingZone(const JS::Zone* zone) const {
return selfHostingGlobal_ && selfHostingGlobal_->zoneFromAnyThread() == zone;
}
static bool CloneValue(JSContext* cx, HandleValue selfHostedValue,
MutableHandleValue vp);