Changeset 215642 in webkit


Ignore:
Timestamp:
Apr 21, 2017 2:42:24 PM (7 years ago)
Author:
mark.lam@apple.com
Message:

Refactor MASM probe to allow printing of custom types.
https://bugs.webkit.org/show_bug.cgi?id=171101

Reviewed by JF Bastien.

For example, this allows us to add MASM printing of CodeBlock* and Air::Args.

In general, MASM print can be used like dataLog, except that it generates JITted
code for doing the dataLogging later when the JITted code runs. MASM print can
print any value type that a specialized Printer template or a setPrinter()
function implemented for that type.

  • CMakeLists.txt:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • assembler/MacroAssembler.h:
  • assembler/MacroAssemblerPrinter.cpp:

(JSC::Printer::printAllRegisters):
(JSC::Printer::printPCRegister):
(JSC::Printer::printRegisterID):
(JSC::Printer::printFPRegisterID):
(JSC::Printer::printAddress):
(JSC::Printer::printMemory):
(JSC::Printer::printCallback):
(JSC::printIndent): Deleted.
(JSC::printCPU): Deleted.
(JSC::printCPURegisters): Deleted.
(JSC::printPC): Deleted.
(JSC::printRegister): Deleted.
(JSC::printMemory): Deleted.
(JSC::MacroAssemblerPrinter::printCallback): Deleted.

  • assembler/MacroAssemblerPrinter.h:

(JSC::AllRegisters::AllRegisters):
(JSC::Printer::Printer<AllRegisters>::Printer):
(JSC::Printer::Printer<PCRegister>::Printer):
(JSC::Printer::Printer<MacroAssembler::RegisterID>::Printer):
(JSC::Printer::Printer<MacroAssembler::FPRegisterID>::Printer):
(JSC::Printer::Printer<MacroAssembler::Address>::Printer):
(JSC::Printer::Printer<Memory>::Printer):
(JSC::Printer::Printer<MemWord<IntType>>::Printer):
(JSC::MacroAssembler::print):
(JSC::MacroAssemblerPrinter::print): Deleted.
(JSC::MacroAssemblerPrinter::PrintArg::PrintArg): Deleted.
(JSC::MacroAssemblerPrinter::appendPrintArg): Deleted.

  • Refactored to move the underlying PrintRecord (and associated data structures) out to Printer.cpp/h.
  • MacroAssemblerPrinter.cpp/h now only add custom Printers for MASM types like RegisterID and Memory. It also defines the implementation of MacroAssembler::print().

As before, JIT code that wishes to use MacroAssembler::print() needs to
#include "MacroAssemblerPrinter.h".

  • Also added the ability to specify an optional indentation (in number of chars) when MASM printing AllRegisters. This is useful because AllRegisters prints a block of data unlike other printers which print inline.
  • assembler/Printer.cpp: Added.

(JSC::Printer::printConstCharString):
(JSC::Printer::printIntptr):
(JSC::Printer::printUintptr):
(JSC::Printer::printPointer):
(JSC::Printer::setPrinter):

  • assembler/Printer.h: Added.

(JSC::Printer::Context::Context):
(JSC::Printer::PrintRecord::PrintRecord):
(JSC::Printer::appendPrinter):
(JSC::Printer::makePrintRecordList):
(JSC::Printer::Printer<RawPointer>::Printer):
(JSC::Printer::setPrinter):
(JSC::Printer::Printer::Printer):

  • Data structures for creating a list of PrintRecords. Classes which wish to add custom support for MASM printing can #include "Printer.h" and implement either:
    1. a specialized Printer template, or
    2. a setPrinter() function.

See Printer<Reg> and Printer<B3::Air::Tmp> in AirPrintSpecial.h for examples of
(1). See CodeBlock's setPrinter() for an example of (2).

  • b3/B3LowerToAir.cpp:

(JSC::B3::Air::LowerToAir::print):

  • b3/air/AirPrintSpecial.cpp: Added.

(JSC::B3::Air::PrintSpecial::PrintSpecial):
(JSC::B3::Air::PrintSpecial::~PrintSpecial):
(JSC::B3::Air::PrintSpecial::forEachArg):
(JSC::B3::Air::PrintSpecial::isValid):
(JSC::B3::Air::PrintSpecial::admitsStack):
(JSC::B3::Air::PrintSpecial::reportUsedRegisters):
(JSC::B3::Air::PrintSpecial::generate):
(JSC::B3::Air::PrintSpecial::extraEarlyClobberedRegs):
(JSC::B3::Air::PrintSpecial::extraClobberedRegs):
(JSC::B3::Air::PrintSpecial::dumpImpl):
(JSC::B3::Air::PrintSpecial::deepDumpImpl):
(JSC::Printer::printAirArg):

  • b3/air/AirPrintSpecial.h: Added.

(JSC::Printer::appendAirArg):
(JSC::Printer::appendAirArgs):
(JSC::Printer::Printer<B3::Air::Tmp>::Printer):
(JSC::Printer::Printer<Reg>::Printer):

  • Add the print() operation for use in LowerToAir. print() will emit a PrintSpecial that will ultimately emit a MASM print to print what we want.
  • LowerToAir's print() adds the ability to print Air::Args.
  • Unlike in the baseline JIT and the DFG, LowerToAir's print() can perturb the usage of registers. This is because PrintSpecial is a patch point, and it prevents certain optimizations. If not used carefully, an attempt to print() an Arg by taking a Tmp, can force the B3 Value into a Tmp earlier than it would otherwise do so. So, use LowerToAir's print() with care.
  • bytecode/CodeBlock.cpp:

(JSC::setPrinter):

  • Now we can MASM print CodeBlock*.

