本文整理汇总了C++中VariableAccessData类的典型用法代码示例。如果您正苦于以下问题:C++ VariableAccessData类的具体用法?C++ VariableAccessData怎么用?C++ VariableAccessData使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了VariableAccessData类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: switch
void LocalOSRAvailabilityCalculator::executeNode(Node* node)
{
switch (node->op()) {
case SetLocal: {
VariableAccessData* variable = node->variableAccessData();
m_availability.operand(variable->local()) =
Availability(node->child1().node(), variable->flushedAt());
break;
}
case GetArgument: {
VariableAccessData* variable = node->variableAccessData();
m_availability.operand(variable->local()) =
Availability(node, variable->flushedAt());
break;
}
case MovHint: {
m_availability.operand(node->unlinkedLocal()) =
Availability(node->child1().node());
break;
}
case ZombieHint: {
m_availability.operand(node->unlinkedLocal()) =
Availability::unavailable();
break;
}
default:
break;
}
}
示例2: switch
void LocalOSRAvailabilityCalculator::executeNode(Node* node)
{
switch (node->op()) {
case PutLocal: {
VariableAccessData* variable = node->variableAccessData();
m_availability.m_locals.operand(variable->local()).setFlush(variable->flushedAt());
break;
}
case KillLocal: {
m_availability.m_locals.operand(node->unlinkedLocal()).setFlush(FlushedAt(ConflictingFlush));
break;
}
case GetLocal: {
VariableAccessData* variable = node->variableAccessData();
m_availability.m_locals.operand(variable->local()) =
Availability(node, variable->flushedAt());
break;
}
case MovHint: {
m_availability.m_locals.operand(node->unlinkedLocal()).setNode(node->child1().node());
break;
}
case ZombieHint: {
m_availability.m_locals.operand(node->unlinkedLocal()).setNodeUnavailable();
break;
}
case LoadVarargs: {
LoadVarargsData* data = node->loadVarargsData();
m_availability.m_locals.operand(data->count) =
Availability(FlushedAt(FlushedInt32, data->machineCount));
for (unsigned i = data->limit; i--;) {
m_availability.m_locals.operand(VirtualRegister(data->start.offset() + i)) =
Availability(FlushedAt(FlushedJSValue, VirtualRegister(data->machineStart.offset() + i)));
}
break;
}
default:
break;
}
promoteHeapAccess(
node,
[&] (PromotedHeapLocation location, Edge value) {
m_availability.m_heap.set(location, Availability(value.node()));
},
[&] (PromotedHeapLocation) { });
}
示例3: noticeOSREntry
void JITCompiler::noticeOSREntry(BasicBlock& basicBlock, JITCompiler::Label blockHead, LinkBuffer& linkBuffer)
{
// OSR entry is not allowed into blocks deemed unreachable by control flow analysis.
if (!basicBlock.intersectionOfCFAHasVisited)
return;
OSREntryData* entry = m_jitCode->appendOSREntryData(basicBlock.bytecodeBegin, linkBuffer.offsetOf(blockHead));
entry->m_expectedValues = basicBlock.intersectionOfPastValuesAtHead;
// Fix the expected values: in our protocol, a dead variable will have an expected
// value of (None, []). But the old JIT may stash some values there. So we really
// need (Top, TOP).
for (size_t argument = 0; argument < basicBlock.variablesAtHead.numberOfArguments(); ++argument) {
Node* node = basicBlock.variablesAtHead.argument(argument);
if (!node || !node->shouldGenerate())
entry->m_expectedValues.argument(argument).makeHeapTop();
}
for (size_t local = 0; local < basicBlock.variablesAtHead.numberOfLocals(); ++local) {
Node* node = basicBlock.variablesAtHead.local(local);
if (!node || !node->shouldGenerate())
entry->m_expectedValues.local(local).makeHeapTop();
else {
VariableAccessData* variable = node->variableAccessData();
entry->m_machineStackUsed.set(variable->machineLocal().toLocal());
switch (variable->flushFormat()) {
case FlushedDouble:
entry->m_localsForcedDouble.set(local);
break;
case FlushedInt52:
entry->m_localsForcedMachineInt.set(local);
break;
default:
break;
}
if (variable->local() != variable->machineLocal()) {
entry->m_reshufflings.append(
OSREntryReshuffling(
variable->local().offset(), variable->machineLocal().offset()));
}
}
}
entry->m_reshufflings.shrinkToFit();
}
示例4: switch
void LocalOSRAvailabilityCalculator::executeNode(Node* node)
{
switch (node->op()) {
case SetLocal: {
VariableAccessData* variable = node->variableAccessData();
m_availability.m_locals.operand(variable->local()) =
Availability(node->child1().node(), variable->flushedAt());
break;
}
case GetArgument: {
VariableAccessData* variable = node->variableAccessData();
m_availability.m_locals.operand(variable->local()) =
Availability(node, variable->flushedAt());
break;
}
case MovHint: {
m_availability.m_locals.operand(node->unlinkedLocal()) =
Availability(node->child1().node());
break;
}
case ZombieHint: {
m_availability.m_locals.operand(node->unlinkedLocal()) =
Availability::unavailable();
break;
}
default:
break;
}
promoteHeapAccess(
node,
[&] (PromotedHeapLocation location, Edge value) {
m_availability.m_heap.set(location, Availability(value.node()));
},
[&] (PromotedHeapLocation) { });
}
示例5: propagate
void propagate(Node* node)
{
NodeFlags flags = node->flags() & NodeBytecodeBackPropMask;
switch (node->op()) {
case GetLocal: {
VariableAccessData* variableAccessData = node->variableAccessData();
flags &= ~NodeBytecodeUsesAsInt; // We don't care about cross-block uses-as-int.
m_changed |= variableAccessData->mergeFlags(flags);
break;
}
case SetLocal: {
VariableAccessData* variableAccessData = node->variableAccessData();
if (!variableAccessData->isLoadedFrom())
break;
flags = variableAccessData->flags();
RELEASE_ASSERT(!(flags & ~NodeBytecodeBackPropMask));
flags |= NodeBytecodeUsesAsNumber; // Account for the fact that control flow may cause overflows that our modeling can't handle.
node->child1()->mergeFlags(flags);
break;
}
case Flush: {
VariableAccessData* variableAccessData = node->variableAccessData();
m_changed |= variableAccessData->mergeFlags(NodeBytecodeUsesAsValue);
break;
}
case MovHint:
case Check:
break;
case BitAnd:
case BitOr:
case BitXor:
case BitRShift:
case BitLShift:
case BitURShift:
case ArithIMul: {
flags |= NodeBytecodeUsesAsInt;
flags &= ~(NodeBytecodeUsesAsNumber | NodeBytecodeNeedsNegZero | NodeBytecodeUsesAsOther);
flags &= ~NodeBytecodeUsesAsArrayIndex;
node->child1()->mergeFlags(flags);
node->child2()->mergeFlags(flags);
break;
}
case StringCharCodeAt: {
node->child1()->mergeFlags(NodeBytecodeUsesAsValue);
node->child2()->mergeFlags(NodeBytecodeUsesAsValue | NodeBytecodeUsesAsInt | NodeBytecodeUsesAsArrayIndex);
break;
}
case UInt32ToNumber: {
node->child1()->mergeFlags(flags);
break;
}
case ValueAdd: {
if (isNotNegZero(node->child1().node()) || isNotNegZero(node->child2().node()))
flags &= ~NodeBytecodeNeedsNegZero;
if (node->child1()->hasNumberResult() || node->child2()->hasNumberResult())
flags &= ~NodeBytecodeUsesAsOther;
if (!isWithinPowerOfTwo<32>(node->child1()) && !isWithinPowerOfTwo<32>(node->child2()))
flags |= NodeBytecodeUsesAsNumber;
if (!m_allowNestedOverflowingAdditions)
flags |= NodeBytecodeUsesAsNumber;
node->child1()->mergeFlags(flags);
node->child2()->mergeFlags(flags);
break;
}
case ArithAdd: {
flags &= ~NodeBytecodeUsesAsOther;
if (isNotNegZero(node->child1().node()) || isNotNegZero(node->child2().node()))
flags &= ~NodeBytecodeNeedsNegZero;
if (!isWithinPowerOfTwo<32>(node->child1()) && !isWithinPowerOfTwo<32>(node->child2()))
flags |= NodeBytecodeUsesAsNumber;
if (!m_allowNestedOverflowingAdditions)
flags |= NodeBytecodeUsesAsNumber;
node->child1()->mergeFlags(flags);
node->child2()->mergeFlags(flags);
break;
}
case ArithClz32: {
flags &= ~(NodeBytecodeUsesAsNumber | NodeBytecodeNeedsNegZero | NodeBytecodeUsesAsOther | ~NodeBytecodeUsesAsArrayIndex);
flags |= NodeBytecodeUsesAsInt;
node->child1()->mergeFlags(flags);
break;
}
case ArithSub: {
flags &= ~NodeBytecodeUsesAsOther;
if (isNotNegZero(node->child1().node()) || isNotPosZero(node->child2().node()))
flags &= ~NodeBytecodeNeedsNegZero;
if (!isWithinPowerOfTwo<32>(node->child1()) && !isWithinPowerOfTwo<32>(node->child2()))
//.........这里部分代码省略.........
示例6: run
bool run()
{
RELEASE_ASSERT(m_graph.m_plan.mode == FTLForOSREntryMode);
RELEASE_ASSERT(m_graph.m_form == ThreadedCPS);
unsigned bytecodeIndex = m_graph.m_plan.osrEntryBytecodeIndex;
RELEASE_ASSERT(bytecodeIndex);
RELEASE_ASSERT(bytecodeIndex != UINT_MAX);
// Needed by createPreHeader().
m_graph.ensureDominators();
CodeBlock* baseline = m_graph.m_profiledBlock;
BasicBlock* target = 0;
for (unsigned blockIndex = m_graph.numBlocks(); blockIndex--;) {
BasicBlock* block = m_graph.block(blockIndex);
if (!block)
continue;
unsigned nodeIndex = 0;
Node* firstNode = block->at(0);
while (firstNode->isSemanticallySkippable())
firstNode = block->at(++nodeIndex);
if (firstNode->op() == LoopHint
&& firstNode->origin.semantic == CodeOrigin(bytecodeIndex)) {
target = block;
break;
}
}
if (!target) {
// This is a terrible outcome. It shouldn't often happen but it might
// happen and so we should defend against it. If it happens, then this
// compilation is a failure.
return false;
}
BlockInsertionSet insertionSet(m_graph);
// We say that the execution count of the entry block is 1, because we know for sure
// that this must be the case. Under our definition of executionCount, "1" means "once
// per invocation". We could have said NaN here, since that would ask any clients of
// executionCount to use best judgement - but that seems unnecessary since we know for
// sure what the executionCount should be in this case.
BasicBlock* newRoot = insertionSet.insert(0, 1);
// We'd really like to use an unset origin, but ThreadedCPS won't allow that.
NodeOrigin origin = NodeOrigin(CodeOrigin(0), CodeOrigin(0), false);
Vector<Node*> locals(baseline->m_numCalleeLocals);
for (int local = 0; local < baseline->m_numCalleeLocals; ++local) {
Node* previousHead = target->variablesAtHead.local(local);
if (!previousHead)
continue;
VariableAccessData* variable = previousHead->variableAccessData();
locals[local] = newRoot->appendNode(
m_graph, variable->prediction(), ExtractOSREntryLocal, origin,
OpInfo(variable->local().offset()));
newRoot->appendNode(
m_graph, SpecNone, MovHint, origin, OpInfo(variable->local().offset()),
Edge(locals[local]));
}
// Now use the origin of the target, since it's not OK to exit, and we will probably hoist
// type checks to here.
origin = target->at(0)->origin;
for (int argument = 0; argument < baseline->numParameters(); ++argument) {
Node* oldNode = target->variablesAtHead.argument(argument);
if (!oldNode) {
// Just for sanity, always have a SetArgument even if it's not needed.
oldNode = m_graph.m_arguments[argument];
}
Node* node = newRoot->appendNode(
m_graph, SpecNone, SetArgument, origin,
OpInfo(oldNode->variableAccessData()));
m_graph.m_arguments[argument] = node;
}
for (int local = 0; local < baseline->m_numCalleeLocals; ++local) {
Node* previousHead = target->variablesAtHead.local(local);
if (!previousHead)
continue;
VariableAccessData* variable = previousHead->variableAccessData();
Node* node = locals[local];
newRoot->appendNode(
m_graph, SpecNone, SetLocal, origin, OpInfo(variable), Edge(node));
}
newRoot->appendNode(
m_graph, SpecNone, Jump, origin,
OpInfo(createPreHeader(m_graph, insertionSet, target)));
insertionSet.execute();
m_graph.resetReachability();
m_graph.killUnreachableBlocks();
return true;
}
示例7: run
bool run()
{
for (unsigned i = m_graph.m_variableAccessData.size(); i--;) {
VariableAccessData* variable = &m_graph.m_variableAccessData[i];
if (!variable->isRoot())
continue;
variable->clearVotes();
}
// Identify the set of variables that are always subject to the same structure
// checks. For now, only consider monomorphic structure checks (one structure).
for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
BasicBlock* block = m_graph.m_blocks[blockIndex].get();
if (!block)
continue;
for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
NodeIndex nodeIndex = block->at(indexInBlock);
Node& node = m_graph[nodeIndex];
if (!node.shouldGenerate())
continue;
switch (node.op()) {
case CheckStructure: {
Node& child = m_graph[node.child1()];
if (child.op() != GetLocal)
break;
VariableAccessData* variable = child.variableAccessData();
variable->vote(VoteStructureCheck);
if (variable->isCaptured() || variable->structureCheckHoistingFailed())
break;
if (!isCellSpeculation(variable->prediction()))
break;
noticeStructureCheck(variable, node.structureSet());
break;
}
case ForwardCheckStructure:
case ForwardStructureTransitionWatchpoint:
// We currently rely on the fact that we're the only ones who would
// insert this node.
ASSERT_NOT_REACHED();
break;
case GetByOffset:
case PutByOffset:
case PutStructure:
case StructureTransitionWatchpoint:
case AllocatePropertyStorage:
case ReallocatePropertyStorage:
case GetPropertyStorage:
case GetByVal:
case PutByVal:
case PutByValAlias:
case GetArrayLength:
case CheckArray:
case GetIndexedPropertyStorage:
case Phantom:
// Don't count these uses.
break;
default:
m_graph.vote(node, VoteOther);
break;
}
}
}
// Disable structure hoisting on variables that appear to mostly be used in
// contexts where it doesn't make sense.
for (unsigned i = m_graph.m_variableAccessData.size(); i--;) {
VariableAccessData* variable = &m_graph.m_variableAccessData[i];
if (!variable->isRoot())
continue;
if (variable->voteRatio() >= Options::structureCheckVoteRatioForHoisting())
continue;
HashMap<VariableAccessData*, CheckData>::iterator iter = m_map.find(variable);
if (iter == m_map.end())
continue;
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLog("Zeroing the structure to hoist for %s because the ratio is %lf.\n",
m_graph.nameOfVariableAccessData(variable), variable->voteRatio());
#endif
iter->second.m_structure = 0;
}
// Identify the set of variables that are live across a structure clobber.
Operands<VariableAccessData*> live(
m_graph.m_blocks[0]->variablesAtTail.numberOfArguments(),
m_graph.m_blocks[0]->variablesAtTail.numberOfLocals());
for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
BasicBlock* block = m_graph.m_blocks[blockIndex].get();
if (!block)
continue;
ASSERT(live.numberOfArguments() == block->variablesAtTail.numberOfArguments());
ASSERT(live.numberOfLocals() == block->variablesAtTail.numberOfLocals());
for (unsigned i = live.size(); i--;) {
NodeIndex indexAtTail = block->variablesAtTail[i];
VariableAccessData* variable;
//.........这里部分代码省略.........
示例8: at
//.........这里部分代码省略.........
if (strlen(nodeFlagsAsString(node.flags()))) {
dataLog("%s%s", hasPrinted ? ", " : "", nodeFlagsAsString(node.flags()));
hasPrinted = true;
}
if (node.hasArrayMode()) {
dataLog("%s%s", hasPrinted ? ", " : "", modeToString(node.arrayMode()));
hasPrinted = true;
}
if (node.hasVarNumber()) {
dataLog("%svar%u", hasPrinted ? ", " : "", node.varNumber());
hasPrinted = true;
}
if (node.hasRegisterPointer()) {
dataLog(
"%sglobal%u(%p)", hasPrinted ? ", " : "",
globalObjectFor(node.codeOrigin)->findRegisterIndex(node.registerPointer()),
node.registerPointer());
hasPrinted = true;
}
if (node.hasIdentifier()) {
dataLog("%sid%u{%s}", hasPrinted ? ", " : "", node.identifierNumber(), m_codeBlock->identifier(node.identifierNumber()).ustring().utf8().data());
hasPrinted = true;
}
if (node.hasStructureSet()) {
for (size_t i = 0; i < node.structureSet().size(); ++i) {
dataLog("%sstruct(%p)", hasPrinted ? ", " : "", node.structureSet()[i]);
hasPrinted = true;
}
}
if (node.hasStructure()) {
dataLog("%sstruct(%p)", hasPrinted ? ", " : "", node.structure());
hasPrinted = true;
}
if (node.hasStructureTransitionData()) {
dataLog("%sstruct(%p -> %p)", hasPrinted ? ", " : "", node.structureTransitionData().previousStructure, node.structureTransitionData().newStructure);
hasPrinted = true;
}
if (node.hasStorageAccessData()) {
StorageAccessData& storageAccessData = m_storageAccessData[node.storageAccessDataIndex()];
dataLog("%sid%u{%s}", hasPrinted ? ", " : "", storageAccessData.identifierNumber, m_codeBlock->identifier(storageAccessData.identifierNumber).ustring().utf8().data());
dataLog(", %lu", static_cast<unsigned long>(storageAccessData.offset));
hasPrinted = true;
}
ASSERT(node.hasVariableAccessData() == node.hasLocal());
if (node.hasVariableAccessData()) {
VariableAccessData* variableAccessData = node.variableAccessData();
int operand = variableAccessData->operand();
if (operandIsArgument(operand))
dataLog("%sarg%u(%s)", hasPrinted ? ", " : "", operandToArgument(operand), nameOfVariableAccessData(variableAccessData));
else
dataLog("%sr%u(%s)", hasPrinted ? ", " : "", operand, nameOfVariableAccessData(variableAccessData));
hasPrinted = true;
}
if (node.hasConstantBuffer()) {
if (hasPrinted)
dataLog(", ");
dataLog("%u:[", node.startConstant());
for (unsigned i = 0; i < node.numConstants(); ++i) {
if (i)
dataLog(", ");
dataLog("%s", m_codeBlock->constantBuffer(node.startConstant())[i].description());
}
dataLog("]");
hasPrinted = true;
}
if (op == JSConstant) {
dataLog("%s$%u", hasPrinted ? ", " : "", node.constantNumber());
JSValue value = valueOfJSConstant(nodeIndex);
dataLog(" = %s", value.description());
hasPrinted = true;
}
if (op == WeakJSConstant) {
dataLog("%s%p", hasPrinted ? ", " : "", node.weakConstant());
hasPrinted = true;
}
if (node.isBranch() || node.isJump()) {
dataLog("%sT:#%u", hasPrinted ? ", " : "", node.takenBlockIndex());
hasPrinted = true;
}
if (node.isBranch()) {
dataLog("%sF:#%u", hasPrinted ? ", " : "", node.notTakenBlockIndex());
hasPrinted = true;
}
dataLog("%sbc#%u", hasPrinted ? ", " : "", node.codeOrigin.bytecodeIndex);
hasPrinted = true;
(void)hasPrinted;
dataLog(")");
if (!skipped) {
if (node.hasVariableAccessData())
dataLog(" predicting %s%s", speculationToString(node.variableAccessData()->prediction()), node.variableAccessData()->shouldUseDoubleFormat() ? ", forcing double" : "");
else if (node.hasHeapPrediction())
dataLog(" predicting %s", speculationToString(node.getHeapPrediction()));
}
dataLog("\n");
}
示例9: run
bool run()
{
ASSERT(m_graph.m_form == SSA);
for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
BasicBlock* block = m_graph.block(blockIndex);
if (!block)
continue;
block->ssa->availabilityAtHead.fill(Availability());
block->ssa->availabilityAtTail.fill(Availability());
}
BasicBlock* root = m_graph.block(0);
for (unsigned argument = root->ssa->availabilityAtHead.numberOfArguments(); argument--;) {
root->ssa->availabilityAtHead.argument(argument) =
Availability::unavailable().withFlush(
FlushedAt(FlushedJSValue, virtualRegisterForArgument(argument)));
}
for (unsigned local = root->ssa->availabilityAtHead.numberOfLocals(); local--;)
root->ssa->availabilityAtHead.local(local) = Availability::unavailable();
if (m_graph.m_plan.mode == FTLForOSREntryMode) {
for (unsigned local = m_graph.m_profiledBlock->m_numCalleeRegisters; local--;) {
root->ssa->availabilityAtHead.local(local) =
Availability::unavailable().withFlush(
FlushedAt(FlushedJSValue, virtualRegisterForLocal(local)));
}
}
// This could be made more efficient by processing blocks in reverse postorder.
Operands<Availability> availability;
bool changed;
do {
changed = false;
for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
BasicBlock* block = m_graph.block(blockIndex);
if (!block)
continue;
availability = block->ssa->availabilityAtHead;
for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
Node* node = block->at(nodeIndex);
switch (node->op()) {
case SetLocal: {
VariableAccessData* variable = node->variableAccessData();
availability.operand(variable->local()) =
Availability(node->child1().node(), variable->flushedAt());
break;
}
case GetArgument: {
VariableAccessData* variable = node->variableAccessData();
availability.operand(variable->local()) =
Availability(node, variable->flushedAt());
break;
}
case MovHint:
case MovHintAndCheck: {
VariableAccessData* variable = node->variableAccessData();
availability.operand(variable->local()) =
Availability(node->child1().node());
break;
}
case ZombieHint: {
VariableAccessData* variable = node->variableAccessData();
availability.operand(variable->local()) = Availability::unavailable();
break;
}
default:
break;
}
}
if (availability == block->ssa->availabilityAtTail)
continue;
block->ssa->availabilityAtTail = availability;
changed = true;
for (unsigned successorIndex = block->numSuccessors(); successorIndex--;) {
BasicBlock* successor = block->successor(successorIndex);
for (unsigned i = availability.size(); i--;) {
successor->ssa->availabilityAtHead[i] = availability[i].merge(
successor->ssa->availabilityAtHead[i]);
}
}
}
} while (changed);
return true;
}
示例10: run
bool run()
{
ASSERT(m_graph.m_form == ThreadedCPS);
for (unsigned i = m_graph.m_variableAccessData.size(); i--;) {
VariableAccessData* variable = &m_graph.m_variableAccessData[i];
if (!variable->isRoot())
continue;
variable->clearVotes();
}
// Identify the set of variables that are always subject to the same structure
// checks. For now, only consider monomorphic structure checks (one structure).
for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
BasicBlock* block = m_graph.m_blocks[blockIndex].get();
if (!block)
continue;
for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
Node* node = block->at(indexInBlock);
switch (node->op()) {
case CheckStructure:
case StructureTransitionWatchpoint: {
Node* child = node->child1().node();
if (child->op() != GetLocal)
break;
VariableAccessData* variable = child->variableAccessData();
variable->vote(VoteStructureCheck);
if (!shouldConsiderForHoisting(variable))
break;
noticeStructureCheck(variable, node->structureSet());
break;
}
case ForwardCheckStructure:
case ForwardStructureTransitionWatchpoint:
// We currently rely on the fact that we're the only ones who would
// insert this node.
RELEASE_ASSERT_NOT_REACHED();
break;
case GetByOffset:
case PutByOffset:
case PutStructure:
case AllocatePropertyStorage:
case ReallocatePropertyStorage:
case GetButterfly:
case GetByVal:
case PutByVal:
case PutByValAlias:
case GetArrayLength:
case CheckArray:
case GetIndexedPropertyStorage:
case Phantom:
// Don't count these uses.
break;
case ArrayifyToStructure:
case Arrayify:
if (node->arrayMode().conversion() == Array::RageConvert) {
// Rage conversion changes structures. We should avoid tying to do
// any kind of hoisting when rage conversion is in play.
Node* child = node->child1().node();
if (child->op() != GetLocal)
break;
VariableAccessData* variable = child->variableAccessData();
variable->vote(VoteOther);
if (!shouldConsiderForHoisting(variable))
break;
noticeStructureCheck(variable, 0);
}
break;
case SetLocal: {
// Find all uses of the source of the SetLocal. If any of them are a
// kind of CheckStructure, then we should notice them to ensure that
// we're not hoisting a check that would contravene checks that are
// already being performed.
VariableAccessData* variable = node->variableAccessData();
if (!shouldConsiderForHoisting(variable))
break;
Node* source = node->child1().node();
for (unsigned subIndexInBlock = 0; subIndexInBlock < block->size(); ++subIndexInBlock) {
Node* subNode = block->at(subIndexInBlock);
switch (subNode->op()) {
case CheckStructure: {
if (subNode->child1() != source)
break;
noticeStructureCheck(variable, subNode->structureSet());
break;
}
case StructureTransitionWatchpoint: {
if (subNode->child1() != source)
break;
noticeStructureCheck(variable, subNode->structure());
break;
}
default:
//.........这里部分代码省略.........
示例11: propagate
void propagate(Node* node)
{
NodeFlags flags = node->flags() & NodeBytecodeBackPropMask;
switch (node->op()) {
case GetLocal: {
VariableAccessData* variableAccessData = node->variableAccessData();
variableAccessData->mergeFlags(flags);
break;
}
case SetLocal: {
VariableAccessData* variableAccessData = node->variableAccessData();
if (!variableAccessData->isLoadedFrom())
break;
node->child1()->mergeFlags(NodeBytecodeUsesAsValue);
break;
}
case BitAnd:
case BitOr:
case BitXor:
case BitRShift:
case BitLShift:
case BitURShift:
case ArithIMul: {
flags |= NodeBytecodeUsesAsInt;
flags &= ~(NodeBytecodeUsesAsNumber | NodeBytecodeNeedsNegZero | NodeBytecodeUsesAsOther);
node->child1()->mergeFlags(flags);
node->child2()->mergeFlags(flags);
break;
}
case ValueToInt32: {
flags |= NodeBytecodeUsesAsInt;
flags &= ~(NodeBytecodeUsesAsNumber | NodeBytecodeNeedsNegZero | NodeBytecodeUsesAsOther);
node->child1()->mergeFlags(flags);
break;
}
case StringCharCodeAt: {
node->child1()->mergeFlags(NodeBytecodeUsesAsValue);
node->child2()->mergeFlags(NodeBytecodeUsesAsValue | NodeBytecodeUsesAsInt);
break;
}
case Identity:
case UInt32ToNumber: {
node->child1()->mergeFlags(flags);
break;
}
case ValueAdd: {
if (isNotNegZero(node->child1().node()) || isNotNegZero(node->child2().node()))
flags &= ~NodeBytecodeNeedsNegZero;
if (node->child1()->hasNumberResult() || node->child2()->hasNumberResult())
flags &= ~NodeBytecodeUsesAsOther;
if (!isWithinPowerOfTwo<32>(node->child1()) && !isWithinPowerOfTwo<32>(node->child2()))
flags |= NodeBytecodeUsesAsNumber;
if (!m_allowNestedOverflowingAdditions)
flags |= NodeBytecodeUsesAsNumber;
node->child1()->mergeFlags(flags);
node->child2()->mergeFlags(flags);
break;
}
case ArithAdd: {
if (isNotNegZero(node->child1().node()) || isNotNegZero(node->child2().node()))
flags &= ~NodeBytecodeNeedsNegZero;
if (!isWithinPowerOfTwo<32>(node->child1()) && !isWithinPowerOfTwo<32>(node->child2()))
flags |= NodeBytecodeUsesAsNumber;
if (!m_allowNestedOverflowingAdditions)
flags |= NodeBytecodeUsesAsNumber;
node->child1()->mergeFlags(flags);
node->child2()->mergeFlags(flags);
break;
}
case ArithSub: {
if (isNotNegZero(node->child1().node()) || isNotPosZero(node->child2().node()))
flags &= ~NodeBytecodeNeedsNegZero;
if (!isWithinPowerOfTwo<32>(node->child1()) && !isWithinPowerOfTwo<32>(node->child2()))
flags |= NodeBytecodeUsesAsNumber;
if (!m_allowNestedOverflowingAdditions)
flags |= NodeBytecodeUsesAsNumber;
node->child1()->mergeFlags(flags);
node->child2()->mergeFlags(flags);
break;
}
case ArithNegate: {
flags &= ~NodeBytecodeUsesAsOther;
node->child1()->mergeFlags(flags);
break;
}
//.........这里部分代码省略.........
示例12: run
bool run()
{
SharedSymbolTable* symbolTable = codeBlock()->symbolTable();
// This enumerates the locals that we actually care about and packs them. So for example
// if we use local 1, 3, 4, 5, 7, then we remap them: 1->0, 3->1, 4->2, 5->3, 7->4. We
// treat a variable as being "used" if there exists an access to it (SetLocal, GetLocal,
// Flush, PhantomLocal).
BitVector usedLocals;
// Collect those variables that are used from IR.
bool hasGetLocalUnlinked = false;
for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
BasicBlock* block = m_graph.block(blockIndex);
if (!block)
continue;
for (unsigned nodeIndex = block->size(); nodeIndex--;) {
Node* node = block->at(nodeIndex);
switch (node->op()) {
case GetLocal:
case SetLocal:
case Flush:
case PhantomLocal: {
VariableAccessData* variable = node->variableAccessData();
if (variable->local().isArgument())
break;
usedLocals.set(variable->local().toLocal());
break;
}
case GetLocalUnlinked: {
VirtualRegister operand = node->unlinkedLocal();
if (operand.isArgument())
break;
usedLocals.set(operand.toLocal());
hasGetLocalUnlinked = true;
break;
}
default:
break;
}
}
}
// Ensure that captured variables and captured inline arguments are pinned down.
// They should have been because of flushes, except that the flushes can be optimized
// away.
if (symbolTable) {
for (int i = symbolTable->captureStart(); i > symbolTable->captureEnd(); i--)
usedLocals.set(VirtualRegister(i).toLocal());
}
if (codeBlock()->usesArguments()) {
usedLocals.set(codeBlock()->argumentsRegister().toLocal());
usedLocals.set(unmodifiedArgumentsRegister(codeBlock()->argumentsRegister()).toLocal());
}
if (codeBlock()->uncheckedActivationRegister().isValid())
usedLocals.set(codeBlock()->activationRegister().toLocal());
for (InlineCallFrameSet::iterator iter = m_graph.m_inlineCallFrames->begin(); !!iter; ++iter) {
InlineCallFrame* inlineCallFrame = *iter;
if (!inlineCallFrame->executable->usesArguments())
continue;
VirtualRegister argumentsRegister = m_graph.argumentsRegisterFor(inlineCallFrame);
usedLocals.set(argumentsRegister.toLocal());
usedLocals.set(unmodifiedArgumentsRegister(argumentsRegister).toLocal());
for (unsigned argument = inlineCallFrame->arguments.size(); argument-- > 1;) {
usedLocals.set(VirtualRegister(
virtualRegisterForArgument(argument).offset() +
inlineCallFrame->stackOffset).toLocal());
}
}
Vector<unsigned> allocation(usedLocals.size());
m_graph.m_nextMachineLocal = 0;
for (unsigned i = 0; i < usedLocals.size(); ++i) {
if (!usedLocals.get(i)) {
allocation[i] = UINT_MAX;
continue;
}
allocation[i] = m_graph.m_nextMachineLocal++;
}
for (unsigned i = m_graph.m_variableAccessData.size(); i--;) {
VariableAccessData* variable = &m_graph.m_variableAccessData[i];
if (!variable->isRoot())
continue;
if (variable->local().isArgument()) {
variable->machineLocal() = variable->local();
continue;
}
size_t local = variable->local().toLocal();
if (local >= allocation.size())
continue;
//.........这里部分代码省略.........
示例13: run
bool run()
{
RELEASE_ASSERT(m_graph.m_plan.mode == FTLForOSREntryMode);
RELEASE_ASSERT(m_graph.m_form == ThreadedCPS);
unsigned bytecodeIndex = m_graph.m_plan.osrEntryBytecodeIndex;
RELEASE_ASSERT(bytecodeIndex);
RELEASE_ASSERT(bytecodeIndex != UINT_MAX);
// Needed by createPreHeader().
m_graph.m_dominators.computeIfNecessary(m_graph);
CodeBlock* baseline = m_graph.m_profiledBlock;
BasicBlock* target = 0;
for (unsigned blockIndex = m_graph.numBlocks(); blockIndex--;) {
BasicBlock* block = m_graph.block(blockIndex);
if (!block)
continue;
unsigned nodeIndex = 0;
Node* firstNode = block->at(0);
while (firstNode->isSemanticallySkippable())
firstNode = block->at(++nodeIndex);
if (firstNode->op() == LoopHint
&& firstNode->origin.semantic == CodeOrigin(bytecodeIndex)) {
target = block;
break;
}
}
if (!target) {
// This is a terrible outcome. It shouldn't often happen but it might
// happen and so we should defend against it. If it happens, then this
// compilation is a failure.
return false;
}
BlockInsertionSet insertionSet(m_graph);
BasicBlock* newRoot = insertionSet.insert(0, QNaN);
NodeOrigin origin = target->at(0)->origin;
Vector<Node*> locals(baseline->m_numCalleeRegisters);
for (int local = 0; local < baseline->m_numCalleeRegisters; ++local) {
Node* previousHead = target->variablesAtHead.local(local);
if (!previousHead)
continue;
VariableAccessData* variable = previousHead->variableAccessData();
locals[local] = newRoot->appendNode(
m_graph, variable->prediction(), ExtractOSREntryLocal, origin,
OpInfo(variable->local().offset()));
newRoot->appendNode(
m_graph, SpecNone, MovHint, origin, OpInfo(variable->local().offset()),
Edge(locals[local]));
}
for (int argument = 0; argument < baseline->numParameters(); ++argument) {
Node* oldNode = target->variablesAtHead.argument(argument);
if (!oldNode) {
// Just for sanity, always have a SetArgument even if it's not needed.
oldNode = m_graph.m_arguments[argument];
}
Node* node = newRoot->appendNode(
m_graph, SpecNone, SetArgument, origin,
OpInfo(oldNode->variableAccessData()));
m_graph.m_arguments[argument] = node;
}
for (int local = 0; local < baseline->m_numCalleeRegisters; ++local) {
Node* previousHead = target->variablesAtHead.local(local);
if (!previousHead)
continue;
VariableAccessData* variable = previousHead->variableAccessData();
Node* node = locals[local];
newRoot->appendNode(
m_graph, SpecNone, SetLocal, origin, OpInfo(variable), Edge(node));
}
newRoot->appendNode(
m_graph, SpecNone, Jump, origin,
OpInfo(createPreHeader(m_graph, insertionSet, target)));
insertionSet.execute();
m_graph.resetReachability();
m_graph.killUnreachableBlocks();
return true;
}
示例14: run
bool run()
{
ASSERT(m_graph.m_form == ThreadedCPS);
ASSERT(m_graph.m_unificationState == LocallyUnified);
// Ensure that all Phi functions are unified.
for (BlockIndex blockIndex = m_graph.m_blocks.size(); blockIndex--;) {
BasicBlock* block = m_graph.m_blocks[blockIndex].get();
if (!block)
continue;
ASSERT(block->isReachable);
for (unsigned phiIndex = block->phis.size(); phiIndex--;) {
Node* phi = block->phis[phiIndex];
for (unsigned childIdx = 0; childIdx < AdjacencyList::Size; ++childIdx) {
if (!phi->children.child(childIdx))
break;
phi->variableAccessData()->unify(
phi->children.child(childIdx)->variableAccessData());
}
}
}
// Ensure that all predictions are fixed up based on the unification.
for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
VariableAccessData* data = &m_graph.m_variableAccessData[i];
data->find()->predict(data->nonUnifiedPrediction());
data->find()->mergeIsCaptured(data->isCaptured());
data->find()->mergeStructureCheckHoistingFailed(data->structureCheckHoistingFailed());
data->find()->mergeShouldNeverUnbox(data->shouldNeverUnbox());
data->find()->mergeIsLoadedFrom(data->isLoadedFrom());
}
m_graph.m_unificationState = GloballyUnified;
return true;
}
示例15: run
bool run()
{
// This enumerates the locals that we actually care about and packs them. So for example
// if we use local 1, 3, 4, 5, 7, then we remap them: 1->0, 3->1, 4->2, 5->3, 7->4. We
// treat a variable as being "used" if there exists an access to it (SetLocal, GetLocal,
// Flush, PhantomLocal).
BitVector usedLocals;
// Collect those variables that are used from IR.
bool hasNodesThatNeedFixup = false;
for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
BasicBlock* block = m_graph.block(blockIndex);
if (!block)
continue;
for (unsigned nodeIndex = block->size(); nodeIndex--;) {
Node* node = block->at(nodeIndex);
switch (node->op()) {
case GetLocal:
case SetLocal:
case Flush:
case PhantomLocal: {
VariableAccessData* variable = node->variableAccessData();
if (variable->local().isArgument())
break;
usedLocals.set(variable->local().toLocal());
break;
}
case GetLocalUnlinked: {
VirtualRegister operand = node->unlinkedLocal();
if (operand.isArgument())
break;
usedLocals.set(operand.toLocal());
hasNodesThatNeedFixup = true;
break;
}
case LoadVarargs:
case ForwardVarargs: {
LoadVarargsData* data = node->loadVarargsData();
if (data->count.isLocal())
usedLocals.set(data->count.toLocal());
if (data->start.isLocal()) {
// This part really relies on the contiguity of stack layout
// assignments.
ASSERT(VirtualRegister(data->start.offset() + data->limit - 1).isLocal());
for (unsigned i = data->limit; i--;)
usedLocals.set(VirtualRegister(data->start.offset() + i).toLocal());
} // the else case shouldn't happen.
hasNodesThatNeedFixup = true;
break;
}
case PutStack:
case GetStack: {
StackAccessData* stack = node->stackAccessData();
if (stack->local.isArgument())
break;
usedLocals.set(stack->local.toLocal());
break;
}
default:
break;
}
}
}
for (InlineCallFrameSet::iterator iter = m_graph.m_plan.inlineCallFrames->begin(); !!iter; ++iter) {
InlineCallFrame* inlineCallFrame = *iter;
if (inlineCallFrame->isVarargs()) {
usedLocals.set(VirtualRegister(
JSStack::ArgumentCount + inlineCallFrame->stackOffset).toLocal());
}
for (unsigned argument = inlineCallFrame->arguments.size(); argument-- > 1;) {
usedLocals.set(VirtualRegister(
virtualRegisterForArgument(argument).offset() +
inlineCallFrame->stackOffset).toLocal());
}
}
Vector<unsigned> allocation(usedLocals.size());
m_graph.m_nextMachineLocal = 0;
for (unsigned i = 0; i < usedLocals.size(); ++i) {
if (!usedLocals.get(i)) {
allocation[i] = UINT_MAX;
continue;
}
allocation[i] = m_graph.m_nextMachineLocal++;
}
for (unsigned i = m_graph.m_variableAccessData.size(); i--;) {
VariableAccessData* variable = &m_graph.m_variableAccessData[i];
if (!variable->isRoot())
continue;
//.........这里部分代码省略.........