From 6e72707e0b72411df12827ae1ab882ab5177f983 Mon Sep 17 00:00:00 2001 From: Moonchild Date: Wed, 8 Jul 2020 14:12:57 +0000 Subject: Issue #618 - Use a single slot for the module's environment object. According to the spec this isn't created until the module is instantiated, but we create it when we compile the module. We stored this previously in InitialEnvironmentSlot and copied it to EnvironmentSlot when it was supposed to be created, but we can just store it in the latter slot straight away and check the module's status and return null if it shouldn't exist yet. This reduces the number of slots needed on a moduleObject to 17. Re: BZ 1420412 Part 1 We can't implement the second part to further reduce our number of slots, because it relies on SetProxyReservedSlot which in turn relies on rearchitecturing JS proxies to make reserved slots dynamic. That's a rabbit hole we really don't want to fall into. So, we'll end up being a bit slower because it can't be in-line allocated with having more than 16 slots, but so be it. I sincerely doubt it will make any practical difference. --- js/src/builtin/Module.js | 7 +++++-- js/src/builtin/ModuleObject.cpp | 41 +++++++++++++++++-------------------- js/src/builtin/ModuleObject.h | 4 ---- js/src/builtin/SelfHostingDefines.h | 10 ++++----- js/src/builtin/TestingFunctions.cpp | 2 -- js/src/vm/SelfHosting.cpp | 12 ----------- 6 files changed, 29 insertions(+), 47 deletions(-) diff --git a/js/src/builtin/Module.js b/js/src/builtin/Module.js index 86b44880dc..c9f20c18c8 100644 --- a/js/src/builtin/Module.js +++ b/js/src/builtin/Module.js @@ -234,8 +234,11 @@ function GetModuleEnvironment(module) { assert(IsModule(module), "Non-module passed to GetModuleEnvironment"); + assert(module.status >= MODULE_STATUS_INSTANTIATING, + "Attempt to access module environement before instantation"); + let env = UnsafeGetReservedSlot(module, MODULE_OBJECT_ENVIRONMENT_SLOT); - assert(env === undefined || IsModuleEnvironment(env), + assert(IsModuleEnvironment(env), "Module environment slot contains unexpected value"); return env; @@ -421,7 +424,7 @@ function ModuleDeclarationEnvironmentSetup(module) } // Steps 5-6 - CreateModuleEnvironment(module); + // Note that we have already created the environment by this point. let env = GetModuleEnvironment(module); // Step 8 diff --git a/js/src/builtin/ModuleObject.cpp b/js/src/builtin/ModuleObject.cpp index a9a2571784..14d27845c8 100644 --- a/js/src/builtin/ModuleObject.cpp +++ b/js/src/builtin/ModuleObject.cpp @@ -657,17 +657,24 @@ ModuleObject::finalize(js::FreeOp* fop, JSObject* obj) fop->delete_(funDecls); } +ModuleEnvironmentObject& +ModuleObject::initialEnvironment() const +{ + Value value = getReservedSlot(EnvironmentSlot); + return value.toObject().as(); +} + ModuleEnvironmentObject* ModuleObject::environment() const { -//- MOZ_ASSERT(status() != MODULE_STATUS_ERRORED); -//+ MOZ_ASSERT(!hadEvaluationError()); + MOZ_ASSERT(!hadEvaluationError()); - Value value = getReservedSlot(EnvironmentSlot); - if (value.isUndefined()) + // According to the spec the environment record is created during + // instantiation, but we create it earlier than that. + if (status() < MODULE_STATUS_INSTANTIATED) return nullptr; - return &value.toObject().as(); + return &initialEnvironment(); } bool @@ -732,7 +739,7 @@ ModuleObject::init(HandleScript script) void ModuleObject::setInitialEnvironment(HandleModuleEnvironmentObject initialEnvironment) { - initReservedSlot(InitialEnvironmentSlot, ObjectValue(*initialEnvironment)); + initReservedSlot(EnvironmentSlot, ObjectValue(*initialEnvironment)); } void @@ -867,12 +874,6 @@ ModuleObject::setHostDefinedField(const JS::Value& value) setReservedSlot(HostDefinedSlot, value); } -ModuleEnvironmentObject& -ModuleObject::initialEnvironment() const -{ - return getReservedSlot(InitialEnvironmentSlot).toObject().as(); -} - Scope* ModuleObject::enclosingScope() const { @@ -898,16 +899,6 @@ ModuleObject::trace(JSTracer* trc, JSObject* obj) funDecls->trace(trc); } -void -ModuleObject::createEnvironment() -{ - // The environment has already been created, we just neet to set it in the - // right slot. - MOZ_ASSERT(!getReservedSlot(InitialEnvironmentSlot).isUndefined()); - MOZ_ASSERT(getReservedSlot(EnvironmentSlot).isUndefined()); - setReservedSlot(EnvironmentSlot, getReservedSlot(InitialEnvironmentSlot)); -} - bool ModuleObject::noteFunctionDeclaration(ExclusiveContext* cx, HandleAtom name, HandleFunction fun) { @@ -923,7 +914,10 @@ ModuleObject::noteFunctionDeclaration(ExclusiveContext* cx, HandleAtom name, Han /* static */ bool ModuleObject::instantiateFunctionDeclarations(JSContext* cx, HandleModuleObject self) { +#ifdef DEBUG + MOZ_ASSERT(self->status() == MODULE_STATUS_INSTANTIATING); MOZ_ASSERT(IsFrozen(cx, self)); +#endif FunctionDeclarationVector* funDecls = self->functionDeclarations(); if (!funDecls) { @@ -954,7 +948,10 @@ ModuleObject::instantiateFunctionDeclarations(JSContext* cx, HandleModuleObject /* static */ bool ModuleObject::execute(JSContext* cx, HandleModuleObject self, MutableHandleValue rval) { +#ifdef DEBUG + MOZ_ASSERT(self->status() == MODULE_STATUS_EVALUATING); MOZ_ASSERT(IsFrozen(cx, self)); +#endif RootedScript script(cx, self->script()); RootedModuleEnvironmentObject scope(cx, self->environment()); diff --git a/js/src/builtin/ModuleObject.h b/js/src/builtin/ModuleObject.h index 5a809c8652..bd3e7044ec 100644 --- a/js/src/builtin/ModuleObject.h +++ b/js/src/builtin/ModuleObject.h @@ -214,7 +214,6 @@ class ModuleObject : public NativeObject enum { ScriptSlot = 0, - InitialEnvironmentSlot, EnvironmentSlot, NamespaceSlot, StatusSlot, @@ -286,9 +285,6 @@ class ModuleObject : public NativeObject void setHostDefinedField(const JS::Value& value); - // For intrinsic_CreateModuleEnvironment. - void createEnvironment(); - // For BytecodeEmitter. bool noteFunctionDeclaration(ExclusiveContext* cx, HandleAtom name, HandleFunction fun); diff --git a/js/src/builtin/SelfHostingDefines.h b/js/src/builtin/SelfHostingDefines.h index 6afa641b12..a3ba36804d 100644 --- a/js/src/builtin/SelfHostingDefines.h +++ b/js/src/builtin/SelfHostingDefines.h @@ -97,11 +97,11 @@ #define REGEXP_STRING_ITERATOR_FLAGS_SLOT 2 #define REGEXP_STRING_ITERATOR_DONE_SLOT 3 -#define MODULE_OBJECT_ENVIRONMENT_SLOT 2 -#define MODULE_OBJECT_STATUS_SLOT 4 -#define MODULE_OBJECT_EVALUATION_ERROR_SLOT 5 // 4 -#define MODULE_OBJECT_DFS_INDEX_SLOT 16 -#define MODULE_OBJECT_DFS_ANCESTOR_INDEX_SLOT 17 +#define MODULE_OBJECT_ENVIRONMENT_SLOT 1 +#define MODULE_OBJECT_STATUS_SLOT 3 +#define MODULE_OBJECT_EVALUATION_ERROR_SLOT 4 +#define MODULE_OBJECT_DFS_INDEX_SLOT 15 +#define MODULE_OBJECT_DFS_ANCESTOR_INDEX_SLOT 16 #define MODULE_STATUS_UNINSTANTIATED 0 #define MODULE_STATUS_INSTANTIATING 1 diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index e93ebeec3d..f589b8076b 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -3566,8 +3566,6 @@ GetModuleEnvironment(JSContext* cx, HandleValue moduleValue) // before they have been instantiated. RootedModuleEnvironmentObject env(cx, &module->initialEnvironment()); MOZ_ASSERT(env); - MOZ_ASSERT_IF(module->environment(), module->environment() == env); - return env; } diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index f98e968b85..50b0c01def 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -2048,17 +2048,6 @@ intrinsic_HostResolveImportedModule(JSContext* cx, unsigned argc, Value* vp) return true; } -static bool -intrinsic_CreateModuleEnvironment(JSContext* cx, unsigned argc, Value* vp) -{ - CallArgs args = CallArgsFromVp(argc, vp); - MOZ_ASSERT(args.length() == 1); - RootedModuleObject module(cx, &args[0].toObject().as()); - module->createEnvironment(); - args.rval().setUndefined(); - return true; -} - static bool intrinsic_CreateImportBinding(JSContext* cx, unsigned argc, Value* vp) { @@ -2658,7 +2647,6 @@ static const JSFunctionSpec intrinsic_functions[] = { CallNonGenericSelfhostedMethod>, 2, 0), JS_FN("HostResolveImportedModule", intrinsic_HostResolveImportedModule, 2, 0), JS_FN("IsModuleEnvironment", intrinsic_IsInstanceOfBuiltin, 1, 0), - JS_FN("CreateModuleEnvironment", intrinsic_CreateModuleEnvironment, 1, 0), JS_FN("CreateImportBinding", intrinsic_CreateImportBinding, 4, 0), JS_FN("CreateNamespaceBinding", intrinsic_CreateNamespaceBinding, 3, 0), JS_FN("InstantiateModuleFunctionDeclarations", -- cgit v1.2.3