Add MacroAssemblerPrinter support for printing memory.
authormark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 29 Aug 2015 00:10:07 +0000 (00:10 +0000)
committermark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 29 Aug 2015 00:10:07 +0000 (00:10 +0000)
https://bugs.webkit.org/show_bug.cgi?id=148600

Reviewed by Saam Barati.

Previously, we can dump registers at runtime.  Now we can dump memory too.
See comment in MacroAssemblerPrinter.h for examples of how to do this.

* assembler/MacroAssemblerPrinter.cpp:
(JSC::printMemory):
(JSC::MacroAssemblerPrinter::printCallback):
* assembler/MacroAssemblerPrinter.h:
(JSC::Memory::Memory):
(JSC::MemWord::MemWord):
(JSC::MacroAssemblerPrinter::PrintArg::PrintArg):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@189134 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/assembler/MacroAssemblerPrinter.cpp
Source/JavaScriptCore/assembler/MacroAssemblerPrinter.h

index 8f49ae2..bb11657 100644 (file)
@@ -1,3 +1,21 @@
+2015-08-28  Mark Lam  <mark.lam@apple.com>
+
+        Add MacroAssemblerPrinter support for printing memory.
+        https://bugs.webkit.org/show_bug.cgi?id=148600
+
+        Reviewed by Saam Barati.
+
+        Previously, we can dump registers at runtime.  Now we can dump memory too.
+        See comment in MacroAssemblerPrinter.h for examples of how to do this.
+
+        * assembler/MacroAssemblerPrinter.cpp:
+        (JSC::printMemory):
+        (JSC::MacroAssemblerPrinter::printCallback):
+        * assembler/MacroAssemblerPrinter.h:
+        (JSC::Memory::Memory):
+        (JSC::MemWord::MemWord):
+        (JSC::MacroAssemblerPrinter::PrintArg::PrintArg):
+
 2015-08-28  Khem Raj  <raj.khem@gmail.com>
 
         JavaScriptCore fails to build using GCC 5
index 18c28b8..4d1256e 100644 (file)
@@ -46,6 +46,7 @@ void printCPURegisters(CPUState&, int indentation = 0);
 // print stream. Hence, no indentation will be applied.
 void printRegister(CPUState&, RegisterID);
 void printRegister(CPUState&, FPRegisterID);
+void printMemory(CPUState&, const Memory&);
     
 static void printIndent(int indentation)
 {
@@ -110,6 +111,62 @@ void printRegister(CPUState& cpu, FPRegisterID regID)
     dataLogF("%s:<0x%016llx %.13g>", name, u.uint64Value, u.doubleValue);
 }
 
