Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (146668 => 146669)
--- trunk/Source/_javascript_Core/ChangeLog 2013-03-22 22:49:33 UTC (rev 146668)
+++ trunk/Source/_javascript_Core/ChangeLog 2013-03-22 23:00:57 UTC (rev 146669)
@@ -1,3 +1,62 @@
+2013-03-21 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.
+
+ 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/DFGOSRExit.cpp:
+ (JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow):
+ * dfg/DFGOSRExit.h:
+ (JSC::DFG::OSRExit::considerAddingAsFrequentExitSite):
+ (OSRExit):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * runtime/Options.h:
+ (JSC):
+
2013-03-22 Filip Pizlo <[email protected]>
DFG folding of PutById to SimpleReplace should consider the specialized function case
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (146668 => 146669)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2013-03-22 22:49:33 UTC (rev 146668)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2013-03-22 23:00:57 UTC (rev 146669)
@@ -2338,10 +2338,6 @@
if (verboseUnlinking)
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");
for (unsigned i = 0; i < m_dfgData->transitions.size(); ++i) {
@@ -2427,7 +2423,7 @@
if (stubInfo.visitWeakReferences())
continue;
- resetStubInternal(repatchBuffer, stubInfo);
+ resetStubDuringGCInternal(repatchBuffer, stubInfo);
}
}
#endif
@@ -2465,6 +2461,12 @@
stubInfo.reset();
}
+
+void CodeBlock::resetStubDuringGCInternal(RepatchBuffer& repatchBuffer, StructureStubInfo& stubInfo)
+{
+ resetStubInternal(repatchBuffer, stubInfo);
+ stubInfo.resetByGC = true;
+}
#endif
void CodeBlock::stronglyVisitStrongReferences(SlotVisitor& visitor)
@@ -2842,12 +2844,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()
@@ -2906,30 +2906,29 @@
return DFG::canCompileFunctionForCall(this);
}
-void ProgramCodeBlock::jettison()
+void CodeBlock::jettison()
{
ASSERT(JITCode::isOptimizingJIT(getJITType()));
ASSERT(this == replacement());
+ alternative()->optimizeAfterWarmUp();
+ tallyFrequentExitSites();
if (DFG::shouldShowDisassembly())
dataLog("Jettisoning ", *this, ".\n");
+ jettisonImpl();
+}
+
+void ProgramCodeBlock::jettisonImpl()
+{
static_cast<ProgramExecutable*>(ownerExecutable())->jettisonOptimizedCode(*globalData());
}
-void EvalCodeBlock::jettison()
+void EvalCodeBlock::jettisonImpl()
{
- ASSERT(JITCode::isOptimizingJIT(getJITType()));
- ASSERT(this == replacement());
- if (DFG::shouldShowDisassembly())
- dataLog("Jettisoning ", *this, ".\n");
static_cast<EvalExecutable*>(ownerExecutable())->jettisonOptimizedCode(*globalData());
}
-void FunctionCodeBlock::jettison()
+void FunctionCodeBlock::jettisonImpl()
{
- ASSERT(JITCode::isOptimizingJIT(getJITType()));
- ASSERT(this == replacement());
- if (DFG::shouldShowDisassembly())
- dataLog("Jettisoning ", *this, ".\n");
static_cast<FunctionExecutable*>(ownerExecutable())->jettisonOptimizedCodeFor(*globalData(), m_isConstructor ? CodeForConstruct : CodeForCall);
}
@@ -3272,7 +3271,7 @@
for (unsigned i = 0; i < m_dfgData->osrExit.size(); ++i) {
DFG::OSRExit& exit = m_dfgData->osrExit[i];
- if (!exit.considerAddingAsFrequentExitSite(this, profiledBlock))
+ if (!exit.considerAddingAsFrequentExitSite(profiledBlock))
continue;
#if DFG_ENABLE(DEBUG_VERBOSE)
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (146668 => 146669)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2013-03-22 22:49:33 UTC (rev 146668)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2013-03-22 23:00:57 UTC (rev 146669)
@@ -437,7 +437,7 @@
JITCode::JITType getJITType() const { return m_jitCode.jitType(); }
ExecutableMemoryHandle* executableMemory() { return getJITCode().getExecutableMemory(); }
virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex) = 0;
- virtual void jettison() = 0;
+ void jettison();
enum JITCompilationResult { AlreadyCompiled, CouldNotCompile, CompiledSuccessfully };
JITCompilationResult jitCompile(ExecState* exec)
{
@@ -1051,10 +1051,17 @@
protected:
#if ENABLE(JIT)
virtual bool 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;
@@ -1064,11 +1071,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
@@ -1145,6 +1147,7 @@
#if ENABLE(JIT)
void resetStubInternal(RepatchBuffer&, StructureStubInfo&);
+ void resetStubDuringGCInternal(RepatchBuffer&, StructureStubInfo&);
#endif
WriteBarrier<UnlinkedCodeBlock> m_unlinkedCode;
int m_numParameters;
@@ -1320,7 +1323,7 @@
#if ENABLE(JIT)
protected:
virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex);
- virtual void jettison();
+ virtual void jettisonImpl();
virtual bool jitCompileImpl(ExecState*);
virtual CodeBlock* replacement();
virtual DFG::CapabilityLevel canCompileWithDFGInternal();
@@ -1345,7 +1348,7 @@
#if ENABLE(JIT)
protected:
virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex);
- virtual void jettison();
+ virtual void jettisonImpl();
virtual bool jitCompileImpl(ExecState*);
virtual CodeBlock* replacement();
virtual DFG::CapabilityLevel canCompileWithDFGInternal();
@@ -1370,7 +1373,7 @@
#if ENABLE(JIT)
protected:
virtual JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex);
- virtual void jettison();
+ virtual void jettisonImpl();
virtual bool jitCompileImpl(ExecState*);
virtual CodeBlock* replacement();
virtual DFG::CapabilityLevel canCompileWithDFGInternal();
Modified: trunk/Source/_javascript_Core/bytecode/GetByIdStatus.cpp (146668 => 146669)
--- trunk/Source/_javascript_Core/bytecode/GetByIdStatus.cpp 2013-03-22 22:49:33 UTC (rev 146668)
+++ trunk/Source/_javascript_Core/bytecode/GetByIdStatus.cpp 2013-03-22 23:00:57 UTC (rev 146669)
@@ -125,6 +125,9 @@
if (!stubInfo.seen)
return computeFromLLInt(profiledBlock, bytecodeIndex, ident);
+ if (stubInfo.resetByGC)
+ return GetByIdStatus(TakesSlowPath, true);
+
PolymorphicAccessStructureList* list;
int listSize;
switch (stubInfo.accessType) {
Modified: trunk/Source/_javascript_Core/bytecode/PutByIdStatus.cpp (146668 => 146669)
--- trunk/Source/_javascript_Core/bytecode/PutByIdStatus.cpp 2013-03-22 22:49:33 UTC (rev 146668)
+++ trunk/Source/_javascript_Core/bytecode/PutByIdStatus.cpp 2013-03-22 23:00:57 UTC (rev 146669)
@@ -94,9 +94,13 @@
if (!stubInfo.seen)
return computeFromLLInt(profiledBlock, bytecodeIndex, ident);
+ if (stubInfo.resetByGC)
+ return PutByIdStatus(TakesSlowPath, 0, 0, 0, invalidOffset);
+
switch (stubInfo.accessType) {
case access_unset:
- return computeFromLLInt(profiledBlock, bytecodeIndex, ident);
+ // 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 = stubInfo.u.putByIdReplace.baseObjectStructure->get(
Modified: trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h (146668 => 146669)
--- trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h 2013-03-22 22:49:33 UTC (rev 146668)
+++ trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h 2013-03-22 23:00:57 UTC (rev 146669)
@@ -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: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (146668 => 146669)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2013-03-22 22:49:33 UTC (rev 146668)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2013-03-22 23:00:57 UTC (rev 146669)
@@ -1708,7 +1708,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,
@@ -2608,7 +2609,9 @@
canCountAsInlined = false;
}
- 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: trunk/Source/_javascript_Core/dfg/DFGOSRExit.cpp (146668 => 146669)
--- trunk/Source/_javascript_Core/dfg/DFGOSRExit.cpp 2013-03-22 22:49:33 UTC (rev 146668)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExit.cpp 2013-03-22 23:00:57 UTC (rev 146669)
@@ -72,11 +72,8 @@
m_patchableCodeOffset = linkBuffer.offsetOf(label);
}
-bool OSRExit::considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock)
+bool OSRExit::considerAddingAsFrequentExitSiteSlow(CodeBlock* profiledCodeBlock)
{
- if (static_cast<double>(m_count) / dfgCodeBlock->osrExitCounter() <= Options::osrExitProminenceForFrequentExitSite())
- return false;
-
FrequentExitSite exitSite;
if (m_kind == ArgumentsEscaped) {
Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExit.h (146668 => 146669)
--- trunk/Source/_javascript_Core/dfg/DFGOSRExit.h 2013-03-22 22:49:33 UTC (rev 146668)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExit.h 2013-03-22 23:00:57 UTC (rev 146669)
@@ -100,11 +100,11 @@
ExitKind m_kind;
uint32_t m_count;
- 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);
}
void setPatchableCodeOffset(MacroAssembler::PatchableJump);
@@ -118,7 +118,7 @@
RefPtr<ValueRecoveryOverride> m_valueRecoveryOverride;
private:
- bool considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock);
+ bool considerAddingAsFrequentExitSiteSlow(CodeBlock* profiledCodeBlock);
};
struct SpeculationFailureDebugInfo {
Modified: trunk/Source/_javascript_Core/jit/JITStubs.cpp (146668 => 146669)
--- trunk/Source/_javascript_Core/jit/JITStubs.cpp 2013-03-22 22:49:33 UTC (rev 146668)
+++ trunk/Source/_javascript_Core/jit/JITStubs.cpp 2013-03-22 23:00:57 UTC (rev 146669)
@@ -1456,10 +1456,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();
@@ -1482,10 +1480,8 @@
asObject(baseValue)->putDirect(callFrame->globalData(), 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: trunk/Source/_javascript_Core/runtime/Options.h (146668 => 146669)
--- trunk/Source/_javascript_Core/runtime/Options.h 2013-03-22 22:49:33 UTC (rev 146668)
+++ trunk/Source/_javascript_Core/runtime/Options.h 2013-03-22 23:00:57 UTC (rev 146669)
@@ -111,7 +111,6 @@
v(unsigned, likelyToTakeSlowCaseMinimumCount, 100) \
v(unsigned, couldTakeSlowCaseMinimumCount, 10) \
\
- v(double, osrExitProminenceForFrequentExitSite, 0.3) \
v(unsigned, osrExitCountForReoptimization, 100) \
v(unsigned, osrExitCountForReoptimizationFromLoop, 5) \
\