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
10namespace v8 {
11namespace internal {
12namespace compiler {
13
14// Forward declarations.
15class Graph;
16
17
18// Base class for templatized NodeMarkers.
19class NodeMarkerBase {
20 public:
21  NodeMarkerBase(Graph* graph, uint32_t num_states);
22  NodeMarkerBase(const NodeMarkerBase&) = delete;
23  NodeMarkerBase& operator=(const NodeMarkerBase&) = delete;
24
25  V8_INLINE Mark Get(const Node* node) {
26    Mark mark = node->mark();
27    if (mark < mark_min_) {
28      return 0;
29    }
30    DCHECK_LT(mark, mark_max_);
31    return mark - mark_min_;
32  }
33  V8_INLINE void Set(Node* node, Mark mark) {
34    DCHECK_LT(mark, mark_max_ - mark_min_);
35    DCHECK_LT(node->mark(), mark_max_);
36    node->set_mark(mark + mark_min_);
37  }
38
39 private:
40  Mark const mark_min_;
41  Mark const mark_max_;
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.
60template <typename State>
61class 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