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

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
« no previous file with comments | « runtime/vm/profiler_service.cc ('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 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 |prefix| and then calls |GetIntegerId| on
263 // the remainder of |s|.
264 static bool GetPrefixedIntegerId(const char* s,
265 const char* prefix,
266 intptr_t* service_id) {
267 if (s == NULL) {
268 return false;
269 }
270 ASSERT(prefix != NULL);
271 const intptr_t kInputLen = strlen(s);
272 const intptr_t kPrefixLen = strlen(prefix);
273 ASSERT(kPrefixLen > 0);
274 if (kInputLen <= kPrefixLen) {
275 return false;
276 }
277 if (strncmp(s, prefix, kPrefixLen) != 0) {
278 return false;
279 }
280 // Prefix satisfied. Move forward.
281 s += kPrefixLen;
282 // Attempt to read integer id.
283 return GetIntegerId(s, service_id);
284 }
285
286
287 static bool IsValidClassId(Isolate* isolate, intptr_t cid) {
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 RawClass* GetClassForId(Isolate* isolate, intptr_t cid) {
296 ASSERT(isolate == Isolate::Current());
297 ASSERT(isolate != NULL);
298 ClassTable* class_table = isolate->class_table();
299 ASSERT(class_table != NULL);
300 return class_table->At(cid);
301 }
302
303
262 // TODO(johnmccutchan): Split into separate file and write unit tests. 304 // TODO(johnmccutchan): Split into separate file and write unit tests.
263 class MethodParameter { 305 class MethodParameter {
264 public: 306 public:
265 MethodParameter(const char* name, bool required) 307 MethodParameter(const char* name, bool required)
266 : name_(name), required_(required) { 308 : name_(name), required_(required) {
267 } 309 }
268 310
269 virtual ~MethodParameter() { } 311 virtual ~MethodParameter() { }
270 312
271 virtual bool Validate(const char* value) const { 313 virtual bool Validate(const char* value) const {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 } 377 }
336 for (const char* cp = value; *cp != '\0'; cp++) { 378 for (const char* cp = value; *cp != '\0'; cp++) {
337 if (*cp < '0' || *cp > '9') { 379 if (*cp < '0' || *cp > '9') {
338 return false; 380 return false;
339 } 381 }
340 } 382 }
341 return true; 383 return true;
342 } 384 }
343 385
344 static intptr_t Parse(const char* value) { 386 static intptr_t Parse(const char* value) {
387 if (value == NULL) {
388 return -1;
389 }
345 char* end_ptr = NULL; 390 char* end_ptr = NULL;
346 uintptr_t result = strtoul(value, &end_ptr, 10); 391 uintptr_t result = strtoul(value, &end_ptr, 10);
347 ASSERT(*end_ptr == '\0'); // Parsed full string 392 ASSERT(*end_ptr == '\0'); // Parsed full string
348 return result; 393 return result;
349 } 394 }
350 }; 395 };
351 396
352 397
353 class IdParameter : public MethodParameter { 398 class IdParameter : public MethodParameter {
354 public: 399 public:
(...skipping 1874 matching lines...) Expand 10 before | Expand all | Expand 10 after
2229 }; 2274 };
2230 2275
2231 2276
2232 static const MethodParameter* get_cpu_profile_params[] = { 2277 static const MethodParameter* get_cpu_profile_params[] = {
2233 ISOLATE_PARAMETER, 2278 ISOLATE_PARAMETER,
2234 new EnumParameter("tags", true, tags_enum_names), 2279 new EnumParameter("tags", true, tags_enum_names),
2235 NULL, 2280 NULL,
2236 }; 2281 };
2237 2282
2238 2283
2284 // TODO(johnmccutchan): Rename this to GetCpuSamples.
2239 static bool GetCpuProfile(Isolate* isolate, JSONStream* js) { 2285 static bool GetCpuProfile(Isolate* isolate, JSONStream* js) {
2240 Profile::TagOrder tag_order = 2286 Profile::TagOrder tag_order =
2241 EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values); 2287 EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values);
2242 ProfilerService::PrintJSON(js, tag_order); 2288 ProfilerService::PrintJSON(js, tag_order);
2243 return true; 2289 return true;
2244 } 2290 }
2245 2291
2246 2292
2293 static const MethodParameter* get_allocation_samples_params[] = {
2294 ISOLATE_PARAMETER,
2295 new EnumParameter("tags", true, tags_enum_names),
2296 new IdParameter("classId", false),
2297 NULL,
2298 };
2299
2300
2301 static bool GetAllocationSamples(Isolate* isolate, JSONStream* js) {
2302 Profile::TagOrder tag_order =
2303 EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values);
2304 const char* class_id = js->LookupParam("classId");
2305 intptr_t cid = -1;
2306 GetPrefixedIntegerId(class_id, "classes/", &cid);
2307 if (IsValidClassId(isolate, cid)) {
2308 const Class& cls = Class::Handle(GetClassForId(isolate, cid));
2309 ProfilerService::PrintAllocationJSON(js, tag_order, cls);
2310 } else {
2311 PrintInvalidParamError(js, "classId");
2312 }
2313 return true;
2314 }
2315
2316
2247 static const MethodParameter* clear_cpu_profile_params[] = { 2317 static const MethodParameter* clear_cpu_profile_params[] = {
2248 ISOLATE_PARAMETER, 2318 ISOLATE_PARAMETER,
2249 NULL, 2319 NULL,
2250 }; 2320 };
2251 2321
2252 2322
2253 static bool ClearCpuProfile(Isolate* isolate, JSONStream* js) { 2323 static bool ClearCpuProfile(Isolate* isolate, JSONStream* js) {
2254 ProfilerService::ClearSamples(); 2324 ProfilerService::ClearSamples();
2255 PrintSuccess(js); 2325 PrintSuccess(js);
2256 return true; 2326 return true;
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
2744 isolate->set_debugger_name(js->LookupParam("name")); 2814 isolate->set_debugger_name(js->LookupParam("name"));
2745 if (Service::NeedsIsolateEvents()) { 2815 if (Service::NeedsIsolateEvents()) {
2746 ServiceEvent event(isolate, ServiceEvent::kIsolateUpdate); 2816 ServiceEvent event(isolate, ServiceEvent::kIsolateUpdate);
2747 Service::HandleEvent(&event); 2817 Service::HandleEvent(&event);
2748 } 2818 }
2749 PrintSuccess(js); 2819 PrintSuccess(js);
2750 return true; 2820 return true;
2751 } 2821 }
2752 2822
2753 2823
2824 static const MethodParameter* set_trace_class_allocation_params[] = {
2825 ISOLATE_PARAMETER,
2826 new IdParameter("classId", true),
2827 new BoolParameter("enable", true),
2828 NULL,
2829 };
2830
2831
2832 static bool SetTraceClassAllocation(Isolate* isolate, JSONStream* js) {
2833 const char* class_id = js->LookupParam("classId");
2834 const bool enable = BoolParameter::Parse(js->LookupParam("enable"));
2835 intptr_t cid = -1;
2836 GetPrefixedIntegerId(class_id, "classes/", &cid);
2837 if (!IsValidClassId(isolate, cid)) {
2838 PrintInvalidParamError(js, "classId");
2839 return true;
2840 }
2841 const Class& cls = Class::Handle(GetClassForId(isolate, cid));
2842 ASSERT(!cls.IsNull());
2843 cls.SetTraceAllocation(enable);
2844 PrintSuccess(js);
2845 return true;
2846 }
2847
2848
2754 static ServiceMethodDescriptor service_methods_[] = { 2849 static ServiceMethodDescriptor service_methods_[] = {
2755 { "_dumpIdZone", DumpIdZone, NULL }, 2850 { "_dumpIdZone", DumpIdZone, NULL },
2756 { "_echo", Echo, 2851 { "_echo", Echo,
2757 NULL }, 2852 NULL },
2758 { "_respondWithMalformedJson", RespondWithMalformedJson, 2853 { "_respondWithMalformedJson", RespondWithMalformedJson,
2759 NULL }, 2854 NULL },
2760 { "_respondWithMalformedObject", RespondWithMalformedObject, 2855 { "_respondWithMalformedObject", RespondWithMalformedObject,
2761 NULL }, 2856 NULL },
2762 { "_triggerEchoEvent", TriggerEchoEvent, 2857 { "_triggerEchoEvent", TriggerEchoEvent,
2763 NULL }, 2858 NULL },
2764 { "addBreakpoint", AddBreakpoint, 2859 { "addBreakpoint", AddBreakpoint,
2765 add_breakpoint_params }, 2860 add_breakpoint_params },
2766 { "addBreakpointAtEntry", AddBreakpointAtEntry, 2861 { "addBreakpointAtEntry", AddBreakpointAtEntry,
2767 add_breakpoint_at_entry_params }, 2862 add_breakpoint_at_entry_params },
2768 { "_addBreakpointAtActivation", AddBreakpointAtActivation, 2863 { "_addBreakpointAtActivation", AddBreakpointAtActivation,
2769 add_breakpoint_at_activation_params }, 2864 add_breakpoint_at_activation_params },
2770 { "_clearCpuProfile", ClearCpuProfile, 2865 { "_clearCpuProfile", ClearCpuProfile,
2771 clear_cpu_profile_params }, 2866 clear_cpu_profile_params },
2772 { "evaluate", Evaluate, 2867 { "evaluate", Evaluate,
2773 evaluate_params }, 2868 evaluate_params },
2774 { "evaluateInFrame", EvaluateInFrame, 2869 { "evaluateInFrame", EvaluateInFrame,
2775 evaluate_in_frame_params }, 2870 evaluate_in_frame_params },
2776 { "_getAllocationProfile", GetAllocationProfile, 2871 { "_getAllocationProfile", GetAllocationProfile,
2777 get_allocation_profile_params }, 2872 get_allocation_profile_params },
2873 { "_getAllocationSamples", GetAllocationSamples,
2874 get_allocation_samples_params },
2778 { "_getCallSiteData", GetCallSiteData, 2875 { "_getCallSiteData", GetCallSiteData,
2779 get_call_site_data_params }, 2876 get_call_site_data_params },
2780 { "getClassList", GetClassList, 2877 { "getClassList", GetClassList,
2781 get_class_list_params }, 2878 get_class_list_params },
2782 { "_getCoverage", GetCoverage, 2879 { "_getCoverage", GetCoverage,
2783 get_coverage_params }, 2880 get_coverage_params },
2784 { "_getCpuProfile", GetCpuProfile, 2881 { "_getCpuProfile", GetCpuProfile,
2785 get_cpu_profile_params }, 2882 get_cpu_profile_params },
2786 { "getFlagList", GetFlagList, 2883 { "getFlagList", GetFlagList,
2787 get_flag_list_params }, 2884 get_flag_list_params },
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2830 { "_requestHeapSnapshot", RequestHeapSnapshot, 2927 { "_requestHeapSnapshot", RequestHeapSnapshot,
2831 request_heap_snapshot_params }, 2928 request_heap_snapshot_params },
2832 { "_setExceptionPauseInfo", SetExceptionPauseInfo, 2929 { "_setExceptionPauseInfo", SetExceptionPauseInfo,
2833 set_exception_pause_info_params }, 2930 set_exception_pause_info_params },
2834 { "_setFlag", SetFlag, 2931 { "_setFlag", SetFlag,
2835 set_flags_params }, 2932 set_flags_params },
2836 { "setLibraryDebuggable", SetLibraryDebuggable, 2933 { "setLibraryDebuggable", SetLibraryDebuggable,
2837 set_library_debuggable_params }, 2934 set_library_debuggable_params },
2838 { "setName", SetName, 2935 { "setName", SetName,
2839 set_name_params }, 2936 set_name_params },
2937 { "_setTraceClassAllocation", SetTraceClassAllocation,
2938 set_trace_class_allocation_params },
2840 }; 2939 };
2841 2940
2842 2941
2843 ServiceMethodDescriptor* FindMethod(const char* method_name) { 2942 ServiceMethodDescriptor* FindMethod(const char* method_name) {
2844 intptr_t num_methods = sizeof(service_methods_) / 2943 intptr_t num_methods = sizeof(service_methods_) /
2845 sizeof(service_methods_[0]); 2944 sizeof(service_methods_[0]);
2846 for (intptr_t i = 0; i < num_methods; i++) { 2945 for (intptr_t i = 0; i < num_methods; i++) {
2847 ServiceMethodDescriptor& method = service_methods_[i]; 2946 ServiceMethodDescriptor& method = service_methods_[i];
2848 if (strcmp(method_name, method.name) == 0) { 2947 if (strcmp(method_name, method.name) == 0) {
2849 return &method; 2948 return &method;
2850 } 2949 }
2851 } 2950 }
2852 return NULL; 2951 return NULL;
2853 } 2952 }
2854 2953
2855 2954
2856 } // namespace dart 2955 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/profiler_service.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698