Index: src/liveedit.cc |
diff --git a/src/liveedit.cc b/src/liveedit.cc |
index 9c5294a26d5031bdc559572b942388609136d681..34b782ce9b764141bf1e2039e15cc58c7cadfd46 100644 |
--- a/src/liveedit.cc |
+++ b/src/liveedit.cc |
@@ -1475,26 +1475,32 @@ static const char* DropFrames(Vector<StackFrame*> frames, |
// Check the nature of the top frame. |
Isolate* isolate = Isolate::Current(); |
Code* pre_top_frame_code = pre_top_frame->LookupCode(); |
+ bool frame_has_padding; |
if (pre_top_frame_code->is_inline_cache_stub() && |
pre_top_frame_code->ic_state() == DEBUG_BREAK) { |
// OK, we can drop inline cache calls. |
*mode = Debug::FRAME_DROPPED_IN_IC_CALL; |
+ frame_has_padding = Debug::FramePaddingLayout::kIsSupported; |
} else if (pre_top_frame_code == |
isolate->debug()->debug_break_slot()) { |
// OK, we can drop debug break slot. |
*mode = Debug::FRAME_DROPPED_IN_DEBUG_SLOT_CALL; |
+ frame_has_padding = Debug::FramePaddingLayout::kIsSupported; |
} else if (pre_top_frame_code == |
isolate->builtins()->builtin( |
Builtins::kFrameDropper_LiveEdit)) { |
// OK, we can drop our own code. |
*mode = Debug::FRAME_DROPPED_IN_DIRECT_CALL; |
+ frame_has_padding = false; |
} else if (pre_top_frame_code == |
isolate->builtins()->builtin(Builtins::kReturn_DebugBreak)) { |
*mode = Debug::FRAME_DROPPED_IN_RETURN_CALL; |
+ frame_has_padding = Debug::FramePaddingLayout::kIsSupported; |
} else if (pre_top_frame_code->kind() == Code::STUB && |
pre_top_frame_code->major_key()) { |
// Entry from our unit tests, it's fine, we support this case. |
*mode = Debug::FRAME_DROPPED_IN_DIRECT_CALL; |
+ frame_has_padding = false; |
} else { |
return "Unknown structure of stack above changing function"; |
} |
@@ -1504,8 +1510,44 @@ static const char* DropFrames(Vector<StackFrame*> frames, |
- Debug::kFrameDropperFrameSize * kPointerSize // Size of the new frame. |
+ kPointerSize; // Bigger address end is exclusive. |
+ Address* top_frame_pc_address = top_frame->pc_address(); |
+ |
+ // top_frame may be damaged below this point. Do not used it. |
+ ASSERT(!(top_frame = NULL)); |
+ |
if (unused_stack_top > unused_stack_bottom) { |
- return "Not enough space for frame dropper frame"; |
+ if (frame_has_padding) { |
+ int shortage_bytes = unused_stack_top - unused_stack_bottom; |
+ |
+ Address padding_start = pre_top_frame->fp() - |
+ Debug::FramePaddingLayout::kFrameBaseSize * kPointerSize; |
+ |
+ Address padding_pointer = padding_start; |
+ while (Memory::int_at(padding_pointer) == |
+ Debug::FramePaddingLayout::kPaddingValue) { |
+ padding_pointer -= kPointerSize; |
+ } |
+ if (Memory::int_at(padding_pointer) / 2 * kPointerSize < shortage_bytes) { |
Yang
2012/05/02 11:38:34
I suppose this is a Smi-untagging.
Use Smi::cast(
Peter Rybin
2012/05/02 23:46:33
Done.
|
+ return "Not enough space for frame dropper frame " |
+ "(even with padding frame)"; |
+ } |
+ Memory::int_at(padding_pointer) -= shortage_bytes / kPointerSize * 2; |
Yang
2012/05/02 11:38:34
Same here.
Peter Rybin
2012/05/02 23:46:33
Done.
|
+ |
+ StackFrame* pre_pre_frame = frames[top_frame_index - 2]; |
+ |
+ memmove(padding_start + kPointerSize - shortage_bytes, |
+ padding_start + kPointerSize, |
+ Debug::FramePaddingLayout::kFrameBaseSize * kPointerSize); |
+ |
+ pre_top_frame->UpdateFp(pre_top_frame->fp() - shortage_bytes); |
+ pre_pre_frame->SetCallerFp(pre_top_frame->fp()); |
+ unused_stack_top -= shortage_bytes; |
+ |
+ STATIC_ASSERT(sizeof(Address) == kPointerSize); |
+ top_frame_pc_address -= shortage_bytes / kPointerSize; |
+ } else { |
+ return "Not enough space for frame dropper frame"; |
+ } |
} |
// Committing now. After this point we should return only NULL value. |
@@ -1515,7 +1557,7 @@ static const char* DropFrames(Vector<StackFrame*> frames, |
ASSERT(!FixTryCatchHandler(pre_top_frame, bottom_js_frame)); |
Handle<Code> code = Isolate::Current()->builtins()->FrameDropper_LiveEdit(); |
- top_frame->set_pc(code->entry()); |
+ *top_frame_pc_address = code->entry(); |
pre_top_frame->SetCallerFp(bottom_js_frame->fp()); |
*restarter_frame_function_pointer = |