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 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
486 } else { | 486 } else { |
487 const Object& result = Object::Handle(zone, | 487 const Object& result = Object::Handle(zone, |
488 DartLibraryCalls::HandleMessage(msg_handler, msg)); | 488 DartLibraryCalls::HandleMessage(msg_handler, msg)); |
489 if (result.IsError()) { | 489 if (result.IsError()) { |
490 success = ProcessUnhandledException(Error::Cast(result)); | 490 success = ProcessUnhandledException(Error::Cast(result)); |
491 } else { | 491 } else { |
492 ASSERT(result.IsNull()); | 492 ASSERT(result.IsNull()); |
493 } | 493 } |
494 } | 494 } |
495 delete message; | 495 delete message; |
| 496 if (success) { |
| 497 const Object& result = |
| 498 Object::Handle(zone, I->InvokePendingServiceExtensionCalls()); |
| 499 if (result.IsError()) { |
| 500 success = ProcessUnhandledException(Error::Cast(result)); |
| 501 } else { |
| 502 ASSERT(result.IsNull()); |
| 503 } |
| 504 } |
496 return success; | 505 return success; |
497 } | 506 } |
498 | 507 |
499 | 508 |
500 void IsolateMessageHandler::NotifyPauseOnStart() { | 509 void IsolateMessageHandler::NotifyPauseOnStart() { |
501 if (Service::debug_stream.enabled()) { | 510 if (Service::debug_stream.enabled()) { |
502 StartIsolateScope start_isolate(isolate()); | 511 StartIsolateScope start_isolate(isolate()); |
503 StackZone zone(I); | 512 StackZone zone(I); |
504 HandleScope handle_scope(I); | 513 HandleScope handle_scope(I); |
505 ServiceEvent pause_event(isolate(), ServiceEvent::kPauseStart); | 514 ServiceEvent pause_event(isolate(), ServiceEvent::kPauseStart); |
506 Service::HandleEvent(&pause_event); | 515 Service::HandleEvent(&pause_event); |
507 } else if (FLAG_trace_service) { | 516 } else if (FLAG_trace_service) { |
508 OS::Print("vm-service: Dropping event of type PauseStart (%s)\n", | 517 OS::Print("vm-service: Dropping event of type PauseStart (%s)\n", |
509 isolate()->name()); | 518 isolate()->name()); |
510 } | 519 } |
511 } | 520 } |
512 | 521 |
513 | 522 |
514 void IsolateMessageHandler::NotifyPauseOnExit() { | 523 void IsolateMessageHandler::NotifyPauseOnExit() { |
515 if (Service::debug_stream.enabled()) { | 524 if (Service::debug_stream.enabled()) { |
516 StartIsolateScope start_isolate(isolate()); | 525 StartIsolateScope start_isolate(isolate()); |
517 StackZone zone(I); | 526 StackZone zone(I); |
518 HandleScope handle_scope(I); | 527 HandleScope handle_scope(I); |
519 ServiceEvent pause_event(isolate(), ServiceEvent::kPauseExit); | 528 ServiceEvent pause_event(isolate(), ServiceEvent::kPauseExit); |
520 Service::HandleEvent(&pause_event); | 529 Service::HandleEvent(&pause_event); |
521 } else if (FLAG_trace_service) { | 530 } else if (FLAG_trace_service) { |
522 OS::Print("vm-service: Dropping event of type PauseExit (%s)\n", | 531 OS::Print("vm-service: Dropping event of type PauseExit (%s)\n", |
523 isolate()->name()); | 532 isolate()->name()); |
524 } | 533 } |
525 } | 534 } |
526 | 535 |
527 | 536 |
528 #if defined(DEBUG) | 537 #if defined(DEBUG) |
529 void IsolateMessageHandler::CheckAccess() { | 538 void IsolateMessageHandler::CheckAccess() { |
530 ASSERT(IsCurrentIsolate()); | 539 ASSERT(IsCurrentIsolate()); |
531 } | 540 } |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
697 last_allocationprofile_accumulator_reset_timestamp_(0), | 706 last_allocationprofile_accumulator_reset_timestamp_(0), |
698 last_allocationprofile_gc_timestamp_(0), | 707 last_allocationprofile_gc_timestamp_(0), |
699 object_id_ring_(NULL), | 708 object_id_ring_(NULL), |
700 trace_buffer_(NULL), | 709 trace_buffer_(NULL), |
701 profiler_data_(NULL), | 710 profiler_data_(NULL), |
702 tag_table_(GrowableObjectArray::null()), | 711 tag_table_(GrowableObjectArray::null()), |
703 current_tag_(UserTag::null()), | 712 current_tag_(UserTag::null()), |
704 default_tag_(UserTag::null()), | 713 default_tag_(UserTag::null()), |
705 collected_closures_(GrowableObjectArray::null()), | 714 collected_closures_(GrowableObjectArray::null()), |
706 deoptimized_code_array_(GrowableObjectArray::null()), | 715 deoptimized_code_array_(GrowableObjectArray::null()), |
| 716 pending_service_extension_calls_(GrowableObjectArray::null()), |
| 717 registered_service_extension_handlers_(GrowableObjectArray::null()), |
707 metrics_list_head_(NULL), | 718 metrics_list_head_(NULL), |
708 compilation_allowed_(true), | 719 compilation_allowed_(true), |
709 cha_(NULL), | 720 cha_(NULL), |
710 next_(NULL), | 721 next_(NULL), |
711 pause_loop_monitor_(NULL), | 722 pause_loop_monitor_(NULL), |
712 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_INITIALIZERS) | 723 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_INITIALIZERS) |
713 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_INIT) | 724 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_INIT) |
714 reusable_handles_() { | 725 reusable_handles_() { |
715 flags_.CopyFrom(api_flags); | 726 flags_.CopyFrom(api_flags); |
716 set_vm_tag(VMTag::kEmbedderTagId); | 727 set_vm_tag(VMTag::kEmbedderTagId); |
(...skipping 917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1634 // Visit the tag table which is stored in the isolate. | 1645 // Visit the tag table which is stored in the isolate. |
1635 visitor->VisitPointer(reinterpret_cast<RawObject**>(&tag_table_)); | 1646 visitor->VisitPointer(reinterpret_cast<RawObject**>(&tag_table_)); |
1636 | 1647 |
1637 // Visit array of closures pending precompilation. | 1648 // Visit array of closures pending precompilation. |
1638 visitor->VisitPointer(reinterpret_cast<RawObject**>(&collected_closures_)); | 1649 visitor->VisitPointer(reinterpret_cast<RawObject**>(&collected_closures_)); |
1639 | 1650 |
1640 // Visit the deoptimized code array which is stored in the isolate. | 1651 // Visit the deoptimized code array which is stored in the isolate. |
1641 visitor->VisitPointer( | 1652 visitor->VisitPointer( |
1642 reinterpret_cast<RawObject**>(&deoptimized_code_array_)); | 1653 reinterpret_cast<RawObject**>(&deoptimized_code_array_)); |
1643 | 1654 |
| 1655 // Visit the pending service extension calls. |
| 1656 visitor->VisitPointer( |
| 1657 reinterpret_cast<RawObject**>(&pending_service_extension_calls_)); |
| 1658 |
| 1659 // Visit the registered service extension handlers. |
| 1660 visitor->VisitPointer( |
| 1661 reinterpret_cast<RawObject**>(®istered_service_extension_handlers_)); |
| 1662 |
1644 // Visit objects in the debugger. | 1663 // Visit objects in the debugger. |
1645 debugger()->VisitObjectPointers(visitor); | 1664 debugger()->VisitObjectPointers(visitor); |
1646 | 1665 |
1647 // Visit objects that are being used for deoptimization. | 1666 // Visit objects that are being used for deoptimization. |
1648 if (deopt_context() != NULL) { | 1667 if (deopt_context() != NULL) { |
1649 deopt_context()->VisitObjectPointers(visitor); | 1668 deopt_context()->VisitObjectPointers(visitor); |
1650 } | 1669 } |
1651 | 1670 |
1652 // Visit objects in thread registry (e.g., Dart stack, handles in zones). | 1671 // Visit objects in thread registry (e.g., Dart stack, handles in zones). |
1653 thread_registry()->VisitObjectPointers(visitor, validate_frames); | 1672 thread_registry()->VisitObjectPointers(visitor, validate_frames); |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1855 if (deoptimized_code.IsNull()) { | 1874 if (deoptimized_code.IsNull()) { |
1856 // Not tracking deoptimized code. | 1875 // Not tracking deoptimized code. |
1857 return; | 1876 return; |
1858 } | 1877 } |
1859 // TODO(johnmccutchan): Scan this array and the isolate's profile before | 1878 // TODO(johnmccutchan): Scan this array and the isolate's profile before |
1860 // old space GC and remove the keep_code flag. | 1879 // old space GC and remove the keep_code flag. |
1861 deoptimized_code.Add(code); | 1880 deoptimized_code.Add(code); |
1862 } | 1881 } |
1863 | 1882 |
1864 | 1883 |
| 1884 void Isolate::set_pending_service_extension_calls( |
| 1885 const GrowableObjectArray& value) { |
| 1886 pending_service_extension_calls_ = value.raw(); |
| 1887 } |
| 1888 |
| 1889 |
| 1890 void Isolate::set_registered_service_extension_handlers( |
| 1891 const GrowableObjectArray& value) { |
| 1892 registered_service_extension_handlers_ = value.raw(); |
| 1893 } |
| 1894 |
| 1895 |
| 1896 RawObject* Isolate::InvokePendingServiceExtensionCalls() { |
| 1897 GrowableObjectArray& calls = |
| 1898 GrowableObjectArray::Handle(GetAndClearPendingServiceExtensionCalls()); |
| 1899 if (calls.IsNull()) { |
| 1900 return Object::null(); |
| 1901 } |
| 1902 // Grab run function. |
| 1903 const Library& developer_lib = Library::Handle(Library::DeveloperLibrary()); |
| 1904 ASSERT(!developer_lib.IsNull()); |
| 1905 const Function& run_extension = Function::Handle( |
| 1906 developer_lib.LookupLocalFunction(Symbols::_runExtension())); |
| 1907 ASSERT(!run_extension.IsNull()); |
| 1908 |
| 1909 const Array& arguments = |
| 1910 Array::Handle(Array::New(kPendingEntrySize, Heap::kNew)); |
| 1911 Object& result = Object::Handle(); |
| 1912 String& method_name = String::Handle(); |
| 1913 Instance& closure = Instance::Handle(); |
| 1914 Array& parameter_keys = Array::Handle(); |
| 1915 Array& parameter_values = Array::Handle(); |
| 1916 Instance& reply_port = Instance::Handle(); |
| 1917 Instance& id = Instance::Handle(); |
| 1918 for (intptr_t i = 0; i < calls.Length(); i += kPendingEntrySize) { |
| 1919 // Grab arguments for call. |
| 1920 closure ^= calls.At(i + kPendingHandlerIndex); |
| 1921 ASSERT(!closure.IsNull()); |
| 1922 arguments.SetAt(kPendingHandlerIndex, closure); |
| 1923 method_name ^= calls.At(i + kPendingMethodNameIndex); |
| 1924 ASSERT(!method_name.IsNull()); |
| 1925 arguments.SetAt(kPendingMethodNameIndex, method_name); |
| 1926 parameter_keys ^= calls.At(i + kPendingKeysIndex); |
| 1927 ASSERT(!parameter_keys.IsNull()); |
| 1928 arguments.SetAt(kPendingKeysIndex, parameter_keys); |
| 1929 parameter_values ^= calls.At(i + kPendingValuesIndex); |
| 1930 ASSERT(!parameter_values.IsNull()); |
| 1931 arguments.SetAt(kPendingValuesIndex, parameter_values); |
| 1932 reply_port ^= calls.At(i + kPendingReplyPortIndex); |
| 1933 ASSERT(!reply_port.IsNull()); |
| 1934 arguments.SetAt(kPendingReplyPortIndex, reply_port); |
| 1935 id ^= calls.At(i + kPendingIdIndex); |
| 1936 arguments.SetAt(kPendingIdIndex, id); |
| 1937 |
| 1938 result = DartEntry::InvokeFunction(run_extension, arguments); |
| 1939 if (result.IsError()) { |
| 1940 if (result.IsUnwindError()) { |
| 1941 // Propagate the unwind error. Remaining service extension calls |
| 1942 // are dropped. |
| 1943 return result.raw(); |
| 1944 } else { |
| 1945 // Send error back over the protocol. |
| 1946 Service::PostError(method_name, |
| 1947 parameter_keys, |
| 1948 parameter_values, |
| 1949 reply_port, |
| 1950 id, |
| 1951 Error::Cast(result)); |
| 1952 } |
| 1953 } |
| 1954 result = DartLibraryCalls::DrainMicrotaskQueue(); |
| 1955 if (result.IsError()) { |
| 1956 return result.raw(); |
| 1957 } |
| 1958 } |
| 1959 return Object::null(); |
| 1960 } |
| 1961 |
| 1962 |
| 1963 RawGrowableObjectArray* Isolate::GetAndClearPendingServiceExtensionCalls() { |
| 1964 RawGrowableObjectArray* r = pending_service_extension_calls_; |
| 1965 pending_service_extension_calls_ = GrowableObjectArray::null(); |
| 1966 return r; |
| 1967 } |
| 1968 |
| 1969 |
| 1970 void Isolate::AppendServiceExtensionCall(const Instance& closure, |
| 1971 const String& method_name, |
| 1972 const Array& parameter_keys, |
| 1973 const Array& parameter_values, |
| 1974 const Instance& reply_port, |
| 1975 const Instance& id) { |
| 1976 GrowableObjectArray& calls = |
| 1977 GrowableObjectArray::Handle(pending_service_extension_calls()); |
| 1978 if (calls.IsNull()) { |
| 1979 calls ^= GrowableObjectArray::New(); |
| 1980 ASSERT(!calls.IsNull()); |
| 1981 set_pending_service_extension_calls(calls); |
| 1982 } |
| 1983 ASSERT(kPendingHandlerIndex == 0); |
| 1984 calls.Add(closure); |
| 1985 ASSERT(kPendingMethodNameIndex == 1); |
| 1986 calls.Add(method_name); |
| 1987 ASSERT(kPendingKeysIndex == 2); |
| 1988 calls.Add(parameter_keys); |
| 1989 ASSERT(kPendingValuesIndex == 3); |
| 1990 calls.Add(parameter_values); |
| 1991 ASSERT(kPendingReplyPortIndex == 4); |
| 1992 calls.Add(reply_port); |
| 1993 ASSERT(kPendingIdIndex == 5); |
| 1994 calls.Add(id); |
| 1995 } |
| 1996 |
| 1997 |
| 1998 // This function is written in C++ and not Dart because we must do this |
| 1999 // operation atomically in the face of random OOB messages. Do not port |
| 2000 // to Dart code unless you can ensure that the operations will can be |
| 2001 // done atomically. |
| 2002 void Isolate::RegisterServiceExtensionHandler(const String& name, |
| 2003 const Instance& closure) { |
| 2004 GrowableObjectArray& handlers = |
| 2005 GrowableObjectArray::Handle(registered_service_extension_handlers()); |
| 2006 if (handlers.IsNull()) { |
| 2007 handlers ^= GrowableObjectArray::New(Heap::kOld); |
| 2008 set_registered_service_extension_handlers(handlers); |
| 2009 } |
| 2010 #if defined(DEBUG) |
| 2011 { |
| 2012 // Sanity check. |
| 2013 const Instance& existing_handler = |
| 2014 Instance::Handle(LookupServiceExtensionHandler(name)); |
| 2015 ASSERT(existing_handler.IsNull()); |
| 2016 } |
| 2017 #endif |
| 2018 ASSERT(kRegisteredNameIndex == 0); |
| 2019 handlers.Add(name, Heap::kOld); |
| 2020 ASSERT(kRegisteredHandlerIndex == 1); |
| 2021 handlers.Add(closure, Heap::kOld); |
| 2022 } |
| 2023 |
| 2024 |
| 2025 // This function is written in C++ and not Dart because we must do this |
| 2026 // operation atomically in the face of random OOB messages. Do not port |
| 2027 // to Dart code unless you can ensure that the operations will can be |
| 2028 // done atomically. |
| 2029 RawInstance* Isolate::LookupServiceExtensionHandler(const String& name) { |
| 2030 const GrowableObjectArray& handlers = |
| 2031 GrowableObjectArray::Handle(registered_service_extension_handlers()); |
| 2032 if (handlers.IsNull()) { |
| 2033 return Instance::null(); |
| 2034 } |
| 2035 String& handler_name = String::Handle(); |
| 2036 for (intptr_t i = 0; i < handlers.Length(); i += kRegisteredEntrySize) { |
| 2037 handler_name ^= handlers.At(i + kRegisteredNameIndex); |
| 2038 ASSERT(!handler_name.IsNull()); |
| 2039 if (handler_name.Equals(name)) { |
| 2040 return Instance::RawCast(handlers.At(i + kRegisteredHandlerIndex)); |
| 2041 } |
| 2042 } |
| 2043 return Instance::null(); |
| 2044 } |
| 2045 |
| 2046 |
1865 void Isolate::WakePauseEventHandler(Dart_Isolate isolate) { | 2047 void Isolate::WakePauseEventHandler(Dart_Isolate isolate) { |
1866 Isolate* iso = reinterpret_cast<Isolate*>(isolate); | 2048 Isolate* iso = reinterpret_cast<Isolate*>(isolate); |
1867 MonitorLocker ml(iso->pause_loop_monitor_); | 2049 MonitorLocker ml(iso->pause_loop_monitor_); |
1868 ml.Notify(); | 2050 ml.Notify(); |
1869 } | 2051 } |
1870 | 2052 |
1871 | 2053 |
1872 void Isolate::PauseEventHandler() { | 2054 void Isolate::PauseEventHandler() { |
1873 // We are stealing a pause event (like a breakpoint) from the | 2055 // We are stealing a pause event (like a breakpoint) from the |
1874 // embedder. We don't know what kind of thread we are on -- it | 2056 // embedder. We don't know what kind of thread we are on -- it |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2170 serialized_message_, serialized_message_len_); | 2352 serialized_message_, serialized_message_len_); |
2171 } | 2353 } |
2172 | 2354 |
2173 | 2355 |
2174 void IsolateSpawnState::Cleanup() { | 2356 void IsolateSpawnState::Cleanup() { |
2175 SwitchIsolateScope switch_scope(I); | 2357 SwitchIsolateScope switch_scope(I); |
2176 Dart::ShutdownIsolate(); | 2358 Dart::ShutdownIsolate(); |
2177 } | 2359 } |
2178 | 2360 |
2179 } // namespace dart | 2361 } // namespace dart |
OLD | NEW |