| Index: runtime/vm/deopt_instructions.cc
|
| diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
|
| index eabb177c95f60576fbb42bb9479d9865ed65f536..95d250032d329fb87249b1290e03e7f65968e210 100644
|
| --- a/runtime/vm/deopt_instructions.cc
|
| +++ b/runtime/vm/deopt_instructions.cc
|
| @@ -21,11 +21,13 @@ DeoptimizationContext::DeoptimizationContext(intptr_t* to_frame_start,
|
| from_frame_(NULL),
|
| from_frame_size_(0),
|
| registers_copy_(NULL),
|
| + xmm_registers_copy_(NULL),
|
| num_args_(num_args),
|
| isolate_(Isolate::Current()) {
|
| from_frame_ = isolate_->deopt_frame_copy();
|
| from_frame_size_ = isolate_->deopt_frame_copy_size();
|
| - registers_copy_ = isolate_->deopt_registers_copy();
|
| + registers_copy_ = isolate_->deopt_cpu_registers_copy();
|
| + xmm_registers_copy_ = isolate_->deopt_xmm_registers_copy();
|
| }
|
|
|
|
|
| @@ -74,6 +76,41 @@ class DeoptStackSlotInstr : public DeoptInstr {
|
| };
|
|
|
|
|
| +class DeoptDoubleStackSlotInstr : public DeoptInstr {
|
| + public:
|
| + explicit DeoptDoubleStackSlotInstr(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 kCopyDoubleStackSlot; }
|
| +
|
| + virtual const char* ToCString() const {
|
| + intptr_t len = OS::SNPrint(NULL, 0, "ds%d", stack_slot_index_);
|
| + char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
|
| + OS::SNPrint(chars, len + 1, "ds%d", 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;
|
| + double* from_addr = reinterpret_cast<double*>(
|
| + deopt_context->GetFromFrameAddressAt(from_index));
|
| + intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index);
|
| + *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0);
|
| + Isolate::Current()->DeferDoubleMaterialization(
|
| + *from_addr, reinterpret_cast<RawDouble**>(to_addr));
|
| + }
|
| +
|
| + private:
|
| + const intptr_t stack_slot_index_; // First argument is 0, always >= 0.
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(DeoptDoubleStackSlotInstr);
|
| +};
|
| +
|
| +
|
| // Deoptimization instruction creating return address using function and
|
| // deopt-id stored at 'object_table_index'.
|
| class DeoptRetAddrInstr : public DeoptInstr {
|
| @@ -145,7 +182,7 @@ class DeoptConstantInstr : public DeoptInstr {
|
| };
|
|
|
|
|
| -// Deoptimization instruction moving a register.
|
| +// Deoptimization instruction moving a CPU register.
|
| class DeoptRegisterInstr: public DeoptInstr {
|
| public:
|
| explicit DeoptRegisterInstr(intptr_t reg_as_int)
|
| @@ -171,6 +208,34 @@ class DeoptRegisterInstr: public DeoptInstr {
|
| };
|
|
|
|
|
| +// Deoptimization instruction moving an XMM register.
|
| +class DeoptXmmRegisterInstr: public DeoptInstr {
|
| + public:
|
| + explicit DeoptXmmRegisterInstr(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 kCopyXmmRegister; }
|
| +
|
| + virtual const char* ToCString() const {
|
| + return Assembler::XmmRegisterName(reg_);
|
| + }
|
| +
|
| + void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) {
|
| + double value = deopt_context->XmmRegisterValue(reg_);
|
| + intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index);
|
| + *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0);
|
| + Isolate::Current()->DeferDoubleMaterialization(
|
| + value, reinterpret_cast<RawDouble**>(to_addr));
|
| + }
|
| +
|
| + private:
|
| + const XmmRegister reg_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(DeoptXmmRegisterInstr);
|
| +};
|
| +
|
| +
|
| // Deoptimization instruction creating a PC marker for the code of
|
| // function at 'object_table_index'.
|
| class DeoptPcMarkerInstr : public DeoptInstr {
|
| @@ -259,9 +324,11 @@ DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t from_index) {
|
| Kind kind = static_cast<Kind>(kind_as_int);
|
| switch (kind) {
|
| case kCopyStackSlot: return new DeoptStackSlotInstr(from_index);
|
| + case kCopyDoubleStackSlot: return new DeoptDoubleStackSlotInstr(from_index);
|
| case kSetRetAddress: return new DeoptRetAddrInstr(from_index);
|
| case kCopyConstant: return new DeoptConstantInstr(from_index);
|
| case kCopyRegister: return new DeoptRegisterInstr(from_index);
|
| + case kCopyXmmRegister: return new DeoptXmmRegisterInstr(from_index);
|
| case kSetPcMarker: return new DeoptPcMarkerInstr(from_index);
|
| case kSetCallerFp: return new DeoptCallerFpInstr();
|
| case kSetCallerPc: return new DeoptCallerPcInstr();
|
| @@ -314,12 +381,20 @@ void DeoptInfoBuilder::AddCopy(const Location& from_loc,
|
| deopt_instr = new DeoptConstantInstr(object_table_index);
|
| } 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());
|
| } else if (from_loc.IsStackSlot()) {
|
| intptr_t from_index = (from_loc.stack_index() < 0) ?
|
| from_loc.stack_index() + num_args_ :
|
| from_loc.stack_index() + num_args_ -
|
| ParsedFunction::kFirstLocalSlotIndex + 1;
|
| deopt_instr = new DeoptStackSlotInstr(from_index);
|
| + } else if (from_loc.IsDoubleStackSlot()) {
|
| + intptr_t from_index = (from_loc.stack_index() < 0) ?
|
| + from_loc.stack_index() + num_args_ :
|
| + from_loc.stack_index() + num_args_ -
|
| + ParsedFunction::kFirstLocalSlotIndex + 1;
|
| + deopt_instr = new DeoptDoubleStackSlotInstr(from_index);
|
| } else {
|
| UNREACHABLE();
|
| }
|
|
|