| 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 "include/dart_native_api.h" | 8 #include "include/dart_native_api.h" |
| 9 #include "platform/assert.h" | 9 #include "platform/assert.h" |
| 10 #include "platform/text_buffer.h" | 10 #include "platform/text_buffer.h" |
| (...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 ASSERT(IsCurrentIsolate()); | 614 ASSERT(IsCurrentIsolate()); |
| 615 } | 615 } |
| 616 #endif | 616 #endif |
| 617 | 617 |
| 618 | 618 |
| 619 bool IsolateMessageHandler::IsCurrentIsolate() const { | 619 bool IsolateMessageHandler::IsCurrentIsolate() const { |
| 620 return (I == Isolate::Current()); | 620 return (I == Isolate::Current()); |
| 621 } | 621 } |
| 622 | 622 |
| 623 | 623 |
| 624 static MessageHandler::MessageStatus StoreError(Isolate* isolate, | 624 static MessageHandler::MessageStatus StoreError(Thread* thread, |
| 625 const Error& error) { | 625 const Error& error) { |
| 626 isolate->object_store()->set_sticky_error(error); | 626 thread->set_sticky_error(error); |
| 627 if (error.IsUnwindError()) { | 627 if (error.IsUnwindError()) { |
| 628 const UnwindError& unwind = UnwindError::Cast(error); | 628 const UnwindError& unwind = UnwindError::Cast(error); |
| 629 if (!unwind.is_user_initiated()) { | 629 if (!unwind.is_user_initiated()) { |
| 630 if (unwind.is_vm_restart()) { | 630 if (unwind.is_vm_restart()) { |
| 631 return MessageHandler::kRestart; | 631 return MessageHandler::kRestart; |
| 632 } else { | 632 } else { |
| 633 return MessageHandler::kShutdown; | 633 return MessageHandler::kShutdown; |
| 634 } | 634 } |
| 635 } | 635 } |
| 636 } | 636 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 673 if (!tmp.IsString()) { | 673 if (!tmp.IsString()) { |
| 674 tmp = String::New(stacktrace.ToCString()); | 674 tmp = String::New(stacktrace.ToCString()); |
| 675 } | 675 } |
| 676 stacktrace_str ^= tmp.raw();; | 676 stacktrace_str ^= tmp.raw();; |
| 677 } else { | 677 } else { |
| 678 exc_str = String::New(result.ToErrorCString()); | 678 exc_str = String::New(result.ToErrorCString()); |
| 679 } | 679 } |
| 680 if (result.IsUnwindError()) { | 680 if (result.IsUnwindError()) { |
| 681 // When unwinding we don't notify error listeners and we ignore | 681 // When unwinding we don't notify error listeners and we ignore |
| 682 // whether errors are fatal for the current isolate. | 682 // whether errors are fatal for the current isolate. |
| 683 return StoreError(I, result); | 683 return StoreError(T, result); |
| 684 } else { | 684 } else { |
| 685 bool has_listener = I->NotifyErrorListeners(exc_str, stacktrace_str); | 685 bool has_listener = I->NotifyErrorListeners(exc_str, stacktrace_str); |
| 686 if (I->ErrorsFatal()) { | 686 if (I->ErrorsFatal()) { |
| 687 if (has_listener) { | 687 if (has_listener) { |
| 688 I->object_store()->clear_sticky_error(); | 688 T->clear_sticky_error(); |
| 689 } else { | 689 } else { |
| 690 I->object_store()->set_sticky_error(result); | 690 T->set_sticky_error(result); |
| 691 } | 691 } |
| 692 return kError; | 692 return kError; |
| 693 } | 693 } |
| 694 } | 694 } |
| 695 return kOK; | 695 return kOK; |
| 696 } | 696 } |
| 697 | 697 |
| 698 | 698 |
| 699 Isolate::Flags::Flags() | 699 Isolate::Flags::Flags() |
| 700 : type_checks_(FLAG_enable_type_checks), | 700 : type_checks_(FLAG_enable_type_checks), |
| (...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1347 SendPort::Handle(SendPort::New(state->on_error_port())); | 1347 SendPort::Handle(SendPort::New(state->on_error_port())); |
| 1348 isolate->AddErrorListener(listener); | 1348 isolate->AddErrorListener(listener); |
| 1349 } | 1349 } |
| 1350 | 1350 |
| 1351 // Switch back to spawning isolate. | 1351 // Switch back to spawning isolate. |
| 1352 | 1352 |
| 1353 | 1353 |
| 1354 if (!ClassFinalizer::ProcessPendingClasses()) { | 1354 if (!ClassFinalizer::ProcessPendingClasses()) { |
| 1355 // Error is in sticky error already. | 1355 // Error is in sticky error already. |
| 1356 #if defined(DEBUG) | 1356 #if defined(DEBUG) |
| 1357 const Error& error = | 1357 const Error& error = Error::Handle(thread->sticky_error()); |
| 1358 Error::Handle(isolate->object_store()->sticky_error()); | |
| 1359 ASSERT(!error.IsUnwindError()); | 1358 ASSERT(!error.IsUnwindError()); |
| 1360 #endif | 1359 #endif |
| 1361 return MessageHandler::kError; | 1360 return MessageHandler::kError; |
| 1362 } | 1361 } |
| 1363 | 1362 |
| 1364 Object& result = Object::Handle(); | 1363 Object& result = Object::Handle(); |
| 1365 result = state->ResolveFunction(); | 1364 result = state->ResolveFunction(); |
| 1366 bool is_spawn_uri = state->is_spawn_uri(); | 1365 bool is_spawn_uri = state->is_spawn_uri(); |
| 1367 if (result.IsError()) { | 1366 if (result.IsError()) { |
| 1368 return StoreError(isolate, Error::Cast(result)); | 1367 return StoreError(thread, Error::Cast(result)); |
| 1369 } | 1368 } |
| 1370 ASSERT(result.IsFunction()); | 1369 ASSERT(result.IsFunction()); |
| 1371 Function& func = Function::Handle(thread->zone()); | 1370 Function& func = Function::Handle(thread->zone()); |
| 1372 func ^= result.raw(); | 1371 func ^= result.raw(); |
| 1373 | 1372 |
| 1374 // TODO(turnidge): Currently we need a way to force a one-time | 1373 // TODO(turnidge): Currently we need a way to force a one-time |
| 1375 // breakpoint for all spawned isolates to support isolate | 1374 // breakpoint for all spawned isolates to support isolate |
| 1376 // debugging. Remove this once the vmservice becomes the standard | 1375 // debugging. Remove this once the vmservice becomes the standard |
| 1377 // way to debug. Set the breakpoint on the static function instead | 1376 // way to debug. Set the breakpoint on the static function instead |
| 1378 // of its implicit closure function because that latter is merely | 1377 // of its implicit closure function because that latter is merely |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1413 args.SetAt(6, capabilities); | 1412 args.SetAt(6, capabilities); |
| 1414 | 1413 |
| 1415 const Library& lib = Library::Handle(Library::IsolateLibrary()); | 1414 const Library& lib = Library::Handle(Library::IsolateLibrary()); |
| 1416 const String& entry_name = String::Handle(String::New("_startIsolate")); | 1415 const String& entry_name = String::Handle(String::New("_startIsolate")); |
| 1417 const Function& entry_point = | 1416 const Function& entry_point = |
| 1418 Function::Handle(lib.LookupLocalFunction(entry_name)); | 1417 Function::Handle(lib.LookupLocalFunction(entry_name)); |
| 1419 ASSERT(entry_point.IsFunction() && !entry_point.IsNull()); | 1418 ASSERT(entry_point.IsFunction() && !entry_point.IsNull()); |
| 1420 | 1419 |
| 1421 result = DartEntry::InvokeFunction(entry_point, args); | 1420 result = DartEntry::InvokeFunction(entry_point, args); |
| 1422 if (result.IsError()) { | 1421 if (result.IsError()) { |
| 1423 return StoreError(isolate, Error::Cast(result)); | 1422 return StoreError(thread, Error::Cast(result)); |
| 1424 } | 1423 } |
| 1425 } | 1424 } |
| 1426 return MessageHandler::kOK; | 1425 return MessageHandler::kOK; |
| 1427 } | 1426 } |
| 1428 | 1427 |
| 1429 | 1428 |
| 1430 static void ShutdownIsolate(uword parameter) { | 1429 static void ShutdownIsolate(uword parameter) { |
| 1431 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); | 1430 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); |
| 1432 // We must wait for any outstanding spawn calls to complete before | 1431 // We must wait for any outstanding spawn calls to complete before |
| 1433 // running the shutdown callback. | 1432 // running the shutdown callback. |
| 1434 isolate->WaitForOutstandingSpawns(); | 1433 isolate->WaitForOutstandingSpawns(); |
| 1435 { | 1434 { |
| 1436 // Print the error if there is one. This may execute dart code to | 1435 // Print the error if there is one. This may execute dart code to |
| 1437 // print the exception object, so we need to use a StartIsolateScope. | 1436 // print the exception object, so we need to use a StartIsolateScope. |
| 1438 StartIsolateScope start_scope(isolate); | 1437 StartIsolateScope start_scope(isolate); |
| 1439 Thread* thread = Thread::Current(); | 1438 Thread* thread = Thread::Current(); |
| 1440 ASSERT(thread->isolate() == isolate); | 1439 ASSERT(thread->isolate() == isolate); |
| 1441 StackZone zone(thread); | 1440 StackZone zone(thread); |
| 1442 HandleScope handle_scope(thread); | 1441 HandleScope handle_scope(thread); |
| 1443 const Error& error = Error::Handle(isolate->object_store()->sticky_error()); | 1442 const Error& error = Error::Handle(thread->sticky_error()); |
| 1444 if (!error.IsNull() && !error.IsUnwindError()) { | 1443 if (!error.IsNull() && !error.IsUnwindError()) { |
| 1445 OS::PrintErr("in ShutdownIsolate: %s\n", error.ToErrorCString()); | 1444 OS::PrintErr("in ShutdownIsolate: %s\n", error.ToErrorCString()); |
| 1446 } | 1445 } |
| 1447 Dart::RunShutdownCallback(); | 1446 Dart::RunShutdownCallback(); |
| 1448 } | 1447 } |
| 1449 // Shut the isolate down. | 1448 // Shut the isolate down. |
| 1450 Dart::ShutdownIsolate(isolate); | 1449 Dart::ShutdownIsolate(isolate); |
| 1451 } | 1450 } |
| 1452 | 1451 |
| 1453 | 1452 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1483 if ((interrupt_bits & kMessageInterrupt) != 0) { | 1482 if ((interrupt_bits & kMessageInterrupt) != 0) { |
| 1484 MessageHandler::MessageStatus status = | 1483 MessageHandler::MessageStatus status = |
| 1485 message_handler()->HandleOOBMessages(); | 1484 message_handler()->HandleOOBMessages(); |
| 1486 if (status != MessageHandler::kOK) { | 1485 if (status != MessageHandler::kOK) { |
| 1487 // False result from HandleOOBMessages signals that the isolate should | 1486 // False result from HandleOOBMessages signals that the isolate should |
| 1488 // be terminating. | 1487 // be terminating. |
| 1489 if (FLAG_trace_isolates) { | 1488 if (FLAG_trace_isolates) { |
| 1490 OS::Print("[!] Terminating isolate due to OOB message:\n" | 1489 OS::Print("[!] Terminating isolate due to OOB message:\n" |
| 1491 "\tisolate: %s\n", name()); | 1490 "\tisolate: %s\n", name()); |
| 1492 } | 1491 } |
| 1493 const Error& error = Error::Handle(object_store()->sticky_error()); | 1492 Thread* thread = Thread::Current(); |
| 1493 const Error& error = Error::Handle(thread->sticky_error()); |
| 1494 ASSERT(!error.IsNull() && error.IsUnwindError()); | 1494 ASSERT(!error.IsNull() && error.IsUnwindError()); |
| 1495 object_store()->clear_sticky_error(); | 1495 thread->clear_sticky_error(); |
| 1496 return error.raw(); | 1496 return error.raw(); |
| 1497 } | 1497 } |
| 1498 } | 1498 } |
| 1499 return Error::null(); | 1499 return Error::null(); |
| 1500 } | 1500 } |
| 1501 | 1501 |
| 1502 | 1502 |
| 1503 uword Isolate::GetAndClearStackOverflowFlags() { | 1503 uword Isolate::GetAndClearStackOverflowFlags() { |
| 1504 uword stack_overflow_flags = stack_overflow_flags_; | 1504 uword stack_overflow_flags = stack_overflow_flags_; |
| 1505 stack_overflow_flags_ = 0; | 1505 stack_overflow_flags_ = 0; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1582 void Isolate::LowLevelShutdown() { | 1582 void Isolate::LowLevelShutdown() { |
| 1583 // Ensure we have a zone and handle scope so that we can call VM functions, | 1583 // Ensure we have a zone and handle scope so that we can call VM functions, |
| 1584 // but we no longer allocate new heap objects. | 1584 // but we no longer allocate new heap objects. |
| 1585 Thread* thread = Thread::Current(); | 1585 Thread* thread = Thread::Current(); |
| 1586 StackZone stack_zone(thread); | 1586 StackZone stack_zone(thread); |
| 1587 HandleScope handle_scope(thread); | 1587 HandleScope handle_scope(thread); |
| 1588 NoSafepointScope no_safepoint_scope; | 1588 NoSafepointScope no_safepoint_scope; |
| 1589 | 1589 |
| 1590 // Notify exit listeners that this isolate is shutting down. | 1590 // Notify exit listeners that this isolate is shutting down. |
| 1591 if (object_store() != NULL) { | 1591 if (object_store() != NULL) { |
| 1592 const Error& error = Error::Handle(object_store()->sticky_error()); | 1592 const Error& error = Error::Handle(thread->sticky_error()); |
| 1593 if (error.IsNull() || | 1593 if (error.IsNull() || |
| 1594 !error.IsUnwindError() || | 1594 !error.IsUnwindError() || |
| 1595 UnwindError::Cast(error).is_user_initiated()) { | 1595 UnwindError::Cast(error).is_user_initiated()) { |
| 1596 NotifyExitListeners(); | 1596 NotifyExitListeners(); |
| 1597 } | 1597 } |
| 1598 } | 1598 } |
| 1599 | 1599 |
| 1600 // Clean up debugger resources. | 1600 // Clean up debugger resources. |
| 1601 if (FLAG_support_debugger) { | 1601 if (FLAG_support_debugger) { |
| 1602 debugger()->Shutdown(); | 1602 debugger()->Shutdown(); |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1874 const Library& lib = | 1874 const Library& lib = |
| 1875 Library::Handle(object_store()->root_library()); | 1875 Library::Handle(object_store()->root_library()); |
| 1876 if (!lib.IsNull()) { | 1876 if (!lib.IsNull()) { |
| 1877 jsobj.AddProperty("rootLib", lib); | 1877 jsobj.AddProperty("rootLib", lib); |
| 1878 } | 1878 } |
| 1879 | 1879 |
| 1880 { | 1880 { |
| 1881 JSONObject tagCounters(&jsobj, "_tagCounters"); | 1881 JSONObject tagCounters(&jsobj, "_tagCounters"); |
| 1882 vm_tag_counters()->PrintToJSONObject(&tagCounters); | 1882 vm_tag_counters()->PrintToJSONObject(&tagCounters); |
| 1883 } | 1883 } |
| 1884 if (object_store()->sticky_error() != Object::null()) { | 1884 if (Thread::Current()->sticky_error() != Object::null()) { |
| 1885 Error& error = Error::Handle(object_store()->sticky_error()); | 1885 Error& error = Error::Handle(Thread::Current()->sticky_error()); |
| 1886 ASSERT(!error.IsNull()); | 1886 ASSERT(!error.IsNull()); |
| 1887 jsobj.AddProperty("error", error, false); | 1887 jsobj.AddProperty("error", error, false); |
| 1888 } | 1888 } |
| 1889 | 1889 |
| 1890 { | 1890 { |
| 1891 const GrowableObjectArray& libs = | 1891 const GrowableObjectArray& libs = |
| 1892 GrowableObjectArray::Handle(object_store()->libraries()); | 1892 GrowableObjectArray::Handle(object_store()->libraries()); |
| 1893 intptr_t num_libs = libs.Length(); | 1893 intptr_t num_libs = libs.Length(); |
| 1894 Library& lib = Library::Handle(); | 1894 Library& lib = Library::Handle(); |
| 1895 | 1895 |
| (...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2667 void IsolateSpawnState::DecrementSpawnCount() { | 2667 void IsolateSpawnState::DecrementSpawnCount() { |
| 2668 ASSERT(spawn_count_monitor_ != NULL); | 2668 ASSERT(spawn_count_monitor_ != NULL); |
| 2669 ASSERT(spawn_count_ != NULL); | 2669 ASSERT(spawn_count_ != NULL); |
| 2670 MonitorLocker ml(spawn_count_monitor_); | 2670 MonitorLocker ml(spawn_count_monitor_); |
| 2671 ASSERT(*spawn_count_ > 0); | 2671 ASSERT(*spawn_count_ > 0); |
| 2672 *spawn_count_ = *spawn_count_ - 1; | 2672 *spawn_count_ = *spawn_count_ - 1; |
| 2673 ml.Notify(); | 2673 ml.Notify(); |
| 2674 } | 2674 } |
| 2675 | 2675 |
| 2676 } // namespace dart | 2676 } // namespace dart |
| OLD | NEW |