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 1501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1512 if (bpt_id < isolate->debugger()->limitBreakpointId()) { | 1512 if (bpt_id < isolate->debugger()->limitBreakpointId()) { |
1513 *result = ObjectIdRing::kCollected; | 1513 *result = ObjectIdRing::kCollected; |
1514 return NULL; | 1514 return NULL; |
1515 } | 1515 } |
1516 } | 1516 } |
1517 } | 1517 } |
1518 return NULL; | 1518 return NULL; |
1519 } | 1519 } |
1520 | 1520 |
1521 | 1521 |
1522 static bool PrintInboundReferences(Isolate* isolate, | 1522 static bool PrintInboundReferences(Thread* thread, |
1523 Object* target, | 1523 Object* target, |
1524 intptr_t limit, | 1524 intptr_t limit, |
1525 JSONStream* js) { | 1525 JSONStream* js) { |
1526 ObjectGraph graph(isolate); | 1526 ObjectGraph graph(thread); |
1527 Array& path = Array::Handle(Array::New(limit * 2)); | 1527 Array& path = Array::Handle(Array::New(limit * 2)); |
1528 intptr_t length = graph.InboundReferences(target, path); | 1528 intptr_t length = graph.InboundReferences(target, path); |
1529 JSONObject jsobj(js); | 1529 JSONObject jsobj(js); |
1530 jsobj.AddProperty("type", "InboundReferences"); | 1530 jsobj.AddProperty("type", "InboundReferences"); |
1531 { | 1531 { |
1532 JSONArray elements(&jsobj, "references"); | 1532 JSONArray elements(&jsobj, "references"); |
1533 Object& source = Object::Handle(); | 1533 Object& source = Object::Handle(); |
1534 Smi& slot_offset = Smi::Handle(); | 1534 Smi& slot_offset = Smi::Handle(); |
1535 Class& source_class = Class::Handle(); | 1535 Class& source_class = Class::Handle(); |
1536 Field& field = Field::Handle(); | 1536 Field& field = Field::Handle(); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1604 if (obj.raw() == Object::sentinel().raw()) { | 1604 if (obj.raw() == Object::sentinel().raw()) { |
1605 if (lookup_result == ObjectIdRing::kCollected) { | 1605 if (lookup_result == ObjectIdRing::kCollected) { |
1606 PrintSentinel(js, kCollectedSentinel); | 1606 PrintSentinel(js, kCollectedSentinel); |
1607 } else if (lookup_result == ObjectIdRing::kExpired) { | 1607 } else if (lookup_result == ObjectIdRing::kExpired) { |
1608 PrintSentinel(js, kExpiredSentinel); | 1608 PrintSentinel(js, kExpiredSentinel); |
1609 } else { | 1609 } else { |
1610 PrintInvalidParamError(js, "targetId"); | 1610 PrintInvalidParamError(js, "targetId"); |
1611 } | 1611 } |
1612 return true; | 1612 return true; |
1613 } | 1613 } |
1614 return PrintInboundReferences(isolate, &obj, limit, js); | 1614 return PrintInboundReferences(thread, &obj, limit, js); |
1615 } | 1615 } |
1616 | 1616 |
1617 | 1617 |
1618 static bool PrintRetainingPath(Isolate* isolate, | 1618 static bool PrintRetainingPath(Thread* thread, |
1619 Object* obj, | 1619 Object* obj, |
1620 intptr_t limit, | 1620 intptr_t limit, |
1621 JSONStream* js) { | 1621 JSONStream* js) { |
1622 ObjectGraph graph(isolate); | 1622 ObjectGraph graph(thread); |
1623 Array& path = Array::Handle(Array::New(limit * 2)); | 1623 Array& path = Array::Handle(Array::New(limit * 2)); |
1624 intptr_t length = graph.RetainingPath(obj, path); | 1624 intptr_t length = graph.RetainingPath(obj, path); |
1625 JSONObject jsobj(js); | 1625 JSONObject jsobj(js); |
1626 jsobj.AddProperty("type", "RetainingPath"); | 1626 jsobj.AddProperty("type", "RetainingPath"); |
1627 jsobj.AddProperty("length", length); | 1627 jsobj.AddProperty("length", length); |
1628 JSONArray elements(&jsobj, "elements"); | 1628 JSONArray elements(&jsobj, "elements"); |
1629 Object& element = Object::Handle(); | 1629 Object& element = Object::Handle(); |
1630 Smi& slot_offset = Smi::Handle(); | 1630 Smi& slot_offset = Smi::Handle(); |
1631 Class& element_class = Class::Handle(); | 1631 Class& element_class = Class::Handle(); |
1632 Array& element_field_map = Array::Handle(); | 1632 Array& element_field_map = Array::Handle(); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1706 if (obj.raw() == Object::sentinel().raw()) { | 1706 if (obj.raw() == Object::sentinel().raw()) { |
1707 if (lookup_result == ObjectIdRing::kCollected) { | 1707 if (lookup_result == ObjectIdRing::kCollected) { |
1708 PrintSentinel(js, kCollectedSentinel); | 1708 PrintSentinel(js, kCollectedSentinel); |
1709 } else if (lookup_result == ObjectIdRing::kExpired) { | 1709 } else if (lookup_result == ObjectIdRing::kExpired) { |
1710 PrintSentinel(js, kExpiredSentinel); | 1710 PrintSentinel(js, kExpiredSentinel); |
1711 } else { | 1711 } else { |
1712 PrintInvalidParamError(js, "targetId"); | 1712 PrintInvalidParamError(js, "targetId"); |
1713 } | 1713 } |
1714 return true; | 1714 return true; |
1715 } | 1715 } |
1716 return PrintRetainingPath(isolate, &obj, limit, js); | 1716 return PrintRetainingPath(thread, &obj, limit, js); |
1717 } | 1717 } |
1718 | 1718 |
1719 | 1719 |
1720 static const MethodParameter* get_retained_size_params[] = { | 1720 static const MethodParameter* get_retained_size_params[] = { |
1721 ISOLATE_PARAMETER, | 1721 ISOLATE_PARAMETER, |
1722 NULL, | 1722 NULL, |
1723 }; | 1723 }; |
1724 | 1724 |
1725 | 1725 |
1726 static bool GetRetainedSize(Isolate* isolate, JSONStream* js) { | 1726 static bool GetRetainedSize(Isolate* isolate, JSONStream* js) { |
1727 const char* target_id = js->LookupParam("targetId"); | 1727 const char* target_id = js->LookupParam("targetId"); |
1728 if (target_id == NULL) { | 1728 if (target_id == NULL) { |
1729 PrintMissingParamError(js, "targetId"); | 1729 PrintMissingParamError(js, "targetId"); |
1730 return true; | 1730 return true; |
1731 } | 1731 } |
1732 ObjectIdRing::LookupResult lookup_result; | 1732 ObjectIdRing::LookupResult lookup_result; |
1733 Object& obj = Object::Handle(LookupHeapObject(isolate, target_id, | 1733 Object& obj = Object::Handle(LookupHeapObject(isolate, target_id, |
1734 &lookup_result)); | 1734 &lookup_result)); |
1735 if (obj.raw() == Object::sentinel().raw()) { | 1735 if (obj.raw() == Object::sentinel().raw()) { |
1736 if (lookup_result == ObjectIdRing::kCollected) { | 1736 if (lookup_result == ObjectIdRing::kCollected) { |
1737 PrintSentinel(js, kCollectedSentinel); | 1737 PrintSentinel(js, kCollectedSentinel); |
1738 } else if (lookup_result == ObjectIdRing::kExpired) { | 1738 } else if (lookup_result == ObjectIdRing::kExpired) { |
1739 PrintSentinel(js, kExpiredSentinel); | 1739 PrintSentinel(js, kExpiredSentinel); |
1740 } else { | 1740 } else { |
1741 PrintInvalidParamError(js, "targetId"); | 1741 PrintInvalidParamError(js, "targetId"); |
1742 } | 1742 } |
1743 return true; | 1743 return true; |
1744 } | 1744 } |
| 1745 Thread* thread = Thread::Current(); |
1745 // TODO(rmacnak): There is no way to get the size retained by a class object. | 1746 // TODO(rmacnak): There is no way to get the size retained by a class object. |
1746 // SizeRetainedByClass should be a separate RPC. | 1747 // SizeRetainedByClass should be a separate RPC. |
1747 if (obj.IsClass()) { | 1748 if (obj.IsClass()) { |
1748 const Class& cls = Class::Cast(obj); | 1749 const Class& cls = Class::Cast(obj); |
1749 ObjectGraph graph(isolate); | 1750 ObjectGraph graph(thread); |
1750 intptr_t retained_size = graph.SizeRetainedByClass(cls.id()); | 1751 intptr_t retained_size = graph.SizeRetainedByClass(cls.id()); |
1751 const Object& result = Object::Handle(Integer::New(retained_size)); | 1752 const Object& result = Object::Handle(Integer::New(retained_size)); |
1752 result.PrintJSON(js, true); | 1753 result.PrintJSON(js, true); |
1753 return true; | 1754 return true; |
1754 } | 1755 } |
1755 | 1756 |
1756 ObjectGraph graph(isolate); | 1757 ObjectGraph graph(thread); |
1757 intptr_t retained_size = graph.SizeRetainedByInstance(obj); | 1758 intptr_t retained_size = graph.SizeRetainedByInstance(obj); |
1758 const Object& result = Object::Handle(Integer::New(retained_size)); | 1759 const Object& result = Object::Handle(Integer::New(retained_size)); |
1759 result.PrintJSON(js, true); | 1760 result.PrintJSON(js, true); |
1760 return true; | 1761 return true; |
1761 } | 1762 } |
1762 | 1763 |
1763 | 1764 |
1764 static const MethodParameter* evaluate_params[] = { | 1765 static const MethodParameter* evaluate_params[] = { |
1765 ISOLATE_PARAMETER, | 1766 ISOLATE_PARAMETER, |
1766 NULL, | 1767 NULL, |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1921 const Object& obj = | 1922 const Object& obj = |
1922 Object::Handle(LookupHeapObject(isolate, target_id, NULL)); | 1923 Object::Handle(LookupHeapObject(isolate, target_id, NULL)); |
1923 if (obj.raw() == Object::sentinel().raw() || | 1924 if (obj.raw() == Object::sentinel().raw() || |
1924 !obj.IsClass()) { | 1925 !obj.IsClass()) { |
1925 PrintInvalidParamError(js, "classId"); | 1926 PrintInvalidParamError(js, "classId"); |
1926 return true; | 1927 return true; |
1927 } | 1928 } |
1928 const Class& cls = Class::Cast(obj); | 1929 const Class& cls = Class::Cast(obj); |
1929 Array& storage = Array::Handle(Array::New(limit)); | 1930 Array& storage = Array::Handle(Array::New(limit)); |
1930 GetInstancesVisitor visitor(cls, storage); | 1931 GetInstancesVisitor visitor(cls, storage); |
1931 ObjectGraph graph(isolate); | 1932 ObjectGraph graph(Thread::Current()); |
1932 graph.IterateObjects(&visitor); | 1933 graph.IterateObjects(&visitor); |
1933 intptr_t count = visitor.count(); | 1934 intptr_t count = visitor.count(); |
1934 if (count < limit) { | 1935 if (count < limit) { |
1935 // Truncate the list using utility method for GrowableObjectArray. | 1936 // Truncate the list using utility method for GrowableObjectArray. |
1936 GrowableObjectArray& wrapper = GrowableObjectArray::Handle( | 1937 GrowableObjectArray& wrapper = GrowableObjectArray::Handle( |
1937 GrowableObjectArray::New(storage)); | 1938 GrowableObjectArray::New(storage)); |
1938 wrapper.SetLength(count); | 1939 wrapper.SetLength(count); |
1939 storage = Array::MakeArray(wrapper); | 1940 storage = Array::MakeArray(wrapper); |
1940 } | 1941 } |
1941 JSONObject jsobj(js); | 1942 JSONObject jsobj(js); |
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2636 // TODO(koda): Provide some id that ties this request to async response(s). | 2637 // TODO(koda): Provide some id that ties this request to async response(s). |
2637 JSONObject jsobj(js); | 2638 JSONObject jsobj(js); |
2638 jsobj.AddProperty("type", "OK"); | 2639 jsobj.AddProperty("type", "OK"); |
2639 return true; | 2640 return true; |
2640 } | 2641 } |
2641 | 2642 |
2642 | 2643 |
2643 void Service::SendGraphEvent(Isolate* isolate) { | 2644 void Service::SendGraphEvent(Isolate* isolate) { |
2644 uint8_t* buffer = NULL; | 2645 uint8_t* buffer = NULL; |
2645 WriteStream stream(&buffer, &allocator, 1 * MB); | 2646 WriteStream stream(&buffer, &allocator, 1 * MB); |
2646 ObjectGraph graph(isolate); | 2647 ObjectGraph graph(Thread::Current()); |
2647 intptr_t node_count = graph.Serialize(&stream); | 2648 intptr_t node_count = graph.Serialize(&stream); |
2648 | 2649 |
2649 // Chrome crashes receiving a single tens-of-megabytes blob, so send the | 2650 // Chrome crashes receiving a single tens-of-megabytes blob, so send the |
2650 // snapshot in megabyte-sized chunks instead. | 2651 // snapshot in megabyte-sized chunks instead. |
2651 const intptr_t kChunkSize = 1 * MB; | 2652 const intptr_t kChunkSize = 1 * MB; |
2652 intptr_t num_chunks = | 2653 intptr_t num_chunks = |
2653 (stream.bytes_written() + (kChunkSize - 1)) / kChunkSize; | 2654 (stream.bytes_written() + (kChunkSize - 1)) / kChunkSize; |
2654 for (intptr_t i = 0; i < num_chunks; i++) { | 2655 for (intptr_t i = 0; i < num_chunks; i++) { |
2655 JSONStream js; | 2656 JSONStream js; |
2656 { | 2657 { |
(...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3326 ServiceMethodDescriptor& method = service_methods_[i]; | 3327 ServiceMethodDescriptor& method = service_methods_[i]; |
3327 if (strcmp(method_name, method.name) == 0) { | 3328 if (strcmp(method_name, method.name) == 0) { |
3328 return &method; | 3329 return &method; |
3329 } | 3330 } |
3330 } | 3331 } |
3331 return NULL; | 3332 return NULL; |
3332 } | 3333 } |
3333 | 3334 |
3334 | 3335 |
3335 } // namespace dart | 3336 } // namespace dart |
OLD | NEW |