Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(375)

Side by Side Diff: runtime/vm/isolate.cc

Issue 1299493007: Rework service extensions to be safe (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/isolate.h ('k') | runtime/vm/json_stream.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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**>(&registered_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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/isolate.h ('k') | runtime/vm/json_stream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698