diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGAbstractState.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGAbstractState.cpp | 170 |
1 files changed, 122 insertions, 48 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp index ee0cc9ab7..7ab05f329 100644 --- a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp +++ b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp @@ -54,13 +54,7 @@ AbstractState::AbstractState(Graph& graph) , m_variables(m_codeBlock->numParameters(), graph.m_localVars) , m_block(0) { - size_t maxBlockSize = 0; - for (size_t i = 0; i < graph.m_blocks.size(); ++i) { - BasicBlock* block = graph.m_blocks[i].get(); - if (block->end - block->begin > maxBlockSize) - maxBlockSize = block->end - block->begin; - } - m_nodes.resize(maxBlockSize); + m_nodes.resize(graph.size()); } AbstractState::~AbstractState() { } @@ -75,8 +69,9 @@ void AbstractState::beginBasicBlock(BasicBlock* basicBlock) ASSERT(basicBlock->variablesAtTail.numberOfLocals() == basicBlock->valuesAtTail.numberOfLocals()); ASSERT(basicBlock->variablesAtHead.numberOfLocals() == basicBlock->variablesAtTail.numberOfLocals()); - for (size_t i = 0; i < basicBlock->end - basicBlock->begin; ++i) - m_nodes[i].clear(); + for (size_t i = 0; i < basicBlock->size(); i++) + m_nodes[basicBlock->at(i)].clear(); + m_variables = basicBlock->valuesAtHead; m_haveStructures = false; for (size_t i = 0; i < m_variables.numberOfArguments(); ++i) { @@ -113,6 +108,11 @@ void AbstractState::initialize(Graph& graph) continue; } + if (graph.argumentIsCaptured(i)) { + root->valuesAtHead.argument(i).makeTop(); + continue; + } + PredictedType prediction = node.variableAccessData()->prediction(); if (isInt32Prediction(prediction)) root->valuesAtHead.argument(i).set(PredictInt32); @@ -143,6 +143,11 @@ void AbstractState::initialize(Graph& graph) else root->valuesAtHead.argument(i).makeTop(); } + for (size_t i = 0; i < root->valuesAtHead.numberOfLocals(); ++i) { + if (!graph.localIsCaptured(i)) + continue; + root->valuesAtHead.local(i).makeTop(); + } } bool AbstractState::endBasicBlock(MergeMode mergeMode) @@ -164,14 +169,28 @@ bool AbstractState::endBasicBlock(MergeMode mergeMode) #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) dataLog(" Merging state for argument %zu.\n", argument); #endif - changed |= mergeStateAtTail(block->valuesAtTail.argument(argument), m_variables.argument(argument), block->variablesAtTail.argument(argument)); + AbstractValue& destination = block->valuesAtTail.argument(argument); + if (m_graph.argumentIsCaptured(argument)) { + if (!destination.isTop()) { + destination.makeTop(); + changed = true; + } + } else + changed |= mergeStateAtTail(destination, m_variables.argument(argument), block->variablesAtTail.argument(argument)); } for (size_t local = 0; local < block->variablesAtTail.numberOfLocals(); ++local) { #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) dataLog(" Merging state for local %zu.\n", local); #endif - changed |= mergeStateAtTail(block->valuesAtTail.local(local), m_variables.local(local), block->variablesAtTail.local(local)); + AbstractValue& destination = block->valuesAtTail.local(local); + if (m_graph.localIsCaptured(local)) { + if (!destination.isTop()) { + destination.makeTop(); + changed = true; + } + } else + changed |= mergeStateAtTail(destination, m_variables.local(local), block->variablesAtTail.local(local)); } } @@ -191,12 +210,13 @@ void AbstractState::reset() m_isValid = false; } -bool AbstractState::execute(NodeIndex nodeIndex) +bool AbstractState::execute(unsigned indexInBlock) { PROFILE(FLAG_FOR_EXECUTION); ASSERT(m_block); ASSERT(m_isValid); + NodeIndex nodeIndex = m_block->at(indexInBlock); Node& node = m_graph[nodeIndex]; if (!node.shouldGenerate()) @@ -216,11 +236,17 @@ bool AbstractState::execute(NodeIndex nodeIndex) } case GetLocal: { - forNode(nodeIndex) = m_variables.operand(node.local()); + if (m_graph.isCaptured(node.local())) + forNode(nodeIndex).makeTop(); + else + forNode(nodeIndex) = m_variables.operand(node.local()); break; } case SetLocal: { + if (m_graph.isCaptured(node.local())) + break; + if (node.variableAccessData()->shouldUseDoubleFormat()) { forNode(node.child1()).filter(PredictNumber); m_variables.operand(node.local()).set(PredictDouble); @@ -265,12 +291,12 @@ bool AbstractState::execute(NodeIndex nodeIndex) break; case ValueToInt32: - if (!m_graph[node.child1()].shouldNotSpeculateInteger()) { + if (m_graph[node.child1()].shouldNotSpeculateInteger()) { if (m_graph[node.child1()].shouldSpeculateDouble()) forNode(node.child1()).filter(PredictNumber); - else - forNode(node.child1()).filter(PredictInt32); - } + } else + forNode(node.child1()).filter(PredictInt32); + forNode(nodeIndex).set(PredictInt32); break; @@ -289,7 +315,7 @@ bool AbstractState::execute(NodeIndex nodeIndex) break; } if (node.op == ValueAdd) { - clobberStructures(nodeIndex); + clobberStructures(indexInBlock); forNode(nodeIndex).set(PredictString | PredictInt32 | PredictNumber); break; } @@ -311,6 +337,17 @@ bool AbstractState::execute(NodeIndex nodeIndex) break; } + case ArithNegate: { + if (m_graph.negateShouldSpeculateInteger(node)) { + forNode(node.child1()).filter(PredictInt32); + forNode(nodeIndex).set(PredictInt32); + break; + } + forNode(node.child1()).filter(PredictNumber); + forNode(nodeIndex).set(PredictDouble); + break; + } + case ArithMul: case ArithDiv: case ArithMin: @@ -368,7 +405,7 @@ bool AbstractState::execute(NodeIndex nodeIndex) else if (child.shouldSpeculateNumber()) forNode(node.child1()).filter(PredictNumber); else - clobberStructures(nodeIndex); + clobberStructures(indexInBlock); forNode(nodeIndex).set(PredictBoolean); break; } @@ -391,7 +428,7 @@ bool AbstractState::execute(NodeIndex nodeIndex) filter = PredictArray; else { filter = PredictTop; - clobberStructures(nodeIndex); + clobberStructures(indexInBlock); } forNode(node.child1()).filter(filter); forNode(node.child2()).filter(filter); @@ -421,7 +458,7 @@ bool AbstractState::execute(NodeIndex nodeIndex) break; } if (!isActionableArrayPrediction(m_graph[node.child1()].prediction()) || !m_graph[node.child2()].shouldSpeculateInteger()) { - clobberStructures(nodeIndex); + clobberStructures(indexInBlock); forNode(nodeIndex).makeTop(); break; } @@ -507,7 +544,7 @@ bool AbstractState::execute(NodeIndex nodeIndex) } if (!m_graph[node.child2()].shouldSpeculateInteger() || !isActionableMutableArrayPrediction(m_graph[node.child1()].prediction())) { ASSERT(node.op == PutByVal); - clobberStructures(nodeIndex); + clobberStructures(indexInBlock); forNode(nodeIndex).makeTop(); break; } @@ -693,10 +730,25 @@ bool AbstractState::execute(NodeIndex nodeIndex) } case NewObject: - forNode(nodeIndex).set(m_codeBlock->globalObject()->emptyObjectStructure()); + forNode(nodeIndex).set(m_codeBlock->globalObjectFor(node.codeOrigin)->emptyObjectStructure()); m_haveStructures = true; break; - + + case CreateActivation: + forNode(nodeIndex).set(m_graph.m_globalData.activationStructure.get()); + m_haveStructures = true; + break; + + case TearOffActivation: + // Does nothing that is user-visible. + break; + + case NewFunction: + case NewFunctionExpression: + case NewFunctionNoCheck: + forNode(nodeIndex).set(m_codeBlock->globalObjectFor(node.codeOrigin)->functionStructure()); + break; + case GetCallee: forNode(nodeIndex).set(PredictFunction); break; @@ -710,7 +762,7 @@ bool AbstractState::execute(NodeIndex nodeIndex) break; case PutScopedVar: - clobberStructures(nodeIndex); + clobberStructures(indexInBlock); break; case GetById: @@ -721,7 +773,7 @@ bool AbstractState::execute(NodeIndex nodeIndex) } if (isCellPrediction(m_graph[node.child1()].prediction())) forNode(node.child1()).filter(PredictCell); - clobberStructures(nodeIndex); + clobberStructures(indexInBlock); forNode(nodeIndex).makeTop(); break; @@ -783,7 +835,7 @@ bool AbstractState::execute(NodeIndex nodeIndex) break; case PutStructure: - clobberStructures(nodeIndex); + clobberStructures(indexInBlock); forNode(node.child1()).set(node.structureTransitionData().newStructure); m_haveStructures = true; break; @@ -874,7 +926,7 @@ bool AbstractState::execute(NodeIndex nodeIndex) case PutById: case PutByIdDirect: forNode(node.child1()).filter(PredictCell); - clobberStructures(nodeIndex); + clobberStructures(indexInBlock); break; case GetGlobalVar: @@ -910,7 +962,7 @@ bool AbstractState::execute(NodeIndex nodeIndex) case ResolveBase: case ResolveBaseStrictPut: case ResolveGlobal: - clobberStructures(nodeIndex); + clobberStructures(indexInBlock); forNode(nodeIndex).makeTop(); break; @@ -927,13 +979,13 @@ bool AbstractState::execute(NodeIndex nodeIndex) return m_isValid; } -inline void AbstractState::clobberStructures(NodeIndex nodeIndex) +inline void AbstractState::clobberStructures(unsigned indexInBlock) { PROFILE(FLAG_FOR_STRUCTURE_CLOBBERING); if (!m_haveStructures) return; - for (size_t i = nodeIndex - m_block->begin + 1; i-- > 0;) - m_nodes[i].clobberStructures(); + for (size_t i = indexInBlock + 1; i--;) + forNode(m_block->at(i)).clobberStructures(); for (size_t i = 0; i < m_variables.numberOfArguments(); ++i) m_variables.argument(i).clobberStructures(); for (size_t i = 0; i < m_variables.numberOfLocals(); ++i) @@ -946,7 +998,7 @@ inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, Abstract if (nodeIndex == NoNode) return false; - AbstractValue* source; + AbstractValue source; Node& node = m_graph[nodeIndex]; if (!node.refCount()) @@ -961,7 +1013,7 @@ inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, Abstract case SetArgument: case Flush: // The block transfers the value from head to tail. - source = &inVariable; + source = inVariable; #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) dataLog(" Transfering from head to tail.\n"); #endif @@ -969,7 +1021,7 @@ inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, Abstract case GetLocal: // The block refines the value with additional speculations. - source = &forNode(nodeIndex); + source = forNode(nodeIndex); #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) dataLog(" Refining.\n"); #endif @@ -978,7 +1030,10 @@ inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, Abstract case SetLocal: // The block sets the variable, and potentially refines it, both // before and after setting it. - source = &forNode(node.child1()); + if (node.variableAccessData()->shouldUseDoubleFormat()) + source.set(PredictDouble); + else + source = forNode(node.child1()); #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) dataLog(" Setting.\n"); #endif @@ -986,11 +1041,10 @@ inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, Abstract default: ASSERT_NOT_REACHED(); - source = 0; break; } - if (destination == *source) { + if (destination == source) { // Abstract execution did not change the output value of the variable, for this // basic block, on this iteration. #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) @@ -1002,7 +1056,7 @@ inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, Abstract // Abstract execution reached a new conclusion about the speculations reached about // this variable after execution of this basic block. Update the state, and return // true to indicate that the fixpoint must go on! - destination = *source; + destination = source; #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) dataLog(" Changed!\n"); #endif @@ -1016,11 +1070,29 @@ inline bool AbstractState::merge(BasicBlock* from, BasicBlock* to) bool changed = false; - for (size_t argument = 0; argument < from->variablesAtTail.numberOfArguments(); ++argument) - changed |= mergeVariableBetweenBlocks(to->valuesAtHead.argument(argument), from->valuesAtTail.argument(argument), to->variablesAtHead.argument(argument), from->variablesAtTail.argument(argument)); + for (size_t argument = 0; argument < from->variablesAtTail.numberOfArguments(); ++argument) { + AbstractValue& destination = to->valuesAtHead.argument(argument); + if (m_graph.argumentIsCaptured(argument)) { + if (destination.isTop()) + continue; + destination.makeTop(); + changed = true; + continue; + } + changed |= mergeVariableBetweenBlocks(destination, from->valuesAtTail.argument(argument), to->variablesAtHead.argument(argument), from->variablesAtTail.argument(argument)); + } - for (size_t local = 0; local < from->variablesAtTail.numberOfLocals(); ++local) - changed |= mergeVariableBetweenBlocks(to->valuesAtHead.local(local), from->valuesAtTail.local(local), to->variablesAtHead.local(local), from->variablesAtTail.local(local)); + for (size_t local = 0; local < from->variablesAtTail.numberOfLocals(); ++local) { + AbstractValue& destination = to->valuesAtHead.local(local); + if (m_graph.localIsCaptured(local)) { + if (destination.isTop()) + continue; + destination.makeTop(); + changed = true; + continue; + } + changed |= mergeVariableBetweenBlocks(destination, from->valuesAtTail.local(local), to->variablesAtHead.local(local), from->variablesAtTail.local(local)); + } if (!to->cfaHasVisited) changed = true; @@ -1034,7 +1106,7 @@ inline bool AbstractState::mergeToSuccessors(Graph& graph, BasicBlock* basicBloc { PROFILE(FLAG_FOR_MERGE_TO_SUCCESSORS); - Node& terminal = graph[basicBlock->end - 1]; + Node& terminal = graph[basicBlock->last()]; ASSERT(terminal.isTerminal()); @@ -1073,15 +1145,17 @@ inline bool AbstractState::mergeVariableBetweenBlocks(AbstractValue& destination void AbstractState::dump(FILE* out) { bool first = true; - for (size_t i = 0; i < m_nodes.size(); ++i) { - if (m_nodes[i].isClear()) + for (size_t i = 0; i < m_block->size(); ++i) { + NodeIndex index = m_block->at(i); + AbstractValue& value = m_nodes[index]; + if (value.isClear()) continue; if (first) first = false; else fprintf(out, " "); - fprintf(out, "@%lu:", static_cast<unsigned long>(i + m_block->begin)); - m_nodes[i].dump(out); + fprintf(out, "@%lu:", static_cast<unsigned long>(index)); + value.dump(out); } } #endif |