| 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 17 matching lines...) Expand all Loading... |
| 28 #include "vm/reusable_handles.h" | 28 #include "vm/reusable_handles.h" |
| 29 #include "vm/service.h" | 29 #include "vm/service.h" |
| 30 #include "vm/service_event.h" | 30 #include "vm/service_event.h" |
| 31 #include "vm/service_isolate.h" | 31 #include "vm/service_isolate.h" |
| 32 #include "vm/simulator.h" | 32 #include "vm/simulator.h" |
| 33 #include "vm/stack_frame.h" | 33 #include "vm/stack_frame.h" |
| 34 #include "vm/stub_code.h" | 34 #include "vm/stub_code.h" |
| 35 #include "vm/symbols.h" | 35 #include "vm/symbols.h" |
| 36 #include "vm/tags.h" | 36 #include "vm/tags.h" |
| 37 #include "vm/thread_interrupter.h" | 37 #include "vm/thread_interrupter.h" |
| 38 #include "vm/timeline.h" |
| 38 #include "vm/timer.h" | 39 #include "vm/timer.h" |
| 39 #include "vm/visitor.h" | 40 #include "vm/visitor.h" |
| 40 | 41 |
| 41 | 42 |
| 42 namespace dart { | 43 namespace dart { |
| 43 | 44 |
| 44 DEFINE_FLAG(bool, trace_isolates, false, | 45 DEFINE_FLAG(bool, trace_isolates, false, |
| 45 "Trace isolate creation and shut down."); | 46 "Trace isolate creation and shut down."); |
| 46 DEFINE_FLAG(bool, pause_isolates_on_start, false, | 47 DEFINE_FLAG(bool, pause_isolates_on_start, false, |
| 47 "Pause isolates before starting."); | 48 "Pause isolates before starting."); |
| 48 DEFINE_FLAG(bool, pause_isolates_on_exit, false, | 49 DEFINE_FLAG(bool, pause_isolates_on_exit, false, |
| 49 "Pause isolates exiting."); | 50 "Pause isolates exiting."); |
| 50 DEFINE_FLAG(bool, break_at_isolate_spawn, false, | 51 DEFINE_FLAG(bool, break_at_isolate_spawn, false, |
| 51 "Insert a one-time breakpoint at the entrypoint for all spawned " | 52 "Insert a one-time breakpoint at the entrypoint for all spawned " |
| 52 "isolates"); | 53 "isolates"); |
| 53 DEFINE_FLAG(charp, isolate_log_filter, NULL, | 54 DEFINE_FLAG(charp, isolate_log_filter, NULL, |
| 54 "Log isolates whose name include the filter. " | 55 "Log isolates whose name include the filter. " |
| 55 "Default: service isolate log messages are suppressed."); | 56 "Default: service isolate log messages are suppressed."); |
| 56 | 57 |
| 58 DEFINE_FLAG(charp, timeline_trace_dir, NULL, |
| 59 "Enable all timeline trace streams and output traces " |
| 60 "into specified directory."); |
| 61 |
| 57 // TODO(iposva): Make these isolate specific flags inaccessible using the | 62 // TODO(iposva): Make these isolate specific flags inaccessible using the |
| 58 // regular FLAG_xyz pattern. | 63 // regular FLAG_xyz pattern. |
| 59 // These flags are per-isolate and only influence the defaults. | 64 // These flags are per-isolate and only influence the defaults. |
| 60 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements."); | 65 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements."); |
| 61 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks."); | 66 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks."); |
| 62 DEFINE_FLAG(bool, error_on_bad_override, false, | 67 DEFINE_FLAG(bool, error_on_bad_override, false, |
| 63 "Report error for bad overrides."); | 68 "Report error for bad overrides."); |
| 64 DEFINE_FLAG(bool, error_on_bad_type, false, | 69 DEFINE_FLAG(bool, error_on_bad_type, false, |
| 65 "Report error for malformed types."); | 70 "Report error for malformed types."); |
| 66 | 71 |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 if (callback) { | 366 if (callback) { |
| 362 // Allow the embedder to handle message notification. | 367 // Allow the embedder to handle message notification. |
| 363 (*callback)(Api::CastIsolate(I)); | 368 (*callback)(Api::CastIsolate(I)); |
| 364 } | 369 } |
| 365 } | 370 } |
| 366 | 371 |
| 367 | 372 |
| 368 bool IsolateMessageHandler::HandleMessage(Message* message) { | 373 bool IsolateMessageHandler::HandleMessage(Message* message) { |
| 369 StackZone zone(I); | 374 StackZone zone(I); |
| 370 HandleScope handle_scope(I); | 375 HandleScope handle_scope(I); |
| 376 TimelineDurationScope tds(I, I->GetIsolateStream(), "HandleMessage"); |
| 377 |
| 371 // TODO(turnidge): Rework collection total dart execution. This can | 378 // TODO(turnidge): Rework collection total dart execution. This can |
| 372 // overcount when other things (gc, compilation) are active. | 379 // overcount when other things (gc, compilation) are active. |
| 373 TIMERSCOPE(isolate_, time_dart_execution); | 380 TIMERSCOPE(isolate_, time_dart_execution); |
| 374 | 381 |
| 375 // If the message is in band we lookup the handler to dispatch to. If the | 382 // If the message is in band we lookup the handler to dispatch to. If the |
| 376 // receive port was closed, we drop the message without deserializing it. | 383 // receive port was closed, we drop the message without deserializing it. |
| 377 // Illegal port is a special case for artificially enqueued isolate library | 384 // Illegal port is a special case for artificially enqueued isolate library |
| 378 // messages which are handled in C++ code below. | 385 // messages which are handled in C++ code below. |
| 379 Object& msg_handler = Object::Handle(I); | 386 Object& msg_handler = Object::Handle(I); |
| 380 if (!message->IsOOB() && (message->dest_port() != Message::kIllegalPort)) { | 387 if (!message->IsOOB() && (message->dest_port() != Message::kIllegalPort)) { |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 655 edge_counter_increment_size_(-1), | 662 edge_counter_increment_size_(-1), |
| 656 compiler_stats_(NULL), | 663 compiler_stats_(NULL), |
| 657 is_service_isolate_(false), | 664 is_service_isolate_(false), |
| 658 log_(new class Log()), | 665 log_(new class Log()), |
| 659 stacktrace_(NULL), | 666 stacktrace_(NULL), |
| 660 stack_frame_index_(-1), | 667 stack_frame_index_(-1), |
| 661 last_allocationprofile_accumulator_reset_timestamp_(0), | 668 last_allocationprofile_accumulator_reset_timestamp_(0), |
| 662 last_allocationprofile_gc_timestamp_(0), | 669 last_allocationprofile_gc_timestamp_(0), |
| 663 object_id_ring_(NULL), | 670 object_id_ring_(NULL), |
| 664 trace_buffer_(NULL), | 671 trace_buffer_(NULL), |
| 672 timeline_event_buffer_(NULL), |
| 665 profiler_data_(NULL), | 673 profiler_data_(NULL), |
| 666 thread_state_(NULL), | 674 thread_state_(NULL), |
| 667 tag_table_(GrowableObjectArray::null()), | 675 tag_table_(GrowableObjectArray::null()), |
| 668 current_tag_(UserTag::null()), | 676 current_tag_(UserTag::null()), |
| 669 default_tag_(UserTag::null()), | 677 default_tag_(UserTag::null()), |
| 670 deoptimized_code_array_(GrowableObjectArray::null()), | 678 deoptimized_code_array_(GrowableObjectArray::null()), |
| 671 metrics_list_head_(NULL), | 679 metrics_list_head_(NULL), |
| 672 cha_(NULL), | 680 cha_(NULL), |
| 673 next_(NULL), | 681 next_(NULL), |
| 674 pause_loop_monitor_(NULL), | 682 pause_loop_monitor_(NULL), |
| (...skipping 28 matching lines...) Expand all Loading... |
| 703 delete log_; | 711 delete log_; |
| 704 log_ = NULL; | 712 log_ = NULL; |
| 705 delete object_id_ring_; | 713 delete object_id_ring_; |
| 706 object_id_ring_ = NULL; | 714 object_id_ring_ = NULL; |
| 707 delete pause_loop_monitor_; | 715 delete pause_loop_monitor_; |
| 708 pause_loop_monitor_ = NULL; | 716 pause_loop_monitor_ = NULL; |
| 709 if (compiler_stats_ != NULL) { | 717 if (compiler_stats_ != NULL) { |
| 710 delete compiler_stats_; | 718 delete compiler_stats_; |
| 711 compiler_stats_ = NULL; | 719 compiler_stats_ = NULL; |
| 712 } | 720 } |
| 721 RemoveTimelineEventBuffer(); |
| 713 } | 722 } |
| 714 | 723 |
| 715 | 724 |
| 716 #if defined(DEBUG) | 725 #if defined(DEBUG) |
| 717 bool Isolate::IsIsolateOf(Thread* thread) { | 726 bool Isolate::IsIsolateOf(Thread* thread) { |
| 718 return this == thread->isolate(); | 727 return this == thread->isolate(); |
| 719 } | 728 } |
| 720 #endif // DEBUG | 729 #endif // DEBUG |
| 721 | 730 |
| 722 | 731 |
| 723 void Isolate::InitOnce() { | 732 void Isolate::InitOnce() { |
| 724 create_callback_ = NULL; | 733 create_callback_ = NULL; |
| 725 isolates_list_monitor_ = new Monitor(); | 734 isolates_list_monitor_ = new Monitor(); |
| 726 ASSERT(isolates_list_monitor_ != NULL); | 735 ASSERT(isolates_list_monitor_ != NULL); |
| 727 } | 736 } |
| 728 | 737 |
| 729 | 738 |
| 730 Isolate* Isolate::Init(const char* name_prefix, | 739 Isolate* Isolate::Init(const char* name_prefix, |
| 731 const Dart_IsolateFlags& api_flags, | 740 const Dart_IsolateFlags& api_flags, |
| 732 bool is_vm_isolate) { | 741 bool is_vm_isolate) { |
| 733 Isolate* result = new Isolate(api_flags); | 742 Isolate* result = new Isolate(api_flags); |
| 734 ASSERT(result != NULL); | 743 ASSERT(result != NULL); |
| 735 | 744 |
| 736 // Initialize metrics. | 745 // Initialize metrics. |
| 737 #define ISOLATE_METRIC_INIT(type, variable, name, unit) \ | 746 #define ISOLATE_METRIC_INIT(type, variable, name, unit) \ |
| 738 result->metric_##variable##_.Init(result, name, NULL, Metric::unit); | 747 result->metric_##variable##_.Init(result, name, NULL, Metric::unit); |
| 739 ISOLATE_METRIC_LIST(ISOLATE_METRIC_INIT); | 748 ISOLATE_METRIC_LIST(ISOLATE_METRIC_INIT); |
| 740 #undef ISOLATE_METRIC_INIT | 749 #undef ISOLATE_METRIC_INIT |
| 741 | 750 |
| 751 const bool force_streams = FLAG_timeline_trace_dir != NULL; |
| 752 |
| 753 // Initialize Timeline streams. |
| 754 #define ISOLATE_TIMELINE_STREAM_INIT(name, enabled_by_default) \ |
| 755 result->stream_##name##_.Init(#name, force_streams || enabled_by_default); |
| 756 ISOLATE_TIMELINE_STREAM_LIST(ISOLATE_TIMELINE_STREAM_INIT); |
| 757 #undef ISOLATE_TIMELINE_STREAM_INIT |
| 758 |
| 759 |
| 742 // TODO(5411455): For now just set the recently created isolate as | 760 // TODO(5411455): For now just set the recently created isolate as |
| 743 // the current isolate. | 761 // the current isolate. |
| 744 Thread::EnterIsolate(result); | 762 Thread::EnterIsolate(result); |
| 745 | 763 |
| 746 // Setup the isolate specific resuable handles. | 764 // Setup the isolate specific resuable handles. |
| 747 #define REUSABLE_HANDLE_ALLOCATION(object) \ | 765 #define REUSABLE_HANDLE_ALLOCATION(object) \ |
| 748 result->object##_handle_ = result->AllocateReusableHandle<object>(); | 766 result->object##_handle_ = result->AllocateReusableHandle<object>(); |
| 749 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_ALLOCATION) | 767 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_ALLOCATION) |
| 750 #undef REUSABLE_HANDLE_ALLOCATION | 768 #undef REUSABLE_HANDLE_ALLOCATION |
| 751 | 769 |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 956 set_is_runnable(true); | 974 set_is_runnable(true); |
| 957 if (!ServiceIsolate::IsServiceIsolate(this)) { | 975 if (!ServiceIsolate::IsServiceIsolate(this)) { |
| 958 message_handler()->set_pause_on_start(FLAG_pause_isolates_on_start); | 976 message_handler()->set_pause_on_start(FLAG_pause_isolates_on_start); |
| 959 message_handler()->set_pause_on_exit(FLAG_pause_isolates_on_exit); | 977 message_handler()->set_pause_on_exit(FLAG_pause_isolates_on_exit); |
| 960 } | 978 } |
| 961 IsolateSpawnState* state = spawn_state(); | 979 IsolateSpawnState* state = spawn_state(); |
| 962 if (state != NULL) { | 980 if (state != NULL) { |
| 963 ASSERT(this == state->isolate()); | 981 ASSERT(this == state->isolate()); |
| 964 Run(); | 982 Run(); |
| 965 } | 983 } |
| 984 TimelineStream* stream = GetIsolateStream(); |
| 985 ASSERT(stream != NULL); |
| 986 TimelineEvent* event = stream->RecordEvent(); |
| 987 if (event != NULL) { |
| 988 event->Instant(stream, "Runnable"); |
| 989 } |
| 966 return true; | 990 return true; |
| 967 } | 991 } |
| 968 | 992 |
| 969 | 993 |
| 970 bool Isolate::VerifyPauseCapability(const Object& capability) const { | 994 bool Isolate::VerifyPauseCapability(const Object& capability) const { |
| 971 return !capability.IsNull() && | 995 return !capability.IsNull() && |
| 972 capability.IsCapability() && | 996 capability.IsCapability() && |
| 973 (pause_capability() == Capability::Cast(capability).Id()); | 997 (pause_capability() == Capability::Cast(capability).Id()); |
| 974 } | 998 } |
| 975 | 999 |
| (...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1445 api_state()->weak_persistent_handles().VisitHandles(&visitor); | 1469 api_state()->weak_persistent_handles().VisitHandles(&visitor); |
| 1446 api_state()->prologue_weak_persistent_handles().VisitHandles(&visitor); | 1470 api_state()->prologue_weak_persistent_handles().VisitHandles(&visitor); |
| 1447 | 1471 |
| 1448 if (FLAG_trace_isolates) { | 1472 if (FLAG_trace_isolates) { |
| 1449 heap()->PrintSizes(); | 1473 heap()->PrintSizes(); |
| 1450 megamorphic_cache_table()->PrintSizes(); | 1474 megamorphic_cache_table()->PrintSizes(); |
| 1451 Symbols::DumpStats(); | 1475 Symbols::DumpStats(); |
| 1452 OS::Print("[-] Stopping isolate:\n" | 1476 OS::Print("[-] Stopping isolate:\n" |
| 1453 "\tisolate: %s\n", name()); | 1477 "\tisolate: %s\n", name()); |
| 1454 } | 1478 } |
| 1479 |
| 1480 if ((timeline_event_buffer_ != NULL) && (FLAG_timeline_trace_dir != NULL)) { |
| 1481 timeline_event_buffer_->WriteTo(FLAG_timeline_trace_dir); |
| 1482 } |
| 1455 } | 1483 } |
| 1456 | 1484 |
| 1457 // TODO(5411455): For now just make sure there are no current isolates | 1485 // TODO(5411455): For now just make sure there are no current isolates |
| 1458 // as we are shutting down the isolate. | 1486 // as we are shutting down the isolate. |
| 1459 Thread::ExitIsolate(); | 1487 Thread::ExitIsolate(); |
| 1460 Profiler::ShutdownProfilingForIsolate(this); | 1488 Profiler::ShutdownProfilingForIsolate(this); |
| 1461 } | 1489 } |
| 1462 | 1490 |
| 1463 | 1491 |
| 1464 Dart_IsolateCreateCallback Isolate::create_callback_ = NULL; | 1492 Dart_IsolateCreateCallback Isolate::create_callback_ = NULL; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1543 } | 1571 } |
| 1544 | 1572 |
| 1545 | 1573 |
| 1546 void Isolate::VisitPrologueWeakPersistentHandles(HandleVisitor* visitor) { | 1574 void Isolate::VisitPrologueWeakPersistentHandles(HandleVisitor* visitor) { |
| 1547 if (api_state() != NULL) { | 1575 if (api_state() != NULL) { |
| 1548 api_state()->VisitPrologueWeakHandles(visitor); | 1576 api_state()->VisitPrologueWeakHandles(visitor); |
| 1549 } | 1577 } |
| 1550 } | 1578 } |
| 1551 | 1579 |
| 1552 | 1580 |
| 1581 void Isolate::SetTimelineEventBuffer( |
| 1582 TimelineEventBuffer* timeline_event_buffer) { |
| 1583 #define ISOLATE_TIMELINE_STREAM_SET_BUFFER(name, enabled_by_default) \ |
| 1584 stream_##name##_.set_buffer(timeline_event_buffer); |
| 1585 ISOLATE_TIMELINE_STREAM_LIST(ISOLATE_TIMELINE_STREAM_SET_BUFFER) |
| 1586 #undef ISOLATE_TIMELINE_STREAM_SET_BUFFER |
| 1587 timeline_event_buffer_ = timeline_event_buffer; |
| 1588 } |
| 1589 |
| 1590 void Isolate::RemoveTimelineEventBuffer() { |
| 1591 SetTimelineEventBuffer(NULL); |
| 1592 delete timeline_event_buffer_; |
| 1593 } |
| 1594 |
| 1595 |
| 1553 void Isolate::PrintJSON(JSONStream* stream, bool ref) { | 1596 void Isolate::PrintJSON(JSONStream* stream, bool ref) { |
| 1554 JSONObject jsobj(stream); | 1597 JSONObject jsobj(stream); |
| 1555 jsobj.AddProperty("type", (ref ? "@Isolate" : "Isolate")); | 1598 jsobj.AddProperty("type", (ref ? "@Isolate" : "Isolate")); |
| 1556 jsobj.AddFixedServiceId("isolates/%" Pd "", | 1599 jsobj.AddFixedServiceId("isolates/%" Pd "", |
| 1557 static_cast<intptr_t>(main_port())); | 1600 static_cast<intptr_t>(main_port())); |
| 1558 | 1601 |
| 1559 jsobj.AddProperty("name", debugger_name()); | 1602 jsobj.AddProperty("name", debugger_name()); |
| 1560 jsobj.AddPropertyF("number", "%" Pd "", | 1603 jsobj.AddPropertyF("number", "%" Pd "", |
| 1561 static_cast<intptr_t>(main_port())); | 1604 static_cast<intptr_t>(main_port())); |
| 1562 if (ref) { | 1605 if (ref) { |
| (...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2031 serialized_message_, serialized_message_len_); | 2074 serialized_message_, serialized_message_len_); |
| 2032 } | 2075 } |
| 2033 | 2076 |
| 2034 | 2077 |
| 2035 void IsolateSpawnState::Cleanup() { | 2078 void IsolateSpawnState::Cleanup() { |
| 2036 SwitchIsolateScope switch_scope(I); | 2079 SwitchIsolateScope switch_scope(I); |
| 2037 Dart::ShutdownIsolate(); | 2080 Dart::ShutdownIsolate(); |
| 2038 } | 2081 } |
| 2039 | 2082 |
| 2040 } // namespace dart | 2083 } // namespace dart |
| OLD | NEW |