Bug 1688794 - Remove code for the (now unused) self-hosting zone. r=jandem,jonco

The dedicated zone for self-hosting can now be removed entirely. Also remove the
object cloning code that was only used for the old self-hosting mechanism.

Differential Revision: https://phabricator.services.mozilla.com/D120547
This commit is contained in:
Ted Campbell 2021-07-28 14:10:01 +00:00
Родитель 1f57d353aa
Коммит f3326c91ec
28 изменённых файлов: 35 добавлений и 598 удалений

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

@ -548,7 +548,7 @@ namespace JS {
D(FULL_CELL_PTR_STR_BUFFER, 28) \
D(TOO_MUCH_JIT_CODE, 29) \
D(FULL_CELL_PTR_BIGINT_BUFFER, 30) \
D(INIT_SELF_HOSTING, 31) \
D(UNUSED5, 31) \
D(NURSERY_MALLOC_BUFFERS, 32) \
\
/* \

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

@ -48,9 +48,6 @@ enum class CompartmentSpecifier {
// Create a new realm in an existing compartment.
ExistingCompartment,
// Internal use only. Create the self-hosting compartment.
NewCompartmentInSelfHostingZone,
};
/**
@ -98,7 +95,6 @@ class JS_PUBLIC_API RealmCreationOptions {
RealmCreationOptions& setNewCompartmentAndZone();
RealmCreationOptions& setExistingCompartment(JSObject* obj);
RealmCreationOptions& setExistingCompartment(Compartment* compartment);
RealmCreationOptions& setNewCompartmentInSelfHostingZone();
// Certain compartments are implementation details of the embedding, and
// references to them should never leak out to script. This flag causes this

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

@ -33,7 +33,7 @@ struct Zone {
Compact
};
enum Kind : uint8_t { NormalZone, AtomsZone, SelfHostingZone, SystemZone };
enum Kind : uint8_t { NormalZone, AtomsZone, SystemZone };
protected:
JSRuntime* const runtime_;
@ -82,7 +82,6 @@ struct Zone {
}
bool isAtomsZone() const { return kind_ == AtomsZone; }
bool isSelfHostingZone() const { return kind_ == SelfHostingZone; }
bool isSystemZone() const { return kind_ == SystemZone; }
static shadow::Zone* from(JS::Zone* zone) {

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

@ -63,10 +63,6 @@
#define PROP_DESC_GETTER_INDEX 1
#define PROP_DESC_SETTER_INDEX 2
// The extended slot of uncloned self-hosted function, in which the canonical
// name for self-hosted builtins is stored by `_SetCanonicalName`.
#define CANONICAL_FUNCTION_NAME_SLOT 0
// The extended slot of cloned self-hosted function, in which the self-hosted
// name for self-hosted builtins is stored.
#define LAZY_FUNCTION_NAME_SLOT 0

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

@ -5938,10 +5938,6 @@ bool Debugger::CallData::findAllGlobals() {
GlobalObject* global = r->maybeGlobal();
if (cx->runtime()->isSelfHostingGlobal(global)) {
continue;
}
// We pulled |global| out of nowhere, so it's possible that it was
// marked gray by XPConnect. Since we're now exposing it to JS code,
// we need to mark it black.

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

@ -432,8 +432,6 @@ bool GCRuntime::checkAllocatorState(JSContext* cx, AllocKind kind) {
kind == AllocKind::SCOPE);
MOZ_ASSERT_IF(!cx->zone()->isAtomsZone(),
kind != AllocKind::ATOM && kind != AllocKind::FAT_INLINE_ATOM);
MOZ_ASSERT_IF(cx->zone()->isSelfHostingZone(),
!rt->parentRuntime && !selfHostingZoneFrozen);
MOZ_ASSERT(!JS::RuntimeHeapIsBusy());
#endif

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

@ -227,7 +227,6 @@ template <typename T>
// into another runtime. The zone's uid lock will protect against multiple
// workers doing this simultaneously.
MOZ_ASSERT(CurrentThreadCanAccessZone(l->zoneFromAnyThread()) ||
l->zoneFromAnyThread()->isSelfHostingZone() ||
CurrentThreadIsPerformingGC());
return l->zoneFromAnyThread()->getHashCodeInfallible(l);
@ -245,8 +244,7 @@ template <typename T>
MOZ_ASSERT(k);
MOZ_ASSERT(l);
MOZ_ASSERT(CurrentThreadCanAccessZone(l->zoneFromAnyThread()) ||
l->zoneFromAnyThread()->isSelfHostingZone());
MOZ_ASSERT(CurrentThreadCanAccessZone(l->zoneFromAnyThread()));
Zone* zone = k->zoneFromAnyThread();
if (zone != l->zoneFromAnyThread()) {

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

@ -520,9 +520,6 @@ MOZ_ALWAYS_INLINE void PreWriteBarrierImpl(TenuredCell* thing) {
// - while we are verifying pre-barriers for a worker runtime
// The barrier is not required in either case.
bool checkThread = zone->isAtomsZone();
#ifdef JS_GC_ZEAL
checkThread = checkThread || zone->isSelfHostingZone();
#endif
JSRuntime* runtime = thing->runtimeFromAnyThread();
if (checkThread && !CurrentThreadCanAccessRuntime(runtime)) {
MOZ_ASSERT(CurrentThreadIsGCFinalizing() ||

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

@ -1597,21 +1597,6 @@ bool GCRuntime::init(uint32_t maxbytes) {
return true;
}
void GCRuntime::freezeSelfHostingZone() {
MOZ_ASSERT(!selfHostingZoneFrozen);
MOZ_ASSERT(!isIncrementalGCInProgress());
for (ZonesIter zone(this, WithAtoms); !zone.done(); zone.next()) {
MOZ_ASSERT(!zone->isGCScheduled());
if (zone->isSelfHostingZone()) {
zone->scheduleGC();
}
}
gc(JS::GCOptions::Shrink, JS::GCReason::INIT_SELF_HOSTING);
selfHostingZoneFrozen = true;
}
void GCRuntime::finish() {
MOZ_ASSERT(inPageLoadCount == 0);
@ -2154,15 +2139,7 @@ AutoDisableCompactingGC::~AutoDisableCompactingGC() {
}
bool GCRuntime::canRelocateZone(Zone* zone) const {
if (zone->isAtomsZone()) {
return false;
}
if (zone->isSelfHostingZone() && selfHostingZoneFrozen) {
return false;
}
return true;
return !zone->isAtomsZone();
}
#ifdef DEBUG
@ -4370,9 +4347,6 @@ void GCRuntime::discardJITCodeForGC() {
void GCRuntime::relazifyFunctionsForShrinkingGC() {
gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::RELAZIFY_FUNCTIONS);
for (GCZonesIter zone(this); !zone.done(); zone.next()) {
if (zone->isSelfHostingZone()) {
continue;
}
RelazifyFunctions(zone, AllocKind::FUNCTION);
RelazifyFunctions(zone, AllocKind::FUNCTION_EXTENDED);
}
@ -8298,19 +8272,14 @@ Realm* js::NewRealm(JSContext* cx, JSPrincipals* principals,
zone = comp->zone();
break;
case JS::CompartmentSpecifier::NewCompartmentAndZone:
case JS::CompartmentSpecifier::NewCompartmentInSelfHostingZone:
break;
}
if (!zone) {
Zone::Kind kind = Zone::NormalZone;
const JSPrincipals* trusted = rt->trustedPrincipals();
if (compSpec == JS::CompartmentSpecifier::NewCompartmentInSelfHostingZone) {
MOZ_ASSERT(!rt->hasInitializedSelfHosting());
kind = Zone::SelfHostingZone;
} else if (compSpec ==
JS::CompartmentSpecifier::NewCompartmentInSystemZone ||
(principals && principals == trusted)) {
if (compSpec == JS::CompartmentSpecifier::NewCompartmentInSystemZone ||
(principals && principals == trusted)) {
kind = Zone::SystemZone;
}

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

@ -135,8 +135,6 @@ void WaitForBackgroundTasks(JSContext* cx);
*/
void MergeRealms(JS::Realm* source, JS::Realm* target);
void CollectSelfHostingZone(JSContext* cx);
enum VerifierType { PreBarrierVerifier };
#ifdef JS_GC_ZEAL

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

@ -290,9 +290,6 @@ class GCRuntime {
JS::HeapState heapState() const { return heapState_; }
void freezeSelfHostingZone();
bool isSelfHostingZoneFrozen() const { return selfHostingZoneFrozen; }
inline bool hasZealMode(ZealMode mode);
inline void clearZealMode(ZealMode mode);
inline bool upcomingZealousGC();
@ -960,12 +957,6 @@ class GCRuntime {
mozilla::Atomic<size_t, mozilla::ReleaseAcquire> numActiveZoneIters;
/*
* The self hosting zone is collected once after initialization. We don't
* allow allocation after this point and we don't collect it again.
*/
WriteOnceData<bool> selfHostingZoneFrozen;
/* During shutdown, the GC needs to clean up every possible object. */
MainThreadData<bool> cleanUpEverything;

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

@ -169,8 +169,7 @@ static inline bool IsThingPoisoned(T* thing) {
template <typename T>
static inline bool IsOwnedByOtherRuntime(JSRuntime* rt, T thing) {
bool other = thing->runtimeFromAnyThread() != rt;
MOZ_ASSERT_IF(other, thing->isPermanentAndMayBeShared() ||
thing->zoneFromAnyThread()->isSelfHostingZone());
MOZ_ASSERT_IF(other, thing->isPermanentAndMayBeShared());
return other;
}

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

@ -343,8 +343,7 @@ void js::gc::GCRuntime::traceRuntimeCommon(JSTracer* trc,
// Trace runtime global roots.
TracePersistentRooted(rt, trc);
// Trace the self-hosting global compartment.
rt->traceSelfHostingGlobal(trc);
// Trace the self-hosting stencil.
rt->traceSelfHostingStencil(trc);
#ifdef JS_HAS_INTL_API
@ -445,7 +444,6 @@ void js::gc::GCRuntime::finishRoots() {
rt->finishPersistentRoots();
rt->finishSelfHosting();
selfHostingZoneFrozen = false;
for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
zone->finishRoots();

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

@ -50,8 +50,7 @@ void JS::TracingContext::getEdgeName(char* buffer, size_t bufferSize) {
JS_PUBLIC_API void JS::TraceChildren(JSTracer* trc, GCCellPtr thing) {
ApplyGCThingTyped(thing.asCell(), thing.kind(), [trc](auto t) {
MOZ_ASSERT_IF(t->runtimeFromAnyThread() != trc->runtime(),
t->isPermanentAndMayBeShared() ||
t->zoneFromAnyThread()->isSelfHostingZone());
t->isPermanentAndMayBeShared());
t->traceChildren(trc);
});
}

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

@ -190,7 +190,6 @@ JS::Zone::Zone(JSRuntime* rt, Kind kind)
MOZ_ASSERT(reinterpret_cast<JS::shadow::Zone*>(this) ==
static_cast<JS::shadow::Zone*>(this));
MOZ_ASSERT_IF(isAtomsZone(), !rt->unsafeAtomsZone());
MOZ_ASSERT_IF(isSelfHostingZone(), !rt->hasInitializedSelfHosting());
// We can't call updateGCStartThresholds until the Zone has been constructed.
AutoLockGC lock(rt);
@ -585,11 +584,6 @@ bool Zone::canCollect() {
return !runtimeFromAnyThread()->hasHelperThreadZones();
}
// We don't collect the self hosting zone after it has been initialized.
if (isSelfHostingZone()) {
return !runtimeFromAnyThread()->gc.isSelfHostingZoneFrozen();
}
// Zones that will be or are currently used by other threads cannot be
// collected.
return !createdForHelperThread();

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

@ -1739,13 +1739,6 @@ JS::RealmCreationOptions& JS::RealmCreationOptions::setNewCompartmentAndZone() {
return *this;
}
JS::RealmCreationOptions&
JS::RealmCreationOptions::setNewCompartmentInSelfHostingZone() {
compSpec_ = CompartmentSpecifier::NewCompartmentInSelfHostingZone;
comp_ = nullptr;
return *this;
}
const JS::RealmCreationOptions& JS::RealmCreationOptionsRef(Realm* realm) {
return realm->creationOptions();
}

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

@ -291,14 +291,6 @@ void js::ErrorToException(JSContext* cx, JSErrorReport* reportp,
JSErrorCallback callback, void* userRef) {
MOZ_ASSERT(!reportp->isWarning());
// We cannot throw a proper object inside the self-hosting realm, as we
// cannot construct the Error constructor without self-hosted code. Just
// print the error to stderr to help debugging.
if (cx->realm()->isSelfHostingRealm()) {
JS::PrintError(stderr, reportp, true);
return;
}
// Find the exception index associated with this error.
JSErrNum errorNumber = static_cast<JSErrNum>(reportp->errorNumber);
if (!callback) {

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

@ -209,13 +209,6 @@ bool Compartment::getNonWrapperObjectForCurrentCompartment(
// Ensure that we have entered a realm.
MOZ_ASSERT(cx->global());
// If we have a cross-compartment wrapper, make sure that the cx isn't
// 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->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
// wrapped by a proxy, so we have to check for that case here manually.

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

@ -833,8 +833,7 @@ bool FrameIter::matchCallee(JSContext* cx, JS::Handle<JSFunction*> fun) const {
// the script clones do not use the same script, they also have a different
// group and Ion will not inline them interchangeably.
//
// See: js::jit::InlineFrameIterator::findNextFrame(),
// js::CloneFunctionAndScript()
// See: js::jit::InlineFrameIterator::findNextFrame()
if (currentCallee->hasBaseScript()) {
if (currentCallee->baseScript() != fun->baseScript()) {
return false;

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

@ -338,28 +338,24 @@ bool GlobalObject::resolveConstructor(JSContext* cx,
global->setConstructor(key, ObjectValue(*ctor));
}
// If we're operating on the self-hosting global, we don't want any
// functions and properties on the builtins and their prototypes.
if (!cx->runtime()->isSelfHostingGlobal(global)) {
if (const JSFunctionSpec* funs = clasp->specPrototypeFunctions()) {
if (!JS_DefineFunctions(cx, proto, funs)) {
return false;
}
if (const JSFunctionSpec* funs = clasp->specPrototypeFunctions()) {
if (!JS_DefineFunctions(cx, proto, funs)) {
return false;
}
if (const JSPropertySpec* props = clasp->specPrototypeProperties()) {
if (!JS_DefineProperties(cx, proto, props)) {
return false;
}
}
if (const JSPropertySpec* props = clasp->specPrototypeProperties()) {
if (!JS_DefineProperties(cx, proto, props)) {
return false;
}
if (const JSFunctionSpec* funs = clasp->specConstructorFunctions()) {
if (!JS_DefineFunctions(cx, ctor, funs)) {
return false;
}
}
if (const JSFunctionSpec* funs = clasp->specConstructorFunctions()) {
if (!JS_DefineFunctions(cx, ctor, funs)) {
return false;
}
if (const JSPropertySpec* props = clasp->specConstructorProperties()) {
if (!JS_DefineProperties(cx, ctor, props)) {
return false;
}
}
if (const JSPropertySpec* props = clasp->specConstructorProperties()) {
if (!JS_DefineProperties(cx, ctor, props)) {
return false;
}
}
@ -937,15 +933,10 @@ NativeObject* GlobalObject::getIntrinsicsHolder(JSContext* cx,
return &slot.toObject().as<NativeObject>();
}
Rooted<NativeObject*> intrinsicsHolder(cx);
bool isSelfHostingGlobal = cx->runtime()->isSelfHostingGlobal(global);
if (isSelfHostingGlobal) {
intrinsicsHolder = global;
} else {
intrinsicsHolder = NewTenuredObjectWithGivenProto<PlainObject>(cx, nullptr);
if (!intrinsicsHolder) {
return nullptr;
}
Rooted<NativeObject*> intrinsicsHolder(
cx, NewTenuredObjectWithGivenProto<PlainObject>(cx, nullptr));
if (!intrinsicsHolder) {
return nullptr;
}
// Define a top-level property 'undefined' with the undefined value.

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

@ -1571,10 +1571,6 @@ void JSFunction::maybeRelazify(JSRuntime* rt) {
MOZ_ASSERT(!realm->hasBeenEnteredIgnoringJit());
}
// The caller should have checked we're not in the self-hosting zone (it's
// shared with worker runtimes so relazifying functions in it will race).
MOZ_ASSERT(!realm->isSelfHostingRealm());
// Don't relazify if the realm is being debugged. The debugger side-tables
// such as the set of active breakpoints require bytecode to exist.
if (realm->isDebuggee()) {
@ -1963,15 +1959,6 @@ JSFunction* js::NewFunctionWithProto(
bool js::GetFunctionPrototype(JSContext* cx, js::GeneratorKind generatorKind,
js::FunctionAsyncKind asyncKind,
js::MutableHandleObject proto) {
// Self-hosted functions have null [[Prototype]]. This allows self-hosting to
// support generators, despite this loop in the builtin object graph:
// - %Generator%.prototype.[[Prototype]] is Iterator.prototype;
// - Iterator.prototype has self-hosted methods (iterator helpers).
if (cx->realm()->isSelfHostingRealm()) {
proto.set(nullptr);
return true;
}
if (generatorKind == js::GeneratorKind::NotGenerator) {
if (asyncKind == js::FunctionAsyncKind::SyncFunction) {
proto.set(nullptr);
@ -2103,45 +2090,6 @@ JSFunction* js::CloneFunctionReuseScript(JSContext* cx, HandleFunction fun,
return clone;
}
JSFunction* js::CloneFunctionAndScript(JSContext* cx, HandleFunction fun,
HandleObject enclosingEnv,
HandleScope newScope,
Handle<ScriptSourceObject*> sourceObject,
gc::AllocKind allocKind,
HandleObject proto /* = nullptr */) {
MOZ_ASSERT(NewFunctionEnvironmentIsWellFormed(cx, enclosingEnv));
MOZ_ASSERT(fun->isInterpreted());
MOZ_ASSERT(!fun->isBoundFunction());
JSScript::AutoDelazify funScript(cx, fun);
if (!funScript) {
return nullptr;
}
RootedFunction clone(
cx, NewFunctionClone(cx, fun, TenuredObject, allocKind, proto));
if (!clone) {
return nullptr;
}
clone->initScript(nullptr);
clone->initEnvironment(enclosingEnv);
RootedScript script(cx, fun->nonLazyScript());
MOZ_ASSERT(script->realm() == fun->realm());
MOZ_ASSERT(cx->compartment() == clone->compartment(),
"Otherwise we could relazify clone below!");
RootedScript clonedScript(
cx, CloneScriptIntoFunction(cx, newScope, clone, script, sourceObject));
if (!clonedScript) {
return nullptr;
}
DebugAPI::onNewScript(cx, clonedScript);
return clone;
}
JSFunction* js::CloneAsmJSModuleFunction(JSContext* cx, HandleFunction fun) {
MOZ_ASSERT(fun->isNativeFun());
MOZ_ASSERT(IsAsmJSModule(fun));
@ -2162,24 +2110,6 @@ JSFunction* js::CloneAsmJSModuleFunction(JSContext* cx, HandleFunction fun) {
return clone;
}
JSFunction* js::CloneSelfHostingIntrinsic(JSContext* cx, HandleFunction fun) {
MOZ_ASSERT(fun->isNativeFun());
MOZ_ASSERT(fun->realm()->isSelfHostingRealm());
MOZ_ASSERT(!fun->isExtended());
MOZ_ASSERT(cx->compartment() != fun->compartment());
JSFunction* clone =
NewFunctionClone(cx, fun, TenuredObject, gc::AllocKind::FUNCTION,
/* proto = */ nullptr);
if (!clone) {
return nullptr;
}
clone->initNative(fun->native(),
fun->hasJitInfo() ? fun->jitInfo() : nullptr);
return clone;
}
static JSAtom* SymbolToFunctionName(JSContext* cx, JS::Symbol* symbol,
FunctionPrefixKind prefixKind) {
// Step 4.a.

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

@ -817,15 +817,8 @@ extern JSFunction* CloneFunctionReuseScript(JSContext* cx, HandleFunction fun,
gc::AllocKind kind,
HandleObject proto);
extern JSFunction* CloneFunctionAndScript(
JSContext* cx, HandleFunction fun, HandleObject enclosingEnv,
HandleScope newScope, Handle<ScriptSourceObject*> sourceObject,
gc::AllocKind kind, HandleObject proto = nullptr);
extern JSFunction* CloneAsmJSModuleFunction(JSContext* cx, HandleFunction fun);
extern JSFunction* CloneSelfHostingIntrinsic(JSContext* cx, HandleFunction fun);
} // namespace js
inline js::FunctionExtended* JSFunction::toExtended() {

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

@ -4840,27 +4840,17 @@ gc::AllocSite* JSScript::createAllocSite() {
void JSScript::AutoDelazify::holdScript(JS::HandleFunction fun) {
if (fun) {
if (fun->realm()->isSelfHostingRealm()) {
// The self-hosting realm is shared across runtimes, so we can't use
// JSAutoRealm: it could cause races. Functions in the self-hosting
// realm will never be lazy, so we can safely assume we don't have
// to delazify.
script_ = fun->nonLazyScript();
} else {
JSAutoRealm ar(cx_, fun);
script_ = JSFunction::getOrCreateScript(cx_, fun);
if (script_) {
oldAllowRelazify_ = script_->allowRelazify();
script_->clearAllowRelazify();
}
JSAutoRealm ar(cx_, fun);
script_ = JSFunction::getOrCreateScript(cx_, fun);
if (script_) {
oldAllowRelazify_ = script_->allowRelazify();
script_->clearAllowRelazify();
}
}
}
void JSScript::AutoDelazify::dropScript() {
// Don't touch script_ if it's in the self-hosting realm, see the comment
// in holdScript.
if (script_ && !script_->realm()->isSelfHostingRealm()) {
if (script_) {
script_->setAllowRelazify(oldAllowRelazify_);
}
script_ = nullptr;

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

@ -118,13 +118,6 @@ 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;

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

@ -409,7 +409,6 @@ class JS::Realm : public JS::shadow::Realm {
unsigned debugModeBits_ = 0;
friend class js::AutoRestoreRealmDebugMode;
bool isSelfHostingRealm_ = false;
bool isSystem_ = false;
js::UniquePtr<js::coverage::LCovRealm> lcovRealm_ = nullptr;
@ -500,9 +499,6 @@ class JS::Realm : public JS::shadow::Realm {
/* Whether to preserve JIT code on non-shrinking GCs. */
bool preserveJitCode() { return creationOptions_.preserveJitCode(); }
bool isSelfHostingRealm() const { return isSelfHostingRealm_; }
void setIsSelfHostingRealm();
/* The global object for this realm.
*
* Note: the global_ field is null briefly during GC, after the global

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

@ -131,7 +131,6 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime)
scriptAndCountsVector(nullptr),
lcovOutput_(),
jitRuntime_(nullptr),
selfHostingGlobal_(nullptr),
gc(thisFromCtor()),
gcInitialized(false),
emptyString(nullptr),

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

@ -658,18 +658,7 @@ struct JSRuntime {
private:
js::UnprotectedData<js::jit::JitRuntime*> jitRuntime_;
/*
* Self-hosting state cloned on demand into other compartments. Shared with
* the parent runtime if there is one.
*/
js::WriteOnceData<js::NativeObject*> selfHostingGlobal_;
static js::GlobalObject* createSelfHostingGlobal(JSContext* cx);
public:
void getUnclonedSelfHostedValue(js::PropertyName* name, JS::Value* vp);
JSFunction* getUnclonedSelfHostedFunction(js::PropertyName* name);
mozilla::Maybe<js::frontend::ScriptIndexRange> getSelfHostedScriptIndexRange(
js::PropertyName* name);
@ -701,11 +690,7 @@ struct JSRuntime {
bool initSelfHosting(JSContext* cx, JS::SelfHostedCache xdrCache = nullptr,
JS::SelfHostedWriter xdrWriter = nullptr);
void finishSelfHosting();
void traceSelfHostingGlobal(JSTracer* trc);
void traceSelfHostingStencil(JSTracer* trc);
bool isSelfHostingGlobal(JSObject* global) {
return global == selfHostingGlobal_;
}
js::GeneratorKind getSelfHostedFunctionGeneratorKind(js::PropertyName* name);
bool delazifySelfHostedFunction(JSContext* cx,
js::Handle<js::PropertyName*> name,
@ -713,11 +698,6 @@ struct JSRuntime {
bool getSelfHostedValue(JSContext* cx, js::Handle<js::PropertyName*> name,
js::MutableHandleValue vp);
void assertSelfHostedFunctionHasCanonicalName(js::HandlePropertyName name);
#if DEBUG
bool isSelfHostingZone(const JS::Zone* zone) const {
return selfHostingGlobal_ && selfHostingGlobal_->zone() == zone;
}
#endif
//-------------------------------------------------------------------------
// Locale information

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

@ -894,17 +894,6 @@ bool js::intrinsic_NewRegExpStringIterator(JSContext* cx, unsigned argc,
return true;
}
static js::PropertyName* GetUnclonedSelfHostedCanonicalName(JSFunction* fun) {
if (!fun->isExtended()) {
return nullptr;
}
Value name = fun->getExtendedSlot(CANONICAL_FUNCTION_NAME_SLOT);
if (!name.isString()) {
return nullptr;
}
return name.toString()->asAtom().asPropertyName();
}
js::PropertyName* js::GetClonedSelfHostedFunctionName(const JSFunction* fun) {
if (!fun->isExtended()) {
return nullptr;
@ -933,10 +922,6 @@ bool js::IsExtendedUnclonedSelfHostedFunctionName(JSAtom* name) {
ExtendedUnclonedSelfHostedFunctionNamePrefix;
}
void js::SetUnclonedSelfHostedCanonicalName(JSFunction* fun, JSAtom* name) {
fun->setExtendedSlot(CANONICAL_FUNCTION_NAME_SLOT, StringValue(name));
}
void js::SetClonedSelfHostedFunctionName(JSFunction* fun,
js::PropertyName* name) {
fun->setExtendedSlot(LAZY_FUNCTION_NAME_SLOT, StringValue(name));
@ -2597,53 +2582,6 @@ void js::FillSelfHostingCompileOptions(CompileOptions& options) {
options.setNoScriptRval(true);
}
GlobalObject* JSRuntime::createSelfHostingGlobal(JSContext* cx) {
MOZ_ASSERT(!cx->isExceptionPending());
MOZ_ASSERT(!cx->realm());
JS::RealmOptions options;
options.creationOptions().setNewCompartmentInSelfHostingZone();
// Debugging the selfHosted zone is not supported because CCWs are not
// allowed in that zone.
options.creationOptions().setInvisibleToDebugger(true);
Realm* realm = NewRealm(cx, nullptr, options);
if (!realm) {
return nullptr;
}
static const JSClassOps shgClassOps = {
nullptr, // addProperty
nullptr, // delProperty
nullptr, // enumerate
nullptr, // newEnumerate
nullptr, // resolve
nullptr, // mayResolve
nullptr, // finalize
nullptr, // call
nullptr, // hasInstance
nullptr, // construct
JS_GlobalObjectTraceHook, // trace
};
static const JSClass shgClass = {"self-hosting-global", JSCLASS_GLOBAL_FLAGS,
&shgClassOps};
AutoRealmUnchecked ar(cx, realm);
Rooted<GlobalObject*> shg(cx, GlobalObject::createInternal(cx, &shgClass));
if (!shg) {
return nullptr;
}
cx->runtime()->selfHostingGlobal_ = shg;
MOZ_ASSERT(realm->zone()->isSelfHostingZone());
realm->setIsSelfHostingRealm();
JS_FireOnNewGlobalObject(cx, shg);
return shg;
}
class MOZ_STACK_CLASS AutoSelfHostingErrorReporter {
JSContext* cx_;
JS::WarningReporter oldReporter_;
@ -2864,15 +2802,6 @@ void JSRuntime::finishSelfHosting() {
selfHostStencil_ = nullptr;
selfHostScriptMap.ref().clear();
selfHostingGlobal_ = nullptr;
}
void JSRuntime::traceSelfHostingGlobal(JSTracer* trc) {
if (selfHostingGlobal_ && !parentRuntime) {
TraceRoot(trc, const_cast<NativeObject**>(&selfHostingGlobal_.ref()),
"self-hosting global");
}
}
void JSRuntime::traceSelfHostingStencil(JSTracer* trc) {
@ -2891,124 +2820,6 @@ GeneratorKind JSRuntime::getSelfHostedFunctionGeneratorKind(
: GeneratorKind::NotGenerator;
}
static bool CloneValue(JSContext* cx, HandleValue selfHostedValue,
MutableHandleValue vp);
static void GetUnclonedValue(NativeObject* selfHostedObject,
const PropertyKey& id, Value* vp) {
if (JSID_IS_INT(id)) {
size_t index = JSID_TO_INT(id);
if (index < selfHostedObject->getDenseInitializedLength() &&
!selfHostedObject->getDenseElement(index).isMagic(JS_ELEMENTS_HOLE)) {
*vp = selfHostedObject->getDenseElement(JSID_TO_INT(id));
return;
}
}
// Since all atoms used by self-hosting are marked as permanent, the only
// reason we'd see a non-permanent atom here is code looking for
// properties on the self hosted global which aren't present.
// Since we ensure that that can't happen during startup, encountering
// non-permanent atoms here should be impossible.
MOZ_ASSERT_IF(JSID_IS_STRING(id), JSID_TO_STRING(id)->isPermanentAtom());
mozilla::Maybe<PropertyInfo> prop = selfHostedObject->lookupPure(id);
MOZ_ASSERT(prop.isSome());
MOZ_ASSERT(prop->isDataProperty());
*vp = selfHostedObject->getSlot(prop->slot());
}
static bool CloneProperties(JSContext* cx, HandleNativeObject selfHostedObject,
HandleObject clone) {
RootedIdVector ids(cx);
Vector<uint8_t, 16> attrs(cx);
for (size_t i = 0; i < selfHostedObject->getDenseInitializedLength(); i++) {
if (!selfHostedObject->getDenseElement(i).isMagic(JS_ELEMENTS_HOLE)) {
if (!ids.append(INT_TO_JSID(i))) {
return false;
}
if (!attrs.append(JSPROP_ENUMERATE)) {
return false;
}
}
}
Rooted<PropertyInfoWithKeyVector> props(cx, PropertyInfoWithKeyVector(cx));
for (ShapePropertyIter<NoGC> iter(selfHostedObject->shape()); !iter.done();
iter++) {
if (iter->enumerable() && !props.append(*iter)) {
return false;
}
}
// Now our properties are in last-to-first order, so....
std::reverse(props.begin(), props.end());
for (size_t i = 0; i < props.length(); ++i) {
MOZ_ASSERT(props[i].isDataProperty(),
"Can't handle cloning accessors here yet.");
if (!ids.append(props[i].key())) {
return false;
}
PropertyInfo prop = props[i];
uint8_t propAttrs = 0;
if (prop.enumerable()) {
propAttrs |= JSPROP_ENUMERATE;
}
if (!prop.configurable()) {
propAttrs |= JSPROP_PERMANENT;
}
if (!prop.writable()) {
propAttrs |= JSPROP_READONLY;
}
if (!attrs.append(propAttrs)) {
return false;
}
}
RootedId id(cx);
RootedValue val(cx);
RootedValue selfHostedValue(cx);
for (uint32_t i = 0; i < ids.length(); i++) {
id = ids[i];
GetUnclonedValue(selfHostedObject, id, selfHostedValue.address());
if (!CloneValue(cx, selfHostedValue, &val) ||
!JS_DefinePropertyById(cx, clone, id, val, attrs[i])) {
return false;
}
}
return true;
}
static JSString* CloneString(JSContext* cx, JSLinearString* selfHostedString) {
size_t len = selfHostedString->length();
{
JS::AutoCheckCannotGC nogc;
JSString* clone;
if (selfHostedString->hasLatin1Chars()) {
clone =
NewStringCopyN<NoGC>(cx, selfHostedString->latin1Chars(nogc), len);
} else {
clone = NewStringCopyNDontDeflate<NoGC>(
cx, selfHostedString->twoByteChars(nogc), len);
}
if (clone) {
return clone;
}
}
AutoStableStringChars chars(cx);
if (!chars.init(cx, selfHostedString)) {
return nullptr;
}
return chars.isLatin1()
? NewStringCopyN<CanGC>(cx, chars.latin1Range().begin().get(), len)
: NewStringCopyNDontDeflate<CanGC>(
cx, chars.twoByteRange().begin().get(), len);
}
// Returns the ScriptSourceObject to use for cloned self-hosted scripts in the
// current realm.
ScriptSourceObject* js::SelfHostingScriptSourceObject(JSContext* cx) {
@ -3042,146 +2853,6 @@ ScriptSourceObject* js::SelfHostingScriptSourceObject(JSContext* cx) {
return sourceObject;
}
static JSObject* CloneObject(JSContext* cx,
HandleNativeObject selfHostedObject) {
#ifdef DEBUG
// Object hash identities are owned by the hashed object, which may be on a
// different thread than the clone target. In theory, these objects are all
// tenured and will not be compacted; however, we simply avoid the issue
// altogether by skipping the cycle-detection when off thread.
mozilla::Maybe<AutoCycleDetector> detect;
if (js::CurrentThreadCanAccessZone(selfHostedObject->zoneFromAnyThread())) {
detect.emplace(cx, selfHostedObject);
if (!detect->init()) {
return nullptr;
}
if (detect->foundCycle()) {
MOZ_CRASH("SelfHosted cloning cannot handle cyclic object graphs.");
}
}
#endif
RootedObject clone(cx);
if (selfHostedObject->is<JSFunction>()) {
RootedFunction selfHostedFunction(cx, &selfHostedObject->as<JSFunction>());
if (selfHostedFunction->isInterpreted()) {
// Arrow functions use the first extended slot for their lexical |this|
// value. And methods use the first extended slot for their home-object.
// We only expect to see normal functions here.
MOZ_ASSERT(selfHostedFunction->kind() == FunctionFlags::NormalFunction);
MOZ_ASSERT(selfHostedFunction->isLambda() == false);
Handle<GlobalObject*> global = cx->global();
Rooted<GlobalLexicalEnvironmentObject*> globalLexical(
cx, &global->lexicalEnvironment());
RootedScope emptyGlobalScope(cx, &global->emptyGlobalScope());
Rooted<ScriptSourceObject*> sourceObject(
cx, SelfHostingScriptSourceObject(cx));
if (!sourceObject) {
return nullptr;
}
MOZ_ASSERT(
!CanReuseScriptForClone(cx->realm(), selfHostedFunction, global));
clone = CloneFunctionAndScript(cx, selfHostedFunction, globalLexical,
emptyGlobalScope, sourceObject,
gc::AllocKind::FUNCTION_EXTENDED);
if (!clone) {
return nullptr;
}
// Save the original function name that we are cloning from. This allows
// the function to potentially be relazified in the future.
SetClonedSelfHostedFunctionName(
&clone->as<JSFunction>(),
selfHostedFunction->explicitName()->asPropertyName());
// If |_SetCanonicalName| was called on the function, the function name to
// use is stored in the extended slot.
if (JSAtom* name =
GetUnclonedSelfHostedCanonicalName(selfHostedFunction)) {
clone->as<JSFunction>().setAtom(name);
}
} else {
clone = CloneSelfHostingIntrinsic(cx, selfHostedFunction);
}
} else if (selfHostedObject->is<RegExpObject>()) {
RegExpObject& reobj = selfHostedObject->as<RegExpObject>();
RootedAtom source(cx, reobj.getSource());
MOZ_ASSERT(source->isPermanentAtom());
clone = RegExpObject::create(cx, source, reobj.getFlags(), TenuredObject);
} else if (selfHostedObject->is<DateObject>()) {
clone =
JS::NewDateObject(cx, selfHostedObject->as<DateObject>().clippedTime());
} else if (selfHostedObject->is<BooleanObject>()) {
clone = BooleanObject::create(
cx, selfHostedObject->as<BooleanObject>().unbox());
} else if (selfHostedObject->is<NumberObject>()) {
clone =
NumberObject::create(cx, selfHostedObject->as<NumberObject>().unbox());
} else if (selfHostedObject->is<StringObject>()) {
JSString* selfHostedString = selfHostedObject->as<StringObject>().unbox();
if (!selfHostedString->isLinear()) {
MOZ_CRASH();
}
RootedString str(cx, CloneString(cx, &selfHostedString->asLinear()));
if (!str) {
return nullptr;
}
clone = StringObject::create(cx, str);
} else if (selfHostedObject->is<ArrayObject>()) {
clone = NewTenuredDenseEmptyArray(cx, nullptr);
} else {
MOZ_ASSERT(selfHostedObject->is<NativeObject>());
clone = NewObjectWithGivenProto(
cx, selfHostedObject->getClass(), nullptr,
selfHostedObject->asTenured().getAllocKind(), TenuredObject);
}
if (!clone) {
return nullptr;
}
if (!CloneProperties(cx, selfHostedObject, clone)) {
return nullptr;
}
return clone;
}
static bool CloneValue(JSContext* cx, HandleValue selfHostedValue,
MutableHandleValue vp) {
if (selfHostedValue.isObject()) {
RootedNativeObject selfHostedObject(
cx, &selfHostedValue.toObject().as<NativeObject>());
JSObject* clone = CloneObject(cx, selfHostedObject);
if (!clone) {
return false;
}
vp.setObject(*clone);
} else if (selfHostedValue.isBoolean() || selfHostedValue.isNumber() ||
selfHostedValue.isNullOrUndefined()) {
// Nothing to do here: these are represented inline in the value.
vp.set(selfHostedValue);
} else if (selfHostedValue.isString()) {
if (!selfHostedValue.toString()->isLinear()) {
MOZ_CRASH();
}
JSLinearString* selfHostedString = &selfHostedValue.toString()->asLinear();
JSString* clone = CloneString(cx, selfHostedString);
if (!clone) {
return false;
}
vp.setString(clone);
} else if (selfHostedValue.isSymbol()) {
// Well-known symbols are shared.
mozilla::DebugOnly<JS::Symbol*> sym = selfHostedValue.toSymbol();
MOZ_ASSERT(sym->isWellKnownSymbol());
MOZ_ASSERT(cx->wellKnownSymbols().get(sym->code()) == sym);
vp.set(selfHostedValue);
} else {
MOZ_CRASH("Self-hosting CloneValue can't clone given value.");
}
return true;
}
bool JSRuntime::delazifySelfHostedFunction(JSContext* cx,
HandlePropertyName name,
HandleFunction targetFun) {
@ -3209,17 +2880,6 @@ bool JSRuntime::delazifySelfHostedFunction(JSContext* cx,
return true;
}
void JSRuntime::getUnclonedSelfHostedValue(PropertyName* name, Value* vp) {
PropertyKey id = NameToId(name);
GetUnclonedValue(selfHostingGlobal_, id, vp);
}
JSFunction* JSRuntime::getUnclonedSelfHostedFunction(PropertyName* name) {
Value selfHostedValue;
getUnclonedSelfHostedValue(name, &selfHostedValue);
return &selfHostedValue.toObject().as<JSFunction>();
}
mozilla::Maybe<frontend::ScriptIndexRange>
JSRuntime::getSelfHostedScriptIndexRange(js::PropertyName* name) {
if (parentRuntime) {