Title: [237220] trunk/Source/_javascript_Core
Revision
237220
Author
yusukesuz...@slowstart.org
Date
2018-10-17 08:48:57 -0700 (Wed, 17 Oct 2018)

Log Message

[JSC] More aggressively use `constexpr` in LowLevelInterpreter.asm for constant values
https://bugs.webkit.org/show_bug.cgi?id=190659

Reviewed by Keith Miller.

Asking the actual constant value to the JSC binary is always the best way to get the correct value.
The value is correctly updated once the original value is changed. We would like to encourage this
approach more in LowLevelInterpreter.asm.

This patch expands the coverage of this approach. We make ObservedType, ResultType, and ArithProfile
constexpr-friendly to produce the magic value used in LowLevelInterpreter.asm at compiling time.
This change allows us to easily extend ArithProfile in the future to adopt BigInt efficiently.

We additionally use `constexpr` for several constant values in LowLevelInterpreter.asm.

* assembler/MaxFrameExtentForSlowPathCall.h:
Use this value in LowLevelInterpreter.asm directly. We also make them constexpr. And we add CPU(ARM64E).

* bytecode/ArithProfile.h:
(JSC::ObservedType::ObservedType):
(JSC::ObservedType::sawInt32 const):
(JSC::ObservedType::isOnlyInt32 const):
(JSC::ObservedType::sawNumber const):
(JSC::ObservedType::isOnlyNumber const):
(JSC::ObservedType::sawNonNumber const):
(JSC::ObservedType::isOnlyNonNumber const):
(JSC::ObservedType::isEmpty const):
(JSC::ObservedType::bits const):
(JSC::ObservedType::withInt32 const):
(JSC::ObservedType::withNumber const):
(JSC::ObservedType::withNonNumber const):
(JSC::ObservedType::withoutNonNumber const):
(JSC::ObservedType::operator== const):
(JSC::ArithProfile::ArithProfile):
(JSC::ArithProfile::fromInt):
(JSC::ArithProfile::observedUnaryInt):
(JSC::ArithProfile::observedUnaryNumber):
(JSC::ArithProfile::observedBinaryIntInt):
(JSC::ArithProfile::observedBinaryNumberInt):
(JSC::ArithProfile::observedBinaryIntNumber):
(JSC::ArithProfile::observedBinaryNumberNumber):
(JSC::ArithProfile::lhsObservedType const):
(JSC::ArithProfile::rhsObservedType const):
(JSC::ArithProfile::bits const):
Make ObservedType and ArithProfile constexpr-friendly.

* llint/LLIntData.cpp:
(JSC::LLInt::Data::performAssertions):
Make several ASSERTs to STATIC_ASSERTs. Remove some unnecessary checks.
* llint/LLIntOffsetsExtractor.cpp:
* llint/LowLevelInterpreter.asm:
Remove unused constant values. Use constexpr more and more aggressively.

* parser/ResultType.h:
(JSC::ResultType::ResultType):
(JSC::ResultType::isInt32 const):
(JSC::ResultType::definitelyIsNumber const):
(JSC::ResultType::definitelyIsString const):
(JSC::ResultType::definitelyIsBoolean const):
(JSC::ResultType::definitelyIsBigInt const):
(JSC::ResultType::mightBeNumber const):
(JSC::ResultType::isNotNumber const):
(JSC::ResultType::mightBeBigInt const):
(JSC::ResultType::isNotBigInt const):
(JSC::ResultType::nullType):
(JSC::ResultType::booleanType):
(JSC::ResultType::numberType):
(JSC::ResultType::numberTypeIsInt32):
(JSC::ResultType::stringOrNumberType):
(JSC::ResultType::addResultType):
(JSC::ResultType::stringType):
(JSC::ResultType::bigIntType):
(JSC::ResultType::unknownType):
(JSC::ResultType::forAdd):
(JSC::ResultType::forLogicalOp):
(JSC::ResultType::forBitOp):
(JSC::ResultType::bits const):
Make ResultType constexpr-friendly.

* runtime/JSCJSValue.h:
Use offsetof instead of OBJECT_OFFSETOF. It is OK since EncodedValueDescriptor is POD.
This change makes TagOffset and PayloadOffset macros constexpr-friendly while OBJECT_OFFSETOF
cannot be used in constexpr since it uses reinterpret_cast.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (237219 => 237220)


