Changeset 36016 in webkit for trunk/JavaScriptCore/kjs


Ignore:
Timestamp:
Sep 1, 2008, 2:22:54 PM (17 years ago)
Author:
[email protected]
Message:

JavaScriptCore:

2008-09-01 Geoffrey Garen <[email protected]>

Reviewed by Darin Adler.

First cut at inline caching for access to vanilla JavaScript properties.


SunSpider says 4% faster. Tests heavy on dictionary-like access have
regressed a bit -- we have a lot of room to improve in this area,
but this patch is over-ripe as-is.


JSCells now have a StructureID that uniquely identifies their layout,
and holds their prototype.


JSValue::put takes a PropertySlot& argument, so it can fill in details
about where it put a value, for the sake of caching.

  • VM/CodeGenerator.cpp: (KJS::CodeGenerator::CodeGenerator): Avoid calling removeDirect if we can, since it disables inline caching in the global object. This can probably improve in the future.
  • kjs/JSGlobalObject.cpp: Nixed reset(), since it complicates caching, and wasn't really necessary.
  • kjs/JSObject.cpp: Tweaked getter / setter behavior not to rely on the IsGetterSetter flag, since the flag was buggy. This is necessary in order to avoid accidentally accessing a getter / setter as a normal property.


Also changed getter / setter creation to honor ReadOnly, matching Mozilla.


  • kjs/PropertyMap.cpp: Nixed clear(), since it complicates caching and isn't necessary.
  • kjs/Shell.cpp: Moved SamplingTool dumping outside the loop. This allows you to aggregate sampling of multiple files (or the same file repeatedly), which helped me track down regressions.
  • kjs/ustring.h: Moved IdentifierRepHash here to share it.

WebCore:

2008-09-01 Geoffrey Garen <[email protected]>

Reviewed by Darin Adler.

First cut at inline caching for access to vanilla JavaScript properties.

Updated for JavaScriptCore changes. Mostly mechanical addition of StructureIDs
to WebCore classes, and PutPropertySlot& arguments to put functions.

(WebCore::JSCSSStyleDeclaration::customPut): Be sure to play nice with
inline caching for global properties, so global assignment can be optimized.

  • ForwardingHeaders/kjs/StructureID.h: Added.
  • bindings/js/JSDOMBinding.h: (WebCore::DOMObject::DOMObject):
  • bindings/js/JSDOMWindowBase.cpp: (WebCore::JSDOMWindowBase::put):
  • bindings/js/JSDOMWindowBase.h:
  • bindings/js/JSDOMWindowCustom.h: (WebCore::JSDOMWindow::customPut):
  • bindings/js/JSDOMWindowShell.cpp: (WebCore::JSDOMWindowShell::JSDOMWindowShell): (WebCore::JSDOMWindowShell::put):
  • bindings/js/JSDOMWindowShell.h:
  • bindings/js/JSEventTargetBase.h: (WebCore::JSEventTargetBase::put):
  • bindings/js/JSEventTargetNode.h: (WebCore::JSEventTargetNode::put):
  • bindings/js/JSHTMLAppletElementCustom.cpp: (WebCore::JSHTMLAppletElement::customPut):
  • bindings/js/JSHTMLEmbedElementCustom.cpp: (WebCore::JSHTMLEmbedElement::customPut):
  • bindings/js/JSHTMLInputElementBase.cpp: (WebCore::JSHTMLInputElementBase::put):
  • bindings/js/JSHTMLInputElementBase.h:
  • bindings/js/JSHTMLObjectElementCustom.cpp: (WebCore::JSHTMLObjectElement::customPut):
  • bindings/js/JSHistoryCustom.cpp: (WebCore::JSHistory::customPut):
  • bindings/js/JSInspectedObjectWrapper.cpp: (WebCore::JSInspectedObjectWrapper::wrap): (WebCore::JSInspectedObjectWrapper::JSInspectedObjectWrapper):
  • bindings/js/JSInspectedObjectWrapper.h:
  • bindings/js/JSInspectorCallbackWrapper.cpp: (WebCore::JSInspectorCallbackWrapper::wrap): (WebCore::JSInspectorCallbackWrapper::JSInspectorCallbackWrapper):
  • bindings/js/JSInspectorCallbackWrapper.h:
  • bindings/js/JSLocationCustom.cpp: (WebCore::JSLocation::customPut):
  • bindings/js/JSPluginElementFunctions.cpp: (WebCore::runtimeObjectCustomPut):
  • bindings/js/JSPluginElementFunctions.h:
  • bindings/js/JSQuarantinedObjectWrapper.cpp: (WebCore::JSQuarantinedObjectWrapper::JSQuarantinedObjectWrapper): (WebCore::JSQuarantinedObjectWrapper::put):
  • bindings/js/JSQuarantinedObjectWrapper.h:
  • bindings/js/JSStorageCustom.cpp: (WebCore::JSStorage::customPut):
  • bindings/objc/WebScriptObject.mm: (-[WebScriptObject setValue:forKey:]):
  • bindings/scripts/CodeGeneratorJS.pm:
  • bridge/NP_jsobject.cpp: (_NPN_SetProperty):
  • bridge/jni/jni_jsobject.mm: (JavaJSObject::setMember):
  • bridge/objc/objc_class.mm: (KJS::Bindings::ObjcClass::fallbackObject):
  • bridge/objc/objc_runtime.h:
  • bridge/objc/objc_runtime.mm: (ObjcFallbackObjectImp::ObjcFallbackObjectImp): (ObjcFallbackObjectImp::put):
  • bridge/runtime.cpp: (KJS::Bindings::Instance::createRuntimeObject):
  • bridge/runtime_array.cpp: (RuntimeArray::put):
  • bridge/runtime_array.h:
  • bridge/runtime_object.cpp: (RuntimeObjectImp::RuntimeObjectImp): (RuntimeObjectImp::put):
  • bridge/runtime_object.h:

LayoutTests:

2008-09-01 Geoffrey Garen <[email protected]>

Reviewed by Darin Adler.

First cut at inline caching for access to vanilla JavaScript properties.


Tests for things I broke along the way.


  • fast/dom/getter-on-window-object2-expected.txt:
  • fast/js/pic: Added.
  • fast/js/pic/cached-deleted-properties-expected.txt: Added.
  • fast/js/pic/cached-deleted-properties.html: Added.
  • fast/js/pic/cached-getter-dictionary-and-proto-expected.txt: Added.
  • fast/js/pic/cached-getter-dictionary-and-proto.html: Added.
  • fast/js/pic/cached-getter-setter-expected.txt: Added.
  • fast/js/pic/cached-getter-setter.html: Added.
  • fast/js/pic/cached-prototype-setter-expected.txt: Added.
  • fast/js/pic/cached-prototype-setter.html: Added.
  • fast/js/pic/cached-single-entry-transition-expected.txt: Added.
  • fast/js/pic/cached-single-entry-transition.html: Added.
  • fast/js/pic/get-empty-string-expected.txt: Added.
  • fast/js/pic/get-empty-string.html: Added.
  • fast/js/pic/get-set-proxy-object-expected.txt: Added.
  • fast/js/pic/get-set-proxy-object.html: Added.
  • fast/js/pic/rehash-poisons-structure-expected.txt: Added.
  • fast/js/pic/rehash-poisons-structure.html: Added.
