LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp [plain text]
#include "config.h"
#include "LLIntPrototypeLoadAdaptiveStructureWatchpoint.h"
#include "CodeBlock.h"
#include "Instruction.h"
#include "JSCellInlines.h"
namespace JSC {
LLIntPrototypeLoadAdaptiveStructureWatchpoint::LLIntPrototypeLoadAdaptiveStructureWatchpoint(CodeBlock* owner, const ObjectPropertyCondition& key, unsigned bytecodeOffset)
: Watchpoint(Watchpoint::Type::LLIntPrototypeLoadAdaptiveStructure)
, m_owner(owner)
, m_bytecodeOffset(bytecodeOffset)
, m_key(key)
{
RELEASE_ASSERT(key.watchingRequiresStructureTransitionWatchpoint());
RELEASE_ASSERT(!key.watchingRequiresReplacementWatchpoint());
}
void LLIntPrototypeLoadAdaptiveStructureWatchpoint::install(VM& vm)
{
RELEASE_ASSERT(m_key.isWatchable());
m_key.object()->structure(vm)->addTransitionWatchpoint(this);
}
void LLIntPrototypeLoadAdaptiveStructureWatchpoint::fireInternal(VM& vm, const FireDetail&)
{
if (!m_owner->isLive())
return;
if (m_key.isWatchable(PropertyCondition::EnsureWatchability)) {
install(vm);
return;
}
auto& instruction = m_owner->instructions().at(m_bytecodeOffset.get());
switch (instruction->opcodeID()) {
case op_get_by_id:
clearLLIntGetByIdCache(instruction->as<OpGetById>().metadata(m_owner.get()).m_modeMetadata);
break;
case op_iterator_open:
clearLLIntGetByIdCache(instruction->as<OpIteratorOpen>().metadata(m_owner.get()).m_modeMetadata);
break;
case op_iterator_next: {
auto& metadata = instruction->as<OpIteratorNext>().metadata(m_owner.get());
clearLLIntGetByIdCache(metadata.m_doneModeMetadata);
clearLLIntGetByIdCache(metadata.m_valueModeMetadata);
break;
}
default:
RELEASE_ASSERT_NOT_REACHED();
break;
}
}
void LLIntPrototypeLoadAdaptiveStructureWatchpoint::clearLLIntGetByIdCache(GetByIdModeMetadata& metadata)
{
metadata.clearToDefaultModeWithoutCache();
}
}