--- trunk/Source/_javascript_Core/ChangeLog	2018-10-17 14:10:44 UTC (rev 237219)
+++ trunk/Source/_javascript_Core/ChangeLog	2018-10-17 15:48:57 UTC (rev 237220)
@@ -1,3 +1,89 @@
+2018-10-17  Yusuke Suzuki  <yusukesuz...@slowstart.org>
+
+        [JSC] More aggressively use `constexpr` in LowLevelInterpreter.asm for constant values
+        https://bugs.webkit.org/show_bug.cgi?id=190659
+
+        Reviewed by Keith Miller.
+
+        Asking the actual constant value to the JSC binary is always the best way to get the correct value.
+        The value is correctly updated once the original value is changed. We would like to encourage this
+        approach more in LowLevelInterpreter.asm.
+
+        This patch expands the coverage of this approach. We make ObservedType, ResultType, and ArithProfile
+        constexpr-friendly to produce the magic value used in LowLevelInterpreter.asm at compiling time.
+        This change allows us to easily extend ArithProfile in the future to adopt BigInt efficiently.
+
+        We additionally use `constexpr` for several constant values in LowLevelInterpreter.asm.
+
+        * assembler/MaxFrameExtentForSlowPathCall.h:
+        Use this value in LowLevelInterpreter.asm directly. We also make them constexpr. And we add CPU(ARM64E).
+
+        * bytecode/ArithProfile.h:
+        (JSC::ObservedType::ObservedType):
+        (JSC::ObservedType::sawInt32 const):
+        (JSC::ObservedType::isOnlyInt32 const):
+        (JSC::ObservedType::sawNumber const):
+        (JSC::ObservedType::isOnlyNumber const):
+        (JSC::ObservedType::sawNonNumber const):
+        (JSC::ObservedType::isOnlyNonNumber const):
+        (JSC::ObservedType::isEmpty const):
+        (JSC::ObservedType::bits const):
+        (JSC::ObservedType::withInt32 const):
+        (JSC::ObservedType::withNumber const):
+        (JSC::ObservedType::withNonNumber const):
+        (JSC::ObservedType::withoutNonNumber const):
+        (JSC::ObservedType::operator== const):
+        (JSC::ArithProfile::ArithProfile):
+        (JSC::ArithProfile::fromInt):
+        (JSC::ArithProfile::observedUnaryInt):
+        (JSC::ArithProfile::observedUnaryNumber):
+        (JSC::ArithProfile::observedBinaryIntInt):
+        (JSC::ArithProfile::observedBinaryNumberInt):
+        (JSC::ArithProfile::observedBinaryIntNumber):
+        (JSC::ArithProfile::observedBinaryNumberNumber):
+        (JSC::ArithProfile::lhsObservedType const):
+        (JSC::ArithProfile::rhsObservedType const):
+        (JSC::ArithProfile::bits const):
+        Make ObservedType and ArithProfile constexpr-friendly.
+
+        * llint/LLIntData.cpp:
+        (JSC::LLInt::Data::performAssertions):
+        Make several ASSERTs to STATIC_ASSERTs. Remove some unnecessary checks.
+        * llint/LLIntOffsetsExtractor.cpp:
+        * llint/LowLevelInterpreter.asm:
+        Remove unused constant values. Use constexpr more and more aggressively.
+
+        * parser/ResultType.h:
+        (JSC::ResultType::ResultType):
+        (JSC::ResultType::isInt32 const):
+        (JSC::ResultType::definitelyIsNumber const):
+        (JSC::ResultType::definitelyIsString const):
+        (JSC::ResultType::definitelyIsBoolean const):
+        (JSC::ResultType::definitelyIsBigInt const):
+        (JSC::ResultType::mightBeNumber const):
+        (JSC::ResultType::isNotNumber const):
+        (JSC::ResultType::mightBeBigInt const):
+        (JSC::ResultType::isNotBigInt const):
+        (JSC::ResultType::nullType):
+        (JSC::ResultType::booleanType):
+        (JSC::ResultType::numberType):
+        (JSC::ResultType::numberTypeIsInt32):
+        (JSC::ResultType::stringOrNumberType):
+        (JSC::ResultType::addResultType):
+        (JSC::ResultType::stringType):
+        (JSC::ResultType::bigIntType):
+        (JSC::ResultType::unknownType):
+        (JSC::ResultType::forAdd):
+        (JSC::ResultType::forLogicalOp):
+        (JSC::ResultType::forBitOp):
+        (JSC::ResultType::bits const):
+        Make ResultType constexpr-friendly.
+
+        * runtime/JSCJSValue.h:
+        Use offsetof instead of OBJECT_OFFSETOF. It is OK since EncodedValueDescriptor is POD.
+        This change makes TagOffset and PayloadOffset macros constexpr-friendly while OBJECT_OFFSETOF
+        cannot be used in constexpr since it uses reinterpret_cast.
+
 2018-10-17  Keith Miller  <keith_mil...@apple.com>
 
         Unreviewed revert Fujii's revert in r237214 with new WinCairo build fix.

Modified: trunk/Source/_javascript_Core/assembler/MaxFrameExtentForSlowPathCall.h (237219 => 237220)


--- trunk/Source/_javascript_Core/assembler/MaxFrameExtentForSlowPathCall.h	2018-10-17 14:10:44 UTC (rev 237219)
+++ trunk/Source/_javascript_Core/assembler/MaxFrameExtentForSlowPathCall.h	2018-10-17 15:48:57 UTC (rev 237220)
@@ -36,31 +36,31 @@
 // from JS code.
 
 #if !ENABLE(ASSEMBLER)
-static const size_t maxFrameExtentForSlowPathCall = 0;
+static constexpr size_t maxFrameExtentForSlowPathCall = 0;
 
 #elif CPU(X86_64) && OS(WINDOWS)
 // 4 args in registers, but stack space needs to be allocated for all args.
-static const size_t maxFrameExtentForSlowPathCall = 64;
+static constexpr size_t maxFrameExtentForSlowPathCall = 64;
 
 #elif CPU(X86_64)
 // All args in registers.
