| 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/disassembler.h" | 5 #include "vm/disassembler.h" |
| 6 | 6 |
| 7 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. | 7 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 8 #if defined(TARGET_ARCH_X64) | 8 #if defined(TARGET_ARCH_X64) |
| 9 #include "platform/utils.h" | 9 #include "platform/utils.h" |
| 10 #include "vm/allocation.h" | 10 #include "vm/allocation.h" |
| 11 #include "vm/heap.h" | 11 #include "vm/heap.h" |
| 12 #include "vm/instructions.h" |
| 12 #include "vm/os.h" | 13 #include "vm/os.h" |
| 13 #include "vm/stack_frame.h" | 14 #include "vm/stack_frame.h" |
| 14 #include "vm/stub_code.h" | 15 #include "vm/stub_code.h" |
| 15 | 16 |
| 16 namespace dart { | 17 namespace dart { |
| 17 | 18 |
| 18 #ifndef PRODUCT | 19 #ifndef PRODUCT |
| 19 | 20 |
| 20 enum OperandType { | 21 enum OperandType { |
| 21 UNSET_OP_ORDER = 0, | 22 UNSET_OP_ORDER = 0, |
| (...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 778 break; | 779 break; |
| 779 } | 780 } |
| 780 default: | 781 default: |
| 781 UNREACHABLE(); | 782 UNREACHABLE(); |
| 782 break; | 783 break; |
| 783 } | 784 } |
| 784 return advance; | 785 return advance; |
| 785 } | 786 } |
| 786 | 787 |
| 787 | 788 |
| 788 static const char* ObjectToCStringNoGC(const Object& obj) { | |
| 789 if (obj.IsSmi() || | |
| 790 obj.IsMint() || | |
| 791 obj.IsDouble() || | |
| 792 obj.IsString() || | |
| 793 obj.IsNull() || | |
| 794 obj.IsBool() || | |
| 795 obj.IsClass() || | |
| 796 obj.IsFunction() || | |
| 797 obj.IsICData() || | |
| 798 obj.IsField() || | |
| 799 obj.IsCode()) { | |
| 800 return obj.ToCString(); | |
| 801 } | |
| 802 | |
| 803 const Class& clazz = Class::Handle(obj.clazz()); | |
| 804 const char* full_class_name = clazz.ToCString(); | |
| 805 return OS::SCreate(Thread::Current()->zone(), | |
| 806 "instance of %s", full_class_name); | |
| 807 } | |
| 808 | |
| 809 | |
| 810 void DisassemblerX64::PrintAddress(uint8_t* addr_byte_ptr) { | 789 void DisassemblerX64::PrintAddress(uint8_t* addr_byte_ptr) { |
| 811 uword addr = reinterpret_cast<uword>(addr_byte_ptr); | 790 uword addr = reinterpret_cast<uword>(addr_byte_ptr); |
| 812 Print("%#" Px "", addr); | 791 Print("%#" Px "", addr); |
| 813 // Try to print as heap object or stub name | |
| 814 if (((addr & kSmiTagMask) == kHeapObjectTag) && | |
| 815 reinterpret_cast<RawObject*>(addr)->IsWellFormed() && | |
| 816 reinterpret_cast<RawObject*>(addr)->IsOldObject() && | |
| 817 !Dart::vm_isolate()->heap()->CodeContains(addr) && | |
| 818 !Isolate::Current()->heap()->CodeContains(addr) && | |
| 819 Disassembler::CanFindOldObject(addr)) { | |
| 820 NoSafepointScope no_safepoint; | |
| 821 const Object& obj = Object::Handle(reinterpret_cast<RawObject*>(addr)); | |
| 822 if (obj.IsArray()) { | |
| 823 const Array& arr = Array::Cast(obj); | |
| 824 intptr_t len = arr.Length(); | |
| 825 if (len > 5) len = 5; // Print a max of 5 elements. | |
| 826 Print(" Array["); | |
| 827 int i = 0; | |
| 828 Object& element = Object::Handle(); | |
| 829 while (i < len) { | |
| 830 element = arr.At(i); | |
| 831 if (i > 0) Print(", "); | |
| 832 Print("%s", ObjectToCStringNoGC(element)); | |
| 833 i++; | |
| 834 } | |
| 835 if (i < arr.Length()) Print(", ..."); | |
| 836 Print("]"); | |
| 837 return; | |
| 838 } | |
| 839 Print(" '%s'", ObjectToCStringNoGC(obj)); | |
| 840 } else { | |
| 841 // 'addr' is not an object, but probably a code address. | |
| 842 const char* name_of_stub = StubCode::NameOfStub(addr); | |
| 843 if (name_of_stub != NULL) { | |
| 844 Print(" [stub: %s]", name_of_stub); | |
| 845 } | |
| 846 } | |
| 847 } | 792 } |
| 848 | 793 |
| 849 | 794 |
| 850 // Returns number of bytes used, including *data. | 795 // Returns number of bytes used, including *data. |
| 851 int DisassemblerX64::JumpShort(uint8_t* data) { | 796 int DisassemblerX64::JumpShort(uint8_t* data) { |
| 852 ASSERT(0xEB == *data); | 797 ASSERT(0xEB == *data); |
| 853 uint8_t b = *(data + 1); | 798 uint8_t b = *(data + 1); |
| 854 uint8_t* dest = data + static_cast<int8_t>(b) + 2; | 799 uint8_t* dest = data + static_cast<int8_t>(b) + 2; |
| 855 Print("jmp "); | 800 Print("jmp "); |
| 856 PrintAddress(dest); | 801 PrintAddress(dest); |
| (...skipping 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1928 | 1873 |
| 1929 int instr_len = data - reinterpret_cast<uint8_t*>(pc); | 1874 int instr_len = data - reinterpret_cast<uint8_t*>(pc); |
| 1930 ASSERT(instr_len > 0); // Ensure progress. | 1875 ASSERT(instr_len > 0); // Ensure progress. |
| 1931 | 1876 |
| 1932 return instr_len; | 1877 return instr_len; |
| 1933 } | 1878 } |
| 1934 | 1879 |
| 1935 | 1880 |
| 1936 void Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size, | 1881 void Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size, |
| 1937 char* human_buffer, intptr_t human_size, | 1882 char* human_buffer, intptr_t human_size, |
| 1938 int* out_instr_len, uword pc) { | 1883 int* out_instr_len, const Code& code, |
| 1884 Object** object, uword pc) { |
| 1939 ASSERT(hex_size > 0); | 1885 ASSERT(hex_size > 0); |
| 1940 ASSERT(human_size > 0); | 1886 ASSERT(human_size > 0); |
| 1941 DisassemblerX64 decoder(human_buffer, human_size); | 1887 DisassemblerX64 decoder(human_buffer, human_size); |
| 1942 int instruction_length = decoder.InstructionDecode(pc); | 1888 int instruction_length = decoder.InstructionDecode(pc); |
| 1943 uint8_t* pc_ptr = reinterpret_cast<uint8_t*>(pc); | 1889 uint8_t* pc_ptr = reinterpret_cast<uint8_t*>(pc); |
| 1944 int hex_index = 0; | 1890 int hex_index = 0; |
| 1945 int remaining_size = hex_size - hex_index; | 1891 int remaining_size = hex_size - hex_index; |
| 1946 for (int i = 0; (i < instruction_length) && (remaining_size > 2); ++i) { | 1892 for (int i = 0; (i < instruction_length) && (remaining_size > 2); ++i) { |
| 1947 OS::SNPrint(&hex_buffer[hex_index], remaining_size, "%02x", pc_ptr[i]); | 1893 OS::SNPrint(&hex_buffer[hex_index], remaining_size, "%02x", pc_ptr[i]); |
| 1948 hex_index += 2; | 1894 hex_index += 2; |
| 1949 remaining_size -= 2; | 1895 remaining_size -= 2; |
| 1950 } | 1896 } |
| 1951 hex_buffer[hex_index] = '\0'; | 1897 hex_buffer[hex_index] = '\0'; |
| 1952 if (out_instr_len) { | 1898 if (out_instr_len) { |
| 1953 *out_instr_len = instruction_length; | 1899 *out_instr_len = instruction_length; |
| 1954 } | 1900 } |
| 1901 |
| 1902 *object = NULL; |
| 1903 if (!code.IsNull()) { |
| 1904 *object = &Object::Handle(); |
| 1905 if (!DecodeLoadObjectFromPoolOrThread(pc, code, *object)) { |
| 1906 *object = NULL; |
| 1907 } |
| 1908 } |
| 1955 } | 1909 } |
| 1956 | 1910 |
| 1957 #endif // !PRODUCT | 1911 #endif // !PRODUCT |
| 1958 | 1912 |
| 1959 } // namespace dart | 1913 } // namespace dart |
| 1960 | 1914 |
| 1961 #endif // defined TARGET_ARCH_X64 | 1915 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |