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

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

Issue 125103004: Move service into VM (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 11 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/service.h" 5 #include "vm/service.h"
6 6
7 #include "include/dart_api.h"
8
7 #include "vm/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/dart_api_impl.h"
8 #include "vm/dart_entry.h" 11 #include "vm/dart_entry.h"
9 #include "vm/debugger.h" 12 #include "vm/debugger.h"
10 #include "vm/heap_histogram.h" 13 #include "vm/heap_histogram.h"
11 #include "vm/isolate.h" 14 #include "vm/isolate.h"
12 #include "vm/message.h" 15 #include "vm/message.h"
16 #include "vm/native_entry.h"
17 #include "vm/native_arguments.h"
13 #include "vm/object.h" 18 #include "vm/object.h"
14 #include "vm/object_id_ring.h" 19 #include "vm/object_id_ring.h"
15 #include "vm/object_store.h" 20 #include "vm/object_store.h"
16 #include "vm/port.h" 21 #include "vm/port.h"
17 #include "vm/profiler.h" 22 #include "vm/profiler.h"
18 23
24
19 namespace dart { 25 namespace dart {
20 26
21 typedef void (*ServiceMessageHandler)(Isolate* isolate, JSONStream* stream); 27 struct ResourcesEntry {
22 28 const char* path_;
23 struct ServiceMessageHandlerEntry { 29 const char* resource_;
24 const char* command; 30 int length_;
25 ServiceMessageHandler handler;
26 }; 31 };
27 32
28 static ServiceMessageHandler FindServiceMessageHandler(const char* command); 33 extern ResourcesEntry __service_resources_[];
34
35 class Resources {
36 public:
37 static const int kNoSuchInstance = -1;
38 static int ResourceLookup(const char* path, const char** resource) {
39 ResourcesEntry* table = ResourceTable();
40 for (int i = 0; table[i].path_ != NULL; i++) {
41 const ResourcesEntry& entry = table[i];
42 if (strcmp(path, entry.path_) == 0) {
43 *resource = entry.resource_;
44 ASSERT(entry.length_ > 0);
45 return entry.length_;
46 }
47 }
48 return kNoSuchInstance;
49 }
50
51 static const char* Path(int idx) {
52 ASSERT(idx >= 0);
53 ResourcesEntry* entry = At(idx);
54 if (entry == NULL) {
55 return NULL;
56 }
57 ASSERT(entry->path_ != NULL);
58 return entry->path_;
59 }
60
61 static const char* Resource(int idx) {
62 ASSERT(idx >= 0);
63 ResourcesEntry* entry = At(idx);
64 if (entry == NULL) {
65 return NULL;
66 }
67 return entry->resource_;
68 }
69
70 private:
71 static ResourcesEntry* At(int idx) {
72 ASSERT(idx >= 0);
73 ResourcesEntry* table = ResourceTable();
74 for (int i = 0; table[i].path_ != NULL; i++) {
75 if (idx == i) {
76 return &table[i];
77 }
78 }
79 return NULL;
80 }
81
82 static ResourcesEntry* ResourceTable() {
83 return &__service_resources_[0];
84 }
85
86 DISALLOW_ALLOCATION();
87 DISALLOW_IMPLICIT_CONSTRUCTORS(Resources);
88 };
29 89
30 90
31 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { 91 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) {
32 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); 92 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
33 return reinterpret_cast<uint8_t*>(new_ptr); 93 return reinterpret_cast<uint8_t*>(new_ptr);
34 } 94 }
35 95
36 96
97 static void SendServiceMessage(Dart_NativeArguments args) {
98 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
99 Isolate* isolate = arguments->isolate();
100 StackZone zone(isolate);
101 HANDLESCOPE(isolate);
102 GET_NON_NULL_NATIVE_ARGUMENT(Instance, sp, arguments->NativeArgAt(0));
103 GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(1));
104
105 // Extract SendPort port id.
106 const Object& sp_id_obj = Object::Handle(DartLibraryCalls::PortGetId(sp));
107 if (sp_id_obj.IsError()) {
108 Exceptions::PropagateError(Error::Cast(sp_id_obj));
109 }
110 Integer& id = Integer::Handle();
111 id ^= sp_id_obj.raw();
112 Dart_Port sp_id = static_cast<Dart_Port>(id.AsInt64Value());
113 ASSERT(sp_id != ILLEGAL_PORT);
114
115 // Serialize message.
116 uint8_t* data = NULL;
117 MessageWriter writer(&data, &allocator);
118 writer.WriteMessage(message);
119
120 // TODO(turnidge): Throw an exception when the return value is false?
121 PortMap::PostMessage(new Message(sp_id, data, writer.BytesWritten(),
122 Message::kOOBPriority));
123 }
124
125
126 struct VmServiceNativeEntry {
127 const char* name;
128 int num_arguments;
129 Dart_NativeFunction function;
130 };
131
132
133 static VmServiceNativeEntry _VmServiceNativeEntries[] = {
134 {"VMService_SendServiceMessage", 2, SendServiceMessage}
135 };
136
137
138 static Dart_NativeFunction VmServiceNativeResolver(Dart_Handle name,
139 int num_arguments,
140 bool* auto_setup_scope) {
141 const Object& obj = Object::Handle(Api::UnwrapHandle(name));
142 if (!obj.IsString()) {
143 return NULL;
144 }
145 const char* function_name = obj.ToCString();
146 ASSERT(function_name != NULL);
147 ASSERT(auto_setup_scope != NULL);
148 *auto_setup_scope = true;
149 intptr_t n =
150 sizeof(_VmServiceNativeEntries) / sizeof(_VmServiceNativeEntries[0]);
151 for (intptr_t i = 0; i < n; i++) {
152 VmServiceNativeEntry entry = _VmServiceNativeEntries[i];
153 if (!strcmp(function_name, entry.name) &&
154 (num_arguments == entry.num_arguments)) {
155 return entry.function;
156 }
157 }
158 return NULL;
159 }
160
161 #define SHUTDOWN(error_msg) \
162 printf("Service Isolate Error: %s\n", error_msg); \
163 Dart_ExitScope(); \
164 Dart_ShutdownIsolate(); \
165 return NULL
166
167 #define SHUTDOWN_ON_ERROR(handle) \
168 if (Dart_IsError(handle)) { \
169 SHUTDOWN(Dart_GetError(handle)); \
170 }
171
172 Isolate* Service::service_isolate_ = NULL;
173 Dart_LibraryTagHandler Service::default_handler_ = NULL;
174 Dart_Port Service::port_ = ILLEGAL_PORT;
175
176 Isolate* Service::GetServiceIsolate(void* callback_data) {
siva 2014/01/14 18:19:00 I am wondering if we should split this into Servic
177 if (service_isolate_ != NULL) {
178 // Already initialized, return service isolate.
179 return service_isolate_;
180 }
181 Dart_ServiceIsolateCreateCalback create_callback =
182 Isolate::ServiceCreateCallback();
183 if (create_callback == NULL) {
184 return NULL;
185 }
186 if (Dart_CurrentIsolate() != NULL) {
187 // Clear current isolate.
188 Dart_ExitIsolate();
189 }
190 char* error = NULL;
191 Dart_Isolate isolate = create_callback(callback_data, &error);
192 if (isolate == NULL) {
193 printf("Service Isolate Error: %s\n", error);
194 return NULL;
195 }
196 Dart_EnterIsolate(isolate);
197 Dart_EnterScope();
198 Dart_Handle result;
199 Dart_Handle root_library = Dart_RootLibrary();
200 SHUTDOWN_ON_ERROR(root_library);
201 ASSERT(root_library == Dart_Null());
202 // Retrieve the embedder default library tag handler.
203 default_handler_ = reinterpret_cast<Isolate*>(isolate)->library_tag_handler();
204 ASSERT(default_handler_ != NULL);
205 // Temporarily install our own.
206 Dart_SetLibraryTagHandler(LibraryTagHandler);
207 // Load VM service library.
208 Dart_Handle library;
209 {
210 const char* resource = NULL;
211 const char* path = "/vmservice.dart";
212 int r = Resources::ResourceLookup(path, &resource);
213 ASSERT(r != Resources::kNoSuchInstance);
214 ASSERT(resource != NULL);
215 Dart_Handle url = Dart_NewStringFromCString("dart:vmservice");
siva 2014/01/14 18:19:00 We have made symbols of other core dart libraries
216 SHUTDOWN_ON_ERROR(url);
217 Dart_Handle source = Dart_NewStringFromCString(resource);
siva 2014/01/14 18:19:00 I think this may not be right to treat the dart:vm
218 SHUTDOWN_ON_ERROR(source);
219 library = Dart_LoadLibrary(url, source);
220 SHUTDOWN_ON_ERROR(library);
221 result = Dart_SetNativeResolver(library, VmServiceNativeResolver);
222 SHUTDOWN_ON_ERROR(result);
223 }
224 // Install embedder default library tag handler again.
225 Dart_SetLibraryTagHandler(default_handler_);
226 default_handler_ = NULL;
227 // Boot the service.
228 {
229 result = Dart_Invoke(library, Dart_NewStringFromCString("boot"), 0, NULL);
230 SHUTDOWN_ON_ERROR(result);
231 HANDLESCOPE(Isolate::Current());
232 const Object& unwrapped_rp = Object::Handle(Api::UnwrapHandle(result));
233 const Instance& rp = Instance::Cast(unwrapped_rp);
234 // Extract RawReceivePort port id.
235 const Object& rp_id_obj = Object::Handle(DartLibraryCalls::PortGetId(rp));
236 if (rp_id_obj.IsError()) {
237 const Error& error = Error::Cast(rp_id_obj);
238 SHUTDOWN(error.ToErrorCString());
239 }
240 ASSERT(rp_id_obj.IsSmi() || rp_id_obj.IsMint());
241 const Integer& id = Integer::Cast(rp_id_obj);
242 port_ = static_cast<Dart_Port>(id.AsInt64Value());
243 }
244 Dart_ExitScope();
245 Dart_ExitIsolate();
246 service_isolate_ = reinterpret_cast<Isolate*>(isolate);
247 return service_isolate_;
siva 2014/01/14 18:19:00 one general comment about this function, we are in
Cutch 2014/01/14 19:53:26 Done.
248 }
249
250
251 // These must be kept in sync with service/constants.dart
252 #define VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID 1
253 #define VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID 2
254
255
256 static Dart_Handle MakeServiceControlMessage(Dart_Port port_id, intptr_t code,
257 Dart_Handle name) {
258 Dart_Handle result;
259 Dart_Handle list = Dart_NewList(4);
260 ASSERT(!Dart_IsError(list));
261 Dart_Handle code_handle = Dart_NewInteger(code);
262 ASSERT(!Dart_IsError(code_handle));
263 result = Dart_ListSetAt(list, 0, code_handle);
264 ASSERT(!Dart_IsError(result));
265 Dart_Handle port_id_handle = Dart_NewInteger(port_id);
266 ASSERT(!Dart_IsError(port_id_handle));
267 result = Dart_ListSetAt(list, 1, port_id_handle);
268 ASSERT(!Dart_IsError(result));
269 Dart_Handle sendPort = Dart_NewSendPort(port_id);
270 ASSERT(!Dart_IsError(sendPort));
271 result = Dart_ListSetAt(list, 2, sendPort);
272 ASSERT(!Dart_IsError(result));
273 result = Dart_ListSetAt(list, 3, name);
274 ASSERT(!Dart_IsError(result));
275 return list;
siva 2014/01/14 18:19:00 Same comment about this function it could be plain
Cutch 2014/01/14 19:53:26 Done.
276 }
277
278
279 bool Service::SendIsolateStartupMessage() {
280 if (!IsRunning()) {
281 return false;
282 }
283 Isolate* isolate = Isolate::Current();
284 ASSERT(isolate != NULL);
285 HANDLESCOPE(isolate);
286 Dart_EnterScope();
287 Dart_Handle name = Api::NewHandle(isolate, String::New(isolate->name()));
288 ASSERT(!Dart_IsError(name));
289 Dart_Handle list =
290 MakeServiceControlMessage(Dart_GetMainPortId(),
291 VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID,
292 name);
293 ASSERT(!Dart_IsError(list));
294 bool r = Dart_Post(port_, list);
295 Dart_ExitScope();
296 return r;
297 }
298
299
300 bool Service::SendIsolateShutdownMessage() {
301 if (!IsRunning()) {
302 return false;
303 }
304 Isolate* isolate = Isolate::Current();
305 ASSERT(isolate != NULL);
306 HANDLESCOPE(isolate);
307 Dart_EnterScope();
308 Dart_Handle list =
309 MakeServiceControlMessage(Dart_GetMainPortId(),
310 VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID,
311 Dart_Null());
312 ASSERT(!Dart_IsError(list));
313 bool r = Dart_Post(port_, list);
314 Dart_ExitScope();
315 return r;
316 }
317
318
319 bool Service::IsRunning() {
320 return port_ != ILLEGAL_PORT;
321 }
322
323
324 Dart_Handle Service::GetSource(const char* name) {
325 ASSERT(name != NULL);
326 int i = 0;
327 while (true) {
328 const char* path = Resources::Path(i);
329 if (path == NULL) {
330 break;
331 }
332 ASSERT(*path != '\0');
333 // Skip the '/'.
334 path++;
335 if (strcmp(name, path) == 0) {
336 return Dart_NewStringFromCString(Resources::Resource(i));
337 }
338 i++;
339 }
340 return Dart_Null();
341 }
342
343
344 Dart_Handle Service::LibraryTagHandler(Dart_LibraryTag tag, Dart_Handle library,
345 Dart_Handle url) {
346 if (!Dart_IsLibrary(library)) {
347 return Dart_NewApiError("not a library");
348 }
349 if (!Dart_IsString(url)) {
350 return Dart_NewApiError("url is not a string");
351 }
352 const char* url_string = NULL;
353 Dart_Handle result = Dart_StringToCString(url, &url_string);
354 if (Dart_IsError(result)) {
355 return result;
356 }
357 if (tag == Dart_kImportTag) {
358 // Embedder handles all requests for external libraries.
359 ASSERT(default_handler_ != NULL);
360 return default_handler_(tag, library, url);
361 }
362 ASSERT((tag == Dart_kSourceTag) || (tag == Dart_kCanonicalizeUrl));
363 if (tag == Dart_kCanonicalizeUrl) {
364 // url is already canonicalized.
365 return url;
366 }
367 Dart_Handle source = GetSource(url_string);
368 if (Dart_IsError(source)) {
369 return source;
370 }
371 return Dart_LoadSource(library, url, source);
372 }
373
374
375 typedef void (*ServiceMessageHandler)(Isolate* isolate, JSONStream* stream);
376
377 struct ServiceMessageHandlerEntry {
378 const char* command;
379 ServiceMessageHandler handler;
380 };
381
382 static ServiceMessageHandler FindServiceMessageHandler(const char* command);
383
37 static void PostReply(const String& reply, const Instance& reply_port) { 384 static void PostReply(const String& reply, const Instance& reply_port) {
38 const Object& id_obj = Object::Handle( 385 const Object& id_obj = Object::Handle(
39 DartLibraryCalls::PortGetId(reply_port)); 386 DartLibraryCalls::PortGetId(reply_port));
40 if (id_obj.IsError()) { 387 if (id_obj.IsError()) {
41 Exceptions::PropagateError(Error::Cast(id_obj)); 388 Exceptions::PropagateError(Error::Cast(id_obj));
42 } 389 }
43 const Integer& id = Integer::Cast(id_obj); 390 const Integer& id = Integer::Cast(id_obj);
44 Dart_Port port = static_cast<Dart_Port>(id.AsInt64Value()); 391 Dart_Port port = static_cast<Dart_Port>(id.AsInt64Value());
45 ASSERT(port != ILLEGAL_PORT); 392 ASSERT(port != ILLEGAL_PORT);
46 393
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 for (intptr_t i = 0; i < num_message_handlers; i++) { 996 for (intptr_t i = 0; i < num_message_handlers; i++) {
650 const ServiceMessageHandlerEntry& entry = __message_handlers[i]; 997 const ServiceMessageHandlerEntry& entry = __message_handlers[i];
651 if (!strcmp(command, entry.command)) { 998 if (!strcmp(command, entry.command)) {
652 return entry.handler; 999 return entry.handler;
653 } 1000 }
654 } 1001 }
655 return HandleFallthrough; 1002 return HandleFallthrough;
656 } 1003 }
657 1004
658 } // namespace dart 1005 } // namespace dart
OLDNEW
« runtime/bin/main.cc ('K') | « runtime/vm/service.h ('k') | runtime/vm/service/client.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698