-static const size_t maxFrameExtentForSlowPathCall = 0;
+static constexpr size_t maxFrameExtentForSlowPathCall = 0;
 
 #elif CPU(X86)
 // 7 args on stack (28 bytes).
-static const size_t maxFrameExtentForSlowPathCall = 40;
+static constexpr size_t maxFrameExtentForSlowPathCall = 40;
 
-#elif CPU(ARM64)
+#elif CPU(ARM64) || CPU(ARM64E)
 // All args in registers.
-static const size_t maxFrameExtentForSlowPathCall = 0;
+static constexpr size_t maxFrameExtentForSlowPathCall = 0;
 
 #elif CPU(ARM)
 // First four args in registers, remaining 4 args on stack.
-static const size_t maxFrameExtentForSlowPathCall = 24;
+static constexpr size_t maxFrameExtentForSlowPathCall = 24;
 
 #elif CPU(MIPS)
 // Though args are in registers, there need to be space on the stack for all args.
-static const size_t maxFrameExtentForSlowPathCall = 40;
+static constexpr size_t maxFrameExtentForSlowPathCall = 40;
 
 #else
 #error "Unsupported CPU: need value for maxFrameExtentForSlowPathCall"
@@ -67,13 +67,13 @@
 
 #endif
 
-COMPILE_ASSERT(!(maxFrameExtentForSlowPathCall % sizeof(Register)), extent_must_be_in_multiples_of_registers);
+static_assert(!(maxFrameExtentForSlowPathCall % sizeof(Register)), "Extent must be in multiples of registers");
 
 #if ENABLE(ASSEMBLER)
 // Make sure that cfr - maxFrameExtentForSlowPathCall bytes will make the stack pointer aligned
-COMPILE_ASSERT((maxFrameExtentForSlowPathCall % 16) == 16 - sizeof(CallerFrameAndPC), extent_must_align_stack_from_callframe_pointer);
+static_assert((maxFrameExtentForSlowPathCall % 16) == 16 - sizeof(CallerFrameAndPC), "Extent must align stack from callframe pointer");
 #endif
 
-static const size_t maxFrameExtentForSlowPathCallInRegisters = maxFrameExtentForSlowPathCall / sizeof(Register);
+static constexpr size_t maxFrameExtentForSlowPathCallInRegisters = maxFrameExtentForSlowPathCall / sizeof(Register);
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/bytecode/ArithProfile.h (237219 => 237220)


