Changeset 28884 in webkit


Ignore:
Timestamp:
Dec 20, 2007 1:32:06 AM (16 years ago)
Author:
ggaren@apple.com
Message:

JavaScriptCore:

Reviewed by Oliver Hunt.


Optimized global access to global variables, using a symbol table.


SunSpider reports a 1.5% overall speedup, a 6.2% speedup on 3d-morph,
and a whopping 33.1% speedup on bitops-bitwise-and.

  • API/JSCallbackObjectFunctions.h: Replaced calls to JSObject:: with calls to Base::, since JSObject is not always our base class. This was always a bug, but the bug is even more apparent after some of my changes.

(KJS::::staticFunctionGetter): Replaced use of getDirect with call to
getOwnPropertySlot. Global declarations are no longer stored in the
property map, so a call to getDirect is insufficient for finding
override properties.

  • API/testapi.c:
  • API/testapi.js: Added test for the getDirect change mentioned above.
  • kjs/ExecState.cpp:
  • kjs/ExecState.h: Dialed back the optimization to store a direct pointer to the localStorage buffer. One ExecState can grow the global object's localStorage without another ExecState's knowledge, so ExecState can't store a direct pointer to the localStorage buffer unless/until we invent a way to update all the relevant ExecStates.
  • kjs/JSGlobalObject.cpp: Inserted the symbol table into get and put operations. (KJS::JSGlobalObject::reset): Reset the symbol table and local storage, too. Also, clear the property map here, removing the need for a separate call.
  • kjs/JSVariableObject.cpp:
  • kjs/JSVariableObject.h: Added support for saving localStorage and the symbol table to the back/forward cache, and restoring them.
  • kjs/function.cpp: (KJS::GlobalFuncImp::callAsFunction): Renamed progNode to evalNode because it's an EvalNode, not a ProgramNode.
  • kjs/lookup.h: (KJS::cacheGlobalObject): Replaced put with faster putDirect, since that's how the rest of lookup.h works. putDirect is safe here because cacheGlobalObject is only used for objects whose names are not valid identifiers.
  • kjs/nodes.cpp: The good stuff!

(KJS::EvalNode::processDeclarations): Replaced hasProperty with
the new hasOwnProperty, which is slightly faster.

  • kjs/object.h: Nixed clearProperties because clear() does this job now.
  • kjs/property_map.cpp:
  • kjs/property_map.h: More back/forward cache support.


  • wtf/Vector.h: (WTF::::grow): Added fast non-branching grow function. I used it in an earlier version of this patch, even though it's not used anymore.

JavaScriptGlue:

Build fix.

  • ForwardingHeaders/wtf/VectorTraits.h: Added.

WebCore:

Reviewed by Oliver Hunt.

Build support:

  • ForwardingHeaders/kjs/SymbolTable.h: Added.
  • ForwardingHeaders/wtf/VectorTraits.h: Added.
  • bindings/js/JSDOMWindowCustom.cpp: (WebCore::JSDOMWindow::customGetOwnPropertySlot): Replaced use of getDirectLocation with getOwnPropertySlot. getDirectLocation is no longer valid, since global declarations are not stored in the property map.

(WebCore::JSDOMWindow::customPut): Replaced use of JSObject::put with
JSGlobalObject::put. JSObject::put is no longer valid, since global
declarations are not stored in the property map.

  • bindings/js/kjs_window.cpp: Replaced JSObject:: calls with Base:: calls, since JSObject is not our base class. This was always a bug, but the bug is even more apparent after some of my changes.

(KJS::Window::clear): Removed call to clearProperties because
JSGlobalObject::reset takes care of that now.

  • history/CachedPage.cpp:
  • history/CachedPage.h: Added support for saving a symbol table and localStorage to the page cache, and restoring it.

WebKit/mac:

Reviewed by Oliver Hunt.

Build fix.

  • ForwardingHeaders/kjs/SymbolTable.h: Added.
  • ForwardingHeaders/wtf/VectorTraits.h: Added.

LayoutTests:

Reviewed by Oliver Hunt.


Added some tests to verify some of the changes I made while optimizing
global access to global variables.

  • fast/dom/Window/resources/window-property-clearing-iframe0.html: Added.
  • fast/dom/Window/resources/window-property-clearing-iframe1.html: Added.
  • fast/dom/Window/window-property-clearing-expected.txt: Added.
  • fast/dom/Window/window-property-clearing.html: Added.
  • fast/dom/getter-on-window-object2-expected.txt: Added.
  • fast/dom/getter-on-window-object2.html: Added.

Checked in failing results for these const tests. The symbol table
optimization broke const. (We didn't know this before because our only
tests used global variables.)

  • fast/js/const-expected.txt:
  • fast/js/kde/const-expected.txt:
  • fast/js/resources/for-in-avoid-duplicates.js: Fixed a typo I noticed. Not related to this patch.
  • fast/dom/Window/window-property-shadowing.html: Changed this test to use "this" instead of "window". The fact that "window" worked before, despite an overriding / shadowing var declaration, was a bug.
