Chromium Code Reviews| 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 = |