Unreviewed, rolling out r251090.
https://bugs.webkit.org/show_bug.cgi?id=202959

"broke tests" (Requested by RMorisset on #webkit).

Reverted changeset:

"Split ArithProfile into a Unary and a Binary version"
https://bugs.webkit.org/show_bug.cgi?id=202832
https://trac.webkit.org/changeset/251090

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@251106 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 5eb2158..37531d5 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,16 @@
+2019-10-14  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r251090.
+        https://bugs.webkit.org/show_bug.cgi?id=202959
+
+        "broke tests" (Requested by RMorisset on #webkit).
+
+        Reverted changeset:
+
+        "Split ArithProfile into a Unary and a Binary version"
+        https://bugs.webkit.org/show_bug.cgi?id=202832
+        https://trac.webkit.org/changeset/251090
+
 2019-10-14  Robin Morisset  <rmorisset@apple.com>
 
         Split ArithProfile into a Unary and a Binary version
diff --git a/Source/JavaScriptCore/bytecode/ArithProfile.cpp b/Source/JavaScriptCore/bytecode/ArithProfile.cpp
index 05ee78a..999933b 100644
--- a/Source/JavaScriptCore/bytecode/ArithProfile.cpp
+++ b/Source/JavaScriptCore/bytecode/ArithProfile.cpp
@@ -32,8 +32,7 @@
 namespace JSC {
 
 #if ENABLE(JIT)
-template<typename BitfieldType>
-void ArithProfile<BitfieldType>::emitObserveResult(CCallHelpers& jit, JSValueRegs regs, TagRegistersMode mode)
+void ArithProfile::emitObserveResult(CCallHelpers& jit, JSValueRegs regs, TagRegistersMode mode)
 {
     if (!shouldEmitSetDouble() && !shouldEmitSetNonNumeric() && !shouldEmitSetBigInt())
         return;
@@ -59,50 +58,41 @@
     done.link(&jit);
 }
 
-template<typename BitfieldType>
-bool ArithProfile<BitfieldType>::shouldEmitSetDouble() const
+bool ArithProfile::shouldEmitSetDouble() const
 {
-    uint32_t mask = Int32Overflow | Int52Overflow | NegZeroDouble | NonNegZeroDouble;
+    uint32_t mask = ArithProfile::Int32Overflow | ArithProfile::Int52Overflow | ArithProfile::NegZeroDouble | ArithProfile::NonNegZeroDouble;
     return (m_bits & mask) != mask;
 }
 
-template<typename BitfieldType>
-void ArithProfile<BitfieldType>::emitSetDouble(CCallHelpers& jit) const
+void ArithProfile::emitSetDouble(CCallHelpers& jit) const
 {
     if (shouldEmitSetDouble())
-        jit.or32(CCallHelpers::TrustedImm32(Int32Overflow | Int52Overflow | NegZeroDouble | NonNegZeroDouble), CCallHelpers::AbsoluteAddress(addressOfBits()));
+        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::Int32Overflow | ArithProfile::Int52Overflow | ArithProfile::NegZeroDouble | ArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(addressOfBits()));
 }
 
-template<typename BitfieldType>
-bool ArithProfile<BitfieldType>::shouldEmitSetNonNumeric() const
+bool ArithProfile::shouldEmitSetNonNumeric() const
 {
     uint32_t mask = ArithProfile::NonNumeric;
     return (m_bits & mask) != mask;
 }
 
-template<typename BitfieldType>
-bool ArithProfile<BitfieldType>::shouldEmitSetBigInt() const
+bool ArithProfile::shouldEmitSetBigInt() const
 {
     uint32_t mask = ArithProfile::BigInt;
     return (m_bits & mask) != mask;
 }
 
-template<typename BitfieldType>
-void ArithProfile<BitfieldType>::emitSetNonNumeric(CCallHelpers& jit) const
+void ArithProfile::emitSetNonNumeric(CCallHelpers& jit) const
 {
     if (shouldEmitSetNonNumeric())
-        jit.or32(CCallHelpers::TrustedImm32(NonNumeric), CCallHelpers::AbsoluteAddress(addressOfBits()));
+        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NonNumeric), CCallHelpers::AbsoluteAddress(addressOfBits()));
 }
 
-template<typename BitfieldType>
-void ArithProfile<BitfieldType>::emitSetBigInt(CCallHelpers& jit) const
+void ArithProfile::emitSetBigInt(CCallHelpers& jit) const
 {
     if (shouldEmitSetBigInt())
-        jit.or32(CCallHelpers::TrustedImm32(BigInt), CCallHelpers::AbsoluteAddress(addressOfBits()));
+        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::BigInt), CCallHelpers::AbsoluteAddress(addressOfBits()));
 }
-
-template class ArithProfile<uint16_t>; // Generate the implementations for UnaryArithProfile
-template class ArithProfile<uint32_t>; // Generate the implementations for BinaryArithProfile
 #endif // ENABLE(JIT)
 
 } // namespace JSC
@@ -111,52 +101,7 @@
     
 using namespace JSC;
 
-void printInternal(PrintStream& out, const UnaryArithProfile& profile)
-{
-    const char* separator = "";
-
-    out.print("Result:<");
-    if (!profile.didObserveNonInt32()) {
-        out.print("Int32");
-        separator = "|";
-    } else {
-        if (profile.didObserveNegZeroDouble()) {
-            out.print(separator, "NegZeroDouble");
-            separator = "|";
-        }
-        if (profile.didObserveNonNegZeroDouble()) {
-            out.print(separator, "NonNegZeroDouble");
-            separator = "|";
-        }
-        if (profile.didObserveNonNumeric()) {
-            out.print(separator, "NonNumeric");
-            separator = "|";
-        }
-        if (profile.didObserveInt32Overflow()) {
-            out.print(separator, "Int32Overflow");
-            separator = "|";
-        }
-        if (profile.didObserveInt52Overflow()) {
-            out.print(separator, "Int52Overflow");
-            separator = "|";
-        }
-        if (profile.didObserveBigInt()) {
-            out.print(separator, "BigInt");
-            separator = "|";
-        }
-    }
-    out.print(">");
-
-    out.print(" Arg ObservedType:<");
-    out.print(profile.argObservedType());
-    out.print(">");
-
-    out.print(" Arg ResultType:<");
-    out.print(RawPointer(bitwise_cast<void*>(static_cast<uintptr_t>(profile.argResultType().bits()))));
-    out.print(">");
-}
-
-void printInternal(PrintStream& out, const BinaryArithProfile& profile)
+void printInternal(PrintStream& out, const ArithProfile& profile)
 {
     const char* separator = "";
 
diff --git a/Source/JavaScriptCore/bytecode/ArithProfile.h b/Source/JavaScriptCore/bytecode/ArithProfile.h
index 679a05f..fcc4e28 100644
--- a/Source/JavaScriptCore/bytecode/ArithProfile.h
+++ b/Source/JavaScriptCore/bytecode/ArithProfile.h
@@ -66,9 +66,102 @@
     uint8_t m_bits { 0 };
 };
 
