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 NodeKeyNodeKey37 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 StateValuesKeyStateValuesKey46 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 graph()73 Graph* graph() { return js_graph_->graph(); } common()74 CommonOperatorBuilder* common() { return js_graph_->common(); } 75 zone()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; TypedNodeTypedNode89 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 iterator()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 StateValuesAccess(Node * node)120 explicit StateValuesAccess(Node* node) : node_(node) {} 121 122 size_t size(); begin()123 iterator begin() { return iterator(node_); } end()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