Location:
trunk/JavaScriptCore/kjs
Files:
2 added
43 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/Arguments.cpp

    r35807 r36016  
    4545
    4646    putDirect(exec->propertyNames().callee, function, DontEnum);
    47     putDirect(exec, exec->propertyNames().length, args.size(), DontEnum);
     47    putDirect(exec->propertyNames().length, jsNumber(exec, args.size()), DontEnum);
    4848 
    4949    int i = 0;
     
    7979}
    8080
    81 void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
     81void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
    8282{
    8383    if (d->indexToNameMap.isMapped(propertyName))
    84         d->activation->put(exec, d->indexToNameMap[propertyName], value);
     84        d->activation->put(exec, d->indexToNameMap[propertyName], value, slot);
    8585    else
    86         JSObject::put(exec, propertyName, value);
     86        JSObject::put(exec, propertyName, value, slot);
    8787}
    8888
  • trunk/JavaScriptCore/kjs/Arguments.h

    r35807 r36016  
    3939
    4040        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    41         virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
     41        virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
    4242        virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
    4343
  • trunk/JavaScriptCore/kjs/ArrayPrototype.cpp

    r36006 r36016  
    114114}
    115115
     116static void putProperty(ExecState* exec, JSObject* obj, const Identifier& propertyName, JSValue* value)
     117{
     118    PutPropertySlot slot;
     119    obj->put(exec, propertyName, value, slot);
     120}
     121
    116122JSValue* arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
    117123{
     
    290296    unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
    291297    if (length == 0) {
    292         thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length));
     298        putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length));
    293299        result = jsUndefined();
    294300    } else {
    295301        result = thisObj->get(exec, length - 1);
    296302        thisObj->deleteProperty(exec, length - 1);
    297         thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length - 1));
     303        putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length - 1));
    298304    }
    299305    return result;
     
    307313        thisObj->put(exec, length + n, args.at(exec, n));
    308314    length += args.size();
    309     thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length));
     315    putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length));
    310316    return jsNumber(exec, length);
    311317}
     
    342348    unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
    343349    if (length == 0) {
    344         thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length));
     350        putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length));
    345351        result = jsUndefined();
    346352    } else {
     
    353359        }
    354360        thisObj->deleteProperty(exec, length - 1);
    355         thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length - 1));
     361        putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length - 1));
    356362    }
    357363    return result;
     
    510516        thisObj->put(exec, k + begin, args.at(exec, k + 2));
    511517
    512     thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length - deleteCount + additionalArgs));
     518    putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length - deleteCount + additionalArgs));
    513519    return result;
    514520}
     
    532538        thisObj->put(exec, k, args.at(exec, k));
    533539    JSValue* result = jsNumber(exec, length + nrArgs);
    534     thisObj->put(exec, exec->propertyNames().length, result);
     540    putProperty(exec, thisObj, exec->propertyNames().length, result);
    535541    return result;
    536542}
  • trunk/JavaScriptCore/kjs/DateConstructor.cpp

    r36006 r36016  
    6161      putDirectFunction(exec, new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().now, dateNow), DontEnum);
    6262
    63       putDirect(exec, exec->propertyNames().length, 7, ReadOnly | DontEnum | DontDelete);
     63      putDirect(exec->propertyNames().length, jsNumber(exec, 7), ReadOnly | DontEnum | DontDelete);
    6464}
    6565
  • trunk/JavaScriptCore/kjs/InternalFunction.cpp

    r35807 r36016  
    3434
    3535InternalFunction::InternalFunction(ExecState* exec)
     36    : JSObject(exec->globalData().nullProtoStructureID)
    3637{
    3738    putDirect(exec->propertyNames().name, jsString(exec, exec->propertyNames().nullIdentifier.ustring()), DontDelete | ReadOnly | DontEnum);
  • trunk/JavaScriptCore/kjs/JSActivation.cpp

    r35807 r36016  
    4242const ClassInfo JSActivation::info = { "JSActivation", 0, 0, 0 };
    4343
    44 JSActivation::JSActivation(PassRefPtr<FunctionBodyNode> functionBody, Register* registers)
    45     : Base(new JSActivationData(functionBody, registers))
     44JSActivation::JSActivation(ExecState* exec, PassRefPtr<FunctionBodyNode> functionBody, Register* registers)
     45    : Base(exec->globalData().nullProtoStructureID, new JSActivationData(functionBody, registers))
    4646{
    4747}
     
    7979    // We don't call through to JSObject because there's no way to give an
    8080    // activation object getter properties or a prototype.
    81     ASSERT(!m_propertyMap.hasGetterSetterProperties());
     81    ASSERT(!hasGetterSetterProperties());
    8282    ASSERT(prototype() == jsNull());
    8383    return false;
    8484}
    8585
    86 void JSActivation::put(ExecState*, const Identifier& propertyName, JSValue* value)
     86void JSActivation::put(ExecState*, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
    8787{
    8888    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
     
    9494    // properties are non-standard extensions that other implementations do not
    9595    // expose in the activation object.
    96     ASSERT(!m_propertyMap.hasGetterSetterProperties());
    97     m_propertyMap.put(propertyName, value, 0, true);
     96    ASSERT(!hasGetterSetterProperties());
     97    putDirect(propertyName, value, 0, true, slot);
    9898}
    9999
     
    109109    // properties are non-standard extensions that other implementations do not
    110110    // expose in the activation object.
    111     ASSERT(!m_propertyMap.hasGetterSetterProperties());
    112     m_propertyMap.put(propertyName, value, attributes, true);
     111    ASSERT(!hasGetterSetterProperties());
     112    PutPropertySlot slot;
     113    putDirect(propertyName, value, attributes, true, slot);
    113114}
    114115
  • trunk/JavaScriptCore/kjs/JSActivation.h

    r35022 r36016  
    4141        typedef JSVariableObject Base;
    4242    public:
    43         JSActivation(PassRefPtr<FunctionBodyNode>, Register*);
     43        JSActivation(ExecState* exec, PassRefPtr<FunctionBodyNode>, Register*);
    4444        virtual ~JSActivation();
    4545       
     
    4949        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    5050
    51         virtual void put(ExecState*, const Identifier&, JSValue*);
     51        virtual void put(ExecState*, const Identifier&, JSValue*, PutPropertySlot&);
    5252        virtual void putWithAttributes(ExecState*, const Identifier&, JSValue*, unsigned attributes);
    5353        virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
  • trunk/JavaScriptCore/kjs/JSArray.cpp

    r35807 r36016  
    126126#endif
    127127
    128 JSArray::JSArray(JSValue* prototype, unsigned initialLength)
     128JSArray::JSArray(DummyConstructTag)
     129    : JSObject(StructureID::create(jsNull()))
     130{
     131    unsigned initialCapacity = 0;
     132
     133    m_storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity)));
     134    m_fastAccessCutoff = 0;
     135    m_storage->m_vectorLength = initialCapacity;
     136    m_storage->m_length = 0;
     137
     138    checkConsistency();
     139}
     140
     141JSArray::JSArray(JSObject* prototype, unsigned initialLength)
    129142    : JSObject(prototype)
    130143{
     
    221234
    222235// ECMA 15.4.5.1
    223 void JSArray::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
     236void JSArray::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
    224237{
    225238    bool isArrayIndex;
     
    240253    }
    241254
    242     JSObject::put(exec, propertyName, value);
     255    JSObject::put(exec, propertyName, value, slot);
    243256}
    244257
     
    277290    if (i >= MIN_SPARSE_ARRAY_INDEX) {
    278291        if (i > MAX_ARRAY_INDEX) {
    279             put(exec, Identifier::from(exec, i), value);
     292            PutPropertySlot slot;
     293            put(exec, Identifier::from(exec, i), value, slot);
    280294            return;
    281295        }
  • trunk/JavaScriptCore/kjs/JSArray.h

    r35900 r36016  
    3939    class JSArray : public JSObject {
    4040    public:
    41         JSArray(JSValue* prototype, unsigned initialLength);
     41        enum DummyConstructTag { DummyConstruct };
     42        JSArray(DummyConstructTag);
     43        JSArray(JSObject* prototype, unsigned initialLength);
    4244        JSArray(ExecState* exec, JSObject* prototype, const ArgList& initialValues);
    4345        virtual ~JSArray();
     
    7072
    7173    protected:
    72         virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
     74        virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
    7375        virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
    7476        virtual bool deleteProperty(ExecState*, unsigned propertyName);
  • trunk/JavaScriptCore/kjs/JSCell.cpp

    r35830 r36016  
    171171}
    172172
    173 void JSCell::put(ExecState* exec, const Identifier& identifier, JSValue* value)
     173void JSCell::put(ExecState* exec, const Identifier& identifier, JSValue* value, PutPropertySlot& slot)
     174{
     175    toObject(exec)->put(exec, identifier, value, slot);
     176}
     177
     178void JSCell::put(ExecState* exec, unsigned identifier, JSValue* value)
    174179{
    175180    toObject(exec)->put(exec, identifier, value);
    176181}
    177182
    178 void JSCell::put(ExecState* exec, unsigned identifier, JSValue* value)
    179 {
    180     toObject(exec)->put(exec, identifier, value);
    181 }
    182 
    183183bool JSCell::deleteProperty(ExecState* exec, const Identifier& identifier)
    184184{
  • trunk/JavaScriptCore/kjs/JSCell.h

    r35830 r36016  
    2424#define JSCell_h
    2525
     26#include "StructureID.h"
    2627#include "JSValue.h"
    2728#include "collector.h"
     
    4041    private:
    4142        JSCell();
     43        JSCell(StructureID*);
    4244        virtual ~JSCell();
    4345
     
    4951        virtual bool isObject() const;
    5052        virtual bool isObject(const ClassInfo*) const;
     53
     54        StructureID* structureID() const;
    5155
    5256        // Extracting the value.
     
    8286        // Object operations, with the toObject operation included.
    8387        virtual const ClassInfo* classInfo() const;
    84         virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
     88        virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
    8589        virtual void put(ExecState*, unsigned propertyName, JSValue*);
    8690        virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
     
    98102        virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
    99103       
    100         intptr_t reserved; // Reserved for work in progress.
     104        StructureID* m_structureID;
    101105    };
    102106
    103107    inline JSCell::JSCell()
     108        : m_structureID(0)
     109    {
     110    }
     111
     112    inline JSCell::JSCell(StructureID* structureID)
     113        : m_structureID(structureID)
    104114    {
    105115    }
     
    112122    {
    113123        return Heap::isNumber(const_cast<JSCell*>(this));
     124    }
     125
     126    inline StructureID* JSCell::structureID() const
     127    {
     128        return m_structureID;
    114129    }
    115130
  • trunk/JavaScriptCore/kjs/JSFunction.cpp

    r35807 r36016  
    109109}
    110110
    111 void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
     111void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
    112112{
    113113    if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
    114114        return;
    115     Base::put(exec, propertyName, value);
     115    Base::put(exec, propertyName, value, slot);
    116116}
    117117
  • trunk/JavaScriptCore/kjs/JSFunction.h

    r35807 r36016  
    4444
    4545        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    46         virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
     46        virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
    4747        virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
    4848
  • trunk/JavaScriptCore/kjs/JSGlobalData.cpp

    r35853 r36016  
    7777    , stringTable(&KJS::stringTable)
    7878#endif
     79    , stringStructureID(StructureID::create(jsNull()))
     80    , numberStructureID(StructureID::create(jsNull()))
     81    , nullProtoStructureID(StructureID::create(jsNull()))
    7982    , identifierTable(createIdentifierTable())
    8083    , propertyNames(new CommonIdentifiers(this))
  • trunk/JavaScriptCore/kjs/JSGlobalData.h

    r36006 r36016  
    5151    class Parser;
    5252    class ParserRefCounted;
     53    class StructureID;
    5354    class UString;
    5455    struct HashTable;
     
    7273        const HashTable* regExpConstructorTable;
    7374        const HashTable* stringTable;
     75       
     76        RefPtr<StructureID> stringStructureID;
     77        RefPtr<StructureID> numberStructureID;
     78        RefPtr<StructureID> nullProtoStructureID;
    7479
    7580        IdentifierTable* identifierTable;
  • trunk/JavaScriptCore/kjs/JSGlobalObject.cpp

    r35853 r36016  
    136136}
    137137
    138 void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
     138void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
    139139{
    140140    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
     
    142142    if (symbolTablePut(propertyName, value))
    143143        return;
    144     return JSVariableObject::put(exec, propertyName, value);
     144    JSVariableObject::put(exec, propertyName, value, slot);
    145145}
    146146
     
    153153
    154154    JSValue* valueBefore = getDirect(propertyName);
    155     JSVariableObject::put(exec, propertyName, value);
     155    PutPropertySlot slot;
     156    JSVariableObject::put(exec, propertyName, value, slot);
    156157    if (!valueBefore) {
    157158        if (JSValue* valueAfter = getDirect(propertyName))
     
    188189    // dangerous. (The allocations below may cause a GC.)
    189190
    190     m_propertyMap.clear();
     191    ASSERT(!hasCustomProperties());
    191192    symbolTable().clear();
    192193    setRegisterArray(0, 0);
     
    334335#endif
    335336
    336     // Set prototype, and also insert the object prototype at the end of the chain.
    337 
     337    resetPrototype(prototype);
     338}
     339
     340// Set prototype, and also insert the object prototype at the end of the chain.
     341void JSGlobalObject::resetPrototype(JSValue* prototype)
     342{
    338343    setPrototype(prototype);
    339344    lastInPrototypeChain(this)->setPrototype(d()->objectPrototype);
  • trunk/JavaScriptCore/kjs/JSGlobalObject.h

    r35807 r36016  
    131131
    132132    public:
    133         JSGlobalObject()
    134             : JSVariableObject(new JSGlobalObjectData(this, this))
     133        void* operator new(size_t, JSGlobalData*);
     134
     135        JSGlobalObject(JSGlobalData* globalData)
     136            : JSVariableObject(globalData->nullProtoStructureID, new JSGlobalObjectData(this, this))
    135137        {
    136138            init(this);
     
    138140
    139141    protected:
    140         JSGlobalObject(JSValue* prototype, JSGlobalObjectData* d, JSObject* globalThisValue)
     142        JSGlobalObject(JSObject* prototype, JSGlobalObjectData* d, JSObject* globalThisValue)
    141143            : JSVariableObject(prototype, d)
    142144        {
     
    149151        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    150152        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable);
    151         virtual void put(ExecState*, const Identifier&, JSValue*);
     153        virtual void put(ExecState*, const Identifier&, JSValue*, PutPropertySlot&);
    152154        virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue* value, unsigned attributes);
    153155
     
    158160        JSGlobalObject*& head() { return d()->globalData->head; }
    159161        JSGlobalObject* next() { return d()->next; }
    160 
    161         // Resets the global object to contain only built-in properties, sets
    162         // the global object's prototype to "prototype," then adds the
    163         // default object prototype to the tail of the global object's
    164         // prototype chain.
    165         void reset(JSValue* prototype);
    166162
    167163        // The following accessors return pristine values, even if a script
     
    231227        void copyGlobalsFrom(RegisterFile&);
    232228        void copyGlobalsTo(RegisterFile&);
    233 
    234         // Per-JSGlobalData hash tables, cached on the global object for faster access.
     229       
     230        void resetPrototype(JSValue* prototype);
     231
    235232        JSGlobalData* globalData() { return d()->globalData.get(); }
    236 
    237         void* operator new(size_t, JSGlobalData*);
    238 
    239         void init(JSObject* thisValue);
    240        
    241233        JSGlobalObjectData* d() const { return static_cast<JSGlobalObjectData*>(JSVariableObject::d); }
    242234
     
    257249
    258250    private:
     251        // FIXME: Fold these functions into the constructor.
     252        void init(JSObject* thisValue);
     253        void reset(JSValue* prototype);
     254
    259255        void* operator new(size_t); // can only be allocated with JSGlobalData
    260256    };
  • trunk/JavaScriptCore/kjs/JSImmediate.cpp

    r35245 r36016  
    4343    JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v == jsNull());
    4444    exec->setException(exception);
    45     return new (exec) JSNotAnObject(exception);
     45    return new (exec) JSNotAnObject(exec, exception);
    4646}
    4747
     
    5656    JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v == jsNull());
    5757    exec->setException(exception);
    58     return new (exec) JSNotAnObject(exception);
     58    return new (exec) JSNotAnObject(exec, exception);
    5959}
    6060
  • trunk/JavaScriptCore/kjs/JSNotAnObject.cpp

    r35830 r36016  
    103103}
    104104
    105 void JSNotAnObject::put(ExecState* exec, const Identifier& , JSValue*)
     105void JSNotAnObject::put(ExecState* exec, const Identifier& , JSValue*, PutPropertySlot&)
    106106{
    107107    UNUSED_PARAM(exec);
  • trunk/JavaScriptCore/kjs/JSNotAnObject.h

    r35830 r36016  
    3636    class JSNotAnObjectErrorStub : public JSObject {
    3737    public:
    38         JSNotAnObjectErrorStub(bool isNull)
    39             : m_isNull(isNull)
     38        JSNotAnObjectErrorStub(ExecState* exec, bool isNull)
     39            : JSObject(exec->globalData().nullProtoStructureID)
     40            , m_isNull(isNull)
    4041        {
    4142        }
     
    5152    class JSNotAnObject : public JSObject {
    5253    public:
    53         JSNotAnObject(JSNotAnObjectErrorStub* exception)
    54             : m_exception(exception)
     54        JSNotAnObject(ExecState* exec, JSNotAnObjectErrorStub* exception)
     55            : JSObject(exec->globalData().nullProtoStructureID)
     56            , m_exception(exception)
    5557        {
    5658        }
     
    7274        virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
    7375
    74         virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
     76        virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
    7577        virtual void put(ExecState*, unsigned propertyName, JSValue*);
    7678
  • trunk/JavaScriptCore/kjs/JSObject.cpp

    r35830 r36016  
    5757#endif
    5858
    59     JSValue* prototype = m_prototype;
    60     if (!prototype->marked())
    61         prototype->mark();
    62 
     59    m_structureID->mark();
    6360    m_propertyMap.mark();
    6461
     
    8784
    8885// ECMA 8.6.2.2
    89 void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
     86void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
    9087{
    9188    ASSERT(value);
     
    114111    JSValue* prototype;
    115112    for (JSObject* obj = this; !obj->m_propertyMap.hasGetterSetterProperties(); obj = static_cast<JSObject*>(prototype)) {
    116         prototype = obj->m_prototype;
     113        prototype = obj->prototype();
    117114        if (prototype == jsNull()) {
    118             m_propertyMap.put(propertyName, value, 0, true);
     115            putDirect(propertyName, value, 0, true, slot);
    119116            return;
    120117        }
     
    126123
    127124    for (JSObject* obj = this; ; obj = static_cast<JSObject*>(prototype)) {
    128         if (JSValue* gs = obj->m_propertyMap.get(propertyName, attributes)) {
    129             if (attributes & IsGetterSetter) {
     125        if (JSValue* gs = obj->m_propertyMap.get(propertyName)) {
     126            if (gs->isGetterSetter()) {
    130127                JSObject* setterFunc = static_cast<GetterSetter*>(gs)->setter();       
    131128                if (!setterFunc) {
     
    147144        }
    148145
    149         prototype = obj->m_prototype;
     146        prototype = obj->prototype();
    150147        if (prototype == jsNull())
    151148            break;
    152149    }
    153    
    154     m_propertyMap.put(propertyName, value, 0, true);
     150
     151    putDirect(propertyName, value, 0, true, slot);
     152    return;
    155153}
    156154
    157155void JSObject::put(ExecState* exec, unsigned propertyName, JSValue* value)
    158156{
    159     put(exec, Identifier::from(exec, propertyName), value);
     157    PutPropertySlot slot;
     158    put(exec, Identifier::from(exec, propertyName), value, slot);
    160159}
    161160
     
    190189        if ((attributes & DontDelete))
    191190            return false;
    192         m_propertyMap.remove(propertyName);
    193         if (attributes & IsGetterSetter)
    194             m_propertyMap.setHasGetterSetterProperties(m_propertyMap.containsGettersOrSetters());
     191        removeDirect(propertyName);
    195192        return true;
    196193    }
    197    
     194
    198195    // Look in the static hashtable of properties
    199196    const HashEntry* entry = findPropertyHashEntry(exec, propertyName);
     
    249246{
    250247    // Must call toString first for Date objects.
    251     if ((hint == PreferString) || (hint != PreferNumber && m_prototype == exec->lexicalGlobalObject()->datePrototype())) {
     248    if ((hint == PreferString) || (hint != PreferNumber && prototype() == exec->lexicalGlobalObject()->datePrototype())) {
    252249        if (JSValue* value = callDefaultValueFunction(exec, this, exec->propertyNames().toString))
    253250            return value;
     
    279276void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction)
    280277{
     278    GetterSetter* getterSetter;
     279    PutPropertySlot slot;
     280
    281281    JSValue* object = getDirect(propertyName);
    282     GetterSetter* getterSetter;
    283282    if (object && object->isGetterSetter())
    284283        getterSetter = static_cast<GetterSetter*>(object);
    285284    else {
    286285        getterSetter = new (exec) GetterSetter;
    287         putDirect(propertyName, getterSetter, IsGetterSetter);
     286        putDirect(propertyName, getterSetter, None, true, slot);
     287    }
     288
     289    // putDirect will change our StructureID if we add a new property. For
     290    // getters and setters, though, we also need to change our StructureID
     291    // if we override an existing non-getter or non-setter.
     292    if (slot.type() != PutPropertySlot::NewProperty) {
     293        if (!m_structureID->isDictionary()) {
     294            RefPtr<StructureID> structureID = StructureID::getterSetterTransition(m_structureID);
     295            setStructureID(structureID.release());
     296        }
    288297    }
    289298
     
    294303void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction)
    295304{
     305    GetterSetter* getterSetter;
     306    PutPropertySlot slot;
     307
    296308    JSValue* object = getDirect(propertyName);
    297     GetterSetter* getterSetter;
    298309    if (object && object->isGetterSetter())
    299310        getterSetter = static_cast<GetterSetter*>(object);
    300311    else {
    301312        getterSetter = new (exec) GetterSetter;
    302         putDirect(propertyName, getterSetter, IsGetterSetter);
    303     }
    304    
     313        putDirect(propertyName, getterSetter, None, true, slot);
     314    }
     315
     316    // putDirect will change our StructureID if we add a new property. For
     317    // getters and setters, though, we also need to change our StructureID
     318    // if we override an existing non-getter or non-setter.
     319    if (slot.type() != PutPropertySlot::NewProperty) {
     320        if (!m_structureID->isDictionary()) {
     321            RefPtr<StructureID> structureID = StructureID::getterSetterTransition(m_structureID);
     322            setStructureID(structureID.release());
     323        }
     324    }
     325
    305326    m_propertyMap.setHasGetterSetterProperties(true);
    306327    getterSetter->setSetter(setterFunction);
     
    413434    }
    414435
    415     if (m_prototype->isObject())
    416         static_cast<JSObject*>(m_prototype)->getPropertyNames(exec, propertyNames);
     436    if (prototype()->isObject())
     437        static_cast<JSObject*>(prototype())->getPropertyNames(exec, propertyNames);
    417438}
    418439
     
    456477{
    457478    m_propertyMap.remove(propertyName);
     479    if (!m_structureID->isDictionary()) {
     480        RefPtr<StructureID> structureID = StructureID::dictionaryTransition(m_structureID);
     481        setStructureID(structureID.release());
     482    }
    458483}
    459484
     
    471496}
    472497
     498PassRefPtr<StructureID> JSObject::createInheritorID()
     499{
     500    m_inheritorID = StructureID::create(this);
     501    return m_inheritorID;
     502}
     503
    473504bool JSObject::isObject() const
    474505{
  • trunk/JavaScriptCore/kjs/JSObject.h

    r35830 r36016  
    3232#include "PropertySlot.h"
    3333#include "ScopeChain.h"
     34#include "StructureID.h"
    3435
    3536namespace KJS {
     
    3738    class InternalFunction;
    3839    class PropertyNameArray;
     40    class StructureID;
    3941    struct HashEntry;
    4042    struct HashTable;
     
    4850        DontDelete   = 1 << 3,  // property can't be deleted
    4951        Function     = 1 << 4,  // property is a function - only used by static hashtables
    50         IsGetterSetter = 1 << 5 // property is a getter or setter
    5152    };
    5253
    5354    class JSObject : public JSCell {
    5455    public:
    55         /**
    56          * Creates a new JSObject with the specified prototype
    57          *
    58          * @param prototype The prototype
    59          */
    60         JSObject(JSValue* prototype);
    61 
    62         /**
    63          * Creates a new JSObject with a prototype of jsNull()
    64          * (that is, the ECMAScript "null" value, not a null object pointer).
    65          */
    66         JSObject();
     56        JSObject(PassRefPtr<StructureID>);
     57        JSObject(JSObject* prototype);
     58        virtual ~JSObject();
    6759
    6860        virtual void mark();
     
    7264        JSValue* prototype() const;
    7365        void setPrototype(JSValue* prototype);
     66       
     67        PassRefPtr<StructureID> inheritorID();
    7468
    7569        virtual UString className() const;
     
    8478        virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
    8579
    86         virtual void put(ExecState*, const Identifier& propertyName, JSValue* value);
     80        virtual void put(ExecState*, const Identifier& propertyName, JSValue* value, PutPropertySlot&);
    8781        virtual void put(ExecState*, unsigned propertyName, JSValue* value);
    8882
     
    125119        JSValue** getDirectLocation(const Identifier& propertyName) { return m_propertyMap.getLocation(propertyName); }
    126120        JSValue** getDirectLocation(const Identifier& propertyName, bool& isWriteable) { return m_propertyMap.getLocation(propertyName, isWriteable); }
    127         void putDirect(const Identifier& propertyName, JSValue* value, unsigned attr = 0);
    128         void putDirect(ExecState*, const Identifier& propertyName, int value, unsigned attr = 0);
     121        size_t offsetForLocation(JSValue** location) { return m_propertyMap.offsetForLocation(location); }
    129122        void removeDirect(const Identifier& propertyName);
    130123        bool hasCustomProperties() { return !m_propertyMap.isEmpty(); }
    131 
    132         // convenience to add a function property under the function's own built-in name
    133         void putDirectFunction(ExecState*, InternalFunction*, unsigned attr = 0);
     124        bool hasGetterSetterProperties() { return m_propertyMap.hasGetterSetterProperties(); }
     125
     126        void putDirect(const Identifier& propertyName, JSValue* value, unsigned attr = 0);
     127        void putDirect(const Identifier& propertyName, JSValue* value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
     128        void putDirectFunction(ExecState* exec, InternalFunction* function, unsigned attr = 0);
     129
     130        // Fast access to known property offsets.
     131        JSValue* getDirectOffset(size_t offset) { return m_propertyMap.getOffset(offset); }
     132        void putDirectOffset(size_t offset, JSValue* v) { m_propertyMap.putOffset(offset, v); }
    134133
    135134        void fillGetterPropertySlot(PropertySlot&, JSValue** location);
     
    143142        virtual bool isGlobalObject() const { return false; }
    144143        virtual bool isVariableObject() const { return false; }
    145 
    146144        virtual bool isWatchdogException() const { return false; }
    147        
    148145        virtual bool isNotAnObjectErrorStub() const { return false; }
    149146
    150147    protected:
    151         PropertyMap m_propertyMap;
    152148        bool getOwnPropertySlotForWrite(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable);
    153149
     
    156152
    157153        const HashEntry* findPropertyHashEntry(ExecState*, const Identifier& propertyName) const;
    158         JSValue* m_prototype;
     154        void setStructureID(PassRefPtr<StructureID>);
     155        PassRefPtr<StructureID> createInheritorID();
     156
     157        PropertyMap m_propertyMap;
     158        RefPtr<StructureID> m_inheritorID;
    159159    };
    160160
    161161  JSObject* constructEmptyObject(ExecState*);
    162162
    163 inline JSObject::JSObject(JSValue* prototype)
    164     : m_prototype(prototype)
     163inline JSObject::JSObject(JSObject* prototype)
     164    : JSCell(prototype->inheritorID().releaseRef()) // ~JSObject balances this ref()
     165{
     166    ASSERT(m_structureID);
     167    ASSERT(this->prototype());
     168    ASSERT(this->prototype() == jsNull() || Heap::heap(this) == Heap::heap(this->prototype()));
     169}
     170
     171inline JSObject::JSObject(PassRefPtr<StructureID> structureID)
     172    : JSCell(structureID.releaseRef()) // ~JSObject balances this ref()
     173{
     174    ASSERT(m_structureID);
     175}
     176
     177inline JSObject::~JSObject()
     178{
     179    ASSERT(m_structureID);
     180    m_structureID->deref();
     181}
     182
     183inline JSValue* JSObject::prototype() const
     184{
     185    return m_structureID->prototype();
     186}
     187
     188inline void JSObject::setPrototype(JSValue* prototype)
    165189{
    166190    ASSERT(prototype);
    167     ASSERT(prototype == jsNull() || Heap::heap(this) == Heap::heap(prototype));
    168 }
    169 
    170 inline JSObject::JSObject()
    171     : m_prototype(jsNull())
    172 {
    173 }
    174 
    175 inline JSValue* JSObject::prototype() const
    176 {
    177     return m_prototype;
    178 }
    179 
    180 inline void JSObject::setPrototype(JSValue* prototype)
    181 {
    182     ASSERT(prototype);
    183     m_prototype = prototype;
     191    RefPtr<StructureID> newStructureID = StructureID::changePrototypeTransition(m_structureID, prototype);
     192    setStructureID(newStructureID.release());
     193}
     194
     195inline void JSObject::setStructureID(PassRefPtr<StructureID> structureID)
     196{
     197    m_structureID->deref();
     198    m_structureID = structureID.releaseRef(); // ~JSObject balances this ref()
     199}
     200
     201inline PassRefPtr<StructureID> JSObject::inheritorID()
     202{
     203    if (m_inheritorID)
     204        return m_inheritorID.get();
     205    return createInheritorID();
    184206}
    185207
     
    226248            return true;
    227249
    228         JSValue* prototype = object->m_prototype;
     250        JSValue* prototype = object->prototype();
    229251        if (!prototype->isObject())
    230252            return false;
     
    242264            return true;
    243265
    244         JSValue* prototype = object->m_prototype;
     266        JSValue* prototype = object->prototype();
    245267        if (!prototype->isObject())
    246268            break;
     
    262284            fillGetterPropertySlot(slot, location);
    263285        } else
    264             slot.setValueSlot(location);
     286            slot.setValueSlot(this, location, offsetForLocation(location));
    265287        return true;
    266288    }
     
    268290    // non-standard Netscape extension
    269291    if (propertyName == exec->propertyNames().underscoreProto) {
    270         slot.setValueSlot(&m_prototype);
     292        slot.setValue(prototype());
    271293        slotIsWriteable = false;
    272294        return true;
     
    285307            fillGetterPropertySlot(slot, location);
    286308        else
    287             slot.setValueSlot(location);
     309            slot.setValueSlot(this, location, offsetForLocation(location));
    288310        return true;
    289311    }
     
    291313    // non-standard Netscape extension
    292314    if (propertyName == exec->propertyNames().underscoreProto) {
    293         slot.setValueSlot(&m_prototype);
     315        slot.setValue(prototype());
    294316        return true;
    295317    }
     
    300322inline void JSObject::putDirect(const Identifier& propertyName, JSValue* value, unsigned attr)
    301323{
     324    PutPropertySlot slot;
     325    putDirect(propertyName, value, attr, false, slot);
     326}
     327
     328inline void JSObject::putDirect(const Identifier& propertyName, JSValue* value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot)
     329{
    302330    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
    303 
    304     m_propertyMap.put(propertyName, value, attr);
    305 }
    306 
    307 inline void JSObject::putDirect(ExecState* exec, const Identifier& propertyName, int value, unsigned attr)
    308 {
    309     m_propertyMap.put(propertyName, jsNumber(exec, value), attr);
     331    m_propertyMap.put(propertyName, value, attr, checkReadOnly, this, slot);
     332    if (slot.type() == PutPropertySlot::NewProperty) {
     333        if (!m_structureID->isDictionary()) {
     334            RefPtr<StructureID> structureID = StructureID::addPropertyTransition(m_structureID, propertyName);
     335            setStructureID(structureID.release());
     336        }
     337    }
    310338}
    311339
     
    316344
    317345inline JSValue* JSValue::get(ExecState* exec, const Identifier& propertyName) const
     346{
     347    PropertySlot slot(const_cast<JSValue*>(this));
     348    return get(exec, propertyName, slot);
     349}
     350
     351inline JSValue* JSValue::get(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) const
    318352{
    319353    if (UNLIKELY(JSImmediate::isImmediate(this))) {
    320354        JSObject* prototype = JSImmediate::prototype(this, exec);
    321         PropertySlot slot(const_cast<JSValue*>(this));
    322355        if (!prototype->getPropertySlot(exec, propertyName, slot))
    323356            return jsUndefined();
     
    325358    }
    326359    JSCell* cell = static_cast<JSCell*>(const_cast<JSValue*>(this));
    327     PropertySlot slot(cell);
    328360    while (true) {
    329361        if (cell->getOwnPropertySlot(exec, propertyName, slot))
     
    339371inline JSValue* JSValue::get(ExecState* exec, unsigned propertyName) const
    340372{
     373    PropertySlot slot(const_cast<JSValue*>(this));
     374    return get(exec, propertyName, slot);
     375}
     376
     377inline JSValue* JSValue::get(ExecState* exec, unsigned propertyName, PropertySlot& slot) const
     378{
    341379    if (UNLIKELY(JSImmediate::isImmediate(this))) {
    342380        JSObject* prototype = JSImmediate::prototype(this, exec);
    343         PropertySlot slot(const_cast<JSValue*>(this));
    344381        if (!prototype->getPropertySlot(exec, propertyName, slot))
    345382            return jsUndefined();
     
    347384    }
    348385    JSCell* cell = const_cast<JSCell*>(asCell());
    349     PropertySlot slot(cell);
    350386    while (true) {
    351387        if (cell->getOwnPropertySlot(exec, propertyName, slot))
     
    359395}
    360396
    361 inline void JSValue::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
     397inline void JSValue::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
     398{
     399    if (UNLIKELY(JSImmediate::isImmediate(this))) {
     400        JSImmediate::toObject(this, exec)->put(exec, propertyName, value, slot);
     401        return;
     402    }
     403    asCell()->put(exec, propertyName, value, slot);
     404}
     405
     406inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue* value)
    362407{
    363408    if (UNLIKELY(JSImmediate::isImmediate(this))) {
     
    368413}
    369414
    370 inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue* value)
    371 {
    372     if (UNLIKELY(JSImmediate::isImmediate(this))) {
    373         JSImmediate::toObject(this, exec)->put(exec, propertyName, value);
    374         return;
    375     }
    376     asCell()->put(exec, propertyName, value);
    377 }
    378 
    379415} // namespace KJS
    380416
  • trunk/JavaScriptCore/kjs/JSStaticScopeObject.cpp

    r35807 r36016  
    3737}
    3838
    39 void JSStaticScopeObject::put(ExecState*, const Identifier& propertyName, JSValue* value)
     39void JSStaticScopeObject::put(ExecState*, const Identifier& propertyName, JSValue* value, PutPropertySlot&)
    4040{
    4141    if (symbolTablePut(propertyName, value))
  • trunk/JavaScriptCore/kjs/JSStaticScopeObject.h

    r35533 r36016  
    4545       
    4646    public:
    47         JSStaticScopeObject(const Identifier& ident, JSValue* value, unsigned attributes)
    48             : JSVariableObject(new JSStaticScopeObjectData())
     47        JSStaticScopeObject(ExecState* exec, const Identifier& ident, JSValue* value, unsigned attributes)
     48            : JSVariableObject(exec->globalData().nullProtoStructureID, new JSStaticScopeObjectData())
    4949        {
    5050            JSStaticScopeObjectData* data = static_cast<JSStaticScopeObjectData*>(d);
     
    5757        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    5858        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable);
    59         virtual void put(ExecState*, const Identifier&, JSValue*);
     59        virtual void put(ExecState*, const Identifier&, JSValue*, PutPropertySlot&);
    6060        void putWithAttributes(ExecState*, const Identifier&, JSValue*, unsigned attributes);
    6161    };
  • trunk/JavaScriptCore/kjs/JSValue.h

    r35830 r36016  
    3838    class JSString;
    3939    class PropertySlot;
     40    class PutPropertySlot;
     41    class StructureID;
    4042    struct ClassInfo;
    4143    struct Instruction;
     
    6870        bool isObject() const;
    6971        bool isObject(const ClassInfo*) const; // FIXME: Merge with inherits.
    70 
     72       
    7173        // Extracting the value.
    7274        bool getBoolean(bool&) const;
     
    126128        // Object operations, with the toObject operation included.
    127129        JSValue* get(ExecState*, const Identifier& propertyName) const;
     130        JSValue* get(ExecState*, const Identifier& propertyName, PropertySlot&) const;
    128131        JSValue* get(ExecState*, unsigned propertyName) const;
    129         void put(ExecState*, const Identifier& propertyName, JSValue*);
     132        JSValue* get(ExecState*, unsigned propertyName, PropertySlot&) const;
     133        void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
    130134        void put(ExecState*, unsigned propertyName, JSValue*);
    131135        bool deleteProperty(ExecState*, const Identifier& propertyName);
  • trunk/JavaScriptCore/kjs/JSVariableObject.h

    r35657 r36016  
    8181        };
    8282
    83         JSVariableObject(JSVariableObjectData* data)
    84             : d(data) // Subclass owns this pointer.
     83        JSVariableObject(PassRefPtr<StructureID> structureID, JSVariableObjectData* data)
     84            : JSObject(structureID)
     85            , d(data) // Subclass owns this pointer.
    8586        {
    8687        }
    8788
    88         JSVariableObject(JSValue* prototype, JSVariableObjectData* data)
     89        JSVariableObject(JSObject* prototype, JSVariableObjectData* data)
    8990            : JSObject(prototype)
    9091            , d(data) // Subclass owns this pointer.
  • trunk/JavaScriptCore/kjs/JSWrapperObject.h

    r35027 r36016  
    3535    class JSWrapperObject : public JSObject {
    3636    public:
    37         JSWrapperObject(JSValue* proto);
     37        JSWrapperObject(JSObject* prototype);
    3838       
    3939        JSValue* internalValue() const;
     
    4646    };
    4747   
    48     inline JSWrapperObject::JSWrapperObject(JSValue* proto)
    49         : JSObject(proto)
     48    inline JSWrapperObject::JSWrapperObject(JSObject* prototype)
     49        : JSObject(prototype)
    5050        , m_internalValue(0)
    5151    {
  • trunk/JavaScriptCore/kjs/ObjectPrototype.cpp

    r36006 r36016  
    4242
    4343ObjectPrototype::ObjectPrototype(ExecState* exec, FunctionPrototype* functionPrototype)
    44     : JSObject() // [[Prototype]] is null
     44    : JSObject(exec->globalData().nullProtoStructureID)
    4545{
    4646    putDirectFunction(exec, new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, objectProtoFuncToString), DontEnum);
  • trunk/JavaScriptCore/kjs/PropertyMap.cpp

    r35027 r36016  
    2222#include "PropertyMap.h"
    2323
    24 #include "JSObject.h"
    2524#include "protect.h"
    2625#include "PropertyNameArray.h"
     
    4443#define USE_SINGLE_ENTRY 1
    4544
    46 // 2/28/2006 ggaren: command-line JS iBench says that USE_SINGLE_ENTRY is a
    47 // 3.2% performance boost.
    48 
    4945namespace KJS {
    5046
     
    8177#endif
    8278
    83 struct PropertyMapEntry {
    84     UString::Rep* key;
    85     JSValue* value;
    86     unsigned attributes;
    87     unsigned index;
    88 
    89     PropertyMapEntry(UString::Rep* k, JSValue* v, int a)
    90         : key(k)
    91         , value(v)
    92         , attributes(a)
    93         , index(0)
    94     {
    95     }
    96 };
    97 
    98 // lastIndexUsed is an ever-increasing index used to identify the order items
    99 // were inserted into the property map. It's required that getEnumerablePropertyNames
    100 // return the properties in the order they were added for compatibility with other
    101 // browsers' JavaScript implementations.
    102 struct PropertyMapHashTable {
    103     unsigned sizeMask;
    104     unsigned size;
    105     unsigned keyCount;
    106     unsigned deletedSentinelCount;
    107     unsigned lastIndexUsed;
    108     unsigned entryIndicies[1];
    109 
    110     PropertyMapEntry* entries()
    111     {
    112         // The entries vector comes after the indices vector.
    113         // The 0th item in the entries vector is not really used; it has to
    114         // have a 0 in its key to allow the hash table lookup to handle deleted
    115         // sentinels without any special-case code, but the other fields are unused.
    116         return reinterpret_cast<PropertyMapEntry*>(&entryIndicies[size]);
    117     }
    118 
    119     static size_t allocationSize(unsigned size)
    120     {
    121         // We never let a hash table get more than half full,
    122         // So the number of indices we need is the size of the hash table.
    123         // But the number of entries is half that (plus one for the deleted sentinel).
    124         return sizeof(PropertyMapHashTable)
    125             + (size - 1) * sizeof(unsigned)
    126             + (1 + size / 2) * sizeof(PropertyMapEntry);
    127     }
    128 };
    129 
    13079static const unsigned emptyEntryIndex = 0;
    13180static const unsigned deletedSentinelIndex = 1;
     
    157106}
    158107
    159 void PropertyMap::clear()
    160 {
    161     if (!m_usingTable) {
    162 #if USE_SINGLE_ENTRY
    163         if (m_singleEntryKey) {
    164             m_singleEntryKey->deref();
    165             m_singleEntryKey = 0;
    166         }
    167 #endif
    168         return;
    169     }
    170 
    171     unsigned entryCount = m_u.table->keyCount + m_u.table->deletedSentinelCount;
    172     for (unsigned i = 1; i <= entryCount; i++) {
    173         if (UString::Rep* key = m_u.table->entries()[i].key)
    174             key->deref();
    175     }
    176     for (unsigned i = 0; i < m_u.table->size; i++)
    177         m_u.table->entryIndicies[i] = emptyEntryIndex;
    178     m_u.table->keyCount = 0;
    179     m_u.table->deletedSentinelCount = 0;
    180 }
    181 
    182108JSValue* PropertyMap::get(const Identifier& propertyName, unsigned& attributes) const
    183109{
     
    388314}
    389315
    390 void PropertyMap::put(const Identifier& propertyName, JSValue* value, unsigned attributes, bool checkReadOnly)
     316void PropertyMap::put(const Identifier& propertyName, JSValue* value, unsigned attributes, bool checkReadOnly, JSObject* slotBase, PutPropertySlot& slot)
    391317{
    392318    ASSERT(!propertyName.isNull());
     
    405331            m_singleEntryAttributes = static_cast<short>(attributes);
    406332            checkConsistency();
     333            slot.setNewProperty(slotBase, KJS_INVALID_OFFSET);
    407334            return;
    408335        }
     
    414341#endif
    415342
    416     if (!m_usingTable || (m_u.table->keyCount + m_u.table->deletedSentinelCount) * 2 >= m_u.table->size)
     343    if (!m_usingTable)
    417344        expand();
    418345
     
    439366            m_u.table->entries()[entryIndex - 1].value = value;
    440367            // Attributes are intentionally not updated.
     368            slot.setExistingProperty(slotBase, offsetForTableLocation(&m_u.table->entries()[entryIndex - 1].value));
    441369            return;
    442370        } else if (entryIndex == deletedSentinelIndex) {
     
    486414    ++m_u.table->keyCount;
    487415
     416    if ((m_u.table->keyCount + m_u.table->deletedSentinelCount) * 2 >= m_u.table->size)
     417        expand();
     418
    488419    checkConsistency();
     420    slot.setNewProperty(slotBase, offsetForTableLocation(&m_u.table->entries()[entryIndex - 1].value));
    489421}
    490422
     
    696628        return +1;
    697629    return 0;
    698 }
    699 
    700 bool PropertyMap::containsGettersOrSetters() const
    701 {
    702     if (!m_usingTable) {
    703 #if USE_SINGLE_ENTRY
    704         return !!(m_singleEntryAttributes & IsGetterSetter);
    705 #else
    706         return false;
    707 #endif
    708     }
    709 
    710     unsigned entryCount = m_u.table->keyCount + m_u.table->deletedSentinelCount;
    711     for (unsigned i = 1; i <= entryCount; i++) {
    712         if (m_u.table->entries()[i].attributes & IsGetterSetter)
    713             return true;
    714     }
    715 
    716     return false;
    717630}
    718631
  • trunk/JavaScriptCore/kjs/PropertyMap.h

    r35068 r36016  
    2222#define PropertyMap_h
    2323
     24#include "PropertySlot.h"
    2425#include "identifier.h"
    2526
     
    3233    struct PropertyMapHashTable;
    3334
     35    struct PropertyMapEntry {
     36        UString::Rep* key;
     37        JSValue* value;
     38        unsigned attributes;
     39        unsigned index;
     40
     41        PropertyMapEntry(UString::Rep* k, JSValue* v, int a)
     42            : key(k)
     43            , value(v)
     44            , attributes(a)
     45            , index(0)
     46        {
     47        }
     48    };
     49
     50    // lastIndexUsed is an ever-increasing index used to identify the order items
     51    // were inserted into the property map. It's required that getEnumerablePropertyNames
     52    // return the properties in the order they were added for compatibility with other
     53    // browsers' JavaScript implementations.
     54    struct PropertyMapHashTable {
     55        unsigned sizeMask;
     56        unsigned size;
     57        unsigned keyCount;
     58        unsigned deletedSentinelCount;
     59        unsigned lastIndexUsed;
     60        unsigned entryIndicies[1];
     61
     62        PropertyMapEntry* entries()
     63        {
     64            // The entries vector comes after the indices vector.
     65            // The 0th item in the entries vector is not really used; it has to
     66            // have a 0 in its key to allow the hash table lookup to handle deleted
     67            // sentinels without any special-case code, but the other fields are unused.
     68            return reinterpret_cast<PropertyMapEntry*>(&entryIndicies[size]);
     69        }
     70
     71        static size_t allocationSize(unsigned size)
     72        {
     73            // We never let a hash table get more than half full,
     74            // So the number of indices we need is the size of the hash table.
     75            // But the number of entries is half that (plus one for the deleted sentinel).
     76            return sizeof(PropertyMapHashTable)
     77                + (size - 1) * sizeof(unsigned)
     78                + (1 + size / 2) * sizeof(PropertyMapEntry);
     79        }
     80    };
     81
    3482    class PropertyMap : Noncopyable {
    3583    public:
     
    3785        ~PropertyMap();
    3886
    39         void clear();
    4087        bool isEmpty() { return !m_usingTable & !m_singleEntryKey; }
    4188
    42         void put(const Identifier& propertyName, JSValue*, unsigned attributes, bool checkReadOnly = false);
     89        void put(const Identifier& propertyName, JSValue*, unsigned attributes, bool checkReadOnly, JSObject* slotBase, PutPropertySlot&);
    4390        void remove(const Identifier& propertyName);
    4491        JSValue* get(const Identifier& propertyName) const;
     
    4693        JSValue** getLocation(const Identifier& propertyName);
    4794        JSValue** getLocation(const Identifier& propertyName, bool& isWriteable);
     95       
     96        JSValue* getOffset(size_t offset)
     97        {
     98            ASSERT(m_usingTable);
     99            return reinterpret_cast<JSValue**>(m_u.table->entryIndicies)[offset];
     100        }
     101        void putOffset(size_t offset, JSValue* v)
     102        {
     103            ASSERT(m_usingTable);
     104            reinterpret_cast<JSValue**>(m_u.table->entryIndicies)[offset] = v;
     105        }
     106
     107        size_t offsetForLocation(JSValue** location) { return m_usingTable ? offsetForTableLocation(location) : KJS_INVALID_OFFSET; }
    48108
    49109        void mark() const;
     
    52112        bool hasGetterSetterProperties() const { return m_getterSetterFlag; }
    53113        void setHasGetterSetterProperties(bool f) { m_getterSetterFlag = f; }
    54 
    55         bool containsGettersOrSetters() const;
    56114
    57115    private:
     
    67125        void insert(const Entry&);
    68126       
     127        size_t offsetForTableLocation(JSValue** location)
     128        {
     129            ASSERT(m_usingTable);
     130            return location - reinterpret_cast<JSValue**>(m_u.table->entryIndicies);
     131        }
     132
    69133        void checkConsistency();
    70134       
  • trunk/JavaScriptCore/kjs/PropertySlot.h

    r35806 r36016  
    3535#define KJS_VALUE_SLOT_MARKER 0
    3636#define KJS_REGISTER_SLOT_MARKER reinterpret_cast<GetValueFunc>(1)
     37#define KJS_INVALID_OFFSET static_cast<size_t>(-1)
    3738
    3839    class PropertySlot {
    3940    public:
    4041        PropertySlot()
     42            : m_offset(KJS_INVALID_OFFSET)
    4143        {
    4244            clearBase();
     
    4648        explicit PropertySlot(JSValue* base)
    4749            : m_slotBase(base)
     50            , m_offset(KJS_INVALID_OFFSET)
    4851        {
    4952            clearValue();
     
    6871                return (*m_data.registerSlot).jsValue(exec);
    6972            return m_getValue(exec, Identifier::from(exec, propertyName), *this);
     73        }
     74
     75        bool isCacheable() const { return m_offset != KJS_INVALID_OFFSET; }
     76        size_t cachedOffset() const
     77        {
     78            ASSERT(isCacheable());
     79            return m_offset;
    7080        }
    7181
     
    8898        }
    8999       
     100        void setValueSlot(JSValue* slotBase, JSValue** valueSlot)
     101        {
     102            ASSERT(valueSlot);
     103            m_getValue = KJS_VALUE_SLOT_MARKER;
     104            m_slotBase = slotBase;
     105            m_data.valueSlot = valueSlot;
     106        }
     107       
     108        void setValueSlot(JSValue* slotBase, JSValue** valueSlot, size_t offset)
     109        {
     110            ASSERT(valueSlot);
     111            m_getValue = KJS_VALUE_SLOT_MARKER;
     112            m_slotBase = slotBase;
     113            m_data.valueSlot = valueSlot;
     114            m_offset = offset;
     115        }
     116       
    90117        void setValue(JSValue* value)
    91118        {
     
    180207        GetValueFunc m_getValue;
    181208       
    182         JSValue* m_value;
    183 
    184209        JSValue* m_slotBase;
    185210        union {
     
    190215            unsigned index;
    191216        } m_data;
     217
     218        JSValue* m_value;
     219
     220        size_t m_offset;
    192221    };
     222   
     223    class PutPropertySlot {
     224    public:
     225        enum SlotType {
     226            Invalid,
     227            ExistingProperty,
     228            NewProperty,
     229        };
     230
     231        PutPropertySlot()
     232            : m_type(Invalid)
     233            , m_base(0)
     234        {
     235        }
     236
     237        void setExistingProperty(JSObject* base, size_t offset)
     238        {
     239            m_type = ExistingProperty;
     240            m_base = base;
     241            m_offset = offset;
     242        }
     243
     244        void setNewProperty(JSObject* base, size_t offset)
     245        {
     246            m_type = NewProperty;
     247            m_base = base;
     248            m_offset = offset;
     249        }
     250
     251        SlotType type() const { return m_type; }
     252        JSObject* slotBase() const { return m_base; }
     253
     254        bool isCacheable() const { return m_type != Invalid; }
     255        size_t cachedOffset() const {
     256            ASSERT(isCacheable());
     257            return m_offset;
     258        }
     259
     260    private:
     261        SlotType m_type;
     262        JSObject* m_base;
     263        size_t m_offset;
     264    };
    193265
    194266} // namespace KJS
  • trunk/JavaScriptCore/kjs/RegExpConstructor.cpp

    r36006 r36016  
    123123    virtual bool getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { if (lazyCreationData()) fillArrayInstance(exec); return JSArray::getOwnPropertySlot(exec, propertyName, slot); }
    124124    virtual bool getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) { if (lazyCreationData()) fillArrayInstance(exec); return JSArray::getOwnPropertySlot(exec, propertyName, slot); }
    125     virtual void put(ExecState* exec, const Identifier& propertyName, JSValue* v) { if (lazyCreationData()) fillArrayInstance(exec); JSArray::put(exec, propertyName, v); }
     125    virtual void put(ExecState* exec, const Identifier& propertyName, JSValue* v, PutPropertySlot& slot) { if (lazyCreationData()) fillArrayInstance(exec); JSArray::put(exec, propertyName, v, slot); }
    126126    virtual void put(ExecState* exec, unsigned propertyName, JSValue* v) { if (lazyCreationData()) fillArrayInstance(exec); JSArray::put(exec, propertyName, v); }
    127127    virtual bool deleteProperty(ExecState* exec, const Identifier& propertyName) { if (lazyCreationData()) fillArrayInstance(exec); return JSArray::deleteProperty(exec, propertyName); }
     
    164164            JSArray::put(exec, i, jsSubstring(exec, d->lastInput, start, d->lastOvector[2 * i + 1] - start));
    165165    }
    166     JSArray::put(exec, exec->propertyNames().index, jsNumber(exec, d->lastOvector[0]));
    167     JSArray::put(exec, exec->propertyNames().input, jsString(exec, d->input));
     166
     167    PutPropertySlot slot;
     168    JSArray::put(exec, exec->propertyNames().index, jsNumber(exec, d->lastOvector[0]), slot);
     169    JSArray::put(exec, exec->propertyNames().input, jsString(exec, d->input), slot);
    168170
    169171    delete d;
     
    257259}
    258260
    259 void RegExpConstructor::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
    260 {
    261     lookupPut<RegExpConstructor, InternalFunction>(exec, propertyName, value, ExecState::regExpConstructorTable(exec), this);
     261void RegExpConstructor::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
     262{
     263    lookupPut<RegExpConstructor, InternalFunction>(exec, propertyName, value, ExecState::regExpConstructorTable(exec), this, slot);
    262264}
    263265
  • trunk/JavaScriptCore/kjs/RegExpConstructor.h

    r35027 r36016  
    5454        RegExpConstructor(ExecState*, FunctionPrototype*, RegExpPrototype*);
    5555
    56         virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
     56        virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
    5757        void putValueProperty(ExecState*, int token, JSValue*);
    5858        virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
  • trunk/JavaScriptCore/kjs/RegExpObject.cpp

    r35807 r36016  
    7979}
    8080
    81 void RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
     81void RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
    8282{
    83     lookupPut<RegExpObject, JSObject>(exec, propertyName, value, ExecState::regExpTable(exec), this);
     83    lookupPut<RegExpObject, JSObject>(exec, propertyName, value, ExecState::regExpTable(exec), this, slot);
    8484}
    8585
  • trunk/JavaScriptCore/kjs/RegExpObject.h

    r35807 r36016  
    4444        bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
    4545        JSValue* getValueProperty(ExecState*, int token) const;
    46         void put(ExecState*, const Identifier& propertyName, JSValue*);
     46        void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
    4747        void putValueProperty(ExecState*, int token, JSValue*);
    4848
  • trunk/JavaScriptCore/kjs/Shell.cpp

    r35911 r36016  
    163163class GlobalObject : public JSGlobalObject {
    164164public:
    165     GlobalObject(Vector<UString>& arguments);
     165    GlobalObject(JSGlobalData*, const Vector<UString>& arguments);
    166166    virtual UString className() const { return "global"; }
    167167};
     
    169169ASSERT_CLASS_FITS_IN_CELL(GlobalObject);
    170170
    171 GlobalObject::GlobalObject(Vector<UString>& arguments)
     171GlobalObject::GlobalObject(JSGlobalData* globalData, const Vector<UString>& arguments)
     172    : JSGlobalObject(globalData)
    172173{
    173174    putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), functionPrototype(), 1, Identifier(globalExec(), "debug"), functionDebug));
     
    332333        CodeGenerator::setDumpsGeneratedCode(true);
    333334
     335#if ENABLE(SAMPLING_TOOL)
     336    Machine* machine = globalObject->globalData()->machine;
     337    machine->m_sampler = new SamplingTool();
     338    machine->m_sampler->start();
     339#endif
     340
    334341    bool success = true;
    335342    for (size_t i = 0; i < fileNames.size(); i++) {
     
    342349            prettyPrintScript(globalObject->globalExec(), fileName, script);
    343350        else {
    344 #if ENABLE(SAMPLING_TOOL)
    345             Machine* machine = globalObject->globalData()->machine;
    346             machine->m_sampler = new SamplingTool();
    347             machine->m_sampler->start();
    348 #endif
    349 
    350351            Completion completion = Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), fileName, 1, script.data());
    351352            success = success && completion.complType() != Throw;
     
    358359
    359360            globalObject->globalExec()->clearException();
     361        }
     362    }
    360363
    361364#if ENABLE(SAMPLING_TOOL)
     
    364367            delete machine->m_sampler;
    365368#endif
    366         }
    367     }
    368369    return success;
    369370}
     
    473474    parseArguments(argc, argv, options);
    474475
    475     GlobalObject* globalObject = new (globalData) GlobalObject(options.arguments);
     476    GlobalObject* globalObject = new (globalData) GlobalObject(globalData, options.arguments);
    476477    bool success = runWithScripts(globalObject, options.fileNames, options.prettyPrint, options.dump);
    477478    if (options.interactive && success)
  • trunk/JavaScriptCore/kjs/StringObject.cpp

    r36006 r36016  
    6262}
    6363
    64 void StringObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
     64void StringObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
    6565{
    6666    if (propertyName == exec->propertyNames().length)
    6767        return;
    68     JSObject::put(exec, propertyName, value);
     68    JSObject::put(exec, propertyName, value, slot);
    6969}
    7070
  • trunk/JavaScriptCore/kjs/StringObject.h

    r35027 r36016  
    3737        virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
    3838
    39         virtual void put(ExecState* exec, const Identifier& propertyName, JSValue*);
     39        virtual void put(ExecState* exec, const Identifier& propertyName, JSValue*, PutPropertySlot&);
    4040        virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
    4141        virtual void getPropertyNames(ExecState*, PropertyNameArray&);
  • trunk/JavaScriptCore/kjs/SymbolTable.h

    r34610 r36016  
    3535
    3636namespace KJS {
    37 
    38     struct IdentifierRepHash : PtrHash<RefPtr<UString::Rep> > {
    39         static unsigned hash(const RefPtr<UString::Rep>& key) { return key->computedHash(); }
    40         static unsigned hash(UString::Rep* key) { return key->computedHash(); }
    41     };
    4237
    4338    static ALWAYS_INLINE int missingSymbolMarker() { return std::numeric_limits<int>::max(); }
     
    124119    };
    125120
    126     typedef HashMap<RefPtr<UString::Rep>, SymbolTableEntry, IdentifierRepHash, HashTraits<RefPtr<UString::Rep> >, SymbolTableIndexHashTraits> SymbolTable;
     121    typedef HashMap<RefPtr<UString::Rep>, SymbolTableEntry, WTF::IdentifierRepHash, HashTraits<RefPtr<UString::Rep> >, SymbolTableIndexHashTraits> SymbolTable;
    127122
    128123} // namespace KJS
  • trunk/JavaScriptCore/kjs/lookup.cpp

    r35195 r36016  
    7575    PrototypeFunction* function = new (exec) PrototypeFunction(exec, entry->length, propertyName, entry->functionValue);
    7676    thisObj->putDirect(propertyName, function, entry->attributes);
    77     slot.setValueSlot(thisObj->getDirectLocation(propertyName));
     77   
     78    JSValue** location = thisObj->getDirectLocation(propertyName);
     79    slot.setValueSlot(thisObj, location, thisObj->offsetForLocation(location));
    7880}
    7981
  • trunk/JavaScriptCore/kjs/lookup.h

    r35900 r36016  
    218218     */
    219219    template <class ThisImp, class ParentImp>
    220     inline void lookupPut(ExecState* exec, const Identifier& propertyName, JSValue* value, const HashTable* table, ThisImp* thisObj)
     220    inline void lookupPut(ExecState* exec, const Identifier& propertyName, JSValue* value, const HashTable* table, ThisImp* thisObj, PutPropertySlot& slot)
    221221    {
    222222        if (!lookupPut<ThisImp>(exec, propertyName, value, table, thisObj))
    223             thisObj->ParentImp::put(exec, propertyName, value); // not found: forward to parent
     223            thisObj->ParentImp::put(exec, propertyName, value, slot); // not found: forward to parent
    224224    }
    225225
  • trunk/JavaScriptCore/kjs/nodes.cpp

    r35986 r36016  
    18431843
    18441844    if (!m_ident.isNull()) {
    1845         JSStaticScopeObject* functionScopeObject = new (exec) JSStaticScopeObject(m_ident, func, ReadOnly | DontDelete);
     1845        JSStaticScopeObject* functionScopeObject = new (exec) JSStaticScopeObject(exec, m_ident, func, ReadOnly | DontDelete);
    18461846        func->scope().push(functionScopeObject);
    18471847    }
  • trunk/JavaScriptCore/kjs/ustring.h

    r36007 r36016  
    367367    template<> struct DefaultHash<RefPtr<KJS::UString::Rep> > {
    368368        typedef StrHash<RefPtr<KJS::UString::Rep> > Hash;
    369     };
     369
     370    };
     371
     372    struct IdentifierRepHash : PtrHash<RefPtr<KJS::UString::Rep> > {
     373        static unsigned hash(const RefPtr<KJS::UString::Rep>& key) { return key->computedHash(); }
     374        static unsigned hash(KJS::UString::Rep* key) { return key->computedHash(); }
     375    };
     376
    370377} // namespace WTF
    371378
Note: See TracChangeset for help on using the changeset viewer.