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