| 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 |