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 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 if (message->RedirectToDeliveryFailurePort()) { | 411 if (message->RedirectToDeliveryFailurePort()) { |
412 PortMap::PostMessage(message); | 412 PortMap::PostMessage(message); |
413 } else { | 413 } else { |
414 delete message; | 414 delete message; |
415 } | 415 } |
416 return true; | 416 return true; |
417 } | 417 } |
418 } | 418 } |
419 | 419 |
420 // Parse the message. | 420 // Parse the message. |
421 MessageSnapshotReader reader(message->data(), | 421 MessageSnapshotReader reader(message->data(), message->len(), thread); |
422 message->len(), | |
423 I, zone); | |
424 const Object& msg_obj = Object::Handle(zone, reader.ReadObject()); | 422 const Object& msg_obj = Object::Handle(zone, reader.ReadObject()); |
425 if (msg_obj.IsError()) { | 423 if (msg_obj.IsError()) { |
426 // An error occurred while reading the message. | 424 // An error occurred while reading the message. |
427 delete message; | 425 delete message; |
428 return ProcessUnhandledException(Error::Cast(msg_obj)); | 426 return ProcessUnhandledException(Error::Cast(msg_obj)); |
429 } | 427 } |
430 if (!msg_obj.IsNull() && !msg_obj.IsInstance()) { | 428 if (!msg_obj.IsNull() && !msg_obj.IsInstance()) { |
431 // TODO(turnidge): We need to decide what an isolate does with | 429 // TODO(turnidge): We need to decide what an isolate does with |
432 // malformed messages. If they (eventually) come from a remote | 430 // malformed messages. If they (eventually) come from a remote |
433 // machine, then it might make sense to drop the message entirely. | 431 // machine, then it might make sense to drop the message entirely. |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 } | 501 } |
504 } | 502 } |
505 return success; | 503 return success; |
506 } | 504 } |
507 | 505 |
508 | 506 |
509 void IsolateMessageHandler::NotifyPauseOnStart() { | 507 void IsolateMessageHandler::NotifyPauseOnStart() { |
510 if (Service::debug_stream.enabled()) { | 508 if (Service::debug_stream.enabled()) { |
511 StartIsolateScope start_isolate(isolate()); | 509 StartIsolateScope start_isolate(isolate()); |
512 StackZone zone(I); | 510 StackZone zone(I); |
513 HandleScope handle_scope(I); | 511 HandleScope handle_scope(thread()); |
514 ServiceEvent pause_event(isolate(), ServiceEvent::kPauseStart); | 512 ServiceEvent pause_event(isolate(), ServiceEvent::kPauseStart); |
515 Service::HandleEvent(&pause_event); | 513 Service::HandleEvent(&pause_event); |
516 } else if (FLAG_trace_service) { | 514 } else if (FLAG_trace_service) { |
517 OS::Print("vm-service: Dropping event of type PauseStart (%s)\n", | 515 OS::Print("vm-service: Dropping event of type PauseStart (%s)\n", |
518 isolate()->name()); | 516 isolate()->name()); |
519 } | 517 } |
520 } | 518 } |
521 | 519 |
522 | 520 |
523 void IsolateMessageHandler::NotifyPauseOnExit() { | 521 void IsolateMessageHandler::NotifyPauseOnExit() { |
524 if (Service::debug_stream.enabled()) { | 522 if (Service::debug_stream.enabled()) { |
525 StartIsolateScope start_isolate(isolate()); | 523 StartIsolateScope start_isolate(isolate()); |
526 StackZone zone(I); | 524 StackZone zone(I); |
527 HandleScope handle_scope(I); | 525 HandleScope handle_scope(thread()); |
528 ServiceEvent pause_event(isolate(), ServiceEvent::kPauseExit); | 526 ServiceEvent pause_event(isolate(), ServiceEvent::kPauseExit); |
529 Service::HandleEvent(&pause_event); | 527 Service::HandleEvent(&pause_event); |
530 } else if (FLAG_trace_service) { | 528 } else if (FLAG_trace_service) { |
531 OS::Print("vm-service: Dropping event of type PauseExit (%s)\n", | 529 OS::Print("vm-service: Dropping event of type PauseExit (%s)\n", |
532 isolate()->name()); | 530 isolate()->name()); |
533 } | 531 } |
534 } | 532 } |
535 | 533 |
536 | 534 |
537 #if defined(DEBUG) | 535 #if defined(DEBUG) |
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1258 | 1256 |
1259 static void StoreError(Isolate* isolate, const Object& obj) { | 1257 static void StoreError(Isolate* isolate, const Object& obj) { |
1260 ASSERT(obj.IsError()); | 1258 ASSERT(obj.IsError()); |
1261 isolate->object_store()->set_sticky_error(Error::Cast(obj)); | 1259 isolate->object_store()->set_sticky_error(Error::Cast(obj)); |
1262 } | 1260 } |
1263 | 1261 |
1264 | 1262 |
1265 static bool RunIsolate(uword parameter) { | 1263 static bool RunIsolate(uword parameter) { |
1266 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); | 1264 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); |
1267 IsolateSpawnState* state = NULL; | 1265 IsolateSpawnState* state = NULL; |
| 1266 Thread* thread = Thread::Current(); |
1268 { | 1267 { |
1269 // TODO(turnidge): Is this locking required here at all anymore? | 1268 // TODO(turnidge): Is this locking required here at all anymore? |
1270 MutexLocker ml(isolate->mutex()); | 1269 MutexLocker ml(isolate->mutex()); |
1271 state = isolate->spawn_state(); | 1270 state = isolate->spawn_state(); |
1272 } | 1271 } |
1273 { | 1272 { |
1274 StartIsolateScope start_scope(isolate); | 1273 StartIsolateScope start_scope(isolate); |
| 1274 ASSERT(thread->isolate() == isolate); |
1275 StackZone zone(isolate); | 1275 StackZone zone(isolate); |
1276 HandleScope handle_scope(isolate); | 1276 HandleScope handle_scope(thread); |
1277 | 1277 |
1278 // If particular values were requested for this newly spawned isolate, then | 1278 // If particular values were requested for this newly spawned isolate, then |
1279 // they are set here before the isolate starts executing user code. | 1279 // they are set here before the isolate starts executing user code. |
1280 isolate->SetErrorsFatal(state->errors_are_fatal()); | 1280 isolate->SetErrorsFatal(state->errors_are_fatal()); |
1281 if (state->on_exit_port() != ILLEGAL_PORT) { | 1281 if (state->on_exit_port() != ILLEGAL_PORT) { |
1282 const SendPort& listener = | 1282 const SendPort& listener = |
1283 SendPort::Handle(SendPort::New(state->on_exit_port())); | 1283 SendPort::Handle(SendPort::New(state->on_exit_port())); |
1284 isolate->AddExitListener(listener, Instance::null_instance()); | 1284 isolate->AddExitListener(listener, Instance::null_instance()); |
1285 } | 1285 } |
1286 if (state->on_error_port() != ILLEGAL_PORT) { | 1286 if (state->on_error_port() != ILLEGAL_PORT) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1335 | 1335 |
1336 // Instead of directly invoking the entry point we call '_startIsolate' with | 1336 // Instead of directly invoking the entry point we call '_startIsolate' with |
1337 // the entry point as argument. | 1337 // the entry point as argument. |
1338 // Since this function ("RunIsolate") is used for both Isolate.spawn and | 1338 // Since this function ("RunIsolate") is used for both Isolate.spawn and |
1339 // Isolate.spawnUri we also send a boolean flag as argument so that the | 1339 // Isolate.spawnUri we also send a boolean flag as argument so that the |
1340 // "_startIsolate" function can act corresponding to how the isolate was | 1340 // "_startIsolate" function can act corresponding to how the isolate was |
1341 // created. | 1341 // created. |
1342 const Array& args = Array::Handle(Array::New(7)); | 1342 const Array& args = Array::Handle(Array::New(7)); |
1343 args.SetAt(0, SendPort::Handle(SendPort::New(state->parent_port()))); | 1343 args.SetAt(0, SendPort::Handle(SendPort::New(state->parent_port()))); |
1344 args.SetAt(1, Instance::Handle(func.ImplicitStaticClosure())); | 1344 args.SetAt(1, Instance::Handle(func.ImplicitStaticClosure())); |
1345 args.SetAt(2, Instance::Handle(state->BuildArgs(zone.GetZone()))); | 1345 args.SetAt(2, Instance::Handle(state->BuildArgs(thread))); |
1346 args.SetAt(3, Instance::Handle(state->BuildMessage(zone.GetZone()))); | 1346 args.SetAt(3, Instance::Handle(state->BuildMessage(thread))); |
1347 args.SetAt(4, is_spawn_uri ? Bool::True() : Bool::False()); | 1347 args.SetAt(4, is_spawn_uri ? Bool::True() : Bool::False()); |
1348 args.SetAt(5, ReceivePort::Handle( | 1348 args.SetAt(5, ReceivePort::Handle( |
1349 ReceivePort::New(isolate->main_port(), true /* control port */))); | 1349 ReceivePort::New(isolate->main_port(), true /* control port */))); |
1350 args.SetAt(6, capabilities); | 1350 args.SetAt(6, capabilities); |
1351 | 1351 |
1352 const Library& lib = Library::Handle(Library::IsolateLibrary()); | 1352 const Library& lib = Library::Handle(Library::IsolateLibrary()); |
1353 const String& entry_name = String::Handle(String::New("_startIsolate")); | 1353 const String& entry_name = String::Handle(String::New("_startIsolate")); |
1354 const Function& entry_point = | 1354 const Function& entry_point = |
1355 Function::Handle(lib.LookupLocalFunction(entry_name)); | 1355 Function::Handle(lib.LookupLocalFunction(entry_name)); |
1356 ASSERT(entry_point.IsFunction() && !entry_point.IsNull()); | 1356 ASSERT(entry_point.IsFunction() && !entry_point.IsNull()); |
1357 | 1357 |
1358 result = DartEntry::InvokeFunction(entry_point, args); | 1358 result = DartEntry::InvokeFunction(entry_point, args); |
1359 if (result.IsError()) { | 1359 if (result.IsError()) { |
1360 StoreError(isolate, result); | 1360 StoreError(isolate, result); |
1361 return false; | 1361 return false; |
1362 } | 1362 } |
1363 } | 1363 } |
1364 return true; | 1364 return true; |
1365 } | 1365 } |
1366 | 1366 |
1367 | 1367 |
1368 static void ShutdownIsolate(uword parameter) { | 1368 static void ShutdownIsolate(uword parameter) { |
1369 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); | 1369 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); |
1370 { | 1370 { |
1371 // Print the error if there is one. This may execute dart code to | 1371 // 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. | 1372 // print the exception object, so we need to use a StartIsolateScope. |
| 1373 Thread* thread = Thread::Current(); |
1373 StartIsolateScope start_scope(isolate); | 1374 StartIsolateScope start_scope(isolate); |
| 1375 ASSERT(thread->isolate() == isolate); |
1374 StackZone zone(isolate); | 1376 StackZone zone(isolate); |
1375 HandleScope handle_scope(isolate); | 1377 HandleScope handle_scope(thread); |
1376 Error& error = Error::Handle(); | 1378 Error& error = Error::Handle(); |
1377 error = isolate->object_store()->sticky_error(); | 1379 error = isolate->object_store()->sticky_error(); |
1378 if (!error.IsNull() && !error.IsUnwindError()) { | 1380 if (!error.IsNull() && !error.IsUnwindError()) { |
1379 OS::PrintErr("in ShutdownIsolate: %s\n", error.ToErrorCString()); | 1381 OS::PrintErr("in ShutdownIsolate: %s\n", error.ToErrorCString()); |
1380 } | 1382 } |
1381 Dart::RunShutdownCallback(); | 1383 Dart::RunShutdownCallback(); |
1382 } | 1384 } |
1383 { | 1385 { |
1384 // Shut the isolate down. | 1386 // Shut the isolate down. |
1385 SwitchIsolateScope switch_scope(isolate); | 1387 SwitchIsolateScope switch_scope(isolate); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1486 void Isolate::Shutdown() { | 1488 void Isolate::Shutdown() { |
1487 ASSERT(this == Isolate::Current()); | 1489 ASSERT(this == Isolate::Current()); |
1488 ASSERT(top_resource() == NULL); | 1490 ASSERT(top_resource() == NULL); |
1489 #if defined(DEBUG) | 1491 #if defined(DEBUG) |
1490 if (heap_ != NULL) { | 1492 if (heap_ != NULL) { |
1491 // The VM isolate keeps all objects marked. | 1493 // The VM isolate keeps all objects marked. |
1492 heap_->Verify(this == Dart::vm_isolate() ? kRequireMarked : kForbidMarked); | 1494 heap_->Verify(this == Dart::vm_isolate() ? kRequireMarked : kForbidMarked); |
1493 } | 1495 } |
1494 #endif // DEBUG | 1496 #endif // DEBUG |
1495 | 1497 |
| 1498 Thread* thread = Thread::Current(); |
| 1499 |
1496 // First, perform higher-level cleanup that may need to allocate. | 1500 // First, perform higher-level cleanup that may need to allocate. |
1497 { | 1501 { |
1498 // Ensure we have a zone and handle scope so that we can call VM functions. | 1502 // Ensure we have a zone and handle scope so that we can call VM functions. |
1499 StackZone stack_zone(this); | 1503 StackZone stack_zone(this); |
1500 HandleScope handle_scope(this); | 1504 HandleScope handle_scope(thread); |
1501 | 1505 |
1502 // Write out the coverage data if collection has been enabled. | 1506 // Write out the coverage data if collection has been enabled. |
1503 CodeCoverage::Write(this); | 1507 CodeCoverage::Write(this); |
1504 } | 1508 } |
1505 | 1509 |
1506 // Remove this isolate from the list *before* we start tearing it down, to | 1510 // Remove this isolate from the list *before* we start tearing it down, to |
1507 // avoid exposing it in a state of decay. | 1511 // avoid exposing it in a state of decay. |
1508 RemoveIsolateFromList(this); | 1512 RemoveIsolateFromList(this); |
1509 | 1513 |
1510 if (heap_ != NULL) { | 1514 if (heap_ != NULL) { |
1511 // Wait for any concurrent GC tasks to finish before shutting down. | 1515 // Wait for any concurrent GC tasks to finish before shutting down. |
1512 // TODO(koda): Support faster sweeper shutdown (e.g., after current page). | 1516 // TODO(koda): Support faster sweeper shutdown (e.g., after current page). |
1513 PageSpace* old_space = heap_->old_space(); | 1517 PageSpace* old_space = heap_->old_space(); |
1514 MonitorLocker ml(old_space->tasks_lock()); | 1518 MonitorLocker ml(old_space->tasks_lock()); |
1515 while (old_space->tasks() > 0) { | 1519 while (old_space->tasks() > 0) { |
1516 ml.Wait(); | 1520 ml.Wait(); |
1517 } | 1521 } |
1518 } | 1522 } |
1519 | 1523 |
1520 // Then, proceed with low-level teardown. | 1524 // Then, proceed with low-level teardown. |
1521 { | 1525 { |
1522 // Ensure we have a zone and handle scope so that we can call VM functions, | 1526 // Ensure we have a zone and handle scope so that we can call VM functions, |
1523 // but we no longer allocate new heap objects. | 1527 // but we no longer allocate new heap objects. |
1524 StackZone stack_zone(this); | 1528 StackZone stack_zone(this); |
1525 HandleScope handle_scope(this); | 1529 HandleScope handle_scope(thread); |
1526 NoSafepointScope no_safepoint_scope; | 1530 NoSafepointScope no_safepoint_scope; |
1527 | 1531 |
1528 if (compiler_stats_ != NULL) { | 1532 if (compiler_stats_ != NULL) { |
1529 compiler_stats()->Print(); | 1533 compiler_stats()->Print(); |
1530 } | 1534 } |
1531 | 1535 |
1532 // Notify exit listeners that this isolate is shutting down. | 1536 // Notify exit listeners that this isolate is shutting down. |
1533 if (object_store() != NULL) { | 1537 if (object_store() != NULL) { |
1534 NotifyExitListeners(); | 1538 NotifyExitListeners(); |
1535 } | 1539 } |
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2146 | 2150 |
2147 | 2151 |
2148 template<class T> | 2152 template<class T> |
2149 T* Isolate::AllocateReusableHandle() { | 2153 T* Isolate::AllocateReusableHandle() { |
2150 T* handle = reinterpret_cast<T*>(reusable_handles_.AllocateScopedHandle()); | 2154 T* handle = reinterpret_cast<T*>(reusable_handles_.AllocateScopedHandle()); |
2151 T::initializeHandle(handle, T::null()); | 2155 T::initializeHandle(handle, T::null()); |
2152 return handle; | 2156 return handle; |
2153 } | 2157 } |
2154 | 2158 |
2155 | 2159 |
2156 static RawInstance* DeserializeObject(Isolate* isolate, | 2160 static RawInstance* DeserializeObject(Thread* thread, |
2157 Zone* zone, | |
2158 uint8_t* obj_data, | 2161 uint8_t* obj_data, |
2159 intptr_t obj_len) { | 2162 intptr_t obj_len) { |
2160 if (obj_data == NULL) { | 2163 if (obj_data == NULL) { |
2161 return Instance::null(); | 2164 return Instance::null(); |
2162 } | 2165 } |
2163 MessageSnapshotReader reader(obj_data, | 2166 MessageSnapshotReader reader(obj_data, obj_len, thread); |
2164 obj_len, | 2167 Zone* zone = thread->zone(); |
2165 isolate, | 2168 const Object& obj = Object::Handle(zone, reader.ReadObject()); |
2166 zone); | |
2167 const Object& obj = Object::Handle(isolate, reader.ReadObject()); | |
2168 ASSERT(!obj.IsError()); | 2169 ASSERT(!obj.IsError()); |
2169 Instance& instance = Instance::Handle(isolate); | 2170 Instance& instance = Instance::Handle(zone); |
2170 instance ^= obj.raw(); // Can't use Instance::Cast because may be null. | 2171 instance ^= obj.raw(); // Can't use Instance::Cast because may be null. |
2171 return instance.raw(); | 2172 return instance.raw(); |
2172 } | 2173 } |
2173 | 2174 |
2174 | 2175 |
2175 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port, | 2176 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port, |
2176 const Function& func, | 2177 const Function& func, |
2177 const Instance& message, | 2178 const Instance& message, |
2178 bool paused, | 2179 bool paused, |
2179 bool errors_are_fatal, | 2180 bool errors_are_fatal, |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2334 const String& msg = String::Handle(String::NewFormatted( | 2335 const String& msg = String::Handle(String::NewFormatted( |
2335 "Unable to resolve static method '%s.%s' in library '%s'.", | 2336 "Unable to resolve static method '%s.%s' in library '%s'.", |
2336 class_name(), function_name(), | 2337 class_name(), function_name(), |
2337 (library_url() != NULL ? library_url() : script_url()))); | 2338 (library_url() != NULL ? library_url() : script_url()))); |
2338 return LanguageError::New(msg); | 2339 return LanguageError::New(msg); |
2339 } | 2340 } |
2340 return func.raw(); | 2341 return func.raw(); |
2341 } | 2342 } |
2342 | 2343 |
2343 | 2344 |
2344 RawInstance* IsolateSpawnState::BuildArgs(Zone* zone) { | 2345 RawInstance* IsolateSpawnState::BuildArgs(Thread* thread) { |
2345 return DeserializeObject(isolate_, zone, | 2346 return DeserializeObject(thread, serialized_args_, serialized_args_len_); |
2346 serialized_args_, serialized_args_len_); | |
2347 } | 2347 } |
2348 | 2348 |
2349 | 2349 |
2350 RawInstance* IsolateSpawnState::BuildMessage(Zone* zone) { | 2350 RawInstance* IsolateSpawnState::BuildMessage(Thread* thread) { |
2351 return DeserializeObject(isolate_, zone, | 2351 return DeserializeObject(thread, |
2352 serialized_message_, serialized_message_len_); | 2352 serialized_message_, serialized_message_len_); |
2353 } | 2353 } |
2354 | 2354 |
2355 | 2355 |
2356 void IsolateSpawnState::Cleanup() { | 2356 void IsolateSpawnState::Cleanup() { |
2357 SwitchIsolateScope switch_scope(I); | 2357 SwitchIsolateScope switch_scope(I); |
2358 Dart::ShutdownIsolate(); | 2358 Dart::ShutdownIsolate(); |
2359 } | 2359 } |
2360 | 2360 |
2361 } // namespace dart | 2361 } // namespace dart |
OLD | NEW |