Changeset 252229 in webkit
- Timestamp:
- Nov 7, 2019 6:46:09 PM (4 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 46 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r252216 r252229 1 2019-11-07 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 <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-07 Tadeu Zagallo <tzagallo@apple.com> 2 167 -
trunk/Source/JavaScriptCore/bytecode/ArithProfile.cpp
r252021 r252229 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
r252021 r252229 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
r252032 r252229 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, … … 280 282 }, 281 283 metadata: { 282 arithProfile: ArithProfile 283 }, 284 metadata_initializers: { 285 arithProfile: :operandTypes 284 arithProfile: BinaryArithProfile 286 285 } 287 286 … … 365 364 dst: VirtualRegister, 366 365 operand: VirtualRegister, 367 operandTypes: OperandTypes, 368 }, 369 metadata: { 370 arithProfile: ArithProfile, 371 }, 372 metadata_initializers: { 373 arithProfile: :operandTypes 366 resultType: ResultType, 367 }, 368 metadata: { 369 arithProfile: UnaryArithProfile, 374 370 } 375 371 -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r252032 r252229 1480 1480 } 1481 1481 1482 JITAddIC* CodeBlock::addJITAddIC( ArithProfile* arithProfile)1482 JITAddIC* CodeBlock::addJITAddIC(BinaryArithProfile* arithProfile) 1483 1483 { 1484 1484 ConcurrentJSLocker locker(m_lock); … … 1486 1486 } 1487 1487 1488 JITMulIC* CodeBlock::addJITMulIC( ArithProfile* arithProfile)1488 JITMulIC* CodeBlock::addJITMulIC(BinaryArithProfile* arithProfile) 1489 1489 { 1490 1490 ConcurrentJSLocker locker(m_lock); … … 1492 1492 } 1493 1493 1494 JITSubIC* CodeBlock::addJITSubIC( ArithProfile* arithProfile)1494 JITSubIC* CodeBlock::addJITSubIC(BinaryArithProfile* arithProfile) 1495 1495 { 1496 1496 ConcurrentJSLocker locker(m_lock); … … 1498 1498 } 1499 1499 1500 JITNegIC* CodeBlock::addJITNegIC( ArithProfile* arithProfile)1500 JITNegIC* CodeBlock::addJITNegIC(UnaryArithProfile* arithProfile) 1501 1501 { 1502 1502 ConcurrentJSLocker locker(m_lock); … … 3085 3085 } 3086 3086 3087 ArithProfile* CodeBlock::arithProfileForBytecodeIndex(BytecodeIndex bytecodeIndex) 3088 { 3089 return arithProfileForPC(instructions().at(bytecodeIndex.offset()).ptr()); 3090 } 3091 3092 ArithProfile* CodeBlock::arithProfileForPC(const Instruction* pc) 3087 BinaryArithProfile* CodeBlock::binaryArithProfileForBytecodeIndex(BytecodeIndex bytecodeIndex) 3088 { 3089 return binaryArithProfileForPC(instructions().at(bytecodeIndex.offset()).ptr()); 3090 } 3091 3092 UnaryArithProfile* CodeBlock::unaryArithProfileForBytecodeIndex(BytecodeIndex bytecodeIndex) 3093 { 3094 return unaryArithProfileForPC(instructions().at(bytecodeIndex.offset()).ptr()); 3095 } 3096 3097 BinaryArithProfile* CodeBlock::binaryArithProfileForPC(const Instruction* pc) 3093 3098 { 3094 3099 switch (pc->opcodeID()) { 3095 case op_negate:3096 return &pc->as<OpNegate>().metadata(this).m_arithProfile;3097 3100 case op_add: 3098 3101 return &pc->as<OpAdd>().metadata(this).m_arithProfile; … … 3110 3113 } 3111 3114 3115 UnaryArithProfile* CodeBlock::unaryArithProfileForPC(const Instruction* pc) 3116 { 3117 switch (pc->opcodeID()) { 3118 case op_negate: 3119 return &pc->as<OpNegate>().metadata(this).m_arithProfile; 3120 default: 3121 break; 3122 } 3123 3124 return nullptr; 3125 } 3126 3112 3127 bool CodeBlock::couldTakeSpecialArithFastCase(BytecodeIndex bytecodeIndex) 3113 3128 { 3114 3129 if (!hasBaselineJITProfiling()) 3115 3130 return false; 3116 ArithProfile* profile = arithProfileForBytecodeIndex(bytecodeIndex);3131 BinaryArithProfile* profile = binaryArithProfileForBytecodeIndex(bytecodeIndex); 3117 3132 if (!profile) 3118 3133 return false; -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.h
r252021 r252229 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
r252032 r252229 237 237 238 238 template<OpcodeSize size> 239 struct Fits<ResultType, size, std::enable_if_t<sizeof(ResultType) != size, std::true_type>> : public Fits<uint8_t, size> { 240 static_assert(sizeof(ResultType) == sizeof(uint8_t)); 241 using Base = Fits<uint8_t, size>; 242 243 static bool check(ResultType type) { return Base::check(type.bits()); } 244 245 static typename Base::TargetType convert(ResultType type) { return Base::convert(type.bits()); } 246 247 static ResultType convert(typename Base::TargetType type) { return ResultType(Base::convert(type)); } 248 }; 249 250 template<OpcodeSize size> 239 251 struct Fits<OperandTypes, size, std::enable_if_t<sizeof(OperandTypes) != size, std::true_type>> { 240 252 static_assert(sizeof(OperandTypes) == sizeof(uint16_t)); -
trunk/Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.cpp
r252021 r252229 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
r252021 r252229 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
r252032 r252229 1517 1517 } 1518 1518 1519 RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src, OperandTypes types)1519 RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src, ResultType type) 1520 1520 { 1521 1521 switch (opcodeID) { … … 1524 1524 break; 1525 1525 case op_negate: 1526 OpNegate::emit(this, dst, src, type s);1526 OpNegate::emit(this, dst, src, type); 1527 1527 break; 1528 1528 case op_bitnot: -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r252032 r252229 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
r252032 r252229 2147 2147 RefPtr<RegisterID> src = generator.emitNode(m_expr); 2148 2148 generator.emitExpressionInfo(position(), position(), position()); 2149 return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src.get(), OperandTypes(m_expr->resultDescriptor()));2149 return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src.get(), m_expr->resultDescriptor()); 2150 2150 } 2151 2151 -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r252032 r252229 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
r252021 r252229 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
r252160 r252229 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
r252021 r252229 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
r252021 r252229 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
r252021 r252229 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
r252021 r252229 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
r252021 r252229 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
r252021 r252229 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
r252021 r252229 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
r252021 r252229 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
r252021 r252229 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
r252021 r252229 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
r252021 r252229 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
r252021 r252229 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
r252021 r252229 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
r252030 r252229 2646 2646 } 2647 2647 2648 ALWAYS_INLINE static JSValue profiledAdd(JSGlobalObject* globalObject, JSValue op1, JSValue op2, ArithProfile& arithProfile)2648 ALWAYS_INLINE static JSValue profiledAdd(JSGlobalObject* globalObject, JSValue op1, JSValue op2, BinaryArithProfile& arithProfile) 2649 2649 { 2650 2650 arithProfile.observeLHSAndRHS(op1, op2); … … 2662 2662 } 2663 2663 2664 EncodedJSValue JIT_OPERATION operationValueAddProfiled(JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)2664 EncodedJSValue JIT_OPERATION operationValueAddProfiled(JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile* arithProfile) 2665 2665 { 2666 2666 ASSERT(arithProfile); … … 2680 2680 JSValue op2 = JSValue::decode(encodedOp2); 2681 2681 2682 ArithProfile* arithProfile = addIC->arithProfile();2682 BinaryArithProfile* arithProfile = addIC->arithProfile(); 2683 2683 ASSERT(arithProfile); 2684 2684 arithProfile->observeLHSAndRHS(op1, op2); … … 2702 2702 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 2703 2703 2704 ArithProfile* arithProfile = addIC->arithProfile();2704 BinaryArithProfile* arithProfile = addIC->arithProfile(); 2705 2705 ASSERT(arithProfile); 2706 2706 return JSValue::encode(profiledAdd(globalObject, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2), *arithProfile)); … … 2717 2717 2718 2718 auto nonOptimizeVariant = operationValueAddNoOptimize; 2719 if ( ArithProfile* arithProfile = addIC->arithProfile())2719 if (BinaryArithProfile* arithProfile = addIC->arithProfile()) 2720 2720 arithProfile->observeLHSAndRHS(op1, op2); 2721 2721 addIC->generateOutOfLine(callFrame->codeBlock(), nonOptimizeVariant); … … 2750 2750 } 2751 2751 2752 ALWAYS_INLINE static EncodedJSValue profiledMul(JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true)2752 ALWAYS_INLINE static EncodedJSValue profiledMul(JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true) 2753 2753 { 2754 2754 VM& vm = globalObject->vm(); … … 2791 2791 2792 2792 auto nonOptimizeVariant = operationValueMulNoOptimize; 2793 if ( ArithProfile* arithProfile = mulIC->arithProfile())2793 if (BinaryArithProfile* arithProfile = mulIC->arithProfile()) 2794 2794 arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2)); 2795 2795 mulIC->generateOutOfLine(callFrame->codeBlock(), nonOptimizeVariant); … … 2802 2802 } 2803 2803 2804 EncodedJSValue JIT_OPERATION operationValueMulProfiled(JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)2804 EncodedJSValue JIT_OPERATION operationValueMulProfiled(JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile* arithProfile) 2805 2805 { 2806 2806 VM& vm = globalObject->vm(); … … 2818 2818 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 2819 2819 2820 ArithProfile* arithProfile = mulIC->arithProfile();2820 BinaryArithProfile* arithProfile = mulIC->arithProfile(); 2821 2821 ASSERT(arithProfile); 2822 2822 arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2)); … … 2837 2837 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 2838 2838 2839 ArithProfile* arithProfile = mulIC->arithProfile();2839 BinaryArithProfile* arithProfile = mulIC->arithProfile(); 2840 2840 ASSERT(arithProfile); 2841 2841 return profiledMul(globalObject, encodedOp1, encodedOp2, *arithProfile); … … 2863 2863 } 2864 2864 2865 EncodedJSValue JIT_OPERATION operationArithNegateProfiled(JSGlobalObject* globalObject, EncodedJSValue encodedOperand, ArithProfile* arithProfile)2865 EncodedJSValue JIT_OPERATION operationArithNegateProfiled(JSGlobalObject* globalObject, EncodedJSValue encodedOperand, UnaryArithProfile* arithProfile) 2866 2866 { 2867 2867 ASSERT(arithProfile); … … 2872 2872 2873 2873 JSValue operand = JSValue::decode(encodedOperand); 2874 arithProfile->observe LHS(operand);2874 arithProfile->observeArg(operand); 2875 2875 2876 2876 JSValue primValue = operand.toPrimitive(globalObject); … … 2900 2900 JSValue operand = JSValue::decode(encodedOperand); 2901 2901 2902 ArithProfile* arithProfile = negIC->arithProfile();2902 UnaryArithProfile* arithProfile = negIC->arithProfile(); 2903 2903 ASSERT(arithProfile); 2904 arithProfile->observe LHS(operand);2904 arithProfile->observeArg(operand); 2905 2905 negIC->generateOutOfLine(callFrame->codeBlock(), operationArithNegateProfiled); 2906 2906 … … 2934 2934 JSValue operand = JSValue::decode(encodedOperand); 2935 2935 2936 if ( ArithProfile* arithProfile = negIC->arithProfile())2937 arithProfile->observe LHS(operand);2936 if (UnaryArithProfile* arithProfile = negIC->arithProfile()) 2937 arithProfile->observeArg(operand); 2938 2938 negIC->generateOutOfLine(callFrame->codeBlock(), operationArithNegate); 2939 2939 … … 2961 2961 } 2962 2962 2963 ALWAYS_INLINE static EncodedJSValue profiledSub(VM& vm, JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true)2963 ALWAYS_INLINE static EncodedJSValue profiledSub(VM& vm, JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true) 2964 2964 { 2965 2965 auto scope = DECLARE_THROW_SCOPE(vm); … … 2985 2985 } 2986 2986 2987 EncodedJSValue JIT_OPERATION operationValueSubProfiled(JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)2987 EncodedJSValue JIT_OPERATION operationValueSubProfiled(JSGlobalObject* globalObject, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile* arithProfile) 2988 2988 { 2989 2989 ASSERT(arithProfile); … … 3003 3003 3004 3004 auto nonOptimizeVariant = operationValueSubNoOptimize; 3005 if ( ArithProfile* arithProfile = subIC->arithProfile())3005 if (BinaryArithProfile* arithProfile = subIC->arithProfile()) 3006 3006 arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2)); 3007 3007 subIC->generateOutOfLine(callFrame->codeBlock(), nonOptimizeVariant); … … 3029 3029 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 3030 3030 3031 ArithProfile* arithProfile = subIC->arithProfile();3031 BinaryArithProfile* arithProfile = subIC->arithProfile(); 3032 3032 ASSERT(arithProfile); 3033 3033 arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2)); … … 3048 3048 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 3049 3049 3050 ArithProfile* arithProfile = subIC->arithProfile();3050 BinaryArithProfile* arithProfile = subIC->arithProfile(); 3051 3051 ASSERT(arithProfile); 3052 3052 return profiledSub(vm, globalObject, encodedOp1, encodedOp2, *arithProfile); -
trunk/Source/JavaScriptCore/jit/JITOperations.h
r252021 r252229 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
r252021 r252229 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
r252021 r252229 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
r252021 r252229 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
r252021 r252229 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
r252021 r252229 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
r252032 r252229 1001 1001 llintOpWithMetadata(op_negate, OpNegate, macro (size, get, dispatch, metadata, return) 1002 1002 1003 macro arithProfile(type)1004 or i type, OpNegate::Metadata::m_arithProfile +ArithProfile::m_bits[t5]1003 macro updateArithProfile(type) 1004 orh type, OpNegate::Metadata::m_arithProfile + UnaryArithProfile::m_bits[t5] 1005 1005 end 1006 1006 … … 1011 1011 btiz t2, 0x7fffffff, .opNegateSlow 1012 1012 negi t2 1013 arithProfile(ArithProfileInt)1013 updateArithProfile(ArithProfileInt) 1014 1014 return (Int32Tag, t2) 1015 1015 .opNegateSrcNotInt: 1016 1016 bia t1, LowestTag, .opNegateSlow 1017 1017 xori 0x80000000, t1 1018 arithProfile(ArithProfileNumber)1018 updateArithProfile(ArithProfileNumber) 1019 1019 return(t1, t2) 1020 1020 … … 1028 1028 llintOpWithMetadata(op_%opcodeName%, opcodeStruct, macro (size, get, dispatch, metadata, return) 1029 1029 macro arithProfile(type) 1030 or i type, %opcodeStruct%::Metadata::m_arithProfile +ArithProfile::m_bits[t5]1030 orh type, %opcodeStruct%::Metadata::m_arithProfile + BinaryArithProfile::m_bits[t5] 1031 1031 end 1032 1032 -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
r252032 r252229 982 982 983 983 llintOpWithMetadata(op_negate, OpNegate, macro (size, get, dispatch, metadata, return) 984 985 macro updateArithProfile(type) 986 orh type, OpNegate::Metadata::m_arithProfile + UnaryArithProfile::m_bits[t1] 987 end 988 984 989 get(m_operand, t0) 985 990 loadConstantOrVariable(size, t0, t3) 986 991 metadata(t1, t2) 987 loadi OpNegate::Metadata::m_arithProfile + ArithProfile::m_bits[t1], t2988 992 bqb t3, numberTag, .opNegateNotInt 989 993 btiz t3, 0x7fffffff, .opNegateSlow 990 994 negi t3 991 995 orq numberTag, t3 992 ori ArithProfileInt, t2 993 storei t2, OpNegate::Metadata::m_arithProfile + ArithProfile::m_bits[t1] 996 updateArithProfile(ArithProfileInt) 994 997 return(t3) 995 998 .opNegateNotInt: 996 999 btqz t3, numberTag, .opNegateSlow 997 1000 xorq 0x8000000000000000, t3 998 ori ArithProfileNumber, t2 999 storei t2, OpNegate::Metadata::m_arithProfile + ArithProfile::m_bits[t1] 1001 updateArithProfile(ArithProfileNumber) 1000 1002 return(t3) 1001 1003 … … 1011 1013 1012 1014 macro profile(type) 1013 or i type, %opcodeStruct%::Metadata::m_arithProfile +ArithProfile::m_bits[t5]1015 orh type, %opcodeStruct%::Metadata::m_arithProfile + UnaryArithProfile::m_bits[t5] 1014 1016 end 1015 1017 -
trunk/Source/JavaScriptCore/offlineasm/arm.rb
r252021 r252229 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
r252021 r252229 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
r252021 r252229 161 161 case type 162 162 when :int8; "int8_t(#{valueStr})" 163 when :int16; "int16_t(#{valueStr})" 163 164 when :int32; "int32_t(#{valueStr})" 164 165 when :int64; "int64_t(#{valueStr})" … … 184 185 case type 185 186 when :int8; int8MemRef 187 when :int16; int16MemRef 186 188 when :int32; int32MemRef 187 189 when :int64; int64MemRef … … 387 389 def cloopEmitOperation(operands, type, operator) 388 390 raise unless type == :intptr || type == :uintptr || type == :int32 || type == :uint32 || \ 389 type == :int64 || type == :uint64 || type == :double 391 type == :int64 || type == :uint64 || type == :double || type == :int16 390 392 if operands.size == 3 391 393 op1 = operands[0] … … 401 403 if dst.is_a? RegisterID and (type == :int32 or type == :uint32) 402 404 truncationHeader = "(uint32_t)(" 405 truncationFooter = ")" 406 elsif dst.is_a? RegisterID and (type == :int16) 407 truncationHeader = "(uint16_t)(" 403 408 truncationFooter = ")" 404 409 else … … 586 591 when "orp" 587 592 cloopEmitOperation(operands, :intptr, "|") 593 when "orh" 594 cloopEmitOperation(operands, :int16, "|") 588 595 589 596 when "xori" -
trunk/Source/JavaScriptCore/offlineasm/instructions.rb
r252021 r252229 47 47 "orf", 48 48 "ord", 49 "orh", 49 50 "rshifti", 50 51 "urshifti", -
trunk/Source/JavaScriptCore/offlineasm/mips.rb
r252021 r252229 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
r252021 r252229 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
r252021 r252229 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
r252021 r252229 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
r252030 r252229 478 478 static void updateArithProfileForUnaryArithOp(OpNegate::Metadata& metadata, JSValue result, JSValue operand) 479 479 { 480 ArithProfile& profile = metadata.m_arithProfile;481 profile.observe LHS(operand);480 UnaryArithProfile& profile = metadata.m_arithProfile; 481 profile.observeArg(operand); 482 482 ASSERT(result.isNumber() || result.isBigInt()); 483 483 if (result.isNumber()) { … … 536 536 static void updateArithProfileForBinaryArithOp(JSGlobalObject*, CodeBlock* codeBlock, const Instruction* pc, JSValue result, JSValue left, JSValue right) 537 537 { 538 ArithProfile& profile = *codeBlock->arithProfileForPC(pc);538 BinaryArithProfile& profile = *codeBlock->binaryArithProfileForPC(pc); 539 539 540 540 if (result.isNumber()) { … … 597 597 JSValue v2 = GET_C(bytecode.m_rhs).jsValue(); 598 598 599 ArithProfile& arithProfile = *codeBlock->arithProfileForPC(pc);599 BinaryArithProfile& arithProfile = *codeBlock->binaryArithProfileForPC(pc); 600 600 arithProfile.observeLHSAndRHS(v1, v2); 601 601
Note: See TracChangeset
for help on using the changeset viewer.