Diff
Modified: trunk/JSTests/ChangeLog (237135 => 237136)
--- trunk/JSTests/ChangeLog 2018-10-15 19:47:03 UTC (rev 237135)
+++ trunk/JSTests/ChangeLog 2018-10-15 19:47:09 UTC (rev 237136)
@@ -1,3 +1,14 @@
+2018-10-15 Saam barati <[email protected]>
+
+ Emit fjcvtzs on ARM64E on Darwin
+ https://bugs.webkit.org/show_bug.cgi?id=184023
+
+ Reviewed by Yusuke Suzuki and Filip Pizlo.
+
+ * stress/double-to-int32-NaN.js: Added.
+ (assert):
+ (foo):
+
2018-10-15 Saam Barati <[email protected]>
JSArray::shiftCountWithArrayStorage is wrong when an array has holes
Added: trunk/JSTests/stress/double-to-int32-NaN.js (0 => 237136)
--- trunk/JSTests/stress/double-to-int32-NaN.js (rev 0)
+++ trunk/JSTests/stress/double-to-int32-NaN.js 2018-10-15 19:47:09 UTC (rev 237136)
@@ -0,0 +1,22 @@
+function assert(b) {
+ if (!b)
+ throw new Error;
+}
+
+function foo(view) {
+ let x = view.getFloat64(0);
+ return [x, x | 0];
+}
+noInline(foo);
+
+let buffer = new ArrayBuffer(8);
+let view = new DataView(buffer);
+for (let i = 0; i < 1000000; ++i) {
+ for (let i = 0; i < 8; ++i) {
+ view.setInt8(i, Math.random() * 255);
+ }
+
+ let [a, b] = foo(view);
+ if (isNaN(a))
+ assert(b === 0);
+}
Modified: trunk/Source/_javascript_Core/ChangeLog (237135 => 237136)
--- trunk/Source/_javascript_Core/ChangeLog 2018-10-15 19:47:03 UTC (rev 237135)
+++ trunk/Source/_javascript_Core/ChangeLog 2018-10-15 19:47:09 UTC (rev 237136)
@@ -1,3 +1,35 @@
+2018-10-15 Saam barati <[email protected]>
+
+ Emit fjcvtzs on ARM64E on Darwin
+ https://bugs.webkit.org/show_bug.cgi?id=184023
+
+ Reviewed by Yusuke Suzuki and Filip Pizlo.
+
+ ARMv8.3 introduced the fjcvtzs instruction which does double->int32
+ conversion using the semantics defined by _javascript_:
+ http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0801g/hko1477562192868.html
+ This patch teaches JSC to use that instruction when possible.
+
+ * assembler/ARM64Assembler.h:
+ (JSC::ARM64Assembler::fjcvtzs):
+ (JSC::ARM64Assembler::fjcvtzsInsn):
+ * assembler/MacroAssemblerARM64.cpp:
+ (JSC::MacroAssemblerARM64::collectCPUFeatures):
+ * assembler/MacroAssemblerARM64.h:
+ (JSC::MacroAssemblerARM64::supportsDoubleToInt32ConversionUsingJavaScriptSemantics):
+ (JSC::MacroAssemblerARM64::convertDoubleToInt32UsingJavaScriptSemantics):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileValueToInt32):
+ * disassembler/ARM64/A64DOpcode.cpp:
+ * disassembler/ARM64/A64DOpcode.h:
+ (JSC::ARM64Disassembler::A64DOpcode::appendInstructionName):
+ * ftl/FTLLowerDFGToB3.cpp:
+ (JSC::FTL::DFG::LowerDFGToB3::doubleToInt32):
+ * jit/JITRightShiftGenerator.cpp:
+ (JSC::JITRightShiftGenerator::generateFastPath):
+ * runtime/MathCommon.h:
+ (JSC::toInt32):
+
2018-10-15 Saam Barati <[email protected]>
JSArray::shiftCountWithArrayStorage is wrong when an array has holes
Modified: trunk/Source/_javascript_Core/assembler/ARM64Assembler.h (237135 => 237136)
--- trunk/Source/_javascript_Core/assembler/ARM64Assembler.h 2018-10-15 19:47:03 UTC (rev 237135)
+++ trunk/Source/_javascript_Core/assembler/ARM64Assembler.h 2018-10-15 19:47:09 UTC (rev 237136)
@@ -2533,6 +2533,11 @@
insn(floatingPointIntegerConversions(DATASIZE_OF(srcsize), DATASIZE_OF(dstsize), FPIntConvOp_UCVTF, rn, vd));
}
+ ALWAYS_INLINE void fjcvtzs(RegisterID rd, FPRegisterID dn)
+ {
+ insn(fjcvtzsInsn(dn, rd));
+ }
+
// Admin methods:
AssemblerLabel labelIgnoringWatchpoints()
@@ -3744,7 +3749,12 @@
{
return 0x08007c00 | size << 30 | result << 16 | fence << 15 | dst << 5 | src;
}
-
+
+ static int fjcvtzsInsn(FPRegisterID dn, RegisterID rd)
+ {
+ return 0x1e7e0000 | (dn << 5) | rd;
+ }
+
// Workaround for Cortex-A53 erratum (835769). Emit an extra nop if the
// last instruction in the buffer is a load, store or prefetch. Needed
// before 64-bit multiply-accumulate instructions.
Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.cpp (237135 => 237136)
--- trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.cpp 2018-10-15 19:47:03 UTC (rev 237135)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.cpp 2018-10-15 19:47:09 UTC (rev 237136)
@@ -533,9 +533,9 @@
void MacroAssemblerARM64::collectCPUFeatures()
{
+#if OS(LINUX)
static std::once_flag onceKey;
std::call_once(onceKey, [] {
-#if OS(LINUX)
// A register for describing ARM64 CPU features are only accessible in kernel mode.
// Thus, some kernel support is necessary to collect CPU features. In Linux, the
// kernel passes CPU feature flags in AT_HWCAP auxiliary vector which is passed
@@ -551,10 +551,12 @@
#endif
s_jscvtCheckState = (hwcaps & HWCAP_JSCVT) ? CPUIDCheckState::Set : CPUIDCheckState::Clear;
+ });
+#elif HAVE(FJCVTZS_INSTRUCTION)
+ s_jscvtCheckState = CPUIDCheckState::Set;
#else
- s_jscvtCheckState = CPUIDCheckState::Clear;
+ s_jscvtCheckState = CPUIDCheckState::Clear;
#endif
- });
}
MacroAssemblerARM64::CPUIDCheckState MacroAssemblerARM64::s_jscvtCheckState = CPUIDCheckState::NotChecked;
Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h (237135 => 237136)
--- trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h 2018-10-15 19:47:03 UTC (rev 237135)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h 2018-10-15 19:47:09 UTC (rev 237136)
@@ -3758,6 +3758,23 @@
{
m_assembler.eor<64>(dest, src, src);
}
+
+ ALWAYS_INLINE static bool supportsDoubleToInt32ConversionUsingJavaScriptSemantics()
+ {
+#if HAVE(FJCVTZS_INSTRUCTION)
+ return true;
+#else
+ if (s_jscvtCheckState == CPUIDCheckState::NotChecked)
+ collectCPUFeatures();
+
+ return s_jscvtCheckState == CPUIDCheckState::Set;
+#endif
+ }
+
+ void convertDoubleToInt32UsingJavaScriptSemantics(FPRegisterID src, RegisterID dest)
+ {
+ m_assembler.fjcvtzs(dest, src); // This zero extends.
+ }
#if ENABLE(FAST_TLS_JIT)
// This will use scratch registers if the offset is not legal.
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (237135 => 237136)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2018-10-15 19:47:03 UTC (rev 237135)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2018-10-15 19:47:09 UTC (rev 237136)
@@ -2344,11 +2344,16 @@
SpeculateDoubleOperand op1(this, node->child1());
FPRReg fpr = op1.fpr();
GPRReg gpr = result.gpr();
- JITCompiler::Jump notTruncatedToInteger = m_jit.branchTruncateDoubleToInt32(fpr, gpr, JITCompiler::BranchIfTruncateFailed);
-
- addSlowPathGenerator(slowPathCall(notTruncatedToInteger, this,
- hasSensibleDoubleToInt() ? operationToInt32SensibleSlow : operationToInt32, NeedToSpill, ExceptionCheckRequirement::CheckNotNeeded, gpr, fpr));
-
+#if CPU(ARM64)
+ if (MacroAssemblerARM64::supportsDoubleToInt32ConversionUsingJavaScriptSemantics())
+ m_jit.convertDoubleToInt32UsingJavaScriptSemantics(fpr, gpr);
+ else
+#endif
+ {
+ JITCompiler::Jump notTruncatedToInteger = m_jit.branchTruncateDoubleToInt32(fpr, gpr, JITCompiler::BranchIfTruncateFailed);
+ addSlowPathGenerator(slowPathCall(notTruncatedToInteger, this,
+ hasSensibleDoubleToInt() ? operationToInt32SensibleSlow : operationToInt32, NeedToSpill, ExceptionCheckRequirement::CheckNotNeeded, gpr, fpr));
+ }
int32Result(gpr, node);
return;
}
@@ -2395,11 +2400,17 @@
// First, if we get here we have a double encoded as a JSValue
unboxDouble(gpr, resultGpr, fpr);
+#if CPU(ARM64)
+ if (MacroAssemblerARM64::supportsDoubleToInt32ConversionUsingJavaScriptSemantics())
+ m_jit.convertDoubleToInt32UsingJavaScriptSemantics(fpr, resultGpr);
+ else
+#endif
+ {
+ silentSpillAllRegisters(resultGpr);
+ callOperation(operationToInt32, resultGpr, fpr);
+ silentFillAllRegisters();
+ }
- silentSpillAllRegisters(resultGpr);
- callOperation(operationToInt32, resultGpr, fpr);
- silentFillAllRegisters();
-
converted.append(m_jit.jump());
isInteger.link(&m_jit);
Modified: trunk/Source/_javascript_Core/disassembler/ARM64/A64DOpcode.cpp (237135 => 237136)
--- trunk/Source/_javascript_Core/disassembler/ARM64/A64DOpcode.cpp 2018-10-15 19:47:03 UTC (rev 237135)
+++ trunk/Source/_javascript_Core/disassembler/ARM64/A64DOpcode.cpp 2018-10-15 19:47:09 UTC (rev 237136)
@@ -818,7 +818,7 @@
"fcvtns", "fcvtnu", "scvtf", "ucvtf", "fcvtas", "fcvtau", "fmov", "fmov",
"fcvtps", "fcvtpu", 0, 0, 0, 0, "fmov", "fmov",
"fcvtms", "fcvtmu", 0, 0, 0, 0, 0, 0,
- "fcvtzs", "fcvtzu", 0, 0, 0, 0, 0, 0
+ "fcvtzs", "fcvtzu", 0, 0, 0, 0, "fjcvtzs", 0
};
const char* A64DOpcodeFloatingPointIntegerConversions::format()
Modified: trunk/Source/_javascript_Core/disassembler/ARM64/A64DOpcode.h (237135 => 237136)
--- trunk/Source/_javascript_Core/disassembler/ARM64/A64DOpcode.h 2018-10-15 19:47:03 UTC (rev 237135)
+++ trunk/Source/_javascript_Core/disassembler/ARM64/A64DOpcode.h 2018-10-15 19:47:09 UTC (rev 237136)
@@ -115,7 +115,7 @@
void appendInstructionName(const char* instructionName)
{
- bufferPrintf(" %-7.7s", instructionName);
+ bufferPrintf(" %-8.8s", instructionName);
}
void appendRegisterName(unsigned registerNumber, bool is64Bit = true);
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (237135 => 237136)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2018-10-15 19:47:03 UTC (rev 237135)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2018-10-15 19:47:09 UTC (rev 237136)
@@ -14427,6 +14427,18 @@
LValue doubleToInt32(LValue doubleValue)
{
+#if CPU(ARM64)
+ if (MacroAssemblerARM64::supportsDoubleToInt32ConversionUsingJavaScriptSemantics()) {
+ PatchpointValue* patchpoint = m_out.patchpoint(Int32);
+ patchpoint->append(ConstrainedValue(doubleValue, B3::ValueRep::SomeRegister));
+ patchpoint->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
+ jit.convertDoubleToInt32UsingJavaScriptSemantics(params[1].fpr(), params[0].gpr());
+ });
+ patchpoint->effects = Effects::none();
+ return patchpoint;
+ }
+#endif
+
if (hasSensibleDoubleToInt())
return sensibleDoubleToInt32(doubleValue);
Modified: trunk/Source/_javascript_Core/jit/JITRightShiftGenerator.cpp (237135 => 237136)
--- trunk/Source/_javascript_Core/jit/JITRightShiftGenerator.cpp 2018-10-15 19:47:03 UTC (rev 237135)
+++ trunk/Source/_javascript_Core/jit/JITRightShiftGenerator.cpp 2018-10-15 19:47:09 UTC (rev 237136)
@@ -70,7 +70,14 @@
m_slowPathJumpList.append(jit.branchIfNotNumber(m_left, m_scratchGPR));
jit.unboxDoubleNonDestructive(m_left, m_leftFPR, m_scratchGPR, m_scratchFPR);
- m_slowPathJumpList.append(jit.branchTruncateDoubleToInt32(m_leftFPR, m_scratchGPR));
+#if CPU(ARM64)
+ if (MacroAssemblerARM64::supportsDoubleToInt32ConversionUsingJavaScriptSemantics())
+ jit.convertDoubleToInt32UsingJavaScriptSemantics(m_leftFPR, m_scratchGPR);
+ else
+#endif
+ {
+ m_slowPathJumpList.append(jit.branchTruncateDoubleToInt32(m_leftFPR, m_scratchGPR));
+ }
if (shiftAmount) {
if (m_shiftType == SignedShift)
@@ -122,7 +129,14 @@
m_slowPathJumpList.append(jit.branchIfNotNumber(m_left, m_scratchGPR));
jit.unboxDoubleNonDestructive(m_left, m_leftFPR, m_scratchGPR, m_scratchFPR);
- m_slowPathJumpList.append(jit.branchTruncateDoubleToInt32(m_leftFPR, m_scratchGPR));
+#if CPU(ARM64)
+ if (MacroAssemblerARM64::supportsDoubleToInt32ConversionUsingJavaScriptSemantics())
+ jit.convertDoubleToInt32UsingJavaScriptSemantics(m_leftFPR, m_scratchGPR);
+ else
+#endif
+ {
+ m_slowPathJumpList.append(jit.branchTruncateDoubleToInt32(m_leftFPR, m_scratchGPR));
+ }
if (m_shiftType == SignedShift)
jit.rshift32(m_right.payloadGPR(), m_scratchGPR);
Modified: trunk/Source/_javascript_Core/runtime/MathCommon.h (237135 => 237136)
--- trunk/Source/_javascript_Core/runtime/MathCommon.h 2018-10-15 19:47:03 UTC (rev 237135)
+++ trunk/Source/_javascript_Core/runtime/MathCommon.h 2018-10-15 19:47:09 UTC (rev 237136)
@@ -139,7 +139,13 @@
ALWAYS_INLINE int32_t toInt32(double number)
{
+#if HAVE(FJCVTZS_INSTRUCTION)
+ int32_t result = 0;
+ __asm__ ("fjcvtzs %w0, %d1" : "=r" (result) : "w" (number) : "cc");
+ return result;
+#else
return toInt32Internal<ToInt32Mode::Generic>(number);
+#endif
}
// This implements ToUInt32, defined in ECMA-262 9.6.
Modified: trunk/Source/WTF/ChangeLog (237135 => 237136)
--- trunk/Source/WTF/ChangeLog 2018-10-15 19:47:03 UTC (rev 237135)
+++ trunk/Source/WTF/ChangeLog 2018-10-15 19:47:09 UTC (rev 237136)
@@ -1,3 +1,12 @@
+2018-10-15 Saam barati <[email protected]>
+
+ Emit fjcvtzs on ARM64E on Darwin
+ https://bugs.webkit.org/show_bug.cgi?id=184023
+
+ Reviewed by Yusuke Suzuki and Filip Pizlo.
+
+ * wtf/Platform.h:
+
2018-10-15 Alex Christensen <[email protected]>
Use pragma once in WTF
Modified: trunk/Source/WTF/wtf/Platform.h (237135 => 237136)
--- trunk/Source/WTF/wtf/Platform.h 2018-10-15 19:47:03 UTC (rev 237135)
+++ trunk/Source/WTF/wtf/Platform.h 2018-10-15 19:47:09 UTC (rev 237136)
@@ -1042,6 +1042,10 @@
#endif
#endif
+#if CPU(ARM64E) && OS(DARWIN)
+#define HAVE_FJCVTZS_INSTRUCTION 1
+#endif
+
#if PLATFORM(IOS_FAMILY)
#if !PLATFORM(WATCHOS) && !PLATFORM(APPLETV) && !PLATFORM(IOSMAC)
#define USE_QUICK_LOOK 1