Chromium Code Reviews| Index: runtime/vm/deopt_instructions.cc |
| =================================================================== |
| --- runtime/vm/deopt_instructions.cc (revision 12897) |
| +++ runtime/vm/deopt_instructions.cc (working copy) |
| @@ -122,6 +122,47 @@ |
| }; |
| +class DeoptMintStackSlotInstr : public DeoptInstr { |
|
srdjan
2012/09/28 16:50:26
Should this be Deopt64bitStackSlotInstr instead si
Florian Schneider
2012/10/02 11:10:31
Done.
|
| + public: |
| + explicit DeoptMintStackSlotInstr(intptr_t from_index) |
| + : stack_slot_index_(from_index) { |
| + ASSERT(stack_slot_index_ >= 0); |
| + } |
| + |
| + virtual intptr_t from_index() const { return stack_slot_index_; } |
| + virtual DeoptInstr::Kind kind() const { return kCopyMintStackSlot; } |
| + |
| + virtual const char* ToCString() const { |
| + const char* format = "ms%"Pd""; |
| + intptr_t len = OS::SNPrint(NULL, 0, format, stack_slot_index_); |
| + char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); |
| + OS::SNPrint(chars, len + 1, format, stack_slot_index_); |
| + return chars; |
| + } |
| + |
| + void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { |
| + intptr_t from_index = |
| + deopt_context->from_frame_size() - stack_slot_index_ - 1; |
| + int64_t* from_addr = reinterpret_cast<int64_t*>( |
| + deopt_context->GetFromFrameAddressAt(from_index)); |
| + intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); |
| + *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
| + if (Smi::IsValid64(*from_addr)) { |
| + *to_addr = reinterpret_cast<intptr_t>( |
| + Smi::New(static_cast<intptr_t>(*from_addr))); |
| + } else { |
| + Isolate::Current()->DeferMintMaterialization( |
| + *from_addr, reinterpret_cast<RawMint**>(to_addr)); |
| + } |
| + } |
| + |
| + private: |
| + const intptr_t stack_slot_index_; // First argument is 0, always >= 0. |
| + |
| + DISALLOW_COPY_AND_ASSIGN(DeoptMintStackSlotInstr); |
| +}; |
| + |
| + |
| // Deoptimization instruction creating return address using function and |
| // deopt-id stored at 'object_table_index'. Uses the deopt-after |
| // continuation point. |
| @@ -292,6 +333,43 @@ |
| }; |
| +class DeoptMintXmmRegisterInstr: public DeoptInstr { |
| + public: |
| + explicit DeoptMintXmmRegisterInstr(intptr_t reg_as_int) |
| + : reg_(static_cast<XmmRegister>(reg_as_int)) {} |
| + |
| + virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); } |
| + virtual DeoptInstr::Kind kind() const { return kCopyMintXmmRegister; } |
| + |
| + virtual const char* ToCString() const { |
| + const char* format = "%s(m)"; |
| + intptr_t len = |
| + OS::SNPrint(NULL, 0, format, Assembler::XmmRegisterName(reg_)); |
| + char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); |
| + OS::SNPrint(chars, len + 1, format, Assembler::XmmRegisterName(reg_)); |
| + return chars; |
| + } |
| + |
| + void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { |
| + int64_t value = deopt_context->XmmRegisterValueAsMint(reg_); |
| + intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); |
| + *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0); |
| + if (Smi::IsValid64(value)) { |
| + *to_addr = reinterpret_cast<intptr_t>( |
| + Smi::New(static_cast<intptr_t>(value))); |
| + } else { |
| + Isolate::Current()->DeferMintMaterialization( |
| + value, reinterpret_cast<RawMint**>(to_addr)); |
| + } |
| + } |
| + |
| + private: |
| + const XmmRegister reg_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(DeoptMintXmmRegisterInstr); |
| +}; |
| + |
| + |
| // Deoptimization instruction creating a PC marker for the code of |
| // function at 'object_table_index'. |
| class DeoptPcMarkerInstr : public DeoptInstr { |
| @@ -383,11 +461,13 @@ |
| switch (kind) { |
| case kCopyStackSlot: return new DeoptStackSlotInstr(from_index); |
| case kCopyDoubleStackSlot: return new DeoptDoubleStackSlotInstr(from_index); |
| + case kCopyMintStackSlot: return new DeoptMintStackSlotInstr(from_index); |
| case kSetRetAfterAddress: return new DeoptRetAddrAfterInstr(from_index); |
| case kSetRetBeforeAddress: return new DeoptRetAddrBeforeInstr(from_index); |
| case kCopyConstant: return new DeoptConstantInstr(from_index); |
| case kCopyRegister: return new DeoptRegisterInstr(from_index); |
| case kCopyXmmRegister: return new DeoptXmmRegisterInstr(from_index); |
| + case kCopyMintXmmRegister: return new DeoptMintXmmRegisterInstr(from_index); |
| case kSetPcMarker: return new DeoptPcMarkerInstr(from_index); |
| case kSetCallerFp: return new DeoptCallerFpInstr(); |
| case kSetCallerPc: return new DeoptCallerPcInstr(); |
| @@ -451,7 +531,12 @@ |
| } else if (from_loc.IsRegister()) { |
| deopt_instr = new DeoptRegisterInstr(from_loc.reg()); |
| } else if (from_loc.IsXmmRegister()) { |
| - deopt_instr = new DeoptXmmRegisterInstr(from_loc.xmm_reg()); |
| + if (from_loc.representation() == Location::kDouble) { |
| + deopt_instr = new DeoptXmmRegisterInstr(from_loc.xmm_reg()); |
| + } else { |
| + ASSERT(from_loc.representation() == Location::kMint); |
| + deopt_instr = new DeoptMintXmmRegisterInstr(from_loc.xmm_reg()); |
| + } |
| } else if (from_loc.IsStackSlot()) { |
| intptr_t from_index = (from_loc.stack_index() < 0) ? |
| from_loc.stack_index() + num_args_ : |
| @@ -463,7 +548,12 @@ |
| from_loc.stack_index() + num_args_ : |
| from_loc.stack_index() + num_args_ - |
| ParsedFunction::kFirstLocalSlotIndex + 1; |
| - deopt_instr = new DeoptDoubleStackSlotInstr(from_index); |
| + if (from_loc.representation() == Location::kDouble) { |
| + deopt_instr = new DeoptDoubleStackSlotInstr(from_index); |
| + } else { |
| + ASSERT(from_loc.representation() == Location::kMint); |
| + deopt_instr = new DeoptMintStackSlotInstr(from_index); |
| + } |
| } else { |
| UNREACHABLE(); |
| } |