• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_COMPILER_OSR_H_
6 #define V8_COMPILER_OSR_H_
7 
8 #include "src/zone/zone.h"
9 
10 // TurboFan structures OSR graphs in a way that separates almost all phases of
11 // compilation from OSR implementation details. This is accomplished with
12 // special control nodes that are added at graph building time. In particular,
13 // the graph is built in such a way that typing still computes the best types
14 // and optimizations and lowering work unchanged. All that remains is to
15 // deconstruct the OSR artifacts before scheduling and code generation.
16 
17 // Graphs built for OSR from the AstGraphBuilder are structured as follows:
18 //                             Start
19 //          +-------------------^^-----+
20 //          |                          |
21 //   OsrNormalEntry               OsrLoopEntry <-------------+
22 //          |                          |                     |
23 //   control flow before loop          |           A     OsrValue
24 //          |                          |           |         |
25 //          | +------------------------+           | +-------+
26 //          | | +-------------+                    | | +--------+
27 //          | | |             |                    | | |        |
28 //        ( Loop )<-----------|------------------ ( phi )       |
29 //          |                 |                                 |
30 //      loop body             | backedge(s)                     |
31 //          |  |              |                                 |
32 //          |  +--------------+                        B  <-----+
33 //          |
34 //         end
35 
36 // The control structure expresses the relationship that the loop has a separate
37 // entrypoint which corresponds to entering the loop directly from the middle
38 // of unoptimized code.
39 // Similarly, the values that come in from unoptimized code are represented with
40 // {OsrValue} nodes that merge into any phis associated with the OSR loop.
41 // In the above diagram, nodes {A} and {B} represent values in the "normal"
42 // graph that correspond to the values of those phis before the loop and on any
43 // backedges, respectively.
44 
45 // To deconstruct OSR, we simply replace the uses of the {OsrNormalEntry}
46 // control node with {Dead} and {OsrLoopEntry} with start and run the
47 // {ControlReducer}. Control reduction propagates the dead control forward,
48 // essentially "killing" all the code before the OSR loop. The entrypoint to the
49 // loop corresponding to the "normal" entry path will also be removed, as well
50 // as the inputs to the loop phis, resulting in the reduced graph:
51 
52 //                             Start
53 //         Dead                  |^-------------------------+
54 //          |                    |                          |
55 //          |                    |                          |
56 //          |                    |                          |
57 //    disconnected, dead         |           A=dead      OsrValue
58 //                               |                          |
59 //            +------------------+                   +------+
60 //            | +-------------+                      | +--------+
61 //            | |             |                      | |        |
62 //        ( Loop )<-----------|------------------ ( phi )       |
63 //          |                 |                                 |
64 //      loop body             | backedge(s)                     |
65 //          |  |              |                                 |
66 //          |  +--------------+                        B  <-----+
67 //          |
68 //         end
69 
70 // Other than the presences of the OsrValue nodes, this is a normal, schedulable
71 // graph. OsrValue nodes are handled specially in the instruction selector to
72 // simply load from the unoptimized frame.
73 
74 // For nested OSR loops, loop peeling must first be applied as many times as
75 // necessary in order to bring the OSR loop up to the top level (i.e. to be
76 // an outer loop).
77 
78 namespace v8 {
79 namespace internal {
80 
81 class CompilationInfo;
82 
83 namespace compiler {
84 
85 class JSGraph;
86 class CommonOperatorBuilder;
87 class Frame;
88 class Linkage;
89 
90 // Encapsulates logic relating to OSR compilations as well has handles some
91 // details of the frame layout.
92 class OsrHelper {
93  public:
94   explicit OsrHelper(CompilationInfo* info);
95   // Only for testing.
OsrHelper(size_t parameter_count,size_t stack_slot_count)96   OsrHelper(size_t parameter_count, size_t stack_slot_count)
97       : parameter_count_(parameter_count),
98         stack_slot_count_(stack_slot_count) {}
99 
100   // Deconstructs the artificial {OsrNormalEntry} and rewrites the graph so
101   // that only the path corresponding to {OsrLoopEntry} remains.
102   void Deconstruct(JSGraph* jsgraph, CommonOperatorBuilder* common,
103                    Zone* tmp_zone);
104 
105   // Prepares the frame w.r.t. OSR.
106   void SetupFrame(Frame* frame);
107 
108   // Returns the number of unoptimized frame slots for this OSR.
UnoptimizedFrameSlots()109   size_t UnoptimizedFrameSlots() { return stack_slot_count_; }
110 
111   // Returns the environment index of the first stack slot.
FirstStackSlotIndex(int parameter_count)112   static int FirstStackSlotIndex(int parameter_count) {
113     // n.b. unlike Crankshaft, TurboFan environments do not contain the context.
114     return 1 + parameter_count;  // receiver + params
115   }
116 
117  private:
118   size_t parameter_count_;
119   size_t stack_slot_count_;
120 };
121 
122 }  // namespace compiler
123 }  // namespace internal
124 }  // namespace v8
125 
126 #endif  // V8_COMPILER_OSR_H_
127