| Index: runtime/vm/deopt_instructions.cc
|
| ===================================================================
|
| --- runtime/vm/deopt_instructions.cc (revision 22714)
|
| +++ runtime/vm/deopt_instructions.cc (working copy)
|
| @@ -36,27 +36,39 @@
|
| from_frame_size_ = isolate_->deopt_frame_copy_size();
|
| registers_copy_ = isolate_->deopt_cpu_registers_copy();
|
| fpu_registers_copy_ = isolate_->deopt_fpu_registers_copy();
|
| + // The deoptimized frame is filled starting just below the sp of its caller
|
| + // down to kDartFrameFixedSize words below its own sp.
|
| + // The chain of frame pointers is recreated from the fp of the caller.
|
| caller_fp_ = GetFromFp();
|
| }
|
|
|
|
|
| intptr_t DeoptimizationContext::GetFromFp() const {
|
| - return from_frame_[from_frame_size_ - num_args_ - 1 - kParamEndSlotFromFp];
|
| + return from_frame_[from_frame_size_ - 1 - num_args_ - kParamEndSlotFromFp];
|
| }
|
|
|
|
|
| +intptr_t DeoptimizationContext::GetFromPp() const {
|
| + return from_frame_[from_frame_size_ - 1 - num_args_ - kParamEndSlotFromFp +
|
| + StackFrame::SavedCallerPpSlotFromFp()];
|
| +}
|
| +
|
| +
|
| intptr_t DeoptimizationContext::GetFromPc() const {
|
| return from_frame_[from_frame_size_ - num_args_ + kSavedPcSlotFromSp];
|
| }
|
|
|
| +
|
| intptr_t DeoptimizationContext::GetCallerFp() const {
|
| return caller_fp_;
|
| }
|
|
|
| +
|
| void DeoptimizationContext::SetCallerFp(intptr_t caller_fp) {
|
| caller_fp_ = caller_fp;
|
| }
|
|
|
| +
|
| // Deoptimization instruction moving value from optimized frame at
|
| // 'from_index' to specified slots in the unoptimized frame.
|
| // 'from_index' represents the slot index of the frame (0 being first argument)
|
| @@ -476,6 +488,11 @@
|
| void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
|
| Function& function = Function::Handle(deopt_context->isolate());
|
| function ^= deopt_context->ObjectAt(object_table_index_);
|
| + if (function.IsNull()) {
|
| + // Callee's PC marker is not used (pc of Deoptimize stub). Set to 0.
|
| + *to_addr = 0;
|
| + return;
|
| + }
|
| const Code& code =
|
| Code::Handle(deopt_context->isolate(), function.unoptimized_code());
|
| ASSERT(!code.IsNull());
|
| @@ -503,6 +520,40 @@
|
| };
|
|
|
|
|
| +// Deoptimization instruction creating a pool pointer for the code of
|
| +// function at 'object_table_index'.
|
| +class DeoptPpInstr : public DeoptInstr {
|
| + public:
|
| + explicit DeoptPpInstr(intptr_t object_table_index)
|
| + : object_table_index_(object_table_index) {
|
| + ASSERT(object_table_index >= 0);
|
| + }
|
| +
|
| + virtual intptr_t from_index() const { return object_table_index_; }
|
| + virtual DeoptInstr::Kind kind() const { return kPp; }
|
| +
|
| + virtual const char* ToCString() const {
|
| + return Isolate::Current()->current_zone()->PrintToString(
|
| + "pp oti:%"Pd"", object_table_index_);
|
| + }
|
| +
|
| + void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
|
| + Function& function = Function::Handle(deopt_context->isolate());
|
| + function ^= deopt_context->ObjectAt(object_table_index_);
|
| + const Code& code =
|
| + Code::Handle(deopt_context->isolate(), function.unoptimized_code());
|
| + ASSERT(!code.IsNull());
|
| + const intptr_t pp = reinterpret_cast<intptr_t>(code.ObjectPool());
|
| + *to_addr = pp;
|
| + }
|
| +
|
| + private:
|
| + intptr_t object_table_index_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(DeoptPpInstr);
|
| +};
|
| +
|
| +
|
| // Deoptimization instruction copying the caller saved FP from optimized frame.
|
| class DeoptCallerFpInstr : public DeoptInstr {
|
| public:
|
| @@ -517,7 +568,8 @@
|
|
|
| void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
|
| *to_addr = deopt_context->GetCallerFp();
|
| - deopt_context->SetCallerFp(reinterpret_cast<intptr_t>(to_addr));
|
| + deopt_context->SetCallerFp(reinterpret_cast<intptr_t>(
|
| + to_addr - (kSavedCallerFpSlotFromFp * kWordSize)));
|
| }
|
|
|
| private:
|
| @@ -525,6 +577,27 @@
|
| };
|
|
|
|
|
| +// Deoptimization instruction copying the caller saved PP from optimized frame.
|
| +class DeoptCallerPpInstr : public DeoptInstr {
|
| + public:
|
| + DeoptCallerPpInstr() {}
|
| +
|
| + virtual intptr_t from_index() const { return 0; }
|
| + virtual DeoptInstr::Kind kind() const { return kCallerPp; }
|
| +
|
| + virtual const char* ToCString() const {
|
| + return "callerpp";
|
| + }
|
| +
|
| + void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
|
| + *to_addr = deopt_context->GetFromPp();
|
| + }
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(DeoptCallerPpInstr);
|
| +};
|
| +
|
| +
|
| // Deoptimization instruction copying the caller return address from optimized
|
| // frame.
|
| class DeoptCallerPcInstr : public DeoptInstr {
|
| @@ -702,7 +775,9 @@
|
| case kUint32x4FpuRegister:
|
| return new DeoptUint32x4FpuRegisterInstr(from_index);
|
| case kPcMarker: return new DeoptPcMarkerInstr(from_index);
|
| + case kPp: return new DeoptPpInstr(from_index);
|
| case kCallerFp: return new DeoptCallerFpInstr();
|
| + case kCallerPp: return new DeoptCallerPpInstr();
|
| case kCallerPc: return new DeoptCallerPcInstr();
|
| case kSuffix: return new DeoptSuffixInstr(from_index);
|
| case kMaterializedObjectRef:
|
| @@ -795,13 +870,19 @@
|
|
|
| void DeoptInfoBuilder::AddPcMarker(const Function& function,
|
| intptr_t to_index) {
|
| - // Function object was already added by AddReturnAddress, find it.
|
| - intptr_t from_index = FindOrAddObjectInTable(function);
|
| + intptr_t object_table_index = FindOrAddObjectInTable(function);
|
| ASSERT(to_index == FrameSize());
|
| - instructions_.Add(new DeoptPcMarkerInstr(from_index));
|
| + instructions_.Add(new DeoptPcMarkerInstr(object_table_index));
|
| }
|
|
|
|
|
| +void DeoptInfoBuilder::AddPp(const Function& function, intptr_t to_index) {
|
| + intptr_t object_table_index = FindOrAddObjectInTable(function);
|
| + ASSERT(to_index == FrameSize());
|
| + instructions_.Add(new DeoptPpInstr(object_table_index));
|
| +}
|
| +
|
| +
|
| void DeoptInfoBuilder::AddCopy(Value* value,
|
| const Location& from_loc,
|
| const intptr_t to_index) {
|
| @@ -864,6 +945,12 @@
|
| }
|
|
|
|
|
| +void DeoptInfoBuilder::AddCallerPp(intptr_t to_index) {
|
| + ASSERT(to_index == FrameSize());
|
| + instructions_.Add(new DeoptCallerPpInstr());
|
| +}
|
| +
|
| +
|
| void DeoptInfoBuilder::AddCallerPc(intptr_t to_index) {
|
| ASSERT(to_index == FrameSize());
|
| instructions_.Add(new DeoptCallerPcInstr());
|
| @@ -898,20 +985,20 @@
|
| }
|
|
|
|
|
| -intptr_t DeoptInfoBuilder::EmitMaterializationArguments() {
|
| - intptr_t slot_idx = 1; // Return address is emitted at 0.
|
| +intptr_t DeoptInfoBuilder::EmitMaterializationArguments(intptr_t to_index) {
|
| + ASSERT(to_index == kDartFrameFixedSize);
|
| for (intptr_t i = 0; i < materializations_.length(); i++) {
|
| MaterializeObjectInstr* mat = materializations_[i];
|
| - AddConstant(mat->cls(), slot_idx++); // Class of the instance to allocate.
|
| + AddConstant(mat->cls(), to_index++); // Class of the instance to allocate.
|
| for (intptr_t i = 0; i < mat->InputCount(); i++) {
|
| if (!mat->InputAt(i)->BindsToConstantNull()) {
|
| // Emit field-value pair.
|
| - AddConstant(mat->FieldAt(i), slot_idx++);
|
| - AddCopy(mat->InputAt(i), mat->LocationAt(i), slot_idx++);
|
| + AddConstant(mat->FieldAt(i), to_index++);
|
| + AddCopy(mat->InputAt(i), mat->LocationAt(i), to_index++);
|
| }
|
| }
|
| }
|
| - return slot_idx;
|
| + return to_index;
|
| }
|
|
|
|
|
|
|