⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 242722 in webkit


Ignore:
Timestamp:
Mar 11, 2019, 11:59:23 AM (7 years ago)
Author:
ysuzuki@apple.com
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.
  1. 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):

Location:
trunk/Source/JavaScriptCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r242718 r242722  
     12019-03-08  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] BuiltinExecutables should behave like a WeakSet instead of generic WeakHandleOwner for memory footprint
     4        https://bugs.webkit.org/show_bug.cgi?id=195508
     5
     6        Reviewed by Darin Adler.
     7
     8        Weak<> is not cheap in terms of memory footprint. We allocate WeakBlock (256 bytes) for book-keeping Weak<>.
     9        Currently BuiltinExecutables has 203 Weak<> members and many WeakBlocks are actually allocated because
     10        many UnlinkedFunctionExecutables in BuiltinExecutables are allocated during JSGlobalObject initialization process.
     11
     12        This patch changes two things in BuiltinExecutables.
     13
     14        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.
     15           We generate SourceCode in xxxSourceCode() method instead of just returning m_xxxSourceCode. This reduces sizeof(BuiltinExecutables) 24 x 203 = 4KB.
     16
     17        2. Instead of using Weak<>, BuiltinExecutables holds raw array of UnlinkedFunctionExecutable*. And Heap::finalizeUnconditionalFinalizers() correctly clears dead executables.
     18           This is similar to JSWeakSet implementation. And it saves WeakBlock allocations.
     19
     20        * builtins/BuiltinExecutables.cpp:
     21        (JSC::BuiltinExecutables::BuiltinExecutables):
     22        (JSC::BuiltinExecutables::finalizeUnconditionally):
     23        (JSC::JSC_FOREACH_BUILTIN_CODE): Deleted.
     24        (JSC::BuiltinExecutables::finalize): Deleted.
     25        * builtins/BuiltinExecutables.h:
     26        (JSC::BuiltinExecutables::static_cast<unsigned>):
     27        (): Deleted.
     28        * heap/Heap.cpp:
     29        (JSC::Heap::finalizeUnconditionalFinalizers):
     30
    1312019-03-11  Robin Morisset  <rmorisset@apple.com>
    232
  • trunk/Source/JavaScriptCore/builtins/BuiltinExecutables.cpp

    r241571 r242722  
    3838    : m_vm(vm)
    3939    , m_combinedSourceProvider(StringSourceProvider::create(StringImpl::createFromLiteral(s_JSCCombinedCode, s_JSCCombinedCodeLength), { }, URL()))
    40 #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)
    41     JSC_FOREACH_BUILTIN_CODE(INITIALIZE_BUILTIN_SOURCE_MEMBERS)
    42 #undef INITIALIZE_BUILTIN_SOURCE_MEMBERS
    4340{
    4441}
     
    263260}
    264261
    265 void BuiltinExecutables::finalize(Handle<Unknown>, void* context)
    266 {
    267     static_cast<Weak<UnlinkedFunctionExecutable>*>(context)->clear();
     262void BuiltinExecutables::finalizeUnconditionally()
     263{
     264    for (auto*& unlinkedExecutable : m_unlinkedExecutables) {
     265        if (unlinkedExecutable && !Heap::isMarked(unlinkedExecutable))
     266            unlinkedExecutable = nullptr;
     267    }
    268268}
    269269
    270270#define DEFINE_BUILTIN_EXECUTABLES(name, functionName, overrideName, length) \
     271SourceCode BuiltinExecutables::name##Source() \
     272{\
     273    return SourceCode { m_combinedSourceProvider.copyRef(), static_cast<int>(s_##name - s_JSCCombinedCode), static_cast<int>((s_##name - s_JSCCombinedCode) + length), 1, 1 };\
     274}\
     275\
    271276UnlinkedFunctionExecutable* BuiltinExecutables::name##Executable() \
    272277{\
    273     if (!m_##name##Executable) {\
     278    unsigned index = static_cast<unsigned>(BuiltinCodeIndex::name);\
     279    if (!m_unlinkedExecutables[index]) {\
    274280        Identifier executableName = m_vm.propertyNames->builtinNames().functionName##PublicName();\
    275281        if (overrideName)\
    276282            executableName = Identifier::fromString(&m_vm, overrideName);\
    277         m_##name##Executable = Weak<UnlinkedFunctionExecutable>(createBuiltinExecutable(m_##name##Source, executableName, s_##name##ConstructAbility), this, &m_##name##Executable);\
     283        m_unlinkedExecutables[index] = createBuiltinExecutable(name##Source(), executableName, s_##name##ConstructAbility);\
    278284    }\
    279     return m_##name##Executable.get();\
     285    return m_unlinkedExecutables[index];\
    280286}
    281287JSC_FOREACH_BUILTIN_CODE(DEFINE_BUILTIN_EXECUTABLES)
    282 #undef EXPOSE_BUILTIN_SOURCES
    283 
    284 }
     288#undef DEFINE_BUILTIN_EXECUTABLES
     289
     290}
  • trunk/Source/JavaScriptCore/builtins/BuiltinExecutables.h

    r240228 r242722  
    3838class VM;
    3939
    40 class BuiltinExecutables final: private WeakHandleOwner {
     40#define BUILTIN_NAME_ONLY(name, functionName, overriddenName, length) name,
     41enum class BuiltinCodeIndex {
     42    JSC_FOREACH_BUILTIN_CODE(BUILTIN_NAME_ONLY)
     43    NumberOfBuiltinCodes
     44};
     45#undef BUILTIN_NAME_ONLY
     46
     47class BuiltinExecutables {
    4148    WTF_MAKE_FAST_ALLOCATED;
    4249public:
     
    4552#define EXPOSE_BUILTIN_EXECUTABLES(name, functionName, overriddenName, length) \
    4653UnlinkedFunctionExecutable* name##Executable(); \
    47 const SourceCode& name##Source() { return m_##name##Source; }
     54SourceCode name##Source();
    4855   
    4956    JSC_FOREACH_BUILTIN_CODE(EXPOSE_BUILTIN_EXECUTABLES)
     
    5461
    5562    static UnlinkedFunctionExecutable* createExecutable(VM&, const SourceCode&, const Identifier&, ConstructorKind, ConstructAbility);
     63
     64    void finalizeUnconditionally();
     65
    5666private:
    57     void finalize(Handle<Unknown>, void* context) override;
    58 
    5967    VM& m_vm;
    6068
     
    6270
    6371    Ref<StringSourceProvider> m_combinedSourceProvider;
    64 #define DECLARE_BUILTIN_SOURCE_MEMBERS(name, functionName, overriddenName, length)\
    65     SourceCode m_##name##Source; \
    66     Weak<UnlinkedFunctionExecutable> m_##name##Executable;
    67     JSC_FOREACH_BUILTIN_CODE(DECLARE_BUILTIN_SOURCE_MEMBERS)
    68 #undef DECLARE_BUILTIN_SOURCE_MEMBERS
     72    UnlinkedFunctionExecutable* m_unlinkedExecutables[static_cast<unsigned>(BuiltinCodeIndex::NumberOfBuiltinCodes)] { };
    6973};
    7074
  • trunk/Source/JavaScriptCore/heap/Heap.cpp

    r242070 r242722  
    2323
    2424#include "BlockDirectoryInlines.h"
     25#include "BuiltinExecutables.h"
    2526#include "CodeBlock.h"
    2627#include "CodeBlockSetInlines.h"
     
    560561void Heap::finalizeUnconditionalFinalizers()
    561562{
     563    vm()->builtinExecutables()->finalizeUnconditionally();
    562564    if (vm()->m_inferredValueSpace)
    563565        finalizeMarkedUnconditionalFinalizers<InferredValue>(vm()->m_inferredValueSpace->space);
Note: See TracChangeset for help on using the changeset viewer.