Chromium Code Reviews| 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 "platform/assert.h" | 9 #include "platform/assert.h" |
| 9 #include "platform/json.h" | 10 #include "platform/json.h" |
| 10 #include "vm/code_observers.h" | 11 #include "vm/code_observers.h" |
| 11 #include "vm/compiler_stats.h" | 12 #include "vm/compiler_stats.h" |
| 12 #include "vm/coverage.h" | 13 #include "vm/coverage.h" |
| 14 #include "vm/dart_api_message.h" | |
| 13 #include "vm/dart_api_state.h" | 15 #include "vm/dart_api_state.h" |
| 14 #include "vm/dart_entry.h" | 16 #include "vm/dart_entry.h" |
| 15 #include "vm/debugger.h" | 17 #include "vm/debugger.h" |
| 16 #include "vm/deopt_instructions.h" | 18 #include "vm/deopt_instructions.h" |
| 17 #include "vm/heap.h" | 19 #include "vm/heap.h" |
| 18 #include "vm/lockers.h" | 20 #include "vm/lockers.h" |
| 19 #include "vm/log.h" | 21 #include "vm/log.h" |
| 20 #include "vm/message_handler.h" | 22 #include "vm/message_handler.h" |
| 21 #include "vm/object_id_ring.h" | 23 #include "vm/object_id_ring.h" |
| 22 #include "vm/object_store.h" | 24 #include "vm/object_store.h" |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 158 void NotifyPauseOnStart(); | 160 void NotifyPauseOnStart(); |
| 159 void NotifyPauseOnExit(); | 161 void NotifyPauseOnExit(); |
| 160 | 162 |
| 161 #if defined(DEBUG) | 163 #if defined(DEBUG) |
| 162 // Check that it is safe to access this handler. | 164 // Check that it is safe to access this handler. |
| 163 void CheckAccess(); | 165 void CheckAccess(); |
| 164 #endif | 166 #endif |
| 165 bool IsCurrentIsolate() const; | 167 bool IsCurrentIsolate() const; |
| 166 virtual Isolate* isolate() const { return isolate_; } | 168 virtual Isolate* isolate() const { return isolate_; } |
| 167 | 169 |
| 168 private: | |
| 169 // Keep both these enums in sync with isolate_patch.dart. | 170 // Keep both these enums in sync with isolate_patch.dart. |
| 170 // The different Isolate API message types. | 171 // The different Isolate API message types. |
| 171 enum { | 172 enum { |
| 172 kPauseMsg = 1, | 173 kPauseMsg = 1, |
| 173 kResumeMsg = 2, | 174 kResumeMsg = 2, |
| 174 kPingMsg = 3, | 175 kPingMsg = 3, |
| 175 kKillMsg = 4, | 176 kKillMsg = 4, |
| 176 kAddExitMsg = 5, | 177 kAddExitMsg = 5, |
| 177 kDelExitMsg = 6, | 178 kDelExitMsg = 6, |
| 178 kAddErrorMsg = 7, | 179 kAddErrorMsg = 7, |
| 179 kDelErrorMsg = 8, | 180 kDelErrorMsg = 8, |
| 180 kErrorFatalMsg = 9, | 181 kErrorFatalMsg = 9, |
| 181 }; | 182 }; |
| 182 // The different Isolate API message priorities for ping and kill messages. | 183 // The different Isolate API message priorities for ping and kill messages. |
| 183 enum { | 184 enum { |
| 184 kImmediateAction = 0, | 185 kImmediateAction = 0, |
| 185 kBeforeNextEventAction = 1, | 186 kBeforeNextEventAction = 1, |
| 186 kAsEventAction = 2 | 187 kAsEventAction = 2 |
| 187 }; | 188 }; |
| 188 | 189 |
| 190 private: | |
| 189 // A result of false indicates that the isolate should terminate the | 191 // A result of false indicates that the isolate should terminate the |
| 190 // processing of further events. | 192 // processing of further events. |
| 191 bool HandleLibMessage(const Array& message); | 193 bool HandleLibMessage(const Array& message); |
| 192 | 194 |
| 193 bool ProcessUnhandledException(const Error& result); | 195 bool ProcessUnhandledException(const Error& result); |
| 194 Isolate* isolate_; | 196 Isolate* isolate_; |
| 195 }; | 197 }; |
| 196 | 198 |
| 197 | 199 |
| 198 IsolateMessageHandler::IsolateMessageHandler(Isolate* isolate) | 200 IsolateMessageHandler::IsolateMessageHandler(Isolate* isolate) |
| (...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 761 bool Isolate::IsIsolateOf(Thread* thread) { | 763 bool Isolate::IsIsolateOf(Thread* thread) { |
| 762 return this == thread->isolate(); | 764 return this == thread->isolate(); |
| 763 } | 765 } |
| 764 #endif // DEBUG | 766 #endif // DEBUG |
| 765 | 767 |
| 766 | 768 |
| 767 void Isolate::InitOnce() { | 769 void Isolate::InitOnce() { |
| 768 create_callback_ = NULL; | 770 create_callback_ = NULL; |
| 769 isolates_list_monitor_ = new Monitor(); | 771 isolates_list_monitor_ = new Monitor(); |
| 770 ASSERT(isolates_list_monitor_ != NULL); | 772 ASSERT(isolates_list_monitor_ != NULL); |
| 773 EnableIsolateCreation(); | |
| 771 } | 774 } |
| 772 | 775 |
| 773 | 776 |
| 774 Isolate* Isolate::Init(const char* name_prefix, | 777 Isolate* Isolate::Init(const char* name_prefix, |
| 775 const Dart_IsolateFlags& api_flags, | 778 const Dart_IsolateFlags& api_flags, |
| 776 bool is_vm_isolate) { | 779 bool is_vm_isolate) { |
| 777 Isolate* result = new Isolate(api_flags); | 780 Isolate* result = new Isolate(api_flags); |
| 778 ASSERT(result != NULL); | 781 ASSERT(result != NULL); |
| 779 | 782 |
| 780 // Initialize metrics. | 783 // Initialize metrics. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 839 if (FLAG_trace_isolates) { | 842 if (FLAG_trace_isolates) { |
| 840 if (name_prefix == NULL || strcmp(name_prefix, "vm-isolate") != 0) { | 843 if (name_prefix == NULL || strcmp(name_prefix, "vm-isolate") != 0) { |
| 841 OS::Print("[+] Starting isolate:\n" | 844 OS::Print("[+] Starting isolate:\n" |
| 842 "\tisolate: %s\n", result->name()); | 845 "\tisolate: %s\n", result->name()); |
| 843 } | 846 } |
| 844 } | 847 } |
| 845 if (FLAG_compiler_stats) { | 848 if (FLAG_compiler_stats) { |
| 846 result->compiler_stats_ = new CompilerStats(result); | 849 result->compiler_stats_ = new CompilerStats(result); |
| 847 } | 850 } |
| 848 ObjectIdRing::Init(result); | 851 ObjectIdRing::Init(result); |
| 849 // Add to isolate list. | 852 |
| 850 AddIsolateTolist(result); | 853 // Add to isolate list. Shutdown and delete the isolate on failure. |
| 854 if (!AddIsolateToList(result)) { | |
| 855 result->LowLevelShutdown(); | |
| 856 Thread::ExitIsolate(); | |
| 857 delete result; | |
| 858 return NULL; | |
| 859 } | |
| 851 | 860 |
| 852 return result; | 861 return result; |
| 853 } | 862 } |
| 854 | 863 |
| 855 | 864 |
| 856 void Isolate::InitializeStackLimit() { | 865 void Isolate::InitializeStackLimit() { |
| 857 SetStackLimitFromStackBase(Isolate::GetCurrentStackPointer()); | 866 SetStackLimitFromStackBase(Isolate::GetCurrentStackPointer()); |
| 858 } | 867 } |
| 859 | 868 |
| 860 | 869 |
| (...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1455 FinalizablePersistentHandle* handle = | 1464 FinalizablePersistentHandle* handle = |
| 1456 reinterpret_cast<FinalizablePersistentHandle*>(addr); | 1465 reinterpret_cast<FinalizablePersistentHandle*>(addr); |
| 1457 handle->UpdateUnreachable(I); | 1466 handle->UpdateUnreachable(I); |
| 1458 } | 1467 } |
| 1459 | 1468 |
| 1460 private: | 1469 private: |
| 1461 DISALLOW_COPY_AND_ASSIGN(FinalizeWeakPersistentHandlesVisitor); | 1470 DISALLOW_COPY_AND_ASSIGN(FinalizeWeakPersistentHandlesVisitor); |
| 1462 }; | 1471 }; |
| 1463 | 1472 |
| 1464 | 1473 |
| 1474 void Isolate::LowLevelShutdown() { | |
| 1475 // Ensure we have a zone and handle scope so that we can call VM functions, | |
| 1476 // but we no longer allocate new heap objects. | |
| 1477 Thread* thread = Thread::Current(); | |
| 1478 StackZone stack_zone(thread); | |
| 1479 HandleScope handle_scope(thread); | |
| 1480 NoSafepointScope no_safepoint_scope; | |
| 1481 | |
| 1482 if (compiler_stats_ != NULL) { | |
| 1483 OS::Print("%s", compiler_stats()->PrintToZone()); | |
| 1484 } | |
| 1485 | |
| 1486 // Notify exit listeners that this isolate is shutting down. | |
| 1487 if (object_store() != NULL) { | |
| 1488 NotifyExitListeners(); | |
| 1489 } | |
| 1490 | |
| 1491 // Clean up debugger resources. | |
| 1492 debugger()->Shutdown(); | |
| 1493 | |
| 1494 // Close all the ports owned by this isolate. | |
| 1495 PortMap::ClosePorts(message_handler()); | |
| 1496 | |
| 1497 // Fail fast if anybody tries to post any more messsages to this isolate. | |
| 1498 delete message_handler(); | |
| 1499 set_message_handler(NULL); | |
| 1500 | |
| 1501 // Dump all accumulated timer data for the isolate. | |
| 1502 timer_list_.ReportTimers(); | |
| 1503 | |
| 1504 // Before analyzing the isolate's timeline blocks- close all of them. | |
| 1505 CloseAllTimelineBlocks(); | |
| 1506 | |
| 1507 // Dump all timing data for the isolate. | |
| 1508 if (FLAG_timing) { | |
| 1509 TimelinePauseTrace tpt; | |
| 1510 tpt.Print(); | |
| 1511 } | |
| 1512 | |
| 1513 // Finalize any weak persistent handles with a non-null referent. | |
| 1514 FinalizeWeakPersistentHandlesVisitor visitor; | |
| 1515 api_state()->weak_persistent_handles().VisitHandles(&visitor); | |
| 1516 api_state()->prologue_weak_persistent_handles().VisitHandles(&visitor); | |
| 1517 | |
| 1518 if (FLAG_trace_isolates) { | |
| 1519 heap()->PrintSizes(); | |
| 1520 megamorphic_cache_table()->PrintSizes(); | |
| 1521 Symbols::DumpStats(); | |
| 1522 OS::Print("[-] Stopping isolate:\n" | |
| 1523 "\tisolate: %s\n", name()); | |
| 1524 } | |
| 1525 if (FLAG_print_metrics) { | |
| 1526 LogBlock lb; | |
| 1527 THR_Print("Printing metrics for %s\n", name()); | |
| 1528 #define ISOLATE_METRIC_PRINT(type, variable, name, unit) \ | |
| 1529 THR_Print("%s\n", metric_##variable##_.ToString()); | |
| 1530 ISOLATE_METRIC_LIST(ISOLATE_METRIC_PRINT); | |
|
turnidge
2015/09/15 16:48:22
ISOLATE_METRIC_LIST tabbed in by 2 more here since
| |
| 1531 #undef ISOLATE_METRIC_PRINT | |
| 1532 THR_Print("\n"); | |
| 1533 } | |
| 1534 } | |
| 1535 | |
| 1536 | |
| 1465 void Isolate::Shutdown() { | 1537 void Isolate::Shutdown() { |
| 1466 ASSERT(this == Isolate::Current()); | 1538 ASSERT(this == Isolate::Current()); |
| 1467 ASSERT(top_resource() == NULL); | 1539 ASSERT(top_resource() == NULL); |
| 1468 #if defined(DEBUG) | 1540 #if defined(DEBUG) |
| 1469 if (heap_ != NULL) { | 1541 if (heap_ != NULL) { |
| 1470 // The VM isolate keeps all objects marked. | 1542 // The VM isolate keeps all objects marked. |
| 1471 heap_->Verify(this == Dart::vm_isolate() ? kRequireMarked : kForbidMarked); | 1543 heap_->Verify(this == Dart::vm_isolate() ? kRequireMarked : kForbidMarked); |
| 1472 } | 1544 } |
| 1473 #endif // DEBUG | 1545 #endif // DEBUG |
| 1474 | 1546 |
| 1475 Thread* thread = Thread::Current(); | 1547 Thread* thread = Thread::Current(); |
| 1476 | 1548 |
| 1477 // First, perform higher-level cleanup that may need to allocate. | 1549 // First, perform higher-level cleanup that may need to allocate. |
| 1478 { | 1550 { |
| 1479 // Ensure we have a zone and handle scope so that we can call VM functions. | 1551 // Ensure we have a zone and handle scope so that we can call VM functions. |
| 1480 StackZone stack_zone(thread); | 1552 StackZone stack_zone(thread); |
| 1481 HandleScope handle_scope(thread); | 1553 HandleScope handle_scope(thread); |
| 1482 | 1554 |
| 1483 // Write out the coverage data if collection has been enabled. | 1555 // Write out the coverage data if collection has been enabled. |
| 1484 CodeCoverage::Write(this); | 1556 if ((this != Dart::vm_isolate()) && |
| 1557 !ServiceIsolate::IsServiceIsolateDescendant(this)) { | |
| 1558 CodeCoverage::Write(this); | |
| 1559 } | |
| 1485 } | 1560 } |
| 1486 | 1561 |
| 1487 // Remove this isolate from the list *before* we start tearing it down, to | 1562 // Remove this isolate from the list *before* we start tearing it down, to |
| 1488 // avoid exposing it in a state of decay. | 1563 // avoid exposing it in a state of decay. |
| 1489 RemoveIsolateFromList(this); | 1564 RemoveIsolateFromList(this); |
| 1490 | 1565 |
| 1491 if (heap_ != NULL) { | 1566 if (heap_ != NULL) { |
| 1492 // Wait for any concurrent GC tasks to finish before shutting down. | 1567 // Wait for any concurrent GC tasks to finish before shutting down. |
| 1493 // TODO(koda): Support faster sweeper shutdown (e.g., after current page). | 1568 // TODO(koda): Support faster sweeper shutdown (e.g., after current page). |
| 1494 PageSpace* old_space = heap_->old_space(); | 1569 PageSpace* old_space = heap_->old_space(); |
| 1495 MonitorLocker ml(old_space->tasks_lock()); | 1570 MonitorLocker ml(old_space->tasks_lock()); |
| 1496 while (old_space->tasks() > 0) { | 1571 while (old_space->tasks() > 0) { |
| 1497 ml.Wait(); | 1572 ml.Wait(); |
| 1498 } | 1573 } |
| 1499 } | 1574 } |
| 1500 | 1575 |
| 1501 // Then, proceed with low-level teardown. | 1576 // Then, proceed with low-level teardown. |
| 1502 { | 1577 LowLevelShutdown(); |
| 1503 // Ensure we have a zone and handle scope so that we can call VM functions, | |
| 1504 // but we no longer allocate new heap objects. | |
| 1505 StackZone stack_zone(thread); | |
| 1506 HandleScope handle_scope(thread); | |
| 1507 NoSafepointScope no_safepoint_scope; | |
| 1508 | |
| 1509 if (compiler_stats_ != NULL) { | |
| 1510 OS::Print("%s", compiler_stats()->PrintToZone()); | |
| 1511 } | |
| 1512 | |
| 1513 // Notify exit listeners that this isolate is shutting down. | |
| 1514 if (object_store() != NULL) { | |
| 1515 NotifyExitListeners(); | |
| 1516 } | |
| 1517 | |
| 1518 // Clean up debugger resources. | |
| 1519 debugger()->Shutdown(); | |
| 1520 | |
| 1521 // Close all the ports owned by this isolate. | |
| 1522 PortMap::ClosePorts(message_handler()); | |
| 1523 | |
| 1524 // Fail fast if anybody tries to post any more messsages to this isolate. | |
| 1525 delete message_handler(); | |
| 1526 set_message_handler(NULL); | |
| 1527 | |
| 1528 // Dump all accumulated timer data for the isolate. | |
| 1529 timer_list_.ReportTimers(); | |
| 1530 | |
| 1531 // Before analyzing the isolate's timeline blocks- close all of them. | |
| 1532 CloseAllTimelineBlocks(); | |
| 1533 | |
| 1534 // Dump all timing data for the isolate. | |
| 1535 if (FLAG_timing) { | |
| 1536 TimelinePauseTrace tpt; | |
| 1537 tpt.Print(); | |
| 1538 } | |
| 1539 | |
| 1540 // Finalize any weak persistent handles with a non-null referent. | |
| 1541 FinalizeWeakPersistentHandlesVisitor visitor; | |
| 1542 api_state()->weak_persistent_handles().VisitHandles(&visitor); | |
| 1543 api_state()->prologue_weak_persistent_handles().VisitHandles(&visitor); | |
| 1544 | |
| 1545 if (FLAG_trace_isolates) { | |
| 1546 heap()->PrintSizes(); | |
| 1547 megamorphic_cache_table()->PrintSizes(); | |
| 1548 Symbols::DumpStats(); | |
| 1549 OS::Print("[-] Stopping isolate:\n" | |
| 1550 "\tisolate: %s\n", name()); | |
| 1551 } | |
| 1552 if (FLAG_print_metrics) { | |
| 1553 LogBlock lb; | |
| 1554 THR_Print("Printing metrics for %s\n", name()); | |
| 1555 #define ISOLATE_METRIC_PRINT(type, variable, name, unit) \ | |
| 1556 THR_Print("%s\n", metric_##variable##_.ToString()); | |
| 1557 ISOLATE_METRIC_LIST(ISOLATE_METRIC_PRINT); | |
| 1558 #undef ISOLATE_METRIC_PRINT | |
| 1559 THR_Print("\n"); | |
| 1560 } | |
| 1561 } | |
| 1562 | 1578 |
| 1563 #if defined(DEBUG) | 1579 #if defined(DEBUG) |
| 1564 // No concurrent sweeper tasks should be running at this point. | 1580 // No concurrent sweeper tasks should be running at this point. |
| 1565 if (heap_ != NULL) { | 1581 if (heap_ != NULL) { |
| 1566 PageSpace* old_space = heap_->old_space(); | 1582 PageSpace* old_space = heap_->old_space(); |
| 1567 MonitorLocker ml(old_space->tasks_lock()); | 1583 MonitorLocker ml(old_space->tasks_lock()); |
| 1568 ASSERT(old_space->tasks() == 0); | 1584 ASSERT(old_space->tasks() == 0); |
| 1569 } | 1585 } |
| 1570 #endif | 1586 #endif |
| 1571 | 1587 |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 1595 Isolate::unhandled_exception_callback_ = NULL; | 1611 Isolate::unhandled_exception_callback_ = NULL; |
| 1596 Dart_IsolateShutdownCallback Isolate::shutdown_callback_ = NULL; | 1612 Dart_IsolateShutdownCallback Isolate::shutdown_callback_ = NULL; |
| 1597 Dart_FileOpenCallback Isolate::file_open_callback_ = NULL; | 1613 Dart_FileOpenCallback Isolate::file_open_callback_ = NULL; |
| 1598 Dart_FileReadCallback Isolate::file_read_callback_ = NULL; | 1614 Dart_FileReadCallback Isolate::file_read_callback_ = NULL; |
| 1599 Dart_FileWriteCallback Isolate::file_write_callback_ = NULL; | 1615 Dart_FileWriteCallback Isolate::file_write_callback_ = NULL; |
| 1600 Dart_FileCloseCallback Isolate::file_close_callback_ = NULL; | 1616 Dart_FileCloseCallback Isolate::file_close_callback_ = NULL; |
| 1601 Dart_EntropySource Isolate::entropy_source_callback_ = NULL; | 1617 Dart_EntropySource Isolate::entropy_source_callback_ = NULL; |
| 1602 | 1618 |
| 1603 Monitor* Isolate::isolates_list_monitor_ = NULL; | 1619 Monitor* Isolate::isolates_list_monitor_ = NULL; |
| 1604 Isolate* Isolate::isolates_list_head_ = NULL; | 1620 Isolate* Isolate::isolates_list_head_ = NULL; |
| 1605 | 1621 bool Isolate::creation_enabled_ = false; |
| 1606 | 1622 |
| 1607 void Isolate::IterateObjectPointers(ObjectPointerVisitor* visitor, | 1623 void Isolate::IterateObjectPointers(ObjectPointerVisitor* visitor, |
| 1608 bool visit_prologue_weak_handles, | 1624 bool visit_prologue_weak_handles, |
| 1609 bool validate_frames) { | 1625 bool validate_frames) { |
| 1610 HeapIterationScope heap_iteration_scope; | 1626 HeapIterationScope heap_iteration_scope; |
| 1611 VisitObjectPointers(visitor, visit_prologue_weak_handles, validate_frames); | 1627 VisitObjectPointers(visitor, visit_prologue_weak_handles, validate_frames); |
| 1612 } | 1628 } |
| 1613 | 1629 |
| 1614 | 1630 |
| 1615 void Isolate::VisitObjectPointers(ObjectPointerVisitor* visitor, | 1631 void Isolate::VisitObjectPointers(ObjectPointerVisitor* visitor, |
| (...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2108 intptr_t count = 0; | 2124 intptr_t count = 0; |
| 2109 Isolate* current = isolates_list_head_; | 2125 Isolate* current = isolates_list_head_; |
| 2110 while (current != NULL) { | 2126 while (current != NULL) { |
| 2111 count++; | 2127 count++; |
| 2112 current = current->next_; | 2128 current = current->next_; |
| 2113 } | 2129 } |
| 2114 return count; | 2130 return count; |
| 2115 } | 2131 } |
| 2116 | 2132 |
| 2117 | 2133 |
| 2118 void Isolate::AddIsolateTolist(Isolate* isolate) { | 2134 bool Isolate::AddIsolateToList(Isolate* isolate) { |
| 2119 MonitorLocker ml(isolates_list_monitor_); | 2135 MonitorLocker ml(isolates_list_monitor_); |
| 2136 if (!creation_enabled_) { | |
| 2137 return false; | |
| 2138 } | |
| 2120 ASSERT(isolate != NULL); | 2139 ASSERT(isolate != NULL); |
| 2121 ASSERT(isolate->next_ == NULL); | 2140 ASSERT(isolate->next_ == NULL); |
| 2122 isolate->next_ = isolates_list_head_; | 2141 isolate->next_ = isolates_list_head_; |
| 2123 isolates_list_head_ = isolate; | 2142 isolates_list_head_ = isolate; |
| 2143 return true; | |
| 2124 } | 2144 } |
| 2125 | 2145 |
| 2126 | 2146 |
| 2127 void Isolate::RemoveIsolateFromList(Isolate* isolate) { | 2147 void Isolate::RemoveIsolateFromList(Isolate* isolate) { |
| 2128 MonitorLocker ml(isolates_list_monitor_); | 2148 MonitorLocker ml(isolates_list_monitor_); |
| 2129 ASSERT(isolate != NULL); | 2149 ASSERT(isolate != NULL); |
| 2130 if (isolate == isolates_list_head_) { | 2150 if (isolate == isolates_list_head_) { |
| 2131 isolates_list_head_ = isolate->next_; | 2151 isolates_list_head_ = isolate->next_; |
| 2152 if (!creation_enabled_) { | |
| 2153 ml.Notify(); | |
| 2154 } | |
| 2132 return; | 2155 return; |
| 2133 } | 2156 } |
| 2134 Isolate* previous = NULL; | 2157 Isolate* previous = NULL; |
| 2135 Isolate* current = isolates_list_head_; | 2158 Isolate* current = isolates_list_head_; |
| 2136 while (current) { | 2159 while (current) { |
| 2137 if (current == isolate) { | 2160 if (current == isolate) { |
| 2138 ASSERT(previous != NULL); | 2161 ASSERT(previous != NULL); |
| 2139 previous->next_ = current->next_; | 2162 previous->next_ = current->next_; |
| 2163 if (!creation_enabled_) { | |
| 2164 ml.Notify(); | |
| 2165 } | |
| 2140 return; | 2166 return; |
| 2141 } | 2167 } |
| 2142 previous = current; | 2168 previous = current; |
| 2143 current = current->next_; | 2169 current = current->next_; |
| 2144 } | 2170 } |
| 2145 UNREACHABLE(); | 2171 // If we are shutting down the VM, the isolate may not be in the list. |
| 2172 ASSERT(!creation_enabled_); | |
| 2146 } | 2173 } |
| 2147 | 2174 |
| 2148 | 2175 |
| 2176 void Isolate::DisableIsolateCreation() { | |
| 2177 MonitorLocker ml(isolates_list_monitor_); | |
| 2178 creation_enabled_ = false; | |
| 2179 } | |
| 2180 | |
| 2181 | |
| 2182 void Isolate::EnableIsolateCreation() { | |
| 2183 MonitorLocker ml(isolates_list_monitor_); | |
| 2184 creation_enabled_ = true; | |
| 2185 } | |
| 2186 | |
| 2187 | |
| 2149 template<class C> | 2188 template<class C> |
| 2150 C* Isolate::AllocateReusableHandle() { | 2189 C* Isolate::AllocateReusableHandle() { |
| 2151 C* handle = reinterpret_cast<C*>(reusable_handles_.AllocateScopedHandle()); | 2190 C* handle = reinterpret_cast<C*>(reusable_handles_.AllocateScopedHandle()); |
| 2152 C::initializeHandle(handle, C::null()); | 2191 C::initializeHandle(handle, C::null()); |
| 2153 return handle; | 2192 return handle; |
| 2154 } | 2193 } |
| 2155 | 2194 |
| 2156 | 2195 |
| 2196 void Isolate::Kill() { | |
| 2197 Dart_CObject kill_msg; | |
| 2198 Dart_CObject* list_values[4]; | |
| 2199 kill_msg.type = Dart_CObject_kArray; | |
| 2200 kill_msg.value.as_array.length = 4; | |
| 2201 kill_msg.value.as_array.values = list_values; | |
| 2202 | |
| 2203 Dart_CObject oob; | |
| 2204 oob.type = Dart_CObject_kInt32; | |
| 2205 oob.value.as_int32 = Message::kIsolateLibOOBMsg; | |
| 2206 list_values[0] = &oob; | |
| 2207 | |
| 2208 Dart_CObject kill; | |
| 2209 kill.type = Dart_CObject_kInt32; | |
| 2210 kill.value.as_int32 = IsolateMessageHandler::kKillMsg; | |
| 2211 list_values[1] = &kill; | |
| 2212 | |
| 2213 Dart_CObject cap; | |
| 2214 cap.type = Dart_CObject_kCapability; | |
| 2215 cap.value.as_capability.id = terminate_capability(); | |
| 2216 list_values[2] = ∩ | |
| 2217 | |
| 2218 Dart_CObject imm; | |
| 2219 imm.type = Dart_CObject_kInt32; | |
| 2220 imm.value.as_int32 = IsolateMessageHandler::kImmediateAction; | |
| 2221 list_values[3] = &imm; | |
| 2222 | |
| 2223 { | |
| 2224 uint8_t* buffer = NULL; | |
| 2225 ApiMessageWriter writer(&buffer, allocator); | |
| 2226 bool success = writer.WriteCMessage(&kill_msg); | |
| 2227 ASSERT(success); | |
| 2228 | |
| 2229 // Post the message at the given port. | |
| 2230 success = PortMap::PostMessage(new Message(main_port(), | |
| 2231 buffer, | |
| 2232 writer.BytesWritten(), | |
| 2233 Message::kOOBPriority)); | |
| 2234 ASSERT(success); | |
| 2235 } | |
| 2236 } | |
| 2237 | |
| 2238 | |
| 2239 class IsolateKillerVisitor : public IsolateVisitor { | |
| 2240 public: | |
| 2241 IsolateKillerVisitor() : target_(NULL) {} | |
| 2242 | |
| 2243 explicit IsolateKillerVisitor(Isolate* isolate) | |
| 2244 : target_(isolate) { | |
| 2245 ASSERT(isolate != Dart::vm_isolate()); | |
| 2246 } | |
| 2247 | |
| 2248 virtual ~IsolateKillerVisitor() {} | |
| 2249 | |
| 2250 void VisitIsolate(Isolate* isolate) { | |
| 2251 ASSERT(isolate != NULL); | |
| 2252 if (ShouldKill(isolate)) { | |
| 2253 isolate->Kill(); | |
| 2254 } | |
| 2255 } | |
| 2256 | |
| 2257 private: | |
| 2258 bool ShouldKill(Isolate* isolate) { | |
| 2259 // If a target_ is specified, then only kill the target_. | |
| 2260 // Otherwise, don't kill the service isolate or vm isolate. | |
| 2261 return (((target_ != NULL) && (isolate == target_)) || | |
| 2262 ((target_ == NULL) && | |
| 2263 !ServiceIsolate::IsServiceIsolateDescendant(isolate) && | |
| 2264 (isolate != Dart::vm_isolate()))); | |
| 2265 } | |
| 2266 | |
| 2267 Isolate* target_; | |
| 2268 }; | |
| 2269 | |
| 2270 | |
| 2271 void Isolate::KillAllIsolates() { | |
| 2272 IsolateKillerVisitor visitor; | |
| 2273 VisitIsolates(&visitor); | |
| 2274 } | |
| 2275 | |
| 2276 | |
| 2277 void Isolate::KillIfExists(Isolate* isolate) { | |
| 2278 IsolateKillerVisitor visitor(isolate); | |
| 2279 VisitIsolates(&visitor); | |
| 2280 } | |
| 2281 | |
| 2282 | |
| 2157 static RawInstance* DeserializeObject(Thread* thread, | 2283 static RawInstance* DeserializeObject(Thread* thread, |
| 2158 uint8_t* obj_data, | 2284 uint8_t* obj_data, |
| 2159 intptr_t obj_len) { | 2285 intptr_t obj_len) { |
| 2160 if (obj_data == NULL) { | 2286 if (obj_data == NULL) { |
| 2161 return Instance::null(); | 2287 return Instance::null(); |
| 2162 } | 2288 } |
| 2163 MessageSnapshotReader reader(obj_data, obj_len, thread); | 2289 MessageSnapshotReader reader(obj_data, obj_len, thread); |
| 2164 Zone* zone = thread->zone(); | 2290 Zone* zone = thread->zone(); |
| 2165 const Object& obj = Object::Handle(zone, reader.ReadObject()); | 2291 const Object& obj = Object::Handle(zone, reader.ReadObject()); |
| 2166 ASSERT(!obj.IsError()); | 2292 ASSERT(!obj.IsError()); |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2349 serialized_message_, serialized_message_len_); | 2475 serialized_message_, serialized_message_len_); |
| 2350 } | 2476 } |
| 2351 | 2477 |
| 2352 | 2478 |
| 2353 void IsolateSpawnState::Cleanup() { | 2479 void IsolateSpawnState::Cleanup() { |
| 2354 SwitchIsolateScope switch_scope(I); | 2480 SwitchIsolateScope switch_scope(I); |
| 2355 Dart::ShutdownIsolate(); | 2481 Dart::ShutdownIsolate(); |
| 2356 } | 2482 } |
| 2357 | 2483 |
| 2358 } // namespace dart | 2484 } // namespace dart |
| OLD | NEW |