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