OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/dart.h" | 5 #include "vm/dart.h" |
6 | 6 |
7 #include "vm/code_observers.h" | 7 #include "vm/code_observers.h" |
8 #include "vm/cpu.h" | 8 #include "vm/cpu.h" |
9 #include "vm/dart_api_state.h" | 9 #include "vm/dart_api_state.h" |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 29 matching lines...) Expand all Loading... |
40 DEFINE_FLAG(bool, keep_code, false, | 40 DEFINE_FLAG(bool, keep_code, false, |
41 "Keep deoptimized code for profiling."); | 41 "Keep deoptimized code for profiling."); |
42 DEFINE_FLAG(bool, shutdown, true, "Do a clean shutdown of the VM"); | 42 DEFINE_FLAG(bool, shutdown, true, "Do a clean shutdown of the VM"); |
43 DEFINE_FLAG(bool, trace_shutdown, false, "Trace VM shutdown on stderr"); | 43 DEFINE_FLAG(bool, trace_shutdown, false, "Trace VM shutdown on stderr"); |
44 | 44 |
45 Isolate* Dart::vm_isolate_ = NULL; | 45 Isolate* Dart::vm_isolate_ = NULL; |
46 int64_t Dart::start_time_ = 0; | 46 int64_t Dart::start_time_ = 0; |
47 ThreadPool* Dart::thread_pool_ = NULL; | 47 ThreadPool* Dart::thread_pool_ = NULL; |
48 DebugInfo* Dart::pprof_symbol_generator_ = NULL; | 48 DebugInfo* Dart::pprof_symbol_generator_ = NULL; |
49 ReadOnlyHandles* Dart::predefined_handles_ = NULL; | 49 ReadOnlyHandles* Dart::predefined_handles_ = NULL; |
| 50 Snapshot::Kind Dart::snapshot_kind_ = Snapshot::kInvalid; |
50 const uint8_t* Dart::instructions_snapshot_buffer_ = NULL; | 51 const uint8_t* Dart::instructions_snapshot_buffer_ = NULL; |
51 const uint8_t* Dart::data_snapshot_buffer_ = NULL; | 52 const uint8_t* Dart::data_snapshot_buffer_ = NULL; |
52 Dart_ThreadExitCallback Dart::thread_exit_callback_ = NULL; | 53 Dart_ThreadExitCallback Dart::thread_exit_callback_ = NULL; |
53 Dart_FileOpenCallback Dart::file_open_callback_ = NULL; | 54 Dart_FileOpenCallback Dart::file_open_callback_ = NULL; |
54 Dart_FileReadCallback Dart::file_read_callback_ = NULL; | 55 Dart_FileReadCallback Dart::file_read_callback_ = NULL; |
55 Dart_FileWriteCallback Dart::file_write_callback_ = NULL; | 56 Dart_FileWriteCallback Dart::file_write_callback_ = NULL; |
56 Dart_FileCloseCallback Dart::file_close_callback_ = NULL; | 57 Dart_FileCloseCallback Dart::file_close_callback_ = NULL; |
57 Dart_EntropySource Dart::entropy_source_callback_ = NULL; | 58 Dart_EntropySource Dart::entropy_source_callback_ = NULL; |
58 | 59 |
59 // Structure for managing read-only global handles allocation used for | 60 // Structure for managing read-only global handles allocation used for |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 Dart_FileReadCallback file_read, | 125 Dart_FileReadCallback file_read, |
125 Dart_FileWriteCallback file_write, | 126 Dart_FileWriteCallback file_write, |
126 Dart_FileCloseCallback file_close, | 127 Dart_FileCloseCallback file_close, |
127 Dart_EntropySource entropy_source, | 128 Dart_EntropySource entropy_source, |
128 Dart_GetVMServiceAssetsArchive get_service_assets) { | 129 Dart_GetVMServiceAssetsArchive get_service_assets) { |
129 CheckOffsets(); | 130 CheckOffsets(); |
130 // TODO(iposva): Fix race condition here. | 131 // TODO(iposva): Fix race condition here. |
131 if (vm_isolate_ != NULL || !Flags::Initialized()) { | 132 if (vm_isolate_ != NULL || !Flags::Initialized()) { |
132 return "VM already initialized or flags not initialized."; | 133 return "VM already initialized or flags not initialized."; |
133 } | 134 } |
134 #if defined(DART_PRECOMPILED_RUNTIME) | |
135 if (instructions_snapshot == NULL) { | |
136 return "Precompiled runtime requires a precompiled snapshot"; | |
137 } | |
138 #else | |
139 if (instructions_snapshot != NULL) { | |
140 return "JIT runtime cannot run a precompiled snapshot"; | |
141 } | |
142 #endif | |
143 set_thread_exit_callback(thread_exit); | 135 set_thread_exit_callback(thread_exit); |
144 SetFileCallbacks(file_open, file_read, file_write, file_close); | 136 SetFileCallbacks(file_open, file_read, file_write, file_close); |
145 set_entropy_source_callback(entropy_source); | 137 set_entropy_source_callback(entropy_source); |
146 OS::InitOnce(); | 138 OS::InitOnce(); |
147 VirtualMemory::InitOnce(); | 139 VirtualMemory::InitOnce(); |
148 OSThread::InitOnce(); | 140 OSThread::InitOnce(); |
149 if (FLAG_support_timeline) { | 141 if (FLAG_support_timeline) { |
150 Timeline::InitOnce(); | 142 Timeline::InitOnce(); |
151 } | 143 } |
152 NOT_IN_PRODUCT(TimelineDurationScope tds(Timeline::GetVMStream(), | 144 NOT_IN_PRODUCT(TimelineDurationScope tds(Timeline::GetVMStream(), |
(...skipping 18 matching lines...) Expand all Loading... |
171 // Create the read-only handles area. | 163 // Create the read-only handles area. |
172 ASSERT(predefined_handles_ == NULL); | 164 ASSERT(predefined_handles_ == NULL); |
173 predefined_handles_ = new ReadOnlyHandles(); | 165 predefined_handles_ = new ReadOnlyHandles(); |
174 // Create the VM isolate and finish the VM initialization. | 166 // Create the VM isolate and finish the VM initialization. |
175 ASSERT(thread_pool_ == NULL); | 167 ASSERT(thread_pool_ == NULL); |
176 thread_pool_ = new ThreadPool(); | 168 thread_pool_ = new ThreadPool(); |
177 { | 169 { |
178 ASSERT(vm_isolate_ == NULL); | 170 ASSERT(vm_isolate_ == NULL); |
179 ASSERT(Flags::Initialized()); | 171 ASSERT(Flags::Initialized()); |
180 const bool is_vm_isolate = true; | 172 const bool is_vm_isolate = true; |
181 const bool precompiled = instructions_snapshot != NULL; | |
182 | 173 |
183 // Setup default flags for the VM isolate. | 174 // Setup default flags for the VM isolate. |
184 Dart_IsolateFlags api_flags; | 175 Dart_IsolateFlags api_flags; |
185 Isolate::FlagsInitialize(&api_flags); | 176 Isolate::FlagsInitialize(&api_flags); |
186 vm_isolate_ = Isolate::Init("vm-isolate", api_flags, is_vm_isolate); | 177 vm_isolate_ = Isolate::Init("vm-isolate", api_flags, is_vm_isolate); |
187 start_time_ = vm_isolate_->start_time(); | 178 start_time_ = vm_isolate_->start_time(); |
188 vm_isolate_->set_compilation_allowed(!precompiled); | |
189 // Verify assumptions about executing in the VM isolate. | 179 // Verify assumptions about executing in the VM isolate. |
190 ASSERT(vm_isolate_ == Isolate::Current()); | 180 ASSERT(vm_isolate_ == Isolate::Current()); |
191 ASSERT(vm_isolate_ == Thread::Current()->isolate()); | 181 ASSERT(vm_isolate_ == Thread::Current()->isolate()); |
192 | 182 |
193 Thread* T = Thread::Current(); | 183 Thread* T = Thread::Current(); |
194 ASSERT(T != NULL); | 184 ASSERT(T != NULL); |
195 StackZone zone(T); | 185 StackZone zone(T); |
196 HandleScope handle_scope(T); | 186 HandleScope handle_scope(T); |
197 Object::InitNull(vm_isolate_); | 187 Object::InitNull(vm_isolate_); |
198 ObjectStore::Init(vm_isolate_); | 188 ObjectStore::Init(vm_isolate_); |
199 TargetCPUFeatures::InitOnce(); | 189 TargetCPUFeatures::InitOnce(); |
200 Object::InitOnce(vm_isolate_); | 190 Object::InitOnce(vm_isolate_); |
201 ArgumentsDescriptor::InitOnce(); | 191 ArgumentsDescriptor::InitOnce(); |
202 ICData::InitOnce(); | 192 ICData::InitOnce(); |
203 // When precompiled the stub code is initialized from the snapshot. | |
204 if (!precompiled) { | |
205 StubCode::InitOnce(); | |
206 } | |
207 if (vm_isolate_snapshot != NULL) { | 193 if (vm_isolate_snapshot != NULL) { |
208 NOT_IN_PRODUCT(TimelineDurationScope tds(Timeline::GetVMStream(), | 194 NOT_IN_PRODUCT(TimelineDurationScope tds(Timeline::GetVMStream(), |
209 "VMIsolateSnapshot")); | 195 "VMIsolateSnapshot")); |
210 if (instructions_snapshot != NULL) { | |
211 vm_isolate_->SetupInstructionsSnapshotPage(instructions_snapshot); | |
212 } | |
213 if (data_snapshot != NULL) { | |
214 vm_isolate_->SetupDataSnapshotPage(data_snapshot); | |
215 } | |
216 const Snapshot* snapshot = Snapshot::SetupFromBuffer(vm_isolate_snapshot); | 196 const Snapshot* snapshot = Snapshot::SetupFromBuffer(vm_isolate_snapshot); |
217 if (snapshot == NULL) { | 197 if (snapshot == NULL) { |
218 return "Invalid vm isolate snapshot seen."; | 198 return "Invalid vm isolate snapshot seen"; |
219 } | 199 } |
220 ASSERT(Snapshot::IsFull(snapshot->kind())); | 200 snapshot_kind_ = snapshot->kind(); |
| 201 if (Snapshot::IncludesCode(snapshot_kind_)) { |
| 202 if (snapshot_kind_ == Snapshot::kAppNoJIT) { |
| 203 #if defined(DART_PRECOMPILED_RUNTIME) |
| 204 vm_isolate_->set_compilation_allowed(false); |
| 205 if (!FLAG_precompiled_runtime) { |
| 206 return "Flag --precompilation was not specified"; |
| 207 } |
| 208 #else |
| 209 return "JIT runtime cannot run a precompiled snapshot"; |
| 210 #endif |
| 211 } |
| 212 if (instructions_snapshot == NULL) { |
| 213 return "Missing instructions snapshot"; |
| 214 } |
| 215 if (data_snapshot == NULL) { |
| 216 return "Missing rodata snapshot"; |
| 217 } |
| 218 vm_isolate_->SetupInstructionsSnapshotPage(instructions_snapshot); |
| 219 vm_isolate_->SetupDataSnapshotPage(data_snapshot); |
| 220 } else if (Snapshot::IsFull(snapshot_kind_)) { |
| 221 #if defined(DART_PRECOMPILED_RUNTIME) |
| 222 return "Precompiled runtime requires a precompiled snapshot"; |
| 223 #else |
| 224 if (instructions_snapshot != NULL) { |
| 225 return "Unexpected instructions snapshot"; |
| 226 } |
| 227 if (data_snapshot != NULL) { |
| 228 return "Unexpected rodata snapshot"; |
| 229 } |
| 230 StubCode::InitOnce(); |
| 231 #endif |
| 232 } else { |
| 233 return "Invalid vm isolate snapshot seen"; |
| 234 } |
221 VmIsolateSnapshotReader reader(snapshot->kind(), | 235 VmIsolateSnapshotReader reader(snapshot->kind(), |
222 snapshot->content(), | 236 snapshot->content(), |
223 snapshot->length(), | 237 snapshot->length(), |
224 instructions_snapshot, | 238 instructions_snapshot, |
225 data_snapshot, | 239 data_snapshot, |
226 T); | 240 T); |
227 const Error& error = Error::Handle(reader.ReadVmIsolateSnapshot()); | 241 const Error& error = Error::Handle(reader.ReadVmIsolateSnapshot()); |
228 if (!error.IsNull()) { | 242 if (!error.IsNull()) { |
229 return error.ToCString(); | 243 return error.ToErrorCString(); |
230 } | 244 } |
231 NOT_IN_PRODUCT(if (tds.enabled()) { | 245 NOT_IN_PRODUCT(if (tds.enabled()) { |
232 tds.SetNumArguments(2); | 246 tds.SetNumArguments(2); |
233 tds.FormatArgument(0, "snapshotSize", "%" Pd, snapshot->length()); | 247 tds.FormatArgument(0, "snapshotSize", "%" Pd, snapshot->length()); |
234 tds.FormatArgument(1, "heapSize", "%" Pd64, | 248 tds.FormatArgument(1, "heapSize", "%" Pd64, |
235 vm_isolate_->heap()->UsedInWords(Heap::kOld) * | 249 vm_isolate_->heap()->UsedInWords(Heap::kOld) * |
236 kWordSize); | 250 kWordSize); |
237 }); | 251 }); |
238 if (FLAG_trace_isolates) { | 252 if (FLAG_trace_isolates) { |
239 OS::Print("Size of vm isolate snapshot = %" Pd "\n", | 253 OS::Print("Size of vm isolate snapshot = %" Pd "\n", |
240 snapshot->length()); | 254 snapshot->length()); |
241 vm_isolate_->heap()->PrintSizes(); | 255 vm_isolate_->heap()->PrintSizes(); |
242 MegamorphicCacheTable::PrintSizes(vm_isolate_); | 256 MegamorphicCacheTable::PrintSizes(vm_isolate_); |
243 intptr_t size; | 257 intptr_t size; |
244 intptr_t capacity; | 258 intptr_t capacity; |
245 Symbols::GetStats(vm_isolate_, &size, &capacity); | 259 Symbols::GetStats(vm_isolate_, &size, &capacity); |
246 OS::Print("VM Isolate: Number of symbols : %" Pd "\n", size); | 260 OS::Print("VM Isolate: Number of symbols : %" Pd "\n", size); |
247 OS::Print("VM Isolate: Symbol table capacity : %" Pd "\n", capacity); | 261 OS::Print("VM Isolate: Symbol table capacity : %" Pd "\n", capacity); |
248 } | 262 } |
249 } else { | 263 } else { |
| 264 #if defined(DART_PRECOMPILED_RUNTIME) |
| 265 return "Precompiled runtime requires a precompiled snapshot"; |
| 266 #else |
| 267 snapshot_kind_ = Snapshot::kNone; |
| 268 StubCode::InitOnce(); |
250 Symbols::InitOnce(vm_isolate_); | 269 Symbols::InitOnce(vm_isolate_); |
| 270 #endif |
251 } | 271 } |
252 // We need to initialize the constants here for the vm isolate thread due to | 272 // We need to initialize the constants here for the vm isolate thread due to |
253 // bootstrapping issues. | 273 // bootstrapping issues. |
254 T->InitVMConstants(); | 274 T->InitVMConstants(); |
255 Scanner::InitOnce(); | 275 Scanner::InitOnce(); |
256 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) | 276 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) |
257 // Dart VM requires at least SSE2. | 277 // Dart VM requires at least SSE2. |
258 if (!TargetCPUFeatures::sse2_supported()) { | 278 if (!TargetCPUFeatures::sse2_supported()) { |
259 return "SSE2 is required."; | 279 return "SSE2 is required."; |
260 } | 280 } |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 NOT_IN_PRODUCT(TimelineDurationScope tds(T, | 500 NOT_IN_PRODUCT(TimelineDurationScope tds(T, |
481 Timeline::GetIsolateStream(), "IsolateSnapshotReader")); | 501 Timeline::GetIsolateStream(), "IsolateSnapshotReader")); |
482 // TODO(turnidge): Remove once length is not part of the snapshot. | 502 // TODO(turnidge): Remove once length is not part of the snapshot. |
483 const Snapshot* snapshot = Snapshot::SetupFromBuffer(snapshot_buffer); | 503 const Snapshot* snapshot = Snapshot::SetupFromBuffer(snapshot_buffer); |
484 if (snapshot == NULL) { | 504 if (snapshot == NULL) { |
485 const String& message = String::Handle( | 505 const String& message = String::Handle( |
486 String::New("Invalid snapshot.")); | 506 String::New("Invalid snapshot.")); |
487 return ApiError::New(message); | 507 return ApiError::New(message); |
488 } | 508 } |
489 ASSERT(Snapshot::IsFull(snapshot->kind())); | 509 ASSERT(Snapshot::IsFull(snapshot->kind())); |
| 510 ASSERT(snapshot->kind() == snapshot_kind_); |
490 if (FLAG_trace_isolates) { | 511 if (FLAG_trace_isolates) { |
491 OS::Print("Size of isolate snapshot = %" Pd "\n", snapshot->length()); | 512 OS::Print("Size of isolate snapshot = %" Pd "\n", snapshot->length()); |
492 } | 513 } |
493 IsolateSnapshotReader reader(snapshot->kind(), | 514 IsolateSnapshotReader reader(snapshot->kind(), |
494 snapshot->content(), | 515 snapshot->content(), |
495 snapshot->length(), | 516 snapshot->length(), |
496 Dart::instructions_snapshot_buffer(), | 517 Dart::instructions_snapshot_buffer(), |
497 Dart::data_snapshot_buffer(), | 518 Dart::data_snapshot_buffer(), |
498 T); | 519 T); |
499 const Error& error = Error::Handle(reader.ReadFullSnapshot()); | 520 const Error& error = Error::Handle(reader.ReadFullSnapshot()); |
500 if (!error.IsNull()) { | 521 if (!error.IsNull()) { |
501 return error.raw(); | 522 return error.raw(); |
502 } | 523 } |
503 NOT_IN_PRODUCT(if (tds.enabled()) { | 524 NOT_IN_PRODUCT(if (tds.enabled()) { |
504 tds.SetNumArguments(2); | 525 tds.SetNumArguments(2); |
505 tds.FormatArgument(0, "snapshotSize", "%" Pd, snapshot->length()); | 526 tds.FormatArgument(0, "snapshotSize", "%" Pd, snapshot->length()); |
506 tds.FormatArgument(1, "heapSize", "%" Pd64, | 527 tds.FormatArgument(1, "heapSize", "%" Pd64, |
507 I->heap()->UsedInWords(Heap::kOld) * kWordSize); | 528 I->heap()->UsedInWords(Heap::kOld) * kWordSize); |
508 }); | 529 }); |
509 if (FLAG_trace_isolates) { | 530 if (FLAG_trace_isolates) { |
510 I->heap()->PrintSizes(); | 531 I->heap()->PrintSizes(); |
511 MegamorphicCacheTable::PrintSizes(I); | 532 MegamorphicCacheTable::PrintSizes(I); |
512 } | 533 } |
513 } else { | 534 } else { |
| 535 ASSERT(snapshot_kind_ == Snapshot::kNone); |
514 // Populate the isolate's symbol table with all symbols from the | 536 // Populate the isolate's symbol table with all symbols from the |
515 // VM isolate. We do this so that when we generate a full snapshot | 537 // VM isolate. We do this so that when we generate a full snapshot |
516 // for the isolate we have a unified symbol table that we can then | 538 // for the isolate we have a unified symbol table that we can then |
517 // read into the VM isolate. | 539 // read into the VM isolate. |
518 Symbols::AddPredefinedSymbolsToIsolate(); | 540 Symbols::AddPredefinedSymbolsToIsolate(); |
519 } | 541 } |
520 | 542 |
521 Object::VerifyBuiltinVtables(); | 543 Object::VerifyBuiltinVtables(); |
522 DEBUG_ONLY(I->heap()->Verify(kForbidMarked)); | 544 DEBUG_ONLY(I->heap()->Verify(kForbidMarked)); |
523 | 545 |
524 { | 546 { |
525 NOT_IN_PRODUCT(TimelineDurationScope tds(T, | 547 NOT_IN_PRODUCT(TimelineDurationScope tds(T, |
526 Timeline::GetIsolateStream(), "StubCode::Init")); | 548 Timeline::GetIsolateStream(), "StubCode::Init")); |
527 StubCode::Init(I); | 549 StubCode::Init(I); |
528 } | 550 } |
529 | 551 |
530 #if !defined(DART_PRECOMPILED_RUNTIME) | 552 #if !defined(DART_PRECOMPILED_RUNTIME) |
531 // When running precompiled, the megamorphic miss function/code comes from the | 553 // When running precompiled, the megamorphic miss function/code comes from the |
532 // snapshot. | 554 // snapshot. |
533 if (!Dart::IsRunningPrecompiledCode()) { | 555 if (!Snapshot::IncludesCode(Dart::snapshot_kind())) { |
534 MegamorphicCacheTable::InitMissHandler(I); | 556 MegamorphicCacheTable::InitMissHandler(I); |
535 } | 557 } |
536 #endif | 558 #endif |
537 | 559 |
538 const Code& miss_code = | 560 const Code& miss_code = |
539 Code::Handle(I->object_store()->megamorphic_miss_code()); | 561 Code::Handle(I->object_store()->megamorphic_miss_code()); |
540 I->set_ic_miss_code(miss_code); | 562 I->set_ic_miss_code(miss_code); |
541 | 563 |
542 if (snapshot_buffer == NULL) { | 564 if (snapshot_buffer == NULL) { |
543 const Error& error = Error::Handle(I->object_store()->PreallocateObjects()); | 565 const Error& error = Error::Handle(I->object_store()->PreallocateObjects()); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
633 return predefined_handles_->handles_.IsValidScopedHandle(address); | 655 return predefined_handles_->handles_.IsValidScopedHandle(address); |
634 } | 656 } |
635 | 657 |
636 | 658 |
637 bool Dart::IsReadOnlyApiHandle(Dart_Handle handle) { | 659 bool Dart::IsReadOnlyApiHandle(Dart_Handle handle) { |
638 ASSERT(predefined_handles_ != NULL); | 660 ASSERT(predefined_handles_ != NULL); |
639 return predefined_handles_->api_handles_.IsValidHandle(handle); | 661 return predefined_handles_->api_handles_.IsValidHandle(handle); |
640 } | 662 } |
641 | 663 |
642 } // namespace dart | 664 } // namespace dart |
OLD | NEW |