| 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 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 IsolateReloadContext::IsolateReloadContext(Isolate* isolate, bool test_mode) | 176 IsolateReloadContext::IsolateReloadContext(Isolate* isolate, bool test_mode) |
| 177 : start_time_micros_(OS::GetCurrentMonotonicMicros()), | 177 : start_time_micros_(OS::GetCurrentMonotonicMicros()), |
| 178 isolate_(isolate), | 178 isolate_(isolate), |
| 179 test_mode_(test_mode), | 179 test_mode_(test_mode), |
| 180 has_error_(false), | 180 has_error_(false), |
| 181 saved_num_cids_(-1), | 181 saved_num_cids_(-1), |
| 182 saved_class_table_(NULL), | 182 saved_class_table_(NULL), |
| 183 num_saved_libs_(-1), | 183 num_saved_libs_(-1), |
| 184 script_uri_(String::null()), | 184 script_uri_(String::null()), |
| 185 error_(Error::null()), | 185 error_(Error::null()), |
| 186 clean_scripts_set_storage_(Array::null()), | |
| 187 compile_time_constants_(Array::null()), | |
| 188 old_classes_set_storage_(Array::null()), | 186 old_classes_set_storage_(Array::null()), |
| 189 class_map_storage_(Array::null()), | 187 class_map_storage_(Array::null()), |
| 190 old_libraries_set_storage_(Array::null()), | 188 old_libraries_set_storage_(Array::null()), |
| 191 library_map_storage_(Array::null()), | 189 library_map_storage_(Array::null()), |
| 192 become_map_storage_(Array::null()), | 190 become_map_storage_(Array::null()), |
| 193 saved_root_library_(Library::null()), | 191 saved_root_library_(Library::null()), |
| 194 saved_libraries_(GrowableObjectArray::null()) { | 192 saved_libraries_(GrowableObjectArray::null()) { |
| 195 // Preallocate storage for maps. | 193 // Preallocate storage for maps. |
| 196 clean_scripts_set_storage_ = | |
| 197 HashTables::New<UnorderedHashSet<ScriptUrlSetTraits> >(4); | |
| 198 old_classes_set_storage_ = | 194 old_classes_set_storage_ = |
| 199 HashTables::New<UnorderedHashSet<ClassMapTraits> >(4); | 195 HashTables::New<UnorderedHashSet<ClassMapTraits> >(4); |
| 200 class_map_storage_ = | 196 class_map_storage_ = |
| 201 HashTables::New<UnorderedHashMap<ClassMapTraits> >(4); | 197 HashTables::New<UnorderedHashMap<ClassMapTraits> >(4); |
| 202 old_libraries_set_storage_ = | 198 old_libraries_set_storage_ = |
| 203 HashTables::New<UnorderedHashSet<LibraryMapTraits> >(4); | 199 HashTables::New<UnorderedHashSet<LibraryMapTraits> >(4); |
| 204 library_map_storage_ = | 200 library_map_storage_ = |
| 205 HashTables::New<UnorderedHashMap<LibraryMapTraits> >(4); | 201 HashTables::New<UnorderedHashMap<LibraryMapTraits> >(4); |
| 206 become_map_storage_ = | 202 become_map_storage_ = |
| 207 HashTables::New<UnorderedHashMap<BecomeMapTraits> >(4); | 203 HashTables::New<UnorderedHashMap<BecomeMapTraits> >(4); |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 } | 465 } |
| 470 old_libraries_set_storage_ = old_libraries_set.Release().raw(); | 466 old_libraries_set_storage_ = old_libraries_set.Release().raw(); |
| 471 | 467 |
| 472 // Reset the registered libraries to the filtered array. | 468 // Reset the registered libraries to the filtered array. |
| 473 Library::RegisterLibraries(Thread::Current(), new_libs); | 469 Library::RegisterLibraries(Thread::Current(), new_libs); |
| 474 // Reset the root library to null. | 470 // Reset the root library to null. |
| 475 object_store()->set_root_library(Library::Handle()); | 471 object_store()->set_root_library(Library::Handle()); |
| 476 } | 472 } |
| 477 | 473 |
| 478 | 474 |
| 479 void IsolateReloadContext::BuildCleanScriptSet() { | |
| 480 const GrowableObjectArray& libs = | |
| 481 GrowableObjectArray::Handle(object_store()->libraries()); | |
| 482 | |
| 483 UnorderedHashSet<ScriptUrlSetTraits> | |
| 484 clean_scripts_set(clean_scripts_set_storage_); | |
| 485 | |
| 486 Library& lib = Library::Handle(); | |
| 487 Array& scripts = Array::Handle(); | |
| 488 Script& script = Script::Handle(); | |
| 489 String& script_url = String::Handle(); | |
| 490 for (intptr_t lib_idx = 0; lib_idx < libs.Length(); lib_idx++) { | |
| 491 lib = Library::RawCast(libs.At(lib_idx)); | |
| 492 ASSERT(!lib.IsNull()); | |
| 493 ASSERT(IsCleanLibrary(lib)); | |
| 494 scripts = lib.LoadedScripts(); | |
| 495 ASSERT(!scripts.IsNull()); | |
| 496 for (intptr_t script_idx = 0; script_idx < scripts.Length(); script_idx++) { | |
| 497 script = Script::RawCast(scripts.At(script_idx)); | |
| 498 ASSERT(!script.IsNull()); | |
| 499 script_url = script.url(); | |
| 500 ASSERT(!script_url.IsNull()); | |
| 501 bool already_present = clean_scripts_set.Insert(script_url); | |
| 502 ASSERT(!already_present); | |
| 503 } | |
| 504 } | |
| 505 | |
| 506 clean_scripts_set_storage_ = clean_scripts_set.Release().raw(); | |
| 507 } | |
| 508 | |
| 509 | |
| 510 void IsolateReloadContext::FilterCompileTimeConstants() { | |
| 511 // Save the compile time constants array. | |
| 512 compile_time_constants_ = I->object_store()->compile_time_constants(); | |
| 513 // Clear the compile time constants array. This will be repopulated | |
| 514 // in the loop below. | |
| 515 I->object_store()->set_compile_time_constants(Array::Handle()); | |
| 516 | |
| 517 if (compile_time_constants_ == Array::null()) { | |
| 518 // Nothing to do. | |
| 519 return; | |
| 520 } | |
| 521 | |
| 522 // Iterate over the saved compile time constants map. | |
| 523 ConstantsMap old_constants(compile_time_constants_); | |
| 524 ConstantsMap::Iterator it(&old_constants); | |
| 525 | |
| 526 Array& key = Array::Handle(); | |
| 527 String& url = String::Handle(); | |
| 528 Smi& token_pos = Smi::Handle(); | |
| 529 Instance& value = Instance::Handle(); | |
| 530 | |
| 531 // We filter the compile time constants map so that after it only contains | |
| 532 // constants from scripts contained in this set. | |
| 533 UnorderedHashSet<ScriptUrlSetTraits> | |
| 534 clean_scripts_set(clean_scripts_set_storage_); | |
| 535 | |
| 536 while (it.MoveNext()) { | |
| 537 const intptr_t entry = it.Current(); | |
| 538 ASSERT(entry != -1); | |
| 539 key = Array::RawCast(old_constants.GetKey(entry)); | |
| 540 ASSERT(!key.IsNull()); | |
| 541 url = String::RawCast(key.At(0)); | |
| 542 ASSERT(!url.IsNull()); | |
| 543 if (clean_scripts_set.ContainsKey(url)) { | |
| 544 // We've found a cached constant from a clean script, add it to the | |
| 545 // compile time constants map again. | |
| 546 token_pos = Smi::RawCast(key.At(1)); | |
| 547 TokenPosition tp(token_pos.Value()); | |
| 548 // Use ^= because this might be null. | |
| 549 value ^= old_constants.GetPayload(entry, 0); | |
| 550 Parser::InsertCachedConstantValue(url, tp, value); | |
| 551 } | |
| 552 } | |
| 553 | |
| 554 old_constants.Release(); | |
| 555 clean_scripts_set.Release(); | |
| 556 } | |
| 557 | |
| 558 | |
| 559 // While reloading everything we do must be reversible so that we can abort | 475 // While reloading everything we do must be reversible so that we can abort |
| 560 // safely if the reload fails. This function stashes things to the side and | 476 // safely if the reload fails. This function stashes things to the side and |
| 561 // prepares the isolate for the reload attempt. | 477 // prepares the isolate for the reload attempt. |
| 562 void IsolateReloadContext::Checkpoint() { | 478 void IsolateReloadContext::Checkpoint() { |
| 563 TIMELINE_SCOPE(Checkpoint); | 479 TIMELINE_SCOPE(Checkpoint); |
| 564 CheckpointClasses(); | 480 CheckpointClasses(); |
| 565 CheckpointLibraries(); | 481 CheckpointLibraries(); |
| 566 BuildCleanScriptSet(); | |
| 567 FilterCompileTimeConstants(); | |
| 568 } | 482 } |
| 569 | 483 |
| 570 | 484 |
| 571 void IsolateReloadContext::RollbackClasses() { | 485 void IsolateReloadContext::RollbackClasses() { |
| 572 TIR_Print("---- ROLLING BACK CLASS TABLE\n"); | 486 TIR_Print("---- ROLLING BACK CLASS TABLE\n"); |
| 573 ASSERT(saved_num_cids_ > 0); | 487 ASSERT(saved_num_cids_ > 0); |
| 574 ASSERT(saved_class_table_ != NULL); | 488 ASSERT(saved_class_table_ != NULL); |
| 575 ClassTable* class_table = I->class_table(); | 489 ClassTable* class_table = I->class_table(); |
| 576 class_table->SetNumCids(saved_num_cids_); | 490 class_table->SetNumCids(saved_num_cids_); |
| 577 // Overwrite classes in class table with the saved classes. | 491 // Overwrite classes in class table with the saved classes. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 607 if (!saved_root_lib.IsNull()) { | 521 if (!saved_root_lib.IsNull()) { |
| 608 object_store()->set_root_library(saved_root_lib); | 522 object_store()->set_root_library(saved_root_lib); |
| 609 } | 523 } |
| 610 | 524 |
| 611 set_saved_root_library(Library::Handle()); | 525 set_saved_root_library(Library::Handle()); |
| 612 set_saved_libraries(GrowableObjectArray::Handle()); | 526 set_saved_libraries(GrowableObjectArray::Handle()); |
| 613 } | 527 } |
| 614 | 528 |
| 615 | 529 |
| 616 void IsolateReloadContext::Rollback() { | 530 void IsolateReloadContext::Rollback() { |
| 617 I->object_store()->set_compile_time_constants( | |
| 618 Array::Handle(compile_time_constants_)); | |
| 619 RollbackClasses(); | 531 RollbackClasses(); |
| 620 RollbackLibraries(); | 532 RollbackLibraries(); |
| 621 } | 533 } |
| 622 | 534 |
| 623 | 535 |
| 624 #ifdef DEBUG | 536 #ifdef DEBUG |
| 625 void IsolateReloadContext::VerifyMaps() { | 537 void IsolateReloadContext::VerifyMaps() { |
| 626 TIMELINE_SCOPE(VerifyMaps); | 538 TIMELINE_SCOPE(VerifyMaps); |
| 627 Class& cls = Class::Handle(); | 539 Class& cls = Class::Handle(); |
| 628 Class& new_cls = Class::Handle(); | 540 Class& new_cls = Class::Handle(); |
| (...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1158 ASSERT(!super_cls.IsNull()); | 1070 ASSERT(!super_cls.IsNull()); |
| 1159 super_cls.AddDirectSubclass(cls); | 1071 super_cls.AddDirectSubclass(cls); |
| 1160 } | 1072 } |
| 1161 } | 1073 } |
| 1162 } | 1074 } |
| 1163 } | 1075 } |
| 1164 | 1076 |
| 1165 #endif // !PRODUCT | 1077 #endif // !PRODUCT |
| 1166 | 1078 |
| 1167 } // namespace dart | 1079 } // namespace dart |
| OLD | NEW |