| 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_IA32) | 8 #if defined(TARGET_ARCH_IA32) |
| 9 #include "platform/utils.h" | 9 #include "platform/utils.h" |
| 10 #include "vm/allocation.h" | 10 #include "vm/allocation.h" |
| (...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 void X86Decoder::PrintXmmComparison(int comparison) { | 458 void X86Decoder::PrintXmmComparison(int comparison) { |
| 459 ASSERT(0 <= comparison); | 459 ASSERT(0 <= comparison); |
| 460 ASSERT(comparison < 8); | 460 ASSERT(comparison < 8); |
| 461 static const char* comparisons[8] = { | 461 static const char* comparisons[8] = { |
| 462 "eq", "lt", "le", "unordered", "not eq", "not lt", "not le", "ordered" | 462 "eq", "lt", "le", "unordered", "not eq", "not lt", "not le", "ordered" |
| 463 }; | 463 }; |
| 464 Print(comparisons[comparison]); | 464 Print(comparisons[comparison]); |
| 465 } | 465 } |
| 466 | 466 |
| 467 | 467 |
| 468 static const char* ObjectToCStringNoGC(const Object& obj) { | |
| 469 if (obj.IsSmi() || | |
| 470 obj.IsMint() || | |
| 471 obj.IsDouble() || | |
| 472 obj.IsString() || | |
| 473 obj.IsNull() || | |
| 474 obj.IsBool() || | |
| 475 obj.IsClass() || | |
| 476 obj.IsFunction() || | |
| 477 obj.IsICData() || | |
| 478 obj.IsField() || | |
| 479 obj.IsCode()) { | |
| 480 return obj.ToCString(); | |
| 481 } | |
| 482 | |
| 483 const Class& clazz = Class::Handle(obj.clazz()); | |
| 484 const char* full_class_name = clazz.ToCString(); | |
| 485 return OS::SCreate(Thread::Current()->zone(), | |
| 486 "instance of %s", full_class_name); | |
| 487 } | |
| 488 | |
| 489 | |
| 490 void X86Decoder::PrintAddress(uword addr) { | 468 void X86Decoder::PrintAddress(uword addr) { |
| 491 char addr_buffer[32]; | 469 char addr_buffer[32]; |
| 492 OS::SNPrint(addr_buffer, sizeof(addr_buffer), "%#" Px "", addr); | 470 OS::SNPrint(addr_buffer, sizeof(addr_buffer), "%#" Px "", addr); |
| 493 Print(addr_buffer); | 471 Print(addr_buffer); |
| 494 // Try to print as heap object or stub name | 472 |
| 495 if (((addr & kSmiTagMask) == kHeapObjectTag) && | 473 // Try to print as stub name. |
| 496 reinterpret_cast<RawObject*>(addr)->IsWellFormed() && | 474 const char* name_of_stub = StubCode::NameOfStub(addr); |
| 497 reinterpret_cast<RawObject*>(addr)->IsOldObject() && | 475 if (name_of_stub != NULL) { |
| 498 !Isolate::Current()->heap()->CodeContains(addr) && | 476 Print(" [stub: "); |
| 499 !Dart::vm_isolate()->heap()->CodeContains(addr) && | 477 Print(name_of_stub); |
| 500 Disassembler::CanFindOldObject(addr)) { | 478 Print("]"); |
| 501 NoSafepointScope no_safepoint; | |
| 502 const Object& obj = Object::Handle(reinterpret_cast<RawObject*>(addr)); | |
| 503 if (obj.IsArray()) { | |
| 504 const Array& arr = Array::Cast(obj); | |
| 505 intptr_t len = arr.Length(); | |
| 506 if (len > 5) len = 5; // Print a max of 5 elements. | |
| 507 Print(" Array["); | |
| 508 int i = 0; | |
| 509 Object& element = Object::Handle(); | |
| 510 while (i < len) { | |
| 511 element = arr.At(i); | |
| 512 if (i > 0) Print(", "); | |
| 513 Print(ObjectToCStringNoGC(element)); | |
| 514 i++; | |
| 515 } | |
| 516 if (i < arr.Length()) Print(", ..."); | |
| 517 Print("]"); | |
| 518 return; | |
| 519 } | |
| 520 Print(" '"); | |
| 521 Print(ObjectToCStringNoGC(obj)); | |
| 522 Print("'"); | |
| 523 } else { | |
| 524 // 'addr' is not an object, but probably a code address. | |
| 525 const char* name_of_stub = StubCode::NameOfStub(addr); | |
| 526 if (name_of_stub != NULL) { | |
| 527 Print(" [stub: "); | |
| 528 Print(name_of_stub); | |
| 529 Print("]"); | |
| 530 } | |
| 531 } | 479 } |
| 532 } | 480 } |
| 533 | 481 |
| 534 | 482 |
| 535 int X86Decoder::PrintRightOperandHelper(uint8_t* modrmp, | 483 int X86Decoder::PrintRightOperandHelper(uint8_t* modrmp, |
| 536 RegisterNamePrinter register_printer) { | 484 RegisterNamePrinter register_printer) { |
| 537 int mod, regop, rm; | 485 int mod, regop, rm; |
| 538 GetModRm(*modrmp, &mod, ®op, &rm); | 486 GetModRm(*modrmp, &mod, ®op, &rm); |
| 539 switch (mod) { | 487 switch (mod) { |
| 540 case 0: | 488 case 0: |
| (...skipping 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1838 | 1786 |
| 1839 int instr_len = data - reinterpret_cast<uint8_t*>(pc); | 1787 int instr_len = data - reinterpret_cast<uint8_t*>(pc); |
| 1840 ASSERT(instr_len > 0); // Ensure progress. | 1788 ASSERT(instr_len > 0); // Ensure progress. |
| 1841 | 1789 |
| 1842 return instr_len; | 1790 return instr_len; |
| 1843 } // NOLINT | 1791 } // NOLINT |
| 1844 | 1792 |
| 1845 | 1793 |
| 1846 void Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size, | 1794 void Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size, |
| 1847 char* human_buffer, intptr_t human_size, | 1795 char* human_buffer, intptr_t human_size, |
| 1848 int* out_instr_len, uword pc) { | 1796 int* out_instr_len, const Code& code, |
| 1797 Object** object, uword pc) { |
| 1849 ASSERT(hex_size > 0); | 1798 ASSERT(hex_size > 0); |
| 1850 ASSERT(human_size > 0); | 1799 ASSERT(human_size > 0); |
| 1851 X86Decoder decoder(human_buffer, human_size); | 1800 X86Decoder decoder(human_buffer, human_size); |
| 1852 int instruction_length = decoder.InstructionDecode(pc); | 1801 int instruction_length = decoder.InstructionDecode(pc); |
| 1853 uint8_t* pc_ptr = reinterpret_cast<uint8_t*>(pc); | 1802 uint8_t* pc_ptr = reinterpret_cast<uint8_t*>(pc); |
| 1854 int hex_index = 0; | 1803 int hex_index = 0; |
| 1855 int remaining_size = hex_size - hex_index; | 1804 int remaining_size = hex_size - hex_index; |
| 1856 for (int i = 0; (i < instruction_length) && (remaining_size > 2); ++i) { | 1805 for (int i = 0; (i < instruction_length) && (remaining_size > 2); ++i) { |
| 1857 OS::SNPrint(&hex_buffer[hex_index], remaining_size, "%02x", pc_ptr[i]); | 1806 OS::SNPrint(&hex_buffer[hex_index], remaining_size, "%02x", pc_ptr[i]); |
| 1858 hex_index += 2; | 1807 hex_index += 2; |
| 1859 remaining_size -= 2; | 1808 remaining_size -= 2; |
| 1860 } | 1809 } |
| 1861 hex_buffer[hex_index] = '\0'; | 1810 hex_buffer[hex_index] = '\0'; |
| 1862 if (out_instr_len) { | 1811 if (out_instr_len) { |
| 1863 *out_instr_len = instruction_length; | 1812 *out_instr_len = instruction_length; |
| 1864 } | 1813 } |
| 1814 |
| 1815 *object = NULL; |
| 1816 if (!code.IsNull() && code.is_alive()) { |
| 1817 intptr_t offsets_length = code.pointer_offsets_length(); |
| 1818 for (intptr_t i = 0; i < offsets_length; i++) { |
| 1819 uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint(); |
| 1820 if ((pc <= addr) && (addr < (pc + instruction_length))) { |
| 1821 *object = &Object::Handle(*reinterpret_cast<RawObject**>(addr)); |
| 1822 break; |
| 1823 } |
| 1824 } |
| 1825 } |
| 1865 } | 1826 } |
| 1866 | 1827 |
| 1867 #endif // !PRODUCT | 1828 #endif // !PRODUCT |
| 1868 | 1829 |
| 1869 } // namespace dart | 1830 } // namespace dart |
| 1870 | 1831 |
| 1871 #endif // defined TARGET_ARCH_IA32 | 1832 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |