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

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: Added a few tests to isolate_reload_test.cc 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
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 OS::Print("%s\n", cls.ToCString());
Cutch 2016/07/26 14:42:45 Use a LogBlock scope object and THR_Print so multi
bakster 2016/07/26 16:54:51 Done.
130 if (cls.NumTypeArguments()) {
131 intptr_t field_offset = cls.type_arguments_field_offset();
132 ASSERT(field_offset != Class::kNoTypeArguments);
133 OS::Print(" - @%" Pd " <type arguments>\n", field_offset);
134 }
135 const Array& fields = Array::Handle(cls.OffsetToFieldMap());
136 Field& field = Field::Handle();
137 String& name = String::Handle();
138 for (intptr_t i = 0; i < fields.Length(); i++) {
139 if (fields.At(i) != Field::null()) {
140 field = Field::RawCast(fields.At(i));
141 ASSERT(field.is_instance());
142 name = field.name();
143 OS::Print(" - @%" Pd " %s\n", field.Offset(), name.ToCString());
144 }
145 }
146
147 OS::Print("Mapping: ");
148 for (int i = 0; i < mapping_.length(); i +=2) {
149 OS::Print(" %" Pd "->%" Pd, mapping_.At(i), mapping_.At(i+1));
150 }
151 OS::Print("\n");
152 }
153
154
155 void InstanceMorpher::Dump() const {
156 OS::Print("Morphing from ");
Cutch 2016/07/26 14:42:45 here too
bakster 2016/07/26 16:54:51 Done.
157 DumpFormatFor(from_);
158 OS::Print("To ");
159 DumpFormatFor(to_);
160 OS::Print("\n");
161 }
162
163
164 void ReasonForCancelling::Report(IsolateReloadContext* context) {
165 const Error& error = Error::Handle(ToError());
166 context->ReportError(error);
167 }
168
169
170 RawError* ReasonForCancelling::ToError() {
171 // By default create the error returned from ToString.
172 const String& message = String::Handle(ToString());
173 OS::Print("[[%s]]\n", message.ToCString());
Cutch 2016/07/26 14:42:46 We should print these to a JSONStream object inste
174 return LanguageError::New(message);
175 }
176
177
178 RawString* ReasonForCancelling::ToString() {
179 UNREACHABLE();
180 return NULL;
181 }
182
183
184 RawError* IsolateReloadContext::error() const {
185 ASSERT(has_error());
186 // Report the first error to the surroundings.
187 const Error& error =
188 Error::Handle(reasons_to_cancel_reload_.At(0)->ToError());
189 OS::Print("[[%s]]\n", error.ToCString());
Cutch 2016/07/26 14:42:45 We should print these to a JSONStream object inste
bakster 2016/07/26 16:54:51 For now, I removed the print statement since it is
190 return error.raw();
191 }
192
47 class ScriptUrlSetTraits { 193 class ScriptUrlSetTraits {
48 public: 194 public:
49 static bool ReportStats() { return false; } 195 static bool ReportStats() { return false; }
50 static const char* Name() { return "ScriptUrlSetTraits"; } 196 static const char* Name() { return "ScriptUrlSetTraits"; }
51 197
52 static bool IsMatch(const Object& a, const Object& b) { 198 static bool IsMatch(const Object& a, const Object& b) {
53 if (!a.IsString() || !b.IsString()) { 199 if (!a.IsString() || !b.IsString()) {
54 return false; 200 return false;
55 } 201 }
56 202
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 String::Handle(a_lib.IsNull() ? String::null() : a_lib.url()); 319 String::Handle(a_lib.IsNull() ? String::null() : a_lib.url());
174 const String& b_lib_url = 320 const String& b_lib_url =
175 String::Handle(b_lib.IsNull() ? String::null() : b_lib.url()); 321 String::Handle(b_lib.IsNull() ? String::null() : b_lib.url());
176 return a_lib_url.Equals(b_lib_url); 322 return a_lib_url.Equals(b_lib_url);
177 } 323 }
178 324
179 325
180 IsolateReloadContext::IsolateReloadContext(Isolate* isolate) 326 IsolateReloadContext::IsolateReloadContext(Isolate* isolate)
181 : start_time_micros_(OS::GetCurrentMonotonicMicros()), 327 : start_time_micros_(OS::GetCurrentMonotonicMicros()),
182 isolate_(isolate), 328 isolate_(isolate),
183 has_error_(false),
184 saved_num_cids_(-1), 329 saved_num_cids_(-1),
185 saved_class_table_(NULL), 330 saved_class_table_(NULL),
186 num_saved_libs_(-1), 331 num_saved_libs_(-1),
332 instance_morphers_(),
333 reasons_to_cancel_reload_(),
334 cid_mapper_(),
187 script_uri_(String::null()), 335 script_uri_(String::null()),
188 error_(Error::null()), 336 error_(Error::null()),
189 old_classes_set_storage_(Array::null()), 337 old_classes_set_storage_(Array::null()),
190 class_map_storage_(Array::null()), 338 class_map_storage_(Array::null()),
191 old_libraries_set_storage_(Array::null()), 339 old_libraries_set_storage_(Array::null()),
192 library_map_storage_(Array::null()), 340 library_map_storage_(Array::null()),
193 become_map_storage_(Array::null()), 341 become_map_storage_(Array::null()),
194 become_enum_mappings_(GrowableObjectArray::null()), 342 become_enum_mappings_(GrowableObjectArray::null()),
195 saved_root_library_(Library::null()), 343 saved_root_library_(Library::null()),
196 saved_libraries_(GrowableObjectArray::null()) { 344 saved_libraries_(GrowableObjectArray::null()) {
197 // NOTE: DO NOT ALLOCATE ANY RAW OBJECTS HERE. The IsolateReloadContext is not 345 // 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 346 // associated with the isolate yet and if a GC is triggered here the raw
199 // objects will not be properly accounted for. 347 // objects will not be properly accounted for.
200 } 348 }
201 349
202 350
203 IsolateReloadContext::~IsolateReloadContext() { 351 IsolateReloadContext::~IsolateReloadContext() {
204 } 352 }
205 353
206 354
207 void IsolateReloadContext::ReportError(const Error& error) { 355 void IsolateReloadContext::ReportError(const Error& error) {
208 has_error_ = true;
209 error_ = error.raw();
210 if (FLAG_trace_reload) { 356 if (FLAG_trace_reload) {
211 THR_Print("ISO-RELOAD: Error: %s\n", error.ToErrorCString()); 357 THR_Print("ISO-RELOAD: Error: %s\n", error.ToErrorCString());
212 } 358 }
213 ServiceEvent service_event(I, ServiceEvent::kIsolateReload); 359 ServiceEvent service_event(I, ServiceEvent::kIsolateReload);
214 service_event.set_reload_error(&error); 360 service_event.set_reload_error(&error);
215 Service::HandleEvent(&service_event); 361 Service::HandleEvent(&service_event);
216 } 362 }
217 363
218 364
219 void IsolateReloadContext::ReportError(const String& error_msg) {
220 ReportError(LanguageError::Handle(LanguageError::New(error_msg)));
221 }
222
223
224 void IsolateReloadContext::ReportSuccess() { 365 void IsolateReloadContext::ReportSuccess() {
225 ServiceEvent service_event(I, ServiceEvent::kIsolateReload); 366 ServiceEvent service_event(I, ServiceEvent::kIsolateReload);
226 Service::HandleEvent(&service_event); 367 Service::HandleEvent(&service_event);
227 } 368 }
228 369
229 370
371 class Aborted : public ReasonForCancelling {
372 public:
373 explicit Aborted(const Error& error)
374 : ReasonForCancelling(), error_(error) { }
375
376 private:
377 const Error& error_;
378
379 RawError* ToError() { return error_.raw(); }
380 RawString* ToString() {
381 return String::NewFormatted("%s", error_.ToErrorCString());
382 }
383 };
384
385
230 void IsolateReloadContext::StartReload() { 386 void IsolateReloadContext::StartReload() {
231 TIMELINE_SCOPE(Reload); 387 TIMELINE_SCOPE(Reload);
232 Thread* thread = Thread::Current(); 388 Thread* thread = Thread::Current();
233 ASSERT(isolate() == thread->isolate()); 389 ASSERT(isolate() == thread->isolate());
234 390
235 // Grab root library before calling CheckpointBeforeReload. 391 // Grab root library before calling CheckpointBeforeReload.
236 const Library& root_lib = Library::Handle(object_store()->root_library()); 392 const Library& root_lib = Library::Handle(object_store()->root_library());
237 ASSERT(!root_lib.IsNull()); 393 ASSERT(!root_lib.IsNull());
238 const String& root_lib_url = String::Handle(root_lib.url()); 394 const String& root_lib_url = String::Handle(root_lib.url());
239 395
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 TransitionVMToNative transition(thread); 430 TransitionVMToNative transition(thread);
275 Api::Scope api_scope(thread); 431 Api::Scope api_scope(thread);
276 432
277 Dart_Handle retval = 433 Dart_Handle retval =
278 (I->library_tag_handler())(Dart_kScriptTag, 434 (I->library_tag_handler())(Dart_kScriptTag,
279 Api::NewHandle(thread, Library::null()), 435 Api::NewHandle(thread, Library::null()),
280 Api::NewHandle(thread, root_lib_url.raw())); 436 Api::NewHandle(thread, root_lib_url.raw()));
281 result = Api::UnwrapHandle(retval); 437 result = Api::UnwrapHandle(retval);
282 } 438 }
283 if (result.IsError()) { 439 if (result.IsError()) {
284 ReportError(Error::Cast(result)); 440 const Error& error = Error::Cast(result);
441 AddReasonForCancelling(new Aborted(error));
285 } 442 }
286 } 443 }
287 444
288 445
289 void IsolateReloadContext::RegisterClass(const Class& new_cls) { 446 void IsolateReloadContext::RegisterClass(const Class& new_cls) {
290 const Class& old_cls = Class::Handle(OldClassOrNull(new_cls)); 447 const Class& old_cls = Class::Handle(OldClassOrNull(new_cls));
291 if (old_cls.IsNull()) { 448 if (old_cls.IsNull()) {
292 I->class_table()->Register(new_cls); 449 I->class_table()->Register(new_cls);
293 450
294 if (FLAG_identity_reload) { 451 if (FLAG_identity_reload) {
(...skipping 17 matching lines...) Expand all
312 } 469 }
313 470
314 471
315 void IsolateReloadContext::FinishReload() { 472 void IsolateReloadContext::FinishReload() {
316 BuildLibraryMapping(); 473 BuildLibraryMapping();
317 TIR_Print("---- DONE FINALIZING\n"); 474 TIR_Print("---- DONE FINALIZING\n");
318 if (ValidateReload()) { 475 if (ValidateReload()) {
319 Commit(); 476 Commit();
320 PostCommit(); 477 PostCommit();
321 } else { 478 } else {
479 ReportReasonsForCancelling();
322 Rollback(); 480 Rollback();
323 } 481 }
324 // ValidateReload mutates the direct subclass information and does 482 // ValidateReload mutates the direct subclass information and does
325 // not remove dead subclasses. Rebuild the direct subclass 483 // not remove dead subclasses. Rebuild the direct subclass
326 // information from scratch. 484 // information from scratch.
327 RebuildDirectSubclasses(); 485 RebuildDirectSubclasses();
328 486
329 if (FLAG_write_protect_code) { 487 if (FLAG_write_protect_code) {
330 // Disable code page write protection while we are reloading. 488 // Disable code page write protection while we are reloading.
331 I->heap()->WriteProtectCode(true); 489 I->heap()->WriteProtectCode(true);
332 } 490 }
333 491
334 BackgroundCompiler::Enable(); 492 BackgroundCompiler::Enable();
335 } 493 }
336 494
337 495
338 void IsolateReloadContext::AbortReload(const Error& error) { 496 void IsolateReloadContext::AbortReload(const Error& error) {
339 ReportError(error); 497 AddReasonForCancelling(new Aborted(error));
498 ReportReasonsForCancelling();
340 Rollback(); 499 Rollback();
341 } 500 }
342 501
343 502
344 void IsolateReloadContext::EnsuredUnoptimizedCodeForStack() { 503 void IsolateReloadContext::EnsuredUnoptimizedCodeForStack() {
345 TIMELINE_SCOPE(EnsuredUnoptimizedCodeForStack); 504 TIMELINE_SCOPE(EnsuredUnoptimizedCodeForStack);
346 StackFrameIterator it(StackFrameIterator::kDontValidateFrames); 505 StackFrameIterator it(StackFrameIterator::kDontValidateFrames);
347 506
348 Function& func = Function::Handle(); 507 Function& func = Function::Handle();
349 while (it.HasNextFrame()) { 508 while (it.HasNextFrame()) {
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
733 892
734 void IsolateReloadContext::PostCommit() { 893 void IsolateReloadContext::PostCommit() {
735 TIMELINE_SCOPE(PostCommit); 894 TIMELINE_SCOPE(PostCommit);
736 set_saved_root_library(Library::Handle()); 895 set_saved_root_library(Library::Handle());
737 set_saved_libraries(GrowableObjectArray::Handle()); 896 set_saved_libraries(GrowableObjectArray::Handle());
738 InvalidateWorld(); 897 InvalidateWorld();
739 TIR_Print("---- DONE COMMIT\n"); 898 TIR_Print("---- DONE COMMIT\n");
740 } 899 }
741 900
742 901
902 void IsolateReloadContext::AddReasonForCancelling(ReasonForCancelling* reason) {
903 reasons_to_cancel_reload_.Add(reason);
904 }
905
906
907 void IsolateReloadContext::AddInstanceMorpher(InstanceMorpher* morpher) {
908 instance_morphers_.Add(morpher);
909 cid_mapper_.Insert(morpher);
910 }
911
912
913 void IsolateReloadContext::ReportReasonsForCancelling() {
914 ASSERT(HasReasonsForCancelling());
915 for (int i = 0; i < reasons_to_cancel_reload_.length(); i++) {
916 reasons_to_cancel_reload_.At(i)->Report(this);
917 }
918 }
919
920
921 // The ObjectLocator is used for collecting instances that
922 // needs to be morphed.
923 class ObjectLocator : public ObjectVisitor {
924 public:
925 explicit ObjectLocator(IsolateReloadContext* context)
926 : context_(context), count_(0) {
927 }
928
929 void VisitObject(RawObject* obj) {
930 InstanceMorpher* morpher =
931 context_->cid_mapper_.LookupValue(obj->GetClassId());
932 if (morpher != NULL) {
933 morpher->AddObject(obj);
934 count_++;
935 }
936 }
937
938 // Return the number of located objects for morphing.
939 intptr_t count() { return count_; }
940 private:
941 IsolateReloadContext* context_;
942 intptr_t count_;
943 };
944
945
946 void IsolateReloadContext::MorphInstances() {
947 ASSERT(HasInstanceMorphers());
948 if (FLAG_trace_reload) {
949 OS::Print("MorphInstance: \n");
Cutch 2016/07/26 14:42:45 Use TIR_Print (it checks FLAG_trace_reload for you
bakster 2016/07/26 16:54:51 Done.
950 for (intptr_t i = 0; i < instance_morphers_.length(); i++) {
951 instance_morphers_.At(i)->Dump();
952 }
953 }
954
955 // Find all objects that need to be morphed.
956 ObjectLocator locator(this);
957 isolate()->heap()->VisitObjects(&locator);
958
959 // Return if no objects are located.
960 intptr_t count = locator.count();
961 if (count == 0) return;
962
963 if (FLAG_trace_reload) {
964 OS::Print("Found %" Pd " object%s subject to morphing.\n",
Cutch 2016/07/26 14:42:45 TIR_Print
bakster 2016/07/26 16:54:51 Done.
965 count, (count > 1) ? "s" : "");
966 }
967
968 Array& before = Array::Handle();
969 Array& after = Array::Handle();
970 { // Prevent GC to take place due object format confusion.
971 // Hint: More than one class share the same cid.
972 NoHeapGrowthControlScope scope;
973 for (intptr_t i = 0; i < instance_morphers_.length(); i++) {
974 instance_morphers_.At(i)->CreateMorphedCopies();
975 }
976 // Create the inputs for Become.
977 intptr_t index = 0;
978 before = Array::New(count);
979 after = Array::New(count);
980 for (intptr_t i = 0; i < instance_morphers_.length(); i++) {
981 InstanceMorpher* morpher = instance_morphers_.At(i);
982 for (intptr_t j = 0; j < morpher->before()->length(); j++) {
983 before.SetAt(index, *morpher->before()->At(j));
984 after.SetAt(index, *morpher->after()->At(j));
985 index++;
986 }
987 }
988 ASSERT(index == count);
989 }
990
991 // This is important: The saved class table (describing before objects)
992 // must be zapped to prevent the forwarding in GetClassForHeapWalkAt.
993 // Instance will from now be described by the isolate's class table.
994 free(saved_class_table_);
995 saved_class_table_ = NULL;
996 Become::ElementsForwardIdentity(before, after);
997 }
998
999
743 bool IsolateReloadContext::ValidateReload() { 1000 bool IsolateReloadContext::ValidateReload() {
744 TIMELINE_SCOPE(ValidateReload); 1001 TIMELINE_SCOPE(ValidateReload);
745 if (has_error_) { 1002 if (has_error()) return false;
746 return false;
747 }
748 1003
749 // Validate libraries. 1004 // Validate libraries.
750 { 1005 {
751 ASSERT(library_map_storage_ != Array::null()); 1006 ASSERT(library_map_storage_ != Array::null());
752 UnorderedHashMap<LibraryMapTraits> map(library_map_storage_); 1007 UnorderedHashMap<LibraryMapTraits> map(library_map_storage_);
753 UnorderedHashMap<LibraryMapTraits>::Iterator it(&map); 1008 UnorderedHashMap<LibraryMapTraits>::Iterator it(&map);
754 Library& lib = Library::Handle(); 1009 Library& lib = Library::Handle();
755 Library& new_lib = Library::Handle(); 1010 Library& new_lib = Library::Handle();
756 while (it.MoveNext()) { 1011 while (it.MoveNext()) {
757 const intptr_t entry = it.Current(); 1012 const intptr_t entry = it.Current();
758 new_lib = Library::RawCast(map.GetKey(entry)); 1013 new_lib = Library::RawCast(map.GetKey(entry));
759 lib = Library::RawCast(map.GetPayload(entry, 0)); 1014 lib = Library::RawCast(map.GetPayload(entry, 0));
760 if (new_lib.raw() != lib.raw()) { 1015 if (new_lib.raw() != lib.raw()) {
761 if (!lib.CanReload(new_lib)) { 1016 lib.CheckReload(new_lib, this);
762 map.Release();
763 return false;
764 }
765 } 1017 }
766 } 1018 }
767 map.Release(); 1019 map.Release();
768 } 1020 }
769 1021
770 // Validate classes. 1022 // Validate classes.
771 { 1023 {
772 ASSERT(class_map_storage_ != Array::null()); 1024 ASSERT(class_map_storage_ != Array::null());
773 UnorderedHashMap<ClassMapTraits> map(class_map_storage_); 1025 UnorderedHashMap<ClassMapTraits> map(class_map_storage_);
774 UnorderedHashMap<ClassMapTraits>::Iterator it(&map); 1026 UnorderedHashMap<ClassMapTraits>::Iterator it(&map);
775 Class& cls = Class::Handle(); 1027 Class& cls = Class::Handle();
776 Class& new_cls = Class::Handle(); 1028 Class& new_cls = Class::Handle();
777 while (it.MoveNext()) { 1029 while (it.MoveNext()) {
778 const intptr_t entry = it.Current(); 1030 const intptr_t entry = it.Current();
779 new_cls = Class::RawCast(map.GetKey(entry)); 1031 new_cls = Class::RawCast(map.GetKey(entry));
780 cls = Class::RawCast(map.GetPayload(entry, 0)); 1032 cls = Class::RawCast(map.GetPayload(entry, 0));
781 if (new_cls.raw() != cls.raw()) { 1033 if (new_cls.raw() != cls.raw()) {
782 if (!cls.CanReload(new_cls)) { 1034 cls.CheckReload(new_cls, this);
783 map.Release();
784 return false;
785 }
786 } 1035 }
787 } 1036 }
788 map.Release(); 1037 map.Release();
789 } 1038 }
790 return true; 1039
1040 // Perform shape shifting of instances if necessary.
1041 if (HasInstanceMorphers()) {
Cutch 2016/07/26 14:42:45 This should be done in the commit path
bakster 2016/07/26 16:54:51 Done.
1042 MorphInstances();
1043 }
1044
1045 return !HasReasonsForCancelling();
791 } 1046 }
792 1047
793 1048
794 RawClass* IsolateReloadContext::FindOriginalClass(const Class& cls) { 1049 RawClass* IsolateReloadContext::FindOriginalClass(const Class& cls) {
795 return MappedClass(cls); 1050 return MappedClass(cls);
796 } 1051 }
797 1052
798 1053
799 RawClass* IsolateReloadContext::GetClassForHeapWalkAt(intptr_t cid) { 1054 RawClass* IsolateReloadContext::GetClassForHeapWalkAt(intptr_t cid) {
800 if (saved_class_table_ != NULL) { 1055 if (saved_class_table_ != NULL) {
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
1131 ASSERT(!super_cls.IsNull()); 1386 ASSERT(!super_cls.IsNull());
1132 super_cls.AddDirectSubclass(cls); 1387 super_cls.AddDirectSubclass(cls);
1133 } 1388 }
1134 } 1389 }
1135 } 1390 }
1136 } 1391 }
1137 1392
1138 #endif // !PRODUCT 1393 #endif // !PRODUCT
1139 1394
1140 } // namespace dart 1395 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698