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_STATE_VALUES_UTILS_H_
6 #define V8_COMPILER_STATE_VALUES_UTILS_H_
7 
8 #include <array>
9 #include "src/compiler/common-operator.h"
10 #include "src/compiler/js-graph.h"
11 #include "src/globals.h"
12 
13 namespace v8 {
14 namespace internal {
15 
16 class BitVector;
17 
18 namespace compiler {
19 
20 class Graph;
21 
22 class V8_EXPORT_PRIVATE StateValuesCache {
23  public:
24   explicit StateValuesCache(JSGraph* js_graph);
25 
26   Node* GetNodeForValues(Node** values, size_t count,
27                          const BitVector* liveness = nullptr,
28                          int liveness_offset = 0);
29 
30  private:
31   static const size_t kMaxInputCount = 8;
32   typedef std::array<Node*, kMaxInputCount> WorkingBuffer;
33 
34   struct NodeKey {
35     Node* node;
36 
37     explicit NodeKey(Node* node) : node(node) {}
38   };
39 
40   struct StateValuesKey : public NodeKey {
41     // ValueArray - array of nodes ({node} has to be nullptr).
42     size_t count;
43     SparseInputMask mask;
44     Node** values;
45 
46     StateValuesKey(size_t count, SparseInputMask mask, Node** values)
47         : NodeKey(nullptr), count(count), mask(mask), values(values) {}
48   };
49 
50   static bool AreKeysEqual(void* key1, void* key2);
51   static bool IsKeysEqualToNode(StateValuesKey* key, Node* node);
52   static bool AreValueKeysEqual(StateValuesKey* key1, StateValuesKey* key2);
53 
54   // Fills {node_buffer}, starting from {node_count}, with {values}, starting
55   // at {values_idx}, sparsely encoding according to {liveness}. {node_count} is
56   // updated with the new number of inputs in {node_buffer}, and a bitmask of
57   // the sparse encoding is returned.
58   SparseInputMask::BitMaskType FillBufferWithValues(WorkingBuffer* node_buffer,
59                                                     size_t* node_count,
60                                                     size_t* values_idx,
61                                                     Node** values, size_t count,
62                                                     const BitVector* liveness,
63                                                     int liveness_offset);
64 
65   Node* BuildTree(size_t* values_idx, Node** values, size_t count,
66                   const BitVector* liveness, int liveness_offset, size_t level);
67 
68   WorkingBuffer* GetWorkingSpace(size_t level);
69   Node* GetEmptyStateValues();
70   Node* GetValuesNodeFromCache(Node** nodes, size_t count,
71                                SparseInputMask mask);
72 
73   Graph* graph() { return js_graph_->graph(); }
74   CommonOperatorBuilder* common() { return js_graph_->common(); }
75 
76   Zone* zone() { return graph()->zone(); }
77 
78   JSGraph* js_graph_;
79   CustomMatcherZoneHashMap hash_map_;
80   ZoneVector<WorkingBuffer> working_space_;  // One working space per level.
81   Node* empty_state_values_;
82 };
83 
84 class V8_EXPORT_PRIVATE StateValuesAccess {
85  public:
86   struct TypedNode {
87     Node* node;
88     MachineType type;
89     TypedNode(Node* node, MachineType type) : node(node), type(type) {}
90   };
91 
92   class V8_EXPORT_PRIVATE iterator {
93    public:
94     // Bare minimum of operators needed for range iteration.
95     bool operator!=(iterator& other);
96     iterator& operator++();
97     TypedNode operator*();
98 
99    private:
100     friend class StateValuesAccess;
101 
102     iterator() : current_depth_(-1) {}
103     explicit iterator(Node* node);
104 
105     Node* node();
106     MachineType type();
107     bool done();
108     void Advance();
109     void EnsureValid();
110 
111     SparseInputMask::InputIterator* Top();
112     void Push(Node* node);
113     void Pop();
114 
115     static const int kMaxInlineDepth = 8;
116     SparseInputMask::InputIterator stack_[kMaxInlineDepth];
117     int current_depth_;
118   };
119 
120   explicit StateValuesAccess(Node* node) : node_(node) {}
121 
122   size_t size();
123   iterator begin() { return iterator(node_); }
124   iterator end() { return iterator(); }
125 
126  private:
127   Node* node_;
128 };
129 
130 }  // namespace compiler
131 }  // namespace internal
132 }  // namespace v8
133 
134 #endif  // V8_COMPILER_STATE_VALUES_UTILS_H_
135