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

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

Issue 98253009: Refactor VM service IDs (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 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
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 "vm/cpu.h" 7 #include "vm/cpu.h"
8 #include "vm/dart_entry.h" 8 #include "vm/dart_entry.h"
9 #include "vm/debugger.h" 9 #include "vm/debugger.h"
10 #include "vm/heap_histogram.h" 10 #include "vm/heap_histogram.h"
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 jsobj.AddProperty("name", isolate->name()); 189 jsobj.AddProperty("name", isolate->name());
190 } 190 }
191 191
192 192
193 static void HandleStackTrace(Isolate* isolate, JSONStream* js) { 193 static void HandleStackTrace(Isolate* isolate, JSONStream* js) {
194 DebuggerStackTrace* stack = isolate->debugger()->StackTrace(); 194 DebuggerStackTrace* stack = isolate->debugger()->StackTrace();
195 JSONObject jsobj(js); 195 JSONObject jsobj(js);
196 jsobj.AddProperty("type", "StackTrace"); 196 jsobj.AddProperty("type", "StackTrace");
197 JSONArray jsarr(&jsobj, "members"); 197 JSONArray jsarr(&jsobj, "members");
198 intptr_t n_frames = stack->Length(); 198 intptr_t n_frames = stack->Length();
199 String& url = String::Handle();
200 String& function = String::Handle(); 199 String& function = String::Handle();
200 Script& script = Script::Handle();
201 for (int i = 0; i < n_frames; i++) { 201 for (int i = 0; i < n_frames; i++) {
202 ActivationFrame* frame = stack->FrameAt(i); 202 ActivationFrame* frame = stack->FrameAt(i);
203 url ^= frame->SourceUrl(); 203 script ^= frame->SourceScript();
204 function ^= frame->function().UserVisibleName(); 204 function ^= frame->function().UserVisibleName();
205 JSONObject jsobj(&jsarr); 205 JSONObject jsobj(&jsarr);
206 jsobj.AddProperty("name", function.ToCString()); 206 jsobj.AddProperty("name", function.ToCString());
207 jsobj.AddProperty("url", url.ToCString()); 207 jsobj.AddProperty("script", script);
208 jsobj.AddProperty("line", frame->LineNumber()); 208 jsobj.AddProperty("line", frame->LineNumber());
209 jsobj.AddProperty("function", frame->function()); 209 jsobj.AddProperty("function", frame->function());
210 jsobj.AddProperty("code", frame->code()); 210 jsobj.AddProperty("code", frame->code());
211 } 211 }
212 } 212 }
213 213
214 214
215 static void HandleObjectHistogram(Isolate* isolate, JSONStream* js) { 215 static void HandleObjectHistogram(Isolate* isolate, JSONStream* js) {
216 ObjectHistogram* histogram = Isolate::Current()->object_histogram(); 216 ObjectHistogram* histogram = Isolate::Current()->object_histogram();
217 if (histogram == NULL) { 217 if (histogram == NULL) {
(...skipping 14 matching lines...) Expand all
232 232
233 233
234 // Print an error message if there is no ID argument. 234 // Print an error message if there is no ID argument.
235 #define REQUIRE_COLLECTION_ID(collection) \ 235 #define REQUIRE_COLLECTION_ID(collection) \
236 if (js->num_arguments() == 1) { \ 236 if (js->num_arguments() == 1) { \
237 PrintError(js, "Must specify collection object id: /%s/id", collection); \ 237 PrintError(js, "Must specify collection object id: /%s/id", collection); \
238 return; \ 238 return; \
239 } 239 }
240 240
241 241
242 #define CHECK_COLLECTION_ID_BOUNDS(collection, length, arg, id, js) \
243 if (!GetIntegerId(arg, &id)) { \
244 PrintError(js, "Must specify collection object id: %s/id", collection); \
245 return; \
246 } \
247 if ((id < 0) || (id >= length)) { \
248 PrintError(js, "%s id (%" Pd ") must be in [0, %" Pd ").", collection, id, \
249 length); \
250 return; \
251 }
252
253
254 static bool GetIntegerId(const char* s, intptr_t* id) {
255 if ((s == NULL) || (*s == '\0')) {
256 // Empty string.
257 return false;
258 }
259 if (id == NULL) {
260 // No id pointer.
261 return false;
262 }
263 intptr_t r = 0;
264 char* end_ptr = NULL;
265 r = strtol(s, &end_ptr, 10);
266 if (end_ptr == s) {
267 // String was not advanced at all, cannot be valid.
268 return false;
269 }
270 *id = r;
271 return true;
272 }
273
274
275 static void HandleClassesClosures(Isolate* isolate, const Class& cls,
276 JSONStream* js) {
277 const GrowableObjectArray& closures =
278 GrowableObjectArray::Handle(cls.closures());
279 intptr_t id;
280 if (js->num_arguments() > 4) {
281 PrintError(js, "Command too long");
282 return;
283 }
284 CHECK_COLLECTION_ID_BOUNDS("closures", closures.Length(), js->GetArgument(3),
285 id, js);
286 Function& function = Function::Handle();
287 function ^= closures.At(id);
288 ASSERT(!function.IsNull());
289 function.PrintToJSONStream(js, false);
290 }
291
292
293 static void HandleClassesFunctions(Isolate* isolate, const Class& cls,
294 JSONStream* js) {
295 const Array& functions =
296 Array::Handle(cls.functions());
297 intptr_t id;
298 if (js->num_arguments() > 4) {
299 PrintError(js, "Command too long");
300 return;
301 }
302 CHECK_COLLECTION_ID_BOUNDS("functions", functions.Length(),
303 js->GetArgument(3), id, js);
304 Function& function = Function::Handle();
305 function ^= functions.At(id);
306 ASSERT(!function.IsNull());
307 function.PrintToJSONStream(js, false);
308 }
309
310
311 static void HandleClassesFields(Isolate* isolate, const Class& cls,
312 JSONStream* js) {
313 const Array& fields =
314 Array::Handle(cls.fields());
315 intptr_t id;
316 if (js->num_arguments() > 4) {
317 PrintError(js, "Command too long");
318 return;
319 }
320 CHECK_COLLECTION_ID_BOUNDS("fields", fields.Length(), js->GetArgument(3),
321 id, js);
322 Field& field = Field::Handle();
323 field ^= fields.At(id);
324 ASSERT(!field.IsNull());
325 field.PrintToJSONStream(js, false);
326 }
327
328
242 static void HandleClasses(Isolate* isolate, JSONStream* js) { 329 static void HandleClasses(Isolate* isolate, JSONStream* js) {
243 if (js->num_arguments() == 1) { 330 if (js->num_arguments() == 1) {
244 ClassTable* table = isolate->class_table(); 331 ClassTable* table = isolate->class_table();
245 table->PrintToJSONStream(js); 332 table->PrintToJSONStream(js);
246 return; 333 return;
247 } 334 }
248 ASSERT(js->num_arguments() >= 2); 335 ASSERT(js->num_arguments() >= 2);
249 intptr_t id = atoi(js->GetArgument(1)); 336 intptr_t id;
337 if (!GetIntegerId(js->GetArgument(1), &id)) {
338 PrintError(js, "Must specify collection object id: /classes/id");
339 return;
340 }
250 ClassTable* table = isolate->class_table(); 341 ClassTable* table = isolate->class_table();
251 if (!table->IsValidIndex(id)) { 342 if (!table->IsValidIndex(id)) {
252 Object::null_object().PrintToJSONStream(js, false); 343 PrintError(js, "%" Pd " is not a valid class id.", id);;
253 } else { 344 return;
254 Class& cls = Class::Handle(table->At(id)); 345 }
346 Class& cls = Class::Handle(table->At(id));
347 if (js->num_arguments() == 2) {
255 cls.PrintToJSONStream(js, false); 348 cls.PrintToJSONStream(js, false);
349 return;
350 } else if (js->num_arguments() >= 3) {
351 const char* second = js->GetArgument(2);
352 if (!strcmp(second, "closures")) {
353 HandleClassesClosures(isolate, cls, js);
354 } else if (!strcmp(second, "fields")) {
355 HandleClassesFields(isolate, cls, js);
356 } else if (!strcmp(second, "functions")) {
357 HandleClassesFunctions(isolate, cls, js);
358 } else {
359 PrintError(js, "Invalid sub collection %s", second);
360 }
361 return;
256 } 362 }
363 UNREACHABLE();
257 } 364 }
258 365
259 366
260 static void HandleLibrary(Isolate* isolate, JSONStream* js) { 367 static void HandleLibrary(Isolate* isolate, JSONStream* js) {
261 if (js->num_arguments() == 1) { 368 if (js->num_arguments() == 1) {
262 const Library& lib = 369 const Library& lib =
263 Library::Handle(isolate->object_store()->root_library()); 370 Library::Handle(isolate->object_store()->root_library());
264 lib.PrintToJSONStream(js, false); 371 lib.PrintToJSONStream(js, false);
265 return; 372 return;
266 } 373 }
267 PrintGenericError(js); 374 PrintGenericError(js);
268 } 375 }
269 376
270 377
378 static void HandleLibraries(Isolate* isolate, JSONStream* js) {
379 // TODO(johnmccutchan): Support fields and functions on libraries.
380 REQUIRE_COLLECTION_ID("libraries");
381 const GrowableObjectArray& libs =
382 GrowableObjectArray::Handle(isolate->object_store()->libraries());
383 ASSERT(!libs.IsNull());
384 intptr_t id = 0;
385 CHECK_COLLECTION_ID_BOUNDS("libraries", libs.Length(), js->GetArgument(1),
386 id, js);
387 Library& lib = Library::Handle();
388 lib ^= libs.At(id);
389 ASSERT(!lib.IsNull());
390 lib.PrintToJSONStream(js, false);
391 }
392
393
271 static void HandleObjects(Isolate* isolate, JSONStream* js) { 394 static void HandleObjects(Isolate* isolate, JSONStream* js) {
272 REQUIRE_COLLECTION_ID("objects"); 395 REQUIRE_COLLECTION_ID("objects");
273 ASSERT(js->num_arguments() >= 2); 396 ASSERT(js->num_arguments() >= 2);
274 ObjectIdRing* ring = isolate->object_id_ring(); 397 ObjectIdRing* ring = isolate->object_id_ring();
275 ASSERT(ring != NULL); 398 ASSERT(ring != NULL);
276 intptr_t id = atoi(js->GetArgument(1)); 399 intptr_t id = -1;
400 if (!GetIntegerId(js->GetArgument(1), &id)) {
401 Object::null_object().PrintToJSONStream(js, false);
402 return;
403 }
277 Object& obj = Object::Handle(ring->GetObjectForId(id)); 404 Object& obj = Object::Handle(ring->GetObjectForId(id));
278 obj.PrintToJSONStream(js, false); 405 obj.PrintToJSONStream(js, false);
279 } 406 }
280 407
281 408
409
410 static void HandleScriptsEnumerate(Isolate* isolate, JSONStream* js) {
411 JSONObject jsobj(js);
412 jsobj.AddProperty("type", "ScriptList");
413 {
414 JSONArray members(&jsobj, "members");
415 const GrowableObjectArray& libs =
416 GrowableObjectArray::Handle(isolate->object_store()->libraries());
417 int num_libs = libs.Length();
418 Library &lib = Library::Handle();
419 Script& script = Script::Handle();
420 for (intptr_t i = 0; i < num_libs; i++) {
421 lib ^= libs.At(i);
422 ASSERT(!lib.IsNull());
423 ASSERT(Smi::IsValid(lib.index()));
424 const Array& loaded_scripts = Array::Handle(lib.LoadedScripts());
425 ASSERT(!loaded_scripts.IsNull());
426 intptr_t num_scripts = loaded_scripts.Length();
427 for (intptr_t i = 0; i < num_scripts; i++) {
428 script ^= loaded_scripts.At(i);
429 members.AddValue(script);
430 }
431 }
432 }
433 }
434
435
436 static void HandleScriptsFetch(Isolate* isolate, JSONStream* js) {
437 const GrowableObjectArray& libs =
438 GrowableObjectArray::Handle(isolate->object_store()->libraries());
439 int num_libs = libs.Length();
440 Library &lib = Library::Handle();
441 Script& script = Script::Handle();
442 String& url = String::Handle();
443 const String& id = String::Handle(String::New(js->GetArgument(1)));
444 ASSERT(!id.IsNull());
445 // The id is the url of the script % encoded, decode it.
446 String& requested_url = String::Handle(String::DecodeURI(id));
447 for (intptr_t i = 0; i < num_libs; i++) {
448 lib ^= libs.At(i);
449 ASSERT(!lib.IsNull());
450 ASSERT(Smi::IsValid(lib.index()));
451 const Array& loaded_scripts = Array::Handle(lib.LoadedScripts());
452 ASSERT(!loaded_scripts.IsNull());
453 intptr_t num_scripts = loaded_scripts.Length();
454 for (intptr_t i = 0; i < num_scripts; i++) {
455 script ^= loaded_scripts.At(i);
456 ASSERT(!script.IsNull());
457 url ^= script.url();
458 if (url.Equals(requested_url)) {
459 script.PrintToJSONStream(js, false);
460 return;
461 }
462 }
463 }
464 PrintError(js, "Cannot find script %s\n", requested_url.ToCString());
465 }
466
467
468 static void HandleScripts(Isolate* isolate, JSONStream* js) {
469 if (js->num_arguments() == 1) {
470 // Enumerate all scripts.
471 HandleScriptsEnumerate(isolate, js);
472 } else if (js->num_arguments() == 2) {
473 // Fetch specific script.
474 HandleScriptsFetch(isolate, js);
475 } else {
476 PrintError(js, "Command too long");
477 }
478 }
479
480
282 static void HandleDebug(Isolate* isolate, JSONStream* js) { 481 static void HandleDebug(Isolate* isolate, JSONStream* js) {
283 if (js->num_arguments() == 1) { 482 if (js->num_arguments() == 1) {
284 PrintError(js, "Must specify a subcommand"); 483 PrintError(js, "Must specify a subcommand");
285 return; 484 return;
286 } 485 }
287 const char* command = js->GetArgument(1); 486 const char* command = js->GetArgument(1);
288 if (!strcmp(command, "breakpoints")) { 487 if (!strcmp(command, "breakpoints")) {
289 if (js->num_arguments() == 2) { 488 if (js->num_arguments() == 2) {
290 // Print breakpoint list. 489 // Print breakpoint list.
291 JSONObject jsobj(js); 490 JSONObject jsobj(js);
292 jsobj.AddProperty("type", "BreakpointList"); 491 jsobj.AddProperty("type", "BreakpointList");
293 JSONArray jsarr(&jsobj, "breakpoints"); 492 JSONArray jsarr(&jsobj, "breakpoints");
294 isolate->debugger()->PrintBreakpointsToJSONArray(&jsarr); 493 isolate->debugger()->PrintBreakpointsToJSONArray(&jsarr);
295 494
296 } else if (js->num_arguments() == 3) { 495 } else if (js->num_arguments() == 3) {
297 // Print individual breakpoint. 496 // Print individual breakpoint.
298 intptr_t id = atoi(js->GetArgument(2)); 497 intptr_t id = 0;
299 SourceBreakpoint* bpt = isolate->debugger()->GetBreakpointById(id); 498 SourceBreakpoint* bpt = NULL;
499 if (GetIntegerId(js->GetArgument(2), &id)) {
500 bpt = isolate->debugger()->GetBreakpointById(id);
501 }
300 if (bpt != NULL) { 502 if (bpt != NULL) {
301 bpt->PrintToJSONStream(js); 503 bpt->PrintToJSONStream(js);
302 } else { 504 } else {
303 PrintError(js, "Unrecognized breakpoint id %s", js->GetArgument(2)); 505 PrintError(js, "Unrecognized breakpoint id %s", js->GetArgument(2));
304 } 506 }
305 507
306 } else { 508 } else {
307 PrintError(js, "Command too long"); 509 PrintError(js, "Command too long");
308 } 510 }
309 } else { 511 } else {
310 PrintError(js, "Unrecognized subcommand '%s'", js->GetArgument(1)); 512 PrintError(js, "Unrecognized subcommand '%s'", js->GetArgument(1));
311 } 513 }
312 } 514 }
313 515
314 516
315 static void HandleCpu(Isolate* isolate, JSONStream* js) { 517 static void HandleCpu(Isolate* isolate, JSONStream* js) {
316 JSONObject jsobj(js); 518 JSONObject jsobj(js);
317 jsobj.AddProperty("type", "CPU"); 519 jsobj.AddProperty("type", "CPU");
318 jsobj.AddProperty("architecture", CPU::Id()); 520 jsobj.AddProperty("architecture", CPU::Id());
319 } 521 }
320 522
321 523
322 static ServiceMessageHandlerEntry __message_handlers[] = { 524 static ServiceMessageHandlerEntry __message_handlers[] = {
323 { "_echo", HandleEcho }, 525 { "_echo", HandleEcho },
324 { "classes", HandleClasses }, 526 { "classes", HandleClasses },
325 { "cpu", HandleCpu }, 527 { "cpu", HandleCpu },
326 { "debug", HandleDebug }, 528 { "debug", HandleDebug },
529 { "libraries", HandleLibraries },
327 { "library", HandleLibrary }, 530 { "library", HandleLibrary },
328 { "name", HandleName }, 531 { "name", HandleName },
329 { "objecthistogram", HandleObjectHistogram}, 532 { "objecthistogram", HandleObjectHistogram},
330 { "objects", HandleObjects }, 533 { "objects", HandleObjects },
534 { "scripts", HandleScripts },
331 { "stacktrace", HandleStackTrace }, 535 { "stacktrace", HandleStackTrace },
332 }; 536 };
333 537
334 538
335 static void HandleFallthrough(Isolate* isolate, JSONStream* js) { 539 static void HandleFallthrough(Isolate* isolate, JSONStream* js) {
336 JSONObject jsobj(js); 540 JSONObject jsobj(js);
337 jsobj.AddProperty("type", "Error"); 541 jsobj.AddProperty("type", "Error");
338 jsobj.AddProperty("text", "request not understood."); 542 jsobj.AddProperty("text", "request not understood.");
339 PrintArgumentsAndOptions(jsobj, js); 543 PrintArgumentsAndOptions(jsobj, js);
340 } 544 }
341 545
342 546
343 static ServiceMessageHandler FindServiceMessageHandler(const char* command) { 547 static ServiceMessageHandler FindServiceMessageHandler(const char* command) {
344 intptr_t num_message_handlers = sizeof(__message_handlers) / 548 intptr_t num_message_handlers = sizeof(__message_handlers) /
345 sizeof(__message_handlers[0]); 549 sizeof(__message_handlers[0]);
346 for (intptr_t i = 0; i < num_message_handlers; i++) { 550 for (intptr_t i = 0; i < num_message_handlers; i++) {
347 const ServiceMessageHandlerEntry& entry = __message_handlers[i]; 551 const ServiceMessageHandlerEntry& entry = __message_handlers[i];
348 if (!strcmp(command, entry.command)) { 552 if (!strcmp(command, entry.command)) {
349 return entry.handler; 553 return entry.handler;
350 } 554 }
351 } 555 }
352 return HandleFallthrough; 556 return HandleFallthrough;
353 } 557 }
354 558
355 } // namespace dart 559 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698