Index: runtime/vm/deopt_instructions.cc |
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc |
index f153fb5c891a596a009cbf333500cd0220c3eadb..9faffcf4182551c944239ccd592f964ddfd8b9e9 100644 |
--- a/runtime/vm/deopt_instructions.cc |
+++ b/runtime/vm/deopt_instructions.cc |
@@ -890,6 +890,77 @@ class DeoptMintStackSlotRegisterInstr : public DeoptInstr { |
}; |
+class DeoptMint32StackSlotInstr : public DeoptInstr { |
+ public: |
+ explicit DeoptMint32StackSlotInstr(intptr_t source_index) |
+ : stack_slot_index_(source_index) { |
+ ASSERT(stack_slot_index_ >= 0); |
+ } |
+ |
+ virtual intptr_t source_index() const { return stack_slot_index_; } |
+ virtual DeoptInstr::Kind kind() const { return kMint32StackSlot; } |
+ |
+ virtual const char* ToCString() const { |
+ return Isolate::Current()->current_zone()->PrintToString( |
+ "(32-bit) int64 s%" Pd "", stack_slot_index_); |
+ } |
+ |
+ void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { |
+ intptr_t source_index = |
+ deopt_context->source_frame_size() - stack_slot_index_ - 1; |
+ intptr_t* source_addr = |
+ deopt_context->GetSourceFrameAddressAt(source_index); |
+ int64_t value = Utils::LowHighTo64Bits(*source_addr, 0); |
+ *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0); |
+ if (Smi::IsValid64(value)) { |
+ *dest_addr = reinterpret_cast<intptr_t>( |
+ Smi::New(static_cast<intptr_t>(value))); |
+ } else { |
+ deopt_context->DeferMintMaterialization( |
+ value, reinterpret_cast<RawMint**>(dest_addr)); |
+ } |
+ } |
+ |
+ private: |
+ const intptr_t stack_slot_index_; // First argument is 0, always >= 0. |
+ |
+ DISALLOW_COPY_AND_ASSIGN(DeoptMint32StackSlotInstr); |
+}; |
+ |
+ |
+class DeoptMint32RegisterInstr: public DeoptInstr { |
+ public: |
+ explicit DeoptMint32RegisterInstr(intptr_t reg_as_int) |
+ : reg_(static_cast<Register>(reg_as_int)) {} |
+ |
+ virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); } |
+ virtual DeoptInstr::Kind kind() const { return kMint32Register; } |
+ |
+ virtual const char* ToCString() const { |
+ return Isolate::Current()->current_zone()->PrintToString( |
+ "(32-bit) int64 register %s", Assembler::RegisterName(reg_)); |
+ } |
+ |
+ void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { |
+ int32_t lo = deopt_context->RegisterValue(reg_); |
+ int64_t value = Utils::LowHighTo64Bits(lo, 0); |
+ *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0); |
+ if (Smi::IsValid64(value)) { |
+ *dest_addr = reinterpret_cast<intptr_t>( |
+ Smi::New(static_cast<intptr_t>(value))); |
+ } else { |
+ deopt_context->DeferMintMaterialization( |
+ value, reinterpret_cast<RawMint**>(dest_addr)); |
+ } |
+ } |
+ |
+ private: |
+ const Register reg_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(DeoptMint32RegisterInstr); |
+}; |
+ |
+ |
// Deoptimization instruction moving an XMM register. |
class DeoptFloat32x4FpuRegisterInstr: public DeoptInstr { |
public: |
@@ -1299,6 +1370,12 @@ DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t source_index) { |
bool flip = DeoptMintStackSlotRegisterInstr::Flip::decode(source_index); |
return new DeoptMintStackSlotRegisterInstr(slot, reg_as_int, flip); |
} |
+ case kMint32Register: { |
+ return new DeoptMint32RegisterInstr(source_index); |
+ } |
+ case kMint32StackSlot: { |
+ return new DeoptMint32StackSlotInstr(source_index); |
+ } |
case kFloat32x4FpuRegister: |
return new DeoptFloat32x4FpuRegisterInstr(source_index); |
case kFloat64x2FpuRegister: |
@@ -1427,8 +1504,13 @@ void DeoptInfoBuilder::AddCopy(Value* value, |
intptr_t object_table_index = FindOrAddObjectInTable(source_loc.constant()); |
deopt_instr = new(isolate()) DeoptConstantInstr(object_table_index); |
} else if (source_loc.IsRegister()) { |
- ASSERT(value->definition()->representation() == kTagged); |
- deopt_instr = new(isolate()) DeoptRegisterInstr(source_loc.reg()); |
+ if (value->definition()->representation() == kTagged) { |
+ deopt_instr = new(isolate()) DeoptRegisterInstr(source_loc.reg()); |
+ } else { |
+ // TODO(johnmccutchan): Add a DeoptInt32RegisterInstr. |
+ ASSERT(value->definition()->representation() == kUnboxedMint32); |
+ deopt_instr = new(isolate()) DeoptMint32RegisterInstr(source_loc.reg()); |
+ } |
} else if (source_loc.IsFpuRegister()) { |
if (value->definition()->representation() == kUnboxedDouble) { |
deopt_instr = new(isolate()) DeoptFpuRegisterInstr(source_loc.fpu_reg()); |
@@ -1444,9 +1526,15 @@ void DeoptInfoBuilder::AddCopy(Value* value, |
new(isolate()) DeoptFloat64x2FpuRegisterInstr(source_loc.fpu_reg()); |
} |
} else if (source_loc.IsStackSlot()) { |
- ASSERT(value->definition()->representation() == kTagged); |
- intptr_t source_index = CalculateStackIndex(source_loc); |
- deopt_instr = new(isolate()) DeoptStackSlotInstr(source_index); |
+ // TODO(johnmccutchan): Add a DeoptInt32RegisterInstr. |
+ if (value->definition()->representation() == kTagged) { |
+ intptr_t source_index = CalculateStackIndex(source_loc); |
+ deopt_instr = new(isolate()) DeoptStackSlotInstr(source_index); |
+ } else { |
+ ASSERT(value->definition()->representation() == kUnboxedMint32); |
+ intptr_t source_index = CalculateStackIndex(source_loc); |
+ deopt_instr = new(isolate()) DeoptMint32StackSlotInstr(source_index); |
+ } |
} else if (source_loc.IsDoubleStackSlot()) { |
ASSERT(value->definition()->representation() == kUnboxedDouble); |
intptr_t source_index = CalculateStackIndex(source_loc); |