| 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/isolate.h" | 5 #include "vm/isolate.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
| 9 #include "platform/json.h" | 9 #include "platform/json.h" |
| 10 #include "vm/code_observers.h" | 10 #include "vm/code_observers.h" |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 // equivalent to setting --enable-asserts and --enable-type-checks. | 88 // equivalent to setting --enable-asserts and --enable-type-checks. |
| 89 DEFINE_FLAG_HANDLER(CheckedModeHandler, | 89 DEFINE_FLAG_HANDLER(CheckedModeHandler, |
| 90 enable_checked_mode, | 90 enable_checked_mode, |
| 91 "Enable checked mode."); | 91 "Enable checked mode."); |
| 92 | 92 |
| 93 DEFINE_FLAG_HANDLER(CheckedModeHandler, | 93 DEFINE_FLAG_HANDLER(CheckedModeHandler, |
| 94 checked, | 94 checked, |
| 95 "Enable checked mode."); | 95 "Enable checked mode."); |
| 96 | 96 |
| 97 | 97 |
| 98 // Quick access to the locally defined isolate() method. | 98 // Quick access to the locally defined thread() and isolate() methods. |
| 99 #define T (thread()) |
| 99 #define I (isolate()) | 100 #define I (isolate()) |
| 100 | 101 |
| 101 #if defined(DEBUG) | 102 #if defined(DEBUG) |
| 102 // Helper class to ensure that a live origin_id is never reused | 103 // Helper class to ensure that a live origin_id is never reused |
| 103 // and assigned to an isolate. | 104 // and assigned to an isolate. |
| 104 class VerifyOriginId : public IsolateVisitor { | 105 class VerifyOriginId : public IsolateVisitor { |
| 105 public: | 106 public: |
| 106 explicit VerifyOriginId(Dart_Port id) : id_(id) {} | 107 explicit VerifyOriginId(Dart_Port id) : id_(id) {} |
| 107 | 108 |
| 108 void VisitIsolate(Isolate* isolate) { | 109 void VisitIsolate(Isolate* isolate) { |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 } else { | 500 } else { |
| 500 ASSERT(result.IsNull()); | 501 ASSERT(result.IsNull()); |
| 501 } | 502 } |
| 502 } | 503 } |
| 503 return success; | 504 return success; |
| 504 } | 505 } |
| 505 | 506 |
| 506 | 507 |
| 507 void IsolateMessageHandler::NotifyPauseOnStart() { | 508 void IsolateMessageHandler::NotifyPauseOnStart() { |
| 508 if (Service::debug_stream.enabled()) { | 509 if (Service::debug_stream.enabled()) { |
| 509 StartIsolateScope start_isolate(isolate()); | 510 StartIsolateScope start_isolate(I); |
| 510 StackZone zone(I); | 511 StackZone zone(T); |
| 511 HandleScope handle_scope(thread()); | 512 HandleScope handle_scope(T); |
| 512 ServiceEvent pause_event(isolate(), ServiceEvent::kPauseStart); | 513 ServiceEvent pause_event(I, ServiceEvent::kPauseStart); |
| 513 Service::HandleEvent(&pause_event); | 514 Service::HandleEvent(&pause_event); |
| 514 } else if (FLAG_trace_service) { | 515 } else if (FLAG_trace_service) { |
| 515 OS::Print("vm-service: Dropping event of type PauseStart (%s)\n", | 516 OS::Print("vm-service: Dropping event of type PauseStart (%s)\n", |
| 516 isolate()->name()); | 517 I->name()); |
| 517 } | 518 } |
| 518 } | 519 } |
| 519 | 520 |
| 520 | 521 |
| 521 void IsolateMessageHandler::NotifyPauseOnExit() { | 522 void IsolateMessageHandler::NotifyPauseOnExit() { |
| 522 if (Service::debug_stream.enabled()) { | 523 if (Service::debug_stream.enabled()) { |
| 523 StartIsolateScope start_isolate(isolate()); | 524 StartIsolateScope start_isolate(I); |
| 524 StackZone zone(I); | 525 StackZone zone(T); |
| 525 HandleScope handle_scope(thread()); | 526 HandleScope handle_scope(T); |
| 526 ServiceEvent pause_event(isolate(), ServiceEvent::kPauseExit); | 527 ServiceEvent pause_event(I, ServiceEvent::kPauseExit); |
| 527 Service::HandleEvent(&pause_event); | 528 Service::HandleEvent(&pause_event); |
| 528 } else if (FLAG_trace_service) { | 529 } else if (FLAG_trace_service) { |
| 529 OS::Print("vm-service: Dropping event of type PauseExit (%s)\n", | 530 OS::Print("vm-service: Dropping event of type PauseExit (%s)\n", |
| 530 isolate()->name()); | 531 I->name()); |
| 531 } | 532 } |
| 532 } | 533 } |
| 533 | 534 |
| 534 | 535 |
| 535 #if defined(DEBUG) | 536 #if defined(DEBUG) |
| 536 void IsolateMessageHandler::CheckAccess() { | 537 void IsolateMessageHandler::CheckAccess() { |
| 537 ASSERT(IsCurrentIsolate()); | 538 ASSERT(IsCurrentIsolate()); |
| 538 } | 539 } |
| 539 #endif | 540 #endif |
| 540 | 541 |
| (...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1265 IsolateSpawnState* state = NULL; | 1266 IsolateSpawnState* state = NULL; |
| 1266 Thread* thread = Thread::Current(); | 1267 Thread* thread = Thread::Current(); |
| 1267 { | 1268 { |
| 1268 // TODO(turnidge): Is this locking required here at all anymore? | 1269 // TODO(turnidge): Is this locking required here at all anymore? |
| 1269 MutexLocker ml(isolate->mutex()); | 1270 MutexLocker ml(isolate->mutex()); |
| 1270 state = isolate->spawn_state(); | 1271 state = isolate->spawn_state(); |
| 1271 } | 1272 } |
| 1272 { | 1273 { |
| 1273 StartIsolateScope start_scope(isolate); | 1274 StartIsolateScope start_scope(isolate); |
| 1274 ASSERT(thread->isolate() == isolate); | 1275 ASSERT(thread->isolate() == isolate); |
| 1275 StackZone zone(isolate); | 1276 StackZone zone(thread); |
| 1276 HandleScope handle_scope(thread); | 1277 HandleScope handle_scope(thread); |
| 1277 | 1278 |
| 1278 // If particular values were requested for this newly spawned isolate, then | 1279 // If particular values were requested for this newly spawned isolate, then |
| 1279 // they are set here before the isolate starts executing user code. | 1280 // they are set here before the isolate starts executing user code. |
| 1280 isolate->SetErrorsFatal(state->errors_are_fatal()); | 1281 isolate->SetErrorsFatal(state->errors_are_fatal()); |
| 1281 if (state->on_exit_port() != ILLEGAL_PORT) { | 1282 if (state->on_exit_port() != ILLEGAL_PORT) { |
| 1282 const SendPort& listener = | 1283 const SendPort& listener = |
| 1283 SendPort::Handle(SendPort::New(state->on_exit_port())); | 1284 SendPort::Handle(SendPort::New(state->on_exit_port())); |
| 1284 isolate->AddExitListener(listener, Instance::null_instance()); | 1285 isolate->AddExitListener(listener, Instance::null_instance()); |
| 1285 } | 1286 } |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1366 | 1367 |
| 1367 | 1368 |
| 1368 static void ShutdownIsolate(uword parameter) { | 1369 static void ShutdownIsolate(uword parameter) { |
| 1369 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); | 1370 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); |
| 1370 { | 1371 { |
| 1371 // Print the error if there is one. This may execute dart code to | 1372 // Print the error if there is one. This may execute dart code to |
| 1372 // print the exception object, so we need to use a StartIsolateScope. | 1373 // print the exception object, so we need to use a StartIsolateScope. |
| 1373 Thread* thread = Thread::Current(); | 1374 Thread* thread = Thread::Current(); |
| 1374 StartIsolateScope start_scope(isolate); | 1375 StartIsolateScope start_scope(isolate); |
| 1375 ASSERT(thread->isolate() == isolate); | 1376 ASSERT(thread->isolate() == isolate); |
| 1376 StackZone zone(isolate); | 1377 StackZone zone(thread); |
| 1377 HandleScope handle_scope(thread); | 1378 HandleScope handle_scope(thread); |
| 1378 Error& error = Error::Handle(); | 1379 Error& error = Error::Handle(); |
| 1379 error = isolate->object_store()->sticky_error(); | 1380 error = isolate->object_store()->sticky_error(); |
| 1380 if (!error.IsNull() && !error.IsUnwindError()) { | 1381 if (!error.IsNull() && !error.IsUnwindError()) { |
| 1381 OS::PrintErr("in ShutdownIsolate: %s\n", error.ToErrorCString()); | 1382 OS::PrintErr("in ShutdownIsolate: %s\n", error.ToErrorCString()); |
| 1382 } | 1383 } |
| 1383 Dart::RunShutdownCallback(); | 1384 Dart::RunShutdownCallback(); |
| 1384 } | 1385 } |
| 1385 { | 1386 { |
| 1386 // Shut the isolate down. | 1387 // Shut the isolate down. |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1493 // The VM isolate keeps all objects marked. | 1494 // The VM isolate keeps all objects marked. |
| 1494 heap_->Verify(this == Dart::vm_isolate() ? kRequireMarked : kForbidMarked); | 1495 heap_->Verify(this == Dart::vm_isolate() ? kRequireMarked : kForbidMarked); |
| 1495 } | 1496 } |
| 1496 #endif // DEBUG | 1497 #endif // DEBUG |
| 1497 | 1498 |
| 1498 Thread* thread = Thread::Current(); | 1499 Thread* thread = Thread::Current(); |
| 1499 | 1500 |
| 1500 // First, perform higher-level cleanup that may need to allocate. | 1501 // First, perform higher-level cleanup that may need to allocate. |
| 1501 { | 1502 { |
| 1502 // Ensure we have a zone and handle scope so that we can call VM functions. | 1503 // Ensure we have a zone and handle scope so that we can call VM functions. |
| 1503 StackZone stack_zone(this); | 1504 StackZone stack_zone(thread); |
| 1504 HandleScope handle_scope(thread); | 1505 HandleScope handle_scope(thread); |
| 1505 | 1506 |
| 1506 // Write out the coverage data if collection has been enabled. | 1507 // Write out the coverage data if collection has been enabled. |
| 1507 CodeCoverage::Write(this); | 1508 CodeCoverage::Write(this); |
| 1508 } | 1509 } |
| 1509 | 1510 |
| 1510 // Remove this isolate from the list *before* we start tearing it down, to | 1511 // Remove this isolate from the list *before* we start tearing it down, to |
| 1511 // avoid exposing it in a state of decay. | 1512 // avoid exposing it in a state of decay. |
| 1512 RemoveIsolateFromList(this); | 1513 RemoveIsolateFromList(this); |
| 1513 | 1514 |
| 1514 if (heap_ != NULL) { | 1515 if (heap_ != NULL) { |
| 1515 // Wait for any concurrent GC tasks to finish before shutting down. | 1516 // Wait for any concurrent GC tasks to finish before shutting down. |
| 1516 // TODO(koda): Support faster sweeper shutdown (e.g., after current page). | 1517 // TODO(koda): Support faster sweeper shutdown (e.g., after current page). |
| 1517 PageSpace* old_space = heap_->old_space(); | 1518 PageSpace* old_space = heap_->old_space(); |
| 1518 MonitorLocker ml(old_space->tasks_lock()); | 1519 MonitorLocker ml(old_space->tasks_lock()); |
| 1519 while (old_space->tasks() > 0) { | 1520 while (old_space->tasks() > 0) { |
| 1520 ml.Wait(); | 1521 ml.Wait(); |
| 1521 } | 1522 } |
| 1522 } | 1523 } |
| 1523 | 1524 |
| 1524 // Then, proceed with low-level teardown. | 1525 // Then, proceed with low-level teardown. |
| 1525 { | 1526 { |
| 1526 // Ensure we have a zone and handle scope so that we can call VM functions, | 1527 // Ensure we have a zone and handle scope so that we can call VM functions, |
| 1527 // but we no longer allocate new heap objects. | 1528 // but we no longer allocate new heap objects. |
| 1528 StackZone stack_zone(this); | 1529 StackZone stack_zone(thread); |
| 1529 HandleScope handle_scope(thread); | 1530 HandleScope handle_scope(thread); |
| 1530 NoSafepointScope no_safepoint_scope; | 1531 NoSafepointScope no_safepoint_scope; |
| 1531 | 1532 |
| 1532 if (compiler_stats_ != NULL) { | 1533 if (compiler_stats_ != NULL) { |
| 1533 compiler_stats()->Print(); | 1534 compiler_stats()->Print(); |
| 1534 } | 1535 } |
| 1535 | 1536 |
| 1536 // Notify exit listeners that this isolate is shutting down. | 1537 // Notify exit listeners that this isolate is shutting down. |
| 1537 if (object_store() != NULL) { | 1538 if (object_store() != NULL) { |
| 1538 NotifyExitListeners(); | 1539 NotifyExitListeners(); |
| (...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2142 previous->next_ = current->next_; | 2143 previous->next_ = current->next_; |
| 2143 return; | 2144 return; |
| 2144 } | 2145 } |
| 2145 previous = current; | 2146 previous = current; |
| 2146 current = current->next_; | 2147 current = current->next_; |
| 2147 } | 2148 } |
| 2148 UNREACHABLE(); | 2149 UNREACHABLE(); |
| 2149 } | 2150 } |
| 2150 | 2151 |
| 2151 | 2152 |
| 2152 template<class T> | 2153 template<class C> |
| 2153 T* Isolate::AllocateReusableHandle() { | 2154 C* Isolate::AllocateReusableHandle() { |
| 2154 T* handle = reinterpret_cast<T*>(reusable_handles_.AllocateScopedHandle()); | 2155 C* handle = reinterpret_cast<C*>(reusable_handles_.AllocateScopedHandle()); |
| 2155 T::initializeHandle(handle, T::null()); | 2156 C::initializeHandle(handle, C::null()); |
| 2156 return handle; | 2157 return handle; |
| 2157 } | 2158 } |
| 2158 | 2159 |
| 2159 | 2160 |
| 2160 static RawInstance* DeserializeObject(Thread* thread, | 2161 static RawInstance* DeserializeObject(Thread* thread, |
| 2161 uint8_t* obj_data, | 2162 uint8_t* obj_data, |
| 2162 intptr_t obj_len) { | 2163 intptr_t obj_len) { |
| 2163 if (obj_data == NULL) { | 2164 if (obj_data == NULL) { |
| 2164 return Instance::null(); | 2165 return Instance::null(); |
| 2165 } | 2166 } |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2352 serialized_message_, serialized_message_len_); | 2353 serialized_message_, serialized_message_len_); |
| 2353 } | 2354 } |
| 2354 | 2355 |
| 2355 | 2356 |
| 2356 void IsolateSpawnState::Cleanup() { | 2357 void IsolateSpawnState::Cleanup() { |
| 2357 SwitchIsolateScope switch_scope(I); | 2358 SwitchIsolateScope switch_scope(I); |
| 2358 Dart::ShutdownIsolate(); | 2359 Dart::ShutdownIsolate(); |
| 2359 } | 2360 } |
| 2360 | 2361 |
| 2361 } // namespace dart | 2362 } // namespace dart |
| OLD | NEW |