-template <typename BitfieldType>
-class ArithProfile {
+struct ArithProfile {
+private:
+    static constexpr uint32_t numberOfFlagBits = 6;
+    static constexpr uint32_t rhsResultTypeShift = numberOfFlagBits;
+    static constexpr uint32_t lhsResultTypeShift = rhsResultTypeShift + ResultType::numBitsNeeded;
+    static constexpr uint32_t rhsObservedTypeShift = lhsResultTypeShift + ResultType::numBitsNeeded;
+    static constexpr uint32_t lhsObservedTypeShift = rhsObservedTypeShift + ObservedType::numBitsNeeded;
+
+    static_assert(ObservedType::numBitsNeeded == 3, "We make a hard assumption about that here.");
+    static constexpr uint32_t clearRhsObservedTypeBitMask = static_cast<uint32_t>(~((1 << rhsObservedTypeShift) | (1 << (rhsObservedTypeShift + 1)) | (1 << (rhsObservedTypeShift + 2))));
+    static constexpr uint32_t clearLhsObservedTypeBitMask = static_cast<uint32_t>(~((1 << lhsObservedTypeShift) | (1 << (lhsObservedTypeShift + 1)) | (1 << (lhsObservedTypeShift + 2))));
+
+    static constexpr uint32_t resultTypeMask = (1 << ResultType::numBitsNeeded) - 1;
+    static constexpr uint32_t observedTypeMask = (1 << ObservedType::numBitsNeeded) - 1;
+
+    enum class ConstantTag { Constant };
+
 public:
+    static constexpr uint32_t specialFastPathBit = 1 << (lhsObservedTypeShift + ObservedType::numBitsNeeded);
+    static_assert((lhsObservedTypeShift + ObservedType::numBitsNeeded) <= (sizeof(uint32_t) * 8) - 1, "Should fit in a uint32_t.");
+    static_assert(!(specialFastPathBit & ~clearLhsObservedTypeBitMask), "These bits should not intersect.");
+    static_assert(specialFastPathBit & clearLhsObservedTypeBitMask, "These bits should intersect.");
+    static_assert(specialFastPathBit > ~clearLhsObservedTypeBitMask, "These bits should not intersect and specialFastPathBit should be a higher bit.");
+
+    ArithProfile(ResultType arg)
+        : ArithProfile(ConstantTag::Constant, arg)
+    {
+        ASSERT(lhsResultType().bits() == arg.bits());
+        ASSERT(lhsObservedType().isEmpty());
+        ASSERT(rhsObservedType().isEmpty());
+    }
+
+    ArithProfile(ResultType lhs, ResultType rhs)
+        : ArithProfile(ConstantTag::Constant, lhs, rhs)
+    {
+        ASSERT(lhsResultType().bits() == lhs.bits() && rhsResultType().bits() == rhs.bits());
+        ASSERT(lhsObservedType().isEmpty());
+        ASSERT(rhsObservedType().isEmpty());
+    }
+
+    ArithProfile(OperandTypes types)
+        : ArithProfile(types.first(), types.second())
+    { }
+
+    ArithProfile() = default;
+
+    static constexpr ArithProfile fromInt(uint32_t bits)
+    {
+        return ArithProfile { ConstantTag::Constant, bits };
+    }
+
+    static constexpr ArithProfile observedUnaryInt()
+    {
+        constexpr ObservedType observedInt32 { ObservedType().withInt32() };
+        constexpr uint32_t bits = observedInt32.bits() << lhsObservedTypeShift;
+        static_assert(bits == 0x800000, "");
+        return fromInt(bits);
+    }
+    static constexpr ArithProfile observedUnaryNumber()
+    {
+        constexpr ObservedType observedNumber { ObservedType().withNumber() };
+        constexpr uint32_t bits = observedNumber.bits() << lhsObservedTypeShift;
+        static_assert(bits == 0x1000000, "");
+        return fromInt(bits);
+    }
+    static constexpr ArithProfile observedBinaryIntInt()
+    {
+        constexpr ObservedType observedInt32 { ObservedType().withInt32() };
+        constexpr uint32_t bits = (observedInt32.bits() << lhsObservedTypeShift) | (observedInt32.bits() << rhsObservedTypeShift);
+        static_assert(bits == 0x900000, "");
+        return fromInt(bits);
+    }
+    static constexpr ArithProfile observedBinaryNumberInt()
+    {
+        constexpr ObservedType observedNumber { ObservedType().withNumber() };
+        constexpr ObservedType observedInt32 { ObservedType().withInt32() };
+        constexpr uint32_t bits = (observedNumber.bits() << lhsObservedTypeShift) | (observedInt32.bits() << rhsObservedTypeShift);
+        static_assert(bits == 0x1100000, "");
+        return fromInt(bits);
+    }
+    static constexpr ArithProfile observedBinaryIntNumber()
+    {
+        constexpr ObservedType observedNumber { ObservedType().withNumber() };
+        constexpr ObservedType observedInt32 { ObservedType().withInt32() };
+        constexpr uint32_t bits = (observedInt32.bits() << lhsObservedTypeShift) | (observedNumber.bits() << rhsObservedTypeShift);
+        static_assert(bits == 0xa00000, "");
+        return fromInt(bits);
+    }
+    static constexpr ArithProfile observedBinaryNumberNumber()
+    {
+        constexpr ObservedType observedNumber { ObservedType().withNumber() };
+        constexpr uint32_t bits = (observedNumber.bits() << lhsObservedTypeShift) | (observedNumber.bits() << rhsObservedTypeShift);
+        static_assert(bits == 0x1200000, "");
+        return fromInt(bits);
+    }
+
     enum ObservedResults {
         NonNegZeroDouble = 1 << 0,
         NegZeroDouble    = 1 << 1,
@@ -77,231 +170,6 @@
         Int52Overflow    = 1 << 4,
         BigInt           = 1 << 5,
     };
-    static constexpr uint32_t observedResultsNumBitsNeeded = 6;
-
-    bool didObserveNonInt32() const { return hasBits(NonNegZeroDouble | NegZeroDouble | NonNumeric | BigInt); }
-    bool didObserveDouble() const { return hasBits(NonNegZeroDouble | NegZeroDouble); }
-    bool didObserveNonNegZeroDouble() const { return hasBits(NonNegZeroDouble); }
-    bool didObserveNegZeroDouble() const { return hasBits(NegZeroDouble); }
-    bool didObserveNonNumeric() const { return hasBits(NonNumeric); }
-    bool didObserveBigInt() const { return hasBits(BigInt); }
-    bool didObserveInt32Overflow() const { return hasBits(Int32Overflow); }
-    bool didObserveInt52Overflow() const { return hasBits(Int52Overflow); }
-
-    void setObservedNonNegZeroDouble() { setBit(NonNegZeroDouble); }
-    void setObservedNegZeroDouble() { setBit(NegZeroDouble); }
-    void setObservedNonNumeric() { setBit(NonNumeric); }
-    void setObservedBigInt() { setBit(BigInt); }
-    void setObservedInt32Overflow() { setBit(Int32Overflow); }
-    void setObservedInt52Overflow() { setBit(Int52Overflow); }
-
-    void observeResult(JSValue value)
-    {
-        if (value.isInt32())
-            return;
-        if (value.isNumber()) {
-            m_bits |= Int32Overflow | Int52Overflow | NonNegZeroDouble | NegZeroDouble;
-            return;
-        }
-        if (value && value.isBigInt()) {
-            m_bits |= BigInt;
-            return;
-        }
-        m_bits |= NonNumeric;
-    }
-
-    const void* addressOfBits() const { return &m_bits; }
-
-#if ENABLE(JIT)
-    // Sets (Int32Overflow | Int52Overflow | NonNegZeroDouble | NegZeroDouble) if it sees a
-    // double. Sets NonNumeric if it sees a non-numeric.
-    void emitObserveResult(CCallHelpers&, JSValueRegs, TagRegistersMode = HaveTagRegisters);
-
-    // Sets (Int32Overflow | Int52Overflow | NonNegZeroDouble | NegZeroDouble).
-    bool shouldEmitSetDouble() const;
-    void emitSetDouble(CCallHelpers&) const;
-
-    // Sets NonNumber.
-    void emitSetNonNumeric(CCallHelpers&) const;
-    bool shouldEmitSetNonNumeric() const;
-
-    // Sets BigInt
-    void emitSetBigInt(CCallHelpers&) const;
-    bool shouldEmitSetBigInt() const;
-#endif // ENABLE(JIT)
-
-    constexpr uint32_t bits() const { return m_bits; }
-
-protected:
-    ArithProfile(BitfieldType bits)
-        : m_bits(bits)
-    {
-    }
-
-    bool hasBits(int mask) const { return m_bits & mask; }
-    void setBit(int mask) { m_bits |= mask; }
-
-    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.
-};
-
-/* This class stores the following components in 16 bits:
- * - ObservedResults
- * - ResultType for the argument
- * - ObservedType for the argument
- */
-class UnaryArithProfile : public ArithProfile<uint16_t> {
-    static constexpr unsigned argResultTypeShift = observedResultsNumBitsNeeded;
-    static constexpr unsigned argObservedTypeShift = argResultTypeShift + ResultType::numBitsNeeded;
-
-    static_assert(argObservedTypeShift + ObservedType::numBitsNeeded <= sizeof(uint16_t) * 8, "Should fit in a uint16_t");
-
-    static constexpr uint16_t clearArgObservedTypeBitMask = static_cast<uint16_t>(~(0b111 << argObservedTypeShift));
-
-    static constexpr uint16_t resultTypeMask = (1 << ResultType::numBitsNeeded) - 1;
-    static constexpr uint16_t observedTypeMask = (1 << ObservedType::numBitsNeeded) - 1;
-
-public:
-    UnaryArithProfile(ResultType arg)
-        : ArithProfile<uint16_t>(arg.bits() << argResultTypeShift)
-    {
-        ASSERT(argResultType().bits() == arg.bits());
-        ASSERT(argObservedType().isEmpty());
-        ASSERT(argObservedType().isEmpty());
-    }
-
-    UnaryArithProfile()
-        : UnaryArithProfile(ResultType::unknownType())
-    {
-    }
-
-    static constexpr uint16_t observedIntBits()
-    {
-        constexpr ObservedType observedInt32 { ObservedType().withInt32() };
-        constexpr uint16_t bits = observedInt32.bits() << argObservedTypeShift;
-        static_assert(bits == 0x2000, "");
-        return bits;
-    }
-    static constexpr uint16_t observedNumberBits()
-    {
-        constexpr ObservedType observedNumber { ObservedType().withNumber() };
-        constexpr uint16_t bits = observedNumber.bits() << argObservedTypeShift;
-        static_assert(bits == 0x4000, "");
-        return bits;
-    }
-
-    ResultType argResultType() const { return ResultType((m_bits >> argResultTypeShift) & resultTypeMask); }
-
-    constexpr ObservedType argObservedType() const { return ObservedType((m_bits >> argObservedTypeShift) & observedTypeMask); }
-    void setArgObservedType(ObservedType type)
-    {
-        uint16_t bits = m_bits;
-        bits &= clearArgObservedTypeBitMask;
-        bits |= type.bits() << argObservedTypeShift;
-        m_bits = bits;
-        ASSERT(argObservedType() == type);
-    }
-
-    void argSawInt32() { setArgObservedType(argObservedType().withInt32()); }
-    void argSawNumber() { setArgObservedType(argObservedType().withNumber()); }
-    void argSawNonNumber() { setArgObservedType(argObservedType().withNonNumber()); }
-
-    void observeArg(JSValue arg)
-    {
-        UnaryArithProfile newProfile = *this;
-        if (arg.isNumber()) {
-            if (arg.isInt32())
-                newProfile.argSawInt32();
-            else
-                newProfile.argSawNumber();
-        } else
-            newProfile.argSawNonNumber();
-
-        m_bits = newProfile.bits();
-    }
-
-    bool isObservedTypeEmpty()
-    {
-        return argObservedType().isEmpty();
-    }
-
-    friend class JSC::LLIntOffsetsExtractor;
-};
-
-/* This class stores the following components in 32 bits:
- * - ObservedResults
- * - ResultType for right-hand-side
- * - ResultType for left-hand-side
- * - ObservedType for right-hand-side
- * - ObservedType for left-hand-side
- * - a bit used by division to indicate whether a special fast path was taken
- */
-class BinaryArithProfile : public ArithProfile<uint32_t> {
-    static constexpr uint32_t rhsResultTypeShift = observedResultsNumBitsNeeded;
-    static constexpr uint32_t lhsResultTypeShift = rhsResultTypeShift + ResultType::numBitsNeeded;
-    static constexpr uint32_t rhsObservedTypeShift = lhsResultTypeShift + ResultType::numBitsNeeded;
-    static constexpr uint32_t lhsObservedTypeShift = rhsObservedTypeShift + ObservedType::numBitsNeeded;
-
-    static_assert(ObservedType::numBitsNeeded == 3, "We make a hard assumption about that here.");
-    static constexpr uint32_t clearRhsObservedTypeBitMask = static_cast<uint32_t>(~(0b111 << rhsObservedTypeShift));
-    static constexpr uint32_t clearLhsObservedTypeBitMask = static_cast<uint32_t>(~(0b111 << lhsObservedTypeShift));
-
-    static constexpr uint32_t resultTypeMask = (1 << ResultType::numBitsNeeded) - 1;
-    static constexpr uint32_t observedTypeMask = (1 << ObservedType::numBitsNeeded) - 1;
-
-public:
-    static constexpr uint32_t specialFastPathBit = 1 << (lhsObservedTypeShift + ObservedType::numBitsNeeded);
-    static_assert((lhsObservedTypeShift + ObservedType::numBitsNeeded + 1) <= sizeof(uint32_t) * 8, "Should fit in a uint32_t.");
-    static_assert(!(specialFastPathBit & ~clearLhsObservedTypeBitMask), "These bits should not intersect.");
-    static_assert(specialFastPathBit & clearLhsObservedTypeBitMask, "These bits should intersect.");
-    static_assert(specialFastPathBit > ~clearLhsObservedTypeBitMask, "These bits should not intersect and specialFastPathBit should be a higher bit.");
-
-    BinaryArithProfile(ResultType lhs, ResultType rhs)
-        : ArithProfile<uint32_t>((lhs.bits() << lhsResultTypeShift) | (rhs.bits() << rhsResultTypeShift))
-    {
-        ASSERT(lhsResultType().bits() == lhs.bits() && rhsResultType().bits() == rhs.bits());
-        ASSERT(lhsObservedType().isEmpty());
-        ASSERT(rhsObservedType().isEmpty());
-    }
-
-    BinaryArithProfile(OperandTypes types)
-        : BinaryArithProfile(types.first(), types.second())
-    { }
-
-    BinaryArithProfile()
-        : BinaryArithProfile(ResultType::unknownType(), ResultType::unknownType())
-    {
-    }
-
-    static constexpr uint32_t observedIntIntBits()
-    {
-        constexpr ObservedType observedInt32 { ObservedType().withInt32() };
-        constexpr uint32_t bits = (observedInt32.bits() << lhsObservedTypeShift) | (observedInt32.bits() << rhsObservedTypeShift);
-        static_assert(bits == 0x900000, "");
-        return bits;
-    }
-    static constexpr uint32_t observedNumberIntBits()
-    {
-        constexpr ObservedType observedNumber { ObservedType().withNumber() };
-        constexpr ObservedType observedInt32 { ObservedType().withInt32() };
-        constexpr uint32_t bits = (observedNumber.bits() << lhsObservedTypeShift) | (observedInt32.bits() << rhsObservedTypeShift);
-        static_assert(bits == 0x1100000, "");
-        return bits;
-    }
-    static constexpr uint32_t observedIntNumberBits()
-    {
-        constexpr ObservedType observedNumber { ObservedType().withNumber() };
-        constexpr ObservedType observedInt32 { ObservedType().withInt32() };
-        constexpr uint32_t bits = (observedInt32.bits() << lhsObservedTypeShift) | (observedNumber.bits() << rhsObservedTypeShift);
-        static_assert(bits == 0xa00000, "");
-        return bits;
-    }
-    static constexpr uint32_t observedNumberNumberBits()
-    {
-        constexpr ObservedType observedNumber { ObservedType().withNumber() };
-        constexpr uint32_t bits = (observedNumber.bits() << lhsObservedTypeShift) | (observedNumber.bits() << rhsObservedTypeShift);
-        static_assert(bits == 0x1200000, "");
-        return bits;
-    }
 
     ResultType lhsResultType() const { return ResultType((m_bits >> lhsResultTypeShift) & resultTypeMask); }
     ResultType rhsResultType() const { return ResultType((m_bits >> rhsResultTypeShift) & resultTypeMask); }
@@ -328,6 +196,39 @@
 
     bool tookSpecialFastPath() const { return m_bits & specialFastPathBit; }
 
+    bool didObserveNonInt32() const { return hasBits(NonNegZeroDouble | NegZeroDouble | NonNumeric | BigInt); }
+    bool didObserveDouble() const { return hasBits(NonNegZeroDouble | NegZeroDouble); }
+    bool didObserveNonNegZeroDouble() const { return hasBits(NonNegZeroDouble); }
+    bool didObserveNegZeroDouble() const { return hasBits(NegZeroDouble); }
+    bool didObserveNonNumeric() const { return hasBits(NonNumeric); }
+    bool didObserveBigInt() const { return hasBits(BigInt); }
+    bool didObserveInt32Overflow() const { return hasBits(Int32Overflow); }
+    bool didObserveInt52Overflow() const { return hasBits(Int52Overflow); }
+
+    void setObservedNonNegZeroDouble() { setBit(NonNegZeroDouble); }
+    void setObservedNegZeroDouble() { setBit(NegZeroDouble); }
+    void setObservedNonNumeric() { setBit(NonNumeric); }
+    void setObservedBigInt() { setBit(BigInt); }
+    void setObservedInt32Overflow() { setBit(Int32Overflow); }
+    void setObservedInt52Overflow() { setBit(Int52Overflow); }
+
+    const void* addressOfBits() const { return &m_bits; }
+
+    void observeResult(JSValue value)
+    {
+        if (value.isInt32())
+            return;
+        if (value.isNumber()) {
+            m_bits |= Int32Overflow | Int52Overflow | NonNegZeroDouble | NegZeroDouble;
+            return;
+        }
+        if (value && value.isBigInt()) {
+            m_bits |= BigInt;
+            return;
+        }
+        m_bits |= NonNumeric;
+    }
+
     void lhsSawInt32() { setLhsObservedType(lhsObservedType().withInt32()); }
     void lhsSawNumber() { setLhsObservedType(lhsObservedType().withNumber()); }
     void lhsSawNonNumber() { setLhsObservedType(lhsObservedType().withNonNumber()); }
@@ -337,7 +238,7 @@
 
     void observeLHS(JSValue lhs)
     {
-        BinaryArithProfile newProfile = *this;
+        ArithProfile newProfile = *this;
         if (lhs.isNumber()) {
             if (lhs.isInt32())
                 newProfile.lhsSawInt32();
@@ -353,7 +254,7 @@
     {
         observeLHS(lhs);
 
-        BinaryArithProfile newProfile = *this;
+        ArithProfile newProfile = *this;
         if (rhs.isNumber()) {
             if (rhs.isInt32())
                 newProfile.rhsSawInt32();
@@ -365,11 +266,47 @@
         m_bits = newProfile.bits();
     }
 
-    bool isObservedTypeEmpty()
+#if ENABLE(JIT)    
+    // Sets (Int32Overflow | Int52Overflow | NonNegZeroDouble | NegZeroDouble) if it sees a
+    // double. Sets NonNumeric if it sees a non-numeric.
+    void emitObserveResult(CCallHelpers&, JSValueRegs, TagRegistersMode = HaveTagRegisters);
+    
+    // Sets (Int32Overflow | Int52Overflow | NonNegZeroDouble | NegZeroDouble).
+    bool shouldEmitSetDouble() const;
+    void emitSetDouble(CCallHelpers&) const;
+    
+    // Sets NonNumber.
+    void emitSetNonNumeric(CCallHelpers&) const;
+    bool shouldEmitSetNonNumeric() const;
+
+    // Sets BigInt
+    void emitSetBigInt(CCallHelpers&) const;
+    bool shouldEmitSetBigInt() const;
+#endif // ENABLE(JIT)
+
+    constexpr uint32_t bits() const { return m_bits; }
+
+private:
+    constexpr explicit ArithProfile(ConstantTag, uint32_t bits)
+        : m_bits(bits)
     {
-        return lhsObservedType().isEmpty() && rhsObservedType().isEmpty();
     }
 
+    constexpr ArithProfile(ConstantTag, ResultType arg)
+        : m_bits(arg.bits() << lhsResultTypeShift)
+    {
+    }
+
+    constexpr ArithProfile(ConstantTag, ResultType lhs, ResultType rhs)
+        : m_bits((lhs.bits() << lhsResultTypeShift) | (rhs.bits() << rhsResultTypeShift))
+    {
+    }
+
+    bool hasBits(int mask) const { return m_bits & mask; }
+    void setBit(int mask) { m_bits |= mask; }
+
+    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.
+
     friend class JSC::LLIntOffsetsExtractor;
 };
 
@@ -377,8 +314,7 @@
 
 namespace WTF {
 
-void printInternal(PrintStream&, const JSC::UnaryArithProfile&);
-void printInternal(PrintStream&, const JSC::BinaryArithProfile&);
+void printInternal(PrintStream&, const JSC::ArithProfile&);
 void printInternal(PrintStream&, const JSC::ObservedType&);
 
 } // namespace WTF
diff --git a/Source/JavaScriptCore/bytecode/BytecodeList.rb b/Source/JavaScriptCore/bytecode/BytecodeList.rb
index fb393ea..c086b8e 100644
--- a/Source/JavaScriptCore/bytecode/BytecodeList.rb
+++ b/Source/JavaScriptCore/bytecode/BytecodeList.rb
@@ -41,7 +41,6 @@
     :JSType,
     :JSValue,
     :LLIntCallLinkInfo,
-    :ResultType,
     :OperandTypes,
     :ProfileTypeBytecodeFlag,
     :PropertyOffset,
@@ -58,8 +57,7 @@
 
     :ValueProfile,
     :ValueProfileAndOperandBuffer,
-    :UnaryArithProfile,
-    :BinaryArithProfile,
+    :ArithProfile,
     :ArrayProfile,
     :ArrayAllocationProfile,
     :ObjectAllocationProfile,
@@ -284,7 +282,7 @@
         operandTypes: OperandTypes,
     },
     metadata: {
-        arithProfile: BinaryArithProfile
+        arithProfile: ArithProfile
     },
     metadata_initializers: {
         arithProfile: :operandTypes
@@ -369,13 +367,13 @@
     args: {
         dst: VirtualRegister,
         operand: VirtualRegister,
-        resultType: ResultType,
+        operandTypes: OperandTypes,
     },
     metadata: {
-        arithProfile: UnaryArithProfile,
+        arithProfile: ArithProfile,
     },
     metadata_initializers: {
-        arithProfile: :resultType
+        arithProfile: :operandTypes
     }
 
 op :not,
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index 143a362..60cc65e 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -1480,25 +1480,25 @@
     return ensureJITData(locker).m_stubInfos.add(accessType);
 }
 
-JITAddIC* CodeBlock::addJITAddIC(BinaryArithProfile* arithProfile)
+JITAddIC* CodeBlock::addJITAddIC(ArithProfile* arithProfile)
 {
     ConcurrentJSLocker locker(m_lock);
     return ensureJITData(locker).m_addICs.add(arithProfile);
 }
 
-JITMulIC* CodeBlock::addJITMulIC(BinaryArithProfile* arithProfile)
+JITMulIC* CodeBlock::addJITMulIC(ArithProfile* arithProfile)
 {
     ConcurrentJSLocker locker(m_lock);
     return ensureJITData(locker).m_mulICs.add(arithProfile);
 }
 
-JITSubIC* CodeBlock::addJITSubIC(BinaryArithProfile* arithProfile)
+JITSubIC* CodeBlock::addJITSubIC(ArithProfile* arithProfile)
 {
     ConcurrentJSLocker locker(m_lock);
     return ensureJITData(locker).m_subICs.add(arithProfile);
 }
 
-JITNegIC* CodeBlock::addJITNegIC(UnaryArithProfile* arithProfile)
+JITNegIC* CodeBlock::addJITNegIC(ArithProfile* arithProfile)
 {
     ConcurrentJSLocker locker(m_lock);
     return ensureJITData(locker).m_negICs.add(arithProfile);
@@ -3085,19 +3085,16 @@
     return instructions().at(offset + target).ptr();
 }
 
-BinaryArithProfile* CodeBlock::binaryArithProfileForBytecodeOffset(InstructionStream::Offset bytecodeOffset)
+ArithProfile* CodeBlock::arithProfileForBytecodeOffset(InstructionStream::Offset bytecodeOffset)
 {
-    return binaryArithProfileForPC(instructions().at(bytecodeOffset).ptr());
+    return arithProfileForPC(instructions().at(bytecodeOffset).ptr());
 }
 
-UnaryArithProfile* CodeBlock::unaryArithProfileForBytecodeOffset(InstructionStream::Offset bytecodeOffset)
-{
-    return unaryArithProfileForPC(instructions().at(bytecodeOffset).ptr());
-}
-
-BinaryArithProfile* CodeBlock::binaryArithProfileForPC(const Instruction* pc)
+ArithProfile* CodeBlock::arithProfileForPC(const Instruction* pc)
 {
     switch (pc->opcodeID()) {
+    case op_negate:
+        return &pc->as<OpNegate>().metadata(this).m_arithProfile;
     case op_add:
         return &pc->as<OpAdd>().metadata(this).m_arithProfile;
     case op_mul:
@@ -3113,23 +3110,11 @@
     return nullptr;
 }
 
-UnaryArithProfile* CodeBlock::unaryArithProfileForPC(const Instruction* pc)
-{
-    switch (pc->opcodeID()) {
-    case op_negate:
-        return &pc->as<OpNegate>().metadata(this).m_arithProfile;
-    default:
-        break;
-    }
-
-    return nullptr;
-}
-
 bool CodeBlock::couldTakeSpecialFastCase(InstructionStream::Offset bytecodeOffset)
 {
     if (!hasBaselineJITProfiling())
         return false;
-    BinaryArithProfile* profile = binaryArithProfileForBytecodeOffset(bytecodeOffset);
+    ArithProfile* profile = arithProfileForBytecodeOffset(bytecodeOffset);
     if (!profile)
         return false;
     return profile->tookSpecialFastPath();
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h
index 2a036ca..4233ea2 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.h
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.h
@@ -83,8 +83,6 @@
 } // namespace DFG
 #endif
 
-class UnaryArithProfile;
-class BinaryArithProfile;
 class BytecodeLivenessAnalysis;
 class CodeBlockSet;
 class ExecutableToCodeBlockEdge;
@@ -98,6 +96,7 @@
 
 enum class AccessType : int8_t;
 
+struct ArithProfile;
 struct OpCatch;
 
 enum ReoptimizationMode { DontCountReoptimization, CountReoptimization };
@@ -280,22 +279,22 @@
     }
     JITData& ensureJITDataSlow(const ConcurrentJSLocker&);
 
-    JITAddIC* addJITAddIC(BinaryArithProfile*);
-    JITMulIC* addJITMulIC(BinaryArithProfile*);
-    JITNegIC* addJITNegIC(UnaryArithProfile*);
-    JITSubIC* addJITSubIC(BinaryArithProfile*);
+    JITAddIC* addJITAddIC(ArithProfile*);
+    JITMulIC* addJITMulIC(ArithProfile*);
+    JITNegIC* addJITNegIC(ArithProfile*);
+    JITSubIC* addJITSubIC(ArithProfile*);
 
     template <typename Generator, typename = typename std::enable_if<std::is_same<Generator, JITAddGenerator>::value>::type>
-    JITAddIC* addMathIC(BinaryArithProfile* profile) { return addJITAddIC(profile); }
+    JITAddIC* addMathIC(ArithProfile* profile) { return addJITAddIC(profile); }
 
     template <typename Generator, typename = typename std::enable_if<std::is_same<Generator, JITMulGenerator>::value>::type>
-    JITMulIC* addMathIC(BinaryArithProfile* profile) { return addJITMulIC(profile); }
+    JITMulIC* addMathIC(ArithProfile* profile) { return addJITMulIC(profile); }
 
     template <typename Generator, typename = typename std::enable_if<std::is_same<Generator, JITNegGenerator>::value>::type>
-    JITNegIC* addMathIC(UnaryArithProfile* profile) { return addJITNegIC(profile); }
+    JITNegIC* addMathIC(ArithProfile* profile) { return addJITNegIC(profile); }
 
     template <typename Generator, typename = typename std::enable_if<std::is_same<Generator, JITSubGenerator>::value>::type>
-    JITSubIC* addMathIC(BinaryArithProfile* profile) { return addJITSubIC(profile); }
+    JITSubIC* addMathIC(ArithProfile* profile) { return addJITSubIC(profile); }
 
     StructureStubInfo* addStubInfo(AccessType);
 
@@ -493,10 +492,8 @@
     template<typename Functor> void forEachObjectAllocationProfile(const Functor&);
     template<typename Functor> void forEachLLIntCallLinkInfo(const Functor&);
 
-    BinaryArithProfile* binaryArithProfileForBytecodeOffset(InstructionStream::Offset bytecodeOffset);
-    UnaryArithProfile* unaryArithProfileForBytecodeOffset(InstructionStream::Offset bytecodeOffset);
-    BinaryArithProfile* binaryArithProfileForPC(const Instruction*);
-    UnaryArithProfile* unaryArithProfileForPC(const Instruction*);
+    ArithProfile* arithProfileForBytecodeOffset(InstructionStream::Offset bytecodeOffset);
+    ArithProfile* arithProfileForPC(const Instruction*);
 
     bool couldTakeSpecialFastCase(InstructionStream::Offset bytecodeOffset);
 
diff --git a/Source/JavaScriptCore/bytecode/Fits.h b/Source/JavaScriptCore/bytecode/Fits.h
index 77794c7..9ab7713 100644
--- a/Source/JavaScriptCore/bytecode/Fits.h
+++ b/Source/JavaScriptCore/bytecode/Fits.h
@@ -237,27 +237,6 @@
 };
 
 template<OpcodeSize size>
-struct Fits<ResultType, size, std::enable_if_t<sizeof(ResultType) != size, std::true_type>> {
-    static_assert(sizeof(ResultType) == sizeof(uint8_t));
-    using TargetType = typename TypeBySize<size>::unsignedType;
-
-    static bool check(ResultType)
-    {
-        return true;
-    }
-
-    static TargetType convert(ResultType type)
-    {
-        return static_cast<TargetType>(type.bits());
-    }
-
-    static ResultType convert(TargetType type)
-    {
-        return ResultType(static_cast<uint8_t>(type));
-    }
-};
-
-template<OpcodeSize size>
 struct Fits<OperandTypes, size, std::enable_if_t<sizeof(OperandTypes) != size, std::true_type>> {
     static_assert(sizeof(OperandTypes) == sizeof(uint16_t));
     using TargetType = typename TypeBySize<size>::unsignedType;
diff --git a/Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.cpp b/Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.cpp
index e027769..7e3cc94 100644
--- a/Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.cpp
+++ b/Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.cpp
@@ -66,16 +66,10 @@
         return;
     }
         
-    case UnaryArithProfileReady: {
-        u.unaryArithProfile->emitObserveResult(jit, regs, DoNotHaveTagRegisters);
+    case ArithProfileReady: {
+        u.arithProfile->emitObserveResult(jit, regs, DoNotHaveTagRegisters);
         return;
-    }
-
-    case BinaryArithProfileReady: {
-        u.binaryArithProfile->emitObserveResult(jit, regs, DoNotHaveTagRegisters);
-        return;
-    }
-    }
+    } }
     
     RELEASE_ASSERT_NOT_REACHED();
 }
@@ -100,16 +94,10 @@
         return;
     }
 
-    case UnaryArithProfileReady: {
-        u.unaryArithProfile->observeResult(value);
+    case ArithProfileReady: {
+        u.arithProfile->observeResult(value);
         return;
-    }
-
-    case BinaryArithProfileReady: {
-        u.binaryArithProfile->observeResult(value);
-        return;
-    }
-    }
+    } }
 
     RELEASE_ASSERT_NOT_REACHED();
 }
diff --git a/Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.h b/Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.h
index 0441501..b5e84b1 100644
--- a/Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.h
+++ b/Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.h
@@ -35,11 +35,10 @@
 
 namespace JSC {
 
-class UnaryArithProfile;
-class BinaryArithProfile;
 class CCallHelpers;
 class CodeBlock;
 class LazyOperandValueProfileKey;
+struct ArithProfile;
 struct ValueProfile;
 
 class MethodOfGettingAValueProfile {
@@ -57,21 +56,12 @@
         } else
             m_kind = None;
     }
-
-    MethodOfGettingAValueProfile(UnaryArithProfile* profile)
+    
+    MethodOfGettingAValueProfile(ArithProfile* profile)
     {
         if (profile) {
-            m_kind = UnaryArithProfileReady;
-            u.unaryArithProfile = profile;
-        } else
-            m_kind = None;
-    }
-
-    MethodOfGettingAValueProfile(BinaryArithProfile* profile)
-    {
-        if (profile) {
-            m_kind = BinaryArithProfileReady;
-            u.binaryArithProfile = profile;
+            m_kind = ArithProfileReady;
+            u.arithProfile = profile;
         } else
             m_kind = None;
     }
@@ -88,16 +78,14 @@
     enum Kind {
         None,
         Ready,
-        UnaryArithProfileReady,
-        BinaryArithProfileReady,
+        ArithProfileReady,
         LazyOperand
     };
     
     Kind m_kind;
     union {
         ValueProfile* profile;
-        UnaryArithProfile* unaryArithProfile;
-        BinaryArithProfile* binaryArithProfile;
+        ArithProfile* arithProfile;
         struct {
             CodeBlock* codeBlock;
             unsigned bytecodeOffset;
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index b7a4aa3..e7914aa 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -1665,14 +1665,14 @@
     return dst;
 }
 
-RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src, ResultType type)
+RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src, OperandTypes types)
 {
     switch (opcodeID) {
     case op_not:
         emitUnaryOp<OpNot>(dst, src);
         break;
     case op_negate:
-        OpNegate::emit(this, dst, src, type);
+        OpNegate::emit(this, dst, src, types);
         break;
     case op_bitnot:
         emitUnaryOp<OpBitnot>(dst, src);
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
index 38e77cd..4197abc 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
@@ -682,7 +682,7 @@
             return dst;
         }
 
-        RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src, ResultType);
+        RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src, OperandTypes);
 
         template<typename BinaryOp>
         std::enable_if_t<
diff --git a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index e481a4f..65937f3 100644
--- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -2136,7 +2136,7 @@
 {
     RefPtr<RegisterID> src = generator.emitNode(m_expr);
     generator.emitExpressionInfo(position(), position(), position());
-    return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src.get(), m_expr->resultDescriptor());
+    return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src.get(), OperandTypes(m_expr->resultDescriptor()));
 }
 
 // ------------------------------ UnaryPlusNode -----------------------------------
diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
index 1fe4dbe..661013a 100644
--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
@@ -942,60 +942,56 @@
         if (!isX86() && (node->op() == ArithMod || node->op() == ValueMod))
             return node;
 
-        switch (node->op()) {
-        case ArithAdd:
-        case ArithSub:
-        case ValueAdd: {
-            BinaryArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->binaryArithProfileForBytecodeOffset(m_currentIndex);
-            if (!arithProfile)
-                break;
-            if (arithProfile->didObserveDouble())
-                node->mergeFlags(NodeMayHaveDoubleResult);
-            if (arithProfile->didObserveNonNumeric())
-                node->mergeFlags(NodeMayHaveNonNumericResult);
-            if (arithProfile->didObserveBigInt())
-                node->mergeFlags(NodeMayHaveBigIntResult);
-            break;
-        }
-        case ValueMul:
-        case ArithMul: {
-            BinaryArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->binaryArithProfileForBytecodeOffset(m_currentIndex);
-            if (!arithProfile)
-                break;
-            if (arithProfile->didObserveInt52Overflow())
-                node->mergeFlags(NodeMayOverflowInt52);
-            if (arithProfile->didObserveInt32Overflow() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow))
-                node->mergeFlags(NodeMayOverflowInt32InBaseline);
-            if (arithProfile->didObserveNegZeroDouble() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero))
-                node->mergeFlags(NodeMayNegZeroInBaseline);
-            if (arithProfile->didObserveDouble())
-                node->mergeFlags(NodeMayHaveDoubleResult);
-            if (arithProfile->didObserveNonNumeric())
-                node->mergeFlags(NodeMayHaveNonNumericResult);
-            if (arithProfile->didObserveBigInt())
-                node->mergeFlags(NodeMayHaveBigIntResult);
-            break;
-        }
-        case ValueNegate:
-        case ArithNegate: {
-            UnaryArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->unaryArithProfileForBytecodeOffset(m_currentIndex);
-            if (!arithProfile)
-                break;
-            if (arithProfile->argObservedType().sawNumber() || arithProfile->didObserveDouble())
-                node->mergeFlags(NodeMayHaveDoubleResult);
-            if (arithProfile->didObserveNegZeroDouble() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero))
-                node->mergeFlags(NodeMayNegZeroInBaseline);
-            if (arithProfile->didObserveInt32Overflow() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow))
-                node->mergeFlags(NodeMayOverflowInt32InBaseline);
-            if (arithProfile->didObserveNonNumeric())
-                node->mergeFlags(NodeMayHaveNonNumericResult);
-            if (arithProfile->didObserveBigInt())
-                node->mergeFlags(NodeMayHaveBigIntResult);
-            break;
-        }
-
-        default:
-            break;
+        {
+            ArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->arithProfileForBytecodeOffset(m_currentIndex);
+            if (arithProfile) {
+                switch (node->op()) {
+                case ArithAdd:
+                case ArithSub:
+                case ValueAdd:
+                    if (arithProfile->didObserveDouble())
+                        node->mergeFlags(NodeMayHaveDoubleResult);
+                    if (arithProfile->didObserveNonNumeric())
+                        node->mergeFlags(NodeMayHaveNonNumericResult);
+                    if (arithProfile->didObserveBigInt())
+                        node->mergeFlags(NodeMayHaveBigIntResult);
+                    break;
+                
+                case ValueMul:
+                case ArithMul: {
+                    if (arithProfile->didObserveInt52Overflow())
+                        node->mergeFlags(NodeMayOverflowInt52);
+                    if (arithProfile->didObserveInt32Overflow() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow))
+                        node->mergeFlags(NodeMayOverflowInt32InBaseline);
+                    if (arithProfile->didObserveNegZeroDouble() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero))
+                        node->mergeFlags(NodeMayNegZeroInBaseline);
+                    if (arithProfile->didObserveDouble())
+                        node->mergeFlags(NodeMayHaveDoubleResult);
+                    if (arithProfile->didObserveNonNumeric())
+                        node->mergeFlags(NodeMayHaveNonNumericResult);
+                    if (arithProfile->didObserveBigInt())
+                        node->mergeFlags(NodeMayHaveBigIntResult);
+                    break;
+                }
+                case ValueNegate:
+                case ArithNegate: {
+                    if (arithProfile->lhsObservedType().sawNumber() || arithProfile->didObserveDouble())
+                        node->mergeFlags(NodeMayHaveDoubleResult);
+                    if (arithProfile->didObserveNegZeroDouble() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, NegativeZero))
+                        node->mergeFlags(NodeMayNegZeroInBaseline);
+                    if (arithProfile->didObserveInt32Overflow() || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow))
+                        node->mergeFlags(NodeMayOverflowInt32InBaseline);
+                    if (arithProfile->didObserveNonNumeric())
+                        node->mergeFlags(NodeMayHaveNonNumericResult);
+                    if (arithProfile->didObserveBigInt())
+                        node->mergeFlags(NodeMayHaveBigIntResult);
+                    break;
+                }
+                
+                default:
+                    break;
+                }
+            }
         }
         
         if (m_inlineStackTop->m_profiledBlock->likelyToTakeSlowCase(m_currentIndex)) {
@@ -1038,7 +1034,7 @@
         // FIXME: It might be possible to make this more granular.
         node->mergeFlags(NodeMayOverflowInt32InBaseline | NodeMayNegZeroInBaseline);
         
-        BinaryArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->binaryArithProfileForBytecodeOffset(m_currentIndex);
+        ArithProfile* arithProfile = m_inlineStackTop->m_profiledBlock->arithProfileForBytecodeOffset(m_currentIndex);
         if (arithProfile->didObserveBigInt())
             node->mergeFlags(NodeMayHaveBigIntResult);
 
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.cpp b/Source/JavaScriptCore/dfg/DFGGraph.cpp
index 4c6d109..9d5b7d9 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.cpp
+++ b/Source/JavaScriptCore/dfg/DFGGraph.cpp
@@ -1652,9 +1652,7 @@
                 return &profiledBlock->valueProfileForBytecodeOffset(node->origin.semantic.bytecodeIndex());
 
             if (profiledBlock->hasBaselineJITProfiling()) {
-                if (BinaryArithProfile* result = profiledBlock->binaryArithProfileForBytecodeOffset(node->origin.semantic.bytecodeIndex()))
-                    return result;
-                if (UnaryArithProfile* result = profiledBlock->unaryArithProfileForBytecodeOffset(node->origin.semantic.bytecodeIndex()))
+                if (ArithProfile* result = profiledBlock->arithProfileForBytecodeOffset(node->origin.semantic.bytecodeIndex()))
                     return result;
             }
         }
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
index f632d11..9d038b5 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -4000,7 +4000,7 @@
 
     CodeBlock* baselineCodeBlock = m_jit.graph().baselineCodeBlockFor(node->origin.semantic);
     unsigned bytecodeIndex = node->origin.semantic.bytecodeIndex();
-    BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeOffset(bytecodeIndex);
+    ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);
     JITAddIC* addIC = m_jit.codeBlock()->addJITAddIC(arithProfile);
     auto repatchingFunction = operationValueAddOptimize;
     auto nonRepatchingFunction = operationValueAdd;
@@ -4024,7 +4024,7 @@
 
         CodeBlock* baselineCodeBlock = m_jit.graph().baselineCodeBlockFor(node->origin.semantic);
         unsigned bytecodeIndex = node->origin.semantic.bytecodeIndex();
-        BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeOffset(bytecodeIndex);
+        ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);
         JITSubIC* subIC = m_jit.codeBlock()->addJITSubIC(arithProfile);
         auto repatchingFunction = operationValueSubOptimize;
         auto nonRepatchingFunction = operationValueSub;
@@ -4618,7 +4618,7 @@
 {
     CodeBlock* baselineCodeBlock = m_jit.graph().baselineCodeBlockFor(node->origin.semantic);
     unsigned bytecodeIndex = node->origin.semantic.bytecodeIndex();
-    UnaryArithProfile* arithProfile = baselineCodeBlock->unaryArithProfileForBytecodeOffset(bytecodeIndex);
+    ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);
     JITNegIC* negIC = m_jit.codeBlock()->addJITNegIC(arithProfile);
     auto repatchingFunction = operationArithNegateOptimize;
     auto nonRepatchingFunction = operationArithNegate;
@@ -4841,7 +4841,7 @@
 
     CodeBlock* baselineCodeBlock = m_jit.graph().baselineCodeBlockFor(node->origin.semantic);
     unsigned bytecodeIndex = node->origin.semantic.bytecodeIndex();
-    BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeOffset(bytecodeIndex);
+    ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);
     JITMulIC* mulIC = m_jit.codeBlock()->addJITMulIC(arithProfile);
     auto repatchingFunction = operationValueMulOptimize;
     auto nonRepatchingFunction = operationValueMul;
diff --git a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp b/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
index 938dc87..a3b84d6 100644
--- a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
+++ b/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
@@ -2107,7 +2107,7 @@
 
         CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic);
         unsigned bytecodeIndex = m_node->origin.semantic.bytecodeIndex();
-        BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeOffset(bytecodeIndex);
+        ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);
         auto repatchingFunction = operationValueAddOptimize;
         auto nonRepatchingFunction = operationValueAdd;
         compileBinaryMathIC<JITAddGenerator>(arithProfile, repatchingFunction, nonRepatchingFunction);
@@ -2126,7 +2126,7 @@
 
         CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic);
         unsigned bytecodeIndex = m_node->origin.semantic.bytecodeIndex();
-        BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeOffset(bytecodeIndex);
+        ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);
         auto repatchingFunction = operationValueSubOptimize;
         auto nonRepatchingFunction = operationValueSub;
         compileBinaryMathIC<JITSubGenerator>(arithProfile, repatchingFunction, nonRepatchingFunction);
@@ -2145,7 +2145,7 @@
 
         CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic);
         unsigned bytecodeIndex = m_node->origin.semantic.bytecodeIndex();
-        BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeOffset(bytecodeIndex);
+        ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);
         auto repatchingFunction = operationValueMulOptimize;
         auto nonRepatchingFunction = operationValueMul;
         compileBinaryMathIC<JITMulGenerator>(arithProfile, repatchingFunction, nonRepatchingFunction);
@@ -2153,7 +2153,7 @@
 
     template <typename Generator, typename Func1, typename Func2,
         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>>
