Changeset 37323 in webkit
- Timestamp:
- Oct 5, 2008 7:48:08 PM (16 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r37321 r37323 1 2008-10-05 Maciej Stachowiak <mjs@apple.com> 2 3 Reviewed by Oliver Hunt. 4 5 - fixed "REGRESSION (r37297): fast/js/deep-recursion-test takes too long and times out" 6 https://bugs.webkit.org/show_bug.cgi?id=21375 7 8 The problem is that dynamicGlobalObject had become O(N) in number 9 of call frames, but unwinding the stack for an exception called it 10 for every call frame, resulting in O(N^2) behavior for an 11 exception thrown from inside deep recursion. 12 13 Instead of doing it that way, stash the dynamic global object in JSGlobalData. 14 15 * JavaScriptCore.exp: 16 * VM/Machine.cpp: 17 (JSC::DynamicGlobalObjectScope::DynamicGlobalObjectScope): Helper class to temporarily 18 store and later restore a dynamicGlobalObject in JSGlobalData. 19 (JSC::DynamicGlobalObjectScope::~DynamicGlobalObjectScope): 20 (JSC::Machine::execute): In each version, establish a DynamicGlobalObjectScope. 21 For ProgramNode, always establish set new dynamicGlobalObject, for FunctionBody and Eval, 22 only if none is currently set. 23 * VM/Machine.h: 24 * kjs/ExecState.h: 25 * kjs/JSGlobalData.cpp: 26 (JSC::JSGlobalData::JSGlobalData): Ininitalize new dynamicGlobalObject field to 0. 27 * kjs/JSGlobalData.h: 28 * kjs/JSGlobalObject.h: 29 (JSC::ExecState::dynamicGlobalObject): Moved here from ExecState for benefit of inlining. 30 Return lexical global object if this is a globalExec(), otherwise look in JSGlobalData 31 for the one stashed there. 32 1 33 2008-10-05 Sam Weinig <sam@webkit.org> 2 34 -
trunk/JavaScriptCore/JavaScriptCore.exp
r37275 r37323 207 207 __ZN3JSC7CStringaSERKS0_ 208 208 __ZN3JSC7JSArray4infoE 209 __ZN3JSC7Machine14firstCallFrameEPKNS_8RegisterE210 209 __ZN3JSC7Profile10restoreAllEv 211 210 __ZN3JSC7Profile5focusEPKNS_11ProfileNodeE -
trunk/JavaScriptCore/VM/Machine.cpp
r37297 r37323 869 869 } 870 870 871 class DynamicGlobalObjectScope { 872 public: 873 DynamicGlobalObjectScope(ExecState* exec, JSGlobalObject* dynamicGlobalObject) 874 : m_exec(exec) 875 , m_savedGlobalObject(exec->globalData().dynamicGlobalObject) 876 { 877 exec->globalData().dynamicGlobalObject = dynamicGlobalObject; 878 } 879 880 ~DynamicGlobalObjectScope() 881 { 882 m_exec->globalData().dynamicGlobalObject = m_savedGlobalObject; 883 } 884 885 private: 886 ExecState* m_exec; 887 JSGlobalObject* m_savedGlobalObject; 888 }; 889 871 890 JSValue* Machine::execute(ProgramNode* programNode, ExecState* exec, ScopeChainNode* scopeChain, JSObject* thisObj, JSValue** exception) 872 891 { … … 886 905 return jsNull(); 887 906 } 907 908 DynamicGlobalObjectScope globalObjectScope(exec, scopeChain->globalObject()); 888 909 889 910 JSGlobalObject* lastGlobalObject = m_registerFile.globalObject(); … … 921 942 922 943 m_registerFile.shrink(oldEnd); 944 923 945 return result; 924 946 } … … 940 962 return jsNull(); 941 963 } 964 965 DynamicGlobalObjectScope globalObjectScope(exec, exec->globalData().dynamicGlobalObject ? exec->globalData().dynamicGlobalObject : scopeChain->globalObject()); 942 966 943 967 Register* argv = oldEnd; … … 992 1016 return jsNull(); 993 1017 } 1018 1019 DynamicGlobalObjectScope globalObjectScope(exec, exec->globalData().dynamicGlobalObject ? exec->globalData().dynamicGlobalObject : scopeChain->globalObject()); 994 1020 995 1021 EvalCodeBlock* codeBlock = &evalNode->byteCode(scopeChain); … … 3949 3975 } 3950 3976 3951 const Register* Machine::firstCallFrame(const Register* callFrame)3952 {3953 const Register* first = 0;3954 for (const Register* frame = callFrame; frame; frame = stripHostCallFrameBit(frame[RegisterFile::CallerRegisters].r()))3955 first = frame;3956 return first;3957 }3958 3959 3977 Register* Machine::callFrame(ExecState* exec, InternalFunction* function) const 3960 3978 { -
trunk/JavaScriptCore/VM/Machine.h
r37297 r37323 104 104 void retrieveLastCaller(ExecState* exec, int& lineNumber, intptr_t& sourceID, UString& sourceURL, JSValue*& function) const; 105 105 106 static const Register* firstCallFrame(const Register* callFrame);107 106 static ScopeChainNode* scopeChain(const Register* r) { return r[RegisterFile::ScopeChain].scopeChain(); } 108 107 static CodeBlock* codeBlock(const Register* r) { return r[RegisterFile::CodeBlock].codeBlock(); } -
trunk/JavaScriptCore/kjs/ExecState.h
r37297 r37323 44 44 45 45 // Global object in which execution began. 46 JSGlobalObject* dynamicGlobalObject() 47 { 48 return Machine::scopeChain(Machine::firstCallFrame(this))->globalObject(); 49 } 46 JSGlobalObject* dynamicGlobalObject(); 50 47 51 48 // Global object in which the currently executing code was defined. -
trunk/JavaScriptCore/kjs/JSGlobalData.cpp
r37297 r37323 92 92 , parser(new Parser) 93 93 , head(0) 94 , dynamicGlobalObject(0) 94 95 , isSharedInstance(isShared) 95 96 , clientData(0) -
trunk/JavaScriptCore/kjs/JSGlobalData.h
r37297 r37323 99 99 100 100 JSGlobalObject* head; 101 JSGlobalObject* dynamicGlobalObject; 101 102 102 103 bool isSharedInstance; -
trunk/JavaScriptCore/kjs/JSGlobalObject.h
r37297 r37323 331 331 } 332 332 333 inline JSGlobalObject* ExecState::dynamicGlobalObject() 334 { 335 if (this == lexicalGlobalObject()->globalExec()) 336 return lexicalGlobalObject(); 337 338 // For any ExecState that's not a globalExec, the 339 // dynamic global object must be set since code is running 340 ASSERT(globalData().dynamicGlobalObject); 341 return globalData().dynamicGlobalObject; 342 } 343 333 344 } // namespace JSC 334 345
Note: See TracChangeset
for help on using the changeset viewer.