Changeset 33480
- Timestamp:
- 05/14/08 23:50:33 (6 months ago)
- Location:
- branches/squirrelfish/JavaScriptCore
- Files:
-
- 10 modified
-
ChangeLog (modified) (1 diff)
-
VM/CodeBlock.cpp (modified) (2 diffs)
-
VM/CodeGenerator.cpp (modified) (1 diff)
-
VM/CodeGenerator.h (modified) (2 diffs)
-
VM/Machine.cpp (modified) (9 diffs)
-
VM/Machine.h (modified) (2 diffs)
-
VM/Opcode.h (modified) (1 diff)
-
kjs/JSActivation.cpp (modified) (1 diff)
-
kjs/Parser.cpp (modified) (1 diff)
-
kjs/nodes.cpp (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/squirrelfish/JavaScriptCore/ChangeLog
r33438 r33480 1 2008-05-14 Geoffrey Garen <ggaren@apple.com> 2 3 Reviewed by Oliver Hunt. 4 5 A little more debugger action: filled in op_debug. All debugger control 6 flow works now, but variable inspection and backtraces still don't. 7 8 SunSpider reports no change. 9 10 * VM/CodeGenerator.cpp: Changed op_debug to accept line number parameters. 11 12 * VM/Machine.cpp: 13 (KJS::Machine::getFunctionAndArguments): Moved op_debug into a 14 NEVER_INLINE function to avoid a stunning 10% performance regression. 15 Also factored out a common function for retrieving the function and 16 arguments from a call frame. 17 18 * kjs/JSActivation.cpp: 19 (KJS::JSActivation::createArgumentsObject): Use the new factored out 20 function mentioned above. 21 22 * kjs/Parser.cpp: 23 (KJS::Parser::parse): Increment m_sourceId before assigning it, so the 24 sourceId we send to the debugger matches the sourceId recorded in the 25 node. 26 27 * kjs/nodes.cpp: Emit debugging hooks. 28 1 29 2008-05-14 Oliver Hunt <oliver@apple.com> 2 30 -
branches/squirrelfish/JavaScriptCore/VM/CodeBlock.cpp
r33437 r33480 98 98 { 99 99 if (debugHookID == DidEnterCallFrame) 100 return " DidEnterCallFrame";100 return "didEnterCallFrame"; 101 101 else if (debugHookID == WillLeaveCallFrame) 102 return " WillLeaveCallFrame";102 return "willLeaveCallFrame"; 103 103 else { 104 104 ASSERT(debugHookID == WillExecuteStatement); 105 return " WillExecuteStatement";105 return "willExecuteStatement"; 106 106 } 107 107 } … … 530 530 break; 531 531 } 532 case op_d bg: {532 case op_debug: { 533 533 int debugHookID = (++it)->u.operand; 534 printf("[%4d] dbg\t\t %s\n", location, debugHookName(debugHookID)); 534 int firstLine = (++it)->u.operand; 535 int lastLine = (++it)->u.operand; 536 printf("[%4d] debug\t\t %s, %d, %d\n", location, debugHookName(debugHookID), firstLine, lastLine); 535 537 break; 536 538 } -
branches/squirrelfish/JavaScriptCore/VM/CodeGenerator.cpp
r33437 r33480 984 984 } 985 985 986 void CodeGenerator::emitDebugHook(DebugHookID debugHookID )986 void CodeGenerator::emitDebugHook(DebugHookID debugHookID, int firstLine, int lastLine) 987 987 { 988 988 if (!m_shouldEmitDebugHooks) 989 989 return; 990 instructions().append(machine().getOpcode(op_d bg));990 instructions().append(machine().getOpcode(op_debug)); 991 991 instructions().append(debugHookID); 992 instructions().append(firstLine); 993 instructions().append(lastLine); 992 994 } 993 995 -
branches/squirrelfish/JavaScriptCore/VM/CodeGenerator.h
r33437 r33480 134 134 // Node::emitCode. They're the only functions that accept a NULL register. 135 135 RegisterID* emitNode(RegisterID* dst, Node* n) { 136 ASSERT(!dst || !dst->isTemporary() || dst->refCount()); // Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary. 136 // Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary. 137 ASSERT(!dst || !dst->isTemporary() || dst->refCount()); 137 138 if (!m_codeBlock->lineInfo.size() || m_codeBlock->lineInfo.last().lineNumber != n->lineNo()) { 138 139 LineInfo info = { instructions().size(), n->lineNo() }; … … 237 238 void emitPopScope(); 238 239 239 void emitDebugHook(DebugHookID );240 void emitDebugHook(DebugHookID, int firstLine, int lastLine); 240 241 241 242 int scopeDepth() { return m_dynamicScopeDepth + m_finallyDepth; } -
branches/squirrelfish/JavaScriptCore/VM/Machine.cpp
r33438 r33480 738 738 } 739 739 740 NEVER_INLINE void Machine::debug(ExecState* exec, const Instruction* vPC, const CodeBlock* codeBlock, const ScopeChainNode*, Register** registerBase, Register* r) 741 { 742 int debugHookID = (++vPC)->u.operand; 743 int firstLine = (++vPC)->u.operand; 744 int lastLine = (++vPC)->u.operand; 745 746 Debugger* debugger = exec->dynamicGlobalObject()->debugger(); 747 if (!debugger) 748 return; 749 750 if (debugHookID == DidEnterCallFrame) { 751 Register* callFrame = r - codeBlock->numLocals - CallFrameHeaderSize; 752 FunctionImp* function; 753 Register* argv; 754 int argc; 755 getFunctionAndArguments(registerBase, callFrame, function, argv, argc); 756 List args(&argv->u.jsValue, argc); 757 debugger->callEvent(exec, codeBlock->ownerNode->sourceId(), firstLine, function, args); 758 } else if (debugHookID == WillLeaveCallFrame) { 759 Register* callFrame = r - codeBlock->numLocals - CallFrameHeaderSize; 760 FunctionImp* function = static_cast<FunctionImp*>(callFrame[Callee].u.jsValue); 761 ASSERT(function->inherits(&FunctionImp::info)); 762 debugger->returnEvent(exec, codeBlock->ownerNode->sourceId(), lastLine, function); 763 } else { 764 ASSERT(debugHookID == WillExecuteStatement); 765 debugger->atStatement(exec, codeBlock->ownerNode->sourceId(), firstLine, lastLine); 766 } 767 } 768 740 769 JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFile* registerFile, Register* r, ScopeChainNode* scopeChain, CodeBlock* codeBlock, JSValue** exception) 741 770 { … … 1361 1390 1362 1391 vPC += 3; 1363 1364 1392 NEXT_OPCODE; 1365 1393 } … … 1373 1401 */ 1374 1402 resolveBase(exec, vPC, r, scopeChain, codeBlock); 1403 1375 1404 vPC += 3; 1376 1377 1405 NEXT_OPCODE; 1378 1406 } … … 1393 1421 1394 1422 vPC += 4; 1395 1396 1423 NEXT_OPCODE; 1397 1424 } … … 1413 1440 if (UNLIKELY(!resolveBaseAndFunc(exec, vPC, r, scopeChain, codeBlock, exceptionValue))) 1414 1441 goto vm_throw; 1442 1415 1443 vPC += 4; 1416 1417 1444 NEXT_OPCODE; 1418 1445 } … … 1605 1632 */ 1606 1633 int target = (++vPC)->u.operand; 1634 1607 1635 vPC += target; 1608 1609 1636 NEXT_OPCODE; 1610 1637 } … … 2094 2121 NEXT_OPCODE; 2095 2122 } 2096 BEGIN_OPCODE(op_d bg) {2097 /* d bg debugHookID(n)2123 BEGIN_OPCODE(op_debug) { 2124 /* debug debugHookID(n) firstLine(n) lastLine(n) 2098 2125 2099 2126 Notifies the debugger of the current state of execution: … … 2103 2130 */ 2104 2131 2105 int debugHookID = (++vPC)->u.operand; 2106 2107 Debugger* debugger = exec->dynamicGlobalObject()->debugger(); 2108 if (!debugger) { 2109 ++vPC; 2110 NEXT_OPCODE; 2111 } 2112 2113 if (debugHookID == DidEnterCallFrame) { 2114 // callEvent 2115 } else if (debugHookID == WillLeaveCallFrame) { 2116 // returnEvent 2117 } else { 2118 // atStatement 2119 ASSERT(debugHookID == WillExecuteStatement); 2120 } 2121 2122 ++vPC; 2132 debug(exec, vPC, codeBlock, scopeChain, registerBase, r); 2133 2134 vPC += 3; 2123 2135 NEXT_OPCODE; 2124 2136 } … … 2197 2209 } 2198 2210 2211 void Machine::getFunctionAndArguments(Register** registerBase, Register* callFrame, FunctionImp*& function, Register*& argv, int& argc) 2212 { 2213 function = static_cast<FunctionImp*>(callFrame[Callee].u.jsValue); 2214 ASSERT(function->inherits(&FunctionImp::info)); 2215 2216 argv = (*registerBase) + callFrame[CallerRegisterOffset].u.i + callFrame[ArgumentStartRegister].u.i + 1; // skip "this" 2217 argc = callFrame[ArgumentCount].u.i - 1; // skip "this" 2218 } 2219 2199 2220 } // namespace KJS -
branches/squirrelfish/JavaScriptCore/VM/Machine.h
r33370 r33480 92 92 JSValue* retrieveCaller(ExecState*, FunctionImp*) const; 93 93 94 void getFunctionAndArguments(Register** registerBase, Register* callFrame, FunctionImp*&, Register*& argv, int& argc); 95 94 96 private: 95 97 enum { MaxReentryDepth = 128 }; … … 97 99 98 100 ALWAYS_INLINE void setScopeChain(ExecState* exec, ScopeChainNode*&, ScopeChainNode*); 101 NEVER_INLINE void debug(ExecState*, const Instruction*, const CodeBlock*, const ScopeChainNode*, Register**, Register*); 99 102 100 103 NEVER_INLINE bool unwindCallFrame(ExecState*, Register**, const Instruction*&, CodeBlock*&, JSValue**&, ScopeChainNode*&, Register*&); -
branches/squirrelfish/JavaScriptCore/VM/Opcode.h
r33437 r33480 116 116 macro(op_sret) \ 117 117 \ 118 macro(op_d bg) \118 macro(op_debug) \ 119 119 \ 120 120 macro(op_end) // end must be the last opcode in the list -
branches/squirrelfish/JavaScriptCore/kjs/JSActivation.cpp
r33339 r33480 179 179 JSObject* JSActivation::createArgumentsObject(ExecState* exec) 180 180 { 181 CodeBlock* codeBlock = &d()->functionBody->generatedCode(); 182 Register* callFrame = registers() - codeBlock->numLocals - Machine::CallFrameHeaderSize; 181 Register* callFrame = registers() - d()->functionBody->generatedCode().numLocals - Machine::CallFrameHeaderSize; 183 182 184 FunctionImp* function = static_cast<FunctionImp*>(callFrame[Machine::Callee].u.jsValue);185 int argv = callFrame[Machine::ArgumentStartRegister].u.i;186 int argc = callFrame[Machine::ArgumentCount].u.i;187 188 List args(& (*registerBase() + callFrame[Machine::CallerRegisterOffset].u.i + argv + 1)->u.jsValue, argc - 1);183 FunctionImp* function; 184 Register* argv; 185 int argc; 186 exec->machine()->getFunctionAndArguments(registerBase(), callFrame, function, argv, argc); 187 List args(&argv->u.jsValue, argc); 189 188 return new Arguments(exec, function, args, this); 190 189 } -
branches/squirrelfish/JavaScriptCore/kjs/Parser.cpp
r33386 r33480 68 68 69 69 lexer.setCode(startingLineNumber, source); 70 *sourceId = m_sourceId++;70 *sourceId = ++m_sourceId; 71 71 72 72 int parseError = kjsyyparse(&lexer); -
branches/squirrelfish/JavaScriptCore/kjs/nodes.cpp
r33437 r33480 4678 4678 StatementVector::iterator end = statements.end(); 4679 4679 for (StatementVector::iterator it = statements.begin(); it != end; ++it) { 4680 generator.emitDebugHook(WillExecuteStatement); 4681 if (RegisterID* r1 = generator.emitNode(dst, it->get())) 4680 StatementNode* n = it->get(); 4681 generator.emitDebugHook(WillExecuteStatement, n->firstLine(), n->lastLine()); 4682 if (RegisterID* r1 = generator.emitNode(dst, n)) 4682 4683 r0 = r1; 4683 4684 } … … 5335 5336 generator.emitLabel(l0.get()); 5336 5337 } 5337 generator.emitDebugHook(WillLeaveCallFrame );5338 generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine()); 5338 5339 return generator.emitReturn(r0); 5339 5340 } … … 5809 5810 RegisterID* FunctionBodyNode::emitCode(CodeGenerator& generator, RegisterID*) 5810 5811 { 5811 generator.emitDebugHook(DidEnterCallFrame );5812 generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine()); 5812 5813 statementListEmitCode(m_children, generator); 5813 5814 if (!m_children.size() || !m_children.last()->isReturnNode()) { 5814 5815 RegisterID* r0 = generator.emitLoad(generator.newTemporary(), jsUndefined()); 5815 generator.emitDebugHook(WillLeaveCallFrame );5816 generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine()); 5816 5817 generator.emitReturn(r0); 5817 5818 }