1 | // Copyright 2015 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_NODE_MARKER_H_ |
6 | #define V8_COMPILER_NODE_MARKER_H_ |
7 | |
8 | #include "src/compiler/node.h" |
9 | |
10 | namespace v8 { |
11 | namespace internal { |
12 | namespace compiler { |
13 | |
14 | // Forward declarations. |
15 | class Graph; |
16 | |
17 | |
18 | // Base class for templatized NodeMarkers. |
19 | class NodeMarkerBase { |
20 | public: |
21 | NodeMarkerBase(Graph* graph, uint32_t num_states); |
22 | |
23 | V8_INLINE Mark Get(const Node* node) { |
24 | Mark mark = node->mark(); |
25 | if (mark < mark_min_) { |
26 | return 0; |
27 | } |
28 | DCHECK_LT(mark, mark_max_); |
29 | return mark - mark_min_; |
30 | } |
31 | V8_INLINE void Set(Node* node, Mark mark) { |
32 | DCHECK_LT(mark, mark_max_ - mark_min_); |
33 | DCHECK_LT(node->mark(), mark_max_); |
34 | node->set_mark(mark + mark_min_); |
35 | } |
36 | |
37 | private: |
38 | Mark const mark_min_; |
39 | Mark const mark_max_; |
40 | |
41 | DISALLOW_COPY_AND_ASSIGN(NodeMarkerBase); |
42 | }; |
43 | |
44 | // A NodeMarker assigns a local "state" to every node of a graph in constant |
45 | // memory. Only one NodeMarker per graph is valid at a given time, that is, |
46 | // after you create a NodeMarker you should no longer use NodeMarkers that |
47 | // were created earlier. Internally, the local state is stored in the Node |
48 | // structure. |
49 | // |
50 | // When you initialize a NodeMarker, all the local states are conceptually |
51 | // set to State(0) in constant time. |
52 | // |
53 | // In its current implementation, in debug mode NodeMarker will try to |
54 | // (efficiently) detect invalid use of an older NodeMarker. Namely, if you set a |
55 | // node with a NodeMarker, and then get or set that node with an older |
56 | // NodeMarker you will get a crash. |
57 | // |
58 | // GraphReducer uses a NodeMarker, so individual Reducers cannot use a |
59 | // NodeMarker. |
60 | template <typename State> |
61 | class NodeMarker : public NodeMarkerBase { |
62 | public: |
63 | V8_INLINE NodeMarker(Graph* graph, uint32_t num_states) |
64 | : NodeMarkerBase(graph, num_states) {} |
65 | |
66 | V8_INLINE State Get(const Node* node) { |
67 | return static_cast<State>(NodeMarkerBase::Get(node)); |
68 | } |
69 | |
70 | V8_INLINE void Set(Node* node, State state) { |
71 | NodeMarkerBase::Set(node, static_cast<Mark>(state)); |
72 | } |
73 | }; |
74 | |
75 | } // namespace compiler |
76 | } // namespace internal |
77 | } // namespace v8 |
78 | |
79 | #endif // V8_COMPILER_NODE_MARKER_H_ |
80 | |