Changeset 176233 in webkit
- Timestamp:
- Nov 17, 2014 2:03:04 PM (9 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r176219 r176233 1 2014-11-17 Mark Lam <mark.lam@apple.com> 2 3 Add printing functionality in JITted code for debugging purposes. 4 <https://webkit.org/b/138660> 5 6 Reviewed by Geoffrey Garen. 7 8 Sometimes, for debugging, it'd be nice to be able to just print the 9 values of constants or registers used in JITted code, or even just 10 a string to log that certain pieces of JITted code have been executed. 11 Using the JIT probe mechanism, we can make this happen. 12 13 * assembler/ARMv7Assembler.h: 14 * assembler/AbstractMacroAssembler.h: 15 (JSC::AbstractMacroAssembler::CPUState::registerName): 16 (JSC::AbstractMacroAssembler::CPUState::registerValue): 17 (JSC::AbstractMacroAssembler::print): 18 (JSC::AbstractMacroAssembler::PrintArg::PrintArg): 19 (JSC::AbstractMacroAssembler::appendPrintArg): 20 (JSC::AbstractMacroAssembler::printInternal): 21 (JSC::AbstractMacroAssembler::printCallback): 22 * assembler/MacroAssemblerARM.cpp: 23 (JSC::MacroAssemblerARM::printCPURegisters): 24 (JSC::MacroAssemblerARM::printRegister): 25 * assembler/MacroAssemblerARM.h: 26 * assembler/MacroAssemblerARMv7.cpp: 27 (JSC::MacroAssemblerARMv7::printCPURegisters): 28 (JSC::MacroAssemblerARMv7::printRegister): 29 * assembler/MacroAssemblerARMv7.h: 30 * assembler/MacroAssemblerX86Common.cpp: 31 (JSC::MacroAssemblerX86Common::printRegister): 32 * assembler/MacroAssemblerX86Common.h: 33 1 34 2014-11-17 Anders Carlsson <andersca@apple.com> 2 35 -
trunk/Source/JavaScriptCore/assembler/ARMv7Assembler.h
r176151 r176233 206 206 } 207 207 208 } // namespace ARMRegister 208 } // namespace ARMRegisters 209 209 210 210 class ARMv7Assembler; -
trunk/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
r176134 r176233 845 845 FOR_EACH_CPU_REGISTER(DECLARE_REGISTER) 846 846 #undef DECLARE_REGISTER 847 848 static const char* registerName(RegisterID regID) 849 { 850 switch (regID) { 851 #define DECLARE_REGISTER(_type, _regName) \ 852 case RegisterID::_regName: \ 853 return #_regName; 854 FOR_EACH_CPU_GPREGISTER(DECLARE_REGISTER) 855 #undef DECLARE_REGISTER 856 } 857 RELEASE_ASSERT_NOT_REACHED(); 858 } 859 860 static const char* registerName(FPRegisterID regID) 861 { 862 switch (regID) { 863 #define DECLARE_REGISTER(_type, _regName) \ 864 case FPRegisterID::_regName: \ 865 return #_regName; 866 FOR_EACH_CPU_FPREGISTER(DECLARE_REGISTER) 867 #undef DECLARE_REGISTER 868 } 869 RELEASE_ASSERT_NOT_REACHED(); 870 } 871 872 void* registerValue(RegisterID regID) 873 { 874 switch (regID) { 875 #define DECLARE_REGISTER(_type, _regName) \ 876 case RegisterID::_regName: \ 877 return _regName; 878 FOR_EACH_CPU_GPREGISTER(DECLARE_REGISTER) 879 #undef DECLARE_REGISTER 880 } 881 RELEASE_ASSERT_NOT_REACHED(); 882 } 883 884 double registerValue(FPRegisterID regID) 885 { 886 switch (regID) { 887 #define DECLARE_REGISTER(_type, _regName) \ 888 case FPRegisterID::_regName: \ 889 return _regName; 890 FOR_EACH_CPU_FPREGISTER(DECLARE_REGISTER) 891 #undef DECLARE_REGISTER 892 } 893 RELEASE_ASSERT_NOT_REACHED(); 894 } 895 847 896 }; 848 897 … … 892 941 } 893 942 943 // This is a marker type only used with print(). See print() below for details. 944 struct AllRegisters { }; 945 946 // Emits code which will print debugging info at runtime. The type of values that 947 // can be printed is encapsulated in the PrintArg struct below. Here are some 948 // examples: 949 // 950 // print("Hello world\n"); // Emits code to print the string. 951 // 952 // CodeBlock* cb = ...; 953 // print(cb); // Emits code to print the pointer value. 954 // 955 // RegisterID regID = ...; 956 // print(regID); // Emits code to print the register value (not the id). 957 // 958 // // Emits code to print all registers. Unlike other items, this prints 959 // // multiple lines as follows: 960 // // cpu { 961 // // eax: 0x123456789 962 // // ebx: 0x000000abc 963 // // ... 964 // // } 965 // print(AllRegisters()); 966 // 967 // // Print multiple things at once. This incurs the probe overhead only once 968 // // to print all the items. 969 // print("cb:", cb, " regID:", regID, " cpu:\n", AllRegisters()); 970 971 template<typename... Arguments> 972 void print(Arguments... args) 973 { 974 printInternal(static_cast<MacroAssemblerType*>(this), args...); 975 } 894 976 895 977 // This function will be called by printCPU() to print the contents of the 896 // target specific registers which are saved away in the CPU Infostruct.978 // target specific registers which are saved away in the CPUState struct. 897 979 // printCPURegisters() should make use of printIndentation() to print the 898 980 // registers with the appropriate amount of indentation. … … 904 986 static void printCPURegisters(CPUState&, int indentation = 0); 905 987 906 // This function emits code to preserve the CPUInfo (e.g. registers), 907 // call a user supplied probe function, and restore the CPUInfo before 988 // This function will be called by print() to print the contents of a 989 // specific register (from the CPUState) in line with other items in the 990 // print stream. Hence, no indentation is needed. 991 // 992 // Note: printRegister() should be implemented by the target specific 993 // MacroAssembler. These prototypes are only provided here to document their 994 // interface. 995 996 static void printRegister(CPUState&, RegisterID); 997 static void printRegister(CPUState&, FPRegisterID); 998 999 // This function emits code to preserve the CPUState (e.g. registers), 1000 // call a user supplied probe function, and restore the CPUState before 908 1001 // continuing with other JIT generated code. 909 1002 // 910 1003 // The user supplied probe function will be called with a single pointer to 911 1004 // a ProbeContext struct (defined above) which contains, among other things, 912 // the preserved CPU Info. This allows the user probe function to inspect913 // the CPU Infoat that point in the JIT generated code.1005 // the preserved CPUState. This allows the user probe function to inspect 1006 // the CPUState at that point in the JIT generated code. 914 1007 // 915 1008 // If the user probe function alters the register values in the ProbeContext, … … 1086 1179 AssemblerType::replaceWithAddressComputation(label.dataLocation()); 1087 1180 } 1088 }; 1181 1182 private: 1183 1184 #if ENABLE(MASM_PROBE) 1185 1186 struct PrintArg { 1187 1188 enum class Type { 1189 AllRegisters, 1190 RegisterID, 1191 FPRegisterID, 1192 ConstCharPtr, 1193 ConstVoidPtr, 1194 IntptrValue, 1195 UintptrValue, 1196 }; 1197 1198 PrintArg(AllRegisters&) 1199 : type(Type::AllRegisters) 1200 { 1201 } 1202 1203 PrintArg(RegisterID regID) 1204 : type(Type::RegisterID) 1205 { 1206 u.gpRegisterID = regID; 1207 } 1208 1209 PrintArg(FPRegisterID regID) 1210 : type(Type::FPRegisterID) 1211 { 1212 u.fpRegisterID = regID; 1213 } 1214 1215 PrintArg(const char* ptr) 1216 : type(Type::ConstCharPtr) 1217 { 1218 u.constCharPtr = ptr; 1219 } 1220 1221 PrintArg(const void* ptr) 1222 : type(Type::ConstVoidPtr) 1223 { 1224 u.constVoidPtr = ptr; 1225 } 1226 1227 PrintArg(int value) 1228 : type(Type::IntptrValue) 1229 { 1230 u.intptrValue = value; 1231 } 1232 1233 PrintArg(unsigned value) 1234 : type(Type::UintptrValue) 1235 { 1236 u.intptrValue = value; 1237 } 1238 1239 PrintArg(intptr_t value) 1240 : type(Type::IntptrValue) 1241 { 1242 u.intptrValue = value; 1243 } 1244 1245 PrintArg(uintptr_t value) 1246 : type(Type::UintptrValue) 1247 { 1248 u.uintptrValue = value; 1249 } 1250 1251 Type type; 1252 union { 1253 RegisterID gpRegisterID; 1254 FPRegisterID fpRegisterID; 1255 const char* constCharPtr; 1256 const void* constVoidPtr; 1257 intptr_t intptrValue; 1258 uintptr_t uintptrValue; 1259 } u; 1260 }; 1261 1262 typedef Vector<PrintArg> PrintArgsList; 1263 1264 template<typename FirstArg, typename... Arguments> 1265 static void appendPrintArg(PrintArgsList* argsList, FirstArg& firstArg, Arguments... otherArgs) 1266 { 1267 argsList->append(PrintArg(firstArg)); 1268 appendPrintArg(argsList, otherArgs...); 1269 } 1270 1271 static void appendPrintArg(PrintArgsList*) { } 1272 1273 1274 template<typename... Arguments> 1275 static void printInternal(MacroAssemblerType* masm, Arguments... args) 1276 { 1277 auto argsList = std::make_unique<PrintArgsList>(); 1278 appendPrintArg(argsList.get(), args...); 1279 masm->probe(printCallback, argsList.release()); 1280 } 1281 1282 static void printCallback(ProbeContext* context) 1283 { 1284 typedef PrintArg Arg; 1285 PrintArgsList& argsList = 1286 *reinterpret_cast<PrintArgsList*>(context->arg1); 1287 for (size_t i = 0; i < argsList.size(); i++) { 1288 auto& arg = argsList[i]; 1289 switch (arg.type) { 1290 case Arg::Type::AllRegisters: 1291 MacroAssemblerType::printCPU(context->cpu); 1292 break; 1293 case Arg::Type::RegisterID: 1294 MacroAssemblerType::printRegister(context->cpu, arg.u.gpRegisterID); 1295 break; 1296 case Arg::Type::FPRegisterID: 1297 MacroAssemblerType::printRegister(context->cpu, arg.u.fpRegisterID); 1298 break; 1299 case Arg::Type::ConstCharPtr: 1300 dataLog(arg.u.constCharPtr); 1301 break; 1302 case Arg::Type::ConstVoidPtr: 1303 dataLogF("%p", arg.u.constVoidPtr); 1304 break; 1305 case Arg::Type::IntptrValue: 1306 dataLog(arg.u.intptrValue); 1307 break; 1308 case Arg::Type::UintptrValue: 1309 dataLog(arg.u.uintptrValue); 1310 break; 1311 } 1312 } 1313 } 1314 1315 #endif // ENABLE(MASM_PROBE) 1316 1317 }; // class AbstractMacroAssembler 1089 1318 1090 1319 } // namespace JSC -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM.cpp
r176134 r176233 102 102 void MacroAssemblerARM::printCPURegisters(CPUState& cpu, int indentation) 103 103 { 104 #define DUMP_GPREGISTER(_type, _regName) { \104 #define PRINT_GPREGISTER(_type, _regName) { \ 105 105 int32_t value = reinterpret_cast<int32_t>(cpu._regName); \ 106 106 INDENT, dataLogF("%5s: 0x%08x %d\n", #_regName, value, value) ; \ 107 107 } 108 FOR_EACH_CPU_GPREGISTER( DUMP_GPREGISTER)109 FOR_EACH_CPU_SPECIAL_REGISTER( DUMP_GPREGISTER)110 #undef DUMP_GPREGISTER108 FOR_EACH_CPU_GPREGISTER(PRINT_GPREGISTER) 109 FOR_EACH_CPU_SPECIAL_REGISTER(PRINT_GPREGISTER) 110 #undef PRINT_GPREGISTER 111 111 112 #define DUMP_FPREGISTER(_type, _regName) { \112 #define PRINT_FPREGISTER(_type, _regName) { \ 113 113 uint64_t* u = reinterpret_cast<uint64_t*>(&cpu._regName); \ 114 114 double* d = reinterpret_cast<double*>(&cpu._regName); \ 115 115 INDENT, dataLogF("%5s: 0x%016llx %.13g\n", #_regName, *u, *d); \ 116 116 } 117 FOR_EACH_CPU_FPREGISTER( DUMP_FPREGISTER)118 #undef DUMP_FPREGISTER117 FOR_EACH_CPU_FPREGISTER(PRINT_FPREGISTER) 118 #undef PRINT_FPREGISTER 119 119 } 120 120 121 121 #undef INDENT 122 123 void MacroAssemblerARM::printRegister(MacroAssemblerARM::CPUState& cpu, RegisterID regID) 124 { 125 const char* name = CPUState::registerName(regID); 126 union { 127 void* voidPtr; 128 intptr_t intptrValue; 129 } u; 130 u.voidPtr = cpu.registerValue(regID); 131 dataLogF("%s:<%p %ld>", name, u.voidPtr, u.intptrValue); 132 } 133 134 void MacroAssemblerARM::printRegister(MacroAssemblerARM::CPUState& cpu, FPRegisterID regID) 135 { 136 const char* name = CPUState::registerName(regID); 137 union { 138 double doubleValue; 139 uint64_t uint64Value; 140 } u; 141 u.doubleValue = cpu.registerValue(regID); 142 dataLogF("%s:<0x%016llx %.13g>", name, u.uint64Value, u.doubleValue); 143 } 122 144 123 145 extern "C" void ctiMasmProbeTrampoline(); -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
r176134 r176233 1437 1437 // AbstractMacroAssembler.h. 1438 1438 static void printCPURegisters(CPUState&, int indentation = 0); 1439 static void printRegister(CPUState&, RegisterID); 1440 static void printRegister(CPUState&, FPRegisterID); 1439 1441 void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0); 1440 1442 #endif // ENABLE(MASM_PROBE) -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.cpp
r176134 r176233 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 37 37 void MacroAssemblerARMv7::printCPURegisters(CPUState& cpu, int indentation) 38 38 { 39 #define DUMP_GPREGISTER(_type, _regName) { \39 #define PRINT_GPREGISTER(_type, _regName) { \ 40 40 int32_t value = reinterpret_cast<int32_t>(cpu._regName); \ 41 41 INDENT, dataLogF("%5s: 0x%08x %d\n", #_regName, value, value) ; \ 42 42 } 43 FOR_EACH_CPU_GPREGISTER( DUMP_GPREGISTER)44 FOR_EACH_CPU_SPECIAL_REGISTER( DUMP_GPREGISTER)45 #undef DUMP_GPREGISTER43 FOR_EACH_CPU_GPREGISTER(PRINT_GPREGISTER) 44 FOR_EACH_CPU_SPECIAL_REGISTER(PRINT_GPREGISTER) 45 #undef PRINT_GPREGISTER 46 46 47 #define DUMP_FPREGISTER(_type, _regName) { \47 #define PRINT_FPREGISTER(_type, _regName) { \ 48 48 uint64_t* u = reinterpret_cast<uint64_t*>(&cpu._regName); \ 49 49 double* d = reinterpret_cast<double*>(&cpu._regName); \ 50 50 INDENT, dataLogF("%5s: 0x%016llx %.13g\n", #_regName, *u, *d); \ 51 51 } 52 FOR_EACH_CPU_FPREGISTER( DUMP_FPREGISTER)53 #undef DUMP_FPREGISTER52 FOR_EACH_CPU_FPREGISTER(PRINT_FPREGISTER) 53 #undef PRINT_FPREGISTER 54 54 } 55 55 56 56 #undef INDENT 57 58 void MacroAssemblerARMv7::printRegister(MacroAssemblerARMv7::CPUState& cpu, RegisterID regID) 59 { 60 const char* name = CPUState::registerName(regID); 61 union { 62 void* voidPtr; 63 intptr_t intptrValue; 64 } u; 65 u.voidPtr = cpu.registerValue(regID); 66 dataLogF("%s:<%p %ld>", name, u.voidPtr, u.intptrValue); 67 } 68 69 void MacroAssemblerARMv7::printRegister(MacroAssemblerARMv7::CPUState& cpu, FPRegisterID regID) 70 { 71 const char* name = CPUState::registerName(regID); 72 union { 73 double doubleValue; 74 uint64_t uint64Value; 75 } u; 76 u.doubleValue = cpu.registerValue(regID); 77 dataLogF("%s:<0x%016llx %.13g>", name, u.uint64Value, u.doubleValue); 78 } 57 79 58 80 extern "C" void ctiMasmProbeTrampoline(); -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
r176134 r176233 1906 1906 // AbstractMacroAssembler.h. 1907 1907 static void printCPURegisters(CPUState&, int indentation = 0); 1908 static void printRegister(CPUState&, RegisterID); 1909 static void printRegister(CPUState&, FPRegisterID); 1908 1910 void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0); 1909 1911 #endif // ENABLE(MASM_PROBE) -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.cpp
r176134 r176233 62 62 63 63 #undef INDENT 64 65 void MacroAssemblerX86Common::printRegister(MacroAssemblerX86Common::CPUState& cpu, RegisterID regID) 66 { 67 const char* name = CPUState::registerName(regID); 68 union { 69 void* voidPtr; 70 intptr_t intptrValue; 71 } u; 72 u.voidPtr = cpu.registerValue(regID); 73 dataLogF("%s:<%p %ld>", name, u.voidPtr, u.intptrValue); 74 } 75 76 void MacroAssemblerX86Common::printRegister(MacroAssemblerX86Common::CPUState& cpu, FPRegisterID regID) 77 { 78 const char* name = CPUState::registerName(regID); 79 union { 80 double doubleValue; 81 uint64_t uint64Value; 82 } u; 83 u.doubleValue = cpu.registerValue(regID); 84 dataLogF("%s:<0x%016llx %.13g>", name, u.uint64Value, u.doubleValue); 85 } 64 86 65 87 extern "C" void ctiMasmProbeTrampoline(); -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
r176134 r176233 1 1 /* 2 * Copyright (C) 2008 Apple Inc. All rights reserved.2 * Copyright (C) 2008, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 1474 1474 // AbstractMacroAssembler.h. 1475 1475 static void printCPURegisters(CPUState&, int indentation = 0); 1476 static void printRegister(CPUState&, RegisterID); 1477 static void printRegister(CPUState&, FPRegisterID); 1476 1478 void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0); 1477 1479 #endif // ENABLE(MASM_PROBE)
Note: See TracChangeset
for help on using the changeset viewer.