Changeset 27028 in webkit for trunk/JavaScriptCore
- Timestamp:
- Oct 25, 2007, 1:11:31 AM (18 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r27027 r27028 1 2007-10-25 Geoffrey Garen <[email protected]> 2 3 Reviewed by Maciej Stachowiak. 4 5 Make a fast path for declaration processing inside Function Code. 6 7 Lifted declaration processing code up from individual declaration nodes 8 and into processDeclarations. 9 10 Broke out processDeclarations into two cases, depending on the type of 11 code. This eliminates 2 branches, and facilitates more radical 12 divergeance in the future. 13 14 2.5% SunSpider speedup. 15 16 * JavaScriptCore.xcodeproj/project.pbxproj: 17 * kjs/nodes.cpp: 18 (KJS::FunctionBodyNode::initializeDeclarationStacks): 19 (KJS::FunctionBodyNode::processDeclarationsFunctionCode): 20 (KJS::FunctionBodyNode::processDeclarationsProgramCode): 21 (KJS::FunctionBodyNode::execute): 22 (KJS::FuncDeclNode::makeFunction): 23 * kjs/nodes.h: 24 (KJS::): 25 1 26 2007-10-25 Maciej Stachowiak <[email protected]> 2 27 -
trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r27026 r27028 1380 1380 isa = PBXProject; 1381 1381 buildConfigurationList = 149C277108902AFE008A9EFC /* Build configuration list for PBXProject "JavaScriptCore" */; 1382 compatibilityVersion = "Xcode 2.4"; 1382 1383 hasScannedForEncodings = 1; 1383 1384 mainGroup = 0867D691FE84028FC02AAC07 /* JavaScriptCore */; -
trunk/JavaScriptCore/kjs/nodes.cpp
r27027 r27028 1850 1850 } 1851 1851 1852 void VarDeclNode::processDeclaration(ExecState* exec)1853 {1854 Context* context = exec->context();1855 JSObject* variable = context->variableObject();1856 1857 if (context->codeType() != FunctionCode)1858 if (variable->hasProperty(exec, ident))1859 return;1860 1861 int flags = Internal;1862 if (context->codeType() != EvalCode)1863 flags |= DontDelete;1864 if (varType == VarDeclNode::Constant)1865 flags |= ReadOnly;1866 variable->put(exec, ident, jsUndefined(), flags);1867 }1868 1869 1852 // ------------------------------ VarDeclListNode ------------------------------ 1870 1853 … … 2628 2611 } 2629 2612 2630 void FunctionBodyNode::processDeclarations(ExecState* exec) 2631 { 2632 if (!m_initializedDeclarationStacks) 2633 initializeDeclarationStacks(exec); 2634 2613 void FunctionBodyNode::processDeclarationsFunctionCode(ExecState* exec) 2614 { 2635 2615 size_t i, size; 2636 2616 2637 JSObject* variableObject = exec->context()->variableObject();2638 const List& args = *exec->context()->arguments();2617 Context* context = exec->context(); 2618 JSObject* variableObject = context->variableObject(); 2639 2619 2640 2620 // The order of additions to the variable object here implicitly enforces the mutual exclusion described in ECMA 10.1.3. 2641 for (i = 0, size = m_varStack.size(); i < size; ++i) 2642 m_varStack[i]->processDeclaration(exec); 2643 2621 for (i = 0, size = m_varStack.size(); i < size; ++i) { 2622 VarDeclNode* node = m_varStack[i]; 2623 int flags = Internal | DontDelete; 2624 if (node->varType == VarDeclNode::Constant) 2625 flags |= ReadOnly; 2626 variableObject->put(exec, node->ident, jsUndefined(), flags); 2627 } 2628 2629 const List& args = *context->arguments(); 2644 2630 for (i = 0, size = m_parameters.size(); i < size; ++i) 2645 2631 variableObject->put(exec, m_parameters[i], args[i], DontDelete); 2646 2632 2647 for (i = 0, size = m_functionStack.size(); i < size; ++i) 2648 m_functionStack[i]->processDeclaration(exec); 2633 for (i = 0, size = m_functionStack.size(); i < size; ++i) { 2634 FuncDeclNode* node = m_functionStack[i]; 2635 variableObject->put(exec, node->ident, node->makeFunction(exec), Internal | DontDelete); 2636 } 2637 } 2638 2639 void FunctionBodyNode::processDeclarationsProgramCode(ExecState* exec) 2640 { 2641 size_t i, size; 2642 2643 Context* context = exec->context(); 2644 JSObject* variableObject = context->variableObject(); 2645 2646 // The order of additions to the variable object here implicitly enforces the mutual exclusion described in ECMA 10.1.3. 2647 for (i = 0, size = m_varStack.size(); i < size; ++i) { 2648 VarDeclNode* node = m_varStack[i]; 2649 if (!variableObject->hasProperty(exec, node->ident)) { 2650 int flags = Internal; 2651 if (context->codeType() != EvalCode) 2652 flags |= DontDelete; 2653 if (node->varType == VarDeclNode::Constant) 2654 flags |= ReadOnly; 2655 variableObject->put(exec, node->ident, jsUndefined(), flags); 2656 } 2657 } 2658 2659 const List& args = *context->arguments(); 2660 for (i = 0, size = m_parameters.size(); i < size; ++i) 2661 variableObject->put(exec, m_parameters[i], args[i], DontDelete); 2662 2663 for (i = 0, size = m_functionStack.size(); i < size; ++i) { 2664 FuncDeclNode* node = m_functionStack[i]; 2665 variableObject->put(exec, node->ident, node->makeFunction(exec), Internal | (context->codeType() == EvalCode ? 0 : DontDelete)); 2666 } 2649 2667 } 2650 2668 … … 2667 2685 } 2668 2686 2687 void FunctionBodyNode::processDeclarations(ExecState* exec) 2688 { 2689 if (!m_initializedDeclarationStacks) 2690 initializeDeclarationStacks(exec); 2691 2692 if (exec->context()->codeType() == FunctionCode) 2693 processDeclarationsFunctionCode(exec); 2694 else 2695 processDeclarationsProgramCode(exec); 2696 } 2697 2669 2698 Completion FunctionBodyNode::execute(ExecState* exec) 2670 2699 { … … 2686 2715 } 2687 2716 2688 void FuncDeclNode::processDeclaration(ExecState* exec) 2689 { 2690 Context *context = exec->context(); 2691 2692 // TODO: let this be an object with [[Class]] property "Function" 2693 FunctionImp *func = new FunctionImp(exec, ident, body.get(), context->scopeChain()); 2717 FunctionImp* FuncDeclNode::makeFunction(ExecState* exec) 2718 { 2719 FunctionImp *func = new FunctionImp(exec, ident, body.get(), exec->context()->scopeChain()); 2694 2720 2695 2721 JSObject *proto = exec->lexicalInterpreter()->builtinObject()->construct(exec, List::empty()); … … 2698 2724 2699 2725 func->put(exec, exec->propertyNames().length, jsNumber(body->numParams()), ReadOnly|DontDelete|DontEnum); 2700 2701 // ECMA 10.2.2 2702 context->variableObject()->put(exec, ident, func, Internal | (context->codeType() == EvalCode ? 0 : DontDelete)); 2726 return func; 2703 2727 } 2704 2728 -
trunk/JavaScriptCore/kjs/nodes.h
r27025 r27028 1005 1005 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1006 1006 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1007 ALWAYS_INLINE void processDeclaration(ExecState*) KJS_FAST_CALL;1008 1007 virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL; 1009 private:1010 JSValue* handleSlowCase(ExecState*, const ScopeChain&, JSValue*) KJS_FAST_CALL KJS_NO_INLINE;1011 1008 Type varType; 1012 1009 Identifier ident; 1010 private: 1011 JSValue* handleSlowCase(ExecState*, const ScopeChain&, JSValue*) KJS_FAST_CALL KJS_NO_INLINE; 1013 1012 RefPtr<AssignExprNode> init; 1014 1013 }; … … 1242 1241 UString paramString() const KJS_FAST_CALL; 1243 1242 Vector<Identifier>& parameters() KJS_FAST_CALL { return m_parameters; } 1244 ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL; 1243 ALWAYS_INLINE void processDeclarations(ExecState*); 1244 ALWAYS_INLINE void processDeclarationsFunctionCode(ExecState*); 1245 ALWAYS_INLINE void processDeclarationsProgramCode(ExecState*); 1245 1246 private: 1246 1247 UString m_sourceURL; … … 1250 1251 bool m_initializedDeclarationStacks; 1251 1252 1253 // Properties that will go into the ActivationImp's symbol table. (Used for initializing the ActivationImp.) 1252 1254 DeclarationStacks::VarStack m_varStack; 1253 1255 DeclarationStacks::FunctionStack m_functionStack; … … 1279 1281 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1280 1282 virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL; 1281 ALWAYS_INLINE void processDeclaration(ExecState*) KJS_FAST_CALL; 1283 ALWAYS_INLINE FunctionImp* makeFunction(ExecState*) KJS_FAST_CALL; 1284 Identifier ident; 1282 1285 private: 1283 1286 void addParams() KJS_FAST_CALL; 1284 Identifier ident;1285 1287 RefPtr<ParameterNode> param; 1286 1288 RefPtr<FunctionBodyNode> body;
Note:
See TracChangeset
for help on using the changeset viewer.