--- trunk/Source/_javascript_Core/bytecode/ArithProfile.h	2018-10-17 14:10:44 UTC (rev 237219)
+++ trunk/Source/_javascript_Core/bytecode/ArithProfile.h	2018-10-17 15:48:57 UTC (rev 237220)
@@ -35,53 +35,56 @@
 class CCallHelpers;
 
 struct ObservedType {
-    ObservedType(uint8_t bits = TypeEmpty)
+    constexpr ObservedType(uint8_t bits = TypeEmpty)
         : m_bits(bits)
     { }
 
-    bool sawInt32() const { return m_bits & TypeInt32; }
-    bool isOnlyInt32() const { return m_bits == TypeInt32; }
-    bool sawNumber() const { return m_bits & TypeNumber; }
-    bool isOnlyNumber() const { return m_bits == TypeNumber; }
-    bool sawNonNumber() const { return m_bits & TypeNonNumber; }
-    bool isOnlyNonNumber() const { return m_bits == TypeNonNumber; }
-    bool isEmpty() const { return !m_bits; }
-    uint8_t bits() const { return m_bits; }
+    constexpr bool sawInt32() const { return m_bits & TypeInt32; }
+    constexpr bool isOnlyInt32() const { return m_bits == TypeInt32; }
+    constexpr bool sawNumber() const { return m_bits & TypeNumber; }
+    constexpr bool isOnlyNumber() const { return m_bits == TypeNumber; }
+    constexpr bool sawNonNumber() const { return m_bits & TypeNonNumber; }
+    constexpr bool isOnlyNonNumber() const { return m_bits == TypeNonNumber; }
+    constexpr bool isEmpty() const { return !m_bits; }
+    constexpr uint8_t bits() const { return m_bits; }
 
-    ObservedType withInt32() const { return ObservedType(m_bits | TypeInt32); }
-    ObservedType withNumber() const { return ObservedType(m_bits | TypeNumber); }
-    ObservedType withNonNumber() const { return ObservedType(m_bits | TypeNonNumber); }
-    ObservedType withoutNonNumber() const { return ObservedType(m_bits & ~TypeNonNumber); }
+    constexpr ObservedType withInt32() const { return ObservedType(m_bits | TypeInt32); }
+    constexpr ObservedType withNumber() const { return ObservedType(m_bits | TypeNumber); }
+    constexpr ObservedType withNonNumber() const { return ObservedType(m_bits | TypeNonNumber); }
+    constexpr ObservedType withoutNonNumber() const { return ObservedType(m_bits & ~TypeNonNumber); }
 
-    bool operator==(const ObservedType& other) const { return m_bits == other.m_bits; }
+    constexpr bool operator==(const ObservedType& other) const { return m_bits == other.m_bits; }
 
-    static const uint8_t TypeEmpty = 0x0;
-    static const uint8_t TypeInt32 = 0x1;
-    static const uint8_t TypeNumber = 0x02;
-    static const uint8_t TypeNonNumber = 0x04;
+    static constexpr uint8_t TypeEmpty = 0x0;
+    static constexpr uint8_t TypeInt32 = 0x1;
+    static constexpr uint8_t TypeNumber = 0x02;
+    static constexpr uint8_t TypeNonNumber = 0x04;
 
-    static const uint32_t numBitsNeeded = 3;
+    static constexpr uint32_t numBitsNeeded = 3;
 
 private:
-    uint8_t m_bits;
+    uint8_t m_bits { 0 };
 };
 
 struct ArithProfile {
 private:
-    static const uint32_t numberOfFlagBits = 5;
-    static const uint32_t rhsResultTypeShift = numberOfFlagBits;
-    static const uint32_t lhsResultTypeShift = rhsResultTypeShift + ResultType::numBitsNeeded;
-    static const uint32_t rhsObservedTypeShift = lhsResultTypeShift + ResultType::numBitsNeeded;
-    static const uint32_t lhsObservedTypeShift = rhsObservedTypeShift + ObservedType::numBitsNeeded;
+    static constexpr uint32_t numberOfFlagBits = 5;
+    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 const uint32_t clearRhsObservedTypeBitMask = static_cast<uint32_t>(~((1 << rhsObservedTypeShift) | (1 << (rhsObservedTypeShift + 1)) | (1 << (rhsObservedTypeShift + 2))));
-    static const uint32_t clearLhsObservedTypeBitMask = static_cast<uint32_t>(~((1 << lhsObservedTypeShift) | (1 << (lhsObservedTypeShift + 1)) | (1 << (lhsObservedTypeShift + 2))));
+    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 const uint32_t resultTypeMask = (1 << ResultType::numBitsNeeded) - 1;
-    static const uint32_t observedTypeMask = (1 << ObservedType::numBitsNeeded) - 1;
+    static constexpr uint32_t resultTypeMask = (1 << ResultType::numBitsNeeded) - 1;
+    static constexpr uint32_t observedTypeMask = (1 << ObservedType::numBitsNeeded) - 1;
+
+    enum class ConstantTag { Constant };
+
 public:
-    static const uint32_t specialFastPathBit = 1 << (lhsObservedTypeShift + ObservedType::numBitsNeeded);
+    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.");
@@ -88,8 +91,8 @@
     static_assert(specialFastPathBit > ~clearLhsObservedTypeBitMask, "These bits should not intersect and specialFastPathBit should be a higher bit.");
 
     ArithProfile(ResultType arg)
+        : ArithProfile(ConstantTag::Constant, arg)
     {
-        m_bits = (arg.bits() << lhsResultTypeShift);
         ASSERT(lhsResultType().bits() == arg.bits());
         ASSERT(lhsObservedType().isEmpty());
         ASSERT(rhsObservedType().isEmpty());
@@ -96,8 +99,8 @@
     }
 
     ArithProfile(ResultType lhs, ResultType rhs)
+        : ArithProfile(ConstantTag::Constant, lhs, rhs)
     {
-        m_bits = (lhs.bits() << lhsResultTypeShift) | (rhs.bits() << rhsResultTypeShift);
         ASSERT(lhsResultType().bits() == lhs.bits() && rhsResultType().bits() == rhs.bits());
         ASSERT(lhsObservedType().isEmpty());
         ASSERT(rhsObservedType().isEmpty());
@@ -104,13 +107,56 @@
     }
     ArithProfile() = default;
 
-    static ArithProfile fromInt(uint32_t bits)
+    static constexpr ArithProfile fromInt(uint32_t bits)
     {
-        ArithProfile result;
-        result.m_bits = bits;
-        return result;
+        return ArithProfile { ConstantTag::Constant, bits };
     }
 
+    static constexpr ArithProfile observedUnaryInt()
+    {
+        constexpr ObservedType observedInt32 { ObservedType().withInt32() };
+        constexpr uint32_t bits = observedInt32.bits() << lhsObservedTypeShift;
+        static_assert(bits == 0x400000, "");
+        return fromInt(bits);
+    }
+    static constexpr ArithProfile observedUnaryNumber()
+    {
+        constexpr ObservedType observedNumber { ObservedType().withNumber() };
+        constexpr uint32_t bits = observedNumber.bits() << lhsObservedTypeShift;
+        static_assert(bits == 0x800000, "");
+        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 == 0x480000, "");
+        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 == 0x880000, "");
+        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 == 0x500000, "");
+        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 == 0x900000, "");
+        return fromInt(bits);
+    }
+
     enum ObservedResults {
         NonNegZeroDouble = 1 << 0,
         NegZeroDouble    = 1 << 1,
@@ -122,8 +168,8 @@
     ResultType lhsResultType() const { return ResultType((m_bits >> lhsResultTypeShift) & resultTypeMask); }
     ResultType rhsResultType() const { return ResultType((m_bits >> rhsResultTypeShift) & resultTypeMask); }
 
-    ObservedType lhsObservedType() const { return ObservedType((m_bits >> lhsObservedTypeShift) & observedTypeMask); }
-    ObservedType rhsObservedType() const { return ObservedType((m_bits >> rhsObservedTypeShift) & observedTypeMask); }
+    constexpr ObservedType lhsObservedType() const { return ObservedType((m_bits >> lhsObservedTypeShift) & observedTypeMask); }
+    constexpr ObservedType rhsObservedType() const { return ObservedType((m_bits >> rhsObservedTypeShift) & observedTypeMask); }
     void setLhsObservedType(ObservedType type)
     {
         uint32_t bits = m_bits;
@@ -222,9 +268,24 @@
     bool shouldEmitSetNonNumber() const;
 #endif // ENABLE(JIT)
 
-    uint32_t bits() const { return m_bits; }
+    constexpr uint32_t bits() const { return m_bits; }
 
 private:
+    constexpr explicit ArithProfile(ConstantTag, uint32_t bits)
+        : m_bits(bits)
+    {
+    }
+
+    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; }
 

Modified: trunk/Source/_javascript_Core/llint/LLIntData.cpp (237219 => 237220)


--- trunk/Source/_javascript_Core/llint/LLIntData.cpp	2018-10-17 14:10:44 UTC (rev 237219)
+++ trunk/Source/_javascript_Core/llint/LLIntData.cpp	2018-10-17 15:48:57 UTC (rev 237220)
@@ -98,11 +98,11 @@
     ASSERT(CallFrame::argumentOffsetIncludingThis(0) == CallFrameSlot::thisArgument);
 
 #if CPU(BIG_ENDIAN)
-    ASSERT(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag) == 0);
-    ASSERT(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload) == 4);
+    STATIC_ASSERT(TagOffset == 0);
+    STATIC_ASSERT(PayloadOffset == 4);
 #else
