OLD | NEW |
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 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 IsolateReloadContext::~IsolateReloadContext() { | 208 IsolateReloadContext::~IsolateReloadContext() { |
209 } | 209 } |
210 | 210 |
211 | 211 |
212 void IsolateReloadContext::ReportError(const Error& error) { | 212 void IsolateReloadContext::ReportError(const Error& error) { |
213 has_error_ = true; | 213 has_error_ = true; |
214 error_ = error.raw(); | 214 error_ = error.raw(); |
215 if (FLAG_trace_reload) { | 215 if (FLAG_trace_reload) { |
216 THR_Print("ISO-RELOAD: Error: %s\n", error.ToErrorCString()); | 216 THR_Print("ISO-RELOAD: Error: %s\n", error.ToErrorCString()); |
217 } | 217 } |
218 ServiceEvent service_event(Isolate::Current(), ServiceEvent::kIsolateReload); | 218 ServiceEvent service_event(I, ServiceEvent::kIsolateReload); |
219 service_event.set_reload_error(&error); | 219 service_event.set_reload_error(&error); |
220 Service::HandleEvent(&service_event); | 220 Service::HandleEvent(&service_event); |
221 } | 221 } |
222 | 222 |
223 | 223 |
224 void IsolateReloadContext::ReportError(const String& error_msg) { | 224 void IsolateReloadContext::ReportError(const String& error_msg) { |
225 ReportError(LanguageError::Handle(LanguageError::New(error_msg))); | 225 ReportError(LanguageError::Handle(LanguageError::New(error_msg))); |
226 } | 226 } |
227 | 227 |
228 | 228 |
229 void IsolateReloadContext::ReportSuccess() { | 229 void IsolateReloadContext::ReportSuccess() { |
230 ServiceEvent service_event(Isolate::Current(), ServiceEvent::kIsolateReload); | 230 ServiceEvent service_event(I, ServiceEvent::kIsolateReload); |
231 Service::HandleEvent(&service_event); | 231 Service::HandleEvent(&service_event); |
232 } | 232 } |
233 | 233 |
234 | 234 |
235 void IsolateReloadContext::StartReload() { | 235 void IsolateReloadContext::StartReload() { |
236 TIMELINE_SCOPE(Reload); | 236 TIMELINE_SCOPE(Reload); |
237 Thread* thread = Thread::Current(); | 237 Thread* thread = Thread::Current(); |
238 | 238 |
239 // Grab root library before calling CheckpointBeforeReload. | 239 // Grab root library before calling CheckpointBeforeReload. |
240 const Library& root_lib = Library::Handle(object_store()->root_library()); | 240 const Library& root_lib = Library::Handle(object_store()->root_library()); |
(...skipping 30 matching lines...) Expand all Loading... |
271 } | 271 } |
272 if (result.IsError()) { | 272 if (result.IsError()) { |
273 ReportError(Error::Cast(result)); | 273 ReportError(Error::Cast(result)); |
274 } | 274 } |
275 } | 275 } |
276 | 276 |
277 | 277 |
278 void IsolateReloadContext::RegisterClass(const Class& new_cls) { | 278 void IsolateReloadContext::RegisterClass(const Class& new_cls) { |
279 const Class& old_cls = Class::Handle(OldClassOrNull(new_cls)); | 279 const Class& old_cls = Class::Handle(OldClassOrNull(new_cls)); |
280 if (old_cls.IsNull()) { | 280 if (old_cls.IsNull()) { |
281 Isolate::Current()->class_table()->Register(new_cls); | 281 I->class_table()->Register(new_cls); |
282 | 282 |
283 if (FLAG_identity_reload) { | 283 if (FLAG_identity_reload) { |
284 TIR_Print("Could not find replacement class for %s\n", | 284 TIR_Print("Could not find replacement class for %s\n", |
285 new_cls.ToCString()); | 285 new_cls.ToCString()); |
286 UNREACHABLE(); | 286 UNREACHABLE(); |
287 } | 287 } |
288 | 288 |
289 // New class maps to itself. | 289 // New class maps to itself. |
290 AddClassMapping(new_cls, new_cls); | 290 AddClassMapping(new_cls, new_cls); |
291 return; | 291 return; |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
590 GrowableObjectArray& saved_libs = GrowableObjectArray::Handle( | 590 GrowableObjectArray& saved_libs = GrowableObjectArray::Handle( |
591 Z, saved_libraries()); | 591 Z, saved_libraries()); |
592 if (!saved_libs.IsNull()) { | 592 if (!saved_libs.IsNull()) { |
593 for (intptr_t i = 0; i < saved_libs.Length(); i++) { | 593 for (intptr_t i = 0; i < saved_libs.Length(); i++) { |
594 lib = Library::RawCast(saved_libs.At(i)); | 594 lib = Library::RawCast(saved_libs.At(i)); |
595 // Restore indexes that were modified in CheckpointLibraries. | 595 // Restore indexes that were modified in CheckpointLibraries. |
596 lib.set_index(i); | 596 lib.set_index(i); |
597 } | 597 } |
598 | 598 |
599 // Reset the registered libraries to the filtered array. | 599 // Reset the registered libraries to the filtered array. |
600 Library::RegisterLibraries(Thread::Current(), saved_libs); | 600 Library::RegisterLibraries(thread, saved_libs); |
601 } | 601 } |
602 | 602 |
603 Library& saved_root_lib = Library::Handle(Z, saved_root_library()); | 603 Library& saved_root_lib = Library::Handle(Z, saved_root_library()); |
604 if (!saved_root_lib.IsNull()) { | 604 if (!saved_root_lib.IsNull()) { |
605 object_store()->set_root_library(saved_root_lib); | 605 object_store()->set_root_library(saved_root_lib); |
606 } | 606 } |
607 | 607 |
608 set_saved_root_library(Library::Handle()); | 608 set_saved_root_library(Library::Handle()); |
609 set_saved_libraries(GrowableObjectArray::Handle()); | 609 set_saved_libraries(GrowableObjectArray::Handle()); |
610 } | 610 } |
611 | 611 |
612 | 612 |
613 void IsolateReloadContext::Rollback() { | 613 void IsolateReloadContext::Rollback() { |
614 I->object_store()->set_compile_time_constants( | 614 I->object_store()->set_compile_time_constants( |
615 Array::Handle(compile_time_constants_)); | 615 Array::Handle(compile_time_constants_)); |
616 RollbackClasses(); | 616 RollbackClasses(); |
617 RollbackLibraries(); | 617 RollbackLibraries(); |
618 } | 618 } |
619 | 619 |
620 | 620 |
621 #ifdef DEBUG | 621 #ifdef DEBUG |
622 void IsolateReloadContext::VerifyMaps() { | 622 void IsolateReloadContext::VerifyMaps() { |
623 TIMELINE_SCOPE(VerifyMaps); | 623 TIMELINE_SCOPE(VerifyMaps); |
624 Class& cls = Class::Handle(); | 624 Class& cls = Class::Handle(); |
625 Class& new_cls = Class::Handle(); | 625 Class& new_cls = Class::Handle(); |
626 Class& cls2 = Class::Handle(); | 626 Class& cls2 = Class::Handle(); |
627 Class& new_cls2 = Class::Handle(); | |
628 | 627 |
629 // Verify that two old classes aren't both mapped to the same new | 628 // Verify that two old classes aren't both mapped to the same new |
630 // class. This could happen is the IsSameClass function is broken. | 629 // class. This could happen is the IsSameClass function is broken. |
631 UnorderedHashMap<ClassMapTraits> class_map(class_map_storage_); | 630 UnorderedHashMap<ClassMapTraits> class_map(class_map_storage_); |
| 631 UnorderedHashMap<ClassMapTraits> reverse_class_map( |
| 632 HashTables::New<UnorderedHashMap<ClassMapTraits> >( |
| 633 class_map.NumOccupied())); |
632 { | 634 { |
633 UnorderedHashMap<ClassMapTraits>::Iterator it(&class_map); | 635 UnorderedHashMap<ClassMapTraits>::Iterator it(&class_map); |
634 while (it.MoveNext()) { | 636 while (it.MoveNext()) { |
635 const intptr_t entry = it.Current(); | 637 const intptr_t entry = it.Current(); |
636 new_cls = Class::RawCast(class_map.GetKey(entry)); | 638 new_cls = Class::RawCast(class_map.GetKey(entry)); |
637 cls = Class::RawCast(class_map.GetPayload(entry, 0)); | 639 cls = Class::RawCast(class_map.GetPayload(entry, 0)); |
638 if (new_cls.raw() != cls.raw()) { | 640 cls2 ^= reverse_class_map.GetOrNull(new_cls); |
639 UnorderedHashMap<ClassMapTraits>::Iterator it2(&class_map); | 641 if (!cls2.IsNull()) { |
640 while (it2.MoveNext()) { | 642 OS::PrintErr("Classes '%s' and '%s' are distinct classes but both map " |
641 new_cls2 = Class::RawCast(class_map.GetKey(entry)); | 643 " to class '%s'\n", |
642 if (new_cls.raw() == new_cls2.raw()) { | 644 cls.ToCString(), cls2.ToCString(), new_cls.ToCString()); |
643 cls2 = Class::RawCast(class_map.GetPayload(entry, 0)); | 645 UNREACHABLE(); |
644 if (cls.raw() != cls2.raw()) { | |
645 OS::PrintErr( | |
646 "Classes '%s' and '%s' are distinct classes but both map to " | |
647 "class '%s'\n", | |
648 cls.ToCString(), cls2.ToCString(), new_cls.ToCString()); | |
649 UNREACHABLE(); | |
650 } | |
651 } | |
652 } | |
653 } | 646 } |
| 647 bool update = reverse_class_map.UpdateOrInsert(cls, new_cls); |
| 648 ASSERT(!update); |
654 } | 649 } |
655 } | 650 } |
656 class_map.Release(); | 651 class_map.Release(); |
| 652 reverse_class_map.Release(); |
657 } | 653 } |
658 #endif | 654 #endif |
659 | 655 |
660 | 656 |
661 void IsolateReloadContext::Commit() { | 657 void IsolateReloadContext::Commit() { |
662 TIMELINE_SCOPE(Commit); | 658 TIMELINE_SCOPE(Commit); |
663 TIR_Print("---- COMMITTING REVERSE MAP\n"); | 659 TIR_Print("---- COMMITTING REVERSE MAP\n"); |
664 | 660 |
665 #ifdef DEBUG | 661 #ifdef DEBUG |
666 VerifyMaps(); | 662 VerifyMaps(); |
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1159 ASSERT(!super_cls.IsNull()); | 1155 ASSERT(!super_cls.IsNull()); |
1160 super_cls.AddDirectSubclass(cls); | 1156 super_cls.AddDirectSubclass(cls); |
1161 } | 1157 } |
1162 } | 1158 } |
1163 } | 1159 } |
1164 } | 1160 } |
1165 | 1161 |
1166 #endif // !PRODUCT | 1162 #endif // !PRODUCT |
1167 | 1163 |
1168 } // namespace dart | 1164 } // namespace dart |
OLD | NEW |