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/handles-inl.h" 10 #include "src/heap/heap.h" 11 #include "src/type-cache.h" 12 13 namespace v8 { 14 namespace internal { 15 namespace compiler { 16 17 // static 18 FieldAccess AccessBuilder::ForMap() { 19 FieldAccess access = { 20 kTaggedBase, HeapObject::kMapOffset, MaybeHandle<Name>(), 21 Type::Any(), MachineType::AnyTagged(), kMapWriteBarrier}; 22 return access; 23 } 24 25 26 // static 27 FieldAccess AccessBuilder::ForHeapNumberValue() { 28 FieldAccess access = {kTaggedBase, 29 HeapNumber::kValueOffset, 30 MaybeHandle<Name>(), 31 TypeCache::Get().kFloat64, 32 MachineType::Float64(), 33 kNoWriteBarrier}; 34 return access; 35 } 36 37 38 // static 39 FieldAccess AccessBuilder::ForJSObjectProperties() { 40 FieldAccess access = { 41 kTaggedBase, JSObject::kPropertiesOffset, MaybeHandle<Name>(), 42 Type::Internal(), MachineType::AnyTagged(), kPointerWriteBarrier}; 43 return access; 44 } 45 46 47 // static 48 FieldAccess AccessBuilder::ForJSObjectElements() { 49 FieldAccess access = { 50 kTaggedBase, JSObject::kElementsOffset, MaybeHandle<Name>(), 51 Type::Internal(), MachineType::AnyTagged(), kPointerWriteBarrier}; 52 return access; 53 } 54 55 56 // static 57 FieldAccess AccessBuilder::ForJSObjectInObjectProperty(Handle<Map> map, 58 int index) { 59 int const offset = map->GetInObjectPropertyOffset(index); 60 FieldAccess access = {kTaggedBase, 61 offset, 62 MaybeHandle<Name>(), 63 Type::Tagged(), 64 MachineType::AnyTagged(), 65 kFullWriteBarrier}; 66 return access; 67 } 68 69 70 // static 71 FieldAccess AccessBuilder::ForJSFunctionPrototypeOrInitialMap() { 72 FieldAccess access = {kTaggedBase, 73 JSFunction::kPrototypeOrInitialMapOffset, 74 MaybeHandle<Name>(), 75 Type::Any(), 76 MachineType::AnyTagged(), 77 kFullWriteBarrier}; 78 return access; 79 } 80 81 // static 82 FieldAccess AccessBuilder::ForJSFunctionContext() { 83 FieldAccess access = { 84 kTaggedBase, JSFunction::kContextOffset, MaybeHandle<Name>(), 85 Type::Internal(), MachineType::AnyTagged(), kPointerWriteBarrier}; 86 return access; 87 } 88 89 90 // static 91 FieldAccess AccessBuilder::ForJSFunctionSharedFunctionInfo() { 92 FieldAccess access = {kTaggedBase, 93 JSFunction::kSharedFunctionInfoOffset, 94 Handle<Name>(), 95 Type::Any(), 96 MachineType::AnyTagged(), 97 kPointerWriteBarrier}; 98 return access; 99 } 100 101 // static 102 FieldAccess AccessBuilder::ForJSFunctionLiterals() { 103 FieldAccess access = { 104 kTaggedBase, JSFunction::kLiteralsOffset, Handle<Name>(), 105 Type::Internal(), MachineType::AnyTagged(), kPointerWriteBarrier}; 106 return access; 107 } 108 109 // static 110 FieldAccess AccessBuilder::ForJSFunctionCodeEntry() { 111 FieldAccess access = {kTaggedBase, 112 JSFunction::kCodeEntryOffset, 113 Handle<Name>(), 114 Type::UntaggedPointer(), 115 MachineType::Pointer(), 116 kNoWriteBarrier}; 117 return access; 118 } 119 120 // static 121 FieldAccess AccessBuilder::ForJSFunctionNextFunctionLink() { 122 FieldAccess access = {kTaggedBase, 123 JSFunction::kNextFunctionLinkOffset, 124 Handle<Name>(), 125 Type::Any(), 126 MachineType::AnyTagged(), 127 kPointerWriteBarrier}; 128 return access; 129 } 130 131 // static 132 FieldAccess AccessBuilder::ForJSGeneratorObjectContext() { 133 FieldAccess access = {kTaggedBase, 134 JSGeneratorObject::kContextOffset, 135 Handle<Name>(), 136 Type::Internal(), 137 MachineType::AnyTagged(), 138 kPointerWriteBarrier}; 139 return access; 140 } 141 142 // static 143 FieldAccess AccessBuilder::ForJSGeneratorObjectContinuation() { 144 TypeCache const& type_cache = TypeCache::Get(); 145 FieldAccess access = {kTaggedBase, 146 JSGeneratorObject::kContinuationOffset, 147 Handle<Name>(), 148 type_cache.kSmi, 149 MachineType::AnyTagged(), 150 kNoWriteBarrier}; 151 return access; 152 } 153 154 // static 155 FieldAccess AccessBuilder::ForJSGeneratorObjectInputOrDebugPos() { 156 FieldAccess access = {kTaggedBase, 157 JSGeneratorObject::kInputOrDebugPosOffset, 158 Handle<Name>(), 159 Type::Any(), 160 MachineType::AnyTagged(), 161 kFullWriteBarrier}; 162 return access; 163 } 164 165 // static 166 FieldAccess AccessBuilder::ForJSGeneratorObjectOperandStack() { 167 FieldAccess access = {kTaggedBase, 168 JSGeneratorObject::kOperandStackOffset, 169 Handle<Name>(), 170 Type::Internal(), 171 MachineType::AnyTagged(), 172 kPointerWriteBarrier}; 173 return access; 174 } 175 176 // static 177 FieldAccess AccessBuilder::ForJSGeneratorObjectResumeMode() { 178 TypeCache const& type_cache = TypeCache::Get(); 179 FieldAccess access = {kTaggedBase, 180 JSGeneratorObject::kResumeModeOffset, 181 Handle<Name>(), 182 type_cache.kSmi, 183 MachineType::AnyTagged(), 184 kNoWriteBarrier}; 185 return access; 186 } 187 188 // static 189 FieldAccess AccessBuilder::ForJSArrayLength(ElementsKind elements_kind) { 190 TypeCache const& type_cache = TypeCache::Get(); 191 FieldAccess access = {kTaggedBase, 192 JSArray::kLengthOffset, 193 Handle<Name>(), 194 type_cache.kJSArrayLengthType, 195 MachineType::AnyTagged(), 196 kFullWriteBarrier}; 197 if (IsFastDoubleElementsKind(elements_kind)) { 198 access.type = type_cache.kFixedDoubleArrayLengthType; 199 access.write_barrier_kind = kNoWriteBarrier; 200 } else if (IsFastElementsKind(elements_kind)) { 201 access.type = type_cache.kFixedArrayLengthType; 202 access.write_barrier_kind = kNoWriteBarrier; 203 } 204 return access; 205 } 206 207 208 // static 209 FieldAccess AccessBuilder::ForJSArrayBufferBackingStore() { 210 FieldAccess access = {kTaggedBase, 211 JSArrayBuffer::kBackingStoreOffset, 212 MaybeHandle<Name>(), 213 Type::UntaggedPointer(), 214 MachineType::Pointer(), 215 kNoWriteBarrier}; 216 return access; 217 } 218 219 220 // static 221 FieldAccess AccessBuilder::ForJSArrayBufferBitField() { 222 FieldAccess access = {kTaggedBase, JSArrayBuffer::kBitFieldOffset, 223 MaybeHandle<Name>(), TypeCache::Get().kInt8, 224 MachineType::Int8(), kNoWriteBarrier}; 225 return access; 226 } 227 228 229 // static 230 FieldAccess AccessBuilder::ForJSArrayBufferViewBuffer() { 231 FieldAccess access = {kTaggedBase, 232 JSArrayBufferView::kBufferOffset, 233 MaybeHandle<Name>(), 234 Type::TaggedPointer(), 235 MachineType::AnyTagged(), 236 kPointerWriteBarrier}; 237 return access; 238 } 239 240 241 // static 242 FieldAccess AccessBuilder::ForJSDateField(JSDate::FieldIndex index) { 243 FieldAccess access = {kTaggedBase, 244 JSDate::kValueOffset + index * kPointerSize, 245 MaybeHandle<Name>(), 246 Type::Number(), 247 MachineType::AnyTagged(), 248 kFullWriteBarrier}; 249 return access; 250 } 251 252 253 // static 254 FieldAccess AccessBuilder::ForJSIteratorResultDone() { 255 FieldAccess access = { 256 kTaggedBase, JSIteratorResult::kDoneOffset, MaybeHandle<Name>(), 257 Type::Any(), MachineType::AnyTagged(), kFullWriteBarrier}; 258 return access; 259 } 260 261 262 // static 263 FieldAccess AccessBuilder::ForJSIteratorResultValue() { 264 FieldAccess access = { 265 kTaggedBase, JSIteratorResult::kValueOffset, MaybeHandle<Name>(), 266 Type::Any(), MachineType::AnyTagged(), kFullWriteBarrier}; 267 return access; 268 } 269 270 271 // static 272 FieldAccess AccessBuilder::ForJSRegExpFlags() { 273 FieldAccess access = { 274 kTaggedBase, JSRegExp::kFlagsOffset, MaybeHandle<Name>(), 275 Type::Tagged(), MachineType::AnyTagged(), kFullWriteBarrier}; 276 return access; 277 } 278 279 280 // static 281 FieldAccess AccessBuilder::ForJSRegExpSource() { 282 FieldAccess access = { 283 kTaggedBase, JSRegExp::kSourceOffset, MaybeHandle<Name>(), 284 Type::Tagged(), MachineType::AnyTagged(), kFullWriteBarrier}; 285 return access; 286 } 287 288 289 // static 290 FieldAccess AccessBuilder::ForFixedArrayLength() { 291 FieldAccess access = {kTaggedBase, 292 FixedArray::kLengthOffset, 293 MaybeHandle<Name>(), 294 TypeCache::Get().kFixedArrayLengthType, 295 MachineType::AnyTagged(), 296 kNoWriteBarrier}; 297 return access; 298 } 299 300 301 // static 302 FieldAccess AccessBuilder::ForDescriptorArrayEnumCache() { 303 FieldAccess access = {kTaggedBase, 304 DescriptorArray::kEnumCacheOffset, 305 Handle<Name>(), 306 Type::TaggedPointer(), 307 MachineType::AnyTagged(), 308 kPointerWriteBarrier}; 309 return access; 310 } 311 312 313 // static 314 FieldAccess AccessBuilder::ForDescriptorArrayEnumCacheBridgeCache() { 315 FieldAccess access = {kTaggedBase, 316 DescriptorArray::kEnumCacheBridgeCacheOffset, 317 Handle<Name>(), 318 Type::TaggedPointer(), 319 MachineType::AnyTagged(), 320 kPointerWriteBarrier}; 321 return access; 322 } 323 324 325 // static 326 FieldAccess AccessBuilder::ForMapBitField() { 327 FieldAccess access = {kTaggedBase, Map::kBitFieldOffset, 328 Handle<Name>(), TypeCache::Get().kUint8, 329 MachineType::Uint8(), kNoWriteBarrier}; 330 return access; 331 } 332 333 334 // static 335 FieldAccess AccessBuilder::ForMapBitField3() { 336 FieldAccess access = {kTaggedBase, Map::kBitField3Offset, 337 Handle<Name>(), TypeCache::Get().kInt32, 338 MachineType::Int32(), kNoWriteBarrier}; 339 return access; 340 } 341 342 343 // static 344 FieldAccess AccessBuilder::ForMapDescriptors() { 345 FieldAccess access = { 346 kTaggedBase, Map::kDescriptorsOffset, Handle<Name>(), 347 Type::TaggedPointer(), MachineType::AnyTagged(), kPointerWriteBarrier}; 348 return access; 349 } 350 351 352 // static 353 FieldAccess AccessBuilder::ForMapInstanceType() { 354 FieldAccess access = {kTaggedBase, Map::kInstanceTypeOffset, 355 Handle<Name>(), TypeCache::Get().kUint8, 356 MachineType::Uint8(), kNoWriteBarrier}; 357 return access; 358 } 359 360 361 // static 362 FieldAccess AccessBuilder::ForMapPrototype() { 363 FieldAccess access = { 364 kTaggedBase, Map::kPrototypeOffset, Handle<Name>(), 365 Type::TaggedPointer(), MachineType::AnyTagged(), kPointerWriteBarrier}; 366 return access; 367 } 368 369 370 // static 371 FieldAccess AccessBuilder::ForNameHashField() { 372 FieldAccess access = {kTaggedBase, Name::kHashFieldOffset, 373 Handle<Name>(), Type::Internal(), 374 MachineType::Uint32(), kNoWriteBarrier}; 375 return access; 376 } 377 378 // static 379 FieldAccess AccessBuilder::ForStringLength() { 380 FieldAccess access = {kTaggedBase, 381 String::kLengthOffset, 382 Handle<Name>(), 383 TypeCache::Get().kStringLengthType, 384 MachineType::AnyTagged(), 385 kNoWriteBarrier}; 386 return access; 387 } 388 389 390 // static 391 FieldAccess AccessBuilder::ForJSGlobalObjectGlobalProxy() { 392 FieldAccess access = {kTaggedBase, 393 JSGlobalObject::kGlobalProxyOffset, 394 Handle<Name>(), 395 Type::Receiver(), 396 MachineType::AnyTagged(), 397 kPointerWriteBarrier}; 398 return access; 399 } 400 401 402 // static 403 FieldAccess AccessBuilder::ForJSGlobalObjectNativeContext() { 404 FieldAccess access = {kTaggedBase, 405 JSGlobalObject::kNativeContextOffset, 406 Handle<Name>(), 407 Type::Internal(), 408 MachineType::AnyTagged(), 409 kPointerWriteBarrier}; 410 return access; 411 } 412 413 414 // static 415 FieldAccess AccessBuilder::ForValue() { 416 FieldAccess access = { 417 kTaggedBase, JSValue::kValueOffset, Handle<Name>(), 418 Type::Any(), MachineType::AnyTagged(), kFullWriteBarrier}; 419 return access; 420 } 421 422 423 // static 424 FieldAccess AccessBuilder::ForArgumentsLength() { 425 FieldAccess access = { 426 kTaggedBase, JSArgumentsObject::kLengthOffset, Handle<Name>(), 427 Type::Any(), MachineType::AnyTagged(), kFullWriteBarrier}; 428 return access; 429 } 430 431 432 // static 433 FieldAccess AccessBuilder::ForArgumentsCallee() { 434 FieldAccess access = {kTaggedBase, 435 JSSloppyArgumentsObject::kCalleeOffset, 436 Handle<Name>(), 437 Type::Any(), 438 MachineType::AnyTagged(), 439 kPointerWriteBarrier}; 440 return access; 441 } 442 443 444 // static 445 FieldAccess AccessBuilder::ForFixedArraySlot(size_t index) { 446 int offset = FixedArray::OffsetOfElementAt(static_cast<int>(index)); 447 FieldAccess access = {kTaggedBase, 448 offset, 449 Handle<Name>(), 450 Type::Any(), 451 MachineType::AnyTagged(), 452 kFullWriteBarrier}; 453 return access; 454 } 455 456 457 // static 458 FieldAccess AccessBuilder::ForContextSlot(size_t index) { 459 int offset = Context::kHeaderSize + static_cast<int>(index) * kPointerSize; 460 DCHECK_EQ(offset, 461 Context::SlotOffset(static_cast<int>(index)) + kHeapObjectTag); 462 FieldAccess access = {kTaggedBase, 463 offset, 464 Handle<Name>(), 465 Type::Any(), 466 MachineType::AnyTagged(), 467 kFullWriteBarrier}; 468 return access; 469 } 470 471 472 // static 473 FieldAccess AccessBuilder::ForPropertyCellValue() { 474 return ForPropertyCellValue(Type::Tagged()); 475 } 476 477 478 // static 479 FieldAccess AccessBuilder::ForPropertyCellValue(Type* type) { 480 FieldAccess access = { 481 kTaggedBase, PropertyCell::kValueOffset, Handle<Name>(), 482 type, MachineType::AnyTagged(), kFullWriteBarrier}; 483 return access; 484 } 485 486 // static 487 ElementAccess AccessBuilder::ForFixedArrayElement() { 488 ElementAccess access = {kTaggedBase, FixedArray::kHeaderSize, Type::Tagged(), 489 MachineType::AnyTagged(), kFullWriteBarrier}; 490 return access; 491 } 492 493 494 // static 495 ElementAccess AccessBuilder::ForFixedDoubleArrayElement() { 496 ElementAccess access = {kTaggedBase, FixedDoubleArray::kHeaderSize, 497 TypeCache::Get().kFloat64, MachineType::Float64(), 498 kNoWriteBarrier}; 499 return access; 500 } 501 502 503 // static 504 ElementAccess AccessBuilder::ForTypedArrayElement(ExternalArrayType type, 505 bool is_external) { 506 BaseTaggedness taggedness = is_external ? kUntaggedBase : kTaggedBase; 507 int header_size = is_external ? 0 : FixedTypedArrayBase::kDataOffset; 508 switch (type) { 509 case kExternalInt8Array: { 510 ElementAccess access = {taggedness, header_size, Type::Signed32(), 511 MachineType::Int8(), kNoWriteBarrier}; 512 return access; 513 } 514 case kExternalUint8Array: 515 case kExternalUint8ClampedArray: { 516 ElementAccess access = {taggedness, header_size, Type::Unsigned32(), 517 MachineType::Uint8(), kNoWriteBarrier}; 518 return access; 519 } 520 case kExternalInt16Array: { 521 ElementAccess access = {taggedness, header_size, Type::Signed32(), 522 MachineType::Int16(), kNoWriteBarrier}; 523 return access; 524 } 525 case kExternalUint16Array: { 526 ElementAccess access = {taggedness, header_size, Type::Unsigned32(), 527 MachineType::Uint16(), kNoWriteBarrier}; 528 return access; 529 } 530 case kExternalInt32Array: { 531 ElementAccess access = {taggedness, header_size, Type::Signed32(), 532 MachineType::Int32(), kNoWriteBarrier}; 533 return access; 534 } 535 case kExternalUint32Array: { 536 ElementAccess access = {taggedness, header_size, Type::Unsigned32(), 537 MachineType::Uint32(), kNoWriteBarrier}; 538 return access; 539 } 540 case kExternalFloat32Array: { 541 ElementAccess access = {taggedness, header_size, Type::Number(), 542 MachineType::Float32(), kNoWriteBarrier}; 543 return access; 544 } 545 case kExternalFloat64Array: { 546 ElementAccess access = {taggedness, header_size, Type::Number(), 547 MachineType::Float64(), kNoWriteBarrier}; 548 return access; 549 } 550 } 551 UNREACHABLE(); 552 ElementAccess access = {kUntaggedBase, 0, Type::None(), MachineType::None(), 553 kNoWriteBarrier}; 554 return access; 555 } 556 557 } // namespace compiler 558 } // namespace internal 559 } // namespace v8 560