Commit eaaa4081 authored by fpizlo@apple.com's avatar fpizlo@apple.com

Resolve opcodes should have value profiling.

https://bugs.webkit.org/show_bug.cgi?id=68723

Reviewed by Oliver Hunt.
        
This adds value profiling to all forms of op_resolve in the
old JIT, and patches that information into the DFG along with
performing the appropriate type propagation.

* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::predict):
* dfg/DFGNode.h:
(JSC::DFG::Node::hasIdentifier):
(JSC::DFG::Node::resolveGlobalDataIndex):
(JSC::DFG::Node::hasPrediction):
* dfg/DFGPropagator.cpp:
(JSC::DFG::Propagator::propagateNodePredictions):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_resolve):
(JSC::JIT::emit_op_resolve_base):
(JSC::JIT::emit_op_resolve_skip):
(JSC::JIT::emit_op_resolve_global):
(JSC::JIT::emitSlow_op_resolve_global):
(JSC::JIT::emit_op_resolve_with_base):
(JSC::JIT::emit_op_resolve_with_this):
(JSC::JIT::emitSlow_op_resolve_global_dynamic):
* jit/JITStubCall.h:
(JSC::JITStubCall::callWithValueProfiling):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@95887 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 04f485d6
2011-09-23 Filip Pizlo <fpizlo@apple.com>
Resolve opcodes should have value profiling.
https://bugs.webkit.org/show_bug.cgi?id=68723
Reviewed by Oliver Hunt.
This adds value profiling to all forms of op_resolve in the
old JIT, and patches that information into the DFG along with
performing the appropriate type propagation.
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::predict):
* dfg/DFGNode.h:
(JSC::DFG::Node::hasIdentifier):
(JSC::DFG::Node::resolveGlobalDataIndex):
(JSC::DFG::Node::hasPrediction):
* dfg/DFGPropagator.cpp:
(JSC::DFG::Propagator::propagateNodePredictions):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_resolve):
(JSC::JIT::emit_op_resolve_base):
(JSC::JIT::emit_op_resolve_skip):
(JSC::JIT::emit_op_resolve_global):
(JSC::JIT::emitSlow_op_resolve_global):
(JSC::JIT::emit_op_resolve_with_base):
(JSC::JIT::emit_op_resolve_with_this):
(JSC::JIT::emitSlow_op_resolve_global_dynamic):
* jit/JITStubCall.h:
(JSC::JITStubCall::callWithValueProfiling):
2011-09-23 Oliver Hunt <oliver@apple.com>
Fix windows build.
......@@ -1415,8 +1415,9 @@ bool ByteCodeParser::parseBlock(unsigned limit)
case op_resolve: {
unsigned identifier = currentInstruction[2].u.operand;
NodeIndex resolve = addToGraph(Resolve, OpInfo(identifier));
NodeIndex resolve = addToGraph(Resolve, OpInfo(identifier), OpInfo(PredictNone));
set(currentInstruction[1].u.operand, resolve);
stronglyPredict(resolve);
NEXT_OPCODE(op_resolve);
}
......@@ -1424,17 +1425,21 @@ bool ByteCodeParser::parseBlock(unsigned limit)
case op_resolve_base: {
unsigned identifier = currentInstruction[2].u.operand;
NodeIndex resolve = addToGraph(currentInstruction[3].u.operand ? ResolveBaseStrictPut : ResolveBase, OpInfo(identifier));
NodeIndex resolve = addToGraph(currentInstruction[3].u.operand ? ResolveBaseStrictPut : ResolveBase, OpInfo(identifier), OpInfo(PredictNone));
set(currentInstruction[1].u.operand, resolve);
stronglyPredict(resolve);
NEXT_OPCODE(op_resolve_base);
}
case op_resolve_global: {
unsigned identifier = currentInstruction[2].u.operand;
NodeIndex resolve = addToGraph(ResolveGlobal, OpInfo(identifier), OpInfo(m_globalResolveNumber++));
NodeIndex resolve = addToGraph(ResolveGlobal, OpInfo(m_graph.m_resolveGlobalData.size()), OpInfo(PredictNone));
m_graph.m_resolveGlobalData.append(ResolveGlobalData());
ResolveGlobalData& data = m_graph.m_resolveGlobalData.last();
data.identifierNumber = currentInstruction[2].u.operand;
data.resolveInfoIndex = m_globalResolveNumber++;
set(currentInstruction[1].u.operand, resolve);
stronglyPredict(resolve);
NEXT_OPCODE(op_resolve_global);
}
......
......@@ -97,6 +97,11 @@ struct StorageAccessData {
// Structure*.
};
struct ResolveGlobalData {
unsigned identifierNumber;
unsigned resolveInfoIndex;
};
typedef Vector <BlockIndex, 2> PredecessorList;
struct BasicBlock {
......@@ -197,6 +202,10 @@ public:
case Construct:
case GetByOffset:
case GetScopedVar:
case Resolve:
case ResolveBase:
case ResolveBaseStrictPut:
case ResolveGlobal:
return node.predict(prediction, source);
default:
return false;
......@@ -316,6 +325,7 @@ public:
Vector<NodeIndex, 16> m_varArgChildren;
Vector<MethodCheckData> m_methodCheckData;
Vector<StorageAccessData> m_storageAccessData;
Vector<ResolveGlobalData> m_resolveGlobalData;
unsigned m_preservedVars;
unsigned m_parameterSlots;
private:
......
......@@ -467,7 +467,6 @@ struct Node {
case Resolve:
case ResolveBase:
case ResolveBaseStrictPut:
case ResolveGlobal:
return true;
default:
return false;
......@@ -481,10 +480,10 @@ struct Node {
return m_opInfo;
}
unsigned resolveInfoIndex()
unsigned resolveGlobalDataIndex()
{
ASSERT(op == ResolveGlobal);
return m_opInfo2;
return m_opInfo;
}
bool hasArithNodeFlags()
......@@ -633,6 +632,10 @@ struct Node {
case Construct:
case GetByOffset:
case GetScopedVar:
case Resolve:
case ResolveBase:
case ResolveBaseStrictPut:
case ResolveGlobal:
return true;
default:
return false;
......
......@@ -534,7 +534,11 @@ private:
break;
}
case GetScopedVar: {
case GetScopedVar:
case Resolve:
case ResolveBase:
case ResolveBaseStrictPut:
case ResolveGlobal: {
changed |= node.predict(m_uses[m_compileIndex] & ~PredictionTagMask, StrongPrediction);
PredictedType prediction = node.getPrediction();
if (isStrongPrediction(prediction))
......@@ -593,6 +597,7 @@ private:
#ifndef NDEBUG
// These get ignored because they don't return anything.
case PutScopedVar:
case DFG::Jump:
case Branch:
case Breakpoint:
......@@ -603,19 +608,9 @@ private:
case ThrowReferenceError:
break;
// These get ignored because we don't have profiling for them, yet.
case Resolve:
case ResolveBase:
case ResolveBaseStrictPut:
case ResolveGlobal:
case PutScopedVar:
break;
// This gets ignored because it doesn't do anything.
case Phantom:
break;
#else
default:
break;
......
......@@ -2055,7 +2055,8 @@ void SpeculativeJIT::compile(Node& node)
GPRReg resolveInfoGPR = resolveInfo.gpr();
GPRReg resultGPR = result.gpr();
GlobalResolveInfo* resolveInfoAddress = &(m_jit.codeBlock()->globalResolveInfo(node.resolveInfoIndex()));
ResolveGlobalData& data = m_jit.graph().m_resolveGlobalData[node.resolveGlobalDataIndex()];
GlobalResolveInfo* resolveInfoAddress = &(m_jit.codeBlock()->globalResolveInfo(data.resolveInfoIndex));
// Check Structure of global object
m_jit.move(JITCompiler::TrustedImmPtr(m_jit.codeBlock()->globalObject()), globalObjectGPR);
......@@ -2065,7 +2066,7 @@ void SpeculativeJIT::compile(Node& node)
silentSpillAllRegisters(resultGPR);
m_jit.move(resolveInfoGPR, GPRInfo::argumentGPR1);
m_jit.move(JITCompiler::TrustedImmPtr(&m_jit.codeBlock()->identifier(node.identifierNumber())), GPRInfo::argumentGPR2);
m_jit.move(JITCompiler::TrustedImmPtr(&m_jit.codeBlock()->identifier(data.identifierNumber)), GPRInfo::argumentGPR2);
m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
JITCompiler::Call functionCall = appendCallWithExceptionCheck(operationResolveGlobal);
m_jit.move(GPRInfo::returnValueGPR, resultGPR);
......
......@@ -518,7 +518,7 @@ void JIT::emit_op_resolve(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_resolve);
stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
stubCall.call(currentInstruction[1].u.operand);
stubCall.callWithValueProfiling(currentInstruction[1].u.operand, FirstProfilingSite);
}
void JIT::emit_op_to_primitive(Instruction* currentInstruction)
......@@ -549,7 +549,7 @@ void JIT::emit_op_resolve_base(Instruction* currentInstruction)
{
JITStubCall stubCall(this, currentInstruction[3].u.operand ? cti_op_resolve_base_strict_put : cti_op_resolve_base);
stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
stubCall.call(currentInstruction[1].u.operand);
stubCall.callWithValueProfiling(currentInstruction[1].u.operand, FirstProfilingSite);
}
void JIT::emit_op_ensure_property_exists(Instruction* currentInstruction)
......@@ -565,7 +565,7 @@ void JIT::emit_op_resolve_skip(Instruction* currentInstruction)
JITStubCall stubCall(this, cti_op_resolve_skip);
stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
stubCall.call(currentInstruction[1].u.operand);
stubCall.callWithValueProfiling(currentInstruction[1].u.operand, FirstProfilingSite);
}
void JIT::emit_op_resolve_global(Instruction* currentInstruction, bool)
......@@ -586,6 +586,7 @@ void JIT::emit_op_resolve_global(Instruction* currentInstruction, bool)
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSGlobalObject, m_propertyStorage)), regT0);
load32(Address(regT2, OBJECT_OFFSETOF(GlobalResolveInfo, offset)), regT1);
loadPtr(BaseIndex(regT0, regT1, ScalePtr), regT0);
emitValueProfilingSite(FirstProfilingSite);
emitPutVirtualRegister(currentInstruction[1].u.operand);
}
......@@ -601,7 +602,7 @@ void JIT::emitSlow_op_resolve_global(Instruction* currentInstruction, Vector<Slo
stubCall.addArgument(TrustedImmPtr(ident));
stubCall.addArgument(Imm32(currentIndex));
stubCall.addArgument(regT0);
stubCall.call(dst);
stubCall.callWithValueProfiling(dst, SubsequentProfilingSite);
}
void JIT::emit_op_not(Instruction* currentInstruction)
......@@ -722,7 +723,7 @@ void JIT::emit_op_resolve_with_base(Instruction* currentInstruction)
JITStubCall stubCall(this, cti_op_resolve_with_base);
stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand)));
stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
stubCall.call(currentInstruction[2].u.operand);
stubCall.callWithValueProfiling(currentInstruction[2].u.operand, FirstProfilingSite);
}
void JIT::emit_op_resolve_with_this(Instruction* currentInstruction)
......@@ -730,7 +731,7 @@ void JIT::emit_op_resolve_with_this(Instruction* currentInstruction)
JITStubCall stubCall(this, cti_op_resolve_with_this);
stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand)));
stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
stubCall.call(currentInstruction[2].u.operand);
stubCall.callWithValueProfiling(currentInstruction[2].u.operand, FirstProfilingSite);
}
void JIT::emit_op_jtrue(Instruction* currentInstruction)
......@@ -1531,7 +1532,7 @@ void JIT::emitSlow_op_resolve_global_dynamic(Instruction* currentInstruction, Ve
stubCall.addArgument(TrustedImmPtr(ident));
stubCall.addArgument(Imm32(currentIndex));
stubCall.addArgument(regT0);
stubCall.call(dst);
stubCall.callWithValueProfiling(dst, SubsequentProfilingSite); // The first profiling site is in emit_op_resolve_global
}
void JIT::emit_op_new_regexp(Instruction* currentInstruction)
......
......@@ -200,6 +200,11 @@ namespace JSC {
m_jit->emitStoreCell(dst, JIT::returnValueRegister);
return call;
}
JIT::Call callWithValueProfiling(unsigned dst, JIT::ValueProfilingSiteKind)
{
return call(dst);
}
#else
JIT::Call call(unsigned dst) // dst is a virtual register.
{
......@@ -208,6 +213,16 @@ namespace JSC {
m_jit->emitPutVirtualRegister(dst);
return call;
}
JIT::Call callWithValueProfiling(unsigned dst, JIT::ValueProfilingSiteKind kind)
{
ASSERT(m_returnType == VoidPtr || m_returnType == Cell);
JIT::Call call = this->call();
ASSERT(JIT::returnValueRegister == JIT::regT0);
m_jit->emitValueProfilingSite(kind);
m_jit->emitPutVirtualRegister(dst);
return call;
}
#endif
JIT::Call call(JIT::RegisterID dst) // dst is a machine register.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment