Changeset 33541 in webkit
- Timestamp:
- May 16, 2008 5:27:52 PM (16 years ago)
- Location:
- branches/squirrelfish
- Files:
-
- 2 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/squirrelfish/JavaScriptCore/ChangeLog
r33517 r33541 1 2008-05-16 Oliver Hunt <oliver@apple.com> 2 3 Reviewed by Geoff. 4 5 Bug 19076: SquirrelFish: RegisterFile can be corrupted if implictly reenter global scope with no declared vars 6 <https://bugs.webkit.org/show_bug.cgi?id=19076> 7 8 Don't delay allocation of initial global RegisterFile, as we can't guarantee we will be able 9 to allocate the global 'this' register safely at any point after initialisation of the Global 10 Object. 11 12 Unfortunately this initial allocation caused a regression of 0.2-0.3%, however this patch adds 13 support for the static slot optimisation for the global Math object which brings it to a 0.3% 14 progression. 15 16 * VM/CodeGenerator.cpp: 17 (KJS::CodeGenerator::programCodeThis): 18 (KJS::CodeGenerator::CodeGenerator): 19 (KJS::CodeGenerator::addParameter): 20 * VM/CodeGenerator.h: 21 * VM/Machine.cpp: 22 (KJS::Machine::execute): 23 * kjs/ExecState.h: 24 * kjs/JSGlobalObject.cpp: 25 (KJS::JSGlobalObject::reset): 26 * kjs/JSGlobalObject.h: 27 (KJS::JSGlobalObject::GlobalPropertyInfo::GlobalPropertyInfo): 28 (KJS::JSGlobalObject::addStaticGlobals): 29 * kjs/nodes.cpp: 30 1 31 2008-05-16 Cameron Zwarich <cwzwarich@uwaterloo.ca> 2 32 -
branches/squirrelfish/JavaScriptCore/VM/CodeGenerator.cpp
r33484 r33541 163 163 } 164 164 165 RegisterID* CodeGenerator::programCodeThis() 166 { 167 static RegisterID programThis(Machine::ProgramCodeThisRegister); 168 return &programThis; 169 } 170 165 171 CodeGenerator::CodeGenerator(ProgramNode* programNode, const Debugger* debugger, const ScopeChain& scopeChain, SymbolTable* symbolTable, CodeBlock* codeBlock, VarStack& varStack, FunctionStack& functionStack, bool canCreateVariables) 166 172 : m_shouldEmitDebugHooks(!!debugger) … … 178 184 { 179 185 // Global code can inherit previously defined symbols. 180 if (int size = symbolTable->size()) { 181 // re-add "this" to symbol table 182 ASSERT(!symbolTable->contains(m_propertyNames->thisIdentifier.ustring().rep())); 183 symbolTable->add(m_propertyNames->thisIdentifier.ustring().rep(), Machine::ProgramCodeThisRegister); 184 ++size; 185 186 // Add previously defined symbols to bookkeeping. 187 m_locals.resize(size); 188 SymbolTable::iterator end = symbolTable->end(); 189 for (SymbolTable::iterator it = symbolTable->begin(); it != end; ++it) 190 m_locals[localsIndex(it->second.getIndex())].setIndex(it->second.getIndex()); 191 192 // Shift new symbols so they get stored prior to previously defined symbols. 193 m_nextVar -= size; 194 } else 195 addVar(m_propertyNames->thisIdentifier, false); // No need to make "this" a true parameter, since it's not passed by our caller. 186 int size = symbolTable->size() + 1; // + 1 slot for "this" 187 m_thisRegister = programCodeThis(); 188 189 // Add previously defined symbols to bookkeeping. 190 m_locals.resize(size); 191 SymbolTable::iterator end = symbolTable->end(); 192 for (SymbolTable::iterator it = symbolTable->begin(); it != end; ++it) 193 m_locals[localsIndex(it->second.getIndex())].setIndex(it->second.getIndex()); 194 195 // Shift new symbols so they get stored prior to previously defined symbols. 196 m_nextVar -= size; 196 197 197 198 JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(scopeChain.bottom()); … … 232 233 , m_scopeNode(functionBody) 233 234 , m_codeBlock(codeBlock) 235 , m_thisRegister(0) 234 236 , m_finallyDepth(0) 235 237 , m_dynamicScopeDepth(0) … … 260 262 m_locals.resize(localsIndex(m_nextParameter) + 1); 261 263 262 addParameter(m_propertyNames->thisIdentifier);264 m_thisRegister = addParameter(m_propertyNames->thisIdentifier); 263 265 for (size_t i = 0; i < parameters.size(); ++i) { 264 266 addParameter(parameters[i]); … … 272 274 , m_scopeNode(evalNode) 273 275 , m_codeBlock(codeBlock) 276 , m_thisRegister(0) 274 277 , m_finallyDepth(0) 275 278 , m_dynamicScopeDepth(0) … … 279 282 , m_propertyNames(CommonIdentifiers::shared()) 280 283 { 281 addVar(m_propertyNames->thisIdentifier, false);284 addVar(m_propertyNames->thisIdentifier, m_thisRegister, false); 282 285 283 286 for (size_t i = 0; i < varStack.size(); ++i) … … 295 298 } 296 299 297 voidCodeGenerator::addParameter(const Identifier& ident)300 RegisterID* CodeGenerator::addParameter(const Identifier& ident) 298 301 { 299 302 // Parameters overwrite var declarations, but not function declarations, 300 303 // in the symbol table. 304 RegisterID* result = 0; 301 305 UString::Rep* rep = ident.ustring().rep(); 302 306 if (!m_functions.contains(rep)) { 303 307 symbolTable().set(rep, m_nextParameter); 304 308 m_locals[localsIndex(m_nextParameter)].setIndex(m_nextParameter); 309 result = &(m_locals[localsIndex(m_nextParameter)]); 305 310 } 306 311 … … 309 314 ++m_nextParameter; 310 315 ++m_codeBlock->numParameters; 316 return result; 311 317 } 312 318 -
branches/squirrelfish/JavaScriptCore/VM/CodeGenerator.h
r33484 r33541 94 94 RegisterID* registerForLocalConstInit(const Identifier&); 95 95 96 // Returns the register storing "this" 97 RegisterID* thisRegister() { return m_thisRegister; } 98 96 99 bool isLocalConstant(const Identifier&); 97 100 … … 289 292 bool addVar(const Identifier&, RegisterID*&, bool isConstant); 290 293 291 voidaddParameter(const Identifier&);294 RegisterID* addParameter(const Identifier&); 292 295 293 296 unsigned addConstant(FuncDeclNode*); … … 312 315 313 316 HashSet<RefPtr<UString::Rep>, IdentifierRepHash> m_functions; 314 317 static RegisterID* programCodeThis(); 318 RegisterID* m_thisRegister; 315 319 SegmentedVector<RegisterID, 512> m_locals; 316 320 SegmentedVector<RegisterID, 512> m_temporaries; -
branches/squirrelfish/JavaScriptCore/VM/Machine.cpp
r33484 r33541 594 594 595 595 RegisterFile* registerFile = registerFileStack->pushGlobalRegisterFile(); 596 ASSERT(registerFile->numGlobalSlots()); 596 597 CodeBlock* codeBlock = &programNode->code(scopeChain, !registerFileStack->inImplicitCall()); 597 598 registerFile->addGlobalSlots(codeBlock->numVars); -
branches/squirrelfish/JavaScriptCore/kjs/ExecState.h
r33421 r33541 75 75 // Global object in which the current script was defined. (Can differ 76 76 // from dynamicGlobalObject() during function calls across frames.) 77 JSGlobalObject* ExecState::lexicalGlobalObject() const77 JSGlobalObject* lexicalGlobalObject() const 78 78 { 79 79 return m_scopeChain->globalObject(); -
branches/squirrelfish/JavaScriptCore/kjs/JSGlobalObject.cpp
r33346 r33541 258 258 _prop.clear(); 259 259 registerFileStack().current()->clear(); 260 registerFileStack().current()->addGlobalSlots(1); 260 261 symbolTable().clear(); 261 262 … … 378 379 379 380 // Set global values. 380 381 putDirect("Math", new MathObjectImp(exec, d()->objectPrototype), DontEnum); 382 putDirect("NaN", jsNaN(), DontEnum | DontDelete); 383 putDirect("Infinity", jsNumber(Inf), DontEnum | DontDelete); 384 putDirect("undefined", jsUndefined(), DontEnum | DontDelete); 381 GlobalPropertyInfo staticGlobals[] = { 382 GlobalPropertyInfo("Math", new MathObjectImp(exec, d()->objectPrototype), DontEnum | DontDelete), 383 GlobalPropertyInfo("NaN", jsNaN(), DontEnum | DontDelete), 384 GlobalPropertyInfo("Infinity", jsNumber(Inf), DontEnum | DontDelete), 385 GlobalPropertyInfo("undefined", jsUndefined(), DontEnum | DontDelete) 386 }; 387 388 addStaticGlobals(staticGlobals, sizeof(staticGlobals) / sizeof(GlobalPropertyInfo)); 385 389 386 390 // Set global functions. -
branches/squirrelfish/JavaScriptCore/kjs/JSGlobalObject.h
r33346 r33541 264 264 JSGlobalObjectData* d() const { return static_cast<JSGlobalObjectData*>(JSVariableObject::d); } 265 265 266 struct GlobalPropertyInfo { 267 GlobalPropertyInfo(const Identifier& i, JSValue* v, unsigned a) 268 : identifier(i) 269 , value(v) 270 , attributes(a) 271 { 272 } 273 274 const Identifier& identifier; 275 JSValue* value; 276 unsigned attributes; 277 }; 278 void addStaticGlobals(GlobalPropertyInfo*, int count); 279 266 280 bool checkTimeout(); 267 281 void resetTimeoutCheck(); … … 269 283 static JSGlobalObject* s_head; 270 284 }; 285 286 inline void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo* globals, int count) 287 { 288 RegisterFile* registerFile = registerFileStack().current(); 289 ASSERT(registerFile->safeForReentry() && registerFile->isGlobal() && !registerFile->size()); 290 int index = -registerFile->numGlobalSlots() - 1; 291 registerFile->addGlobalSlots(count); 292 for (int i = 0; i < count; ++i) { 293 ASSERT(globals[i].attributes & DontDelete); 294 SymbolTableEntry newEntry(index, globals[i].attributes); 295 symbolTable().add(globals[i].identifier.ustring().rep(), newEntry); 296 valueAt(index) = globals[i].value; 297 --index; 298 } 299 } 271 300 272 301 inline bool JSGlobalObject::timedOut() -
branches/squirrelfish/JavaScriptCore/kjs/nodes.cpp
r33517 r33541 585 585 RegisterID* ThisNode::emitCode(CodeGenerator& generator, RegisterID* dst) 586 586 { 587 RegisterID* r0 = generator.registerForLocal(generator.propertyNames().thisIdentifier); 588 return generator.moveToDestinationIfNeeded(dst, r0); 587 return generator.moveToDestinationIfNeeded(dst, generator.thisRegister()); 589 588 } 590 589 -
branches/squirrelfish/LayoutTests/ChangeLog
r33517 r33541 1 2008-05-16 Oliver Hunt <oliver@apple.com> 2 3 Reviewed by Geoff 4 5 Bug 19076: SquirrelFish: RegisterFile can be corrupted if implictly reenter global scope with no declared vars 6 <https://bugs.webkit.org/show_bug.cgi?id=19076> 7 8 Test that we can re-enter safely. 9 10 * fast/js/direct-entry-to-function-code-expected.txt: Added. 11 * fast/js/direct-entry-to-function-code.html: Added. 12 1 13 2008-05-16 Cameron Zwarich <cwzwarich@uwaterloo.ca> 2 14
Note: See TracChangeset
for help on using the changeset viewer.