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

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

Issue 2153143002: Rework how enums are implemented and reloaded (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 5 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
« no previous file with comments | « runtime/vm/isolate_reload.h ('k') | runtime/vm/isolate_reload_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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/isolate_reload.h" 5 #include "vm/isolate_reload.h"
6 6
7 #include "vm/become.h" 7 #include "vm/become.h"
8 #include "vm/code_generator.h" 8 #include "vm/code_generator.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/dart_api_impl.h" 10 #include "vm/dart_api_impl.h"
11 #include "vm/hash_table.h" 11 #include "vm/hash_table.h"
12 #include "vm/isolate.h" 12 #include "vm/isolate.h"
13 #include "vm/log.h" 13 #include "vm/log.h"
14 #include "vm/object.h" 14 #include "vm/object.h"
15 #include "vm/object_store.h" 15 #include "vm/object_store.h"
16 #include "vm/parser.h" 16 #include "vm/parser.h"
17 #include "vm/safepoint.h" 17 #include "vm/safepoint.h"
18 #include "vm/service_event.h" 18 #include "vm/service_event.h"
19 #include "vm/stack_frame.h" 19 #include "vm/stack_frame.h"
20 #include "vm/thread.h" 20 #include "vm/thread.h"
21 #include "vm/timeline.h" 21 #include "vm/timeline.h"
22 #include "vm/visitor.h" 22 #include "vm/visitor.h"
23 23
24 namespace dart { 24 namespace dart {
25 25
26 DEFINE_FLAG(bool, trace_reload, false, "Trace isolate reloading"); 26 DEFINE_FLAG(bool, trace_reload, false, "Trace isolate reloading");
27 DEFINE_FLAG(bool, trace_reload_verbose, false,
28 "trace isolate reloading verbose");
27 DEFINE_FLAG(bool, identity_reload, false, "Enable checks for identity reload."); 29 DEFINE_FLAG(bool, identity_reload, false, "Enable checks for identity reload.");
28 DEFINE_FLAG(int, reload_every, 0, "Reload every N stack overflow checks."); 30 DEFINE_FLAG(int, reload_every, 0, "Reload every N stack overflow checks.");
29 DEFINE_FLAG(bool, reload_every_optimized, true, "Only from optimized code."); 31 DEFINE_FLAG(bool, reload_every_optimized, true, "Only from optimized code.");
30 DEFINE_FLAG(bool, reload_every_back_off, false, 32 DEFINE_FLAG(bool, reload_every_back_off, false,
31 "Double the --reload-every value after each reload."); 33 "Double the --reload-every value after each reload.");
32 DEFINE_FLAG(bool, check_reloaded, false, 34 DEFINE_FLAG(bool, check_reloaded, false,
33 "Assert that an isolate has reloaded at least once.") 35 "Assert that an isolate has reloaded at least once.")
34 #ifndef PRODUCT 36 #ifndef PRODUCT
35 37
36 #define I (isolate()) 38 #define I (isolate())
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 static uword Hash(const Object& obj) { 112 static uword Hash(const Object& obj) {
111 if (obj.IsLibrary()) { 113 if (obj.IsLibrary()) {
112 return Library::Cast(obj).UrlHash(); 114 return Library::Cast(obj).UrlHash();
113 } else if (obj.IsClass()) { 115 } else if (obj.IsClass()) {
114 if (Class::Cast(obj).id() == kFreeListElement) { 116 if (Class::Cast(obj).id() == kFreeListElement) {
115 return 0; 117 return 0;
116 } 118 }
117 return String::HashRawSymbol(Class::Cast(obj).Name()); 119 return String::HashRawSymbol(Class::Cast(obj).Name());
118 } else if (obj.IsField()) { 120 } else if (obj.IsField()) {
119 return String::HashRawSymbol(Field::Cast(obj).name()); 121 return String::HashRawSymbol(Field::Cast(obj).name());
122 } else if (obj.IsInstance()) {
123 return Smi::Handle(Smi::RawCast(Instance::Cast(obj).HashCode())).Value();
120 } 124 }
121 return 0; 125 return 0;
122 } 126 }
123 }; 127 };
124 128
125 129
126 bool IsolateReloadContext::IsSameField(const Field& a, const Field& b) { 130 bool IsolateReloadContext::IsSameField(const Field& a, const Field& b) {
127 if (a.is_static() != b.is_static()) { 131 if (a.is_static() != b.is_static()) {
128 return false; 132 return false;
129 } 133 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 saved_num_cids_(-1), 185 saved_num_cids_(-1),
182 saved_class_table_(NULL), 186 saved_class_table_(NULL),
183 num_saved_libs_(-1), 187 num_saved_libs_(-1),
184 script_uri_(String::null()), 188 script_uri_(String::null()),
185 error_(Error::null()), 189 error_(Error::null()),
186 old_classes_set_storage_(Array::null()), 190 old_classes_set_storage_(Array::null()),
187 class_map_storage_(Array::null()), 191 class_map_storage_(Array::null()),
188 old_libraries_set_storage_(Array::null()), 192 old_libraries_set_storage_(Array::null()),
189 library_map_storage_(Array::null()), 193 library_map_storage_(Array::null()),
190 become_map_storage_(Array::null()), 194 become_map_storage_(Array::null()),
195 become_enum_mappings_(GrowableObjectArray::null()),
191 saved_root_library_(Library::null()), 196 saved_root_library_(Library::null()),
192 saved_libraries_(GrowableObjectArray::null()) { 197 saved_libraries_(GrowableObjectArray::null()) {
193 // NOTE: DO NOT ALLOCATE ANY RAW OBJECTS HERE. The IsolateReloadContext is not 198 // NOTE: DO NOT ALLOCATE ANY RAW OBJECTS HERE. The IsolateReloadContext is not
194 // associated with the isolate yet and if a GC is triggered here the raw 199 // associated with the isolate yet and if a GC is triggered here the raw
195 // objects will not be properly accounted for. 200 // objects will not be properly accounted for.
196 } 201 }
197 202
198 203
199 IsolateReloadContext::~IsolateReloadContext() { 204 IsolateReloadContext::~IsolateReloadContext() {
200 } 205 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 old_classes_set_storage_ = 242 old_classes_set_storage_ =
238 HashTables::New<UnorderedHashSet<ClassMapTraits> >(4); 243 HashTables::New<UnorderedHashSet<ClassMapTraits> >(4);
239 class_map_storage_ = 244 class_map_storage_ =
240 HashTables::New<UnorderedHashMap<ClassMapTraits> >(4); 245 HashTables::New<UnorderedHashMap<ClassMapTraits> >(4);
241 old_libraries_set_storage_ = 246 old_libraries_set_storage_ =
242 HashTables::New<UnorderedHashSet<LibraryMapTraits> >(4); 247 HashTables::New<UnorderedHashSet<LibraryMapTraits> >(4);
243 library_map_storage_ = 248 library_map_storage_ =
244 HashTables::New<UnorderedHashMap<LibraryMapTraits> >(4); 249 HashTables::New<UnorderedHashMap<LibraryMapTraits> >(4);
245 become_map_storage_ = 250 become_map_storage_ =
246 HashTables::New<UnorderedHashMap<BecomeMapTraits> >(4); 251 HashTables::New<UnorderedHashMap<BecomeMapTraits> >(4);
252 // Keep a separate array for enum mappings to avoid having to invoke
253 // hashCode on the instances.
254 become_enum_mappings_ = GrowableObjectArray::New(Heap::kOld);
247 255
248 // Disable the background compiler while we are performing the reload. 256 // Disable the background compiler while we are performing the reload.
249 BackgroundCompiler::Disable(); 257 BackgroundCompiler::Disable();
250 258
251 if (FLAG_write_protect_code) { 259 if (FLAG_write_protect_code) {
252 // Disable code page write protection while we are reloading. 260 // Disable code page write protection while we are reloading.
253 I->heap()->WriteProtectCode(false); 261 I->heap()->WriteProtectCode(false);
254 } 262 }
255 263
256 // Ensure all functions on the stack have unoptimized code. 264 // Ensure all functions on the stack have unoptimized code.
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 { 603 {
596 UnorderedHashMap<ClassMapTraits>::Iterator it(&class_map); 604 UnorderedHashMap<ClassMapTraits>::Iterator it(&class_map);
597 while (it.MoveNext()) { 605 while (it.MoveNext()) {
598 const intptr_t entry = it.Current(); 606 const intptr_t entry = it.Current();
599 new_cls = Class::RawCast(class_map.GetKey(entry)); 607 new_cls = Class::RawCast(class_map.GetKey(entry));
600 cls = Class::RawCast(class_map.GetPayload(entry, 0)); 608 cls = Class::RawCast(class_map.GetPayload(entry, 0));
601 if (new_cls.raw() != cls.raw()) { 609 if (new_cls.raw() != cls.raw()) {
602 ASSERT(new_cls.is_enum_class() == cls.is_enum_class()); 610 ASSERT(new_cls.is_enum_class() == cls.is_enum_class());
603 if (new_cls.is_enum_class() && new_cls.is_finalized()) { 611 if (new_cls.is_enum_class() && new_cls.is_finalized()) {
604 new_cls.ReplaceEnum(cls); 612 new_cls.ReplaceEnum(cls);
613 } else {
614 new_cls.CopyStaticFieldValues(cls);
605 } 615 }
606 new_cls.CopyStaticFieldValues(cls);
607 cls.PatchFieldsAndFunctions(); 616 cls.PatchFieldsAndFunctions();
608 } 617 }
609 } 618 }
610 } 619 }
611 620
612 class_map.Release(); 621 class_map.Release();
613 } 622 }
614 623
615 // Copy over certain properties of libraries, e.g. is the library 624 // Copy over certain properties of libraries, e.g. is the library
616 // debuggable? 625 // debuggable?
(...skipping 22 matching lines...) Expand all
639 } 648 }
640 649
641 { 650 {
642 TIMELINE_SCOPE(UpdateLibrariesArray); 651 TIMELINE_SCOPE(UpdateLibrariesArray);
643 // Update the libraries array. 652 // Update the libraries array.
644 Library& lib = Library::Handle(); 653 Library& lib = Library::Handle();
645 const GrowableObjectArray& libs = GrowableObjectArray::Handle( 654 const GrowableObjectArray& libs = GrowableObjectArray::Handle(
646 I->object_store()->libraries()); 655 I->object_store()->libraries());
647 for (intptr_t i = 0; i < libs.Length(); i++) { 656 for (intptr_t i = 0; i < libs.Length(); i++) {
648 lib = Library::RawCast(libs.At(i)); 657 lib = Library::RawCast(libs.At(i));
649 TIR_Print("Lib '%s' at index %" Pd "\n", lib.ToCString(), i); 658 VTIR_Print("Lib '%s' at index %" Pd "\n", lib.ToCString(), i);
650 lib.set_index(i); 659 lib.set_index(i);
651 } 660 }
652 661
653 // Initialize library side table. 662 // Initialize library side table.
654 library_infos_.SetLength(libs.Length()); 663 library_infos_.SetLength(libs.Length());
655 for (intptr_t i = 0; i < libs.Length(); i++) { 664 for (intptr_t i = 0; i < libs.Length(); i++) {
656 lib = Library::RawCast(libs.At(i)); 665 lib = Library::RawCast(libs.At(i));
657 // Mark the library dirty if it comes after the libraries we saved. 666 // Mark the library dirty if it comes after the libraries we saved.
658 library_infos_[i].dirty = i >= num_saved_libs_; 667 library_infos_[i].dirty = i >= num_saved_libs_;
659 } 668 }
660 } 669 }
661 670
662 { 671 {
672 const GrowableObjectArray& become_enum_mappings =
673 GrowableObjectArray::Handle(become_enum_mappings_);
663 UnorderedHashMap<BecomeMapTraits> become_map(become_map_storage_); 674 UnorderedHashMap<BecomeMapTraits> become_map(become_map_storage_);
664 intptr_t replacement_count = become_map.NumOccupied(); 675 intptr_t replacement_count = become_map.NumOccupied() +
676 become_enum_mappings.Length() / 2;
665 const Array& before = 677 const Array& before =
666 Array::Handle(Array::New(replacement_count, Heap::kOld)); 678 Array::Handle(Array::New(replacement_count, Heap::kOld));
667 const Array& after = 679 const Array& after =
668 Array::Handle(Array::New(replacement_count, Heap::kOld)); 680 Array::Handle(Array::New(replacement_count, Heap::kOld));
669 Object& obj = Object::Handle(); 681 Object& obj = Object::Handle();
670 intptr_t replacement_index = 0; 682 intptr_t replacement_index = 0;
671 UnorderedHashMap<BecomeMapTraits>::Iterator it(&become_map); 683 UnorderedHashMap<BecomeMapTraits>::Iterator it(&become_map);
672 while (it.MoveNext()) { 684 while (it.MoveNext()) {
673 const intptr_t entry = it.Current(); 685 const intptr_t entry = it.Current();
674 obj = become_map.GetKey(entry); 686 obj = become_map.GetKey(entry);
675 before.SetAt(replacement_index, obj); 687 before.SetAt(replacement_index, obj);
676 obj = become_map.GetPayload(entry, 0); 688 obj = become_map.GetPayload(entry, 0);
677 after.SetAt(replacement_index, obj); 689 after.SetAt(replacement_index, obj);
678 replacement_index++; 690 replacement_index++;
679 } 691 }
692 for (intptr_t i = 0; i < become_enum_mappings.Length(); i += 2) {
693 obj = become_enum_mappings.At(i);
694 before.SetAt(replacement_index, obj);
695 obj = become_enum_mappings.At(i + 1);
696 after.SetAt(replacement_index, obj);
697 replacement_index++;
698 }
680 ASSERT(replacement_index == replacement_count); 699 ASSERT(replacement_index == replacement_count);
681 become_map.Release(); 700 become_map.Release();
682 701
683 Become::ElementsForwardIdentity(before, after); 702 Become::ElementsForwardIdentity(before, after);
684 } 703 }
685 704
686 if (FLAG_identity_reload) { 705 if (FLAG_identity_reload) {
687 if (saved_num_cids_ != I->class_table()->NumCids()) { 706 if (saved_num_cids_ != I->class_table()->NumCids()) {
688 TIR_Print("Identity reload failed! B#C=%" Pd " A#C=%" Pd "\n", 707 TIR_Print("Identity reload failed! B#C=%" Pd " A#C=%" Pd "\n",
689 saved_num_cids_, 708 saved_num_cids_,
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
1062 void IsolateReloadContext::AddBecomeMapping(const Object& old, 1081 void IsolateReloadContext::AddBecomeMapping(const Object& old,
1063 const Object& neu) { 1082 const Object& neu) {
1064 ASSERT(become_map_storage_ != Array::null()); 1083 ASSERT(become_map_storage_ != Array::null());
1065 UnorderedHashMap<BecomeMapTraits> become_map(become_map_storage_); 1084 UnorderedHashMap<BecomeMapTraits> become_map(become_map_storage_);
1066 bool update = become_map.UpdateOrInsert(old, neu); 1085 bool update = become_map.UpdateOrInsert(old, neu);
1067 ASSERT(!update); 1086 ASSERT(!update);
1068 become_map_storage_ = become_map.Release().raw(); 1087 become_map_storage_ = become_map.Release().raw();
1069 } 1088 }
1070 1089
1071 1090
1091 void IsolateReloadContext::AddEnumBecomeMapping(const Object& old,
1092 const Object& neu) {
1093 const GrowableObjectArray& become_enum_mappings =
1094 GrowableObjectArray::Handle(become_enum_mappings_);
1095 become_enum_mappings.Add(old);
1096 become_enum_mappings.Add(neu);
1097 ASSERT((become_enum_mappings.Length() % 2) == 0);
1098 }
1099
1100
1072 void IsolateReloadContext::RebuildDirectSubclasses() { 1101 void IsolateReloadContext::RebuildDirectSubclasses() {
1073 ClassTable* class_table = I->class_table(); 1102 ClassTable* class_table = I->class_table();
1074 intptr_t num_cids = class_table->NumCids(); 1103 intptr_t num_cids = class_table->NumCids();
1075 1104
1076 // Clear the direct subclasses for all classes. 1105 // Clear the direct subclasses for all classes.
1077 Class& cls = Class::Handle(); 1106 Class& cls = Class::Handle();
1078 GrowableObjectArray& subclasses = GrowableObjectArray::Handle(); 1107 GrowableObjectArray& subclasses = GrowableObjectArray::Handle();
1079 for (intptr_t i = 1; i < num_cids; i++) { 1108 for (intptr_t i = 1; i < num_cids; i++) {
1080 if (class_table->HasValidClassAt(i)) { 1109 if (class_table->HasValidClassAt(i)) {
1081 cls = class_table->At(i); 1110 cls = class_table->At(i);
(...skipping 16 matching lines...) Expand all
1098 ASSERT(!super_cls.IsNull()); 1127 ASSERT(!super_cls.IsNull());
1099 super_cls.AddDirectSubclass(cls); 1128 super_cls.AddDirectSubclass(cls);
1100 } 1129 }
1101 } 1130 }
1102 } 1131 }
1103 } 1132 }
1104 1133
1105 #endif // !PRODUCT 1134 #endif // !PRODUCT
1106 1135
1107 } // namespace dart 1136 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/isolate_reload.h ('k') | runtime/vm/isolate_reload_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698