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