Diff
Modified: branches/safari-605-branch/Source/_javascript_Core/ChangeLog (227129 => 227130)
--- branches/safari-605-branch/Source/_javascript_Core/ChangeLog 2018-01-18 07:24:07 UTC (rev 227129)
+++ branches/safari-605-branch/Source/_javascript_Core/ChangeLog 2018-01-18 07:24:10 UTC (rev 227130)
@@ -1,5 +1,30 @@
2018-01-17 Jason Marcell <jmarc...@apple.com>
+ Cherry-pick r227096. rdar://problem/36609546
+
+ 2018-01-17 Saam Barati <sbar...@apple.com>
+
+ Support MultiGetByOffset in the DFG
+ https://bugs.webkit.org/show_bug.cgi?id=181466
+
+ Reviewed by Keith Miller.
+
+ This seems to benefit Speedometer in my local testing. It seems like this
+ might be around a 0.5% improvement.
+
+ * dfg/DFGAbstractInterpreterInlines.h:
+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::handleGetById):
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::supportsMultiGetByOffset):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2018-01-17 Jason Marcell <jmarc...@apple.com>
+
Cherry-pick r227053. rdar://problem/36587231
2018-01-17 Saam Barati <sbar...@apple.com>
Modified: branches/safari-605-branch/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (227129 => 227130)
--- branches/safari-605-branch/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2018-01-18 07:24:07 UTC (rev 227129)
+++ branches/safari-605-branch/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2018-01-18 07:24:10 UTC (rev 227130)
@@ -2875,10 +2875,6 @@
// contradiction then there must always be a contradiction even if subsequent passes don't
// realize it. This is the case here.
- // Ordinarily you have to be careful with calling setFoundConstants()
- // because of the effect on compile times, but this node is FTL-only.
- m_state.setFoundConstants(true);
-
UniquedStringImpl* uid = m_graph.identifiers()[node->multiGetByOffsetData().identifierNumber];
AbstractValue base = forNode(node->child1());
@@ -2887,8 +2883,10 @@
for (const MultiGetByOffsetCase& getCase : node->multiGetByOffsetData().cases) {
RegisteredStructureSet set = getCase.set();
set.filter(base);
- if (set.isEmpty())
+ if (set.isEmpty()) {
+ m_state.setFoundConstants(true);
continue;
+ }
baseSet.merge(set);
switch (getCase.method().kind()) {
Modified: branches/safari-605-branch/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (227129 => 227130)
--- branches/safari-605-branch/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2018-01-18 07:24:07 UTC (rev 227129)
+++ branches/safari-605-branch/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2018-01-18 07:24:10 UTC (rev 227130)
@@ -3924,8 +3924,7 @@
}
if (getByIdStatus.numVariants() > 1) {
- if (getByIdStatus.makesCalls() || !isFTL(m_graph.m_plan.mode)
- || !Options::usePolymorphicAccessInlining()) {
+ if (getByIdStatus.makesCalls() || !m_graph.supportsMultiGetByOffset(currentCodeOrigin()) || !Options::usePolymorphicAccessInlining()) {
set(VirtualRegister(destinationOperand),
addToGraph(getById, OpInfo(identifierNumber), OpInfo(prediction), base));
return;
Modified: branches/safari-605-branch/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp (227129 => 227130)
--- branches/safari-605-branch/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp 2018-01-18 07:24:07 UTC (rev 227129)
+++ branches/safari-605-branch/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp 2018-01-18 07:24:10 UTC (rev 227130)
@@ -522,7 +522,7 @@
break;
}
- if (!isFTL(m_graph.m_plan.mode))
+ if (!m_graph.supportsMultiGetByOffset(node->origin.semantic))
break;
MultiGetByOffsetData* data = ""
Modified: branches/safari-605-branch/Source/_javascript_Core/dfg/DFGGraph.h (227129 => 227130)
--- branches/safari-605-branch/Source/_javascript_Core/dfg/DFGGraph.h 2018-01-18 07:24:07 UTC (rev 227129)
+++ branches/safari-605-branch/Source/_javascript_Core/dfg/DFGGraph.h 2018-01-18 07:24:10 UTC (rev 227130)
@@ -970,6 +970,17 @@
return result;
}
+ bool supportsMultiGetByOffset(CodeOrigin origin)
+ {
+ if (!is64Bit())
+ return false;
+ if (isFTL(m_plan.mode))
+ return true;
+ // We want to ensure we get polyvariant profiling data from the GetById. This allows
+ // the same get_by_id inlined into two separate functions to get independent profiling data.
+ return !origin.inlineCallFrame;
+ }
+
VM& m_vm;
Plan& m_plan;
CodeBlock* m_codeBlock;
Modified: branches/safari-605-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (227129 => 227130)
--- branches/safari-605-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2018-01-18 07:24:07 UTC (rev 227129)
+++ branches/safari-605-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2018-01-18 07:24:10 UTC (rev 227130)
@@ -4332,6 +4332,89 @@
jsValueResult(resultGPR, node);
break;
}
+
+ case MultiGetByOffset: {
+ SpeculateCellOperand base(this, node->child1());
+ GPRTemporary result(this);
+
+ GPRReg baseGPR = base.gpr();
+ GPRReg resultGPR = result.gpr();
+
+ MultiGetByOffsetData& data = ""
+
+ MacroAssembler::JumpList success;
+ MacroAssembler::Jump next;
+ for (unsigned i = 0; i < data.cases.size(); i++) {
+ if (next.isSet())
+ next.link(&m_jit);
+
+ MultiGetByOffsetCase getCase = data.cases[i];
+ GetByOffsetMethod method = getCase.method();
+ const RegisteredStructureSet& structures = getCase.set();
+
+ if (structures.size() == 1) {
+ next = m_jit.branchWeakStructure(JITCompiler::NotEqual,
+ JITCompiler::Address(baseGPR, JSCell::structureIDOffset()), structures[0]);
+ } else {
+ m_jit.load32(JITCompiler::Address(baseGPR, JSCell::structureIDOffset()), resultGPR);
+ JITCompiler::JumpList match;
+ for (size_t i = 0; i < structures.size() - 1; ++i) {
+ match.append(
+ m_jit.branchWeakStructure(JITCompiler::Equal, resultGPR, structures[i]));
+ }
+ next = m_jit.branchWeakStructure(JITCompiler::NotEqual, resultGPR, structures.last());
+ match.link(&m_jit);
+ }
+
+ switch (method.kind()) {
+ case GetByOffsetMethod::Invalid:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+
+ case GetByOffsetMethod::Constant:
+ m_jit.move(MacroAssembler::Imm64(JSValue::encode(method.constant()->value())), resultGPR);
+ break;
+
+ case GetByOffsetMethod::Load:
+ case GetByOffsetMethod::LoadFromPrototype: {
+ PropertyOffset offset = method.offset();
+ if (method.kind() == GetByOffsetMethod::Load) {
+ if (isInlineOffset(offset)) {
+ m_jit.load64(
+ CCallHelpers::Address(baseGPR, offsetRelativeToBase(offset)), resultGPR);
+ } else {
+ m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), resultGPR);
+ m_jit.load64(
+ CCallHelpers::Address(resultGPR, offsetRelativeToBase(offset)), resultGPR);
+ }
+ } else {
+ JSObject* base = asObject(method.prototype()->value());
+ if (isInlineOffset(offset)) {
+ char* pointerToField = bitwise_cast<char*>(base) + offsetRelativeToBase(offset);
+ m_jit.load64(pointerToField, resultGPR);
+ } else {
+ char* pointerToButterfly = bitwise_cast<char*>(base) + JSObject::butterflyOffset();
+ m_jit.loadPtr(pointerToButterfly, resultGPR);
+ m_jit.load64(
+ CCallHelpers::Address(resultGPR, offsetRelativeToBase(offset)), resultGPR);
+ }
+
+ }
+ break;
+ }
+ }
+ success.append(m_jit.jump());
+ }
+
+ if (next.isSet())
+ next.link(&m_jit);
+ speculationCheck(BadCache, JSValueRegs(baseGPR), node->child1(), m_jit.jump());
+ if (!success.empty())
+ success.link(&m_jit);
+ jsValueResult(resultGPR, node);
+ break;
+ }
+
case GetGetter: {
compileGetGetter(node);
@@ -5643,7 +5726,6 @@
case ExtractOSREntryLocal:
case CheckInBounds:
case ArithIMul:
- case MultiGetByOffset:
case MultiPutByOffset:
case FiatInt52:
case CheckBadCell: