Changeset 28884 in webkit
- Timestamp:
- Dec 20, 2007 1:32:06 AM (16 years ago)
- Location:
- trunk
- Files:
-
- 11 added
- 35 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/API/JSCallbackObjectFunctions.h
r28468 r28884 97 97 return m_class->className; 98 98 99 return JSObject::className();99 return Base::className(); 100 100 } 101 101 … … 141 141 } 142 142 143 return JSObject::getOwnPropertySlot(exec, propertyName, slot);143 return Base::getOwnPropertySlot(exec, propertyName, slot); 144 144 } 145 145 … … 188 188 } 189 189 190 return JSObject::put(exec, propertyName, value, attr);190 return Base::put(exec, propertyName, value, attr); 191 191 } 192 192 … … 228 228 } 229 229 230 return JSObject::deleteProperty(exec, propertyName);230 return Base::deleteProperty(exec, propertyName); 231 231 } 232 232 … … 362 362 } 363 363 364 JSObject::getPropertyNames(exec, propertyNames);364 Base::getPropertyNames(exec, propertyNames); 365 365 } 366 366 … … 378 378 } 379 379 380 return JSObject::toNumber(exec);380 return Base::toNumber(exec); 381 381 } 382 382 … … 394 394 } 395 395 396 return JSObject::toString(exec);396 return Base::toString(exec); 397 397 } 398 398 … … 454 454 JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase()); 455 455 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); 458 460 459 461 for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parentClass) { -
trunk/JavaScriptCore/API/testapi.c
r28636 r28884 508 508 } 509 509 510 static 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 } 510 520 511 521 static JSStaticValue globalObject_staticValues[] = { 512 522 { "globalStaticValue", globalObject_get, globalObject_set, kJSPropertyAttributeNone }, 513 523 { 0, 0, 0, 0 } 524 }; 525 526 static JSStaticFunction globalObject_staticFunctions[] = { 527 { "globalStaticFunction", globalObject_call, kJSPropertyAttributeNone }, 528 { 0, 0, 0 } 514 529 }; 515 530 … … 541 556 globalObjectClassDefinition.initialize = globalObject_initialize; 542 557 globalObjectClassDefinition.staticValues = globalObject_staticValues; 558 globalObjectClassDefinition.staticFunctions = globalObject_staticFunctions; 559 globalObjectClassDefinition.attributes = kJSClassAttributeNoAutomaticPrototype; 543 560 JSClassRef globalObjectClass = JSClassCreate(&globalObjectClassDefinition); 544 561 context = JSGlobalContextCreate(globalObjectClass); -
trunk/JavaScriptCore/API/testapi.js
r27885 r28884 54 54 } 55 55 56 function globalStaticFunction() 57 { 58 return 4; 59 } 60 56 61 shouldBe("globalStaticValue", 3); 62 shouldBe("globalStaticFunction()", 4); 57 63 58 64 shouldBe("typeof MyObject", "function"); // our object implements 'call' -
trunk/JavaScriptCore/ChangeLog
r28859 r28884 1 2007-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 1 64 2007-12-09 Mark Rowe <mrowe@apple.com> 2 65 -
trunk/JavaScriptCore/JavaScriptCore.exp
r28854 r28884 136 136 __ZN3KJS14JSGlobalObject16stopTimeoutCheckEv 137 137 __ZN3KJS14JSGlobalObject17startTimeoutCheckEv 138 __ZN3KJS14JSGlobalObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE 139 __ZN3KJS14JSGlobalObject3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueEi 138 140 __ZN3KJS14JSGlobalObject4initEv 139 141 __ZN3KJS14JSGlobalObject4markEv … … 243 245 __ZNK3KJS13ArrayInstance7getItemEj 244 246 __ZNK3KJS14JSGlobalObject12saveBuiltinsERNS_13SavedBuiltinsE 247 __ZNK3KJS16JSVariableObject15saveSymbolTableERN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEE 248 __ZNK3KJS16JSVariableObject16saveLocalStorageERNS_15SavedPropertiesE 249 __ZNK3KJS16JSVariableObject18restoreSymbolTableERN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEE 250 __ZNK3KJS16JSVariableObject19restoreLocalStorageERNS_15SavedPropertiesE 245 251 __ZNK3KJS19InternalFunctionImp14implementsCallEv 246 252 __ZNK3KJS19InternalFunctionImp21implementsHasInstanceEv -
trunk/JavaScriptCore/kjs/ExecState.cpp
r28608 r28884 77 77 break; 78 78 } 79 80 m_localStorage = &m_variableObject->localStorage(); 79 81 80 82 if (scopeNode) … … 104 106 return dynamicGlobalObject(); 105 107 } 106 107 void ExecState::updateLocalStorage()108 {109 m_localStorageBuffer = m_activation->localStorage().data();110 }111 108 112 109 } // namespace KJS -
trunk/JavaScriptCore/kjs/ExecState.h
r28608 r28884 25 25 #define ExecState_H 26 26 27 #include "value.h" 27 #include "LabelStack.h" 28 #include "LocalStorage.h" 29 #include "scope_chain.h" 28 30 #include "types.h" 29 #include "CommonIdentifiers.h"30 #include "LabelStack.h"31 #include "scope_chain.h"32 31 33 32 namespace KJS { … … 40 39 41 40 class ActivationImp; 41 class CommonIdentifiers; 42 42 class FunctionImp; 43 43 class GlobalFuncImp; … … 82 82 83 83 ExecState* callingExecState() { return m_callingExec; } 84 ExecState* savedExec() { return m_savedExec; } 84 85 85 86 ActivationImp* activationObject() { return m_activation; } … … 107 108 const CommonIdentifiers& propertyNames() const { return *m_propertyNames; } 108 109 109 LocalStorageEntry* localStorage() { return m_localStorageBuffer; } 110 void updateLocalStorage(); 110 LocalStorage& localStorage() { return *m_localStorage; } 111 111 112 112 public: … … 132 132 const List* m_arguments; 133 133 ActivationImp* m_activation; 134 LocalStorage Entry* m_localStorageBuffer;134 LocalStorage* m_localStorage; 135 135 136 136 ScopeChain m_scopeChain; -
trunk/JavaScriptCore/kjs/JSGlobalObject.cpp
r28527 r28884 130 130 } 131 131 132 bool 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 139 void 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 132 146 static inline JSObject* lastInPrototypeChain(JSObject* object) 133 147 { … … 140 154 void JSGlobalObject::reset(JSValue* prototype) 141 155 { 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(); 147 163 148 164 // Prototypes … … 182 198 d()->typeErrorConstructor = 0; 183 199 d()->URIErrorConstructor = 0; 200 201 ExecState* exec = &d()->globalExec; 184 202 185 203 // Prototypes -
trunk/JavaScriptCore/kjs/JSGlobalObject.h
r28565 r28884 148 148 virtual ~JSGlobalObject(); 149 149 150 virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); 151 virtual void put(ExecState*, const Identifier&, JSValue*, int attr = None); 152 150 153 // Linked list of all global objects. 151 154 static JSGlobalObject* head() { return s_head; } -
trunk/JavaScriptCore/kjs/JSVariableObject.cpp
r28777 r28884 31 31 32 32 #include "PropertyNameArray.h" 33 #include "property_map.h" 33 34 34 35 namespace KJS { 35 36 36 37 UString::Rep* IdentifierRepHashTraits::nullRepPtr = &UString::Rep::null; // Didn't want to make a whole source file for just this. 38 39 void JSVariableObject::saveSymbolTable(SymbolTable& s) const 40 { 41 s = *d->symbolTable; 42 } 43 44 void JSVariableObject::restoreSymbolTable(SymbolTable& s) const 45 { 46 *d->symbolTable = s; 47 } 48 49 void 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 69 void 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 } 37 77 38 78 bool JSVariableObject::deleteProperty(ExecState* exec, const Identifier& propertyName) -
trunk/JavaScriptCore/kjs/JSVariableObject.h
r28608 r28884 40 40 SymbolTable& symbolTable() { return *d->symbolTable; } 41 41 LocalStorage& localStorage() { return d->localStorage; } 42 43 void saveSymbolTable(SymbolTable& s) const; 44 void restoreSymbolTable(SymbolTable& s) const; 42 45 46 void saveLocalStorage(SavedProperties& s) const; 47 void restoreLocalStorage(SavedProperties& s) const; 48 43 49 virtual bool deleteProperty(ExecState*, const Identifier&); 44 50 virtual void getPropertyNames(ExecState*, PropertyNameArray&); -
trunk/JavaScriptCore/kjs/LocalStorage.h
r27249 r28884 26 26 #define KJS_LOCAL_STORAGE_H 27 27 28 #include <wtf/Vector.h> 28 #include <wtf/Forward.h> 29 #include <wtf/VectorTraits.h> 29 30 30 31 namespace KJS { -
trunk/JavaScriptCore/kjs/function.cpp
r28608 r28884 700 700 int errLine; 701 701 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); 703 703 704 704 Debugger* dbg = exec->dynamicGlobalObject()->debugger(); … … 710 710 711 711 // no program node means a syntax occurred 712 if (! progNode)712 if (!evalNode) 713 713 return throwError(exec, SyntaxError, errMsg, errLine, sourceId, NULL); 714 714 … … 718 718 JSGlobalObject* globalObject = switchGlobal ? static_cast<JSGlobalObject*>(thisObj) : exec->dynamicGlobalObject(); 719 719 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()); 721 721 if (exec->hadException()) 722 722 newExec.setException(exec->exception()); … … 727 727 } 728 728 729 Completion c = progNode->execute(&newExec);729 Completion c = evalNode->execute(&newExec); 730 730 731 731 if (switchGlobal) -
trunk/JavaScriptCore/kjs/lookup.h
r28468 r28884 283 283 } 284 284 JSObject* newObject = new ClassCtor(exec); 285 globalObject->put (exec,propertyName, newObject, Internal | DontEnum);285 globalObject->putDirect(propertyName, newObject, Internal | DontEnum); 286 286 return newObject; 287 287 } -
trunk/JavaScriptCore/kjs/nodes.cpp
r28855 r28884 3489 3489 inline void VarDeclNode::evaluateSingle(ExecState* exec) 3490 3490 { 3491 ASSERT(exec->variableObject()->hasOwnProperty(exec, ident) || exec->codeType() == EvalCode); // Guaranteed by processDeclarations. 3491 3492 const ScopeChain& chain = exec->scopeChain(); 3492 3493 JSObject* variableObject = exec->variableObject(); … … 3496 3497 bool inGlobalScope = ++chain.begin() == chain.end(); 3497 3498 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; 3509 3522 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 } 3523 3525 } 3524 3526 } … … 4275 4277 void FunctionBodyNode::initializeSymbolTable(ExecState* exec) 4276 4278 { 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 4302 void 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 4346 void ScopeNode::optimizeVariableAccess(ExecState* exec) 4295 4347 { 4296 4348 DeclarationStacks::NodeStack nodeStack; … … 4299 4351 return; 4300 4352 4353 SymbolTable& symbolTable = exec->variableObject()->symbolTable(); 4301 4354 while (true) { 4302 node->optimizeVariableAccess( m_symbolTable, nodeStack);4355 node->optimizeVariableAccess(symbolTable, nodeStack); 4303 4356 4304 4357 size_t size = nodeStack.size(); … … 4315 4368 if (!m_initialized) { 4316 4369 initializeSymbolTable(exec); 4317 optimizeVariableAccess( );4370 optimizeVariableAccess(exec); 4318 4371 4319 4372 m_initialized = true; … … 4321 4374 4322 4375 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. 4323 4379 localStorage.reserveCapacity(m_varStack.size() + m_parameters.size() + m_functionStack.size()); 4324 4380 4325 4381 int minAttributes = Internal | DontDelete; 4326 4382 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) { 4332 4396 VarDeclNode* node = m_varStack[i]; 4333 4397 int attributes = minAttributes; 4334 4398 if (node->varType == VarDeclNode::Constant) 4335 4399 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 4404 static void gccIsCrazy() KJS_FAST_CALL; 4405 static void gccIsCrazy() 4406 { 4407 } 4408 4409 void 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) { 4344 4431 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 4360 4448 VarDeclNode* node = m_varStack[i]; 4361 if (variableObject->hasProperty(exec, node->ident))4362 continue;4363 4449 int attributes = minAttributes; 4364 4450 if (node->varType == VarDeclNode::Constant) 4365 4451 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); 4372 4456 } 4373 4457 } … … 4375 4459 void EvalNode::processDeclarations(ExecState* exec) 4376 4460 { 4461 // We could optimize access to pre-existing symbols here, but SunSpider 4462 // reports that to be a net loss. 4463 4377 4464 size_t i, size; 4378 4465 … … 4383 4470 for (i = 0, size = m_varStack.size(); i < size; ++i) { 4384 4471 VarDeclNode* node = m_varStack[i]; 4385 if (variableObject->has Property(exec, node->ident))4472 if (variableObject->hasOwnProperty(exec, node->ident)) 4386 4473 continue; 4387 4474 int attributes = minAttributes; -
trunk/JavaScriptCore/kjs/nodes.h
r28855 r28884 1948 1948 ScopeNode(SourceElements*, DeclarationStacks::VarStack*, DeclarationStacks::FunctionStack*) KJS_FAST_CALL; 1949 1949 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; 1954 1955 1955 1956 DeclarationStacks::VarStack m_varStack; … … 1967 1968 1968 1969 private: 1970 void initializeSymbolTable(ExecState*) KJS_FAST_CALL; 1969 1971 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.) 1970 1975 }; 1971 1976 … … 1992 1997 private: 1993 1998 void initializeSymbolTable(ExecState*) KJS_FAST_CALL; 1994 void optimizeVariableAccess() KJS_FAST_CALL;1995 1999 ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL; 1996 2000 -
trunk/JavaScriptCore/kjs/object.cpp
r28476 r28884 335 335 } 336 336 337 bool JSObject::hasOwnProperty(ExecState* exec, const Identifier& propertyName) const 338 { 339 PropertySlot slot; 340 return const_cast<JSObject*>(this)->getOwnPropertySlot(exec, propertyName, slot); 341 } 342 337 343 bool JSObject::deleteProperty(ExecState *exec, unsigned propertyName) 338 344 { -
trunk/JavaScriptCore/kjs/object.h
r28527 r28884 112 112 */ 113 113 JSObject(); 114 114 115 115 virtual void mark(); 116 116 virtual JSType type() const; … … 284 284 * @return true if the object has the property, otherwise false 285 285 */ 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; 288 289 289 290 /** … … 444 445 void defineSetter(ExecState *exec, const Identifier& propertyName, JSObject *setterFunc); 445 446 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 453 447 void saveProperties(SavedProperties &p) const { _prop.save(p); } 454 448 void restoreProperties(const SavedProperties &p) { _prop.restore(p); } … … 456 450 virtual bool isActivationObject() { return false; } 457 451 virtual bool isGlobalObject() const { return false; } 452 458 453 protected: 459 454 PropertyMap _prop; 455 460 456 private: 461 457 const HashEntry* findPropertyHashEntry( const Identifier& propertyName ) const; -
trunk/JavaScriptCore/kjs/object_object.cpp
r28476 r28884 75 75 case ValueOf: 76 76 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)))); 81 79 case IsPrototypeOf: { 82 80 if (!args[0]->isObject()) -
trunk/JavaScriptCore/kjs/property_map.cpp
r28110 r28884 123 123 }; 124 124 125 struct SavedProperty {126 Identifier key;127 ProtectedPtr<JSValue> value;128 unsigned attributes;129 };130 131 125 static const unsigned emptyEntryIndex = 0; 132 126 static const unsigned deletedSentinelIndex = 1; -
trunk/JavaScriptCore/kjs/property_map.h
r28110 r28884 24 24 25 25 #include "identifier.h" 26 #include "protect.h" 26 27 #include <wtf/OwnArrayPtr.h> 27 28 … … 34 35 struct PropertyMapEntry; 35 36 struct PropertyMapHashTable; 36 struct SavedProperty;37 37 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 { 41 45 SavedProperties(); 42 46 ~SavedProperties(); 43 47 44 private:45 48 unsigned m_count; 46 49 OwnArrayPtr<SavedProperty> m_properties; … … 51 54 PropertyMap(); 52 55 ~PropertyMap(); 53 56 54 57 void clear(); 55 58 -
trunk/JavaScriptCore/wtf/Vector.h
r28517 r28884 452 452 453 453 void shrink(size_t size); 454 void grow(size_t size); 454 455 void resize(size_t size); 455 456 void reserveCapacity(size_t newCapacity); … … 632 633 ASSERT(size <= m_size); 633 634 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); 634 645 m_size = size; 635 646 } -
trunk/JavaScriptGlue/ChangeLog
r28591 r28884 1 2007-12-19 Geoffrey Garen <ggaren@apple.com> 2 3 Build fix. 4 5 * ForwardingHeaders/wtf/VectorTraits.h: Added. 6 1 7 2007-12-10 Timothy Hatcher <timothy@apple.com> 2 8 -
trunk/LayoutTests/ChangeLog
r28883 r28884 1 2007-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 1 29 2007-12-19 Dan Bernstein <mitz@apple.com> 2 30 -
trunk/LayoutTests/fast/dom/Window/window-property-shadowing.html
r23987 r28884 12 12 <pre id="console"></pre> 13 13 <script> 14 if ( window.layoutTestController)14 if (this.layoutTestController) 15 15 layoutTestController.dumpAsText(); 16 16 -
trunk/LayoutTests/fast/js/const-expected.txt
r12001 r28884 4 4 5 5 6 PASS x is "RIGHT" 7 PASS y is "RIGHT" 6 FAIL x should be RIGHT. Was WRONG. 7 FAIL y should be RIGHT. Was WRONG. 8 8 PASS successfullyParsed is true 9 9 -
trunk/LayoutTests/fast/js/kde/const-expected.txt
r11962 r28884 5 5 6 6 PASS c is 11 7 PASS c is 11 7 FAIL c should be 11. Was 22. 8 8 PASS v is 1 9 9 PASS successfullyParsed is true -
trunk/LayoutTests/fast/js/resources/for-in-avoid-duplicates.js
r15468 r28884 9 9 } 10 10 11 constr uctor.prototype = { xxx: "baz", yyy: "quux" };11 constr.prototype = { xxx: "baz", yyy: "quux" }; 12 12 13 13 var obj = new constr(); -
trunk/WebCore/ChangeLog
r28882 r28884 1 2007-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 1 30 2007-12-19 Dan Bernstein <mitz@apple.com> 2 31 -
trunk/WebCore/bindings/js/JSDOMWindowCustom.cpp
r28565 r28884 55 55 56 56 // 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)) 60 59 slot.setUndefined(this); 61 return true;62 }63 60 64 // FIXME: Come up with a way of having JavaScriptCore handle getters/setters in this case65 if (_prop.hasGetterSetterProperties() && val[0]->type() == KJS::GetterSetterType)66 fillGetterPropertySlot(slot, val);67 else68 slot.setValueSlot(this, val);69 61 return true; 70 62 } … … 100 92 return true; 101 93 102 // Called by an internal KJS, save time and jump directly to JS Object.94 // Called by an internal KJS, save time and jump directly to JSGlobalObject. 103 95 if (attr != KJS::None && attr != KJS::DontDelete) { 104 KJS::JS Object::put(exec, propertyName, value, attr);96 KJS::JSGlobalObject::put(exec, propertyName, value, attr); 105 97 return true; 106 98 } 107 99 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)) { 110 103 if (allowsAccessFrom(exec)) 111 KJS::JS Object::put(exec, propertyName, value, attr);104 KJS::JSGlobalObject::put(exec, propertyName, value, attr); 112 105 return true; 113 106 } -
trunk/WebCore/bindings/js/kjs_window.cpp
r28858 r28884 275 275 void Window::mark() 276 276 { 277 JSGlobalObject::mark();277 Base::mark(); 278 278 if (d->loc && !d->loc->marked()) 279 279 d->loc->mark(); … … 659 659 } 660 660 661 return JSObject::getOwnPropertySlot(exec, propertyName, slot);661 return Base::getOwnPropertySlot(exec, propertyName, slot); 662 662 } 663 663 … … 668 668 if (entry->attr & Function) { 669 669 if (allowsAccessFrom(exec)) 670 JSObject::put(exec, propertyName, value, attr);670 Base::put(exec, propertyName, value, attr); 671 671 return; 672 672 } … … 794 794 } 795 795 if (allowsAccessFrom(exec)) 796 JSObject::put(exec, propertyName, value, attr);796 Base::put(exec, propertyName, value, attr); 797 797 } 798 798 … … 847 847 ASSERT(impl()->frame()); 848 848 impl()->frame()->keepAlive(); 849 return JSGlobalObject::globalExec();849 return Base::globalExec(); 850 850 } 851 851 … … 950 950 951 951 clearAllTimeouts(); 952 clearProperties();953 952 clearHelperObjectProperties(); 954 953 -
trunk/WebCore/bindings/js/kjs_window.h
r28858 r28884 49 49 // This is the only WebCore JS binding which does not inherit from DOMObject 50 50 class Window : public JSGlobalObject { 51 typedef JSGlobalObject Base; 52 51 53 friend class WebCore::JSLocation; 52 54 friend class WebCore::ScheduledAction; -
trunk/WebCore/history/CachedPage.cpp
r28798 r28884 84 84 , m_windowProperties(new SavedProperties) 85 85 , m_locationProperties(new SavedProperties) 86 , m_windowLocalStorage(new SavedProperties) 86 87 , m_windowBuiltins(new SavedBuiltins) 87 88 { … … 93 94 94 95 Frame* mainFrame = page->mainFrame(); 95 KJSProxy* proxy = mainFrame->scriptProxy(); 96 KJS::Window* window = KJS::Window::retrieveWindow(mainFrame); 96 Window* window = Window::retrieveWindow(mainFrame); 97 97 98 98 mainFrame->clearTimers(); … … 100 100 JSLock lock; 101 101 102 if ( proxy &&window) {103 proxy->globalObject()->saveBuiltins(*m_windowBuiltins.get());102 if (window) { 103 window->saveBuiltins(*m_windowBuiltins.get()); 104 104 window->saveProperties(*m_windowProperties.get()); 105 window->saveSymbolTable(m_windowSymbolTable); 106 window->saveLocalStorage(*m_windowLocalStorage.get()); 105 107 window->location()->saveProperties(*m_locationProperties.get()); 106 108 m_pausedTimeouts.set(window->pauseTimeouts()); … … 129 131 130 132 Frame* mainFrame = page->mainFrame(); 131 KJSProxy* proxy = mainFrame->scriptProxy(); 132 KJS::Window* window = KJS::Window::retrieveWindow(mainFrame); 133 Window* window = Window::retrieveWindow(mainFrame); 133 134 134 135 JSLock lock; 135 136 136 if ( proxy &&window) {137 proxy->globalObject()->restoreBuiltins(*m_windowBuiltins.get());137 if (window) { 138 window->restoreBuiltins(*m_windowBuiltins.get()); 138 139 window->restoreProperties(*m_windowProperties.get()); 140 window->restoreSymbolTable(m_windowSymbolTable); 141 window->restoreLocalStorage(*m_windowLocalStorage.get()); 139 142 window->location()->restoreProperties(*m_locationProperties.get()); 140 143 window->resumeTimeouts(m_pausedTimeouts.get()); … … 195 198 m_pausedTimeouts.clear(); 196 199 m_cachedPagePlatformData.clear(); 200 m_windowLocalStorage.clear(); 201 m_windowSymbolTable.clear(); 197 202 198 203 gcController().garbageCollectSoon(); -
trunk/WebCore/history/CachedPage.h
r28779 r28884 28 28 29 29 #include "DocumentLoader.h" 30 #include <kjs/SymbolTable.h> 30 31 #include <wtf/RefCounted.h> 31 32 #include <wtf/Forward.h> … … 41 42 42 43 class SavedBuiltins; 43 classSavedProperties;44 struct SavedProperties; 44 45 } 45 46 … … 84 85 OwnPtr<KJS::SavedProperties> m_windowProperties; 85 86 OwnPtr<KJS::SavedProperties> m_locationProperties; 87 OwnPtr<KJS::SavedProperties> m_windowLocalStorage; 88 KJS::SymbolTable m_windowSymbolTable; 86 89 OwnPtr<KJS::SavedBuiltins> m_windowBuiltins; 87 90 OwnPtr<PausedTimeouts> m_pausedTimeouts; -
trunk/WebKit/mac/ChangeLog
r28795 r28884 1 2007-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 1 10 2007-12-16 Mark Rowe <mrowe@apple.com> 2 11
Note: See TracChangeset
for help on using the changeset viewer.