Changeset 251090 in webkit
- Timestamp:
- Oct 14, 2019 1:28:41 PM (4 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 39 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r251088 r251090 1 2019-10-14 Robin Morisset <rmorisset@apple.com> 2 3 Split ArithProfile into a Unary and a Binary version 4 https://bugs.webkit.org/show_bug.cgi?id=202832 5 6 Reviewed by Keith Miller. 7 8 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. 9 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. 10 11 * bytecode/ArithProfile.cpp: 12 (JSC::ArithProfile<BitfieldType>::emitObserveResult): 13 (JSC::ArithProfile<BitfieldType>::shouldEmitSetDouble const): 14 (JSC::ArithProfile<BitfieldType>::emitSetDouble const): 15 (JSC::ArithProfile<BitfieldType>::shouldEmitSetNonNumeric const): 16 (JSC::ArithProfile<BitfieldType>::shouldEmitSetBigInt const): 17 (JSC::ArithProfile<BitfieldType>::emitSetNonNumeric const): 18 (JSC::ArithProfile<BitfieldType>::emitSetBigInt const): 19 (WTF::printInternal): 20 * bytecode/ArithProfile.h: 21 (JSC::ArithProfile::didObserveNonInt32 const): 22 (JSC::ArithProfile::didObserveDouble const): 23 (JSC::ArithProfile::didObserveNonNegZeroDouble const): 24 (JSC::ArithProfile::didObserveNegZeroDouble const): 25 (JSC::ArithProfile::didObserveNonNumeric const): 26 (JSC::ArithProfile::didObserveBigInt const): 27 (JSC::ArithProfile::didObserveInt32Overflow const): 28 (JSC::ArithProfile::didObserveInt52Overflow const): 29 (JSC::ArithProfile::setObservedNonNegZeroDouble): 30 (JSC::ArithProfile::setObservedNegZeroDouble): 31 (JSC::ArithProfile::setObservedNonNumeric): 32 (JSC::ArithProfile::setObservedBigInt): 33 (JSC::ArithProfile::setObservedInt32Overflow): 34 (JSC::ArithProfile::setObservedInt52Overflow): 35 (JSC::ArithProfile::observeResult): 36 (JSC::ArithProfile::addressOfBits const): 37 (JSC::ArithProfile::bits const): 38 (JSC::ArithProfile::ArithProfile): 39 (JSC::ArithProfile::hasBits const): 40 (JSC::ArithProfile::setBit): 41 (JSC::UnaryArithProfile::UnaryArithProfile): 42 (JSC::UnaryArithProfile::observedIntBits): 43 (JSC::UnaryArithProfile::observedNumberBits): 44 (JSC::UnaryArithProfile::argResultType const): 45 (JSC::UnaryArithProfile::argObservedType const): 46 (JSC::UnaryArithProfile::setArgObservedType): 47 (JSC::UnaryArithProfile::argSawInt32): 48 (JSC::UnaryArithProfile::argSawNumber): 49 (JSC::UnaryArithProfile::argSawNonNumber): 50 (JSC::UnaryArithProfile::observeArg): 51 (JSC::UnaryArithProfile::isObservedTypeEmpty): 52 (JSC::BinaryArithProfile::BinaryArithProfile): 53 (JSC::BinaryArithProfile::observedIntIntBits): 54 (JSC::BinaryArithProfile::observedNumberIntBits): 55 (JSC::BinaryArithProfile::observedIntNumberBits): 56 (JSC::BinaryArithProfile::observedNumberNumberBits): 57 (JSC::BinaryArithProfile::observeLHS): 58 (JSC::BinaryArithProfile::observeLHSAndRHS): 59 (JSC::BinaryArithProfile::isObservedTypeEmpty): 60 * bytecode/BytecodeList.rb: 61 * bytecode/CodeBlock.cpp: 62 (JSC::CodeBlock::addJITAddIC): 63 (JSC::CodeBlock::addJITMulIC): 64 (JSC::CodeBlock::addJITSubIC): 65 (JSC::CodeBlock::addJITNegIC): 66 (JSC::CodeBlock::binaryArithProfileForBytecodeOffset): 67 (JSC::CodeBlock::unaryArithProfileForBytecodeOffset): 68 (JSC::CodeBlock::binaryArithProfileForPC): 69 (JSC::CodeBlock::unaryArithProfileForPC): 70 (JSC::CodeBlock::couldTakeSpecialFastCase): 71 * bytecode/CodeBlock.h: 72 (JSC::CodeBlock::addMathIC): 73 * bytecode/Fits.h: 74 * bytecode/MethodOfGettingAValueProfile.cpp: 75 (JSC::MethodOfGettingAValueProfile::emitReportValue const): 76 (JSC::MethodOfGettingAValueProfile::reportValue): 77 * bytecode/MethodOfGettingAValueProfile.h: 78 (JSC::MethodOfGettingAValueProfile::MethodOfGettingAValueProfile): 79 * bytecompiler/BytecodeGenerator.cpp: 80 (JSC::BytecodeGenerator::emitUnaryOp): 81 * bytecompiler/BytecodeGenerator.h: 82 * bytecompiler/NodesCodegen.cpp: 83 (JSC::UnaryOpNode::emitBytecode): 84 * dfg/DFGByteCodeParser.cpp: 85 (JSC::DFG::ByteCodeParser::makeSafe): 86 (JSC::DFG::ByteCodeParser::makeDivSafe): 87 * dfg/DFGGraph.cpp: 88 (JSC::DFG::Graph::methodOfGettingAValueProfileFor): 89 * dfg/DFGSpeculativeJIT.cpp: 90 (JSC::DFG::SpeculativeJIT::compileValueAdd): 91 (JSC::DFG::SpeculativeJIT::compileValueSub): 92 (JSC::DFG::SpeculativeJIT::compileValueNegate): 93 (JSC::DFG::SpeculativeJIT::compileValueMul): 94 * ftl/FTLLowerDFGToB3.cpp: 95 (JSC::FTL::DFG::LowerDFGToB3::compileValueAdd): 96 (JSC::FTL::DFG::LowerDFGToB3::compileValueSub): 97 (JSC::FTL::DFG::LowerDFGToB3::compileValueMul): 98 (JSC::FTL::DFG::LowerDFGToB3::compileUnaryMathIC): 99 (JSC::FTL::DFG::LowerDFGToB3::compileBinaryMathIC): 100 (JSC::FTL::DFG::LowerDFGToB3::compileArithAddOrSub): 101 (JSC::FTL::DFG::LowerDFGToB3::compileValueNegate): 102 * jit/JIT.h: 103 * jit/JITAddGenerator.cpp: 104 (JSC::JITAddGenerator::generateInline): 105 (JSC::JITAddGenerator::generateFastPath): 106 * jit/JITAddGenerator.h: 107 * jit/JITArithmetic.cpp: 108 (JSC::JIT::emit_op_negate): 109 (JSC::JIT::emit_op_add): 110 (JSC::JIT::emitMathICFast): 111 (JSC::JIT::emitMathICSlow): 112 (JSC::JIT::emit_op_div): 113 (JSC::JIT::emit_op_mul): 114 (JSC::JIT::emit_op_sub): 115 * jit/JITDivGenerator.cpp: 116 (JSC::JITDivGenerator::generateFastPath): 117 * jit/JITDivGenerator.h: 118 (JSC::JITDivGenerator::JITDivGenerator): 119 * jit/JITInlines.h: 120 (JSC::JIT::copiedArithProfile): 121 * jit/JITMathIC.h: 122 (JSC::JITMathIC::JITMathIC): 123 (JSC::JITMathIC::generateInline): 124 (JSC::JITMathIC::arithProfile const): 125 (JSC::isBinaryProfileEmpty): 126 (JSC::JITBinaryMathIC::JITBinaryMathIC): 127 (JSC::isUnaryProfileEmpty): 128 (JSC::JITUnaryMathIC::JITUnaryMathIC): 129 * jit/JITMulGenerator.cpp: 130 (JSC::JITMulGenerator::generateInline): 131 (JSC::JITMulGenerator::generateFastPath): 132 * jit/JITMulGenerator.h: 133 * jit/JITNegGenerator.cpp: 134 (JSC::JITNegGenerator::generateInline): 135 (JSC::JITNegGenerator::generateFastPath): 136 * jit/JITNegGenerator.h: 137 * jit/JITOperations.cpp: 138 * jit/JITOperations.h: 139 * jit/JITSubGenerator.cpp: 140 (JSC::JITSubGenerator::generateInline): 141 (JSC::JITSubGenerator::generateFastPath): 142 * jit/JITSubGenerator.h: 143 * llint/LLIntData.cpp: 144 (JSC::LLInt::Data::performAssertions): 145 * llint/LLIntOffsetsExtractor.cpp: 146 (JSC::LLIntOffsetsExtractor::dummy): 147 * llint/LowLevelInterpreter.asm: 148 * llint/LowLevelInterpreter32_64.asm: 149 * llint/LowLevelInterpreter64.asm: 150 * parser/ResultType.h: 151 (JSC::ResultType::ResultType): 152 * runtime/CommonSlowPaths.cpp: 153 (JSC::updateArithProfileForUnaryArithOp): 154 (JSC::updateArithProfileForBinaryArithOp): 155 (JSC::SLOW_PATH_DECL): 156 1 157 2019-10-14 Yusuke Suzuki <ysuzuki@apple.com> 2 158 -
trunk/Source/JavaScriptCore/bytecode/ArithProfile.cpp
r237972 r251090 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 { 63 uint32_t mask = ArithProfile::Int32Overflow | ArithProfile::Int52Overflow | ArithProfile::NegZeroDouble | ArithProfile::NonNegZeroDouble; 62 template<typename BitfieldType> 63 bool ArithProfile<BitfieldType>::shouldEmitSetDouble() const 64 { 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())); 71 } 72 73 bool ArithProfile::shouldEmitSetNonNumeric() const 73 jit.or32(CCallHelpers::TrustedImm32(Int32Overflow | Int52Overflow | NegZeroDouble | NonNegZeroDouble), CCallHelpers::AbsoluteAddress(addressOfBits())); 74 } 75 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())); 89 } 90 91 void ArithProfile::emitSetBigInt(CCallHelpers& jit) const 94 jit.or32(CCallHelpers::TrustedImm32(NonNumeric), CCallHelpers::AbsoluteAddress(addressOfBits())); 95 } 96 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())); 95 } 101 jit.or32(CCallHelpers::TrustedImm32(BigInt), CCallHelpers::AbsoluteAddress(addressOfBits())); 102 } 103 104 template class ArithProfile<uint16_t>; // Generate the implementations for UnaryArithProfile 105 template class ArithProfile<uint32_t>; // Generate the implementations for BinaryArithProfile 96 106 #endif // ENABLE(JIT) 97 107 … … 102 112 using namespace JSC; 103 113 104 void printInternal(PrintStream& out, const ArithProfile& profile) 114 void printInternal(PrintStream& out, const UnaryArithProfile& profile) 115 { 116 const char* separator = ""; 117 118 out.print("Result:<"); 119 if (!profile.didObserveNonInt32()) { 120 out.print("Int32"); 121 separator = "|"; 122 } else { 123 if (profile.didObserveNegZeroDouble()) { 124 out.print(separator, "NegZeroDouble"); 125 separator = "|"; 126 } 127 if (profile.didObserveNonNegZeroDouble()) { 128 out.print(separator, "NonNegZeroDouble"); 129 separator = "|"; 130 } 131 if (profile.didObserveNonNumeric()) { 132 out.print(separator, "NonNumeric"); 133 separator = "|"; 134 } 135 if (profile.didObserveInt32Overflow()) { 136 out.print(separator, "Int32Overflow"); 137 separator = "|"; 138 } 139 if (profile.didObserveInt52Overflow()) { 140 out.print(separator, "Int52Overflow"); 141 separator = "|"; 142 } 143 if (profile.didObserveBigInt()) { 144 out.print(separator, "BigInt"); 145 separator = "|"; 146 } 147 } 148 out.print(">"); 149 150 out.print(" Arg ObservedType:<"); 151 out.print(profile.argObservedType()); 152 out.print(">"); 153 154 out.print(" Arg ResultType:<"); 155 out.print(RawPointer(bitwise_cast<void*>(static_cast<uintptr_t>(profile.argResultType().bits())))); 156 out.print(">"); 157 } 158 159 void printInternal(PrintStream& out, const BinaryArithProfile& profile) 105 160 { 106 161 const char* separator = ""; -
trunk/Source/JavaScriptCore/bytecode/ArithProfile.h
r240138 r251090 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(BitfieldType bits) 137 : m_bits(bits) 138 { 139 } 140 141 bool hasBits(int mask) const { return m_bits & mask; } 142 void setBit(int mask) { m_bits |= mask; } 143 144 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. 145 }; 146 147 /* This class stores the following components in 16 bits: 148 * - ObservedResults 149 * - ResultType for the argument 150 * - ObservedType for the argument 151 */ 152 class UnaryArithProfile : public ArithProfile<uint16_t> { 153 static constexpr unsigned argResultTypeShift = observedResultsNumBitsNeeded; 154 static constexpr unsigned argObservedTypeShift = argResultTypeShift + ResultType::numBitsNeeded; 155 156 static_assert(argObservedTypeShift + ObservedType::numBitsNeeded <= sizeof(uint16_t) * 8, "Should fit in a uint16_t"); 157 158 static constexpr uint16_t clearArgObservedTypeBitMask = static_cast<uint16_t>(~(0b111 << argObservedTypeShift)); 159 160 static constexpr uint16_t resultTypeMask = (1 << ResultType::numBitsNeeded) - 1; 161 static constexpr uint16_t observedTypeMask = (1 << ObservedType::numBitsNeeded) - 1; 162 163 public: 164 UnaryArithProfile(ResultType arg) 165 : ArithProfile<uint16_t>(arg.bits() << argResultTypeShift) 166 { 167 ASSERT(argResultType().bits() == arg.bits()); 168 ASSERT(argObservedType().isEmpty()); 169 ASSERT(argObservedType().isEmpty()); 170 } 171 172 UnaryArithProfile() 173 : UnaryArithProfile(ResultType::unknownType()) 174 { 175 } 176 177 static constexpr uint16_t observedIntBits() 178 { 179 constexpr ObservedType observedInt32 { ObservedType().withInt32() }; 180 constexpr uint16_t bits = observedInt32.bits() << argObservedTypeShift; 181 static_assert(bits == 0x2000, ""); 182 return bits; 183 } 184 static constexpr uint16_t observedNumberBits() 185 { 186 constexpr ObservedType observedNumber { ObservedType().withNumber() }; 187 constexpr uint16_t bits = observedNumber.bits() << argObservedTypeShift; 188 static_assert(bits == 0x4000, ""); 189 return bits; 190 } 191 192 ResultType argResultType() const { return ResultType((m_bits >> argResultTypeShift) & resultTypeMask); } 193 194 constexpr ObservedType argObservedType() const { return ObservedType((m_bits >> argObservedTypeShift) & observedTypeMask); } 195 void setArgObservedType(ObservedType type) 196 { 197 uint16_t bits = m_bits; 198 bits &= clearArgObservedTypeBitMask; 199 bits |= type.bits() << argObservedTypeShift; 200 m_bits = bits; 201 ASSERT(argObservedType() == type); 202 } 203 204 void argSawInt32() { setArgObservedType(argObservedType().withInt32()); } 205 void argSawNumber() { setArgObservedType(argObservedType().withNumber()); } 206 void argSawNonNumber() { setArgObservedType(argObservedType().withNonNumber()); } 207 208 void observeArg(JSValue arg) 209 { 210 UnaryArithProfile newProfile = *this; 211 if (arg.isNumber()) { 212 if (arg.isInt32()) 213 newProfile.argSawInt32(); 214 else 215 newProfile.argSawNumber(); 216 } else 217 newProfile.argSawNonNumber(); 218 219 m_bits = newProfile.bits(); 220 } 221 222 bool isObservedTypeEmpty() 223 { 224 return argObservedType().isEmpty(); 225 } 226 227 friend class JSC::LLIntOffsetsExtractor; 228 }; 229 230 /* This class stores the following components in 32 bits: 231 * - ObservedResults 232 * - ResultType for right-hand-side 233 * - ResultType for left-hand-side 234 * - ObservedType for right-hand-side 235 * - ObservedType for left-hand-side 236 * - a bit used by division to indicate whether a special fast path was taken 237 */ 238 class BinaryArithProfile : public ArithProfile<uint32_t> { 239 static constexpr uint32_t rhsResultTypeShift = observedResultsNumBitsNeeded; 240 static constexpr uint32_t lhsResultTypeShift = rhsResultTypeShift + ResultType::numBitsNeeded; 241 static constexpr uint32_t rhsObservedTypeShift = lhsResultTypeShift + ResultType::numBitsNeeded; 242 static constexpr uint32_t lhsObservedTypeShift = rhsObservedTypeShift + ObservedType::numBitsNeeded; 243 244 static_assert(ObservedType::numBitsNeeded == 3, "We make a hard assumption about that here."); 245 static constexpr uint32_t clearRhsObservedTypeBitMask = static_cast<uint32_t>(~(0b111 << rhsObservedTypeShift)); 246 static constexpr uint32_t clearLhsObservedTypeBitMask = static_cast<uint32_t>(~(0b111 << lhsObservedTypeShift)); 247 248 static constexpr uint32_t resultTypeMask = (1 << ResultType::numBitsNeeded) - 1; 249 static constexpr uint32_t observedTypeMask = (1 << ObservedType::numBitsNeeded) - 1; 250 251 public: 252 static constexpr uint32_t specialFastPathBit = 1 << (lhsObservedTypeShift + ObservedType::numBitsNeeded); 253 static_assert((lhsObservedTypeShift + ObservedType::numBitsNeeded + 1) <= sizeof(uint32_t) * 8, "Should fit in a uint32_t."); 254 static_assert(!(specialFastPathBit & ~clearLhsObservedTypeBitMask), "These bits should not intersect."); 255 static_assert(specialFastPathBit & clearLhsObservedTypeBitMask, "These bits should intersect."); 256 static_assert(specialFastPathBit > ~clearLhsObservedTypeBitMask, "These bits should not intersect and specialFastPathBit should be a higher bit."); 257 258 BinaryArithProfile(ResultType lhs, ResultType rhs) 259 : ArithProfile<uint32_t>((lhs.bits() << lhsResultTypeShift) | (rhs.bits() << rhsResultTypeShift)) 260 { 261 ASSERT(lhsResultType().bits() == lhs.bits() && rhsResultType().bits() == rhs.bits()); 262 ASSERT(lhsObservedType().isEmpty()); 263 ASSERT(rhsObservedType().isEmpty()); 264 } 265 266 BinaryArithProfile(OperandTypes types) 267 : BinaryArithProfile(types.first(), types.second()) 268 { } 269 270 BinaryArithProfile() 271 : BinaryArithProfile(ResultType::unknownType(), ResultType::unknownType()) 272 { 273 } 274 275 static constexpr uint32_t observedIntIntBits() 276 { 277 constexpr ObservedType observedInt32 { ObservedType().withInt32() }; 278 constexpr uint32_t bits = (observedInt32.bits() << lhsObservedTypeShift) | (observedInt32.bits() << rhsObservedTypeShift); 279 static_assert(bits == 0x900000, ""); 280 return bits; 281 } 282 static constexpr uint32_t observedNumberIntBits() 283 { 284 constexpr ObservedType observedNumber { ObservedType().withNumber() }; 285 constexpr ObservedType observedInt32 { ObservedType().withInt32() }; 286 constexpr uint32_t bits = (observedNumber.bits() << lhsObservedTypeShift) | (observedInt32.bits() << rhsObservedTypeShift); 287 static_assert(bits == 0x1100000, ""); 288 return bits; 289 } 290 static constexpr uint32_t observedIntNumberBits() 291 { 292 constexpr ObservedType observedNumber { ObservedType().withNumber() }; 293 constexpr ObservedType observedInt32 { ObservedType().withInt32() }; 294 constexpr uint32_t bits = (observedInt32.bits() << lhsObservedTypeShift) | (observedNumber.bits() << rhsObservedTypeShift); 295 static_assert(bits == 0xa00000, ""); 296 return bits; 297 } 298 static constexpr uint32_t observedNumberNumberBits() 299 { 300 constexpr ObservedType observedNumber { ObservedType().withNumber() }; 301 constexpr uint32_t bits = (observedNumber.bits() << lhsObservedTypeShift) | (observedNumber.bits() << rhsObservedTypeShift); 302 static_assert(bits == 0x1200000, ""); 303 return bits; 304 } 305 306 ResultType lhsResultType() const { return ResultType((m_bits >> lhsResultTypeShift) & resultTypeMask); } 307 ResultType rhsResultType() const { return ResultType((m_bits >> rhsResultTypeShift) & resultTypeMask); } 308 309 constexpr ObservedType lhsObservedType() const { return ObservedType((m_bits >> lhsObservedTypeShift) & observedTypeMask); } 310 constexpr ObservedType rhsObservedType() const { return ObservedType((m_bits >> rhsObservedTypeShift) & observedTypeMask); } 311 void setLhsObservedType(ObservedType type) 312 { 313 uint32_t bits = m_bits; 314 bits &= clearLhsObservedTypeBitMask; 315 bits |= type.bits() << lhsObservedTypeShift; 316 m_bits = bits; 317 ASSERT(lhsObservedType() == type); 318 } 319 320 void setRhsObservedType(ObservedType type) 321 { 322 uint32_t bits = m_bits; 323 bits &= clearRhsObservedTypeBitMask; 324 bits |= type.bits() << rhsObservedTypeShift; 325 m_bits = bits; 326 ASSERT(rhsObservedType() == type); 327 } 328 329 bool tookSpecialFastPath() const { return m_bits & specialFastPathBit; } 330 232 331 void lhsSawInt32() { setLhsObservedType(lhsObservedType().withInt32()); } 233 332 void lhsSawNumber() { setLhsObservedType(lhsObservedType().withNumber()); } … … 239 338 void observeLHS(JSValue lhs) 240 339 { 241 ArithProfile newProfile = *this;340 BinaryArithProfile newProfile = *this; 242 341 if (lhs.isNumber()) { 243 342 if (lhs.isInt32()) … … 255 354 observeLHS(lhs); 256 355 257 ArithProfile newProfile = *this;356 BinaryArithProfile newProfile = *this; 258 357 if (rhs.isNumber()) { 259 358 if (rhs.isInt32()) … … 267 366 } 268 367 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. 368 bool isObservedTypeEmpty() 369 { 370 return lhsObservedType().isEmpty() && rhsObservedType().isEmpty(); 371 } 309 372 310 373 friend class JSC::LLIntOffsetsExtractor; … … 315 378 namespace WTF { 316 379 317 void printInternal(PrintStream&, const JSC::ArithProfile&); 380 void printInternal(PrintStream&, const JSC::UnaryArithProfile&); 381 void printInternal(PrintStream&, const JSC::BinaryArithProfile&); 318 382 void printInternal(PrintStream&, const JSC::ObservedType&); 319 383 -
trunk/Source/JavaScriptCore/bytecode/BytecodeList.rb
r250806 r251090 42 42 :JSValue, 43 43 :LLIntCallLinkInfo, 44 :ResultType, 44 45 :OperandTypes, 45 46 :ProfileTypeBytecodeFlag, … … 58 59 :ValueProfile, 59 60 :ValueProfileAndOperandBuffer, 60 :ArithProfile, 61 :UnaryArithProfile, 62 :BinaryArithProfile, 61 63 :ArrayProfile, 62 64 :ArrayAllocationProfile, … … 283 285 }, 284 286 metadata: { 285 arithProfile: ArithProfile287 arithProfile: BinaryArithProfile 286 288 }, 287 289 metadata_initializers: { … … 368 370 dst: VirtualRegister, 369 371 operand: VirtualRegister, 370 operandTypes: OperandTypes,371 }, 372 metadata: { 373 arithProfile: ArithProfile,372 resultType: ResultType, 373 }, 374 metadata: { 375 arithProfile: UnaryArithProfile, 374 376 }, 375 377 metadata_initializers: { 376 arithProfile: : operandTypes378 arithProfile: :resultType 377 379 } 378 380 -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r250655 r251090 1481 1481 } 1482 1482 1483 JITAddIC* CodeBlock::addJITAddIC( ArithProfile* arithProfile)1483 JITAddIC* CodeBlock::addJITAddIC(BinaryArithProfile* arithProfile) 1484 1484 { 1485 1485 ConcurrentJSLocker locker(m_lock); … … 1487 1487 } 1488 1488 1489 JITMulIC* CodeBlock::addJITMulIC( ArithProfile* arithProfile)1489 JITMulIC* CodeBlock::addJITMulIC(BinaryArithProfile* arithProfile) 1490 1490 { 1491 1491 ConcurrentJSLocker locker(m_lock); … … 1493 1493 } 1494 1494 1495 JITSubIC* CodeBlock::addJITSubIC( ArithProfile* arithProfile)1495 JITSubIC* CodeBlock::addJITSubIC(BinaryArithProfile* arithProfile) 1496 1496 { 1497 1497 ConcurrentJSLocker locker(m_lock); … … 1499 1499 } 1500 1500 1501 JITNegIC* CodeBlock::addJITNegIC( ArithProfile* arithProfile)1501 JITNegIC* CodeBlock::addJITNegIC(UnaryArithProfile* arithProfile) 1502 1502 { 1503 1503 ConcurrentJSLocker locker(m_lock); … … 3086 3086 } 3087 3087 3088 ArithProfile* CodeBlock::arithProfileForBytecodeOffset(InstructionStream::Offset bytecodeOffset) 3089 { 3090 return arithProfileForPC(instructions().at(bytecodeOffset).ptr()); 3091 } 3092 3093 ArithProfile* CodeBlock::arithProfileForPC(const Instruction* pc) 3088 BinaryArithProfile* CodeBlock::binaryArithProfileForBytecodeOffset(InstructionStream::Offset bytecodeOffset) 3089 { 3090 return binaryArithProfileForPC(instructions().at(bytecodeOffset).ptr()); 3091 } 3092 3093 UnaryArithProfile* CodeBlock::unaryArithProfileForBytecodeOffset(InstructionStream::Offset bytecodeOffset) 3094 { 3095 return unaryArithProfileForPC(instructions().at(bytecodeOffset).ptr()); 3096 } 3097 3098 BinaryArithProfile* CodeBlock::binaryArithProfileForPC(const Instruction* pc) 3094 3099 { 3095 3100 switch (pc->opcodeID()) { 3096 case op_negate:3097 return &pc->as<OpNegate>().metadata(this).m_arithProfile;3098 3101 case op_add: 3099 3102 return &pc->as<OpAdd>().metadata(this).m_arithProfile; … … 3111 3114 } 3112 3115 3116 UnaryArithProfile* CodeBlock::unaryArithProfileForPC(const Instruction* pc) 3117 { 3118 switch (pc->opcodeID()) { 3119 case op_negate: 3120 return &pc->as<OpNegate>().metadata(this).m_arithProfile; 3121 default: 3122 break; 3123 } 3124 3125 return nullptr; 3126 } 3127 3113 3128 bool CodeBlock::couldTakeSpecialFastCase(InstructionStream::Offset bytecodeOffset) 3114 3129 { 3115 3130 if (!hasBaselineJITProfiling()) 3116 3131 return false; 3117 ArithProfile* profile = arithProfileForBytecodeOffset(bytecodeOffset);3132 BinaryArithProfile* profile = binaryArithProfileForBytecodeOffset(bytecodeOffset); 3118 3133 if (!profile) 3119 3134 return false; -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.h
r250806 r251090 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); … … 493 494 template<typename Functor> void forEachLLIntCallLinkInfo(const Functor&); 494 495 495 ArithProfile* arithProfileForBytecodeOffset(InstructionStream::Offset bytecodeOffset); 496 ArithProfile* arithProfileForPC(const Instruction*); 496 BinaryArithProfile* binaryArithProfileForBytecodeOffset(InstructionStream::Offset bytecodeOffset); 497 UnaryArithProfile* unaryArithProfileForBytecodeOffset(InstructionStream::Offset bytecodeOffset); 498 BinaryArithProfile* binaryArithProfileForPC(const Instruction*); 499 UnaryArithProfile* unaryArithProfileForPC(const Instruction*); 497 500 498 501 bool couldTakeSpecialFastCase(InstructionStream::Offset bytecodeOffset); -
trunk/Source/JavaScriptCore/bytecode/Fits.h
r245906 r251090 238 238 239 239 template<OpcodeSize size> 240 struct Fits<ResultType, size, std::enable_if_t<sizeof(ResultType) != size, std::true_type>> { 241 static_assert(sizeof(ResultType) == sizeof(uint8_t)); 242 using TargetType = typename TypeBySize<size>::unsignedType; 243 244 static bool check(ResultType) 245 { 246 return true; 247 } 248 249 static TargetType convert(ResultType type) 250 { 251 return static_cast<TargetType>(type.bits()); 252 } 253 254 static ResultType convert(TargetType type) 255 { 256 return ResultType(static_cast<uint8_t>(type)); 257 } 258 }; 259 260 template<OpcodeSize size> 240 261 struct Fits<OperandTypes, size, std::enable_if_t<sizeof(OperandTypes) != size, std::true_type>> { 241 262 static_assert(sizeof(OperandTypes) == sizeof(uint16_t)); -
trunk/Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.cpp
r240893 r251090 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
r222871 r251090 36 36 namespace JSC { 37 37 38 class UnaryArithProfile; 39 class BinaryArithProfile; 38 40 class CCallHelpers; 39 41 class CodeBlock; 40 42 class LazyOperandValueProfileKey; 41 struct ArithProfile;42 43 struct ValueProfile; 43 44 … … 57 58 m_kind = None; 58 59 } 59 60 MethodOfGettingAValueProfile( ArithProfile* profile)60 61 MethodOfGettingAValueProfile(UnaryArithProfile* profile) 61 62 { 62 63 if (profile) { 63 m_kind = ArithProfileReady; 64 u.arithProfile = profile; 64 m_kind = UnaryArithProfileReady; 65 u.unaryArithProfile = profile; 66 } else 67 m_kind = None; 68 } 69 70 MethodOfGettingAValueProfile(BinaryArithProfile* profile) 71 { 72 if (profile) { 73 m_kind = BinaryArithProfileReady; 74 u.binaryArithProfile = profile; 65 75 } else 66 76 m_kind = None; … … 79 89 None, 80 90 Ready, 81 ArithProfileReady, 91 UnaryArithProfileReady, 92 BinaryArithProfileReady, 82 93 LazyOperand 83 94 }; … … 86 97 union { 87 98 ValueProfile* profile; 88 ArithProfile* arithProfile; 99 UnaryArithProfile* unaryArithProfile; 100 BinaryArithProfile* binaryArithProfile; 89 101 struct { 90 102 CodeBlock* codeBlock; -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r250630 r251090 1666 1666 } 1667 1667 1668 RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src, OperandTypes types)1668 RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src, ResultType type) 1669 1669 { 1670 1670 switch (opcodeID) { … … 1673 1673 break; 1674 1674 case op_negate: 1675 OpNegate::emit(this, dst, src, type s);1675 OpNegate::emit(this, dst, src, type); 1676 1676 break; 1677 1677 case op_bitnot: -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r250630 r251090 683 683 } 684 684 685 RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src, OperandTypes);685 RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src, ResultType); 686 686 687 687 template<typename BinaryOp> -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r250630 r251090 2137 2137 RefPtr<RegisterID> src = generator.emitNode(m_expr); 2138 2138 generator.emitExpressionInfo(position(), position(), position()); 2139 return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src.get(), OperandTypes(m_expr->resultDescriptor()));2139 return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src.get(), m_expr->resultDescriptor()); 2140 2140 } 2141 2141 -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r250909 r251090 943 943 return node; 944 944 945 { 946 ArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->arithProfileForBytecodeOffset(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->binaryArithProfileForBytecodeOffset(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->binaryArithProfileForBytecodeOffset(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->unaryArithProfileForBytecodeOffset(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 … … 1035 1039 node->mergeFlags(NodeMayOverflowInt32InBaseline | NodeMayNegZeroInBaseline); 1036 1040 1037 ArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->arithProfileForBytecodeOffset(m_currentIndex);1041 BinaryArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->binaryArithProfileForBytecodeOffset(m_currentIndex); 1038 1042 if (arithProfile->didObserveBigInt()) 1039 1043 node->mergeFlags(NodeMayHaveBigIntResult); -
trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp
r250180 r251090 1653 1653 1654 1654 if (profiledBlock->hasBaselineJITProfiling()) { 1655 if (ArithProfile* result = profiledBlock->arithProfileForBytecodeOffset(node->origin.semantic.bytecodeIndex())) 1655 if (BinaryArithProfile* result = profiledBlock->binaryArithProfileForBytecodeOffset(node->origin.semantic.bytecodeIndex())) 1656 return result; 1657 if (UnaryArithProfile* result = profiledBlock->unaryArithProfileForBytecodeOffset(node->origin.semantic.bytecodeIndex())) 1656 1658 return result; 1657 1659 } -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r250803 r251090 4001 4001 CodeBlock* baselineCodeBlock = m_jit.graph().baselineCodeBlockFor(node->origin.semantic); 4002 4002 unsigned bytecodeIndex = node->origin.semantic.bytecodeIndex(); 4003 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);4003 BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeOffset(bytecodeIndex); 4004 4004 JITAddIC* addIC = m_jit.codeBlock()->addJITAddIC(arithProfile); 4005 4005 auto repatchingFunction = operationValueAddOptimize; … … 4025 4025 CodeBlock* baselineCodeBlock = m_jit.graph().baselineCodeBlockFor(node->origin.semantic); 4026 4026 unsigned bytecodeIndex = node->origin.semantic.bytecodeIndex(); 4027 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);4027 BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeOffset(bytecodeIndex); 4028 4028 JITSubIC* subIC = m_jit.codeBlock()->addJITSubIC(arithProfile); 4029 4029 auto repatchingFunction = operationValueSubOptimize; … … 4619 4619 CodeBlock* baselineCodeBlock = m_jit.graph().baselineCodeBlockFor(node->origin.semantic); 4620 4620 unsigned bytecodeIndex = node->origin.semantic.bytecodeIndex(); 4621 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);4621 UnaryArithProfile* arithProfile = baselineCodeBlock->unaryArithProfileForBytecodeOffset(bytecodeIndex); 4622 4622 JITNegIC* negIC = m_jit.codeBlock()->addJITNegIC(arithProfile); 4623 4623 auto repatchingFunction = operationArithNegateOptimize; … … 4842 4842 CodeBlock* baselineCodeBlock = m_jit.graph().baselineCodeBlockFor(node->origin.semantic); 4843 4843 unsigned bytecodeIndex = node->origin.semantic.bytecodeIndex(); 4844 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);4844 BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeOffset(bytecodeIndex); 4845 4845 JITMulIC* mulIC = m_jit.codeBlock()->addJITMulIC(arithProfile); 4846 4846 auto repatchingFunction = operationValueMulOptimize; -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r250886 r251090 2108 2108 CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic); 2109 2109 unsigned bytecodeIndex = m_node->origin.semantic.bytecodeIndex(); 2110 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);2110 BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeOffset(bytecodeIndex); 2111 2111 auto repatchingFunction = operationValueAddOptimize; 2112 2112 auto nonRepatchingFunction = operationValueAdd; … … 2127 2127 CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic); 2128 2128 unsigned bytecodeIndex = m_node->origin.semantic.bytecodeIndex(); 2129 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);2129 BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeOffset(bytecodeIndex); 2130 2130 auto repatchingFunction = operationValueSubOptimize; 2131 2131 auto nonRepatchingFunction = operationValueSub; … … 2146 2146 CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic); 2147 2147 unsigned bytecodeIndex = m_node->origin.semantic.bytecodeIndex(); 2148 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);2148 BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeOffset(bytecodeIndex); 2149 2149 auto repatchingFunction = operationValueMulOptimize; 2150 2150 auto nonRepatchingFunction = operationValueMul; … … 2154 2154 template <typename Generator, typename Func1, typename Func2, 2155 2155 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>> 2156 void compileUnaryMathIC( ArithProfile* arithProfile, Func1 repatchingFunction, Func2 nonRepatchingFunction)2156 void compileUnaryMathIC(UnaryArithProfile* arithProfile, Func1 repatchingFunction, Func2 nonRepatchingFunction) 2157 2157 { 2158 2158 Node* node = m_node; … … 2240 2240 template <typename Generator, typename Func1, typename Func2, 2241 2241 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>> 2242 void compileBinaryMathIC( ArithProfile* arithProfile, Func1 repatchingFunction, Func2 nonRepatchingFunction)2242 void compileBinaryMathIC(BinaryArithProfile* arithProfile, Func1 repatchingFunction, Func2 nonRepatchingFunction) 2243 2243 { 2244 2244 Node* node = m_node; … … 2407 2407 CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic); 2408 2408 unsigned bytecodeIndex = m_node->origin.semantic.bytecodeIndex(); 2409 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);2409 BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeOffset(bytecodeIndex); 2410 2410 auto repatchingFunction = operationValueSubOptimize; 2411 2411 auto nonRepatchingFunction = operationValueSub; … … 3073 3073 CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic); 3074 3074 unsigned bytecodeIndex = m_node->origin.semantic.bytecodeIndex(); 3075 ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);3075 UnaryArithProfile* arithProfile = baselineCodeBlock->unaryArithProfileForBytecodeOffset(bytecodeIndex); 3076 3076 auto repatchingFunction = operationArithNegateOptimize; 3077 3077 auto nonRepatchingFunction = operationArithNegate; -
trunk/Source/JavaScriptCore/jit/JIT.h
r249547 r251090 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
r226440 r251090 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
r218794 r251090 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
r250094 r251090 453 453 void JIT::emit_op_negate(const Instruction* currentInstruction) 454 454 { 455 ArithProfile* arithProfile = ¤tInstruction->as<OpNegate>().metadata(m_codeBlock).m_arithProfile;455 UnaryArithProfile* arithProfile = ¤tInstruction->as<OpNegate>().metadata(m_codeBlock).m_arithProfile; 456 456 JITNegIC* negateIC = m_codeBlock->addJITNegIC(arithProfile); 457 457 m_instructionToMathIC.add(currentInstruction, negateIC); … … 634 634 } 635 635 636 ALWAYS_INLINE static OperandTypes getOperandTypes(const ArithProfile& arithProfile)637 {638 return OperandTypes(arithProfile.lhsResultType(), arithProfile.rhsResultType());639 }640 641 636 void JIT::emit_op_add(const Instruction* currentInstruction) 642 637 { 643 ArithProfile* arithProfile = ¤tInstruction->as<OpAdd>().metadata(m_codeBlock).m_arithProfile;638 BinaryArithProfile* arithProfile = ¤tInstruction->as<OpAdd>().metadata(m_codeBlock).m_arithProfile; 644 639 JITAddIC* addIC = m_codeBlock->addJITAddIC(arithProfile); 645 640 m_instructionToMathIC.add(currentInstruction, addIC); … … 686 681 bool generatedInlineCode = mathIC->generateInline(*this, mathICGenerationState); 687 682 if (!generatedInlineCode) { 688 ArithProfile* arithProfile = mathIC->arithProfile();683 UnaryArithProfile* arithProfile = mathIC->arithProfile(); 689 684 if (arithProfile && shouldEmitProfiling()) 690 685 callOperationWithResult(profiledFunction, resultRegs, srcRegs, arithProfile); … … 709 704 { 710 705 auto bytecode = currentInstruction->as<Op>(); 711 OperandTypes types = getOperandTypes(copiedArithProfile(bytecode));706 BinaryArithProfile arithProfile = copiedArithProfile(bytecode); 712 707 int result = bytecode.m_dst.offset(); 713 708 int op1 = bytecode.m_lhs.offset(); … … 728 723 #endif 729 724 730 SnippetOperand leftOperand( types.first());731 SnippetOperand rightOperand( types.second());725 SnippetOperand leftOperand(arithProfile.lhsResultType()); 726 SnippetOperand rightOperand(arithProfile.rhsResultType()); 732 727 733 728 if (isOperandConstantInt(op1)) … … 759 754 else if (rightOperand.isConst()) 760 755 emitGetVirtualRegister(op2, rightRegs); 761 ArithProfile* arithProfile = mathIC->arithProfile();756 BinaryArithProfile* arithProfile = mathIC->arithProfile(); 762 757 if (arithProfile && shouldEmitProfiling()) 763 758 callOperationWithResult(profiledFunction, resultRegs, leftRegs, rightRegs, arithProfile); … … 799 794 #endif 800 795 801 ArithProfile* arithProfile = mathIC->arithProfile();796 UnaryArithProfile* arithProfile = mathIC->arithProfile(); 802 797 if (arithProfile && shouldEmitProfiling()) { 803 798 if (mathICGenerationState.shouldSlowPathRepatch) … … 831 826 832 827 auto bytecode = currentInstruction->as<Op>(); 833 OperandTypes types = getOperandTypes(copiedArithProfile(bytecode));828 BinaryArithProfile consistentArithProfile = copiedArithProfile(bytecode); 834 829 int result = bytecode.m_dst.offset(); 835 830 int op1 = bytecode.m_lhs.offset(); … … 846 841 #endif 847 842 848 SnippetOperand leftOperand( types.first());849 SnippetOperand rightOperand( types.second());843 SnippetOperand leftOperand(consistentArithProfile.lhsResultType()); 844 SnippetOperand rightOperand(consistentArithProfile.rhsResultType()); 850 845 851 846 if (isOperandConstantInt(op1)) … … 865 860 #endif 866 861 867 ArithProfile* arithProfile = mathIC->arithProfile();862 BinaryArithProfile* arithProfile = mathIC->arithProfile(); 868 863 if (arithProfile && shouldEmitProfiling()) { 869 864 if (mathICGenerationState.shouldSlowPathRepatch) … … 893 888 { 894 889 auto bytecode = currentInstruction->as<OpDiv>(); 895 auto& metadata = bytecode.metadata(m_codeBlock);890 BinaryArithProfile consistentArithProfile = copiedArithProfile(bytecode); 896 891 int result = bytecode.m_dst.offset(); 897 892 int op1 = bytecode.m_lhs.offset(); … … 899 894 900 895 #if USE(JSVALUE64) 901 OperandTypes types = getOperandTypes(metadata.m_arithProfile);902 896 JSValueRegs leftRegs = JSValueRegs(regT0); 903 897 JSValueRegs rightRegs = JSValueRegs(regT1); … … 905 899 GPRReg scratchGPR = regT2; 906 900 #else 907 OperandTypes types = getOperandTypes(metadata.m_arithProfile);908 901 JSValueRegs leftRegs = JSValueRegs(regT1, regT0); 909 902 JSValueRegs rightRegs = JSValueRegs(regT3, regT2); … … 913 906 FPRReg scratchFPR = fpRegT2; 914 907 915 ArithProfile* arithProfile = nullptr;908 BinaryArithProfile* arithProfile = nullptr; 916 909 if (shouldEmitProfiling()) 917 910 arithProfile = ¤tInstruction->as<OpDiv>().metadata(m_codeBlock).m_arithProfile; 918 911 919 SnippetOperand leftOperand( types.first());920 SnippetOperand rightOperand( types.second());912 SnippetOperand leftOperand(consistentArithProfile.lhsResultType()); 913 SnippetOperand rightOperand(consistentArithProfile.rhsResultType()); 921 914 922 915 if (isOperandConstantInt(op1)) … … 960 953 void JIT::emit_op_mul(const Instruction* currentInstruction) 961 954 { 962 ArithProfile* arithProfile = ¤tInstruction->as<OpMul>().metadata(m_codeBlock).m_arithProfile;955 BinaryArithProfile* arithProfile = ¤tInstruction->as<OpMul>().metadata(m_codeBlock).m_arithProfile; 963 956 JITMulIC* mulIC = m_codeBlock->addJITMulIC(arithProfile); 964 957 m_instructionToMathIC.add(currentInstruction, mulIC); … … 976 969 void JIT::emit_op_sub(const Instruction* currentInstruction) 977 970 { 978 ArithProfile* arithProfile = ¤tInstruction->as<OpSub>().metadata(m_codeBlock).m_arithProfile;971 BinaryArithProfile* arithProfile = ¤tInstruction->as<OpSub>().metadata(m_codeBlock).m_arithProfile; 979 972 JITSubIC* subIC = m_codeBlock->addJITSubIC(arithProfile); 980 973 m_instructionToMathIC.add(currentInstruction, subIC); -
trunk/Source/JavaScriptCore/jit/JITDivGenerator.cpp
r250094 r251090 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
r242812 r251090 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
r250630 r251090 718 718 719 719 template<typename BinaryOp> 720 ALWAYS_INLINE ArithProfile JIT::copiedArithProfile(BinaryOp bytecode)720 ALWAYS_INLINE BinaryArithProfile JIT::copiedArithProfile(BinaryOp bytecode) 721 721 { 722 722 uint64_t key = (static_cast<uint64_t>(BinaryOp::opcodeID) + 1) << 32 | static_cast<uint64_t>(bytecode.m_metadataID); … … 724 724 if (iterator != m_copiedArithProfiles.end()) 725 725 return iterator->value; 726 ArithProfile arithProfile = bytecode.metadata(m_codeBlock).m_arithProfile;726 BinaryArithProfile arithProfile = bytecode.metadata(m_codeBlock).m_arithProfile; 727 727 m_copiedArithProfiles.add(key, arithProfile); 728 728 return arithProfile; -
trunk/Source/JavaScriptCore/jit/JITMathIC.h
r245239 r251090 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)249 inline bool isBinaryProfileEmpty(BinaryArithProfile& arithProfile) 250 250 { 251 251 return arithProfile.lhsObservedType().isEmpty() || arithProfile.rhsObservedType().isEmpty(); 252 252 } 253 253 template <typename GeneratorType> 254 class JITBinaryMathIC : public JITMathIC<GeneratorType, isBinaryProfileEmpty> {254 class JITBinaryMathIC : public JITMathIC<GeneratorType, BinaryArithProfile> { 255 255 public: 256 JITBinaryMathIC( ArithProfile* arithProfile)257 : JITMathIC<GeneratorType, isBinaryProfileEmpty>(arithProfile)256 JITBinaryMathIC(BinaryArithProfile* arithProfile) 257 : JITMathIC<GeneratorType, BinaryArithProfile>(arithProfile) 258 258 { 259 259 } … … 265 265 266 266 267 inline bool isUnaryProfileEmpty( ArithProfile& arithProfile)267 inline bool isUnaryProfileEmpty(BinaryArithProfile& arithProfile) 268 268 { 269 269 return arithProfile.lhsObservedType().isEmpty(); 270 270 } 271 271 template <typename GeneratorType> 272 class JITUnaryMathIC : public JITMathIC<GeneratorType, isUnaryProfileEmpty> {272 class JITUnaryMathIC : public JITMathIC<GeneratorType, UnaryArithProfile> { 273 273 public: 274 JITUnaryMathIC( ArithProfile* arithProfile)275 : JITMathIC<GeneratorType, isUnaryProfileEmpty>(arithProfile)274 JITUnaryMathIC(UnaryArithProfile* arithProfile) 275 : JITMathIC<GeneratorType, UnaryArithProfile>(arithProfile) 276 276 { 277 277 } -
trunk/Source/JavaScriptCore/jit/JITMulGenerator.cpp
r250094 r251090 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
r206525 r251090 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
r226440 r251090 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
r206525 r251090 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
r250803 r251090 2555 2555 } 2556 2556 2557 ALWAYS_INLINE static EncodedJSValue profiledAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile& arithProfile)2557 ALWAYS_INLINE static EncodedJSValue profiledAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile& arithProfile) 2558 2558 { 2559 2559 VM& vm = exec->vm(); … … 2575 2575 } 2576 2576 2577 EncodedJSValue JIT_OPERATION operationValueAddProfiled(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)2577 EncodedJSValue JIT_OPERATION operationValueAddProfiled(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile* arithProfile) 2578 2578 { 2579 2579 ASSERT(arithProfile); … … 2589 2589 JSValue op2 = JSValue::decode(encodedOp2); 2590 2590 2591 ArithProfile* arithProfile = addIC->arithProfile();2591 BinaryArithProfile* arithProfile = addIC->arithProfile(); 2592 2592 ASSERT(arithProfile); 2593 2593 arithProfile->observeLHSAndRHS(op1, op2); … … 2610 2610 NativeCallFrameTracer tracer(vm, exec); 2611 2611 2612 ArithProfile* arithProfile = addIC->arithProfile();2612 BinaryArithProfile* arithProfile = addIC->arithProfile(); 2613 2613 ASSERT(arithProfile); 2614 2614 return profiledAdd(exec, encodedOp1, encodedOp2, *arithProfile); … … 2624 2624 2625 2625 auto nonOptimizeVariant = operationValueAddNoOptimize; 2626 if ( ArithProfile* arithProfile = addIC->arithProfile())2626 if (BinaryArithProfile* arithProfile = addIC->arithProfile()) 2627 2627 arithProfile->observeLHSAndRHS(op1, op2); 2628 2628 addIC->generateOutOfLine(exec->codeBlock(), nonOptimizeVariant); … … 2656 2656 } 2657 2657 2658 ALWAYS_INLINE static EncodedJSValue profiledMul(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true)2658 ALWAYS_INLINE static EncodedJSValue profiledMul(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true) 2659 2659 { 2660 2660 VM& vm = exec->vm(); … … 2694 2694 2695 2695 auto nonOptimizeVariant = operationValueMulNoOptimize; 2696 if ( ArithProfile* arithProfile = mulIC->arithProfile())2696 if (BinaryArithProfile* arithProfile = mulIC->arithProfile()) 2697 2697 arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2)); 2698 2698 mulIC->generateOutOfLine(exec->codeBlock(), nonOptimizeVariant); … … 2705 2705 } 2706 2706 2707 EncodedJSValue JIT_OPERATION operationValueMulProfiled(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)2707 EncodedJSValue JIT_OPERATION operationValueMulProfiled(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile* arithProfile) 2708 2708 { 2709 2709 VM& vm = exec->vm(); … … 2719 2719 NativeCallFrameTracer tracer(vm, exec); 2720 2720 2721 ArithProfile* arithProfile = mulIC->arithProfile();2721 BinaryArithProfile* arithProfile = mulIC->arithProfile(); 2722 2722 ASSERT(arithProfile); 2723 2723 arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2)); … … 2737 2737 NativeCallFrameTracer tracer(vm, exec); 2738 2738 2739 ArithProfile* arithProfile = mulIC->arithProfile();2739 BinaryArithProfile* arithProfile = mulIC->arithProfile(); 2740 2740 ASSERT(arithProfile); 2741 2741 return profiledMul(exec, encodedOp1, encodedOp2, *arithProfile); … … 2761 2761 } 2762 2762 2763 ALWAYS_INLINE static EncodedJSValue profiledNegate(ExecState* exec, EncodedJSValue encodedOperand, ArithProfile& arithProfile)2763 ALWAYS_INLINE static EncodedJSValue profiledNegate(ExecState* exec, EncodedJSValue encodedOperand, UnaryArithProfile& arithProfile) 2764 2764 { 2765 2765 VM& vm = exec->vm(); … … 2768 2768 2769 2769 JSValue operand = JSValue::decode(encodedOperand); 2770 arithProfile.observe LHS(operand);2770 arithProfile.observeArg(operand); 2771 2771 2772 2772 JSValue primValue = operand.toPrimitive(exec); … … 2792 2792 } 2793 2793 2794 EncodedJSValue JIT_OPERATION operationArithNegateProfiled(ExecState* exec, EncodedJSValue operand, ArithProfile* arithProfile)2794 EncodedJSValue JIT_OPERATION operationArithNegateProfiled(ExecState* exec, EncodedJSValue operand, UnaryArithProfile* arithProfile) 2795 2795 { 2796 2796 ASSERT(arithProfile); … … 2806 2806 JSValue operand = JSValue::decode(encodedOperand); 2807 2807 2808 ArithProfile* arithProfile = negIC->arithProfile();2808 UnaryArithProfile* arithProfile = negIC->arithProfile(); 2809 2809 ASSERT(arithProfile); 2810 arithProfile->observe LHS(operand);2810 arithProfile->observeArg(operand); 2811 2811 negIC->generateOutOfLine(exec->codeBlock(), operationArithNegateProfiled); 2812 2812 … … 2839 2839 JSValue operand = JSValue::decode(encodedOperand); 2840 2840 2841 if ( ArithProfile* arithProfile = negIC->arithProfile())2842 arithProfile->observe LHS(operand);2841 if (UnaryArithProfile* arithProfile = negIC->arithProfile()) 2842 arithProfile->observeArg(operand); 2843 2843 negIC->generateOutOfLine(exec->codeBlock(), operationArithNegate); 2844 2844 … … 2866 2866 } 2867 2867 2868 ALWAYS_INLINE static EncodedJSValue profiledSub(VM& vm, ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true)2868 ALWAYS_INLINE static EncodedJSValue profiledSub(VM& vm, ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true) 2869 2869 { 2870 2870 auto scope = DECLARE_THROW_SCOPE(vm); … … 2889 2889 } 2890 2890 2891 EncodedJSValue JIT_OPERATION operationValueSubProfiled(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)2891 EncodedJSValue JIT_OPERATION operationValueSubProfiled(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile* arithProfile) 2892 2892 { 2893 2893 ASSERT(arithProfile); … … 2905 2905 2906 2906 auto nonOptimizeVariant = operationValueSubNoOptimize; 2907 if ( ArithProfile* arithProfile = subIC->arithProfile())2907 if (BinaryArithProfile* arithProfile = subIC->arithProfile()) 2908 2908 arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2)); 2909 2909 subIC->generateOutOfLine(exec->codeBlock(), nonOptimizeVariant); … … 2929 2929 NativeCallFrameTracer tracer(vm, exec); 2930 2930 2931 ArithProfile* arithProfile = subIC->arithProfile();2931 BinaryArithProfile* arithProfile = subIC->arithProfile(); 2932 2932 ASSERT(arithProfile); 2933 2933 arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2)); … … 2947 2947 NativeCallFrameTracer tracer(vm, exec); 2948 2948 2949 ArithProfile* arithProfile = subIC->arithProfile();2949 BinaryArithProfile* arithProfile = subIC->arithProfile(); 2950 2950 ASSERT(arithProfile); 2951 2951 return profiledSub(vm, exec, encodedOp1, encodedOp2, *arithProfile); -
trunk/Source/JavaScriptCore/jit/JITOperations.h
r250803 r251090 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 using ExecState = CallFrame; … … 80 81 Aap: ArrayAllocationProfile* 81 82 Ap: ArrayProfile* 82 Arp: ArithProfile*83 Arp: BinaryArithProfile* 83 84 B: Butterfly* 84 85 By: ByValInfo* … … 146 147 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJA)(ExecState*, EncodedJSValue, JSArray*); 147 148 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EAPZ)(ExecState*, JSArray*, void*, int32_t); 148 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJArp)(ExecState*, EncodedJSValue, ArithProfile*);149 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJArp)(ExecState*, EncodedJSValue, BinaryArithProfile*); 149 150 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJI)(ExecState*, EncodedJSValue, UniquedStringImpl*); 150 151 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJ)(ExecState*, EncodedJSValue, EncodedJSValue); … … 152 153 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJJJ)(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue, EncodedJSValue); 153 154 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJAp)(ExecState*, EncodedJSValue, EncodedJSValue, ArrayProfile*); 154 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJArp)(ExecState*, EncodedJSValue, EncodedJSValue, ArithProfile*);155 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJArp)(ExecState*, EncodedJSValue, EncodedJSValue, BinaryArithProfile*); 155 156 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJBy)(ExecState*, EncodedJSValue, EncodedJSValue, ByValInfo*); 156 157 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJMic)(ExecState*, EncodedJSValue, EncodedJSValue, void*); … … 483 484 484 485 EncodedJSValue JIT_OPERATION operationValueAdd(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL; 485 EncodedJSValue JIT_OPERATION operationValueAddProfiled(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*) WTF_INTERNAL;486 EncodedJSValue JIT_OPERATION operationValueAddProfiled(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile*) WTF_INTERNAL; 486 487 EncodedJSValue JIT_OPERATION operationValueAddProfiledOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC*) WTF_INTERNAL; 487 488 EncodedJSValue JIT_OPERATION operationValueAddProfiledNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC*) WTF_INTERNAL; … … 493 494 EncodedJSValue JIT_OPERATION operationValueMulProfiledOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC*) WTF_INTERNAL; 494 495 EncodedJSValue JIT_OPERATION operationValueMulProfiledNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC*) WTF_INTERNAL; 495 EncodedJSValue JIT_OPERATION operationValueMulProfiled(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*) WTF_INTERNAL;496 EncodedJSValue JIT_OPERATION operationValueMulProfiled(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile*) WTF_INTERNAL; 496 497 EncodedJSValue JIT_OPERATION operationArithNegate(ExecState*, EncodedJSValue operand); 497 EncodedJSValue JIT_OPERATION operationArithNegateProfiled(ExecState*, EncodedJSValue operand, ArithProfile*);498 EncodedJSValue JIT_OPERATION operationArithNegateProfiled(ExecState*, EncodedJSValue operand, UnaryArithProfile*); 498 499 EncodedJSValue JIT_OPERATION operationArithNegateProfiledOptimize(ExecState*, EncodedJSValue encodedOperand, JITNegIC*); 499 500 EncodedJSValue JIT_OPERATION operationArithNegateOptimize(ExecState*, EncodedJSValue encodedOperand, JITNegIC*); 500 501 EncodedJSValue JIT_OPERATION operationValueSub(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL; 501 EncodedJSValue JIT_OPERATION operationValueSubProfiled(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*) WTF_INTERNAL;502 EncodedJSValue JIT_OPERATION operationValueSubProfiled(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile*) WTF_INTERNAL; 502 503 EncodedJSValue JIT_OPERATION operationValueSubOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC*) WTF_INTERNAL; 503 504 EncodedJSValue JIT_OPERATION operationValueSubNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC*) WTF_INTERNAL; -
trunk/Source/JavaScriptCore/jit/JITSubGenerator.cpp
r226440 r251090 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
r206525 r251090 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
r250094 r251090 136 136 137 137 { 138 ArithProfile arithProfile; 138 UnaryArithProfile arithProfile; 139 arithProfile.argSawInt32(); 140 ASSERT(arithProfile.bits() == UnaryArithProfile::observedIntBits()); 141 ASSERT(arithProfile.argObservedType().isOnlyInt32()); 142 } 143 { 144 UnaryArithProfile arithProfile; 145 arithProfile.argSawNumber(); 146 ASSERT(arithProfile.bits() == UnaryArithProfile::observedNumberBits()); 147 ASSERT(arithProfile.argObservedType().isOnlyNumber()); 148 } 149 150 { 151 BinaryArithProfile arithProfile; 139 152 arithProfile.lhsSawInt32(); 140 153 arithProfile.rhsSawInt32(); 141 ASSERT(arithProfile.bits() == ArithProfile::observedBinaryIntInt().bits());142 STATIC_ASSERT(ArithProfile::observedBinaryIntInt().lhsObservedType().isOnlyInt32());143 STATIC_ASSERT(ArithProfile::observedBinaryIntInt().rhsObservedType().isOnlyInt32());154 ASSERT(arithProfile.bits() == BinaryArithProfile::observedIntIntBits()); 155 ASSERT(arithProfile.lhsObservedType().isOnlyInt32()); 156 ASSERT(arithProfile.rhsObservedType().isOnlyInt32()); 144 157 } 145 158 { 146 ArithProfile arithProfile;159 BinaryArithProfile arithProfile; 147 160 arithProfile.lhsSawNumber(); 148 161 arithProfile.rhsSawInt32(); 149 ASSERT(arithProfile.bits() == ArithProfile::observedBinaryNumberInt().bits());150 STATIC_ASSERT(ArithProfile::observedBinaryNumberInt().lhsObservedType().isOnlyNumber());151 STATIC_ASSERT(ArithProfile::observedBinaryNumberInt().rhsObservedType().isOnlyInt32());162 ASSERT(arithProfile.bits() == BinaryArithProfile::observedNumberIntBits()); 163 ASSERT(arithProfile.lhsObservedType().isOnlyNumber()); 164 ASSERT(arithProfile.rhsObservedType().isOnlyInt32()); 152 165 } 153 166 { 154 ArithProfile arithProfile;167 BinaryArithProfile arithProfile; 155 168 arithProfile.lhsSawNumber(); 156 169 arithProfile.rhsSawNumber(); 157 ASSERT(arithProfile.bits() == ArithProfile::observedBinaryNumberNumber().bits());158 STATIC_ASSERT(ArithProfile::observedBinaryNumberNumber().lhsObservedType().isOnlyNumber());159 STATIC_ASSERT(ArithProfile::observedBinaryNumberNumber().rhsObservedType().isOnlyNumber());170 ASSERT(arithProfile.bits() == BinaryArithProfile::observedNumberNumberBits()); 171 ASSERT(arithProfile.lhsObservedType().isOnlyNumber()); 172 ASSERT(arithProfile.rhsObservedType().isOnlyNumber()); 160 173 } 161 174 { 162 ArithProfile arithProfile;175 BinaryArithProfile arithProfile; 163 176 arithProfile.lhsSawInt32(); 164 177 arithProfile.rhsSawNumber(); 165 ASSERT(arithProfile.bits() == ArithProfile::observedBinaryIntNumber().bits());166 STATIC_ASSERT(ArithProfile::observedBinaryIntNumber().lhsObservedType().isOnlyInt32());167 STATIC_ASSERT(ArithProfile::observedBinaryIntNumber().rhsObservedType().isOnlyNumber());178 ASSERT(arithProfile.bits() == BinaryArithProfile::observedIntNumberBits()); 179 ASSERT(arithProfile.lhsObservedType().isOnlyInt32()); 180 ASSERT(arithProfile.rhsObservedType().isOnlyNumber()); 168 181 } 169 182 } -
trunk/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp
r249547 r251090 87 87 const int64_t* LLIntOffsetsExtractor::dummy() 88 88 { 89 // This is a file generated by offlineasm/generate_offset s_extractor.rb, and contains code89 // This is a file generated by offlineasm/generate_offset_extractor.rb, and contains code 90 90 // to create a table of offsets, sizes, and a header identifying what combination of 91 91 // Platform.h macros we have set. We include it inside of a method on LLIntOffsetsExtractor -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
r250949 r251090 241 241 const ShadowChickenTailMarker = constexpr ShadowChicken::Packet::tailMarkerValue 242 242 243 # ArithProfile data 244 const ArithProfileInt = constexpr (ArithProfile::observedUnaryInt().bits()) 245 const ArithProfileNumber = constexpr (ArithProfile::observedUnaryNumber().bits()) 246 const ArithProfileIntInt = constexpr (ArithProfile::observedBinaryIntInt().bits()) 247 const ArithProfileNumberInt = constexpr (ArithProfile::observedBinaryNumberInt().bits()) 248 const ArithProfileIntNumber = constexpr (ArithProfile::observedBinaryIntNumber().bits()) 249 const ArithProfileNumberNumber = constexpr (ArithProfile::observedBinaryNumberNumber().bits()) 243 # UnaryArithProfile data 244 const ArithProfileInt = constexpr (UnaryArithProfile::observedIntBits()) 245 const ArithProfileNumber = constexpr (UnaryArithProfile::observedNumberBits()) 246 247 # BinaryArithProfile data 248 const ArithProfileIntInt = constexpr (BinaryArithProfile::observedIntIntBits()) 249 const ArithProfileNumberInt = constexpr (BinaryArithProfile::observedNumberIntBits()) 250 const ArithProfileIntNumber = constexpr (BinaryArithProfile::observedIntNumberBits()) 251 const ArithProfileNumberNumber = constexpr (BinaryArithProfile::observedNumberNumberBits()) 250 252 251 253 # Pointer Tags -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
r250982 r251090 1005 1005 1006 1006 macro arithProfile(type) 1007 ori type, OpNegate::Metadata::m_arithProfile + ArithProfile::m_bits[t5]1007 ori type, OpNegate::Metadata::m_arithProfile + BinaryArithProfile::m_bits[t5] 1008 1008 end 1009 1009 … … 1031 1031 llintOpWithMetadata(op_%opcodeName%, opcodeStruct, macro (size, get, dispatch, metadata, return) 1032 1032 macro arithProfile(type) 1033 ori type, %opcodeStruct%::Metadata::m_arithProfile + ArithProfile::m_bits[t5]1033 ori type, %opcodeStruct%::Metadata::m_arithProfile + BinaryArithProfile::m_bits[t5] 1034 1034 end 1035 1035 -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
r250806 r251090 977 977 loadConstantOrVariable(size, t0, t3) 978 978 metadata(t1, t2) 979 loadi OpNegate::Metadata::m_arithProfile + ArithProfile::m_bits[t1], t2979 loadi OpNegate::Metadata::m_arithProfile + BinaryArithProfile::m_bits[t1], t2 980 980 bqb t3, numberTag, .opNegateNotInt 981 981 btiz t3, 0x7fffffff, .opNegateSlow … … 983 983 orq numberTag, t3 984 984 ori ArithProfileInt, t2 985 storei t2, OpNegate::Metadata::m_arithProfile + ArithProfile::m_bits[t1]985 storei t2, OpNegate::Metadata::m_arithProfile + BinaryArithProfile::m_bits[t1] 986 986 return(t3) 987 987 .opNegateNotInt: … … 989 989 xorq 0x8000000000000000, t3 990 990 ori ArithProfileNumber, t2 991 storei t2, OpNegate::Metadata::m_arithProfile + ArithProfile::m_bits[t1]991 storei t2, OpNegate::Metadata::m_arithProfile + BinaryArithProfile::m_bits[t1] 992 992 return(t3) 993 993 … … 1003 1003 1004 1004 macro profile(type) 1005 ori type, %opcodeStruct%::Metadata::m_arithProfile + ArithProfile::m_bits[t5]1005 ori type, %opcodeStruct%::Metadata::m_arithProfile + BinaryArithProfile::m_bits[t5] 1006 1006 end 1007 1007 -
trunk/Source/JavaScriptCore/parser/ResultType.h
r249736 r251090 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
r250630 r251090 488 488 static void updateArithProfileForUnaryArithOp(OpNegate::Metadata& metadata, JSValue result, JSValue operand) 489 489 { 490 ArithProfile& profile = metadata.m_arithProfile;491 profile.observe LHS(operand);490 UnaryArithProfile& profile = metadata.m_arithProfile; 491 profile.observeArg(operand); 492 492 ASSERT(result.isNumber() || result.isBigInt()); 493 493 if (result.isNumber()) { … … 547 547 { 548 548 CodeBlock* codeBlock = exec->codeBlock(); 549 ArithProfile& profile = *codeBlock->arithProfileForPC(pc);549 BinaryArithProfile& profile = *codeBlock->binaryArithProfileForPC(pc); 550 550 551 551 if (result.isNumber()) { … … 608 608 JSValue v2 = GET_C(bytecode.m_rhs).jsValue(); 609 609 610 ArithProfile& arithProfile = *exec->codeBlock()->arithProfileForPC(pc);610 BinaryArithProfile& arithProfile = *exec->codeBlock()->binaryArithProfileForPC(pc); 611 611 arithProfile.observeLHSAndRHS(v1, v2); 612 612
Note: See TracChangeset
for help on using the changeset viewer.