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 |