| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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.h" | 7 #include "vm/assembler.h" |
| 8 #include "vm/code_patcher.h" | 8 #include "vm/code_patcher.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/disassembler.h" | 10 #include "vm/disassembler.h" |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 if (FLAG_trace_deoptimization_verbose) { | 338 if (FLAG_trace_deoptimization_verbose) { |
| 339 for (intptr_t i = 0; i < frame_size; i++) { | 339 for (intptr_t i = 0; i < frame_size; i++) { |
| 340 intptr_t* to_addr = GetDestFrameAddressAt(i); | 340 intptr_t* to_addr = GetDestFrameAddressAt(i); |
| 341 THR_Print("*%" Pd ". [%p] 0x%" Px " [%s]\n", i, to_addr, *to_addr, | 341 THR_Print("*%" Pd ". [%p] 0x%" Px " [%s]\n", i, to_addr, *to_addr, |
| 342 deopt_instructions[i + (len - frame_size)]->ToCString()); | 342 deopt_instructions[i + (len - frame_size)]->ToCString()); |
| 343 } | 343 } |
| 344 } | 344 } |
| 345 } | 345 } |
| 346 | 346 |
| 347 | 347 |
| 348 intptr_t* DeoptContext::CatchEntryState(intptr_t num_vars) { | |
| 349 const Code& code = Code::Handle(code_); | |
| 350 const TypedData& deopt_info = TypedData::Handle(deopt_info_); | |
| 351 GrowableArray<DeoptInstr*> deopt_instructions; | |
| 352 const Array& deopt_table = Array::Handle(code.deopt_info_array()); | |
| 353 ASSERT(!deopt_table.IsNull()); | |
| 354 DeoptInfo::Unpack(deopt_table, deopt_info, &deopt_instructions); | |
| 355 | |
| 356 intptr_t* state = new intptr_t[2 * num_vars + 1]; | |
| 357 state[0] = num_vars; | |
| 358 | |
| 359 Function& function = Function::Handle(zone(), code.function()); | |
| 360 intptr_t params = | |
| 361 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); | |
| 362 for (intptr_t i = 0; i < num_vars; i++) { | |
| 363 #if defined(TARGET_ARCH_DBC) | |
| 364 const intptr_t len = deopt_instructions.length(); | |
| 365 intptr_t slot = i < params ? i : i + kParamEndSlotFromFp; | |
| 366 DeoptInstr* instr = deopt_instructions[len - 1 - slot]; | |
| 367 intptr_t dest_index = kNumberOfCpuRegisters - 1 - i; | |
| 368 #else | |
| 369 const intptr_t len = deopt_instructions.length(); | |
| 370 intptr_t slot = | |
| 371 i < params ? i : i + kParamEndSlotFromFp - kFirstLocalSlotFromFp; | |
| 372 DeoptInstr* instr = deopt_instructions[len - 1 - slot]; | |
| 373 intptr_t dest_index = i - params; | |
| 374 #endif | |
| 375 CatchEntryStatePair p = instr->ToCatchEntryStatePair(this, dest_index); | |
| 376 state[1 + 2 * i] = p.src; | |
| 377 state[2 + 2 * i] = p.dest; | |
| 378 } | |
| 379 | |
| 380 return state; | |
| 381 } | |
| 382 | |
| 383 | |
| 384 static void FillDeferredSlots(DeoptContext* deopt_context, | 348 static void FillDeferredSlots(DeoptContext* deopt_context, |
| 385 DeferredSlot** slot_list) { | 349 DeferredSlot** slot_list) { |
| 386 DeferredSlot* slot = *slot_list; | 350 DeferredSlot* slot = *slot_list; |
| 387 *slot_list = NULL; | 351 *slot_list = NULL; |
| 388 | 352 |
| 389 while (slot != NULL) { | 353 while (slot != NULL) { |
| 390 DeferredSlot* current = slot; | 354 DeferredSlot* current = slot; |
| 391 slot = slot->next(); | 355 slot = slot->next(); |
| 392 | 356 |
| 393 current->Materialize(deopt_context); | 357 current->Materialize(deopt_context); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 return Thread::Current()->zone()->PrintToString("%" Pd "", | 478 return Thread::Current()->zone()->PrintToString("%" Pd "", |
| 515 object_table_index_); | 479 object_table_index_); |
| 516 } | 480 } |
| 517 | 481 |
| 518 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { | 482 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { |
| 519 const PassiveObject& obj = PassiveObject::Handle( | 483 const PassiveObject& obj = PassiveObject::Handle( |
| 520 deopt_context->zone(), deopt_context->ObjectAt(object_table_index_)); | 484 deopt_context->zone(), deopt_context->ObjectAt(object_table_index_)); |
| 521 *reinterpret_cast<RawObject**>(dest_addr) = obj.raw(); | 485 *reinterpret_cast<RawObject**>(dest_addr) = obj.raw(); |
| 522 } | 486 } |
| 523 | 487 |
| 524 CatchEntryStatePair ToCatchEntryStatePair(DeoptContext* deopt_context, | |
| 525 intptr_t dest_slot) { | |
| 526 return CatchEntryStatePair::FromConstant(object_table_index_, dest_slot); | |
| 527 } | |
| 528 | |
| 529 private: | 488 private: |
| 530 const intptr_t object_table_index_; | 489 const intptr_t object_table_index_; |
| 531 | 490 |
| 532 DISALLOW_COPY_AND_ASSIGN(DeoptConstantInstr); | 491 DISALLOW_COPY_AND_ASSIGN(DeoptConstantInstr); |
| 533 }; | 492 }; |
| 534 | 493 |
| 535 | 494 |
| 536 // Deoptimization instruction moving value from optimized frame at | 495 // Deoptimization instruction moving value from optimized frame at |
| 537 // 'source_index' to specified slots in the unoptimized frame. | 496 // 'source_index' to specified slots in the unoptimized frame. |
| 538 // 'source_index' represents the slot index of the frame (0 being | 497 // 'source_index' represents the slot index of the frame (0 being |
| 539 // first argument) and accounts for saved return address, frame | 498 // first argument) and accounts for saved return address, frame |
| 540 // pointer, pool pointer and pc marker. | 499 // pointer, pool pointer and pc marker. |
| 541 // Deoptimization instruction moving a CPU register. | 500 // Deoptimization instruction moving a CPU register. |
| 542 class DeoptWordInstr : public DeoptInstr { | 501 class DeoptWordInstr : public DeoptInstr { |
| 543 public: | 502 public: |
| 544 explicit DeoptWordInstr(intptr_t source_index) : source_(source_index) {} | 503 explicit DeoptWordInstr(intptr_t source_index) : source_(source_index) {} |
| 545 | 504 |
| 546 explicit DeoptWordInstr(const CpuRegisterSource& source) : source_(source) {} | 505 explicit DeoptWordInstr(const CpuRegisterSource& source) : source_(source) {} |
| 547 | 506 |
| 548 virtual intptr_t source_index() const { return source_.source_index(); } | 507 virtual intptr_t source_index() const { return source_.source_index(); } |
| 549 virtual DeoptInstr::Kind kind() const { return kWord; } | 508 virtual DeoptInstr::Kind kind() const { return kWord; } |
| 550 | 509 |
| 551 virtual const char* ArgumentsToCString() const { return source_.ToCString(); } | 510 virtual const char* ArgumentsToCString() const { return source_.ToCString(); } |
| 552 | 511 |
| 553 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { | 512 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { |
| 554 *dest_addr = source_.Value<intptr_t>(deopt_context); | 513 *dest_addr = source_.Value<intptr_t>(deopt_context); |
| 555 } | 514 } |
| 556 | 515 |
| 557 CatchEntryStatePair ToCatchEntryStatePair(DeoptContext* deopt_context, | |
| 558 intptr_t dest_slot) { | |
| 559 return CatchEntryStatePair::FromMove(source_.StackSlot(deopt_context), | |
| 560 dest_slot); | |
| 561 } | |
| 562 | |
| 563 private: | 516 private: |
| 564 const CpuRegisterSource source_; | 517 const CpuRegisterSource source_; |
| 565 | 518 |
| 566 DISALLOW_COPY_AND_ASSIGN(DeoptWordInstr); | 519 DISALLOW_COPY_AND_ASSIGN(DeoptWordInstr); |
| 567 }; | 520 }; |
| 568 | 521 |
| 569 | 522 |
| 570 class DeoptIntegerInstrBase : public DeoptInstr { | 523 class DeoptIntegerInstrBase : public DeoptInstr { |
| 571 public: | 524 public: |
| 572 DeoptIntegerInstrBase() {} | 525 DeoptIntegerInstrBase() {} |
| (...skipping 799 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1372 Smi* offset, | 1325 Smi* offset, |
| 1373 TypedData* info, | 1326 TypedData* info, |
| 1374 Smi* reason) { | 1327 Smi* reason) { |
| 1375 intptr_t i = index * kEntrySize; | 1328 intptr_t i = index * kEntrySize; |
| 1376 *offset ^= table.At(i); | 1329 *offset ^= table.At(i); |
| 1377 *info ^= table.At(i + 1); | 1330 *info ^= table.At(i + 1); |
| 1378 *reason ^= table.At(i + 2); | 1331 *reason ^= table.At(i + 2); |
| 1379 } | 1332 } |
| 1380 | 1333 |
| 1381 } // namespace dart | 1334 } // namespace dart |
| OLD | NEW |