| Index: runtime/vm/deopt_instructions.cc
|
| diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
|
| index 8d219cb5868863a720b8c363c844232c77a9191a..c2baadf9768c7371afca74b2bfb07b8af888944a 100644
|
| --- a/runtime/vm/deopt_instructions.cc
|
| +++ b/runtime/vm/deopt_instructions.cc
|
| @@ -168,37 +168,48 @@ class DeoptInt64StackSlotInstr : public DeoptInstr {
|
| // continuation point.
|
| class DeoptRetAddrAfterInstr : public DeoptInstr {
|
| public:
|
| - explicit DeoptRetAddrAfterInstr(intptr_t object_table_index)
|
| - : object_table_index_(object_table_index) {
|
| + DeoptRetAddrAfterInstr(intptr_t object_table_index, intptr_t deopt_id)
|
| + : object_table_index_(object_table_index), deopt_id_(deopt_id) {
|
| ASSERT(object_table_index >= 0);
|
| + ASSERT(deopt_id >= 0);
|
| }
|
|
|
| - virtual intptr_t from_index() const { return object_table_index_; }
|
| + explicit DeoptRetAddrAfterInstr(intptr_t from_index)
|
| + : object_table_index_(ObjectTableIndex::decode(from_index)),
|
| + deopt_id_(DeoptId::decode(from_index)) {
|
| + }
|
| +
|
| + virtual intptr_t from_index() const {
|
| + return ObjectTableIndex::encode(object_table_index_) |
|
| + DeoptId::encode(deopt_id_);
|
| + }
|
| virtual DeoptInstr::Kind kind() const { return kSetRetAfterAddress; }
|
|
|
| virtual const char* ToCString() const {
|
| - const char* format = "ret aft oti:%"Pd"";
|
| - intptr_t len = OS::SNPrint(NULL, 0, format, object_table_index_);
|
| + const char* format = "ret aft oti:%"Pd"(%"Pd")";
|
| + intptr_t len = OS::SNPrint(NULL, 0, format, object_table_index_, deopt_id_);
|
| char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
|
| - OS::SNPrint(chars, len + 1, format, object_table_index_);
|
| + OS::SNPrint(chars, len + 1, format, object_table_index_, deopt_id_);
|
| return chars;
|
| }
|
|
|
| void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) {
|
| Function& function = Function::Handle(deopt_context->isolate());
|
| function ^= deopt_context->ObjectAt(object_table_index_);
|
| - Smi& deopt_id_as_smi = Smi::Handle(deopt_context->isolate());
|
| - deopt_id_as_smi ^= deopt_context->ObjectAt(object_table_index_ + 1);
|
| const Code& code =
|
| Code::Handle(deopt_context->isolate(), function.unoptimized_code());
|
| - uword continue_at_pc =
|
| - code.GetDeoptAfterPcAtDeoptId(deopt_id_as_smi.Value());
|
| + uword continue_at_pc = code.GetDeoptAfterPcAtDeoptId(deopt_id_);
|
| intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index);
|
| *to_addr = continue_at_pc;
|
| }
|
|
|
| private:
|
| + static const intptr_t kFieldWidth = kBitsPerWord / 2;
|
| + class ObjectTableIndex : public BitField<intptr_t, 0, kFieldWidth> { };
|
| + class DeoptId : public BitField<intptr_t, kFieldWidth, kFieldWidth> { };
|
| +
|
| const intptr_t object_table_index_;
|
| + const intptr_t deopt_id_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(DeoptRetAddrAfterInstr);
|
| };
|
| @@ -209,37 +220,48 @@ class DeoptRetAddrAfterInstr : public DeoptInstr {
|
| // continuation point.
|
| class DeoptRetAddrBeforeInstr : public DeoptInstr {
|
| public:
|
| - explicit DeoptRetAddrBeforeInstr(intptr_t object_table_index)
|
| - : object_table_index_(object_table_index) {
|
| + DeoptRetAddrBeforeInstr(intptr_t object_table_index, intptr_t deopt_id)
|
| + : object_table_index_(object_table_index), deopt_id_(deopt_id) {
|
| ASSERT(object_table_index >= 0);
|
| + ASSERT(deopt_id_ >= 0);
|
| }
|
|
|
| - virtual intptr_t from_index() const { return object_table_index_; }
|
| + explicit DeoptRetAddrBeforeInstr(intptr_t from_index)
|
| + : object_table_index_(ObjectTableIndex::decode(from_index)),
|
| + deopt_id_(DeoptId::decode(from_index)) {
|
| + }
|
| +
|
| + virtual intptr_t from_index() const {
|
| + return ObjectTableIndex::encode(object_table_index_) |
|
| + DeoptId::encode(deopt_id_);
|
| + }
|
| virtual DeoptInstr::Kind kind() const { return kSetRetBeforeAddress; }
|
|
|
| virtual const char* ToCString() const {
|
| - const char* format = "ret bef oti:%"Pd"";
|
| - intptr_t len = OS::SNPrint(NULL, 0, format, object_table_index_);
|
| + const char* format = "ret bef oti:%"Pd"(%"Pd")";
|
| + intptr_t len = OS::SNPrint(NULL, 0, format, object_table_index_, deopt_id_);
|
| char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
|
| - OS::SNPrint(chars, len + 1, format, object_table_index_);
|
| + OS::SNPrint(chars, len + 1, format, object_table_index_, deopt_id_);
|
| return chars;
|
| }
|
|
|
| void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) {
|
| Function& function = Function::Handle(deopt_context->isolate());
|
| function ^= deopt_context->ObjectAt(object_table_index_);
|
| - Smi& deopt_id_as_smi = Smi::Handle(deopt_context->isolate());
|
| - deopt_id_as_smi ^= deopt_context->ObjectAt(object_table_index_ + 1);
|
| const Code& code =
|
| Code::Handle(deopt_context->isolate(), function.unoptimized_code());
|
| - uword continue_at_pc =
|
| - code.GetDeoptBeforePcAtDeoptId(deopt_id_as_smi.Value());
|
| + uword continue_at_pc = code.GetDeoptBeforePcAtDeoptId(deopt_id_);
|
| intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index);
|
| *to_addr = continue_at_pc;
|
| }
|
|
|
| private:
|
| + static const intptr_t kFieldWidth = kBitsPerWord / 2;
|
| + class ObjectTableIndex : public BitField<intptr_t, 0, kFieldWidth> { };
|
| + class DeoptId : public BitField<intptr_t, kFieldWidth, kFieldWidth> { };
|
| +
|
| const intptr_t object_table_index_;
|
| + const intptr_t deopt_id_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(DeoptRetAddrBeforeInstr);
|
| };
|
| @@ -463,7 +485,7 @@ DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t from_index) {
|
| case kCopyDoubleStackSlot: return new DeoptDoubleStackSlotInstr(from_index);
|
| case kCopyInt64StackSlot: return new DeoptInt64StackSlotInstr(from_index);
|
| case kSetRetAfterAddress: return new DeoptRetAddrAfterInstr(from_index);
|
| - case kSetRetBeforeAddress: return new DeoptRetAddrBeforeInstr(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);
|
| @@ -494,22 +516,18 @@ intptr_t DeoptInfoBuilder::FindOrAddObjectInTable(const Object& obj) const {
|
| void DeoptInfoBuilder::AddReturnAddressBefore(const Function& function,
|
| intptr_t deopt_id,
|
| intptr_t to_index) {
|
| - const intptr_t object_table_index = object_table_.Length();
|
| - object_table_.Add(function);
|
| - object_table_.Add(Smi::ZoneHandle(Smi::New(deopt_id)));
|
| + const intptr_t object_table_index = FindOrAddObjectInTable(function);
|
| ASSERT(to_index == instructions_.length());
|
| - instructions_.Add(new DeoptRetAddrBeforeInstr(object_table_index));
|
| + instructions_.Add(new DeoptRetAddrBeforeInstr(object_table_index, deopt_id));
|
| }
|
|
|
|
|
| void DeoptInfoBuilder::AddReturnAddressAfter(const Function& function,
|
| intptr_t deopt_id,
|
| intptr_t to_index) {
|
| - const intptr_t object_table_index = object_table_.Length();
|
| - object_table_.Add(function);
|
| - object_table_.Add(Smi::ZoneHandle(Smi::New(deopt_id)));
|
| + const intptr_t object_table_index = FindOrAddObjectInTable(function);
|
| ASSERT(to_index == instructions_.length());
|
| - instructions_.Add(new DeoptRetAddrAfterInstr(object_table_index));
|
| + instructions_.Add(new DeoptRetAddrAfterInstr(object_table_index, deopt_id));
|
| }
|
|
|
|
|
|
|