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

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

Issue 1231603008: Expose allocation tracing over service protocol (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 5 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
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 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 // Skip the dash. 252 // Skip the dash.
253 s++; 253 s++;
254 // Extract the PC. 254 // Extract the PC.
255 if (!GetUnsignedIntegerId(s, address, 16)) { 255 if (!GetUnsignedIntegerId(s, address, 16)) {
256 return false; 256 return false;
257 } 257 }
258 return true; 258 return true;
259 } 259 }
260 260
261 261
262 // Verifies that |s| begins with |directory| and then calls |GetIntegerId| on
263 // the remainder of |s|.
264 // NOTE: Callers are required to include a trailing / in |directory|.
265 static bool GetIntegerIdFromDirectory(const char* s,
266 const char* directory,
267 intptr_t* service_id) {
turnidge 2015/07/13 23:37:49 The word Directory here bothers me some. How abou
Cutch 2015/07/14 15:53:47 Done.
268 ASSERT(s != NULL);
269 ASSERT(directory != NULL);
270 const intptr_t kInputLen = strlen(s);
271 const intptr_t kDirectoryLen = strlen(directory);
272 ASSERT(kDirectoryLen > 0);
273 ASSERT(directory[kDirectoryLen - 1] == '/');
274 if (kInputLen <= kDirectoryLen) {
275 return false;
276 }
277 if (strncmp(s, directory, kDirectoryLen) != 0) {
278 return false;
279 }
280 // Directory prefix satisfied. Move forward.
281 s += kDirectoryLen;
282 // Attempt to read integer id.
283 return GetIntegerId(s, service_id);
284 }
285
286
287 static bool ValidateClassId(Isolate* isolate, intptr_t cid) {
turnidge 2015/07/13 23:37:49 Change name to IsValidClassId?
Cutch 2015/07/14 15:53:47 Done.
288 ASSERT(isolate != NULL);
289 ClassTable* class_table = isolate->class_table();
290 ASSERT(class_table != NULL);
291 return class_table->IsValidIndex(cid) && class_table->HasValidClassAt(cid);
292 }
293
294
295 static bool ValidateClassId(Isolate* isolate, const char* class_id) {
296 intptr_t cid;
297 if (!GetIntegerIdFromDirectory(class_id, "classes/", &cid)) {
298 return false;
299 }
300 return ValidateClassId(isolate, cid);
301 }
turnidge 2015/07/13 23:37:49 I would like you to get rid of the overloaded vers
Cutch 2015/07/14 15:53:47 Done.
302
303
304 static RawClass* GetClassForId(Isolate* isolate, intptr_t cid) {
305 ASSERT(isolate == Isolate::Current());
306 ASSERT(isolate != NULL);
307 ClassTable* class_table = isolate->class_table();
308 ASSERT(class_table != NULL);
309 return class_table->At(cid);
310 }
311
312
313 static RawClass* GetClassForId(Isolate* isolate, const char* class_id) {
314 intptr_t cid;
315 ASSERT(GetIntegerIdFromDirectory(class_id, "classes/", &cid));
turnidge 2015/07/13 23:37:49 Do ASSERTs get removed in release builds? I don't
Cutch 2015/07/14 15:53:47 Good catch.
316 return GetClassForId(isolate, cid);
317 }
318
319
262 // TODO(johnmccutchan): Split into separate file and write unit tests. 320 // TODO(johnmccutchan): Split into separate file and write unit tests.
263 class MethodParameter { 321 class MethodParameter {
264 public: 322 public:
265 MethodParameter(const char* name, bool required) 323 MethodParameter(const char* name, bool required)
266 : name_(name), required_(required) { 324 : name_(name), required_(required) {
267 } 325 }
268 326
269 virtual ~MethodParameter() { } 327 virtual ~MethodParameter() { }
270 328
271 virtual bool Validate(const char* value) const { 329 virtual bool Validate(const char* value) const {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 } 393 }
336 for (const char* cp = value; *cp != '\0'; cp++) { 394 for (const char* cp = value; *cp != '\0'; cp++) {
337 if (*cp < '0' || *cp > '9') { 395 if (*cp < '0' || *cp > '9') {
338 return false; 396 return false;
339 } 397 }
340 } 398 }
341 return true; 399 return true;
342 } 400 }
343 401
344 static intptr_t Parse(const char* value) { 402 static intptr_t Parse(const char* value) {
403 if (value == NULL) {
404 return -1;
405 }
345 char* end_ptr = NULL; 406 char* end_ptr = NULL;
346 uintptr_t result = strtoul(value, &end_ptr, 10); 407 uintptr_t result = strtoul(value, &end_ptr, 10);
347 ASSERT(*end_ptr == '\0'); // Parsed full string 408 ASSERT(*end_ptr == '\0'); // Parsed full string
348 return result; 409 return result;
349 } 410 }
350 }; 411 };
351 412
352 413
353 class IdParameter : public MethodParameter { 414 class IdParameter : public MethodParameter {
354 public: 415 public:
(...skipping 1870 matching lines...) Expand 10 before | Expand all | Expand 10 after
2225 Profile::kUser, 2286 Profile::kUser,
2226 Profile::kVMUser, 2287 Profile::kVMUser,
2227 Profile::kVM, 2288 Profile::kVM,
2228 Profile::kNoTags, // Default value. 2289 Profile::kNoTags, // Default value.
2229 }; 2290 };
2230 2291
2231 2292
2232 static const MethodParameter* get_cpu_profile_params[] = { 2293 static const MethodParameter* get_cpu_profile_params[] = {
2233 ISOLATE_PARAMETER, 2294 ISOLATE_PARAMETER,
2234 new EnumParameter("tags", true, tags_enum_names), 2295 new EnumParameter("tags", true, tags_enum_names),
2296 new IdParameter("classId", false),
2235 NULL, 2297 NULL,
2236 }; 2298 };
2237 2299
2238 2300
2239 static bool GetCpuProfile(Isolate* isolate, JSONStream* js) { 2301 static bool GetCpuProfile(Isolate* isolate, JSONStream* js) {
turnidge 2015/07/13 23:37:49 As mentioned elsewhere, consider separating cpu an
Cutch 2015/07/14 15:53:47 Done.
2240 Profile::TagOrder tag_order = 2302 Profile::TagOrder tag_order =
2241 EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values); 2303 EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values);
2242 ProfilerService::PrintJSON(js, tag_order); 2304 const char* class_id = js->LookupParam("classId");
2305 if (ValidateClassId(isolate, class_id)) {
2306 const Class& cls = Class::Handle(GetClassForId(isolate, class_id));
turnidge 2015/07/13 23:37:49 You are double-parsing the class id, once in Valid
Cutch 2015/07/14 15:53:47 Done.
2307 ProfilerService::PrintAllocationJSON(js, tag_order, cls);
2308 } else {
2309 ProfilerService::PrintJSON(js, tag_order);
2310 }
2243 return true; 2311 return true;
2244 } 2312 }
2245 2313
2246 2314
2247 static const MethodParameter* clear_cpu_profile_params[] = { 2315 static const MethodParameter* clear_cpu_profile_params[] = {
2248 ISOLATE_PARAMETER, 2316 ISOLATE_PARAMETER,
2249 NULL, 2317 NULL,
2250 }; 2318 };
2251 2319
2252 2320
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
2744 isolate->set_debugger_name(js->LookupParam("name")); 2812 isolate->set_debugger_name(js->LookupParam("name"));
2745 if (Service::NeedsIsolateEvents()) { 2813 if (Service::NeedsIsolateEvents()) {
2746 ServiceEvent event(isolate, ServiceEvent::kIsolateUpdate); 2814 ServiceEvent event(isolate, ServiceEvent::kIsolateUpdate);
2747 Service::HandleEvent(&event); 2815 Service::HandleEvent(&event);
2748 } 2816 }
2749 PrintSuccess(js); 2817 PrintSuccess(js);
2750 return true; 2818 return true;
2751 } 2819 }
2752 2820
2753 2821
2822 static const MethodParameter* trace_class_allocation_params[] = {
2823 ISOLATE_PARAMETER,
2824 new IdParameter("classId", true),
2825 new BoolParameter("enable", true),
2826 NULL,
2827 };
2828
2829
2830 static bool TraceClassAllocation(Isolate* isolate, JSONStream* js) {
2831 const char* class_id = js->LookupParam("classId");
2832 const bool enable = BoolParameter::Parse(js->LookupParam("enable"));
2833
2834 if (!ValidateClassId(isolate, class_id)) {
2835 PrintInvalidParamError(js, "cid");
2836 return true;
2837 }
2838
2839 const Class& cls = Class::Handle(GetClassForId(isolate, class_id));
2840 ASSERT(!cls.IsNull());
2841
2842 cls.SetTraceAllocation(enable);
2843 PrintSuccess(js);
2844 return true;
2845 }
2846
2847
2754 static ServiceMethodDescriptor service_methods_[] = { 2848 static ServiceMethodDescriptor service_methods_[] = {
2755 { "_dumpIdZone", DumpIdZone, NULL }, 2849 { "_dumpIdZone", DumpIdZone, NULL },
2756 { "_echo", Echo, 2850 { "_echo", Echo,
2757 NULL }, 2851 NULL },
2758 { "_respondWithMalformedJson", RespondWithMalformedJson, 2852 { "_respondWithMalformedJson", RespondWithMalformedJson,
2759 NULL }, 2853 NULL },
2760 { "_respondWithMalformedObject", RespondWithMalformedObject, 2854 { "_respondWithMalformedObject", RespondWithMalformedObject,
2761 NULL }, 2855 NULL },
2762 { "_triggerEchoEvent", TriggerEchoEvent, 2856 { "_triggerEchoEvent", TriggerEchoEvent,
2763 NULL }, 2857 NULL },
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
2830 { "_requestHeapSnapshot", RequestHeapSnapshot, 2924 { "_requestHeapSnapshot", RequestHeapSnapshot,
2831 request_heap_snapshot_params }, 2925 request_heap_snapshot_params },
2832 { "_setExceptionPauseInfo", SetExceptionPauseInfo, 2926 { "_setExceptionPauseInfo", SetExceptionPauseInfo,
2833 set_exception_pause_info_params }, 2927 set_exception_pause_info_params },
2834 { "_setFlag", SetFlag, 2928 { "_setFlag", SetFlag,
2835 set_flags_params }, 2929 set_flags_params },
2836 { "setLibraryDebuggable", SetLibraryDebuggable, 2930 { "setLibraryDebuggable", SetLibraryDebuggable,
2837 set_library_debuggable_params }, 2931 set_library_debuggable_params },
2838 { "setName", SetName, 2932 { "setName", SetName,
2839 set_name_params }, 2933 set_name_params },
2934 { "_traceClassAllocation", TraceClassAllocation,
turnidge 2015/07/13 23:37:49 Consider changing rpc name for consistency with se
Cutch 2015/07/14 15:53:48 Done.
2935 trace_class_allocation_params },
2840 }; 2936 };
2841 2937
2842 2938
2843 ServiceMethodDescriptor* FindMethod(const char* method_name) { 2939 ServiceMethodDescriptor* FindMethod(const char* method_name) {
2844 intptr_t num_methods = sizeof(service_methods_) / 2940 intptr_t num_methods = sizeof(service_methods_) /
2845 sizeof(service_methods_[0]); 2941 sizeof(service_methods_[0]);
2846 for (intptr_t i = 0; i < num_methods; i++) { 2942 for (intptr_t i = 0; i < num_methods; i++) {
2847 ServiceMethodDescriptor& method = service_methods_[i]; 2943 ServiceMethodDescriptor& method = service_methods_[i];
2848 if (strcmp(method_name, method.name) == 0) { 2944 if (strcmp(method_name, method.name) == 0) {
2849 return &method; 2945 return &method;
2850 } 2946 }
2851 } 2947 }
2852 return NULL; 2948 return NULL;
2853 } 2949 }
2854 2950
2855 2951
2856 } // namespace dart 2952 } // namespace dart
OLDNEW
« runtime/observatory/tests/service/test_helper.dart ('K') | « runtime/vm/profiler_service.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698