Index: src/ia32/lithium-ia32.cc |
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc |
index 8d660858508411408bd1ffc9aa31f7a86a22873b..07dbf13d19a3d4b20ccfb8d99cdc1ab0ddb1885b 100644 |
--- a/src/ia32/lithium-ia32.cc |
+++ b/src/ia32/lithium-ia32.cc |
@@ -32,6 +32,7 @@ |
#include "lithium-allocator-inl.h" |
#include "ia32/lithium-ia32.h" |
#include "ia32/lithium-codegen-ia32.h" |
+#include "hydrogen-osr.h" |
namespace v8 { |
namespace internal { |
@@ -483,6 +484,14 @@ LPlatformChunk* LChunkBuilder::Build() { |
USE(alignment_state_index); |
} |
+ // If compiling for OSR, reserve space for the unoptimized frame, |
+ // which will be subsumed into this frame. |
+ if (graph()->has_osr()) { |
+ for (int i = graph()->osr()->UnoptimizedFrameSlots(); i > 0; i--) { |
+ chunk_->GetNextSpillIndex(false); |
+ } |
+ } |
+ |
const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); |
for (int i = 0; i < blocks->length(); i++) { |
HBasicBlock* next = NULL; |
@@ -2537,10 +2546,23 @@ LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { |
LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { |
- int spill_index = chunk()->GetNextSpillIndex(false); // Not double-width. |
- if (spill_index > LUnallocated::kMaxFixedSlotIndex) { |
- Abort(kTooManySpillSlotsNeededForOSR); |
- spill_index = 0; |
+ // Use an index that corresponds to the location in the unoptimized frame, |
+ // which the optimized frame will subsume. |
+ int env_index = instr->index(); |
+ int spill_index = 0; |
+ if (instr->environment()->is_parameter_index(env_index)) { |
+ spill_index = chunk()->GetParameterStackSlot(env_index); |
+ } else { |
+ spill_index = env_index - instr->environment()->first_local_index(); |
+ if (spill_index > LUnallocated::kMaxFixedSlotIndex) { |
+ Abort(kNotEnoughSpillSlotsForOsr); |
+ spill_index = 0; |
+ } |
+ if (spill_index == 0) { |
+ // The dynamic frame alignment state overwrites the first local. |
+ // The first local is saved at the end of the unoptimized frame. |
+ spill_index = graph()->osr()->UnoptimizedFrameSlots(); |
+ } |
} |
return DefineAsSpilled(new(zone()) LUnknownOSRValue, spill_index); |
} |