OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/object.h" | 5 #include "vm/object.h" |
6 | 6 |
7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 1800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1811 intptr_t Class::FindFunctionIndex(const Function& needle) const { | 1811 intptr_t Class::FindFunctionIndex(const Function& needle) const { |
1812 Isolate* isolate = Isolate::Current(); | 1812 Isolate* isolate = Isolate::Current(); |
1813 if (EnsureIsFinalized(isolate) != Error::null()) { | 1813 if (EnsureIsFinalized(isolate) != Error::null()) { |
1814 return -1; | 1814 return -1; |
1815 } | 1815 } |
1816 ReusableHandleScope reused_handles(isolate); | 1816 ReusableHandleScope reused_handles(isolate); |
1817 Array& funcs = reused_handles.ArrayHandle(); | 1817 Array& funcs = reused_handles.ArrayHandle(); |
1818 funcs ^= functions(); | 1818 funcs ^= functions(); |
1819 ASSERT(!funcs.IsNull()); | 1819 ASSERT(!funcs.IsNull()); |
1820 Function& function = reused_handles.FunctionHandle(); | 1820 Function& function = reused_handles.FunctionHandle(); |
1821 String& function_name = reused_handles.StringHandle(); | |
1822 String& needle_name = String::Handle(isolate); | |
1823 needle_name ^= needle.name(); | |
1824 const intptr_t len = funcs.Length(); | 1821 const intptr_t len = funcs.Length(); |
1825 for (intptr_t i = 0; i < len; i++) { | 1822 for (intptr_t i = 0; i < len; i++) { |
1826 function ^= funcs.At(i); | 1823 function ^= funcs.At(i); |
1827 function_name ^= function.name(); | 1824 if (function.raw() == needle.raw()) { |
1828 if (function_name.Equals(needle_name)) { | |
1829 return i; | 1825 return i; |
1830 } | 1826 } |
1831 } | 1827 } |
1832 // No function found. | 1828 // No function found. |
1833 return -1; | 1829 return -1; |
1834 } | 1830 } |
1835 | 1831 |
1836 | 1832 |
| 1833 RawFunction* Class::FunctionFromIndex(intptr_t idx) const { |
| 1834 const Array& funcs = Array::Handle(functions()); |
| 1835 if ((idx < 0) || (idx >= funcs.Length())) { |
| 1836 return Function::null(); |
| 1837 } |
| 1838 Function& func = Function::Handle(); |
| 1839 func ^= funcs.At(idx); |
| 1840 ASSERT(!func.IsNull()); |
| 1841 return func.raw(); |
| 1842 } |
| 1843 |
| 1844 |
| 1845 RawFunction* Class::ImplicitClosureFunctionFromIndex(intptr_t idx) const { |
| 1846 const Array& funcs = Array::Handle(functions()); |
| 1847 if ((idx < 0) || (idx >= funcs.Length())) { |
| 1848 return Function::null(); |
| 1849 } |
| 1850 Function& func = Function::Handle(); |
| 1851 func ^= funcs.At(idx); |
| 1852 ASSERT(!func.IsNull()); |
| 1853 if (!func.HasImplicitClosureFunction()) { |
| 1854 return Function::null(); |
| 1855 } |
| 1856 const Function& closure_func = |
| 1857 Function::Handle(func.ImplicitClosureFunction()); |
| 1858 ASSERT(!closure_func.IsNull()); |
| 1859 return closure_func.raw(); |
| 1860 } |
| 1861 |
| 1862 |
| 1863 intptr_t Class::FindImplicitClosureFunctionIndex(const Function& needle) const { |
| 1864 Isolate* isolate = Isolate::Current(); |
| 1865 if (EnsureIsFinalized(isolate) != Error::null()) { |
| 1866 return -1; |
| 1867 } |
| 1868 ReusableHandleScope reused_handles(isolate); |
| 1869 Array& funcs = reused_handles.ArrayHandle(); |
| 1870 funcs ^= functions(); |
| 1871 ASSERT(!funcs.IsNull()); |
| 1872 Function& function = reused_handles.FunctionHandle(); |
| 1873 Function& implicit_closure = Function::Handle(); |
| 1874 const intptr_t len = funcs.Length(); |
| 1875 for (intptr_t i = 0; i < len; i++) { |
| 1876 function ^= funcs.At(i); |
| 1877 implicit_closure ^= function.implicit_closure_function(); |
| 1878 if (implicit_closure.IsNull()) { |
| 1879 // Skip non-implicit closure functions. |
| 1880 continue; |
| 1881 } |
| 1882 if (needle.raw() == implicit_closure.raw()) { |
| 1883 return i; |
| 1884 } |
| 1885 } |
| 1886 // No function found. |
| 1887 return -1; |
| 1888 } |
| 1889 |
| 1890 |
| 1891 |
| 1892 intptr_t Class::FindInvocationDispatcherFunctionIndex( |
| 1893 const Function& needle) const { |
| 1894 Isolate* isolate = Isolate::Current(); |
| 1895 if (EnsureIsFinalized(isolate) != Error::null()) { |
| 1896 return -1; |
| 1897 } |
| 1898 ReusableHandleScope reused_handles(isolate); |
| 1899 Array& funcs = reused_handles.ArrayHandle(); |
| 1900 funcs ^= invocation_dispatcher_cache(); |
| 1901 ASSERT(!funcs.IsNull()); |
| 1902 Object& object = reused_handles.ObjectHandle(); |
| 1903 const intptr_t len = funcs.Length(); |
| 1904 for (intptr_t i = 0; i < len; i++) { |
| 1905 object = funcs.At(i); |
| 1906 // The invocation_dispatcher_cache is a table with some entries that |
| 1907 // are functions. |
| 1908 if (object.IsFunction()) { |
| 1909 if (Function::Cast(object).raw() == needle.raw()) { |
| 1910 return i; |
| 1911 } |
| 1912 } |
| 1913 } |
| 1914 // No function found. |
| 1915 return -1; |
| 1916 } |
| 1917 |
| 1918 |
| 1919 |
| 1920 RawFunction* Class::InvocationDispatcherFunctionFromIndex(intptr_t idx) const { |
| 1921 ReusableHandleScope reused_handles(Isolate::Current()); |
| 1922 Array& dispatcher_cache = reused_handles.ArrayHandle(); |
| 1923 dispatcher_cache ^= invocation_dispatcher_cache(); |
| 1924 Object& object = reused_handles.ObjectHandle(); |
| 1925 object = dispatcher_cache.At(idx); |
| 1926 if (!object.IsFunction()) { |
| 1927 return Function::null(); |
| 1928 } |
| 1929 return Function::Cast(object).raw(); |
| 1930 } |
| 1931 |
| 1932 |
1837 void Class::AddClosureFunction(const Function& function) const { | 1933 void Class::AddClosureFunction(const Function& function) const { |
1838 GrowableObjectArray& closures = | 1934 GrowableObjectArray& closures = |
1839 GrowableObjectArray::Handle(raw_ptr()->closure_functions_); | 1935 GrowableObjectArray::Handle(raw_ptr()->closure_functions_); |
1840 if (closures.IsNull()) { | 1936 if (closures.IsNull()) { |
1841 closures = GrowableObjectArray::New(4); | 1937 closures = GrowableObjectArray::New(4); |
1842 StorePointer(&raw_ptr()->closure_functions_, closures.raw()); | 1938 StorePointer(&raw_ptr()->closure_functions_, closures.raw()); |
1843 } | 1939 } |
1844 ASSERT(function.IsNonImplicitClosureFunction()); | 1940 ASSERT(function.IsNonImplicitClosureFunction()); |
1845 closures.Add(function); | 1941 closures.Add(function); |
1846 } | 1942 } |
(...skipping 20 matching lines...) Expand all Loading... |
1867 best_fit_token_pos = closure.token_pos(); | 1963 best_fit_token_pos = closure.token_pos(); |
1868 } | 1964 } |
1869 } | 1965 } |
1870 closure = Function::null(); | 1966 closure = Function::null(); |
1871 if (best_fit_index >= 0) { | 1967 if (best_fit_index >= 0) { |
1872 closure ^= closures.At(best_fit_index); | 1968 closure ^= closures.At(best_fit_index); |
1873 } | 1969 } |
1874 return closure.raw(); | 1970 return closure.raw(); |
1875 } | 1971 } |
1876 | 1972 |
1877 intptr_t Class::FindClosureIndex(intptr_t token_pos) const { | 1973 intptr_t Class::FindClosureIndex(const Function& needle) const { |
1878 if (closures() == GrowableObjectArray::null()) { | 1974 if (closures() == GrowableObjectArray::null()) { |
1879 return -1; | 1975 return -1; |
1880 } | 1976 } |
1881 Isolate* isolate = Isolate::Current(); | 1977 Isolate* isolate = Isolate::Current(); |
1882 ReusableHandleScope reused_handles(isolate); | 1978 ReusableHandleScope reused_handles(isolate); |
1883 const GrowableObjectArray& closures_array = | 1979 const GrowableObjectArray& closures_array = |
1884 GrowableObjectArray::Handle(isolate, closures()); | 1980 GrowableObjectArray::Handle(isolate, closures()); |
1885 Function& closure = reused_handles.FunctionHandle(); | 1981 Function& closure = reused_handles.FunctionHandle(); |
1886 intptr_t num_closures = closures_array.Length(); | 1982 intptr_t num_closures = closures_array.Length(); |
1887 intptr_t best_fit_token_pos = -1; | |
1888 intptr_t best_fit_index = -1; | |
1889 for (intptr_t i = 0; i < num_closures; i++) { | 1983 for (intptr_t i = 0; i < num_closures; i++) { |
1890 closure ^= closures_array.At(i); | 1984 closure ^= closures_array.At(i); |
1891 ASSERT(!closure.IsNull()); | 1985 ASSERT(!closure.IsNull()); |
1892 if ((closure.token_pos() <= token_pos) && | 1986 if (closure.raw() == needle.raw()) { |
1893 (token_pos <= closure.end_token_pos()) && | 1987 return i; |
1894 (best_fit_token_pos < closure.token_pos())) { | |
1895 best_fit_index = i; | |
1896 best_fit_token_pos = closure.token_pos(); | |
1897 } | 1988 } |
1898 } | 1989 } |
1899 return best_fit_index; | 1990 return -1; |
1900 } | 1991 } |
1901 | 1992 |
1902 | 1993 |
| 1994 RawFunction* Class::ClosureFunctionFromIndex(intptr_t idx) const { |
| 1995 const GrowableObjectArray& closures_array = |
| 1996 GrowableObjectArray::Handle(closures()); |
| 1997 if ((idx < 0) || (idx >= closures_array.Length())) { |
| 1998 return Function::null(); |
| 1999 } |
| 2000 Function& func = Function::Handle(); |
| 2001 func ^= closures_array.At(idx); |
| 2002 ASSERT(!func.IsNull()); |
| 2003 return func.raw(); |
| 2004 } |
| 2005 |
| 2006 |
1903 void Class::set_signature_function(const Function& value) const { | 2007 void Class::set_signature_function(const Function& value) const { |
1904 ASSERT(value.IsClosureFunction() || value.IsSignatureFunction()); | 2008 ASSERT(value.IsClosureFunction() || value.IsSignatureFunction()); |
1905 StorePointer(&raw_ptr()->signature_function_, value.raw()); | 2009 StorePointer(&raw_ptr()->signature_function_, value.raw()); |
1906 } | 2010 } |
1907 | 2011 |
1908 | 2012 |
1909 void Class::set_state_bits(intptr_t bits) const { | 2013 void Class::set_state_bits(intptr_t bits) const { |
1910 raw_ptr()->state_bits_ = static_cast<uint16_t>(bits); | 2014 raw_ptr()->state_bits_ = static_cast<uint16_t>(bits); |
1911 } | 2015 } |
1912 | 2016 |
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2470 field_name ^= field.name(); | 2574 field_name ^= field.name(); |
2471 if (field_name.Equals(needle_name)) { | 2575 if (field_name.Equals(needle_name)) { |
2472 return i; | 2576 return i; |
2473 } | 2577 } |
2474 } | 2578 } |
2475 // No field found. | 2579 // No field found. |
2476 return -1; | 2580 return -1; |
2477 } | 2581 } |
2478 | 2582 |
2479 | 2583 |
| 2584 RawField* Class::FieldFromIndex(intptr_t idx) const { |
| 2585 const Array& flds = Array::Handle(fields()); |
| 2586 if ((idx < 0) || (idx >= flds.Length())) { |
| 2587 return Field::null(); |
| 2588 } |
| 2589 Field& field = Field::Handle(); |
| 2590 field ^= flds.At(idx); |
| 2591 ASSERT(!field.IsNull()); |
| 2592 return field.raw(); |
| 2593 } |
| 2594 |
| 2595 |
2480 template <class FakeInstance> | 2596 template <class FakeInstance> |
2481 RawClass* Class::New(intptr_t index) { | 2597 RawClass* Class::New(intptr_t index) { |
2482 ASSERT(Object::class_class() != Class::null()); | 2598 ASSERT(Object::class_class() != Class::null()); |
2483 Class& result = Class::Handle(); | 2599 Class& result = Class::Handle(); |
2484 { | 2600 { |
2485 RawObject* raw = Object::Allocate(Class::kClassId, | 2601 RawObject* raw = Object::Allocate(Class::kClassId, |
2486 Class::InstanceSize(), | 2602 Class::InstanceSize(), |
2487 Heap::kOld); | 2603 Heap::kOld); |
2488 NoGCScope no_gc; | 2604 NoGCScope no_gc; |
2489 result ^= raw; | 2605 result ^= raw; |
(...skipping 1954 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4444 | 4560 |
4445 | 4561 |
4446 RawType* Function::RedirectionType() const { | 4562 RawType* Function::RedirectionType() const { |
4447 ASSERT(IsRedirectingFactory()); | 4563 ASSERT(IsRedirectingFactory()); |
4448 const Object& obj = Object::Handle(raw_ptr()->data_); | 4564 const Object& obj = Object::Handle(raw_ptr()->data_); |
4449 ASSERT(!obj.IsNull()); | 4565 ASSERT(!obj.IsNull()); |
4450 return RedirectionData::Cast(obj).type(); | 4566 return RedirectionData::Cast(obj).type(); |
4451 } | 4567 } |
4452 | 4568 |
4453 | 4569 |
| 4570 const char* Function::KindToCString(RawFunction::Kind kind) { |
| 4571 switch (kind) { |
| 4572 case RawFunction::kRegularFunction: |
| 4573 return "kRegularFunction"; |
| 4574 break; |
| 4575 case RawFunction::kClosureFunction: |
| 4576 return "kClosureFunction"; |
| 4577 break; |
| 4578 case RawFunction::kSignatureFunction: |
| 4579 return "kSignatureFunction"; |
| 4580 break; |
| 4581 case RawFunction::kGetterFunction: |
| 4582 return "kGetterFunction"; |
| 4583 break; |
| 4584 case RawFunction::kSetterFunction: |
| 4585 return "kSetterFunction"; |
| 4586 break; |
| 4587 case RawFunction::kConstructor: |
| 4588 return "kConstructor"; |
| 4589 break; |
| 4590 case RawFunction::kImplicitGetter: |
| 4591 return "kImplicitGetter"; |
| 4592 break; |
| 4593 case RawFunction::kImplicitSetter: |
| 4594 return "kImplicitSetter"; |
| 4595 break; |
| 4596 case RawFunction::kImplicitStaticFinalGetter: |
| 4597 return "kImplicitStaticFinalGetter"; |
| 4598 break; |
| 4599 case RawFunction::kStaticInitializer: |
| 4600 return "kStaticInitializer"; |
| 4601 break; |
| 4602 case RawFunction::kMethodExtractor: |
| 4603 return "kMethodExtractor"; |
| 4604 break; |
| 4605 case RawFunction::kNoSuchMethodDispatcher: |
| 4606 return "kNoSuchMethodDispatcher"; |
| 4607 break; |
| 4608 case RawFunction::kInvokeFieldDispatcher: |
| 4609 return "kInvokeFieldDispatcher"; |
| 4610 break; |
| 4611 default: |
| 4612 UNREACHABLE(); |
| 4613 return NULL; |
| 4614 } |
| 4615 } |
| 4616 |
| 4617 |
4454 void Function::SetRedirectionType(const Type& type) const { | 4618 void Function::SetRedirectionType(const Type& type) const { |
4455 ASSERT(IsFactory()); | 4619 ASSERT(IsFactory()); |
4456 Object& obj = Object::Handle(raw_ptr()->data_); | 4620 Object& obj = Object::Handle(raw_ptr()->data_); |
4457 if (obj.IsNull()) { | 4621 if (obj.IsNull()) { |
4458 obj = RedirectionData::New(); | 4622 obj = RedirectionData::New(); |
4459 set_data(obj); | 4623 set_data(obj); |
4460 } | 4624 } |
4461 RedirectionData::Cast(obj).set_type(type); | 4625 RedirectionData::Cast(obj).set_type(type); |
4462 } | 4626 } |
4463 | 4627 |
(...skipping 1240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5704 static_str, abstract_str, kind_str, const_str); | 5868 static_str, abstract_str, kind_str, const_str); |
5705 return chars; | 5869 return chars; |
5706 } | 5870 } |
5707 | 5871 |
5708 | 5872 |
5709 void Function::PrintToJSONStream(JSONStream* stream, bool ref) const { | 5873 void Function::PrintToJSONStream(JSONStream* stream, bool ref) const { |
5710 const char* internal_function_name = String::Handle(name()).ToCString(); | 5874 const char* internal_function_name = String::Handle(name()).ToCString(); |
5711 const char* function_name = | 5875 const char* function_name = |
5712 String::Handle(QualifiedUserVisibleName()).ToCString(); | 5876 String::Handle(QualifiedUserVisibleName()).ToCString(); |
5713 Class& cls = Class::Handle(Owner()); | 5877 Class& cls = Class::Handle(Owner()); |
| 5878 ASSERT(!cls.IsNull()); |
5714 Error& err = Error::Handle(); | 5879 Error& err = Error::Handle(); |
5715 err ^= cls.EnsureIsFinalized(Isolate::Current()); | 5880 err ^= cls.EnsureIsFinalized(Isolate::Current()); |
5716 ASSERT(err.IsNull()); | 5881 ASSERT(err.IsNull()); |
5717 const Function& func = *this; | 5882 intptr_t id = -1; |
5718 intptr_t id; | 5883 const char* selector = NULL; |
5719 if (IsNonImplicitClosureFunction()) { | 5884 if (IsNonImplicitClosureFunction()) { |
5720 id = cls.FindClosureIndex(token_pos()); | 5885 id = cls.FindClosureIndex(*this); |
| 5886 selector = "closures"; |
| 5887 } else if (IsImplicitClosureFunction()) { |
| 5888 id = cls.FindImplicitClosureFunctionIndex(*this); |
| 5889 selector = "implicit_closures"; |
| 5890 } else if (IsNoSuchMethodDispatcher() || IsInvokeFieldDispatcher()) { |
| 5891 id = cls.FindInvocationDispatcherFunctionIndex(*this); |
| 5892 selector = "dispatchers"; |
5721 } else { | 5893 } else { |
5722 id = cls.FindFunctionIndex(func); | 5894 id = cls.FindFunctionIndex(*this); |
| 5895 selector = "functions"; |
5723 } | 5896 } |
5724 ASSERT(id >= 0); | 5897 ASSERT(id >= 0); |
5725 intptr_t cid = cls.id(); | 5898 intptr_t cid = cls.id(); |
5726 JSONObject jsobj(stream); | 5899 JSONObject jsobj(stream); |
5727 jsobj.AddProperty("type", JSONType(ref)); | 5900 jsobj.AddProperty("type", JSONType(ref)); |
5728 if (IsNonImplicitClosureFunction()) { | 5901 jsobj.AddPropertyF("id", "classes/%" Pd "/%s/%" Pd "", cid, selector, id); |
5729 jsobj.AddPropertyF("id", "classes/%" Pd "/closures/%" Pd "", cid, id); | |
5730 } else { | |
5731 jsobj.AddPropertyF("id", "classes/%" Pd "/functions/%" Pd "", cid, id); | |
5732 } | |
5733 jsobj.AddProperty("name", internal_function_name); | 5902 jsobj.AddProperty("name", internal_function_name); |
5734 jsobj.AddProperty("user_name", function_name); | 5903 jsobj.AddProperty("user_name", function_name); |
5735 if (ref) return; | 5904 if (ref) return; |
5736 jsobj.AddProperty("is_static", is_static()); | 5905 jsobj.AddProperty("is_static", is_static()); |
5737 jsobj.AddProperty("is_const", is_const()); | 5906 jsobj.AddProperty("is_const", is_const()); |
5738 jsobj.AddProperty("is_optimizable", is_optimizable()); | 5907 jsobj.AddProperty("is_optimizable", is_optimizable()); |
5739 jsobj.AddProperty("is_inlinable", IsInlineable()); | 5908 jsobj.AddProperty("is_inlinable", IsInlineable()); |
5740 const char* kind_string = NULL; | 5909 const char* kind_string = Function::KindToCString(kind()); |
5741 switch (kind()) { | |
5742 case RawFunction::kRegularFunction: | |
5743 kind_string = "regular"; | |
5744 break; | |
5745 case RawFunction::kGetterFunction: | |
5746 kind_string = "getter"; | |
5747 break; | |
5748 case RawFunction::kSetterFunction: | |
5749 kind_string = "setter"; | |
5750 break; | |
5751 case RawFunction::kImplicitGetter: | |
5752 kind_string = "implicit getter"; | |
5753 break; | |
5754 case RawFunction::kImplicitSetter: | |
5755 kind_string = "implicit setter"; | |
5756 break; | |
5757 case RawFunction::kMethodExtractor: | |
5758 kind_string = "method extractor"; | |
5759 break; | |
5760 case RawFunction::kNoSuchMethodDispatcher: | |
5761 kind_string = "no such method"; | |
5762 break; | |
5763 case RawFunction::kClosureFunction: | |
5764 kind_string = "closure"; | |
5765 break; | |
5766 case RawFunction::kConstructor: | |
5767 kind_string = "constructor"; | |
5768 break; | |
5769 case RawFunction::kStaticInitializer: | |
5770 kind_string = "static initializer"; | |
5771 break; | |
5772 case RawFunction::kImplicitStaticFinalGetter: | |
5773 kind_string = "static final getter"; | |
5774 break; | |
5775 default: | |
5776 UNREACHABLE(); | |
5777 } | |
5778 jsobj.AddProperty("kind", kind_string); | 5910 jsobj.AddProperty("kind", kind_string); |
5779 jsobj.AddProperty("unoptimized_code", Object::Handle(unoptimized_code())); | 5911 jsobj.AddProperty("unoptimized_code", Object::Handle(unoptimized_code())); |
5780 jsobj.AddProperty("usage_counter", usage_counter()); | 5912 jsobj.AddProperty("usage_counter", usage_counter()); |
5781 jsobj.AddProperty("optimized_call_site_count", optimized_call_site_count()); | 5913 jsobj.AddProperty("optimized_call_site_count", optimized_call_site_count()); |
5782 jsobj.AddProperty("code", Object::Handle(CurrentCode())); | 5914 jsobj.AddProperty("code", Object::Handle(CurrentCode())); |
5783 jsobj.AddProperty("deoptimizations", | 5915 jsobj.AddProperty("deoptimizations", |
5784 static_cast<intptr_t>(deoptimization_counter())); | 5916 static_cast<intptr_t>(deoptimization_counter())); |
5785 } | 5917 } |
5786 | 5918 |
5787 | 5919 |
(...skipping 3896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9684 const intptr_t i = BinarySearchInSCallTable(pc); | 9816 const intptr_t i = BinarySearchInSCallTable(pc); |
9685 ASSERT(i >= 0); | 9817 ASSERT(i >= 0); |
9686 const Array& array = | 9818 const Array& array = |
9687 Array::Handle(raw_ptr()->static_calls_target_table_); | 9819 Array::Handle(raw_ptr()->static_calls_target_table_); |
9688 ASSERT(code.IsNull() || | 9820 ASSERT(code.IsNull() || |
9689 (code.function() == array.At(i + kSCallTableFunctionEntry))); | 9821 (code.function() == array.At(i + kSCallTableFunctionEntry))); |
9690 array.SetAt(i + kSCallTableCodeEntry, code); | 9822 array.SetAt(i + kSCallTableCodeEntry, code); |
9691 } | 9823 } |
9692 | 9824 |
9693 | 9825 |
9694 void Code::Disassemble() const { | 9826 void Code::Disassemble(DisassemblyFormatter* formatter) const { |
| 9827 const bool fix_patch = CodePatcher::CodeIsPatchable(*this) && |
| 9828 CodePatcher::IsEntryPatched(*this); |
| 9829 if (fix_patch) { |
| 9830 // The disassembler may choke on illegal instructions if the code has been |
| 9831 // patched, un-patch the code before disassembling and re-patch after. |
| 9832 CodePatcher::RestoreEntry(*this); |
| 9833 } |
9695 const Instructions& instr = Instructions::Handle(instructions()); | 9834 const Instructions& instr = Instructions::Handle(instructions()); |
9696 uword start = instr.EntryPoint(); | 9835 uword start = instr.EntryPoint(); |
9697 Disassembler::Disassemble(start, start + instr.size(), comments()); | 9836 if (formatter == NULL) { |
| 9837 Disassembler::Disassemble(start, start + instr.size(), comments()); |
| 9838 } else { |
| 9839 Disassembler::Disassemble(start, start + instr.size(), formatter, |
| 9840 comments()); |
| 9841 } |
| 9842 if (fix_patch) { |
| 9843 // Redo the patch. |
| 9844 CodePatcher::PatchEntry(*this); |
| 9845 } |
9698 } | 9846 } |
9699 | 9847 |
9700 | 9848 |
9701 const Code::Comments& Code::comments() const { | 9849 const Code::Comments& Code::comments() const { |
9702 Comments* comments = new Code::Comments(Array::Handle(raw_ptr()->comments_)); | 9850 Comments* comments = new Code::Comments(Array::Handle(raw_ptr()->comments_)); |
9703 return *comments; | 9851 return *comments; |
9704 } | 9852 } |
9705 | 9853 |
9706 | 9854 |
9707 void Code::set_comments(const Code::Comments& comments) const { | 9855 void Code::set_comments(const Code::Comments& comments) const { |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9869 const char* Code::ToCString() const { | 10017 const char* Code::ToCString() const { |
9870 const char* kFormat = "Code entry:%p"; | 10018 const char* kFormat = "Code entry:%p"; |
9871 intptr_t len = OS::SNPrint(NULL, 0, kFormat, EntryPoint()) + 1; | 10019 intptr_t len = OS::SNPrint(NULL, 0, kFormat, EntryPoint()) + 1; |
9872 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 10020 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
9873 OS::SNPrint(chars, len, kFormat, EntryPoint()); | 10021 OS::SNPrint(chars, len, kFormat, EntryPoint()); |
9874 return chars; | 10022 return chars; |
9875 } | 10023 } |
9876 | 10024 |
9877 | 10025 |
9878 void Code::PrintToJSONStream(JSONStream* stream, bool ref) const { | 10026 void Code::PrintToJSONStream(JSONStream* stream, bool ref) const { |
9879 Isolate* isolate = Isolate::Current(); | |
9880 ObjectIdRing* ring = isolate->object_id_ring(); | |
9881 intptr_t id = ring->GetIdForObject(raw()); | |
9882 JSONObject jsobj(stream); | 10027 JSONObject jsobj(stream); |
9883 jsobj.AddProperty("type", JSONType(ref)); | 10028 jsobj.AddProperty("type", JSONType(ref)); |
9884 jsobj.AddPropertyF("id", "objects/%" Pd "", id); | 10029 jsobj.AddPropertyF("id", "code/%" Px "", EntryPoint()); |
| 10030 jsobj.AddPropertyF("start", "%" Px "", EntryPoint()); |
| 10031 jsobj.AddPropertyF("end", "%" Px "", EntryPoint() + Size()); |
9885 Function& func = Function::Handle(); | 10032 Function& func = Function::Handle(); |
| 10033 func ^= function(); |
| 10034 ASSERT(!func.IsNull()); |
9886 String& name = String::Handle(); | 10035 String& name = String::Handle(); |
9887 func ^= function(); | |
9888 ASSERT(!func.IsNull()); | 10036 ASSERT(!func.IsNull()); |
9889 name ^= func.name(); | 10037 name ^= func.name(); |
9890 const char* internal_function_name = name.ToCString(); | 10038 const char* internal_function_name = name.ToCString(); |
9891 jsobj.AddPropertyF("name", "%s%s", is_optimized() ? "*" : "", | 10039 jsobj.AddPropertyF("name", "%s%s", is_optimized() ? "*" : "", |
9892 internal_function_name); | 10040 internal_function_name); |
9893 name ^= func.QualifiedUserVisibleName(); | 10041 name ^= func.QualifiedUserVisibleName(); |
9894 const char* function_name = name.ToCString(); | 10042 const char* function_name = name.ToCString(); |
9895 jsobj.AddPropertyF("user_name", "%s%s", is_optimized() ? "*" : "", | 10043 jsobj.AddPropertyF("user_name", "%s%s", is_optimized() ? "*" : "", |
9896 function_name); | 10044 function_name); |
9897 if (ref) { | 10045 if (ref) { |
9898 return; | 10046 return; |
9899 } | 10047 } |
9900 jsobj.AddProperty("is_optimized", is_optimized()); | 10048 jsobj.AddProperty("is_optimized", is_optimized()); |
9901 jsobj.AddProperty("is_alive", is_alive()); | 10049 jsobj.AddProperty("is_alive", is_alive()); |
9902 jsobj.AddProperty("function", Object::Handle(function())); | 10050 jsobj.AddProperty("function", Object::Handle(function())); |
9903 JSONArray jsarr(&jsobj, "disassembly"); | 10051 JSONArray jsarr(&jsobj, "disassembly"); |
9904 DisassembleToJSONStream formatter(jsarr); | 10052 DisassembleToJSONStream formatter(jsarr); |
9905 const Instructions& instr = Instructions::Handle(instructions()); | 10053 Disassemble(&formatter); |
9906 uword start = instr.EntryPoint(); | |
9907 Disassembler::Disassemble(start, start + instr.size(), &formatter, | |
9908 comments()); | |
9909 } | 10054 } |
9910 | 10055 |
9911 | 10056 |
9912 uword Code::GetPatchCodePc() const { | 10057 uword Code::GetPatchCodePc() const { |
9913 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); | 10058 const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); |
9914 return descriptors.GetPcForKind(PcDescriptors::kPatchCode); | 10059 return descriptors.GetPcForKind(PcDescriptors::kPatchCode); |
9915 } | 10060 } |
9916 | 10061 |
9917 | 10062 |
9918 uword Code::GetLazyDeoptPc() const { | 10063 uword Code::GetLazyDeoptPc() const { |
(...skipping 6863 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16782 return "_MirrorReference"; | 16927 return "_MirrorReference"; |
16783 } | 16928 } |
16784 | 16929 |
16785 | 16930 |
16786 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { | 16931 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { |
16787 Instance::PrintToJSONStream(stream, ref); | 16932 Instance::PrintToJSONStream(stream, ref); |
16788 } | 16933 } |
16789 | 16934 |
16790 | 16935 |
16791 } // namespace dart | 16936 } // namespace dart |
OLD | NEW |