1/*
2 * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "DFGPredictionInjectionPhase.h"
28
29#if ENABLE(DFG_JIT)
30
31#include "DFGBasicBlockInlines.h"
32#include "DFGGraph.h"
33#include "DFGPhase.h"
34#include "JSCInlines.h"
35
36namespace JSC { namespace DFG {
37
38class PredictionInjectionPhase : public Phase {
39public:
40 PredictionInjectionPhase(Graph& graph)
41 : Phase(graph, "prediction injection")
42 {
43 }
44
45 bool run()
46 {
47 ASSERT(m_graph.m_form == ThreadedCPS);
48 ASSERT(m_graph.m_unificationState == GloballyUnified);
49
50 ASSERT(codeBlock()->numParameters() >= 1);
51 {
52 ConcurrentJSLocker locker(profiledBlock()->m_lock);
53
54 // We only do this for the arguments at the first block. The arguments from
55 // other entrypoints have already been populated with their predictions.
56 auto& arguments = m_graph.m_rootToArguments.find(m_graph.block(0))->value;
57
58 for (size_t arg = 0; arg < static_cast<size_t>(codeBlock()->numParameters()); ++arg) {
59 ValueProfile& profile = profiledBlock()->valueProfileForArgument(arg);
60 arguments[arg]->variableAccessData()->predict(
61 profile.computeUpdatedPrediction(locker));
62 }
63 }
64
65 for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
66 BasicBlock* block = m_graph.block(blockIndex);
67 if (!block)
68 continue;
69 if (!block->isOSRTarget)
70 continue;
71 if (block->bytecodeBegin != m_graph.m_plan.osrEntryBytecodeIndex())
72 continue;
73 const Operands<Optional<JSValue>>& mustHandleValues = m_graph.m_plan.mustHandleValues();
74 for (size_t i = 0; i < mustHandleValues.size(); ++i) {
75 int operand = mustHandleValues.operandForIndex(i);
76 Optional<JSValue> value = mustHandleValues[i];
77 if (!value)
78 continue;
79 Node* node = block->variablesAtHead.operand(operand);
80 if (!node)
81 continue;
82 ASSERT(node->accessesStack(m_graph));
83 node->variableAccessData()->predict(speculationFromValue(value.value()));
84 }
85 }
86
87 return true;
88 }
89};
90
91bool performPredictionInjection(Graph& graph)
92{
93 return runPhase<PredictionInjectionPhase>(graph);
94}
95
96} } // namespace JSC::DFG
97
98#endif // ENABLE(DFG_JIT)
99
100