Changeset 36317 in webkit for trunk/JavaScriptCore
- Timestamp:
- Sep 10, 2008, 2:23:35 AM (17 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r36316 r36317 1 2008-09-09 Oliver Hunt <[email protected]> 2 3 Reviewed by Maciej Stachowiak. 4 5 Add optimised access to known properties on the global object. 6 7 Improve cross scope access to the global object by emitting 8 code to access it directly rather than by walking the scope chain. 9 10 This is a 0.8% win in SunSpider and a 1.7% win in the v8 benchmarks. 11 12 * VM/CTI.cpp: 13 (JSC::CTI::privateCompileMainPass): 14 (JSC::CTI::emitGetVariableObjectRegister): 15 (JSC::CTI::emitPutVariableObjectRegister): 16 * VM/CTI.h: 17 * VM/CodeBlock.cpp: 18 (JSC::CodeBlock::dump): 19 * VM/CodeGenerator.cpp: 20 (JSC::CodeGenerator::findScopedProperty): 21 (JSC::CodeGenerator::emitResolve): 22 (JSC::CodeGenerator::emitGetScopedVar): 23 (JSC::CodeGenerator::emitPutScopedVar): 24 * VM/CodeGenerator.h: 25 * VM/Machine.cpp: 26 (JSC::Machine::privateExecute): 27 * VM/Opcode.h: 28 * kjs/nodes.cpp: 29 (JSC::FunctionCallResolveNode::emitCode): 30 (JSC::PostfixResolveNode::emitCode): 31 (JSC::PrefixResolveNode::emitCode): 32 (JSC::ReadModifyResolveNode::emitCode): 33 (JSC::AssignResolveNode::emitCode): 34 1 35 2008-09-10 Maciej Stachowiak <[email protected]> 2 36 -
trunk/JavaScriptCore/VM/CTI.cpp
r36316 r36317 629 629 break; 630 630 } 631 case op_get_global_var: { 632 JSVariableObject* globalObject = static_cast<JSVariableObject*>(instruction[i + 2].u.jsCell); 633 m_jit.movl_i32r(reinterpret_cast<unsigned>(globalObject), X86::eax); 634 emitGetVariableObjectRegister(X86::eax, instruction[i + 3].u.operand, X86::eax); 635 emitPutResult(instruction[i + 1].u.operand, X86::eax); 636 i += 4; 637 break; 638 } 639 case op_put_global_var: { 640 JSVariableObject* globalObject = static_cast<JSVariableObject*>(instruction[i + 1].u.jsCell); 641 m_jit.movl_i32r(reinterpret_cast<unsigned>(globalObject), X86::eax); 642 emitGetArg(instruction[i + 3].u.operand, X86::edx); 643 emitPutVariableObjectRegister(X86::edx, X86::eax, instruction[i + 2].u.operand); 644 i += 4; 645 break; 646 } 631 647 case op_get_scoped_var: { 632 648 int skip = instruction[i + 3].u.operand + m_codeBlock->needsFullScopeChain; … … 637 653 638 654 m_jit.movl_mr(OBJECT_OFFSET(ScopeChainNode, object), X86::eax, X86::eax); 639 m_jit.movl_mr(JSVariableObject::offsetOf_d(), X86::eax, X86::eax); 640 m_jit.movl_mr(JSVariableObject::offsetOf_Data_registers(), X86::eax, X86::eax); 641 m_jit.movl_mr((instruction[i + 2].u.operand) * sizeof(Register), X86::eax, X86::eax); 655 emitGetVariableObjectRegister(X86::eax, instruction[i + 2].u.operand, X86::eax); 642 656 emitPutResult(instruction[i + 1].u.operand); 643 657 i += 4; … … 653 667 654 668 m_jit.movl_mr(OBJECT_OFFSET(ScopeChainNode, object), X86::edx, X86::edx); 655 m_jit.movl_mr(JSVariableObject::offsetOf_d(), X86::edx, X86::edx); 656 m_jit.movl_mr(JSVariableObject::offsetOf_Data_registers(), X86::edx, X86::edx); 657 m_jit.movl_rm(X86::eax, (instruction[i + 1].u.operand) * sizeof(Register), X86::edx); 669 emitPutVariableObjectRegister(X86::eax, X86::edx, instruction[i + 1].u.operand); 658 670 i += 4; 659 671 break; … … 1831 1843 } 1832 1844 1845 void CTI::emitGetVariableObjectRegister(X86Assembler::RegisterID variableObject, int index, X86Assembler::RegisterID dst) 1846 { 1847 m_jit.movl_mr(JSVariableObject::offsetOf_d(), variableObject, dst); 1848 m_jit.movl_mr(JSVariableObject::offsetOf_Data_registers(), dst, dst); 1849 m_jit.movl_mr(index * sizeof(Register), dst, dst); 1850 } 1851 1852 void CTI::emitPutVariableObjectRegister(X86Assembler::RegisterID src, X86Assembler::RegisterID variableObject, int index) 1853 { 1854 m_jit.movl_mr(JSVariableObject::offsetOf_d(), variableObject, variableObject); 1855 m_jit.movl_mr(JSVariableObject::offsetOf_Data_registers(), variableObject, variableObject); 1856 m_jit.movl_rm(src, index * sizeof(Register), variableObject); 1857 } 1858 1833 1859 #if ENABLE(WREC) 1834 1860 -
trunk/JavaScriptCore/VM/CTI.h
r36316 r36317 330 330 void emitCall(unsigned opcodeIndex, CTIHelper_v); 331 331 void emitCall(unsigned opcodeIndex, CTIHelper_s); 332 332 333 void emitGetVariableObjectRegister(X86Assembler::RegisterID variableObject, int index, X86Assembler::RegisterID dst); 334 void emitPutVariableObjectRegister(X86Assembler::RegisterID src, X86Assembler::RegisterID variableObject, int index); 335 333 336 void emitSlowScriptCheck(unsigned opcodeIndex); 334 337 #ifndef NDEBUG -
trunk/JavaScriptCore/VM/CodeBlock.cpp
r36263 r36317 523 523 break; 524 524 } 525 case op_get_global_var: { 526 int r0 = (++it)->u.operand; 527 JSValue* scope = static_cast<JSValue*>((++it)->u.jsCell); 528 int index = (++it)->u.operand; 529 printf("[%4d] get_global_var\t %s, %s, %d\n", location, registerName(r0).c_str(), valueToSourceString(exec, scope).ascii(), index); 530 break; 531 } 532 case op_put_global_var: { 533 JSValue* scope = static_cast<JSValue*>((++it)->u.jsCell); 534 int index = (++it)->u.operand; 535 int r0 = (++it)->u.operand; 536 printf("[%4d] put_global_var\t %s, %d, %s\n", location, valueToSourceString(exec, scope).ascii(), index, registerName(r0).c_str()); 537 break; 538 } 525 539 case op_resolve_base: { 526 540 int r0 = (++it)->u.operand; -
trunk/JavaScriptCore/VM/CodeGenerator.cpp
r36263 r36317 678 678 } 679 679 680 bool CodeGenerator::findScopedProperty(const Identifier& property, int& index, size_t& stackDepth, bool forWriting )680 bool CodeGenerator::findScopedProperty(const Identifier& property, int& index, size_t& stackDepth, bool forWriting, JSValue*& globalObject) 681 681 { 682 682 // Cases where we cannot optimise the lookup … … 703 703 stackDepth = 0; 704 704 index = missingSymbolMarker(); 705 if (++iter == end) 706 globalObject = currentVariableObject; 705 707 return false; 706 708 } 707 709 stackDepth = depth; 708 710 index = entry.getIndex(); 711 if (++iter == end) 712 globalObject = currentVariableObject; 709 713 return true; 710 714 } … … 716 720 stackDepth = depth; 717 721 index = missingSymbolMarker(); 722 JSObject* scope = *iter; 723 if (++iter == end) 724 globalObject = scope; 718 725 return true; 719 726 } … … 723 730 size_t depth = 0; 724 731 int index = 0; 725 if (!findScopedProperty(property, index, depth, false)) { 732 JSValue* globalObject = 0; 733 if (!findScopedProperty(property, index, depth, false, globalObject)) { 726 734 // We can't optimise at all :-( 727 735 emitOpcode(op_resolve); … … 742 750 743 751 // Directly index the property lookup across multiple scopes. Yay! 744 return emitGetScopedVar(dst, depth, index); 745 } 746 747 RegisterID* CodeGenerator::emitGetScopedVar(RegisterID* dst, size_t depth, int index) 748 { 752 return emitGetScopedVar(dst, depth, index, globalObject); 753 } 754 755 RegisterID* CodeGenerator::emitGetScopedVar(RegisterID* dst, size_t depth, int index, JSValue* globalObject) 756 { 757 if (globalObject) { 758 emitOpcode(op_get_global_var); 759 instructions().append(dst->index()); 760 instructions().append(static_cast<JSCell*>(globalObject)); 761 instructions().append(index); 762 return dst; 763 } 764 749 765 emitOpcode(op_get_scoped_var); 750 766 instructions().append(dst->index()); … … 754 770 } 755 771 756 RegisterID* CodeGenerator::emitPutScopedVar(size_t depth, int index, RegisterID* value) 757 { 772 RegisterID* CodeGenerator::emitPutScopedVar(size_t depth, int index, RegisterID* value, JSValue* globalObject) 773 { 774 if (globalObject) { 775 emitOpcode(op_put_global_var); 776 instructions().append(static_cast<JSCell*>(globalObject)); 777 instructions().append(index); 778 instructions().append(value->index()); 779 return value; 780 } 758 781 emitOpcode(op_put_scoped_var); 759 782 instructions().append(index); -
trunk/JavaScriptCore/VM/CodeGenerator.h
r36263 r36317 104 104 // NB: depth does _not_ include the local scope. eg. a depth of 0 refers 105 105 // to the scope containing this codeblock. 106 bool findScopedProperty(const Identifier&, int& index, size_t& depth, bool forWriting );106 bool findScopedProperty(const Identifier&, int& index, size_t& depth, bool forWriting, JSValue*& globalObject); 107 107 108 108 // Returns the register storing "this" … … 257 257 258 258 RegisterID* emitResolve(RegisterID* dst, const Identifier& property); 259 RegisterID* emitGetScopedVar(RegisterID* dst, size_t skip, int index );260 RegisterID* emitPutScopedVar(size_t skip, int index, RegisterID* value );259 RegisterID* emitGetScopedVar(RegisterID* dst, size_t skip, int index, JSValue* globalObject); 260 RegisterID* emitPutScopedVar(size_t skip, int index, RegisterID* value, JSValue* globalObject); 261 261 262 262 RegisterID* emitResolveBase(RegisterID* dst, const Identifier& property); -
trunk/JavaScriptCore/VM/Machine.cpp
r36316 r36317 2087 2087 NEXT_OPCODE; 2088 2088 } 2089 BEGIN_OPCODE(op_get_global_var) { 2090 /* get_global_var dst(r) index(n) 2091 2092 Gets the global var at global slot index and places it in register dst. 2093 */ 2094 int dst = (++vPC)->u.operand; 2095 JSGlobalObject* scope = static_cast<JSGlobalObject*>((++vPC)->u.jsCell); 2096 ASSERT(scope->isGlobalObject()); 2097 int index = (++vPC)->u.operand; 2098 2099 r[dst] = scope->registerAt(index); 2100 ++vPC; 2101 NEXT_OPCODE; 2102 } 2103 BEGIN_OPCODE(op_put_global_var) { 2104 /* put_global_var globalObject(c) index(n) value(r) 2105 2106 Puts value into global slot index. 2107 */ 2108 JSGlobalObject* scope = static_cast<JSGlobalObject*>((++vPC)->u.jsCell); 2109 ASSERT(scope->isGlobalObject()); 2110 int index = (++vPC)->u.operand; 2111 int value = (++vPC)->u.operand; 2112 2113 scope->registerAt(index) = r[value].jsValue(exec); 2114 ++vPC; 2115 NEXT_OPCODE; 2116 } 2089 2117 BEGIN_OPCODE(op_get_scoped_var) { 2090 2118 /* get_scoped_var dst(r) index(n) skip(n) -
trunk/JavaScriptCore/VM/Opcode.h
r36263 r36317 85 85 macro(op_get_scoped_var) \ 86 86 macro(op_put_scoped_var) \ 87 macro(op_get_global_var) \ 88 macro(op_put_global_var) \ 87 89 macro(op_resolve_base) \ 88 90 macro(op_resolve_with_base) \ -
trunk/JavaScriptCore/kjs/nodes.cpp
r36270 r36317 433 433 int index = 0; 434 434 size_t depth = 0; 435 if (generator.findScopedProperty(m_ident, index, depth, false) && index != missingSymbolMarker()) { 436 RegisterID* func = generator.emitGetScopedVar(generator.newTemporary(), depth, index); 435 JSValue* globalObject = 0; 436 if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) { 437 RegisterID* func = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject); 437 438 return generator.emitCall(generator.finalDestination(dst), func, 0, m_args.get(), m_divot, m_startOffset, m_endOffset); 438 439 } … … 491 492 int index = 0; 492 493 size_t depth = 0; 493 if (generator.findScopedProperty(m_ident, index, depth, true) && index != missingSymbolMarker()) { 494 RefPtr<RegisterID> value = generator.emitGetScopedVar(generator.newTemporary(), depth, index); 494 JSValue* globalObject = 0; 495 if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) { 496 RefPtr<RegisterID> value = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject); 495 497 RegisterID* oldValue; 496 498 if (dst == ignoredResult()) { … … 500 502 oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator); 501 503 } 502 generator.emitPutScopedVar(depth, index, value.get() );504 generator.emitPutScopedVar(depth, index, value.get(), globalObject); 503 505 return oldValue; 504 506 } … … 674 676 int index = 0; 675 677 size_t depth = 0; 676 if (generator.findScopedProperty(m_ident, index, depth, false) && index != missingSymbolMarker()) { 677 RefPtr<RegisterID> propDst = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index); 678 JSValue* globalObject = 0; 679 if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) { 680 RefPtr<RegisterID> propDst = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject); 678 681 emitPreIncOrDec(generator, propDst.get(), m_operator); 679 generator.emitPutScopedVar(depth, index, propDst.get() );682 generator.emitPutScopedVar(depth, index, propDst.get(), globalObject); 680 683 return generator.moveToDestinationIfNeeded(dst, propDst.get());; 681 684 } … … 885 888 int index = 0; 886 889 size_t depth = 0; 887 if (generator.findScopedProperty(m_ident, index, depth, true) && index != missingSymbolMarker()) { 888 RefPtr<RegisterID> src1 = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index); 890 JSValue* globalObject = 0; 891 if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) { 892 RefPtr<RegisterID> src1 = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject); 889 893 RegisterID* src2 = generator.emitNode(m_right.get()); 890 894 RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator); 891 generator.emitPutScopedVar(depth, index, result );895 generator.emitPutScopedVar(depth, index, result, globalObject); 892 896 return result; 893 897 } … … 916 920 int index = 0; 917 921 size_t depth = 0; 918 if (generator.findScopedProperty(m_ident, index, depth, true) && index != missingSymbolMarker()) { 922 JSValue* globalObject = 0; 923 if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) { 919 924 if (dst == ignoredResult()) 920 925 dst = 0; 921 926 RegisterID* value = generator.emitNode(dst, m_right.get()); 922 generator.emitPutScopedVar(depth, index, value );927 generator.emitPutScopedVar(depth, index, value, globalObject); 923 928 return value; 924 929 }
Note:
See TracChangeset
for help on using the changeset viewer.