| 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 "platform/globals.h" | 8 #include "platform/globals.h" |
| 9 | 9 |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 1439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1450 return Object::sentinel().raw(); | 1450 return Object::sentinel().raw(); |
| 1451 } | 1451 } |
| 1452 return type.raw(); | 1452 return type.raw(); |
| 1453 } | 1453 } |
| 1454 | 1454 |
| 1455 // Not found. | 1455 // Not found. |
| 1456 return Object::sentinel().raw(); | 1456 return Object::sentinel().raw(); |
| 1457 } | 1457 } |
| 1458 | 1458 |
| 1459 | 1459 |
| 1460 static RawObject* LookupHeapObjectTypeArguments(Isolate* isolate, |
| 1461 char** parts, int num_parts) { |
| 1462 // TypeArguments ids look like: "typearguments/17" |
| 1463 if (num_parts < 2) { |
| 1464 return Object::sentinel().raw(); |
| 1465 } |
| 1466 intptr_t id; |
| 1467 if (!GetIntegerId(parts[1], &id)) { |
| 1468 return Object::sentinel().raw(); |
| 1469 } |
| 1470 ObjectStore* object_store = isolate->object_store(); |
| 1471 const Array& table = Array::Handle(object_store->canonical_type_arguments()); |
| 1472 ASSERT(table.Length() > 0); |
| 1473 const intptr_t table_size = table.Length() - 1; |
| 1474 if ((id < 0) || (id >= table_size) || (table.At(id) == Object::null())) { |
| 1475 return Object::sentinel().raw(); |
| 1476 } |
| 1477 return table.At(id); |
| 1478 } |
| 1479 |
| 1480 |
| 1460 static RawObject* LookupHeapObjectCode(Isolate* isolate, | 1481 static RawObject* LookupHeapObjectCode(Isolate* isolate, |
| 1461 char** parts, int num_parts) { | 1482 char** parts, int num_parts) { |
| 1462 if (num_parts != 2) { | 1483 if (num_parts != 2) { |
| 1463 return Object::sentinel().raw(); | 1484 return Object::sentinel().raw(); |
| 1464 } | 1485 } |
| 1465 uword pc; | 1486 uword pc; |
| 1466 static const char* kCollectedPrefix = "collected-"; | 1487 static const char* kCollectedPrefix = "collected-"; |
| 1467 static intptr_t kCollectedPrefixLen = strlen(kCollectedPrefix); | 1488 static intptr_t kCollectedPrefixLen = strlen(kCollectedPrefix); |
| 1468 static const char* kNativePrefix = "native-"; | 1489 static const char* kNativePrefix = "native-"; |
| 1469 static intptr_t kNativePrefixLen = strlen(kNativePrefix); | 1490 static intptr_t kNativePrefixLen = strlen(kNativePrefix); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1546 *result = lookup_result; | 1567 *result = lookup_result; |
| 1547 } | 1568 } |
| 1548 return Object::sentinel().raw(); | 1569 return Object::sentinel().raw(); |
| 1549 } | 1570 } |
| 1550 return obj.raw(); | 1571 return obj.raw(); |
| 1551 | 1572 |
| 1552 } else if (strcmp(parts[0], "libraries") == 0) { | 1573 } else if (strcmp(parts[0], "libraries") == 0) { |
| 1553 return LookupHeapObjectLibraries(isolate, parts, num_parts); | 1574 return LookupHeapObjectLibraries(isolate, parts, num_parts); |
| 1554 } else if (strcmp(parts[0], "classes") == 0) { | 1575 } else if (strcmp(parts[0], "classes") == 0) { |
| 1555 return LookupHeapObjectClasses(isolate, parts, num_parts); | 1576 return LookupHeapObjectClasses(isolate, parts, num_parts); |
| 1577 } else if (strcmp(parts[0], "typearguments") == 0) { |
| 1578 return LookupHeapObjectTypeArguments(isolate, parts, num_parts); |
| 1556 } else if (strcmp(parts[0], "code") == 0) { | 1579 } else if (strcmp(parts[0], "code") == 0) { |
| 1557 return LookupHeapObjectCode(isolate, parts, num_parts); | 1580 return LookupHeapObjectCode(isolate, parts, num_parts); |
| 1558 } | 1581 } |
| 1559 | 1582 |
| 1560 // Not found. | 1583 // Not found. |
| 1561 return Object::sentinel().raw(); | 1584 return Object::sentinel().raw(); |
| 1562 } | 1585 } |
| 1563 | 1586 |
| 1564 | 1587 |
| 1565 static void PrintSentinel(JSONStream* js, | 1588 static void PrintSentinel(JSONStream* js, |
| (...skipping 1206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2772 } | 2795 } |
| 2773 if (should_collect) { | 2796 if (should_collect) { |
| 2774 isolate->UpdateLastAllocationProfileGCTimestamp(); | 2797 isolate->UpdateLastAllocationProfileGCTimestamp(); |
| 2775 isolate->heap()->CollectAllGarbage(); | 2798 isolate->heap()->CollectAllGarbage(); |
| 2776 } | 2799 } |
| 2777 isolate->class_table()->AllocationProfilePrintJSON(js); | 2800 isolate->class_table()->AllocationProfilePrintJSON(js); |
| 2778 return true; | 2801 return true; |
| 2779 } | 2802 } |
| 2780 | 2803 |
| 2781 | 2804 |
| 2782 static bool HandleTypeArguments(Isolate* isolate, JSONStream* js) { | |
| 2783 ObjectStore* object_store = isolate->object_store(); | |
| 2784 const Array& table = Array::Handle(object_store->canonical_type_arguments()); | |
| 2785 ASSERT(table.Length() > 0); | |
| 2786 TypeArguments& type_args = TypeArguments::Handle(); | |
| 2787 const intptr_t table_size = table.Length() - 1; | |
| 2788 const intptr_t table_used = Smi::Value(Smi::RawCast(table.At(table_size))); | |
| 2789 bool only_with_instantiations = false; | |
| 2790 if (js->num_arguments() >= 2) { | |
| 2791 const char* second = js->GetArgument(1); | |
| 2792 if (strcmp(second, "withinstantiations") == 0) { | |
| 2793 only_with_instantiations = true; | |
| 2794 if (js->num_arguments() > 2) { | |
| 2795 PrintError(js, "Command too long"); | |
| 2796 return true; | |
| 2797 } | |
| 2798 } | |
| 2799 } | |
| 2800 if ((js->num_arguments() == 1) || only_with_instantiations) { | |
| 2801 JSONObject jsobj(js); | |
| 2802 jsobj.AddProperty("type", "TypeArgumentsList"); | |
| 2803 jsobj.AddProperty("table_size", table_size); | |
| 2804 jsobj.AddProperty("table_used", table_used); | |
| 2805 JSONArray members(&jsobj, "members"); | |
| 2806 for (intptr_t i = 0; i < table_size; i++) { | |
| 2807 type_args ^= table.At(i); | |
| 2808 if (!type_args.IsNull()) { | |
| 2809 if (!only_with_instantiations || type_args.HasInstantiations()) { | |
| 2810 members.AddValue(type_args); | |
| 2811 } | |
| 2812 } | |
| 2813 } | |
| 2814 return true; | |
| 2815 } | |
| 2816 ASSERT((js->num_arguments() >= 2) && !only_with_instantiations); | |
| 2817 intptr_t id; | |
| 2818 if (!GetIntegerId(js->GetArgument(1), &id)) { | |
| 2819 // Note that the table index of the canonical type arguments will change | |
| 2820 // when the table grows. Should we not support this access at all? | |
| 2821 PrintError(js, "Must specify collection object id: /typearguments/id"); | |
| 2822 return true; | |
| 2823 } | |
| 2824 if ((id < 0) || (id >= table_size) || (table.At(id) == Object::null())) { | |
| 2825 PrintError(js, "%" Pd " is not a valid typearguments id.", id); | |
| 2826 return true; | |
| 2827 } | |
| 2828 type_args ^= table.At(id); | |
| 2829 type_args.PrintJSON(js, false); | |
| 2830 return true; | |
| 2831 } | |
| 2832 | |
| 2833 | |
| 2834 static bool HandleIsolateGetHeapMap(Isolate* isolate, JSONStream* js) { | 2805 static bool HandleIsolateGetHeapMap(Isolate* isolate, JSONStream* js) { |
| 2835 isolate->heap()->PrintHeapMapToJSONStream(isolate, js); | 2806 isolate->heap()->PrintHeapMapToJSONStream(isolate, js); |
| 2836 return true; | 2807 return true; |
| 2837 } | 2808 } |
| 2838 | 2809 |
| 2839 | 2810 |
| 2840 static bool HandleIsolateRequestHeapSnapshot(Isolate* isolate, JSONStream* js) { | 2811 static bool HandleIsolateRequestHeapSnapshot(Isolate* isolate, JSONStream* js) { |
| 2841 Service::SendGraphEvent(isolate); | 2812 Service::SendGraphEvent(isolate); |
| 2842 // TODO(koda): Provide some id that ties this request to async response(s). | 2813 // TODO(koda): Provide some id that ties this request to async response(s). |
| 2843 JSONObject jsobj(js); | 2814 JSONObject jsobj(js); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2932 { "_malformedobject", HandleMalformedObject }, // debug | 2903 { "_malformedobject", HandleMalformedObject }, // debug |
| 2933 { "_echo", HandleIsolateEcho }, // debug | 2904 { "_echo", HandleIsolateEcho }, // debug |
| 2934 { "", HandleIsolate }, // getObject | 2905 { "", HandleIsolate }, // getObject |
| 2935 { "address", HandleAddress }, // to do | 2906 { "address", HandleAddress }, // to do |
| 2936 { "classes", HandleClasses }, // getObject | 2907 { "classes", HandleClasses }, // getObject |
| 2937 { "code", HandleCode }, // getObject | 2908 { "code", HandleCode }, // getObject |
| 2938 { "libraries", HandleLibraries }, // getObject | 2909 { "libraries", HandleLibraries }, // getObject |
| 2939 { "metrics", HandleMetrics }, // to do - complex? | 2910 { "metrics", HandleMetrics }, // to do - complex? |
| 2940 { "objects", HandleObjects }, // getObject | 2911 { "objects", HandleObjects }, // getObject |
| 2941 { "scripts", HandleScripts }, // getObject | 2912 { "scripts", HandleScripts }, // getObject |
| 2942 { "typearguments", HandleTypeArguments }, // confusing | |
| 2943 }; | 2913 }; |
| 2944 | 2914 |
| 2945 | 2915 |
| 2946 static IsolateMessageHandler FindIsolateMessageHandler(const char* command) { | 2916 static IsolateMessageHandler FindIsolateMessageHandler(const char* command) { |
| 2947 intptr_t num_message_handlers = sizeof(isolate_handlers) / | 2917 intptr_t num_message_handlers = sizeof(isolate_handlers) / |
| 2948 sizeof(isolate_handlers[0]); | 2918 sizeof(isolate_handlers[0]); |
| 2949 for (intptr_t i = 0; i < num_message_handlers; i++) { | 2919 for (intptr_t i = 0; i < num_message_handlers; i++) { |
| 2950 const IsolateMessageHandlerEntry& entry = isolate_handlers[i]; | 2920 const IsolateMessageHandlerEntry& entry = isolate_handlers[i]; |
| 2951 if (strcmp(command, entry.command) == 0) { | 2921 if (strcmp(command, entry.command) == 0) { |
| 2952 return entry.handler; | 2922 return entry.handler; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2995 | 2965 |
| 2996 | 2966 |
| 2997 static bool HandleIsolateGetClassList(Isolate* isolate, JSONStream* js) { | 2967 static bool HandleIsolateGetClassList(Isolate* isolate, JSONStream* js) { |
| 2998 ClassTable* table = isolate->class_table(); | 2968 ClassTable* table = isolate->class_table(); |
| 2999 JSONObject jsobj(js); | 2969 JSONObject jsobj(js); |
| 3000 table->PrintToJSONObject(&jsobj); | 2970 table->PrintToJSONObject(&jsobj); |
| 3001 return true; | 2971 return true; |
| 3002 } | 2972 } |
| 3003 | 2973 |
| 3004 | 2974 |
| 2975 static bool HandleIsolateGetTypeArgumentsList(Isolate* isolate, |
| 2976 JSONStream* js) { |
| 2977 bool only_with_instantiations = false; |
| 2978 if (js->OptionIs("onlyWithInstantiations", "true")) { |
| 2979 only_with_instantiations = true; |
| 2980 } |
| 2981 ObjectStore* object_store = isolate->object_store(); |
| 2982 const Array& table = Array::Handle(object_store->canonical_type_arguments()); |
| 2983 ASSERT(table.Length() > 0); |
| 2984 TypeArguments& type_args = TypeArguments::Handle(); |
| 2985 const intptr_t table_size = table.Length() - 1; |
| 2986 const intptr_t table_used = Smi::Value(Smi::RawCast(table.At(table_size))); |
| 2987 JSONObject jsobj(js); |
| 2988 jsobj.AddProperty("type", "TypeArgumentsList"); |
| 2989 jsobj.AddProperty("canonicalTypeArgumentsTableSize", table_size); |
| 2990 jsobj.AddProperty("canonicalTypeArgumentsTableUsed", table_used); |
| 2991 JSONArray members(&jsobj, "typeArguments"); |
| 2992 for (intptr_t i = 0; i < table_size; i++) { |
| 2993 type_args ^= table.At(i); |
| 2994 if (!type_args.IsNull()) { |
| 2995 if (!only_with_instantiations || type_args.HasInstantiations()) { |
| 2996 members.AddValue(type_args); |
| 2997 } |
| 2998 } |
| 2999 } |
| 3000 return true; |
| 3001 } |
| 3002 |
| 3003 |
| 3005 static IsolateMessageHandlerEntry isolate_handlers_new[] = { | 3004 static IsolateMessageHandlerEntry isolate_handlers_new[] = { |
| 3006 { "getIsolate", HandleIsolate }, | 3005 { "getIsolate", HandleIsolate }, |
| 3007 { "getObject", HandleIsolateGetObject }, | 3006 { "getObject", HandleIsolateGetObject }, |
| 3008 { "getBreakpoints", HandleIsolateGetBreakpoints }, | 3007 { "getBreakpoints", HandleIsolateGetBreakpoints }, |
| 3009 { "pause", HandleIsolatePause }, | 3008 { "pause", HandleIsolatePause }, |
| 3010 { "resume", HandleIsolateResume }, | 3009 { "resume", HandleIsolateResume }, |
| 3011 { "getStack", HandleIsolateGetStack }, | 3010 { "getStack", HandleIsolateGetStack }, |
| 3012 { "getCpuProfile", HandleIsolateGetCpuProfile }, | 3011 { "getCpuProfile", HandleIsolateGetCpuProfile }, |
| 3013 { "getTagProfile", HandleIsolateGetTagProfile }, | 3012 { "getTagProfile", HandleIsolateGetTagProfile }, |
| 3014 { "getAllocationProfile", HandleIsolateGetAllocationProfile }, | 3013 { "getAllocationProfile", HandleIsolateGetAllocationProfile }, |
| 3015 { "getHeapMap", HandleIsolateGetHeapMap }, | 3014 { "getHeapMap", HandleIsolateGetHeapMap }, |
| 3016 { "addBreakpoint", HandleIsolateAddBreakpoint }, | 3015 { "addBreakpoint", HandleIsolateAddBreakpoint }, |
| 3017 { "removeBreakpoint", HandleIsolateRemoveBreakpoint }, | 3016 { "removeBreakpoint", HandleIsolateRemoveBreakpoint }, |
| 3018 { "getCoverage", HandleIsolateGetCoverage }, | 3017 { "getCoverage", HandleIsolateGetCoverage }, |
| 3019 { "eval", HandleIsolateEval }, | 3018 { "eval", HandleIsolateEval }, |
| 3020 { "getRetainedSize", HandleIsolateGetRetainedSize }, | 3019 { "getRetainedSize", HandleIsolateGetRetainedSize }, |
| 3021 { "getRetainingPath", HandleIsolateGetRetainingPath }, | 3020 { "getRetainingPath", HandleIsolateGetRetainingPath }, |
| 3022 { "getInboundReferences", HandleIsolateGetInboundReferences }, | 3021 { "getInboundReferences", HandleIsolateGetInboundReferences }, |
| 3023 { "getInstances", HandleIsolateGetInstances }, | 3022 { "getInstances", HandleIsolateGetInstances }, |
| 3024 { "requestHeapSnapshot", HandleIsolateRequestHeapSnapshot }, | 3023 { "requestHeapSnapshot", HandleIsolateRequestHeapSnapshot }, |
| 3025 { "getClassList", HandleIsolateGetClassList }, | 3024 { "getClassList", HandleIsolateGetClassList }, |
| 3025 { "getTypeArgumentsList", HandleIsolateGetTypeArgumentsList } |
| 3026 }; | 3026 }; |
| 3027 | 3027 |
| 3028 | 3028 |
| 3029 static IsolateMessageHandler FindIsolateMessageHandlerNew(const char* command) { | 3029 static IsolateMessageHandler FindIsolateMessageHandlerNew(const char* command) { |
| 3030 intptr_t num_message_handlers = sizeof(isolate_handlers_new) / | 3030 intptr_t num_message_handlers = sizeof(isolate_handlers_new) / |
| 3031 sizeof(isolate_handlers_new[0]); | 3031 sizeof(isolate_handlers_new[0]); |
| 3032 for (intptr_t i = 0; i < num_message_handlers; i++) { | 3032 for (intptr_t i = 0; i < num_message_handlers; i++) { |
| 3033 const IsolateMessageHandlerEntry& entry = isolate_handlers_new[i]; | 3033 const IsolateMessageHandlerEntry& entry = isolate_handlers_new[i]; |
| 3034 if (strcmp(command, entry.command) == 0) { | 3034 if (strcmp(command, entry.command) == 0) { |
| 3035 return entry.handler; | 3035 return entry.handler; |
| (...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3480 while (current != NULL) { | 3480 while (current != NULL) { |
| 3481 if (strcmp(name, current->name()) == 0) { | 3481 if (strcmp(name, current->name()) == 0) { |
| 3482 return current; | 3482 return current; |
| 3483 } | 3483 } |
| 3484 current = current->next(); | 3484 current = current->next(); |
| 3485 } | 3485 } |
| 3486 return NULL; | 3486 return NULL; |
| 3487 } | 3487 } |
| 3488 | 3488 |
| 3489 } // namespace dart | 3489 } // namespace dart |
| OLD | NEW |