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