[JSC] Make more fields lazy in JSGlobalObject
authorysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 8 Mar 2019 06:17:32 +0000 (06:17 +0000)
committerysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 8 Mar 2019 06:17:32 +0000 (06:17 +0000)
https://bugs.webkit.org/show_bug.cgi?id=195449

Reviewed by Mark Lam.

Source/JavaScriptCore:

This patch makes more fields lazy-allocated in JSGlobalObject to save memory.

1. Some minor structures like moduleRecordStructure.
2. Some functions like parseInt / parseFloat. While they are eagerly created in JIT mode anyway to materialize NumberConstructor, we can lazily allocate them in non JIT mode.
3. ArrayBuffer constructor. While it is eagerly allocated in WebCore, we can make lazily allocated in JSC.

* interpreter/Interpreter.cpp:
(JSC::Interpreter::execute):
* runtime/JSArrayBufferPrototype.h:
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::parseIntFunction const):
(JSC::JSGlobalObject::parseFloatFunction const):
(JSC::JSGlobalObject::evalFunction const):
(JSC::JSGlobalObject::strictEvalActivationStructure const):
(JSC::JSGlobalObject::moduleRecordStructure const):
(JSC::JSGlobalObject::moduleNamespaceObjectStructure const):
(JSC::JSGlobalObject::proxyObjectStructure const):
(JSC::JSGlobalObject::callableProxyObjectStructure const):
(JSC::JSGlobalObject::proxyRevokeStructure const):
(JSC::JSGlobalObject::arrayBufferConstructor const):
(JSC::JSGlobalObject::arrayBufferPrototype const):
(JSC::JSGlobalObject::arrayBufferStructure const):
* runtime/ProxyObject.h:
* runtime/StrictEvalActivation.cpp:
(JSC::StrictEvalActivation::StrictEvalActivation):
* runtime/StrictEvalActivation.h:
* wasm/js/JSWebAssemblyMemory.cpp:
(JSC::JSWebAssemblyMemory::buffer):
* wasm/js/WebAssemblyModuleConstructor.cpp:
(JSC::webAssemblyModuleCustomSections):

Source/WebCore:

Use arrayBufferConstructor() since getDirect does not work with lazy property.

* bindings/js/JSDOMGlobalObject.cpp:
(WebCore::JSDOMGlobalObject::addBuiltinGlobals):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242636 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/interpreter/Interpreter.cpp
Source/JavaScriptCore/runtime/JSArrayBufferPrototype.h
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/JSGlobalObject.h
Source/JavaScriptCore/runtime/ProxyObject.h
Source/JavaScriptCore/runtime/StrictEvalActivation.cpp
Source/JavaScriptCore/runtime/StrictEvalActivation.h
Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyModuleConstructor.cpp
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/JSDOMGlobalObject.cpp

index 194ed19..b912bdf 100644 (file)
@@ -1,5 +1,46 @@
 2019-03-07  Yusuke Suzuki  <ysuzuki@apple.com>
 
+        [JSC] Make more fields lazy in JSGlobalObject
+        https://bugs.webkit.org/show_bug.cgi?id=195449
+
+        Reviewed by Mark Lam.
+
+        This patch makes more fields lazy-allocated in JSGlobalObject to save memory.
+
+        1. Some minor structures like moduleRecordStructure.
+        2. Some functions like parseInt / parseFloat. While they are eagerly created in JIT mode anyway to materialize NumberConstructor, we can lazily allocate them in non JIT mode.
+        3. ArrayBuffer constructor. While it is eagerly allocated in WebCore, we can make lazily allocated in JSC.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::execute):
+        * runtime/JSArrayBufferPrototype.h:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::parseIntFunction const):
+        (JSC::JSGlobalObject::parseFloatFunction const):
+        (JSC::JSGlobalObject::evalFunction const):
+        (JSC::JSGlobalObject::strictEvalActivationStructure const):
+        (JSC::JSGlobalObject::moduleRecordStructure const):
+        (JSC::JSGlobalObject::moduleNamespaceObjectStructure const):
+        (JSC::JSGlobalObject::proxyObjectStructure const):
+        (JSC::JSGlobalObject::callableProxyObjectStructure const):
+        (JSC::JSGlobalObject::proxyRevokeStructure const):
+        (JSC::JSGlobalObject::arrayBufferConstructor const):
+        (JSC::JSGlobalObject::arrayBufferPrototype const):
+        (JSC::JSGlobalObject::arrayBufferStructure const):
+        * runtime/ProxyObject.h:
+        * runtime/StrictEvalActivation.cpp:
+        (JSC::StrictEvalActivation::StrictEvalActivation):
+        * runtime/StrictEvalActivation.h:
+        * wasm/js/JSWebAssemblyMemory.cpp:
+        (JSC::JSWebAssemblyMemory::buffer):
+        * wasm/js/WebAssemblyModuleConstructor.cpp:
+        (JSC::webAssemblyModuleCustomSections):
+
+2019-03-07  Yusuke Suzuki  <ysuzuki@apple.com>
+
         [JSC] Remove merging must handle values into proven types in CFA
         https://bugs.webkit.org/show_bug.cgi?id=195444
 
