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

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

Issue 300223011: - Add possibility to redirect messages if they were not delivered. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 6 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
« no previous file with comments | « no previous file | 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 "lib/mirrors.h" 10 #include "lib/mirrors.h"
(...skipping 27 matching lines...) Expand all
38 namespace dart { 38 namespace dart {
39 39
40 DEFINE_FLAG(bool, trace_isolates, false, 40 DEFINE_FLAG(bool, trace_isolates, false,
41 "Trace isolate creation and shut down."); 41 "Trace isolate creation and shut down.");
42 DEFINE_FLAG(bool, pause_isolates_on_start, false, 42 DEFINE_FLAG(bool, pause_isolates_on_start, false,
43 "Pause isolates before starting."); 43 "Pause isolates before starting.");
44 DEFINE_FLAG(bool, pause_isolates_on_exit, false, 44 DEFINE_FLAG(bool, pause_isolates_on_exit, false,
45 "Pause isolates exiting."); 45 "Pause isolates exiting.");
46 46
47 47
48 // Quick access to the locally defined isolate() method.
49 #define I (isolate())
50
51
48 void Isolate::RegisterClass(const Class& cls) { 52 void Isolate::RegisterClass(const Class& cls) {
49 class_table()->Register(cls); 53 class_table()->Register(cls);
50 } 54 }
51 55
52 56
53 void Isolate::RegisterClassAt(intptr_t index, const Class& cls) { 57 void Isolate::RegisterClassAt(intptr_t index, const Class& cls) {
54 class_table()->RegisterAt(index, cls); 58 class_table()->RegisterAt(index, cls);
55 } 59 }
56 60
57 61
58 void Isolate::ValidateClassTable() { 62 void Isolate::ValidateClassTable() {
59 class_table()->Validate(); 63 class_table()->Validate();
60 } 64 }
61 65
62 66
63 class IsolateMessageHandler : public MessageHandler { 67 class IsolateMessageHandler : public MessageHandler {
64 public: 68 public:
65 explicit IsolateMessageHandler(Isolate* isolate); 69 explicit IsolateMessageHandler(Isolate* isolate);
66 ~IsolateMessageHandler(); 70 ~IsolateMessageHandler();
67 71
68 const char* name() const; 72 const char* name() const;
69 void MessageNotify(Message::Priority priority); 73 void MessageNotify(Message::Priority priority);
70 bool HandleMessage(Message* message); 74 bool HandleMessage(Message* message);
71 75
72 #if defined(DEBUG) 76 #if defined(DEBUG)
73 // Check that it is safe to access this handler. 77 // Check that it is safe to access this handler.
74 void CheckAccess(); 78 void CheckAccess();
75 #endif 79 #endif
76 bool IsCurrentIsolate() const; 80 bool IsCurrentIsolate() const;
77 virtual Isolate* GetIsolate() const { return isolate_; } 81 virtual Isolate* isolate() const { return isolate_; }
78 bool UnhandledExceptionCallbackHandler(const Object& message, 82 bool UnhandledExceptionCallbackHandler(const Object& message,
79 const UnhandledException& error); 83 const UnhandledException& error);
80 84
81 private: 85 private:
82 bool ProcessUnhandledException(const Object& message, const Error& result); 86 bool ProcessUnhandledException(const Object& message, const Error& result);
83 RawFunction* ResolveCallbackFunction(); 87 RawFunction* ResolveCallbackFunction();
84 Isolate* isolate_; 88 Isolate* isolate_;
85 }; 89 };
86 90
87 91
88 IsolateMessageHandler::IsolateMessageHandler(Isolate* isolate) 92 IsolateMessageHandler::IsolateMessageHandler(Isolate* isolate)
89 : isolate_(isolate) { 93 : isolate_(isolate) {
90 } 94 }
91 95
92 96
93 IsolateMessageHandler::~IsolateMessageHandler() { 97 IsolateMessageHandler::~IsolateMessageHandler() {
94 } 98 }
95 99
96 const char* IsolateMessageHandler::name() const { 100 const char* IsolateMessageHandler::name() const {
97 return isolate_->name(); 101 return isolate_->name();
98 } 102 }
99 103
100 104
101 void IsolateMessageHandler::MessageNotify(Message::Priority priority) { 105 void IsolateMessageHandler::MessageNotify(Message::Priority priority) {
102 if (priority >= Message::kOOBPriority) { 106 if (priority >= Message::kOOBPriority) {
103 // Handle out of band messages even if the isolate is busy. 107 // Handle out of band messages even if the isolate is busy.
104 isolate_->ScheduleInterrupts(Isolate::kMessageInterrupt); 108 I->ScheduleInterrupts(Isolate::kMessageInterrupt);
105 } 109 }
106 Dart_MessageNotifyCallback callback = isolate_->message_notify_callback(); 110 Dart_MessageNotifyCallback callback = I->message_notify_callback();
107 if (callback) { 111 if (callback) {
108 // Allow the embedder to handle message notification. 112 // Allow the embedder to handle message notification.
109 (*callback)(Api::CastIsolate(isolate_)); 113 (*callback)(Api::CastIsolate(I));
110 } 114 }
111 } 115 }
112 116
113 117
114 bool IsolateMessageHandler::HandleMessage(Message* message) { 118 bool IsolateMessageHandler::HandleMessage(Message* message) {
115 StartIsolateScope start_scope(isolate_); 119 StartIsolateScope start_scope(I);
116 StackZone zone(isolate_); 120 StackZone zone(I);
117 HandleScope handle_scope(isolate_); 121 HandleScope handle_scope(I);
118 // TODO(turnidge): Rework collection total dart execution. This can 122 // TODO(turnidge): Rework collection total dart execution. This can
119 // overcount when other things (gc, compilation) are active. 123 // overcount when other things (gc, compilation) are active.
120 TIMERSCOPE(isolate_, time_dart_execution); 124 TIMERSCOPE(isolate_, time_dart_execution);
121 125
122 // If the message is in band we lookup the handler to dispatch to. If the 126 // If the message is in band we lookup the handler to dispatch to. If the
123 // receive port was closed, we drop the message without deserializing it. 127 // receive port was closed, we drop the message without deserializing it.
124 Object& msg_handler = Object::Handle(); 128 Object& msg_handler = Object::Handle(I);
125 if (!message->IsOOB()) { 129 if (!message->IsOOB()) {
126 msg_handler = DartLibraryCalls::LookupHandler(message->dest_port()); 130 msg_handler = DartLibraryCalls::LookupHandler(message->dest_port());
127 if (msg_handler.IsError()) { 131 if (msg_handler.IsError()) {
128 return ProcessUnhandledException(Object::null_instance(), 132 return ProcessUnhandledException(Object::null_instance(),
129 Error::Cast(msg_handler)); 133 Error::Cast(msg_handler));
130 } 134 }
131 if (msg_handler.IsNull()) { 135 if (msg_handler.IsNull()) {
132 delete message; 136 // If the port has been closed then the message will be dropped at this
137 // point. Make sure to post to the delivery failure port in that case.
138 if (message->RedirectToDeliveryFailurePort()) {
139 PortMap::PostMessage(message);
140 } else {
141 delete message;
142 }
133 return true; 143 return true;
134 } 144 }
135 } 145 }
136 146
137 // Parse the message. 147 // Parse the message.
138 SnapshotReader reader(message->data(), message->len(), 148 SnapshotReader reader(message->data(), message->len(), Snapshot::kMessage, I);
139 Snapshot::kMessage, Isolate::Current()); 149 const Object& msg_obj = Object::Handle(I, reader.ReadObject());
140 const Object& msg_obj = Object::Handle(reader.ReadObject());
141 if (msg_obj.IsError()) { 150 if (msg_obj.IsError()) {
142 // An error occurred while reading the message. 151 // An error occurred while reading the message.
143 return ProcessUnhandledException(Object::null_instance(), 152 return ProcessUnhandledException(Object::null_instance(),
144 Error::Cast(msg_obj)); 153 Error::Cast(msg_obj));
145 } 154 }
146 if (!msg_obj.IsNull() && !msg_obj.IsInstance()) { 155 if (!msg_obj.IsNull() && !msg_obj.IsInstance()) {
147 // TODO(turnidge): We need to decide what an isolate does with 156 // TODO(turnidge): We need to decide what an isolate does with
148 // malformed messages. If they (eventually) come from a remote 157 // malformed messages. If they (eventually) come from a remote
149 // machine, then it might make sense to drop the message entirely. 158 // machine, then it might make sense to drop the message entirely.
150 // In the case that the message originated locally, which is 159 // In the case that the message originated locally, which is
151 // always true for now, then this should never occur. 160 // always true for now, then this should never occur.
152 UNREACHABLE(); 161 UNREACHABLE();
153 } 162 }
154 163
155 Instance& msg = Instance::Handle(); 164 Instance& msg = Instance::Handle(I);
156 msg ^= msg_obj.raw(); // Can't use Instance::Cast because may be null. 165 msg ^= msg_obj.raw(); // Can't use Instance::Cast because may be null.
157 166
158 bool success = true; 167 bool success = true;
159 if (message->IsOOB()) { 168 if (message->IsOOB()) {
160 Service::HandleIsolateMessage(isolate_, msg); 169 ASSERT(msg.IsArray());
170 const Object& oob_tag = Object::Handle(I, Array::Cast(msg).At(0));
171 ASSERT(oob_tag.IsSmi());
172 switch (Smi::Cast(oob_tag).Value()) {
173 case Message::kServiceOOBMsg: {
174 Service::HandleIsolateMessage(I, msg);
175 break;
176 }
177 default: {
178 UNREACHABLE();
179 break;
180 }
181 }
161 } else { 182 } else {
162 const Object& result = Object::Handle( 183 const Object& result = Object::Handle(I,
163 DartLibraryCalls::HandleMessage(msg_handler, msg)); 184 DartLibraryCalls::HandleMessage(msg_handler, msg));
164 if (result.IsError()) { 185 if (result.IsError()) {
165 success = ProcessUnhandledException(msg, Error::Cast(result)); 186 success = ProcessUnhandledException(msg, Error::Cast(result));
166 } else { 187 } else {
167 ASSERT(result.IsNull()); 188 ASSERT(result.IsNull());
168 } 189 }
169 } 190 }
170 delete message; 191 delete message;
171 return success; 192 return success;
172 } 193 }
173 194
174 195
175 RawFunction* IsolateMessageHandler::ResolveCallbackFunction() { 196 RawFunction* IsolateMessageHandler::ResolveCallbackFunction() {
176 ASSERT(isolate_->object_store()->unhandled_exception_handler() != NULL); 197 ASSERT(I->object_store()->unhandled_exception_handler() != NULL);
177 String& callback_name = String::Handle(isolate_); 198 String& callback_name = String::Handle(I);
178 if (isolate_->object_store()->unhandled_exception_handler() != 199 if (I->object_store()->unhandled_exception_handler() != String::null()) {
179 String::null()) { 200 callback_name = I->object_store()->unhandled_exception_handler();
180 callback_name = isolate_->object_store()->unhandled_exception_handler();
181 } else { 201 } else {
182 callback_name = String::New("_unhandledExceptionCallback"); 202 callback_name = String::New("_unhandledExceptionCallback");
183 } 203 }
184 Library& lib = 204 Library& lib = Library::Handle(I, I->object_store()->isolate_library());
185 Library::Handle(isolate_, isolate_->object_store()->isolate_library()); 205 Function& func = Function::Handle(I, lib.LookupLocalFunction(callback_name));
186 Function& func =
187 Function::Handle(isolate_, lib.LookupLocalFunction(callback_name));
188 if (func.IsNull()) { 206 if (func.IsNull()) {
189 lib = isolate_->object_store()->root_library(); 207 lib = I->object_store()->root_library();
190 // Note: bootstrap code in builtin library may attempt to resolve a 208 // Note: bootstrap code in builtin library may attempt to resolve a
191 // callback function before the script is fully loaded, in which case 209 // callback function before the script is fully loaded, in which case
192 // the root library may not be registered yet. 210 // the root library may not be registered yet.
193 if (!lib.IsNull()) { 211 if (!lib.IsNull()) {
194 func = lib.LookupLocalFunction(callback_name); 212 func = lib.LookupLocalFunction(callback_name);
195 } 213 }
196 } 214 }
197 return func.raw(); 215 return func.raw();
198 } 216 }
199 217
200 218
201 bool IsolateMessageHandler::UnhandledExceptionCallbackHandler( 219 bool IsolateMessageHandler::UnhandledExceptionCallbackHandler(
202 const Object& message, const UnhandledException& error) { 220 const Object& message, const UnhandledException& error) {
203 const Instance& cause = Instance::Handle(isolate_, error.exception()); 221 const Instance& cause = Instance::Handle(I, error.exception());
204 const Instance& stacktrace = 222 const Instance& stacktrace = Instance::Handle(I, error.stacktrace());
205 Instance::Handle(isolate_, error.stacktrace());
206 223
207 // Wrap these args into an IsolateUncaughtException object. 224 // Wrap these args into an IsolateUncaughtException object.
208 const Array& exception_args = Array::Handle(Array::New(3)); 225 const Array& exception_args = Array::Handle(I, Array::New(3));
209 exception_args.SetAt(0, message); 226 exception_args.SetAt(0, message);
210 exception_args.SetAt(1, cause); 227 exception_args.SetAt(1, cause);
211 exception_args.SetAt(2, stacktrace); 228 exception_args.SetAt(2, stacktrace);
212 const Object& exception = 229 const Object& exception = Object::Handle(I,
213 Object::Handle(isolate_, 230 Exceptions::Create(Exceptions::kIsolateUnhandledException,
214 Exceptions::Create(Exceptions::kIsolateUnhandledException, 231 exception_args));
215 exception_args));
216 if (exception.IsError()) { 232 if (exception.IsError()) {
217 return false; 233 return false;
218 } 234 }
219 ASSERT(exception.IsInstance()); 235 ASSERT(exception.IsInstance());
220 236
221 // Invoke script's callback function. 237 // Invoke script's callback function.
222 Object& function = Object::Handle(isolate_, ResolveCallbackFunction()); 238 Object& function = Object::Handle(I, ResolveCallbackFunction());
223 if (function.IsNull() || function.IsError()) { 239 if (function.IsNull() || function.IsError()) {
224 return false; 240 return false;
225 } 241 }
226 const Array& callback_args = Array::Handle(Array::New(1)); 242 const Array& callback_args = Array::Handle(I, Array::New(1));
227 callback_args.SetAt(0, exception); 243 callback_args.SetAt(0, exception);
228 const Object& result = 244 const Object& result = Object::Handle(I,
229 Object::Handle(DartEntry::InvokeFunction(Function::Cast(function), 245 DartEntry::InvokeFunction(Function::Cast(function), callback_args));
230 callback_args));
231 if (result.IsError()) { 246 if (result.IsError()) {
232 const Error& err = Error::Cast(result); 247 const Error& err = Error::Cast(result);
233 OS::PrintErr("failed calling unhandled exception callback: %s\n", 248 OS::PrintErr("failed calling unhandled exception callback: %s\n",
234 err.ToErrorCString()); 249 err.ToErrorCString());
235 return false; 250 return false;
236 } 251 }
237 252
238 ASSERT(result.IsBool()); 253 ASSERT(result.IsBool());
239 bool continue_from_exception = Bool::Cast(result).value(); 254 bool continue_from_exception = Bool::Cast(result).value();
240 if (continue_from_exception) { 255 if (continue_from_exception) {
241 isolate_->object_store()->clear_sticky_error(); 256 I->object_store()->clear_sticky_error();
242 } 257 }
243 return continue_from_exception; 258 return continue_from_exception;
244 } 259 }
245 260
246 #if defined(DEBUG) 261 #if defined(DEBUG)
247 void IsolateMessageHandler::CheckAccess() { 262 void IsolateMessageHandler::CheckAccess() {
248 ASSERT(IsCurrentIsolate()); 263 ASSERT(IsCurrentIsolate());
249 } 264 }
250 #endif 265 #endif
251 266
252 267
253 bool IsolateMessageHandler::IsCurrentIsolate() const { 268 bool IsolateMessageHandler::IsCurrentIsolate() const {
254 return (isolate_ == Isolate::Current()); 269 return (I == Isolate::Current());
255 } 270 }
256 271
257 272
258 bool IsolateMessageHandler::ProcessUnhandledException( 273 bool IsolateMessageHandler::ProcessUnhandledException(
259 const Object& message, const Error& result) { 274 const Object& message, const Error& result) {
260 if (result.IsUnhandledException()) { 275 if (result.IsUnhandledException()) {
261 // Invoke the isolate's uncaught exception handler, if it exists. 276 // Invoke the isolate's uncaught exception handler, if it exists.
262 const UnhandledException& error = UnhandledException::Cast(result); 277 const UnhandledException& error = UnhandledException::Cast(result);
263 RawInstance* exception = error.exception(); 278 RawInstance* exception = error.exception();
264 if ((exception != isolate_->object_store()->out_of_memory()) && 279 if ((exception != I->object_store()->out_of_memory()) &&
265 (exception != isolate_->object_store()->stack_overflow())) { 280 (exception != I->object_store()->stack_overflow())) {
266 if (UnhandledExceptionCallbackHandler(message, error)) { 281 if (UnhandledExceptionCallbackHandler(message, error)) {
267 return true; 282 return true;
268 } 283 }
269 } 284 }
270 } 285 }
271 286
272 // Invoke the isolate's unhandled exception callback if there is one. 287 // Invoke the isolate's unhandled exception callback if there is one.
273 if (Isolate::UnhandledExceptionCallback() != NULL) { 288 if (Isolate::UnhandledExceptionCallback() != NULL) {
274 Dart_EnterScope(); 289 Dart_EnterScope();
275 Dart_Handle error = Api::NewHandle(isolate_, result.raw()); 290 Dart_Handle error = Api::NewHandle(I, result.raw());
276 (Isolate::UnhandledExceptionCallback())(error); 291 (Isolate::UnhandledExceptionCallback())(error);
277 Dart_ExitScope(); 292 Dart_ExitScope();
278 } 293 }
279 294
280 isolate_->object_store()->set_sticky_error(result); 295 I->object_store()->set_sticky_error(result);
281 return false; 296 return false;
282 } 297 }
283 298
284 299
285 #if defined(DEBUG) 300 #if defined(DEBUG)
286 // static 301 // static
287 void BaseIsolate::AssertCurrent(BaseIsolate* isolate) { 302 void BaseIsolate::AssertCurrent(BaseIsolate* isolate) {
288 ASSERT(isolate == Isolate::Current()); 303 ASSERT(isolate == Isolate::Current());
289 } 304 }
290 #endif // defined(DEBUG) 305 #endif // defined(DEBUG)
(...skipping 915 matching lines...) Expand 10 before | Expand all | Expand 10 after
1206 return func.raw(); 1221 return func.raw();
1207 } 1222 }
1208 1223
1209 1224
1210 void IsolateSpawnState::Cleanup() { 1225 void IsolateSpawnState::Cleanup() {
1211 SwitchIsolateScope switch_scope(isolate()); 1226 SwitchIsolateScope switch_scope(isolate());
1212 Dart::ShutdownIsolate(); 1227 Dart::ShutdownIsolate();
1213 } 1228 }
1214 1229
1215 } // namespace dart 1230 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/json_stream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698