-    void compileUnaryMathIC(UnaryArithProfile* arithProfile, Func1 repatchingFunction, Func2 nonRepatchingFunction)
+    void compileUnaryMathIC(ArithProfile* arithProfile, Func1 repatchingFunction, Func2 nonRepatchingFunction)
     {
         Node* node = m_node;
 
@@ -2239,7 +2239,7 @@
 
     template <typename Generator, typename Func1, typename Func2,
         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>>
-    void compileBinaryMathIC(BinaryArithProfile* arithProfile, Func1 repatchingFunction, Func2 nonRepatchingFunction)
+    void compileBinaryMathIC(ArithProfile* arithProfile, Func1 repatchingFunction, Func2 nonRepatchingFunction)
     {
         Node* node = m_node;
         
@@ -2406,7 +2406,7 @@
 
             CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic);
             unsigned bytecodeIndex = m_node->origin.semantic.bytecodeIndex();
-            BinaryArithProfile* arithProfile = baselineCodeBlock->binaryArithProfileForBytecodeOffset(bytecodeIndex);
+            ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);
             auto repatchingFunction = operationValueSubOptimize;
             auto nonRepatchingFunction = operationValueSub;
             compileBinaryMathIC<JITSubGenerator>(arithProfile, repatchingFunction, nonRepatchingFunction);
@@ -3072,7 +3072,7 @@
         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
         CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic);
         unsigned bytecodeIndex = m_node->origin.semantic.bytecodeIndex();
-        UnaryArithProfile* arithProfile = baselineCodeBlock->unaryArithProfileForBytecodeOffset(bytecodeIndex);
+        ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);
         auto repatchingFunction = operationArithNegateOptimize;
         auto nonRepatchingFunction = operationArithNegate;
         compileUnaryMathIC<JITNegGenerator>(arithProfile, repatchingFunction, nonRepatchingFunction);
diff --git a/Source/JavaScriptCore/jit/JIT.h b/Source/JavaScriptCore/jit/JIT.h
index 0d22fd0..427e9ae 100644
--- a/Source/JavaScriptCore/jit/JIT.h
+++ b/Source/JavaScriptCore/jit/JIT.h
@@ -919,7 +919,7 @@
         // It will give the slow path the same value read by the fast path.
         GetPutInfo copiedGetPutInfo(OpPutToScope);
         template<typename BinaryOp>
-        BinaryArithProfile copiedArithProfile(BinaryOp);
+        ArithProfile copiedArithProfile(BinaryOp);
 
         Interpreter* m_interpreter;
 
@@ -939,7 +939,7 @@
         Vector<SwitchRecord> m_switches;
 
         HashMap<unsigned, unsigned> m_copiedGetPutInfos;
-        HashMap<uint64_t, BinaryArithProfile> m_copiedArithProfiles;
+        HashMap<uint64_t, ArithProfile> m_copiedArithProfiles;
 
         JumpList m_exceptionChecks;
         JumpList m_exceptionChecksWithCallFrameRollback;
diff --git a/Source/JavaScriptCore/jit/JITAddGenerator.cpp b/Source/JavaScriptCore/jit/JITAddGenerator.cpp
index 740b2ed..627af27 100644
--- a/Source/JavaScriptCore/jit/JITAddGenerator.cpp
+++ b/Source/JavaScriptCore/jit/JITAddGenerator.cpp
@@ -34,7 +34,7 @@
 
 namespace JSC {
 
-JITMathICInlineResult JITAddGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const BinaryArithProfile* arithProfile)
+JITMathICInlineResult JITAddGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const ArithProfile* arithProfile)
 {
     // We default to speculating int32.
     ObservedType lhs = ObservedType().withInt32();
@@ -73,7 +73,7 @@
     return JITMathICInlineResult::GenerateFullSnippet;
 }
 
-bool JITAddGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const BinaryArithProfile* arithProfile, bool shouldEmitProfiling)
+bool JITAddGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile* arithProfile, bool shouldEmitProfiling)
 {
     ASSERT(m_scratchGPR != InvalidGPRReg);
     ASSERT(m_scratchGPR != m_left.payloadGPR());
diff --git a/Source/JavaScriptCore/jit/JITAddGenerator.h b/Source/JavaScriptCore/jit/JITAddGenerator.h
index 675cf93..4dc34a2 100644
--- a/Source/JavaScriptCore/jit/JITAddGenerator.h
+++ b/Source/JavaScriptCore/jit/JITAddGenerator.h
@@ -55,8 +55,8 @@
         ASSERT(!m_leftOperand.isConstInt32() || !m_rightOperand.isConstInt32());
     }
 
-    JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const BinaryArithProfile*);
-    bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const BinaryArithProfile*, bool shouldEmitProfiling);
+    JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const ArithProfile*);
+    bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile*, bool shouldEmitProfiling);
 
     static bool isLeftOperandValidConstant(SnippetOperand leftOperand) { return leftOperand.isPositiveConstInt32(); }
     static bool isRightOperandValidConstant(SnippetOperand rightOperand) { return rightOperand.isPositiveConstInt32(); }
diff --git a/Source/JavaScriptCore/jit/JITArithmetic.cpp b/Source/JavaScriptCore/jit/JITArithmetic.cpp
index 67f9986..f420ae9 100644
--- a/Source/JavaScriptCore/jit/JITArithmetic.cpp
+++ b/Source/JavaScriptCore/jit/JITArithmetic.cpp
@@ -452,7 +452,7 @@
 
 void JIT::emit_op_negate(const Instruction* currentInstruction)
 {
-    UnaryArithProfile* arithProfile = &currentInstruction->as<OpNegate>().metadata(m_codeBlock).m_arithProfile;
+    ArithProfile* arithProfile = &currentInstruction->as<OpNegate>().metadata(m_codeBlock).m_arithProfile;
     JITNegIC* negateIC = m_codeBlock->addJITNegIC(arithProfile);
     m_instructionToMathIC.add(currentInstruction, negateIC);
     emitMathICFast<OpNegate>(negateIC, currentInstruction, operationArithNegateProfiled, operationArithNegate);
@@ -633,9 +633,14 @@
     emitRightShiftFastPath(currentInstruction, op_urshift);
 }
 