-    ASSERT(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag) == 4);
-    ASSERT(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload) == 0);
+    STATIC_ASSERT(TagOffset == 4);
+    STATIC_ASSERT(PayloadOffset == 0);
 #endif
 #if USE(JSVALUE32_64)
     STATIC_ASSERT(JSValue::Int32Tag == static_cast<unsigned>(-1));
@@ -123,15 +123,6 @@
     STATIC_ASSERT(ValueUndefined == (TagBitTypeOther | TagBitUndefined));
     STATIC_ASSERT(ValueNull == TagBitTypeOther);
 #endif
-#if (CPU(X86_64) && !OS(WINDOWS)) || CPU(ARM64) || !ENABLE(ASSEMBLER)
-    STATIC_ASSERT(!maxFrameExtentForSlowPathCall);
-#elif CPU(ARM)
-    STATIC_ASSERT(maxFrameExtentForSlowPathCall == 24);
-#elif CPU(X86) || CPU(MIPS)
-    STATIC_ASSERT(maxFrameExtentForSlowPathCall == 40);
-#elif CPU(X86_64) && OS(WINDOWS)
-    STATIC_ASSERT(maxFrameExtentForSlowPathCall == 64);
-#endif
 
 #if ENABLE(C_LOOP) || USE(JSVALUE32_64)
     ASSERT(!CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters());
@@ -151,47 +142,37 @@
     ASSERT(bitwise_cast<int**>(&testVector)[0] == testVector.begin());
 #endif
 
-    ASSERT(StringImpl::s_hashFlag8BitBuffer == 8);
-
     {
-        uint32_t bits = 0x480000;
-        UNUSED_PARAM(bits);
         ArithProfile arithProfile;
         arithProfile.lhsSawInt32();
         arithProfile.rhsSawInt32();
-        ASSERT(arithProfile.bits() == bits);
-        ASSERT(ArithProfile::fromInt(bits).lhsObservedType().isOnlyInt32());
-        ASSERT(ArithProfile::fromInt(bits).rhsObservedType().isOnlyInt32());
+        ASSERT(arithProfile.bits() == ArithProfile::observedBinaryIntInt().bits());
+        STATIC_ASSERT(ArithProfile::observedBinaryIntInt().lhsObservedType().isOnlyInt32());
+        STATIC_ASSERT(ArithProfile::observedBinaryIntInt().rhsObservedType().isOnlyInt32());
     }
     {
-        uint32_t bits = 0x880000;
-        UNUSED_PARAM(bits);
         ArithProfile arithProfile;
         arithProfile.lhsSawNumber();
         arithProfile.rhsSawInt32();
-        ASSERT(arithProfile.bits() == bits);
-        ASSERT(ArithProfile::fromInt(bits).lhsObservedType().isOnlyNumber());
-        ASSERT(ArithProfile::fromInt(bits).rhsObservedType().isOnlyInt32());
+        ASSERT(arithProfile.bits() == ArithProfile::observedBinaryNumberInt().bits());
+        STATIC_ASSERT(ArithProfile::observedBinaryNumberInt().lhsObservedType().isOnlyNumber());
+        STATIC_ASSERT(ArithProfile::observedBinaryNumberInt().rhsObservedType().isOnlyInt32());
     }
     {
-        uint32_t bits = 0x900000;
-        UNUSED_PARAM(bits);
         ArithProfile arithProfile;
         arithProfile.lhsSawNumber();
         arithProfile.rhsSawNumber();
-        ASSERT(arithProfile.bits() == bits);
-        ASSERT(ArithProfile::fromInt(bits).lhsObservedType().isOnlyNumber());
-        ASSERT(ArithProfile::fromInt(bits).rhsObservedType().isOnlyNumber());
+        ASSERT(arithProfile.bits() == ArithProfile::observedBinaryNumberNumber().bits());
+        STATIC_ASSERT(ArithProfile::observedBinaryNumberNumber().lhsObservedType().isOnlyNumber());
+        STATIC_ASSERT(ArithProfile::observedBinaryNumberNumber().rhsObservedType().isOnlyNumber());
     }
     {
-        uint32_t bits = 0x500000;
-        UNUSED_PARAM(bits);
         ArithProfile arithProfile;
         arithProfile.lhsSawInt32();
         arithProfile.rhsSawNumber();
-        ASSERT(arithProfile.bits() == bits);
-        ASSERT(ArithProfile::fromInt(bits).lhsObservedType().isOnlyInt32());
-        ASSERT(ArithProfile::fromInt(bits).rhsObservedType().isOnlyNumber());
+        ASSERT(arithProfile.bits() == ArithProfile::observedBinaryIntNumber().bits());
+        STATIC_ASSERT(ArithProfile::observedBinaryIntNumber().lhsObservedType().isOnlyInt32());
+        STATIC_ASSERT(ArithProfile::observedBinaryIntNumber().rhsObservedType().isOnlyNumber());
     }
 }
 IGNORE_CLANG_WARNINGS_END

