Title: [242722] trunk/Source/_javascript_Core
Revision
242722
Author
[email protected]
Date
2019-03-11 11:59:23 -0700 (Mon, 11 Mar 2019)

Log Message

[JSC] BuiltinExecutables should behave like a WeakSet instead of generic WeakHandleOwner for memory footprint
https://bugs.webkit.org/show_bug.cgi?id=195508

Reviewed by Darin Adler.

Weak<> is not cheap in terms of memory footprint. We allocate WeakBlock (256 bytes) for book-keeping Weak<>.
Currently BuiltinExecutables has 203 Weak<> members and many WeakBlocks are actually allocated because
many UnlinkedFunctionExecutables in BuiltinExecutables are allocated during JSGlobalObject initialization process.

This patch changes two things in BuiltinExecutables.

1. Previously we have m_xxxSourceCode fields too. But we do not need to keep it since we know how to produce it when it is required.
   We generate SourceCode in xxxSourceCode() method instead of just returning m_xxxSourceCode. This reduces sizeof(BuiltinExecutables) 24 x 203 = 4KB.

2. Instead of using Weak<>, BuiltinExecutables holds raw array of UnlinkedFunctionExecutable*. And Heap::finalizeUnconditionalFinalizers() correctly clears dead executables.
   This is similar to JSWeakSet implementation. And it saves WeakBlock allocations.

* builtins/BuiltinExecutables.cpp:
(JSC::BuiltinExecutables::BuiltinExecutables):
(JSC::BuiltinExecutables::finalizeUnconditionally):
(JSC::JSC_FOREACH_BUILTIN_CODE): Deleted.
(JSC::BuiltinExecutables::finalize): Deleted.
* builtins/BuiltinExecutables.h:
(JSC::BuiltinExecutables::static_cast<unsigned>):
(): Deleted.
* heap/Heap.cpp:
(JSC::Heap::finalizeUnconditionalFinalizers):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (242721 => 242722)


--- trunk/Source/_javascript_Core/ChangeLog	2019-03-11 18:45:52 UTC (rev 242721)
+++ trunk/Source/_javascript_Core/ChangeLog	2019-03-11 18:59:23 UTC (rev 242722)
@@ -1,3 +1,33 @@
+2019-03-08  Yusuke Suzuki  <[email protected]>
+
+        [JSC] BuiltinExecutables should behave like a WeakSet instead of generic WeakHandleOwner for memory footprint
+        https://bugs.webkit.org/show_bug.cgi?id=195508
+
+        Reviewed by Darin Adler.
+
+        Weak<> is not cheap in terms of memory footprint. We allocate WeakBlock (256 bytes) for book-keeping Weak<>.
+        Currently BuiltinExecutables has 203 Weak<> members and many WeakBlocks are actually allocated because
+        many UnlinkedFunctionExecutables in BuiltinExecutables are allocated during JSGlobalObject initialization process.
+
+        This patch changes two things in BuiltinExecutables.
+
+        1. Previously we have m_xxxSourceCode fields too. But we do not need to keep it since we know how to produce it when it is required.
+           We generate SourceCode in xxxSourceCode() method instead of just returning m_xxxSourceCode. This reduces sizeof(BuiltinExecutables) 24 x 203 = 4KB.
+
+        2. Instead of using Weak<>, BuiltinExecutables holds raw array of UnlinkedFunctionExecutable*. And Heap::finalizeUnconditionalFinalizers() correctly clears dead executables.
+           This is similar to JSWeakSet implementation. And it saves WeakBlock allocations.
+
+        * builtins/BuiltinExecutables.cpp:
+        (JSC::BuiltinExecutables::BuiltinExecutables):
+        (JSC::BuiltinExecutables::finalizeUnconditionally):
+        (JSC::JSC_FOREACH_BUILTIN_CODE): Deleted.
+        (JSC::BuiltinExecutables::finalize): Deleted.
+        * builtins/BuiltinExecutables.h:
+        (JSC::BuiltinExecutables::static_cast<unsigned>):
+        (): Deleted.
+        * heap/Heap.cpp:
+        (JSC::Heap::finalizeUnconditionalFinalizers):
+
 2019-03-11  Robin Morisset  <[email protected]>
 
         IntlDateTimeFormat can be shrunk by 32 bytes

Modified: trunk/Source/_javascript_Core/builtins/BuiltinExecutables.cpp (242721 => 242722)


--- trunk/Source/_javascript_Core/builtins/BuiltinExecutables.cpp	2019-03-11 18:45:52 UTC (rev 242721)
+++ trunk/Source/_javascript_Core/builtins/BuiltinExecutables.cpp	2019-03-11 18:59:23 UTC (rev 242722)
@@ -37,9 +37,6 @@
 BuiltinExecutables::BuiltinExecutables(VM& vm)
     : m_vm(vm)
     , m_combinedSourceProvider(StringSourceProvider::create(StringImpl::createFromLiteral(s_JSCCombinedCode, s_JSCCombinedCodeLength), { }, URL()))
-#define INITIALIZE_BUILTIN_SOURCE_MEMBERS(name, functionName, overrideName, length) , m_##name##Source(m_combinedSourceProvider.copyRef(), s_##name - s_JSCCombinedCode, (s_##name - s_JSCCombinedCode) + length, 1, 1)
-    JSC_FOREACH_BUILTIN_CODE(INITIALIZE_BUILTIN_SOURCE_MEMBERS)
-#undef INITIALIZE_BUILTIN_SOURCE_MEMBERS
 {
 }
 
@@ -262,23 +259,32 @@
     return functionExecutable;
 }
 
