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

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
« no previous file with comments | « runtime/vm/service.h ('k') | runtime/vm/service/client.dart » ('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/service.h" 5 #include "vm/service.h"
6 6
7 #include "include/dart_api.h"
8
9 #include "vm/compiler.h"
7 #include "vm/cpu.h" 10 #include "vm/cpu.h"
11 #include "vm/dart_api_impl.h"
8 #include "vm/dart_entry.h" 12 #include "vm/dart_entry.h"
9 #include "vm/debugger.h" 13 #include "vm/debugger.h"
10 #include "vm/heap_histogram.h" 14 #include "vm/heap_histogram.h"
11 #include "vm/isolate.h" 15 #include "vm/isolate.h"
12 #include "vm/message.h" 16 #include "vm/message.h"
17 #include "vm/native_entry.h"
18 #include "vm/native_arguments.h"
13 #include "vm/object.h" 19 #include "vm/object.h"
14 #include "vm/object_id_ring.h" 20 #include "vm/object_id_ring.h"
15 #include "vm/object_store.h" 21 #include "vm/object_store.h"
16 #include "vm/port.h" 22 #include "vm/port.h"
17 #include "vm/profiler.h" 23 #include "vm/profiler.h"
24 #include "vm/symbols.h"
25
18 26
19 namespace dart { 27 namespace dart {
20 28
21 typedef void (*ServiceMessageHandler)(Isolate* isolate, JSONStream* stream); 29 struct ResourcesEntry {
22 30 const char* path_;
23 struct ServiceMessageHandlerEntry { 31 const char* resource_;
24 const char* command; 32 int length_;
25 ServiceMessageHandler handler;
26 }; 33 };
27 34
28 static ServiceMessageHandler FindServiceMessageHandler(const char* command); 35 extern ResourcesEntry __service_resources_[];
36
37 class Resources {
38 public:
39 static const int kNoSuchInstance = -1;
40 static int ResourceLookup(const char* path, const char** resource) {
41 ResourcesEntry* table = ResourceTable();
42 for (int i = 0; table[i].path_ != NULL; i++) {
43 const ResourcesEntry& entry = table[i];
44 if (strcmp(path, entry.path_) == 0) {
45 *resource = entry.resource_;
46 ASSERT(entry.length_ > 0);
47 return entry.length_;
48 }
49 }
50 return kNoSuchInstance;
51 }
52
53 static const char* Path(int idx) {
54 ASSERT(idx >= 0);
55 ResourcesEntry* entry = At(idx);
56 if (entry == NULL) {
57 return NULL;
58 }
59 ASSERT(entry->path_ != NULL);
60 return entry->path_;
61 }
62
63 static int Length(int idx) {
64 ASSERT(idx >= 0);
65 ResourcesEntry* entry = At(idx);
66 if (entry == NULL) {
67 return kNoSuchInstance;
68 }
69 ASSERT(entry->path_ != NULL);
70 return entry->length_;
71 }
72
73 static const uint8_t* Resource(int idx) {
74 ASSERT(idx >= 0);
75 ResourcesEntry* entry = At(idx);
76 if (entry == NULL) {
77 return NULL;
78 }
79 return reinterpret_cast<const uint8_t*>(entry->resource_);
80 }
81
82 private:
83 static ResourcesEntry* At(int idx) {
84 ASSERT(idx >= 0);
85 ResourcesEntry* table = ResourceTable();
86 for (int i = 0; table[i].path_ != NULL; i++) {
87 if (idx == i) {
88 return &table[i];
89 }
90 }
91 return NULL;
92 }
93
94 static ResourcesEntry* ResourceTable() {
95 return &__service_resources_[0];
96 }
97
98 DISALLOW_ALLOCATION();
99 DISALLOW_IMPLICIT_CONSTRUCTORS(Resources);
100 };
29 101
30 102
31 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { 103 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); 104 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
33 return reinterpret_cast<uint8_t*>(new_ptr); 105 return reinterpret_cast<uint8_t*>(new_ptr);
34 } 106 }
35 107
36 108
109 static void SendServiceMessage(Dart_NativeArguments args) {
110 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
111 Isolate* isolate = arguments->isolate();
112 StackZone zone(isolate);
113 HANDLESCOPE(isolate);
114 GET_NON_NULL_NATIVE_ARGUMENT(Instance, sp, arguments->NativeArgAt(0));
115 GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(1));
116
117 // Extract SendPort port id.
118 const Object& sp_id_obj = Object::Handle(DartLibraryCalls::PortGetId(sp));
119 if (sp_id_obj.IsError()) {
120 Exceptions::PropagateError(Error::Cast(sp_id_obj));
121 }
122 Integer& id = Integer::Handle();
123 id ^= sp_id_obj.raw();
124 Dart_Port sp_id = static_cast<Dart_Port>(id.AsInt64Value());
125 ASSERT(sp_id != ILLEGAL_PORT);
126
127 // Serialize message.
128 uint8_t* data = NULL;
129 MessageWriter writer(&data, &allocator);
130 writer.WriteMessage(message);
131
132 // TODO(turnidge): Throw an exception when the return value is false?
133 PortMap::PostMessage(new Message(sp_id, data, writer.BytesWritten(),
134 Message::kOOBPriority));
135 }
136
137
138 struct VmServiceNativeEntry {
139 const char* name;
140 int num_arguments;
141 Dart_NativeFunction function;
142 };
143
144
145 static VmServiceNativeEntry _VmServiceNativeEntries[] = {
146 {"VMService_SendServiceMessage", 2, SendServiceMessage}
147 };
148
149
150 static Dart_NativeFunction VmServiceNativeResolver(Dart_Handle name,
151 int num_arguments,
152 bool* auto_setup_scope) {
153 const Object& obj = Object::Handle(Api::UnwrapHandle(name));
154 if (!obj.IsString()) {
155 return NULL;
156 }
157 const char* function_name = obj.ToCString();
158 ASSERT(function_name != NULL);
159 ASSERT(auto_setup_scope != NULL);
160 *auto_setup_scope = true;
161 intptr_t n =
162 sizeof(_VmServiceNativeEntries) / sizeof(_VmServiceNativeEntries[0]);
163 for (intptr_t i = 0; i < n; i++) {
164 VmServiceNativeEntry entry = _VmServiceNativeEntries[i];
165 if (!strcmp(function_name, entry.name) &&
166 (num_arguments == entry.num_arguments)) {
167 return entry.function;
168 }
169 }
170 return NULL;
171 }
172
173
174 Isolate* Service::service_isolate_ = NULL;
175 Dart_LibraryTagHandler Service::default_handler_ = NULL;
176 Dart_Port Service::port_ = ILLEGAL_PORT;
177
178 static Dart_Port ExtractPort(Dart_Handle receivePort) {
179 HANDLESCOPE(Isolate::Current());
180 const Object& unwrapped_rp = Object::Handle(Api::UnwrapHandle(receivePort));
181 const Instance& rp = Instance::Cast(unwrapped_rp);
182 // Extract RawReceivePort port id.
183 const Object& rp_id_obj = Object::Handle(DartLibraryCalls::PortGetId(rp));
184 if (rp_id_obj.IsError()) {
185 return ILLEGAL_PORT;
186 }
187 ASSERT(rp_id_obj.IsSmi() || rp_id_obj.IsMint());
188 const Integer& id = Integer::Cast(rp_id_obj);
189 return static_cast<Dart_Port>(id.AsInt64Value());
190 }
191
192
193 Isolate* Service::GetServiceIsolate(void* callback_data) {
194 if (service_isolate_ != NULL) {
195 // Already initialized, return service isolate.
196 return service_isolate_;
197 }
198 Dart_ServiceIsolateCreateCalback create_callback =
199 Isolate::ServiceCreateCallback();
200 if (create_callback == NULL) {
201 return NULL;
202 }
203 Isolate::SetCurrent(NULL);
204 char* error = NULL;
205 Isolate* isolate = reinterpret_cast<Isolate*>(
206 create_callback(callback_data, &error));
207 if (isolate == NULL) {
208 return NULL;
209 }
210 Isolate::SetCurrent(isolate);
211 {
212 // Install the dart:vmservice library.
213 StackZone zone(isolate);
214 HANDLESCOPE(isolate);
215 Library& library =
216 Library::Handle(isolate, isolate->object_store()->root_library());
217 // Isolate is empty.
218 ASSERT(library.IsNull());
219 // Grab embedder tag handler.
220 default_handler_ = isolate->library_tag_handler();
221 ASSERT(default_handler_ != NULL);
222 // Temporarily install our own.
223 isolate->set_library_tag_handler(LibraryTagHandler);
224 // Get script resource.
225 const char* resource = NULL;
226 const char* path = "/vmservice.dart";
227 intptr_t r = Resources::ResourceLookup(path, &resource);
228 ASSERT(r != Resources::kNoSuchInstance);
229 ASSERT(resource != NULL);
230 const String& source_str = String::Handle(
231 String::FromUTF8(reinterpret_cast<const uint8_t*>(resource), r));
232 ASSERT(!source_str.IsNull());
233 const String& url_str = String::Handle(Symbols::DartVMService().raw());
234 library ^= Library::LookupLibrary(url_str);
235 ASSERT(library.IsNull());
236 // Setup library.
237 library = Library::New(url_str);
238 library.Register();
239 const Script& script = Script::Handle(
240 isolate, Script::New(url_str, source_str, RawScript::kLibraryTag));
241 library.SetLoadInProgress();
242 Dart_EnterScope(); // Need to enter scope for tag handler.
243 const Error& error = Error::Handle(isolate,
244 Compiler::Compile(library, script));
245 ASSERT(error.IsNull());
246 Dart_ExitScope();
247 library.SetLoaded();
248 // Install embedder default library tag handler again.
249 isolate->set_library_tag_handler(default_handler_);
250 default_handler_ = NULL;
251 library.set_native_entry_resolver(VmServiceNativeResolver);
252 }
253 {
254 // Boot the dart:vmservice library.
255 Dart_EnterScope();
256 Dart_Handle result;
257 Dart_Handle url_str =
258 Dart_NewStringFromCString(Symbols::Name(Symbols::kDartVMServiceId));
259 Dart_Handle library = Dart_LookupLibrary(url_str);
260 ASSERT(Dart_IsLibrary(library));
261 result = Dart_Invoke(library, Dart_NewStringFromCString("boot"), 0, NULL);
262 ASSERT(!Dart_IsError(result));
263 port_ = ExtractPort(result);
264 ASSERT(port_ != ILLEGAL_PORT);
265 Dart_ExitScope();
266 }
267 Isolate::SetCurrent(NULL);
268 service_isolate_ = reinterpret_cast<Isolate*>(isolate);
269 return service_isolate_;
270 }
271
272
273 // These must be kept in sync with service/constants.dart
274 #define VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID 1
275 #define VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID 2
276
277
278 static RawArray* MakeServiceControlMessage(Dart_Port port_id, intptr_t code,
279 const String& name) {
280 const Array& list = Array::Handle(Array::New(4));
281 ASSERT(!list.IsNull());
282 const Integer& code_int = Integer::Handle(Integer::New(code));
283 const Integer& port_int = Integer::Handle(Integer::New(port_id));
284 const Object& send_port = Object::Handle(
285 DartLibraryCalls::NewSendPort(port_id));
286 ASSERT(!send_port.IsNull());
287 list.SetAt(0, code_int);
288 list.SetAt(1, port_int);
289 list.SetAt(2, send_port);
290 list.SetAt(3, name);
291 return list.raw();
292 }
293
294
295 bool Service::SendIsolateStartupMessage() {
296 if (!IsRunning()) {
297 return false;
298 }
299 Isolate* isolate = Isolate::Current();
300 ASSERT(isolate != NULL);
301 HANDLESCOPE(isolate);
302 const String& name = String::Handle(String::New(isolate->name()));
303 ASSERT(!name.IsNull());
304 const Array& list = Array::Handle(
305 MakeServiceControlMessage(Dart_GetMainPortId(),
306 VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID,
307 name));
308 ASSERT(!list.IsNull());
309 uint8_t* data = NULL;
310 MessageWriter writer(&data, &allocator);
311 writer.WriteMessage(list);
312 intptr_t len = writer.BytesWritten();
313 return PortMap::PostMessage(
314 new Message(port_, data, len, Message::kNormalPriority));
315 }
316
317
318 bool Service::SendIsolateShutdownMessage() {
319 if (!IsRunning()) {
320 return false;
321 }
322 Isolate* isolate = Isolate::Current();
323 ASSERT(isolate != NULL);
324 HANDLESCOPE(isolate);
325 const Array& list = Array::Handle(
326 MakeServiceControlMessage(Dart_GetMainPortId(),
327 VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID,
328 String::Handle(String::null())));
329 ASSERT(!list.IsNull());
330 uint8_t* data = NULL;
331 MessageWriter writer(&data, &allocator);
332 writer.WriteMessage(list);
333 intptr_t len = writer.BytesWritten();
334 return PortMap::PostMessage(
335 new Message(port_, data, len, Message::kNormalPriority));
336 }
337
338
339 bool Service::IsRunning() {
340 return port_ != ILLEGAL_PORT;
341 }
342
343
344 Dart_Handle Service::GetSource(const char* name) {
345 ASSERT(name != NULL);
346 int i = 0;
347 while (true) {
348 const char* path = Resources::Path(i);
349 if (path == NULL) {
350 break;
351 }
352 ASSERT(*path != '\0');
353 // Skip the '/'.
354 path++;
355 if (strcmp(name, path) == 0) {
356 const uint8_t* str = Resources::Resource(i);
357 intptr_t length = Resources::Length(i);
358 return Dart_NewStringFromUTF8(str, length);
359 }
360 i++;
361 }
362 return Dart_Null();
363 }
364
365
366 Dart_Handle Service::LibraryTagHandler(Dart_LibraryTag tag, Dart_Handle library,
367 Dart_Handle url) {
368 if (!Dart_IsLibrary(library)) {
369 return Dart_NewApiError("not a library");
370 }
371 if (!Dart_IsString(url)) {
372 return Dart_NewApiError("url is not a string");
373 }
374 const char* url_string = NULL;
375 Dart_Handle result = Dart_StringToCString(url, &url_string);
376 if (Dart_IsError(result)) {
377 return result;
378 }
379 if (tag == Dart_kImportTag) {
380 // Embedder handles all requests for external libraries.
381 ASSERT(default_handler_ != NULL);
382 return default_handler_(tag, library, url);
383 }
384 ASSERT((tag == Dart_kSourceTag) || (tag == Dart_kCanonicalizeUrl));
385 if (tag == Dart_kCanonicalizeUrl) {
386 // url is already canonicalized.
387 return url;
388 }
389 Dart_Handle source = GetSource(url_string);
390 if (Dart_IsError(source)) {
391 return source;
392 }
393 return Dart_LoadSource(library, url, source);
394 }
395
396
397 typedef void (*ServiceMessageHandler)(Isolate* isolate, JSONStream* stream);
398
399 struct ServiceMessageHandlerEntry {
400 const char* command;
401 ServiceMessageHandler handler;
402 };
403
404 static ServiceMessageHandler FindServiceMessageHandler(const char* command);
405
37 static void PostReply(const String& reply, const Instance& reply_port) { 406 static void PostReply(const String& reply, const Instance& reply_port) {
38 const Object& id_obj = Object::Handle( 407 const Object& id_obj = Object::Handle(
39 DartLibraryCalls::PortGetId(reply_port)); 408 DartLibraryCalls::PortGetId(reply_port));
40 if (id_obj.IsError()) { 409 if (id_obj.IsError()) {
41 Exceptions::PropagateError(Error::Cast(id_obj)); 410 Exceptions::PropagateError(Error::Cast(id_obj));
42 } 411 }
43 const Integer& id = Integer::Cast(id_obj); 412 const Integer& id = Integer::Cast(id_obj);
44 Dart_Port port = static_cast<Dart_Port>(id.AsInt64Value()); 413 Dart_Port port = static_cast<Dart_Port>(id.AsInt64Value());
45 ASSERT(port != ILLEGAL_PORT); 414 ASSERT(port != ILLEGAL_PORT);
46 415
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 for (intptr_t i = 0; i < num_message_handlers; i++) { 1018 for (intptr_t i = 0; i < num_message_handlers; i++) {
650 const ServiceMessageHandlerEntry& entry = __message_handlers[i]; 1019 const ServiceMessageHandlerEntry& entry = __message_handlers[i];
651 if (!strcmp(command, entry.command)) { 1020 if (!strcmp(command, entry.command)) {
652 return entry.handler; 1021 return entry.handler;
653 } 1022 }
654 } 1023 }
655 return HandleFallthrough; 1024 return HandleFallthrough;
656 } 1025 }
657 1026
658 } // namespace dart 1027 } // namespace dart
OLDNEW
« no previous file with comments | « 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