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 11:04:49 +00:00
Родитель ed10bfc397
Коммит c1653cd065
15 изменённых файлов: 78 добавлений и 39 удалений

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

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

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

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

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

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

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

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

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

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

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

@ -36,8 +36,6 @@ ZoneAllocator::ZoneAllocator(JSRuntime* rt)
mallocHeapSize(nullptr), mallocHeapSize(nullptr),
jitHeapSize(nullptr), jitHeapSize(nullptr),
jitHeapThreshold(jit::MaxCodeBytesPerProcess * 0.8) { jitHeapThreshold(jit::MaxCodeBytesPerProcess * 0.8) {
AutoLockGC lock(rt);
updateGCThresholds(rt->gc, GC_NORMAL, lock);
} }
ZoneAllocator::~ZoneAllocator() { ZoneAllocator::~ZoneAllocator() {
@ -143,7 +141,6 @@ JS::Zone::Zone(JSRuntime* rt)
tenuredBigInts(this, 0), tenuredBigInts(this, 0),
allocNurseryStrings(this, true), allocNurseryStrings(this, true),
allocNurseryBigInts(this, true), allocNurseryBigInts(this, true),
isSystem(this, false),
suppressAllocationMetadataBuilder(this, false), suppressAllocationMetadataBuilder(this, false),
uniqueIds_(this), uniqueIds_(this),
tenuredAllocsSinceMinorGC_(0), tenuredAllocsSinceMinorGC_(0),
@ -179,7 +176,10 @@ JS::Zone::Zone(JSRuntime* rt)
/* Ensure that there are no vtables to mess us up here. */ /* Ensure that there are no vtables to mess us up here. */
MOZ_ASSERT(reinterpret_cast<JS::shadow::Zone*>(this) == MOZ_ASSERT(reinterpret_cast<JS::shadow::Zone*>(this) ==
static_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() { Zone::~Zone() {
@ -189,18 +189,37 @@ Zone::~Zone() {
JSRuntime* rt = runtimeFromAnyThread(); JSRuntime* rt = runtimeFromAnyThread();
if (this == rt->gc.systemZone) { if (this == rt->gc.systemZone) {
MOZ_ASSERT(isSystemZone());
rt->gc.systemZone = nullptr; rt->gc.systemZone = nullptr;
} }
js_delete(jitZone_.ref()); js_delete(jitZone_.ref());
} }
bool Zone::init(bool isSystemArg) { bool Zone::init() {
isSystem = isSystemArg;
regExps_.ref() = make_unique<RegExpZone>(this); regExps_.ref() = make_unique<RegExpZone>(this);
return regExps_.ref() && gcWeakKeys().init() && gcNurseryWeakKeys().init(); 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) { void Zone::setNeedsIncrementalBarrier(bool needs) {
needsIncrementalBarrier_ = needs; needsIncrementalBarrier_ = needs;
} }

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

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

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

@ -337,11 +337,9 @@ JS_FRIEND_API bool js::IsSystemRealm(JS::Realm* realm) {
return realm->isSystem(); 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) { JS_FRIEND_API bool js::IsAtomsZone(JS::Zone* zone) { return zone->isAtomsZone(); }
return zone->runtimeFromAnyThread()->isAtomsZone(zone);
}
JS_FRIEND_API bool js::IsFunctionObject(JSObject* obj) { JS_FRIEND_API bool js::IsFunctionObject(JSObject* obj) {
return obj->is<JSFunction>(); return obj->is<JSFunction>();

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

@ -10,6 +10,7 @@
#include "js/Wrapper.h" #include "js/Wrapper.h"
#include "proxy/DeadObjectProxy.h" #include "proxy/DeadObjectProxy.h"
#include "vm/Iteration.h" #include "vm/Iteration.h"
#include "vm/Runtime.h"
#include "vm/WrapperObject.h" #include "vm/WrapperObject.h"
#include "gc/Nursery-inl.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 // 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 // wrappers for objects in other runtimes, which may be the case for the
// self-hosting zone. // self-hosting zone.
MOZ_ASSERT(!cx->runtime()->isSelfHostingZone(cx->zone())); MOZ_ASSERT(!cx->zone()->isSelfHostingZone());
MOZ_ASSERT(!cx->runtime()->isSelfHostingZone(obj->zone())); MOZ_ASSERT(!obj->zone()->isSelfHostingZone());
// The object is already in the right compartment. Normally same- // The object is already in the right compartment. Normally same-
// compartment returns the object itself, however, windows are always // compartment returns the object itself, however, windows are always

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

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

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

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

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

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

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

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

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

@ -2621,6 +2621,7 @@ GlobalObject* JSRuntime::createSelfHostingGlobal(JSContext* cx) {
} }
cx->runtime()->selfHostingGlobal_ = shg; cx->runtime()->selfHostingGlobal_ = shg;
realm->zone()->setIsSelfHostingZone();
realm->setIsSelfHostingRealm(); realm->setIsSelfHostingRealm();
if (!GlobalObject::initSelfHostingBuiltins(cx, shg, intrinsic_functions)) { 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, static bool CloneValue(JSContext* cx, HandleValue selfHostedValue,
MutableHandleValue vp); MutableHandleValue vp);