Diff
Modified: branches/dfgFourthTier/Source/_javascript_Core/ChangeLog (151072 => 151073)
--- branches/dfgFourthTier/Source/_javascript_Core/ChangeLog 2013-06-01 18:02:36 UTC (rev 151072)
+++ branches/dfgFourthTier/Source/_javascript_Core/ChangeLog 2013-06-01 22:24:14 UTC (rev 151073)
@@ -1,3 +1,67 @@
+2013-06-01 Filip Pizlo <[email protected]>
+
+ Fix some minor issues in the DFG's profiling of heap accesses
+ https://bugs.webkit.org/show_bug.cgi?id=113010
+
+ Reviewed by Goeffrey Garen.
+
+ Carefully merge r146669 from trunk. This required some fiddling since it
+ wasn't a clean apply.
+
+ Original changelog:
+
+ 1) If a CodeBlock gets jettisoned by GC, we should count the exit sites.
+
+ 2) If a CodeBlock clears a structure stub during GC, it should record this, and
+ the DFG should prefer to not inline that access (i.e. treat it as if it had an
+ exit site).
+
+ 3) If a PutById was seen by the baseline JIT, and the JIT attempted to cache it,
+ but it chose not to, then assume that it will take slow path.
+
+ 4) If we frequently exited because of a structure check on a weak constant,
+ don't try to inline that access in the future.
+
+ 5) Treat all exits that were counted as being frequent.
+
+ 81% speed-up on Octane/gbemu. Small speed-ups elsewhere, and no regressions.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::finalizeUnconditionally):
+ (JSC):
+ (JSC::CodeBlock::resetStubDuringGCInternal):
+ (JSC::CodeBlock::reoptimize):
+ (JSC::CodeBlock::jettison):
+ (JSC::ProgramCodeBlock::jettisonImpl):
+ (JSC::EvalCodeBlock::jettisonImpl):
+ (JSC::FunctionCodeBlock::jettisonImpl):
+ (JSC::CodeBlock::tallyFrequentExitSites):
+ * bytecode/CodeBlock.h:
+ (CodeBlock):
+ (JSC::CodeBlock::tallyFrequentExitSites):
+ (ProgramCodeBlock):
+ (EvalCodeBlock):
+ (FunctionCodeBlock):
+ * bytecode/GetByIdStatus.cpp:
+ (JSC::GetByIdStatus::computeFor):
+ * bytecode/PutByIdStatus.cpp:
+ (JSC::PutByIdStatus::computeFor):
+ * bytecode/StructureStubInfo.h:
+ (JSC::StructureStubInfo::StructureStubInfo):
+ (StructureStubInfo):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::handleGetById):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGOSRExitBase.cpp:
+ (JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSiteSlow):
+ * dfg/DFGOSRExitBase.h:
+ (JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSite):
+ (OSRExitBase):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * runtime/Options.h:
+ (JSC):
+
2013-05-31 Filip Pizlo <[email protected]>
Remove CodeOrigin::valueProfileOffset since it was only needed for op_call_put_result.
Modified: branches/dfgFourthTier/Source/_javascript_Core/bytecode/CodeBlock.cpp (151072 => 151073)
--- branches/dfgFourthTier/Source/_javascript_Core/bytecode/CodeBlock.cpp 2013-06-01 18:02:36 UTC (rev 151072)
+++ branches/dfgFourthTier/Source/_javascript_Core/bytecode/CodeBlock.cpp 2013-06-01 22:24:14 UTC (rev 151073)
@@ -2266,10 +2266,6 @@
if (Options::verboseOSR())
dataLog(*this, " has dead weak references, jettisoning during GC.\n");
- // Make sure that the baseline JIT knows that it should re-warm-up before
- // optimizing.
- alternative()->optimizeAfterWarmUp();
-
if (DFG::shouldShowDisassembly()) {
dataLog(*this, " will be jettisoned because of the following dead references:\n");
DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
@@ -2356,7 +2352,7 @@
if (stubInfo.visitWeakReferences())
continue;
- resetStubInternal(repatchBuffer, stubInfo);
+ resetStubDuringGCInternal(repatchBuffer, stubInfo);
}
}
#endif
@@ -2399,6 +2395,12 @@
stubInfo.reset();
}
+
+void CodeBlock::resetStubDuringGCInternal(RepatchBuffer& repatchBuffer, StructureStubInfo& stubInfo)
+{
+ resetStubInternal(repatchBuffer, stubInfo);
+ stubInfo.resetByGC = true;
+}
#endif
void CodeBlock::stronglyVisitStrongReferences(SlotVisitor& visitor)
@@ -2761,12 +2763,10 @@
{
ASSERT(replacement() != this);
ASSERT(replacement()->alternative() == this);
- replacement()->tallyFrequentExitSites();
if (DFG::shouldShowDisassembly())
dataLog(*replacement(), " will be jettisoned due to reoptimization of ", *this, ".\n");
replacement()->jettison();
countReoptimization();
- optimizeAfterWarmUp();
}
CodeBlock* ProgramCodeBlock::replacement()
@@ -2846,30 +2846,29 @@
return DFG::functionForCallCapabilityLevel(this);
}
-void ProgramCodeBlock::jettison()
+void CodeBlock::jettison()
{
ASSERT(JITCode::isOptimizingJIT(jitType()));
ASSERT(this == replacement());
+ alternative()->optimizeAfterWarmUp();
+ tallyFrequentExitSites();
if (DFG::shouldShowDisassembly())
dataLog("Jettisoning ", *this, ".\n");
+ jettisonImpl();
+}
+
+void ProgramCodeBlock::jettisonImpl()
+{
static_cast<ProgramExecutable*>(ownerExecutable())->jettisonOptimizedCode(*vm());
}
-void EvalCodeBlock::jettison()
+void EvalCodeBlock::jettisonImpl()
{
- ASSERT(JITCode::isOptimizingJIT(jitType()));
- ASSERT(this == replacement());
- if (DFG::shouldShowDisassembly())
- dataLog("Jettisoning ", *this, ".\n");
static_cast<EvalExecutable*>(ownerExecutable())->jettisonOptimizedCode(*vm());
}
-void FunctionCodeBlock::jettison()
+void FunctionCodeBlock::jettisonImpl()
{
- ASSERT(JITCode::isOptimizingJIT(jitType()));
- ASSERT(this == replacement());
- if (DFG::shouldShowDisassembly())
- dataLog("Jettisoning ", *this, ".\n");
static_cast<FunctionExecutable*>(ownerExecutable())->jettisonOptimizedCodeFor(*vm(), m_isConstructor ? CodeForConstruct : CodeForCall);
}
@@ -3351,7 +3350,7 @@
for (unsigned i = 0; i < jitCode->osrExit.size(); ++i) {
DFG::OSRExit& exit = jitCode->osrExit[i];
- if (!exit.considerAddingAsFrequentExitSite(this, profiledBlock))
+ if (!exit.considerAddingAsFrequentExitSite(profiledBlock))
continue;
#if DFG_ENABLE(DEBUG_VERBOSE)
@@ -3371,7 +3370,7 @@
for (unsigned i = 0; i < jitCode->osrExit.size(); ++i) {
FTL::OSRExit& exit = jitCode->osrExit[i];
- if (!exit.considerAddingAsFrequentExitSite(this, profiledBlock))
+ if (!exit.considerAddingAsFrequentExitSite(profiledBlock))
continue;
#if DFG_ENABLE(DEBUG_VERBOSE)
Modified: branches/dfgFourthTier/Source/_javascript_Core/bytecode/CodeBlock.h (151072 => 151073)
--- branches/dfgFourthTier/Source/_javascript_Core/bytecode/CodeBlock.h 2013-06-01 18:02:36 UTC (rev 151072)
+++ branches/dfgFourthTier/Source/_javascript_Core/bytecode/CodeBlock.h 2013-06-01 22:24:14 UTC (rev 151073)
@@ -284,7 +284,7 @@
}
virtual JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex) = 0;
virtual CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>) = 0;
- virtual void jettison() = 0;
+ void jettison();
CompilationResult jitCompile(ExecState* exec)
{
if (jitType() != JITCode::InterpreterThunk) {
@@ -903,10 +903,17 @@
protected:
#if ENABLE(JIT)
virtual CompilationResult jitCompileImpl(ExecState*) = 0;
+ virtual void jettisonImpl() = 0;
#endif
virtual void visitWeakReferences(SlotVisitor&);
virtual void finalizeUnconditionally();
+#if ENABLE(DFG_JIT)
+ void tallyFrequentExitSites();
+#else
+ void tallyFrequentExitSites() { }
+#endif
+
private:
friend class DFGCodeBlocks;
@@ -918,11 +925,6 @@
ClosureCallStubRoutine* findClosureCallForReturnPC(ReturnAddressPtr);
#endif
-#if ENABLE(DFG_JIT)
- void tallyFrequentExitSites();
-#else
- void tallyFrequentExitSites() { }
-#endif
#if ENABLE(VALUE_PROFILER)
void updateAllPredictionsAndCountLiveness(OperationInProgress, unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles);
#endif
@@ -999,6 +1001,7 @@
#if ENABLE(JIT)
void resetStubInternal(RepatchBuffer&, StructureStubInfo&);
+ void resetStubDuringGCInternal(RepatchBuffer&, StructureStubInfo&);
#endif
WriteBarrier<UnlinkedCodeBlock> m_unlinkedCode;
int m_numParameters;
@@ -1134,7 +1137,7 @@
protected:
virtual JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);
virtual CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>);
- virtual void jettison();
+ virtual void jettisonImpl();
virtual CompilationResult jitCompileImpl(ExecState*);
virtual CodeBlock* replacement();
virtual DFG::CapabilityLevel capabilityLevelInternal();
@@ -1160,7 +1163,7 @@
protected:
virtual JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);
virtual CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>);
- virtual void jettison();
+ virtual void jettisonImpl();
virtual CompilationResult jitCompileImpl(ExecState*);
virtual CodeBlock* replacement();
virtual DFG::CapabilityLevel capabilityLevelInternal();
@@ -1186,7 +1189,7 @@
protected:
virtual JSObject* compileOptimized(ExecState*, JSScope*, CompilationResult&, unsigned bytecodeIndex);
virtual CompilationResult replaceWithDeferredOptimizedCode(PassRefPtr<DFG::Plan>);
- virtual void jettison();
+ virtual void jettisonImpl();
virtual CompilationResult jitCompileImpl(ExecState*);
virtual CodeBlock* replacement();
virtual DFG::CapabilityLevel capabilityLevelInternal();
Modified: branches/dfgFourthTier/Source/_javascript_Core/bytecode/GetByIdStatus.cpp (151072 => 151073)
--- branches/dfgFourthTier/Source/_javascript_Core/bytecode/GetByIdStatus.cpp 2013-06-01 18:02:36 UTC (rev 151072)
+++ branches/dfgFourthTier/Source/_javascript_Core/bytecode/GetByIdStatus.cpp 2013-06-01 22:24:14 UTC (rev 151073)
@@ -122,6 +122,9 @@
if (!stubInfo.seen)
return computeFromLLInt(profiledBlock, bytecodeIndex, uid);
+ if (stubInfo.resetByGC)
+ return GetByIdStatus(TakesSlowPath, true);
+
PolymorphicAccessStructureList* list;
int listSize;
switch (stubInfo.accessType) {
Modified: branches/dfgFourthTier/Source/_javascript_Core/bytecode/PutByIdStatus.cpp (151072 => 151073)
--- branches/dfgFourthTier/Source/_javascript_Core/bytecode/PutByIdStatus.cpp 2013-06-01 18:02:36 UTC (rev 151072)
+++ branches/dfgFourthTier/Source/_javascript_Core/bytecode/PutByIdStatus.cpp 2013-06-01 22:24:14 UTC (rev 151073)
@@ -99,9 +99,13 @@
if (!stubInfo.seen)
return computeFromLLInt(profiledBlock, bytecodeIndex, uid);
+ if (stubInfo.resetByGC)
+ return PutByIdStatus(TakesSlowPath, 0, 0, 0, invalidOffset);
+
switch (stubInfo.accessType) {
case access_unset:
- return computeFromLLInt(profiledBlock, bytecodeIndex, uid);
+ // If the JIT saw it but didn't optimize it, then assume that this takes slow path.
+ return PutByIdStatus(TakesSlowPath, 0, 0, 0, invalidOffset);
case access_put_by_id_replace: {
PropertyOffset offset =
Modified: branches/dfgFourthTier/Source/_javascript_Core/bytecode/StructureStubInfo.h (151072 => 151073)
--- branches/dfgFourthTier/Source/_javascript_Core/bytecode/StructureStubInfo.h 2013-06-01 18:02:36 UTC (rev 151072)
+++ branches/dfgFourthTier/Source/_javascript_Core/bytecode/StructureStubInfo.h 2013-06-01 22:24:14 UTC (rev 151073)
@@ -97,6 +97,7 @@
StructureStubInfo()
: accessType(access_unset)
, seen(false)
+ , resetByGC(false)
{
}
@@ -200,7 +201,8 @@
unsigned bytecodeIndex;
int8_t accessType;
- int8_t seen;
+ bool seen : 1;
+ bool resetByGC : 1;
#if ENABLE(DFG_JIT)
CodeOrigin codeOrigin;
Modified: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (151072 => 151073)
--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2013-06-01 18:02:36 UTC (rev 151072)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2013-06-01 22:24:14 UTC (rev 151073)
@@ -1669,7 +1669,8 @@
const GetByIdStatus& getByIdStatus)
{
if (!getByIdStatus.isSimple()
- || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)) {
+ || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
+ || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadWeakConstantCache)) {
set(destinationOperand,
addToGraph(
getByIdStatus.makesCalls() ? GetByIdFlush : GetById,
@@ -2558,7 +2559,9 @@
if (!putByIdStatus.isSet())
addToGraph(ForceOSRExit);
- bool hasExitSite = m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache);
+ bool hasExitSite =
+ m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
+ || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadWeakConstantCache);
if (!hasExitSite && putByIdStatus.isSimpleReplace()) {
addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(putByIdStatus.oldStructure())), base);
Modified: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGOSRExitBase.cpp (151072 => 151073)
--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGOSRExitBase.cpp 2013-06-01 18:02:36 UTC (rev 151072)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGOSRExitBase.cpp 2013-06-01 22:24:14 UTC (rev 151073)
@@ -35,11 +35,8 @@
namespace JSC { namespace DFG {
-bool OSRExitBase::considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock)
+bool OSRExitBase::considerAddingAsFrequentExitSiteSlow(CodeBlock* profiledCodeBlock)
{
- if (static_cast<double>(m_count) / dfgCodeBlock->osrExitCounter() <= Options::osrExitProminenceForFrequentExitSite())
- return false;
-
FrequentExitSite exitSite;
if (m_kind == ArgumentsEscaped) {
Modified: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGOSRExitBase.h (151072 => 151073)
--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGOSRExitBase.h 2013-06-01 18:02:36 UTC (rev 151072)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGOSRExitBase.h 2013-06-01 22:24:14 UTC (rev 151073)
@@ -56,11 +56,11 @@
CodeOrigin m_codeOrigin;
CodeOrigin m_codeOriginForExitProfile;
- bool considerAddingAsFrequentExitSite(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock)
+ bool considerAddingAsFrequentExitSite(CodeBlock* profiledCodeBlock)
{
if (!m_count || !exitKindIsCountable(m_kind))
return false;
- return considerAddingAsFrequentExitSiteSlow(dfgCodeBlock, profiledCodeBlock);
+ return considerAddingAsFrequentExitSiteSlow(profiledCodeBlock);
}
// Returns true if the forward conversion is really needed.
@@ -69,7 +69,7 @@
Node*& nextBCNode, Node*& lastMovHint);
private:
- bool considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock);
+ bool considerAddingAsFrequentExitSiteSlow(CodeBlock* profiledCodeBlock);
};
} } // namespace JSC::DFG
Modified: branches/dfgFourthTier/Source/_javascript_Core/jit/JITStubs.cpp (151072 => 151073)
--- branches/dfgFourthTier/Source/_javascript_Core/jit/JITStubs.cpp 2013-06-01 18:02:36 UTC (rev 151072)
+++ branches/dfgFourthTier/Source/_javascript_Core/jit/JITStubs.cpp 2013-06-01 22:24:14 UTC (rev 151073)
@@ -528,10 +528,8 @@
stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot);
if (accessType == static_cast<AccessType>(stubInfo->accessType)) {
- if (!stubInfo->seenOnce())
- stubInfo->setSeen();
- else
- tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, false);
+ stubInfo->setSeen();
+ tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, false);
}
CHECK_FOR_EXCEPTION_AT_END();
@@ -554,10 +552,8 @@
asObject(baseValue)->putDirect(callFrame->vm(), ident, stackFrame.args[2].jsValue(), slot);
if (accessType == static_cast<AccessType>(stubInfo->accessType)) {
- if (!stubInfo->seenOnce())
- stubInfo->setSeen();
- else
- tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, true);
+ stubInfo->setSeen();
+ tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, true);
}
CHECK_FOR_EXCEPTION_AT_END();
Modified: branches/dfgFourthTier/Source/_javascript_Core/runtime/Options.h (151072 => 151073)
--- branches/dfgFourthTier/Source/_javascript_Core/runtime/Options.h 2013-06-01 18:02:36 UTC (rev 151072)
+++ branches/dfgFourthTier/Source/_javascript_Core/runtime/Options.h 2013-06-01 22:24:14 UTC (rev 151073)
@@ -124,7 +124,6 @@
v(unsigned, likelyToTakeSlowCaseMinimumCount, 100) \
v(unsigned, couldTakeSlowCaseMinimumCount, 10) \
\
- v(double, osrExitProminenceForFrequentExitSite, 0.3) \
v(unsigned, osrExitCountForReoptimization, 100) \
v(unsigned, osrExitCountForReoptimizationFromLoop, 5) \
\