Changeset 197308 in webkit


Ignore:
Timestamp:
Feb 28, 2016 9:26:05 PM (8 years ago)
Author:
akling@apple.com
Message:

Make JSFunction.name allocation fully lazy.
<https://webkit.org/b/154806>

Reviewed by Saam Barati.

We were reifying the "name" field on functions lazily, but created the string
value itself up front. This patch gets rid of the up-front allocation,
saving us a JSString allocation per function in most cases.

  • builtins/BuiltinExecutables.cpp:

(JSC::createExecutableInternal):

  • bytecode/UnlinkedFunctionExecutable.cpp:

(JSC::UnlinkedFunctionExecutable::visitChildren):

  • bytecode/UnlinkedFunctionExecutable.h:
  • runtime/CodeCache.cpp:

(JSC::CodeCache::getFunctionExecutableFromGlobalCode):

  • runtime/Executable.h:
  • runtime/JSFunction.cpp:

(JSC::JSFunction::reifyName):

Location:
trunk/Source/JavaScriptCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r197305 r197308  
     12016-02-28  Andreas Kling  <akling@apple.com>
     2
     3        Make JSFunction.name allocation fully lazy.
     4        <https://webkit.org/b/154806>
     5
     6        Reviewed by Saam Barati.
     7
     8        We were reifying the "name" field on functions lazily, but created the string
     9        value itself up front. This patch gets rid of the up-front allocation,
     10        saving us a JSString allocation per function in most cases.
     11
     12        * builtins/BuiltinExecutables.cpp:
     13        (JSC::createExecutableInternal):
     14        * bytecode/UnlinkedFunctionExecutable.cpp:
     15        (JSC::UnlinkedFunctionExecutable::visitChildren):
     16        * bytecode/UnlinkedFunctionExecutable.h:
     17        * runtime/CodeCache.cpp:
     18        (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
     19        * runtime/Executable.h:
     20        * runtime/JSFunction.cpp:
     21        (JSC::JSFunction::reifyName):
     22
    1232016-02-28  Andreas Kling  <akling@apple.com>
    224
  • trunk/Source/JavaScriptCore/builtins/BuiltinExecutables.cpp

    r196525 r197308  
    110110    VariableEnvironment dummyTDZVariables;
    111111    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, kind, constructAbility, dummyTDZVariables, DerivedContextType::None, WTFMove(sourceOverride));
    112     functionExecutable->setNameValue(vm, jsString(&vm, name.string()));
    113112    return functionExecutable;
    114113}
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp

    r197043 r197308  
    117117    visitor.append(&thisObject->m_unlinkedCodeBlockForCall);
    118118    visitor.append(&thisObject->m_unlinkedCodeBlockForConstruct);
    119     visitor.append(&thisObject->m_nameValue);
    120119}
    121120
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h

    r197043 r197308  
    7777    const Identifier& name() const { return m_name; }
    7878    const Identifier& inferredName() const { return m_inferredName; }
    79     JSString* nameValue() const { return m_nameValue.get(); }
    80     void setNameValue(VM& vm, JSString* nameValue) { m_nameValue.set(vm, this, nameValue); }
    8179    unsigned parameterCount() const { return m_parameterCount; };
    8280    SourceParseMode parseMode() const { return static_cast<SourceParseMode>(m_sourceParseMode); };
     
    163161    Identifier m_name;
    164162    Identifier m_inferredName;
    165     WriteBarrier<JSString> m_nameValue;
    166163    RefPtr<SourceProvider> m_sourceOverride;
    167164
     
    169166
    170167protected:
    171     void finishCreation(VM& vm)
    172     {
    173         Base::finishCreation(vm);
    174         m_nameValue.set(vm, this, jsString(&vm, name().string()));
    175     }
    176 
    177168    static void visitChildren(JSCell*, SlotVisitor&);
    178169
  • trunk/Source/JavaScriptCore/runtime/CodeCache.cpp

    r196272 r197308  
    188188        return nullptr;
    189189   
     190    metadata->overrideName(name);
    190191    metadata->setEndPosition(positionBeforeLastNewline);
    191192    // The Function constructor only has access to global variables, so no variables will be under TDZ.
     
    193194    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, UnlinkedNormalFunction, ConstructAbility::CanConstruct, emptyTDZVariables, DerivedContextType::None);
    194195
    195     functionExecutable->m_nameValue.set(vm, functionExecutable, jsString(&vm, name.string()));
    196 
    197196    m_sourceCode.addCache(key, SourceCodeValue(vm, functionExecutable, m_sourceCode.age()));
    198197    return functionExecutable;
  • trunk/Source/JavaScriptCore/runtime/Executable.h

    r195876 r197308  
    668668    const Identifier& name() { return m_unlinkedExecutable->name(); }
    669669    const Identifier& inferredName() { return m_unlinkedExecutable->inferredName(); }
    670     JSString* nameValue() const { return m_unlinkedExecutable->nameValue(); }
    671670    size_t parameterCount() const { return m_unlinkedExecutable->parameterCount(); } // Excluding 'this'!
    672671    SourceParseMode parseMode() const { return m_unlinkedExecutable->parseMode(); }
  • trunk/Source/JavaScriptCore/runtime/JSFunction.cpp

    r197205 r197308  
    590590    ASSERT(!hasReifiedName());
    591591    ASSERT(!isHostFunction());
    592     JSValue initialValue = jsExecutable()->nameValue();
    593592    unsigned initialAttributes = DontEnum | ReadOnly;
    594593    const Identifier& identifier = exec->propertyNames().name;
    595     putDirect(vm, identifier, initialValue, initialAttributes);
     594    putDirect(vm, identifier, jsString(exec, jsExecutable()->name().string()), initialAttributes);
    596595
    597596    rareData->setHasReifiedName();
Note: See TracChangeset for help on using the changeset viewer.