Modified: trunk/Source/_javascript_Core/llint/LLIntOffsetsExtractor.cpp (237219 => 237220)


--- trunk/Source/_javascript_Core/llint/LLIntOffsetsExtractor.cpp	2018-10-17 14:10:44 UTC (rev 237219)
+++ trunk/Source/_javascript_Core/llint/LLIntOffsetsExtractor.cpp	2018-10-17 15:48:57 UTC (rev 237220)
@@ -25,6 +25,7 @@
 
 #include "config.h"
 
+#include "ArithProfile.h"
 #include "ArrayProfile.h"
 #include "BytecodeStructs.h"
 #include "CodeBlock.h"
@@ -50,6 +51,7 @@
 #include "JumpTable.h"
 #include "LLIntOfflineAsmConfig.h"
 #include "MarkedSpace.h"
+#include "MaxFrameExtentForSlowPathCall.h"
 #include "NativeExecutable.h"
 #include "ProtoCallFrame.h"
 #include "ShadowChicken.h"

Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm (237219 => 237220)


--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm	2018-10-17 14:10:44 UTC (rev 237219)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm	2018-10-17 15:48:57 UTC (rev 237220)
@@ -154,22 +154,21 @@
 # These declarations must match interpreter/JSStack.h.
 
 const PtrSize = constexpr (sizeof(void*))
+const MachineRegisterSize = constexpr (sizeof(CPURegister))
+const SlotSize = constexpr (sizeof(Register))
 
 if JSVALUE64
     const CallFrameHeaderSlots = 5
-    const MachineRegisterSize = 8
 else
     const CallFrameHeaderSlots = 4
     const CallFrameAlignSlots = 1
-    const MachineRegisterSize = 4
 end
-const SlotSize = 8
 
 const JSLexicalEnvironment_variables = (sizeof JSLexicalEnvironment + SlotSize - 1) & ~(SlotSize - 1)
 const DirectArguments_storage = (sizeof DirectArguments + SlotSize - 1) & ~(SlotSize - 1)
 
-const StackAlignment = 16
-const StackAlignmentSlots = 2
+const StackAlignment = constexpr (stackAlignmentBytes())
+const StackAlignmentSlots = constexpr (stackAlignmentRegisters())
 const StackAlignmentMask = StackAlignment - 1
 
 const CallerFrameAndPCSize = constexpr (sizeof(CallerFrameAndPC))
@@ -185,25 +184,25 @@
 
 # Some value representation constants.
 if JSVALUE64
-    const TagBitTypeOther = 0x2
-    const TagBitBool      = 0x4
-    const TagBitUndefined = 0x8
-    const ValueEmpty      = 0x0
-    const ValueFalse      = TagBitTypeOther | TagBitBool
-    const ValueTrue       = TagBitTypeOther | TagBitBool | 1
-    const ValueUndefined  = TagBitTypeOther | TagBitUndefined
-    const ValueNull       = TagBitTypeOther
-    const TagTypeNumber   = 0xffff000000000000
-    const TagMask         = TagTypeNumber | TagBitTypeOther
+    const TagBitTypeOther = constexpr TagBitTypeOther
+    const TagBitBool      = constexpr TagBitBool
+    const TagBitUndefined = constexpr TagBitUndefined
+    const ValueEmpty      = constexpr ValueEmpty
+    const ValueFalse      = constexpr ValueFalse
+    const ValueTrue       = constexpr ValueTrue
+    const ValueUndefined  = constexpr ValueUndefined
+    const ValueNull       = constexpr ValueNull
+    const TagTypeNumber   = constexpr TagTypeNumber
+    const TagMask         = constexpr TagMask
 else
