Changeset 127393 in webkit
- Timestamp:
- Sep 2, 2012 2:27:23 PM (12 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r127376 r127393 1 2012-09-02 Geoffrey Garen <ggaren@apple.com> 2 3 Refactored scope chain opcodes to support optimization for named function expressions 4 https://bugs.webkit.org/show_bug.cgi?id=95658 5 6 Reviewed by Sam Weinig. 7 8 Renamed 9 push_scope => push_with_scope 10 push_new_scope => push_name_scope 11 to clarify the difference between them. 12 13 Changed push_with_scope and push_name_scope not to save the new scope in 14 a temporary register, since doing so made optimization harder. 15 16 (The old behavior was a hold-over from when the scope chain wasn't 17 a GC object, and wouldn't be marked otherwise. Now, the scope chain is 18 marked because it is a GC object pointed to by the call frame.) 19 20 Changed push_name_scope to accept an operand specifying the attributes 21 for the named property, instead of assuming DontDelete, because a named 22 function expression needs ReadOnly|DontDelete. 23 24 * bytecompiler/BytecodeGenerator.cpp: 25 (JSC::BytecodeGenerator::highestUsedRegister): Removed this function, 26 which used to be related to preserving saved scope object temporaries, 27 because it had no callers. 28 1 29 2012-09-01 Geoffrey Garen <ggaren@apple.com> 2 30 -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r127374 r127393 1480 1480 break; 1481 1481 } 1482 case op_push_ scope: {1483 int r0 = (++it)->u.operand; 1484 dataLog("[%4d] push_ scope\t %s", location, registerName(exec, r0).data());1482 case op_push_with_scope: { 1483 int r0 = (++it)->u.operand; 1484 dataLog("[%4d] push_with_scope\t %s", location, registerName(exec, r0).data()); 1485 1485 dumpBytecodeCommentAndNewLine(location); 1486 1486 break; … … 1491 1491 break; 1492 1492 } 1493 case op_push_new_scope: { 1494 int r0 = (++it)->u.operand; 1493 case op_push_name_scope: { 1495 1494 int id0 = (++it)->u.operand; 1496 1495 int r1 = (++it)->u.operand; 1497 dataLog("[%4d] push_new_scope \t%s, %s, %s", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data()); 1496 unsigned attributes = (++it)->u.operand; 1497 dataLog("[%4d] push_name_scope \t%s, %s, %u", location, idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data(), attributes); 1498 1498 dumpBytecodeCommentAndNewLine(location); 1499 1499 break; -
trunk/Source/JavaScriptCore/bytecode/Opcode.h
r127199 r127393 189 189 macro(op_next_pname, 7) \ 190 190 \ 191 macro(op_push_ scope, 2) \191 macro(op_push_with_scope, 2) \ 192 192 macro(op_pop_scope, 1) \ 193 macro(op_push_n ew_scope, 4) \193 macro(op_push_name_scope, 4) \ 194 194 \ 195 195 macro(op_catch, 2) \ -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r127202 r127393 641 641 result->setTemporary(); 642 642 return result; 643 }644 645 RegisterID* BytecodeGenerator::highestUsedRegister()646 {647 size_t count = m_codeBlock->m_numCalleeRegisters;648 while (m_calleeRegisters.size() < count)649 newRegister();650 return &m_calleeRegisters.last();651 643 } 652 644 … … 2094 2086 } 2095 2087 2096 RegisterID* BytecodeGenerator::emitPushScope(RegisterID* scope) 2097 { 2098 ASSERT(scope->isTemporary()); 2088 RegisterID* BytecodeGenerator::emitPushWithScope(RegisterID* scope) 2089 { 2099 2090 ControlFlowContext context; 2100 2091 context.isFinallyBlock = false; … … 2102 2093 m_dynamicScopeDepth++; 2103 2094 2104 return emitUnaryNoDstOp(op_push_ scope, scope);2095 return emitUnaryNoDstOp(op_push_with_scope, scope); 2105 2096 } 2106 2097 … … 2453 2444 } 2454 2445 2455 void BytecodeGenerator::emitPushN ewScope(RegisterID* dst, const Identifier& property, RegisterID* value)2446 void BytecodeGenerator::emitPushNameScope(const Identifier& property, RegisterID* value, unsigned attributes) 2456 2447 { 2457 2448 ControlFlowContext context; … … 2460 2451 m_dynamicScopeDepth++; 2461 2452 2462 emitOpcode(op_push_new_scope); 2463 instructions().append(dst->index()); 2453 emitOpcode(op_push_name_scope); 2464 2454 instructions().append(addConstant(property)); 2465 2455 instructions().append(value->index()); 2456 instructions().append(attributes); 2466 2457 } 2467 2458 -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r127202 r127393 297 297 RegisterID* newTemporary(); 298 298 299 RegisterID* highestUsedRegister();300 301 299 // The same as newTemporary(), but this function returns "suggestion" if 302 300 // "suggestion" is a temporary. This function is helpful in situations … … 523 521 void emitThrowReferenceError(const String& message); 524 522 525 void emitPushN ewScope(RegisterID* dst, const Identifier& property, RegisterID* value);526 527 RegisterID* emitPush Scope(RegisterID* scope);523 void emitPushNameScope(const Identifier& property, RegisterID* value, unsigned attributes); 524 525 RegisterID* emitPushWithScope(RegisterID* scope); 528 526 void emitPopScope(); 529 527 -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r127191 r127393 1757 1757 { 1758 1758 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column()); 1759 1760 RefPtr<RegisterID> scope = generator.newTemporary(); 1761 generator.emitNode(scope.get(), m_expr); // scope must be protected until popped 1759 1760 RefPtr<RegisterID> scope = generator.emitNode(m_expr); 1762 1761 generator.emitExpressionInfo(m_divot, m_expressionLength, 0); 1763 generator.emitPush Scope(scope.get());1762 generator.emitPushWithScope(scope.get()); 1764 1763 RegisterID* result = generator.emitNode(dst, m_statement); 1765 1764 generator.emitPopScope(); … … 1997 1996 } 1998 1997 1999 generator.emitPushN ewScope(exceptionRegister.get(), m_exceptionIdent, exceptionRegister.get());1998 generator.emitPushNameScope(m_exceptionIdent, exceptionRegister.get(), DontDelete); 2000 1999 generator.emitNode(dst, m_catchBlock); 2001 2000 generator.emitPopScope(); -
trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp
r127374 r127393 1427 1427 1428 1428 #if ENABLE(CLASSIC_INTERPRETER) 1429 NEVER_INLINE JSScope* Interpreter::create ExceptionScope(CallFrame* callFrame, const Instruction* vPC)1429 NEVER_INLINE JSScope* Interpreter::createNameScope(CallFrame* callFrame, const Instruction* vPC) 1430 1430 { 1431 int dst = vPC[1].u.operand;1432 1431 CodeBlock* codeBlock = callFrame->codeBlock(); 1433 Identifier& property = codeBlock->identifier(vPC[ 2].u.operand);1434 JSValue value = callFrame->r(vPC[ 3].u.operand).jsValue();1435 JSNameScope* scope = JSNameScope::create(callFrame, property, value, DontDelete);1436 callFrame->uncheckedR(dst) = JSValue(scope);1432 Identifier& property = codeBlock->identifier(vPC[1].u.operand); 1433 JSValue value = callFrame->r(vPC[2].u.operand).jsValue(); 1434 unsigned attributes = vPC[3].u.operand; 1435 JSNameScope* scope = JSNameScope::create(callFrame, property, value, attributes); 1437 1436 return scope; 1438 1437 } … … 4815 4814 NEXT_INSTRUCTION(); 4816 4815 } 4817 DEFINE_OPCODE(op_push_ scope) {4818 /* push_ scope scope(r)4816 DEFINE_OPCODE(op_push_with_scope) { 4817 /* push_with_scope scope(r) 4819 4818 4820 4819 Converts register scope to object, and pushes it onto the top 4821 of the current scope chain. The contents of the register scope 4822 are replaced by the result of toObject conversion of the scope. 4820 of the scope chain. 4823 4821 */ 4824 4822 int scope = vPC[1].u.operand; … … 4827 4825 CHECK_FOR_EXCEPTION(); 4828 4826 4829 callFrame->uncheckedR(scope) = JSValue(o);4830 4827 callFrame->setScope(JSWithScope::create(callFrame, o)); 4831 4828 4832 vPC += OPCODE_LENGTH(op_push_ scope);4829 vPC += OPCODE_LENGTH(op_push_with_scope); 4833 4830 NEXT_INSTRUCTION(); 4834 4831 } … … 4928 4925 goto *(&&skip_new_scope); 4929 4926 #endif 4930 DEFINE_OPCODE(op_push_n ew_scope) {4931 /* new_scope dst(r) property(id) value(r)4927 DEFINE_OPCODE(op_push_name_scope) { 4928 /* new_scope property(id) value(r) attributes(unsigned) 4932 4929 4933 Constructs a new NameScopeObject with property set to value. That scope 4934 object is then pushed onto the ScopeChain. The scope object is then stored 4935 in dst for GC. 4930 Constructs a name scope of the form { property<attributes>: value }, 4931 and pushes it onto the scope chain. 4936 4932 */ 4937 callFrame->setScope(create ExceptionScope(callFrame, vPC));4938 4939 vPC += OPCODE_LENGTH(op_push_n ew_scope);4933 callFrame->setScope(createNameScope(callFrame, vPC)); 4934 4935 vPC += OPCODE_LENGTH(op_push_name_scope); 4940 4936 NEXT_INSTRUCTION(); 4941 4937 } -
trunk/Source/JavaScriptCore/jit/JIT.cpp
r126926 r127393 319 319 DEFINE_OP(op_profile_did_call) 320 320 DEFINE_OP(op_profile_will_call) 321 DEFINE_OP(op_push_n ew_scope)322 DEFINE_OP(op_push_ scope)321 DEFINE_OP(op_push_name_scope) 322 DEFINE_OP(op_push_with_scope) 323 323 case op_put_by_id_out_of_line: 324 324 case op_put_by_id_transition_direct: -
trunk/Source/JavaScriptCore/jit/JIT.h
r127202 r127393 672 672 void emit_op_profile_did_call(Instruction*); 673 673 void emit_op_profile_will_call(Instruction*); 674 void emit_op_push_n ew_scope(Instruction*);675 void emit_op_push_ scope(Instruction*);674 void emit_op_push_name_scope(Instruction*); 675 void emit_op_push_with_scope(Instruction*); 676 676 void emit_op_put_by_id(Instruction*); 677 677 void emit_op_put_by_index(Instruction*); -
trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp
r127345 r127393 1004 1004 } 1005 1005 1006 void JIT::emit_op_push_ scope(Instruction* currentInstruction)1007 { 1008 JITStubCall stubCall(this, cti_op_push_ scope);1006 void JIT::emit_op_push_with_scope(Instruction* currentInstruction) 1007 { 1008 JITStubCall stubCall(this, cti_op_push_with_scope); 1009 1009 stubCall.addArgument(currentInstruction[1].u.operand, regT2); 1010 1010 stubCall.call(currentInstruction[1].u.operand); … … 1073 1073 } 1074 1074 1075 void JIT::emit_op_push_new_scope(Instruction* currentInstruction) 1076 { 1077 JITStubCall stubCall(this, cti_op_push_new_scope); 1078 stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand))); 1079 stubCall.addArgument(currentInstruction[3].u.operand, regT2); 1080 stubCall.call(currentInstruction[1].u.operand); 1075 void JIT::emit_op_push_name_scope(Instruction* currentInstruction) 1076 { 1077 JITStubCall stubCall(this, cti_op_push_name_scope); 1078 stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[1].u.operand))); 1079 stubCall.addArgument(currentInstruction[2].u.operand, regT2); 1080 stubCall.addArgument(TrustedImm32(currentInstruction[3].u.operand)); 1081 stubCall.call(); 1081 1082 } 1082 1083 -
trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
r127202 r127393 1359 1359 } 1360 1360 1361 void JIT::emit_op_push_ scope(Instruction* currentInstruction)1362 { 1363 JITStubCall stubCall(this, cti_op_push_ scope);1361 void JIT::emit_op_push_with_scope(Instruction* currentInstruction) 1362 { 1363 JITStubCall stubCall(this, cti_op_push_with_scope); 1364 1364 stubCall.addArgument(currentInstruction[1].u.operand); 1365 1365 stubCall.call(currentInstruction[1].u.operand); … … 1398 1398 } 1399 1399 1400 void JIT::emit_op_push_new_scope(Instruction* currentInstruction) 1401 { 1402 JITStubCall stubCall(this, cti_op_push_new_scope); 1403 stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand))); 1404 stubCall.addArgument(currentInstruction[3].u.operand); 1405 stubCall.call(currentInstruction[1].u.operand); 1400 void JIT::emit_op_push_name_scope(Instruction* currentInstruction) 1401 { 1402 JITStubCall stubCall(this, cti_op_push_name_scope); 1403 stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[1].u.operand))); 1404 stubCall.addArgument(currentInstruction[2].u.operand); 1405 stubCall.addArgument(TrustedImm32(currentInstruction[3].u.operand)); 1406 stubCall.call(); 1406 1407 } 1407 1408 -
trunk/Source/JavaScriptCore/jit/JITStubs.cpp
r127349 r127393 3142 3142 } 3143 3143 3144 DEFINE_STUB_FUNCTION(JSObject*, op_push_ scope)3144 DEFINE_STUB_FUNCTION(JSObject*, op_push_with_scope) 3145 3145 { 3146 3146 STUB_INIT_STACK_FRAME(stackFrame); … … 3259 3259 } 3260 3260 3261 DEFINE_STUB_FUNCTION( JSObject*, op_push_new_scope)3262 { 3263 STUB_INIT_STACK_FRAME(stackFrame); 3264 3265 JSNameScope* scope = JSNameScope::create(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.args[1].jsValue(), DontDelete);3261 DEFINE_STUB_FUNCTION(void, op_push_name_scope) 3262 { 3263 STUB_INIT_STACK_FRAME(stackFrame); 3264 3265 JSNameScope* scope = JSNameScope::create(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.args[1].jsValue(), stackFrame.args[2].int32()); 3266 3266 3267 3267 CallFrame* callFrame = stackFrame.callFrame; 3268 3268 callFrame->setScope(scope); 3269 return scope;3270 3269 } 3271 3270 -
trunk/Source/JavaScriptCore/jit/JITStubs.h
r127374 r127393 418 418 JSObject* JIT_STUB cti_op_new_regexp(STUB_ARGS_DECLARATION) WTF_INTERNAL; 419 419 JSObject* JIT_STUB cti_op_push_activation(STUB_ARGS_DECLARATION) WTF_INTERNAL; 420 JSObject* JIT_STUB cti_op_push_new_scope(STUB_ARGS_DECLARATION) WTF_INTERNAL;421 JSObject* JIT_STUB cti_op_push_ scope(STUB_ARGS_DECLARATION) WTF_INTERNAL;420 void JIT_STUB cti_op_push_name_scope(STUB_ARGS_DECLARATION) WTF_INTERNAL; 421 JSObject* JIT_STUB cti_op_push_with_scope(STUB_ARGS_DECLARATION) WTF_INTERNAL; 422 422 JSObject* JIT_STUB cti_op_put_by_id_transition_realloc(STUB_ARGS_DECLARATION) WTF_INTERNAL; 423 423 JSPropertyNameIterator* JIT_STUB cti_op_get_pnames(STUB_ARGS_DECLARATION) WTF_INTERNAL; -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r127349 r127393 1531 1531 } 1532 1532 1533 LLINT_SLOW_PATH_DECL(slow_path_push_ scope)1534 { 1535 LLINT_BEGIN(); 1536 JSValue v = LLINT_OP (1).jsValue();1533 LLINT_SLOW_PATH_DECL(slow_path_push_with_scope) 1534 { 1535 LLINT_BEGIN(); 1536 JSValue v = LLINT_OP_C(1).jsValue(); 1537 1537 JSObject* o = v.toObject(exec); 1538 1538 LLINT_CHECK_EXCEPTION(); 1539 1539 1540 LLINT_OP(1) = o;1541 1540 exec->setScope(JSWithScope::create(exec, o)); 1542 1541 … … 1551 1550 } 1552 1551 1553 LLINT_SLOW_PATH_DECL(slow_path_push_n ew_scope)1552 LLINT_SLOW_PATH_DECL(slow_path_push_name_scope) 1554 1553 { 1555 1554 LLINT_BEGIN(); 1556 1555 CodeBlock* codeBlock = exec->codeBlock(); 1557 JSNameScope* scope = JSNameScope::create(exec, codeBlock->identifier(pc[ 2].u.operand), LLINT_OP(3).jsValue(), DontDelete);1556 JSNameScope* scope = JSNameScope::create(exec, codeBlock->identifier(pc[1].u.operand), LLINT_OP(2).jsValue(), pc[3].u.operand); 1558 1557 exec->setScope(scope); 1559 LLINT_ RETURN(scope);1558 LLINT_END(); 1560 1559 } 1561 1560 -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h
r127333 r127393 203 203 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_pnames); 204 204 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_next_pname); 205 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_push_ scope);205 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_push_with_scope); 206 206 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_pop_scope); 207 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_push_n ew_scope);207 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_push_name_scope); 208 208 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_throw); 209 209 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_throw_reference_error); -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
r127374 r127393 774 774 775 775 776 _llint_op_push_ scope:777 traceExecution() 778 callSlowPath(_llint_slow_path_push_ scope)776 _llint_op_push_with_scope: 777 traceExecution() 778 callSlowPath(_llint_slow_path_push_with_scope) 779 779 dispatch(2) 780 780 … … 786 786 787 787 788 _llint_op_push_n ew_scope:789 traceExecution() 790 callSlowPath(_llint_slow_path_push_n ew_scope)788 _llint_op_push_name_scope: 789 traceExecution() 790 callSlowPath(_llint_slow_path_push_name_scope) 791 791 dispatch(4) 792 792
Note: See TracChangeset
for help on using the changeset viewer.