1 // Copyright 2014 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_SIMPLIFIED_OPERATOR_H_ 6 #define V8_COMPILER_SIMPLIFIED_OPERATOR_H_ 7 8 #include <iosfwd> 9 10 #include "src/handles.h" 11 #include "src/machine-type.h" 12 #include "src/objects.h" 13 14 namespace v8 { 15 namespace internal { 16 17 // Forward declarations. 18 template <class> 19 class TypeImpl; 20 struct ZoneTypeConfig; 21 typedef TypeImpl<ZoneTypeConfig> Type; 22 class Zone; 23 24 25 namespace compiler { 26 27 // Forward declarations. 28 class Operator; 29 struct SimplifiedOperatorGlobalCache; 30 31 32 enum BaseTaggedness { kUntaggedBase, kTaggedBase }; 33 34 std::ostream& operator<<(std::ostream&, BaseTaggedness); 35 36 37 // An access descriptor for loads/stores of array buffers. 38 class BufferAccess final { 39 public: BufferAccess(ExternalArrayType external_array_type)40 explicit BufferAccess(ExternalArrayType external_array_type) 41 : external_array_type_(external_array_type) {} 42 external_array_type()43 ExternalArrayType external_array_type() const { return external_array_type_; } 44 MachineType machine_type() const; 45 46 private: 47 ExternalArrayType const external_array_type_; 48 }; 49 50 bool operator==(BufferAccess, BufferAccess); 51 bool operator!=(BufferAccess, BufferAccess); 52 53 size_t hash_value(BufferAccess); 54 55 std::ostream& operator<<(std::ostream&, BufferAccess); 56 57 BufferAccess const BufferAccessOf(const Operator* op) WARN_UNUSED_RESULT; 58 59 60 // An access descriptor for loads/stores of fixed structures like field 61 // accesses of heap objects. Accesses from either tagged or untagged base 62 // pointers are supported; untagging is done automatically during lowering. 63 struct FieldAccess { 64 BaseTaggedness base_is_tagged; // specifies if the base pointer is tagged. 65 int offset; // offset of the field, without tag. 66 MaybeHandle<Name> name; // debugging only. 67 Type* type; // type of the field. 68 MachineType machine_type; // machine type of the field. 69 tagFieldAccess70 int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; } 71 }; 72 73 bool operator==(FieldAccess const&, FieldAccess const&); 74 bool operator!=(FieldAccess const&, FieldAccess const&); 75 76 size_t hash_value(FieldAccess const&); 77 78 std::ostream& operator<<(std::ostream&, FieldAccess const&); 79 80 FieldAccess const& FieldAccessOf(const Operator* op) WARN_UNUSED_RESULT; 81 82 83 // An access descriptor for loads/stores of indexed structures like characters 84 // in strings or off-heap backing stores. Accesses from either tagged or 85 // untagged base pointers are supported; untagging is done automatically during 86 // lowering. 87 struct ElementAccess { 88 BaseTaggedness base_is_tagged; // specifies if the base pointer is tagged. 89 int header_size; // size of the header, without tag. 90 Type* type; // type of the element. 91 MachineType machine_type; // machine type of the element. 92 tagElementAccess93 int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; } 94 }; 95 96 bool operator==(ElementAccess const&, ElementAccess const&); 97 bool operator!=(ElementAccess const&, ElementAccess const&); 98 99 size_t hash_value(ElementAccess const&); 100 101 std::ostream& operator<<(std::ostream&, ElementAccess const&); 102 103 ElementAccess const& ElementAccessOf(const Operator* op) WARN_UNUSED_RESULT; 104 105 106 // Interface for building simplified operators, which represent the 107 // medium-level operations of V8, including adding numbers, allocating objects, 108 // indexing into objects and arrays, etc. 109 // All operators are typed but many are representation independent. 110 111 // Number values from JS can be in one of these representations: 112 // - Tagged: word-sized integer that is either 113 // - a signed small integer (31 or 32 bits plus a tag) 114 // - a tagged pointer to a HeapNumber object that has a float64 field 115 // - Int32: an untagged signed 32-bit integer 116 // - Uint32: an untagged unsigned 32-bit integer 117 // - Float64: an untagged float64 118 119 // Additional representations for intermediate code or non-JS code: 120 // - Int64: an untagged signed 64-bit integer 121 // - Uint64: an untagged unsigned 64-bit integer 122 // - Float32: an untagged float32 123 124 // Boolean values can be: 125 // - Bool: a tagged pointer to either the canonical JS #false or 126 // the canonical JS #true object 127 // - Bit: an untagged integer 0 or 1, but word-sized 128 class SimplifiedOperatorBuilder final : public ZoneObject { 129 public: 130 explicit SimplifiedOperatorBuilder(Zone* zone); 131 132 const Operator* BooleanNot(); 133 const Operator* BooleanToNumber(); 134 135 const Operator* NumberEqual(); 136 const Operator* NumberLessThan(); 137 const Operator* NumberLessThanOrEqual(); 138 const Operator* NumberAdd(); 139 const Operator* NumberSubtract(); 140 const Operator* NumberMultiply(); 141 const Operator* NumberDivide(); 142 const Operator* NumberModulus(); 143 const Operator* NumberBitwiseOr(); 144 const Operator* NumberBitwiseXor(); 145 const Operator* NumberBitwiseAnd(); 146 const Operator* NumberShiftLeft(); 147 const Operator* NumberShiftRight(); 148 const Operator* NumberShiftRightLogical(); 149 const Operator* NumberToInt32(); 150 const Operator* NumberToUint32(); 151 const Operator* NumberIsHoleNaN(); 152 153 const Operator* PlainPrimitiveToNumber(); 154 155 const Operator* ReferenceEqual(Type* type); 156 157 const Operator* StringEqual(); 158 const Operator* StringLessThan(); 159 const Operator* StringLessThanOrEqual(); 160 161 const Operator* ChangeTaggedToInt32(); 162 const Operator* ChangeTaggedToUint32(); 163 const Operator* ChangeTaggedToFloat64(); 164 const Operator* ChangeInt32ToTagged(); 165 const Operator* ChangeUint32ToTagged(); 166 const Operator* ChangeFloat64ToTagged(); 167 const Operator* ChangeBoolToBit(); 168 const Operator* ChangeBitToBool(); 169 170 const Operator* ObjectIsNumber(); 171 const Operator* ObjectIsSmi(); 172 173 const Operator* Allocate(PretenureFlag pretenure = NOT_TENURED); 174 175 const Operator* LoadField(FieldAccess const&); 176 const Operator* StoreField(FieldAccess const&); 177 178 // load-buffer buffer, offset, length 179 const Operator* LoadBuffer(BufferAccess); 180 181 // store-buffer buffer, offset, length, value 182 const Operator* StoreBuffer(BufferAccess); 183 184 // load-element [base + index], length 185 const Operator* LoadElement(ElementAccess const&); 186 187 // store-element [base + index], length, value 188 const Operator* StoreElement(ElementAccess const&); 189 190 private: zone()191 Zone* zone() const { return zone_; } 192 193 const SimplifiedOperatorGlobalCache& cache_; 194 Zone* const zone_; 195 196 DISALLOW_COPY_AND_ASSIGN(SimplifiedOperatorBuilder); 197 }; 198 199 } // namespace compiler 200 } // namespace internal 201 } // namespace v8 202 203 #endif // V8_COMPILER_SIMPLIFIED_OPERATOR_H_ 204