Changeset 98405 in webkit
- Timestamp:
- Oct 25, 2011, 4:06:13 PM (15 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 7 edited
-
ChangeLog (modified) (1 diff)
-
dfg/DFGJITCodeGenerator.h (modified) (1 diff)
-
dfg/DFGJITCodeGenerator32_64.cpp (modified) (1 diff)
-
dfg/DFGJITCodeGenerator64.cpp (modified) (1 diff)
-
dfg/DFGJITCompiler.cpp (modified) (3 diffs)
-
dfg/DFGJITCompiler.h (modified) (6 diffs)
-
dfg/DFGJITCompiler32_64.cpp (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r98398 r98405 1 2011-10-25 Gavin Barraclough <barraclough@apple.com> 2 3 Separate out function linking & exception check data structures. 4 https://bugs.webkit.org/show_bug.cgi?id=70858 5 6 Reviewed by Oliver Hunt. 7 8 This will make it easier to refactor the callOperation methods to spilt the value 9 representation specific handling from the cpu/calling-convention implementation. 10 11 * dfg/DFGJITCodeGenerator.h: 12 (JSC::DFG::appendCallWithExceptionCheck): 13 * dfg/DFGJITCodeGenerator32_64.cpp: 14 (JSC::DFG::JITCodeGenerator::emitCall): 15 * dfg/DFGJITCodeGenerator64.cpp: 16 (JSC::DFG::JITCodeGenerator::emitCall): 17 * dfg/DFGJITCompiler.cpp: 18 (JSC::DFG::JITCompiler::compileBody): 19 (JSC::DFG::JITCompiler::link): 20 * dfg/DFGJITCompiler.h: 21 (JSC::DFG::CallLinkRecord::CallLinkRecord): 22 (JSC::DFG::CallExceptionRecord::CallExceptionRecord): 23 (JSC::DFG::JITCompiler::JITCompiler): 24 (JSC::DFG::JITCompiler::notifyCall): 25 (JSC::DFG::JITCompiler::appendCall): 26 (JSC::DFG::JITCompiler::addExceptionCheck): 27 (JSC::DFG::JITCompiler::addFastExceptionCheck): 28 * dfg/DFGJITCompiler32_64.cpp: 29 (JSC::DFG::JITCompiler::compileBody): 30 (JSC::DFG::JITCompiler::link): 31 1 32 2011-10-25 Filip Pizlo <fpizlo@apple.com> 2 33 -
trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.h
r98291 r98405 1551 1551 JITCompiler::Call appendCallWithExceptionCheck(const FunctionPtr& function) 1552 1552 { 1553 return m_jit.a ppendCallWithExceptionCheck(function, at(m_compileIndex).codeOrigin);1553 return m_jit.addExceptionCheck(m_jit.appendCall(function), at(m_compileIndex).codeOrigin); 1554 1554 } 1555 1555 JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, GPRReg result) -
trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator32_64.cpp
r98321 r98405 1366 1366 m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 1367 1367 m_jit.poke(GPRInfo::argumentGPR0); 1368 JITCompiler::Call slowCall = m_jit.a ppendCallWithFastExceptionCheck(slowCallFunction, at(m_compileIndex).codeOrigin);1368 JITCompiler::Call slowCall = m_jit.addFastExceptionCheck(m_jit.appendCall(slowCallFunction), at(m_compileIndex).codeOrigin); 1369 1369 m_jit.move(Imm32(numPassedArgs), GPRInfo::regT1); 1370 1370 m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister); -
trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator64.cpp
r97410 r98405 1312 1312 1313 1313 m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 1314 JITCompiler::Call slowCall = m_jit.a ppendCallWithFastExceptionCheck(slowCallFunction, at(m_compileIndex).codeOrigin);1314 JITCompiler::Call slowCall = m_jit.addFastExceptionCheck(m_jit.appendCall(slowCallFunction), at(m_compileIndex).codeOrigin); 1315 1315 m_jit.move(Imm32(numPassedArgs), GPRInfo::regT1); 1316 1316 m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister); -
trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp
r98179 r98405 611 611 linkOSRExits(speculative); 612 612 613 // Iterate over the m_calls vector, checking for exception checks,614 // and linking them to here.615 for (unsigned i = 0; i < m_ calls.size(); ++i) {616 Jump& exceptionCheck = m_ calls[i].m_exceptionCheck;613 // Iterate over the m_calls vector, checking for jumps to link. 614 bool didLinkExceptionCheck = false; 615 for (unsigned i = 0; i < m_exceptionChecks.size(); ++i) { 616 Jump& exceptionCheck = m_exceptionChecks[i].m_exceptionCheck; 617 617 if (exceptionCheck.isSet()) { 618 618 exceptionCheck.link(this); 619 ++m_exceptionCheckCount; 620 } 621 } 619 didLinkExceptionCheck = true; 620 } 621 } 622 622 623 // If any exception checks were linked, generate code to lookup a handler. 623 if ( m_exceptionCheckCount) {624 if (didLinkExceptionCheck) { 624 625 // lookupExceptionHandler is passed two arguments, exec (the CallFrame*), and 625 626 // an identifier for the operation that threw the exception, which we can use … … 629 630 move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 630 631 peek(GPRInfo::argumentGPR1, -1); 631 m_calls.append(Call Record(call(), lookupExceptionHandler));632 m_calls.append(CallLinkRecord(call(), lookupExceptionHandler)); 632 633 // lookupExceptionHandler leaves the handler CallFrame* in the returnValueGPR, 633 634 // and the address of the handler in returnValueGPR2. … … 644 645 645 646 // Link all calls out from the JIT code to their respective functions. 646 for (unsigned i = 0; i < m_calls.size(); ++i) { 647 if (m_calls[i].m_function.value()) 648 linkBuffer.link(m_calls[i].m_call, m_calls[i].m_function); 649 } 647 for (unsigned i = 0; i < m_calls.size(); ++i) 648 linkBuffer.link(m_calls[i].m_call, m_calls[i].m_function); 650 649 651 650 if (m_codeBlock->needsCallReturnIndices()) { 652 m_codeBlock->callReturnIndexVector().reserveCapacity(m_exceptionCheckCount); 653 for (unsigned i = 0; i < m_calls.size(); ++i) { 654 if (m_calls[i].m_handlesExceptions) { 655 unsigned returnAddressOffset = linkBuffer.returnAddressOffset(m_calls[i].m_call); 656 unsigned exceptionInfo = m_calls[i].m_codeOrigin.bytecodeIndex; 657 m_codeBlock->callReturnIndexVector().append(CallReturnOffsetToBytecodeOffset(returnAddressOffset, exceptionInfo)); 658 } 651 m_codeBlock->callReturnIndexVector().reserveCapacity(m_exceptionChecks.size()); 652 for (unsigned i = 0; i < m_exceptionChecks.size(); ++i) { 653 unsigned returnAddressOffset = linkBuffer.returnAddressOffset(m_exceptionChecks[i].m_call); 654 unsigned exceptionInfo = m_exceptionChecks[i].m_codeOrigin.bytecodeIndex; 655 m_codeBlock->callReturnIndexVector().append(CallReturnOffsetToBytecodeOffset(returnAddressOffset, exceptionInfo)); 659 656 } 660 657 } -
trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h
r98179 r98405 64 64 #endif 65 65 66 // === Call Record ===66 // === CallLinkRecord === 67 67 // 68 // A record of a call out from JIT code to a helper function. 69 // Every CallRecord contains a reference to the call instruction & the function 70 // that it needs to be linked to. Calls that might throw an exception also record 71 // the Jump taken on exception (unset if not present), and ExceptionInfo (presently 72 // an unsigned, bytecode index) used to recover handler/source info. 73 struct CallRecord { 74 // Constructor for a call with no exception handler. 75 CallRecord(MacroAssembler::Call call, FunctionPtr function) 68 // A record of a call out from JIT code that needs linking to a helper function. 69 // Every CallLinkRecord contains a reference to the call instruction & the function 70 // that it needs to be linked to. 71 struct CallLinkRecord { 72 CallLinkRecord(MacroAssembler::Call call, FunctionPtr function) 76 73 : m_call(call) 77 74 , m_function(function) 78 , m_handlesExceptions(false) 79 { 80 } 81 82 // Constructor for a call with an exception handler. 83 CallRecord(MacroAssembler::Call call, FunctionPtr function, MacroAssembler::Jump exceptionCheck, CodeOrigin codeOrigin) 75 { 76 } 77 78 MacroAssembler::Call m_call; 79 FunctionPtr m_function; 80 }; 81 82 // === CallExceptionRecord === 83 // 84 // A record of a call out from JIT code that might throw an exception. 85 // Calls that might throw an exception also record the Jump taken on exception 86 // (unset if not present) and code origin used to recover handler/source info. 87 struct CallExceptionRecord { 88 CallExceptionRecord(MacroAssembler::Call call, CodeOrigin codeOrigin) 84 89 : m_call(call) 85 , m_function(function) 90 , m_codeOrigin(codeOrigin) 91 { 92 } 93 94 CallExceptionRecord(MacroAssembler::Call call, MacroAssembler::Jump exceptionCheck, CodeOrigin codeOrigin) 95 : m_call(call) 86 96 , m_exceptionCheck(exceptionCheck) 87 97 , m_codeOrigin(codeOrigin) 88 , m_handlesExceptions(true)89 {90 }91 92 // Constructor for a call that may cause exceptions, but which are handled93 // through some mechanism other than the in-line exception handler.94 CallRecord(MacroAssembler::Call call, FunctionPtr function, CodeOrigin codeOrigin)95 : m_call(call)96 , m_function(function)97 , m_codeOrigin(codeOrigin)98 , m_handlesExceptions(true)99 98 { 100 99 } 101 100 102 101 MacroAssembler::Call m_call; 103 FunctionPtr m_function;104 102 MacroAssembler::Jump m_exceptionCheck; 105 103 CodeOrigin m_codeOrigin; 106 bool m_handlesExceptions;107 104 }; 108 105 … … 121 118 , m_graph(dfg) 122 119 , m_codeBlock(codeBlock) 123 , m_exceptionCheckCount(0)124 120 { 125 121 } … … 210 206 211 207 // Notify the JIT of a call that does not require linking. 212 void notifyCall(Call call, CodeOrigin codeOrigin)213 { 214 m_ calls.append(CallRecord(call, FunctionPtr(), codeOrigin));208 void notifyCall(Call functionCall, CodeOrigin codeOrigin) 209 { 210 m_exceptionChecks.append(CallExceptionRecord(functionCall, codeOrigin)); 215 211 } 216 212 … … 219 215 { 220 216 Call functionCall = call(); 221 m_calls.append(CallRecord(functionCall, function)); 222 // FIXME: should be able to JIT_ASSERT here that globalData->exception is null on return back to JIT code. 217 m_calls.append(CallLinkRecord(functionCall, function)); 223 218 return functionCall; 224 219 } 225 220 226 221 // Add a call out from JIT code, with an exception check. 227 Call appendCallWithExceptionCheck(const FunctionPtr& function, CodeOrigin codeOrigin) 228 { 229 Call functionCall = call(); 222 Call addExceptionCheck(Call functionCall, CodeOrigin codeOrigin) 223 { 230 224 #if USE(JSVALUE64) 231 225 Jump exceptionCheck = branchTestPtr(NonZero, AbsoluteAddress(&globalData()->exception)); … … 233 227 Jump exceptionCheck = branch32(NotEqual, AbsoluteAddress(reinterpret_cast<char*>(&globalData()->exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag)); 234 228 #endif 235 m_ calls.append(CallRecord(functionCall, function, exceptionCheck, codeOrigin));229 m_exceptionChecks.append(CallExceptionRecord(functionCall, exceptionCheck, codeOrigin)); 236 230 return functionCall; 237 231 } 238 232 239 233 // Add a call out from JIT code, with a fast exception check that tests if the return value is zero. 240 Call appendCallWithFastExceptionCheck(const FunctionPtr& function, CodeOrigin codeOrigin) 241 { 242 Call functionCall = call(); 234 Call addFastExceptionCheck(Call functionCall, CodeOrigin codeOrigin) 235 { 243 236 Jump exceptionCheck = branchTestPtr(Zero, GPRInfo::returnValueGPR); 244 m_ calls.append(CallRecord(functionCall, function, exceptionCheck, codeOrigin));237 m_exceptionChecks.append(CallExceptionRecord(functionCall, exceptionCheck, codeOrigin)); 245 238 return functionCall; 246 239 } … … 467 460 // Vector of calls out from JIT code, including exception handler information. 468 461 // Count of the number of CallRecords with exception handlers. 469 Vector<Call Record> m_calls;470 unsigned m_exceptionCheckCount;462 Vector<CallLinkRecord> m_calls; 463 Vector<CallExceptionRecord> m_exceptionChecks; 471 464 472 465 // JIT code map for OSR entrypoints. -
trunk/Source/JavaScriptCore/dfg/DFGJITCompiler32_64.cpp
r98291 r98405 569 569 linkOSRExits(speculative); 570 570 571 // Iterate over the m_calls vector, checking for exception checks,572 // and linking them to here.573 for (unsigned i = 0; i < m_ calls.size(); ++i) {574 Jump& exceptionCheck = m_ calls[i].m_exceptionCheck;571 // Iterate over the m_calls vector, checking for jumps to link. 572 bool didLinkExceptionCheck = false; 573 for (unsigned i = 0; i < m_exceptionChecks.size(); ++i) { 574 Jump& exceptionCheck = m_exceptionChecks[i].m_exceptionCheck; 575 575 if (exceptionCheck.isSet()) { 576 576 exceptionCheck.link(this); 577 ++m_exceptionCheckCount; 578 } 579 } 577 didLinkExceptionCheck = true; 578 } 579 } 580 580 581 // If any exception checks were linked, generate code to lookup a handler. 581 if ( m_exceptionCheckCount) {582 if (didLinkExceptionCheck) { 582 583 // lookupExceptionHandler is passed two arguments, exec (the CallFrame*), and 583 584 // an identifier for the operation that threw the exception, which we can use … … 585 586 // of the call out from JIT code that threw the exception; this is still 586 587 // available on the stack, just below the stack pointer! 588 move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 587 589 peek(GPRInfo::argumentGPR1, -1); 588 poke(GPRInfo::callFrameRegister); 589 poke(GPRInfo::argumentGPR1, 1); 590 m_calls.append(CallRecord(call(), lookupExceptionHandler)); 590 m_calls.append(CallLinkRecord(call(), lookupExceptionHandler)); 591 591 // lookupExceptionHandler leaves the handler CallFrame* in the returnValueGPR, 592 592 // and the address of the handler in returnValueGPR2. … … 603 603 604 604 // Link all calls out from the JIT code to their respective functions. 605 for (unsigned i = 0; i < m_calls.size(); ++i) { 606 if (m_calls[i].m_function.value()) 607 linkBuffer.link(m_calls[i].m_call, m_calls[i].m_function); 608 } 605 for (unsigned i = 0; i < m_calls.size(); ++i) 606 linkBuffer.link(m_calls[i].m_call, m_calls[i].m_function); 609 607 610 608 if (m_codeBlock->needsCallReturnIndices()) { 611 m_codeBlock->callReturnIndexVector().reserveCapacity(m_exceptionCheckCount); 612 for (unsigned i = 0; i < m_calls.size(); ++i) { 613 if (m_calls[i].m_handlesExceptions) { 614 unsigned returnAddressOffset = linkBuffer.returnAddressOffset(m_calls[i].m_call); 615 unsigned exceptionInfo = m_calls[i].m_codeOrigin.bytecodeIndex; 616 m_codeBlock->callReturnIndexVector().append(CallReturnOffsetToBytecodeOffset(returnAddressOffset, exceptionInfo)); 617 } 609 m_codeBlock->callReturnIndexVector().reserveCapacity(m_exceptionChecks.size()); 610 for (unsigned i = 0; i < m_exceptionChecks.size(); ++i) { 611 unsigned returnAddressOffset = linkBuffer.returnAddressOffset(m_exceptionChecks[i].m_call); 612 unsigned exceptionInfo = m_exceptionChecks[i].m_codeOrigin.bytecodeIndex; 613 m_codeBlock->callReturnIndexVector().append(CallReturnOffsetToBytecodeOffset(returnAddressOffset, exceptionInfo)); 618 614 } 619 615 }
Note:
See TracChangeset
for help on using the changeset viewer.