Location:
trunk
Files:
11 added
35 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/API/JSCallbackObjectFunctions.h

    r28468 r28884  
    9797        return m_class->className;
    9898   
    99     return JSObject::className();
     99    return Base::className();
    100100}
    101101
     
    141141    }
    142142   
    143     return JSObject::getOwnPropertySlot(exec, propertyName, slot);
     143    return Base::getOwnPropertySlot(exec, propertyName, slot);
    144144}
    145145
     
    188188    }
    189189   
    190     return JSObject::put(exec, propertyName, value, attr);
     190    return Base::put(exec, propertyName, value, attr);
    191191}
    192192
     
    228228    }
    229229   
    230     return JSObject::deleteProperty(exec, propertyName);
     230    return Base::deleteProperty(exec, propertyName);
    231231}
    232232
     
    362362    }
    363363   
    364     JSObject::getPropertyNames(exec, propertyNames);
     364    Base::getPropertyNames(exec, propertyNames);
    365365}
    366366
     
    378378        }
    379379           
    380     return JSObject::toNumber(exec);
     380    return Base::toNumber(exec);
    381381}
    382382
     
    394394        }
    395395           
    396     return JSObject::toString(exec);
     396    return Base::toString(exec);
    397397}
    398398
     
    454454    JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase());
    455455   
    456     if (JSValue* cachedOrOverrideValue = thisObj->getDirect(propertyName))
    457         return cachedOrOverrideValue;
     456    // Check for cached or override property.
     457    PropertySlot slot2;
     458    if (thisObj->Base::getOwnPropertySlot(exec, propertyName, slot2))
     459        return slot2.getValue(exec, thisObj, propertyName);
    458460   
    459461    for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parentClass) {
  • trunk/JavaScriptCore/API/testapi.c

    r28636 r28884  
    508508}
    509509
     510static JSValueRef globalObject_call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
     511{
     512    UNUSED_PARAM(function);
     513    UNUSED_PARAM(thisObject);
     514    UNUSED_PARAM(argumentCount);
     515    UNUSED_PARAM(arguments);
     516    UNUSED_PARAM(exception);
     517
     518    return JSValueMakeNumber(ctx, 3);
     519}
    510520
    511521static JSStaticValue globalObject_staticValues[] = {
    512522    { "globalStaticValue", globalObject_get, globalObject_set, kJSPropertyAttributeNone },
    513523    { 0, 0, 0, 0 }
     524};
     525
     526static JSStaticFunction globalObject_staticFunctions[] = {
     527    { "globalStaticFunction", globalObject_call, kJSPropertyAttributeNone },
     528    { 0, 0, 0 }
    514529};
    515530
     
    541556    globalObjectClassDefinition.initialize = globalObject_initialize;
    542557    globalObjectClassDefinition.staticValues = globalObject_staticValues;
     558    globalObjectClassDefinition.staticFunctions = globalObject_staticFunctions;
     559    globalObjectClassDefinition.attributes = kJSClassAttributeNoAutomaticPrototype;
    543560    JSClassRef globalObjectClass = JSClassCreate(&globalObjectClassDefinition);
    544561    context = JSGlobalContextCreate(globalObjectClass);
  • trunk/JavaScriptCore/API/testapi.js

    r27885 r28884  
    5454}
    5555
     56function globalStaticFunction()
     57{
     58    return 4;
     59}
     60
    5661shouldBe("globalStaticValue", 3);
     62shouldBe("globalStaticFunction()", 4);
    5763
    5864shouldBe("typeof MyObject", "function"); // our object implements 'call'
  • trunk/JavaScriptCore/ChangeLog

    r28859 r28884  
     12007-12-19  Geoffrey Garen  <ggaren@apple.com>
     2
     3        Reviewed by Oliver Hunt.
     4       
     5        Optimized global access to global variables, using a symbol table.
     6       
     7        SunSpider reports a 1.5% overall speedup, a 6.2% speedup on 3d-morph,
     8        and a whopping 33.1% speedup on bitops-bitwise-and.
     9
     10        * API/JSCallbackObjectFunctions.h: Replaced calls to JSObject:: with
     11        calls to Base::, since JSObject is not always our base class. This
     12        was always a bug, but the bug is even more apparent after some of my
     13        changes.
     14
     15        (KJS::::staticFunctionGetter): Replaced use of getDirect with call to
     16        getOwnPropertySlot. Global declarations are no longer stored in the
     17        property map, so a call to getDirect is insufficient for finding
     18        override properties.
     19
     20        * API/testapi.c:
     21        * API/testapi.js: Added test for the getDirect change mentioned above.
     22
     23        * kjs/ExecState.cpp:
     24        * kjs/ExecState.h: Dialed back the optimization to store a direct
     25        pointer to the localStorage buffer. One ExecState can grow the global
     26        object's localStorage without another ExecState's knowledge, so
     27        ExecState can't store a direct pointer to the localStorage buffer
     28        unless/until we invent a way to update all the relevant ExecStates.
     29
     30        * kjs/JSGlobalObject.cpp: Inserted the symbol table into get and put
     31        operations.
     32        (KJS::JSGlobalObject::reset): Reset the symbol table and local storage,
     33        too. Also, clear the property map here, removing the need for a
     34        separate call.
     35
     36        * kjs/JSVariableObject.cpp:
     37        * kjs/JSVariableObject.h: Added support for saving localStorage and the
     38        symbol table to the back/forward cache, and restoring them.
     39
     40        * kjs/function.cpp:
     41        (KJS::GlobalFuncImp::callAsFunction): Renamed progNode to evalNode
     42        because it's an EvalNode, not a ProgramNode.
     43
     44        * kjs/lookup.h:
     45        (KJS::cacheGlobalObject): Replaced put with faster putDirect, since
     46        that's how the rest of lookup.h works. putDirect is safe here because
     47        cacheGlobalObject is only used for objects whose names are not valid
     48        identifiers.
     49
     50        * kjs/nodes.cpp: The good stuff!
     51
     52        (KJS::EvalNode::processDeclarations): Replaced hasProperty with
     53        the new hasOwnProperty, which is slightly faster.
     54
     55        * kjs/object.h: Nixed clearProperties because clear() does this job now.
     56
     57        * kjs/property_map.cpp:
     58        * kjs/property_map.h: More back/forward cache support.
     59       
     60        * wtf/Vector.h:
     61        (WTF::::grow): Added fast non-branching grow function. I used it in
     62        an earlier version of this patch, even though it's not used anymore.
     63
    1642007-12-09  Mark Rowe  <mrowe@apple.com>
    265
  • trunk/JavaScriptCore/JavaScriptCore.exp

    r28854 r28884  
    136136__ZN3KJS14JSGlobalObject16stopTimeoutCheckEv
    137137__ZN3KJS14JSGlobalObject17startTimeoutCheckEv
     138__ZN3KJS14JSGlobalObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
     139__ZN3KJS14JSGlobalObject3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueEi
    138140__ZN3KJS14JSGlobalObject4initEv
    139141__ZN3KJS14JSGlobalObject4markEv
     
    243245__ZNK3KJS13ArrayInstance7getItemEj
    244246__ZNK3KJS14JSGlobalObject12saveBuiltinsERNS_13SavedBuiltinsE
     247__ZNK3KJS16JSVariableObject15saveSymbolTableERN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEE
     248__ZNK3KJS16JSVariableObject16saveLocalStorageERNS_15SavedPropertiesE
     249__ZNK3KJS16JSVariableObject18restoreSymbolTableERN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEE
     250__ZNK3KJS16JSVariableObject19restoreLocalStorageERNS_15SavedPropertiesE
    245251__ZNK3KJS19InternalFunctionImp14implementsCallEv
    246252__ZNK3KJS19InternalFunctionImp21implementsHasInstanceEv
  • trunk/JavaScriptCore/kjs/ExecState.cpp

    r28608 r28884  
    7777        break;
    7878    }
     79   
     80    m_localStorage = &m_variableObject->localStorage();
    7981
    8082    if (scopeNode)
     
    104106    return dynamicGlobalObject();
    105107}
    106    
    107 void ExecState::updateLocalStorage()
    108 {
    109     m_localStorageBuffer = m_activation->localStorage().data();
    110 }
    111108
    112109} // namespace KJS
  • trunk/JavaScriptCore/kjs/ExecState.h

    r28608 r28884  
    2525#define ExecState_H
    2626
    27 #include "value.h"
     27#include "LabelStack.h"
     28#include "LocalStorage.h"
     29#include "scope_chain.h"
    2830#include "types.h"
    29 #include "CommonIdentifiers.h"
    30 #include "LabelStack.h"
    31 #include "scope_chain.h"
    3231
    3332namespace KJS  {
     
    4039   
    4140    class ActivationImp;
     41    class CommonIdentifiers;
    4242    class FunctionImp;
    4343    class GlobalFuncImp;
     
    8282       
    8383        ExecState* callingExecState() { return m_callingExec; }
     84        ExecState* savedExec() { return m_savedExec; }
    8485       
    8586        ActivationImp* activationObject() { return m_activation; }
     
    107108        const CommonIdentifiers& propertyNames() const { return *m_propertyNames; }
    108109
    109         LocalStorageEntry* localStorage() { return m_localStorageBuffer; }
    110         void updateLocalStorage();
     110        LocalStorage& localStorage() { return *m_localStorage; }
    111111   
    112112    public:
     
    132132        const List* m_arguments;
    133133        ActivationImp* m_activation;
    134         LocalStorageEntry* m_localStorageBuffer;
     134        LocalStorage* m_localStorage;
    135135
    136136        ScopeChain m_scopeChain;
  • trunk/JavaScriptCore/kjs/JSGlobalObject.cpp

    r28527 r28884  
    130130}
    131131
     132bool JSGlobalObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
     133{
     134    if (symbolTableGet(propertyName, slot))
     135        return true;
     136    return JSVariableObject::getOwnPropertySlot(exec, propertyName, slot);
     137}
     138
     139void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attr)
     140{
     141    if (symbolTablePut(propertyName, value, attr))
     142        return;
     143    return JSVariableObject::put(exec, propertyName, value, attr);
     144}
     145
    132146static inline JSObject* lastInPrototypeChain(JSObject* object)
    133147{
     
    140154void JSGlobalObject::reset(JSValue* prototype)
    141155{
    142     // Clear before inititalizing, to avoid marking uninitialized (dangerous) or
    143     // stale (wasteful) pointers during possible garbage collection while creating
    144     // new objects below.
    145 
    146     ExecState* exec = &d()->globalExec;
     156    // Clear before inititalizing, to avoid calling mark() on stale pointers --
     157    // which would be wasteful -- or uninitialized pointers -- which would be
     158    // dangerous. (The allocations below may cause a GC.)
     159
     160    _prop.clear();
     161    localStorage().clear();
     162    symbolTable().clear();
    147163
    148164    // Prototypes
     
    182198    d()->typeErrorConstructor = 0;
    183199    d()->URIErrorConstructor = 0;
     200
     201    ExecState* exec = &d()->globalExec;
    184202
    185203    // Prototypes
  • trunk/JavaScriptCore/kjs/JSGlobalObject.h

    r28565 r28884  
    148148        virtual ~JSGlobalObject();
    149149
     150        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
     151        virtual void put(ExecState*, const Identifier&, JSValue*, int attr = None);
     152
    150153        // Linked list of all global objects.
    151154        static JSGlobalObject* head() { return s_head; }
  • trunk/JavaScriptCore/kjs/JSVariableObject.cpp

    r28777 r28884  
    3131
    3232#include "PropertyNameArray.h"
     33#include "property_map.h"
    3334
    3435namespace KJS {
    3536
    3637UString::Rep* IdentifierRepHashTraits::nullRepPtr = &UString::Rep::null; // Didn't want to make a whole source file for just this.
     38
     39void JSVariableObject::saveSymbolTable(SymbolTable& s) const
     40{
     41    s = *d->symbolTable;
     42}
     43
     44void JSVariableObject::restoreSymbolTable(SymbolTable& s) const
     45{
     46    *d->symbolTable = s;
     47}
     48
     49void JSVariableObject::saveLocalStorage(SavedProperties& p) const
     50{
     51    unsigned count = d->localStorage.size();
     52
     53    p.m_properties.clear();
     54    p.m_count = count;
     55
     56    if (!count)
     57        return;
     58
     59    p.m_properties.set(new SavedProperty[count]);
     60   
     61    SavedProperty* prop = p.m_properties.get();
     62    for (size_t i = 0; i < count; ++i, ++prop) {
     63        LocalStorageEntry& entry = d->localStorage[i];
     64        prop->value = entry.value;
     65        prop->attributes = entry.attributes;
     66    }
     67}
     68
     69void JSVariableObject::restoreLocalStorage(SavedProperties& p) const
     70{
     71    unsigned count = p.m_count;
     72    d->localStorage.resize(count);
     73    SavedProperty* prop = p.m_properties.get();
     74    for (size_t i = 0; i < count; ++i, ++prop)
     75        d->localStorage[i] = LocalStorageEntry(prop->value, prop->attributes);
     76}
    3777
    3878bool JSVariableObject::deleteProperty(ExecState* exec, const Identifier& propertyName)
  • trunk/JavaScriptCore/kjs/JSVariableObject.h

    r28608 r28884  
    4040        SymbolTable& symbolTable() { return *d->symbolTable; }
    4141        LocalStorage& localStorage() { return d->localStorage; }
     42       
     43        void saveSymbolTable(SymbolTable& s) const;
     44        void restoreSymbolTable(SymbolTable& s) const;
    4245
     46        void saveLocalStorage(SavedProperties& s) const;
     47        void restoreLocalStorage(SavedProperties& s) const;
     48       
    4349        virtual bool deleteProperty(ExecState*, const Identifier&);
    4450        virtual void getPropertyNames(ExecState*, PropertyNameArray&);
  • trunk/JavaScriptCore/kjs/LocalStorage.h

    r27249 r28884  
    2626#define KJS_LOCAL_STORAGE_H
    2727
    28 #include <wtf/Vector.h>
     28#include <wtf/Forward.h>
     29#include <wtf/VectorTraits.h>
    2930
    3031namespace KJS {
  • trunk/JavaScriptCore/kjs/function.cpp

    r28608 r28884  
    700700        int errLine;
    701701        UString errMsg;
    702         RefPtr<EvalNode> progNode(parser().parse<EvalNode>(UString(), 0, s.data(), s.size(), &sourceId, &errLine, &errMsg));
     702        RefPtr<EvalNode> evalNode = parser().parse<EvalNode>(UString(), 0, s.data(), s.size(), &sourceId, &errLine, &errMsg);
    703703
    704704        Debugger* dbg = exec->dynamicGlobalObject()->debugger();
     
    710710
    711711        // no program node means a syntax occurred
    712         if (!progNode)
     712        if (!evalNode)
    713713          return throwError(exec, SyntaxError, errMsg, errLine, sourceId, NULL);
    714714
     
    718718        JSGlobalObject* globalObject = switchGlobal ? static_cast<JSGlobalObject*>(thisObj) : exec->dynamicGlobalObject();
    719719        JSObject* thisVal = static_cast<JSObject*>(exec->thisValue());
    720         ExecState newExec(globalObject, thisVal, progNode.get(), EvalCode, exec, globalObject->currentExec());
     720        ExecState newExec(globalObject, thisVal, evalNode.get(), EvalCode, exec, globalObject->currentExec());
    721721        if (exec->hadException())
    722722            newExec.setException(exec->exception());
     
    727727        }
    728728       
    729         Completion c = progNode->execute(&newExec);
     729        Completion c = evalNode->execute(&newExec);
    730730         
    731731        if (switchGlobal)
  • trunk/JavaScriptCore/kjs/lookup.h

    r28468 r28884  
    283283    }
    284284    JSObject* newObject = new ClassCtor(exec);
    285     globalObject->put(exec, propertyName, newObject, Internal | DontEnum);
     285    globalObject->putDirect(propertyName, newObject, Internal | DontEnum);
    286286    return newObject;
    287287  }
  • trunk/JavaScriptCore/kjs/nodes.cpp

    r28855 r28884  
    34893489inline void VarDeclNode::evaluateSingle(ExecState* exec)
    34903490{
     3491    ASSERT(exec->variableObject()->hasOwnProperty(exec, ident) || exec->codeType() == EvalCode); // Guaranteed by processDeclarations.
    34913492    const ScopeChain& chain = exec->scopeChain();
    34923493    JSObject* variableObject = exec->variableObject();
     
    34963497    bool inGlobalScope = ++chain.begin() == chain.end();
    34973498
    3498     if (inGlobalScope && (init || !variableObject->getDirect(ident))) {
    3499         JSValue* val = init ? init->evaluate(exec) : jsUndefined();
    3500         int flags = Internal;
    3501         if (exec->codeType() != EvalCode)
    3502             flags |= DontDelete;
    3503         if (varType == VarDeclNode::Constant)
    3504             flags |= ReadOnly;
    3505         variableObject->putDirect(ident, val, flags);
    3506     } else if (init) {
    3507         JSValue* val = init->evaluate(exec);
    3508         KJS_CHECKEXCEPTIONVOID
     3499    if (init) {
     3500        if (inGlobalScope) {
     3501            JSValue* val = init->evaluate(exec);
     3502            int flags = Internal;
     3503            if (exec->codeType() != EvalCode)
     3504                flags |= DontDelete;
     3505            if (varType == VarDeclNode::Constant)
     3506                flags |= ReadOnly;
     3507            variableObject->put(exec, ident, val, flags);
     3508        } else {
     3509            JSValue* val = init->evaluate(exec);
     3510            KJS_CHECKEXCEPTIONVOID
     3511
     3512            // if the variable object is the top of the scope chain, then that must
     3513            // be where this variable is declared, processVarDecls would have put
     3514            // it there. Don't search the scope chain, to optimize this very common case.
     3515            if (chain.top() != variableObject)
     3516                return handleSlowCase(exec, chain, val);
     3517
     3518            unsigned flags = 0;
     3519            variableObject->getPropertyAttributes(ident, flags);
     3520            if (varType == VarDeclNode::Constant)
     3521                flags |= ReadOnly;
    35093522           
    3510         // if the variable object is the top of the scope chain, then that must
    3511         // be where this variable is declared, processVarDecls would have put
    3512         // it there. Don't search the scope chain, to optimize this very common case.
    3513         if (chain.top() != variableObject)
    3514             return handleSlowCase(exec, chain, val);
    3515 
    3516         unsigned flags = 0;
    3517         variableObject->getPropertyAttributes(ident, flags);
    3518         if (varType == VarDeclNode::Constant)
    3519             flags |= ReadOnly;
    3520        
    3521         ASSERT(variableObject->hasProperty(exec, ident));
    3522         variableObject->put(exec, ident, val, flags);
     3523            variableObject->put(exec, ident, val, flags);
     3524        }
    35233525    }
    35243526}
     
    42754277void FunctionBodyNode::initializeSymbolTable(ExecState* exec)
    42764278{
    4277     size_t i, size;
    4278     size_t count = 0;
    4279 
    4280     // The order of additions here implicitly enforces the mutual exclusion described in ECMA 10.1.3.
    4281     for (i = 0, size = m_varStack.size(); i < size; ++i) {
    4282         if (m_varStack[i]->ident != exec->propertyNames().arguments)
    4283             m_symbolTable.set(m_varStack[i]->ident.ustring().rep(), count);
    4284         count++;
    4285     }
    4286 
    4287     for (i = 0, size = m_parameters.size(); i < size; ++i)
    4288         m_symbolTable.set(m_parameters[i].ustring().rep(), count++);
    4289 
    4290     for (i = 0, size = m_functionStack.size(); i < size; ++i)
    4291         m_symbolTable.set(m_functionStack[i]->ident.ustring().rep(), count++);
    4292 }
    4293 
    4294 void FunctionBodyNode::optimizeVariableAccess()
     4279    SymbolTable& symbolTable = exec->variableObject()->symbolTable();
     4280    ASSERT(!symbolTable.size());
     4281
     4282    size_t localStorageIndex = 0;
     4283
     4284    for (size_t i = 0, size = m_parameters.size(); i < size; ++i, ++localStorageIndex) {
     4285        UString::Rep* rep = m_parameters[i].ustring().rep();
     4286        symbolTable.set(rep, localStorageIndex);
     4287    }
     4288
     4289    for (size_t i = 0, size = m_functionStack.size(); i < size; ++i, ++localStorageIndex) {
     4290        UString::Rep* rep = m_functionStack[i]->ident.ustring().rep();
     4291        symbolTable.set(rep, localStorageIndex);
     4292    }
     4293
     4294    for (size_t i = 0, size = m_varStack.size(); i < size; ++i, ++localStorageIndex) {
     4295        Identifier& ident = m_varStack[i]->ident;
     4296        if (ident == exec->propertyNames().arguments)
     4297            continue;
     4298        symbolTable.add(ident.ustring().rep(), localStorageIndex);
     4299    }
     4300}
     4301
     4302void ProgramNode::initializeSymbolTable(ExecState* exec)
     4303{
     4304    // If a previous script defined a symbol with the same name as one of our
     4305    // symbols, to avoid breaking previously optimized nodes, we need to reuse
     4306    // the symbol's existing storage index. So, we can't be as efficient as
     4307    // FunctionBodyNode::initializeSymbolTable, which knows that no bindings
     4308    // have yet been made.
     4309   
     4310    JSVariableObject* variableObject = exec->variableObject();
     4311    SymbolTable& symbolTable = variableObject->symbolTable();
     4312
     4313    size_t localStorageIndex = symbolTable.size();
     4314    size_t size;
     4315   
     4316    size = m_functionStack.size();
     4317    m_functionIndexes.resize(size);
     4318    for (size_t i = 0; i < size; ++i) {
     4319        UString::Rep* rep = m_functionStack[i]->ident.ustring().rep();
     4320        pair<SymbolTable::iterator, bool> result = symbolTable.add(rep, localStorageIndex);
     4321        m_functionIndexes[i] = result.first->second;
     4322        if (result.second)
     4323            ++localStorageIndex;
     4324    }
     4325
     4326    size = m_varStack.size();
     4327    m_varIndexes.resize(size);
     4328    for (size_t i = 0; i < size; ++i) {
     4329        const Identifier& ident = m_varStack[i]->ident;
     4330        if (variableObject->getDirect(ident)) {
     4331            m_varIndexes[i] = missingSymbolMarker(); // Signal not to initialize this declaration.
     4332            continue;
     4333        }
     4334
     4335        UString::Rep* rep = ident.ustring().rep();
     4336        pair<SymbolTable::iterator, bool> result = symbolTable.add(rep, localStorageIndex);
     4337        if (!result.second) {
     4338            m_varIndexes[i] = missingSymbolMarker(); // Signal not to initialize this declaration.
     4339            continue;
     4340        }
     4341        m_varIndexes[i] = result.first->second;
     4342        ++localStorageIndex;
     4343    }
     4344}
     4345
     4346void ScopeNode::optimizeVariableAccess(ExecState* exec)
    42954347{
    42964348    DeclarationStacks::NodeStack nodeStack;
     
    42994351        return;
    43004352   
     4353    SymbolTable& symbolTable = exec->variableObject()->symbolTable();
    43014354    while (true) {
    4302         node->optimizeVariableAccess(m_symbolTable, nodeStack);
     4355        node->optimizeVariableAccess(symbolTable, nodeStack);
    43034356       
    43044357        size_t size = nodeStack.size();
     
    43154368    if (!m_initialized) {
    43164369        initializeSymbolTable(exec);
    4317         optimizeVariableAccess();
     4370        optimizeVariableAccess(exec);
    43184371       
    43194372        m_initialized = true;
     
    43214374
    43224375    LocalStorage& localStorage = exec->variableObject()->localStorage();
     4376   
     4377    // We can't just resize localStorage here because that would temporarily
     4378    // leave uninitialized entries, which would crash GC during the mark phase.
    43234379    localStorage.reserveCapacity(m_varStack.size() + m_parameters.size() + m_functionStack.size());
    43244380   
    43254381    int minAttributes = Internal | DontDelete;
    43264382   
    4327     size_t i, size;
    4328 
    4329     // NOTE: Must match the order of addition in initializeSymbolTable().
    4330 
    4331     for (i = 0, size = m_varStack.size(); i < size; ++i) {
     4383    // In order for our localStorage indexes to be correct, we must match the
     4384    // order of addition in initializeSymbolTable().
     4385
     4386    const List& args = *exec->arguments();
     4387    for (size_t i = 0, size = m_parameters.size(); i < size; ++i)
     4388        localStorage.uncheckedAppend(LocalStorageEntry(args[i], DontDelete));
     4389
     4390    for (size_t i = 0, size = m_functionStack.size(); i < size; ++i) {
     4391        FuncDeclNode* node = m_functionStack[i];
     4392        localStorage.uncheckedAppend(LocalStorageEntry(node->makeFunction(exec), minAttributes));
     4393    }
     4394
     4395    for (size_t i = 0, size = m_varStack.size(); i < size; ++i) {
    43324396        VarDeclNode* node = m_varStack[i];
    43334397        int attributes = minAttributes;
    43344398        if (node->varType == VarDeclNode::Constant)
    43354399            attributes |= ReadOnly;
    4336         localStorage.append(LocalStorageEntry(jsUndefined(), attributes));
    4337     }
    4338 
    4339     const List& args = *exec->arguments();
    4340     for (i = 0, size = m_parameters.size(); i < size; ++i)
    4341         localStorage.append(LocalStorageEntry(args[i], DontDelete));
    4342 
    4343     for (i = 0, size = m_functionStack.size(); i < size; ++i) {
     4400        localStorage.uncheckedAppend(LocalStorageEntry(jsUndefined(), attributes));
     4401    }
     4402}
     4403
     4404static void gccIsCrazy() KJS_FAST_CALL;
     4405static void gccIsCrazy()
     4406{
     4407}
     4408
     4409void ProgramNode::processDeclarations(ExecState* exec)
     4410{
     4411    // If you remove this call, some SunSpider tests, including
     4412    // bitops-nsieve-bits.js, will regress substantially on Mac, due to a ~40%
     4413    // increase in L2 cache misses. FIXME: WTF?
     4414    gccIsCrazy();
     4415   
     4416    initializeSymbolTable(exec);
     4417    optimizeVariableAccess(exec);
     4418
     4419    LocalStorage& localStorage = exec->variableObject()->localStorage();
     4420
     4421    // We can't just resize localStorage here because that would temporarily
     4422    // leave uninitialized entries, which would crash GC during the mark phase.
     4423    localStorage.reserveCapacity(localStorage.size() + m_varStack.size() + m_functionStack.size());
     4424
     4425    int minAttributes = Internal | DontDelete;
     4426
     4427    // In order for our localStorage indexes to be correct, we must match the
     4428    // order of addition in initializeSymbolTable().
     4429
     4430    for (size_t i = 0, size = m_functionStack.size(); i < size; ++i) {
    43444431        FuncDeclNode* node = m_functionStack[i];
    4345         localStorage.append(LocalStorageEntry(node->makeFunction(exec), minAttributes));
    4346     }
    4347 
    4348     exec->updateLocalStorage();
    4349 }
    4350 
    4351 void ProgramNode::processDeclarations(ExecState* exec)
    4352 {
    4353     size_t i, size;
    4354 
    4355     JSVariableObject* variableObject = exec->variableObject();
    4356    
    4357     int minAttributes = Internal | DontDelete;
    4358 
    4359     for (i = 0, size = m_varStack.size(); i < size; ++i) {
     4432        LocalStorageEntry entry = LocalStorageEntry(node->makeFunction(exec), minAttributes);
     4433        size_t index = m_functionIndexes[i];
     4434
     4435        if (index == localStorage.size())
     4436            localStorage.uncheckedAppend(entry);
     4437        else {
     4438            ASSERT(index < localStorage.size());
     4439            localStorage[index] = entry;
     4440        }
     4441    }
     4442
     4443    for (size_t i = 0, size = m_varStack.size(); i < size; ++i) {
     4444        size_t index = m_varIndexes[i];
     4445        if (index == missingSymbolMarker())
     4446            continue;
     4447
    43604448        VarDeclNode* node = m_varStack[i];
    4361         if (variableObject->hasProperty(exec, node->ident))
    4362             continue;
    43634449        int attributes = minAttributes;
    43644450        if (node->varType == VarDeclNode::Constant)
    43654451            attributes |= ReadOnly;
    4366         variableObject->put(exec, node->ident, jsUndefined(), attributes);
    4367     }
    4368 
    4369     for (i = 0, size = m_functionStack.size(); i < size; ++i) {
    4370         FuncDeclNode* node = m_functionStack[i];
    4371         variableObject->put(exec, node->ident, node->makeFunction(exec), minAttributes);
     4452        LocalStorageEntry entry = LocalStorageEntry(jsUndefined(), attributes);
     4453           
     4454        ASSERT(index == localStorage.size());
     4455        localStorage.uncheckedAppend(entry);
    43724456    }
    43734457}
     
    43754459void EvalNode::processDeclarations(ExecState* exec)
    43764460{
     4461    // We could optimize access to pre-existing symbols here, but SunSpider
     4462    // reports that to be a net loss.
     4463
    43774464    size_t i, size;
    43784465
     
    43834470    for (i = 0, size = m_varStack.size(); i < size; ++i) {
    43844471        VarDeclNode* node = m_varStack[i];
    4385         if (variableObject->hasProperty(exec, node->ident))
     4472        if (variableObject->hasOwnProperty(exec, node->ident))
    43864473            continue;
    43874474        int attributes = minAttributes;
  • trunk/JavaScriptCore/kjs/nodes.h

    r28855 r28884  
    19481948    ScopeNode(SourceElements*, DeclarationStacks::VarStack*, DeclarationStacks::FunctionStack*) KJS_FAST_CALL;
    19491949
    1950     int sourceId() KJS_FAST_CALL { return m_sourceId; }
    1951     const UString& sourceURL() KJS_FAST_CALL { return m_sourceURL; }
    1952 
    1953   protected:
     1950    int sourceId() const KJS_FAST_CALL { return m_sourceId; }
     1951    const UString& sourceURL() const KJS_FAST_CALL { return m_sourceURL; }
     1952
     1953  protected:
     1954    void optimizeVariableAccess(ExecState*) KJS_FAST_CALL;
    19541955
    19551956    DeclarationStacks::VarStack m_varStack;
     
    19671968   
    19681969  private:
     1970    void initializeSymbolTable(ExecState*) KJS_FAST_CALL;
    19691971    ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL;
     1972
     1973    Vector<size_t> m_varIndexes; // Storage indexes belonging to the nodes in m_varStack. (Recorded to avoid double lookup.)
     1974    Vector<size_t> m_functionIndexes; // Storage indexes belonging to the nodes in m_functionStack. (Recorded to avoid double lookup.)
    19701975  };
    19711976
     
    19921997  private:
    19931998    void initializeSymbolTable(ExecState*) KJS_FAST_CALL;
    1994     void optimizeVariableAccess() KJS_FAST_CALL;
    19951999    ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL;
    19962000
  • trunk/JavaScriptCore/kjs/object.cpp

    r28476 r28884  
    335335}
    336336
     337bool JSObject::hasOwnProperty(ExecState* exec, const Identifier& propertyName) const
     338{
     339    PropertySlot slot;
     340    return const_cast<JSObject*>(this)->getOwnPropertySlot(exec, propertyName, slot);
     341}
     342
    337343bool JSObject::deleteProperty(ExecState *exec, unsigned propertyName)
    338344{
  • trunk/JavaScriptCore/kjs/object.h

    r28527 r28884  
    112112     */
    113113    JSObject();
    114 
     114   
    115115    virtual void mark();
    116116    virtual JSType type() const;
     
    284284     * @return true if the object has the property, otherwise false
    285285     */
    286     bool hasProperty(ExecState *exec, const Identifier &propertyName) const;
    287     bool hasProperty(ExecState *exec, unsigned propertyName) const;
     286    bool hasProperty(ExecState*, const Identifier&) const;
     287    bool hasProperty(ExecState*, unsigned) const;
     288    bool hasOwnProperty(ExecState*, const Identifier&) const;
    288289
    289290    /**
     
    444445    void defineSetter(ExecState *exec, const Identifier& propertyName, JSObject *setterFunc);
    445446
    446     /**
    447      * Remove all properties from this object.
    448      * This doesn't take DontDelete into account, and isn't in the ECMA spec.
    449      * It's simply a quick way to remove everything stored in the property map.
    450      */
    451     void clearProperties() { _prop.clear(); }
    452 
    453447    void saveProperties(SavedProperties &p) const { _prop.save(p); }
    454448    void restoreProperties(const SavedProperties &p) { _prop.restore(p); }
     
    456450    virtual bool isActivationObject() { return false; }
    457451    virtual bool isGlobalObject() const { return false; }
     452
    458453  protected:
    459454    PropertyMap _prop;
     455
    460456  private:
    461457    const HashEntry* findPropertyHashEntry( const Identifier& propertyName ) const;
  • trunk/JavaScriptCore/kjs/object_object.cpp

    r28476 r28884  
    7575        case ValueOf:
    7676            return thisObj;
    77         case HasOwnProperty: {
    78             PropertySlot slot;
    79             return jsBoolean(thisObj->getOwnPropertySlot(exec, Identifier(args[0]->toString(exec)), slot));
    80         }
     77        case HasOwnProperty:
     78            return jsBoolean(thisObj->hasOwnProperty(exec, Identifier(args[0]->toString(exec))));
    8179        case IsPrototypeOf: {
    8280            if (!args[0]->isObject())
  • trunk/JavaScriptCore/kjs/property_map.cpp

    r28110 r28884  
    123123};
    124124
    125 struct SavedProperty {
    126     Identifier key;
    127     ProtectedPtr<JSValue> value;
    128     unsigned attributes;
    129 };
    130 
    131125static const unsigned emptyEntryIndex = 0;
    132126static const unsigned deletedSentinelIndex = 1;
  • trunk/JavaScriptCore/kjs/property_map.h

    r28110 r28884  
    2424
    2525#include "identifier.h"
     26#include "protect.h"
    2627#include <wtf/OwnArrayPtr.h>
    2728
     
    3435    struct PropertyMapEntry;
    3536    struct PropertyMapHashTable;
    36     struct SavedProperty;
    3737   
    38     class SavedProperties {
    39         friend class PropertyMap;
    40     public:
     38    struct SavedProperty {
     39        Identifier key;
     40        ProtectedPtr<JSValue> value;
     41        unsigned attributes;
     42    };
     43
     44    struct SavedProperties {
    4145        SavedProperties();
    4246        ~SavedProperties();
    4347       
    44     private:
    4548        unsigned m_count;
    4649        OwnArrayPtr<SavedProperty> m_properties;
     
    5154        PropertyMap();
    5255        ~PropertyMap();
    53 
     56       
    5457        void clear();
    5558       
  • trunk/JavaScriptCore/wtf/Vector.h

    r28517 r28884  
    452452
    453453        void shrink(size_t size);
     454        void grow(size_t size);
    454455        void resize(size_t size);
    455456        void reserveCapacity(size_t newCapacity);
     
    632633        ASSERT(size <= m_size);
    633634        TypeOperations::destruct(begin() + size, end());
     635        m_size = size;
     636    }
     637
     638    template<typename T, size_t inlineCapacity>
     639    void Vector<T, inlineCapacity>::grow(size_t size)
     640    {
     641        ASSERT(size >= m_size);
     642        if (size > capacity())
     643            expandCapacity(size);
     644        TypeOperations::initialize(end(), begin() + size);
    634645        m_size = size;
    635646    }
  • trunk/JavaScriptGlue/ChangeLog

    r28591 r28884  
     12007-12-19  Geoffrey Garen  <ggaren@apple.com>
     2
     3        Build fix.
     4
     5        * ForwardingHeaders/wtf/VectorTraits.h: Added.
     6
    172007-12-10  Timothy Hatcher  <timothy@apple.com>
    28
  • trunk/LayoutTests/ChangeLog

    r28883 r28884  
     12007-12-19  Geoffrey Garen  <ggaren@apple.com>
     2
     3        Reviewed by Oliver Hunt.
     4       
     5        Added some tests to verify some of the changes I made while optimizing
     6        global access to global variables.
     7
     8        * fast/dom/Window/resources/window-property-clearing-iframe0.html: Added.
     9        * fast/dom/Window/resources/window-property-clearing-iframe1.html: Added.
     10        * fast/dom/Window/window-property-clearing-expected.txt: Added.
     11        * fast/dom/Window/window-property-clearing.html: Added.
     12        * fast/dom/getter-on-window-object2-expected.txt: Added.
     13        * fast/dom/getter-on-window-object2.html: Added.
     14
     15        Checked in failing results for these const tests. The symbol table
     16        optimization broke const. (We didn't know this before because our only
     17        tests used global variables.)
     18
     19        * fast/js/const-expected.txt:
     20        * fast/js/kde/const-expected.txt:
     21
     22        * fast/js/resources/for-in-avoid-duplicates.js: Fixed a typo I noticed.
     23        Not related to this patch.
     24
     25        * fast/dom/Window/window-property-shadowing.html: Changed this test to
     26        use "this" instead of "window". The fact that "window" worked before,
     27        despite an overriding / shadowing var declaration, was a bug.
     28
    1292007-12-19  Dan Bernstein  <mitz@apple.com>
    230
  • trunk/LayoutTests/fast/dom/Window/window-property-shadowing.html

    r23987 r28884  
    1212    <pre id="console"></pre>
    1313    <script>
    14         if (window.layoutTestController)
     14        if (this.layoutTestController)
    1515            layoutTestController.dumpAsText();
    1616
  • trunk/LayoutTests/fast/js/const-expected.txt

    r12001 r28884  
    44
    55
    6 PASS x is "RIGHT"
    7 PASS y is "RIGHT"
     6FAIL x should be RIGHT. Was WRONG.
     7FAIL y should be RIGHT. Was WRONG.
    88PASS successfullyParsed is true
    99
  • trunk/LayoutTests/fast/js/kde/const-expected.txt

    r11962 r28884  
    55
    66PASS c is 11
    7 PASS c is 11
     7FAIL c should be 11. Was 22.
    88PASS v is 1
    99PASS successfullyParsed is true
  • trunk/LayoutTests/fast/js/resources/for-in-avoid-duplicates.js

    r15468 r28884  
    99}
    1010
    11 constructor.prototype = { xxx: "baz", yyy: "quux" };
     11constr.prototype = { xxx: "baz", yyy: "quux" };
    1212
    1313var obj = new constr();
  • trunk/WebCore/ChangeLog

    r28882 r28884  
     12007-12-19  Geoffrey Garen  <ggaren@apple.com>
     2
     3        Reviewed by Oliver Hunt.
     4
     5        Build support:
     6        * ForwardingHeaders/kjs/SymbolTable.h: Added.
     7        * ForwardingHeaders/wtf/VectorTraits.h: Added.
     8
     9        * bindings/js/JSDOMWindowCustom.cpp:
     10        (WebCore::JSDOMWindow::customGetOwnPropertySlot): Replaced use of
     11        getDirectLocation with getOwnPropertySlot. getDirectLocation is no
     12        longer valid, since global declarations are not stored in the property
     13        map.
     14
     15        (WebCore::JSDOMWindow::customPut): Replaced use of JSObject::put with
     16        JSGlobalObject::put. JSObject::put is no longer valid, since global
     17        declarations are not stored in the property map.
     18
     19        * bindings/js/kjs_window.cpp: Replaced JSObject:: calls with Base::
     20        calls, since JSObject is not our base class. This was always a bug, but
     21        the bug is even more apparent after some of my changes.
     22
     23        (KJS::Window::clear): Removed call to clearProperties because
     24        JSGlobalObject::reset takes care of that now.
     25
     26        * history/CachedPage.cpp:
     27        * history/CachedPage.h: Added support for saving a symbol table and
     28        localStorage to the page cache, and restoring it.
     29
    1302007-12-19  Dan Bernstein  <mitz@apple.com>
    231
  • trunk/WebCore/bindings/js/JSDOMWindowCustom.cpp

    r28565 r28884  
    5555
    5656    // Look for overrides first
    57     KJS::JSValue** val = getDirectLocation(propertyName);
    58     if (val) {
    59         if (!allowsAccessFrom(exec)) {
     57    if (JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot)) {
     58        if (!allowsAccessFrom(exec))
    6059            slot.setUndefined(this);
    61             return true;
    62         }
    6360
    64         // FIXME: Come up with a way of having JavaScriptCore handle getters/setters in this case
    65         if (_prop.hasGetterSetterProperties() && val[0]->type() == KJS::GetterSetterType)
    66             fillGetterPropertySlot(slot, val);
    67         else
    68             slot.setValueSlot(this, val);
    6961        return true;
    7062    }
     
    10092        return true;
    10193
    102     // Called by an internal KJS, save time and jump directly to JSObject.
     94    // Called by an internal KJS, save time and jump directly to JSGlobalObject.
    10395    if (attr != KJS::None && attr != KJS::DontDelete) {
    104         KJS::JSObject::put(exec, propertyName, value, attr);
     96        KJS::JSGlobalObject::put(exec, propertyName, value, attr);
    10597        return true;
    10698    }
    10799
    108     // We have a local override (e.g. "var location"), save time and jump directly to JSObject.
    109     if (KJS::JSObject::getDirect(propertyName)) {
     100    // We have a local override (e.g. "var location"), save time and jump directly to JSGlobalObject.
     101    KJS::PropertySlot slot;
     102    if (KJS::JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot)) {
    110103        if (allowsAccessFrom(exec))
    111             KJS::JSObject::put(exec, propertyName, value, attr);
     104            KJS::JSGlobalObject::put(exec, propertyName, value, attr);
    112105        return true;
    113106    }
  • trunk/WebCore/bindings/js/kjs_window.cpp

    r28858 r28884  
    275275void Window::mark()
    276276{
    277     JSGlobalObject::mark();
     277    Base::mark();
    278278    if (d->loc && !d->loc->marked())
    279279        d->loc->mark();
     
    659659  }
    660660
    661   return JSObject::getOwnPropertySlot(exec, propertyName, slot);
     661  return Base::getOwnPropertySlot(exec, propertyName, slot);
    662662}
    663663
     
    668668     if (entry->attr & Function) {
    669669       if (allowsAccessFrom(exec))
    670          JSObject::put(exec, propertyName, value, attr);
     670         Base::put(exec, propertyName, value, attr);
    671671       return;
    672672    }
     
    794794  }
    795795  if (allowsAccessFrom(exec))
    796     JSObject::put(exec, propertyName, value, attr);
     796    Base::put(exec, propertyName, value, attr);
    797797}
    798798
     
    847847    ASSERT(impl()->frame());
    848848    impl()->frame()->keepAlive();
    849     return JSGlobalObject::globalExec();
     849    return Base::globalExec();
    850850}
    851851
     
    950950
    951951  clearAllTimeouts();
    952   clearProperties();
    953952  clearHelperObjectProperties();
    954953
  • trunk/WebCore/bindings/js/kjs_window.h

    r28858 r28884  
    4949  // This is the only WebCore JS binding which does not inherit from DOMObject
    5050  class Window : public JSGlobalObject {
     51    typedef JSGlobalObject Base;
     52   
    5153    friend class WebCore::JSLocation;
    5254    friend class WebCore::ScheduledAction;
  • trunk/WebCore/history/CachedPage.cpp

    r28798 r28884  
    8484    , m_windowProperties(new SavedProperties)
    8585    , m_locationProperties(new SavedProperties)
     86    , m_windowLocalStorage(new SavedProperties)
    8687    , m_windowBuiltins(new SavedBuiltins)
    8788{
     
    9394   
    9495    Frame* mainFrame = page->mainFrame();
    95     KJSProxy* proxy = mainFrame->scriptProxy();
    96     KJS::Window* window = KJS::Window::retrieveWindow(mainFrame);
     96    Window* window = Window::retrieveWindow(mainFrame);
    9797
    9898    mainFrame->clearTimers();
     
    100100    JSLock lock;
    101101
    102     if (proxy && window) {
    103         proxy->globalObject()->saveBuiltins(*m_windowBuiltins.get());
     102    if (window) {
     103        window->saveBuiltins(*m_windowBuiltins.get());
    104104        window->saveProperties(*m_windowProperties.get());
     105        window->saveSymbolTable(m_windowSymbolTable);
     106        window->saveLocalStorage(*m_windowLocalStorage.get());
    105107        window->location()->saveProperties(*m_locationProperties.get());
    106108        m_pausedTimeouts.set(window->pauseTimeouts());
     
    129131
    130132    Frame* mainFrame = page->mainFrame();
    131     KJSProxy* proxy = mainFrame->scriptProxy();
    132     KJS::Window* window = KJS::Window::retrieveWindow(mainFrame);
     133    Window* window = Window::retrieveWindow(mainFrame);
    133134
    134135    JSLock lock;
    135136
    136     if (proxy && window) {
    137         proxy->globalObject()->restoreBuiltins(*m_windowBuiltins.get());
     137    if (window) {
     138        window->restoreBuiltins(*m_windowBuiltins.get());
    138139        window->restoreProperties(*m_windowProperties.get());
     140        window->restoreSymbolTable(m_windowSymbolTable);
     141        window->restoreLocalStorage(*m_windowLocalStorage.get());
    139142        window->location()->restoreProperties(*m_locationProperties.get());
    140143        window->resumeTimeouts(m_pausedTimeouts.get());
     
    195198    m_pausedTimeouts.clear();
    196199    m_cachedPagePlatformData.clear();
     200    m_windowLocalStorage.clear();
     201    m_windowSymbolTable.clear();
    197202
    198203    gcController().garbageCollectSoon();
  • trunk/WebCore/history/CachedPage.h

    r28779 r28884  
    2828
    2929#include "DocumentLoader.h"
     30#include <kjs/SymbolTable.h>
    3031#include <wtf/RefCounted.h>
    3132#include <wtf/Forward.h>
     
    4142   
    4243    class SavedBuiltins;
    43     class SavedProperties;
     44    struct SavedProperties;
    4445}
    4546
     
    8485    OwnPtr<KJS::SavedProperties> m_windowProperties;
    8586    OwnPtr<KJS::SavedProperties> m_locationProperties;
     87    OwnPtr<KJS::SavedProperties> m_windowLocalStorage;
     88    KJS::SymbolTable m_windowSymbolTable;
    8689    OwnPtr<KJS::SavedBuiltins> m_windowBuiltins;
    8790    OwnPtr<PausedTimeouts> m_pausedTimeouts;
  • trunk/WebKit/mac/ChangeLog

    r28795 r28884  
     12007-12-19  Geoffrey Garen  <ggaren@apple.com>
     2
     3        Reviewed by Oliver Hunt.
     4
     5        Build fix.
     6
     7        * ForwardingHeaders/kjs/SymbolTable.h: Added.
     8        * ForwardingHeaders/wtf/VectorTraits.h: Added.
     9
    1102007-12-16  Mark Rowe  <mrowe@apple.com>
    211
Note: See TracChangeset for help on using the changeset viewer.