(WTF::printInternal):

  • Now we can dataLog CodeBlock* (including null CodeBlock pointers).
  • bytecode/CodeBlock.h:
  • runtime/VM.cpp:

(JSC::VM::throwException):

  • Use the new ability to dataLog CodeBlock*. No need to do an explicit null check before printing anymore.
Location:
trunk/Source/JavaScriptCore
Files:
4 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r215606 r215642  
    7373    assembler/MacroAssemblerPrinter.cpp
    7474    assembler/MacroAssemblerX86Common.cpp
     75    assembler/Printer.cpp
    7576
    7677    b3/air/AirAllocateRegistersAndStackByLinearScan.cpp
     
    106107    b3/air/AirPhaseInsertionSet.cpp
    107108    b3/air/AirPhaseScope.cpp
     109    b3/air/AirPrintSpecial.cpp
    108110    b3/air/AirRegLiveness.cpp
    109111    b3/air/AirReportUsedRegisters.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r215638 r215642  
     12017-04-20  Mark Lam  <mark.lam@apple.com>
     2
     3        Refactor MASM probe to allow printing of custom types.
     4        https://bugs.webkit.org/show_bug.cgi?id=171101
     5
     6        Reviewed by JF Bastien.
     7
     8        For example, this allows us to add MASM printing of CodeBlock* and Air::Args.
     9
     10        In general, MASM print can be used like dataLog, except that it generates JITted
     11        code for doing the dataLogging later when the JITted code runs.  MASM print can
     12        print any value type that a specialized Printer template or a setPrinter()
     13        function implemented for that type.
     14
     15        * CMakeLists.txt:
     16        * JavaScriptCore.xcodeproj/project.pbxproj:
     17        * assembler/MacroAssembler.h:
     18
     19        * assembler/MacroAssemblerPrinter.cpp:
     20        (JSC::Printer::printAllRegisters):
     21        (JSC::Printer::printPCRegister):
     22        (JSC::Printer::printRegisterID):
     23        (JSC::Printer::printFPRegisterID):
     24        (JSC::Printer::printAddress):
     25        (JSC::Printer::printMemory):
     26        (JSC::Printer::printCallback):
     27        (JSC::printIndent): Deleted.
     28        (JSC::printCPU): Deleted.
     29        (JSC::printCPURegisters): Deleted.
     30        (JSC::printPC): Deleted.
     31        (JSC::printRegister): Deleted.
     32        (JSC::printMemory): Deleted.
     33        (JSC::MacroAssemblerPrinter::printCallback): Deleted.
     34        * assembler/MacroAssemblerPrinter.h:
     35        (JSC::AllRegisters::AllRegisters):
     36        (JSC::Printer::Printer<AllRegisters>::Printer):
     37        (JSC::Printer::Printer<PCRegister>::Printer):
     38        (JSC::Printer::Printer<MacroAssembler::RegisterID>::Printer):
     39        (JSC::Printer::Printer<MacroAssembler::FPRegisterID>::Printer):
     40        (JSC::Printer::Printer<MacroAssembler::Address>::Printer):
     41        (JSC::Printer::Printer<Memory>::Printer):
     42        (JSC::Printer::Printer<MemWord<IntType>>::Printer):
     43        (JSC::MacroAssembler::print):
     44        (JSC::MacroAssemblerPrinter::print): Deleted.
     45        (JSC::MacroAssemblerPrinter::PrintArg::PrintArg): Deleted.
     46        (JSC::MacroAssemblerPrinter::appendPrintArg): Deleted.
     47        - Refactored to move the underlying PrintRecord (and associated data structures)
     48          out to Printer.cpp/h.
     49        - MacroAssemblerPrinter.cpp/h now only add custom Printers for MASM types like
     50          RegisterID and Memory.  It also defines the implementation of
     51          MacroAssembler::print().
     52
     53          As before, JIT code that wishes to use MacroAssembler::print() needs to
     54          #include "MacroAssemblerPrinter.h".
     55
     56        - Also added the ability to specify an optional indentation (in number of chars)
     57          when MASM printing AllRegisters.  This is useful because AllRegisters prints
     58          a block of data unlike other printers which print inline.
     59
     60        * assembler/Printer.cpp: Added.
     61        (JSC::Printer::printConstCharString):
     62        (JSC::Printer::printIntptr):
     63        (JSC::Printer::printUintptr):
     64        (JSC::Printer::printPointer):
     65        (JSC::Printer::setPrinter):
     66        * assembler/Printer.h: Added.
     67        (JSC::Printer::Context::Context):
     68        (JSC::Printer::PrintRecord::PrintRecord):
     69        (JSC::Printer::appendPrinter):
     70        (JSC::Printer::makePrintRecordList):
     71        (JSC::Printer::Printer<RawPointer>::Printer):
     72        (JSC::Printer::setPrinter):
     73        (JSC::Printer::Printer::Printer):
     74        - Data structures for creating a list of PrintRecords.  Classes which wish to
     75          add custom support for MASM printing can #include "Printer.h" and implement
     76          either:
     77          1. a specialized Printer template, or
     78          2. a setPrinter() function.
     79
     80          See Printer<Reg> and Printer<B3::Air::Tmp> in AirPrintSpecial.h for examples of
     81          (1).  See CodeBlock's setPrinter() for an example of (2).
     82
     83        * b3/B3LowerToAir.cpp:
     84        (JSC::B3::Air::LowerToAir::print):
     85        * b3/air/AirPrintSpecial.cpp: Added.
     86        (JSC::B3::Air::PrintSpecial::PrintSpecial):
     87        (JSC::B3::Air::PrintSpecial::~PrintSpecial):
     88        (JSC::B3::Air::PrintSpecial::forEachArg):
     89        (JSC::B3::Air::PrintSpecial::isValid):
     90        (JSC::B3::Air::PrintSpecial::admitsStack):
     91        (JSC::B3::Air::PrintSpecial::reportUsedRegisters):
     92        (JSC::B3::Air::PrintSpecial::generate):
     93        (JSC::B3::Air::PrintSpecial::extraEarlyClobberedRegs):
     94        (JSC::B3::Air::PrintSpecial::extraClobberedRegs):
     95        (JSC::B3::Air::PrintSpecial::dumpImpl):
     96        (JSC::B3::Air::PrintSpecial::deepDumpImpl):
     97        (JSC::Printer::printAirArg):
     98        * b3/air/AirPrintSpecial.h: Added.
     99        (JSC::Printer::appendAirArg):
     100        (JSC::Printer::appendAirArgs):
     101        (JSC::Printer::Printer<B3::Air::Tmp>::Printer):
     102        (JSC::Printer::Printer<Reg>::Printer):
     103        - Add the print() operation for use in LowerToAir.  print() will emit a
     104          PrintSpecial that will ultimately emit a MASM print to print what we want.
     105        - LowerToAir's print() adds the ability to print Air::Args.
     106        - Unlike in the baseline JIT and the DFG, LowerToAir's print() can perturb the
     107          usage of registers.  This is because PrintSpecial is a patch point, and it
     108          prevents certain optimizations.  If not used carefully, an attempt to print()
     109          an Arg by taking a Tmp, can force the B3 Value into a Tmp earlier than it would
     110          otherwise do so.  So, use LowerToAir's print() with care.
     111
     112        * bytecode/CodeBlock.cpp:
     113        (JSC::setPrinter):
     114        - Now we can MASM print CodeBlock*.
     115        (WTF::printInternal):
     116        - Now we can dataLog CodeBlock* (including null CodeBlock pointers).
     117
     118        * bytecode/CodeBlock.h:
     119
     120        * runtime/VM.cpp:
     121        (JSC::VM::throwException):
     122        - Use the new ability to dataLog CodeBlock*.  No need to do an explicit null
     123          check before printing anymore.
     124
    11252017-04-21  Keith Miller  <keith_miller@apple.com>
    2126
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r215353 r215642  
    24462446                FE5068651AE246390009DAB7 /* DeferredSourceDump.h in Headers */ = {isa = PBXBuildFile; fileRef = FE5068641AE246390009DAB7 /* DeferredSourceDump.h */; settings = {ATTRIBUTES = (Private, ); }; };
    24472447                FE5068671AE25E280009DAB7 /* DeferredSourceDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE5068661AE25E280009DAB7 /* DeferredSourceDump.cpp */; };
     2448                FE5628CD1E99512D00C49E45 /* AirPrintSpecial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE5628CB1E99512400C49E45 /* AirPrintSpecial.cpp */; };
     2449                FE5628CE1E99513200C49E45 /* AirPrintSpecial.h in Headers */ = {isa = PBXBuildFile; fileRef = FE5628CC1E99512400C49E45 /* AirPrintSpecial.h */; };
    24482450                FE5932A7183C5A2600A1ECCC /* VMEntryScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE5932A5183C5A2600A1ECCC /* VMEntryScope.cpp */; };
    24492451                FE5932A8183C5A2600A1ECCC /* VMEntryScope.h in Headers */ = {isa = PBXBuildFile; fileRef = FE5932A6183C5A2600A1ECCC /* VMEntryScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
    24502452                FE6029D91D6E1E4F0030204D /* ExceptionEventLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE6029D81D6E1E330030204D /* ExceptionEventLocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
     2453                FE63DD541EA9B61E00103A69 /* Printer.h in Headers */ = {isa = PBXBuildFile; fileRef = FE63DD531EA9B60E00103A69 /* Printer.h */; settings = {ATTRIBUTES = (Private, ); }; };
     2454                FE63DD561EA9BC6700103A69 /* Printer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE63DD551EA9BC5D00103A69 /* Printer.cpp */; };
    24512455                FE6491371D78F01D00A694D4 /* ExceptionScope.h in Headers */ = {isa = PBXBuildFile; fileRef = FE6491361D78F01300A694D4 /* ExceptionScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
    24522456                FE6491391D78F3AF00A694D4 /* ExceptionScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE6491381D78F3A300A694D4 /* ExceptionScope.cpp */; };
     
    50725076                FE5068641AE246390009DAB7 /* DeferredSourceDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeferredSourceDump.h; sourceTree = "<group>"; };
    50735077                FE5068661AE25E280009DAB7 /* DeferredSourceDump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeferredSourceDump.cpp; sourceTree = "<group>"; };
     5078                FE5628CB1E99512400C49E45 /* AirPrintSpecial.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirPrintSpecial.cpp; path = b3/air/AirPrintSpecial.cpp; sourceTree = "<group>"; };
     5079                FE5628CC1E99512400C49E45 /* AirPrintSpecial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirPrintSpecial.h; path = b3/air/AirPrintSpecial.h; sourceTree = "<group>"; };
    50745080                FE5932A5183C5A2600A1ECCC /* VMEntryScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMEntryScope.cpp; sourceTree = "<group>"; };
    50755081                FE5932A6183C5A2600A1ECCC /* VMEntryScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMEntryScope.h; sourceTree = "<group>"; };
    50765082                FE6029D81D6E1E330030204D /* ExceptionEventLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExceptionEventLocation.h; sourceTree = "<group>"; };
     5083                FE63DD531EA9B60E00103A69 /* Printer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Printer.h; sourceTree = "<group>"; };
     5084                FE63DD551EA9BC5D00103A69 /* Printer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Printer.cpp; sourceTree = "<group>"; };
    50775085                FE6491361D78F01300A694D4 /* ExceptionScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExceptionScope.h; sourceTree = "<group>"; };
    50785086                FE6491381D78F3A300A694D4 /* ExceptionScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExceptionScope.cpp; sourceTree = "<group>"; };
     
    56535661                                0FEC855E1BDACDC70080FF74 /* AirPhaseScope.cpp */,
    56545662                                0FEC855F1BDACDC70080FF74 /* AirPhaseScope.h */,
     5663                                FE5628CB1E99512400C49E45 /* AirPrintSpecial.cpp */,
     5664                                FE5628CC1E99512400C49E45 /* AirPrintSpecial.h */,
    56555665                                0FF4B4BA1E88449500DBBE86 /* AirRegLiveness.cpp */,
    56565666                                0FF4B4BB1E88449500DBBE86 /* AirRegLiveness.h */,
     
    75277537                                65860177185A8F5E00030EEE /* MaxFrameExtentForSlowPathCall.h */,
    75287538                                86C568DF11A213EE0007F7F0 /* MIPSAssembler.h */,
     7539                                FE63DD551EA9BC5D00103A69 /* Printer.cpp */,
     7540                                FE63DD531EA9B60E00103A69 /* Printer.h */,
    75297541                                9688CB140ED12B4E001D649F /* X86Assembler.h */,
    75307542                        );
     
    82668278                                0F33FCF81C136E2500323F67 /* B3StackmapGenerationParams.h in Headers */,
    82678279                                0FEC85311BDACDAC0080FF74 /* B3StackmapSpecial.h in Headers */,
     8280                                FE5628CE1E99513200C49E45 /* AirPrintSpecial.h in Headers */,
    82688281                                0F338DF21BE93AD10013C88F /* B3StackmapValue.h in Headers */,
    82698282                                0F9495881C57F47500413A48 /* B3StackSlot.h in Headers */,
     
    85478560                                0FFB921C16D02F110055A5DB /* DFGOSRExitCompilationInfo.h in Headers */,
    85488561                                0FC0977114693AF500CF2442 /* DFGOSRExitCompiler.h in Headers */,
     8562                                FE63DD541EA9B61E00103A69 /* Printer.h in Headers */,
    85498563                                0F7025AA1714B0FC00382C0E /* DFGOSRExitCompilerCommon.h in Headers */,
    85508564                                0F392C8A1B46188400844728 /* DFGOSRExitFuzz.h in Headers */,
     
    1031510329                                0F2FCCFB18A60070001A27F8 /* DFGSafepoint.cpp in Sources */,
    1031610330                                86EC9DD21328DF82002B2AD7 /* DFGSpeculativeJIT.cpp in Sources */,
     10331                                FE63DD561EA9BC6700103A69 /* Printer.cpp in Sources */,
    1031710332                                86880F1F14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp in Sources */,
    1031810333                                86880F4D14353B2100B08D42 /* DFGSpeculativeJIT64.cpp in Sources */,
     
    1054510560                                14ABDF600A437FEF00ECCA01 /* JSCallbackObject.cpp in Sources */,
    1054610561                                657CF45819BF6662004ACBF2 /* JSCallee.cpp in Sources */,
     10562                                FE5628CD1E99512D00C49E45 /* AirPrintSpecial.cpp in Sources */,
    1054710563                                A7D801A81880D6A80026C39B /* JSCBuiltins.cpp in Sources */,
    1054810564                                147F39D1107EC37600427A48 /* JSCell.cpp in Sources */,
  • trunk/Source/JavaScriptCore/assembler/MacroAssembler.h

    r215592 r215642  
    6363
    6464namespace JSC {
     65
     66namespace Printer {
     67
     68struct PrintRecord;
     69typedef Vector<PrintRecord> PrintRecordList;
     70
     71}
    6572
    6673class MacroAssembler : public MacroAssemblerBase {
     
    18211828    // See comments in MacroAssemblerPrinter.h for examples of how to use this.
    18221829    template<typename... Arguments>
    1823     void print(Arguments... args);
     1830    void print(Arguments&&... args);
     1831
     1832    void print(Printer::PrintRecordList*);
    18241833};
    18251834
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerPrinter.cpp

    r215592 r215642  
    3232
    3333namespace JSC {
     34namespace Printer {
    3435
    3536using CPUState = MacroAssembler::CPUState;
     
    3738using FPRegisterID = MacroAssembler::FPRegisterID;
    3839
    39 static void printIndent(int indentation)
     40void printAllRegisters(PrintStream& out, Context& context)
    4041{
    41     for (; indentation > 0; indentation--)
    42         dataLog("    ");
    43 }
     42    auto& cpu = context.probeContext.cpu;
     43    unsigned charsToIndent = context.data.as<unsigned>();
    4444
    45 #define INDENT printIndent(indentation)
    46    
    47 void printCPU(CPUState& cpu, int indentation)
    48 {
    49     INDENT, dataLog("cpu: {\n");
    50     printCPURegisters(cpu, indentation + 1);
    51     INDENT, dataLog("}\n");
    52 }
     45    auto indent = [&] () {
     46        for (unsigned i = 0; i < charsToIndent; ++i)
     47            out.print(" ");
     48    };
     49#define INDENT indent()
    5350
    54 void printCPURegisters(CPUState& cpu, int indentation)
    55 {
     51    INDENT, out.print("cpu: {\n");
     52
    5653#if USE(JSVALUE32_64)
    5754    #define INTPTR_HEX_VALUE_FORMAT "0x%08lx"
     
    6259    #define PRINT_GPREGISTER(_type, _regName) { \
    6360        intptr_t value = reinterpret_cast<intptr_t>(cpu._regName); \
    64         INDENT, dataLogF("%6s: " INTPTR_HEX_VALUE_FORMAT "  %ld\n", #_regName, value, value) ; \
     61        INDENT, out.printf("    %6s: " INTPTR_HEX_VALUE_FORMAT "  %ld\n", #_regName, value, value) ; \
    6562    }
    6663    FOR_EACH_CPU_GPREGISTER(PRINT_GPREGISTER)
     
    7269        uint64_t* u = reinterpret_cast<uint64_t*>(&cpu._regName); \
    7370        double* d = reinterpret_cast<double*>(&cpu._regName); \
    74         INDENT, dataLogF("%6s: 0x%016llx  %.13g\n", #_regName, *u, *d); \
     71        INDENT, out.printf("    %6s: 0x%016llx  %.13g\n", #_regName, *u, *d); \
    7572    }
    7673    FOR_EACH_CPU_FPREGISTER(PRINT_FPREGISTER)
    7774    #undef PRINT_FPREGISTER
     75
     76    INDENT, out.print("}\n");
     77#undef INDENT
     78
    7879}
    7980
    80 static void printPC(CPUState& cpu)
     81void printPCRegister(PrintStream& out, Context& context)
    8182{
    82     union {
    83         void* voidPtr;
    84         intptr_t intptrValue;
    85     } u;
     83    auto cpu = context.probeContext.cpu;
     84    void* value;
    8685#if CPU(X86) || CPU(X86_64)
    87     u.voidPtr = cpu.eip;
     86    value = cpu.eip;
    8887#elif CPU(ARM_TRADITIONAL) || CPU(ARM_THUMB2) || CPU(ARM64)
    89     u.voidPtr = cpu.pc;
     88    value = cpu.pc;
    9089#else
    9190#error "Unsupported CPU"
    9291#endif
    93     dataLogF("pc:<%p %ld>", u.voidPtr, u.intptrValue);
     92    out.printf("pc:<%p %ld>", value, bitwise_cast<intptr_t>(value));
    9493}
    9594
    96 void printRegister(CPUState& cpu, RegisterID regID)
     95void printRegisterID(PrintStream& out, Context& context)
    9796{
     97    RegisterID regID = context.data.as<RegisterID>();
    9898    const char* name = CPUState::gprName(regID);
    99     union {
    100         void* voidPtr;
    101         intptr_t intptrValue;
    102     } u;
    103     u.voidPtr = cpu.gpr(regID);
    104     dataLogF("%s:<%p %ld>", name, u.voidPtr, u.intptrValue);
     99    void* value = context.probeContext.gpr(regID);
     100    out.printf("%s:<%p %ld>", name, value, bitwise_cast<intptr_t>(value));
    105101}
    106102
    107 void printRegister(CPUState& cpu, FPRegisterID regID)
     103void printFPRegisterID(PrintStream& out, Context& context)
    108104{
     105    FPRegisterID regID = context.data.as<FPRegisterID>();
    109106    const char* name = CPUState::fprName(regID);
    110     union {
    111         double doubleValue;
    112         uint64_t uint64Value;
    113     } u;
    114     u.doubleValue = cpu.fpr(regID);
    115     dataLogF("%s:<0x%016llx %.13g>", name, u.uint64Value, u.doubleValue);
     107    double value = context.probeContext.fpr(regID);
     108    out.printf("%s:<0x%016llx %.13g>", name, bitwise_cast<uint64_t>(value), value);
    116109}
    117110
    118 void printMemory(CPUState& cpu, const Memory& memory)
     111void printAddress(PrintStream& out, Context& context)
    119112{
     113    MacroAssembler::Address address = context.data.as<MacroAssembler::Address>();
     114    RegisterID regID = address.base;
     115    const char* name = CPUState::gprName(regID);
     116    void* value = context.probeContext.gpr(regID);
     117    out.printf("Address{base:%s:<%p %ld>, offset:<0x%x %d>", name, value, bitwise_cast<intptr_t>(value), address.offset, address.offset);
     118}
     119
     120void printMemory(PrintStream& out, Context& context)
     121{
     122    const Memory& memory = context.data.as<Memory>();
     123
    120124    uint8_t* ptr = nullptr;
    121125    switch (memory.addressType) {
    122126    case Memory::AddressType::Address: {
    123         ptr = reinterpret_cast<uint8_t*>(cpu.gpr(memory.u.address.base));
     127        ptr = reinterpret_cast<uint8_t*>(context.probeContext.gpr(memory.u.address.base));
    124128        ptr += memory.u.address.offset;
    125129        break;
     
    134138        if (memory.numBytes == sizeof(int8_t)) {
    135139            auto p = reinterpret_cast<int8_t*>(ptr);
    136             dataLogF("%p:<0x%02x %d>", p, *p, *p);
     140            out.printf("%p:<0x%02x %d>", p, *p, *p);
    137141            return;
    138142        }
    139143        if (memory.numBytes == sizeof(int16_t)) {
    140144            auto p = reinterpret_cast<int16_t*>(ptr);
    141             dataLogF("%p:<0x%04x %d>", p, *p, *p);
     145            out.printf("%p:<0x%04x %d>", p, *p, *p);
    142146            return;
    143147        }
    144148        if (memory.numBytes == sizeof(int32_t)) {
    145149            auto p = reinterpret_cast<int32_t*>(ptr);
    146             dataLogF("%p:<0x%08x %d>", p, *p, *p);
     150            out.printf("%p:<0x%08x %d>", p, *p, *p);
    147151            return;
    148152        }
    149153        if (memory.numBytes == sizeof(int64_t)) {
    150154            auto p = reinterpret_cast<int64_t*>(ptr);
    151             dataLogF("%p:<0x%016llx %lld>", p, *p, *p);
     155            out.printf("%p:<0x%016llx %lld>", p, *p, *p);
    152156            return;
    153157        }
     
    159163    for (size_t i = 0; i < numBytes; i++) {
    160164        if (!(i % 16))
    161             dataLogF("%p: ", &ptr[i]);
     165            out.printf("%p: ", &ptr[i]);
    162166        else if (!(i % 4))
    163             dataLog(" ");
     167            out.printf(" ");
    164168
    165         dataLogF("%02x", ptr[i]);
     169        out.printf("%02x", ptr[i]);
    166170
    167171        if (i % 16 == 15)
    168             dataLog("\n");
     172            out.print("\n");
    169173    }
    170174    if (numBytes % 16 < 15)
    171         dataLog("\n");
     175        out.print("\n");
    172176}
    173177
    174 void MacroAssemblerPrinter::printCallback(ProbeContext* context)
     178void printCallback(ProbeContext* probeContext)
    175179{
    176     typedef PrintArg Arg;
    177     PrintArgsList& argsList =
    178     *reinterpret_cast<PrintArgsList*>(context->arg);
    179     for (size_t i = 0; i < argsList.size(); i++) {
    180         auto& arg = argsList[i];
    181         switch (arg.type) {
    182         case Arg::Type::AllRegisters:
    183             printCPU(context->cpu, 1);
    184             break;
    185         case Arg::Type::PCRegister:
    186             printPC(context->cpu);
    187             break;
    188         case Arg::Type::RegisterID:
    189             printRegister(context->cpu, arg.u.gpRegisterID);
    190             break;
    191         case Arg::Type::FPRegisterID:
    192             printRegister(context->cpu, arg.u.fpRegisterID);
    193             break;
    194         case Arg::Type::Memory:
    195             printMemory(context->cpu, arg.u.memory);
    196             break;
    197         case Arg::Type::ConstCharPtr:
    198             dataLog(arg.u.constCharPtr);
    199             break;
    200         case Arg::Type::ConstVoidPtr:
    201             dataLogF("%p", arg.u.constVoidPtr);
    202             break;
    203         case Arg::Type::IntptrValue:
    204             dataLog(arg.u.intptrValue);
    205             break;
    206         case Arg::Type::UintptrValue:
    207             dataLog(arg.u.uintptrValue);
    208             break;
    209         }
     180    auto& out = WTF::dataFile();
     181    PrintRecordList& list = *reinterpret_cast<PrintRecordList*>(probeContext->arg);
     182    for (size_t i = 0; i < list.size(); i++) {
     183        auto& record = list[i];
     184        Context context(*probeContext, record.data);
     185        record.printer(out, context);
    210186    }
    211187}
    212188
     189} // namespace Printer
    213190} // namespace JSC
    214191
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerPrinter.h

    r215595 r215642  
    2727
    2828#include "MacroAssembler.h"
     29#include "Printer.h"
    2930
    3031namespace JSC {
     
    5556//
    5657//      CodeBlock* cb = ...;
    57 //      jit.print(cb, "\n");        // Emits code to print the pointer value.
     58//      jit.print(cb, "\n");             // Emits code to print the codeBlock value.
     59//      jit.print(RawPointer(cb), "\n"); // Emits code to print the pointer value.
    5860//
    5961//      RegisterID regID = ...;
     
    6264//      // Emits code to print all registers. Unlike other items, this prints
    6365//      // multiple lines as follows:
    64 //      //      cpu {
    65 //      //          eax: 0x123456789
    66 //      //          ebx: 0x000000abc
    67 //      //          ...
    68 //      //      }
    69 //      jit.print(AllRegisters());
     66//      //     cpu {
     67//      //         eax: 0x123456789
     68//      //         ebx: 0x000000abc
     69//      //         ...
     70//      //     }
     71//      unsigned indentation = 4;
     72//      jit.print(AllRegisters(indentation));
    7073//
    7174//      jit.print(MemWord<uint8_t>(regID), "\n");   // Emits code to print a byte pointed to by the register.
     
    8285//      jit.print("cb:", cb, " regID:", regID, " cpu:\n", AllRegisters());
    8386//
    84 //   The type of values that can be printed is encapsulated in the PrintArg struct below.
     87//   The type of values that can be printed is determine by the availability of a
     88//   specialized Printer template, or a setPrinter() function for the value type.
    8589//
    8690//   Note: print() does not automatically insert a '\n' at the end of the line.
     
    8892
    8993
    90 // This is a marker type only used with MacroAssemblerPrinter::print().
    91 // See MacroAssemblerPrinter::print() below for details.
    92 struct AllRegisters { };
     94struct AllRegisters {
     95    explicit AllRegisters(unsigned charsToIndent = 0)
     96        : charsToIndent(charsToIndent)
     97    { }
     98    unsigned charsToIndent;
     99};
    93100struct PCRegister { };
    94101
     
    108115    };
    109116
    110     Memory(RegisterID& reg, size_t bytes, DumpStyle style = GenericDump)
     117    explicit Memory(RegisterID& reg, size_t bytes, DumpStyle style = GenericDump)
    111118        : addressType(AddressType::Address)
    112119        , dumpStyle(style)
     
    116123    }
    117124
    118     Memory(const Address& address, size_t bytes, DumpStyle style = GenericDump)
     125    explicit Memory(const Address& address, size_t bytes, DumpStyle style = GenericDump)
    119126        : addressType(AddressType::Address)
    120127        , dumpStyle(style)
     
    124131    }
    125132
    126     Memory(const AbsoluteAddress& address, size_t bytes, DumpStyle style = GenericDump)
     133    explicit Memory(const AbsoluteAddress& address, size_t bytes, DumpStyle style = GenericDump)
    127134        : addressType(AddressType::AbsoluteAddress)
    128135        , dumpStyle(style)
     
    145152template <typename IntType>
    146153struct MemWord : public Memory {
    147     MemWord(RegisterID& reg)
     154    explicit MemWord(RegisterID& reg)
    148155        : Memory(reg, sizeof(IntType), Memory::SingleWordDump)
    149156    { }
    150157
    151     MemWord(const Address& address)
     158    explicit MemWord(const Address& address)
    152159        : Memory(address, sizeof(IntType), Memory::SingleWordDump)
    153160    { }
    154161
    155     MemWord(const AbsoluteAddress& address)
     162    explicit MemWord(const AbsoluteAddress& address)
    156163        : Memory(address, sizeof(IntType), Memory::SingleWordDump)
    157164    { }
    158165};
    159166
    160 
    161 class MacroAssemblerPrinter {
    162     using CPUState = MacroAssembler::CPUState;
    163     using RegisterID = MacroAssembler::RegisterID;
    164     using FPRegisterID = MacroAssembler::FPRegisterID;
    165    
    166 public:
    167     template<typename... Arguments>
    168     static void print(MacroAssembler* masm, Arguments... args)
    169     {
    170         auto argsList = std::make_unique<PrintArgsList>();
    171         appendPrintArg(argsList.get(), args...);
    172         masm->probe(printCallback, argsList.release());
    173     }
    174    
    175 private:
    176     struct PrintArg {
    177 
    178         enum class Type {
    179             AllRegisters,
    180             PCRegister,
    181             RegisterID,
    182             FPRegisterID,
    183             Memory,
    184             ConstCharPtr,
    185             ConstVoidPtr,
    186             IntptrValue,
    187             UintptrValue,
    188         };
    189        
    190         PrintArg(AllRegisters&)
    191             : type(Type::AllRegisters)
    192         {
    193         }
    194        
    195         PrintArg(PCRegister&)
    196             : type(Type::PCRegister)
    197         {
    198         }
    199        
    200         PrintArg(RegisterID regID)
    201             : type(Type::RegisterID)
    202         {
    203             u.gpRegisterID = regID;
    204         }
    205        
    206         PrintArg(FPRegisterID regID)
    207             : type(Type::FPRegisterID)
    208         {
    209             u.fpRegisterID = regID;
    210         }
    211 
    212         PrintArg(const Memory& memory)
    213             : type(Type::Memory)
    214         {
    215             u.memory = memory;
    216         }
    217 
    218         PrintArg(const char* ptr)
    219             : type(Type::ConstCharPtr)
    220         {
    221             u.constCharPtr = ptr;
    222         }
    223        
    224         PrintArg(const void* ptr)
    225             : type(Type::ConstVoidPtr)
    226         {
    227             u.constVoidPtr = ptr;
    228         }
    229        
    230         PrintArg(int value)
    231             : type(Type::IntptrValue)
    232         {
    233             u.intptrValue = value;
    234         }
    235        
    236         PrintArg(unsigned value)
    237             : type(Type::UintptrValue)
    238         {
    239             u.intptrValue = value;
    240         }
    241        
    242         PrintArg(intptr_t value)
    243             : type(Type::IntptrValue)
    244         {
    245             u.intptrValue = value;
    246         }
    247        
    248         PrintArg(uintptr_t value)
    249             : type(Type::UintptrValue)
    250         {
    251             u.uintptrValue = value;
    252         }
    253        
    254         Type type;
    255         union Value {
    256             Value() { }
    257 
    258             RegisterID gpRegisterID;
    259             FPRegisterID fpRegisterID;
    260             Memory memory;
    261             const char* constCharPtr;
    262             const void* constVoidPtr;
    263             intptr_t intptrValue;
    264             uintptr_t uintptrValue;
    265         } u;
    266     };
    267 
    268     typedef Vector<PrintArg> PrintArgsList;
    269    
    270     template<typename FirstArg, typename... Arguments>
    271     static void appendPrintArg(PrintArgsList* argsList, FirstArg& firstArg, Arguments... otherArgs)
    272     {
    273         argsList->append(PrintArg(firstArg));
    274         appendPrintArg(argsList, otherArgs...);
    275     }
    276    
    277     static void appendPrintArg(PrintArgsList*) { }
    278 
    279 private:
    280     static void printCallback(ProbeContext*);
    281 };
     167namespace Printer {
     168
     169// Add some specialized printers.
     170
     171void printAllRegisters(PrintStream&, Context&);
     172void printPCRegister(PrintStream&, Context&);
     173void printRegisterID(PrintStream&, Context&);
     174void printFPRegisterID(PrintStream&, Context&);
     175void printAddress(PrintStream&, Context&);
     176void printMemory(PrintStream&, Context&);
     177
     178template<>
     179struct Printer<AllRegisters> : public PrintRecord {
     180    Printer(AllRegisters allRegisters)
     181        : PrintRecord(static_cast<uintptr_t>(allRegisters.charsToIndent), printAllRegisters)
     182    { }
     183};
     184
     185template<>
     186struct Printer<PCRegister> : public PrintRecord {
     187    Printer(PCRegister&)
     188        : PrintRecord(printPCRegister)
     189    { }
     190};
     191
     192template<>
     193struct Printer<MacroAssembler::RegisterID> : public PrintRecord {
     194    Printer(MacroAssembler::RegisterID id)
     195        : PrintRecord(static_cast<uintptr_t>(id), printRegisterID)
     196    { }
     197};
     198
     199template<>
     200struct Printer<MacroAssembler::FPRegisterID> : public PrintRecord {
     201    Printer(MacroAssembler::FPRegisterID id)
     202        : PrintRecord(static_cast<uintptr_t>(id), printFPRegisterID)
     203    { }
     204};
     205
     206template<>
     207struct Printer<MacroAssembler::Address> : public PrintRecord {
     208    Printer(MacroAssembler::Address address)
     209        : PrintRecord(Data(&address, sizeof(address)), printAddress)
     210    { }
     211};
     212
     213template<>
     214struct Printer<Memory> : public PrintRecord {
     215    Printer(Memory memory)
     216        : PrintRecord(Data(&memory, sizeof(memory)), printMemory)
     217    { }
     218};
     219
     220template<typename IntType>
     221struct Printer<MemWord<IntType>> : public Printer<Memory> {
     222    Printer(MemWord<IntType> word)
     223        : Printer<Memory>(word)
     224    { }
     225};
     226
     227void printCallback(ProbeContext*);
     228
     229} // namespace Printer
    282230
    283231template<typename... Arguments>
    284 void MacroAssembler::print(Arguments... args)
     232inline void MacroAssembler::print(Arguments&&... arguments)
    285233{
    286     MacroAssemblerPrinter::print(this, args...);
     234    auto printRecordList = Printer::makePrintRecordList(std::forward<Arguments>(arguments)...);
     235    probe(Printer::printCallback, printRecordList);
    287236}
    288237
    289 
    290 // These printers will print a block of information. That block may be
    291 // indented with the specified indentation.
    292 void printCPU(MacroAssembler::CPUState&, int indentation = 0);
    293 void printCPURegisters(MacroAssembler::CPUState&, int indentation = 0);
    294 
    295 // These printers will print the specified information in line in the
    296 // print stream. Hence, no indentation will be applied.
    297 void printRegister(MacroAssembler::CPUState&, MacroAssembler::RegisterID);
    298 void printRegister(MacroAssembler::CPUState&, MacroAssembler::FPRegisterID);
    299 void printMemory(MacroAssembler::CPUState&, const Memory&);
     238inline void MacroAssembler::print(Printer::PrintRecordList* printRecordList)
     239{
     240    probe(Printer::printCallback, printRecordList);
     241}
    300242
    301243#else // ENABLE(MASM_PROBE)
    302244
    303245template<typename... Arguments>
    304 void MacroAssembler::print(Arguments...) { }
     246inline void MacroAssembler::print(Arguments&&...) { }
     247
     248inline void MacroAssembler::print(Printer::PrintRecordList*) { }
    305249
    306250#endif // ENABLE(MASM_PROBE)
  • trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp

    r215565 r215642  
    3434#include "AirInsertionSet.h"
    3535#include "AirInstInlines.h"
     36#include "AirPrintSpecial.h"
    3637#include "AirStackSlot.h"
    3738#include "B3ArgumentRegValue.h"
     
    11281129    }
    11291130
     1131#if ENABLE(MASM_PROBE)
     1132    template<typename... Arguments>
     1133    void print(Arguments&&... arguments)
     1134    {
     1135        Value* origin = m_value;
     1136        print(origin, std::forward<Arguments>(arguments)...);
     1137    }
     1138
     1139    template<typename... Arguments>
     1140    void print(Value* origin, Arguments&&... arguments)
     1141    {
     1142        auto printList = Printer::makePrintRecordList(arguments...);
     1143        auto printSpecial = static_cast<PrintSpecial*>(m_code.addSpecial(std::make_unique<PrintSpecial>(printList)));
     1144        Inst inst(Patch, origin, Arg::special(printSpecial));
     1145        Printer::appendAirArgs(inst, std::forward<Arguments>(arguments)...);
     1146        append(WTFMove(inst));
     1147    }
     1148#else
     1149    template<typename... Arguments>
     1150    void print(Arguments&&...) { }
     1151#endif // ENABLE(MASM_PROBE)
     1152
    11301153    template<typename... Arguments>
    11311154    void append(Air::Opcode opcode, Arguments&&... arguments)
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r215476 r215642  
    31123112}
    31133113
     3114void setPrinter(Printer::PrintRecord& record, CodeBlock* codeBlock)
     3115{
     3116    Printer::setPrinter(record, toCString(codeBlock));
     3117}
    31143118
    31153119} // namespace JSC
     3120
     3121namespace WTF {
     3122   
     3123void printInternal(PrintStream& out, JSC::CodeBlock* codeBlock)
     3124{
     3125    if (UNLIKELY(!codeBlock)) {
     3126        out.print("<null codeBlock>");
     3127        return;
     3128    }
     3129    out.print(*codeBlock);
     3130}
     3131   
     3132} // namespace WTF
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r214931 r215642  
    6161#include "ObjectAllocationProfile.h"
    6262#include "Options.h"
     63#include "Printer.h"
    6364#include "ProfilerJettisonReason.h"
    6465#include "ProgramExecutable.h"
     
    10881089    (codeBlock->vm()->logEvent(codeBlock, summary, [&] () { return toCString details; }))
    10891090
     1091
     1092void setPrinter(Printer::PrintRecord&, CodeBlock*);
     1093
    10901094} // namespace JSC
     1095
     1096namespace WTF {
     1097   
     1098JS_EXPORT_PRIVATE void printInternal(PrintStream&, JSC::CodeBlock*);
     1099
     1100} // namespace WTF
  • trunk/Source/JavaScriptCore/runtime/VM.cpp

    r214905 r215642  
    606606    if (Options::breakOnThrow()) {
    607607        CodeBlock* codeBlock = exec->codeBlock();
    608         dataLog("Throwing exception in call frame ", RawPointer(exec), " for code block ");
    609         if (codeBlock)
    610             dataLog(*codeBlock, "\n");
    611         else
    612             dataLog("<nullptr>\n");
     608        dataLog("Throwing exception in call frame ", RawPointer(exec), " for code block ", codeBlock, "\n");
    613609        CRASH();
    614610    }
Note: See TracChangeset for help on using the changeset viewer.