OLD | NEW |
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 "include/dart_native_api.h" | 8 #include "include/dart_native_api.h" |
9 #include "platform/globals.h" | 9 #include "platform/globals.h" |
10 | 10 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 ASSERT(zone != NULL); | 90 ASSERT(zone != NULL); |
91 const intptr_t id = ring_->GetIdForObject(obj.raw(), policy_); | 91 const intptr_t id = ring_->GetIdForObject(obj.raw(), policy_); |
92 return zone->PrintToString("objects/%" Pd "", id); | 92 return zone->PrintToString("objects/%" Pd "", id); |
93 } | 93 } |
94 | 94 |
95 | 95 |
96 // TODO(johnmccutchan): Unify embedder service handler lists and their APIs. | 96 // TODO(johnmccutchan): Unify embedder service handler lists and their APIs. |
97 EmbedderServiceHandler* Service::isolate_service_handler_head_ = NULL; | 97 EmbedderServiceHandler* Service::isolate_service_handler_head_ = NULL; |
98 EmbedderServiceHandler* Service::root_service_handler_head_ = NULL; | 98 EmbedderServiceHandler* Service::root_service_handler_head_ = NULL; |
99 struct ServiceMethodDescriptor; | 99 struct ServiceMethodDescriptor; |
100 ServiceMethodDescriptor* FindMethod(const char* method_name); | 100 const ServiceMethodDescriptor* FindMethod(const char* method_name); |
101 | 101 |
102 | 102 |
103 // Support for streams defined in embedders. | 103 // Support for streams defined in embedders. |
104 Dart_ServiceStreamListenCallback Service::stream_listen_callback_ = NULL; | 104 Dart_ServiceStreamListenCallback Service::stream_listen_callback_ = NULL; |
105 Dart_ServiceStreamCancelCallback Service::stream_cancel_callback_ = NULL; | 105 Dart_ServiceStreamCancelCallback Service::stream_cancel_callback_ = NULL; |
106 Dart_GetVMServiceAssetsArchive Service::get_service_assets_callback_ = NULL; | 106 Dart_GetVMServiceAssetsArchive Service::get_service_assets_callback_ = NULL; |
107 | 107 |
108 // These are the set of streams known to the core VM. | 108 // These are the set of streams known to the core VM. |
109 StreamInfo Service::vm_stream("VM"); | 109 StreamInfo Service::vm_stream("VM"); |
110 StreamInfo Service::isolate_stream("Isolate"); | 110 StreamInfo Service::isolate_stream("Isolate"); |
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 return (value != NULL); | 484 return (value != NULL); |
485 } | 485 } |
486 }; | 486 }; |
487 | 487 |
488 | 488 |
489 #define ISOLATE_PARAMETER new IdParameter("isolateId", true) | 489 #define ISOLATE_PARAMETER new IdParameter("isolateId", true) |
490 | 490 |
491 | 491 |
492 class EnumParameter : public MethodParameter { | 492 class EnumParameter : public MethodParameter { |
493 public: | 493 public: |
494 EnumParameter(const char* name, bool required, const char** enums) | 494 EnumParameter(const char* name, bool required, const char* const* enums) |
495 : MethodParameter(name, required), | 495 : MethodParameter(name, required), |
496 enums_(enums) { | 496 enums_(enums) { |
497 } | 497 } |
498 | 498 |
499 virtual bool Validate(const char* value) const { | 499 virtual bool Validate(const char* value) const { |
500 if (value == NULL) { | 500 if (value == NULL) { |
501 return true; | 501 return true; |
502 } | 502 } |
503 for (intptr_t i = 0; enums_[i] != NULL; i++) { | 503 for (intptr_t i = 0; enums_[i] != NULL; i++) { |
504 if (strcmp(value, enums_[i]) == 0) { | 504 if (strcmp(value, enums_[i]) == 0) { |
505 return true; | 505 return true; |
506 } | 506 } |
507 } | 507 } |
508 return false; | 508 return false; |
509 } | 509 } |
510 | 510 |
511 private: | 511 private: |
512 const char** enums_; | 512 const char* const* enums_; |
513 }; | 513 }; |
514 | 514 |
515 | 515 |
516 // If the key is not found, this function returns the last element in the | 516 // If the key is not found, this function returns the last element in the |
517 // values array. This can be used to encode the default value. | 517 // values array. This can be used to encode the default value. |
518 template<typename T> | 518 template<typename T> |
519 T EnumMapper(const char* value, const char** enums, T* values) { | 519 T EnumMapper(const char* value, const char* const* enums, T* values) { |
520 ASSERT(value != NULL); | 520 ASSERT(value != NULL); |
521 intptr_t i = 0; | 521 intptr_t i = 0; |
522 for (i = 0; enums[i] != NULL; i++) { | 522 for (i = 0; enums[i] != NULL; i++) { |
523 if (strcmp(value, enums[i]) == 0) { | 523 if (strcmp(value, enums[i]) == 0) { |
524 return values[i]; | 524 return values[i]; |
525 } | 525 } |
526 } | 526 } |
527 // Default value. | 527 // Default value. |
528 return values[i]; | 528 return values[i]; |
529 } | 529 } |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
637 // TODO(johnmccutchan): Support creating, deleting, and selecting | 637 // TODO(johnmccutchan): Support creating, deleting, and selecting |
638 // custom service id zones. | 638 // custom service id zones. |
639 // For now, always return an error. | 639 // For now, always return an error. |
640 PrintInvalidParamError(&js, "_idZone"); | 640 PrintInvalidParamError(&js, "_idZone"); |
641 js.PostReply(); | 641 js.PostReply(); |
642 return; | 642 return; |
643 } | 643 } |
644 } | 644 } |
645 const char* c_method_name = method_name.ToCString(); | 645 const char* c_method_name = method_name.ToCString(); |
646 | 646 |
647 ServiceMethodDescriptor* method = FindMethod(c_method_name); | 647 const ServiceMethodDescriptor* method = FindMethod(c_method_name); |
648 if (method != NULL) { | 648 if (method != NULL) { |
649 if (!ValidateParameters(method->parameters, &js)) { | 649 if (!ValidateParameters(method->parameters, &js)) { |
650 js.PostReply(); | 650 js.PostReply(); |
651 return; | 651 return; |
652 } | 652 } |
653 if (method->entry(T, &js)) { | 653 if (method->entry(T, &js)) { |
654 js.PostReply(); | 654 js.PostReply(); |
655 } else { | 655 } else { |
656 // NOTE(turnidge): All message handlers currently return true, | 656 // NOTE(turnidge): All message handlers currently return true, |
657 // so this case shouldn't be reached, at present. | 657 // so this case shouldn't be reached, at present. |
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1378 return table.At(id); | 1378 return table.At(id); |
1379 } | 1379 } |
1380 | 1380 |
1381 | 1381 |
1382 static RawObject* LookupHeapObjectCode(Isolate* isolate, | 1382 static RawObject* LookupHeapObjectCode(Isolate* isolate, |
1383 char** parts, int num_parts) { | 1383 char** parts, int num_parts) { |
1384 if (num_parts != 2) { | 1384 if (num_parts != 2) { |
1385 return Object::sentinel().raw(); | 1385 return Object::sentinel().raw(); |
1386 } | 1386 } |
1387 uword pc; | 1387 uword pc; |
1388 static const char* kCollectedPrefix = "collected-"; | 1388 static const char* const kCollectedPrefix = "collected-"; |
1389 static intptr_t kCollectedPrefixLen = strlen(kCollectedPrefix); | 1389 static intptr_t kCollectedPrefixLen = strlen(kCollectedPrefix); |
1390 static const char* kNativePrefix = "native-"; | 1390 static const char* const kNativePrefix = "native-"; |
1391 static intptr_t kNativePrefixLen = strlen(kNativePrefix); | 1391 static const intptr_t kNativePrefixLen = strlen(kNativePrefix); |
1392 static const char* kReusedPrefix = "reused-"; | 1392 static const char* const kReusedPrefix = "reused-"; |
1393 static intptr_t kReusedPrefixLen = strlen(kReusedPrefix); | 1393 static const intptr_t kReusedPrefixLen = strlen(kReusedPrefix); |
1394 const char* id = parts[1]; | 1394 const char* id = parts[1]; |
1395 if (strncmp(kCollectedPrefix, id, kCollectedPrefixLen) == 0) { | 1395 if (strncmp(kCollectedPrefix, id, kCollectedPrefixLen) == 0) { |
1396 if (!GetUnsignedIntegerId(&id[kCollectedPrefixLen], &pc, 16)) { | 1396 if (!GetUnsignedIntegerId(&id[kCollectedPrefixLen], &pc, 16)) { |
1397 return Object::sentinel().raw(); | 1397 return Object::sentinel().raw(); |
1398 } | 1398 } |
1399 // TODO(turnidge): Return "collected" instead. | 1399 // TODO(turnidge): Return "collected" instead. |
1400 return Object::null(); | 1400 return Object::null(); |
1401 } | 1401 } |
1402 if (strncmp(kNativePrefix, id, kNativePrefixLen) == 0) { | 1402 if (strncmp(kNativePrefix, id, kNativePrefixLen) == 0) { |
1403 if (!GetUnsignedIntegerId(&id[kNativePrefixLen], &pc, 16)) { | 1403 if (!GetUnsignedIntegerId(&id[kNativePrefixLen], &pc, 16)) { |
(...skipping 1035 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2439 }; | 2439 }; |
2440 | 2440 |
2441 | 2441 |
2442 static bool GetIsolateMetric(Thread* thread, JSONStream* js) { | 2442 static bool GetIsolateMetric(Thread* thread, JSONStream* js) { |
2443 const char* metric_id = js->LookupParam("metricId"); | 2443 const char* metric_id = js->LookupParam("metricId"); |
2444 if (metric_id == NULL) { | 2444 if (metric_id == NULL) { |
2445 PrintMissingParamError(js, "metricId"); | 2445 PrintMissingParamError(js, "metricId"); |
2446 return true; | 2446 return true; |
2447 } | 2447 } |
2448 // Verify id begins with "metrics/". | 2448 // Verify id begins with "metrics/". |
2449 static const char* kMetricIdPrefix = "metrics/"; | 2449 static const char* const kMetricIdPrefix = "metrics/"; |
2450 static intptr_t kMetricIdPrefixLen = strlen(kMetricIdPrefix); | 2450 static intptr_t kMetricIdPrefixLen = strlen(kMetricIdPrefix); |
2451 if (strncmp(metric_id, kMetricIdPrefix, kMetricIdPrefixLen) != 0) { | 2451 if (strncmp(metric_id, kMetricIdPrefix, kMetricIdPrefixLen) != 0) { |
2452 PrintInvalidParamError(js, "metricId"); | 2452 PrintInvalidParamError(js, "metricId"); |
2453 return true; | 2453 return true; |
2454 } | 2454 } |
2455 // Check if id begins with "metrics/native/". | 2455 // Check if id begins with "metrics/native/". |
2456 static const char* kNativeMetricIdPrefix = "metrics/native/"; | 2456 static const char* const kNativeMetricIdPrefix = "metrics/native/"; |
2457 static intptr_t kNativeMetricIdPrefixLen = strlen(kNativeMetricIdPrefix); | 2457 static intptr_t kNativeMetricIdPrefixLen = strlen(kNativeMetricIdPrefix); |
2458 const bool native_metric = | 2458 const bool native_metric = |
2459 strncmp(metric_id, kNativeMetricIdPrefix, kNativeMetricIdPrefixLen) == 0; | 2459 strncmp(metric_id, kNativeMetricIdPrefix, kNativeMetricIdPrefixLen) == 0; |
2460 if (native_metric) { | 2460 if (native_metric) { |
2461 const char* id = metric_id + kNativeMetricIdPrefixLen; | 2461 const char* id = metric_id + kNativeMetricIdPrefixLen; |
2462 return HandleNativeMetric(thread, js, id); | 2462 return HandleNativeMetric(thread, js, id); |
2463 } | 2463 } |
2464 const char* id = metric_id + kMetricIdPrefixLen; | 2464 const char* id = metric_id + kMetricIdPrefixLen; |
2465 return HandleDartMetric(thread, js, id); | 2465 return HandleDartMetric(thread, js, id); |
2466 } | 2466 } |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2655 | 2655 |
2656 | 2656 |
2657 static bool GetTagProfile(Thread* thread, JSONStream* js) { | 2657 static bool GetTagProfile(Thread* thread, JSONStream* js) { |
2658 JSONObject miniProfile(js); | 2658 JSONObject miniProfile(js); |
2659 miniProfile.AddProperty("type", "TagProfile"); | 2659 miniProfile.AddProperty("type", "TagProfile"); |
2660 thread->isolate()->vm_tag_counters()->PrintToJSONObject(&miniProfile); | 2660 thread->isolate()->vm_tag_counters()->PrintToJSONObject(&miniProfile); |
2661 return true; | 2661 return true; |
2662 } | 2662 } |
2663 | 2663 |
2664 | 2664 |
2665 static const char* tags_enum_names[] = { | 2665 static const char* const tags_enum_names[] = { |
2666 "None", | 2666 "None", |
2667 "UserVM", | 2667 "UserVM", |
2668 "UserOnly", | 2668 "UserOnly", |
2669 "VMUser", | 2669 "VMUser", |
2670 "VMOnly", | 2670 "VMOnly", |
2671 NULL, | 2671 NULL, |
2672 }; | 2672 }; |
2673 | 2673 |
2674 | 2674 |
2675 static Profile::TagOrder tags_enum_values[] = { | 2675 static const Profile::TagOrder tags_enum_values[] = { |
2676 Profile::kNoTags, | 2676 Profile::kNoTags, |
2677 Profile::kUserVM, | 2677 Profile::kUserVM, |
2678 Profile::kUser, | 2678 Profile::kUser, |
2679 Profile::kVMUser, | 2679 Profile::kVMUser, |
2680 Profile::kVM, | 2680 Profile::kVM, |
2681 Profile::kNoTags, // Default value. | 2681 Profile::kNoTags, // Default value. |
2682 }; | 2682 }; |
2683 | 2683 |
2684 | 2684 |
2685 static const MethodParameter* get_cpu_profile_params[] = { | 2685 static const MethodParameter* get_cpu_profile_params[] = { |
(...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3390 return true; | 3390 return true; |
3391 } | 3391 } |
3392 const Class& cls = Class::Handle(GetClassForId(isolate, cid)); | 3392 const Class& cls = Class::Handle(GetClassForId(isolate, cid)); |
3393 ASSERT(!cls.IsNull()); | 3393 ASSERT(!cls.IsNull()); |
3394 cls.SetTraceAllocation(enable); | 3394 cls.SetTraceAllocation(enable); |
3395 PrintSuccess(js); | 3395 PrintSuccess(js); |
3396 return true; | 3396 return true; |
3397 } | 3397 } |
3398 | 3398 |
3399 | 3399 |
3400 static ServiceMethodDescriptor service_methods_[] = { | 3400 static const ServiceMethodDescriptor service_methods_[] = { |
3401 { "_dumpIdZone", DumpIdZone, NULL }, | 3401 { "_dumpIdZone", DumpIdZone, NULL }, |
3402 { "_echo", Echo, | 3402 { "_echo", Echo, |
3403 NULL }, | 3403 NULL }, |
3404 { "_respondWithMalformedJson", RespondWithMalformedJson, | 3404 { "_respondWithMalformedJson", RespondWithMalformedJson, |
3405 NULL }, | 3405 NULL }, |
3406 { "_respondWithMalformedObject", RespondWithMalformedObject, | 3406 { "_respondWithMalformedObject", RespondWithMalformedObject, |
3407 NULL }, | 3407 NULL }, |
3408 { "_triggerEchoEvent", TriggerEchoEvent, | 3408 { "_triggerEchoEvent", TriggerEchoEvent, |
3409 NULL }, | 3409 NULL }, |
3410 { "addBreakpoint", AddBreakpoint, | 3410 { "addBreakpoint", AddBreakpoint, |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3497 set_name_params }, | 3497 set_name_params }, |
3498 { "_setTraceClassAllocation", SetTraceClassAllocation, | 3498 { "_setTraceClassAllocation", SetTraceClassAllocation, |
3499 set_trace_class_allocation_params }, | 3499 set_trace_class_allocation_params }, |
3500 { "setVMName", SetVMName, | 3500 { "setVMName", SetVMName, |
3501 set_vm_name_params }, | 3501 set_vm_name_params }, |
3502 { "_setVMTimelineFlag", SetVMTimelineFlag, | 3502 { "_setVMTimelineFlag", SetVMTimelineFlag, |
3503 set_vm_timeline_flag_params }, | 3503 set_vm_timeline_flag_params }, |
3504 }; | 3504 }; |
3505 | 3505 |
3506 | 3506 |
3507 ServiceMethodDescriptor* FindMethod(const char* method_name) { | 3507 const ServiceMethodDescriptor* FindMethod(const char* method_name) { |
3508 intptr_t num_methods = sizeof(service_methods_) / | 3508 intptr_t num_methods = sizeof(service_methods_) / |
3509 sizeof(service_methods_[0]); | 3509 sizeof(service_methods_[0]); |
3510 for (intptr_t i = 0; i < num_methods; i++) { | 3510 for (intptr_t i = 0; i < num_methods; i++) { |
3511 ServiceMethodDescriptor& method = service_methods_[i]; | 3511 const ServiceMethodDescriptor& method = service_methods_[i]; |
3512 if (strcmp(method_name, method.name) == 0) { | 3512 if (strcmp(method_name, method.name) == 0) { |
3513 return &method; | 3513 return &method; |
3514 } | 3514 } |
3515 } | 3515 } |
3516 return NULL; | 3516 return NULL; |
3517 } | 3517 } |
3518 | 3518 |
3519 | 3519 |
3520 } // namespace dart | 3520 } // namespace dart |
OLD | NEW |