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/clustered_snapshot.h" | 5 #include "vm/clustered_snapshot.h" |
6 | 6 |
7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
8 #include "vm/bootstrap.h" | 8 #include "vm/bootstrap.h" |
9 #include "vm/class_finalizer.h" | 9 #include "vm/class_finalizer.h" |
10 #include "vm/dart.h" | 10 #include "vm/dart.h" |
(...skipping 4699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4710 } | 4710 } |
4711 } | 4711 } |
4712 | 4712 |
4713 intptr_t num_objects = num_base_objects_ + num_written_objects_; | 4713 intptr_t num_objects = num_base_objects_ + num_written_objects_; |
4714 #if defined(ARCH_IS_64_BIT) | 4714 #if defined(ARCH_IS_64_BIT) |
4715 if (!Utils::IsInt(32, num_objects)) { | 4715 if (!Utils::IsInt(32, num_objects)) { |
4716 FATAL("Ref overflow"); | 4716 FATAL("Ref overflow"); |
4717 } | 4717 } |
4718 #endif | 4718 #endif |
4719 | 4719 |
| 4720 Write<int32_t>(num_base_objects_); |
4720 Write<int32_t>(num_objects); | 4721 Write<int32_t>(num_objects); |
4721 Write<int32_t>(num_clusters); | 4722 Write<int32_t>(num_clusters); |
4722 | 4723 |
4723 for (intptr_t cid = 1; cid < num_cids_; cid++) { | 4724 for (intptr_t cid = 1; cid < num_cids_; cid++) { |
4724 SerializationCluster* cluster = clusters_by_cid_[cid]; | 4725 SerializationCluster* cluster = clusters_by_cid_[cid]; |
4725 if (cluster != NULL) { | 4726 if (cluster != NULL) { |
4726 cluster->WriteAlloc(this); | 4727 cluster->WriteAlloc(this); |
4727 #if defined(DEBUG) | 4728 #if defined(DEBUG) |
4728 Write<int32_t>(next_ref_index_); | 4729 Write<int32_t>(next_ref_index_); |
4729 #endif | 4730 #endif |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5083 const String& msg = String::Handle(String::New(message_buffer, Heap::kOld)); | 5084 const String& msg = String::Handle(String::New(message_buffer, Heap::kOld)); |
5084 return ApiError::New(msg, Heap::kOld); | 5085 return ApiError::New(msg, Heap::kOld); |
5085 } | 5086 } |
5086 free(const_cast<char*>(expected_features)); | 5087 free(const_cast<char*>(expected_features)); |
5087 Advance(expected_len + 1); | 5088 Advance(expected_len + 1); |
5088 return ApiError::null(); | 5089 return ApiError::null(); |
5089 } | 5090 } |
5090 | 5091 |
5091 | 5092 |
5092 void Deserializer::Prepare() { | 5093 void Deserializer::Prepare() { |
| 5094 num_base_objects_ = Read<int32_t>(); |
5093 num_objects_ = Read<int32_t>(); | 5095 num_objects_ = Read<int32_t>(); |
5094 num_clusters_ = Read<int32_t>(); | 5096 num_clusters_ = Read<int32_t>(); |
5095 | 5097 |
5096 clusters_ = new DeserializationCluster*[num_clusters_]; | 5098 clusters_ = new DeserializationCluster*[num_clusters_]; |
5097 refs_ = Array::New(num_objects_ + 1, Heap::kOld); | 5099 refs_ = Array::New(num_objects_ + 1, Heap::kOld); |
5098 } | 5100 } |
5099 | 5101 |
5100 | 5102 |
5101 void Deserializer::Deserialize() { | 5103 void Deserializer::Deserialize() { |
5102 // TODO(rmacnak): Verify num of base objects. | 5104 if (num_base_objects_ != (next_ref_index_ - 1)) { |
| 5105 FATAL2("Snapshot expects %" Pd |
| 5106 " base objects, but deserializer provided %" Pd, |
| 5107 num_base_objects_, next_ref_index_ - 1); |
| 5108 } |
5103 | 5109 |
5104 { | 5110 { |
5105 NOT_IN_PRODUCT(TimelineDurationScope tds( | 5111 NOT_IN_PRODUCT(TimelineDurationScope tds( |
5106 thread(), Timeline::GetIsolateStream(), "ReadAlloc")); | 5112 thread(), Timeline::GetIsolateStream(), "ReadAlloc")); |
5107 for (intptr_t i = 0; i < num_clusters_; i++) { | 5113 for (intptr_t i = 0; i < num_clusters_; i++) { |
5108 clusters_[i] = ReadCluster(); | 5114 clusters_[i] = ReadCluster(); |
5109 clusters_[i]->ReadAlloc(this); | 5115 clusters_[i]->ReadAlloc(this); |
5110 #if defined(DEBUG) | 5116 #if defined(DEBUG) |
5111 intptr_t serializers_next_ref_index_ = Read<int32_t>(); | 5117 intptr_t serializers_next_ref_index_ = Read<int32_t>(); |
5112 ASSERT(serializers_next_ref_index_ == next_ref_index_); | 5118 ASSERT(serializers_next_ref_index_ == next_ref_index_); |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5349 ObjectStore* object_store = isolate()->object_store(); | 5355 ObjectStore* object_store = isolate()->object_store(); |
5350 ASSERT(object_store != NULL); | 5356 ASSERT(object_store != NULL); |
5351 | 5357 |
5352 #if defined(DEBUG) | 5358 #if defined(DEBUG) |
5353 // Ensure the class table is valid. | 5359 // Ensure the class table is valid. |
5354 isolate()->ValidateClassTable(); | 5360 isolate()->ValidateClassTable(); |
5355 #endif | 5361 #endif |
5356 // Can't have any mutation happening while we're serializing. | 5362 // Can't have any mutation happening while we're serializing. |
5357 ASSERT(isolate()->background_compiler() == NULL); | 5363 ASSERT(isolate()->background_compiler() == NULL); |
5358 | 5364 |
5359 if (vm_snapshot_data_buffer != NULL) { | 5365 // TODO(rmacnak): The special case for AOT causes us to always generate the |
| 5366 // same VM isolate snapshot for every app. AOT snapshots should be cleaned up |
| 5367 // so the VM isolate snapshot is generated separately and each app is |
| 5368 // generated from a VM that has loaded this snapshots, much like app-jit |
| 5369 // snapshots. |
| 5370 if ((vm_snapshot_data_buffer != NULL) && (kind != Snapshot::kAppAOT)) { |
5360 NOT_IN_PRODUCT(TimelineDurationScope tds( | 5371 NOT_IN_PRODUCT(TimelineDurationScope tds( |
5361 thread(), Timeline::GetIsolateStream(), "PrepareNewVMIsolate")); | 5372 thread(), Timeline::GetIsolateStream(), "PrepareNewVMIsolate")); |
5362 | 5373 |
5363 // Collect all the token stream objects into an array so that we can write | 5374 // Collect all the token stream objects into an array so that we can write |
5364 // it out as part of the VM isolate snapshot. We first count the number of | 5375 // it out as part of the VM isolate snapshot. We first count the number of |
5365 // token streams, allocate an array and then fill it up with the token | 5376 // token streams, allocate an array and then fill it up with the token |
5366 // streams. | 5377 // streams. |
5367 SnapshotTokenStreamVisitor token_streams_counter(thread()); | 5378 SnapshotTokenStreamVisitor token_streams_counter(thread()); |
5368 heap()->IterateOldObjects(&token_streams_counter); | 5379 heap()->IterateOldObjects(&token_streams_counter); |
5369 Dart::vm_isolate()->heap()->IterateOldObjects(&token_streams_counter); | 5380 Dart::vm_isolate()->heap()->IterateOldObjects(&token_streams_counter); |
5370 intptr_t count = token_streams_counter.count(); | 5381 intptr_t count = token_streams_counter.count(); |
5371 token_streams_ = Array::New(count, Heap::kOld); | 5382 token_streams_ = Array::New(count, Heap::kOld); |
5372 SnapshotTokenStreamVisitor script_visitor(thread(), &token_streams_); | 5383 SnapshotTokenStreamVisitor script_visitor(thread(), &token_streams_); |
5373 heap()->IterateOldObjects(&script_visitor); | 5384 heap()->IterateOldObjects(&script_visitor); |
5374 Dart::vm_isolate()->heap()->IterateOldObjects(&script_visitor); | 5385 Dart::vm_isolate()->heap()->IterateOldObjects(&script_visitor); |
5375 ASSERT(script_visitor.count() == count); | 5386 ASSERT(script_visitor.count() == count); |
5376 | 5387 |
5377 // Tuck away the current symbol table. | 5388 // Tuck away the current symbol table. |
5378 saved_symbol_table_ = object_store->symbol_table(); | 5389 saved_symbol_table_ = object_store->symbol_table(); |
5379 | 5390 |
5380 // Create a unified symbol table that will be written as the vm isolate's | 5391 // Create a unified symbol table that will be written as the vm isolate's |
5381 // symbol table. | 5392 // symbol table. |
5382 new_vm_symbol_table_ = Symbols::UnifiedSymbolTable(); | 5393 new_vm_symbol_table_ = Symbols::UnifiedSymbolTable(); |
5383 | 5394 |
5384 // Create an empty symbol table that will be written as the isolate's symbol | 5395 // Create an empty symbol table that will be written as the isolate's symbol |
5385 // table. | 5396 // table. |
5386 Symbols::SetupSymbolTable(isolate()); | 5397 Symbols::SetupSymbolTable(isolate()); |
5387 } else { | 5398 } else { |
5388 // Reuse the current vm isolate. | 5399 // Reuse the current vm isolate. |
| 5400 saved_symbol_table_ = object_store->symbol_table(); |
| 5401 new_vm_symbol_table_ = Dart::vm_isolate()->object_store()->symbol_table(); |
5389 } | 5402 } |
5390 } | 5403 } |
5391 | 5404 |
5392 FullSnapshotWriter::~FullSnapshotWriter() { | 5405 FullSnapshotWriter::~FullSnapshotWriter() { |
5393 // We may run Dart code afterwards, restore the symbol table if needed. | 5406 // We may run Dart code afterwards, restore the symbol table if needed. |
5394 if (!saved_symbol_table_.IsNull()) { | 5407 if (!saved_symbol_table_.IsNull()) { |
5395 isolate()->object_store()->set_symbol_table(saved_symbol_table_); | 5408 isolate()->object_store()->set_symbol_table(saved_symbol_table_); |
5396 saved_symbol_table_ = Array::null(); | 5409 saved_symbol_table_ = Array::null(); |
5397 } | 5410 } |
5398 new_vm_symbol_table_ = Array::null(); | 5411 new_vm_symbol_table_ = Array::null(); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5549 thread_->isolate()->SetupImagePage(data_buffer_, | 5562 thread_->isolate()->SetupImagePage(data_buffer_, |
5550 /* is_executable */ false); | 5563 /* is_executable */ false); |
5551 } | 5564 } |
5552 | 5565 |
5553 deserializer.ReadIsolateSnapshot(thread_->isolate()->object_store()); | 5566 deserializer.ReadIsolateSnapshot(thread_->isolate()->object_store()); |
5554 | 5567 |
5555 return ApiError::null(); | 5568 return ApiError::null(); |
5556 } | 5569 } |
5557 | 5570 |
5558 } // namespace dart | 5571 } // namespace dart |
OLD | NEW |