-    const Int32Tag = -1
-    const BooleanTag = -2
-    const NullTag = -3
-    const UndefinedTag = -4
-    const CellTag = -5
-    const EmptyValueTag = -6
-    const DeletedValueTag = -7
-    const LowestTag = DeletedValueTag
+    const Int32Tag = constexpr JSValue::Int32Tag
+    const BooleanTag = constexpr JSValue::BooleanTag
+    const NullTag = constexpr JSValue::NullTag
+    const UndefinedTag = constexpr JSValue::UndefinedTag
+    const CellTag = constexpr JSValue::CellTag
+    const EmptyValueTag = constexpr JSValue::EmptyValueTag
+    const DeletedValueTag = constexpr JSValue::DeletedValueTag
+    const LowestTag = constexpr JSValue::LowestTag
 end
 
 # PutByIdFlags data
@@ -223,19 +222,9 @@
 const PutByIdSecondaryTypeObjectOrOther = constexpr PutByIdSecondaryTypeObjectOrOther
 const PutByIdSecondaryTypeTop = constexpr PutByIdSecondaryTypeTop
 
-const CallOpCodeSize = 9
+const CallOpCodeSize = constexpr op_call_length
 
-if X86_64 or ARM64 or ARM64E or C_LOOP
-    const maxFrameExtentForSlowPathCall = 0
-elsif ARM or ARMv7_TRADITIONAL or ARMv7
-    const maxFrameExtentForSlowPathCall = 24
-elsif X86 or X86_WIN
-    const maxFrameExtentForSlowPathCall = 40
-elsif MIPS
-    const maxFrameExtentForSlowPathCall = 40
-elsif X86_64_WIN
-    const maxFrameExtentForSlowPathCall = 64
-end
+const maxFrameExtentForSlowPathCall = constexpr maxFrameExtentForSlowPathCall
 
 if X86_64 or X86_64_WIN or ARM64 or ARM64E
     const CalleeSaveSpaceAsVirtualRegisters = 3
@@ -255,12 +244,12 @@
 const ShadowChickenTailMarker = constexpr ShadowChicken::Packet::tailMarkerValue
 
 # ArithProfile data
-const ArithProfileInt = 0x400000
-const ArithProfileIntInt = 0x480000
-const ArithProfileNumber = 0x800000
-const ArithProfileNumberInt = 0x880000
-const ArithProfileNumberNumber = 0x900000
-const ArithProfileIntNumber = 0x500000
+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
@@ -361,13 +350,8 @@
 end
 
 # Constants for reasoning about value representation.
-if BIG_ENDIAN
-    const TagOffset = 0
-    const PayloadOffset = 4
-else
-    const TagOffset = 4
-    const PayloadOffset = 0
-end
+const TagOffset = constexpr TagOffset
+const PayloadOffset = constexpr PayloadOffset
 
 # Constant for reasoning about butterflies.
 const IsArray                  = constexpr IsArray
@@ -422,10 +406,10 @@
 const LLIntReturnPC = ArgumentCount + TagOffset
 
 # String flags.
-const HashFlags8BitBuffer = 8
+const HashFlags8BitBuffer = constexpr StringImpl::s_hashFlag8BitBuffer
 
 # Copied from PropertyOffset.h
-const firstOutOfLineOffset = 100
+const firstOutOfLineOffset = constexpr firstOutOfLineOffset
 
 # ResolveType
 const GlobalProperty = constexpr GlobalProperty
@@ -450,13 +434,6 @@
 
 const BlackThreshold = constexpr blackThreshold
 
-# Allocation constants
-if JSVALUE64
-    const JSFinalObjectSizeClassIndex = 1
-else
-    const JSFinalObjectSizeClassIndex = 3
-end
-
 # This must match wtf/Vector.h
 const VectorBufferOffset = 0
 if JSVALUE64

Modified: trunk/Source/_javascript_Core/parser/ResultType.h (237219 => 237220)


--- trunk/Source/_javascript_Core/parser/ResultType.h	2018-10-17 14:10:44 UTC (rev 237219)
+++ trunk/Source/_javascript_Core/parser/ResultType.h	2018-10-17 15:48:57 UTC (rev 237220)
@@ -32,116 +32,116 @@
         friend struct OperandTypes;
 
         using Type = uint8_t;
-        static const Type TypeInt32 = 1;
-        static const Type TypeMaybeNumber = 0x02;
-        static const Type TypeMaybeString = 0x04;
-        static const Type TypeMaybeNull   = 0x08;
-        static const Type TypeMaybeBool   = 0x10;
-        static const Type TypeMaybeBigInt = 0x20;
-        static const Type TypeMaybeOther  = 0x40;
+        static constexpr Type TypeInt32 = 1;
+        static constexpr Type TypeMaybeNumber = 0x02;
+        static constexpr Type TypeMaybeString = 0x04;
+        static constexpr Type TypeMaybeNull   = 0x08;
+        static constexpr Type TypeMaybeBool   = 0x10;
+        static constexpr Type TypeMaybeBigInt = 0x20;
+        static constexpr Type TypeMaybeOther  = 0x40;
 
