Index: src/arm/lithium-arm.cc |
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc |
index 132e1a60e83b3d46c325ea33cfe01bc656e299ac..9695072ac1ac847c90f4fa550a3d818f84d9fec4 100644 |
--- a/src/arm/lithium-arm.cc |
+++ b/src/arm/lithium-arm.cc |
@@ -30,6 +30,7 @@ |
#include "lithium-allocator-inl.h" |
#include "arm/lithium-arm.h" |
#include "arm/lithium-codegen-arm.h" |
+#include "hydrogen-osr.h" |
namespace v8 { |
namespace internal { |
@@ -433,6 +434,15 @@ LPlatformChunk* LChunkBuilder::Build() { |
chunk_ = new(zone()) LPlatformChunk(info(), graph()); |
LPhase phase("L_Building chunk", chunk_); |
status_ = BUILDING; |
+ |
+ // 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; |
@@ -2439,10 +2449,18 @@ 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(kTooManySpillSlotsNeededForOSR); |
+ spill_index = 0; |
+ } |
} |
return DefineAsSpilled(new(zone()) LUnknownOSRValue, spill_index); |
} |