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

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

Issue 2179983002: Implemented schema change for the isolate reload operation. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: CL response Created 4 years, 4 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"
(...skipping 26 matching lines...) Expand all
37 37
38 #define I (isolate()) 38 #define I (isolate())
39 #define Z (thread->zone()) 39 #define Z (thread->zone())
40 40
41 #define TIMELINE_SCOPE(name) \ 41 #define TIMELINE_SCOPE(name) \
42 TimelineDurationScope tds##name(Thread::Current(), \ 42 TimelineDurationScope tds##name(Thread::Current(), \
43 Timeline::GetIsolateStream(), \ 43 Timeline::GetIsolateStream(), \
44 #name) 44 #name)
45 45
46 46
47 InstanceMorpher::InstanceMorpher(const Class& from, const Class& to)
48 : from_(from), to_(to), mapping_() {
49 ComputeMapping();
50 before_ = new ZoneGrowableArray<const Instance*>();
51 after_ = new ZoneGrowableArray<const Instance*>();
52 ASSERT(from_.id() == to_.id());
53 cid_ = from_.id();
54 }
55
56
57 void InstanceMorpher::AddObject(RawObject* object) const {
58 ASSERT(object->GetClassId() == cid());
59 const Instance& instance = Instance::Cast(Object::Handle(object));
60 before_->Add(&instance);
61 }
62
63
64 void InstanceMorpher::ComputeMapping() {
65 if (from_.NumTypeArguments()) {
66 // Add copying of the optional type argument field.
67 intptr_t from_offset = from_.type_arguments_field_offset();
68 ASSERT(from_offset != Class::kNoTypeArguments);
69 intptr_t to_offset = to_.type_arguments_field_offset();
70 ASSERT(to_offset != Class::kNoTypeArguments);
71 mapping_.Add(from_offset);
72 mapping_.Add(to_offset);
73 }
74
75 // Add copying of the instance fields if matching by name.
76 // Note: currently the type of the fields are ignored.
77 const Array& from_fields = Array::Handle(from_.OffsetToFieldMap());
78 const Array& to_fields = Array::Handle(to_.OffsetToFieldMap());
79 Field& from_field = Field::Handle();
80 Field& to_field = Field::Handle();
81 String& from_name = String::Handle();
82 String& to_name = String::Handle();
83 for (intptr_t i = 0; i < from_fields.Length(); i++) {
84 if (from_fields.At(i) == Field::null()) continue; // Ignore non-fields.
85 from_field = Field::RawCast(from_fields.At(i));
86 ASSERT(from_field.is_instance());
87 from_name = from_field.name();
88 // We now have to find where this field is in the to class.
89 for (intptr_t j = 0; j < to_fields.Length(); j++) {
90 if (to_fields.At(j) == Field::null()) continue; // Ignore non-fields.
91 to_field = Field::RawCast(to_fields.At(j));
92 ASSERT(to_field.is_instance());
93 to_name = to_field.name();
94 if (from_name.Equals(to_name)) {
95 // Success
96 mapping_.Add(from_field.Offset());
97 mapping_.Add(to_field.Offset());
98 }
99 }
100 }
101 }
102
103
104 RawInstance* InstanceMorpher::Morph(const Instance& instance) const {
105 const Instance& result = Instance::Handle(Instance::New(to_));
106 // Morph the context from instance to result using mapping_.
107 for (intptr_t i = 0; i < mapping_.length(); i +=2) {
108 intptr_t from_offset = mapping_.At(i);
109 intptr_t to_offset = mapping_.At(i+1);
110 const Object& value =
111 Object::Handle(instance.RawGetFieldAtOffset(from_offset));
112 result.RawSetFieldAtOffset(to_offset, value);
113 }
114 // Convert the instance into a filler object.
115 Become::MakeDummyObject(instance);
116 return result.raw();
117 }
118
119
120 void InstanceMorpher::CreateMorphedCopies() const {
121 for (intptr_t i = 0; i < before()->length(); i++) {
122 const Instance& copy = Instance::Handle(Morph(*before()->At(i)));
123 after()->Add(&copy);
124 }
125 }
126
127
128 void InstanceMorpher::DumpFormatFor(const Class& cls) const {
129 LogBlock blocker;
Cutch 2016/07/26 17:10:16 Remove this LogBlock -- the one in Dump should be
bakster 2016/07/26 18:01:47 Done.
130 THR_Print("%s\n", cls.ToCString());
131 if (cls.NumTypeArguments()) {
132 intptr_t field_offset = cls.type_arguments_field_offset();
133 ASSERT(field_offset != Class::kNoTypeArguments);
134 THR_Print(" - @%" Pd " <type arguments>\n", field_offset);
135 }
136 const Array& fields = Array::Handle(cls.OffsetToFieldMap());
137 Field& field = Field::Handle();
138 String& name = String::Handle();
139 for (intptr_t i = 0; i < fields.Length(); i++) {
140 if (fields.At(i) != Field::null()) {
141 field = Field::RawCast(fields.At(i));
142 ASSERT(field.is_instance());
143 name = field.name();
144 THR_Print(" - @%" Pd " %s\n", field.Offset(), name.ToCString());
145 }
146 }
147
148 THR_Print("Mapping: ");
149 for (int i = 0; i < mapping_.length(); i +=2) {
150 THR_Print(" %" Pd "->%" Pd, mapping_.At(i), mapping_.At(i+1));
151 }
152 THR_Print("\n");
153 }
154
155
156 void InstanceMorpher::Dump() const {
157 LogBlock blocker;
158 THR_Print("Morphing from ");
159 DumpFormatFor(from_);
160 THR_Print("To ");
161 DumpFormatFor(to_);
162 THR_Print("\n");
163 }
164
165
166 void ReasonForCancelling::Report(IsolateReloadContext* context) {
167 const Error& error = Error::Handle(ToError());
168 context->ReportError(error);
169 }
170
171
172 RawError* ReasonForCancelling::ToError() {
173 // By default create the error returned from ToString.
174 const String& message = String::Handle(ToString());
175 return LanguageError::New(message);
176 }
177
178
179 RawString* ReasonForCancelling::ToString() {
180 UNREACHABLE();
181 return NULL;
182 }
183
184
185 RawError* IsolateReloadContext::error() const {
186 ASSERT(has_error());
187 // Report the first error to the surroundings.
188 const Error& error =
189 Error::Handle(reasons_to_cancel_reload_.At(0)->ToError());
190 OS::Print("[[%s]]\n", error.ToCString());
191 return error.raw();
192 }
193
47 class ScriptUrlSetTraits { 194 class ScriptUrlSetTraits {
48 public: 195 public:
49 static bool ReportStats() { return false; } 196 static bool ReportStats() { return false; }
50 static const char* Name() { return "ScriptUrlSetTraits"; } 197 static const char* Name() { return "ScriptUrlSetTraits"; }
51 198
52 static bool IsMatch(const Object& a, const Object& b) { 199 static bool IsMatch(const Object& a, const Object& b) {
53 if (!a.IsString() || !b.IsString()) { 200 if (!a.IsString() || !b.IsString()) {
54 return false; 201 return false;
55 } 202 }
56 203
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 String::Handle(a_lib.IsNull() ? String::null() : a_lib.url()); 320 String::Handle(a_lib.IsNull() ? String::null() : a_lib.url());
174 const String& b_lib_url = 321 const String& b_lib_url =
175 String::Handle(b_lib.IsNull() ? String::null() : b_lib.url()); 322 String::Handle(b_lib.IsNull() ? String::null() : b_lib.url());
176 return a_lib_url.Equals(b_lib_url); 323 return a_lib_url.Equals(b_lib_url);
177 } 324 }
178 325
179 326
180 IsolateReloadContext::IsolateReloadContext(Isolate* isolate) 327 IsolateReloadContext::IsolateReloadContext(Isolate* isolate)
181 : start_time_micros_(OS::GetCurrentMonotonicMicros()), 328 : start_time_micros_(OS::GetCurrentMonotonicMicros()),
182 isolate_(isolate), 329 isolate_(isolate),
183 has_error_(false),
184 saved_num_cids_(-1), 330 saved_num_cids_(-1),
185 saved_class_table_(NULL), 331 saved_class_table_(NULL),
186 num_saved_libs_(-1), 332 num_saved_libs_(-1),
333 instance_morphers_(),
334 reasons_to_cancel_reload_(),
335 cid_mapper_(),
187 script_uri_(String::null()), 336 script_uri_(String::null()),
188 error_(Error::null()), 337 error_(Error::null()),
189 old_classes_set_storage_(Array::null()), 338 old_classes_set_storage_(Array::null()),
190 class_map_storage_(Array::null()), 339 class_map_storage_(Array::null()),
191 old_libraries_set_storage_(Array::null()), 340 old_libraries_set_storage_(Array::null()),
192 library_map_storage_(Array::null()), 341 library_map_storage_(Array::null()),
193 become_map_storage_(Array::null()), 342 become_map_storage_(Array::null()),
194 become_enum_mappings_(GrowableObjectArray::null()), 343 become_enum_mappings_(GrowableObjectArray::null()),
195 saved_root_library_(Library::null()), 344 saved_root_library_(Library::null()),
196 saved_libraries_(GrowableObjectArray::null()) { 345 saved_libraries_(GrowableObjectArray::null()) {
197 // NOTE: DO NOT ALLOCATE ANY RAW OBJECTS HERE. The IsolateReloadContext is not 346 // NOTE: DO NOT ALLOCATE ANY RAW OBJECTS HERE. The IsolateReloadContext is not
198 // associated with the isolate yet and if a GC is triggered here the raw 347 // associated with the isolate yet and if a GC is triggered here the raw
199 // objects will not be properly accounted for. 348 // objects will not be properly accounted for.
200 } 349 }
201 350
202 351
203 IsolateReloadContext::~IsolateReloadContext() { 352 IsolateReloadContext::~IsolateReloadContext() {
204 } 353 }
205 354
206 355
207 void IsolateReloadContext::ReportError(const Error& error) { 356 void IsolateReloadContext::ReportError(const Error& error) {
208 has_error_ = true;
209 error_ = error.raw();
210 if (FLAG_trace_reload) { 357 if (FLAG_trace_reload) {
211 THR_Print("ISO-RELOAD: Error: %s\n", error.ToErrorCString()); 358 THR_Print("ISO-RELOAD: Error: %s\n", error.ToErrorCString());
212 } 359 }
213 ServiceEvent service_event(I, ServiceEvent::kIsolateReload); 360 ServiceEvent service_event(I, ServiceEvent::kIsolateReload);
214 service_event.set_reload_error(&error); 361 service_event.set_reload_error(&error);
215 Service::HandleEvent(&service_event); 362 Service::HandleEvent(&service_event);
216 } 363 }
217 364
218 365
219 void IsolateReloadContext::ReportError(const String& error_msg) {
220 ReportError(LanguageError::Handle(LanguageError::New(error_msg)));
221 }
222
223
224 void IsolateReloadContext::ReportSuccess() { 366 void IsolateReloadContext::ReportSuccess() {
225 ServiceEvent service_event(I, ServiceEvent::kIsolateReload); 367 ServiceEvent service_event(I, ServiceEvent::kIsolateReload);
226 Service::HandleEvent(&service_event); 368 Service::HandleEvent(&service_event);
227 } 369 }
228 370
229 371
372 class Aborted : public ReasonForCancelling {
373 public:
374 explicit Aborted(const Error& error)
375 : ReasonForCancelling(), error_(error) { }
376
377 private:
378 const Error& error_;
379
380 RawError* ToError() { return error_.raw(); }
381 RawString* ToString() {
382 return String::NewFormatted("%s", error_.ToErrorCString());
383 }
384 };
385
386
230 void IsolateReloadContext::StartReload() { 387 void IsolateReloadContext::StartReload() {
231 TIMELINE_SCOPE(Reload); 388 TIMELINE_SCOPE(Reload);
232 Thread* thread = Thread::Current(); 389 Thread* thread = Thread::Current();
233 ASSERT(isolate() == thread->isolate()); 390 ASSERT(isolate() == thread->isolate());
234 391
235 // Grab root library before calling CheckpointBeforeReload. 392 // Grab root library before calling CheckpointBeforeReload.
236 const Library& root_lib = Library::Handle(object_store()->root_library()); 393 const Library& root_lib = Library::Handle(object_store()->root_library());
237 ASSERT(!root_lib.IsNull()); 394 ASSERT(!root_lib.IsNull());
238 const String& root_lib_url = String::Handle(root_lib.url()); 395 const String& root_lib_url = String::Handle(root_lib.url());
239 396
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 TransitionVMToNative transition(thread); 431 TransitionVMToNative transition(thread);
275 Api::Scope api_scope(thread); 432 Api::Scope api_scope(thread);
276 433
277 Dart_Handle retval = 434 Dart_Handle retval =
278 (I->library_tag_handler())(Dart_kScriptTag, 435 (I->library_tag_handler())(Dart_kScriptTag,
279 Api::NewHandle(thread, Library::null()), 436 Api::NewHandle(thread, Library::null()),
280 Api::NewHandle(thread, root_lib_url.raw())); 437 Api::NewHandle(thread, root_lib_url.raw()));
281 result = Api::UnwrapHandle(retval); 438 result = Api::UnwrapHandle(retval);
282 } 439 }
283 if (result.IsError()) { 440 if (result.IsError()) {
284 ReportError(Error::Cast(result)); 441 const Error& error = Error::Cast(result);
442 AddReasonForCancelling(new Aborted(error));
285 } 443 }
286 } 444 }
287 445
288 446
289 void IsolateReloadContext::RegisterClass(const Class& new_cls) { 447 void IsolateReloadContext::RegisterClass(const Class& new_cls) {
290 const Class& old_cls = Class::Handle(OldClassOrNull(new_cls)); 448 const Class& old_cls = Class::Handle(OldClassOrNull(new_cls));
291 if (old_cls.IsNull()) { 449 if (old_cls.IsNull()) {
292 I->class_table()->Register(new_cls); 450 I->class_table()->Register(new_cls);
293 451
294 if (FLAG_identity_reload) { 452 if (FLAG_identity_reload) {
(...skipping 17 matching lines...) Expand all
312 } 470 }
313 471
314 472
315 void IsolateReloadContext::FinishReload() { 473 void IsolateReloadContext::FinishReload() {
316 BuildLibraryMapping(); 474 BuildLibraryMapping();
317 TIR_Print("---- DONE FINALIZING\n"); 475 TIR_Print("---- DONE FINALIZING\n");
318 if (ValidateReload()) { 476 if (ValidateReload()) {
319 Commit(); 477 Commit();
320 PostCommit(); 478 PostCommit();
321 } else { 479 } else {
480 ReportReasonsForCancelling();
322 Rollback(); 481 Rollback();
323 } 482 }
324 // ValidateReload mutates the direct subclass information and does 483 // ValidateReload mutates the direct subclass information and does
325 // not remove dead subclasses. Rebuild the direct subclass 484 // not remove dead subclasses. Rebuild the direct subclass
326 // information from scratch. 485 // information from scratch.
327 RebuildDirectSubclasses(); 486 RebuildDirectSubclasses();
328 487
329 if (FLAG_write_protect_code) { 488 if (FLAG_write_protect_code) {
330 // Disable code page write protection while we are reloading. 489 // Disable code page write protection while we are reloading.
331 I->heap()->WriteProtectCode(true); 490 I->heap()->WriteProtectCode(true);
332 } 491 }
333 492
334 BackgroundCompiler::Enable(); 493 BackgroundCompiler::Enable();
335 } 494 }
336 495
337 496
338 void IsolateReloadContext::AbortReload(const Error& error) { 497 void IsolateReloadContext::AbortReload(const Error& error) {
339 ReportError(error); 498 AddReasonForCancelling(new Aborted(error));
499 ReportReasonsForCancelling();
340 Rollback(); 500 Rollback();
341 } 501 }
342 502
343 503
344 void IsolateReloadContext::EnsuredUnoptimizedCodeForStack() { 504 void IsolateReloadContext::EnsuredUnoptimizedCodeForStack() {
345 TIMELINE_SCOPE(EnsuredUnoptimizedCodeForStack); 505 TIMELINE_SCOPE(EnsuredUnoptimizedCodeForStack);
346 StackFrameIterator it(StackFrameIterator::kDontValidateFrames); 506 StackFrameIterator it(StackFrameIterator::kDontValidateFrames);
347 507
348 Function& func = Function::Handle(); 508 Function& func = Function::Handle();
349 while (it.HasNextFrame()) { 509 while (it.HasNextFrame()) {
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 class_map.Release(); 738 class_map.Release();
579 reverse_class_map.Release(); 739 reverse_class_map.Release();
580 } 740 }
581 #endif 741 #endif
582 742
583 743
584 void IsolateReloadContext::Commit() { 744 void IsolateReloadContext::Commit() {
585 TIMELINE_SCOPE(Commit); 745 TIMELINE_SCOPE(Commit);
586 TIR_Print("---- COMMITTING REVERSE MAP\n"); 746 TIR_Print("---- COMMITTING REVERSE MAP\n");
587 747
748 // Perform shape shifting of instances if necessary.
749 if (HasInstanceMorphers()) {
750 MorphInstances();
Cutch 2016/07/26 17:10:16 Calling MorphInstances resets the saved_class_tabl
bakster 2016/07/26 18:01:47 The placement will be documents.
751 }
752
588 #ifdef DEBUG 753 #ifdef DEBUG
589 VerifyMaps(); 754 VerifyMaps();
590 #endif 755 #endif
591 756
592 { 757 {
593 TIMELINE_SCOPE(CopyStaticFieldsAndPatchFieldsAndFunctions); 758 TIMELINE_SCOPE(CopyStaticFieldsAndPatchFieldsAndFunctions);
594 // Copy static field values from the old classes to the new classes. 759 // Copy static field values from the old classes to the new classes.
595 // Patch fields and functions in the old classes so that they retain 760 // Patch fields and functions in the old classes so that they retain
596 // the old script. 761 // the old script.
597 Class& cls = Class::Handle(); 762 Class& cls = Class::Handle();
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 } 824 }
660 825
661 // Initialize library side table. 826 // Initialize library side table.
662 library_infos_.SetLength(libs.Length()); 827 library_infos_.SetLength(libs.Length());
663 for (intptr_t i = 0; i < libs.Length(); i++) { 828 for (intptr_t i = 0; i < libs.Length(); i++) {
664 lib = Library::RawCast(libs.At(i)); 829 lib = Library::RawCast(libs.At(i));
665 // Mark the library dirty if it comes after the libraries we saved. 830 // Mark the library dirty if it comes after the libraries we saved.
666 library_infos_[i].dirty = i >= num_saved_libs_; 831 library_infos_[i].dirty = i >= num_saved_libs_;
667 } 832 }
668 } 833 }
669 834
Cutch 2016/07/26 17:10:16 call MorphInstances here instead
bakster 2016/07/26 18:01:47 Acknowledged.
670 { 835 {
671 const GrowableObjectArray& become_enum_mappings = 836 const GrowableObjectArray& become_enum_mappings =
672 GrowableObjectArray::Handle(become_enum_mappings_); 837 GrowableObjectArray::Handle(become_enum_mappings_);
673 UnorderedHashMap<BecomeMapTraits> become_map(become_map_storage_); 838 UnorderedHashMap<BecomeMapTraits> become_map(become_map_storage_);
674 intptr_t replacement_count = become_map.NumOccupied() + 839 intptr_t replacement_count = become_map.NumOccupied() +
675 become_enum_mappings.Length() / 2; 840 become_enum_mappings.Length() / 2;
676 const Array& before = 841 const Array& before =
677 Array::Handle(Array::New(replacement_count, Heap::kOld)); 842 Array::Handle(Array::New(replacement_count, Heap::kOld));
678 const Array& after = 843 const Array& after =
679 Array::Handle(Array::New(replacement_count, Heap::kOld)); 844 Array::Handle(Array::New(replacement_count, Heap::kOld));
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
733 898
734 void IsolateReloadContext::PostCommit() { 899 void IsolateReloadContext::PostCommit() {
735 TIMELINE_SCOPE(PostCommit); 900 TIMELINE_SCOPE(PostCommit);
736 set_saved_root_library(Library::Handle()); 901 set_saved_root_library(Library::Handle());
737 set_saved_libraries(GrowableObjectArray::Handle()); 902 set_saved_libraries(GrowableObjectArray::Handle());
738 InvalidateWorld(); 903 InvalidateWorld();
739 TIR_Print("---- DONE COMMIT\n"); 904 TIR_Print("---- DONE COMMIT\n");
740 } 905 }
741 906
742 907
908 void IsolateReloadContext::AddReasonForCancelling(ReasonForCancelling* reason) {
909 reasons_to_cancel_reload_.Add(reason);
910 }
911
912
913 void IsolateReloadContext::AddInstanceMorpher(InstanceMorpher* morpher) {
914 instance_morphers_.Add(morpher);
915 cid_mapper_.Insert(morpher);
916 }
917
918
919 void IsolateReloadContext::ReportReasonsForCancelling() {
920 ASSERT(HasReasonsForCancelling());
921 for (int i = 0; i < reasons_to_cancel_reload_.length(); i++) {
922 reasons_to_cancel_reload_.At(i)->Report(this);
923 }
924 }
925
926
927 // The ObjectLocator is used for collecting instances that
928 // needs to be morphed.
929 class ObjectLocator : public ObjectVisitor {
930 public:
931 explicit ObjectLocator(IsolateReloadContext* context)
932 : context_(context), count_(0) {
933 }
934
935 void VisitObject(RawObject* obj) {
936 InstanceMorpher* morpher =
937 context_->cid_mapper_.LookupValue(obj->GetClassId());
938 if (morpher != NULL) {
939 morpher->AddObject(obj);
940 count_++;
941 }
942 }
943
944 // Return the number of located objects for morphing.
945 intptr_t count() { return count_; }
946 private:
Cutch 2016/07/26 17:10:16 blank line between count() and private:
bakster 2016/07/26 18:01:47 Done.
947 IsolateReloadContext* context_;
948 intptr_t count_;
949 };
950
951
952 void IsolateReloadContext::MorphInstances() {
953 TIMELINE_SCOPE(MorphInstances);
954 ASSERT(HasInstanceMorphers());
955 if (FLAG_trace_reload) {
956 LogBlock blocker;
957 TIR_Print("MorphInstance: \n");
958 for (intptr_t i = 0; i < instance_morphers_.length(); i++) {
959 instance_morphers_.At(i)->Dump();
960 }
961 }
962
963 // Find all objects that need to be morphed.
964 ObjectLocator locator(this);
965 isolate()->heap()->VisitObjects(&locator);
966
967 // Return if no objects are located.
968 intptr_t count = locator.count();
969 if (count == 0) return;
970
971 TIR_Print("Found %" Pd " object%s subject to morphing.\n",
972 count, (count > 1) ? "s" : "");
973
974 Array& before = Array::Handle();
975 Array& after = Array::Handle();
976 { // Prevent GC to take place due object format confusion.
977 // Hint: More than one class share the same cid.
978 NoHeapGrowthControlScope scope;
979 for (intptr_t i = 0; i < instance_morphers_.length(); i++) {
980 instance_morphers_.At(i)->CreateMorphedCopies();
981 }
982 // Create the inputs for Become.
983 intptr_t index = 0;
984 before = Array::New(count);
985 after = Array::New(count);
986 for (intptr_t i = 0; i < instance_morphers_.length(); i++) {
987 InstanceMorpher* morpher = instance_morphers_.At(i);
988 for (intptr_t j = 0; j < morpher->before()->length(); j++) {
989 before.SetAt(index, *morpher->before()->At(j));
990 after.SetAt(index, *morpher->after()->At(j));
991 index++;
992 }
993 }
994 ASSERT(index == count);
995 }
996
997 // This is important: The saved class table (describing before objects)
998 // must be zapped to prevent the forwarding in GetClassForHeapWalkAt.
999 // Instance will from now be described by the isolate's class table.
1000 free(saved_class_table_);
1001 saved_class_table_ = NULL;
1002 Become::ElementsForwardIdentity(before, after);
1003 }
1004
1005
743 bool IsolateReloadContext::ValidateReload() { 1006 bool IsolateReloadContext::ValidateReload() {
744 TIMELINE_SCOPE(ValidateReload); 1007 TIMELINE_SCOPE(ValidateReload);
745 if (has_error_) { 1008 if (has_error()) return false;
746 return false;
747 }
748 1009
749 // Validate libraries. 1010 // Validate libraries.
750 { 1011 {
751 ASSERT(library_map_storage_ != Array::null()); 1012 ASSERT(library_map_storage_ != Array::null());
752 UnorderedHashMap<LibraryMapTraits> map(library_map_storage_); 1013 UnorderedHashMap<LibraryMapTraits> map(library_map_storage_);
753 UnorderedHashMap<LibraryMapTraits>::Iterator it(&map); 1014 UnorderedHashMap<LibraryMapTraits>::Iterator it(&map);
754 Library& lib = Library::Handle(); 1015 Library& lib = Library::Handle();
755 Library& new_lib = Library::Handle(); 1016 Library& new_lib = Library::Handle();
756 while (it.MoveNext()) { 1017 while (it.MoveNext()) {
757 const intptr_t entry = it.Current(); 1018 const intptr_t entry = it.Current();
758 new_lib = Library::RawCast(map.GetKey(entry)); 1019 new_lib = Library::RawCast(map.GetKey(entry));
759 lib = Library::RawCast(map.GetPayload(entry, 0)); 1020 lib = Library::RawCast(map.GetPayload(entry, 0));
760 if (new_lib.raw() != lib.raw()) { 1021 if (new_lib.raw() != lib.raw()) {
761 if (!lib.CanReload(new_lib)) { 1022 lib.CheckReload(new_lib, this);
762 map.Release();
763 return false;
764 }
765 } 1023 }
766 } 1024 }
767 map.Release(); 1025 map.Release();
768 } 1026 }
769 1027
770 // Validate classes. 1028 // Validate classes.
771 { 1029 {
772 ASSERT(class_map_storage_ != Array::null()); 1030 ASSERT(class_map_storage_ != Array::null());
773 UnorderedHashMap<ClassMapTraits> map(class_map_storage_); 1031 UnorderedHashMap<ClassMapTraits> map(class_map_storage_);
774 UnorderedHashMap<ClassMapTraits>::Iterator it(&map); 1032 UnorderedHashMap<ClassMapTraits>::Iterator it(&map);
775 Class& cls = Class::Handle(); 1033 Class& cls = Class::Handle();
776 Class& new_cls = Class::Handle(); 1034 Class& new_cls = Class::Handle();
777 while (it.MoveNext()) { 1035 while (it.MoveNext()) {
778 const intptr_t entry = it.Current(); 1036 const intptr_t entry = it.Current();
779 new_cls = Class::RawCast(map.GetKey(entry)); 1037 new_cls = Class::RawCast(map.GetKey(entry));
780 cls = Class::RawCast(map.GetPayload(entry, 0)); 1038 cls = Class::RawCast(map.GetPayload(entry, 0));
781 if (new_cls.raw() != cls.raw()) { 1039 if (new_cls.raw() != cls.raw()) {
782 if (!cls.CanReload(new_cls)) { 1040 cls.CheckReload(new_cls, this);
783 map.Release();
784 return false;
785 }
786 } 1041 }
787 } 1042 }
788 map.Release(); 1043 map.Release();
789 } 1044 }
790 return true; 1045
1046 return !HasReasonsForCancelling();
791 } 1047 }
792 1048
793 1049
794 RawClass* IsolateReloadContext::FindOriginalClass(const Class& cls) { 1050 RawClass* IsolateReloadContext::FindOriginalClass(const Class& cls) {
795 return MappedClass(cls); 1051 return MappedClass(cls);
796 } 1052 }
797 1053
798 1054
799 RawClass* IsolateReloadContext::GetClassForHeapWalkAt(intptr_t cid) { 1055 RawClass* IsolateReloadContext::GetClassForHeapWalkAt(intptr_t cid) {
800 if (saved_class_table_ != NULL) { 1056 if (saved_class_table_ != NULL) {
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
1131 ASSERT(!super_cls.IsNull()); 1387 ASSERT(!super_cls.IsNull());
1132 super_cls.AddDirectSubclass(cls); 1388 super_cls.AddDirectSubclass(cls);
1133 } 1389 }
1134 } 1390 }
1135 } 1391 }
1136 } 1392 }
1137 1393
1138 #endif // !PRODUCT 1394 #endif // !PRODUCT
1139 1395
1140 } // namespace dart 1396 } // 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