+ALWAYS_INLINE static OperandTypes getOperandTypes(const ArithProfile& arithProfile)
+{
+    return OperandTypes(arithProfile.lhsResultType(), arithProfile.rhsResultType());
+}
+
 void JIT::emit_op_add(const Instruction* currentInstruction)
 {
-    BinaryArithProfile* arithProfile = &currentInstruction->as<OpAdd>().metadata(m_codeBlock).m_arithProfile;
+    ArithProfile* arithProfile = &currentInstruction->as<OpAdd>().metadata(m_codeBlock).m_arithProfile;
     JITAddIC* addIC = m_codeBlock->addJITAddIC(arithProfile);
     m_instructionToMathIC.add(currentInstruction, addIC);
     emitMathICFast<OpAdd>(addIC, currentInstruction, operationValueAddProfiled, operationValueAdd);
@@ -680,7 +685,7 @@
 
     bool generatedInlineCode = mathIC->generateInline(*this, mathICGenerationState);
     if (!generatedInlineCode) {
-        UnaryArithProfile* arithProfile = mathIC->arithProfile();
+        ArithProfile* arithProfile = mathIC->arithProfile();
         if (arithProfile && shouldEmitProfiling())
             callOperationWithResult(profiledFunction, resultRegs, srcRegs, arithProfile);
         else
@@ -703,7 +708,7 @@
 void JIT::emitMathICFast(JITBinaryMathIC<Generator>* mathIC, const Instruction* currentInstruction, ProfiledFunction profiledFunction, NonProfiledFunction nonProfiledFunction)
 {
     auto bytecode = currentInstruction->as<Op>();
-    BinaryArithProfile arithProfile = copiedArithProfile(bytecode);
+    OperandTypes types = getOperandTypes(copiedArithProfile(bytecode));
     int result = bytecode.m_dst.offset();
     int op1 = bytecode.m_lhs.offset();
     int op2 = bytecode.m_rhs.offset();
@@ -722,8 +727,8 @@
     FPRReg scratchFPR = fpRegT2;
 #endif
 
-    SnippetOperand leftOperand(arithProfile.lhsResultType());
-    SnippetOperand rightOperand(arithProfile.rhsResultType());
+    SnippetOperand leftOperand(types.first());
+    SnippetOperand rightOperand(types.second());
 
     if (isOperandConstantInt(op1))
         leftOperand.setConstInt32(getOperandConstantInt(op1));
@@ -753,7 +758,7 @@
             emitGetVirtualRegister(op1, leftRegs);
         else if (rightOperand.isConst())
             emitGetVirtualRegister(op2, rightRegs);
-        BinaryArithProfile* arithProfile = mathIC->arithProfile();
+        ArithProfile* arithProfile = mathIC->arithProfile();
         if (arithProfile && shouldEmitProfiling())
             callOperationWithResult(profiledFunction, resultRegs, leftRegs, rightRegs, arithProfile);
         else
@@ -793,7 +798,7 @@
     auto slowPathStart = label();
 #endif
 
-    UnaryArithProfile* arithProfile = mathIC->arithProfile();
+    ArithProfile* arithProfile = mathIC->arithProfile();
     if (arithProfile && shouldEmitProfiling()) {
         if (mathICGenerationState.shouldSlowPathRepatch)
             mathICGenerationState.slowPathCall = callOperationWithResult(reinterpret_cast<J_JITOperation_EJMic>(profiledRepatchFunction), resultRegs, srcRegs, TrustedImmPtr(mathIC));
@@ -825,7 +830,7 @@
     mathICGenerationState.slowPathStart = label();
 
     auto bytecode = currentInstruction->as<Op>();
-    BinaryArithProfile consistentArithProfile = copiedArithProfile(bytecode);
+    OperandTypes types = getOperandTypes(copiedArithProfile(bytecode));
     int result = bytecode.m_dst.offset();
     int op1 = bytecode.m_lhs.offset();
     int op2 = bytecode.m_rhs.offset();
@@ -840,8 +845,8 @@
     JSValueRegs resultRegs = leftRegs;
 #endif
     
-    SnippetOperand leftOperand(consistentArithProfile.lhsResultType());
-    SnippetOperand rightOperand(consistentArithProfile.rhsResultType());
+    SnippetOperand leftOperand(types.first());
+    SnippetOperand rightOperand(types.second());
 
     if (isOperandConstantInt(op1))
         leftOperand.setConstInt32(getOperandConstantInt(op1));
@@ -859,7 +864,7 @@
     auto slowPathStart = label();
 #endif
 
-    BinaryArithProfile* arithProfile = mathIC->arithProfile();
+    ArithProfile* arithProfile = mathIC->arithProfile();
     if (arithProfile && shouldEmitProfiling()) {
         if (mathICGenerationState.shouldSlowPathRepatch)
             mathICGenerationState.slowPathCall = callOperationWithResult(bitwise_cast<J_JITOperation_EJJMic>(profiledRepatchFunction), resultRegs, leftRegs, rightRegs, TrustedImmPtr(mathIC));
@@ -887,17 +892,19 @@
 void JIT::emit_op_div(const Instruction* currentInstruction)
 {
     auto bytecode = currentInstruction->as<OpDiv>();
-    BinaryArithProfile consistentArithProfile = copiedArithProfile(bytecode);
+    auto& metadata = bytecode.metadata(m_codeBlock);
     int result = bytecode.m_dst.offset();
     int op1 = bytecode.m_lhs.offset();
     int op2 = bytecode.m_rhs.offset();
 
 #if USE(JSVALUE64)
+    OperandTypes types = getOperandTypes(metadata.m_arithProfile);
     JSValueRegs leftRegs = JSValueRegs(regT0);
     JSValueRegs rightRegs = JSValueRegs(regT1);
     JSValueRegs resultRegs = leftRegs;
     GPRReg scratchGPR = regT2;
 #else
+    OperandTypes types = getOperandTypes(metadata.m_arithProfile);
     JSValueRegs leftRegs = JSValueRegs(regT1, regT0);
     JSValueRegs rightRegs = JSValueRegs(regT3, regT2);
     JSValueRegs resultRegs = leftRegs;
@@ -905,12 +912,12 @@
 #endif
     FPRReg scratchFPR = fpRegT2;
 
-    BinaryArithProfile* arithProfile = nullptr;
+    ArithProfile* arithProfile = nullptr;
     if (shouldEmitProfiling())
         arithProfile = &currentInstruction->as<OpDiv>().metadata(m_codeBlock).m_arithProfile;
 
-    SnippetOperand leftOperand(consistentArithProfile.lhsResultType());
-    SnippetOperand rightOperand(consistentArithProfile.rhsResultType());
+    SnippetOperand leftOperand(types.first());
+    SnippetOperand rightOperand(types.second());
 
     if (isOperandConstantInt(op1))
         leftOperand.setConstInt32(getOperandConstantInt(op1));
@@ -952,7 +959,7 @@
 
 void JIT::emit_op_mul(const Instruction* currentInstruction)
 {
-    BinaryArithProfile* arithProfile = &currentInstruction->as<OpMul>().metadata(m_codeBlock).m_arithProfile;
+    ArithProfile* arithProfile = &currentInstruction->as<OpMul>().metadata(m_codeBlock).m_arithProfile;
     JITMulIC* mulIC = m_codeBlock->addJITMulIC(arithProfile);
     m_instructionToMathIC.add(currentInstruction, mulIC);
     emitMathICFast<OpMul>(mulIC, currentInstruction, operationValueMulProfiled, operationValueMul);
@@ -968,7 +975,7 @@
 
 void JIT::emit_op_sub(const Instruction* currentInstruction)
 {
-    BinaryArithProfile* arithProfile = &currentInstruction->as<OpSub>().metadata(m_codeBlock).m_arithProfile;
+    ArithProfile* arithProfile = &currentInstruction->as<OpSub>().metadata(m_codeBlock).m_arithProfile;
     JITSubIC* subIC = m_codeBlock->addJITSubIC(arithProfile);
     m_instructionToMathIC.add(currentInstruction, subIC);
     emitMathICFast<OpSub>(subIC, currentInstruction, operationValueSubProfiled, operationValueSub);
diff --git a/Source/JavaScriptCore/jit/JITDivGenerator.cpp b/Source/JavaScriptCore/jit/JITDivGenerator.cpp
index b8c4798..66e1be1 100644
--- a/Source/JavaScriptCore/jit/JITDivGenerator.cpp
+++ b/Source/JavaScriptCore/jit/JITDivGenerator.cpp
@@ -130,7 +130,7 @@
     notDoubleZero.link(&jit);
 #endif
     if (m_arithProfile)
-        jit.or32(CCallHelpers::TrustedImm32(BinaryArithProfile::specialFastPathBit), CCallHelpers::AbsoluteAddress(m_arithProfile->addressOfBits()));
+        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::specialFastPathBit), CCallHelpers::AbsoluteAddress(m_arithProfile->addressOfBits()));
     jit.boxDouble(m_leftFPR, m_result);
 }
 
diff --git a/Source/JavaScriptCore/jit/JITDivGenerator.h b/Source/JavaScriptCore/jit/JITDivGenerator.h
index 708db10..8396677 100644
--- a/Source/JavaScriptCore/jit/JITDivGenerator.h
+++ b/Source/JavaScriptCore/jit/JITDivGenerator.h
@@ -37,7 +37,7 @@
     JITDivGenerator(SnippetOperand leftOperand, SnippetOperand rightOperand,
         JSValueRegs result, JSValueRegs left, JSValueRegs right,
         FPRReg leftFPR, FPRReg rightFPR, GPRReg scratchGPR, FPRReg scratchFPR,
-        BinaryArithProfile* arithProfile = nullptr)
+        ArithProfile* arithProfile = nullptr)
         : m_leftOperand(leftOperand)
         , m_rightOperand(rightOperand)
         , m_result(result)
@@ -71,7 +71,7 @@
     GPRReg m_scratchGPR;
     FPRReg m_scratchFPR;
     bool m_didEmitFastPath { false };
-    BinaryArithProfile* m_arithProfile;
+    ArithProfile* m_arithProfile;
 
     CCallHelpers::JumpList m_endJumpList;
     CCallHelpers::JumpList m_slowPathJumpList;
diff --git a/Source/JavaScriptCore/jit/JITInlines.h b/Source/JavaScriptCore/jit/JITInlines.h
index 57a81ec..3959b8d 100644
--- a/Source/JavaScriptCore/jit/JITInlines.h
+++ b/Source/JavaScriptCore/jit/JITInlines.h
@@ -717,13 +717,13 @@
 }
 
 template<typename BinaryOp>
-ALWAYS_INLINE BinaryArithProfile JIT::copiedArithProfile(BinaryOp bytecode)
+ALWAYS_INLINE ArithProfile JIT::copiedArithProfile(BinaryOp bytecode)
 {
     uint64_t key = (static_cast<uint64_t>(BinaryOp::opcodeID) + 1) << 32 | static_cast<uint64_t>(bytecode.m_metadataID);
     auto iterator = m_copiedArithProfiles.find(key);
     if (iterator != m_copiedArithProfiles.end())
         return iterator->value;
-    BinaryArithProfile arithProfile = bytecode.metadata(m_codeBlock).m_arithProfile;
+    ArithProfile arithProfile = bytecode.metadata(m_codeBlock).m_arithProfile;
     m_copiedArithProfiles.add(key, arithProfile);
     return arithProfile;
 }
diff --git a/Source/JavaScriptCore/jit/JITMathIC.h b/Source/JavaScriptCore/jit/JITMathIC.h
index 8464622..5645e42 100644
--- a/Source/JavaScriptCore/jit/JITMathIC.h
+++ b/Source/JavaScriptCore/jit/JITMathIC.h
@@ -52,11 +52,11 @@
 
 #define ENABLE_MATH_IC_STATS 0
 
-template <typename GeneratorType, typename ArithProfileType>
+template <typename GeneratorType, bool(*isProfileEmpty)(ArithProfile&)>
 class JITMathIC {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    JITMathIC(ArithProfileType* arithProfile)
+    JITMathIC(ArithProfile* arithProfile)
         : m_arithProfile(arithProfile)
     {
     }
@@ -71,7 +71,7 @@
         size_t startSize = jit.m_assembler.buffer().codeSize();
 
         if (m_arithProfile) {
-            if (m_arithProfile->isObservedTypeEmpty()) {
+            if (isProfileEmpty(*m_arithProfile)) {
                 // It looks like the MathIC has yet to execute. We don't want to emit code in this
                 // case for a couple reasons. First, the operation may never execute, so if we don't emit
                 // code, it's a win. Second, if the operation does execute, we can emit better code
@@ -223,7 +223,7 @@
         m_slowPathStartLocation = linkBuffer.locationOf<JSInternalPtrTag>(state.slowPathStart);
     }
 
-    ArithProfileType* arithProfile() const { return m_arithProfile; }
+    ArithProfile* arithProfile() const { return m_arithProfile; }
 
 #if ENABLE(MATH_IC_STATS)
     size_t m_generatedCodeSize { 0 };
@@ -236,7 +236,7 @@
     }
 #endif
 
-    ArithProfileType* m_arithProfile;
+    ArithProfile* m_arithProfile;
     MacroAssemblerCodeRef<JITStubRoutinePtrTag> m_code;
     CodeLocationLabel<JSInternalPtrTag> m_inlineStart;
     CodeLocationLabel<JSInternalPtrTag> m_inlineEnd;
@@ -246,15 +246,15 @@
     GeneratorType m_generator;
 };
 
-inline bool isBinaryProfileEmpty(BinaryArithProfile& arithProfile)
+inline bool isBinaryProfileEmpty(ArithProfile& arithProfile)
 {
     return arithProfile.lhsObservedType().isEmpty() || arithProfile.rhsObservedType().isEmpty();
 }
 template <typename GeneratorType>
-class JITBinaryMathIC : public JITMathIC<GeneratorType, BinaryArithProfile> {
+class JITBinaryMathIC : public JITMathIC<GeneratorType, isBinaryProfileEmpty> {
 public:
-    JITBinaryMathIC(BinaryArithProfile* arithProfile)
-        : JITMathIC<GeneratorType, BinaryArithProfile>(arithProfile)
+    JITBinaryMathIC(ArithProfile* arithProfile)
+        : JITMathIC<GeneratorType, isBinaryProfileEmpty>(arithProfile)
     {
     }
 };
@@ -264,15 +264,15 @@
 typedef JITBinaryMathIC<JITSubGenerator> JITSubIC;
 
 
-inline bool isUnaryProfileEmpty(BinaryArithProfile& arithProfile)
+inline bool isUnaryProfileEmpty(ArithProfile& arithProfile)
 {
     return arithProfile.lhsObservedType().isEmpty();
 }
 template <typename GeneratorType>
-class JITUnaryMathIC : public JITMathIC<GeneratorType, UnaryArithProfile> {
+class JITUnaryMathIC : public JITMathIC<GeneratorType, isUnaryProfileEmpty> {
 public:
-    JITUnaryMathIC(UnaryArithProfile* arithProfile)
-        : JITMathIC<GeneratorType, UnaryArithProfile>(arithProfile)
+    JITUnaryMathIC(ArithProfile* arithProfile)
+        : JITMathIC<GeneratorType, isUnaryProfileEmpty>(arithProfile)
     {
     }
 };
diff --git a/Source/JavaScriptCore/jit/JITMulGenerator.cpp b/Source/JavaScriptCore/jit/JITMulGenerator.cpp
index cf6baa5..83d293b 100644
--- a/Source/JavaScriptCore/jit/JITMulGenerator.cpp
+++ b/Source/JavaScriptCore/jit/JITMulGenerator.cpp
@@ -33,7 +33,7 @@
 
 namespace JSC {
 
-JITMathICInlineResult JITMulGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const BinaryArithProfile* arithProfile)
+JITMathICInlineResult JITMulGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const ArithProfile* arithProfile)
 {
     // We default to speculating int32.
     ObservedType lhs = ObservedType().withInt32();
@@ -89,7 +89,7 @@
     return JITMathICInlineResult::GenerateFullSnippet;
 }
 
-bool JITMulGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const BinaryArithProfile* arithProfile, bool shouldEmitProfiling)
+bool JITMulGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile* arithProfile, bool shouldEmitProfiling)
 {
     ASSERT(m_scratchGPR != InvalidGPRReg);
     ASSERT(m_scratchGPR != m_left.payloadGPR());
@@ -205,18 +205,18 @@
 
         CCallHelpers::Jump notNegativeZero = jit.branch64(CCallHelpers::NotEqual, m_result.payloadGPR(), CCallHelpers::TrustedImm64(negativeZeroBits));
 
-        jit.or32(CCallHelpers::TrustedImm32(BinaryArithProfile::NegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));
+        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));
         CCallHelpers::Jump done = jit.jump();
 
         notNegativeZero.link(&jit);
-        jit.or32(CCallHelpers::TrustedImm32(BinaryArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));
+        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));
 
         jit.move(m_result.payloadGPR(), m_scratchGPR);
         jit.urshiftPtr(CCallHelpers::Imm32(52), m_scratchGPR);
         jit.and32(CCallHelpers::Imm32(0x7ff), m_scratchGPR);
         CCallHelpers::Jump noInt52Overflow = jit.branch32(CCallHelpers::LessThanOrEqual, m_scratchGPR, CCallHelpers::TrustedImm32(0x431));
 
-        jit.or32(CCallHelpers::TrustedImm32(BinaryArithProfile::Int52Overflow), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));
+        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::Int52Overflow), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));
         noInt52Overflow.link(&jit);
 
         done.link(&jit);
@@ -227,18 +227,18 @@
         notNegativeZero.append(jit.branch32(CCallHelpers::NotEqual, m_result.payloadGPR(), CCallHelpers::TrustedImm32(0)));
         notNegativeZero.append(jit.branch32(CCallHelpers::NotEqual, m_result.tagGPR(), CCallHelpers::TrustedImm32(negativeZeroBits >> 32)));
 
-        jit.or32(CCallHelpers::TrustedImm32(BinaryArithProfile::NegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));
+        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));
         CCallHelpers::Jump done = jit.jump();
 
         notNegativeZero.link(&jit);
-        jit.or32(CCallHelpers::TrustedImm32(BinaryArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));
+        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));
 
         jit.move(m_result.tagGPR(), m_scratchGPR);
         jit.urshiftPtr(CCallHelpers::Imm32(52 - 32), m_scratchGPR);
         jit.and32(CCallHelpers::Imm32(0x7ff), m_scratchGPR);
         CCallHelpers::Jump noInt52Overflow = jit.branch32(CCallHelpers::LessThanOrEqual, m_scratchGPR, CCallHelpers::TrustedImm32(0x431));
         
-        jit.or32(CCallHelpers::TrustedImm32(BinaryArithProfile::Int52Overflow), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));
+        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::Int52Overflow), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));
 
         endJumpList.append(noInt52Overflow);
         if (m_scratchGPR == m_result.tagGPR() || m_scratchGPR == m_result.payloadGPR())
diff --git a/Source/JavaScriptCore/jit/JITMulGenerator.h b/Source/JavaScriptCore/jit/JITMulGenerator.h
index 6087796..36d26ea 100644
--- a/Source/JavaScriptCore/jit/JITMulGenerator.h
+++ b/Source/JavaScriptCore/jit/JITMulGenerator.h
@@ -56,8 +56,8 @@
         ASSERT(!m_leftOperand.isPositiveConstInt32() || !m_rightOperand.isPositiveConstInt32());
     }
 
-    JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const BinaryArithProfile*);
-    bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowJumpList, const BinaryArithProfile*, bool shouldEmitProfiling);
+    JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const ArithProfile*);
+    bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowJumpList, const ArithProfile*, bool shouldEmitProfiling);
 
     static bool isLeftOperandValidConstant(SnippetOperand leftOperand) { return leftOperand.isPositiveConstInt32(); }
     static bool isRightOperandValidConstant(SnippetOperand rightOperand) { return rightOperand.isPositiveConstInt32(); }
diff --git a/Source/JavaScriptCore/jit/JITNegGenerator.cpp b/Source/JavaScriptCore/jit/JITNegGenerator.cpp
index ceebe39..92c29dd 100644
--- a/Source/JavaScriptCore/jit/JITNegGenerator.cpp
+++ b/Source/JavaScriptCore/jit/JITNegGenerator.cpp
@@ -32,7 +32,7 @@
 
 namespace JSC {
 
-JITMathICInlineResult JITNegGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const UnaryArithProfile* arithProfile)
+JITMathICInlineResult JITNegGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const ArithProfile* arithProfile)
 {
     ASSERT(m_scratchGPR != InvalidGPRReg);
     ASSERT(m_scratchGPR != m_src.payloadGPR());
@@ -45,7 +45,7 @@
     // We default to speculating int32.
     ObservedType observedTypes = ObservedType().withInt32();
     if (arithProfile)
-        observedTypes = arithProfile->argObservedType();
+        observedTypes = arithProfile->lhsObservedType();
     ASSERT_WITH_MESSAGE(!observedTypes.isEmpty(), "We should not attempt to generate anything if we do not have a profile.");
 
     if (observedTypes.isOnlyNonNumber())
@@ -82,7 +82,7 @@
     return JITMathICInlineResult::GenerateFullSnippet;
 }
 
-bool JITNegGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const UnaryArithProfile* arithProfile, bool shouldEmitProfiling)
+bool JITNegGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile* arithProfile, bool shouldEmitProfiling)
 {
     ASSERT(m_scratchGPR != m_src.payloadGPR());
     ASSERT(m_scratchGPR != m_result.payloadGPR());
@@ -117,7 +117,7 @@
 #endif
     // The flags of ArithNegate are basic in DFG.
     // We only need to know if we ever produced a number.
-    if (shouldEmitProfiling && arithProfile && !arithProfile->argObservedType().sawNumber() && !arithProfile->didObserveDouble())
+    if (shouldEmitProfiling && arithProfile && !arithProfile->lhsObservedType().sawNumber() && !arithProfile->didObserveDouble())
         arithProfile->emitSetDouble(jit);
     return true;
 }
diff --git a/Source/JavaScriptCore/jit/JITNegGenerator.h b/Source/JavaScriptCore/jit/JITNegGenerator.h
index 787b707..8a0c2d5 100644
--- a/Source/JavaScriptCore/jit/JITNegGenerator.h
+++ b/Source/JavaScriptCore/jit/JITNegGenerator.h
@@ -43,8 +43,8 @@
         , m_scratchGPR(scratchGPR)
     { }
 
-    JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const UnaryArithProfile*);
-    bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const UnaryArithProfile*, bool shouldEmitProfiling);
+    JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const ArithProfile*);
+    bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile*, bool shouldEmitProfiling);
 
 private:
     JSValueRegs m_result;
diff --git a/Source/JavaScriptCore/jit/JITOperations.cpp b/Source/JavaScriptCore/jit/JITOperations.cpp
index 1879459..639463c 100644
--- a/Source/JavaScriptCore/jit/JITOperations.cpp
+++ b/Source/JavaScriptCore/jit/JITOperations.cpp
@@ -2554,7 +2554,7 @@
     return JSValue::encode(jsAdd(exec, op1, op2));
 }
 
-ALWAYS_INLINE static EncodedJSValue profiledAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile& arithProfile)
+ALWAYS_INLINE static EncodedJSValue profiledAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile& arithProfile)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
@@ -2574,7 +2574,7 @@
     return unprofiledAdd(exec, encodedOp1, encodedOp2);
 }
 
-EncodedJSValue JIT_OPERATION operationValueAddProfiled(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile* arithProfile)
+EncodedJSValue JIT_OPERATION operationValueAddProfiled(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)
 {
     ASSERT(arithProfile);
     return profiledAdd(exec, encodedOp1, encodedOp2, *arithProfile);
@@ -2588,7 +2588,7 @@
     JSValue op1 = JSValue::decode(encodedOp1);
     JSValue op2 = JSValue::decode(encodedOp2);
 
-    BinaryArithProfile* arithProfile = addIC->arithProfile();
+    ArithProfile* arithProfile = addIC->arithProfile();
     ASSERT(arithProfile);
     arithProfile->observeLHSAndRHS(op1, op2);
     auto nonOptimizeVariant = operationValueAddProfiledNoOptimize;
@@ -2609,7 +2609,7 @@
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
 
-    BinaryArithProfile* arithProfile = addIC->arithProfile();
+    ArithProfile* arithProfile = addIC->arithProfile();
     ASSERT(arithProfile);
     return profiledAdd(exec, encodedOp1, encodedOp2, *arithProfile);
 }
@@ -2623,7 +2623,7 @@
     JSValue op2 = JSValue::decode(encodedOp2);
 
     auto nonOptimizeVariant = operationValueAddNoOptimize;
-    if (BinaryArithProfile* arithProfile = addIC->arithProfile())
+    if (ArithProfile* arithProfile = addIC->arithProfile())
         arithProfile->observeLHSAndRHS(op1, op2);
     addIC->generateOutOfLine(exec->codeBlock(), nonOptimizeVariant);
 
@@ -2655,7 +2655,7 @@
     return JSValue::encode(jsMul(exec, op1, op2));
 }
 
-ALWAYS_INLINE static EncodedJSValue profiledMul(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true)
+ALWAYS_INLINE static EncodedJSValue profiledMul(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true)
 {
     VM& vm = exec->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
@@ -2693,7 +2693,7 @@
     NativeCallFrameTracer tracer(vm, exec);
 
     auto nonOptimizeVariant = operationValueMulNoOptimize;
-    if (BinaryArithProfile* arithProfile = mulIC->arithProfile())
+    if (ArithProfile* arithProfile = mulIC->arithProfile())
         arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
     mulIC->generateOutOfLine(exec->codeBlock(), nonOptimizeVariant);
 
@@ -2704,7 +2704,7 @@
     return unprofiledMul(exec, encodedOp1, encodedOp2);
 }
 
-EncodedJSValue JIT_OPERATION operationValueMulProfiled(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile* arithProfile)
+EncodedJSValue JIT_OPERATION operationValueMulProfiled(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
@@ -2718,7 +2718,7 @@
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
 
-    BinaryArithProfile* arithProfile = mulIC->arithProfile();
+    ArithProfile* arithProfile = mulIC->arithProfile();
     ASSERT(arithProfile);
     arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
     auto nonOptimizeVariant = operationValueMulProfiledNoOptimize;
@@ -2736,7 +2736,7 @@
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
 
-    BinaryArithProfile* arithProfile = mulIC->arithProfile();
+    ArithProfile* arithProfile = mulIC->arithProfile();
     ASSERT(arithProfile);
     return profiledMul(exec, encodedOp1, encodedOp2, *arithProfile);
 }
@@ -2760,14 +2760,14 @@
     return JSValue::encode(jsNumber(-number));
 }
 
-ALWAYS_INLINE static EncodedJSValue profiledNegate(ExecState* exec, EncodedJSValue encodedOperand, UnaryArithProfile& arithProfile)
+ALWAYS_INLINE static EncodedJSValue profiledNegate(ExecState* exec, EncodedJSValue encodedOperand, ArithProfile& arithProfile)
 {
     VM& vm = exec->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
     NativeCallFrameTracer tracer(vm, exec);
 
     JSValue operand = JSValue::decode(encodedOperand);
-    arithProfile.observeArg(operand);
+    arithProfile.observeLHS(operand);
     
     JSValue primValue = operand.toPrimitive(exec);
     RETURN_IF_EXCEPTION(scope, encodedJSValue());
@@ -2791,7 +2791,7 @@
     return unprofiledNegate(exec, operand);
 }
 
-EncodedJSValue JIT_OPERATION operationArithNegateProfiled(ExecState* exec, EncodedJSValue operand, UnaryArithProfile* arithProfile)
+EncodedJSValue JIT_OPERATION operationArithNegateProfiled(ExecState* exec, EncodedJSValue operand, ArithProfile* arithProfile)
 {
     ASSERT(arithProfile);
     return profiledNegate(exec, operand, *arithProfile);
@@ -2805,9 +2805,9 @@
     
     JSValue operand = JSValue::decode(encodedOperand);
 
-    UnaryArithProfile* arithProfile = negIC->arithProfile();
+    ArithProfile* arithProfile = negIC->arithProfile();
     ASSERT(arithProfile);
-    arithProfile->observeArg(operand);
+    arithProfile->observeLHS(operand);
     negIC->generateOutOfLine(exec->codeBlock(), operationArithNegateProfiled);
 
 #if ENABLE(MATH_IC_STATS)
@@ -2838,8 +2838,8 @@
 
     JSValue operand = JSValue::decode(encodedOperand);
 
-    if (UnaryArithProfile* arithProfile = negIC->arithProfile())
-        arithProfile->observeArg(operand);
+    if (ArithProfile* arithProfile = negIC->arithProfile())
+        arithProfile->observeLHS(operand);
     negIC->generateOutOfLine(exec->codeBlock(), operationArithNegate);
 
 #if ENABLE(MATH_IC_STATS)
@@ -2865,7 +2865,7 @@
     return JSValue::encode(jsSub(exec, op1, op2));
 }
 
-ALWAYS_INLINE static EncodedJSValue profiledSub(VM& vm, ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true)
+ALWAYS_INLINE static EncodedJSValue profiledSub(VM& vm, ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true)
 {
     auto scope = DECLARE_THROW_SCOPE(vm);
 
@@ -2888,7 +2888,7 @@
     return unprofiledSub(exec, encodedOp1, encodedOp2);
 }
 
-EncodedJSValue JIT_OPERATION operationValueSubProfiled(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile* arithProfile)
+EncodedJSValue JIT_OPERATION operationValueSubProfiled(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)
 {
     ASSERT(arithProfile);
 
@@ -2904,7 +2904,7 @@
     NativeCallFrameTracer tracer(vm, exec);
 
     auto nonOptimizeVariant = operationValueSubNoOptimize;
-    if (BinaryArithProfile* arithProfile = subIC->arithProfile())
+    if (ArithProfile* arithProfile = subIC->arithProfile())
         arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
     subIC->generateOutOfLine(exec->codeBlock(), nonOptimizeVariant);
 
@@ -2928,7 +2928,7 @@
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
 
-    BinaryArithProfile* arithProfile = subIC->arithProfile();
+    ArithProfile* arithProfile = subIC->arithProfile();
     ASSERT(arithProfile);
     arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
     auto nonOptimizeVariant = operationValueSubProfiledNoOptimize;
@@ -2946,7 +2946,7 @@
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
 
-    BinaryArithProfile* arithProfile = subIC->arithProfile();
+    ArithProfile* arithProfile = subIC->arithProfile();
     ASSERT(arithProfile);
     return profiledSub(vm, exec, encodedOp1, encodedOp2, *arithProfile);
 }
diff --git a/Source/JavaScriptCore/jit/JITOperations.h b/Source/JavaScriptCore/jit/JITOperations.h
index 3b6aaf0..9db6734 100644
--- a/Source/JavaScriptCore/jit/JITOperations.h
+++ b/Source/JavaScriptCore/jit/JITOperations.h
@@ -38,8 +38,6 @@
     
 class ArrayAllocationProfile;
 class ArrayProfile;
-class UnaryArithProfile;
-class BinaryArithProfile;
 class Butterfly;
 class CallFrame;
 class CallLinkInfo;
@@ -66,6 +64,7 @@
 struct ByValInfo;
 struct InlineCallFrame;
 struct Instruction;
+struct ArithProfile;
 
 using ExecState = CallFrame;
 
@@ -80,7 +79,7 @@
     A: JSArray*
     Aap: ArrayAllocationProfile*
     Ap: ArrayProfile*
-    Arp: BinaryArithProfile*
+    Arp: ArithProfile*
     B: Butterfly*
     By: ByValInfo*
     C: JSCell*
@@ -146,13 +145,13 @@
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJC)(ExecState*, EncodedJSValue, JSCell*);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJA)(ExecState*, EncodedJSValue, JSArray*);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EAPZ)(ExecState*, JSArray*, void*, int32_t);
-typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJArp)(ExecState*, EncodedJSValue, BinaryArithProfile*);
+typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJArp)(ExecState*, EncodedJSValue, ArithProfile*);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJI)(ExecState*, EncodedJSValue, UniquedStringImpl*);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJ)(ExecState*, EncodedJSValue, EncodedJSValue);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJJ)(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJJJ)(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue, EncodedJSValue);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJAp)(ExecState*, EncodedJSValue, EncodedJSValue, ArrayProfile*);
-typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJArp)(ExecState*, EncodedJSValue, EncodedJSValue, BinaryArithProfile*);
+typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJArp)(ExecState*, EncodedJSValue, EncodedJSValue, ArithProfile*);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJBy)(ExecState*, EncodedJSValue, EncodedJSValue, ByValInfo*);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJMic)(ExecState*, EncodedJSValue, EncodedJSValue, void*);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJMic)(ExecState*, EncodedJSValue, void*);
@@ -483,7 +482,7 @@
 int32_t JIT_OPERATION operationInstanceOfCustom(ExecState*, EncodedJSValue encodedValue, JSObject* constructor, EncodedJSValue encodedHasInstance) WTF_INTERNAL;
 
 EncodedJSValue JIT_OPERATION operationValueAdd(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationValueAddProfiled(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationValueAddProfiled(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationValueAddProfiledOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationValueAddProfiledNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationValueAddOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC*) WTF_INTERNAL;
@@ -493,13 +492,13 @@
 EncodedJSValue JIT_OPERATION operationValueMulNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationValueMulProfiledOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationValueMulProfiledNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC*) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationValueMulProfiled(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationValueMulProfiled(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationArithNegate(ExecState*, EncodedJSValue operand);
-EncodedJSValue JIT_OPERATION operationArithNegateProfiled(ExecState*, EncodedJSValue operand, UnaryArithProfile*);
+EncodedJSValue JIT_OPERATION operationArithNegateProfiled(ExecState*, EncodedJSValue operand, ArithProfile*);
 EncodedJSValue JIT_OPERATION operationArithNegateProfiledOptimize(ExecState*, EncodedJSValue encodedOperand, JITNegIC*);
 EncodedJSValue JIT_OPERATION operationArithNegateOptimize(ExecState*, EncodedJSValue encodedOperand, JITNegIC*);
 EncodedJSValue JIT_OPERATION operationValueSub(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationValueSubProfiled(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BinaryArithProfile*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationValueSubProfiled(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationValueSubOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationValueSubNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationValueSubProfiledOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC*) WTF_INTERNAL;
diff --git a/Source/JavaScriptCore/jit/JITSubGenerator.cpp b/Source/JavaScriptCore/jit/JITSubGenerator.cpp
index 7b1a8b8..795c275 100644
--- a/Source/JavaScriptCore/jit/JITSubGenerator.cpp
+++ b/Source/JavaScriptCore/jit/JITSubGenerator.cpp
@@ -33,7 +33,7 @@
 
 namespace JSC {
 
-JITMathICInlineResult JITSubGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const BinaryArithProfile* arithProfile)
+JITMathICInlineResult JITSubGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const ArithProfile* arithProfile)
 {
     // We default to speculating int32.
     ObservedType lhs = ObservedType().withInt32();
@@ -78,7 +78,7 @@
     return JITMathICInlineResult::GenerateFullSnippet;
 }
 
-bool JITSubGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const BinaryArithProfile* arithProfile, bool shouldEmitProfiling)
+bool JITSubGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile* arithProfile, bool shouldEmitProfiling)
 {
     ASSERT(m_scratchGPR != InvalidGPRReg);
     ASSERT(m_scratchGPR != m_left.payloadGPR());
diff --git a/Source/JavaScriptCore/jit/JITSubGenerator.h b/Source/JavaScriptCore/jit/JITSubGenerator.h
index 3491a83..561f633 100644
--- a/Source/JavaScriptCore/jit/JITSubGenerator.h
+++ b/Source/JavaScriptCore/jit/JITSubGenerator.h
@@ -53,8 +53,8 @@
         , m_scratchFPR(scratchFPR)
     { }
 
-    JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const BinaryArithProfile*);
-    bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const BinaryArithProfile*, bool shouldEmitProfiling);
+    JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const ArithProfile*);
+    bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile*, bool shouldEmitProfiling);
 
     static bool isLeftOperandValidConstant(SnippetOperand) { return false; }
     static bool isRightOperandValidConstant(SnippetOperand) { return false; }
