Changeset 252015 in webkit
- Timestamp:
- Nov 4, 2019, 2:20:37 PM (6 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 46 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r252006 r252015 1 2019-11-04 Robin Morisset <[email protected]> 2 3 Split ArithProfile into a Unary and a Binary version 4 https://bugs.webkit.org/show_bug.cgi?id=202832 5 <rdar://problem/56266847> 6 7 Reviewed by Keith Miller. 8 9 ArithProfile was for a long time only used for add/sub/mul/div, but recently it started being used for negate. And it will soon also have to be used for inc and dec due to BigInt. 10 So in this patch I make a separate version that only has the data for a single argument, and thus takes half as much memory. 11 12 After discussing this change with Phil I realized that the ResultType(s) that were taking space in ArithProfile are not needed: they never change and a copy is already in the bytecode instruction itself. 13 Removing them allowed shrinking both kinds of ArithProfile to fit in 16 bits (9 and 13 respectively). 14 I kept the two kinds separate because they may shrink or grow independently in the future. 15 16 This also required adding the "orh" instruction to the offline assembler, to set bits in the ArithProfile. 17 This in turn motivated the addition of "storeh", as on RISC platforms "orh" on a memory location is actually loadh -> orh -> storeh. 18 19 * bytecode/ArithProfile.cpp: 20 (JSC::ArithProfile<BitfieldType>::emitObserveResult): 21 (JSC::ArithProfile<BitfieldType>::shouldEmitSetDouble const): 22 (JSC::ArithProfile<BitfieldType>::emitSetDouble const): 23 (JSC::ArithProfile<BitfieldType>::shouldEmitSetNonNumeric const): 24 (JSC::ArithProfile<BitfieldType>::shouldEmitSetBigInt const): 25 (JSC::ArithProfile<BitfieldType>::emitSetNonNumeric const): 26 (JSC::ArithProfile<BitfieldType>::emitSetBigInt const): 27 (WTF::printInternal): 28 * bytecode/ArithProfile.h: 29 (JSC::ArithProfile::didObserveNonInt32 const): 30 (JSC::ArithProfile::didObserveDouble const): 31 (JSC::ArithProfile::didObserveNonNegZeroDouble const): 32 (JSC::ArithProfile::didObserveNegZeroDouble const): 33 (JSC::ArithProfile::didObserveNonNumeric const): 34 (JSC::ArithProfile::didObserveBigInt const): 35 (JSC::ArithProfile::didObserveInt32Overflow const): 36 (JSC::ArithProfile::didObserveInt52Overflow const): 37 (JSC::ArithProfile::setObservedNonNegZeroDouble): 38 (JSC::ArithProfile::setObservedNegZeroDouble): 39 (JSC::ArithProfile::setObservedNonNumeric): 40 (JSC::ArithProfile::setObservedBigInt): 41 (JSC::ArithProfile::setObservedInt32Overflow): 42 (JSC::ArithProfile::setObservedInt52Overflow): 43 (JSC::ArithProfile::observeResult): 44 (JSC::ArithProfile::addressOfBits const): 45 (JSC::ArithProfile::bits const): 46 (JSC::ArithProfile::ArithProfile): 47 (JSC::ArithProfile::hasBits const): 48 (JSC::ArithProfile::setBit): 49 (JSC::UnaryArithProfile::UnaryArithProfile): 50 (JSC::UnaryArithProfile::observedIntBits): 51 (JSC::UnaryArithProfile::observedNumberBits): 52 (JSC::UnaryArithProfile::argObservedType const): 53 (JSC::UnaryArithProfile::setArgObservedType): 54 (JSC::UnaryArithProfile::argSawInt32): 55 (JSC::UnaryArithProfile::argSawNumber): 56 (JSC::UnaryArithProfile::argSawNonNumber): 57 (JSC::UnaryArithProfile::observeArg): 58 (JSC::UnaryArithProfile::isObservedTypeEmpty): 59 (JSC::BinaryArithProfile::BinaryArithProfile): 60 (JSC::BinaryArithProfile::observedIntIntBits): 61 (JSC::BinaryArithProfile::observedNumberIntBits): 62 (JSC::BinaryArithProfile::observedIntNumberBits): 63 (JSC::BinaryArithProfile::observedNumberNumberBits): 64 (JSC::BinaryArithProfile::setLhsObservedType): 65 (JSC::BinaryArithProfile::setRhsObservedType): 66 (JSC::BinaryArithProfile::observeLHS): 67 (JSC::BinaryArithProfile::observeLHSAndRHS): 68 (JSC::BinaryArithProfile::isObservedTypeEmpty): 69 * bytecode/BytecodeList.rb: 70 * bytecode/CodeBlock.cpp: 71 (JSC::CodeBlock::addJITAddIC): 72 (JSC::CodeBlock::addJITMulIC): 73 (JSC::CodeBlock::addJITSubIC): 74 (JSC::CodeBlock::addJITNegIC): 75 (JSC::CodeBlock::binaryArithProfileForBytecodeOffset): 76 (JSC::CodeBlock::unaryArithProfileForBytecodeOffset): 77 (JSC::CodeBlock::binaryArithProfileForPC): 78 (JSC::CodeBlock::unaryArithProfileForPC): 79 (JSC::CodeBlock::couldTakeSpecialFastCase): 80 * bytecode/CodeBlock.h: 81 (JSC::CodeBlock::addMathIC): 82 * bytecode/Fits.h: 83 * bytecode/MethodOfGettingAValueProfile.cpp: 84 (JSC::MethodOfGettingAValueProfile::emitReportValue const): 85 (JSC::MethodOfGettingAValueProfile::reportValue): 86 * bytecode/MethodOfGettingAValueProfile.h: 87 (JSC::MethodOfGettingAValueProfile::MethodOfGettingAValueProfile): 88 * bytecompiler/BytecodeGenerator.cpp: 89 (JSC::BytecodeGenerator::emitUnaryOp): 90 * bytecompiler/BytecodeGenerator.h: 91 * bytecompiler/NodesCodegen.cpp: 92 (JSC::UnaryOpNode::emitBytecode): 93 * dfg/DFGByteCodeParser.cpp: 94 (JSC::DFG::ByteCodeParser::makeSafe): 95 (JSC::DFG::ByteCodeParser::makeDivSafe): 96 * dfg/DFGGraph.cpp: 97 (JSC::DFG::Graph::methodOfGettingAValueProfileFor): 98 * dfg/DFGSpeculativeJIT.cpp: 99 (JSC::DFG::SpeculativeJIT::compileValueAdd): 100 (JSC::DFG::SpeculativeJIT::compileValueSub): 101 (JSC::DFG::SpeculativeJIT::compileValueNegate): 102 (JSC::DFG::SpeculativeJIT::compileValueMul): 103 * ftl/FTLLowerDFGToB3.cpp: 104 (JSC::FTL::DFG::LowerDFGToB3::compileValueAdd): 105 (JSC::FTL::DFG::LowerDFGToB3::compileValueSub): 106 (JSC::FTL::DFG::LowerDFGToB3::compileValueMul): 107 (JSC::FTL::DFG::LowerDFGToB3::compileUnaryMathIC): 108 (JSC::FTL::DFG::LowerDFGToB3::compileBinaryMathIC): 109 (JSC::FTL::DFG::LowerDFGToB3::compileArithAddOrSub): 110 (JSC::FTL::DFG::LowerDFGToB3::compileValueNegate): 111 * jit/JIT.h: 112 * jit/JITAddGenerator.cpp: 113 (JSC::JITAddGenerator::generateInline): 114 (JSC::JITAddGenerator::generateFastPath): 115 * jit/JITAddGenerator.h: 116 * jit/JITArithmetic.cpp: 117 (JSC::JIT::emit_op_negate): 118 (JSC::JIT::emit_op_add): 119 (JSC::JIT::emitMathICFast): 120 (JSC::JIT::emitMathICSlow): 121 (JSC::JIT::emit_op_div): 122 (JSC::JIT::emit_op_mul): 123 (JSC::JIT::emit_op_sub): 124 * jit/JITDivGenerator.cpp: 125 (JSC::JITDivGenerator::generateFastPath): 126 * jit/JITDivGenerator.h: 127 (JSC::JITDivGenerator::JITDivGenerator): 128 * jit/JITInlines.h: 129 (JSC::JIT::copiedArithProfile): 130 * jit/JITMathIC.h: 131 (JSC::JITMathIC::JITMathIC): 132 (JSC::JITMathIC::generateInline): 133 (JSC::JITMathIC::arithProfile const): 134 (JSC::isBinaryProfileEmpty): 135 (JSC::JITBinaryMathIC::JITBinaryMathIC): 136 (JSC::isUnaryProfileEmpty): 137 (JSC::JITUnaryMathIC::JITUnaryMathIC): 138 * jit/JITMulGenerator.cpp: 139 (JSC::JITMulGenerator::generateInline): 140 (JSC::JITMulGenerator::generateFastPath): 141 * jit/JITMulGenerator.h: 142 * jit/JITNegGenerator.cpp: 143 (JSC::JITNegGenerator::generateInline): 144 (JSC::JITNegGenerator::generateFastPath): 145 * jit/JITNegGenerator.h: 146 * jit/JITOperations.cpp: 147 * jit/JITOperations.h: 148 * jit/JITSubGenerator.cpp: 149 (JSC::JITSubGenerator::generateInline): 150 (JSC::JITSubGenerator::generateFastPath): 151 * jit/JITSubGenerator.h: 152 * llint/LLIntData.cpp: 153 (JSC::LLInt::Data::performAssertions): 154 * llint/LLIntOffsetsExtractor.cpp: 155 (JSC::LLIntOffsetsExtractor::dummy): 156 * llint/LowLevelInterpreter.asm: 157 * llint/LowLevelInterpreter32_64.asm: 158 * llint/LowLevelInterpreter64.asm: 159 * parser/ResultType.h: 160 (JSC::ResultType::ResultType): 161 * runtime/CommonSlowPaths.cpp: 162 (JSC::updateArithProfileForUnaryArithOp): 163 (JSC::updateArithProfileForBinaryArithOp): 164 (JSC::SLOW_PATH_DECL): 165 1 166 2019-11-04 Mark Lam <[email protected]> 2 167 -
trunk/Source/JavaScriptCore/bytecode/ArithProfile.cpp
r251106 r252015 33 33 34 34 #if ENABLE(JIT) 35 void ArithProfile::emitObserveResult(CCallHelpers& jit, JSValueRegs regs, TagRegistersMode mode) 35 template<typename BitfieldType> 36 void ArithProfile<BitfieldType>::emitObserveResult(CCallHelpers& jit, JSValueRegs regs, TagRegistersMode mode) 36 37 { 37 38 if (!shouldEmitSetDouble() && !shouldEmitSetNonNumeric() && !shouldEmitSetBigInt()) … … 59 60 } 60 61 61 bool ArithProfile::shouldEmitSetDouble() const 62 template<typename BitfieldType> 63 bool ArithProfile<BitfieldType>::shouldEmitSetDouble() const 62 64 { 63 uint32_t mask = ArithProfile::Int32Overflow | ArithProfile::Int52Overflow | ArithProfile::NegZeroDouble | ArithProfile::NonNegZeroDouble;65 uint32_t mask = Int32Overflow | Int52Overflow | NegZeroDouble | NonNegZeroDouble; 64 66 return (m_bits & mask) != mask; 65 67 } 66 68 67 void ArithProfile::emitSetDouble(CCallHelpers& jit) const 69 template<typename BitfieldType> 70 void ArithProfile<BitfieldType>::emitSetDouble(CCallHelpers& jit) const 68 71 { 69 72 if (shouldEmitSetDouble()) 70 jit.or32(CCallHelpers::TrustedImm32( ArithProfile::Int32Overflow | ArithProfile::Int52Overflow | ArithProfile::NegZeroDouble | ArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(addressOfBits()));73 jit.or32(CCallHelpers::TrustedImm32(Int32Overflow | Int52Overflow | NegZeroDouble | NonNegZeroDouble), CCallHelpers::AbsoluteAddress(addressOfBits())); 71 74 } 72 75 73 bool ArithProfile::shouldEmitSetNonNumeric() const 76 template<typename BitfieldType> 77 bool ArithProfile<BitfieldType>::shouldEmitSetNonNumeric() const 74 78 { 75 79 uint32_t mask = ArithProfile::NonNumeric; … … 77 81 } 78 82 79 bool ArithProfile::shouldEmitSetBigInt() const 83 template<typename BitfieldType> 84 bool ArithProfile<BitfieldType>::shouldEmitSetBigInt() const 80 85 { 81 86 uint32_t mask = ArithProfile::BigInt; … … 83 88 } 84 89 85 void ArithProfile::emitSetNonNumeric(CCallHelpers& jit) const 90 template<typename BitfieldType> 91 void ArithProfile<BitfieldType>::emitSetNonNumeric(CCallHelpers& jit) const 86 92 { 87 93 if (shouldEmitSetNonNumeric()) 88 jit.or32(CCallHelpers::TrustedImm32( ArithProfile::NonNumeric), CCallHelpers::AbsoluteAddress(addressOfBits()));94 jit.or32(CCallHelpers::TrustedImm32(NonNumeric), CCallHelpers::AbsoluteAddress(addressOfBits())); 89 95 } 90 96 91 void ArithProfile::emitSetBigInt(CCallHelpers& jit) const 97 template<typename BitfieldType> 98 void ArithProfile<BitfieldType>::emitSetBigInt(CCallHelpers& jit) const 92 99 { 93 100 if (shouldEmitSetBigInt()) 94 jit.or32(CCallHelpers::TrustedImm32( ArithProfile::BigInt), CCallHelpers::AbsoluteAddress(addressOfBits()));101 jit.or32(CCallHelpers::TrustedImm32(BigInt), CCallHelpers::AbsoluteAddress(addressOfBits())); 95 102 } 103 104 // Generate the implementations of the functions above for UnaryArithProfile/BinaryArithProfile 105 // If changing the size of either, add the corresponding lines here. 106 template class ArithProfile<uint16_t>; 96 107 #endif // ENABLE(JIT) 97 108 … … 102 113 using namespace JSC; 103 114 104 void printInternal(PrintStream& out, const ArithProfile& profile) 115 template <typename T> 116 void printInternal(PrintStream& out, const ArithProfile<T>& profile) 105 117 { 106 118 const char* separator = ""; … … 136 148 } 137 149 } 150 out.print(">"); 151 } 152 153 void printInternal(PrintStream& out, const UnaryArithProfile& profile) 154 { 155 printInternal(out, static_cast<ArithProfile<UnaryArithProfileBase>>(profile)); 156 157 out.print(" Arg ObservedType:<"); 158 out.print(profile.argObservedType()); 159 out.print(">"); 160 } 161 162 void printInternal(PrintStream& out, const BinaryArithProfile& profile) 163 { 164 printInternal(out, static_cast<ArithProfile<UnaryArithProfileBase>>(profile)); 165 138 166 if (profile.tookSpecialFastPath()) 139 out.print(separator, "Took special fast path."); 140 out.print(">"); 167 out.print(" Took special fast path."); 141 168 142 169 out.print(" LHS ObservedType:<"); … … 144 171 out.print("> RHS ObservedType:<"); 145 172 out.print(profile.rhsObservedType()); 146 out.print(">");147 148 out.print(" LHS ResultType:<", RawPointer(bitwise_cast<void*>(static_cast<uintptr_t>(profile.lhsResultType().bits()))));149 out.print("> RHS ResultType:<", RawPointer(bitwise_cast<void*>(static_cast<uintptr_t>(profile.rhsResultType().bits()))));150 173 out.print(">"); 151 174 } -
trunk/Source/JavaScriptCore/bytecode/ArithProfile.h
r251106 r252015 67 67 }; 68 68 69 struct ArithProfile { 70 private: 71 static constexpr uint32_t numberOfFlagBits = 6; 72 static constexpr uint32_t rhsResultTypeShift = numberOfFlagBits; 73 static constexpr uint32_t lhsResultTypeShift = rhsResultTypeShift + ResultType::numBitsNeeded; 74 static constexpr uint32_t rhsObservedTypeShift = lhsResultTypeShift + ResultType::numBitsNeeded; 75 static constexpr uint32_t lhsObservedTypeShift = rhsObservedTypeShift + ObservedType::numBitsNeeded; 76 77 static_assert(ObservedType::numBitsNeeded == 3, "We make a hard assumption about that here."); 78 static constexpr uint32_t clearRhsObservedTypeBitMask = static_cast<uint32_t>(~((1 << rhsObservedTypeShift) | (1 << (rhsObservedTypeShift + 1)) | (1 << (rhsObservedTypeShift + 2)))); 79 static constexpr uint32_t clearLhsObservedTypeBitMask = static_cast<uint32_t>(~((1 << lhsObservedTypeShift) | (1 << (lhsObservedTypeShift + 1)) | (1 << (lhsObservedTypeShift + 2)))); 80 81 static constexpr uint32_t resultTypeMask = (1 << ResultType::numBitsNeeded) - 1; 82 static constexpr uint32_t observedTypeMask = (1 << ObservedType::numBitsNeeded) - 1; 83 84 enum class ConstantTag { Constant }; 85 69 template <typename BitfieldType> 70 class ArithProfile { 86 71 public: 87 static constexpr uint32_t specialFastPathBit = 1 << (lhsObservedTypeShift + ObservedType::numBitsNeeded);88 static_assert((lhsObservedTypeShift + ObservedType::numBitsNeeded) <= (sizeof(uint32_t) * 8) - 1, "Should fit in a uint32_t.");89 static_assert(!(specialFastPathBit & ~clearLhsObservedTypeBitMask), "These bits should not intersect.");90 static_assert(specialFastPathBit & clearLhsObservedTypeBitMask, "These bits should intersect.");91 static_assert(specialFastPathBit > ~clearLhsObservedTypeBitMask, "These bits should not intersect and specialFastPathBit should be a higher bit.");92 93 ArithProfile(ResultType arg)94 : ArithProfile(ConstantTag::Constant, arg)95 {96 ASSERT(lhsResultType().bits() == arg.bits());97 ASSERT(lhsObservedType().isEmpty());98 ASSERT(rhsObservedType().isEmpty());99 }100 101 ArithProfile(ResultType lhs, ResultType rhs)102 : ArithProfile(ConstantTag::Constant, lhs, rhs)103 {104 ASSERT(lhsResultType().bits() == lhs.bits() && rhsResultType().bits() == rhs.bits());105 ASSERT(lhsObservedType().isEmpty());106 ASSERT(rhsObservedType().isEmpty());107 }108 109 ArithProfile(OperandTypes types)110 : ArithProfile(types.first(), types.second())111 { }112 113 ArithProfile() = default;114 115 static constexpr ArithProfile fromInt(uint32_t bits)116 {117 return ArithProfile { ConstantTag::Constant, bits };118 }119 120 static constexpr ArithProfile observedUnaryInt()121 {122 constexpr ObservedType observedInt32 { ObservedType().withInt32() };123 constexpr uint32_t bits = observedInt32.bits() << lhsObservedTypeShift;124 static_assert(bits == 0x800000, "");125 return fromInt(bits);126 }127 static constexpr ArithProfile observedUnaryNumber()128 {129 constexpr ObservedType observedNumber { ObservedType().withNumber() };130 constexpr uint32_t bits = observedNumber.bits() << lhsObservedTypeShift;131 static_assert(bits == 0x1000000, "");132 return fromInt(bits);133 }134 static constexpr ArithProfile observedBinaryIntInt()135 {136 constexpr ObservedType observedInt32 { ObservedType().withInt32() };137 constexpr uint32_t bits = (observedInt32.bits() << lhsObservedTypeShift) | (observedInt32.bits() << rhsObservedTypeShift);138 static_assert(bits == 0x900000, "");139 return fromInt(bits);140 }141 static constexpr ArithProfile observedBinaryNumberInt()142 {143 constexpr ObservedType observedNumber { ObservedType().withNumber() };144 constexpr ObservedType observedInt32 { ObservedType().withInt32() };145 constexpr uint32_t bits = (observedNumber.bits() << lhsObservedTypeShift) | (observedInt32.bits() << rhsObservedTypeShift);146 static_assert(bits == 0x1100000, "");147 return fromInt(bits);148 }149 static constexpr ArithProfile observedBinaryIntNumber()150 {151 constexpr ObservedType observedNumber { ObservedType().withNumber() };152 constexpr ObservedType observedInt32 { ObservedType().withInt32() };153 constexpr uint32_t bits = (observedInt32.bits() << lhsObservedTypeShift) | (observedNumber.bits() << rhsObservedTypeShift);154 static_assert(bits == 0xa00000, "");155 return fromInt(bits);156 }157 static constexpr ArithProfile observedBinaryNumberNumber()158 {159 constexpr ObservedType observedNumber { ObservedType().withNumber() };160 constexpr uint32_t bits = (observedNumber.bits() << lhsObservedTypeShift) | (observedNumber.bits() << rhsObservedTypeShift);161 static_assert(bits == 0x1200000, "");162 return fromInt(bits);163 }164 165 72 enum ObservedResults { 166 73 NonNegZeroDouble = 1 << 0, … … 171 78 BigInt = 1 << 5, 172 79 }; 173 174 ResultType lhsResultType() const { return ResultType((m_bits >> lhsResultTypeShift) & resultTypeMask); } 175 ResultType rhsResultType() const { return ResultType((m_bits >> rhsResultTypeShift) & resultTypeMask); } 176 177 constexpr ObservedType lhsObservedType() const { return ObservedType((m_bits >> lhsObservedTypeShift) & observedTypeMask); } 178 constexpr ObservedType rhsObservedType() const { return ObservedType((m_bits >> rhsObservedTypeShift) & observedTypeMask); } 179 void setLhsObservedType(ObservedType type) 180 { 181 uint32_t bits = m_bits; 182 bits &= clearLhsObservedTypeBitMask; 183 bits |= type.bits() << lhsObservedTypeShift; 184 m_bits = bits; 185 ASSERT(lhsObservedType() == type); 186 } 187 188 void setRhsObservedType(ObservedType type) 189 { 190 uint32_t bits = m_bits; 191 bits &= clearRhsObservedTypeBitMask; 192 bits |= type.bits() << rhsObservedTypeShift; 193 m_bits = bits; 194 ASSERT(rhsObservedType() == type); 195 } 196 197 bool tookSpecialFastPath() const { return m_bits & specialFastPathBit; } 80 static constexpr uint32_t observedResultsNumBitsNeeded = 6; 198 81 199 82 bool didObserveNonInt32() const { return hasBits(NonNegZeroDouble | NegZeroDouble | NonNumeric | BigInt); } … … 212 95 void setObservedInt32Overflow() { setBit(Int32Overflow); } 213 96 void setObservedInt52Overflow() { setBit(Int52Overflow); } 214 215 const void* addressOfBits() const { return &m_bits; }216 97 217 98 void observeResult(JSValue value) … … 230 111 } 231 112 113 const void* addressOfBits() const { return &m_bits; } 114 115 #if ENABLE(JIT) 116 // Sets (Int32Overflow | Int52Overflow | NonNegZeroDouble | NegZeroDouble) if it sees a 117 // double. Sets NonNumeric if it sees a non-numeric. 118 void emitObserveResult(CCallHelpers&, JSValueRegs, TagRegistersMode = HaveTagRegisters); 119 120 // Sets (Int32Overflow | Int52Overflow | NonNegZeroDouble | NegZeroDouble). 121 bool shouldEmitSetDouble() const; 122 void emitSetDouble(CCallHelpers&) const; 123 124 // Sets NonNumber. 125 void emitSetNonNumeric(CCallHelpers&) const; 126 bool shouldEmitSetNonNumeric() const; 127 128 // Sets BigInt 129 void emitSetBigInt(CCallHelpers&) const; 130 bool shouldEmitSetBigInt() const; 131 #endif // ENABLE(JIT) 132 133 constexpr uint32_t bits() const { return m_bits; } 134 135 protected: 136 ArithProfile() 137 { 138 } 139 140 bool hasBits(int mask) const { return m_bits & mask; } 141 void setBit(int mask) { m_bits |= mask; } 142 143 BitfieldType m_bits { 0 }; // We take care to update m_bits only in a single operation. We don't ever store an inconsistent bit representation to it. 144 }; 145 146 /* This class stores the following components in 16 bits: 147 * - ObservedResults 148 * - ObservedType for the argument 149 */ 150 using UnaryArithProfileBase = uint16_t; 151 class UnaryArithProfile : public ArithProfile<UnaryArithProfileBase> { 152 static constexpr unsigned argObservedTypeShift = observedResultsNumBitsNeeded; 153 154 static_assert(argObservedTypeShift + ObservedType::numBitsNeeded <= sizeof(UnaryArithProfileBase) * 8, "Should fit in a the type of the underlying bitfield."); 155 156 static constexpr UnaryArithProfileBase clearArgObservedTypeBitMask = static_cast<UnaryArithProfileBase>(~(0b111 << argObservedTypeShift)); 157 158 static constexpr UnaryArithProfileBase observedTypeMask = (1 << ObservedType::numBitsNeeded) - 1; 159 160 public: 161 UnaryArithProfile() 162 : ArithProfile<UnaryArithProfileBase>() 163 { 164 ASSERT(argObservedType().isEmpty()); 165 ASSERT(argObservedType().isEmpty()); 166 } 167 168 static constexpr UnaryArithProfileBase observedIntBits() 169 { 170 constexpr ObservedType observedInt32 { ObservedType().withInt32() }; 171 constexpr UnaryArithProfileBase bits = observedInt32.bits() << argObservedTypeShift; 172 return bits; 173 } 174 static constexpr UnaryArithProfileBase observedNumberBits() 175 { 176 constexpr ObservedType observedNumber { ObservedType().withNumber() }; 177 constexpr UnaryArithProfileBase bits = observedNumber.bits() << argObservedTypeShift; 178 return bits; 179 } 180 181 constexpr ObservedType argObservedType() const { return ObservedType((m_bits >> argObservedTypeShift) & observedTypeMask); } 182 void setArgObservedType(ObservedType type) 183 { 184 UnaryArithProfileBase bits = m_bits; 185 bits &= clearArgObservedTypeBitMask; 186 bits |= type.bits() << argObservedTypeShift; 187 m_bits = bits; 188 ASSERT(argObservedType() == type); 189 } 190 191 void argSawInt32() { setArgObservedType(argObservedType().withInt32()); } 192 void argSawNumber() { setArgObservedType(argObservedType().withNumber()); } 193 void argSawNonNumber() { setArgObservedType(argObservedType().withNonNumber()); } 194 195 void observeArg(JSValue arg) 196 { 197 UnaryArithProfile newProfile = *this; 198 if (arg.isNumber()) { 199 if (arg.isInt32()) 200 newProfile.argSawInt32(); 201 else 202 newProfile.argSawNumber(); 203 } else 204 newProfile.argSawNonNumber(); 205 206 m_bits = newProfile.bits(); 207 } 208 209 bool isObservedTypeEmpty() 210 { 211 return argObservedType().isEmpty(); 212 } 213 214 friend class JSC::LLIntOffsetsExtractor; 215 }; 216 217 /* This class stores the following components in 16 bits: 218 * - ObservedResults 219 * - ObservedType for right-hand-side 220 * - ObservedType for left-hand-side 221 * - a bit used by division to indicate whether a special fast path was taken 222 */ 223 using BinaryArithProfileBase = uint16_t; 224 class BinaryArithProfile : public ArithProfile<BinaryArithProfileBase> { 225 static constexpr uint32_t rhsObservedTypeShift = observedResultsNumBitsNeeded; 226 static constexpr uint32_t lhsObservedTypeShift = rhsObservedTypeShift + ObservedType::numBitsNeeded; 227 228 static_assert(ObservedType::numBitsNeeded == 3, "We make a hard assumption about that here."); 229 static constexpr BinaryArithProfileBase clearRhsObservedTypeBitMask = static_cast<BinaryArithProfileBase>(~(0b111 << rhsObservedTypeShift)); 230 static constexpr BinaryArithProfileBase clearLhsObservedTypeBitMask = static_cast<BinaryArithProfileBase>(~(0b111 << lhsObservedTypeShift)); 231 232 static constexpr BinaryArithProfileBase observedTypeMask = (1 << ObservedType::numBitsNeeded) - 1; 233 234 public: 235 static constexpr BinaryArithProfileBase specialFastPathBit = 1 << (lhsObservedTypeShift + ObservedType::numBitsNeeded); 236 static_assert((lhsObservedTypeShift + ObservedType::numBitsNeeded + 1) <= sizeof(BinaryArithProfileBase) * 8, "Should fit in a uint32_t."); 237 static_assert(!(specialFastPathBit & ~clearLhsObservedTypeBitMask), "These bits should not intersect."); 238 static_assert(specialFastPathBit & clearLhsObservedTypeBitMask, "These bits should intersect."); 239 static_assert(specialFastPathBit > ~clearLhsObservedTypeBitMask, "These bits should not intersect and specialFastPathBit should be a higher bit."); 240 241 BinaryArithProfile() 242 : ArithProfile<BinaryArithProfileBase> () 243 { 244 ASSERT(lhsObservedType().isEmpty()); 245 ASSERT(rhsObservedType().isEmpty()); 246 } 247 248 static constexpr BinaryArithProfileBase observedIntIntBits() 249 { 250 constexpr ObservedType observedInt32 { ObservedType().withInt32() }; 251 constexpr BinaryArithProfileBase bits = (observedInt32.bits() << lhsObservedTypeShift) | (observedInt32.bits() << rhsObservedTypeShift); 252 return bits; 253 } 254 static constexpr BinaryArithProfileBase observedNumberIntBits() 255 { 256 constexpr ObservedType observedNumber { ObservedType().withNumber() }; 257 constexpr ObservedType observedInt32 { ObservedType().withInt32() }; 258 constexpr BinaryArithProfileBase bits = (observedNumber.bits() << lhsObservedTypeShift) | (observedInt32.bits() << rhsObservedTypeShift); 259 return bits; 260 } 261 static constexpr BinaryArithProfileBase observedIntNumberBits() 262 { 263 constexpr ObservedType observedNumber { ObservedType().withNumber() }; 264 constexpr ObservedType observedInt32 { ObservedType().withInt32() }; 265 constexpr BinaryArithProfileBase bits = (observedInt32.bits() << lhsObservedTypeShift) | (observedNumber.bits() << rhsObservedTypeShift); 266 return bits; 267 } 268 static constexpr BinaryArithProfileBase observedNumberNumberBits() 269 { 270 constexpr ObservedType observedNumber { ObservedType().withNumber() }; 271 constexpr BinaryArithProfileBase bits = (observedNumber.bits() << lhsObservedTypeShift) | (observedNumber.bits() << rhsObservedTypeShift); 272 return bits; 273 } 274 275 constexpr ObservedType lhsObservedType() const { return ObservedType((m_bits >> lhsObservedTypeShift) & observedTypeMask); } 276 constexpr ObservedType rhsObservedType() const { return ObservedType((m_bits >> rhsObservedTypeShift) & observedTypeMask); } 277 void setLhsObservedType(ObservedType type) 278 { 279 BinaryArithProfileBase bits = m_bits; 280 bits &= clearLhsObservedTypeBitMask; 281 bits |= type.bits() << lhsObservedTypeShift; 282 m_bits = bits; 283 ASSERT(lhsObservedType() == type); 284 } 285 286 void setRhsObservedType(ObservedType type) 287 { 288 BinaryArithProfileBase bits = m_bits; 289 bits &= clearRhsObservedTypeBitMask; 290 bits |= type.bits() << rhsObservedTypeShift; 291 m_bits = bits; 292 ASSERT(rhsObservedType() == type); 293 } 294 295 bool tookSpecialFastPath() const { return m_bits & specialFastPathBit; } 296 232 297 void lhsSawInt32() { setLhsObservedType(lhsObservedType().withInt32()); } 233 298 void lhsSawNumber() { setLhsObservedType(lhsObservedType().withNumber()); } … … 239 304 void observeLHS(JSValue lhs) 240 305 { 241 ArithProfile newProfile = *this;306 BinaryArithProfile newProfile = *this; 242 307 if (lhs.isNumber()) { 243 308 if (lhs.isInt32()) … … 255 320 observeLHS(lhs); 256 321 257 ArithProfile newProfile = *this;322 BinaryArithProfile newProfile = *this; 258 323 if (rhs.isNumber()) { 259 324 if (rhs.isInt32()) … … 267 332 } 268 333 269 #if ENABLE(JIT) 270 // Sets (Int32Overflow | Int52Overflow | NonNegZeroDouble | NegZeroDouble) if it sees a 271 // double. Sets NonNumeric if it sees a non-numeric. 272 void emitObserveResult(CCallHelpers&, JSValueRegs, TagRegistersMode = HaveTagRegisters); 273 274 // Sets (Int32Overflow | Int52Overflow | NonNegZeroDouble | NegZeroDouble). 275 bool shouldEmitSetDouble() const; 276 void emitSetDouble(CCallHelpers&) const; 277 278 // Sets NonNumber. 279 void emitSetNonNumeric(CCallHelpers&) const; 280 bool shouldEmitSetNonNumeric() const; 281 282 // Sets BigInt 283 void emitSetBigInt(CCallHelpers&) const; 284 bool shouldEmitSetBigInt() const; 285 #endif // ENABLE(JIT) 286 287 constexpr uint32_t bits() const { return m_bits; } 288 289 private: 290 constexpr explicit ArithProfile(ConstantTag, uint32_t bits) 291 : m_bits(bits) 292 { 293 } 294 295 constexpr ArithProfile(ConstantTag, ResultType arg) 296 : m_bits(arg.bits() << lhsResultTypeShift) 297 { 298 } 299 300 constexpr ArithProfile(ConstantTag, ResultType lhs, ResultType rhs) 301 : m_bits((lhs.bits() << lhsResultTypeShift) | (rhs.bits() << rhsResultTypeShift)) 302 { 303 } 304 305 bool hasBits(int mask) const { return m_bits & mask; } 306 void setBit(int mask) { m_bits |= mask; } 307 308 uint32_t m_bits { 0 }; // We take care to update m_bits only in a single operation. We don't ever store an inconsistent bit representation to it. 334 bool isObservedTypeEmpty() 335 { 336 return lhsObservedType().isEmpty() && rhsObservedType().isEmpty(); 337 } 309 338 310 339 friend class JSC::LLIntOffsetsExtractor; … … 315 344 namespace WTF { 316 345 317 void printInternal(PrintStream&, const JSC::ArithProfile&); 346 void printInternal(PrintStream&, const JSC::UnaryArithProfile&); 347 void printInternal(PrintStream&, const JSC::BinaryArithProfile&); 318 348 void printInternal(PrintStream&, const JSC::ObservedType&); 319 349 -
trunk/Source/JavaScriptCore/bytecode/BytecodeList.rb
r251886 r252015 42 42 :JSValue, 43 43 :LLIntCallLinkInfo, 44 :ResultType, 44 45 :OperandTypes, 45 46 :ProfileTypeBytecodeFlag, … … 59 60 :ValueProfile, 60 61 :ValueProfileAndOperandBuffer, 61 :ArithProfile, 62 :UnaryArithProfile, 63 :BinaryArithProfile, 62 64 :ArrayProfile, 63 65 :ArrayAllocationProfile, … … 284 286 }, 285 287 metadata: { 286 arithProfile: ArithProfile 287 }, 288 metadata_initializers: { 289 arithProfile: :operandTypes 288 arithProfile: BinaryArithProfile 290 289 } 291 290 … … 369 368 dst: VirtualRegister, 370 369 operand: VirtualRegister, 371 operandTypes: OperandTypes, 372 }, 373 metadata: { 374 arithProfile: ArithProfile, 375 }, 376 metadata_initializers: { 377 arithProfile: :operandTypes 370 resultType: ResultType, 371 }, 372 metadata: { 373 arithProfile: UnaryArithProfile, 378 374 } 379 375 -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r251886 r252015 1479 1479 } 1480 1480 1481 JITAddIC* CodeBlock::addJITAddIC( ArithProfile* arithProfile)1481 JITAddIC* CodeBlock::addJITAddIC(BinaryArithProfile* arithProfile) 1482 1482 { 1483 1483 ConcurrentJSLocker locker(m_lock); … … 1485 1485 } 1486 1486 1487 JITMulIC* CodeBlock::addJITMulIC( ArithProfile* arithProfile)1487 JITMulIC* CodeBlock::addJITMulIC(BinaryArithProfile* arithProfile) 1488 1488 { 1489 1489 ConcurrentJSLocker locker(m_lock); … … 1491 1491 } 1492 1492 1493 JITSubIC* CodeBlock::addJITSubIC( ArithProfile* arithProfile)1493 JITSubIC* CodeBlock::addJITSubIC(BinaryArithProfile* arithProfile) 1494 1494 { 1495 1495 ConcurrentJSLocker locker(m_lock); … … 1497 1497 } 1498 1498 1499 JITNegIC* CodeBlock::addJITNegIC( ArithProfile* arithProfile)1499 JITNegIC* CodeBlock::addJITNegIC(UnaryArithProfile* arithProfile) 1500 1500 { 1501 1501 ConcurrentJSLocker locker(m_lock); … … 3084 3084 } 3085 3085 3086 ArithProfile* CodeBlock::arithProfileForBytecodeIndex(BytecodeIndex bytecodeIndex) 3087 { 3088 return arithProfileForPC(instructions().at(bytecodeIndex.offset()).ptr()); 3089 } 3090 3091 ArithProfile* CodeBlock::arithProfileForPC(const Instruction* pc) 3086 BinaryArithProfile* CodeBlock::binaryArithProfileForBytecodeIndex(BytecodeIndex bytecodeIndex) 3087 { 3088 return binaryArithProfileForPC(instructions().at(bytecodeIndex.offset()).ptr()); 3089 } 3090 3091 UnaryArithProfile* CodeBlock::unaryArithProfileForBytecodeIndex(BytecodeIndex bytecodeIndex) 3092 { 3093 return unaryArithProfileForPC(instructions().at(bytecodeIndex.offset()).ptr()); 3094 } 3095 3096 BinaryArithProfile* CodeBlock::binaryArithProfileForPC(const Instruction* pc) 3092 3097 { 3093 3098 switch (pc->opcodeID()) { 3094 case op_negate:3095 return &pc->as<OpNegate>().metadata(this).m_arithProfile;3096 3099 case op_add: 3097 3100 return &pc->as<OpAdd>().metadata(this).m_arithProfile; … … 3109 3112 } 3110 3113 3114 UnaryArithProfile* CodeBlock::unaryArithProfileForPC(const Instruction* pc) 3115 { 3116 switch (pc->opcodeID()) { 3117 case op_negate: 3118 return &pc->as<OpNegate>().metadata(this).m_arithProfile; 3119 default: 3120 break; 3121 } 3122 3123 return nullptr; 3124 } 3125 3111 3126 bool CodeBlock::couldTakeSpecialArithFastCase(BytecodeIndex bytecodeIndex) 3112 3127 { 3113 3128 if (!hasBaselineJITProfiling()) 3114 3129 return false; 3115 ArithProfile* profile = arithProfileForBytecodeIndex(bytecodeIndex);3130 BinaryArithProfile* profile = binaryArithProfileForBytecodeIndex(bytecodeIndex); 3116 3131 if (!profile) 3117 3132 return false; -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.h
r251584 r252015 84 84 #endif 85 85 86 class UnaryArithProfile; 87 class BinaryArithProfile; 86 88 class BytecodeLivenessAnalysis; 87 89 class CodeBlockSet; … … 97 99 enum class AccessType : int8_t; 98 100 99 struct ArithProfile;100 101 struct OpCatch; 101 102 … … 280 281 JITData& ensureJITDataSlow(const ConcurrentJSLocker&); 281 282 282 JITAddIC* addJITAddIC( ArithProfile*);283 JITMulIC* addJITMulIC( ArithProfile*);284 JITNegIC* addJITNegIC( ArithProfile*);285 JITSubIC* addJITSubIC( ArithProfile*);283 JITAddIC* addJITAddIC(BinaryArithProfile*); 284 JITMulIC* addJITMulIC(BinaryArithProfile*); 285 JITNegIC* addJITNegIC(UnaryArithProfile*); 286 JITSubIC* addJITSubIC(BinaryArithProfile*); 286 287 287 288 template <typename Generator, typename = typename std::enable_if<std::is_same<Generator, JITAddGenerator>::value>::type> 288 JITAddIC* addMathIC( ArithProfile* profile) { return addJITAddIC(profile); }289 JITAddIC* addMathIC(BinaryArithProfile* profile) { return addJITAddIC(profile); } 289 290 290 291 template <typename Generator, typename = typename std::enable_if<std::is_same<Generator, JITMulGenerator>::value>::type> 291 JITMulIC* addMathIC( ArithProfile* profile) { return addJITMulIC(profile); }292 JITMulIC* addMathIC(BinaryArithProfile* profile) { return addJITMulIC(profile); } 292 293 293 294 template <typename Generator, typename = typename std::enable_if<std::is_same<Generator, JITNegGenerator>::value>::type> 294 JITNegIC* addMathIC( ArithProfile* profile) { return addJITNegIC(profile); }295 JITNegIC* addMathIC(UnaryArithProfile* profile) { return addJITNegIC(profile); } 295 296 296 297 template <typename Generator, typename = typename std::enable_if<std::is_same<Generator, JITSubGenerator>::value>::type> 297 JITSubIC* addMathIC( ArithProfile* profile) { return addJITSubIC(profile); }298 JITSubIC* addMathIC(BinaryArithProfile* profile) { return addJITSubIC(profile); } 298 299 299 300 StructureStubInfo* addStubInfo(AccessType); … … 498 499 template<typename Functor> void forEachLLIntCallLinkInfo(const Functor&); 499 500 500 ArithProfile* arithProfileForBytecodeIndex(BytecodeIndex); 501 ArithProfile* arithProfileForPC(const Instruction*); 501 BinaryArithProfile* binaryArithProfileForBytecodeIndex(BytecodeIndex); 502 UnaryArithProfile* unaryArithProfileForBytecodeIndex(BytecodeIndex); 503 BinaryArithProfile* binaryArithProfileForPC(const Instruction*); 504 UnaryArithProfile* unaryArithProfileForPC(const Instruction*); 502 505 503 506 bool couldTakeSpecialArithFastCase(BytecodeIndex bytecodeOffset); -
trunk/Source/JavaScriptCore/bytecode/Fits.h
r251886 r252015 238 238 239 239 template<OpcodeSize size> 240 struct Fits<ResultType, size, std::enable_if_t<sizeof(ResultType) != size, std::true_type>> : public Fits<uint8_t, size> { 241 static_assert(sizeof(ResultType) == sizeof(uint8_t)); 242 using Base = Fits<uint8_t, size>; 243 244 static bool check(ResultType type) { return Base::check(type.bits()); } 245 246 static typename Base::TargetType convert(ResultType type) { return Base::convert(type.bits()); } 247 248 static ResultType convert(typename Base::TargetType type) { return ResultType(Base::convert(type)); } 249 }; 250 251 template<OpcodeSize size> 240 252 struct Fits<OperandTypes, size, std::enable_if_t<sizeof(OperandTypes) != size, std::true_type>> { 241 253 static_assert(sizeof(OperandTypes) == sizeof(uint16_t)); -
trunk/Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.cpp
r251468 r252015 67 67 } 68 68 69 case ArithProfileReady: {70 u. arithProfile->emitObserveResult(jit, regs, DoNotHaveTagRegisters);69 case UnaryArithProfileReady: { 70 u.unaryArithProfile->emitObserveResult(jit, regs, DoNotHaveTagRegisters); 71 71 return; 72 } } 72 } 73 74 case BinaryArithProfileReady: { 75 u.binaryArithProfile->emitObserveResult(jit, regs, DoNotHaveTagRegisters); 76 return; 77 } 78 } 73 79 74 80 RELEASE_ASSERT_NOT_REACHED(); … … 95 101 } 96 102 97 case ArithProfileReady: {98 u. arithProfile->observeResult(value);103 case UnaryArithProfileReady: { 104 u.unaryArithProfile->observeResult(value); 99 105 return; 100 } } 106 } 107 108 case BinaryArithProfileReady: { 109 u.binaryArithProfile->observeResult(value); 110 return; 111 } 112 } 101 113 102 114 RELEASE_ASSERT_NOT_REACHED(); -
trunk/Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.h
r251468 r252015 37 37 namespace JSC { 38 38 39 class UnaryArithProfile; 40 class BinaryArithProfile; 39 41 class CCallHelpers; 40 42 class CodeBlock; 41 43 class LazyOperandValueProfileKey; 42 struct ArithProfile;43 44 struct ValueProfile; 44 45 … … 58 59 m_kind = None; 59 60 } 60 61 MethodOfGettingAValueProfile( ArithProfile* profile)61 62 MethodOfGettingAValueProfile(UnaryArithProfile* profile) 62 63 { 63 64 if (profile) { 64 m_kind = ArithProfileReady; 65 u.arithProfile = profile; 65 m_kind = UnaryArithProfileReady; 66 u.unaryArithProfile = profile; 67 } else 68 m_kind = None; 69 } 70 71 MethodOfGettingAValueProfile(BinaryArithProfile* profile) 72 { 73 if (profile) { 74 m_kind = BinaryArithProfileReady; 75 u.binaryArithProfile = profile; 66 76 } else 67 77 m_kind = None; … … 80 90 None, 81 91 Ready, 82 ArithProfileReady, 92 UnaryArithProfileReady, 93 BinaryArithProfileReady, 83 94 LazyOperand 84 95 }; … … 91 102 92 103 ValueProfile* profile; 93 ArithProfile* arithProfile; 104 UnaryArithProfile* unaryArithProfile; 105 BinaryArithProfile* binaryArithProfile; 94 106 struct { 95 107 CodeBlock* codeBlock; -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r251886 r252015 1534 1534 } 1535 1535 1536 RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src, OperandTypes types)1536 RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src, ResultType type) 1537 1537 { 1538 1538 switch (opcodeID) { … … 1541 1541 break; 1542 1542 case op_negate: 1543 OpNegate::emit(this, dst, src, type s);1543 OpNegate::emit(this, dst, src, type); 1544 1544 break; 1545 1545 case op_bitnot: -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r251886 r252015 682 682 } 683 683 684 RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src, OperandTypes);684 RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src, ResultType); 685 685 686 686 template<typename BinaryOp> -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r251371 r252015 2140 2140 RefPtr<RegisterID> src = generator.emitNode(m_expr); 2141 2141 generator.emitExpressionInfo(position(), position(), position()); 2142 return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src.get(), OperandTypes(m_expr->resultDescriptor()));2142 return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src.get(), m_expr->resultDescriptor()); 2143 2143 } 2144 2144 -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r251886 r252015 943 943 return node; 944 944 945 { 946 ArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->arithProfileForBytecodeIndex(m_currentIndex); 947 if (arithProfile) { 948 switch (node->op()) { 949 case ArithAdd: 950 case ArithSub: 951 case ValueAdd: 952 if (arithProfile->didObserveDouble()) 953 node->mergeFlags(NodeMayHaveDoubleResult); 954 if (arithProfile->didObserveNonNumeric()) 955 node->mergeFlags(NodeMayHaveNonNumericResult); 956 if (arithProfile->didObserveBigInt()) 957 node->mergeFlags(NodeMayHaveBigIntResult); 958 break; 959 960 case ValueMul: 961 case ArithMul: { 962 if (arithProfile->didObserveInt52Overflow()) 963 node->mergeFlags(NodeMayOverflowInt52); 964 if (arithProfile->didObserveInt32Overflow() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow)) 965 node->mergeFlags(NodeMayOverflowInt32InBaseline); 966 if (arithProfile->didObserveNegZeroDouble() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero)) 967 node->mergeFlags(NodeMayNegZeroInBaseline); 968 if (arithProfile->didObserveDouble()) 969 node->mergeFlags(NodeMayHaveDoubleResult); 970 if (arithProfile->didObserveNonNumeric()) 971 node->mergeFlags(NodeMayHaveNonNumericResult); 972 if (arithProfile->didObserveBigInt()) 973 node->mergeFlags(NodeMayHaveBigIntResult); 974 break; 975 } 976 case ValueNegate: 977 case ArithNegate: { 978 if (arithProfile->lhsObservedType().sawNumber() || arithProfile->didObserveDouble()) 979 node->mergeFlags(NodeMayHaveDoubleResult); 980 if (arithProfile->didObserveNegZeroDouble() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero)) 981 node->mergeFlags(NodeMayNegZeroInBaseline); 982 if (arithProfile->didObserveInt32Overflow() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow)) 983 node->mergeFlags(NodeMayOverflowInt32InBaseline); 984 if (arithProfile->didObserveNonNumeric()) 985 node->mergeFlags(NodeMayHaveNonNumericResult); 986 if (arithProfile->didObserveBigInt()) 987 node->mergeFlags(NodeMayHaveBigIntResult); 988 break; 989 } 990 991 default: 992 break; 993 } 994 } 945 switch (node->op()) { 946 case ArithAdd: 947 case ArithSub: 948 case ValueAdd: { 949 BinaryArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->binaryArithProfileForBytecodeIndex(m_currentIndex); 950 if (!arithProfile) 951 break; 952 if (arithProfile->didObserveDouble()) 953 node->mergeFlags(NodeMayHaveDoubleResult); 954 if (arithProfile->didObserveNonNumeric()) 955 node->mergeFlags(NodeMayHaveNonNumericResult); 956 if (arithProfile->didObserveBigInt()) 957 node->mergeFlags(NodeMayHaveBigIntResult); 958 break; 959 } 960 case ValueMul: 961 case ArithMul: { 962 BinaryArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->binaryArithProfileForBytecodeIndex(m_currentIndex); 963 if (!arithProfile) 964 break; 965 if (arithProfile->didObserveInt52Overflow()) 966 node->mergeFlags(NodeMayOverflowInt52); 967 if (arithProfile->didObserveInt32Overflow() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow)) 968 node->mergeFlags(NodeMayOverflowInt32InBaseline); 969 if (arithProfile->didObserveNegZeroDouble() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero)) 970 node->mergeFlags(NodeMayNegZeroInBaseline); 971 if (arithProfile->didObserveDouble()) 972 node->mergeFlags(NodeMayHaveDoubleResult); 973 if (arithProfile->didObserveNonNumeric()) 974 node->mergeFlags(NodeMayHaveNonNumericResult); 975 if (arithProfile->didObserveBigInt()) 976 node->mergeFlags(NodeMayHaveBigIntResult); 977 break; 978 } 979 case ValueNegate: 980 case ArithNegate: { 981 UnaryArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->unaryArithProfileForBytecodeIndex(m_currentIndex); 982 if (!arithProfile) 983 break; 984 if (arithProfile->argObservedType().sawNumber() || arithProfile->didObserveDouble()) 985 node->mergeFlags(NodeMayHaveDoubleResult); 986 if (arithProfile->didObserveNegZeroDouble() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero)) 987 node->mergeFlags(NodeMayNegZeroInBaseline); 988 if (arithProfile->didObserveInt32Overflow() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow)) 989 node->mergeFlags(NodeMayOverflowInt32InBaseline); 990 if (arithProfile->didObserveNonNumeric()) 991 node->mergeFlags(NodeMayHaveNonNumericResult); 992 if (arithProfile->didObserveBigInt()) 993 node->mergeFlags(NodeMayHaveBigIntResult); 994 break; 995 } 996 997 default: 998 break; 995 999 } 996 1000 … … 1034 1038 // FIXME: It might be possible to make this more granular. 1035 1039 node->mergeFlags(NodeMayOverflowInt32InBaseline | NodeMayNegZeroInBaseline); 1036 1037 ArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->arithProfileForBytecodeIndex(m_currentIndex);1040 1041 BinaryArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->binaryArithProfileForBytecodeIndex(m_currentIndex); 1038 1042 if (arithProfile->didObserveBigInt()) 1039 1043 node->mergeFlags(NodeMayHaveBigIntResult); -
trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp
r251826 r252015 1655 1655 1656 1656 if (profiledBlock->hasBaselineJITProfiling()) { 1657 if (ArithProfile* result = profiledBlock->arithProfileForBytecodeIndex(node->origin.semantic.bytecodeIndex())) 1657 if (BinaryArithProfile* result = profiledBlock->binaryArithProfileForBytecodeIndex(node->origin.semantic.bytecodeIndex())) 1658 return result; 1659 if (UnaryArithProfile* result = profiledBlock->unaryArithProfileForBytecodeIndex(node->origin.semantic.bytecodeIndex())) 1658 1660 return result; 1659 1661 } -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r251826 r252015 3996 3996 CodeBlock* baselineCodeBlock = m_jit.graph().baselineCodeBlockFor(node->origin.semantic); 3997 3997 BytecodeIndex bytecodeIndex = node->origin.semantic.bytecodeIndex(); 3998 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeIndex(bytecodeIndex);3998 BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeIndex(bytecodeIndex); 3999 3999 JITAddIC* addIC = m_jit.codeBlock()->addJITAddIC(arithProfile); 4000 4000 auto repatchingFunction = operationValueAddOptimize; … … 4020 4020 CodeBlock* baselineCodeBlock = m_jit.graph().baselineCodeBlockFor(node->origin.semantic); 4021 4021 BytecodeIndex bytecodeIndex = node->origin.semantic.bytecodeIndex(); 4022 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeIndex(bytecodeIndex);4022 BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeIndex(bytecodeIndex); 4023 4023 JITSubIC* subIC = m_jit.codeBlock()->addJITSubIC(arithProfile); 4024 4024 auto repatchingFunction = operationValueSubOptimize; … … 4614 4614 CodeBlock* baselineCodeBlock = m_jit.graph().baselineCodeBlockFor(node->origin.semantic); 4615 4615 BytecodeIndex bytecodeIndex = node->origin.semantic.bytecodeIndex(); 4616 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeIndex(bytecodeIndex);4616 UnaryArithProfile* arithProfile = baselineCodeBlock->unaryArithProfileForBytecodeIndex(bytecodeIndex); 4617 4617 JITNegIC* negIC = m_jit.codeBlock()->addJITNegIC(arithProfile); 4618 4618 auto repatchingFunction = operationArithNegateOptimize; … … 4837 4837 CodeBlock* baselineCodeBlock = m_jit.graph().baselineCodeBlockFor(node->origin.semantic); 4838 4838 BytecodeIndex bytecodeIndex = node->origin.semantic.bytecodeIndex(); 4839 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeIndex(bytecodeIndex);4839 BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeIndex(bytecodeIndex); 4840 4840 JITMulIC* mulIC = m_jit.codeBlock()->addJITMulIC(arithProfile); 4841 4841 auto repatchingFunction = operationValueMulOptimize; -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r251826 r252015 2117 2117 CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic); 2118 2118 BytecodeIndex bytecodeIndex = m_node->origin.semantic.bytecodeIndex(); 2119 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeIndex(bytecodeIndex);2119 BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeIndex(bytecodeIndex); 2120 2120 auto repatchingFunction = operationValueAddOptimize; 2121 2121 auto nonRepatchingFunction = operationValueAdd; … … 2138 2138 CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic); 2139 2139 BytecodeIndex bytecodeIndex = m_node->origin.semantic.bytecodeIndex(); 2140 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeIndex(bytecodeIndex);2140 BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeIndex(bytecodeIndex); 2141 2141 auto repatchingFunction = operationValueSubOptimize; 2142 2142 auto nonRepatchingFunction = operationValueSub; … … 2159 2159 CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic); 2160 2160 BytecodeIndex bytecodeIndex = m_node->origin.semantic.bytecodeIndex(); 2161 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeIndex(bytecodeIndex);2161 BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeIndex(bytecodeIndex); 2162 2162 auto repatchingFunction = operationValueMulOptimize; 2163 2163 auto nonRepatchingFunction = operationValueMul; … … 2167 2167 template <typename Generator, typename Func1, typename Func2, 2168 2168 typename = std::enable_if_t<std::is_function<typename std::remove_pointer<Func1>::type>::value && std::is_function<typename std::remove_pointer<Func2>::type>::value>> 2169 void compileUnaryMathIC( ArithProfile* arithProfile, Func1 repatchingFunction, Func2 nonRepatchingFunction)2169 void compileUnaryMathIC(UnaryArithProfile* arithProfile, Func1 repatchingFunction, Func2 nonRepatchingFunction) 2170 2170 { 2171 2171 Node* node = m_node; … … 2253 2253 template <typename Generator, typename Func1, typename Func2, 2254 2254 typename = std::enable_if_t<std::is_function<typename std::remove_pointer<Func1>::type>::value && std::is_function<typename std::remove_pointer<Func2>::type>::value>> 2255 void compileBinaryMathIC( ArithProfile* arithProfile, Func1 repatchingFunction, Func2 nonRepatchingFunction)2255 void compileBinaryMathIC(BinaryArithProfile* arithProfile, Func1 repatchingFunction, Func2 nonRepatchingFunction) 2256 2256 { 2257 2257 Node* node = m_node; … … 2422 2422 CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic); 2423 2423 BytecodeIndex bytecodeIndex = m_node->origin.semantic.bytecodeIndex(); 2424 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeIndex(bytecodeIndex);2424 BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeIndex(bytecodeIndex); 2425 2425 auto repatchingFunction = operationValueSubOptimize; 2426 2426 auto nonRepatchingFunction = operationValueSub; … … 3100 3100 CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic); 3101 3101 BytecodeIndex bytecodeIndex = m_node->origin.semantic.bytecodeIndex(); 3102 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeIndex(bytecodeIndex);3102 UnaryArithProfile* arithProfile = baselineCodeBlock->unaryArithProfileForBytecodeIndex(bytecodeIndex); 3103 3103 auto repatchingFunction = operationArithNegateOptimize; 3104 3104 auto nonRepatchingFunction = operationArithNegate; -
trunk/Source/JavaScriptCore/jit/JIT.h
r251471 r252015 920 920 GetPutInfo copiedGetPutInfo(OpPutToScope); 921 921 template<typename BinaryOp> 922 ArithProfile copiedArithProfile(BinaryOp);922 BinaryArithProfile copiedArithProfile(BinaryOp); 923 923 924 924 Interpreter* m_interpreter; … … 940 940 941 941 HashMap<unsigned, unsigned> m_copiedGetPutInfos; 942 HashMap<uint64_t, ArithProfile> m_copiedArithProfiles;942 HashMap<uint64_t, BinaryArithProfile> m_copiedArithProfiles; 943 943 944 944 JumpList m_exceptionChecks; -
trunk/Source/JavaScriptCore/jit/JITAddGenerator.cpp
r251106 r252015 35 35 namespace JSC { 36 36 37 JITMathICInlineResult JITAddGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const ArithProfile* arithProfile)37 JITMathICInlineResult JITAddGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const BinaryArithProfile* arithProfile) 38 38 { 39 39 // We default to speculating int32. … … 74 74 } 75 75 76 bool JITAddGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile* arithProfile, bool shouldEmitProfiling)76 bool JITAddGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const BinaryArithProfile* arithProfile, bool shouldEmitProfiling) 77 77 { 78 78 ASSERT(m_scratchGPR != InvalidGPRReg); -
trunk/Source/JavaScriptCore/jit/JITAddGenerator.h
r251106 r252015 56 56 } 57 57 58 JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const ArithProfile*);59 bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile*, bool shouldEmitProfiling);58 JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const BinaryArithProfile*); 59 bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const BinaryArithProfile*, bool shouldEmitProfiling); 60 60 61 61 static bool isLeftOperandValidConstant(SnippetOperand leftOperand) { return leftOperand.isPositiveConstInt32(); } -
trunk/Source/JavaScriptCore/jit/JITArithmetic.cpp
r251886 r252015 454 454 void JIT::emit_op_negate(const Instruction* currentInstruction) 455 455 { 456 ArithProfile* arithProfile = ¤tInstruction->as<OpNegate>().metadata(m_codeBlock).m_arithProfile;456 UnaryArithProfile* arithProfile = ¤tInstruction->as<OpNegate>().metadata(m_codeBlock).m_arithProfile; 457 457 JITNegIC* negateIC = m_codeBlock->addJITNegIC(arithProfile); 458 458 m_instructionToMathIC.add(currentInstruction, negateIC); … … 635 635 } 636 636 637 ALWAYS_INLINE static OperandTypes getOperandTypes(const ArithProfile& arithProfile)638 {639 return OperandTypes(arithProfile.lhsResultType(), arithProfile.rhsResultType());640 }641 642 637 void JIT::emit_op_add(const Instruction* currentInstruction) 643 638 { 644 ArithProfile* arithProfile = ¤tInstruction->as<OpAdd>().metadata(m_codeBlock).m_arithProfile;639 BinaryArithProfile* arithProfile = ¤tInstruction->as<OpAdd>().metadata(m_codeBlock).m_arithProfile; 645 640 JITAddIC* addIC = m_codeBlock->addJITAddIC(arithProfile); 646 641 m_instructionToMathIC.add(currentInstruction, addIC); … … 687 682 bool generatedInlineCode = mathIC->generateInline(*this, mathICGenerationState); 688 683 if (!generatedInlineCode) { 689 ArithProfile* arithProfile = mathIC->arithProfile();684 UnaryArithProfile* arithProfile = mathIC->arithProfile(); 690 685 if (arithProfile && shouldEmitProfiling()) 691 686 callOperationWithResult(profiledFunction, resultRegs, TrustedImmPtr(m_codeBlock->globalObject()), srcRegs, arithProfile); … … 710 705 { 711 706 auto bytecode = currentInstruction->as<Op>(); 712 OperandTypes types = getOperandTypes(copiedArithProfile(bytecode));713 707 int result = bytecode.m_dst.offset(); 714 708 int op1 = bytecode.m_lhs.offset(); … … 729 723 #endif 730 724 731 SnippetOperand leftOperand( types.first());732 SnippetOperand rightOperand( types.second());725 SnippetOperand leftOperand(bytecode.m_operandTypes.first()); 726 SnippetOperand rightOperand(bytecode.m_operandTypes.second()); 733 727 734 728 if (isOperandConstantInt(op1)) … … 760 754 else if (rightOperand.isConst()) 761 755 emitGetVirtualRegister(op2, rightRegs); 762 ArithProfile* arithProfile = mathIC->arithProfile();756 BinaryArithProfile* arithProfile = mathIC->arithProfile(); 763 757 if (arithProfile && shouldEmitProfiling()) 764 758 callOperationWithResult(profiledFunction, resultRegs, TrustedImmPtr(m_codeBlock->globalObject()), leftRegs, rightRegs, arithProfile); … … 800 794 #endif 801 795 802 ArithProfile* arithProfile = mathIC->arithProfile();796 UnaryArithProfile* arithProfile = mathIC->arithProfile(); 803 797 if (arithProfile && shouldEmitProfiling()) { 804 798 if (mathICGenerationState.shouldSlowPathRepatch) … … 832 826 833 827 auto bytecode = currentInstruction->as<Op>(); 834 OperandTypes types = getOperandTypes(copiedArithProfile(bytecode));835 828 int result = bytecode.m_dst.offset(); 836 829 int op1 = bytecode.m_lhs.offset(); … … 847 840 #endif 848 841 849 SnippetOperand leftOperand( types.first());850 SnippetOperand rightOperand( types.second());842 SnippetOperand leftOperand(bytecode.m_operandTypes.first()); 843 SnippetOperand rightOperand(bytecode.m_operandTypes.second()); 851 844 852 845 if (isOperandConstantInt(op1)) … … 866 859 #endif 867 860 868 ArithProfile* arithProfile = mathIC->arithProfile();861 BinaryArithProfile* arithProfile = mathIC->arithProfile(); 869 862 if (arithProfile && shouldEmitProfiling()) { 870 863 if (mathICGenerationState.shouldSlowPathRepatch) … … 894 887 { 895 888 auto bytecode = currentInstruction->as<OpDiv>(); 896 auto& metadata = bytecode.metadata(m_codeBlock);897 889 int result = bytecode.m_dst.offset(); 898 890 int op1 = bytecode.m_lhs.offset(); … … 900 892 901 893 #if USE(JSVALUE64) 902 OperandTypes types = getOperandTypes(metadata.m_arithProfile);903 894 JSValueRegs leftRegs = JSValueRegs(regT0); 904 895 JSValueRegs rightRegs = JSValueRegs(regT1); … … 906 897 GPRReg scratchGPR = regT2; 907 898 #else 908 OperandTypes types = getOperandTypes(metadata.m_arithProfile);909 899 JSValueRegs leftRegs = JSValueRegs(regT1, regT0); 910 900 JSValueRegs rightRegs = JSValueRegs(regT3, regT2); … … 914 904 FPRReg scratchFPR = fpRegT2; 915 905 916 ArithProfile* arithProfile = nullptr;906 BinaryArithProfile* arithProfile = nullptr; 917 907 if (shouldEmitProfiling()) 918 908 arithProfile = ¤tInstruction->as<OpDiv>().metadata(m_codeBlock).m_arithProfile; 919 909 920 SnippetOperand leftOperand( types.first());921 SnippetOperand rightOperand( types.second());910 SnippetOperand leftOperand(bytecode.m_operandTypes.first()); 911 SnippetOperand rightOperand(bytecode.m_operandTypes.second()); 922 912 923 913 if (isOperandConstantInt(op1)) … … 961 951 void JIT::emit_op_mul(const Instruction* currentInstruction) 962 952 { 963 ArithProfile* arithProfile = ¤tInstruction->as<OpMul>().metadata(m_codeBlock).m_arithProfile;953 BinaryArithProfile* arithProfile = ¤tInstruction->as<OpMul>().metadata(m_codeBlock).m_arithProfile; 964 954 JITMulIC* mulIC = m_codeBlock->addJITMulIC(arithProfile); 965 955 m_instructionToMathIC.add(currentInstruction, mulIC); … … 977 967 void JIT::emit_op_sub(const Instruction* currentInstruction) 978 968 { 979 ArithProfile* arithProfile = ¤tInstruction->as<OpSub>().metadata(m_codeBlock).m_arithProfile;969 BinaryArithProfile* arithProfile = ¤tInstruction->as<OpSub>().metadata(m_codeBlock).m_arithProfile; 980 970 JITSubIC* subIC = m_codeBlock->addJITSubIC(arithProfile); 981 971 m_instructionToMathIC.add(currentInstruction, subIC); -
trunk/Source/JavaScriptCore/jit/JITDivGenerator.cpp
r251106 r252015 131 131 #endif 132 132 if (m_arithProfile) 133 jit.or32(CCallHelpers::TrustedImm32( ArithProfile::specialFastPathBit), CCallHelpers::AbsoluteAddress(m_arithProfile->addressOfBits()));133 jit.or32(CCallHelpers::TrustedImm32(BinaryArithProfile::specialFastPathBit), CCallHelpers::AbsoluteAddress(m_arithProfile->addressOfBits())); 134 134 jit.boxDouble(m_leftFPR, m_result); 135 135 } -
trunk/Source/JavaScriptCore/jit/JITDivGenerator.h
r251106 r252015 38 38 JSValueRegs result, JSValueRegs left, JSValueRegs right, 39 39 FPRReg leftFPR, FPRReg rightFPR, GPRReg scratchGPR, FPRReg scratchFPR, 40 ArithProfile* arithProfile = nullptr)40 BinaryArithProfile* arithProfile = nullptr) 41 41 : m_leftOperand(leftOperand) 42 42 , m_rightOperand(rightOperand) … … 72 72 FPRReg m_scratchFPR; 73 73 bool m_didEmitFastPath { false }; 74 ArithProfile* m_arithProfile;74 BinaryArithProfile* m_arithProfile; 75 75 76 76 CCallHelpers::JumpList m_endJumpList; -
trunk/Source/JavaScriptCore/jit/JITInlines.h
r251534 r252015 717 717 718 718 template<typename BinaryOp> 719 ALWAYS_INLINE ArithProfile JIT::copiedArithProfile(BinaryOp bytecode)719 ALWAYS_INLINE BinaryArithProfile JIT::copiedArithProfile(BinaryOp bytecode) 720 720 { 721 721 uint64_t key = (static_cast<uint64_t>(BinaryOp::opcodeID) + 1) << 32 | static_cast<uint64_t>(bytecode.m_metadataID); … … 723 723 if (iterator != m_copiedArithProfiles.end()) 724 724 return iterator->value; 725 ArithProfile arithProfile = bytecode.metadata(m_codeBlock).m_arithProfile;725 BinaryArithProfile arithProfile = bytecode.metadata(m_codeBlock).m_arithProfile; 726 726 m_copiedArithProfiles.add(key, arithProfile); 727 727 return arithProfile; -
trunk/Source/JavaScriptCore/jit/JITMathIC.h
r251106 r252015 53 53 #define ENABLE_MATH_IC_STATS 0 54 54 55 template <typename GeneratorType, bool(*isProfileEmpty)(ArithProfile&)>55 template <typename GeneratorType, typename ArithProfileType> 56 56 class JITMathIC { 57 57 WTF_MAKE_FAST_ALLOCATED; 58 58 public: 59 JITMathIC(ArithProfile * arithProfile)59 JITMathIC(ArithProfileType* arithProfile) 60 60 : m_arithProfile(arithProfile) 61 61 { … … 72 72 73 73 if (m_arithProfile) { 74 if ( isProfileEmpty(*m_arithProfile)) {74 if (m_arithProfile->isObservedTypeEmpty()) { 75 75 // It looks like the MathIC has yet to execute. We don't want to emit code in this 76 76 // case for a couple reasons. First, the operation may never execute, so if we don't emit … … 224 224 } 225 225 226 ArithProfile * arithProfile() const { return m_arithProfile; }226 ArithProfileType* arithProfile() const { return m_arithProfile; } 227 227 228 228 #if ENABLE(MATH_IC_STATS) … … 237 237 #endif 238 238 239 ArithProfile * m_arithProfile;239 ArithProfileType* m_arithProfile; 240 240 MacroAssemblerCodeRef<JITStubRoutinePtrTag> m_code; 241 241 CodeLocationLabel<JSInternalPtrTag> m_inlineStart; … … 247 247 }; 248 248 249 inline bool isBinaryProfileEmpty(ArithProfile& arithProfile)250 {251 return arithProfile.lhsObservedType().isEmpty() || arithProfile.rhsObservedType().isEmpty();252 }253 249 template <typename GeneratorType> 254 class JITBinaryMathIC : public JITMathIC<GeneratorType, isBinaryProfileEmpty> {250 class JITBinaryMathIC : public JITMathIC<GeneratorType, BinaryArithProfile> { 255 251 public: 256 JITBinaryMathIC( ArithProfile* arithProfile)257 : JITMathIC<GeneratorType, isBinaryProfileEmpty>(arithProfile)252 JITBinaryMathIC(BinaryArithProfile* arithProfile) 253 : JITMathIC<GeneratorType, BinaryArithProfile>(arithProfile) 258 254 { 259 255 } … … 264 260 typedef JITBinaryMathIC<JITSubGenerator> JITSubIC; 265 261 266 267 inline bool isUnaryProfileEmpty(ArithProfile& arithProfile)268 {269 return arithProfile.lhsObservedType().isEmpty();270 }271 262 template <typename GeneratorType> 272 class JITUnaryMathIC : public JITMathIC<GeneratorType, isUnaryProfileEmpty> {263 class JITUnaryMathIC : public JITMathIC<GeneratorType, UnaryArithProfile> { 273 264 public: 274 JITUnaryMathIC( ArithProfile* arithProfile)275 : JITMathIC<GeneratorType, isUnaryProfileEmpty>(arithProfile)265 JITUnaryMathIC(UnaryArithProfile* arithProfile) 266 : JITMathIC<GeneratorType, UnaryArithProfile>(arithProfile) 276 267 { 277 268 } -
trunk/Source/JavaScriptCore/jit/JITMulGenerator.cpp
r251106 r252015 34 34 namespace JSC { 35 35 36 JITMathICInlineResult JITMulGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const ArithProfile* arithProfile)36 JITMathICInlineResult JITMulGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const BinaryArithProfile* arithProfile) 37 37 { 38 38 // We default to speculating int32. … … 90 90 } 91 91 92 bool JITMulGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile* arithProfile, bool shouldEmitProfiling)92 bool JITMulGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const BinaryArithProfile* arithProfile, bool shouldEmitProfiling) 93 93 { 94 94 ASSERT(m_scratchGPR != InvalidGPRReg); … … 206 206 CCallHelpers::Jump notNegativeZero = jit.branch64(CCallHelpers::NotEqual, m_result.payloadGPR(), CCallHelpers::TrustedImm64(negativeZeroBits)); 207 207 208 jit.or32(CCallHelpers::TrustedImm32( ArithProfile::NegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));208 jit.or32(CCallHelpers::TrustedImm32(BinaryArithProfile::NegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits())); 209 209 CCallHelpers::Jump done = jit.jump(); 210 210 211 211 notNegativeZero.link(&jit); 212 jit.or32(CCallHelpers::TrustedImm32( ArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));212 jit.or32(CCallHelpers::TrustedImm32(BinaryArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits())); 213 213 214 214 jit.move(m_result.payloadGPR(), m_scratchGPR); … … 217 217 CCallHelpers::Jump noInt52Overflow = jit.branch32(CCallHelpers::LessThanOrEqual, m_scratchGPR, CCallHelpers::TrustedImm32(0x431)); 218 218 219 jit.or32(CCallHelpers::TrustedImm32( ArithProfile::Int52Overflow), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));219 jit.or32(CCallHelpers::TrustedImm32(BinaryArithProfile::Int52Overflow), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits())); 220 220 noInt52Overflow.link(&jit); 221 221 … … 228 228 notNegativeZero.append(jit.branch32(CCallHelpers::NotEqual, m_result.tagGPR(), CCallHelpers::TrustedImm32(negativeZeroBits >> 32))); 229 229 230 jit.or32(CCallHelpers::TrustedImm32( ArithProfile::NegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));230 jit.or32(CCallHelpers::TrustedImm32(BinaryArithProfile::NegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits())); 231 231 CCallHelpers::Jump done = jit.jump(); 232 232 233 233 notNegativeZero.link(&jit); 234 jit.or32(CCallHelpers::TrustedImm32( ArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));234 jit.or32(CCallHelpers::TrustedImm32(BinaryArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits())); 235 235 236 236 jit.move(m_result.tagGPR(), m_scratchGPR); … … 239 239 CCallHelpers::Jump noInt52Overflow = jit.branch32(CCallHelpers::LessThanOrEqual, m_scratchGPR, CCallHelpers::TrustedImm32(0x431)); 240 240 241 jit.or32(CCallHelpers::TrustedImm32( ArithProfile::Int52Overflow), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));241 jit.or32(CCallHelpers::TrustedImm32(BinaryArithProfile::Int52Overflow), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits())); 242 242 243 243 endJumpList.append(noInt52Overflow); -
trunk/Source/JavaScriptCore/jit/JITMulGenerator.h
r251106 r252015 57 57 } 58 58 59 JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const ArithProfile*);60 bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowJumpList, const ArithProfile*, bool shouldEmitProfiling);59 JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const BinaryArithProfile*); 60 bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowJumpList, const BinaryArithProfile*, bool shouldEmitProfiling); 61 61 62 62 static bool isLeftOperandValidConstant(SnippetOperand leftOperand) { return leftOperand.isPositiveConstInt32(); } -
trunk/Source/JavaScriptCore/jit/JITNegGenerator.cpp
r251106 r252015 33 33 namespace JSC { 34 34 35 JITMathICInlineResult JITNegGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const ArithProfile* arithProfile)35 JITMathICInlineResult JITNegGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const UnaryArithProfile* arithProfile) 36 36 { 37 37 ASSERT(m_scratchGPR != InvalidGPRReg); … … 46 46 ObservedType observedTypes = ObservedType().withInt32(); 47 47 if (arithProfile) 48 observedTypes = arithProfile-> lhsObservedType();48 observedTypes = arithProfile->argObservedType(); 49 49 ASSERT_WITH_MESSAGE(!observedTypes.isEmpty(), "We should not attempt to generate anything if we do not have a profile."); 50 50 … … 83 83 } 84 84 85 bool JITNegGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile* arithProfile, bool shouldEmitProfiling)85 bool JITNegGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const UnaryArithProfile* arithProfile, bool shouldEmitProfiling) 86 86 { 87 87 ASSERT(m_scratchGPR != m_src.payloadGPR()); … … 118 118 // The flags of ArithNegate are basic in DFG. 119 119 // We only need to know if we ever produced a number. 120 if (shouldEmitProfiling && arithProfile && !arithProfile-> lhsObservedType().sawNumber() && !arithProfile->didObserveDouble())120 if (shouldEmitProfiling && arithProfile && !arithProfile->argObservedType().sawNumber() && !arithProfile->didObserveDouble()) 121 121 arithProfile->emitSetDouble(jit); 122 122 return true; -
trunk/Source/JavaScriptCore/jit/JITNegGenerator.h
r251106 r252015 44 44 { } 45 45 46 JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const ArithProfile*);47 bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile*, bool shouldEmitProfiling);46 JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const UnaryArithProfile*); 47 bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const UnaryArithProfile*, bool shouldEmitProfiling); 48 48 49 49 private: -
trunk/Source/JavaScriptCore/jit/JITOperations.cpp
r251903 r252015 2645 2645 } 2646 2646 2647 ALWAYS_INLINE static JSValue profiledAdd(JSGlobalObject* globalObject, JSValue op1, JSValue op2, ArithProfile& arithProfile)2647 ALWAYS_INLINE static JSValue profiledAdd(JSGlobalObject* globalObject, JSValue op1, JSValue op2, BinaryArithProfile& arithProfile) 2648 2648 { 2649 2649 arithProfile.observeLHSAndRHS(op1, op2); … … 2661 2661 } 2662 2662 2663 EncodedJSValue JIT_OPERATION operationValueAddProfiled(JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)2663 EncodedJSValue JIT_OPERATION operationValueAddProfiled(JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile* arithProfile) 2664 2664 { 2665 2665 ASSERT(arithProfile); … … 2679 2679 JSValue op2 = JSValue::decode(encodedOp2); 2680 2680 2681 ArithProfile* arithProfile = addIC->arithProfile();2681 BinaryArithProfile* arithProfile = addIC->arithProfile(); 2682 2682 ASSERT(arithProfile); 2683 2683 arithProfile->observeLHSAndRHS(op1, op2); … … 2701 2701 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 2702 2702 2703 ArithProfile* arithProfile = addIC->arithProfile();2703 BinaryArithProfile* arithProfile = addIC->arithProfile(); 2704 2704 ASSERT(arithProfile); 2705 2705 return JSValue::encode(profiledAdd(globalObject, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2), *arithProfile)); … … 2716 2716 2717 2717 auto nonOptimizeVariant = operationValueAddNoOptimize; 2718 if ( ArithProfile* arithProfile = addIC->arithProfile())2718 if (BinaryArithProfile* arithProfile = addIC->arithProfile()) 2719 2719 arithProfile->observeLHSAndRHS(op1, op2); 2720 2720 addIC->generateOutOfLine(callFrame->codeBlock(), nonOptimizeVariant); … … 2749 2749 } 2750 2750 2751 ALWAYS_INLINE static EncodedJSValue profiledMul(JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true)2751 ALWAYS_INLINE static EncodedJSValue profiledMul(JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true) 2752 2752 { 2753 2753 VM& vm = globalObject->vm(); … … 2790 2790 2791 2791 auto nonOptimizeVariant = operationValueMulNoOptimize; 2792 if ( ArithProfile* arithProfile = mulIC->arithProfile())2792 if (BinaryArithProfile* arithProfile = mulIC->arithProfile()) 2793 2793 arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2)); 2794 2794 mulIC->generateOutOfLine(callFrame->codeBlock(), nonOptimizeVariant); … … 2801 2801 } 2802 2802 2803 EncodedJSValue JIT_OPERATION operationValueMulProfiled(JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)2803 EncodedJSValue JIT_OPERATION operationValueMulProfiled(JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile* arithProfile) 2804 2804 { 2805 2805 VM& vm = globalObject->vm(); … … 2817 2817 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 2818 2818 2819 ArithProfile* arithProfile = mulIC->arithProfile();2819 BinaryArithProfile* arithProfile = mulIC->arithProfile(); 2820 2820 ASSERT(arithProfile); 2821 2821 arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2)); … … 2836 2836 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 2837 2837 2838 ArithProfile* arithProfile = mulIC->arithProfile();2838 BinaryArithProfile* arithProfile = mulIC->arithProfile(); 2839 2839 ASSERT(arithProfile); 2840 2840 return profiledMul(globalObject, encodedOp1, encodedOp2, *arithProfile); … … 2862 2862 } 2863 2863 2864 EncodedJSValue JIT_OPERATION operationArithNegateProfiled(JSGlobalObject* globalObject, EncodedJSValue encodedOperand, ArithProfile* arithProfile)2864 EncodedJSValue JIT_OPERATION operationArithNegateProfiled(JSGlobalObject* globalObject, EncodedJSValue encodedOperand, UnaryArithProfile* arithProfile) 2865 2865 { 2866 2866 ASSERT(arithProfile); … … 2871 2871 2872 2872 JSValue operand = JSValue::decode(encodedOperand); 2873 arithProfile->observe LHS(operand);2873 arithProfile->observeArg(operand); 2874 2874 2875 2875 JSValue primValue = operand.toPrimitive(globalObject); … … 2899 2899 JSValue operand = JSValue::decode(encodedOperand); 2900 2900 2901 ArithProfile* arithProfile = negIC->arithProfile();2901 UnaryArithProfile* arithProfile = negIC->arithProfile(); 2902 2902 ASSERT(arithProfile); 2903 arithProfile->observe LHS(operand);2903 arithProfile->observeArg(operand); 2904 2904 negIC->generateOutOfLine(callFrame->codeBlock(), operationArithNegateProfiled); 2905 2905 … … 2933 2933 JSValue operand = JSValue::decode(encodedOperand); 2934 2934 2935 if ( ArithProfile* arithProfile = negIC->arithProfile())2936 arithProfile->observe LHS(operand);2935 if (UnaryArithProfile* arithProfile = negIC->arithProfile()) 2936 arithProfile->observeArg(operand); 2937 2937 negIC->generateOutOfLine(callFrame->codeBlock(), operationArithNegate); 2938 2938 … … 2960 2960 } 2961 2961 2962 ALWAYS_INLINE static EncodedJSValue profiledSub(VM& vm, JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true)2962 ALWAYS_INLINE static EncodedJSValue profiledSub(VM& vm, JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true) 2963 2963 { 2964 2964 auto scope = DECLARE_THROW_SCOPE(vm); … … 2984 2984 } 2985 2985 2986 EncodedJSValue JIT_OPERATION operationValueSubProfiled(JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)2986 EncodedJSValue JIT_OPERATION operationValueSubProfiled(JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile* arithProfile) 2987 2987 { 2988 2988 ASSERT(arithProfile); … … 3002 3002 3003 3003 auto nonOptimizeVariant = operationValueSubNoOptimize; 3004 if ( ArithProfile* arithProfile = subIC->arithProfile())3004 if (BinaryArithProfile* arithProfile = subIC->arithProfile()) 3005 3005 arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2)); 3006 3006 subIC->generateOutOfLine(callFrame->codeBlock(), nonOptimizeVariant); … … 3028 3028 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 3029 3029 3030 ArithProfile* arithProfile = subIC->arithProfile();3030 BinaryArithProfile* arithProfile = subIC->arithProfile(); 3031 3031 ASSERT(arithProfile); 3032 3032 arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2)); … … 3047 3047 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 3048 3048 3049 ArithProfile* arithProfile = subIC->arithProfile();3049 BinaryArithProfile* arithProfile = subIC->arithProfile(); 3050 3050 ASSERT(arithProfile); 3051 3051 return profiledSub(vm, globalObject, encodedOp1, encodedOp2, *arithProfile); -
trunk/Source/JavaScriptCore/jit/JITOperations.h
r251518 r252015 39 39 class ArrayAllocationProfile; 40 40 class ArrayProfile; 41 class UnaryArithProfile; 42 class BinaryArithProfile; 41 43 class Butterfly; 42 44 class CallFrame; … … 65 67 struct InlineCallFrame; 66 68 struct Instruction; 67 struct ArithProfile;68 69 69 70 extern "C" { … … 78 79 Aap: ArrayAllocationProfile* 79 80 Ap: ArrayProfile* 80 Arp: ArithProfile*81 Arp: BinaryArithProfile* 81 82 B: Butterfly* 82 83 By: ByValInfo* … … 283 284 284 285 EncodedJSValue JIT_OPERATION operationValueAdd(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL; 285 EncodedJSValue JIT_OPERATION operationValueAddProfiled(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*) WTF_INTERNAL;286 EncodedJSValue JIT_OPERATION operationValueAddProfiled(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile*) WTF_INTERNAL; 286 287 EncodedJSValue JIT_OPERATION operationValueAddProfiledOptimize(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC*) WTF_INTERNAL; 287 288 EncodedJSValue JIT_OPERATION operationValueAddProfiledNoOptimize(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC*) WTF_INTERNAL; … … 293 294 EncodedJSValue JIT_OPERATION operationValueMulProfiledOptimize(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC*) WTF_INTERNAL; 294 295 EncodedJSValue JIT_OPERATION operationValueMulProfiledNoOptimize(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC*) WTF_INTERNAL; 295 EncodedJSValue JIT_OPERATION operationValueMulProfiled(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*) WTF_INTERNAL;296 EncodedJSValue JIT_OPERATION operationValueMulProfiled(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile*) WTF_INTERNAL; 296 297 EncodedJSValue JIT_OPERATION operationArithNegate(JSGlobalObject*, EncodedJSValue operand); 297 EncodedJSValue JIT_OPERATION operationArithNegateProfiled(JSGlobalObject*, EncodedJSValue operand, ArithProfile*);298 EncodedJSValue JIT_OPERATION operationArithNegateProfiled(JSGlobalObject*, EncodedJSValue operand, UnaryArithProfile*); 298 299 EncodedJSValue JIT_OPERATION operationArithNegateProfiledOptimize(JSGlobalObject*, EncodedJSValue encodedOperand, JITNegIC*); 299 300 EncodedJSValue JIT_OPERATION operationArithNegateOptimize(JSGlobalObject*, EncodedJSValue encodedOperand, JITNegIC*); 300 301 EncodedJSValue JIT_OPERATION operationValueSub(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL; 301 EncodedJSValue JIT_OPERATION operationValueSubProfiled(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*) WTF_INTERNAL;302 EncodedJSValue JIT_OPERATION operationValueSubProfiled(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile*) WTF_INTERNAL; 302 303 EncodedJSValue JIT_OPERATION operationValueSubOptimize(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC*) WTF_INTERNAL; 303 304 EncodedJSValue JIT_OPERATION operationValueSubNoOptimize(JSGlobalObject*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC*) WTF_INTERNAL; -
trunk/Source/JavaScriptCore/jit/JITSubGenerator.cpp
r251106 r252015 34 34 namespace JSC { 35 35 36 JITMathICInlineResult JITSubGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const ArithProfile* arithProfile)36 JITMathICInlineResult JITSubGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const BinaryArithProfile* arithProfile) 37 37 { 38 38 // We default to speculating int32. … … 79 79 } 80 80 81 bool JITSubGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile* arithProfile, bool shouldEmitProfiling)81 bool JITSubGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const BinaryArithProfile* arithProfile, bool shouldEmitProfiling) 82 82 { 83 83 ASSERT(m_scratchGPR != InvalidGPRReg); -
trunk/Source/JavaScriptCore/jit/JITSubGenerator.h
r251106 r252015 54 54 { } 55 55 56 JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const ArithProfile*);57 bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile*, bool shouldEmitProfiling);56 JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const BinaryArithProfile*); 57 bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const BinaryArithProfile*, bool shouldEmitProfiling); 58 58 59 59 static bool isLeftOperandValidConstant(SnippetOperand) { return false; } -
trunk/Source/JavaScriptCore/llint/LLIntData.cpp
r251886 r252015 148 148 149 149 { 150 ArithProfile arithProfile; 150 UnaryArithProfile arithProfile; 151 arithProfile.argSawInt32(); 152 ASSERT(arithProfile.bits() == UnaryArithProfile::observedIntBits()); 153 ASSERT(arithProfile.argObservedType().isOnlyInt32()); 154 } 155 { 156 UnaryArithProfile arithProfile; 157 arithProfile.argSawNumber(); 158 ASSERT(arithProfile.bits() == UnaryArithProfile::observedNumberBits()); 159 ASSERT(arithProfile.argObservedType().isOnlyNumber()); 160 } 161 162 { 163 BinaryArithProfile arithProfile; 151 164 arithProfile.lhsSawInt32(); 152 165 arithProfile.rhsSawInt32(); 153 ASSERT(arithProfile.bits() == ArithProfile::observedBinaryIntInt().bits());154 STATIC_ASSERT(ArithProfile::observedBinaryIntInt().lhsObservedType().isOnlyInt32());155 STATIC_ASSERT(ArithProfile::observedBinaryIntInt().rhsObservedType().isOnlyInt32());166 ASSERT(arithProfile.bits() == BinaryArithProfile::observedIntIntBits()); 167 ASSERT(arithProfile.lhsObservedType().isOnlyInt32()); 168 ASSERT(arithProfile.rhsObservedType().isOnlyInt32()); 156 169 } 157 170 { 158 ArithProfile arithProfile;171 BinaryArithProfile arithProfile; 159 172 arithProfile.lhsSawNumber(); 160 173 arithProfile.rhsSawInt32(); 161 ASSERT(arithProfile.bits() == ArithProfile::observedBinaryNumberInt().bits());162 STATIC_ASSERT(ArithProfile::observedBinaryNumberInt().lhsObservedType().isOnlyNumber());163 STATIC_ASSERT(ArithProfile::observedBinaryNumberInt().rhsObservedType().isOnlyInt32());174 ASSERT(arithProfile.bits() == BinaryArithProfile::observedNumberIntBits()); 175 ASSERT(arithProfile.lhsObservedType().isOnlyNumber()); 176 ASSERT(arithProfile.rhsObservedType().isOnlyInt32()); 164 177 } 165 178 { 166 ArithProfile arithProfile;179 BinaryArithProfile arithProfile; 167 180 arithProfile.lhsSawNumber(); 168 181 arithProfile.rhsSawNumber(); 169 ASSERT(arithProfile.bits() == ArithProfile::observedBinaryNumberNumber().bits());170 STATIC_ASSERT(ArithProfile::observedBinaryNumberNumber().lhsObservedType().isOnlyNumber());171 STATIC_ASSERT(ArithProfile::observedBinaryNumberNumber().rhsObservedType().isOnlyNumber());182 ASSERT(arithProfile.bits() == BinaryArithProfile::observedNumberNumberBits()); 183 ASSERT(arithProfile.lhsObservedType().isOnlyNumber()); 184 ASSERT(arithProfile.rhsObservedType().isOnlyNumber()); 172 185 } 173 186 { 174 ArithProfile arithProfile;187 BinaryArithProfile arithProfile; 175 188 arithProfile.lhsSawInt32(); 176 189 arithProfile.rhsSawNumber(); 177 ASSERT(arithProfile.bits() == ArithProfile::observedBinaryIntNumber().bits());178 STATIC_ASSERT(ArithProfile::observedBinaryIntNumber().lhsObservedType().isOnlyInt32());179 STATIC_ASSERT(ArithProfile::observedBinaryIntNumber().rhsObservedType().isOnlyNumber());190 ASSERT(arithProfile.bits() == BinaryArithProfile::observedIntNumberBits()); 191 ASSERT(arithProfile.lhsObservedType().isOnlyInt32()); 192 ASSERT(arithProfile.rhsObservedType().isOnlyNumber()); 180 193 } 181 194 } -
trunk/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp
r251886 r252015 92 92 const int64_t* LLIntOffsetsExtractor::dummy() 93 93 { 94 // This is a file generated by offlineasm/generate_offset s_extractor.rb, and contains code94 // This is a file generated by offlineasm/generate_offset_extractor.rb, and contains code 95 95 // to create a table of offsets, sizes, and a header identifying what combination of 96 96 // Platform.h macros we have set. We include it inside of a method on LLIntOffsetsExtractor -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
r251904 r252015 242 242 const ShadowChickenTailMarker = constexpr ShadowChicken::Packet::tailMarkerValue 243 243 244 # ArithProfile data 245 const ArithProfileInt = constexpr (ArithProfile::observedUnaryInt().bits()) 246 const ArithProfileNumber = constexpr (ArithProfile::observedUnaryNumber().bits()) 247 const ArithProfileIntInt = constexpr (ArithProfile::observedBinaryIntInt().bits()) 248 const ArithProfileNumberInt = constexpr (ArithProfile::observedBinaryNumberInt().bits()) 249 const ArithProfileIntNumber = constexpr (ArithProfile::observedBinaryIntNumber().bits()) 250 const ArithProfileNumberNumber = constexpr (ArithProfile::observedBinaryNumberNumber().bits()) 244 # UnaryArithProfile data 245 const ArithProfileInt = constexpr (UnaryArithProfile::observedIntBits()) 246 const ArithProfileNumber = constexpr (UnaryArithProfile::observedNumberBits()) 247 248 # BinaryArithProfile data 249 const ArithProfileIntInt = constexpr (BinaryArithProfile::observedIntIntBits()) 250 const ArithProfileNumberInt = constexpr (BinaryArithProfile::observedNumberIntBits()) 251 const ArithProfileIntNumber = constexpr (BinaryArithProfile::observedIntNumberBits()) 252 const ArithProfileNumberNumber = constexpr (BinaryArithProfile::observedNumberNumberBits()) 251 253 252 254 # Pointer Tags -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
r251894 r252015 993 993 llintOpWithMetadata(op_negate, OpNegate, macro (size, get, dispatch, metadata, return) 994 994 995 macro arithProfile(type)996 or i type, OpNegate::Metadata::m_arithProfile +ArithProfile::m_bits[t5]995 macro updateArithProfile(type) 996 orh type, OpNegate::Metadata::m_arithProfile + UnaryArithProfile::m_bits[t5] 997 997 end 998 998 … … 1003 1003 btiz t2, 0x7fffffff, .opNegateSlow 1004 1004 negi t2 1005 arithProfile(ArithProfileInt)1005 updateArithProfile(ArithProfileInt) 1006 1006 return (Int32Tag, t2) 1007 1007 .opNegateSrcNotInt: 1008 1008 bia t1, LowestTag, .opNegateSlow 1009 1009 xori 0x80000000, t1 1010 arithProfile(ArithProfileNumber)1010 updateArithProfile(ArithProfileNumber) 1011 1011 return(t1, t2) 1012 1012 … … 1020 1020 llintOpWithMetadata(op_%opcodeName%, opcodeStruct, macro (size, get, dispatch, metadata, return) 1021 1021 macro arithProfile(type) 1022 or i type, %opcodeStruct%::Metadata::m_arithProfile +ArithProfile::m_bits[t5]1022 orh type, %opcodeStruct%::Metadata::m_arithProfile + BinaryArithProfile::m_bits[t5] 1023 1023 end 1024 1024 -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
r251886 r252015 965 965 966 966 llintOpWithMetadata(op_negate, OpNegate, macro (size, get, dispatch, metadata, return) 967 968 macro updateArithProfile(type) 969 orh type, OpNegate::Metadata::m_arithProfile + UnaryArithProfile::m_bits[t1] 970 end 971 967 972 get(m_operand, t0) 968 973 loadConstantOrVariable(size, t0, t3) 969 974 metadata(t1, t2) 970 loadi OpNegate::Metadata::m_arithProfile + ArithProfile::m_bits[t1], t2971 975 bqb t3, numberTag, .opNegateNotInt 972 976 btiz t3, 0x7fffffff, .opNegateSlow 973 977 negi t3 974 978 orq numberTag, t3 975 ori ArithProfileInt, t2 976 storei t2, OpNegate::Metadata::m_arithProfile + ArithProfile::m_bits[t1] 979 updateArithProfile(ArithProfileInt) 977 980 return(t3) 978 981 .opNegateNotInt: 979 982 btqz t3, numberTag, .opNegateSlow 980 983 xorq 0x8000000000000000, t3 981 ori ArithProfileNumber, t2 982 storei t2, OpNegate::Metadata::m_arithProfile + ArithProfile::m_bits[t1] 984 updateArithProfile(ArithProfileNumber) 983 985 return(t3) 984 986 … … 994 996 995 997 macro profile(type) 996 or i type, %opcodeStruct%::Metadata::m_arithProfile +ArithProfile::m_bits[t5]998 orh type, %opcodeStruct%::Metadata::m_arithProfile + UnaryArithProfile::m_bits[t5] 997 999 end 998 1000 -
trunk/Source/JavaScriptCore/offlineasm/arm.rb
r251966 r252015 300 300 } 301 301 result = riscLowerMalformedAddressesDouble(result) 302 result = riscLowerMisplacedImmediates(result, ["storeb", "store i", "storep", "storeq"])302 result = riscLowerMisplacedImmediates(result, ["storeb", "storeh", "storei", "storep", "storeq"]) 303 303 result = riscLowerMalformedImmediates(result, 0..0xff, 0..0x0ff) 304 304 result = riscLowerMisplacedAddresses(result) … … 419 419 when "andi", "andp" 420 420 emitArmCompact("ands", "and", operands) 421 when "ori", "orp" 421 when "ori", "orp", "orh" 422 422 emitArmCompact("orrs", "orr", operands) 423 423 when "oris" -
trunk/Source/JavaScriptCore/offlineasm/arm64.rb
r251966 r252015 394 394 when "loadb", "loadbsi", "loadbsq", "storeb", /^bb/, /^btb/, /^cb/, /^tb/ 395 395 size = 1 396 when "loadh", "loadhsi", "loadhsq", " storeh"396 when "loadh", "loadhsi", "loadhsq", "orh", "storeh" 397 397 size = 2 398 398 when "loadi", "loadis", "storei", "addi", "andi", "lshifti", "muli", "negi", … … 419 419 } 420 420 421 result = riscLowerMisplacedImmediates(result, ["storeb", "store i", "storep", "storeq"])421 result = riscLowerMisplacedImmediates(result, ["storeb", "storeh", "storei", "storep", "storeq"]) 422 422 423 423 # The rules for which immediates are valid for and/or/xor instructions are fairly involved, see https://dinfuehr.github.io/blog/encoding-of-immediate-values-on-aarch64/ … … 712 712 when "orq" 713 713 emitARM64TAC("orr", operands, :quad) 714 when "orh" 715 emitARM64TAC("orr", operands, :word) # not :half because 16-bit registers don't exist on ARM. 714 716 when "xori" 715 717 emitARM64TAC("eor", operands, :word) -
trunk/Source/JavaScriptCore/offlineasm/cloop.rb
r251893 r252015 586 586 when "orp" 587 587 cloopEmitOperation(operands, :intptr, "|") 588 when "orh" 589 cloopEmitOperation(operands, :int16, "|") 588 590 589 591 when "xori" -
trunk/Source/JavaScriptCore/offlineasm/instructions.rb
r251886 r252015 47 47 "orf", 48 48 "ord", 49 "orh", 49 50 "rshifti", 50 51 "urshifti", -
trunk/Source/JavaScriptCore/offlineasm/mips.rb
r251966 r252015 528 528 when /^(addi|subi)/ 529 529 newList << node.riscLowerMalformedImmediatesRecurse(newList, -0x7fff..0x7fff) 530 when "andi", "andp", "ori", "orp", " xori", "xorp"530 when "andi", "andp", "ori", "orp", "orh", "xori", "xorp" 531 531 newList << node.riscLowerMalformedImmediatesRecurse(newList, 0..0xffff) 532 532 else … … 861 861 when "andi", "andp" 862 862 emitMIPSCompact("and", "and", operands) 863 when "ori", "orp" 863 when "ori", "orp", "orh" 864 864 emitMIPSCompact("or", "orr", operands) 865 865 when "oris" -
trunk/Source/JavaScriptCore/offlineasm/risc.rb
r251966 r252015 463 463 annotation = node.annotation 464 464 case node.opcode 465 when "addi", "addis", "andi", "lshifti", "muli", "negi", "noti", "ori", "or is",465 when "addi", "addis", "andi", "lshifti", "muli", "negi", "noti", "ori", "orh", "oris", 466 466 "rshifti", "urshifti", "subi", "subis", "xori", /^bi/, /^bti/, /^ci/, /^ti/ 467 467 newList << Instruction.new(node.codeOrigin, -
trunk/Source/JavaScriptCore/offlineasm/x86.rb
r251905 r252015 1124 1124 when "ord" 1125 1125 handleX86Op("orpd", :double) 1126 when "orh" 1127 handleX86Op("or#{x86Suffix(:half)}", :half) 1126 1128 when "rshifti" 1127 1129 handleX86Shift("sar#{x86Suffix(:int)}", :int) -
trunk/Source/JavaScriptCore/parser/ResultType.h
r251106 r252015 49 49 static_assert((TypeBits & ((1 << numBitsNeeded) - 1)) == TypeBits, "This is necessary for correctness."); 50 50 51 constexpr explicit ResultType() 52 : ResultType(unknownType()) 53 { 54 } 51 55 constexpr explicit ResultType(Type type) 52 56 : m_bits(type) -
trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
r251518 r252015 477 477 static void updateArithProfileForUnaryArithOp(OpNegate::Metadata& metadata, JSValue result, JSValue operand) 478 478 { 479 ArithProfile& profile = metadata.m_arithProfile;480 profile.observe LHS(operand);479 UnaryArithProfile& profile = metadata.m_arithProfile; 480 profile.observeArg(operand); 481 481 ASSERT(result.isNumber() || result.isBigInt()); 482 482 if (result.isNumber()) { … … 535 535 static void updateArithProfileForBinaryArithOp(JSGlobalObject*, CodeBlock* codeBlock, const Instruction* pc, JSValue result, JSValue left, JSValue right) 536 536 { 537 ArithProfile& profile = *codeBlock->arithProfileForPC(pc);537 BinaryArithProfile& profile = *codeBlock->binaryArithProfileForPC(pc); 538 538 539 539 if (result.isNumber()) { … … 596 596 JSValue v2 = GET_C(bytecode.m_rhs).jsValue(); 597 597 598 ArithProfile& arithProfile = *codeBlock->arithProfileForPC(pc);598 BinaryArithProfile& arithProfile = *codeBlock->binaryArithProfileForPC(pc); 599 599 arithProfile.observeLHSAndRHS(v1, v2); 600 600
Note:
See TracChangeset
for help on using the changeset viewer.