| 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/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
| 10 #include "vm/locations.h" | 10 #include "vm/locations.h" |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); | 270 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); |
| 271 OS::SNPrint(chars, len + 1, format, object_table_index_, deopt_id_); | 271 OS::SNPrint(chars, len + 1, format, object_table_index_, deopt_id_); |
| 272 return chars; | 272 return chars; |
| 273 } | 273 } |
| 274 | 274 |
| 275 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { | 275 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { |
| 276 Function& function = Function::Handle(deopt_context->isolate()); | 276 Function& function = Function::Handle(deopt_context->isolate()); |
| 277 function ^= deopt_context->ObjectAt(object_table_index_); | 277 function ^= deopt_context->ObjectAt(object_table_index_); |
| 278 const Code& code = | 278 const Code& code = |
| 279 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); | 279 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); |
| 280 ASSERT(!code.IsNull()); |
| 280 uword continue_at_pc = code.GetDeoptAfterPcAtDeoptId(deopt_id_); | 281 uword continue_at_pc = code.GetDeoptAfterPcAtDeoptId(deopt_id_); |
| 282 ASSERT(continue_at_pc != 0); |
| 281 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); | 283 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); |
| 282 *to_addr = continue_at_pc; | 284 *to_addr = continue_at_pc; |
| 283 } | 285 } |
| 284 | 286 |
| 285 intptr_t object_table_index() const { return object_table_index_; } | 287 intptr_t object_table_index() const { return object_table_index_; } |
| 286 intptr_t deopt_id() const { return deopt_id_; } | 288 intptr_t deopt_id() const { return deopt_id_; } |
| 287 | 289 |
| 288 private: | 290 private: |
| 289 static const intptr_t kFieldWidth = kBitsPerWord / 2; | 291 static const intptr_t kFieldWidth = kBitsPerWord / 2; |
| 290 class ObjectTableIndex : public BitField<intptr_t, 0, kFieldWidth> { }; | 292 class ObjectTableIndex : public BitField<intptr_t, 0, kFieldWidth> { }; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); | 327 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len + 1); |
| 326 OS::SNPrint(chars, len + 1, format, object_table_index_, deopt_id_); | 328 OS::SNPrint(chars, len + 1, format, object_table_index_, deopt_id_); |
| 327 return chars; | 329 return chars; |
| 328 } | 330 } |
| 329 | 331 |
| 330 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { | 332 void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) { |
| 331 Function& function = Function::Handle(deopt_context->isolate()); | 333 Function& function = Function::Handle(deopt_context->isolate()); |
| 332 function ^= deopt_context->ObjectAt(object_table_index_); | 334 function ^= deopt_context->ObjectAt(object_table_index_); |
| 333 const Code& code = | 335 const Code& code = |
| 334 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); | 336 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); |
| 337 ASSERT(!code.IsNull()); |
| 335 uword continue_at_pc = code.GetDeoptBeforePcAtDeoptId(deopt_id_); | 338 uword continue_at_pc = code.GetDeoptBeforePcAtDeoptId(deopt_id_); |
| 339 ASSERT(continue_at_pc != 0); |
| 336 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); | 340 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); |
| 337 *to_addr = continue_at_pc; | 341 *to_addr = continue_at_pc; |
| 338 | 342 |
| 339 uword pc = code.GetPcForDeoptId(deopt_id_, PcDescriptors::kIcCall); | 343 uword pc = code.GetPcForDeoptId(deopt_id_, PcDescriptors::kIcCall); |
| 340 if (pc != 0) { | 344 if (pc != 0) { |
| 341 // If the deoptimization happened at an IC call, update the IC data | 345 // If the deoptimization happened at an IC call, update the IC data |
| 342 // to avoid repeated deoptimization at the same site next time around. | 346 // to avoid repeated deoptimization at the same site next time around. |
| 343 ICData& ic_data = ICData::Handle(); | 347 ICData& ic_data = ICData::Handle(); |
| 344 CodePatcher::GetInstanceCallAt(pc, code, &ic_data, NULL); | 348 CodePatcher::GetInstanceCallAt(pc, code, &ic_data, NULL); |
| 345 if (!ic_data.IsNull()) { | 349 if (!ic_data.IsNull()) { |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); | 582 Code::Handle(deopt_context->isolate(), function.unoptimized_code()); |
| 579 ASSERT(!code.IsNull()); | 583 ASSERT(!code.IsNull()); |
| 580 intptr_t pc_marker = code.EntryPoint() + | 584 intptr_t pc_marker = code.EntryPoint() + |
| 581 Assembler::kOffsetOfSavedPCfromEntrypoint; | 585 Assembler::kOffsetOfSavedPCfromEntrypoint; |
| 582 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); | 586 intptr_t* to_addr = deopt_context->GetToFrameAddressAt(to_index); |
| 583 *to_addr = pc_marker; | 587 *to_addr = pc_marker; |
| 584 // Increment the deoptimization counter. This effectively increments each | 588 // Increment the deoptimization counter. This effectively increments each |
| 585 // function occurring in the optimized frame. | 589 // function occurring in the optimized frame. |
| 586 function.set_deoptimization_counter(function.deoptimization_counter() + 1); | 590 function.set_deoptimization_counter(function.deoptimization_counter() + 1); |
| 587 if (FLAG_trace_deoptimization) { | 591 if (FLAG_trace_deoptimization) { |
| 588 OS::PrintErr("Deoptimizing inlined %s (count %d)\n", | 592 OS::PrintErr("Deoptimizing %s (count %d)\n", |
| 589 function.ToFullyQualifiedCString(), | 593 function.ToFullyQualifiedCString(), |
| 590 function.deoptimization_counter()); | 594 function.deoptimization_counter()); |
| 591 } | 595 } |
| 592 // Clear invocation counter so that hopefully the function gets reoptimized | 596 // Clear invocation counter so that hopefully the function gets reoptimized |
| 593 // only after more feedback has been collected. | 597 // only after more feedback has been collected. |
| 594 function.set_usage_counter(0); | 598 function.set_usage_counter(0); |
| 595 if (function.HasOptimizedCode()) function.SwitchToUnoptimizedCode(); | 599 if (function.HasOptimizedCode()) function.SwitchToUnoptimizedCode(); |
| 596 } | 600 } |
| 597 | 601 |
| 598 private: | 602 private: |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 712 uword DeoptInstr::GetRetAfterAddress(DeoptInstr* instr, | 716 uword DeoptInstr::GetRetAfterAddress(DeoptInstr* instr, |
| 713 const Array& object_table, | 717 const Array& object_table, |
| 714 Function* func) { | 718 Function* func) { |
| 715 ASSERT(instr->kind() == kRetAfterAddress); | 719 ASSERT(instr->kind() == kRetAfterAddress); |
| 716 DeoptRetAfterAddressInstr* ret_after_instr = | 720 DeoptRetAfterAddressInstr* ret_after_instr = |
| 717 static_cast<DeoptRetAfterAddressInstr*>(instr); | 721 static_cast<DeoptRetAfterAddressInstr*>(instr); |
| 718 ASSERT(!object_table.IsNull()); | 722 ASSERT(!object_table.IsNull()); |
| 719 ASSERT(func != NULL); | 723 ASSERT(func != NULL); |
| 720 *func ^= object_table.At(ret_after_instr->object_table_index()); | 724 *func ^= object_table.At(ret_after_instr->object_table_index()); |
| 721 const Code& code = Code::Handle(func->unoptimized_code()); | 725 const Code& code = Code::Handle(func->unoptimized_code()); |
| 722 return code.GetDeoptAfterPcAtDeoptId(ret_after_instr->deopt_id()); | 726 ASSERT(!code.IsNull()); |
| 727 uword res = code.GetDeoptAfterPcAtDeoptId(ret_after_instr->deopt_id()); |
| 728 ASSERT(res != 0); |
| 729 return res; |
| 723 } | 730 } |
| 724 | 731 |
| 725 | 732 |
| 726 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t from_index) { | 733 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t from_index) { |
| 727 Kind kind = static_cast<Kind>(kind_as_int); | 734 Kind kind = static_cast<Kind>(kind_as_int); |
| 728 switch (kind) { | 735 switch (kind) { |
| 729 case kStackSlot: return new DeoptStackSlotInstr(from_index); | 736 case kStackSlot: return new DeoptStackSlotInstr(from_index); |
| 730 case kDoubleStackSlot: return new DeoptDoubleStackSlotInstr(from_index); | 737 case kDoubleStackSlot: return new DeoptDoubleStackSlotInstr(from_index); |
| 731 case kInt64StackSlot: return new DeoptInt64StackSlotInstr(from_index); | 738 case kInt64StackSlot: return new DeoptInt64StackSlotInstr(from_index); |
| 732 case kFloat32x4StackSlot: | 739 case kFloat32x4StackSlot: |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 Smi* offset, | 969 Smi* offset, |
| 963 DeoptInfo* info, | 970 DeoptInfo* info, |
| 964 Smi* reason) { | 971 Smi* reason) { |
| 965 intptr_t i = index * kEntrySize; | 972 intptr_t i = index * kEntrySize; |
| 966 *offset ^= table.At(i); | 973 *offset ^= table.At(i); |
| 967 *info ^= table.At(i + 1); | 974 *info ^= table.At(i + 1); |
| 968 *reason ^= table.At(i + 2); | 975 *reason ^= table.At(i + 2); |
| 969 } | 976 } |
| 970 | 977 |
| 971 } // namespace dart | 978 } // namespace dart |
| OLD | NEW |