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 |