| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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/service_isolate.h" | 5 #include "vm/service_isolate.h" |
| 6 | 6 |
| 7 #include "vm/compiler.h" | 7 #include "vm/compiler.h" |
| 8 #include "vm/dart_api_impl.h" | 8 #include "vm/dart_api_impl.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
| 11 #include "vm/lockers.h" | 11 #include "vm/lockers.h" |
| 12 #include "vm/message.h" | 12 #include "vm/message.h" |
| 13 #include "vm/message_handler.h" | 13 #include "vm/message_handler.h" |
| 14 #include "vm/native_arguments.h" |
| 14 #include "vm/native_entry.h" | 15 #include "vm/native_entry.h" |
| 15 #include "vm/native_arguments.h" | |
| 16 #include "vm/object.h" | 16 #include "vm/object.h" |
| 17 #include "vm/object_store.h" | 17 #include "vm/object_store.h" |
| 18 #include "vm/port.h" | 18 #include "vm/port.h" |
| 19 #include "vm/service.h" | 19 #include "vm/service.h" |
| 20 #include "vm/symbols.h" | 20 #include "vm/symbols.h" |
| 21 #include "vm/thread_pool.h" | 21 #include "vm/thread_pool.h" |
| 22 #include "vm/timeline.h" | 22 #include "vm/timeline.h" |
| 23 | 23 |
| 24 namespace dart { | 24 namespace dart { |
| 25 | 25 |
| 26 #define Z (T->zone()) | 26 #define Z (T->zone()) |
| 27 | 27 |
| 28 | |
| 29 DEFINE_FLAG(bool, trace_service, false, "Trace VM service requests."); | 28 DEFINE_FLAG(bool, trace_service, false, "Trace VM service requests."); |
| 30 DEFINE_FLAG(bool, | 29 DEFINE_FLAG(bool, |
| 31 trace_service_pause_events, | 30 trace_service_pause_events, |
| 32 false, | 31 false, |
| 33 "Trace VM service isolate pause events."); | 32 "Trace VM service isolate pause events."); |
| 34 DEFINE_FLAG(bool, | 33 DEFINE_FLAG(bool, |
| 35 trace_service_verbose, | 34 trace_service_verbose, |
| 36 false, | 35 false, |
| 37 "Provide extra service tracing information."); | 36 "Provide extra service tracing information."); |
| 38 | 37 |
| 39 static uint8_t* malloc_allocator(uint8_t* ptr, | 38 static uint8_t* malloc_allocator(uint8_t* ptr, |
| 40 intptr_t old_size, | 39 intptr_t old_size, |
| 41 intptr_t new_size) { | 40 intptr_t new_size) { |
| 42 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); | 41 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); |
| 43 return reinterpret_cast<uint8_t*>(new_ptr); | 42 return reinterpret_cast<uint8_t*>(new_ptr); |
| 44 } | 43 } |
| 45 | 44 |
| 46 static void malloc_deallocator(uint8_t* ptr) { | 45 static void malloc_deallocator(uint8_t* ptr) { |
| 47 free(reinterpret_cast<void*>(ptr)); | 46 free(reinterpret_cast<void*>(ptr)); |
| 48 } | 47 } |
| 49 | 48 |
| 50 | |
| 51 // These must be kept in sync with service/constants.dart | 49 // These must be kept in sync with service/constants.dart |
| 52 #define VM_SERVICE_ISOLATE_EXIT_MESSAGE_ID 0 | 50 #define VM_SERVICE_ISOLATE_EXIT_MESSAGE_ID 0 |
| 53 #define VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID 1 | 51 #define VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID 1 |
| 54 #define VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID 2 | 52 #define VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID 2 |
| 55 | 53 |
| 56 #define VM_SERVICE_WEB_SERVER_CONTROL_MESSAGE_ID 3 | 54 #define VM_SERVICE_WEB_SERVER_CONTROL_MESSAGE_ID 3 |
| 57 #define VM_SERVICE_SERVER_INFO_MESSAGE_ID 4 | 55 #define VM_SERVICE_SERVER_INFO_MESSAGE_ID 4 |
| 58 | 56 |
| 59 static RawArray* MakeServiceControlMessage(Dart_Port port_id, | 57 static RawArray* MakeServiceControlMessage(Dart_Port port_id, |
| 60 intptr_t code, | 58 intptr_t code, |
| 61 const String& name) { | 59 const String& name) { |
| 62 const Array& list = Array::Handle(Array::New(4)); | 60 const Array& list = Array::Handle(Array::New(4)); |
| 63 ASSERT(!list.IsNull()); | 61 ASSERT(!list.IsNull()); |
| 64 const Integer& code_int = Integer::Handle(Integer::New(code)); | 62 const Integer& code_int = Integer::Handle(Integer::New(code)); |
| 65 const Integer& port_int = Integer::Handle(Integer::New(port_id)); | 63 const Integer& port_int = Integer::Handle(Integer::New(port_id)); |
| 66 const SendPort& send_port = SendPort::Handle(SendPort::New(port_id)); | 64 const SendPort& send_port = SendPort::Handle(SendPort::New(port_id)); |
| 67 list.SetAt(0, code_int); | 65 list.SetAt(0, code_int); |
| 68 list.SetAt(1, port_int); | 66 list.SetAt(1, port_int); |
| 69 list.SetAt(2, send_port); | 67 list.SetAt(2, send_port); |
| 70 list.SetAt(3, name); | 68 list.SetAt(3, name); |
| 71 return list.raw(); | 69 return list.raw(); |
| 72 } | 70 } |
| 73 | 71 |
| 74 | |
| 75 static RawArray* MakeServerControlMessage(const SendPort& sp, | 72 static RawArray* MakeServerControlMessage(const SendPort& sp, |
| 76 intptr_t code, | 73 intptr_t code, |
| 77 bool enable = false) { | 74 bool enable = false) { |
| 78 const Array& list = Array::Handle(Array::New(3)); | 75 const Array& list = Array::Handle(Array::New(3)); |
| 79 ASSERT(!list.IsNull()); | 76 ASSERT(!list.IsNull()); |
| 80 list.SetAt(0, Integer::Handle(Integer::New(code))); | 77 list.SetAt(0, Integer::Handle(Integer::New(code))); |
| 81 list.SetAt(1, sp); | 78 list.SetAt(1, sp); |
| 82 list.SetAt(2, Bool::Get(enable)); | 79 list.SetAt(2, Bool::Get(enable)); |
| 83 return list.raw(); | 80 return list.raw(); |
| 84 } | 81 } |
| 85 | 82 |
| 86 | |
| 87 static RawArray* MakeServiceExitMessage() { | 83 static RawArray* MakeServiceExitMessage() { |
| 88 const Array& list = Array::Handle(Array::New(1)); | 84 const Array& list = Array::Handle(Array::New(1)); |
| 89 ASSERT(!list.IsNull()); | 85 ASSERT(!list.IsNull()); |
| 90 const intptr_t code = VM_SERVICE_ISOLATE_EXIT_MESSAGE_ID; | 86 const intptr_t code = VM_SERVICE_ISOLATE_EXIT_MESSAGE_ID; |
| 91 const Integer& code_int = Integer::Handle(Integer::New(code)); | 87 const Integer& code_int = Integer::Handle(Integer::New(code)); |
| 92 list.SetAt(0, code_int); | 88 list.SetAt(0, code_int); |
| 93 return list.raw(); | 89 return list.raw(); |
| 94 } | 90 } |
| 95 | 91 |
| 96 | |
| 97 const char* ServiceIsolate::kName = "vm-service"; | 92 const char* ServiceIsolate::kName = "vm-service"; |
| 98 Isolate* ServiceIsolate::isolate_ = NULL; | 93 Isolate* ServiceIsolate::isolate_ = NULL; |
| 99 Dart_Port ServiceIsolate::port_ = ILLEGAL_PORT; | 94 Dart_Port ServiceIsolate::port_ = ILLEGAL_PORT; |
| 100 Dart_Port ServiceIsolate::load_port_ = ILLEGAL_PORT; | 95 Dart_Port ServiceIsolate::load_port_ = ILLEGAL_PORT; |
| 101 Dart_Port ServiceIsolate::origin_ = ILLEGAL_PORT; | 96 Dart_Port ServiceIsolate::origin_ = ILLEGAL_PORT; |
| 102 Dart_IsolateCreateCallback ServiceIsolate::create_callback_ = NULL; | 97 Dart_IsolateCreateCallback ServiceIsolate::create_callback_ = NULL; |
| 103 uint8_t* ServiceIsolate::exit_message_ = NULL; | 98 uint8_t* ServiceIsolate::exit_message_ = NULL; |
| 104 intptr_t ServiceIsolate::exit_message_length_ = 0; | 99 intptr_t ServiceIsolate::exit_message_length_ = 0; |
| 105 Monitor* ServiceIsolate::monitor_ = new Monitor(); | 100 Monitor* ServiceIsolate::monitor_ = new Monitor(); |
| 106 bool ServiceIsolate::initializing_ = true; | 101 bool ServiceIsolate::initializing_ = true; |
| 107 bool ServiceIsolate::shutting_down_ = false; | 102 bool ServiceIsolate::shutting_down_ = false; |
| 108 char* ServiceIsolate::server_address_ = NULL; | 103 char* ServiceIsolate::server_address_ = NULL; |
| 109 | 104 |
| 110 void ServiceIsolate::RequestServerInfo(const SendPort& sp) { | 105 void ServiceIsolate::RequestServerInfo(const SendPort& sp) { |
| 111 const Array& message = Array::Handle(MakeServerControlMessage( | 106 const Array& message = Array::Handle(MakeServerControlMessage( |
| 112 sp, VM_SERVICE_SERVER_INFO_MESSAGE_ID, false /* ignored */)); | 107 sp, VM_SERVICE_SERVER_INFO_MESSAGE_ID, false /* ignored */)); |
| 113 ASSERT(!message.IsNull()); | 108 ASSERT(!message.IsNull()); |
| 114 uint8_t* data = NULL; | 109 uint8_t* data = NULL; |
| 115 MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false); | 110 MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false); |
| 116 writer.WriteMessage(message); | 111 writer.WriteMessage(message); |
| 117 intptr_t len = writer.BytesWritten(); | 112 intptr_t len = writer.BytesWritten(); |
| 118 PortMap::PostMessage(new Message(port_, data, len, Message::kNormalPriority)); | 113 PortMap::PostMessage(new Message(port_, data, len, Message::kNormalPriority)); |
| 119 } | 114 } |
| 120 | 115 |
| 121 | |
| 122 void ServiceIsolate::ControlWebServer(const SendPort& sp, bool enable) { | 116 void ServiceIsolate::ControlWebServer(const SendPort& sp, bool enable) { |
| 123 const Array& message = Array::Handle(MakeServerControlMessage( | 117 const Array& message = Array::Handle(MakeServerControlMessage( |
| 124 sp, VM_SERVICE_WEB_SERVER_CONTROL_MESSAGE_ID, enable)); | 118 sp, VM_SERVICE_WEB_SERVER_CONTROL_MESSAGE_ID, enable)); |
| 125 ASSERT(!message.IsNull()); | 119 ASSERT(!message.IsNull()); |
| 126 uint8_t* data = NULL; | 120 uint8_t* data = NULL; |
| 127 MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false); | 121 MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false); |
| 128 writer.WriteMessage(message); | 122 writer.WriteMessage(message); |
| 129 intptr_t len = writer.BytesWritten(); | 123 intptr_t len = writer.BytesWritten(); |
| 130 PortMap::PostMessage(new Message(port_, data, len, Message::kNormalPriority)); | 124 PortMap::PostMessage(new Message(port_, data, len, Message::kNormalPriority)); |
| 131 } | 125 } |
| 132 | 126 |
| 133 | |
| 134 void ServiceIsolate::SetServerAddress(const char* address) { | 127 void ServiceIsolate::SetServerAddress(const char* address) { |
| 135 if (server_address_ != NULL) { | 128 if (server_address_ != NULL) { |
| 136 free(server_address_); | 129 free(server_address_); |
| 137 server_address_ = NULL; | 130 server_address_ = NULL; |
| 138 } | 131 } |
| 139 if (address == NULL) { | 132 if (address == NULL) { |
| 140 return; | 133 return; |
| 141 } | 134 } |
| 142 server_address_ = strdup(address); | 135 server_address_ = strdup(address); |
| 143 } | 136 } |
| 144 | 137 |
| 145 | |
| 146 bool ServiceIsolate::NameEquals(const char* name) { | 138 bool ServiceIsolate::NameEquals(const char* name) { |
| 147 ASSERT(name != NULL); | 139 ASSERT(name != NULL); |
| 148 return strcmp(name, kName) == 0; | 140 return strcmp(name, kName) == 0; |
| 149 } | 141 } |
| 150 | 142 |
| 151 | |
| 152 bool ServiceIsolate::Exists() { | 143 bool ServiceIsolate::Exists() { |
| 153 MonitorLocker ml(monitor_); | 144 MonitorLocker ml(monitor_); |
| 154 return isolate_ != NULL; | 145 return isolate_ != NULL; |
| 155 } | 146 } |
| 156 | 147 |
| 157 | |
| 158 bool ServiceIsolate::IsRunning() { | 148 bool ServiceIsolate::IsRunning() { |
| 159 MonitorLocker ml(monitor_); | 149 MonitorLocker ml(monitor_); |
| 160 return (port_ != ILLEGAL_PORT) && (isolate_ != NULL); | 150 return (port_ != ILLEGAL_PORT) && (isolate_ != NULL); |
| 161 } | 151 } |
| 162 | 152 |
| 163 | |
| 164 bool ServiceIsolate::IsServiceIsolate(const Isolate* isolate) { | 153 bool ServiceIsolate::IsServiceIsolate(const Isolate* isolate) { |
| 165 MonitorLocker ml(monitor_); | 154 MonitorLocker ml(monitor_); |
| 166 return isolate == isolate_; | 155 return isolate == isolate_; |
| 167 } | 156 } |
| 168 | 157 |
| 169 | |
| 170 bool ServiceIsolate::IsServiceIsolateDescendant(const Isolate* isolate) { | 158 bool ServiceIsolate::IsServiceIsolateDescendant(const Isolate* isolate) { |
| 171 MonitorLocker ml(monitor_); | 159 MonitorLocker ml(monitor_); |
| 172 return isolate->origin_id() == origin_; | 160 return isolate->origin_id() == origin_; |
| 173 } | 161 } |
| 174 | 162 |
| 175 | |
| 176 Dart_Port ServiceIsolate::Port() { | 163 Dart_Port ServiceIsolate::Port() { |
| 177 MonitorLocker ml(monitor_); | 164 MonitorLocker ml(monitor_); |
| 178 return port_; | 165 return port_; |
| 179 } | 166 } |
| 180 | 167 |
| 181 | |
| 182 Dart_Port ServiceIsolate::WaitForLoadPort() { | 168 Dart_Port ServiceIsolate::WaitForLoadPort() { |
| 183 MonitorLocker ml(monitor_); | 169 MonitorLocker ml(monitor_); |
| 184 while (initializing_ && (load_port_ == ILLEGAL_PORT)) { | 170 while (initializing_ && (load_port_ == ILLEGAL_PORT)) { |
| 185 ml.Wait(); | 171 ml.Wait(); |
| 186 } | 172 } |
| 187 return load_port_; | 173 return load_port_; |
| 188 } | 174 } |
| 189 | 175 |
| 190 | |
| 191 Dart_Port ServiceIsolate::LoadPort() { | 176 Dart_Port ServiceIsolate::LoadPort() { |
| 192 MonitorLocker ml(monitor_); | 177 MonitorLocker ml(monitor_); |
| 193 return load_port_; | 178 return load_port_; |
| 194 } | 179 } |
| 195 | 180 |
| 196 | |
| 197 bool ServiceIsolate::SendIsolateStartupMessage() { | 181 bool ServiceIsolate::SendIsolateStartupMessage() { |
| 198 if (!IsRunning()) { | 182 if (!IsRunning()) { |
| 199 return false; | 183 return false; |
| 200 } | 184 } |
| 201 Thread* thread = Thread::Current(); | 185 Thread* thread = Thread::Current(); |
| 202 Isolate* isolate = thread->isolate(); | 186 Isolate* isolate = thread->isolate(); |
| 203 if (IsServiceIsolateDescendant(isolate)) { | 187 if (IsServiceIsolateDescendant(isolate)) { |
| 204 return false; | 188 return false; |
| 205 } | 189 } |
| 206 ASSERT(isolate != NULL); | 190 ASSERT(isolate != NULL); |
| 207 HANDLESCOPE(thread); | 191 HANDLESCOPE(thread); |
| 208 const String& name = String::Handle(String::New(isolate->name())); | 192 const String& name = String::Handle(String::New(isolate->name())); |
| 209 ASSERT(!name.IsNull()); | 193 ASSERT(!name.IsNull()); |
| 210 const Array& list = Array::Handle(MakeServiceControlMessage( | 194 const Array& list = Array::Handle(MakeServiceControlMessage( |
| 211 Dart_GetMainPortId(), VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID, name)); | 195 Dart_GetMainPortId(), VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID, name)); |
| 212 ASSERT(!list.IsNull()); | 196 ASSERT(!list.IsNull()); |
| 213 uint8_t* data = NULL; | 197 uint8_t* data = NULL; |
| 214 MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false); | 198 MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false); |
| 215 writer.WriteMessage(list); | 199 writer.WriteMessage(list); |
| 216 intptr_t len = writer.BytesWritten(); | 200 intptr_t len = writer.BytesWritten(); |
| 217 if (FLAG_trace_service) { | 201 if (FLAG_trace_service) { |
| 218 OS::Print("vm-service: Isolate %s %" Pd64 " registered.\n", | 202 OS::Print("vm-service: Isolate %s %" Pd64 " registered.\n", |
| 219 name.ToCString(), Dart_GetMainPortId()); | 203 name.ToCString(), Dart_GetMainPortId()); |
| 220 } | 204 } |
| 221 return PortMap::PostMessage( | 205 return PortMap::PostMessage( |
| 222 new Message(port_, data, len, Message::kNormalPriority)); | 206 new Message(port_, data, len, Message::kNormalPriority)); |
| 223 } | 207 } |
| 224 | 208 |
| 225 | |
| 226 bool ServiceIsolate::SendIsolateShutdownMessage() { | 209 bool ServiceIsolate::SendIsolateShutdownMessage() { |
| 227 if (!IsRunning()) { | 210 if (!IsRunning()) { |
| 228 return false; | 211 return false; |
| 229 } | 212 } |
| 230 Thread* thread = Thread::Current(); | 213 Thread* thread = Thread::Current(); |
| 231 Isolate* isolate = thread->isolate(); | 214 Isolate* isolate = thread->isolate(); |
| 232 if (IsServiceIsolateDescendant(isolate)) { | 215 if (IsServiceIsolateDescendant(isolate)) { |
| 233 return false; | 216 return false; |
| 234 } | 217 } |
| 235 ASSERT(isolate != NULL); | 218 ASSERT(isolate != NULL); |
| 236 HANDLESCOPE(thread); | 219 HANDLESCOPE(thread); |
| 237 const String& name = String::Handle(String::New(isolate->name())); | 220 const String& name = String::Handle(String::New(isolate->name())); |
| 238 ASSERT(!name.IsNull()); | 221 ASSERT(!name.IsNull()); |
| 239 const Array& list = Array::Handle(MakeServiceControlMessage( | 222 const Array& list = Array::Handle(MakeServiceControlMessage( |
| 240 Dart_GetMainPortId(), VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID, name)); | 223 Dart_GetMainPortId(), VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID, name)); |
| 241 ASSERT(!list.IsNull()); | 224 ASSERT(!list.IsNull()); |
| 242 uint8_t* data = NULL; | 225 uint8_t* data = NULL; |
| 243 MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false); | 226 MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false); |
| 244 writer.WriteMessage(list); | 227 writer.WriteMessage(list); |
| 245 intptr_t len = writer.BytesWritten(); | 228 intptr_t len = writer.BytesWritten(); |
| 246 if (FLAG_trace_service) { | 229 if (FLAG_trace_service) { |
| 247 OS::Print("vm-service: Isolate %s %" Pd64 " deregistered.\n", | 230 OS::Print("vm-service: Isolate %s %" Pd64 " deregistered.\n", |
| 248 name.ToCString(), Dart_GetMainPortId()); | 231 name.ToCString(), Dart_GetMainPortId()); |
| 249 } | 232 } |
| 250 return PortMap::PostMessage( | 233 return PortMap::PostMessage( |
| 251 new Message(port_, data, len, Message::kNormalPriority)); | 234 new Message(port_, data, len, Message::kNormalPriority)); |
| 252 } | 235 } |
| 253 | 236 |
| 254 | |
| 255 void ServiceIsolate::SendServiceExitMessage() { | 237 void ServiceIsolate::SendServiceExitMessage() { |
| 256 if (!IsRunning()) { | 238 if (!IsRunning()) { |
| 257 return; | 239 return; |
| 258 } | 240 } |
| 259 if ((exit_message_ == NULL) || (exit_message_length_ == 0)) { | 241 if ((exit_message_ == NULL) || (exit_message_length_ == 0)) { |
| 260 return; | 242 return; |
| 261 } | 243 } |
| 262 if (FLAG_trace_service) { | 244 if (FLAG_trace_service) { |
| 263 OS::Print("vm-service: sending service exit message.\n"); | 245 OS::Print("vm-service: sending service exit message.\n"); |
| 264 } | 246 } |
| 265 PortMap::PostMessage(new Message(port_, exit_message_, exit_message_length_, | 247 PortMap::PostMessage(new Message(port_, exit_message_, exit_message_length_, |
| 266 Message::kNormalPriority)); | 248 Message::kNormalPriority)); |
| 267 } | 249 } |
| 268 | 250 |
| 269 | |
| 270 void ServiceIsolate::SetServicePort(Dart_Port port) { | 251 void ServiceIsolate::SetServicePort(Dart_Port port) { |
| 271 MonitorLocker ml(monitor_); | 252 MonitorLocker ml(monitor_); |
| 272 port_ = port; | 253 port_ = port; |
| 273 } | 254 } |
| 274 | 255 |
| 275 | |
| 276 void ServiceIsolate::SetServiceIsolate(Isolate* isolate) { | 256 void ServiceIsolate::SetServiceIsolate(Isolate* isolate) { |
| 277 MonitorLocker ml(monitor_); | 257 MonitorLocker ml(monitor_); |
| 278 isolate_ = isolate; | 258 isolate_ = isolate; |
| 279 if (isolate_ != NULL) { | 259 if (isolate_ != NULL) { |
| 280 isolate_->is_service_isolate_ = true; | 260 isolate_->is_service_isolate_ = true; |
| 281 origin_ = isolate_->origin_id(); | 261 origin_ = isolate_->origin_id(); |
| 282 } | 262 } |
| 283 } | 263 } |
| 284 | 264 |
| 285 void ServiceIsolate::SetLoadPort(Dart_Port port) { | 265 void ServiceIsolate::SetLoadPort(Dart_Port port) { |
| 286 MonitorLocker ml(monitor_); | 266 MonitorLocker ml(monitor_); |
| 287 load_port_ = port; | 267 load_port_ = port; |
| 288 } | 268 } |
| 289 | 269 |
| 290 | |
| 291 void ServiceIsolate::MaybeMakeServiceIsolate(Isolate* I) { | 270 void ServiceIsolate::MaybeMakeServiceIsolate(Isolate* I) { |
| 292 Thread* T = Thread::Current(); | 271 Thread* T = Thread::Current(); |
| 293 ASSERT(I == T->isolate()); | 272 ASSERT(I == T->isolate()); |
| 294 ASSERT(I != NULL); | 273 ASSERT(I != NULL); |
| 295 ASSERT(I->name() != NULL); | 274 ASSERT(I->name() != NULL); |
| 296 if (!ServiceIsolate::NameEquals(I->name())) { | 275 if (!ServiceIsolate::NameEquals(I->name())) { |
| 297 // Not service isolate. | 276 // Not service isolate. |
| 298 return; | 277 return; |
| 299 } | 278 } |
| 300 if (Exists()) { | 279 if (Exists()) { |
| 301 // Service isolate already exists. | 280 // Service isolate already exists. |
| 302 return; | 281 return; |
| 303 } | 282 } |
| 304 SetServiceIsolate(I); | 283 SetServiceIsolate(I); |
| 305 } | 284 } |
| 306 | 285 |
| 307 | |
| 308 void ServiceIsolate::ConstructExitMessageAndCache(Isolate* I) { | 286 void ServiceIsolate::ConstructExitMessageAndCache(Isolate* I) { |
| 309 // Construct and cache exit message here so we can send it without needing an | 287 // Construct and cache exit message here so we can send it without needing an |
| 310 // isolate. | 288 // isolate. |
| 311 Thread* T = Thread::Current(); | 289 Thread* T = Thread::Current(); |
| 312 ASSERT(I == T->isolate()); | 290 ASSERT(I == T->isolate()); |
| 313 ASSERT(I != NULL); | 291 ASSERT(I != NULL); |
| 314 StackZone zone(T); | 292 StackZone zone(T); |
| 315 HANDLESCOPE(T); | 293 HANDLESCOPE(T); |
| 316 ASSERT(exit_message_ == NULL); | 294 ASSERT(exit_message_ == NULL); |
| 317 ASSERT(exit_message_length_ == 0); | 295 ASSERT(exit_message_length_ == 0); |
| 318 const Array& list = Array::Handle(Z, MakeServiceExitMessage()); | 296 const Array& list = Array::Handle(Z, MakeServiceExitMessage()); |
| 319 ASSERT(!list.IsNull()); | 297 ASSERT(!list.IsNull()); |
| 320 MessageWriter writer(&exit_message_, &malloc_allocator, &malloc_deallocator, | 298 MessageWriter writer(&exit_message_, &malloc_allocator, &malloc_deallocator, |
| 321 false); | 299 false); |
| 322 writer.WriteMessage(list); | 300 writer.WriteMessage(list); |
| 323 exit_message_length_ = writer.BytesWritten(); | 301 exit_message_length_ = writer.BytesWritten(); |
| 324 ASSERT(exit_message_ != NULL); | 302 ASSERT(exit_message_ != NULL); |
| 325 ASSERT(exit_message_length_ != 0); | 303 ASSERT(exit_message_length_ != 0); |
| 326 } | 304 } |
| 327 | 305 |
| 328 | |
| 329 void ServiceIsolate::FinishedExiting() { | 306 void ServiceIsolate::FinishedExiting() { |
| 330 MonitorLocker ml(monitor_); | 307 MonitorLocker ml(monitor_); |
| 331 shutting_down_ = false; | 308 shutting_down_ = false; |
| 332 ml.NotifyAll(); | 309 ml.NotifyAll(); |
| 333 } | 310 } |
| 334 | 311 |
| 335 | |
| 336 void ServiceIsolate::FinishedInitializing() { | 312 void ServiceIsolate::FinishedInitializing() { |
| 337 MonitorLocker ml(monitor_); | 313 MonitorLocker ml(monitor_); |
| 338 initializing_ = false; | 314 initializing_ = false; |
| 339 ml.NotifyAll(); | 315 ml.NotifyAll(); |
| 340 } | 316 } |
| 341 | 317 |
| 342 | |
| 343 class RunServiceTask : public ThreadPool::Task { | 318 class RunServiceTask : public ThreadPool::Task { |
| 344 public: | 319 public: |
| 345 virtual void Run() { | 320 virtual void Run() { |
| 346 ASSERT(Isolate::Current() == NULL); | 321 ASSERT(Isolate::Current() == NULL); |
| 347 #ifndef PRODUCT | 322 #ifndef PRODUCT |
| 348 TimelineDurationScope tds(Timeline::GetVMStream(), "ServiceIsolateStartup"); | 323 TimelineDurationScope tds(Timeline::GetVMStream(), "ServiceIsolateStartup"); |
| 349 #endif // !PRODUCT | 324 #endif // !PRODUCT |
| 350 char* error = NULL; | 325 char* error = NULL; |
| 351 Isolate* isolate = NULL; | 326 Isolate* isolate = NULL; |
| 352 | 327 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 } | 449 } |
| 475 return false; | 450 return false; |
| 476 } | 451 } |
| 477 ASSERT(result.IsReceivePort()); | 452 ASSERT(result.IsReceivePort()); |
| 478 const ReceivePort& rp = ReceivePort::Cast(result); | 453 const ReceivePort& rp = ReceivePort::Cast(result); |
| 479 ServiceIsolate::SetLoadPort(rp.Id()); | 454 ServiceIsolate::SetLoadPort(rp.Id()); |
| 480 return false; | 455 return false; |
| 481 } | 456 } |
| 482 }; | 457 }; |
| 483 | 458 |
| 484 | |
| 485 void ServiceIsolate::Run() { | 459 void ServiceIsolate::Run() { |
| 486 // Grab the isolate create callback here to avoid race conditions with tests | 460 // Grab the isolate create callback here to avoid race conditions with tests |
| 487 // that change this after Dart_Initialize returns. | 461 // that change this after Dart_Initialize returns. |
| 488 create_callback_ = Isolate::CreateCallback(); | 462 create_callback_ = Isolate::CreateCallback(); |
| 489 Dart::thread_pool()->Run(new RunServiceTask()); | 463 Dart::thread_pool()->Run(new RunServiceTask()); |
| 490 } | 464 } |
| 491 | 465 |
| 492 | |
| 493 void ServiceIsolate::KillServiceIsolate() { | 466 void ServiceIsolate::KillServiceIsolate() { |
| 494 { | 467 { |
| 495 MonitorLocker ml(monitor_); | 468 MonitorLocker ml(monitor_); |
| 496 shutting_down_ = true; | 469 shutting_down_ = true; |
| 497 } | 470 } |
| 498 Isolate::KillIfExists(isolate_, Isolate::kInternalKillMsg); | 471 Isolate::KillIfExists(isolate_, Isolate::kInternalKillMsg); |
| 499 { | 472 { |
| 500 MonitorLocker ml(monitor_); | 473 MonitorLocker ml(monitor_); |
| 501 while (shutting_down_) { | 474 while (shutting_down_) { |
| 502 ml.Wait(); | 475 ml.Wait(); |
| 503 } | 476 } |
| 504 } | 477 } |
| 505 } | 478 } |
| 506 | 479 |
| 507 | |
| 508 void ServiceIsolate::Shutdown() { | 480 void ServiceIsolate::Shutdown() { |
| 509 if (IsRunning()) { | 481 if (IsRunning()) { |
| 510 { | 482 { |
| 511 MonitorLocker ml(monitor_); | 483 MonitorLocker ml(monitor_); |
| 512 shutting_down_ = true; | 484 shutting_down_ = true; |
| 513 } | 485 } |
| 514 SendServiceExitMessage(); | 486 SendServiceExitMessage(); |
| 515 { | 487 { |
| 516 MonitorLocker ml(monitor_); | 488 MonitorLocker ml(monitor_); |
| 517 while (shutting_down_ && (port_ != ILLEGAL_PORT)) { | 489 while (shutting_down_ && (port_ != ILLEGAL_PORT)) { |
| 518 ml.Wait(); | 490 ml.Wait(); |
| 519 } | 491 } |
| 520 } | 492 } |
| 521 } else { | 493 } else { |
| 522 if (isolate_ != NULL) { | 494 if (isolate_ != NULL) { |
| 523 // TODO(johnmccutchan,turnidge) When it is possible to properly create | 495 // TODO(johnmccutchan,turnidge) When it is possible to properly create |
| 524 // the VMService object and set up its shutdown handler in the service | 496 // the VMService object and set up its shutdown handler in the service |
| 525 // isolate's main() function, this case will no longer be possible and | 497 // isolate's main() function, this case will no longer be possible and |
| 526 // can be removed. | 498 // can be removed. |
| 527 KillServiceIsolate(); | 499 KillServiceIsolate(); |
| 528 } | 500 } |
| 529 } | 501 } |
| 530 if (server_address_ != NULL) { | 502 if (server_address_ != NULL) { |
| 531 free(server_address_); | 503 free(server_address_); |
| 532 server_address_ = NULL; | 504 server_address_ = NULL; |
| 533 } | 505 } |
| 534 } | 506 } |
| 535 | 507 |
| 536 | |
| 537 void ServiceIsolate::BootVmServiceLibrary() { | 508 void ServiceIsolate::BootVmServiceLibrary() { |
| 538 Thread* thread = Thread::Current(); | 509 Thread* thread = Thread::Current(); |
| 539 const Library& vmservice_library = | 510 const Library& vmservice_library = |
| 540 Library::Handle(Library::LookupLibrary(thread, Symbols::DartVMService())); | 511 Library::Handle(Library::LookupLibrary(thread, Symbols::DartVMService())); |
| 541 ASSERT(!vmservice_library.IsNull()); | 512 ASSERT(!vmservice_library.IsNull()); |
| 542 const String& boot_function_name = String::Handle(String::New("boot")); | 513 const String& boot_function_name = String::Handle(String::New("boot")); |
| 543 const Function& boot_function = Function::Handle( | 514 const Function& boot_function = Function::Handle( |
| 544 vmservice_library.LookupFunctionAllowPrivate(boot_function_name)); | 515 vmservice_library.LookupFunctionAllowPrivate(boot_function_name)); |
| 545 ASSERT(!boot_function.IsNull()); | 516 ASSERT(!boot_function.IsNull()); |
| 546 const Object& result = Object::Handle( | 517 const Object& result = Object::Handle( |
| 547 DartEntry::InvokeFunction(boot_function, Object::empty_array())); | 518 DartEntry::InvokeFunction(boot_function, Object::empty_array())); |
| 548 ASSERT(!result.IsNull()); | 519 ASSERT(!result.IsNull()); |
| 549 if (result.IsUnwindError() || result.IsUnhandledException()) { | 520 if (result.IsUnwindError() || result.IsUnhandledException()) { |
| 550 Exceptions::PropagateError(Error::Cast(result)); | 521 Exceptions::PropagateError(Error::Cast(result)); |
| 551 } | 522 } |
| 552 Dart_Port port = ILLEGAL_PORT; | 523 Dart_Port port = ILLEGAL_PORT; |
| 553 if (result.IsReceivePort()) { | 524 if (result.IsReceivePort()) { |
| 554 port = ReceivePort::Cast(result).Id(); | 525 port = ReceivePort::Cast(result).Id(); |
| 555 } | 526 } |
| 556 ASSERT(port != ILLEGAL_PORT); | 527 ASSERT(port != ILLEGAL_PORT); |
| 557 ServiceIsolate::SetServicePort(port); | 528 ServiceIsolate::SetServicePort(port); |
| 558 } | 529 } |
| 559 | 530 |
| 560 | |
| 561 void ServiceIsolate::VisitObjectPointers(ObjectPointerVisitor* visitor) {} | 531 void ServiceIsolate::VisitObjectPointers(ObjectPointerVisitor* visitor) {} |
| 562 | 532 |
| 563 } // namespace dart | 533 } // namespace dart |
| OLD | NEW |