diff options
Diffstat (limited to 'Source/JavaScriptCore/assembler/AbstractMacroAssembler.h')
-rw-r--r-- | Source/JavaScriptCore/assembler/AbstractMacroAssembler.h | 383 |
1 files changed, 28 insertions, 355 deletions
diff --git a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h index 6e82dcc5e..28537201b 100644 --- a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h +++ b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, 2012, 2014, 2015 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2012 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,7 +26,6 @@ #ifndef AbstractMacroAssembler_h #define AbstractMacroAssembler_h -#include "AbortReason.h" #include "AssemblerBuffer.h" #include "CodeLocation.h" #include "MacroAssemblerCodeRef.h" @@ -39,9 +38,9 @@ namespace JSC { -inline bool isARMv7IDIVSupported() +inline bool isARMv7s() { -#if HAVE(ARM_IDIV_INSTRUCTIONS) +#if CPU(APPLE_ARMV7S) return true; #else return false; @@ -66,9 +65,9 @@ inline bool isX86() #endif } -inline bool optimizeForARMv7IDIVSupported() +inline bool optimizeForARMv7s() { - return isARMv7IDIVSupported() && Options::enableArchitectureSpecificOptimizations(); + return isARMv7s() && Options::enableArchitectureSpecificOptimizations(); } inline bool optimizeForARM64() @@ -88,11 +87,10 @@ namespace DFG { struct OSRExit; } -template <class AssemblerType, class MacroAssemblerType> +template <class AssemblerType> class AbstractMacroAssembler { public: friend class JITWriteBarrierBase; - typedef AbstractMacroAssembler<AssemblerType, MacroAssemblerType> AbstractMacroAssemblerType; typedef AssemblerType AssemblerType_T; typedef MacroAssemblerCodePtr CodePtr; @@ -142,7 +140,7 @@ public: { return Address(base, offset + additionalOffset); } - + RegisterID base; int32_t offset; }; @@ -205,11 +203,6 @@ public: RegisterID index; Scale scale; int32_t offset; - - BaseIndex withOffset(int32_t additionalOffset) - { - return BaseIndex(base, index, scale, offset + additionalOffset); - } }; // AbsoluteAddress: @@ -361,7 +354,7 @@ public: // A Label records a point in the generated instruction stream, typically such that // it may be used as a destination for a jump. class Label { - template<class TemplateAssemblerType, class TemplateMacroAssemblerType> + template<class TemplateAssemblerType> friend class AbstractMacroAssembler; friend struct DFG::OSRExit; friend class Jump; @@ -374,7 +367,7 @@ public: { } - Label(AbstractMacroAssemblerType* masm) + Label(AbstractMacroAssembler<AssemblerType>* masm) : m_label(masm->m_assembler.label()) { masm->invalidateAllTempRegisters(); @@ -396,7 +389,7 @@ public: // // addPtr(TrustedImmPtr(i), a, b) class ConvertibleLoadLabel { - template<class TemplateAssemblerType, class TemplateMacroAssemblerType> + template<class TemplateAssemblerType> friend class AbstractMacroAssembler; friend class LinkBuffer; @@ -405,7 +398,7 @@ public: { } - ConvertibleLoadLabel(AbstractMacroAssemblerType* masm) + ConvertibleLoadLabel(AbstractMacroAssembler<AssemblerType>* masm) : m_label(masm->m_assembler.labelIgnoringWatchpoints()) { } @@ -420,7 +413,7 @@ public: // A DataLabelPtr is used to refer to a location in the code containing a pointer to be // patched after the code has been generated. class DataLabelPtr { - template<class TemplateAssemblerType, class TemplateMacroAssemblerType> + template<class TemplateAssemblerType> friend class AbstractMacroAssembler; friend class LinkBuffer; public: @@ -428,7 +421,7 @@ public: { } - DataLabelPtr(AbstractMacroAssemblerType* masm) + DataLabelPtr(AbstractMacroAssembler<AssemblerType>* masm) : m_label(masm->m_assembler.label()) { } @@ -441,10 +434,10 @@ public: // DataLabel32: // - // A DataLabel32 is used to refer to a location in the code containing a 32-bit constant to be + // A DataLabelPtr is used to refer to a location in the code containing a pointer to be // patched after the code has been generated. class DataLabel32 { - template<class TemplateAssemblerType, class TemplateMacroAssemblerType> + template<class TemplateAssemblerType> friend class AbstractMacroAssembler; friend class LinkBuffer; public: @@ -452,7 +445,7 @@ public: { } - DataLabel32(AbstractMacroAssemblerType* masm) + DataLabel32(AbstractMacroAssembler<AssemblerType>* masm) : m_label(masm->m_assembler.label()) { } @@ -468,7 +461,7 @@ public: // A DataLabelCompact is used to refer to a location in the code containing a // compact immediate to be patched after the code has been generated. class DataLabelCompact { - template<class TemplateAssemblerType, class TemplateMacroAssemblerType> + template<class TemplateAssemblerType> friend class AbstractMacroAssembler; friend class LinkBuffer; public: @@ -476,7 +469,7 @@ public: { } - DataLabelCompact(AbstractMacroAssemblerType* masm) + DataLabelCompact(AbstractMacroAssembler<AssemblerType>* masm) : m_label(masm->m_assembler.label()) { } @@ -499,7 +492,7 @@ public: // relative offset such that when executed it will call to the desired // destination. class Call { - template<class TemplateAssemblerType, class TemplateMacroAssemblerType> + template<class TemplateAssemblerType> friend class AbstractMacroAssembler; public: @@ -543,7 +536,7 @@ public: // relative offset such that when executed it will jump to the desired // destination. class Jump { - template<class TemplateAssemblerType, class TemplateMacroAssemblerType> + template<class TemplateAssemblerType> friend class AbstractMacroAssembler; friend class Call; friend struct DFG::OSRExit; @@ -608,7 +601,7 @@ public: return result; } - void link(AbstractMacroAssemblerType* masm) const + void link(AbstractMacroAssembler<AssemblerType>* masm) const { masm->invalidateAllTempRegisters(); @@ -632,7 +625,7 @@ public: #endif } - void linkTo(Label label, AbstractMacroAssemblerType* masm) const + void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm) const { #if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION) masm->checkRegisterAllocationAgainstBranchRange(label.m_label.m_offset, m_label.m_offset); @@ -700,11 +693,10 @@ public: JumpList(Jump jump) { - if (jump.isSet()) - append(jump); + append(jump); } - void link(AbstractMacroAssemblerType* masm) + void link(AbstractMacroAssembler<AssemblerType>* masm) { size_t size = m_jumps.size(); for (size_t i = 0; i < size; ++i) @@ -712,7 +704,7 @@ public: m_jumps.clear(); } - void linkTo(Label label, AbstractMacroAssemblerType* masm) + void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm) { size_t size = m_jumps.size(); for (size_t i = 0; i < size; ++i) @@ -842,195 +834,12 @@ public: AssemblerType::cacheFlush(code, size); } -#if ENABLE(MASM_PROBE) - - struct CPUState { - #define DECLARE_REGISTER(_type, _regName) \ - _type _regName; - FOR_EACH_CPU_REGISTER(DECLARE_REGISTER) - #undef DECLARE_REGISTER - - static const char* registerName(RegisterID regID) - { - switch (regID) { - #define DECLARE_REGISTER(_type, _regName) \ - case RegisterID::_regName: \ - return #_regName; - FOR_EACH_CPU_GPREGISTER(DECLARE_REGISTER) - #undef DECLARE_REGISTER - } - RELEASE_ASSERT_NOT_REACHED(); - } - - static const char* registerName(FPRegisterID regID) - { - switch (regID) { - #define DECLARE_REGISTER(_type, _regName) \ - case FPRegisterID::_regName: \ - return #_regName; - FOR_EACH_CPU_FPREGISTER(DECLARE_REGISTER) - #undef DECLARE_REGISTER - } - RELEASE_ASSERT_NOT_REACHED(); - } - - void* registerValue(RegisterID regID) - { - switch (regID) { - #define DECLARE_REGISTER(_type, _regName) \ - case RegisterID::_regName: \ - return _regName; - FOR_EACH_CPU_GPREGISTER(DECLARE_REGISTER) - #undef DECLARE_REGISTER - } - RELEASE_ASSERT_NOT_REACHED(); - } - - double registerValue(FPRegisterID regID) - { - switch (regID) { - #define DECLARE_REGISTER(_type, _regName) \ - case FPRegisterID::_regName: \ - return _regName; - FOR_EACH_CPU_FPREGISTER(DECLARE_REGISTER) - #undef DECLARE_REGISTER - } - RELEASE_ASSERT_NOT_REACHED(); - } - - }; - - struct ProbeContext; - typedef void (*ProbeFunction)(struct ProbeContext*); - - struct ProbeContext { - ProbeFunction probeFunction; - void* arg1; - void* arg2; - CPUState cpu; - - void print(int indentation = 0) - { - #define INDENT MacroAssemblerType::printIndent(indentation) - - INDENT, dataLogF("ProbeContext %p {\n", this); - indentation++; - { - INDENT, dataLogF("probeFunction: %p\n", probeFunction); - INDENT, dataLogF("arg1: %p %llu\n", arg1, reinterpret_cast<int64_t>(arg1)); - INDENT, dataLogF("arg2: %p %llu\n", arg2, reinterpret_cast<int64_t>(arg2)); - MacroAssemblerType::printCPU(cpu, indentation); - } - indentation--; - INDENT, dataLog("}\n"); - - #undef INDENT - } - }; - - static void printIndent(int indentation) - { - for (; indentation > 0; indentation--) - dataLog(" "); - } - - static void printCPU(CPUState& cpu, int indentation = 0) - { - #define INDENT printIndent(indentation) - - INDENT, dataLog("cpu: {\n"); - MacroAssemblerType::printCPURegisters(cpu, indentation + 1); - INDENT, dataLog("}\n"); - - #undef INDENT - } - - // This is a marker type only used with print(). See print() below for details. - struct AllRegisters { }; - - // Emits code which will print debugging info at runtime. The type of values that - // can be printed is encapsulated in the PrintArg struct below. Here are some - // examples: - // - // print("Hello world\n"); // Emits code to print the string. - // - // CodeBlock* cb = ...; - // print(cb); // Emits code to print the pointer value. - // - // RegisterID regID = ...; - // print(regID); // Emits code to print the register value (not the id). - // - // // Emits code to print all registers. Unlike other items, this prints - // // multiple lines as follows: - // // cpu { - // // eax: 0x123456789 - // // ebx: 0x000000abc - // // ... - // // } - // print(AllRegisters()); - // - // // Print multiple things at once. This incurs the probe overhead only once - // // to print all the items. - // print("cb:", cb, " regID:", regID, " cpu:\n", AllRegisters()); - - template<typename... Arguments> - void print(Arguments... args) - { - printInternal(static_cast<MacroAssemblerType*>(this), args...); - } - - // This function will be called by printCPU() to print the contents of the - // target specific registers which are saved away in the CPUState struct. - // printCPURegisters() should make use of printIndentation() to print the - // registers with the appropriate amount of indentation. - // - // Note: printCPURegisters() should be implemented by the target specific - // MacroAssembler. This prototype is only provided here to document the - // interface. - - static void printCPURegisters(CPUState&, int indentation = 0); - - // This function will be called by print() to print the contents of a - // specific register (from the CPUState) in line with other items in the - // print stream. Hence, no indentation is needed. - // - // Note: printRegister() should be implemented by the target specific - // MacroAssembler. These prototypes are only provided here to document their - // interface. - - static void printRegister(CPUState&, RegisterID); - static void printRegister(CPUState&, FPRegisterID); - - // This function emits code to preserve the CPUState (e.g. registers), - // call a user supplied probe function, and restore the CPUState before - // continuing with other JIT generated code. - // - // The user supplied probe function will be called with a single pointer to - // a ProbeContext struct (defined above) which contains, among other things, - // the preserved CPUState. This allows the user probe function to inspect - // the CPUState at that point in the JIT generated code. - // - // If the user probe function alters the register values in the ProbeContext, - // the altered values will be loaded into the CPU registers when the probe - // returns. - // - // The ProbeContext is stack allocated and is only valid for the duration - // of the call to the user probe function. - // - // Note: probe() should be implemented by the target specific MacroAssembler. - // This prototype is only provided here to document the interface. - - void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0); - -#endif // ENABLE(MASM_PROBE) - AssemblerType m_assembler; protected: AbstractMacroAssembler() : m_randomSource(cryptographicallyRandomNumber()) { - invalidateAllTempRegisters(); } uint32_t random() @@ -1065,7 +874,7 @@ protected: friend class Label; public: - CachedTempRegister(AbstractMacroAssemblerType* masm, RegisterID registerID) + CachedTempRegister(AbstractMacroAssembler<AssemblerType>* masm, RegisterID registerID) : m_masm(masm) , m_registerID(registerID) , m_value(0) @@ -1093,7 +902,7 @@ protected: ALWAYS_INLINE void invalidate() { m_masm->clearTempRegisterValid(m_validBit); } private: - AbstractMacroAssemblerType* m_masm; + AbstractMacroAssembler<AssemblerType>* m_masm; RegisterID m_registerID; intptr_t m_value; unsigned m_validBit; @@ -1183,143 +992,7 @@ protected: { AssemblerType::replaceWithAddressComputation(label.dataLocation()); } - -private: - -#if ENABLE(MASM_PROBE) - - struct PrintArg { - - enum class Type { - AllRegisters, - RegisterID, - FPRegisterID, - ConstCharPtr, - ConstVoidPtr, - IntptrValue, - UintptrValue, - }; - - PrintArg(AllRegisters&) - : type(Type::AllRegisters) - { - } - - PrintArg(RegisterID regID) - : type(Type::RegisterID) - { - u.gpRegisterID = regID; - } - - PrintArg(FPRegisterID regID) - : type(Type::FPRegisterID) - { - u.fpRegisterID = regID; - } - - PrintArg(const char* ptr) - : type(Type::ConstCharPtr) - { - u.constCharPtr = ptr; - } - - PrintArg(const void* ptr) - : type(Type::ConstVoidPtr) - { - u.constVoidPtr = ptr; - } - - PrintArg(int value) - : type(Type::IntptrValue) - { - u.intptrValue = value; - } - - PrintArg(unsigned value) - : type(Type::UintptrValue) - { - u.intptrValue = value; - } - - PrintArg(intptr_t value) - : type(Type::IntptrValue) - { - u.intptrValue = value; - } - - PrintArg(uintptr_t value) - : type(Type::UintptrValue) - { - u.uintptrValue = value; - } - - Type type; - union { - RegisterID gpRegisterID; - FPRegisterID fpRegisterID; - const char* constCharPtr; - const void* constVoidPtr; - intptr_t intptrValue; - uintptr_t uintptrValue; - } u; - }; - - typedef Vector<PrintArg> PrintArgsList; - - template<typename FirstArg, typename... Arguments> - static void appendPrintArg(PrintArgsList* argsList, FirstArg& firstArg, Arguments... otherArgs) - { - argsList->append(PrintArg(firstArg)); - appendPrintArg(argsList, otherArgs...); - } - - static void appendPrintArg(PrintArgsList*) { } - - - template<typename... Arguments> - static void printInternal(MacroAssemblerType* masm, Arguments... args) - { - auto argsList = std::make_unique<PrintArgsList>(); - appendPrintArg(argsList.get(), args...); - masm->probe(printCallback, argsList.release()); - } - - static void printCallback(ProbeContext* context) - { - typedef PrintArg Arg; - PrintArgsList& argsList = - *reinterpret_cast<PrintArgsList*>(context->arg1); - for (size_t i = 0; i < argsList.size(); i++) { - auto& arg = argsList[i]; - switch (arg.type) { - case Arg::Type::AllRegisters: - MacroAssemblerType::printCPU(context->cpu); - break; - case Arg::Type::RegisterID: - MacroAssemblerType::printRegister(context->cpu, arg.u.gpRegisterID); - break; - case Arg::Type::FPRegisterID: - MacroAssemblerType::printRegister(context->cpu, arg.u.fpRegisterID); - break; - case Arg::Type::ConstCharPtr: - dataLog(arg.u.constCharPtr); - break; - case Arg::Type::ConstVoidPtr: - dataLogF("%p", arg.u.constVoidPtr); - break; - case Arg::Type::IntptrValue: - dataLog(arg.u.intptrValue); - break; - case Arg::Type::UintptrValue: - dataLog(arg.u.uintptrValue); - break; - } - } - } - -#endif // ENABLE(MASM_PROBE) - -}; // class AbstractMacroAssembler +}; } // namespace JSC |