+void printMemory(CPUState& cpu, const Memory& memory)
+{
+    uint8_t* ptr = nullptr;
+    switch (memory.addressType) {
+    case Memory::AddressType::Address: {
+        ptr = reinterpret_cast<uint8_t*>(cpu.registerValue(memory.u.address.base));
+        ptr += memory.u.address.offset;
+        break;
+    }
+    case Memory::AddressType::AbsoluteAddress: {
+        ptr = reinterpret_cast<uint8_t*>(const_cast<void*>(memory.u.absoluteAddress.m_ptr));
+        break;
+    }
+    }
+
+    if (memory.dumpStyle == Memory::SingleWordDump) {
+        if (memory.numBytes == sizeof(int8_t)) {
+            auto p = reinterpret_cast<int8_t*>(ptr);
+            dataLogF("%p:<0x%02x %d>", p, *p, *p);
+            return;
+        }
+        if (memory.numBytes == sizeof(int16_t)) {
+            auto p = reinterpret_cast<int16_t*>(ptr);
+            dataLogF("%p:<0x%04x %d>", p, *p, *p);
+            return;
+        }
+        if (memory.numBytes == sizeof(int32_t)) {
+            auto p = reinterpret_cast<int32_t*>(ptr);
+            dataLogF("%p:<0x%08x %d>", p, *p, *p);
+            return;
+        }
+        if (memory.numBytes == sizeof(int64_t)) {
+            auto p = reinterpret_cast<int64_t*>(ptr);
+            dataLogF("%p:<0x%016llx %lld>", p, *p, *p);
+            return;
+        }
+        // Else, unknown word size. Fall thru and dump in the generic way.
+    }
+
+    // Generic dump: dump rows of 16 bytes in 4 byte groupings.
+    size_t numBytes = memory.numBytes;
+    for (size_t i = 0; i < numBytes; i++) {
+        if (!(i % 16))
+            dataLogF("%p: ", &ptr[i]);
+        else if (!(i % 4))
+            dataLog(" ");
+
+        dataLogF("%02x", ptr[i]);
+
+        if (i % 16 == 15)
+            dataLog("\n");
+    }
+    if (numBytes % 16 < 15)
+        dataLog("\n");
+}
+
 void MacroAssemblerPrinter::printCallback(ProbeContext* context)
 {
     typedef PrintArg Arg;
@@ -127,6 +184,9 @@ void MacroAssemblerPrinter::printCallback(ProbeContext* context)
         case Arg::Type::FPRegisterID:
             printRegister(context->cpu, arg.u.fpRegisterID);
             break;
+        case Arg::Type::Memory:
+            printMemory(context->cpu, arg.u.memory);
+            break;
         case Arg::Type::ConstCharPtr:
             dataLog(arg.u.constCharPtr);
             break;
index 7750cad..2a0ee00 100644 (file)
@@ -67,6 +67,15 @@ namespace JSC {
 //      //      }
 //      jit.print(AllRegisters());
 //
+//      jit.print(MemWord<uint8_t>(regID), "\n");   // Emits code to print a byte pointed to by the register.
+//      jit.print(MemWord<uint32_t>(regID), "\n");  // Emits code to print a 32-bit word pointed to by the register.
+//
+//      jit.print(MemWord<uint8_t>(Address(regID, 23), "\n");     // Emits code to print a byte at the address.
+//      jit.print(MemWord<intptr_t>(AbsoluteAddress(&cb), "\n");  // Emits code to print an intptr_t sized word at the address.
+//
+//      jit.print(Memory(reg, 100), "\n");              // Emits code to print a 100 bytes at the address pointed by the register.
+//      jit.print(Memory(Address(reg, 4), 100), "\n");  // Emits code to print a 100 bytes at the address.
+//
 //      // Print multiple things at once. This incurs the probe overhead only once
 //      // to print all the items.
 //      jit.print("cb:", cb, " regID:", regID, " cpu:\n", AllRegisters());
@@ -81,6 +90,72 @@ namespace JSC {
 // See MacroAssemblerPrinter::print() below for details.
 struct AllRegisters { };
 
+struct Memory {
+    using Address = MacroAssembler::Address;
+    using AbsoluteAddress = MacroAssembler::AbsoluteAddress;
+    using RegisterID = MacroAssembler::RegisterID;
+
+    enum class AddressType {
+        Address,
+        AbsoluteAddress,
+    };
+
+    enum DumpStyle {
+        SingleWordDump,
+        GenericDump,
+    };
+
+    Memory(RegisterID& reg, size_t bytes, DumpStyle style = GenericDump)
+        : addressType(AddressType::Address)
+        , dumpStyle(style)
+        , numBytes(bytes)
+    {
+        u.address = Address(reg, 0);
+    }
+
+    Memory(const Address& address, size_t bytes, DumpStyle style = GenericDump)
+        : addressType(AddressType::Address)
+        , dumpStyle(style)
+        , numBytes(bytes)
+    {
+        u.address = address;
+    }
+
+    Memory(const AbsoluteAddress& address, size_t bytes, DumpStyle style = GenericDump)
+        : addressType(AddressType::AbsoluteAddress)
+        , dumpStyle(style)
+        , numBytes(bytes)
+    {
+        u.absoluteAddress = address;
+    }
+
+    AddressType addressType;
+    DumpStyle dumpStyle;
+    size_t numBytes;
+    union UnionedAddress {
+        UnionedAddress() { }
+
+        Address address;
+        AbsoluteAddress absoluteAddress;
+    } u;
+};
+
+template <typename IntType>
+struct MemWord : public Memory {
+    MemWord(RegisterID& reg)
+        : Memory(reg, sizeof(IntType), Memory::SingleWordDump)
+    { }
+
+    MemWord(const Address& address)
+        : Memory(address, sizeof(IntType), Memory::SingleWordDump)
+    { }
+
+    MemWord(const AbsoluteAddress& address)
+        : Memory(address, sizeof(IntType), Memory::SingleWordDump)
+    { }
+};
+
+
 class MacroAssemblerPrinter {
     using CPUState = MacroAssembler::CPUState;
     using ProbeContext = MacroAssembler::ProbeContext;
@@ -103,6 +178,7 @@ private:
             AllRegisters,
             RegisterID,
             FPRegisterID,
+            Memory,
             ConstCharPtr,
             ConstVoidPtr,
             IntptrValue,
@@ -125,7 +201,13 @@ private:
         {
             u.fpRegisterID = regID;
         }
-        
+
+        PrintArg(const Memory& memory)
+            : type(Type::Memory)
+        {
+            u.memory = memory;
+        }
+
         PrintArg(const char* ptr)
             : type(Type::ConstCharPtr)
         {
@@ -163,9 +245,12 @@ private:
         }
         
         Type type;
-        union {
+        union Value {
+            Value() { }
+
             RegisterID gpRegisterID;
             FPRegisterID fpRegisterID;
+            Memory memory;
             const char* constCharPtr;
             const void* constVoidPtr;
             intptr_t intptrValue;