Diff
Modified: trunk/JSTests/ChangeLog (220734 => 220735)
--- trunk/JSTests/ChangeLog 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/JSTests/ChangeLog 2017-08-15 04:18:56 UTC (rev 220735)
@@ -1,3 +1,13 @@
+2017-08-14 Keith Miller <[email protected]>
+
+ Add testing tool to lie to the DFG about profiles
+ https://bugs.webkit.org/show_bug.cgi?id=175487
+
+ Reviewed by Saam Barati.
+
+ * stress/compare-eq-incomplete-profile.js: Added.
+ (const.test.createBuiltin):
+
2017-08-14 Robin Morisset <[email protected]>
Support the with keyword in DFG
Added: trunk/JSTests/stress/compare-eq-incomplete-profile.js (0 => 220735)
--- trunk/JSTests/stress/compare-eq-incomplete-profile.js (rev 0)
+++ trunk/JSTests/stress/compare-eq-incomplete-profile.js 2017-08-15 04:18:56 UTC (rev 220735)
@@ -0,0 +1,10 @@
+const test = createBuiltin(`(function (arg) {
+ let other = @undefined;
+ @idWithProfile(other, "SpecObject");
+ return arg == other;
+})`);
+
+for (let i = 0; i < 10000; i++) {
+ test({});
+ test(null);
+}
Modified: trunk/Source/_javascript_Core/ChangeLog (220734 => 220735)
--- trunk/Source/_javascript_Core/ChangeLog 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-08-15 04:18:56 UTC (rev 220735)
@@ -1,3 +1,63 @@
+2017-08-14 Keith Miller <[email protected]>
+
+ Add testing tool to lie to the DFG about profiles
+ https://bugs.webkit.org/show_bug.cgi?id=175487
+
+ Reviewed by Saam Barati.
+
+ This patch adds a new bytecode identity_with_profile that lets
+ us lie to the DFG about what profiles it has seen as the input to
+ another bytecode. Previously, there was no reliable way to force
+ a given profile when we tired up.
+
+ * bytecode/BytecodeDumper.cpp:
+ (JSC::BytecodeDumper<Block>::dumpBytecode):
+ * bytecode/BytecodeIntrinsicRegistry.h:
+ * bytecode/BytecodeList.json:
+ * bytecode/BytecodeUseDef.h:
+ (JSC::computeUsesForBytecodeOffset):
+ (JSC::computeDefsForBytecodeOffset):
+ * bytecode/SpeculatedType.cpp:
+ (JSC::speculationFromString):
+ * bytecode/SpeculatedType.h:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitIdWithProfile):
+ * bytecompiler/BytecodeGenerator.h:
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::BytecodeIntrinsicNode::emit_intrinsic_idWithProfile):
+ * dfg/DFGAbstractInterpreterInlines.h:
+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGCapabilities.cpp:
+ (JSC::DFG::capabilityLevel):
+ * dfg/DFGClobberize.h:
+ (JSC::DFG::clobberize):
+ * dfg/DFGDoesGC.cpp:
+ (JSC::DFG::doesGC):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGMayExit.cpp:
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::getForcedPrediction):
+ * dfg/DFGNodeType.h:
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ * dfg/DFGSafeToExecute.h:
+ (JSC::DFG::safeToExecute):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGValidate.cpp:
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ * jit/JIT.h:
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_identity_with_profile):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_identity_with_profile):
+ * llint/LowLevelInterpreter.asm:
+
2017-08-14 Simon Fraser <[email protected]>
Remove Proximity Events and related code
Modified: trunk/Source/_javascript_Core/bytecode/BytecodeDumper.cpp (220734 => 220735)
--- trunk/Source/_javascript_Core/bytecode/BytecodeDumper.cpp 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeDumper.cpp 2017-08-15 04:18:56 UTC (rev 220735)
@@ -1569,6 +1569,14 @@
out.printf("%s, %d", registerName(condition).data(), line);
break;
}
+ case op_identity_with_profile: {
+ int r0 = (++it)->u.operand;
+ ++it; // Profile top half
+ ++it; // Profile bottom half
+ printLocationAndOp(out, location, it, "identity_with_profile");
+ out.printf("%s", registerName(r0).data());
+ break;
+ }
case op_unreachable: {
printLocationAndOp(out, location, it, "unreachable");
break;
Modified: trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.h (220734 => 220735)
--- trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.h 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.h 2017-08-15 04:18:56 UTC (rev 220735)
@@ -41,6 +41,7 @@
macro(argument) \
macro(argumentCount) \
macro(assert) \
+ macro(idWithProfile) \
macro(isObject) \
macro(isJSArray) \
macro(isProxyObject) \
Modified: trunk/Source/_javascript_Core/bytecode/BytecodeList.json (220734 => 220735)
--- trunk/Source/_javascript_Core/bytecode/BytecodeList.json 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeList.json 2017-08-15 04:18:56 UTC (rev 220735)
@@ -51,6 +51,7 @@
{ "name" : "op_bitxor", "length" : 5 },
{ "name" : "op_bitor", "length" : 5 },
{ "name" : "op_overrides_has_instance", "length" : 4 },
+ { "name" : "op_identity_with_profile", "length" : 4 },
{ "name" : "op_instanceof", "length" : 4 },
{ "name" : "op_instanceof_custom", "length" : 5 },
{ "name" : "op_typeof", "length" : 3 },
Modified: trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.h (220734 => 220735)
--- trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.h 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.h 2017-08-15 04:18:56 UTC (rev 220735)
@@ -60,6 +60,7 @@
case op_get_scope:
case op_to_this:
case op_check_tdz:
+ case op_identity_with_profile:
case op_profile_type:
case op_throw:
case op_end:
@@ -423,6 +424,7 @@
case op_instanceof_custom:
case op_get_by_val:
case op_typeof:
+ case op_identity_with_profile:
case op_is_empty:
case op_is_undefined:
case op_is_boolean:
Modified: trunk/Source/_javascript_Core/bytecode/SpeculatedType.cpp (220734 => 220735)
--- trunk/Source/_javascript_Core/bytecode/SpeculatedType.cpp 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/bytecode/SpeculatedType.cpp 2017-08-15 04:18:56 UTC (rev 220735)
@@ -659,5 +659,122 @@
return polluteDouble(value);
}
+SpeculatedType speculationFromString(const char* speculation)
+{
+ if (!strncmp(speculation, "SpecNone", strlen("SpecNone")))
+ return SpecNone;
+ if (!strncmp(speculation, "SpecFinalObject", strlen("SpecFinalObject")))
+ return SpecFinalObject;
+ if (!strncmp(speculation, "SpecArray", strlen("SpecArray")))
+ return SpecArray;
+ if (!strncmp(speculation, "SpecFunction", strlen("SpecFunction")))
+ return SpecFunction;
+ if (!strncmp(speculation, "SpecInt8Array", strlen("SpecInt8Array")))
+ return SpecInt8Array;
+ if (!strncmp(speculation, "SpecInt16Array", strlen("SpecInt16Array")))
+ return SpecInt16Array;
+ if (!strncmp(speculation, "SpecInt32Array", strlen("SpecInt32Array")))
+ return SpecInt32Array;
+ if (!strncmp(speculation, "SpecUint8Array", strlen("SpecUint8Array")))
+ return SpecUint8Array;
+ if (!strncmp(speculation, "SpecUint8ClampedArray", strlen("SpecUint8ClampedArray")))
+ return SpecUint8ClampedArray;
+ if (!strncmp(speculation, "SpecUint16Array", strlen("SpecUint16Array")))
+ return SpecUint16Array;
+ if (!strncmp(speculation, "SpecUint32Array", strlen("SpecUint32Array")))
+ return SpecUint32Array;
+ if (!strncmp(speculation, "SpecFloat32Array", strlen("SpecFloat32Array")))
+ return SpecFloat32Array;
+ if (!strncmp(speculation, "SpecFloat64Array", strlen("SpecFloat64Array")))
+ return SpecFloat64Array;
+ if (!strncmp(speculation, "SpecTypedArrayView", strlen("SpecTypedArrayView")))
+ return SpecTypedArrayView;
+ if (!strncmp(speculation, "SpecDirectArguments", strlen("SpecDirectArguments")))
+ return SpecDirectArguments;
+ if (!strncmp(speculation, "SpecScopedArguments", strlen("SpecScopedArguments")))
+ return SpecScopedArguments;
+ if (!strncmp(speculation, "SpecStringObject", strlen("SpecStringObject")))
+ return SpecStringObject;
+ if (!strncmp(speculation, "SpecRegExpObject", strlen("SpecRegExpObject")))
+ return SpecRegExpObject;
+ if (!strncmp(speculation, "SpecMapObject", strlen("SpecMapObject")))
+ return SpecMapObject;
+ if (!strncmp(speculation, "SpecSetObject", strlen("SpecSetObject")))
+ return SpecSetObject;
+ if (!strncmp(speculation, "SpecProxyObject", strlen("SpecProxyObject")))
+ return SpecProxyObject;
+ if (!strncmp(speculation, "SpecDerivedArray", strlen("SpecDerivedArray")))
+ return SpecDerivedArray;
+ if (!strncmp(speculation, "SpecObjectOther", strlen("SpecObjectOther")))
+ return SpecObjectOther;
+ if (!strncmp(speculation, "SpecObject", strlen("SpecObject")))
+ return SpecObject;
+ if (!strncmp(speculation, "SpecStringIdent", strlen("SpecStringIdent")))
+ return SpecStringIdent;
+ if (!strncmp(speculation, "SpecStringVar", strlen("SpecStringVar")))
+ return SpecStringVar;
+ if (!strncmp(speculation, "SpecString", strlen("SpecString")))
+ return SpecString;
+ if (!strncmp(speculation, "SpecSymbol", strlen("SpecSymbol")))
+ return SpecSymbol;
+ if (!strncmp(speculation, "SpecCellOther", strlen("SpecCellOther")))
+ return SpecCellOther;
+ if (!strncmp(speculation, "SpecCell", strlen("SpecCell")))
+ return SpecCell;
+ if (!strncmp(speculation, "SpecBoolInt32", strlen("SpecBoolInt32")))
+ return SpecBoolInt32;
+ if (!strncmp(speculation, "SpecNonBoolInt32", strlen("SpecNonBoolInt32")))
+ return SpecNonBoolInt32;
+ if (!strncmp(speculation, "SpecInt32Only", strlen("SpecInt32Only")))
+ return SpecInt32Only;
+ if (!strncmp(speculation, "SpecInt52Only", strlen("SpecInt52Only")))
+ return SpecInt52Only;
+ if (!strncmp(speculation, "SpecAnyInt", strlen("SpecAnyInt")))
+ return SpecAnyInt;
+ if (!strncmp(speculation, "SpecAnyIntAsDouble", strlen("SpecAnyIntAsDouble")))
+ return SpecAnyIntAsDouble;
+ if (!strncmp(speculation, "SpecNonIntAsDouble", strlen("SpecNonIntAsDouble")))
+ return SpecNonIntAsDouble;
+ if (!strncmp(speculation, "SpecDoubleReal", strlen("SpecDoubleReal")))
+ return SpecDoubleReal;
+ if (!strncmp(speculation, "SpecDoublePureNaN", strlen("SpecDoublePureNaN")))
+ return SpecDoublePureNaN;
+ if (!strncmp(speculation, "SpecDoubleImpureNaN", strlen("SpecDoubleImpureNaN")))
+ return SpecDoubleImpureNaN;
+ if (!strncmp(speculation, "SpecDoubleNaN", strlen("SpecDoubleNaN")))
+ return SpecDoubleNaN;
+ if (!strncmp(speculation, "SpecBytecodeDouble", strlen("SpecBytecodeDouble")))
+ return SpecBytecodeDouble;
+ if (!strncmp(speculation, "SpecFullDouble", strlen("SpecFullDouble")))
+ return SpecFullDouble;
+ if (!strncmp(speculation, "SpecBytecodeRealNumber", strlen("SpecBytecodeRealNumber")))
+ return SpecBytecodeRealNumber;
+ if (!strncmp(speculation, "SpecFullRealNumber", strlen("SpecFullRealNumber")))
+ return SpecFullRealNumber;
+ if (!strncmp(speculation, "SpecBytecodeNumber", strlen("SpecBytecodeNumber")))
+ return SpecBytecodeNumber;
+ if (!strncmp(speculation, "SpecFullNumber", strlen("SpecFullNumber")))
+ return SpecFullNumber;
+ if (!strncmp(speculation, "SpecBoolean", strlen("SpecBoolean")))
+ return SpecBoolean;
+ if (!strncmp(speculation, "SpecOther", strlen("SpecOther")))
+ return SpecOther;
+ if (!strncmp(speculation, "SpecMisc", strlen("SpecMisc")))
+ return SpecMisc;
+ if (!strncmp(speculation, "SpecHeapTop", strlen("SpecHeapTop")))
+ return SpecHeapTop;
+ if (!strncmp(speculation, "SpecPrimitive", strlen("SpecPrimitive")))
+ return SpecPrimitive;
+ if (!strncmp(speculation, "SpecEmpty", strlen("SpecEmpty")))
+ return SpecEmpty;
+ if (!strncmp(speculation, "SpecBytecodeTop", strlen("SpecBytecodeTop")))
+ return SpecBytecodeTop;
+ if (!strncmp(speculation, "SpecFullTop", strlen("SpecFullTop")))
+ return SpecFullTop;
+ if (!strncmp(speculation, "SpecCellCheck", strlen("SpecCellCheck")))
+ return SpecCellCheck;
+ RELEASE_ASSERT_NOT_REACHED();
+}
+
} // namespace JSC
Modified: trunk/Source/_javascript_Core/bytecode/SpeculatedType.h (220734 => 220735)
--- trunk/Source/_javascript_Core/bytecode/SpeculatedType.h 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/bytecode/SpeculatedType.h 2017-08-15 04:18:56 UTC (rev 220735)
@@ -498,4 +498,7 @@
SpeculatedType typeOfDoubleBinaryOp(SpeculatedType, SpeculatedType);
SpeculatedType typeOfDoubleUnaryOp(SpeculatedType);
+// This is mostly for debugging so we can fill profiles from strings.
+SpeculatedType speculationFromString(const char*);
+
} // namespace JSC
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (220734 => 220735)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2017-08-15 04:18:56 UTC (rev 220735)
@@ -2974,6 +2974,15 @@
return condition;
}
+RegisterID* BytecodeGenerator::emitIdWithProfile(RegisterID* src, SpeculatedType profile)
+{
+ emitOpcode(op_identity_with_profile);
+ instructions().append(src->index());
+ instructions().append(static_cast<uint32_t>(profile >> 32));
+ instructions().append(static_cast<uint32_t>(profile));
+ return src;
+}
+
void BytecodeGenerator::emitUnreachable()
{
emitOpcode(op_unreachable);
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (220734 => 220735)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2017-08-15 04:18:56 UTC (rev 220735)
@@ -686,6 +686,7 @@
RegisterID* emitPutByIndex(RegisterID* base, unsigned index, RegisterID* value);
RegisterID* emitAssert(RegisterID* condition, int line);
+ RegisterID* emitIdWithProfile(RegisterID* src, SpeculatedType profile);
void emitUnreachable();
void emitPutGetterById(RegisterID* base, const Identifier& property, unsigned propertyDescriptorOptions, RegisterID* getter);
Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (220734 => 220735)
--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2017-08-15 04:18:56 UTC (rev 220735)
@@ -1023,6 +1023,22 @@
return generator.moveToDestinationIfNeeded(dst, generator.emitToString(generator.tempDestination(dst), src.get()));
}
+
+RegisterID* BytecodeIntrinsicNode::emit_intrinsic_idWithProfile(BytecodeGenerator& generator, RegisterID* dst)
+{
+
+ ArgumentListNode* node = m_args->m_listNode;
+ RefPtr<RegisterID> idValue = generator.emitNode(node);
+ SpeculatedType speculation = SpecNone;
+ while (node->m_next) {
+ node = node->m_next;
+ ASSERT(node->m_expr->isString());
+ const Identifier& ident = static_cast<StringNode*>(node->m_expr)->value();
+ speculation |= speculationFromString(ident.utf8().data());
+ }
+
+ return generator.moveToDestinationIfNeeded(dst, generator.emitIdWithProfile(idValue.get(), speculation));
+}
RegisterID* BytecodeIntrinsicNode::emit_intrinsic_isJSArray(JSC::BytecodeGenerator& generator, JSC::RegisterID* dst)
{
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (220734 => 220735)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2017-08-15 04:18:56 UTC (rev 220735)
@@ -199,7 +199,8 @@
}
break;
}
-
+
+ case IdentityWithProfile:
case Identity: {
forNode(node) = forNode(node->child1());
if (forNode(node).value())
Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (220734 => 220735)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2017-08-15 04:18:56 UTC (rev 220735)
@@ -4459,6 +4459,13 @@
NEXT_OPCODE(op_overrides_has_instance);
}
+ case op_identity_with_profile: {
+ Node* src = ""
+ SpeculatedType speculation = static_cast<SpeculatedType>(currentInstruction[2].u.operand) << 32 | static_cast<SpeculatedType>(currentInstruction[3].u.operand);
+ set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(IdentityWithProfile, OpInfo(speculation), src));
+ NEXT_OPCODE(op_identity_with_profile);
+ }
+
case op_instanceof: {
Node* value = get(VirtualRegister(currentInstruction[2].u.operand));
Node* prototype = get(VirtualRegister(currentInstruction[3].u.operand));
Modified: trunk/Source/_javascript_Core/dfg/DFGCapabilities.cpp (220734 => 220735)
--- trunk/Source/_javascript_Core/dfg/DFGCapabilities.cpp 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/dfg/DFGCapabilities.cpp 2017-08-15 04:18:56 UTC (rev 220735)
@@ -135,6 +135,7 @@
case op_profile_control_flow:
case op_mov:
case op_overrides_has_instance:
+ case op_identity_with_profile:
case op_instanceof:
case op_instanceof_custom:
case op_is_empty:
Modified: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (220734 => 220735)
--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h 2017-08-15 04:18:56 UTC (rev 220735)
@@ -137,6 +137,7 @@
return;
case Identity:
+ case IdentityWithProfile:
case Phantom:
case Check:
case ExtractOSREntryLocal:
Modified: trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp (220734 => 220735)
--- trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp 2017-08-15 04:18:56 UTC (rev 220735)
@@ -49,6 +49,7 @@
case Int52Constant:
case LazyJSConstant:
case Identity:
+ case IdentityWithProfile:
case GetCallee:
case GetArgumentCountIncludingThis:
case GetRestLength:
Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (220734 => 220735)
--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2017-08-15 04:18:56 UTC (rev 220735)
@@ -1573,7 +1573,7 @@
// fixup rules for them.
DFG_CRASH(m_graph, node, "Unexpected node during fixup");
break;
-
+
case PutGlobalVariable: {
fixEdge<CellUse>(node->child1());
speculateForBarrier(node->child2());
@@ -1929,6 +1929,11 @@
break;
}
+ case IdentityWithProfile: {
+ node->clearFlags(NodeMustGenerate);
+ break;
+ }
+
#if !ASSERT_DISABLED
// Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
case SetArgument:
Modified: trunk/Source/_javascript_Core/dfg/DFGMayExit.cpp (220734 => 220735)
--- trunk/Source/_javascript_Core/dfg/DFGMayExit.cpp 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/dfg/DFGMayExit.cpp 2017-08-15 04:18:56 UTC (rev 220735)
@@ -58,6 +58,7 @@
case Phantom:
case Check:
case Identity:
+ case IdentityWithProfile:
case GetLocal:
case LoopHint:
case Phi:
Modified: trunk/Source/_javascript_Core/dfg/DFGNode.h (220734 => 220735)
--- trunk/Source/_javascript_Core/dfg/DFGNode.h 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/dfg/DFGNode.h 2017-08-15 04:18:56 UTC (rev 220735)
@@ -1535,6 +1535,12 @@
ASSERT(hasHeapPrediction());
m_opInfo2 = prediction;
}
+
+ SpeculatedType getForcedPrediction()
+ {
+ ASSERT(op() == IdentityWithProfile);
+ return m_opInfo.as<SpeculatedType>();
+ }
bool hasCellOperand()
{
Modified: trunk/Source/_javascript_Core/dfg/DFGNodeType.h (220734 => 220735)
--- trunk/Source/_javascript_Core/dfg/DFGNodeType.h 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/dfg/DFGNodeType.h 2017-08-15 04:18:56 UTC (rev 220735)
@@ -47,6 +47,8 @@
/* is to make one node alias another. CSE will later usually eliminate this node, */\
/* though it may choose not to if it would corrupt predictions (very rare). */\
macro(Identity, NodeResultJS) \
+ /* Used for debugging to force a profile to appear as anything we want. */ \
+ macro(IdentityWithProfile, NodeResultJS | NodeMustGenerate) \
\
/* Nodes for handling functions (both as call and as construct). */\
macro(ToThis, NodeResultJS) \
Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (220734 => 220735)
--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2017-08-15 04:18:56 UTC (rev 220735)
@@ -988,6 +988,11 @@
break;
}
+ case IdentityWithProfile: {
+ setPrediction(m_currentNode->getForcedPrediction());
+ break;
+ }
+
case GetLocal:
case SetLocal:
case UInt32ToNumber:
Modified: trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h (220734 => 220735)
--- trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h 2017-08-15 04:18:56 UTC (rev 220735)
@@ -143,6 +143,7 @@
case Int52Constant:
case LazyJSConstant:
case Identity:
+ case IdentityWithProfile:
case ToThis:
case CreateThis:
case GetCallee:
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (220734 => 220735)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2017-08-15 04:18:56 UTC (rev 220735)
@@ -5680,6 +5680,7 @@
case AtomicsStore:
case AtomicsSub:
case AtomicsXor:
+ case IdentityWithProfile:
DFG_CRASH(m_jit.graph(), node, "unexpected node in DFG backend");
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (220734 => 220735)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2017-08-15 04:18:56 UTC (rev 220735)
@@ -6121,6 +6121,7 @@
case PhantomCreateRest:
case PhantomSpread:
case PhantomNewArrayWithSpread:
+ case IdentityWithProfile:
DFG_CRASH(m_jit.graph(), node, "Unexpected node");
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGValidate.cpp (220734 => 220735)
--- trunk/Source/_javascript_Core/dfg/DFGValidate.cpp 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/dfg/DFGValidate.cpp 2017-08-15 04:18:56 UTC (rev 220735)
@@ -222,6 +222,7 @@
switch (node->op()) {
case Identity:
+ case IdentityWithProfile:
VALIDATE((node), canonicalResultRepresentation(node->result()) == canonicalResultRepresentation(node->child1()->result()));
break;
case SetLocal:
Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (220734 => 220735)
--- trunk/Source/_javascript_Core/jit/JIT.cpp 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp 2017-08-15 04:18:56 UTC (rev 220735)
@@ -289,6 +289,7 @@
DEFINE_OP(op_get_rest_length)
DEFINE_OP(op_check_tdz)
DEFINE_OP(op_assert)
+ DEFINE_OP(op_identity_with_profile)
DEFINE_OP(op_unreachable)
DEFINE_OP(op_debug)
DEFINE_OP(op_del_by_id)
Modified: trunk/Source/_javascript_Core/jit/JIT.h (220734 => 220735)
--- trunk/Source/_javascript_Core/jit/JIT.h 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/jit/JIT.h 2017-08-15 04:18:56 UTC (rev 220735)
@@ -488,6 +488,7 @@
void emit_op_get_rest_length(Instruction*);
void emit_op_check_tdz(Instruction*);
void emit_op_assert(Instruction*);
+ void emit_op_identity_with_profile(Instruction*);
void emit_op_unreachable(Instruction*);
void emit_op_debug(Instruction*);
void emit_op_del_by_id(Instruction*);
Modified: trunk/Source/_javascript_Core/jit/JITOpcodes.cpp (220734 => 220735)
--- trunk/Source/_javascript_Core/jit/JITOpcodes.cpp 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/jit/JITOpcodes.cpp 2017-08-15 04:18:56 UTC (rev 220735)
@@ -559,6 +559,11 @@
slowPathCall.call();
}
+void JIT::emit_op_identity_with_profile(Instruction*)
+{
+ // We don't need to do anything here...
+}
+
void JIT::emit_op_create_lexical_environment(Instruction* currentInstruction)
{
JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_create_lexical_environment);
Modified: trunk/Source/_javascript_Core/jit/JITOpcodes32_64.cpp (220734 => 220735)
--- trunk/Source/_javascript_Core/jit/JITOpcodes32_64.cpp 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/jit/JITOpcodes32_64.cpp 2017-08-15 04:18:56 UTC (rev 220735)
@@ -859,6 +859,11 @@
slowPathCall.call();
}
+void JIT::emit_op_identity_with_profile(Instruction*)
+{
+ // We don't need to do anything here...
+}
+
void JIT::emit_op_create_lexical_environment(Instruction* currentInstruction)
{
JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_create_lexical_environment);
Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm (220734 => 220735)
--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm 2017-08-15 01:49:16 UTC (rev 220734)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm 2017-08-15 04:18:56 UTC (rev 220735)
@@ -1723,6 +1723,11 @@
dispatch(constexpr op_assert_length)
+_llint_op_identity_with_profile:
+ traceExecution()
+ dispatch(constexpr op_identity_with_profile_length)
+
+
_llint_op_unreachable:
traceExecution()
callOpcodeSlowPath(_slow_path_unreachable)