BytecodeOperandsForCheckpoint.h [plain text]
#pragma once
#include "ArrayProfile.h"
#include "BytecodeStructs.h"
#include "ValueProfile.h"
namespace JSC {
template<typename BytecodeMetadata>
ArrayProfile* arrayProfileForImpl(BytecodeMetadata& metadata, unsigned checkpointIndex)
{
UNUSED_PARAM(checkpointIndex);
return &metadata.m_callLinkInfo.m_arrayProfile;
}
template<typename BytecodeMetadata>
bool hasArrayProfileFor(BytecodeMetadata& metadata, unsigned checkpointIndex)
{
return arrayProfileForImpl(metadata, checkpointIndex);
}
template<typename BytecodeMetadata>
ArrayProfile& arrayProfileFor(BytecodeMetadata& metadata, unsigned checkpointIndex)
{
ASSERT(hasArrayProfileFor(metadata, checkpointIndex));
return *arrayProfileForImpl(metadata, checkpointIndex);
}
template<typename BytecodeMetadata>
ValueProfile* valueProfileForImpl(BytecodeMetadata& metadata, unsigned checkpointIndex)
{
UNUSED_PARAM(checkpointIndex);
if constexpr (BytecodeMetadata::opcodeID == op_iterator_open) {
switch (checkpointIndex) {
case OpIteratorOpen::symbolCall: return &metadata.m_iteratorProfile;
case OpIteratorOpen::getNext: return &metadata.m_nextProfile;
default: RELEASE_ASSERT_NOT_REACHED();
}
} else if constexpr (BytecodeMetadata::opcodeID == op_iterator_next) {
switch (checkpointIndex) {
case OpIteratorNext::computeNext: return &metadata.m_nextResultProfile;
case OpIteratorNext::getDone: return &metadata.m_doneProfile;
case OpIteratorNext::getValue: return &metadata.m_valueProfile;
default: RELEASE_ASSERT_NOT_REACHED();
}
} else
return &metadata.m_profile;
}
template<typename BytecodeMetadata>
bool hasValueProfileFor(BytecodeMetadata& metadata, unsigned checkpointIndex)
{
return valueProfileForImpl(metadata, checkpointIndex);
}
template<typename BytecodeMetadata>
ValueProfile& valueProfileFor(BytecodeMetadata& metadata, unsigned checkpointIndex)
{
ASSERT(hasValueProfileFor(metadata, checkpointIndex));
return *valueProfileForImpl(metadata, checkpointIndex);
}
template<typename Bytecode>
Operand destinationFor(const Bytecode& bytecode, unsigned checkpointIndex, JITType type = JITType::None)
{
UNUSED_PARAM(checkpointIndex);
if constexpr (Bytecode::opcodeID == op_iterator_open) {
switch (checkpointIndex) {
case OpIteratorOpen::symbolCall: return bytecode.m_iterator;
case OpIteratorOpen::getNext: return bytecode.m_next;
default: RELEASE_ASSERT_NOT_REACHED();
}
return { };
} else if constexpr (Bytecode::opcodeID == op_iterator_next) {
switch (checkpointIndex) {
case OpIteratorNext::computeNext: {
if (type == JITType::DFGJIT || type == JITType::FTLJIT)
return Operand::tmp(OpIteratorNext::nextResult);
return bytecode.m_value; }
case OpIteratorNext::getDone: return bytecode.m_done;
case OpIteratorNext::getValue: return bytecode.m_value;
default: RELEASE_ASSERT_NOT_REACHED();
}
return { };
} else
return bytecode.m_dst;
}
template<typename Bytecode>
VirtualRegister calleeFor(const Bytecode& bytecode, unsigned checkpointIndex)
{
UNUSED_PARAM(checkpointIndex);
if constexpr (Bytecode::opcodeID == op_iterator_open) {
ASSERT(checkpointIndex == OpIteratorOpen::symbolCall);
return bytecode.m_symbolIterator;
} else if constexpr (Bytecode::opcodeID == op_iterator_next) {
ASSERT(checkpointIndex == OpIteratorNext::computeNext);
return bytecode.m_next;
} else
return bytecode.m_callee;
}
template<typename Bytecode>
unsigned argumentCountIncludingThisFor(const Bytecode& bytecode, unsigned checkpointIndex)
{
UNUSED_PARAM(checkpointIndex);
if constexpr (Bytecode::opcodeID == op_iterator_open) {
ASSERT(checkpointIndex == OpIteratorOpen::symbolCall);
return 1;
} else if constexpr (Bytecode::opcodeID == op_iterator_next) {
ASSERT(checkpointIndex == OpIteratorNext::computeNext);
return 1;
} else
return bytecode.m_argc;
}
template<typename Bytecode>
ptrdiff_t stackOffsetInRegistersForCall(const Bytecode& bytecode, unsigned checkpointIndex)
{
UNUSED_PARAM(checkpointIndex);
if constexpr (Bytecode::opcodeID == op_iterator_open) {
ASSERT(checkpointIndex == OpIteratorOpen::symbolCall);
return CallFrame::headerSizeInRegisters - bytecode.m_iterable.offset();
} else if constexpr (Bytecode::opcodeID == op_iterator_next) {
ASSERT(checkpointIndex == OpIteratorNext::computeNext);
return CallFrame::headerSizeInRegisters - bytecode.m_iterator.offset();
} else
return bytecode.m_argv;
}
template<typename BytecodeMetadata>
LLIntCallLinkInfo& callLinkInfoFor(BytecodeMetadata& metadata, unsigned checkpointIndex)
{
UNUSED_PARAM(checkpointIndex);
return metadata.m_callLinkInfo;
}
}