-void BuiltinExecutables::finalize(Handle<Unknown>, void* context)
+void BuiltinExecutables::finalizeUnconditionally()
 {
-    static_cast<Weak<UnlinkedFunctionExecutable>*>(context)->clear();
+    for (auto*& unlinkedExecutable : m_unlinkedExecutables) {
+        if (unlinkedExecutable && !Heap::isMarked(unlinkedExecutable))
+            unlinkedExecutable = nullptr;
+    }
 }
 
 #define DEFINE_BUILTIN_EXECUTABLES(name, functionName, overrideName, length) \
+SourceCode BuiltinExecutables::name##Source() \
+{\
+    return SourceCode { m_combinedSourceProvider.copyRef(), static_cast<int>(s_##name - s_JSCCombinedCode), static_cast<int>((s_##name - s_JSCCombinedCode) + length), 1, 1 };\
+}\
+\
 UnlinkedFunctionExecutable* BuiltinExecutables::name##Executable() \
 {\
-    if (!m_##name##Executable) {\
+    unsigned index = static_cast<unsigned>(BuiltinCodeIndex::name);\
+    if (!m_unlinkedExecutables[index]) {\
         Identifier executableName = m_vm.propertyNames->builtinNames().functionName##PublicName();\
         if (overrideName)\
             executableName = Identifier::fromString(&m_vm, overrideName);\
-        m_##name##Executable = Weak<UnlinkedFunctionExecutable>(createBuiltinExecutable(m_##name##Source, executableName, s_##name##ConstructAbility), this, &m_##name##Executable);\
+        m_unlinkedExecutables[index] = createBuiltinExecutable(name##Source(), executableName, s_##name##ConstructAbility);\
     }\
-    return m_##name##Executable.get();\
+    return m_unlinkedExecutables[index];\
 }
 JSC_FOREACH_BUILTIN_CODE(DEFINE_BUILTIN_EXECUTABLES)
-#undef EXPOSE_BUILTIN_SOURCES
+#undef DEFINE_BUILTIN_EXECUTABLES
 
 }

Modified: trunk/Source/_javascript_Core/builtins/BuiltinExecutables.h (242721 => 242722)


--- trunk/Source/_javascript_Core/builtins/BuiltinExecutables.h	2019-03-11 18:45:52 UTC (rev 242721)
+++ trunk/Source/_javascript_Core/builtins/BuiltinExecutables.h	2019-03-11 18:59:23 UTC (rev 242722)
@@ -37,7 +37,14 @@
 class Identifier;
 class VM;
 
-class BuiltinExecutables final: private WeakHandleOwner {
+#define BUILTIN_NAME_ONLY(name, functionName, overriddenName, length) name,
+enum class BuiltinCodeIndex {
+    JSC_FOREACH_BUILTIN_CODE(BUILTIN_NAME_ONLY)
+    NumberOfBuiltinCodes
+};
+#undef BUILTIN_NAME_ONLY
+
+class BuiltinExecutables {
     WTF_MAKE_FAST_ALLOCATED;
 public:
     explicit BuiltinExecutables(VM&);
@@ -44,7 +51,7 @@
 
 #define EXPOSE_BUILTIN_EXECUTABLES(name, functionName, overriddenName, length) \
 UnlinkedFunctionExecutable* name##Executable(); \
-const SourceCode& name##Source() { return m_##name##Source; }
+SourceCode name##Source();
     
     JSC_FOREACH_BUILTIN_CODE(EXPOSE_BUILTIN_EXECUTABLES)
 #undef EXPOSE_BUILTIN_EXECUTABLES
@@ -53,19 +60,16 @@
     UnlinkedFunctionExecutable* createDefaultConstructor(ConstructorKind, const Identifier& name);
 
     static UnlinkedFunctionExecutable* createExecutable(VM&, const SourceCode&, const Identifier&, ConstructorKind, ConstructAbility);
+
+    void finalizeUnconditionally();
+
 private:
-    void finalize(Handle<Unknown>, void* context) override;
-
     VM& m_vm;
 
     UnlinkedFunctionExecutable* createBuiltinExecutable(const SourceCode&, const Identifier&, ConstructAbility);
 
     Ref<StringSourceProvider> m_combinedSourceProvider;
-#define DECLARE_BUILTIN_SOURCE_MEMBERS(name, functionName, overriddenName, length)\
-    SourceCode m_##name##Source; \
-    Weak<UnlinkedFunctionExecutable> m_##name##Executable;
-    JSC_FOREACH_BUILTIN_CODE(DECLARE_BUILTIN_SOURCE_MEMBERS)
-#undef DECLARE_BUILTIN_SOURCE_MEMBERS
+    UnlinkedFunctionExecutable* m_unlinkedExecutables[static_cast<unsigned>(BuiltinCodeIndex::NumberOfBuiltinCodes)] { };
 };
 
 }

Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (242721 => 242722)


--- trunk/Source/_javascript_Core/heap/Heap.cpp	2019-03-11 18:45:52 UTC (rev 242721)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp	2019-03-11 18:59:23 UTC (rev 242722)
@@ -22,6 +22,7 @@
 #include "Heap.h"
 
 #include "BlockDirectoryInlines.h"
+#include "BuiltinExecutables.h"
 #include "CodeBlock.h"
 #include "CodeBlockSetInlines.h"
 #include "CollectingScope.h"
@@ -559,6 +560,7 @@
 
 void Heap::finalizeUnconditionalFinalizers()
 {
+    vm()->builtinExecutables()->finalizeUnconditionally();
     if (vm()->m_inferredValueSpace)
         finalizeMarkedUnconditionalFinalizers<InferredValue>(vm()->m_inferredValueSpace->space);
     vm()->forEachCodeBlockSpace(
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to