index fa93028..7f15d19 100644 (file)
@@ -1021,7 +1021,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
 
     JSScope* variableObject;
     if ((numVariables || numTopLevelFunctionDecls) && eval->isStrictMode()) {
-        scope = StrictEvalActivation::create(callFrame, scope);
+        scope = StrictEvalActivation::create(vm, callFrame->lexicalGlobalObject()->strictEvalActivationStructure(), scope);
         variableObject = scope;
     } else {
         for (JSScope* node = scope; ; node = node->next()) {
index 4550bf8..c621781 100644 (file)
@@ -38,7 +38,7 @@ protected:
     void finishCreation(VM&, JSGlobalObject*);
 
 public:
-    static JSArrayBufferPrototype* create(VM&, JSGlobalObject*, Structure*, ArrayBufferSharingMode);
+    static JSArrayBufferPrototype* create(VM&, JSGlobalObject*, Structure*, ArrayBufferSharingMode = ArrayBufferSharingMode::Default);
     
     DECLARE_INFO;
     
index eeac385..8190c17 100644 (file)
@@ -319,7 +319,11 @@ const GlobalObjectMethodTable JSGlobalObject::s_globalObjectMethodTable = {
   decodeURIComponent    globalFuncDecodeURIComponent                 DontEnum|Function 1
   encodeURI             globalFuncEncodeURI                          DontEnum|Function 1
   encodeURIComponent    globalFuncEncodeURIComponent                 DontEnum|Function 1
+  eval                  JSGlobalObject::m_evalFunction               DontEnum|CellProperty
   globalThis            JSGlobalObject::m_globalThis                 DontEnum|CellProperty
+  parseInt              JSGlobalObject::m_parseIntFunction           DontEnum|CellProperty
+  parseFloat            JSGlobalObject::m_parseFloatFunction         DontEnum|CellProperty
+  ArrayBuffer           JSGlobalObject::m_arrayBufferStructure       DontEnum|ClassStructure
   EvalError             JSGlobalObject::m_evalErrorStructure         DontEnum|ClassStructure
   RangeError            JSGlobalObject::m_rangeErrorStructure        DontEnum|ClassStructure
   ReferenceError        JSGlobalObject::m_referenceErrorStructure    DontEnum|ClassStructure
@@ -570,7 +574,10 @@ void JSGlobalObject::init(VM& vm)
         [] (const Initializer<Structure>& init) {
             init.set(JSModuleEnvironment::createStructure(init.vm, init.owner));
         });
-    m_strictEvalActivationStructure.set(vm, this, StrictEvalActivation::createStructure(vm, this, jsNull()));
+    m_strictEvalActivationStructure.initLater(
+        [] (const Initializer<Structure>& init) {
+            init.set(StrictEvalActivation::createStructure(init.vm, init.owner, jsNull()));
+        });
     m_debuggerScopeStructure.initLater(
         [] (const Initializer<Structure>& init) {
             init.set(DebuggerScope::createStructure(init.vm, init.owner));
@@ -637,23 +644,38 @@ void JSGlobalObject::init(VM& vm)
     m_regExpMatchesArrayStructure.set(vm, this, createRegExpMatchesArrayStructure(vm, this));
     m_regExpMatchesArrayWithGroupsStructure.set(vm, this, createRegExpMatchesArrayWithGroupsStructure(vm, this));
 
-    m_moduleRecordStructure.set(vm, this, JSModuleRecord::createStructure(vm, this, jsNull()));
-    m_moduleNamespaceObjectStructure.set(vm, this, JSModuleNamespaceObject::createStructure(vm, this, jsNull()));
-    {
-        bool isCallable = false;
-        m_proxyObjectStructure.set(vm, this, ProxyObject::createStructure(vm, this, jsNull(), isCallable));
-        isCallable = true;
-        m_callableProxyObjectStructure.set(vm, this, ProxyObject::createStructure(vm, this, jsNull(), isCallable));
-    }
-    m_proxyRevokeStructure.set(vm, this, ProxyRevoke::createStructure(vm, this, m_functionPrototype.get()));
+    m_moduleRecordStructure.initLater(
+        [] (const Initializer<Structure>& init) {
+            init.set(JSModuleRecord::createStructure(init.vm, init.owner, jsNull()));
+        });
+    m_moduleNamespaceObjectStructure.initLater(
+        [] (const Initializer<Structure>& init) {
+            init.set(JSModuleNamespaceObject::createStructure(init.vm, init.owner, jsNull()));
+        });
+    m_proxyObjectStructure.initLater(
+        [] (const Initializer<Structure>& init) {
+            bool isCallable = false;
+            init.set(ProxyObject::createStructure(init.vm, init.owner, jsNull(), isCallable));
+        });
+    m_callableProxyObjectStructure.initLater(
+        [] (const Initializer<Structure>& init) {
+            bool isCallable = true;
+            init.set(ProxyObject::createStructure(init.vm, init.owner, jsNull(), isCallable));
+        });
+    m_proxyRevokeStructure.initLater(
+        [] (const Initializer<Structure>& init) {
+            init.set(ProxyRevoke::createStructure(init.vm, init.owner, init.owner->m_functionPrototype.get()));
+        });
 
-    m_parseIntFunction.set(vm, this, JSFunction::create(vm, this, 2, vm.propertyNames->parseInt.string(), globalFuncParseInt, ParseIntIntrinsic));
-    putDirectWithoutTransition(vm, vm.propertyNames->parseInt, m_parseIntFunction.get(), static_cast<unsigned>(PropertyAttribute::DontEnum));
-    m_parseFloatFunction.set(vm, this, JSFunction::create(vm, this, 1, vm.propertyNames->parseFloat.string(), globalFuncParseFloat, NoIntrinsic));
-    putDirectWithoutTransition(vm, vm.propertyNames->parseFloat, m_parseFloatFunction.get(), static_cast<unsigned>(PropertyAttribute::DontEnum));
+    m_parseIntFunction.initLater(
+        [] (const Initializer<JSFunction>& init) {
+            init.set(JSFunction::create(init.vm, init.owner, 2, init.vm.propertyNames->parseInt.string(), globalFuncParseInt, ParseIntIntrinsic));
+        });
+    m_parseFloatFunction.initLater(
+        [] (const Initializer<JSFunction>& init) {
+            init.set(JSFunction::create(init.vm, init.owner, 1, init.vm.propertyNames->parseFloat.string(), globalFuncParseFloat, NoIntrinsic));
+        });
     
-    m_arrayBufferPrototype.set(vm, this, JSArrayBufferPrototype::create(vm, this, JSArrayBufferPrototype::createStructure(vm, this, m_objectPrototype.get()), ArrayBufferSharingMode::Default));
-    m_arrayBufferStructure.set(vm, this, JSArrayBuffer::createStructure(vm, this, m_arrayBufferPrototype.get()));
 #if ENABLE(SHARED_ARRAY_BUFFER)
     m_sharedArrayBufferPrototype.set(vm, this, JSArrayBufferPrototype::create(vm, this, JSArrayBufferPrototype::createStructure(vm, this, m_objectPrototype.get()), ArrayBufferSharingMode::Shared));
     m_sharedArrayBufferStructure.set(vm, this, JSArrayBuffer::createStructure(vm, this, m_sharedArrayBufferPrototype.get()));
@@ -707,9 +729,6 @@ void JSGlobalObject::init(VM& vm)
     RegExpConstructor* regExpConstructor = RegExpConstructor::create(vm, RegExpConstructor::createStructure(vm, this, m_functionPrototype.get()), m_regExpPrototype.get(), m_speciesGetterSetter.get());
     m_regExpGlobalData.cachedResult().record(vm, this, nullptr, jsEmptyString(&vm), MatchResult(0, 0));
     
-    JSArrayBufferConstructor* arrayBufferConstructor = JSArrayBufferConstructor::create(vm, JSArrayBufferConstructor::createStructure(vm, this, m_functionPrototype.get()), m_arrayBufferPrototype.get(), m_speciesGetterSetter.get());
-    m_arrayBufferPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, arrayBufferConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
-
 #if ENABLE(SHARED_ARRAY_BUFFER)
     JSSharedArrayBufferConstructor* sharedArrayBufferConstructor = nullptr;
     sharedArrayBufferConstructor = JSSharedArrayBufferConstructor::create(vm, JSSharedArrayBufferConstructor::createStructure(vm, this, m_functionPrototype.get()), m_sharedArrayBufferPrototype.get(), m_speciesGetterSetter.get());
@@ -793,7 +812,6 @@ m_ ## lowerName ## Prototype->putDirectWithoutTransition(vm, vm.propertyNames->c
     putDirectWithoutTransition(vm, vm.propertyNames->builtinNames().ObjectPrivateName(), objectConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
     putDirectWithoutTransition(vm, vm.propertyNames->builtinNames().ArrayPrivateName(), arrayConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
 
-    putDirectWithoutTransition(vm, vm.propertyNames->ArrayBuffer, arrayBufferConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
 #if ENABLE(SHARED_ARRAY_BUFFER)
     putDirectWithoutTransition(vm, vm.propertyNames->SharedArrayBuffer, sharedArrayBufferConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
     putDirectWithoutTransition(vm, Identifier::fromString(exec, "Atomics"), atomicsObject, static_cast<unsigned>(PropertyAttribute::DontEnum));
@@ -809,8 +827,10 @@ putDirectWithoutTransition(vm, vm.propertyNames-> jsName, lowerName ## Construct
 #undef PUT_CONSTRUCTOR_FOR_SIMPLE_TYPE
     m_iteratorResultObjectStructure.set(vm, this, createIteratorResultObjectStructure(vm, *this));
     
-    m_evalFunction.set(vm, this, JSFunction::create(vm, this, 1, vm.propertyNames->eval.string(), globalFuncEval));
-    putDirectWithoutTransition(vm, vm.propertyNames->eval, m_evalFunction.get(), static_cast<unsigned>(PropertyAttribute::DontEnum));
+    m_evalFunction.initLater(
+        [] (const Initializer<JSFunction>& init) {
+            init.set(JSFunction::create(init.vm, init.owner, 1, init.vm.propertyNames->eval.string(), globalFuncEval, NoIntrinsic));
+        });
     
 #if ENABLE(INTL)
     m_collatorStructure.initLater(
@@ -1610,14 +1630,14 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
     visitor.append(thisObject->m_nullGetterFunction);
     visitor.append(thisObject->m_nullSetterFunction);
 
-    visitor.append(thisObject->m_parseIntFunction);
-    visitor.append(thisObject->m_parseFloatFunction);
-    visitor.append(thisObject->m_evalFunction);
+    thisObject->m_parseIntFunction.visit(visitor);
+    thisObject->m_parseFloatFunction.visit(visitor);
     visitor.append(thisObject->m_callFunction);
     visitor.append(thisObject->m_applyFunction);
     visitor.append(thisObject->m_throwTypeErrorFunction);
     thisObject->m_arrayProtoToStringFunction.visit(visitor);
     thisObject->m_arrayProtoValuesFunction.visit(visitor);
+    thisObject->m_evalFunction.visit(visitor);
     thisObject->m_initializePromiseFunction.visit(visitor);
     thisObject->m_iteratorProtocolFunction.visit(visitor);
     thisObject->m_promiseResolveFunction.visit(visitor);
@@ -1642,7 +1662,7 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
 
     thisObject->m_debuggerScopeStructure.visit(visitor);
     thisObject->m_withScopeStructure.visit(visitor);
-    visitor.append(thisObject->m_strictEvalActivationStructure);
+    thisObject->m_strictEvalActivationStructure.visit(visitor);
     visitor.append(thisObject->m_lexicalEnvironmentStructure);
     thisObject->m_moduleEnvironmentStructure.visit(visitor);
     visitor.append(thisObject->m_directArgumentsStructure);
@@ -1688,14 +1708,12 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
     visitor.append(thisObject->m_iteratorResultObjectStructure);
     visitor.append(thisObject->m_regExpMatchesArrayStructure);
     visitor.append(thisObject->m_regExpMatchesArrayWithGroupsStructure);
-    visitor.append(thisObject->m_moduleRecordStructure);
-    visitor.append(thisObject->m_moduleNamespaceObjectStructure);
-    visitor.append(thisObject->m_proxyObjectStructure);
-    visitor.append(thisObject->m_callableProxyObjectStructure);
-    visitor.append(thisObject->m_proxyRevokeStructure);
+    thisObject->m_moduleRecordStructure.visit(visitor);
+    thisObject->m_moduleNamespaceObjectStructure.visit(visitor);
+    thisObject->m_proxyObjectStructure.visit(visitor);
+    thisObject->m_callableProxyObjectStructure.visit(visitor);
+    thisObject->m_proxyRevokeStructure.visit(visitor);
     
-    visitor.append(thisObject->m_arrayBufferPrototype);
-    visitor.append(thisObject->m_arrayBufferStructure);
 #if ENABLE(SHARED_ARRAY_BUFFER)
     visitor.append(thisObject->m_sharedArrayBufferPrototype);
     visitor.append(thisObject->m_sharedArrayBufferStructure);
index d0a65d5..a8548e5 100644 (file)
@@ -142,7 +142,7 @@ template<typename Watchpoint> class ObjectPropertyChangeAdaptiveWatchpoint;
     FOR_EACH_SIMPLE_BUILTIN_TYPE_WITH_CONSTRUCTOR(macro) \
     macro(JSInternalPromise, internalPromise, internalPromise, JSInternalPromise, InternalPromise, object) \
 
-#define FOR_EACH_LAZY_BUILTIN_TYPE(macro) \
+#define FOR_EACH_LAZY_BUILTIN_TYPE_WITH_DECLARATION(macro) \
     macro(Boolean, boolean, booleanObject, BooleanObject, Boolean, object) \
     macro(Date, date, date, DateInstance, Date, object) \
     macro(Error, error, error, ErrorInstance, Error, object) \
@@ -151,6 +151,10 @@ template<typename Watchpoint> class ObjectPropertyChangeAdaptiveWatchpoint;
     DEFINE_STANDARD_BUILTIN(macro, WeakMap, weakMap) \
     DEFINE_STANDARD_BUILTIN(macro, WeakSet, weakSet) \
 
+#define FOR_EACH_LAZY_BUILTIN_TYPE(macro) \
+    FOR_EACH_LAZY_BUILTIN_TYPE_WITH_DECLARATION(macro) \
+    macro(JSArrayBuffer, arrayBuffer, arrayBuffer, JSArrayBuffer, ArrayBuffer, object) \
+
 #if ENABLE(WEBASSEMBLY)
 #define FOR_EACH_WEBASSEMBLY_CONSTRUCTOR_TYPE(macro) \
     macro(WebAssemblyCompileError, webAssemblyCompileError, WebAssemblyCompileError, WebAssemblyCompileError, CompileError, error) \
@@ -172,7 +176,7 @@ template<typename Watchpoint> class ObjectPropertyChangeAdaptiveWatchpoint;
 class IteratorPrototype;
 FOR_EACH_SIMPLE_BUILTIN_TYPE(DECLARE_SIMPLE_BUILTIN_TYPE)
 FOR_BIG_INT_BUILTIN_TYPE_WITH_CONSTRUCTOR(DECLARE_SIMPLE_BUILTIN_TYPE)
-FOR_EACH_LAZY_BUILTIN_TYPE(DECLARE_SIMPLE_BUILTIN_TYPE)
+FOR_EACH_LAZY_BUILTIN_TYPE_WITH_DECLARATION(DECLARE_SIMPLE_BUILTIN_TYPE)
 FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(DECLARE_SIMPLE_BUILTIN_TYPE)
 FOR_EACH_WEBASSEMBLY_CONSTRUCTOR_TYPE(DECLARE_SIMPLE_BUILTIN_TYPE)
 
@@ -260,7 +264,6 @@ public:
     WriteBarrier<JSCallee> m_globalCallee;
     WriteBarrier<JSCallee> m_stackOverflowFrameCallee;
 
-    WriteBarrier<ErrorConstructor> m_errorConstructor;
     LazyClassStructure m_evalErrorStructure;
     LazyClassStructure m_rangeErrorStructure;
     LazyClassStructure m_referenceErrorStructure;
@@ -283,15 +286,15 @@ public:
     WriteBarrier<NullGetterFunction> m_nullGetterFunction;
     WriteBarrier<NullSetterFunction> m_nullSetterFunction;
 
-    WriteBarrier<JSFunction> m_parseIntFunction;
-    WriteBarrier<JSFunction> m_parseFloatFunction;
+    LazyProperty<JSGlobalObject, JSFunction> m_parseIntFunction;
+    LazyProperty<JSGlobalObject, JSFunction> m_parseFloatFunction;
 
-    WriteBarrier<JSFunction> m_evalFunction;
     WriteBarrier<JSFunction> m_callFunction;
     WriteBarrier<JSFunction> m_applyFunction;
     WriteBarrier<JSFunction> m_throwTypeErrorFunction;
     LazyProperty<JSGlobalObject, JSFunction> m_arrayProtoToStringFunction;
     LazyProperty<JSGlobalObject, JSFunction> m_arrayProtoValuesFunction;
+    LazyProperty<JSGlobalObject, JSFunction> m_evalFunction;
     LazyProperty<JSGlobalObject, JSFunction> m_initializePromiseFunction;
     LazyProperty<JSGlobalObject, JSFunction> m_iteratorProtocolFunction;
     LazyProperty<JSGlobalObject, JSFunction> m_promiseResolveFunction;
@@ -320,7 +323,7 @@ public:
 
     LazyProperty<JSGlobalObject, Structure> m_debuggerScopeStructure;
     LazyProperty<JSGlobalObject, Structure> m_withScopeStructure;
-    WriteBarrier<Structure> m_strictEvalActivationStructure;
+    LazyProperty<JSGlobalObject, Structure> m_strictEvalActivationStructure;
     WriteBarrier<Structure> m_lexicalEnvironmentStructure;
     LazyProperty<JSGlobalObject, Structure> m_moduleEnvironmentStructure;
     WriteBarrier<Structure> m_directArgumentsStructure;
@@ -373,13 +376,11 @@ public:
     WriteBarrier<Structure> m_iteratorResultObjectStructure;
     WriteBarrier<Structure> m_regExpMatchesArrayStructure;
     WriteBarrier<Structure> m_regExpMatchesArrayWithGroupsStructure;
-    WriteBarrier<Structure> m_moduleRecordStructure;
-    WriteBarrier<Structure> m_moduleNamespaceObjectStructure;
-    WriteBarrier<Structure> m_proxyObjectStructure;
-    WriteBarrier<Structure> m_callableProxyObjectStructure;
-    WriteBarrier<Structure> m_proxyRevokeStructure;
-    WriteBarrier<JSArrayBufferPrototype> m_arrayBufferPrototype;
-    WriteBarrier<Structure> m_arrayBufferStructure;
+    LazyProperty<JSGlobalObject, Structure> m_moduleRecordStructure;
+    LazyProperty<JSGlobalObject, Structure> m_moduleNamespaceObjectStructure;
+    LazyProperty<JSGlobalObject, Structure> m_proxyObjectStructure;
+    LazyProperty<JSGlobalObject, Structure> m_callableProxyObjectStructure;
+    LazyProperty<JSGlobalObject, Structure> m_proxyRevokeStructure;
 #if ENABLE(SHARED_ARRAY_BUFFER)
     WriteBarrier<JSArrayBufferPrototype> m_sharedArrayBufferPrototype;
     WriteBarrier<Structure> m_sharedArrayBufferStructure;
@@ -593,10 +594,10 @@ public:
     NullGetterFunction* nullGetterFunction() const { return m_nullGetterFunction.get(); }
     NullSetterFunction* nullSetterFunction() const { return m_nullSetterFunction.get(); }
 
-    JSFunction* parseIntFunction() const { return m_parseIntFunction.get(); }
-    JSFunction* parseFloatFunction() const { return m_parseFloatFunction.get(); }
+    JSFunction* parseIntFunction() const { return m_parseIntFunction.get(this); }
+    JSFunction* parseFloatFunction() const { return m_parseFloatFunction.get(this); }
 
-    JSFunction* evalFunction() const { return m_evalFunction.get(); }
+    JSFunction* evalFunction() const { return m_evalFunction.get(this); }
     JSFunction* callFunction() const { return m_callFunction.get(); }
     JSFunction* applyFunction() const { return m_applyFunction.get(); }
     JSFunction* throwTypeErrorFunction() const { return m_throwTypeErrorFunction.get(); }
@@ -645,7 +646,7 @@ public:
 
     Structure* debuggerScopeStructure() const { return m_debuggerScopeStructure.get(this); }
     Structure* withScopeStructure() const { return m_withScopeStructure.get(this); }
-    Structure* strictEvalActivationStructure() const { return m_strictEvalActivationStructure.get(); }
+    Structure* strictEvalActivationStructure() const { return m_strictEvalActivationStructure.get(this); }
     Structure* activationStructure() const { return m_lexicalEnvironmentStructure.get(); }
     Structure* moduleEnvironmentStructure() const { return m_moduleEnvironmentStructure.get(this); }
     Structure* directArgumentsStructure() const { return m_directArgumentsStructure.get(); }
@@ -751,11 +752,11 @@ public:
     Structure* iteratorResultObjectStructure() const { return m_iteratorResultObjectStructure.get(); }
     Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); }
     Structure* regExpMatchesArrayWithGroupsStructure() const { return m_regExpMatchesArrayWithGroupsStructure.get(); }
-    Structure* moduleRecordStructure() const { return m_moduleRecordStructure.get(); }
-    Structure* moduleNamespaceObjectStructure() const { return m_moduleNamespaceObjectStructure.get(); }
-    Structure* proxyObjectStructure() const { return m_proxyObjectStructure.get(); }
-    Structure* callableProxyObjectStructure() const { return m_callableProxyObjectStructure.get(); }
-    Structure* proxyRevokeStructure() const { return m_proxyRevokeStructure.get(); }
+    Structure* moduleRecordStructure() const { return m_moduleRecordStructure.get(this); }
+    Structure* moduleNamespaceObjectStructure() const { return m_moduleNamespaceObjectStructure.get(this); }
+    Structure* proxyObjectStructure() const { return m_proxyObjectStructure.get(this); }
+    Structure* callableProxyObjectStructure() const { return m_callableProxyObjectStructure.get(this); }
+    Structure* proxyRevokeStructure() const { return m_proxyRevokeStructure.get(this); }
     Structure* restParameterStructure() const { return arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous); }
     Structure* originalRestParameterStructure() const { return originalArrayStructureForIndexingType(ArrayWithContiguous); }
 #if ENABLE(WEBASSEMBLY)
@@ -800,17 +801,19 @@ public:
     void setName(const String&);
     const String& name() const { return m_name; }
 
-    JSArrayBufferPrototype* arrayBufferPrototype(ArrayBufferSharingMode sharingMode) const
+    JSObject* arrayBufferConstructor() const { return m_arrayBufferStructure.constructor(this); }
+
+    JSObject* arrayBufferPrototype(ArrayBufferSharingMode sharingMode) const
     {
         switch (sharingMode) {
         case ArrayBufferSharingMode::Default:
-            return m_arrayBufferPrototype.get();
+            return m_arrayBufferStructure.prototype(this);
 #if ENABLE(SHARED_ARRAY_BUFFER)
         case ArrayBufferSharingMode::Shared:
             return m_sharedArrayBufferPrototype.get();
 #else
         default:
-            return m_arrayBufferPrototype.get();
+            return m_arrayBufferStructure.prototype(this);
 #endif
         }
     }
@@ -818,13 +821,13 @@ public:
     {
         switch (sharingMode) {
         case ArrayBufferSharingMode::Default:
-            return m_arrayBufferStructure.get();
+            return m_arrayBufferStructure.get(this);
 #if ENABLE(SHARED_ARRAY_BUFFER)
         case ArrayBufferSharingMode::Shared:
             return m_sharedArrayBufferStructure.get();
 #else
         default:
-            return m_arrayBufferStructure.get();
+            return m_arrayBufferStructure.get(this);
 #endif
         }
         RELEASE_ASSERT_NOT_REACHED();
index d204a9d..df7a1ee 100644 (file)
@@ -39,7 +39,8 @@ public:
     static ProxyObject* create(ExecState* exec, JSGlobalObject* globalObject, JSValue target, JSValue handler)
     {
         VM& vm = exec->vm();
-        ProxyObject* proxy = new (NotNull, allocateCell<ProxyObject>(vm.heap)) ProxyObject(vm, ProxyObject::structureForTarget(globalObject, target));
+        Structure* structure = ProxyObject::structureForTarget(globalObject, target);
+        ProxyObject* proxy = new (NotNull, allocateCell<ProxyObject>(vm.heap)) ProxyObject(vm, structure);
         proxy->finishCreation(vm, exec, target, handler);
         return proxy;
     }
index 3d63352..6e419fa 100644 (file)
@@ -35,12 +35,8 @@ STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(StrictEvalActivation);
 
 const ClassInfo StrictEvalActivation::s_info = { "Object", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(StrictEvalActivation) };
 
-StrictEvalActivation::StrictEvalActivation(ExecState* exec, JSScope* currentScope)
-    : Base(
-        exec->vm(),
-        exec->lexicalGlobalObject()->strictEvalActivationStructure(),
-        currentScope
-    )
+StrictEvalActivation::StrictEvalActivation(VM& vm, Structure* structure, JSScope* currentScope)
+    : Base(vm, structure, currentScope)
 {
 }
 
index 2be09f5..f1bc1d6 100644 (file)
@@ -33,12 +33,11 @@ class StrictEvalActivation final : public JSScope {
 public:
     using Base = JSScope;
 
-    static StrictEvalActivation* create(ExecState* exec, JSScope* currentScope)
+    static StrictEvalActivation* create(VM& vm, Structure* structure, JSScope* currentScope)
     {
-        VM& vm = exec->vm();
-        StrictEvalActivation* lexicalEnvironment = new (NotNull, allocateCell<StrictEvalActivation>(vm.heap)) StrictEvalActivation(exec, currentScope);
-        lexicalEnvironment->finishCreation(vm);
-        return lexicalEnvironment;
+        StrictEvalActivation* scope = new (NotNull, allocateCell<StrictEvalActivation>(vm.heap)) StrictEvalActivation(vm, structure, currentScope);
+        scope->finishCreation(vm);
+        return scope;
     }
 
     static bool deleteProperty(JSCell*, ExecState*, PropertyName);
@@ -51,7 +50,7 @@ public:
     DECLARE_INFO;
 
 private:
-    StrictEvalActivation(ExecState*, JSScope*);
+    StrictEvalActivation(VM&, Structure*, JSScope*);
 };
 
 } // namespace JSC
index 7a6a5f0..34b990d 100644 (file)
@@ -83,7 +83,7 @@ JSArrayBuffer* JSWebAssemblyMemory::buffer(VM& vm, JSGlobalObject* globalObject)
     auto destructor = [protectedMemory = WTFMove(protectedMemory)] (void*) { };
     m_buffer = ArrayBuffer::createFromBytes(memory().memory(), memory().size(), WTFMove(destructor));
     m_buffer->makeWasmMemory();
-    m_bufferWrapper.set(vm, this, JSArrayBuffer::create(vm, globalObject->m_arrayBufferStructure.get(), m_buffer.get()));
+    m_bufferWrapper.set(vm, this, JSArrayBuffer::create(vm, globalObject->arrayBufferStructure(ArrayBufferSharingMode::Default), m_buffer.get()));
     RELEASE_ASSERT(m_bufferWrapper);
     return m_bufferWrapper.get();
 }
index db049c1..e481c2d 100644 (file)
@@ -88,7 +88,7 @@ EncodedJSValue JSC_HOST_CALL webAssemblyModuleCustomSections(ExecState* exec)
             if (!buffer)
                 return JSValue::encode(throwException(exec, throwScope, createOutOfMemoryError(exec)));
 
-            result->push(exec, JSArrayBuffer::create(vm, globalObject->m_arrayBufferStructure.get(), WTFMove(buffer)));
+            result->push(exec, JSArrayBuffer::create(vm, globalObject->arrayBufferStructure(ArrayBufferSharingMode::Default), WTFMove(buffer)));
             RETURN_IF_EXCEPTION(throwScope, { });
         }
     }
index d1df0f8..97f9740 100644 (file)
@@ -1,3 +1,15 @@
+2019-03-07  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        [JSC] Make more fields lazy in JSGlobalObject
+        https://bugs.webkit.org/show_bug.cgi?id=195449
+
+        Reviewed by Mark Lam.
+
+        Use arrayBufferConstructor() since getDirect does not work with lazy property.
+
+        * bindings/js/JSDOMGlobalObject.cpp:
+        (WebCore::JSDOMGlobalObject::addBuiltinGlobals):
+
 2019-03-07  Zalan Bujtas  <zalan@apple.com>
 
         [ContentChangeObserver][REGRESSION] Check if visibility change happens while dispatching mouseMoved
index a4ec4d0..d144091 100644 (file)
@@ -126,7 +126,7 @@ void JSDOMGlobalObject::addBuiltinGlobals(VM& vm)
             JSFunction::create(vm, this, 1, String(), structuredCloneArrayBuffer), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
         JSDOMGlobalObject::GlobalPropertyInfo(clientData.builtinNames().structuredCloneArrayBufferViewPrivateName(),
             JSFunction::create(vm, this, 1, String(), structuredCloneArrayBufferView), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
-        JSDOMGlobalObject::GlobalPropertyInfo(vm.propertyNames->builtinNames().ArrayBufferPrivateName(), getDirect(vm, vm.propertyNames->ArrayBuffer), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+        JSDOMGlobalObject::GlobalPropertyInfo(vm.propertyNames->builtinNames().ArrayBufferPrivateName(), arrayBufferConstructor(), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
 #if ENABLE(STREAMS_API)
         JSDOMGlobalObject::GlobalPropertyInfo(clientData.builtinNames().streamClosedPrivateName(), jsNumber(1), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
         JSDOMGlobalObject::GlobalPropertyInfo(clientData.builtinNames().streamClosingPrivateName(), jsNumber(2), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),