Diff
Modified: releases/WebKitGTK/webkit-2.14/JSTests/ChangeLog (207058 => 207059)
--- releases/WebKitGTK/webkit-2.14/JSTests/ChangeLog 2016-10-11 07:11:40 UTC (rev 207058)
+++ releases/WebKitGTK/webkit-2.14/JSTests/ChangeLog 2016-10-11 07:14:34 UTC (rev 207059)
@@ -1,3 +1,16 @@
+2016-09-08 Saam Barati <sbar...@apple.com>
+
+ We should inline operationConvertJSValueToBoolean into JIT code
+ https://bugs.webkit.org/show_bug.cgi?id=161729
+
+ Reviewed by Filip Pizlo.
+
+ * stress/value-to-boolean.js: Added.
+ (assert):
+ (test1):
+ (test2):
+ (test3):
+
2016-09-06 Saam Barati <sbar...@apple.com>
ProxyObject's structure should not have ObjectPrototype as its prototype and it should not have special behavior for intercepting "__proto__"
Added: releases/WebKitGTK/webkit-2.14/JSTests/stress/value-to-boolean.js (0 => 207059)
--- releases/WebKitGTK/webkit-2.14/JSTests/stress/value-to-boolean.js (rev 0)
+++ releases/WebKitGTK/webkit-2.14/JSTests/stress/value-to-boolean.js 2016-10-11 07:14:34 UTC (rev 207059)
@@ -0,0 +1,65 @@
+function assert(b) {
+ if (!b)
+ throw new Error("Bad assertion")
+}
+noInline(assert);
+
+let tests = [
+ [true, true],
+ [false, false],
+ ["", false],
+ ["" + "" + "", false],
+ ["foo", true],
+ ["foo" + "bar", true],
+ [{}, true],
+ [Symbol(), true],
+ [undefined, false],
+ [null, false],
+ [0, false],
+ [-0, false],
+ [+0, false],
+ [NaN, false],
+ [10, true],
+ [10.2012, true],
+ [function() { }, true],
+ [new String("foo"), true],
+ [new String(""), true],
+ [new String, true]
+];
+
+function test1(c) {
+ return !!c;
+}
+noInline(test1);
+
+function test2(c) {
+ if (c)
+ return true;
+ return false;
+}
+noInline(test2);
+
+function test3(c) {
+ if (!c)
+ return false;
+ return true;
+}
+noInline(test3);
+
+let testFunctions = [test1, test2, test3];
+
+for (let testFunction of testFunctions) {
+ for (let i = 0; i < 10000; i++) {
+ let item = tests[i % tests.length];
+ assert(testFunction(item[0]) === item[1]);
+ }
+}
+
+let masquerader = makeMasquerader();
+for (let testFunction of testFunctions) {
+ for (let i = 0; i < 10000; i++) {
+ for (let i = 0; i < 10000; i++) {
+ assert(testFunction(masquerader) === false);
+ }
+ }
+}
Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/ChangeLog (207058 => 207059)
--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/ChangeLog 2016-10-11 07:11:40 UTC (rev 207058)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/ChangeLog 2016-10-11 07:14:34 UTC (rev 207059)
@@ -1,3 +1,43 @@
+2016-09-08 Saam Barati <sbar...@apple.com>
+
+ We should inline operationConvertJSValueToBoolean into JIT code
+ https://bugs.webkit.org/show_bug.cgi?id=161729
+
+ Reviewed by Filip Pizlo.
+
+ This patch introduces an AssemblyHelpers emitter function
+ that replaces operationConvertJSValueToBoolean. This operation
+ was showing up when I was doing performance analysis for the
+ speedometer benchmark. I saw that it was spending about 1% of
+ its time in this function. Hopefully this patch can help us speedup
+ up speedometer by a little bit.
+
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compileLogicalNot):
+ (JSC::DFG::SpeculativeJIT::emitBranch):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compileLogicalNot):
+ (JSC::DFG::SpeculativeJIT::emitBranch):
+ * jit/AssemblyHelpers.cpp:
+ (JSC::AssemblyHelpers::emitConvertValueToBoolean):
+ * jit/AssemblyHelpers.h:
+ (JSC::AssemblyHelpers::emitAllocateDestructibleObject): Deleted.
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_jfalse):
+ (JSC::JIT::emit_op_jtrue):
+ (JSC::JIT::emitSlow_op_jfalse): Deleted.
+ (JSC::JIT::emitSlow_op_jtrue): Deleted.
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_jfalse):
+ (JSC::JIT::emit_op_jtrue):
+ (JSC::JIT::emitSlow_op_jfalse): Deleted.
+ (JSC::JIT::emitSlow_op_jtrue): Deleted.
+ * jit/JITOperations.cpp:
+ * jit/JITOperations.h:
+
2016-09-08 Filip Pizlo <fpi...@apple.com>
Heap version should be 32-bit
Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (207058 => 207059)
--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2016-10-11 07:11:40 UTC (rev 207058)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2016-10-11 07:14:34 UTC (rev 207059)
@@ -434,6 +434,11 @@
fixEdge<StringUse>(node->child1());
else if (node->child1()->shouldSpeculateStringOrOther())
fixEdge<StringOrOtherUse>(node->child1());
+ else {
+ WatchpointSet* masqueradesAsUndefinedWatchpoint = m_graph.globalObjectFor(node->origin.semantic)->masqueradesAsUndefinedWatchpoint();
+ if (masqueradesAsUndefinedWatchpoint->isStillValid())
+ m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
+ }
break;
}
@@ -978,6 +983,11 @@
fixEdge<StringUse>(node->child1());
else if (node->child1()->shouldSpeculateStringOrOther())
fixEdge<StringOrOtherUse>(node->child1());
+ else {
+ WatchpointSet* masqueradesAsUndefinedWatchpoint = m_graph.globalObjectFor(node->origin.semantic)->masqueradesAsUndefinedWatchpoint();
+ if (masqueradesAsUndefinedWatchpoint->isStillValid())
+ m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
+ }
break;
}
Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (207058 => 207059)
--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2016-10-11 07:11:40 UTC (rev 207058)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2016-10-11 07:14:34 UTC (rev 207059)
@@ -1685,24 +1685,18 @@
case UntypedUse: {
JSValueOperand arg1(this, node->child1());
- GPRTemporary resultPayload(this, Reuse, arg1, PayloadWord);
- GPRReg arg1TagGPR = arg1.tagGPR();
- GPRReg arg1PayloadGPR = arg1.payloadGPR();
- JSValueRegs arg1Regs = arg1.jsValueRegs();
- GPRReg resultPayloadGPR = resultPayload.gpr();
-
- arg1.use();
+ GPRTemporary result(this);
+ GPRTemporary temp(this);
+ FPRTemporary valueFPR(this);
+ FPRTemporary tempFPR(this);
- JITCompiler::Jump slowCase = m_jit.branch32(JITCompiler::NotEqual, arg1TagGPR, TrustedImm32(JSValue::BooleanTag));
-
- m_jit.move(arg1PayloadGPR, resultPayloadGPR);
+ GPRReg resultGPR = result.gpr();
- addSlowPathGenerator(
- slowPathCall(
- slowCase, this, operationConvertJSValueToBoolean, resultPayloadGPR, arg1Regs, NeedToSpill, ExceptionCheckRequirement::CheckNotNeeded));
-
- m_jit.xor32(TrustedImm32(1), resultPayloadGPR);
- booleanResult(resultPayloadGPR, node, UseChildrenCalledExplicitly);
+ bool shouldCheckMasqueradesAsUndefined = !masqueradesAsUndefinedWatchpointIsStillValid();
+ JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->origin.semantic);
+ bool negateResult = true;
+ m_jit.emitConvertValueToBoolean(arg1.jsValueRegs(), resultGPR, temp.gpr(), valueFPR.fpr(), tempFPR.fpr(), shouldCheckMasqueradesAsUndefined, globalObject, negateResult);
+ booleanResult(resultGPR, node);
return;
}
case StringUse:
@@ -1834,30 +1828,22 @@
case UntypedUse: {
JSValueOperand value(this, node->child1());
- value.fill();
- GPRReg valueTagGPR = value.tagGPR();
- GPRReg valuePayloadGPR = value.payloadGPR();
+ FPRTemporary valueFPR(this);
+ FPRTemporary tempFPR(this);
+ GPRTemporary result(this);
+ GPRTemporary temp(this);
- GPRTemporary result(this);
+ JSValueRegs valueRegs = value.jsValueRegs();
GPRReg resultGPR = result.gpr();
use(node->child1());
-
- JITCompiler::Jump fastPath = m_jit.branch32(JITCompiler::Equal, valueTagGPR, JITCompiler::TrustedImm32(JSValue::Int32Tag));
- JITCompiler::Jump slowPath = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, JITCompiler::TrustedImm32(JSValue::BooleanTag));
- fastPath.link(&m_jit);
- branchTest32(JITCompiler::Zero, valuePayloadGPR, notTaken);
+ bool shouldCheckMasqueradesAsUndefined = !masqueradesAsUndefinedWatchpointIsStillValid();
+ JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->origin.semantic);
+ m_jit.emitConvertValueToBoolean(valueRegs, resultGPR, temp.gpr(), valueFPR.fpr(), tempFPR.fpr(), shouldCheckMasqueradesAsUndefined, globalObject);
+ branchTest32(JITCompiler::Zero, resultGPR, notTaken);
jump(taken, ForceJump);
- slowPath.link(&m_jit);
- silentSpillAllRegisters(resultGPR);
- callOperation(operationConvertJSValueToBoolean, resultGPR, value.jsValueRegs());
- silentFillAllRegisters(resultGPR);
-
- branchTest32(JITCompiler::NonZero, resultGPR, taken);
- jump(notTaken);
-
noResult(node, UseChildrenCalledExplicitly);
return;
}
Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (207058 => 207059)
--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2016-10-11 07:11:40 UTC (rev 207058)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2016-10-11 07:14:34 UTC (rev 207059)
@@ -1838,18 +1838,22 @@
GPRReg arg1GPR = arg1.gpr();
GPRReg resultGPR = result.gpr();
-
- arg1.use();
-
- m_jit.move(arg1GPR, resultGPR);
- m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), resultGPR);
- JITCompiler::Jump slowCase = m_jit.branchTest64(JITCompiler::NonZero, resultGPR, TrustedImm32(static_cast<int32_t>(~1)));
-
- addSlowPathGenerator(
- slowPathCall(slowCase, this, operationConvertJSValueToBoolean, resultGPR, arg1GPR, NeedToSpill, ExceptionCheckRequirement::CheckNotNeeded));
-
- m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueTrue)), resultGPR);
- jsValueResult(resultGPR, node, DataFormatJSBoolean, UseChildrenCalledExplicitly);
+
+ FPRTemporary valueFPR(this);
+ FPRTemporary tempFPR(this);
+
+ bool shouldCheckMasqueradesAsUndefined = !masqueradesAsUndefinedWatchpointIsStillValid();
+ JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->origin.semantic);
+ Optional<GPRTemporary> scratch;
+ GPRReg scratchGPR = InvalidGPRReg;
+ if (shouldCheckMasqueradesAsUndefined) {
+ scratch = GPRTemporary(this);
+ scratchGPR = scratch->gpr();
+ }
+ bool negateResult = true;
+ m_jit.emitConvertValueToBoolean(JSValueRegs(arg1GPR), resultGPR, scratchGPR, valueFPR.fpr(), tempFPR.fpr(), shouldCheckMasqueradesAsUndefined, globalObject, negateResult);
+ m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
+ jsValueResult(resultGPR, node, DataFormatJSBoolean);
return;
}
case StringUse:
@@ -1992,7 +1996,20 @@
value.use();
} else {
GPRTemporary result(this);
+ FPRTemporary fprValue(this);
+ FPRTemporary fprTemp(this);
+ Optional<GPRTemporary> scratch;
+
+ GPRReg scratchGPR = InvalidGPRReg;
+ bool shouldCheckMasqueradesAsUndefined = !masqueradesAsUndefinedWatchpointIsStillValid();
+ if (shouldCheckMasqueradesAsUndefined) {
+ scratch = GPRTemporary(this);
+ scratchGPR = scratch->gpr();
+ }
+
GPRReg resultGPR = result.gpr();
+ FPRReg valueFPR = fprValue.fpr();
+ FPRReg tempFPR = fprTemp.fpr();
if (node->child1()->prediction() & SpecInt32Only) {
branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(0))), notTaken);
@@ -2005,11 +2022,10 @@
}
value.use();
+
+ JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->origin.semantic);
+ m_jit.emitConvertValueToBoolean(JSValueRegs(valueGPR), resultGPR, scratchGPR, valueFPR, tempFPR, shouldCheckMasqueradesAsUndefined, globalObject);
- silentSpillAllRegisters(resultGPR);
- callOperation(operationConvertJSValueToBoolean, resultGPR, valueGPR);
- silentFillAllRegisters(resultGPR);
-
branchTest32(MacroAssembler::NonZero, resultGPR, taken);
jump(notTaken);
}
Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/AssemblyHelpers.cpp (207058 => 207059)
--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/AssemblyHelpers.cpp 2016-10-11 07:11:40 UTC (rev 207058)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/AssemblyHelpers.cpp 2016-10-11 07:14:34 UTC (rev 207059)
@@ -672,6 +672,94 @@
}
#endif // USE(JSVALUE64)
+void AssemblyHelpers::emitConvertValueToBoolean(JSValueRegs value, GPRReg result, GPRReg scratch, FPRReg valueAsFPR, FPRReg tempFPR, bool shouldCheckMasqueradesAsUndefined, JSGlobalObject* globalObject, bool negateResult)
+{
+ // Implements the following control flow structure:
+ // if (value is boolean) {
+ // result = value === true
+ // } else if (value is integer) {
+ // result = value !== 0
+ // } else if (value is double) {
+ // result = value !== 0.0 && !isNaN(value);
+ // } else if (value is cell) {
+ // if (value is string) {
+ // result = value.length() !== 0;
+ // } else {
+ // do crazy things for masquerades as undefined
+ // }
+ // } else {
+ // result = false;
+ // }
+ //
+ // if (negateResult)
+ // result = !result;
+
+ JumpList done;
+ auto notBoolean = branchIfNotBoolean(value, result);
+#if USE(JSVALUE64)
+ compare32(negateResult ? NotEqual : Equal, value.gpr(), TrustedImm32(ValueTrue), result);
+#else
+ compare32(negateResult ? Equal : NotEqual, value.payloadGPR(), TrustedImm32(0), result);
+#endif
+ done.append(jump());
+
+ notBoolean.link(this);
+#if USE(JSVALUE64)
+ auto isNotNumber = branchIfNotNumber(value.gpr());
+#else
+ ASSERT(scratch != InvalidGPRReg);
+ auto isNotNumber = branchIfNotNumber(value, scratch);
+#endif
+ auto isDouble = branchIfNotInt32(value);
+
+ // It's an int32.
+ compare32(negateResult ? Equal : NotEqual, value.payloadGPR(), TrustedImm32(0), result);
+ done.append(jump());
+
+ isDouble.link(this);
+#if USE(JSVALUE64)
+ unboxDouble(value.gpr(), result, valueAsFPR);
+#else
+ unboxDouble(value, valueAsFPR, tempFPR);
+#endif
+ auto isZeroOrNaN = branchDoubleZeroOrNaN(valueAsFPR, tempFPR);
+ move(negateResult ? TrustedImm32(0) : TrustedImm32(1), result);
+ done.append(jump());
+ isZeroOrNaN.link(this);
+ move(negateResult ? TrustedImm32(1) : TrustedImm32(0), result);
+ done.append(jump());
+
+ isNotNumber.link(this);
+ auto isNotCellAndIsNotNumberAndIsNotBoolean = branchIfNotCell(value);
+ auto isCellButNotString = branch8(NotEqual,
+ Address(value.payloadGPR(), JSCell::typeInfoTypeOffset()), TrustedImm32(StringType));
+ load32(Address(value.payloadGPR(), JSString::offsetOfLength()), result);
+ compare32(negateResult ? Equal : NotEqual, result, TrustedImm32(0), result);
+ done.append(jump());
+
+ isCellButNotString.link(this);
+ if (shouldCheckMasqueradesAsUndefined) {
+ ASSERT(scratch != InvalidGPRReg);
+ JumpList isNotMasqueradesAsUndefined;
+ isNotMasqueradesAsUndefined.append(branchTest8(Zero, Address(value.payloadGPR(), JSCell::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined)));
+ emitLoadStructure(value.payloadGPR(), result, scratch);
+ move(TrustedImmPtr(globalObject), scratch);
+ isNotMasqueradesAsUndefined.append(branchPtr(NotEqual, Address(result, Structure::globalObjectOffset()), scratch));
+ // We act like we are "undefined" here.
+ move(negateResult ? TrustedImm32(1) : TrustedImm32(0), result);
+ done.append(jump());
+ isNotMasqueradesAsUndefined.link(this);
+ }
+ move(negateResult ? TrustedImm32(0) : TrustedImm32(1), result);
+ done.append(jump());
+
+ // null or undefined.
+ isNotCellAndIsNotNumberAndIsNotBoolean.link(this);
+ move(negateResult ? TrustedImm32(1) : TrustedImm32(0), result);
+
+ done.link(this);
+}
+
} // namespace JSC
#endif // ENABLE(JIT)
Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/AssemblyHelpers.h (207058 => 207059)
--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/AssemblyHelpers.h 2016-10-11 07:11:40 UTC (rev 207058)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/AssemblyHelpers.h 2016-10-11 07:14:34 UTC (rev 207059)
@@ -1526,6 +1526,8 @@
emitStoreStructureWithTypeInfo(structure, resultGPR, scratchGPR2);
storePtr(TrustedImmPtr(0), Address(resultGPR, JSObject::butterflyOffset()));
}
+
+ void emitConvertValueToBoolean(JSValueRegs value, GPRReg result, GPRReg scratchIfShouldCheckMasqueradesAsUndefined, FPRReg, FPRReg, bool shouldCheckMasqueradesAsUndefined, JSGlobalObject*, bool negateResult = false);
template<typename ClassType>
void emitAllocateDestructibleObject(GPRReg resultGPR, Structure* structure, GPRReg scratchGPR1, GPRReg scratchGPR2, JumpList& slowPath)
Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/JIT.cpp (207058 => 207059)
--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/JIT.cpp 2016-10-11 07:11:40 UTC (rev 207058)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/JIT.cpp 2016-10-11 07:14:34 UTC (rev 207059)
@@ -447,7 +447,6 @@
DEFINE_SLOWCASE_OP(op_get_by_val)
DEFINE_SLOWCASE_OP(op_instanceof)
DEFINE_SLOWCASE_OP(op_instanceof_custom)
- DEFINE_SLOWCASE_OP(op_jfalse)
DEFINE_SLOWCASE_OP(op_jless)
DEFINE_SLOWCASE_OP(op_jlesseq)
DEFINE_SLOWCASE_OP(op_jgreater)
@@ -456,7 +455,6 @@
DEFINE_SLOWCASE_OP(op_jnlesseq)
DEFINE_SLOWCASE_OP(op_jngreater)
DEFINE_SLOWCASE_OP(op_jngreatereq)
- DEFINE_SLOWCASE_OP(op_jtrue)
DEFINE_SLOWCASE_OP(op_loop_hint)
DEFINE_SLOWCASE_OP(op_watchdog)
DEFINE_SLOWCASE_OP(op_lshift)
Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/JIT.h (207058 => 207059)
--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/JIT.h 2016-10-11 07:11:40 UTC (rev 207058)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/JIT.h 2016-10-11 07:14:34 UTC (rev 207059)
@@ -624,7 +624,6 @@
void emitSlow_op_get_argument_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_instanceof(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_instanceof_custom(Instruction*, Vector<SlowCaseEntry>::iterator&);
- void emitSlow_op_jfalse(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_jless(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_jlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_jgreater(Instruction*, Vector<SlowCaseEntry>::iterator&);
Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/JITOpcodes.cpp (207058 => 207059)
--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/JITOpcodes.cpp 2016-10-11 07:11:40 UTC (rev 207058)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/JITOpcodes.cpp 2016-10-11 07:14:34 UTC (rev 207059)
@@ -362,15 +362,16 @@
void JIT::emit_op_jfalse(Instruction* currentInstruction)
{
unsigned target = currentInstruction[2].u.operand;
- emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
- addJump(branch64(Equal, regT0, TrustedImm64(JSValue::encode(jsNumber(0)))), target);
- Jump isNonZero = emitJumpIfInt(regT0);
+ GPRReg value = regT0;
+ GPRReg result = regT1;
+ GPRReg scratch = regT2;
+ bool shouldCheckMasqueradesAsUndefined = true;
- addJump(branch64(Equal, regT0, TrustedImm64(JSValue::encode(jsBoolean(false)))), target);
- addSlowCase(branch64(NotEqual, regT0, TrustedImm64(JSValue::encode(jsBoolean(true)))));
+ emitGetVirtualRegister(currentInstruction[1].u.operand, value);
+ emitConvertValueToBoolean(JSValueRegs(value), result, scratch, fpRegT0, fpRegT1, shouldCheckMasqueradesAsUndefined, m_codeBlock->globalObject());
- isNonZero.link(this);
+ addJump(branchTest32(Zero, result), target);
}
void JIT::emit_op_jeq_null(Instruction* currentInstruction)
@@ -444,15 +445,14 @@
void JIT::emit_op_jtrue(Instruction* currentInstruction)
{
unsigned target = currentInstruction[2].u.operand;
- emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
- Jump isZero = branch64(Equal, regT0, TrustedImm64(JSValue::encode(jsNumber(0))));
- addJump(emitJumpIfInt(regT0), target);
-
- addJump(branch64(Equal, regT0, TrustedImm64(JSValue::encode(jsBoolean(true)))), target);
- addSlowCase(branch64(NotEqual, regT0, TrustedImm64(JSValue::encode(jsBoolean(false)))));
-
- isZero.link(this);
+ GPRReg value = regT0;
+ GPRReg result = regT1;
+ GPRReg scratch = regT2;
+ bool shouldCheckMasqueradesAsUndefined = true;
+ emitGetVirtualRegister(currentInstruction[1].u.operand, value);
+ emitConvertValueToBoolean(JSValueRegs(value), result, scratch, fpRegT0, fpRegT1, shouldCheckMasqueradesAsUndefined, m_codeBlock->globalObject());
+ addJump(branchTest32(NonZero, result), target);
}
void JIT::emit_op_neq(Instruction* currentInstruction)
@@ -837,20 +837,6 @@
slowPathCall.call();
}
-void JIT::emitSlow_op_jfalse(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- linkSlowCase(iter);
- callOperation(operationConvertJSValueToBoolean, regT0);
- emitJumpSlowToHot(branchTest32(Zero, returnValueGPR), currentInstruction[2].u.operand); // inverted!
-}
-
-void JIT::emitSlow_op_jtrue(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- linkSlowCase(iter);
- callOperation(operationConvertJSValueToBoolean, regT0);
- emitJumpSlowToHot(branchTest32(NonZero, returnValueGPR), currentInstruction[2].u.operand);
-}
-
void JIT::emitSlow_op_eq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
linkSlowCase(iter);
Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/JITOpcodes32_64.cpp (207058 => 207059)
--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/JITOpcodes32_64.cpp 2016-10-11 07:11:40 UTC (rev 207058)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/JITOpcodes32_64.cpp 2016-10-11 07:14:34 UTC (rev 207059)
@@ -475,31 +475,13 @@
emitLoad(cond, regT1, regT0);
- ASSERT((JSValue::BooleanTag + 1 == JSValue::Int32Tag) && !(JSValue::Int32Tag + 1));
- addSlowCase(branch32(Below, regT1, TrustedImm32(JSValue::BooleanTag)));
- addJump(branchTest32(Zero, regT0), target);
-}
+ JSValueRegs value(regT1, regT0);
+ GPRReg scratch = regT2;
+ GPRReg result = regT3;
+ bool shouldCheckMasqueradesAsUndefined = true;
+ emitConvertValueToBoolean(value, result, scratch, fpRegT0, fpRegT1, shouldCheckMasqueradesAsUndefined, m_codeBlock->globalObject());
-void JIT::emitSlow_op_jfalse(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- int cond = currentInstruction[1].u.operand;
- unsigned target = currentInstruction[2].u.operand;
-
- linkSlowCase(iter);
-
- if (supportsFloatingPoint()) {
- // regT1 contains the tag from the hot path.
- Jump notNumber = branch32(Above, regT1, TrustedImm32(JSValue::LowestTag));
-
- emitLoadDouble(cond, fpRegT0);
- emitJumpSlowToHot(branchDoubleZeroOrNaN(fpRegT0, fpRegT1), target);
- emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jfalse));
-
- notNumber.link(this);
- }
-
- callOperation(operationConvertJSValueToBoolean, regT1, regT0);
- emitJumpSlowToHot(branchTest32(Zero, returnValueGPR), target); // Inverted.
+ addJump(branchTest32(Zero, result), target);
}
void JIT::emit_op_jtrue(Instruction* currentInstruction)
@@ -508,34 +490,15 @@
unsigned target = currentInstruction[2].u.operand;
emitLoad(cond, regT1, regT0);
+ bool shouldCheckMasqueradesAsUndefined = true;
+ JSValueRegs value(regT1, regT0);
+ GPRReg scratch = regT2;
+ GPRReg result = regT3;
+ emitConvertValueToBoolean(value, result, scratch, fpRegT0, fpRegT1, shouldCheckMasqueradesAsUndefined, m_codeBlock->globalObject());
- ASSERT((JSValue::BooleanTag + 1 == JSValue::Int32Tag) && !(JSValue::Int32Tag + 1));
- addSlowCase(branch32(Below, regT1, TrustedImm32(JSValue::BooleanTag)));
- addJump(branchTest32(NonZero, regT0), target);
+ addJump(branchTest32(NonZero, result), target);
}
-void JIT::emitSlow_op_jtrue(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- int cond = currentInstruction[1].u.operand;
- unsigned target = currentInstruction[2].u.operand;
-
- linkSlowCase(iter);
-
- if (supportsFloatingPoint()) {
- // regT1 contains the tag from the hot path.
- Jump notNumber = branch32(Above, regT1, TrustedImm32(JSValue::LowestTag));
-
- emitLoadDouble(cond, fpRegT0);
- emitJumpSlowToHot(branchDoubleNonZero(fpRegT0, fpRegT1), target);
- emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jtrue));
-
- notNumber.link(this);
- }
-
- callOperation(operationConvertJSValueToBoolean, regT1, regT0);
- emitJumpSlowToHot(branchTest32(NonZero, returnValueGPR), target);
-}
-
void JIT::emit_op_jeq_null(Instruction* currentInstruction)
{
int src = ""
Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/JITOperations.cpp (207058 => 207059)
--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/JITOperations.cpp 2016-10-11 07:11:40 UTC (rev 207058)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/JITOperations.cpp 2016-10-11 07:14:34 UTC (rev 207059)
@@ -1032,14 +1032,6 @@
return jsLessEq<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
}
-size_t JIT_OPERATION operationConvertJSValueToBoolean(ExecState* exec, EncodedJSValue encodedOp)
-{
- VM* vm = &exec->vm();
- NativeCallFrameTracer tracer(vm, exec);
-
- return JSValue::decode(encodedOp).toBoolean(exec);
-}
-
size_t JIT_OPERATION operationCompareEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
{
VM* vm = &exec->vm();
Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/JITOperations.h (207058 => 207059)
--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/JITOperations.h 2016-10-11 07:11:40 UTC (rev 207058)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/jit/JITOperations.h 2016-10-11 07:14:34 UTC (rev 207059)
@@ -346,7 +346,6 @@
size_t JIT_OPERATION operationCompareLessEq(ExecState*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
size_t JIT_OPERATION operationCompareGreater(ExecState*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
size_t JIT_OPERATION operationCompareGreaterEq(ExecState*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
-size_t JIT_OPERATION operationConvertJSValueToBoolean(ExecState*, EncodedJSValue) WTF_INTERNAL;
size_t JIT_OPERATION operationCompareEq(ExecState*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
#if USE(JSVALUE64)
EncodedJSValue JIT_OPERATION operationCompareStringEq(ExecState*, JSCell* left, JSCell* right) WTF_INTERNAL;