ExecutableToCodeBlockEdge.cpp [plain text]
#include "config.h"
#include "ExecutableToCodeBlockEdge.h"
#include "IsoCellSetInlines.h"
namespace JSC {
const ClassInfo ExecutableToCodeBlockEdge::s_info = { "ExecutableToCodeBlockEdge", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(ExecutableToCodeBlockEdge) };
Structure* ExecutableToCodeBlockEdge::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
}
ExecutableToCodeBlockEdge* ExecutableToCodeBlockEdge::create(VM& vm, CodeBlock* codeBlock)
{
ExecutableToCodeBlockEdge* result = new (NotNull, allocateCell<ExecutableToCodeBlockEdge>(vm.heap)) ExecutableToCodeBlockEdge(vm, codeBlock);
result->finishCreation(vm);
return result;
}
void ExecutableToCodeBlockEdge::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
VM& vm = visitor.vm();
ExecutableToCodeBlockEdge* edge = jsCast<ExecutableToCodeBlockEdge*>(cell);
Base::visitChildren(cell, visitor);
CodeBlock* codeBlock = edge->m_codeBlock.get();
if (!codeBlock)
return;
if (!edge->m_isActive) {
visitor.appendUnbarriered(codeBlock);
return;
}
ConcurrentJSLocker locker(codeBlock->m_lock);
if (codeBlock->shouldVisitStrongly(locker))
visitor.appendUnbarriered(codeBlock);
if (!Heap::isMarked(codeBlock))
vm.executableToCodeBlockEdgesWithFinalizers.add(edge);
if (JITCode::isOptimizingJIT(codeBlock->jitType())) {
visitor.append(codeBlock->m_alternative);
}
visitor.appendUnbarriered(codeBlock->globalObject());
vm.executableToCodeBlockEdgesWithConstraints.add(edge);
edge->runConstraint(locker, vm, visitor);
}
void ExecutableToCodeBlockEdge::visitOutputConstraints(JSCell* cell, SlotVisitor& visitor)
{
VM& vm = visitor.vm();
ExecutableToCodeBlockEdge* edge = jsCast<ExecutableToCodeBlockEdge*>(cell);
edge->runConstraint(NoLockingNecessary, vm, visitor);
}
void ExecutableToCodeBlockEdge::finalizeUnconditionally(VM& vm)
{
CodeBlock* codeBlock = m_codeBlock.get();
if (!Heap::isMarked(codeBlock)) {
if (codeBlock->shouldJettisonDueToWeakReference())
codeBlock->jettison(Profiler::JettisonDueToWeakReference);
else
codeBlock->jettison(Profiler::JettisonDueToOldAge);
m_codeBlock.clear();
}
vm.executableToCodeBlockEdgesWithFinalizers.remove(this);
vm.executableToCodeBlockEdgesWithConstraints.remove(this);
}
void ExecutableToCodeBlockEdge::activate()
{
m_isActive = true;
}
void ExecutableToCodeBlockEdge::deactivate()
{
m_isActive = false;
}
CodeBlock* ExecutableToCodeBlockEdge::deactivateAndUnwrap(ExecutableToCodeBlockEdge* edge)
{
if (!edge)
return nullptr;
edge->deactivate();
return edge->codeBlock();
}
ExecutableToCodeBlockEdge* ExecutableToCodeBlockEdge::wrap(CodeBlock* codeBlock)
{
if (!codeBlock)
return nullptr;
return codeBlock->ownerEdge();
}
ExecutableToCodeBlockEdge* ExecutableToCodeBlockEdge::wrapAndActivate(CodeBlock* codeBlock)
{
if (!codeBlock)
return nullptr;
ExecutableToCodeBlockEdge* result = codeBlock->ownerEdge();
result->activate();
return result;
}
ExecutableToCodeBlockEdge::ExecutableToCodeBlockEdge(VM& vm, CodeBlock* codeBlock)
: Base(vm, vm.executableToCodeBlockEdgeStructure.get())
, m_codeBlock(vm, this, codeBlock)
{
}
void ExecutableToCodeBlockEdge::runConstraint(const ConcurrentJSLocker& locker, VM& vm, SlotVisitor& visitor)
{
CodeBlock* codeBlock = m_codeBlock.get();
codeBlock->propagateTransitions(locker, visitor);
codeBlock->determineLiveness(locker, visitor);
if (Heap::isMarked(codeBlock))
vm.executableToCodeBlockEdgesWithConstraints.remove(this);
}
}