Changeset 215642 in webkit
- Timestamp:
- Apr 21, 2017, 2:42:24 PM (8 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 4 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/CMakeLists.txt
r215606 r215642 73 73 assembler/MacroAssemblerPrinter.cpp 74 74 assembler/MacroAssemblerX86Common.cpp 75 assembler/Printer.cpp 75 76 76 77 b3/air/AirAllocateRegistersAndStackByLinearScan.cpp … … 106 107 b3/air/AirPhaseInsertionSet.cpp 107 108 b3/air/AirPhaseScope.cpp 109 b3/air/AirPrintSpecial.cpp 108 110 b3/air/AirRegLiveness.cpp 109 111 b3/air/AirReportUsedRegisters.cpp -
trunk/Source/JavaScriptCore/ChangeLog
r215638 r215642 1 2017-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 1 125 2017-04-21 Keith Miller <keith_miller@apple.com> 2 126 -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r215353 r215642 2446 2446 FE5068651AE246390009DAB7 /* DeferredSourceDump.h in Headers */ = {isa = PBXBuildFile; fileRef = FE5068641AE246390009DAB7 /* DeferredSourceDump.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2447 2447 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 */; }; 2448 2450 FE5932A7183C5A2600A1ECCC /* VMEntryScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE5932A5183C5A2600A1ECCC /* VMEntryScope.cpp */; }; 2449 2451 FE5932A8183C5A2600A1ECCC /* VMEntryScope.h in Headers */ = {isa = PBXBuildFile; fileRef = FE5932A6183C5A2600A1ECCC /* VMEntryScope.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2450 2452 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 */; }; 2451 2455 FE6491371D78F01D00A694D4 /* ExceptionScope.h in Headers */ = {isa = PBXBuildFile; fileRef = FE6491361D78F01300A694D4 /* ExceptionScope.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2452 2456 FE6491391D78F3AF00A694D4 /* ExceptionScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE6491381D78F3A300A694D4 /* ExceptionScope.cpp */; }; … … 5072 5076 FE5068641AE246390009DAB7 /* DeferredSourceDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeferredSourceDump.h; sourceTree = "<group>"; }; 5073 5077 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>"; }; 5074 5080 FE5932A5183C5A2600A1ECCC /* VMEntryScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMEntryScope.cpp; sourceTree = "<group>"; }; 5075 5081 FE5932A6183C5A2600A1ECCC /* VMEntryScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMEntryScope.h; sourceTree = "<group>"; }; 5076 5082 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>"; }; 5077 5085 FE6491361D78F01300A694D4 /* ExceptionScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExceptionScope.h; sourceTree = "<group>"; }; 5078 5086 FE6491381D78F3A300A694D4 /* ExceptionScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExceptionScope.cpp; sourceTree = "<group>"; }; … … 5653 5661 0FEC855E1BDACDC70080FF74 /* AirPhaseScope.cpp */, 5654 5662 0FEC855F1BDACDC70080FF74 /* AirPhaseScope.h */, 5663 FE5628CB1E99512400C49E45 /* AirPrintSpecial.cpp */, 5664 FE5628CC1E99512400C49E45 /* AirPrintSpecial.h */, 5655 5665 0FF4B4BA1E88449500DBBE86 /* AirRegLiveness.cpp */, 5656 5666 0FF4B4BB1E88449500DBBE86 /* AirRegLiveness.h */, … … 7527 7537 65860177185A8F5E00030EEE /* MaxFrameExtentForSlowPathCall.h */, 7528 7538 86C568DF11A213EE0007F7F0 /* MIPSAssembler.h */, 7539 FE63DD551EA9BC5D00103A69 /* Printer.cpp */, 7540 FE63DD531EA9B60E00103A69 /* Printer.h */, 7529 7541 9688CB140ED12B4E001D649F /* X86Assembler.h */, 7530 7542 ); … … 8266 8278 0F33FCF81C136E2500323F67 /* B3StackmapGenerationParams.h in Headers */, 8267 8279 0FEC85311BDACDAC0080FF74 /* B3StackmapSpecial.h in Headers */, 8280 FE5628CE1E99513200C49E45 /* AirPrintSpecial.h in Headers */, 8268 8281 0F338DF21BE93AD10013C88F /* B3StackmapValue.h in Headers */, 8269 8282 0F9495881C57F47500413A48 /* B3StackSlot.h in Headers */, … … 8547 8560 0FFB921C16D02F110055A5DB /* DFGOSRExitCompilationInfo.h in Headers */, 8548 8561 0FC0977114693AF500CF2442 /* DFGOSRExitCompiler.h in Headers */, 8562 FE63DD541EA9B61E00103A69 /* Printer.h in Headers */, 8549 8563 0F7025AA1714B0FC00382C0E /* DFGOSRExitCompilerCommon.h in Headers */, 8550 8564 0F392C8A1B46188400844728 /* DFGOSRExitFuzz.h in Headers */, … … 10315 10329 0F2FCCFB18A60070001A27F8 /* DFGSafepoint.cpp in Sources */, 10316 10330 86EC9DD21328DF82002B2AD7 /* DFGSpeculativeJIT.cpp in Sources */, 10331 FE63DD561EA9BC6700103A69 /* Printer.cpp in Sources */, 10317 10332 86880F1F14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp in Sources */, 10318 10333 86880F4D14353B2100B08D42 /* DFGSpeculativeJIT64.cpp in Sources */, … … 10545 10560 14ABDF600A437FEF00ECCA01 /* JSCallbackObject.cpp in Sources */, 10546 10561 657CF45819BF6662004ACBF2 /* JSCallee.cpp in Sources */, 10562 FE5628CD1E99512D00C49E45 /* AirPrintSpecial.cpp in Sources */, 10547 10563 A7D801A81880D6A80026C39B /* JSCBuiltins.cpp in Sources */, 10548 10564 147F39D1107EC37600427A48 /* JSCell.cpp in Sources */, -
trunk/Source/JavaScriptCore/assembler/MacroAssembler.h
r215592 r215642 63 63 64 64 namespace JSC { 65 66 namespace Printer { 67 68 struct PrintRecord; 69 typedef Vector<PrintRecord> PrintRecordList; 70 71 } 65 72 66 73 class MacroAssembler : public MacroAssemblerBase { … … 1821 1828 // See comments in MacroAssemblerPrinter.h for examples of how to use this. 1822 1829 template<typename... Arguments> 1823 void print(Arguments... args); 1830 void print(Arguments&&... args); 1831 1832 void print(Printer::PrintRecordList*); 1824 1833 }; 1825 1834 -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerPrinter.cpp
r215592 r215642 32 32 33 33 namespace JSC { 34 namespace Printer { 34 35 35 36 using CPUState = MacroAssembler::CPUState; … … 37 38 using FPRegisterID = MacroAssembler::FPRegisterID; 38 39 39 static void printIndent(int indentation)40 void printAllRegisters(PrintStream& out, Context& context) 40 41 { 41 for (; indentation > 0; indentation--) 42 dataLog(" "); 43 } 42 auto& cpu = context.probeContext.cpu; 43 unsigned charsToIndent = context.data.as<unsigned>(); 44 44 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() 53 50 54 void printCPURegisters(CPUState& cpu, int indentation) 55 { 51 INDENT, out.print("cpu: {\n"); 52 56 53 #if USE(JSVALUE32_64) 57 54 #define INTPTR_HEX_VALUE_FORMAT "0x%08lx" … … 62 59 #define PRINT_GPREGISTER(_type, _regName) { \ 63 60 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) ; \ 65 62 } 66 63 FOR_EACH_CPU_GPREGISTER(PRINT_GPREGISTER) … … 72 69 uint64_t* u = reinterpret_cast<uint64_t*>(&cpu._regName); \ 73 70 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); \ 75 72 } 76 73 FOR_EACH_CPU_FPREGISTER(PRINT_FPREGISTER) 77 74 #undef PRINT_FPREGISTER 75 76 INDENT, out.print("}\n"); 77 #undef INDENT 78 78 79 } 79 80 80 static void printPC(CPUState& cpu)81 void printPCRegister(PrintStream& out, Context& context) 81 82 { 82 union { 83 void* voidPtr; 84 intptr_t intptrValue; 85 } u; 83 auto cpu = context.probeContext.cpu; 84 void* value; 86 85 #if CPU(X86) || CPU(X86_64) 87 u.voidPtr= cpu.eip;86 value = cpu.eip; 88 87 #elif CPU(ARM_TRADITIONAL) || CPU(ARM_THUMB2) || CPU(ARM64) 89 u.voidPtr= cpu.pc;88 value = cpu.pc; 90 89 #else 91 90 #error "Unsupported CPU" 92 91 #endif 93 dataLogF("pc:<%p %ld>", u.voidPtr, u.intptrValue);92 out.printf("pc:<%p %ld>", value, bitwise_cast<intptr_t>(value)); 94 93 } 95 94 96 void printRegister (CPUState& cpu, RegisterID regID)95 void printRegisterID(PrintStream& out, Context& context) 97 96 { 97 RegisterID regID = context.data.as<RegisterID>(); 98 98 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)); 105 101 } 106 102 107 void print Register(CPUState& cpu, FPRegisterID regID)103 void printFPRegisterID(PrintStream& out, Context& context) 108 104 { 105 FPRegisterID regID = context.data.as<FPRegisterID>(); 109 106 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); 116 109 } 117 110 118 void print Memory(CPUState& cpu, const Memory& memory)111 void printAddress(PrintStream& out, Context& context) 119 112 { 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 120 void printMemory(PrintStream& out, Context& context) 121 { 122 const Memory& memory = context.data.as<Memory>(); 123 120 124 uint8_t* ptr = nullptr; 121 125 switch (memory.addressType) { 122 126 case Memory::AddressType::Address: { 123 ptr = reinterpret_cast<uint8_t*>(c pu.gpr(memory.u.address.base));127 ptr = reinterpret_cast<uint8_t*>(context.probeContext.gpr(memory.u.address.base)); 124 128 ptr += memory.u.address.offset; 125 129 break; … … 134 138 if (memory.numBytes == sizeof(int8_t)) { 135 139 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); 137 141 return; 138 142 } 139 143 if (memory.numBytes == sizeof(int16_t)) { 140 144 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); 142 146 return; 143 147 } 144 148 if (memory.numBytes == sizeof(int32_t)) { 145 149 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); 147 151 return; 148 152 } 149 153 if (memory.numBytes == sizeof(int64_t)) { 150 154 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); 152 156 return; 153 157 } … … 159 163 for (size_t i = 0; i < numBytes; i++) { 160 164 if (!(i % 16)) 161 dataLogF("%p: ", &ptr[i]);165 out.printf("%p: ", &ptr[i]); 162 166 else if (!(i % 4)) 163 dataLog(" ");167 out.printf(" "); 164 168 165 dataLogF("%02x", ptr[i]);169 out.printf("%02x", ptr[i]); 166 170 167 171 if (i % 16 == 15) 168 dataLog("\n");172 out.print("\n"); 169 173 } 170 174 if (numBytes % 16 < 15) 171 dataLog("\n");175 out.print("\n"); 172 176 } 173 177 174 void MacroAssemblerPrinter::printCallback(ProbeContext* context)178 void printCallback(ProbeContext* probeContext) 175 179 { 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); 210 186 } 211 187 } 212 188 189 } // namespace Printer 213 190 } // namespace JSC 214 191 -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerPrinter.h
r215595 r215642 27 27 28 28 #include "MacroAssembler.h" 29 #include "Printer.h" 29 30 30 31 namespace JSC { … … 55 56 // 56 57 // 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. 58 60 // 59 61 // RegisterID regID = ...; … … 62 64 // // Emits code to print all registers. Unlike other items, this prints 63 65 // // 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)); 70 73 // 71 74 // jit.print(MemWord<uint8_t>(regID), "\n"); // Emits code to print a byte pointed to by the register. … … 82 85 // jit.print("cb:", cb, " regID:", regID, " cpu:\n", AllRegisters()); 83 86 // 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. 85 89 // 86 90 // Note: print() does not automatically insert a '\n' at the end of the line. … … 88 92 89 93 90 // This is a marker type only used with MacroAssemblerPrinter::print(). 91 // See MacroAssemblerPrinter::print() below for details. 92 struct AllRegisters { }; 94 struct AllRegisters { 95 explicit AllRegisters(unsigned charsToIndent = 0) 96 : charsToIndent(charsToIndent) 97 { } 98 unsigned charsToIndent; 99 }; 93 100 struct PCRegister { }; 94 101 … … 108 115 }; 109 116 110 Memory(RegisterID& reg, size_t bytes, DumpStyle style = GenericDump)117 explicit Memory(RegisterID& reg, size_t bytes, DumpStyle style = GenericDump) 111 118 : addressType(AddressType::Address) 112 119 , dumpStyle(style) … … 116 123 } 117 124 118 Memory(const Address& address, size_t bytes, DumpStyle style = GenericDump)125 explicit Memory(const Address& address, size_t bytes, DumpStyle style = GenericDump) 119 126 : addressType(AddressType::Address) 120 127 , dumpStyle(style) … … 124 131 } 125 132 126 Memory(const AbsoluteAddress& address, size_t bytes, DumpStyle style = GenericDump)133 explicit Memory(const AbsoluteAddress& address, size_t bytes, DumpStyle style = GenericDump) 127 134 : addressType(AddressType::AbsoluteAddress) 128 135 , dumpStyle(style) … … 145 152 template <typename IntType> 146 153 struct MemWord : public Memory { 147 MemWord(RegisterID& reg)154 explicit MemWord(RegisterID& reg) 148 155 : Memory(reg, sizeof(IntType), Memory::SingleWordDump) 149 156 { } 150 157 151 MemWord(const Address& address)158 explicit MemWord(const Address& address) 152 159 : Memory(address, sizeof(IntType), Memory::SingleWordDump) 153 160 { } 154 161 155 MemWord(const AbsoluteAddress& address)162 explicit MemWord(const AbsoluteAddress& address) 156 163 : Memory(address, sizeof(IntType), Memory::SingleWordDump) 157 164 { } 158 165 }; 159 166 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 }; 167 namespace Printer { 168 169 // Add some specialized printers. 170 171 void printAllRegisters(PrintStream&, Context&); 172 void printPCRegister(PrintStream&, Context&); 173 void printRegisterID(PrintStream&, Context&); 174 void printFPRegisterID(PrintStream&, Context&); 175 void printAddress(PrintStream&, Context&); 176 void printMemory(PrintStream&, Context&); 177 178 template<> 179 struct Printer<AllRegisters> : public PrintRecord { 180 Printer(AllRegisters allRegisters) 181 : PrintRecord(static_cast<uintptr_t>(allRegisters.charsToIndent), printAllRegisters) 182 { } 183 }; 184 185 template<> 186 struct Printer<PCRegister> : public PrintRecord { 187 Printer(PCRegister&) 188 : PrintRecord(printPCRegister) 189 { } 190 }; 191 192 template<> 193 struct Printer<MacroAssembler::RegisterID> : public PrintRecord { 194 Printer(MacroAssembler::RegisterID id) 195 : PrintRecord(static_cast<uintptr_t>(id), printRegisterID) 196 { } 197 }; 198 199 template<> 200 struct Printer<MacroAssembler::FPRegisterID> : public PrintRecord { 201 Printer(MacroAssembler::FPRegisterID id) 202 : PrintRecord(static_cast<uintptr_t>(id), printFPRegisterID) 203 { } 204 }; 205 206 template<> 207 struct Printer<MacroAssembler::Address> : public PrintRecord { 208 Printer(MacroAssembler::Address address) 209 : PrintRecord(Data(&address, sizeof(address)), printAddress) 210 { } 211 }; 212 213 template<> 214 struct Printer<Memory> : public PrintRecord { 215 Printer(Memory memory) 216 : PrintRecord(Data(&memory, sizeof(memory)), printMemory) 217 { } 218 }; 219 220 template<typename IntType> 221 struct Printer<MemWord<IntType>> : public Printer<Memory> { 222 Printer(MemWord<IntType> word) 223 : Printer<Memory>(word) 224 { } 225 }; 226 227 void printCallback(ProbeContext*); 228 229 } // namespace Printer 282 230 283 231 template<typename... Arguments> 284 void MacroAssembler::print(Arguments... args)232 inline void MacroAssembler::print(Arguments&&... arguments) 285 233 { 286 MacroAssemblerPrinter::print(this, args...); 234 auto printRecordList = Printer::makePrintRecordList(std::forward<Arguments>(arguments)...); 235 probe(Printer::printCallback, printRecordList); 287 236 } 288 237 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&); 238 inline void MacroAssembler::print(Printer::PrintRecordList* printRecordList) 239 { 240 probe(Printer::printCallback, printRecordList); 241 } 300 242 301 243 #else // ENABLE(MASM_PROBE) 302 244 303 245 template<typename... Arguments> 304 void MacroAssembler::print(Arguments...) { } 246 inline void MacroAssembler::print(Arguments&&...) { } 247 248 inline void MacroAssembler::print(Printer::PrintRecordList*) { } 305 249 306 250 #endif // ENABLE(MASM_PROBE) -
trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp
r215565 r215642 34 34 #include "AirInsertionSet.h" 35 35 #include "AirInstInlines.h" 36 #include "AirPrintSpecial.h" 36 37 #include "AirStackSlot.h" 37 38 #include "B3ArgumentRegValue.h" … … 1128 1129 } 1129 1130 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 1130 1153 template<typename... Arguments> 1131 1154 void append(Air::Opcode opcode, Arguments&&... arguments) -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r215476 r215642 3112 3112 } 3113 3113 3114 void setPrinter(Printer::PrintRecord& record, CodeBlock* codeBlock) 3115 { 3116 Printer::setPrinter(record, toCString(codeBlock)); 3117 } 3114 3118 3115 3119 } // namespace JSC 3120 3121 namespace WTF { 3122 3123 void 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 61 61 #include "ObjectAllocationProfile.h" 62 62 #include "Options.h" 63 #include "Printer.h" 63 64 #include "ProfilerJettisonReason.h" 64 65 #include "ProgramExecutable.h" … … 1088 1089 (codeBlock->vm()->logEvent(codeBlock, summary, [&] () { return toCString details; })) 1089 1090 1091 1092 void setPrinter(Printer::PrintRecord&, CodeBlock*); 1093 1090 1094 } // namespace JSC 1095 1096 namespace WTF { 1097 1098 JS_EXPORT_PRIVATE void printInternal(PrintStream&, JSC::CodeBlock*); 1099 1100 } // namespace WTF -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r214905 r215642 606 606 if (Options::breakOnThrow()) { 607 607 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"); 613 609 CRASH(); 614 610 }
Note:
See TracChangeset
for help on using the changeset viewer.