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 #include "src/compiler/access-builder.h" 6 7 #include "src/contexts.h" 8 #include "src/frames.h" 9 #include "src/heap/heap.h" 10 #include "src/type-cache.h" 11 #include "src/types-inl.h" 12 13 namespace v8 { 14 namespace internal { 15 namespace compiler { 16 17 // static 18 FieldAccess AccessBuilder::ForMap() { 19 FieldAccess access = {kTaggedBase, HeapObject::kMapOffset, 20 MaybeHandle<Name>(), Type::Any(), 21 MachineType::AnyTagged()}; 22 return access; 23 } 24 25 26 // static 27 FieldAccess AccessBuilder::ForHeapNumberValue() { 28 FieldAccess access = {kTaggedBase, HeapNumber::kValueOffset, 29 MaybeHandle<Name>(), TypeCache().Get().kFloat64, 30 MachineType::Float64()}; 31 return access; 32 } 33 34 35 // static 36 FieldAccess AccessBuilder::ForJSObjectProperties() { 37 FieldAccess access = {kTaggedBase, JSObject::kPropertiesOffset, 38 MaybeHandle<Name>(), Type::Internal(), 39 MachineType::AnyTagged()}; 40 return access; 41 } 42 43 44 // static 45 FieldAccess AccessBuilder::ForJSObjectElements() { 46 FieldAccess access = {kTaggedBase, JSObject::kElementsOffset, 47 MaybeHandle<Name>(), Type::Internal(), 48 MachineType::AnyTagged()}; 49 return access; 50 } 51 52 53 // static 54 FieldAccess AccessBuilder::ForJSObjectInObjectProperty(Handle<Map> map, 55 int index) { 56 int const offset = map->GetInObjectPropertyOffset(index); 57 FieldAccess access = {kTaggedBase, offset, MaybeHandle<Name>(), 58 Type::Tagged(), MachineType::AnyTagged()}; 59 return access; 60 } 61 62 63 // static 64 FieldAccess AccessBuilder::ForJSFunctionContext() { 65 FieldAccess access = {kTaggedBase, JSFunction::kContextOffset, 66 MaybeHandle<Name>(), Type::Internal(), 67 MachineType::AnyTagged()}; 68 return access; 69 } 70 71 72 // static 73 FieldAccess AccessBuilder::ForJSFunctionSharedFunctionInfo() { 74 FieldAccess access = {kTaggedBase, JSFunction::kSharedFunctionInfoOffset, 75 Handle<Name>(), Type::Any(), MachineType::AnyTagged()}; 76 return access; 77 } 78 79 80 // static 81 FieldAccess AccessBuilder::ForJSArrayLength(ElementsKind elements_kind) { 82 TypeCache const& type_cache = TypeCache::Get(); 83 FieldAccess access = {kTaggedBase, JSArray::kLengthOffset, Handle<Name>(), 84 type_cache.kJSArrayLengthType, 85 MachineType::AnyTagged()}; 86 if (IsFastDoubleElementsKind(elements_kind)) { 87 access.type = type_cache.kFixedDoubleArrayLengthType; 88 } else if (IsFastElementsKind(elements_kind)) { 89 access.type = type_cache.kFixedArrayLengthType; 90 } 91 return access; 92 } 93 94 95 // static 96 FieldAccess AccessBuilder::ForJSArrayBufferBackingStore() { 97 FieldAccess access = {kTaggedBase, JSArrayBuffer::kBackingStoreOffset, 98 MaybeHandle<Name>(), Type::UntaggedPointer(), 99 MachineType::Pointer()}; 100 return access; 101 } 102 103 104 // static 105 FieldAccess AccessBuilder::ForJSArrayBufferBitField() { 106 FieldAccess access = {kTaggedBase, JSArrayBuffer::kBitFieldOffset, 107 MaybeHandle<Name>(), TypeCache::Get().kInt8, 108 MachineType::Int8()}; 109 return access; 110 } 111 112 113 // static 114 FieldAccess AccessBuilder::ForJSArrayBufferViewBuffer() { 115 FieldAccess access = {kTaggedBase, JSArrayBufferView::kBufferOffset, 116 MaybeHandle<Name>(), Type::TaggedPointer(), 117 MachineType::AnyTagged()}; 118 return access; 119 } 120 121 122 // static 123 FieldAccess AccessBuilder::ForJSDateField(JSDate::FieldIndex index) { 124 FieldAccess access = { 125 kTaggedBase, JSDate::kValueOffset + index * kPointerSize, 126 MaybeHandle<Name>(), Type::Number(), MachineType::AnyTagged()}; 127 return access; 128 } 129 130 131 // static 132 FieldAccess AccessBuilder::ForJSIteratorResultDone() { 133 FieldAccess access = {kTaggedBase, JSIteratorResult::kDoneOffset, 134 MaybeHandle<Name>(), Type::Any(), 135 MachineType::AnyTagged()}; 136 return access; 137 } 138 139 140 // static 141 FieldAccess AccessBuilder::ForJSIteratorResultValue() { 142 FieldAccess access = {kTaggedBase, JSIteratorResult::kValueOffset, 143 MaybeHandle<Name>(), Type::Any(), 144 MachineType::AnyTagged()}; 145 return access; 146 } 147 148 149 // static 150 FieldAccess AccessBuilder::ForJSRegExpFlags() { 151 FieldAccess access = {kTaggedBase, JSRegExp::kFlagsOffset, 152 MaybeHandle<Name>(), Type::Tagged(), 153 MachineType::AnyTagged()}; 154 return access; 155 } 156 157 158 // static 159 FieldAccess AccessBuilder::ForJSRegExpSource() { 160 FieldAccess access = {kTaggedBase, JSRegExp::kSourceOffset, 161 MaybeHandle<Name>(), Type::Tagged(), 162 MachineType::AnyTagged()}; 163 return access; 164 } 165 166 167 // static 168 FieldAccess AccessBuilder::ForFixedArrayLength() { 169 FieldAccess access = { 170 kTaggedBase, FixedArray::kLengthOffset, MaybeHandle<Name>(), 171 TypeCache::Get().kFixedArrayLengthType, MachineType::AnyTagged()}; 172 return access; 173 } 174 175 176 // static 177 FieldAccess AccessBuilder::ForDescriptorArrayEnumCache() { 178 FieldAccess access = {kTaggedBase, DescriptorArray::kEnumCacheOffset, 179 Handle<Name>(), Type::TaggedPointer(), 180 MachineType::AnyTagged()}; 181 return access; 182 } 183 184 185 // static 186 FieldAccess AccessBuilder::ForDescriptorArrayEnumCacheBridgeCache() { 187 FieldAccess access = { 188 kTaggedBase, DescriptorArray::kEnumCacheBridgeCacheOffset, Handle<Name>(), 189 Type::TaggedPointer(), MachineType::AnyTagged()}; 190 return access; 191 } 192 193 194 // static 195 FieldAccess AccessBuilder::ForMapBitField() { 196 FieldAccess access = {kTaggedBase, Map::kBitFieldOffset, Handle<Name>(), 197 TypeCache::Get().kUint8, MachineType::Uint8()}; 198 return access; 199 } 200 201 202 // static 203 FieldAccess AccessBuilder::ForMapBitField3() { 204 FieldAccess access = {kTaggedBase, Map::kBitField3Offset, Handle<Name>(), 205 TypeCache::Get().kInt32, MachineType::Int32()}; 206 return access; 207 } 208 209 210 // static 211 FieldAccess AccessBuilder::ForMapDescriptors() { 212 FieldAccess access = {kTaggedBase, Map::kDescriptorsOffset, Handle<Name>(), 213 Type::TaggedPointer(), MachineType::AnyTagged()}; 214 return access; 215 } 216 217 218 // static 219 FieldAccess AccessBuilder::ForMapInstanceType() { 220 FieldAccess access = {kTaggedBase, Map::kInstanceTypeOffset, Handle<Name>(), 221 TypeCache::Get().kUint8, MachineType::Uint8()}; 222 return access; 223 } 224 225 226 // static 227 FieldAccess AccessBuilder::ForMapPrototype() { 228 FieldAccess access = {kTaggedBase, Map::kPrototypeOffset, Handle<Name>(), 229 Type::TaggedPointer(), MachineType::AnyTagged()}; 230 return access; 231 } 232 233 234 // static 235 FieldAccess AccessBuilder::ForStringLength() { 236 FieldAccess access = {kTaggedBase, String::kLengthOffset, Handle<Name>(), 237 TypeCache::Get().kStringLengthType, 238 MachineType::AnyTagged()}; 239 return access; 240 } 241 242 243 // static 244 FieldAccess AccessBuilder::ForJSGlobalObjectGlobalProxy() { 245 FieldAccess access = {kTaggedBase, JSGlobalObject::kGlobalProxyOffset, 246 Handle<Name>(), Type::Receiver(), 247 MachineType::AnyTagged()}; 248 return access; 249 } 250 251 252 // static 253 FieldAccess AccessBuilder::ForJSGlobalObjectNativeContext() { 254 FieldAccess access = {kTaggedBase, JSGlobalObject::kNativeContextOffset, 255 Handle<Name>(), Type::Internal(), 256 MachineType::AnyTagged()}; 257 return access; 258 } 259 260 261 // static 262 FieldAccess AccessBuilder::ForValue() { 263 FieldAccess access = {kTaggedBase, JSValue::kValueOffset, Handle<Name>(), 264 Type::Any(), MachineType::AnyTagged()}; 265 return access; 266 } 267 268 269 // static 270 FieldAccess AccessBuilder::ForArgumentsLength() { 271 int offset = 272 JSObject::kHeaderSize + Heap::kArgumentsLengthIndex * kPointerSize; 273 FieldAccess access = {kTaggedBase, offset, Handle<Name>(), Type::Any(), 274 MachineType::AnyTagged()}; 275 return access; 276 } 277 278 279 // static 280 FieldAccess AccessBuilder::ForArgumentsCallee() { 281 int offset = 282 JSObject::kHeaderSize + Heap::kArgumentsCalleeIndex * kPointerSize; 283 FieldAccess access = {kTaggedBase, offset, Handle<Name>(), Type::Any(), 284 MachineType::AnyTagged()}; 285 return access; 286 } 287 288 289 // static 290 FieldAccess AccessBuilder::ForFixedArraySlot(size_t index) { 291 int offset = FixedArray::OffsetOfElementAt(static_cast<int>(index)); 292 FieldAccess access = {kTaggedBase, offset, Handle<Name>(), Type::Any(), 293 MachineType::AnyTagged()}; 294 return access; 295 } 296 297 298 // static 299 FieldAccess AccessBuilder::ForContextSlot(size_t index) { 300 int offset = Context::kHeaderSize + static_cast<int>(index) * kPointerSize; 301 DCHECK_EQ(offset, 302 Context::SlotOffset(static_cast<int>(index)) + kHeapObjectTag); 303 FieldAccess access = {kTaggedBase, offset, Handle<Name>(), Type::Any(), 304 MachineType::AnyTagged()}; 305 return access; 306 } 307 308 309 // static 310 FieldAccess AccessBuilder::ForPropertyCellValue() { 311 return ForPropertyCellValue(Type::Tagged()); 312 } 313 314 315 // static 316 FieldAccess AccessBuilder::ForPropertyCellValue(Type* type) { 317 FieldAccess access = {kTaggedBase, PropertyCell::kValueOffset, Handle<Name>(), 318 type, MachineType::AnyTagged()}; 319 return access; 320 } 321 322 323 // static 324 FieldAccess AccessBuilder::ForSharedFunctionInfoTypeFeedbackVector() { 325 FieldAccess access = {kTaggedBase, SharedFunctionInfo::kFeedbackVectorOffset, 326 Handle<Name>(), Type::Any(), MachineType::AnyTagged()}; 327 return access; 328 } 329 330 331 // static 332 ElementAccess AccessBuilder::ForFixedArrayElement() { 333 ElementAccess access = {kTaggedBase, FixedArray::kHeaderSize, Type::Tagged(), 334 MachineType::AnyTagged()}; 335 return access; 336 } 337 338 339 // static 340 ElementAccess AccessBuilder::ForFixedDoubleArrayElement() { 341 ElementAccess access = {kTaggedBase, FixedDoubleArray::kHeaderSize, 342 TypeCache::Get().kFloat64, MachineType::Float64()}; 343 return access; 344 } 345 346 347 // static 348 ElementAccess AccessBuilder::ForTypedArrayElement(ExternalArrayType type, 349 bool is_external) { 350 BaseTaggedness taggedness = is_external ? kUntaggedBase : kTaggedBase; 351 int header_size = is_external ? 0 : FixedTypedArrayBase::kDataOffset; 352 switch (type) { 353 case kExternalInt8Array: { 354 ElementAccess access = {taggedness, header_size, Type::Signed32(), 355 MachineType::Int8()}; 356 return access; 357 } 358 case kExternalUint8Array: 359 case kExternalUint8ClampedArray: { 360 ElementAccess access = {taggedness, header_size, Type::Unsigned32(), 361 MachineType::Uint8()}; 362 return access; 363 } 364 case kExternalInt16Array: { 365 ElementAccess access = {taggedness, header_size, Type::Signed32(), 366 MachineType::Int16()}; 367 return access; 368 } 369 case kExternalUint16Array: { 370 ElementAccess access = {taggedness, header_size, Type::Unsigned32(), 371 MachineType::Uint16()}; 372 return access; 373 } 374 case kExternalInt32Array: { 375 ElementAccess access = {taggedness, header_size, Type::Signed32(), 376 MachineType::Int32()}; 377 return access; 378 } 379 case kExternalUint32Array: { 380 ElementAccess access = {taggedness, header_size, Type::Unsigned32(), 381 MachineType::Uint32()}; 382 return access; 383 } 384 case kExternalFloat32Array: { 385 ElementAccess access = {taggedness, header_size, Type::Number(), 386 MachineType::Float32()}; 387 return access; 388 } 389 case kExternalFloat64Array: { 390 ElementAccess access = {taggedness, header_size, Type::Number(), 391 MachineType::Float64()}; 392 return access; 393 } 394 } 395 UNREACHABLE(); 396 ElementAccess access = {kUntaggedBase, 0, Type::None(), MachineType::None()}; 397 return access; 398 } 399 400 401 // static 402 FieldAccess AccessBuilder::ForStatsCounter() { 403 FieldAccess access = {kUntaggedBase, 0, MaybeHandle<Name>(), 404 TypeCache::Get().kInt32, MachineType::Int32()}; 405 return access; 406 } 407 408 } // namespace compiler 409 } // namespace internal 410 } // namespace v8 411