Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1186)

Side by Side Diff: runtime/vm/deopt_instructions.cc

Issue 1052563003: VM: Add infrastructure to support deferred generation of unoptimized code. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/intermediate_language.h" 10 #include "vm/intermediate_language.h"
10 #include "vm/locations.h" 11 #include "vm/locations.h"
11 #include "vm/parser.h" 12 #include "vm/parser.h"
12 #include "vm/stack_frame.h" 13 #include "vm/stack_frame.h"
13 #include "vm/thread.h" 14 #include "vm/thread.h"
14 15
15 namespace dart { 16 namespace dart {
16 17
17 DEFINE_FLAG(bool, compress_deopt_info, true, 18 DEFINE_FLAG(bool, compress_deopt_info, true,
18 "Compress the size of the deoptimization info for optimized code."); 19 "Compress the size of the deoptimization info for optimized code.");
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 } 371 }
371 372
372 virtual DeoptInstr::Kind kind() const { return kRetAddress; } 373 virtual DeoptInstr::Kind kind() const { return kRetAddress; }
373 374
374 virtual const char* ArgumentsToCString() const { 375 virtual const char* ArgumentsToCString() const {
375 return Thread::Current()->zone()->PrintToString( 376 return Thread::Current()->zone()->PrintToString(
376 "%" Pd ", %" Pd "", object_table_index_, deopt_id_); 377 "%" Pd ", %" Pd "", object_table_index_, deopt_id_);
377 } 378 }
378 379
379 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 380 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
380 Code& code = Code::Handle(deopt_context->zone()); 381 *dest_addr = Smi::RawValue(0);
381 code ^= deopt_context->ObjectAt(object_table_index_); 382 deopt_context->DeferRetAddrMaterialization(
382 ASSERT(!code.IsNull()); 383 object_table_index_, deopt_id_, dest_addr);
383 uword continue_at_pc = code.GetPcForDeoptId(deopt_id_,
384 RawPcDescriptors::kDeopt);
385 ASSERT(continue_at_pc != 0);
386 *dest_addr = continue_at_pc;
387
388 uword pc = code.GetPcForDeoptId(deopt_id_, RawPcDescriptors::kIcCall);
389 if (pc != 0) {
390 // If the deoptimization happened at an IC call, update the IC data
391 // to avoid repeated deoptimization at the same site next time around.
392 ICData& ic_data = ICData::Handle();
393 CodePatcher::GetInstanceCallAt(pc, code, &ic_data);
394 if (!ic_data.IsNull()) {
395 ic_data.AddDeoptReason(deopt_context->deopt_reason());
396 }
397 } else {
398 const Function& function = Function::Handle(code.function());
399 if (deopt_context->HasDeoptFlag(ICData::kHoisted)) {
400 // Prevent excessive deoptimization.
401 function.set_allows_hoisting_check_class(false);
402 }
403
404 if (deopt_context->HasDeoptFlag(ICData::kGeneralized)) {
405 function.set_allows_bounds_check_generalization(false);
406 }
407 }
408 } 384 }
409 385
410 intptr_t object_table_index() const { return object_table_index_; } 386 intptr_t object_table_index() const { return object_table_index_; }
411 intptr_t deopt_id() const { return deopt_id_; } 387 intptr_t deopt_id() const { return deopt_id_; }
412 388
413 private: 389 private:
414 static const intptr_t kFieldWidth = kBitsPerWord / 2; 390 static const intptr_t kFieldWidth = kBitsPerWord / 2;
415 class ObjectTableIndex : public BitField<intptr_t, 0, kFieldWidth> { }; 391 class ObjectTableIndex : public BitField<intptr_t, 0, kFieldWidth> { };
416 class DeoptId : public BitField<intptr_t, kFieldWidth, kFieldWidth> { }; 392 class DeoptId : public BitField<intptr_t, kFieldWidth, kFieldWidth> { };
417 393
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 610
635 virtual intptr_t source_index() const { return object_table_index_; } 611 virtual intptr_t source_index() const { return object_table_index_; }
636 virtual DeoptInstr::Kind kind() const { return kPcMarker; } 612 virtual DeoptInstr::Kind kind() const { return kPcMarker; }
637 613
638 virtual const char* ArgumentsToCString() const { 614 virtual const char* ArgumentsToCString() const {
639 return Thread::Current()->zone()->PrintToString( 615 return Thread::Current()->zone()->PrintToString(
640 "%" Pd "", object_table_index_); 616 "%" Pd "", object_table_index_);
641 } 617 }
642 618
643 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 619 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
644 Code& code = Code::Handle(deopt_context->zone()); 620 *dest_addr = Smi::RawValue(0);
645 code ^= deopt_context->ObjectAt(object_table_index_); 621 deopt_context->DeferPcMarkerMaterialization(
646 if (code.IsNull()) { 622 object_table_index_, dest_addr);
647 // Callee's PC marker is not used (pc of Deoptimize stub). Set to 0.
648 *dest_addr = 0;
649 return;
650 }
651 const Function& function =
652 Function::Handle(deopt_context->zone(), code.function());
653 ASSERT(function.HasCode());
654 const intptr_t pc_marker =
655 code.EntryPoint() + Assembler::EntryPointToPcMarkerOffset();
656 *dest_addr = pc_marker;
657 // Increment the deoptimization counter. This effectively increments each
658 // function occurring in the optimized frame.
659 function.set_deoptimization_counter(function.deoptimization_counter() + 1);
660 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
661 OS::PrintErr("Deoptimizing %s (count %d)\n",
662 function.ToFullyQualifiedCString(),
663 function.deoptimization_counter());
664 }
665 // Clear invocation counter so that hopefully the function gets reoptimized
666 // only after more feedback has been collected.
667 function.set_usage_counter(0);
668 if (function.HasOptimizedCode()) {
669 function.SwitchToUnoptimizedCode();
670 }
671 } 623 }
672 624
673 private: 625 private:
674 intptr_t object_table_index_; 626 intptr_t object_table_index_;
675 627
676 DISALLOW_COPY_AND_ASSIGN(DeoptPcMarkerInstr); 628 DISALLOW_COPY_AND_ASSIGN(DeoptPcMarkerInstr);
677 }; 629 };
678 630
679 631
680 // Deoptimization instruction creating a pool pointer for the code of 632 // Deoptimization instruction creating a pool pointer for the code of
681 // function at 'object_table_index'. 633 // function at 'object_table_index'.
682 class DeoptPpInstr : public DeoptInstr { 634 class DeoptPpInstr : public DeoptInstr {
683 public: 635 public:
684 explicit DeoptPpInstr(intptr_t object_table_index) 636 explicit DeoptPpInstr(intptr_t object_table_index)
685 : object_table_index_(object_table_index) { 637 : object_table_index_(object_table_index) {
686 ASSERT(object_table_index >= 0); 638 ASSERT(object_table_index >= 0);
687 } 639 }
688 640
689 virtual intptr_t source_index() const { return object_table_index_; } 641 virtual intptr_t source_index() const { return object_table_index_; }
690 virtual DeoptInstr::Kind kind() const { return kPp; } 642 virtual DeoptInstr::Kind kind() const { return kPp; }
691 643
692 virtual const char* ArgumentsToCString() const { 644 virtual const char* ArgumentsToCString() const {
693 return Thread::Current()->zone()->PrintToString( 645 return Thread::Current()->zone()->PrintToString(
694 "%" Pd "", object_table_index_); 646 "%" Pd "", object_table_index_);
695 } 647 }
696 648
697 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) { 649 void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
698 Code& code = Code::Handle(deopt_context->zone()); 650 *dest_addr = Smi::RawValue(0);
699 code ^= deopt_context->ObjectAt(object_table_index_); 651 deopt_context->DeferPpMaterialization(object_table_index_,
700 ASSERT(!code.IsNull()); 652 reinterpret_cast<RawObject**>(dest_addr));
701 const intptr_t pp = reinterpret_cast<intptr_t>(code.ObjectPool());
702 *dest_addr = pp;
703 } 653 }
704 654
705 private: 655 private:
706 intptr_t object_table_index_; 656 intptr_t object_table_index_;
707 657
708 DISALLOW_COPY_AND_ASSIGN(DeoptPpInstr); 658 DISALLOW_COPY_AND_ASSIGN(DeoptPpInstr);
709 }; 659 };
710 660
711 661
712 // Deoptimization instruction copying the caller saved FP from optimized frame. 662 // Deoptimization instruction copying the caller saved FP from optimized frame.
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
883 uword DeoptInstr::GetRetAddress(DeoptInstr* instr, 833 uword DeoptInstr::GetRetAddress(DeoptInstr* instr,
884 const Array& object_table, 834 const Array& object_table,
885 Code* code) { 835 Code* code) {
886 ASSERT(instr->kind() == kRetAddress); 836 ASSERT(instr->kind() == kRetAddress);
887 DeoptRetAddressInstr* ret_address_instr = 837 DeoptRetAddressInstr* ret_address_instr =
888 static_cast<DeoptRetAddressInstr*>(instr); 838 static_cast<DeoptRetAddressInstr*>(instr);
889 // The following assert may trigger when displaying a backtrace 839 // The following assert may trigger when displaying a backtrace
890 // from the simulator. 840 // from the simulator.
891 ASSERT(Isolate::IsDeoptAfter(ret_address_instr->deopt_id())); 841 ASSERT(Isolate::IsDeoptAfter(ret_address_instr->deopt_id()));
892 ASSERT(!object_table.IsNull()); 842 ASSERT(!object_table.IsNull());
843 Function& function = Function::Handle();
844 function ^= object_table.At(ret_address_instr->object_table_index());
893 ASSERT(code != NULL); 845 ASSERT(code != NULL);
894 *code ^= object_table.At(ret_address_instr->object_table_index()); 846 Compiler::EnsureUnoptimizedCode(Thread::Current(), function);
847 *code ^= function.unoptimized_code();
895 ASSERT(!code->IsNull()); 848 ASSERT(!code->IsNull());
896 uword res = code->GetPcForDeoptId(ret_address_instr->deopt_id(), 849 uword res = code->GetPcForDeoptId(ret_address_instr->deopt_id(),
897 RawPcDescriptors::kDeopt); 850 RawPcDescriptors::kDeopt);
898 ASSERT(res != 0); 851 ASSERT(res != 0);
899 return res; 852 return res;
900 } 853 }
901 854
902 855
903 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t source_index) { 856 DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t source_index) {
904 Kind kind = static_cast<Kind>(kind_as_int); 857 Kind kind = static_cast<Kind>(kind_as_int);
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1076 return FpuRegisterSource(FpuRegisterSource::kRegister, loc.fpu_reg()); 1029 return FpuRegisterSource(FpuRegisterSource::kRegister, loc.fpu_reg());
1077 } else { 1030 } else {
1078 ASSERT((stack_slot_kind == Location::kQuadStackSlot) || 1031 ASSERT((stack_slot_kind == Location::kQuadStackSlot) ||
1079 (stack_slot_kind == Location::kDoubleStackSlot)); 1032 (stack_slot_kind == Location::kDoubleStackSlot));
1080 ASSERT(loc.kind() == stack_slot_kind); 1033 ASSERT(loc.kind() == stack_slot_kind);
1081 return FpuRegisterSource( 1034 return FpuRegisterSource(
1082 FpuRegisterSource::kStackSlot, CalculateStackIndex(loc)); 1035 FpuRegisterSource::kStackSlot, CalculateStackIndex(loc));
1083 } 1036 }
1084 } 1037 }
1085 1038
1086 void DeoptInfoBuilder::AddReturnAddress(const Code& code, 1039 void DeoptInfoBuilder::AddReturnAddress(const Function& function,
1087 intptr_t deopt_id, 1040 intptr_t deopt_id,
1088 intptr_t dest_index) { 1041 intptr_t dest_index) {
1089 // Check that deopt_id exists. 1042 const intptr_t object_table_index = FindOrAddObjectInTable(function);
1090 // TODO(vegorov): verify after deoptimization targets as well.
1091 #ifdef DEBUG
1092 ASSERT(Isolate::IsDeoptAfter(deopt_id) ||
1093 (code.GetPcForDeoptId(deopt_id, RawPcDescriptors::kDeopt) != 0));
1094 #endif
1095 const intptr_t object_table_index = FindOrAddObjectInTable(code);
1096 ASSERT(dest_index == FrameSize()); 1043 ASSERT(dest_index == FrameSize());
1097 instructions_.Add( 1044 instructions_.Add(
1098 new(zone()) DeoptRetAddressInstr(object_table_index, deopt_id)); 1045 new(zone()) DeoptRetAddressInstr(object_table_index, deopt_id));
1099 } 1046 }
1100 1047
1101 1048
1102 void DeoptInfoBuilder::AddPcMarker(const Code& code, 1049 void DeoptInfoBuilder::AddPcMarker(const Function& function,
1103 intptr_t dest_index) { 1050 intptr_t dest_index) {
1104 intptr_t object_table_index = FindOrAddObjectInTable(code); 1051 intptr_t object_table_index = FindOrAddObjectInTable(function);
1105 ASSERT(dest_index == FrameSize()); 1052 ASSERT(dest_index == FrameSize());
1106 instructions_.Add(new(zone()) DeoptPcMarkerInstr(object_table_index)); 1053 instructions_.Add(new(zone()) DeoptPcMarkerInstr(object_table_index));
1107 } 1054 }
1108 1055
1109 1056
1110 void DeoptInfoBuilder::AddPp(const Code& code, 1057 void DeoptInfoBuilder::AddPp(const Function& function,
1111 intptr_t dest_index) { 1058 intptr_t dest_index) {
1112 intptr_t object_table_index = FindOrAddObjectInTable(code); 1059 intptr_t object_table_index = FindOrAddObjectInTable(function);
1113 ASSERT(dest_index == FrameSize()); 1060 ASSERT(dest_index == FrameSize());
1114 instructions_.Add(new(zone()) DeoptPpInstr(object_table_index)); 1061 instructions_.Add(new(zone()) DeoptPpInstr(object_table_index));
1115 } 1062 }
1116 1063
1117 1064
1118 void DeoptInfoBuilder::AddCopy(Value* value, 1065 void DeoptInfoBuilder::AddCopy(Value* value,
1119 const Location& source_loc, 1066 const Location& source_loc,
1120 const intptr_t dest_index) { 1067 const intptr_t dest_index) {
1121 DeoptInstr* deopt_instr = NULL; 1068 DeoptInstr* deopt_instr = NULL;
1122 if (source_loc.IsConstant()) { 1069 if (source_loc.IsConstant()) {
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
1354 Smi* offset, 1301 Smi* offset,
1355 DeoptInfo* info, 1302 DeoptInfo* info,
1356 Smi* reason) { 1303 Smi* reason) {
1357 intptr_t i = index * kEntrySize; 1304 intptr_t i = index * kEntrySize;
1358 *offset ^= table.At(i); 1305 *offset ^= table.At(i);
1359 *info ^= table.At(i + 1); 1306 *info ^= table.At(i + 1);
1360 *reason ^= table.At(i + 2); 1307 *reason ^= table.At(i + 2);
1361 } 1308 }
1362 1309
1363 } // namespace dart 1310 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698