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

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

Issue 895943002: Support root-level json rpc requests in the vm service. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 10 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') | 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/service.h" 5 #include "vm/service.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/globals.h" 8 #include "platform/globals.h"
9 9
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 823 matching lines...) Expand 10 before | Expand all | Expand 10 after
834 // posting the reply (this can be used for asynchronous delegation of 834 // posting the reply (this can be used for asynchronous delegation of
835 // the response handling). 835 // the response handling).
836 typedef bool (*RootMessageHandler)(JSONStream* stream); 836 typedef bool (*RootMessageHandler)(JSONStream* stream);
837 837
838 struct RootMessageHandlerEntry { 838 struct RootMessageHandlerEntry {
839 const char* command; 839 const char* command;
840 RootMessageHandler handler; 840 RootMessageHandler handler;
841 }; 841 };
842 842
843 static RootMessageHandler FindRootMessageHandler(const char* command); 843 static RootMessageHandler FindRootMessageHandler(const char* command);
844 static RootMessageHandler FindRootMessageHandlerNew(const char* command);
844 845
845 846
846 static void PrintArgumentsAndOptions(const JSONObject& obj, JSONStream* js) { 847 static void PrintArgumentsAndOptions(const JSONObject& obj, JSONStream* js) {
847 JSONObject jsobj(&obj, "request"); 848 JSONObject jsobj(&obj, "request");
848 { 849 {
849 JSONArray jsarr(&jsobj, "arguments"); 850 JSONArray jsarr(&jsobj, "arguments");
850 for (intptr_t i = 0; i < js->num_arguments(); i++) { 851 for (intptr_t i = 0; i < js->num_arguments(); i++) {
851 jsarr.AddValue(js->GetArgument(i)); 852 jsarr.AddValue(js->GetArgument(i));
852 } 853 }
853 } 854 }
(...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after
1449 return Object::sentinel().raw(); 1450 return Object::sentinel().raw();
1450 } 1451 }
1451 return type.raw(); 1452 return type.raw();
1452 } 1453 }
1453 1454
1454 // Not found. 1455 // Not found.
1455 return Object::sentinel().raw(); 1456 return Object::sentinel().raw();
1456 } 1457 }
1457 1458
1458 1459
1460 static RawObject* LookupHeapObjectCode(Isolate* isolate,
1461 char** parts, int num_parts) {
1462 if (num_parts != 2) {
1463 return Object::sentinel().raw();
1464 }
1465 uword pc;
1466 static const char* kCollectedPrefix = "collected-";
1467 static intptr_t kCollectedPrefixLen = strlen(kCollectedPrefix);
1468 static const char* kNativePrefix = "native-";
1469 static intptr_t kNativePrefixLen = strlen(kNativePrefix);
1470 static const char* kReusedPrefix = "reused-";
1471 static intptr_t kReusedPrefixLen = strlen(kReusedPrefix);
1472 const char* id = parts[1];
1473 if (strncmp(kCollectedPrefix, id, kCollectedPrefixLen) == 0) {
1474 if (!GetUnsignedIntegerId(&id[kCollectedPrefixLen], &pc, 16)) {
1475 return Object::sentinel().raw();
1476 }
1477 // TODO(turnidge): Return "collected" instead.
1478 return Object::null();
1479 }
1480 if (strncmp(kNativePrefix, id, kNativePrefixLen) == 0) {
1481 if (!GetUnsignedIntegerId(&id[kNativePrefixLen], &pc, 16)) {
1482 return Object::sentinel().raw();
1483 }
1484 // TODO(johnmccutchan): Support native Code.
1485 return Object::null();
1486 }
1487 if (strncmp(kReusedPrefix, id, kReusedPrefixLen) == 0) {
1488 if (!GetUnsignedIntegerId(&id[kReusedPrefixLen], &pc, 16)) {
1489 return Object::sentinel().raw();
1490 }
1491 // TODO(turnidge): Return "expired" instead.
1492 return Object::null();
1493 }
1494 int64_t timestamp = 0;
1495 if (!GetCodeId(id, &timestamp, &pc) || (timestamp < 0)) {
1496 return Object::sentinel().raw();
1497 }
1498 Code& code = Code::Handle(Code::FindCode(pc, timestamp));
1499 if (!code.IsNull()) {
1500 return code.raw();
1501 }
1502
1503 // Not found.
1504 return Object::sentinel().raw();
1505 }
1506
1507
1459 static RawObject* LookupHeapObject(Isolate* isolate, 1508 static RawObject* LookupHeapObject(Isolate* isolate,
1460 const char* id_original, 1509 const char* id_original,
1461 ObjectIdRing::LookupResult* result) { 1510 ObjectIdRing::LookupResult* result) {
1462 char* id = isolate->current_zone()->MakeCopyOfString(id_original); 1511 char* id = isolate->current_zone()->MakeCopyOfString(id_original);
1463 1512
1464 // Parse the id by splitting at each '/'. 1513 // Parse the id by splitting at each '/'.
1465 const int MAX_PARTS = 8; 1514 const int MAX_PARTS = 8;
1466 char* parts[MAX_PARTS]; 1515 char* parts[MAX_PARTS];
1467 int num_parts = 0; 1516 int num_parts = 0;
1468 int i = 0; 1517 int i = 0;
(...skipping 28 matching lines...) Expand all
1497 *result = lookup_result; 1546 *result = lookup_result;
1498 } 1547 }
1499 return Object::sentinel().raw(); 1548 return Object::sentinel().raw();
1500 } 1549 }
1501 return obj.raw(); 1550 return obj.raw();
1502 1551
1503 } else if (strcmp(parts[0], "libraries") == 0) { 1552 } else if (strcmp(parts[0], "libraries") == 0) {
1504 return LookupHeapObjectLibraries(isolate, parts, num_parts); 1553 return LookupHeapObjectLibraries(isolate, parts, num_parts);
1505 } else if (strcmp(parts[0], "classes") == 0) { 1554 } else if (strcmp(parts[0], "classes") == 0) {
1506 return LookupHeapObjectClasses(isolate, parts, num_parts); 1555 return LookupHeapObjectClasses(isolate, parts, num_parts);
1556 } else if (strcmp(parts[0], "code") == 0) {
1557 return LookupHeapObjectCode(isolate, parts, num_parts);
1507 } 1558 }
1508 1559
1509 // Not found. 1560 // Not found.
1510 return Object::sentinel().raw(); 1561 return Object::sentinel().raw();
1511 } 1562 }
1512 1563
1513 1564
1514 static void PrintSentinel(JSONStream* js, 1565 static void PrintSentinel(JSONStream* js,
1515 const char* id, 1566 const char* id,
1516 const char* preview) { 1567 const char* preview) {
(...skipping 1385 matching lines...) Expand 10 before | Expand all | Expand 10 after
2902 } 2953 }
2903 } 2954 }
2904 if (FLAG_trace_service) { 2955 if (FLAG_trace_service) {
2905 OS::Print("vm-service: No isolate message handler for <%s>.\n", command); 2956 OS::Print("vm-service: No isolate message handler for <%s>.\n", command);
2906 } 2957 }
2907 return NULL; 2958 return NULL;
2908 } 2959 }
2909 2960
2910 2961
2911 static bool HandleIsolateGetObject(Isolate* isolate, JSONStream* js) { 2962 static bool HandleIsolateGetObject(Isolate* isolate, JSONStream* js) {
2912 const char* id = js->LookupOption("id"); 2963 const char* id = js->LookupOption("objectId");
2913 if (id == NULL) { 2964 if (id == NULL) {
2914 // TODO(turnidge): Print the isolate here instead. 2965 // TODO(turnidge): Print the isolate here instead.
2915 PrintError(js, "GetObject expects an 'id' parameter\n", 2966 PrintError(js, "GetObject expects an 'objectId' parameter\n",
2916 js->num_arguments()); 2967 js->num_arguments());
2917 return true; 2968 return true;
2918 } 2969 }
2919 2970
2920 // Handle heap objects. 2971 // Handle heap objects.
2921 ObjectIdRing::LookupResult lookup_result; 2972 ObjectIdRing::LookupResult lookup_result;
2922 const Object& obj = 2973 const Object& obj =
2923 Object::Handle(LookupHeapObject(isolate, id, &lookup_result)); 2974 Object::Handle(LookupHeapObject(isolate, id, &lookup_result));
2924 if (obj.raw() != Object::sentinel().raw()) { 2975 if (obj.raw() != Object::sentinel().raw()) {
2925 // We found a heap object for this id. Return it. 2976 // We found a heap object for this id. Return it.
(...skipping 19 matching lines...) Expand all
2945 2996
2946 static bool HandleIsolateGetClassList(Isolate* isolate, JSONStream* js) { 2997 static bool HandleIsolateGetClassList(Isolate* isolate, JSONStream* js) {
2947 ClassTable* table = isolate->class_table(); 2998 ClassTable* table = isolate->class_table();
2948 JSONObject jsobj(js); 2999 JSONObject jsobj(js);
2949 table->PrintToJSONObject(&jsobj); 3000 table->PrintToJSONObject(&jsobj);
2950 return true; 3001 return true;
2951 } 3002 }
2952 3003
2953 3004
2954 static IsolateMessageHandlerEntry isolate_handlers_new[] = { 3005 static IsolateMessageHandlerEntry isolate_handlers_new[] = {
3006 { "getIsolate", HandleIsolate },
2955 { "getObject", HandleIsolateGetObject }, 3007 { "getObject", HandleIsolateGetObject },
2956 { "getBreakpoints", HandleIsolateGetBreakpoints }, 3008 { "getBreakpoints", HandleIsolateGetBreakpoints },
2957 { "pause", HandleIsolatePause }, 3009 { "pause", HandleIsolatePause },
2958 { "resume", HandleIsolateResume }, 3010 { "resume", HandleIsolateResume },
2959 { "getStack", HandleIsolateGetStack }, 3011 { "getStack", HandleIsolateGetStack },
2960 { "getCpuProfile", HandleIsolateGetCpuProfile }, 3012 { "getCpuProfile", HandleIsolateGetCpuProfile },
2961 { "getTagProfile", HandleIsolateGetTagProfile }, 3013 { "getTagProfile", HandleIsolateGetTagProfile },
2962 { "getAllocationProfile", HandleIsolateGetAllocationProfile }, 3014 { "getAllocationProfile", HandleIsolateGetAllocationProfile },
2963 { "getHeapMap", HandleIsolateGetHeapMap }, 3015 { "getHeapMap", HandleIsolateGetHeapMap },
2964 { "addBreakpoint", HandleIsolateAddBreakpoint }, 3016 { "addBreakpoint", HandleIsolateAddBreakpoint },
(...skipping 18 matching lines...) Expand all
2983 return entry.handler; 3035 return entry.handler;
2984 } 3036 }
2985 } 3037 }
2986 if (FLAG_trace_service) { 3038 if (FLAG_trace_service) {
2987 OS::Print("Service has no isolate message handler for <%s>\n", command); 3039 OS::Print("Service has no isolate message handler for <%s>\n", command);
2988 } 3040 }
2989 return NULL; 3041 return NULL;
2990 } 3042 }
2991 3043
2992 3044
3045 void Service::HandleRootMessageNew(const Array& msg) {
3046 Isolate* isolate = Isolate::Current();
3047 ASSERT(!msg.IsNull());
3048
3049 {
3050 StackZone zone(isolate);
3051 HANDLESCOPE(isolate);
3052
3053 const Array& message = Array::Cast(msg);
3054 // Message is a list with five entries.
3055 ASSERT(message.Length() == 5);
3056
3057 Instance& reply_port = Instance::Handle(isolate);
3058 String& method = String::Handle(isolate);
3059 Array& param_keys = Array::Handle(isolate);
3060 Array& param_values = Array::Handle(isolate);
3061 reply_port ^= msg.At(1);
3062 method ^= msg.At(2);
3063 param_keys ^= msg.At(3);
3064 param_values ^= msg.At(4);
3065
3066 ASSERT(!method.IsNull());
3067 ASSERT(!param_keys.IsNull());
3068 ASSERT(!param_values.IsNull());
3069 ASSERT(param_keys.Length() == param_values.Length());
3070
3071 if (!reply_port.IsSendPort()) {
3072 FATAL("SendPort expected.");
3073 }
3074
3075 RootMessageHandler handler =
3076 FindRootMessageHandlerNew(method.ToCString());
3077 {
3078 JSONStream js;
3079 js.SetupNew(zone.GetZone(), SendPort::Cast(reply_port).Id(),
3080 method, param_keys, param_values);
3081 if (handler == NULL) {
3082 // Check for an embedder handler.
3083 EmbedderServiceHandler* e_handler =
3084 FindRootEmbedderHandler(method.ToCString());
3085 if (e_handler != NULL) {
3086 EmbedderHandleMessage(e_handler, &js);
3087 } else {
3088 PrintError(&js, "Unrecognized path");
3089 }
3090 js.PostReply();
3091 } else {
3092 if (handler(&js)) {
3093 // Handler returns true if the reply is ready to be posted.
3094 // TODO(johnmccutchan): Support asynchronous replies.
3095 js.PostReply();
3096 }
3097 }
3098 }
3099 }
3100 }
3101
3102
2993 void Service::HandleRootMessage(const Instance& msg) { 3103 void Service::HandleRootMessage(const Instance& msg) {
2994 Isolate* isolate = Isolate::Current(); 3104 Isolate* isolate = Isolate::Current();
2995 ASSERT(!msg.IsNull()); 3105 ASSERT(!msg.IsNull());
2996 ASSERT(msg.IsArray()); 3106 ASSERT(msg.IsArray());
2997 3107
2998 { 3108 {
2999 StackZone zone(isolate); 3109 StackZone zone(isolate);
3000 HANDLESCOPE(isolate); 3110 HANDLESCOPE(isolate);
3001 3111
3002 const Array& message = Array::Cast(msg); 3112 const Array& message = Array::Cast(msg);
3003 // Message is a list with five entries. 3113 // Message is a list with five entries.
3004 ASSERT(message.Length() == 5); 3114 ASSERT(message.Length() == 5);
3005 3115
3116 Object& tmp = Object::Handle(isolate);
3117 tmp = message.At(2);
3118 if (tmp.IsString()) {
3119 return Service::HandleRootMessageNew(message);
3120 }
3121
3006 Instance& reply_port = Instance::Handle(isolate); 3122 Instance& reply_port = Instance::Handle(isolate);
3007 GrowableObjectArray& path = GrowableObjectArray::Handle(isolate); 3123 GrowableObjectArray& path = GrowableObjectArray::Handle(isolate);
3008 Array& option_keys = Array::Handle(isolate); 3124 Array& option_keys = Array::Handle(isolate);
3009 Array& option_values = Array::Handle(isolate); 3125 Array& option_values = Array::Handle(isolate);
3010 3126
3011 reply_port ^= message.At(1); 3127 reply_port ^= message.At(1);
3012 path ^= message.At(2); 3128 path ^= message.At(2);
3013 option_keys ^= message.At(3); 3129 option_keys ^= message.At(3);
3014 option_values ^= message.At(4); 3130 option_values ^= message.At(4);
3015 3131
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
3172 return entry.handler; 3288 return entry.handler;
3173 } 3289 }
3174 } 3290 }
3175 if (FLAG_trace_service) { 3291 if (FLAG_trace_service) {
3176 OS::Print("vm-service: No root message handler for <%s>.\n", command); 3292 OS::Print("vm-service: No root message handler for <%s>.\n", command);
3177 } 3293 }
3178 return NULL; 3294 return NULL;
3179 } 3295 }
3180 3296
3181 3297
3298 static RootMessageHandlerEntry root_handlers_new[] = {
3299 { "getVM", HandleVM },
3300 };
3301
3302
3303 static RootMessageHandler FindRootMessageHandlerNew(const char* command) {
3304 intptr_t num_message_handlers = sizeof(root_handlers_new) /
3305 sizeof(root_handlers_new[0]);
3306 for (intptr_t i = 0; i < num_message_handlers; i++) {
3307 const RootMessageHandlerEntry& entry = root_handlers_new[i];
3308 if (strcmp(command, entry.command) == 0) {
3309 return entry.handler;
3310 }
3311 }
3312 if (FLAG_trace_service) {
3313 OS::Print("vm-service: No root message handler for <%s>.\n", command);
3314 }
3315 return NULL;
3316 }
3317
3318
3182 void Service::SendEvent(intptr_t eventId, const Object& eventMessage) { 3319 void Service::SendEvent(intptr_t eventId, const Object& eventMessage) {
3183 if (!IsRunning()) { 3320 if (!IsRunning()) {
3184 return; 3321 return;
3185 } 3322 }
3186 Isolate* isolate = Isolate::Current(); 3323 Isolate* isolate = Isolate::Current();
3187 ASSERT(isolate != NULL); 3324 ASSERT(isolate != NULL);
3188 HANDLESCOPE(isolate); 3325 HANDLESCOPE(isolate);
3189 3326
3190 // Construct a list of the form [eventId, eventMessage]. 3327 // Construct a list of the form [eventId, eventMessage].
3191 const Array& list = Array::Handle(Array::New(2)); 3328 const Array& list = Array::Handle(Array::New(2));
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
3343 while (current != NULL) { 3480 while (current != NULL) {
3344 if (strcmp(name, current->name()) == 0) { 3481 if (strcmp(name, current->name()) == 0) {
3345 return current; 3482 return current;
3346 } 3483 }
3347 current = current->next(); 3484 current = current->next();
3348 } 3485 }
3349 return NULL; 3486 return NULL;
3350 } 3487 }
3351 3488
3352 } // namespace dart 3489 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/service.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698