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

OSRExit::m_watchpointIndex should be in OSRExitCompilationInfo

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

Reviewed by Mark Hahnenberg.
        
Also enable ExitKind to tell you if it's a watchpoint.

* bytecode/ExitKind.cpp:
(JSC::exitKindToString):
* bytecode/ExitKind.h:
(JSC::isWatchpoint):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::setLocal):
(JSC::DFG::ByteCodeParser::setArgument):
(JSC::DFG::ByteCodeParser::handleCall):
(JSC::DFG::ByteCodeParser::handleGetById):
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::linkOSRExits):
(JSC::DFG::JITCompiler::link):
* dfg/DFGJITCompiler.h:
(JSC::DFG::JITCompiler::appendExitInfo):
* dfg/DFGOSRExit.cpp:
(JSC::DFG::OSRExit::OSRExit):
* dfg/DFGOSRExit.h:
* dfg/DFGOSRExitCompilationInfo.h:
(JSC::DFG::OSRExitCompilationInfo::OSRExitCompilationInfo):
* dfg/DFGOSRExitCompiler.cpp:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::speculationWatchpoint):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@158141 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 5d05e88f
2013-10-28 Filip Pizlo <fpizlo@apple.com>
OSRExit::m_watchpointIndex should be in OSRExitCompilationInfo
https://bugs.webkit.org/show_bug.cgi?id=123423
Reviewed by Mark Hahnenberg.
Also enable ExitKind to tell you if it's a watchpoint.
* bytecode/ExitKind.cpp:
(JSC::exitKindToString):
* bytecode/ExitKind.h:
(JSC::isWatchpoint):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::setLocal):
(JSC::DFG::ByteCodeParser::setArgument):
(JSC::DFG::ByteCodeParser::handleCall):
(JSC::DFG::ByteCodeParser::handleGetById):
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::linkOSRExits):
(JSC::DFG::JITCompiler::link):
* dfg/DFGJITCompiler.h:
(JSC::DFG::JITCompiler::appendExitInfo):
* dfg/DFGOSRExit.cpp:
(JSC::DFG::OSRExit::OSRExit):
* dfg/DFGOSRExit.h:
* dfg/DFGOSRExitCompilationInfo.h:
(JSC::DFG::OSRExitCompilationInfo::OSRExitCompilationInfo):
* dfg/DFGOSRExitCompiler.cpp:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::speculationWatchpoint):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
2013-10-28 Myles C. Maxfield <mmaxfield@apple.com>
Parsing support for -webkit-text-decoration-skip: ink
......
......@@ -44,8 +44,12 @@ const char* exitKindToString(ExitKind kind)
return "BadExecutable";
case BadCache:
return "BadCache";
case BadCacheWatchpoint:
return "BadCacheWatchpoint";
case BadWeakConstantCache:
return "BadWeakConstantCache";
case BadWeakConstantCacheWatchpoint:
return "BadWeakConstantCacheWatchpoint";
case BadIndexingType:
return "BadIndexingType";
case Overflow:
......
......@@ -35,6 +35,8 @@ enum ExitKind {
BadExecutable, // We exited because we made an incorrect assumption about what executable we would see.
BadCache, // We exited because an inline cache was wrong.
BadWeakConstantCache, // We exited because a cache on a weak constant (usually a prototype) was wrong.
BadCacheWatchpoint, // Same as BadCache but from a watchpoint.
BadWeakConstantCacheWatchpoint, // Same as BadWeakConstantCache but from a watchpoint.
BadIndexingType, // We exited because an indexing type was wrong.
Overflow, // We exited because of overflow.
NegativeZero, // We exited because we encountered negative zero.
......@@ -54,6 +56,18 @@ enum ExitKind {
const char* exitKindToString(ExitKind);
bool exitKindIsCountable(ExitKind);
inline bool isWatchpoint(ExitKind kind)
{
switch (kind) {
case BadCacheWatchpoint:
case BadWeakConstantCacheWatchpoint:
case UncountableWatchpoint:
return true;
default:
return false;
}
}
} // namespace JSC
namespace WTF {
......
......@@ -311,7 +311,8 @@ private:
VariableAccessData* variableAccessData = newVariableAccessData(operand, isCaptured);
variableAccessData->mergeStructureCheckHoistingFailed(
m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache));
m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
|| m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCacheWatchpoint));
variableAccessData->mergeCheckArrayHoistingFailed(
m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIndexingType));
Node* node = addToGraph(SetLocal, OpInfo(variableAccessData), value);
......@@ -367,7 +368,8 @@ private:
variableAccessData->mergeShouldNeverUnbox(true);
variableAccessData->mergeStructureCheckHoistingFailed(
m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache));
m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
|| m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCacheWatchpoint));
variableAccessData->mergeCheckArrayHoistingFailed(
m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIndexingType));
Node* node = addToGraph(SetLocal, OpInfo(variableAccessData), value);
......@@ -1141,7 +1143,9 @@ void ByteCodeParser::handleCall(Instruction* currentInstruction, NodeType op, Co
else {
callLinkStatus = CallLinkStatus::computeFor(m_inlineStackTop->m_profiledBlock, m_currentIndex);
callLinkStatus.setHasBadFunctionExitSite(m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadFunction));
callLinkStatus.setHasBadCacheExitSite(m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache));
callLinkStatus.setHasBadCacheExitSite(
m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
|| m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCacheWatchpoint));
callLinkStatus.setHasBadExecutableExitSite(m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadExecutable));
}
......@@ -1762,7 +1766,9 @@ void ByteCodeParser::handleGetById(
{
if (!getByIdStatus.isSimple()
|| m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
|| m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadWeakConstantCache)) {
|| m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCacheWatchpoint)
|| m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadWeakConstantCache)
|| m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadWeakConstantCacheWatchpoint)) {
set(VirtualRegister(destinationOperand),
addToGraph(
getByIdStatus.makesCalls() ? GetByIdFlush : GetById,
......@@ -1846,7 +1852,8 @@ bool ByteCodeParser::parseBlock(unsigned limit)
VariableAccessData* variable = newVariableAccessData(
virtualRegisterForArgument(argument), m_codeBlock->isCaptured(virtualRegisterForArgument(argument)));
variable->mergeStructureCheckHoistingFailed(
m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache));
m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
|| m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCacheWatchpoint));
variable->mergeCheckArrayHoistingFailed(
m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIndexingType));
......@@ -1903,7 +1910,8 @@ bool ByteCodeParser::parseBlock(unsigned limit)
if (!cachedStructure
|| cachedStructure->classInfo()->methodTable.toThis != JSObject::info()->methodTable.toThis
|| m_inlineStackTop->m_profiledBlock->couldTakeSlowCase(m_currentIndex)
|| m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)) {
|| m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
|| m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCacheWatchpoint)) {
setThis(addToGraph(ToThis, op1));
} else {
addToGraph(
......@@ -2473,7 +2481,9 @@ bool ByteCodeParser::parseBlock(unsigned limit)
bool hasExitSite =
m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)
|| m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadWeakConstantCache);
|| m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCacheWatchpoint)
|| m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadWeakConstantCache)
|| m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadWeakConstantCacheWatchpoint);
if (!hasExitSite && putByIdStatus.isSimpleReplace()) {
addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(putByIdStatus.oldStructure())), base);
......
......@@ -64,26 +64,26 @@ void JITCompiler::linkOSRExits()
ASSERT(m_jitCode->osrExit.size() == m_exitCompilationInfo.size());
if (m_graph.compilation()) {
for (unsigned i = 0; i < m_jitCode->osrExit.size(); ++i) {
OSRExit& exit = m_jitCode->osrExit[i];
OSRExitCompilationInfo& info = m_exitCompilationInfo[i];
Vector<Label> labels;
if (exit.m_watchpointIndex == std::numeric_limits<unsigned>::max()) {
OSRExitCompilationInfo& info = m_exitCompilationInfo[i];
if (info.m_watchpointIndex == std::numeric_limits<unsigned>::max()) {
for (unsigned j = 0; j < info.m_failureJumps.jumps().size(); ++j)
labels.append(info.m_failureJumps.jumps()[j].label());
} else
labels.append(m_jitCode->watchpoints[exit.m_watchpointIndex].sourceLabel());
labels.append(m_jitCode->watchpoints[info.m_watchpointIndex].sourceLabel());
m_exitSiteLabels.append(labels);
}
}
for (unsigned i = 0; i < m_jitCode->osrExit.size(); ++i) {
OSRExit& exit = m_jitCode->osrExit[i];
JumpList& failureJumps = m_exitCompilationInfo[i].m_failureJumps;
ASSERT(failureJumps.empty() == (exit.m_watchpointIndex != std::numeric_limits<unsigned>::max()));
if (exit.m_watchpointIndex == std::numeric_limits<unsigned>::max())
OSRExitCompilationInfo& info = m_exitCompilationInfo[i];
JumpList& failureJumps = info.m_failureJumps;
ASSERT(failureJumps.empty() == (info.m_watchpointIndex != std::numeric_limits<unsigned>::max()));
if (info.m_watchpointIndex == std::numeric_limits<unsigned>::max())
failureJumps.link(this);
else
m_jitCode->watchpoints[exit.m_watchpointIndex].setDestination(label());
m_jitCode->watchpoints[info.m_watchpointIndex].setDestination(label());
jitAssertHasValidCallFrame();
store32(TrustedImm32(i), &vm()->osrExitIndex);
exit.setPatchableCodeOffset(patchableJump());
......@@ -254,10 +254,11 @@ void JITCompiler::link(LinkBuffer& linkBuffer)
CodeLocationLabel target = CodeLocationLabel(osrExitThunk.code());
for (unsigned i = 0; i < m_jitCode->osrExit.size(); ++i) {
OSRExit& exit = m_jitCode->osrExit[i];
OSRExitCompilationInfo& info = m_exitCompilationInfo[i];
linkBuffer.link(exit.getPatchableCodeOffsetAsJump(), target);
exit.correctJump(linkBuffer);
if (exit.m_watchpointIndex != std::numeric_limits<unsigned>::max())
m_jitCode->watchpoints[exit.m_watchpointIndex].correctLabels(linkBuffer);
if (info.m_watchpointIndex != std::numeric_limits<unsigned>::max())
m_jitCode->watchpoints[info.m_watchpointIndex].correctLabels(linkBuffer);
}
if (m_graph.compilation()) {
......
......@@ -197,11 +197,12 @@ public:
m_exceptionChecks.append(branchTestPtr(Zero, GPRInfo::returnValueGPR));
}
void appendExitInfo(MacroAssembler::JumpList jumpsToFail = MacroAssembler::JumpList())
OSRExitCompilationInfo& appendExitInfo(MacroAssembler::JumpList jumpsToFail = MacroAssembler::JumpList())
{
OSRExitCompilationInfo info;
info.m_failureJumps = jumpsToFail;
m_exitCompilationInfo.append(info);
return m_exitCompilationInfo.last();
}
#if USE(JSVALUE32_64)
......@@ -353,7 +354,7 @@ private:
Vector<InlineCacheWrapper<JITPutByIdGenerator>, 4> m_putByIds;
Vector<InRecord, 4> m_ins;
Vector<JSCallRecord, 4> m_jsCalls;
Vector<OSRExitCompilationInfo> m_exitCompilationInfo;
SegmentedVector<OSRExitCompilationInfo, 4> m_exitCompilationInfo;
Vector<Vector<Label>> m_exitSiteLabels;
Call m_callArityFixup;
......
......@@ -41,7 +41,6 @@ OSRExit::OSRExit(ExitKind kind, JSValueSource jsValueSource, MethodOfGettingAVal
, m_valueProfile(valueProfile)
, m_patchableCodeOffset(0)
, m_recoveryIndex(recoveryIndex)
, m_watchpointIndex(std::numeric_limits<unsigned>::max())
, m_streamIndex(streamIndex)
, m_lastSetOperand(jit->m_lastSetOperand)
{
......
......@@ -96,7 +96,6 @@ struct OSRExit : public OSRExitBase {
unsigned m_patchableCodeOffset;
unsigned m_recoveryIndex;
unsigned m_watchpointIndex;
void setPatchableCodeOffset(MacroAssembler::PatchableJump);
MacroAssembler::Jump getPatchableCodeOffsetAsJump() const;
......
......@@ -37,7 +37,13 @@
namespace JSC { namespace DFG {
struct OSRExitCompilationInfo {
OSRExitCompilationInfo()
: m_watchpointIndex(std::numeric_limits<unsigned>::max())
{
}
MacroAssembler::JumpList m_failureJumps;
unsigned m_watchpointIndex;
};
} } // namespace JSC::DFG
......
......@@ -95,8 +95,7 @@ void compileOSRExit(ExecState* exec)
Profiler::OSRExit* profilerExit = compilation->addOSRExit(
exitIndex, Profiler::OriginStack(database, codeBlock, exit.m_codeOrigin),
exit.m_kind,
exit.m_watchpointIndex != std::numeric_limits<unsigned>::max());
exit.m_kind, isWatchpoint(exit.m_kind));
jit.add64(CCallHelpers::TrustedImm32(1), CCallHelpers::AbsoluteAddress(profilerExit->counterAddress()));
}
......
......@@ -205,17 +205,16 @@ JumpReplacementWatchpoint* SpeculativeJIT::speculationWatchpoint(ExitKind kind,
if (!m_compileOkay)
return 0;
ASSERT(m_isCheckingArgumentTypes || m_canExit);
m_jit.appendExitInfo(JITCompiler::JumpList());
OSRExit& exit = m_jit.jitCode()->osrExit[
m_jit.jitCode()->appendOSRExit(OSRExit(
kind, jsValueSource,
m_jit.graph().methodOfGettingAValueProfileFor(node),
this, m_stream->size()))];
exit.m_watchpointIndex = m_jit.jitCode()->appendWatchpoint(
OSRExitCompilationInfo& info = m_jit.appendExitInfo(JITCompiler::JumpList());
m_jit.jitCode()->appendOSRExit(OSRExit(
kind, jsValueSource,
m_jit.graph().methodOfGettingAValueProfileFor(node),
this, m_stream->size()));
info.m_watchpointIndex = m_jit.jitCode()->appendWatchpoint(
JumpReplacementWatchpoint(m_jit.watchpointLabel()));
if (m_speculationDirection == ForwardSpeculation)
convertLastOSRExitToForward();
return &m_jit.jitCode()->watchpoints[exit.m_watchpointIndex];
return &m_jit.jitCode()->watchpoints[info.m_watchpointIndex];
}
JumpReplacementWatchpoint* SpeculativeJIT::speculationWatchpoint(ExitKind kind)
......
......@@ -3903,7 +3903,7 @@ void SpeculativeJIT::compile(Node* node)
m_jit.addWeakReference(node->structure());
m_jit.addLazily(
speculationWatchpoint(
node->child1()->op() == WeakJSConstant ? BadWeakConstantCache : BadCache),
node->child1()->op() == WeakJSConstant ? BadWeakConstantCacheWatchpoint : BadCacheWatchpoint),
node->structure()->transitionWatchpointSet());
#if !ASSERT_DISABLED
......
......@@ -4197,7 +4197,7 @@ void SpeculativeJIT::compile(Node* node)
m_jit.addWeakReference(node->structure());
m_jit.addLazily(
speculationWatchpoint(
node->child1()->op() == WeakJSConstant ? BadWeakConstantCache : BadCache),
node->child1()->op() == WeakJSConstant ? BadWeakConstantCacheWatchpoint : BadCacheWatchpoint),
node->structure()->transitionWatchpointSet());
#if !ASSERT_DISABLED
......
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