diff --git a/Source/JavaScriptCore/llint/LLIntData.cpp b/Source/JavaScriptCore/llint/LLIntData.cpp
index c0341c9..bda308c 100644
--- a/Source/JavaScriptCore/llint/LLIntData.cpp
+++ b/Source/JavaScriptCore/llint/LLIntData.cpp
@@ -135,49 +135,36 @@
 #endif
 
     {
-        UnaryArithProfile arithProfile;
-        arithProfile.argSawInt32();
-        ASSERT(arithProfile.bits() == UnaryArithProfile::observedIntBits());
-        ASSERT(arithProfile.argObservedType().isOnlyInt32());
-    }
-    {
-        UnaryArithProfile arithProfile;
-        arithProfile.argSawNumber();
-        ASSERT(arithProfile.bits() == UnaryArithProfile::observedNumberBits());
-        ASSERT(arithProfile.argObservedType().isOnlyNumber());
-    }
-
-    {
-        BinaryArithProfile arithProfile;
+        ArithProfile arithProfile;
         arithProfile.lhsSawInt32();
         arithProfile.rhsSawInt32();
-        ASSERT(arithProfile.bits() == BinaryArithProfile::observedIntIntBits());
-        ASSERT(arithProfile.lhsObservedType().isOnlyInt32());
-        ASSERT(arithProfile.rhsObservedType().isOnlyInt32());
+        ASSERT(arithProfile.bits() == ArithProfile::observedBinaryIntInt().bits());
+        STATIC_ASSERT(ArithProfile::observedBinaryIntInt().lhsObservedType().isOnlyInt32());
+        STATIC_ASSERT(ArithProfile::observedBinaryIntInt().rhsObservedType().isOnlyInt32());
     }
     {
-        BinaryArithProfile arithProfile;
+        ArithProfile arithProfile;
         arithProfile.lhsSawNumber();
         arithProfile.rhsSawInt32();
-        ASSERT(arithProfile.bits() == BinaryArithProfile::observedNumberIntBits());
-        ASSERT(arithProfile.lhsObservedType().isOnlyNumber());
-        ASSERT(arithProfile.rhsObservedType().isOnlyInt32());
+        ASSERT(arithProfile.bits() == ArithProfile::observedBinaryNumberInt().bits());
+        STATIC_ASSERT(ArithProfile::observedBinaryNumberInt().lhsObservedType().isOnlyNumber());
+        STATIC_ASSERT(ArithProfile::observedBinaryNumberInt().rhsObservedType().isOnlyInt32());
     }
     {
-        BinaryArithProfile arithProfile;
+        ArithProfile arithProfile;
         arithProfile.lhsSawNumber();
         arithProfile.rhsSawNumber();
-        ASSERT(arithProfile.bits() == BinaryArithProfile::observedNumberNumberBits());
-        ASSERT(arithProfile.lhsObservedType().isOnlyNumber());
-        ASSERT(arithProfile.rhsObservedType().isOnlyNumber());
+        ASSERT(arithProfile.bits() == ArithProfile::observedBinaryNumberNumber().bits());
+        STATIC_ASSERT(ArithProfile::observedBinaryNumberNumber().lhsObservedType().isOnlyNumber());
+        STATIC_ASSERT(ArithProfile::observedBinaryNumberNumber().rhsObservedType().isOnlyNumber());
     }
     {
-        BinaryArithProfile arithProfile;
+        ArithProfile arithProfile;
         arithProfile.lhsSawInt32();
         arithProfile.rhsSawNumber();
-        ASSERT(arithProfile.bits() == BinaryArithProfile::observedIntNumberBits());
-        ASSERT(arithProfile.lhsObservedType().isOnlyInt32());
-        ASSERT(arithProfile.rhsObservedType().isOnlyNumber());
+        ASSERT(arithProfile.bits() == ArithProfile::observedBinaryIntNumber().bits());
+        STATIC_ASSERT(ArithProfile::observedBinaryIntNumber().lhsObservedType().isOnlyInt32());
+        STATIC_ASSERT(ArithProfile::observedBinaryIntNumber().rhsObservedType().isOnlyNumber());
     }
 }
 IGNORE_WARNINGS_END
diff --git a/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp b/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp
index f5d9177..a25f984 100644
--- a/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp
+++ b/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp
@@ -86,7 +86,7 @@
 
 const int64_t* LLIntOffsetsExtractor::dummy()
 {
-// This is a file generated by offlineasm/generate_offset_extractor.rb, and contains code
+// This is a file generated by offlineasm/generate_offsets_extractor.rb, and contains code
 // to create a table of offsets, sizes, and a header identifying what combination of
 // Platform.h macros we have set. We include it inside of a method on LLIntOffsetsExtractor
 // because the fields whose offsets we're extracting are mostly private. So we make their
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
index 6fd1698..c3d17d8 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
@@ -240,15 +240,13 @@
 # ShadowChicken data
 const ShadowChickenTailMarker = constexpr ShadowChicken::Packet::tailMarkerValue
 
-# UnaryArithProfile data
-const ArithProfileInt = constexpr (UnaryArithProfile::observedIntBits())
-const ArithProfileNumber = constexpr (UnaryArithProfile::observedNumberBits())
-
-# BinaryArithProfile data
-const ArithProfileIntInt = constexpr (BinaryArithProfile::observedIntIntBits())
-const ArithProfileNumberInt = constexpr (BinaryArithProfile::observedNumberIntBits())
-const ArithProfileIntNumber = constexpr (BinaryArithProfile::observedIntNumberBits())
-const ArithProfileNumberNumber = constexpr (BinaryArithProfile::observedNumberNumberBits())
+# ArithProfile data
+const ArithProfileInt = constexpr (ArithProfile::observedUnaryInt().bits())
+const ArithProfileNumber = constexpr (ArithProfile::observedUnaryNumber().bits())
+const ArithProfileIntInt = constexpr (ArithProfile::observedBinaryIntInt().bits())
+const ArithProfileNumberInt = constexpr (ArithProfile::observedBinaryNumberInt().bits())
+const ArithProfileIntNumber = constexpr (ArithProfile::observedBinaryIntNumber().bits())
+const ArithProfileNumberNumber = constexpr (ArithProfile::observedBinaryNumberNumber().bits())
 
 # Pointer Tags
 const BytecodePtrTag = constexpr BytecodePtrTag
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
index 590bc7e..30435c4 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
@@ -1004,7 +1004,7 @@
 llintOpWithMetadata(op_negate, OpNegate, macro (size, get, dispatch, metadata, return)
 
     macro arithProfile(type)
-        ori type, OpNegate::Metadata::m_arithProfile + BinaryArithProfile::m_bits[t5]
+        ori type, OpNegate::Metadata::m_arithProfile + ArithProfile::m_bits[t5]
     end
 
     metadata(t5, t0)
@@ -1030,7 +1030,7 @@
 macro binaryOpCustomStore(opcodeName, opcodeStruct, integerOperationAndStore, doubleOperation)
     llintOpWithMetadata(op_%opcodeName%, opcodeStruct, macro (size, get, dispatch, metadata, return)
         macro arithProfile(type)
-            ori type, %opcodeStruct%::Metadata::m_arithProfile + BinaryArithProfile::m_bits[t5]
+            ori type, %opcodeStruct%::Metadata::m_arithProfile + ArithProfile::m_bits[t5]
         end
 
         metadata(t5, t2)
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
index 059b5a3..b2fb551 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
@@ -976,19 +976,19 @@
     get(m_operand, t0)
     loadConstantOrVariable(size, t0, t3)
     metadata(t1, t2)
-    loadi OpNegate::Metadata::m_arithProfile + BinaryArithProfile::m_bits[t1], t2
+    loadi OpNegate::Metadata::m_arithProfile + ArithProfile::m_bits[t1], t2
     bqb t3, numberTag, .opNegateNotInt
     btiz t3, 0x7fffffff, .opNegateSlow
     negi t3
     orq numberTag, t3
     ori ArithProfileInt, t2
-    storei t2, OpNegate::Metadata::m_arithProfile + BinaryArithProfile::m_bits[t1]
+    storei t2, OpNegate::Metadata::m_arithProfile + ArithProfile::m_bits[t1]
     return(t3)
 .opNegateNotInt:
     btqz t3, numberTag, .opNegateSlow
     xorq 0x8000000000000000, t3
     ori ArithProfileNumber, t2
-    storei t2, OpNegate::Metadata::m_arithProfile + BinaryArithProfile::m_bits[t1]
+    storei t2, OpNegate::Metadata::m_arithProfile + ArithProfile::m_bits[t1]
     return(t3)
 
 .opNegateSlow:
@@ -1002,7 +1002,7 @@
         metadata(t5, t0)
 
         macro profile(type)
-            ori type, %opcodeStruct%::Metadata::m_arithProfile + BinaryArithProfile::m_bits[t5]
+            ori type, %opcodeStruct%::Metadata::m_arithProfile + ArithProfile::m_bits[t5]
         end
 
         get(m_rhs, t0)
diff --git a/Source/JavaScriptCore/parser/ResultType.h b/Source/JavaScriptCore/parser/ResultType.h
index 5622f28..9b3d0d7 100644
--- a/Source/JavaScriptCore/parser/ResultType.h
+++ b/Source/JavaScriptCore/parser/ResultType.h
@@ -48,10 +48,6 @@
         static constexpr int numBitsNeeded = 7;
         static_assert((TypeBits & ((1 << numBitsNeeded) - 1)) == TypeBits, "This is necessary for correctness.");
 
-        constexpr explicit ResultType()
-            : ResultType(unknownType())
-        {
-        }
         constexpr explicit ResultType(Type type)
             : m_bits(type)
         {
diff --git a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
index 340b900..924f7e5 100644
--- a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
+++ b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
@@ -487,8 +487,8 @@
 #if ENABLE(JIT)
 static void updateArithProfileForUnaryArithOp(OpNegate::Metadata& metadata, JSValue result, JSValue operand)
 {
-    UnaryArithProfile& profile = metadata.m_arithProfile;
-    profile.observeArg(operand);
+    ArithProfile& profile = metadata.m_arithProfile;
+    profile.observeLHS(operand);
     ASSERT(result.isNumber() || result.isBigInt());
     if (result.isNumber()) {
         if (!result.isInt32()) {
@@ -546,7 +546,7 @@
 static void updateArithProfileForBinaryArithOp(ExecState* exec, const Instruction* pc, JSValue result, JSValue left, JSValue right)
 {
     CodeBlock* codeBlock = exec->codeBlock();
-    BinaryArithProfile& profile = *codeBlock->binaryArithProfileForPC(pc);
+    ArithProfile& profile = *codeBlock->arithProfileForPC(pc);
 
     if (result.isNumber()) {
         if (!result.isInt32()) {
@@ -607,7 +607,7 @@
     JSValue v1 = GET_C(bytecode.m_lhs).jsValue();
     JSValue v2 = GET_C(bytecode.m_rhs).jsValue();
 
-    BinaryArithProfile& arithProfile = *exec->codeBlock()->binaryArithProfileForPC(pc);
+    ArithProfile& arithProfile = *exec->codeBlock()->arithProfileForPC(pc);
     arithProfile.observeLHSAndRHS(v1, v2);
 
     JSValue result = jsAdd(exec, v1, v2);