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

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

Issue 800713002: - Implement Isolate.kill. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years 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
« runtime/vm/isolate.h ('K') | « runtime/vm/isolate.h ('k') | no next file » | 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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 virtual Isolate* isolate() const { return isolate_; } 99 virtual Isolate* isolate() const { return isolate_; }
100 bool UnhandledExceptionCallbackHandler(const Object& message, 100 bool UnhandledExceptionCallbackHandler(const Object& message,
101 const UnhandledException& error); 101 const UnhandledException& error);
102 102
103 private: 103 private:
104 // Keep in sync with isolate_patch.dart. 104 // Keep in sync with isolate_patch.dart.
105 enum { 105 enum {
106 kPauseMsg = 1, 106 kPauseMsg = 1,
107 kResumeMsg = 2, 107 kResumeMsg = 2,
108 kPingMsg = 3, 108 kPingMsg = 3,
109 kKillMsg = 4,
109 110
110 kImmediateAction = 0, 111 kImmediateAction = 0,
111 kBeforeNextEventAction = 1, 112 kBeforeNextEventAction = 1,
112 kAsEventAction = 2 113 kAsEventAction = 2
113 }; 114 };
114 115
115 void HandleLibMessage(const Array& message); 116 // A result of false indicates that the isolate should terminate the
117 // processing of further events.
118 bool HandleLibMessage(const Array& message);
siva 2014/12/13 00:24:05 Not for this CL but it might be more readable to h
Ivan Posva 2014/12/13 00:36:47 Seems like a plan.
119
116 bool ProcessUnhandledException(const Object& message, const Error& result); 120 bool ProcessUnhandledException(const Object& message, const Error& result);
117 RawFunction* ResolveCallbackFunction(); 121 RawFunction* ResolveCallbackFunction();
118 Isolate* isolate_; 122 Isolate* isolate_;
119 }; 123 };
120 124
121 125
122 IsolateMessageHandler::IsolateMessageHandler(Isolate* isolate) 126 IsolateMessageHandler::IsolateMessageHandler(Isolate* isolate)
123 : isolate_(isolate) { 127 : isolate_(isolate) {
124 } 128 }
125 129
126 130
127 IsolateMessageHandler::~IsolateMessageHandler() { 131 IsolateMessageHandler::~IsolateMessageHandler() {
128 } 132 }
129 133
130 const char* IsolateMessageHandler::name() const { 134 const char* IsolateMessageHandler::name() const {
131 return isolate_->name(); 135 return isolate_->name();
132 } 136 }
133 137
134 138
135 // Isolate library OOB messages are fixed sized arrays which have the 139 // Isolate library OOB messages are fixed sized arrays which have the
136 // following format: 140 // following format:
137 // [ OOB dispatch, Isolate library dispatch, <message specific data> ] 141 // [ OOB dispatch, Isolate library dispatch, <message specific data> ]
138 void IsolateMessageHandler::HandleLibMessage(const Array& message) { 142 bool IsolateMessageHandler::HandleLibMessage(const Array& message) {
139 if (message.Length() < 2) return; 143 if (message.Length() < 2) return true;
140 const Object& type = Object::Handle(I, message.At(1)); 144 const Object& type = Object::Handle(I, message.At(1));
141 if (!type.IsSmi()) return; 145 if (!type.IsSmi()) return true;
142 const Smi& msg_type = Smi::Cast(type); 146 const Smi& msg_type = Smi::Cast(type);
143 switch (msg_type.Value()) { 147 switch (msg_type.Value()) {
144 case kPauseMsg: { 148 case kPauseMsg: {
145 // [ OOB, kPauseMsg, pause capability, resume capability ] 149 // [ OOB, kPauseMsg, pause capability, resume capability ]
146 if (message.Length() != 4) return; 150 if (message.Length() != 4) return true;
147 Object& obj = Object::Handle(I, message.At(2)); 151 Object& obj = Object::Handle(I, message.At(2));
148 if (!obj.IsCapability()) return; 152 if (!I->VerifyPauseCapability(obj)) return true;
149 if (!I->VerifyPauseCapability(Capability::Cast(obj))) return;
150 obj = message.At(3); 153 obj = message.At(3);
151 if (!obj.IsCapability()) return; 154 if (!obj.IsCapability()) return true;
152 if (I->AddResumeCapability(Capability::Cast(obj))) { 155 if (I->AddResumeCapability(Capability::Cast(obj))) {
153 increment_paused(); 156 increment_paused();
154 } 157 }
155 break; 158 break;
156 } 159 }
157 case kResumeMsg: { 160 case kResumeMsg: {
158 // [ OOB, kResumeMsg, pause capability, resume capability ] 161 // [ OOB, kResumeMsg, pause capability, resume capability ]
159 if (message.Length() != 4) return; 162 if (message.Length() != 4) return true;
160 Object& obj = Object::Handle(I, message.At(2)); 163 Object& obj = Object::Handle(I, message.At(2));
161 if (!obj.IsCapability()) return; 164 if (!I->VerifyPauseCapability(obj)) return true;
162 if (!I->VerifyPauseCapability(Capability::Cast(obj))) return;
163 obj = message.At(3); 165 obj = message.At(3);
164 if (!obj.IsCapability()) return; 166 if (!obj.IsCapability()) return true;
165 if (I->RemoveResumeCapability(Capability::Cast(obj))) { 167 if (I->RemoveResumeCapability(Capability::Cast(obj))) {
166 decrement_paused(); 168 decrement_paused();
167 } 169 }
168 break; 170 break;
169 } 171 }
170 case kPingMsg: { 172 case kPingMsg: {
171 // [ OOB, kPingMsg, responsePort, pingType ] 173 // [ OOB, kPingMsg, responsePort, priority ]
172 if (message.Length() != 4) return; 174 if (message.Length() != 4) return true;
173 const Object& obj2 = Object::Handle(I, message.At(2)); 175 const Object& obj2 = Object::Handle(I, message.At(2));
174 if (!obj2.IsSendPort()) return; 176 if (!obj2.IsSendPort()) return true;
175 const SendPort& send_port = SendPort::Cast(obj2); 177 const SendPort& send_port = SendPort::Cast(obj2);
176 const Object& obj3 = Object::Handle(I, message.At(3)); 178 const Object& obj3 = Object::Handle(I, message.At(3));
177 if (!obj3.IsSmi()) return; 179 if (!obj3.IsSmi()) return true;
178 const intptr_t ping_type = Smi::Cast(obj3).Value(); 180 const intptr_t priority = Smi::Cast(obj3).Value();
179 if (ping_type == kImmediateAction) { 181 if (priority == kImmediateAction) {
180 uint8_t* data = NULL; 182 uint8_t* data = NULL;
181 intptr_t len = 0; 183 intptr_t len = 0;
182 SerializeObject(Object::null_instance(), &data, &len); 184 SerializeObject(Object::null_instance(), &data, &len);
183 PortMap::PostMessage(new Message(send_port.Id(), 185 PortMap::PostMessage(new Message(send_port.Id(),
184 data, len, 186 data, len,
185 Message::kNormalPriority)); 187 Message::kNormalPriority));
186 } else if (ping_type == kBeforeNextEventAction) { 188 } else {
189 ASSERT((priority == kBeforeNextEventAction) ||
190 (priority == kAsEventAction));
187 // Update the message so that it will be handled immediately when it 191 // Update the message so that it will be handled immediately when it
188 // is picked up from the message queue the next time. 192 // is picked up from the message queue the next time.
189 message.SetAt( 193 message.SetAt(
190 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); 194 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg)));
191 message.SetAt(3, Smi::Handle(I, Smi::New(kImmediateAction))); 195 message.SetAt(3, Smi::Handle(I, Smi::New(kImmediateAction)));
192 uint8_t* data = NULL; 196 uint8_t* data = NULL;
193 intptr_t len = 0; 197 intptr_t len = 0;
194 SerializeObject(message, &data, &len); 198 SerializeObject(message, &data, &len);
195 this->PostMessage(new Message(Message::kIllegalPort, 199 this->PostMessage(new Message(Message::kIllegalPort,
196 data, len, 200 data, len,
197 Message::kNormalPriority), 201 Message::kNormalPriority),
198 true /* at_head */); 202 priority == kBeforeNextEventAction /* at_head */);
199 } else if (ping_type == kAsEventAction) { 203 }
204 break;
205 }
206 case kKillMsg: {
207 // [ OOB, kKillMsg, terminate capability, priority ]
208 if (message.Length() != 4) return true;
209 Object& obj = Object::Handle(I, message.At(3));
210 if (!obj.IsSmi()) return true;
211 const intptr_t priority = Smi::Cast(obj).Value();
212 if (priority == kImmediateAction) {
213 obj = message.At(2);
214 // Signal that the isolate should stop execution.
215 return !I->VerifyTerminateCapability(obj);
216 } else {
217 ASSERT((priority == kBeforeNextEventAction) ||
218 (priority == kAsEventAction));
200 // Update the message so that it will be handled immediately when it 219 // Update the message so that it will be handled immediately when it
201 // is picked up from the message queue the next time. 220 // is picked up from the message queue the next time.
202 message.SetAt( 221 message.SetAt(
203 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg))); 222 0, Smi::Handle(I, Smi::New(Message::kDelayedIsolateLibOOBMsg)));
204 message.SetAt(3, Smi::Handle(I, Smi::New(kImmediateAction))); 223 message.SetAt(3, Smi::Handle(I, Smi::New(kImmediateAction)));
205 uint8_t* data = NULL; 224 uint8_t* data = NULL;
206 intptr_t len = 0; 225 intptr_t len = 0;
207 SerializeObject(message, &data, &len); 226 SerializeObject(message, &data, &len);
208 this->PostMessage(new Message(Message::kIllegalPort, 227 this->PostMessage(new Message(Message::kIllegalPort,
209 data, len, 228 data, len,
210 Message::kNormalPriority)); 229 Message::kNormalPriority),
230 priority == kBeforeNextEventAction /* at_head */);
211 } 231 }
212 break; 232 break;
213 } 233 }
214 #if defined(DEBUG) 234 #if defined(DEBUG)
215 // Malformed OOB messages are silently ignored in release builds. 235 // Malformed OOB messages are silently ignored in release builds.
216 default: 236 default:
217 UNREACHABLE(); 237 UNREACHABLE();
218 break; 238 break;
219 #endif // defined(DEBUG) 239 #endif // defined(DEBUG)
220 } 240 }
241 return true;
221 } 242 }
222 243
223 244
224 void IsolateMessageHandler::MessageNotify(Message::Priority priority) { 245 void IsolateMessageHandler::MessageNotify(Message::Priority priority) {
225 if (priority >= Message::kOOBPriority) { 246 if (priority >= Message::kOOBPriority) {
226 // Handle out of band messages even if the isolate is busy. 247 // Handle out of band messages even if the isolate is busy.
227 I->ScheduleInterrupts(Isolate::kMessageInterrupt); 248 I->ScheduleInterrupts(Isolate::kMessageInterrupt);
228 } 249 }
229 Dart_MessageNotifyCallback callback = I->message_notify_callback(); 250 Dart_MessageNotifyCallback callback = I->message_notify_callback();
230 if (callback) { 251 if (callback) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 const Array& oob_msg = Array::Cast(msg); 317 const Array& oob_msg = Array::Cast(msg);
297 if (oob_msg.Length() > 0) { 318 if (oob_msg.Length() > 0) {
298 const Object& oob_tag = Object::Handle(I, oob_msg.At(0)); 319 const Object& oob_tag = Object::Handle(I, oob_msg.At(0));
299 if (oob_tag.IsSmi()) { 320 if (oob_tag.IsSmi()) {
300 switch (Smi::Cast(oob_tag).Value()) { 321 switch (Smi::Cast(oob_tag).Value()) {
301 case Message::kServiceOOBMsg: { 322 case Message::kServiceOOBMsg: {
302 Service::HandleIsolateMessage(I, oob_msg); 323 Service::HandleIsolateMessage(I, oob_msg);
303 break; 324 break;
304 } 325 }
305 case Message::kIsolateLibOOBMsg: { 326 case Message::kIsolateLibOOBMsg: {
306 HandleLibMessage(oob_msg); 327 success = HandleLibMessage(oob_msg);
307 break; 328 break;
308 } 329 }
309 #if defined(DEBUG) 330 #if defined(DEBUG)
310 // Malformed OOB messages are silently ignored in release builds. 331 // Malformed OOB messages are silently ignored in release builds.
311 default: { 332 default: {
312 UNREACHABLE(); 333 UNREACHABLE();
313 break; 334 break;
314 } 335 }
315 #endif // defined(DEBUG) 336 #endif // defined(DEBUG)
316 } 337 }
317 } 338 }
318 } 339 }
319 } 340 }
320 } else if (message->dest_port() == Message::kIllegalPort) { 341 } else if (message->dest_port() == Message::kIllegalPort) {
321 // Check whether this is a delayed OOB message which needed handling as 342 // Check whether this is a delayed OOB message which needed handling as
322 // part of the regular message dispatch. All other messages are dropped on 343 // part of the regular message dispatch. All other messages are dropped on
323 // the floor. 344 // the floor.
324 if (msg.IsArray()) { 345 if (msg.IsArray()) {
325 const Array& msg_arr = Array::Cast(msg); 346 const Array& msg_arr = Array::Cast(msg);
326 if (msg_arr.Length() > 0) { 347 if (msg_arr.Length() > 0) {
327 const Object& oob_tag = Object::Handle(I, msg_arr.At(0)); 348 const Object& oob_tag = Object::Handle(I, msg_arr.At(0));
328 if (oob_tag.IsSmi() && 349 if (oob_tag.IsSmi() &&
329 (Smi::Cast(oob_tag).Value() == Message::kDelayedIsolateLibOOBMsg)) { 350 (Smi::Cast(oob_tag).Value() == Message::kDelayedIsolateLibOOBMsg)) {
330 HandleLibMessage(Array::Cast(msg_arr)); 351 success = HandleLibMessage(Array::Cast(msg_arr));
331 } 352 }
332 } 353 }
333 } 354 }
334 } else { 355 } else {
335 const Object& result = Object::Handle(I, 356 const Object& result = Object::Handle(I,
336 DartLibraryCalls::HandleMessage(msg_handler, msg)); 357 DartLibraryCalls::HandleMessage(msg_handler, msg));
337 if (result.IsError()) { 358 if (result.IsError()) {
338 success = ProcessUnhandledException(msg, Error::Cast(result)); 359 success = ProcessUnhandledException(msg, Error::Cast(result));
339 } else { 360 } else {
340 ASSERT(result.IsNull()); 361 ASSERT(result.IsNull());
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
814 } 835 }
815 IsolateSpawnState* state = spawn_state(); 836 IsolateSpawnState* state = spawn_state();
816 if (state != NULL) { 837 if (state != NULL) {
817 ASSERT(this == state->isolate()); 838 ASSERT(this == state->isolate());
818 Run(); 839 Run();
819 } 840 }
820 return true; 841 return true;
821 } 842 }
822 843
823 844
824 bool Isolate::VerifyPauseCapability(const Capability& capability) const { 845 bool Isolate::VerifyPauseCapability(const Object& capability) const {
825 return !capability.IsNull() && (pause_capability() == capability.Id()); 846 return !capability.IsNull() &&
847 capability.IsCapability() &&
848 (pause_capability() == Capability::Cast(capability).Id());
849 }
850
851
852 bool Isolate::VerifyTerminateCapability(const Object& capability) const {
853 return !capability.IsNull() &&
854 capability.IsCapability() &&
855 (terminate_capability() == Capability::Cast(capability).Id());
826 } 856 }
827 857
828 858
829 bool Isolate::AddResumeCapability(const Capability& capability) { 859 bool Isolate::AddResumeCapability(const Capability& capability) {
830 // Ensure a limit for the number of resume capabilities remembered. 860 // Ensure a limit for the number of resume capabilities remembered.
831 static const intptr_t kMaxResumeCapabilities = kSmiMax / (6*kWordSize); 861 static const intptr_t kMaxResumeCapabilities = kSmiMax / (6*kWordSize);
832 862
833 const GrowableObjectArray& caps = GrowableObjectArray::Handle( 863 const GrowableObjectArray& caps = GrowableObjectArray::Handle(
834 this, object_store()->resume_capabilities()); 864 this, object_store()->resume_capabilities());
835 Capability& current = Capability::Handle(this); 865 Capability& current = Capability::Handle(this);
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
967 static void ShutdownIsolate(uword parameter) { 997 static void ShutdownIsolate(uword parameter) {
968 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); 998 Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
969 { 999 {
970 // Print the error if there is one. This may execute dart code to 1000 // Print the error if there is one. This may execute dart code to
971 // print the exception object, so we need to use a StartIsolateScope. 1001 // print the exception object, so we need to use a StartIsolateScope.
972 StartIsolateScope start_scope(isolate); 1002 StartIsolateScope start_scope(isolate);
973 StackZone zone(isolate); 1003 StackZone zone(isolate);
974 HandleScope handle_scope(isolate); 1004 HandleScope handle_scope(isolate);
975 Error& error = Error::Handle(); 1005 Error& error = Error::Handle();
976 error = isolate->object_store()->sticky_error(); 1006 error = isolate->object_store()->sticky_error();
977 if (!error.IsNull()) { 1007 if (!error.IsNull() && !error.IsUnwindError()) {
978 OS::PrintErr("in ShutdownIsolate: %s\n", error.ToErrorCString()); 1008 OS::PrintErr("in ShutdownIsolate: %s\n", error.ToErrorCString());
979 } 1009 }
980 Dart::RunShutdownCallback(); 1010 Dart::RunShutdownCallback();
981 } 1011 }
982 { 1012 {
983 // Shut the isolate down. 1013 // Shut the isolate down.
984 SwitchIsolateScope switch_scope(isolate); 1014 SwitchIsolateScope switch_scope(isolate);
985 Dart::ShutdownIsolate(); 1015 Dart::ShutdownIsolate();
986 } 1016 }
987 } 1017 }
(...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after
1639 serialized_message_, serialized_message_len_); 1669 serialized_message_, serialized_message_len_);
1640 } 1670 }
1641 1671
1642 1672
1643 void IsolateSpawnState::Cleanup() { 1673 void IsolateSpawnState::Cleanup() {
1644 SwitchIsolateScope switch_scope(I); 1674 SwitchIsolateScope switch_scope(I);
1645 Dart::ShutdownIsolate(); 1675 Dart::ShutdownIsolate();
1646 } 1676 }
1647 1677
1648 } // namespace dart 1678 } // namespace dart
OLDNEW
« runtime/vm/isolate.h ('K') | « runtime/vm/isolate.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698