| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/deopt_instructions.h" | 5 #include "vm/deopt_instructions.h" |
| 6 | 6 |
| 7 #include "vm/assembler_macros.h" | 7 #include "vm/assembler_macros.h" |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 #include "vm/locations.h" | 9 #include "vm/locations.h" |
| 10 #include "vm/parser.h" | 10 #include "vm/parser.h" |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 | 161 |
| 162 DISALLOW_COPY_AND_ASSIGN(DeoptInt64StackSlotInstr); | 162 DISALLOW_COPY_AND_ASSIGN(DeoptInt64StackSlotInstr); |
| 163 }; | 163 }; |
| 164 | 164 |
| 165 | 165 |
| 166 // Deoptimization instruction creating return address using function and | 166 // Deoptimization instruction creating return address using function and |
| 167 // deopt-id stored at 'object_table_index'. Uses the deopt-after | 167 // deopt-id stored at 'object_table_index'. Uses the deopt-after |
| 168 // continuation point. | 168 // continuation point. |
| 169 class DeoptRetAddrAfterInstr : public DeoptInstr { | 169 class DeoptRetAddrAfterInstr : public DeoptInstr { |
| 170 public: | 170 public: |
| 171 explicit DeoptRetAddrAfterInstr(intptr_t object_table_index) | 171 DeoptRetAddrAfterInstr(intptr_t object_table_index, intptr_t deopt_id) |
| 172 : object_table_index_(object_table_index) { | 172 : object_table_index_(object_table_index), deopt_id_(deopt_id) { |
| 173 ASSERT(object_table_index >= 0); | 173 ASSERT(object_table_index >= 0); |
| 174 ASSERT(deopt_id >= 0); |
| 174 } | 175 } |
| 175 | 176 |
| 176 virtual intptr_t from_index() const { return object_table_index_; } | 177 explicit DeoptRetAddrAfterInstr(intptr_t from_index) |
| 178 : object_table_index_(ObjectTableIndex::decode(from_index)), |
| 179 deopt_id_(DeoptId::decode(from_index)) { |
| 180 } |
| 181 |
| 182 virtual intptr_t from_index() const { |
| 183 return ObjectTableIndex::encode(object_table_index_) | |
| 184 DeoptId::encode(deopt_id_); |
| 185 } |
| 177 virtual DeoptInstr::Kind kind() const { return kSetRetAfterAddress; } | 186 virtual DeoptInstr::Kind kind() const { return kSetRetAfterAddress; } |
| 178 | 187 |
| 179 virtual const char* ToCString() const { | 188 virtual const char* ToCString() const { |
| 180 const char* format = "ret aft oti:%"Pd""; | 189 const char* format = "ret aft oti:%"Pd"(%"Pd")"; |
| 181 intptr_t len = OS::SNPrint(NULL, 0, format, object_table_index_); | 190 intptr_t len = OS::SNPrint(NULL, 0, format, object_table_index_, deopt_id_); |
| 182 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); | 191 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); |
| 183 OS::SNPrint(chars, len + 1, format, object_table_index_); | 192 OS::SNPrint(chars, len + 1, format, object_table_index_, deopt_id_); |
| 184 return chars; | 193 return chars; |
| 185 } | 194 } |
| 186 | 195 |
| 187 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { | 196 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { |
| 188 Function& function = Function::Handle(deopt_context->isolate()); | 197 Function& function = Function::Handle(deopt_context->isolate()); |
| 189 function ^= deopt_context->ObjectAt(object_table_index_); | 198 function ^= deopt_context->ObjectAt(object_table_index_); |
| 190 Smi& deopt_id_as_smi = Smi::Handle(deopt_context->isolate()); | |
| 191 deopt_id_as_smi ^= deopt_context->ObjectAt(object_table_index_ + 1); | |
| 192 const Code& code = | 199 const Code& code = |
| 193 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); | 200 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); |
| 194 uword continue_at_pc = | 201 uword continue_at_pc = code.GetDeoptAfterPcAtDeoptId(deopt_id_); |
| 195 code.GetDeoptAfterPcAtDeoptId(deopt_id_as_smi.Value()); | |
| 196 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); | 202 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); |
| 197 *to_addr = continue_at_pc; | 203 *to_addr = continue_at_pc; |
| 198 } | 204 } |
| 199 | 205 |
| 200 private: | 206 private: |
| 207 static const intptr_t kFieldWidth = kBitsPerWord / 2; |
| 208 class ObjectTableIndex : public BitField<intptr_t, 0, kFieldWidth> { }; |
| 209 class DeoptId : public BitField<intptr_t, kFieldWidth, kFieldWidth> { }; |
| 210 |
| 201 const intptr_t object_table_index_; | 211 const intptr_t object_table_index_; |
| 212 const intptr_t deopt_id_; |
| 202 | 213 |
| 203 DISALLOW_COPY_AND_ASSIGN(DeoptRetAddrAfterInstr); | 214 DISALLOW_COPY_AND_ASSIGN(DeoptRetAddrAfterInstr); |
| 204 }; | 215 }; |
| 205 | 216 |
| 206 | 217 |
| 207 // Deoptimization instruction creating return address using function and | 218 // Deoptimization instruction creating return address using function and |
| 208 // deopt-id stored at 'object_table_index'. Uses the deopt-before | 219 // deopt-id stored at 'object_table_index'. Uses the deopt-before |
| 209 // continuation point. | 220 // continuation point. |
| 210 class DeoptRetAddrBeforeInstr : public DeoptInstr { | 221 class DeoptRetAddrBeforeInstr : public DeoptInstr { |
| 211 public: | 222 public: |
| 212 explicit DeoptRetAddrBeforeInstr(intptr_t object_table_index) | 223 DeoptRetAddrBeforeInstr(intptr_t object_table_index, intptr_t deopt_id) |
| 213 : object_table_index_(object_table_index) { | 224 : object_table_index_(object_table_index), deopt_id_(deopt_id) { |
| 214 ASSERT(object_table_index >= 0); | 225 ASSERT(object_table_index >= 0); |
| 226 ASSERT(deopt_id_ >= 0); |
| 215 } | 227 } |
| 216 | 228 |
| 217 virtual intptr_t from_index() const { return object_table_index_; } | 229 explicit DeoptRetAddrBeforeInstr(intptr_t from_index) |
| 230 : object_table_index_(ObjectTableIndex::decode(from_index)), |
| 231 deopt_id_(DeoptId::decode(from_index)) { |
| 232 } |
| 233 |
| 234 virtual intptr_t from_index() const { |
| 235 return ObjectTableIndex::encode(object_table_index_) | |
| 236 DeoptId::encode(deopt_id_); |
| 237 } |
| 218 virtual DeoptInstr::Kind kind() const { return kSetRetBeforeAddress; } | 238 virtual DeoptInstr::Kind kind() const { return kSetRetBeforeAddress; } |
| 219 | 239 |
| 220 virtual const char* ToCString() const { | 240 virtual const char* ToCString() const { |
| 221 const char* format = "ret bef oti:%"Pd""; | 241 const char* format = "ret bef oti:%"Pd"(%"Pd")"; |
| 222 intptr_t len = OS::SNPrint(NULL, 0, format, object_table_index_); | 242 intptr_t len = OS::SNPrint(NULL, 0, format, object_table_index_, deopt_id_); |
| 223 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); | 243 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); |
| 224 OS::SNPrint(chars, len + 1, format, object_table_index_); | 244 OS::SNPrint(chars, len + 1, format, object_table_index_, deopt_id_); |
| 225 return chars; | 245 return chars; |
| 226 } | 246 } |
| 227 | 247 |
| 228 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { | 248 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { |
| 229 Function& function = Function::Handle(deopt_context->isolate()); | 249 Function& function = Function::Handle(deopt_context->isolate()); |
| 230 function ^= deopt_context->ObjectAt(object_table_index_); | 250 function ^= deopt_context->ObjectAt(object_table_index_); |
| 231 Smi& deopt_id_as_smi = Smi::Handle(deopt_context->isolate()); | |
| 232 deopt_id_as_smi ^= deopt_context->ObjectAt(object_table_index_ + 1); | |
| 233 const Code& code = | 251 const Code& code = |
| 234 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); | 252 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); |
| 235 uword continue_at_pc = | 253 uword continue_at_pc = code.GetDeoptBeforePcAtDeoptId(deopt_id_); |
| 236 code.GetDeoptBeforePcAtDeoptId(deopt_id_as_smi.Value()); | |
| 237 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); | 254 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); |
| 238 *to_addr = continue_at_pc; | 255 *to_addr = continue_at_pc; |
| 239 } | 256 } |
| 240 | 257 |
| 241 private: | 258 private: |
| 259 static const intptr_t kFieldWidth = kBitsPerWord / 2; |
| 260 class ObjectTableIndex : public BitField<intptr_t, 0, kFieldWidth> { }; |
| 261 class DeoptId : public BitField<intptr_t, kFieldWidth, kFieldWidth> { }; |
| 262 |
| 242 const intptr_t object_table_index_; | 263 const intptr_t object_table_index_; |
| 264 const intptr_t deopt_id_; |
| 243 | 265 |
| 244 DISALLOW_COPY_AND_ASSIGN(DeoptRetAddrBeforeInstr); | 266 DISALLOW_COPY_AND_ASSIGN(DeoptRetAddrBeforeInstr); |
| 245 }; | 267 }; |
| 246 | 268 |
| 247 | 269 |
| 248 // Deoptimization instruction moving a constant stored at 'object_table_index'. | 270 // Deoptimization instruction moving a constant stored at 'object_table_index'. |
| 249 class DeoptConstantInstr : public DeoptInstr { | 271 class DeoptConstantInstr : public DeoptInstr { |
| 250 public: | 272 public: |
| 251 explicit DeoptConstantInstr(intptr_t object_table_index) | 273 explicit DeoptConstantInstr(intptr_t object_table_index) |
| 252 : object_table_index_(object_table_index) { | 274 : object_table_index_(object_table_index) { |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 }; | 478 }; |
| 457 | 479 |
| 458 | 480 |
| 459 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t from_index) { | 481 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t from_index) { |
| 460 Kind kind = static_cast<Kind>(kind_as_int); | 482 Kind kind = static_cast<Kind>(kind_as_int); |
| 461 switch (kind) { | 483 switch (kind) { |
| 462 case kCopyStackSlot: return new DeoptStackSlotInstr(from_index); | 484 case kCopyStackSlot: return new DeoptStackSlotInstr(from_index); |
| 463 case kCopyDoubleStackSlot: return new DeoptDoubleStackSlotInstr(from_index); | 485 case kCopyDoubleStackSlot: return new DeoptDoubleStackSlotInstr(from_index); |
| 464 case kCopyInt64StackSlot: return new DeoptInt64StackSlotInstr(from_index); | 486 case kCopyInt64StackSlot: return new DeoptInt64StackSlotInstr(from_index); |
| 465 case kSetRetAfterAddress: return new DeoptRetAddrAfterInstr(from_index); | 487 case kSetRetAfterAddress: return new DeoptRetAddrAfterInstr(from_index); |
| 466 case kSetRetBeforeAddress: return new DeoptRetAddrBeforeInstr(from_index); | 488 case kSetRetBeforeAddress: return new DeoptRetAddrBeforeInstr(from_index); |
| 467 case kCopyConstant: return new DeoptConstantInstr(from_index); | 489 case kCopyConstant: return new DeoptConstantInstr(from_index); |
| 468 case kCopyRegister: return new DeoptRegisterInstr(from_index); | 490 case kCopyRegister: return new DeoptRegisterInstr(from_index); |
| 469 case kCopyXmmRegister: return new DeoptXmmRegisterInstr(from_index); | 491 case kCopyXmmRegister: return new DeoptXmmRegisterInstr(from_index); |
| 470 case kCopyInt64XmmRegister: | 492 case kCopyInt64XmmRegister: |
| 471 return new DeoptInt64XmmRegisterInstr(from_index); | 493 return new DeoptInt64XmmRegisterInstr(from_index); |
| 472 case kSetPcMarker: return new DeoptPcMarkerInstr(from_index); | 494 case kSetPcMarker: return new DeoptPcMarkerInstr(from_index); |
| 473 case kSetCallerFp: return new DeoptCallerFpInstr(); | 495 case kSetCallerFp: return new DeoptCallerFpInstr(); |
| 474 case kSetCallerPc: return new DeoptCallerPcInstr(); | 496 case kSetCallerPc: return new DeoptCallerPcInstr(); |
| 475 } | 497 } |
| 476 UNREACHABLE(); | 498 UNREACHABLE(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 487 // Add object. | 509 // Add object. |
| 488 const intptr_t result = object_table_.Length(); | 510 const intptr_t result = object_table_.Length(); |
| 489 object_table_.Add(obj); | 511 object_table_.Add(obj); |
| 490 return result; | 512 return result; |
| 491 } | 513 } |
| 492 | 514 |
| 493 | 515 |
| 494 void DeoptInfoBuilder::AddReturnAddressBefore(const Function& function, | 516 void DeoptInfoBuilder::AddReturnAddressBefore(const Function& function, |
| 495 intptr_t deopt_id, | 517 intptr_t deopt_id, |
| 496 intptr_t to_index) { | 518 intptr_t to_index) { |
| 497 const intptr_t object_table_index = object_table_.Length(); | 519 const intptr_t object_table_index = FindOrAddObjectInTable(function); |
| 498 object_table_.Add(function); | |
| 499 object_table_.Add(Smi::ZoneHandle(Smi::New(deopt_id))); | |
| 500 ASSERT(to_index == instructions_.length()); | 520 ASSERT(to_index == instructions_.length()); |
| 501 instructions_.Add(new DeoptRetAddrBeforeInstr(object_table_index)); | 521 instructions_.Add(new DeoptRetAddrBeforeInstr(object_table_index, deopt_id)); |
| 502 } | 522 } |
| 503 | 523 |
| 504 | 524 |
| 505 void DeoptInfoBuilder::AddReturnAddressAfter(const Function& function, | 525 void DeoptInfoBuilder::AddReturnAddressAfter(const Function& function, |
| 506 intptr_t deopt_id, | 526 intptr_t deopt_id, |
| 507 intptr_t to_index) { | 527 intptr_t to_index) { |
| 508 const intptr_t object_table_index = object_table_.Length(); | 528 const intptr_t object_table_index = FindOrAddObjectInTable(function); |
| 509 object_table_.Add(function); | |
| 510 object_table_.Add(Smi::ZoneHandle(Smi::New(deopt_id))); | |
| 511 ASSERT(to_index == instructions_.length()); | 529 ASSERT(to_index == instructions_.length()); |
| 512 instructions_.Add(new DeoptRetAddrAfterInstr(object_table_index)); | 530 instructions_.Add(new DeoptRetAddrAfterInstr(object_table_index, deopt_id)); |
| 513 } | 531 } |
| 514 | 532 |
| 515 | 533 |
| 516 void DeoptInfoBuilder::AddPcMarker(const Function& function, | 534 void DeoptInfoBuilder::AddPcMarker(const Function& function, |
| 517 intptr_t to_index) { | 535 intptr_t to_index) { |
| 518 // Function object was already added by AddReturnAddress, find it. | 536 // Function object was already added by AddReturnAddress, find it. |
| 519 intptr_t from_index = FindOrAddObjectInTable(function); | 537 intptr_t from_index = FindOrAddObjectInTable(function); |
| 520 ASSERT(to_index == instructions_.length()); | 538 ASSERT(to_index == instructions_.length()); |
| 521 instructions_.Add(new DeoptPcMarkerInstr(from_index)); | 539 instructions_.Add(new DeoptPcMarkerInstr(from_index)); |
| 522 } | 540 } |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 Smi* offset, | 632 Smi* offset, |
| 615 DeoptInfo* info, | 633 DeoptInfo* info, |
| 616 Smi* reason) { | 634 Smi* reason) { |
| 617 intptr_t i = index * kEntrySize; | 635 intptr_t i = index * kEntrySize; |
| 618 *offset ^= table.At(i); | 636 *offset ^= table.At(i); |
| 619 *info ^= table.At(i + 1); | 637 *info ^= table.At(i + 1); |
| 620 *reason ^= table.At(i + 2); | 638 *reason ^= table.At(i + 2); |
| 621 } | 639 } |
| 622 | 640 |
| 623 } // namespace dart | 641 } // namespace dart |
| OLD | NEW |