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/become.h" | 7 #include "vm/become.h" |
8 #include "vm/clustered_snapshot.h" | 8 #include "vm/clustered_snapshot.h" |
9 #include "vm/code_observers.h" | 9 #include "vm/code_observers.h" |
10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 30 matching lines...) Expand all Loading... |
41 DECLARE_FLAG(bool, print_class_table); | 41 DECLARE_FLAG(bool, print_class_table); |
42 DECLARE_FLAG(bool, trace_time_all); | 42 DECLARE_FLAG(bool, trace_time_all); |
43 DEFINE_FLAG(bool, keep_code, false, "Keep deoptimized code for profiling."); | 43 DEFINE_FLAG(bool, keep_code, false, "Keep deoptimized code for profiling."); |
44 DEFINE_FLAG(bool, trace_shutdown, false, "Trace VM shutdown on stderr"); | 44 DEFINE_FLAG(bool, trace_shutdown, false, "Trace VM shutdown on stderr"); |
45 | 45 |
46 Isolate* Dart::vm_isolate_ = NULL; | 46 Isolate* Dart::vm_isolate_ = NULL; |
47 int64_t Dart::start_time_micros_ = 0; | 47 int64_t Dart::start_time_micros_ = 0; |
48 ThreadPool* Dart::thread_pool_ = NULL; | 48 ThreadPool* Dart::thread_pool_ = NULL; |
49 DebugInfo* Dart::pprof_symbol_generator_ = NULL; | 49 DebugInfo* Dart::pprof_symbol_generator_ = NULL; |
50 ReadOnlyHandles* Dart::predefined_handles_ = NULL; | 50 ReadOnlyHandles* Dart::predefined_handles_ = NULL; |
51 Snapshot::Kind Dart::snapshot_kind_ = Snapshot::kInvalid; | 51 Snapshot::Kind Dart::vm_snapshot_kind_ = Snapshot::kInvalid; |
52 const uint8_t* Dart::instructions_snapshot_buffer_ = NULL; | |
53 const uint8_t* Dart::data_snapshot_buffer_ = NULL; | |
54 Dart_ThreadExitCallback Dart::thread_exit_callback_ = NULL; | 52 Dart_ThreadExitCallback Dart::thread_exit_callback_ = NULL; |
55 Dart_FileOpenCallback Dart::file_open_callback_ = NULL; | 53 Dart_FileOpenCallback Dart::file_open_callback_ = NULL; |
56 Dart_FileReadCallback Dart::file_read_callback_ = NULL; | 54 Dart_FileReadCallback Dart::file_read_callback_ = NULL; |
57 Dart_FileWriteCallback Dart::file_write_callback_ = NULL; | 55 Dart_FileWriteCallback Dart::file_write_callback_ = NULL; |
58 Dart_FileCloseCallback Dart::file_close_callback_ = NULL; | 56 Dart_FileCloseCallback Dart::file_close_callback_ = NULL; |
59 Dart_EntropySource Dart::entropy_source_callback_ = NULL; | 57 Dart_EntropySource Dart::entropy_source_callback_ = NULL; |
60 | 58 |
61 // Structure for managing read-only global handles allocation used for | 59 // Structure for managing read-only global handles allocation used for |
62 // creating global read-only handles that are pre created and initialized | 60 // creating global read-only handles that are pre created and initialized |
63 // for use across all isolates. Having these global pre created handles | 61 // for use across all isolates. Having these global pre created handles |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 CHECK_OFFSET(SingleTargetCache::upper_limit_offset(), 28); | 115 CHECK_OFFSET(SingleTargetCache::upper_limit_offset(), 28); |
118 CHECK_OFFSET(Isolate::object_store_offset(), 56); | 116 CHECK_OFFSET(Isolate::object_store_offset(), 56); |
119 NOT_IN_PRODUCT(CHECK_OFFSET(sizeof(ClassHeapStats), 208)); | 117 NOT_IN_PRODUCT(CHECK_OFFSET(sizeof(ClassHeapStats), 208)); |
120 #endif | 118 #endif |
121 #undef CHECK_OFFSET | 119 #undef CHECK_OFFSET |
122 } | 120 } |
123 | 121 |
124 | 122 |
125 char* Dart::InitOnce(const uint8_t* vm_isolate_snapshot, | 123 char* Dart::InitOnce(const uint8_t* vm_isolate_snapshot, |
126 const uint8_t* instructions_snapshot, | 124 const uint8_t* instructions_snapshot, |
127 const uint8_t* data_snapshot, | |
128 Dart_IsolateCreateCallback create, | 125 Dart_IsolateCreateCallback create, |
129 Dart_IsolateShutdownCallback shutdown, | 126 Dart_IsolateShutdownCallback shutdown, |
130 Dart_ThreadExitCallback thread_exit, | 127 Dart_ThreadExitCallback thread_exit, |
131 Dart_FileOpenCallback file_open, | 128 Dart_FileOpenCallback file_open, |
132 Dart_FileReadCallback file_read, | 129 Dart_FileReadCallback file_read, |
133 Dart_FileWriteCallback file_write, | 130 Dart_FileWriteCallback file_write, |
134 Dart_FileCloseCallback file_close, | 131 Dart_FileCloseCallback file_close, |
135 Dart_EntropySource entropy_source, | 132 Dart_EntropySource entropy_source, |
136 Dart_GetVMServiceAssetsArchive get_service_assets) { | 133 Dart_GetVMServiceAssetsArchive get_service_assets) { |
137 CheckOffsets(); | 134 CheckOffsets(); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 Object::InitOnce(vm_isolate_); | 203 Object::InitOnce(vm_isolate_); |
207 ArgumentsDescriptor::InitOnce(); | 204 ArgumentsDescriptor::InitOnce(); |
208 ICData::InitOnce(); | 205 ICData::InitOnce(); |
209 if (vm_isolate_snapshot != NULL) { | 206 if (vm_isolate_snapshot != NULL) { |
210 NOT_IN_PRODUCT(TimelineDurationScope tds(Timeline::GetVMStream(), | 207 NOT_IN_PRODUCT(TimelineDurationScope tds(Timeline::GetVMStream(), |
211 "VMIsolateSnapshot")); | 208 "VMIsolateSnapshot")); |
212 const Snapshot* snapshot = Snapshot::SetupFromBuffer(vm_isolate_snapshot); | 209 const Snapshot* snapshot = Snapshot::SetupFromBuffer(vm_isolate_snapshot); |
213 if (snapshot == NULL) { | 210 if (snapshot == NULL) { |
214 return strdup("Invalid vm isolate snapshot seen"); | 211 return strdup("Invalid vm isolate snapshot seen"); |
215 } | 212 } |
216 snapshot_kind_ = snapshot->kind(); | 213 vm_snapshot_kind_ = snapshot->kind(); |
217 | 214 |
218 if (Snapshot::IncludesCode(snapshot_kind_)) { | 215 if (Snapshot::IncludesCode(vm_snapshot_kind_)) { |
219 if (snapshot_kind_ == Snapshot::kAppAOT) { | 216 if (vm_snapshot_kind_ == Snapshot::kAppAOT) { |
220 #if defined(DART_PRECOMPILED_RUNTIME) | 217 #if defined(DART_PRECOMPILED_RUNTIME) |
221 vm_isolate_->set_compilation_allowed(false); | 218 vm_isolate_->set_compilation_allowed(false); |
222 if (!FLAG_precompiled_runtime) { | 219 if (!FLAG_precompiled_runtime) { |
223 return strdup("Flag --precompilation was not specified"); | 220 return strdup("Flag --precompilation was not specified"); |
224 } | 221 } |
225 #else | 222 #else |
226 return strdup("JIT runtime cannot run a precompiled snapshot"); | 223 return strdup("JIT runtime cannot run a precompiled snapshot"); |
227 #endif | 224 #endif |
228 } | 225 } |
229 if (instructions_snapshot == NULL) { | 226 if (instructions_snapshot == NULL) { |
230 return strdup("Missing instructions snapshot"); | 227 return strdup("Missing instructions snapshot"); |
231 } | 228 } |
232 if (data_snapshot == NULL) { | 229 } else if (Snapshot::IsFull(vm_snapshot_kind_)) { |
233 return strdup("Missing rodata snapshot"); | |
234 } | |
235 } else if (Snapshot::IsFull(snapshot_kind_)) { | |
236 #if defined(DART_PRECOMPILED_RUNTIME) | 230 #if defined(DART_PRECOMPILED_RUNTIME) |
237 return strdup("Precompiled runtime requires a precompiled snapshot"); | 231 return strdup("Precompiled runtime requires a precompiled snapshot"); |
238 #else | 232 #else |
239 StubCode::InitOnce(); | 233 StubCode::InitOnce(); |
240 #endif | 234 #endif |
241 } else { | 235 } else { |
242 return strdup("Invalid vm isolate snapshot seen"); | 236 return strdup("Invalid vm isolate snapshot seen"); |
243 } | 237 } |
244 if (instructions_snapshot != NULL) { | 238 FullSnapshotReader reader(snapshot, instructions_snapshot, T); |
245 vm_isolate_->SetupInstructionsSnapshotPage(instructions_snapshot); | 239 const Error& error = Error::Handle(reader.ReadVMSnapshot()); |
246 } | |
247 if (instructions_snapshot != NULL) { | |
248 vm_isolate_->SetupDataSnapshotPage(data_snapshot); | |
249 } | |
250 VmIsolateSnapshotReader reader(snapshot->kind(), snapshot->content(), | |
251 snapshot->length(), instructions_snapshot, | |
252 data_snapshot, T); | |
253 const Error& error = Error::Handle(reader.ReadVmIsolateSnapshot()); | |
254 if (!error.IsNull()) { | 240 if (!error.IsNull()) { |
255 // Must copy before leaving the zone. | 241 // Must copy before leaving the zone. |
256 return strdup(error.ToErrorCString()); | 242 return strdup(error.ToErrorCString()); |
257 } | 243 } |
258 #if !defined(PRODUCT) | 244 #if !defined(PRODUCT) |
259 if (tds.enabled()) { | 245 if (tds.enabled()) { |
260 tds.SetNumArguments(2); | 246 tds.SetNumArguments(2); |
261 tds.FormatArgument(0, "snapshotSize", "%" Pd, snapshot->length()); | 247 tds.FormatArgument(0, "snapshotSize", "%" Pd, snapshot->length()); |
262 tds.FormatArgument( | 248 tds.FormatArgument( |
263 1, "heapSize", "%" Pd64, | 249 1, "heapSize", "%" Pd64, |
(...skipping 10 matching lines...) Expand all Loading... |
274 Symbols::GetStats(vm_isolate_, &size, &capacity); | 260 Symbols::GetStats(vm_isolate_, &size, &capacity); |
275 OS::Print("VM Isolate: Number of symbols : %" Pd "\n", size); | 261 OS::Print("VM Isolate: Number of symbols : %" Pd "\n", size); |
276 OS::Print("VM Isolate: Symbol table capacity : %" Pd "\n", capacity); | 262 OS::Print("VM Isolate: Symbol table capacity : %" Pd "\n", capacity); |
277 } | 263 } |
278 } else { | 264 } else { |
279 #if defined(DART_PRECOMPILED_RUNTIME) | 265 #if defined(DART_PRECOMPILED_RUNTIME) |
280 return strdup("Precompiled runtime requires a precompiled snapshot"); | 266 return strdup("Precompiled runtime requires a precompiled snapshot"); |
281 #elif !defined(DART_NO_SNAPSHOT) | 267 #elif !defined(DART_NO_SNAPSHOT) |
282 return strdup("Missing vm isolate snapshot"); | 268 return strdup("Missing vm isolate snapshot"); |
283 #else | 269 #else |
284 snapshot_kind_ = Snapshot::kNone; | 270 vm_snapshot_kind_ = Snapshot::kNone; |
285 StubCode::InitOnce(); | 271 StubCode::InitOnce(); |
286 Symbols::InitOnce(vm_isolate_); | 272 Symbols::InitOnce(vm_isolate_); |
287 #endif | 273 #endif |
288 } | 274 } |
289 // We need to initialize the constants here for the vm isolate thread due to | 275 // We need to initialize the constants here for the vm isolate thread due to |
290 // bootstrapping issues. | 276 // bootstrapping issues. |
291 T->InitVMConstants(); | 277 T->InitVMConstants(); |
292 Scanner::InitOnce(); | 278 Scanner::InitOnce(); |
293 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) | 279 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) |
294 // Dart VM requires at least SSE2. | 280 // Dart VM requires at least SSE2. |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
497 | 483 |
498 | 484 |
499 Isolate* Dart::CreateIsolate(const char* name_prefix, | 485 Isolate* Dart::CreateIsolate(const char* name_prefix, |
500 const Dart_IsolateFlags& api_flags) { | 486 const Dart_IsolateFlags& api_flags) { |
501 // Create a new isolate. | 487 // Create a new isolate. |
502 Isolate* isolate = Isolate::Init(name_prefix, api_flags); | 488 Isolate* isolate = Isolate::Init(name_prefix, api_flags); |
503 return isolate; | 489 return isolate; |
504 } | 490 } |
505 | 491 |
506 | 492 |
507 RawError* Dart::InitializeIsolate(const uint8_t* snapshot_buffer, | 493 static bool IsSnapshotCompatible(Snapshot::Kind vm_kind, |
| 494 Snapshot::Kind isolate_kind) { |
| 495 if (vm_kind == isolate_kind) return true; |
| 496 if (vm_kind == Snapshot::kCore && isolate_kind == Snapshot::kAppJIT) |
| 497 return true; |
| 498 return Snapshot::IsFull(isolate_kind); |
| 499 } |
| 500 |
| 501 |
| 502 RawError* Dart::InitializeIsolate(const uint8_t* snapshot_data, |
| 503 const uint8_t* snapshot_instructions, |
508 intptr_t snapshot_length, | 504 intptr_t snapshot_length, |
509 kernel::Program* kernel_program, | 505 kernel::Program* kernel_program, |
510 void* data) { | 506 void* data) { |
511 // Initialize the new isolate. | 507 // Initialize the new isolate. |
512 Thread* T = Thread::Current(); | 508 Thread* T = Thread::Current(); |
513 Isolate* I = T->isolate(); | 509 Isolate* I = T->isolate(); |
514 NOT_IN_PRODUCT(TimelineDurationScope tds(T, Timeline::GetIsolateStream(), | 510 NOT_IN_PRODUCT(TimelineDurationScope tds(T, Timeline::GetIsolateStream(), |
515 "InitializeIsolate"); | 511 "InitializeIsolate"); |
516 tds.SetNumArguments(1); | 512 tds.SetNumArguments(1); |
517 tds.CopyArgument(0, "isolateName", I->name());) | 513 tds.CopyArgument(0, "isolateName", I->name());) |
518 ASSERT(I != NULL); | 514 ASSERT(I != NULL); |
519 StackZone zone(T); | 515 StackZone zone(T); |
520 HandleScope handle_scope(T); | 516 HandleScope handle_scope(T); |
521 { | 517 { |
522 NOT_IN_PRODUCT(TimelineDurationScope tds(T, Timeline::GetIsolateStream(), | 518 NOT_IN_PRODUCT(TimelineDurationScope tds(T, Timeline::GetIsolateStream(), |
523 "ObjectStore::Init")); | 519 "ObjectStore::Init")); |
524 ObjectStore::Init(I); | 520 ObjectStore::Init(I); |
525 } | 521 } |
526 | 522 |
527 Error& error = Error::Handle(T->zone()); | 523 Error& error = Error::Handle(T->zone()); |
528 error = Object::Init(I, kernel_program); | 524 error = Object::Init(I, kernel_program); |
529 if (!error.IsNull()) { | 525 if (!error.IsNull()) { |
530 return error.raw(); | 526 return error.raw(); |
531 } | 527 } |
532 if ((snapshot_buffer != NULL) && kernel_program == NULL) { | 528 if ((snapshot_data != NULL) && kernel_program == NULL) { |
533 // Read the snapshot and setup the initial state. | 529 // Read the snapshot and setup the initial state. |
534 NOT_IN_PRODUCT(TimelineDurationScope tds(T, Timeline::GetIsolateStream(), | 530 NOT_IN_PRODUCT(TimelineDurationScope tds(T, Timeline::GetIsolateStream(), |
535 "IsolateSnapshotReader")); | 531 "IsolateSnapshotReader")); |
536 // TODO(turnidge): Remove once length is not part of the snapshot. | 532 // TODO(turnidge): Remove once length is not part of the snapshot. |
537 const Snapshot* snapshot = Snapshot::SetupFromBuffer(snapshot_buffer); | 533 const Snapshot* snapshot = Snapshot::SetupFromBuffer(snapshot_data); |
538 if (snapshot == NULL) { | 534 if (snapshot == NULL) { |
539 const String& message = String::Handle(String::New("Invalid snapshot")); | 535 const String& message = String::Handle(String::New("Invalid snapshot")); |
540 return ApiError::New(message); | 536 return ApiError::New(message); |
541 } | 537 } |
542 if (snapshot->kind() != snapshot_kind_ && | 538 if (!IsSnapshotCompatible(vm_snapshot_kind_, snapshot->kind())) { |
543 !((snapshot->kind() == Snapshot::kAppJIT) && | 539 const String& message = String::Handle(String::NewFormatted( |
544 (snapshot_kind_ == Snapshot::kCore))) { | 540 "Incompatible snapshot kinds: vm '%s', isolate '%s'", |
545 const String& message = String::Handle( | 541 Snapshot::KindToCString(vm_snapshot_kind_), |
546 String::NewFormatted("Invalid snapshot kind: got '%s', expected '%s'", | 542 Snapshot::KindToCString(snapshot->kind()))); |
547 Snapshot::KindToCString(snapshot->kind()), | |
548 Snapshot::KindToCString(snapshot_kind_))); | |
549 return ApiError::New(message); | 543 return ApiError::New(message); |
550 } | 544 } |
551 ASSERT(Snapshot::IsFull(snapshot->kind())); | |
552 if (FLAG_trace_isolates) { | 545 if (FLAG_trace_isolates) { |
553 OS::Print("Size of isolate snapshot = %" Pd "\n", snapshot->length()); | 546 OS::Print("Size of isolate snapshot = %" Pd "\n", snapshot->length()); |
554 } | 547 } |
555 IsolateSnapshotReader reader( | 548 FullSnapshotReader reader(snapshot, snapshot_instructions, T); |
556 snapshot->kind(), snapshot->content(), snapshot->length(), | 549 const Error& error = Error::Handle(reader.ReadIsolateSnapshot()); |
557 Dart::instructions_snapshot_buffer(), Dart::data_snapshot_buffer(), T); | |
558 const Error& error = Error::Handle(reader.ReadFullSnapshot()); | |
559 if (!error.IsNull()) { | 550 if (!error.IsNull()) { |
560 return error.raw(); | 551 return error.raw(); |
561 } | 552 } |
562 #if !defined(PRODUCT) | 553 #if !defined(PRODUCT) |
563 if (tds.enabled()) { | 554 if (tds.enabled()) { |
564 tds.SetNumArguments(2); | 555 tds.SetNumArguments(2); |
565 tds.FormatArgument(0, "snapshotSize", "%" Pd, snapshot->length()); | 556 tds.FormatArgument(0, "snapshotSize", "%" Pd, snapshot->length()); |
566 tds.FormatArgument(1, "heapSize", "%" Pd64, | 557 tds.FormatArgument(1, "heapSize", "%" Pd64, |
567 I->heap()->UsedInWords(Heap::kOld) * kWordSize); | 558 I->heap()->UsedInWords(Heap::kOld) * kWordSize); |
568 } | 559 } |
569 #endif // !defined(PRODUCT) | 560 #endif // !defined(PRODUCT) |
570 if (FLAG_trace_isolates) { | 561 if (FLAG_trace_isolates) { |
571 I->heap()->PrintSizes(); | 562 I->heap()->PrintSizes(); |
572 MegamorphicCacheTable::PrintSizes(I); | 563 MegamorphicCacheTable::PrintSizes(I); |
573 } | 564 } |
574 } else { | 565 } else { |
575 if ((snapshot_kind_ != Snapshot::kNone) && kernel_program == NULL) { | 566 if ((vm_snapshot_kind_ != Snapshot::kNone) && kernel_program == NULL) { |
576 const String& message = | 567 const String& message = |
577 String::Handle(String::New("Missing isolate snapshot")); | 568 String::Handle(String::New("Missing isolate snapshot")); |
578 return ApiError::New(message); | 569 return ApiError::New(message); |
579 } | 570 } |
580 } | 571 } |
581 | 572 |
582 Object::VerifyBuiltinVtables(); | 573 Object::VerifyBuiltinVtables(); |
583 DEBUG_ONLY(I->heap()->Verify(kForbidMarked)); | 574 DEBUG_ONLY(I->heap()->Verify(kForbidMarked)); |
584 | 575 |
585 { | 576 { |
(...skipping 10 matching lines...) Expand all Loading... |
596 // app snapshot, otherwise create them. | 587 // app snapshot, otherwise create them. |
597 if (I->object_store()->megamorphic_miss_code() == Code::null()) { | 588 if (I->object_store()->megamorphic_miss_code() == Code::null()) { |
598 MegamorphicCacheTable::InitMissHandler(I); | 589 MegamorphicCacheTable::InitMissHandler(I); |
599 } | 590 } |
600 #endif // defined(DART_PRECOMPILED_RUNTIME) | 591 #endif // defined(DART_PRECOMPILED_RUNTIME) |
601 | 592 |
602 const Code& miss_code = | 593 const Code& miss_code = |
603 Code::Handle(I->object_store()->megamorphic_miss_code()); | 594 Code::Handle(I->object_store()->megamorphic_miss_code()); |
604 I->set_ic_miss_code(miss_code); | 595 I->set_ic_miss_code(miss_code); |
605 | 596 |
606 if ((snapshot_buffer == NULL) || (kernel_program != NULL)) { | 597 if ((snapshot_data == NULL) || (kernel_program != NULL)) { |
607 const Error& error = Error::Handle(I->object_store()->PreallocateObjects()); | 598 const Error& error = Error::Handle(I->object_store()->PreallocateObjects()); |
608 if (!error.IsNull()) { | 599 if (!error.IsNull()) { |
609 return error.raw(); | 600 return error.raw(); |
610 } | 601 } |
611 } | 602 } |
612 | 603 |
613 I->heap()->InitGrowthControl(); | 604 I->heap()->InitGrowthControl(); |
614 I->set_init_callback_data(data); | 605 I->set_init_callback_data(data); |
615 Api::SetupAcquiredError(I); | 606 Api::SetupAcquiredError(I); |
616 if (FLAG_print_class_table) { | 607 if (FLAG_print_class_table) { |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
749 return predefined_handles_->handles_.IsValidScopedHandle(address); | 740 return predefined_handles_->handles_.IsValidScopedHandle(address); |
750 } | 741 } |
751 | 742 |
752 | 743 |
753 bool Dart::IsReadOnlyApiHandle(Dart_Handle handle) { | 744 bool Dart::IsReadOnlyApiHandle(Dart_Handle handle) { |
754 ASSERT(predefined_handles_ != NULL); | 745 ASSERT(predefined_handles_ != NULL); |
755 return predefined_handles_->api_handles_.IsValidHandle(handle); | 746 return predefined_handles_->api_handles_.IsValidHandle(handle); |
756 } | 747 } |
757 | 748 |
758 } // namespace dart | 749 } // namespace dart |
OLD | NEW |