diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2010-06-09 10:09:37 -0700 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2010-06-09 10:09:37 -0700 |
commit | cd232a9ccecb5102170d4d40c91f06bb538104e0 (patch) | |
tree | 0aae9a3cd2cc09b83d552bed26be3cc8ead2e03e /deps/v8/src/debug.cc | |
parent | cec775a0de4948343078d205f45216ade6e331c3 (diff) | |
download | node-new-cd232a9ccecb5102170d4d40c91f06bb538104e0.tar.gz |
Upgrade V8 to 2.2.16
Diffstat (limited to 'deps/v8/src/debug.cc')
-rw-r--r-- | deps/v8/src/debug.cc | 75 |
1 files changed, 54 insertions, 21 deletions
diff --git a/deps/v8/src/debug.cc b/deps/v8/src/debug.cc index e279ee9eff..ca20a65b65 100644 --- a/deps/v8/src/debug.cc +++ b/deps/v8/src/debug.cc @@ -129,10 +129,14 @@ void BreakLocationIterator::Next() { ASSERT(statement_position_ >= 0); } - // Check for breakable code target. Look in the original code as setting - // break points can cause the code targets in the running (debugged) code to - // be of a different kind than in the original code. - if (RelocInfo::IsCodeTarget(rmode())) { + if (IsDebugBreakSlot()) { + // There is always a possible break point at a debug break slot. + break_point_++; + return; + } else if (RelocInfo::IsCodeTarget(rmode())) { + // Check for breakable code target. Look in the original code as setting + // break points can cause the code targets in the running (debugged) code + // to be of a different kind than in the original code. Address target = original_rinfo()->target_address(); Code* code = Code::GetCodeFromTargetAddress(target); if ((code->is_inline_cache_stub() && @@ -329,6 +333,9 @@ void BreakLocationIterator::SetDebugBreak() { if (RelocInfo::IsJSReturn(rmode())) { // Patch the frame exit code with a break point. SetDebugBreakAtReturn(); + } else if (IsDebugBreakSlot()) { + // Patch the code in the break slot. + SetDebugBreakAtSlot(); } else { // Patch the IC call. SetDebugBreakAtIC(); @@ -346,6 +353,9 @@ void BreakLocationIterator::ClearDebugBreak() { if (RelocInfo::IsJSReturn(rmode())) { // Restore the frame exit code. ClearDebugBreakAtReturn(); + } else if (IsDebugBreakSlot()) { + // Restore the code in the break slot. + ClearDebugBreakAtSlot(); } else { // Patch the IC call. ClearDebugBreakAtIC(); @@ -417,6 +427,8 @@ bool BreakLocationIterator::HasBreakPoint() { bool BreakLocationIterator::IsDebugBreak() { if (RelocInfo::IsJSReturn(rmode())) { return IsDebugBreakAtReturn(); + } else if (IsDebugBreakSlot()) { + return IsDebugBreakAtSlot(); } else { return Debug::IsDebugBreak(rinfo()->target_address()); } @@ -478,6 +490,11 @@ bool BreakLocationIterator::IsDebuggerStatement() { } +bool BreakLocationIterator::IsDebugBreakSlot() { + return RelocInfo::DEBUG_BREAK_SLOT == rmode(); +} + + Object* BreakLocationIterator::BreakPointObjects() { return debug_info_->GetBreakPointObjects(code_position()); } @@ -573,6 +590,7 @@ bool Debug::break_on_uncaught_exception_ = true; Handle<Context> Debug::debug_context_ = Handle<Context>(); Code* Debug::debug_break_return_ = NULL; +Code* Debug::debug_break_slot_ = NULL; void ScriptCache::Add(Handle<Script> script) { @@ -656,6 +674,10 @@ void Debug::Setup(bool create_heap_objects) { debug_break_return_ = Builtins::builtin(Builtins::Return_DebugBreak); ASSERT(debug_break_return_->IsCode()); + // Get code to handle debug break in debug break slots. + debug_break_slot_ = + Builtins::builtin(Builtins::Slot_DebugBreak); + ASSERT(debug_break_slot_->IsCode()); } } @@ -824,6 +846,7 @@ void Debug::PreemptionWhileInDebugger() { void Debug::Iterate(ObjectVisitor* v) { v->VisitPointer(BitCast<Object**, Code**>(&(debug_break_return_))); + v->VisitPointer(BitCast<Object**, Code**>(&(debug_break_slot_))); } @@ -1631,16 +1654,21 @@ void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { // break point is still active after processing the break point. Address addr = frame->pc() - Assembler::kCallTargetAddressOffset; - // Check if the location is at JS exit. + // Check if the location is at JS exit or debug break slot. bool at_js_return = false; bool break_at_js_return_active = false; + bool at_debug_break_slot = false; RelocIterator it(debug_info->code()); - while (!it.done()) { + while (!it.done() && !at_js_return && !at_debug_break_slot) { if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) { at_js_return = (it.rinfo()->pc() == addr - Assembler::kPatchReturnSequenceAddressOffset); break_at_js_return_active = it.rinfo()->IsPatchedReturnSequence(); } + if (RelocInfo::IsDebugBreakSlot(it.rinfo()->rmode())) { + at_debug_break_slot = (it.rinfo()->pc() == + addr - Assembler::kPatchDebugBreakSlotAddressOffset); + } it.next(); } @@ -1657,25 +1685,30 @@ void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { // Move back to where the call instruction sequence started. thread_local_.after_break_target_ = addr - Assembler::kPatchReturnSequenceAddressOffset; - } else { - // Check if there still is a debug break call at the target address. If the - // break point has been removed it will have disappeared. If it have - // disappeared don't try to look in the original code as the running code - // will have the right address. This takes care of the case where the last - // break point is removed from the function and therefore no "original code" - // is available. If the debug break call is still there find the address in - // the original code. - if (IsDebugBreak(Assembler::target_address_at(addr))) { - // If the break point is still there find the call address which was - // overwritten in the original code by the call to DebugBreakXXX. - - // Find the corresponding address in the original code. - addr += original_code->instruction_start() - code->instruction_start(); - } + } else if (at_debug_break_slot) { + // Address of where the debug break slot starts. + addr = addr - Assembler::kPatchDebugBreakSlotAddressOffset; + + // Continue just after the slot. + thread_local_.after_break_target_ = addr + Assembler::kDebugBreakSlotLength; + } else if (IsDebugBreak(Assembler::target_address_at(addr))) { + // We now know that there is still a debug break call at the target address, + // so the break point is still there and the original code will hold the + // address to jump to in order to complete the call which is replaced by a + // call to DebugBreakXXX. + + // Find the corresponding address in the original code. + addr += original_code->instruction_start() - code->instruction_start(); // Install jump to the call address in the original code. This will be the // call which was overwritten by the call to DebugBreakXXX. thread_local_.after_break_target_ = Assembler::target_address_at(addr); + } else { + // There is no longer a break point present. Don't try to look in the + // original code as the running code will have the right address. This takes + // care of the case where the last break point is removed from the function + // and therefore no "original code" is available. + thread_local_.after_break_target_ = Assembler::target_address_at(addr); } } |