| 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 |