diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGOSREntrypointCreationPhase.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGOSREntrypointCreationPhase.cpp | 65 |
1 files changed, 40 insertions, 25 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGOSREntrypointCreationPhase.cpp b/Source/JavaScriptCore/dfg/DFGOSREntrypointCreationPhase.cpp index 4f82d15fa..5d22edd60 100644 --- a/Source/JavaScriptCore/dfg/DFGOSREntrypointCreationPhase.cpp +++ b/Source/JavaScriptCore/dfg/DFGOSREntrypointCreationPhase.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Apple Inc. All rights reserved. + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,7 +33,7 @@ #include "DFGGraph.h" #include "DFGLoopPreHeaderCreationPhase.h" #include "DFGPhase.h" -#include "Operations.h" +#include "JSCInlines.h" namespace JSC { namespace DFG { @@ -54,7 +54,7 @@ public: RELEASE_ASSERT(bytecodeIndex != UINT_MAX); // Needed by createPreHeader(). - m_graph.m_dominators.computeIfNecessary(m_graph); + m_graph.ensureDominators(); CodeBlock* baseline = m_graph.m_profiledBlock; @@ -63,9 +63,12 @@ public: 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->codeOrigin == CodeOrigin(bytecodeIndex)) { + && firstNode->origin.semantic == CodeOrigin(bytecodeIndex)) { target = block; break; } @@ -80,46 +83,59 @@ public: BlockInsertionSet insertionSet(m_graph); - BasicBlock* newRoot = insertionSet.insert(0); - CodeOrigin codeOrigin = target->at(0)->codeOrigin; + // 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); - 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, codeOrigin, - OpInfo(oldNode->variableAccessData())); - m_graph.m_arguments[argument] = node; - } - Vector<Node*> locals(baseline->m_numCalleeRegisters); - for (int local = 0; local < baseline->m_numCalleeRegisters; ++local) { + 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, codeOrigin, + m_graph, variable->prediction(), ExtractOSREntryLocal, origin, OpInfo(variable->local().offset())); newRoot->appendNode( - m_graph, SpecNone, MovHint, codeOrigin, OpInfo(variable->local().offset()), + m_graph, SpecNone, MovHint, origin, OpInfo(variable->local().offset()), Edge(locals[local])); } - for (int local = 0; local < baseline->m_numCalleeRegisters; ++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, codeOrigin, OpInfo(variable), Edge(node)); + m_graph, SpecNone, SetLocal, origin, OpInfo(variable), Edge(node)); } newRoot->appendNode( - m_graph, SpecNone, Jump, codeOrigin, + m_graph, SpecNone, Jump, origin, OpInfo(createPreHeader(m_graph, insertionSet, target))); insertionSet.execute(); @@ -131,7 +147,6 @@ public: bool performOSREntrypointCreation(Graph& graph) { - SamplingRegion samplingRegion("DFG OSR Entrypoint Creation"); return runPhase<OSREntrypointCreationPhase>(graph); } |