-        static const Type TypeBits = TypeMaybeNumber | TypeMaybeString | TypeMaybeNull | TypeMaybeBool | TypeMaybeBigInt | TypeMaybeOther;
+        static constexpr Type TypeBits = TypeMaybeNumber | TypeMaybeString | TypeMaybeNull | TypeMaybeBool | TypeMaybeBigInt | TypeMaybeOther;
 
     public:
-        static const int numBitsNeeded = 7;
+        static constexpr int numBitsNeeded = 7;
         static_assert((TypeBits & ((1 << numBitsNeeded) - 1)) == TypeBits, "This is necessary for correctness.");
 
-        explicit ResultType(Type type)
+        constexpr explicit ResultType(Type type)
             : m_bits(type)
         {
         }
 
-        bool isInt32() const
+        constexpr bool isInt32() const
         {
             return m_bits & TypeInt32;
         }
 
-        bool definitelyIsNumber() const
+        constexpr bool definitelyIsNumber() const
         {
             return (m_bits & TypeBits) == TypeMaybeNumber;
         }
         
-        bool definitelyIsString() const
+        constexpr bool definitelyIsString() const
         {
             return (m_bits & TypeBits) == TypeMaybeString;
         }
 
-        bool definitelyIsBoolean() const
+        constexpr bool definitelyIsBoolean() const
         {
             return (m_bits & TypeBits) == TypeMaybeBool;
         }
 
-        bool definitelyIsBigInt() const
+        constexpr bool definitelyIsBigInt() const
         {
             return (m_bits & TypeBits) == TypeMaybeBigInt;
         }
 
-        bool mightBeNumber() const
+        constexpr bool mightBeNumber() const
         {
             return m_bits & TypeMaybeNumber;
         }
 
-        bool isNotNumber() const
+        constexpr bool isNotNumber() const
         {
             return !mightBeNumber();
         }
         
-        bool mightBeBigInt() const
+        constexpr bool mightBeBigInt() const
         {
             return m_bits & TypeMaybeBigInt;
         }
 
-        bool isNotBigInt() const
+        constexpr bool isNotBigInt() const
         {
             return !mightBeBigInt();
         }
         
-        static ResultType nullType()
+        static constexpr ResultType nullType()
         {
             return ResultType(TypeMaybeNull);
         }
         
-        static ResultType booleanType()
+        static constexpr ResultType booleanType()
         {
             return ResultType(TypeMaybeBool);
         }
         
-        static ResultType numberType()
+        static constexpr ResultType numberType()
         {
             return ResultType(TypeMaybeNumber);
         }
         
-        static ResultType numberTypeIsInt32()
+        static constexpr ResultType numberTypeIsInt32()
         {
             return ResultType(TypeInt32 | TypeMaybeNumber);
         }
         
-        static ResultType stringOrNumberType()
+        static constexpr ResultType stringOrNumberType()
         {
             return ResultType(TypeMaybeNumber | TypeMaybeString);
         }
         
-        static ResultType addResultType()
+        static constexpr ResultType addResultType()
         {
             return ResultType(TypeMaybeNumber | TypeMaybeString | TypeMaybeBigInt);
         }
         
-        static ResultType stringType()
+        static constexpr ResultType stringType()
         {
             return ResultType(TypeMaybeString);
         }
         
-        static ResultType bigIntType()
+        static constexpr ResultType bigIntType()
         {
             return ResultType(TypeMaybeBigInt);
         }
         
-        static ResultType unknownType()
+        static constexpr ResultType unknownType()
         {
             return ResultType(TypeBits);
         }
         
-        static ResultType forAdd(ResultType op1, ResultType op2)
+        static constexpr ResultType forAdd(ResultType op1, ResultType op2)
         {
             if (op1.definitelyIsNumber() && op2.definitelyIsNumber())
                 return numberType();
@@ -154,7 +154,7 @@
 
         // Unlike in C, a logical op produces the value of the
         // last _expression_ evaluated (and not true or false).
-        static ResultType forLogicalOp(ResultType op1, ResultType op2)
+        static constexpr ResultType forLogicalOp(ResultType op1, ResultType op2)
         {
             if (op1.definitelyIsBoolean() && op2.definitelyIsBoolean())
                 return booleanType();
@@ -167,12 +167,12 @@
             return unknownType();
         }
 
-        static ResultType forBitOp()
+        static constexpr ResultType forBitOp()
         {
             return numberTypeIsInt32();
         }
 
-        Type bits() const { return m_bits; }
+        constexpr Type bits() const { return m_bits; }
 
     private:
         Type m_bits;

Modified: trunk/Source/_javascript_Core/runtime/JSCJSValue.h (237219 => 237220)


--- trunk/Source/_javascript_Core/runtime/JSCJSValue.h	2018-10-17 14:10:44 UTC (rev 237219)
+++ trunk/Source/_javascript_Core/runtime/JSCJSValue.h	2018-10-17 15:48:57 UTC (rev 237220)
@@ -108,8 +108,8 @@
 #endif
 };
 
-#define TagOffset (OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag))
-#define PayloadOffset (OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload))
+#define TagOffset (offsetof(EncodedValueDescriptor, asBits.tag))
+#define PayloadOffset (offsetof(EncodedValueDescriptor, asBits.payload))
 
 #if USE(JSVALUE64)
 #define CellPayloadOffset 0
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to