Commit 25e78934 authored by mhahnenberg@apple.com's avatar mhahnenberg@apple.com

<https://webkit.org/b/119919> Concurrent JIT crashes in various fast/js/dfg-*...

<https://webkit.org/b/119919> Concurrent JIT crashes in various fast/js/dfg-* tests while the main thread is setting innerHTML

Reviewed by Geoffrey Garen.

More fixes for WriteBarrier deferral during concurrent JIT-ing. This patch makes the use of DesiredWriteBarriers class and the 
initializeLazyWriteBarrierFor* wrapper functions more sane. 

Refactored DesiredWriteBarrier to require an owner, a type, a CodeBlock, and an index. The type indicates how to use the CodeBlock
and index when triggering the WriteBarrier at the end of compilation. 

The client code of initializeLazy* is now responsible for creating the WriteBarrier that will be initialized as well as passing
in the relevant index to be used at the end of compilation. Things were kind of muddled before in that one function did a 
little extra work that really shouldn't have been its responsibility.

* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::addConstant):
(JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
* dfg/DFGDesiredWriteBarriers.cpp:
(JSC::DFG::DesiredWriteBarrier::DesiredWriteBarrier):
(JSC::DFG::DesiredWriteBarrier::trigger):
* dfg/DFGDesiredWriteBarriers.h:
(JSC::DFG::DesiredWriteBarriers::add):
(JSC::DFG::initializeLazyWriteBarrierForInlineCallFrameExecutable):
(JSC::DFG::initializeLazyWriteBarrierForInlineCallFrameCallee):
(JSC::DFG::initializeLazyWriteBarrierForConstant):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::truncateConstantToInt32):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::constantRegisterForConstant):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@154351 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 6f7f26cc
2013-08-20 Mark Hahnenberg <mhahnenberg@apple.com>
<https://webkit.org/b/119919> Concurrent JIT crashes in various fast/js/dfg-* tests while the main thread is setting innerHTML
Reviewed by Geoffrey Garen.
More fixes for WriteBarrier deferral during concurrent JIT-ing. This patch makes the use of DesiredWriteBarriers class and the
initializeLazyWriteBarrierFor* wrapper functions more sane.
Refactored DesiredWriteBarrier to require an owner, a type, a CodeBlock, and an index. The type indicates how to use the CodeBlock
and index when triggering the WriteBarrier at the end of compilation.
The client code of initializeLazy* is now responsible for creating the WriteBarrier that will be initialized as well as passing
in the relevant index to be used at the end of compilation. Things were kind of muddled before in that one function did a
little extra work that really shouldn't have been its responsibility.
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::addConstant):
(JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
* dfg/DFGDesiredWriteBarriers.cpp:
(JSC::DFG::DesiredWriteBarrier::DesiredWriteBarrier):
(JSC::DFG::DesiredWriteBarrier::trigger):
* dfg/DFGDesiredWriteBarriers.h:
(JSC::DFG::DesiredWriteBarriers::add):
(JSC::DFG::initializeLazyWriteBarrierForInlineCallFrameExecutable):
(JSC::DFG::initializeLazyWriteBarrierForInlineCallFrameCallee):
(JSC::DFG::initializeLazyWriteBarrierForConstant):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::truncateConstantToInt32):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::constantRegisterForConstant):
2013-08-20 Michael Saboff <msaboff@apple.com>
https://bugs.webkit.org/show_bug.cgi?id=120075
......
......@@ -403,9 +403,12 @@ private:
void addConstant(JSValue value)
{
unsigned constantIndex = m_codeBlock->addConstantLazily();
initializeLazyWriteBarrierForConstant(
m_graph.m_plan.writeBarriers,
m_codeBlock->constants()[constantIndex],
m_codeBlock,
m_graph.m_plan.writeBarriers,
constantIndex,
m_codeBlock->ownerExecutable(),
value);
}
......@@ -3290,16 +3293,20 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry(
ASSERT(callsiteBlockHead);
InlineCallFrame inlineCallFrame;
initializeLazyWriteBarrier(
inlineCallFrame.executable,
initializeLazyWriteBarrierForInlineCallFrameExecutable(
byteCodeParser->m_graph.m_plan.writeBarriers,
inlineCallFrame.executable,
byteCodeParser->m_codeBlock,
byteCodeParser->m_codeBlock->inlineCallFrames().size(),
byteCodeParser->m_codeBlock->ownerExecutable(),
codeBlock->ownerExecutable());
inlineCallFrame.stackOffset = inlineCallFrameStart + JSStack::CallFrameHeaderSize;
if (callee) {
initializeLazyWriteBarrier(
inlineCallFrame.callee,
initializeLazyWriteBarrierForInlineCallFrameCallee(
byteCodeParser->m_graph.m_plan.writeBarriers,
inlineCallFrame.callee,
byteCodeParser->m_codeBlock,
byteCodeParser->m_codeBlock->inlineCallFrames().size(),
byteCodeParser->m_codeBlock->ownerExecutable(),
callee);
}
......
......@@ -34,33 +34,35 @@
namespace JSC { namespace DFG {
DesiredWriteBarrier::DesiredWriteBarrier(WriteBarrier<Unknown>* barrier, JSCell* owner)
DesiredWriteBarrier::DesiredWriteBarrier(Type type, CodeBlock* codeBlock, unsigned index, JSCell* owner)
: m_owner(owner)
, m_type(NormalType)
, m_type(type)
, m_codeBlock(codeBlock)
, m_index(index)
{
u.m_barrier = barrier;
}
DesiredWriteBarrier::DesiredWriteBarrier(Vector<WriteBarrier<Unknown> >* barriers, unsigned index, JSCell* owner)
: m_owner(owner)
, m_type(VectorType)
{
u.barrier_vector.m_barriers = barriers;
u.barrier_vector.m_index = index;
}
void DesiredWriteBarrier::trigger(VM& vm)
{
switch (m_type) {
case NormalType: {
u.m_barrier->set(vm, m_owner, u.m_barrier->get());
case ConstantType: {
WriteBarrier<Unknown>& barrier = m_codeBlock->constants()[m_index];
barrier.set(vm, m_owner, barrier.get());
break;
}
case VectorType: {
unsigned index = u.barrier_vector.m_index;
WriteBarrier<Unknown>& barrier = u.barrier_vector.m_barriers->at(index);
barrier.set(vm, m_owner, barrier.get());
case InlineCallFrameExecutableType: {
InlineCallFrame& inlineCallFrame = m_codeBlock->inlineCallFrames()[m_index];
WriteBarrier<ScriptExecutable>& executable = inlineCallFrame.executable;
executable.set(vm, m_owner, executable.get());
break;
}
case InlineCallFrameCalleeType: {
InlineCallFrame& inlineCallFrame = m_codeBlock->inlineCallFrames()[m_index];
ASSERT(!!inlineCallFrame.callee);
WriteBarrier<JSFunction>& callee = inlineCallFrame.callee;
callee.set(vm, m_owner, callee.get());
break;
}
......@@ -75,26 +77,12 @@ DesiredWriteBarriers::~DesiredWriteBarriers()
{
}
DesiredWriteBarrier& DesiredWriteBarriers::addImpl(WriteBarrier<Unknown>* barrier, JSCell* owner)
{
m_barriers.append(DesiredWriteBarrier(barrier, owner));
return m_barriers.last();
}
void DesiredWriteBarriers::trigger(VM& vm)
{
for (unsigned i = 0; i < m_barriers.size(); i++)
m_barriers[i].trigger(vm);
}
void initializeLazyWriteBarrierForConstant(CodeBlock* codeBlock, DesiredWriteBarriers& barriers, JSCell* owner, JSValue value)
{
unsigned constantIndex = codeBlock->addConstantLazily();
WriteBarrier<Unknown>& barrier = codeBlock->constants()[constantIndex];
barrier = WriteBarrier<Unknown>(
barriers.add(codeBlock->constants(), constantIndex, owner), value);
}
} } // namespace JSC::DFG
#endif // ENABLE(DFG_JIT)
......@@ -33,28 +33,24 @@
namespace JSC {
class JSFunction;
class ScriptExecutable;
class VM;
namespace DFG {
class DesiredWriteBarrier {
public:
DesiredWriteBarrier(WriteBarrier<Unknown>*, JSCell* owner);
DesiredWriteBarrier(Vector<WriteBarrier<Unknown> >*, unsigned index, JSCell* owner);
enum Type { ConstantType, InlineCallFrameExecutableType, InlineCallFrameCalleeType };
DesiredWriteBarrier(Type, CodeBlock*, unsigned index, JSCell* owner);
void trigger(VM&);
private:
JSCell* m_owner;
enum WriteBarrierType { NormalType, VectorType };
WriteBarrierType m_type;
union {
WriteBarrier<Unknown>* m_barrier;
struct {
Vector<WriteBarrier<Unknown> >* m_barriers;
unsigned m_index;
} barrier_vector;
} u;
Type m_type;
CodeBlock* m_codeBlock;
unsigned m_index;
};
class DesiredWriteBarriers {
......@@ -62,33 +58,35 @@ public:
DesiredWriteBarriers();
~DesiredWriteBarriers();
template <typename T>
DesiredWriteBarrier& add(WriteBarrier<T>& barrier, JSCell* owner)
DesiredWriteBarrier& add(DesiredWriteBarrier::Type type, CodeBlock* codeBlock, unsigned index, JSCell* owner)
{
return addImpl(reinterpret_cast<WriteBarrier<Unknown>*>(&barrier), owner);
}
DesiredWriteBarrier& add(Vector<WriteBarrier<Unknown> >& barriers, unsigned index, JSCell* owner)
{
m_barriers.append(DesiredWriteBarrier(&barriers, index, owner));
m_barriers.append(DesiredWriteBarrier(type, codeBlock, index, owner));
return m_barriers.last();
}
void trigger(VM&);
private:
DesiredWriteBarrier& addImpl(WriteBarrier<Unknown>*, JSCell*);
Vector<DesiredWriteBarrier> m_barriers;
};
template <typename T, typename U>
void initializeLazyWriteBarrier(WriteBarrier<T>& barrier, DesiredWriteBarriers& barriers, JSCell* owner, U value)
inline void initializeLazyWriteBarrierForInlineCallFrameExecutable(DesiredWriteBarriers& barriers, WriteBarrier<ScriptExecutable>& barrier, CodeBlock* codeBlock, unsigned index, JSCell* owner, ScriptExecutable* value)
{
barrier = WriteBarrier<T>(barriers.add(barrier, owner), value);
DesiredWriteBarrier& desiredBarrier = barriers.add(DesiredWriteBarrier::InlineCallFrameExecutableType, codeBlock, index, owner);
barrier = WriteBarrier<ScriptExecutable>(desiredBarrier, value);
}
void initializeLazyWriteBarrierForConstant(CodeBlock*, DesiredWriteBarriers&, JSCell* owner, JSValue);
inline void initializeLazyWriteBarrierForInlineCallFrameCallee(DesiredWriteBarriers& barriers, WriteBarrier<JSFunction>& barrier, CodeBlock* codeBlock, unsigned index, JSCell* owner, JSFunction* value)
{
DesiredWriteBarrier& desiredBarrier = barriers.add(DesiredWriteBarrier::InlineCallFrameCalleeType, codeBlock, index, owner);
barrier = WriteBarrier<JSFunction>(desiredBarrier, value);
}
inline void initializeLazyWriteBarrierForConstant(DesiredWriteBarriers& barriers, WriteBarrier<Unknown>& barrier, CodeBlock* codeBlock, unsigned index, JSCell* owner, JSValue value)
{
DesiredWriteBarrier& desiredBarrier = barriers.add(DesiredWriteBarrier::ConstantType, codeBlock, index, owner);
barrier = WriteBarrier<Unknown>(desiredBarrier, value);
}
} } // namespace JSC::DFG
......
......@@ -1380,9 +1380,12 @@ private:
ASSERT(value.isInt32());
unsigned constantRegister;
if (!codeBlock()->findConstant(value, constantRegister)) {
constantRegister = codeBlock()->addConstantLazily();
initializeLazyWriteBarrierForConstant(
codeBlock(),
m_graph.m_plan.writeBarriers,
codeBlock()->constants()[constantRegister],
codeBlock(),
constantRegister,
codeBlock()->ownerExecutable(),
value);
}
......
......@@ -155,9 +155,12 @@ public:
{
unsigned constantRegister;
if (!m_codeBlock->findConstant(value, constantRegister)) {
constantRegister = m_codeBlock->addConstantLazily();
initializeLazyWriteBarrierForConstant(
m_codeBlock,
m_plan.writeBarriers,
m_codeBlock->constants()[constantRegister],
m_codeBlock,
constantRegister,
m_codeBlock->ownerExecutable(),
value);
}
......
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