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

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

Issue 881373002: Implemented more of the Isolate API (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 9 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 | Annotate | Revision Log
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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 bool IsCurrentIsolate() const; 122 bool IsCurrentIsolate() const;
123 virtual Isolate* isolate() const { return isolate_; } 123 virtual Isolate* isolate() const { return isolate_; }
124 124
125 private: 125 private:
126 // Keep in sync with isolate_patch.dart. 126 // Keep in sync with isolate_patch.dart.
127 enum { 127 enum {
128 kPauseMsg = 1, 128 kPauseMsg = 1,
129 kResumeMsg = 2, 129 kResumeMsg = 2,
130 kPingMsg = 3, 130 kPingMsg = 3,
131 kKillMsg = 4, 131 kKillMsg = 4,
132 kAddExitMsg = 5,
133 kDelExitMsg = 6,
134 kAddErrorMsg = 7,
135 kDelErrorMsg = 8,
136 kErrorFatalMsg = 9,
132 137
133 kImmediateAction = 0, 138 kImmediateAction = 0,
134 kBeforeNextEventAction = 1, 139 kBeforeNextEventAction = 1,
135 kAsEventAction = 2 140 kAsEventAction = 2
siva 2015/03/06 23:56:04 can these be in two enum blocks seems confusing to
Ivan Posva 2015/03/07 04:20:39 Done.
136 }; 141 };
137 142
138 // A result of false indicates that the isolate should terminate the 143 // A result of false indicates that the isolate should terminate the
139 // processing of further events. 144 // processing of further events.
140 bool HandleLibMessage(const Array& message); 145 bool HandleLibMessage(const Array& message);
141 146
142 bool ProcessUnhandledException(const Error& result); 147 bool ProcessUnhandledException(const Error& result);
143 Isolate* isolate_; 148 Isolate* isolate_;
144 }; 149 };
145 150
(...skipping 11 matching lines...) Expand all
157 } 162 }
158 163
159 164
160 // Isolate library OOB messages are fixed sized arrays which have the 165 // Isolate library OOB messages are fixed sized arrays which have the
161 // following format: 166 // following format:
162 // [ OOB dispatch, Isolate library dispatch, <message specific data> ] 167 // [ OOB dispatch, Isolate library dispatch, <message specific data> ]
163 bool IsolateMessageHandler::HandleLibMessage(const Array& message) { 168 bool IsolateMessageHandler::HandleLibMessage(const Array& message) {
164 if (message.Length() < 2) return true; 169 if (message.Length() < 2) return true;
165 const Object& type = Object::Handle(I, message.At(1)); 170 const Object& type = Object::Handle(I, message.At(1));
166 if (!type.IsSmi()) return true; 171 if (!type.IsSmi()) return true;
167 const Smi& msg_type = Smi::Cast(type); 172 const intptr_t msg_type = Smi::Cast(type).Value();
168 switch (msg_type.Value()) { 173 switch (msg_type) {
169 case kPauseMsg: { 174 case kPauseMsg: {
170 // [ OOB, kPauseMsg, pause capability, resume capability ] 175 // [ OOB, kPauseMsg, pause capability, resume capability ]
171 if (message.Length() != 4) return true; 176 if (message.Length() != 4) return true;
172 Object& obj = Object::Handle(I, message.At(2)); 177 Object& obj = Object::Handle(I, message.At(2));
173 if (!I->VerifyPauseCapability(obj)) return true; 178 if (!I->VerifyPauseCapability(obj)) return true;
174 obj = message.At(3); 179 obj = message.At(3);
175 if (!obj.IsCapability()) return true; 180 if (!obj.IsCapability()) return true;
176 if (I->AddResumeCapability(Capability::Cast(obj))) { 181 if (I->AddResumeCapability(Capability::Cast(obj))) {
177 increment_paused(); 182 increment_paused();
178 } 183 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 uint8_t* data = NULL; 250 uint8_t* data = NULL;
246 intptr_t len = 0; 251 intptr_t len = 0;
247 SerializeObject(message, &data, &len, false); 252 SerializeObject(message, &data, &len, false);
248 this->PostMessage(new Message(Message::kIllegalPort, 253 this->PostMessage(new Message(Message::kIllegalPort,
249 data, len, 254 data, len,
250 Message::kNormalPriority), 255 Message::kNormalPriority),
251 priority == kBeforeNextEventAction /* at_head */); 256 priority == kBeforeNextEventAction /* at_head */);
252 } 257 }
253 break; 258 break;
254 } 259 }
260 case kAddExitMsg:
261 case kDelExitMsg:
262 case kAddErrorMsg:
263 case kDelErrorMsg: {
264 // [ OOB, msg, listener port ]
265 if (message.Length() != 3) return true;
266 Object& obj = Object::Handle(I, message.At(2));
siva 2015/03/06 23:56:04 const Object& obj = ...;
Ivan Posva 2015/03/07 04:20:39 Done.
267 if (!obj.IsSendPort()) return true;
siva 2015/03/06 23:56:04 Did we change the C++ style here, we always used t
Ivan Posva 2015/03/07 04:20:39 There are 2628 places in the project that use the
268 const SendPort& listener = SendPort::Cast(obj);
269 switch (msg_type) {
270 case kAddExitMsg:
271 I->AddExitListener(listener);
272 break;
273 case kDelExitMsg:
274 I->RemoveExitListener(listener);
275 break;
276 case kAddErrorMsg:
277 I->AddErrorListener(listener);
278 break;
279 case kDelErrorMsg:
280 I->RemoveErrorListener(listener);
281 break;
282 default:
283 UNREACHABLE();
284 }
285 break;
286 }
287 case kErrorFatalMsg: {
288 // [ OOB, kErrorFatalMsg, terminate capability, val ]
289 if (message.Length() != 4) return true;
290 // Check that the terminate capability has been passed correctly.
291 Object& obj = Object::Handle(I, message.At(2));
292 if (!I->VerifyTerminateCapability(obj)) return true;
293 // Get the value to be set.
294 obj = message.At(3);
295 if (!obj.IsBool()) return true;
296 I->SetErrorsFatal(Bool::Cast(obj).value());
297 break;
298 }
255 #if defined(DEBUG) 299 #if defined(DEBUG)
256 // Malformed OOB messages are silently ignored in release builds. 300 // Malformed OOB messages are silently ignored in release builds.
257 default: 301 default:
258 UNREACHABLE(); 302 UNREACHABLE();
259 break; 303 break;
260 #endif // defined(DEBUG) 304 #endif // defined(DEBUG)
261 } 305 }
262 return true; 306 return true;
263 } 307 }
264 308
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 } 454 }
411 455
412 // Invoke the isolate's unhandled exception callback if there is one. 456 // Invoke the isolate's unhandled exception callback if there is one.
413 if (Isolate::UnhandledExceptionCallback() != NULL) { 457 if (Isolate::UnhandledExceptionCallback() != NULL) {
414 Dart_EnterScope(); 458 Dart_EnterScope();
415 Dart_Handle error = Api::NewHandle(I, result.raw()); 459 Dart_Handle error = Api::NewHandle(I, result.raw());
416 (Isolate::UnhandledExceptionCallback())(error); 460 (Isolate::UnhandledExceptionCallback())(error);
417 Dart_ExitScope(); 461 Dart_ExitScope();
418 } 462 }
419 463
420 I->object_store()->set_sticky_error(result); 464 // Generate the error and stacktrace strings for the error message.
421 return false; 465 String& exc_str = String::Handle(I);
466 String& stacktrace_str = String::Handle(I);
467 if (result.IsUnhandledException()) {
468 const UnhandledException& uhe = UnhandledException::Cast(result);
469 const Instance& exception = Instance::Handle(I, uhe.exception());
470 Object& tmp = Object::Handle(I);
471 tmp = DartLibraryCalls::ToString(exception);
472 if (!tmp.IsString()) {
473 tmp = String::New(exception.ToCString());
474 }
475 exc_str ^= tmp.raw();
476
477 const Instance& stacktrace = Instance::Handle(I, uhe.stacktrace());
478 tmp = DartLibraryCalls::ToString(stacktrace);
479 if (!tmp.IsString()) {
480 tmp = String::New(stacktrace.ToCString());
481 }
482 stacktrace_str ^= tmp.raw();;
483 } else {
484 exc_str = String::New(result.ToErrorCString());
485 }
486 I->NotifyErrorListeners(exc_str, stacktrace_str);
487
488 if (I->ErrorsFatal()) {
489 I->object_store()->set_sticky_error(result);
490 return false;
491 }
492 return true;
422 } 493 }
423 494
424 495
425 #if defined(DEBUG) 496 #if defined(DEBUG)
426 // static 497 // static
427 void BaseIsolate::AssertCurrent(BaseIsolate* isolate) { 498 void BaseIsolate::AssertCurrent(BaseIsolate* isolate) {
428 ASSERT(isolate == Isolate::Current()); 499 ASSERT(isolate == Isolate::Current());
429 } 500 }
430 #endif // defined(DEBUG) 501 #endif // defined(DEBUG)
431 502
(...skipping 10 matching lines...) Expand all
442 Isolate::Isolate() 513 Isolate::Isolate()
443 : vm_tag_(0), 514 : vm_tag_(0),
444 store_buffer_(), 515 store_buffer_(),
445 message_notify_callback_(NULL), 516 message_notify_callback_(NULL),
446 name_(NULL), 517 name_(NULL),
447 start_time_(OS::GetCurrentTimeMicros()), 518 start_time_(OS::GetCurrentTimeMicros()),
448 main_port_(0), 519 main_port_(0),
449 origin_id_(0), 520 origin_id_(0),
450 pause_capability_(0), 521 pause_capability_(0),
451 terminate_capability_(0), 522 terminate_capability_(0),
523 errors_fatal_(true),
452 heap_(NULL), 524 heap_(NULL),
453 object_store_(NULL), 525 object_store_(NULL),
454 top_exit_frame_info_(0), 526 top_exit_frame_info_(0),
455 init_callback_data_(NULL), 527 init_callback_data_(NULL),
456 environment_callback_(NULL), 528 environment_callback_(NULL),
457 library_tag_handler_(NULL), 529 library_tag_handler_(NULL),
458 api_state_(NULL), 530 api_state_(NULL),
459 stub_code_(NULL), 531 stub_code_(NULL),
460 debugger_(NULL), 532 debugger_(NULL),
461 single_step_(false), 533 single_step_(false),
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 Isolate::Isolate(Isolate* original) 579 Isolate::Isolate(Isolate* original)
508 : vm_tag_(0), 580 : vm_tag_(0),
509 store_buffer_(true), 581 store_buffer_(true),
510 class_table_(original->class_table()), 582 class_table_(original->class_table()),
511 message_notify_callback_(NULL), 583 message_notify_callback_(NULL),
512 name_(NULL), 584 name_(NULL),
513 start_time_(OS::GetCurrentTimeMicros()), 585 start_time_(OS::GetCurrentTimeMicros()),
514 main_port_(0), 586 main_port_(0),
515 pause_capability_(0), 587 pause_capability_(0),
516 terminate_capability_(0), 588 terminate_capability_(0),
589 errors_fatal_(true),
517 heap_(NULL), 590 heap_(NULL),
518 object_store_(NULL), 591 object_store_(NULL),
519 top_exit_frame_info_(0), 592 top_exit_frame_info_(0),
520 init_callback_data_(NULL), 593 init_callback_data_(NULL),
521 environment_callback_(NULL), 594 environment_callback_(NULL),
522 library_tag_handler_(NULL), 595 library_tag_handler_(NULL),
523 api_state_(NULL), 596 api_state_(NULL),
524 stub_code_(NULL), 597 stub_code_(NULL),
525 debugger_(NULL), 598 debugger_(NULL),
526 single_step_(false), 599 single_step_(false),
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 // Remove the matching capability from the list. 983 // Remove the matching capability from the list.
911 current = Capability::null(); 984 current = Capability::null();
912 caps.SetAt(i, current); 985 caps.SetAt(i, current);
913 return true; 986 return true;
914 } 987 }
915 } 988 }
916 return false; 989 return false;
917 } 990 }
918 991
919 992
993 // TODO(iposva): Remove duplicated code and start using some hash based
994 // structure instead of these linear lookups.
995 void Isolate::AddExitListener(const SendPort& listener) {
996 // Ensure a limit for the number of listeners remembered.
997 static const intptr_t kMaxListeners = kSmiMax / (6*kWordSize);
siva 2015/03/06 23:56:04 spaces 6 * kWOrdSize
Ivan Posva 2015/03/07 04:20:39 Done.
998
999 const GrowableObjectArray& listeners = GrowableObjectArray::Handle(
1000 this, object_store()->exit_listeners());
1001 SendPort& current = SendPort::Handle(this);
1002 intptr_t insertion_index = -1;
1003 for (intptr_t i = 0; i < listeners.Length(); i++) {
1004 current ^= listeners.At(i);
1005 if (current.IsNull()) {
1006 if (insertion_index < 0) {
1007 insertion_index = i;
1008 }
1009 } else if (current.Id() == listener.Id()) {
1010 return;
1011 }
1012 }
1013 if (insertion_index < 0) {
1014 if (listeners.Length() >= kMaxListeners) {
1015 // Cannot grow the array of listeners beyond its max. Additional
1016 // listeners are ignored. In practice will never happen as we will
1017 // run out of memory beforehand.
1018 return;
1019 }
1020 listeners.Add(listener);
1021 } else {
1022 listeners.SetAt(insertion_index, listener);
1023 }
1024 }
1025
1026
1027 void Isolate::RemoveExitListener(const SendPort& listener) {
1028 const GrowableObjectArray& listeners = GrowableObjectArray::Handle(
1029 this, object_store()->exit_listeners());
1030 SendPort& current = SendPort::Handle(this);
1031 for (intptr_t i = 0; i < listeners.Length(); i++) {
1032 current ^= listeners.At(i);
1033 if (!current.IsNull() && (current.Id() == listener.Id())) {
1034 // Remove the matching listener from the list.
1035 current = SendPort::null();
1036 listeners.SetAt(i, current);
1037 return;
1038 }
1039 }
1040 }
1041
1042
1043 void Isolate::NotifyExitListeners() {
1044 const GrowableObjectArray& listeners = GrowableObjectArray::Handle(
1045 this, this->object_store()->exit_listeners());
1046 SendPort& listener = SendPort::Handle(this);
1047 for (intptr_t i = 0; i < listeners.Length(); i++) {
1048 listener ^= listeners.At(i);
1049 if (!listener.IsNull()) {
1050 Dart_Port port_id = listener.Id();
1051 uint8_t* data = NULL;
1052 intptr_t len = 0;
1053 SerializeObject(Object::null_instance(), &data, &len, false);
1054 Message* msg = new Message(port_id, data, len, Message::kNormalPriority);
1055 PortMap::PostMessage(msg);
1056 }
1057 }
1058 }
1059
1060
1061 void Isolate::AddErrorListener(const SendPort& listener) {
1062 // Ensure a limit for the number of listeners remembered.
1063 static const intptr_t kMaxListeners = kSmiMax / (6*kWordSize);
1064
1065 const GrowableObjectArray& listeners = GrowableObjectArray::Handle(
1066 this, object_store()->error_listeners());
1067 SendPort& current = SendPort::Handle(this);
1068 intptr_t insertion_index = -1;
1069 for (intptr_t i = 0; i < listeners.Length(); i++) {
1070 current ^= listeners.At(i);
1071 if (current.IsNull()) {
1072 if (insertion_index < 0) {
1073 insertion_index = i;
1074 }
1075 } else if (current.Id() == listener.Id()) {
1076 return;
1077 }
1078 }
1079 if (insertion_index < 0) {
1080 if (listeners.Length() >= kMaxListeners) {
1081 // Cannot grow the array of listeners beyond its max. Additional
1082 // listeners are ignored. In practice will never happen as we will
1083 // run out of memory beforehand.
1084 return;
1085 }
1086 listeners.Add(listener);
1087 } else {
1088 listeners.SetAt(insertion_index, listener);
1089 }
1090 }
1091
1092
1093 void Isolate::RemoveErrorListener(const SendPort& listener) {
1094 const GrowableObjectArray& listeners = GrowableObjectArray::Handle(
1095 this, object_store()->error_listeners());
1096 SendPort& current = SendPort::Handle(this);
1097 for (intptr_t i = 0; i < listeners.Length(); i++) {
1098 current ^= listeners.At(i);
1099 if (!current.IsNull() && (current.Id() == listener.Id())) {
1100 // Remove the matching listener from the list.
1101 current = SendPort::null();
1102 listeners.SetAt(i, current);
1103 return;
1104 }
1105 }
1106 }
1107
1108
1109 void Isolate::NotifyErrorListeners(const String& msg,
1110 const String& stacktrace) {
1111 const Array& arr = Array::Handle(this, Array::New(2));
1112 arr.SetAt(0, msg);
1113 arr.SetAt(1, stacktrace);
1114 const GrowableObjectArray& listeners = GrowableObjectArray::Handle(
1115 this, this->object_store()->error_listeners());
1116 SendPort& listener = SendPort::Handle(this);
1117 for (intptr_t i = 0; i < listeners.Length(); i++) {
1118 listener ^= listeners.At(i);
1119 if (!listener.IsNull()) {
1120 Dart_Port port_id = listener.Id();
1121 uint8_t* data = NULL;
1122 intptr_t len = 0;
1123 SerializeObject(arr, &data, &len, false);
1124 Message* msg = new Message(port_id, data, len, Message::kNormalPriority);
1125 PortMap::PostMessage(msg);
1126 }
1127 }
1128 }
1129
1130
920 static void StoreError(Isolate* isolate, const Object& obj) { 1131 static void StoreError(Isolate* isolate, const Object& obj) {
921 ASSERT(obj.IsError()); 1132 ASSERT(obj.IsError());
922 isolate->object_store()->set_sticky_error(Error::Cast(obj)); 1133 isolate->object_store()->set_sticky_error(Error::Cast(obj));
923 } 1134 }
924 1135
925 1136
926 static bool RunIsolate(uword parameter) { 1137 static bool RunIsolate(uword parameter) {
927 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); 1138 Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
928 IsolateSpawnState* state = NULL; 1139 IsolateSpawnState* state = NULL;
929 { 1140 {
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
1142 // Remove this isolate from the list *before* we start tearing it down, to 1353 // Remove this isolate from the list *before* we start tearing it down, to
1143 // avoid exposing it in a state of decay. 1354 // avoid exposing it in a state of decay.
1144 RemoveIsolateFromList(this); 1355 RemoveIsolateFromList(this);
1145 1356
1146 // Create an area where we do have a zone and a handle scope so that we can 1357 // Create an area where we do have a zone and a handle scope so that we can
1147 // call VM functions while tearing this isolate down. 1358 // call VM functions while tearing this isolate down.
1148 { 1359 {
1149 StackZone stack_zone(this); 1360 StackZone stack_zone(this);
1150 HandleScope handle_scope(this); 1361 HandleScope handle_scope(this);
1151 1362
1363 // Notify exit listeners that this isolate is shutting down.
1364 NotifyExitListeners();
1365
1152 // Clean up debugger resources. 1366 // Clean up debugger resources.
1153 debugger()->Shutdown(); 1367 debugger()->Shutdown();
1154 1368
1155 // Close all the ports owned by this isolate. 1369 // Close all the ports owned by this isolate.
1156 PortMap::ClosePorts(message_handler()); 1370 PortMap::ClosePorts(message_handler());
1157 1371
1158 // Fail fast if anybody tries to post any more messsages to this isolate. 1372 // Fail fast if anybody tries to post any more messsages to this isolate.
1159 delete message_handler(); 1373 delete message_handler();
1160 set_message_handler(NULL); 1374 set_message_handler(NULL);
1161 1375
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after
1725 serialized_message_, serialized_message_len_); 1939 serialized_message_, serialized_message_len_);
1726 } 1940 }
1727 1941
1728 1942
1729 void IsolateSpawnState::Cleanup() { 1943 void IsolateSpawnState::Cleanup() {
1730 SwitchIsolateScope switch_scope(I); 1944 SwitchIsolateScope switch_scope(I);
1731 Dart::ShutdownIsolate(); 1945 Dart::ShutdownIsolate();
1732 } 1946 }
1733 1947
1734 } // namespace dart 1948 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698