Index: src/ia32/debug-ia32.cc |
diff --git a/src/ia32/debug-ia32.cc b/src/ia32/debug-ia32.cc |
index 710cbaf19be318edf5c73408db650b84ae749487..901e38bfe3e33a855270d5ed107549a780291073 100644 |
--- a/src/ia32/debug-ia32.cc |
+++ b/src/ia32/debug-ia32.cc |
@@ -1,4 +1,4 @@ |
-// Copyright 2011 the V8 project authors. All rights reserved. |
+// Copyright 2012 the V8 project authors. All rights reserved. |
// Redistribution and use in source and binary forms, with or without |
// modification, are permitted provided that the following conditions are |
// met: |
@@ -91,9 +91,11 @@ void BreakLocationIterator::ClearDebugBreakAtSlot() { |
rinfo()->PatchCode(original_rinfo()->pc(), Assembler::kDebugBreakSlotLength); |
} |
+// All debug break stubs support padding for LiveEdit. |
+const bool Debug::FramePaddingLayout::kIsSupported = true; |
-#define __ ACCESS_MASM(masm) |
+#define __ ACCESS_MASM(masm) |
static void Generate_DebugBreakCallHelper(MacroAssembler* masm, |
RegList object_regs, |
@@ -103,6 +105,13 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm, |
{ |
FrameScope scope(masm, StackFrame::INTERNAL); |
+ // Load padding words on stack. |
+ for (int i = 0; i < Debug::FramePaddingLayout::kInitialSize; i++) { |
+ __ push(Immediate(Smi::FromInt( |
+ Debug::FramePaddingLayout::kPaddingValue))); |
+ } |
+ __ push(Immediate(Smi::FromInt(Debug::FramePaddingLayout::kInitialSize))); |
+ |
// Store the registers containing live values on the expression stack to |
// make sure that these are correctly updated during GC. Non object values |
// are stored as a smi causing it to be untouched by GC. |
@@ -134,6 +143,10 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm, |
CEntryStub ceb(1); |
__ CallStub(&ceb); |
+ // Automatically find register that could be used after register restore. |
+ // We need one register for padding skip instructions. |
+ Register unused_reg = { -1 }; |
+ |
// Restore the register values containing object pointers from the |
// expression stack. |
for (int i = kNumJSCallerSaved; --i >= 0;) { |
@@ -142,15 +155,29 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm, |
if (FLAG_debug_code) { |
__ Set(reg, Immediate(kDebugZapValue)); |
} |
+ bool taken = reg.code() == esi.code(); |
if ((object_regs & (1 << r)) != 0) { |
__ pop(reg); |
+ taken = true; |
} |
if ((non_object_regs & (1 << r)) != 0) { |
__ pop(reg); |
__ SmiUntag(reg); |
+ taken = true; |
+ } |
+ if (!taken) { |
+ unused_reg = reg; |
} |
} |
+ ASSERT(unused_reg.code() != -1); |
+ |
+ // Read current padding counter and skip corresponding number of words. |
+ __ pop(unused_reg); |
+ // We divide stored value by 2 (untagging) and multiply it by word's size. |
+ STATIC_ASSERT(kSmiTagSize == 1); |
+ __ lea(esp, Operand(esp, unused_reg, times_half_pointer_size, 0)); |
+ |
// Get rid of the internal frame. |
} |