1014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Copyright 2015 the V8 project authors. All rights reserved.
2014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// found in the LICENSE file.
4014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifndef V8_COMPILER_NODE_MARKER_H_
6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define V8_COMPILER_NODE_MARKER_H_
7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/node.h"
9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace v8 {
11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace internal {
12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace compiler {
13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Forward declarations.
15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Graph;
16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Base class for templatized NodeMarkers.
19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass NodeMarkerBase {
20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  NodeMarkerBase(Graph* graph, uint32_t num_states);
22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V8_INLINE Mark Get(Node* node) {
24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Mark mark = node->mark();
25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (mark < mark_min_) {
26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      mark = mark_min_;
27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      node->set_mark(mark_min_);
28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_LT(mark, mark_max_);
30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return mark - mark_min_;
31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V8_INLINE void Set(Node* node, Mark mark) {
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_LT(mark, mark_max_ - mark_min_);
34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_LT(node->mark(), mark_max_);
35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    node->set_mark(mark + mark_min_);
36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Mark const mark_min_;
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Mark const mark_max_;
41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(NodeMarkerBase);
43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// A NodeMarker assigns a local "state" to every node of a graph in constant
4613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// memory. Only one NodeMarker per graph is valid at a given time, that is,
4713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// after you create a NodeMarker you should no longer use NodeMarkers that
4813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// were created earlier. Internally, the local state is stored in the Node
4913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// structure.
5013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch//
5113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// When you initialize a NodeMarker, all the local states are conceptually
5213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// set to State(0) in constant time.
5313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch//
5413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// In its current implementation, in debug mode NodeMarker will try to
5513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// (efficiently) detect invalid use of an older NodeMarker. Namely, if you get
5613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// or set a node with a NodeMarker, and then get or set that node
5713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// with an older NodeMarker you will get a crash.
5813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch//
5913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// GraphReducer uses a NodeMarker, so individual Reducers cannot use a
6013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// NodeMarker.
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <typename State>
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass NodeMarker : public NodeMarkerBase {
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V8_INLINE NodeMarker(Graph* graph, uint32_t num_states)
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : NodeMarkerBase(graph, num_states) {}
66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V8_INLINE State Get(Node* node) {
68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return static_cast<State>(NodeMarkerBase::Get(node));
69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V8_INLINE void Set(Node* node, State state) {
72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    NodeMarkerBase::Set(node, static_cast<Mark>(state));
73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace compiler
77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif  // V8_COMPILER_NODE_MARKER_H_
81