Changeset 128265 in webkit


Ignore:
Timestamp:
Sep 11, 2012 11:14:56 PM (12 years ago)
Author:
ggaren@apple.com
Message:

Don't allocate a backing store just for a function's name
https://bugs.webkit.org/show_bug.cgi?id=96468

Reviewed by Oliver Hunt.

Treat function.name like function.length etc., and use a custom getter.
This saves space in closures.

  • debugger/DebuggerCallFrame.cpp:

(JSC::DebuggerCallFrame::functionName):

  • debugger/DebuggerCallFrame.h:

(DebuggerCallFrame): Updated for interface change.

  • runtime/Executable.h:

(JSC::JSFunction::JSFunction): Do a little inlining.

  • runtime/JSFunction.cpp:

(JSC::JSFunction::finishCreation): Gone now. That's the point of the patch.

(JSC::JSFunction::name):
(JSC::JSFunction::displayName):
(JSC::JSFunction::nameGetter):
(JSC::JSFunction::getOwnPropertySlot):
(JSC::JSFunction::getOwnPropertyDescriptor):
(JSC::JSFunction::getOwnPropertyNames):
(JSC::JSFunction::put):
(JSC::JSFunction::deleteProperty):
(JSC::JSFunction::defineOwnProperty): Added custom accessors for .name
just like .length and others.

  • runtime/JSFunction.h:

(JSC::JSFunction::create):
(JSFunction): Updated for interface changes.

Location:
trunk/Source/JavaScriptCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r128262 r128265  
     12012-09-11  Geoffrey Garen  <ggaren@apple.com>
     2
     3        Don't allocate a backing store just for a function's name
     4        https://bugs.webkit.org/show_bug.cgi?id=96468
     5
     6        Reviewed by Oliver Hunt.
     7
     8        Treat function.name like function.length etc., and use a custom getter.
     9        This saves space in closures.
     10
     11        * debugger/DebuggerCallFrame.cpp:
     12        (JSC::DebuggerCallFrame::functionName):
     13        * debugger/DebuggerCallFrame.h:
     14        (DebuggerCallFrame): Updated for interface change.
     15
     16        * runtime/Executable.h:
     17        (JSC::JSFunction::JSFunction): Do a little inlining.
     18
     19        * runtime/JSFunction.cpp:
     20        (JSC::JSFunction::finishCreation): Gone now. That's the point of the patch.
     21
     22        (JSC::JSFunction::name):
     23        (JSC::JSFunction::displayName):
     24        (JSC::JSFunction::nameGetter):
     25        (JSC::JSFunction::getOwnPropertySlot):
     26        (JSC::JSFunction::getOwnPropertyDescriptor):
     27        (JSC::JSFunction::getOwnPropertyNames):
     28        (JSC::JSFunction::put):
     29        (JSC::JSFunction::deleteProperty):
     30        (JSC::JSFunction::defineOwnProperty): Added custom accessors for .name
     31        just like .length and others.
     32
     33        * runtime/JSFunction.h:
     34        (JSC::JSFunction::create):
     35        (JSFunction): Updated for interface changes.
     36
    1372012-09-11  Mark Hahnenberg  <mhahnenberg@apple.com>
    238
  • trunk/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp

    r127202 r128265  
    3737namespace JSC {
    3838
    39 const String* DebuggerCallFrame::functionName() const
     39String DebuggerCallFrame::functionName() const
    4040{
    4141    if (!m_callFrame->codeBlock())
    42         return 0;
     42        return String();
    4343
    4444    if (!m_callFrame->callee())
    45         return 0;
     45        return String();
    4646
    4747    JSObject* function = m_callFrame->callee();
    4848    if (!function || !function->inherits(&JSFunction::s_info))
    49         return 0;
    50     return &jsCast<JSFunction*>(function)->name(m_callFrame);
     49        return String();
     50    return jsCast<JSFunction*>(function)->name(m_callFrame);
    5151}
    5252   
  • trunk/Source/JavaScriptCore/debugger/DebuggerCallFrame.h

    r127202 r128265  
    5252        JSGlobalObject* dynamicGlobalObject() const { return m_callFrame->dynamicGlobalObject(); }
    5353        JSScope* scope() const { return m_callFrame->scope(); }
    54         JS_EXPORT_PRIVATE const String* functionName() const;
     54        JS_EXPORT_PRIVATE String functionName() const;
    5555        JS_EXPORT_PRIVATE String calculatedFunctionName() const;
    5656        JS_EXPORT_PRIVATE Type type() const;
  • trunk/Source/JavaScriptCore/runtime/Executable.h

    r127958 r128265  
    3232#include "JSFunction.h"
    3333#include "Interpreter.h"
     34#include "JSGlobalObject.h"
    3435#include "LLIntCLoop.h"
    3536#include "Nodes.h"
     
    754755        WriteBarrier<SharedSymbolTable> m_symbolTable;
    755756    };
     757
     758    inline JSFunction::JSFunction(JSGlobalData& globalData, FunctionExecutable* executable, JSScope* scope)
     759        : Base(globalData, scope->globalObject()->functionStructure())
     760        , m_executable(globalData, this, executable)
     761        , m_scope(globalData, this, scope)
     762    {
     763    }
    756764
    757765    inline FunctionExecutable* JSFunction::jsExecutable() const
  • trunk/Source/JavaScriptCore/runtime/JSFunction.cpp

    r127958 r128265  
    8585}
    8686
    87 JSFunction::JSFunction(ExecState* exec, FunctionExecutable* executable, JSScope* scope)
    88     : Base(exec->globalData(), scope->globalObject()->functionStructure())
    89     , m_executable(exec->globalData(), this, executable)
    90     , m_scope(exec->globalData(), this, scope)
    91 {
    92 }
    93 
    9487void JSFunction::finishCreation(ExecState* exec, NativeExecutable* executable, int length, const String& name)
    9588{
     
    9992    putDirect(exec->globalData(), exec->globalData().propertyNames->name, jsString(exec, name), DontDelete | ReadOnly | DontEnum);
    10093    putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
    101 }
    102 
    103 void JSFunction::finishCreation(ExecState* exec, FunctionExecutable* executable, JSScope* scope)
    104 {
    105     JSGlobalData& globalData = exec->globalData();
    106     Base::finishCreation(globalData);
    107     ASSERT(inherits(&s_info));
    108 
    109     // Switching the structure here is only safe if we currently have the function structure!
    110     ASSERT(structure() == scope->globalObject()->functionStructure());
    111     setStructureAndReallocateStorageIfNecessary(
    112         globalData,
    113         scope->globalObject()->namedFunctionStructure());
    114     putDirectOffset(globalData, scope->globalObject()->functionNameOffset(), executable->nameValue());
    11594}
    11695
     
    125104}
    126105
    127 const String& JSFunction::name(ExecState* exec)
    128 {
    129     return asString(getDirect(exec->globalData(), exec->globalData().propertyNames->name))->tryGetValue();
    130 }
    131 
    132 const String JSFunction::displayName(ExecState* exec)
     106String JSFunction::name(ExecState* exec)
     107{
     108    return get(exec, exec->globalData().propertyNames->name).toWTFString(exec);
     109}
     110
     111String JSFunction::displayName(ExecState* exec)
    133112{
    134113    JSValue displayName = getDirect(exec->globalData(), exec->globalData().propertyNames->displayName);
     
    214193}
    215194
     195JSValue JSFunction::nameGetter(ExecState*, JSValue slotBase, PropertyName)
     196{
     197    JSFunction* thisObj = jsCast<JSFunction*>(slotBase);
     198    ASSERT(!thisObj->isHostFunction());
     199    return thisObj->jsExecutable()->nameValue();
     200}
     201
    216202bool JSFunction::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
    217203{
     
    252238    }
    253239
     240    if (propertyName == exec->propertyNames().name) {
     241        slot.setCacheableCustom(thisObject, nameGetter);
     242        return true;
     243    }
     244
    254245    if (propertyName == exec->propertyNames().caller) {
    255246        if (thisObject->jsExecutable()->isStrictMode()) {
     
    300291    }
    301292   
     293    if (propertyName == exec->propertyNames().name) {
     294        descriptor.setDescriptor(thisObject->jsExecutable()->nameValue(), ReadOnly | DontEnum | DontDelete);
     295        return true;
     296    }
     297
    302298    if (propertyName == exec->propertyNames().caller) {
    303299        if (thisObject->jsExecutable()->isStrictMode()) {
     
    328324        propertyNames.add(exec->propertyNames().caller);
    329325        propertyNames.add(exec->propertyNames().length);
     326        propertyNames.add(exec->propertyNames().name);
    330327    }
    331328    Base::getOwnPropertyNames(thisObject, exec, propertyNames, mode);
     
    357354        return;
    358355    }
    359     if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length || propertyName == exec->propertyNames().caller) {
     356    if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length || propertyName == exec->propertyNames().name || propertyName == exec->propertyNames().caller) {
    360357        if (slot.isStrictMode())
    361358            throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
     
    372369        && (propertyName == exec->propertyNames().arguments
    373370            || propertyName == exec->propertyNames().length
     371            || propertyName == exec->propertyNames().name
    374372            || propertyName == exec->propertyNames().prototype
    375373            || propertyName == exec->propertyNames().caller))
     
    410408    } else if (propertyName == exec->propertyNames().length)
    411409        valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), jsNumber(thisObject->jsExecutable()->parameterCount()));
     410    else if (propertyName == exec->propertyNames().name)
     411        valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), thisObject->jsExecutable()->nameValue());
    412412    else
    413413        return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
  • trunk/Source/JavaScriptCore/runtime/JSFunction.h

    r127202 r128265  
    6060        static JSFunction* create(ExecState* exec, FunctionExecutable* executable, JSScope* scope)
    6161        {
    62             JSFunction* function = new (NotNull, allocateCell<JSFunction>(*exec->heap())) JSFunction(exec, executable, scope);
     62            JSGlobalData& globalData = exec->globalData();
     63            JSFunction* function = new (NotNull, allocateCell<JSFunction>(globalData.heap)) JSFunction(globalData, executable, scope);
    6364            ASSERT(function->structure()->globalObject());
    64             function->finishCreation(exec, executable, scope);
     65            function->finishCreation(globalData);
    6566            return function;
    6667        }
    6768       
    68         JS_EXPORT_PRIVATE const String& name(ExecState*);
    69         JS_EXPORT_PRIVATE const String displayName(ExecState*);
     69        JS_EXPORT_PRIVATE String name(ExecState*);
     70        JS_EXPORT_PRIVATE String displayName(ExecState*);
    7071        const String calculatedDisplayName(ExecState*);
    7172
     
    138139
    139140        JS_EXPORT_PRIVATE JSFunction(ExecState*, JSGlobalObject*, Structure*);
    140         JSFunction(ExecState*, FunctionExecutable*, JSScope*);
     141        JSFunction(JSGlobalData&, FunctionExecutable*, JSScope*);
    141142       
    142143        void finishCreation(ExecState*, NativeExecutable*, int length, const String& name);
    143         void finishCreation(ExecState*, FunctionExecutable*, JSScope*);
     144        using Base::finishCreation;
    144145
    145146        Structure* cacheInheritorID(ExecState*);
     
    164165        static JSValue callerGetter(ExecState*, JSValue, PropertyName);
    165166        static JSValue lengthGetter(ExecState*, JSValue, PropertyName);
     167        static JSValue nameGetter(ExecState*, JSValue, PropertyName);
    166168
    167169        WriteBarrier<ExecutableBase> m_executable;
Note: See TracChangeset for help on using the changeset viewer.