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_OBJECTS_BODY_DESCRIPTORS_INL_H_ 6 #define V8_OBJECTS_BODY_DESCRIPTORS_INL_H_ 7 8 #include "src/assembler-inl.h" 9 #include "src/objects-body-descriptors.h" 10 #include "src/transitions.h" 11 12 namespace v8 { 13 namespace internal { 14 15 template <int start_offset> 16 int FlexibleBodyDescriptor<start_offset>::SizeOf(Map* map, HeapObject* object) { 17 return object->SizeFromMap(map); 18 } 19 20 21 bool BodyDescriptorBase::IsValidSlotImpl(HeapObject* obj, int offset) { 22 if (!FLAG_unbox_double_fields || obj->map()->HasFastPointerLayout()) { 23 return true; 24 } else { 25 DCHECK(FLAG_unbox_double_fields); 26 DCHECK(IsAligned(offset, kPointerSize)); 27 28 LayoutDescriptorHelper helper(obj->map()); 29 DCHECK(!helper.all_fields_tagged()); 30 return helper.IsTagged(offset); 31 } 32 } 33 34 template <typename ObjectVisitor> 35 void BodyDescriptorBase::IterateBodyImpl(HeapObject* obj, int start_offset, 36 int end_offset, ObjectVisitor* v) { 37 if (!FLAG_unbox_double_fields || obj->map()->HasFastPointerLayout()) { 38 IteratePointers(obj, start_offset, end_offset, v); 39 } else { 40 DCHECK(FLAG_unbox_double_fields); 41 DCHECK(IsAligned(start_offset, kPointerSize) && 42 IsAligned(end_offset, kPointerSize)); 43 44 LayoutDescriptorHelper helper(obj->map()); 45 DCHECK(!helper.all_fields_tagged()); 46 for (int offset = start_offset; offset < end_offset;) { 47 int end_of_region_offset; 48 if (helper.IsTagged(offset, end_offset, &end_of_region_offset)) { 49 IteratePointers(obj, offset, end_of_region_offset, v); 50 } 51 offset = end_of_region_offset; 52 } 53 } 54 } 55 56 57 template <typename StaticVisitor> 58 void BodyDescriptorBase::IterateBodyImpl(Heap* heap, HeapObject* obj, 59 int start_offset, int end_offset) { 60 if (!FLAG_unbox_double_fields || obj->map()->HasFastPointerLayout()) { 61 IteratePointers<StaticVisitor>(heap, obj, start_offset, end_offset); 62 } else { 63 DCHECK(FLAG_unbox_double_fields); 64 DCHECK(IsAligned(start_offset, kPointerSize) && 65 IsAligned(end_offset, kPointerSize)); 66 67 LayoutDescriptorHelper helper(obj->map()); 68 DCHECK(!helper.all_fields_tagged()); 69 for (int offset = start_offset; offset < end_offset;) { 70 int end_of_region_offset; 71 if (helper.IsTagged(offset, end_offset, &end_of_region_offset)) { 72 IteratePointers<StaticVisitor>(heap, obj, offset, end_of_region_offset); 73 } 74 offset = end_of_region_offset; 75 } 76 } 77 } 78 79 80 template <typename ObjectVisitor> 81 DISABLE_CFI_PERF 82 void BodyDescriptorBase::IteratePointers(HeapObject* obj, int start_offset, 83 int end_offset, ObjectVisitor* v) { 84 v->VisitPointers(HeapObject::RawField(obj, start_offset), 85 HeapObject::RawField(obj, end_offset)); 86 } 87 88 89 template <typename StaticVisitor> 90 DISABLE_CFI_PERF 91 void BodyDescriptorBase::IteratePointers(Heap* heap, HeapObject* obj, 92 int start_offset, int end_offset) { 93 StaticVisitor::VisitPointers(heap, obj, 94 HeapObject::RawField(obj, start_offset), 95 HeapObject::RawField(obj, end_offset)); 96 } 97 98 99 template <typename ObjectVisitor> 100 void BodyDescriptorBase::IteratePointer(HeapObject* obj, int offset, 101 ObjectVisitor* v) { 102 v->VisitPointer(HeapObject::RawField(obj, offset)); 103 } 104 105 106 template <typename StaticVisitor> 107 void BodyDescriptorBase::IteratePointer(Heap* heap, HeapObject* obj, 108 int offset) { 109 StaticVisitor::VisitPointer(heap, obj, HeapObject::RawField(obj, offset)); 110 } 111 112 113 // Iterates the function object according to the visiting policy. 114 template <JSFunction::BodyVisitingPolicy body_visiting_policy> 115 class JSFunction::BodyDescriptorImpl final : public BodyDescriptorBase { 116 public: 117 STATIC_ASSERT(kNonWeakFieldsEndOffset == kCodeEntryOffset); 118 STATIC_ASSERT(kCodeEntryOffset + kPointerSize == kNextFunctionLinkOffset); 119 STATIC_ASSERT(kNextFunctionLinkOffset + kPointerSize == kSize); 120 121 static bool IsValidSlot(HeapObject* obj, int offset) { 122 if (offset < kSize) return true; 123 return IsValidSlotImpl(obj, offset); 124 } 125 126 template <typename ObjectVisitor> 127 static inline void IterateBody(HeapObject* obj, int object_size, 128 ObjectVisitor* v) { 129 IteratePointers(obj, kPropertiesOffset, kNonWeakFieldsEndOffset, v); 130 131 if (body_visiting_policy & kVisitCodeEntry) { 132 v->VisitCodeEntry(obj->address() + kCodeEntryOffset); 133 } 134 135 if (body_visiting_policy & kVisitNextFunction) { 136 IteratePointers(obj, kNextFunctionLinkOffset, kSize, v); 137 } 138 IterateBodyImpl(obj, kSize, object_size, v); 139 } 140 141 template <typename StaticVisitor> 142 static inline void IterateBody(HeapObject* obj, int object_size) { 143 Heap* heap = obj->GetHeap(); 144 IteratePointers<StaticVisitor>(heap, obj, kPropertiesOffset, 145 kNonWeakFieldsEndOffset); 146 147 if (body_visiting_policy & kVisitCodeEntry) { 148 StaticVisitor::VisitCodeEntry(heap, obj, 149 obj->address() + kCodeEntryOffset); 150 } 151 152 if (body_visiting_policy & kVisitNextFunction) { 153 IteratePointers<StaticVisitor>(heap, obj, kNextFunctionLinkOffset, kSize); 154 } 155 IterateBodyImpl<StaticVisitor>(heap, obj, kSize, object_size); 156 } 157 158 static inline int SizeOf(Map* map, HeapObject* object) { 159 return map->instance_size(); 160 } 161 }; 162 163 164 class JSArrayBuffer::BodyDescriptor final : public BodyDescriptorBase { 165 public: 166 STATIC_ASSERT(kByteLengthOffset + kPointerSize == kBackingStoreOffset); 167 STATIC_ASSERT(kBackingStoreOffset + kPointerSize == kBitFieldSlot); 168 STATIC_ASSERT(kBitFieldSlot + kPointerSize == kSize); 169 170 static bool IsValidSlot(HeapObject* obj, int offset) { 171 if (offset < kBackingStoreOffset) return true; 172 if (offset < kSize) return false; 173 return IsValidSlotImpl(obj, offset); 174 } 175 176 template <typename ObjectVisitor> 177 static inline void IterateBody(HeapObject* obj, int object_size, 178 ObjectVisitor* v) { 179 IteratePointers(obj, kPropertiesOffset, kBackingStoreOffset, v); 180 IterateBodyImpl(obj, kSize, object_size, v); 181 } 182 183 template <typename StaticVisitor> 184 static inline void IterateBody(HeapObject* obj, int object_size) { 185 Heap* heap = obj->GetHeap(); 186 IteratePointers<StaticVisitor>(heap, obj, kPropertiesOffset, 187 kBackingStoreOffset); 188 IterateBodyImpl<StaticVisitor>(heap, obj, kSize, object_size); 189 } 190 191 static inline int SizeOf(Map* map, HeapObject* object) { 192 return map->instance_size(); 193 } 194 }; 195 196 197 class BytecodeArray::BodyDescriptor final : public BodyDescriptorBase { 198 public: 199 static bool IsValidSlot(HeapObject* obj, int offset) { 200 return offset >= kConstantPoolOffset && 201 offset <= kSourcePositionTableOffset; 202 } 203 204 template <typename ObjectVisitor> 205 static inline void IterateBody(HeapObject* obj, int object_size, 206 ObjectVisitor* v) { 207 IteratePointer(obj, kConstantPoolOffset, v); 208 IteratePointer(obj, kHandlerTableOffset, v); 209 IteratePointer(obj, kSourcePositionTableOffset, v); 210 } 211 212 template <typename StaticVisitor> 213 static inline void IterateBody(HeapObject* obj, int object_size) { 214 Heap* heap = obj->GetHeap(); 215 IteratePointer<StaticVisitor>(heap, obj, kConstantPoolOffset); 216 IteratePointer<StaticVisitor>(heap, obj, kHandlerTableOffset); 217 IteratePointer<StaticVisitor>(heap, obj, kSourcePositionTableOffset); 218 } 219 220 static inline int SizeOf(Map* map, HeapObject* obj) { 221 return reinterpret_cast<BytecodeArray*>(obj)->BytecodeArraySize(); 222 } 223 }; 224 225 226 class FixedTypedArrayBase::BodyDescriptor final : public BodyDescriptorBase { 227 public: 228 static bool IsValidSlot(HeapObject* obj, int offset) { 229 return offset == kBasePointerOffset; 230 } 231 232 template <typename ObjectVisitor> 233 static inline void IterateBody(HeapObject* obj, int object_size, 234 ObjectVisitor* v) { 235 IteratePointer(obj, kBasePointerOffset, v); 236 } 237 238 template <typename StaticVisitor> 239 static inline void IterateBody(HeapObject* obj, int object_size) { 240 Heap* heap = obj->GetHeap(); 241 IteratePointer<StaticVisitor>(heap, obj, kBasePointerOffset); 242 } 243 244 static inline int SizeOf(Map* map, HeapObject* object) { 245 return reinterpret_cast<FixedTypedArrayBase*>(object)->size(); 246 } 247 }; 248 249 250 template <JSWeakCollection::BodyVisitingPolicy body_visiting_policy> 251 class JSWeakCollection::BodyDescriptorImpl final : public BodyDescriptorBase { 252 public: 253 STATIC_ASSERT(kTableOffset + kPointerSize == kNextOffset); 254 STATIC_ASSERT(kNextOffset + kPointerSize == kSize); 255 256 static bool IsValidSlot(HeapObject* obj, int offset) { 257 return IsValidSlotImpl(obj, offset); 258 } 259 260 template <typename ObjectVisitor> 261 static inline void IterateBody(HeapObject* obj, int object_size, 262 ObjectVisitor* v) { 263 if (body_visiting_policy == kVisitStrong) { 264 IterateBodyImpl(obj, kPropertiesOffset, object_size, v); 265 } else { 266 IteratePointers(obj, kPropertiesOffset, kTableOffset, v); 267 IterateBodyImpl(obj, kSize, object_size, v); 268 } 269 } 270 271 template <typename StaticVisitor> 272 static inline void IterateBody(HeapObject* obj, int object_size) { 273 Heap* heap = obj->GetHeap(); 274 if (body_visiting_policy == kVisitStrong) { 275 IterateBodyImpl<StaticVisitor>(heap, obj, kPropertiesOffset, object_size); 276 } else { 277 IteratePointers<StaticVisitor>(heap, obj, kPropertiesOffset, 278 kTableOffset); 279 IterateBodyImpl<StaticVisitor>(heap, obj, kSize, object_size); 280 } 281 } 282 283 static inline int SizeOf(Map* map, HeapObject* object) { 284 return map->instance_size(); 285 } 286 }; 287 288 289 class Foreign::BodyDescriptor final : public BodyDescriptorBase { 290 public: 291 static bool IsValidSlot(HeapObject* obj, int offset) { return false; } 292 293 template <typename ObjectVisitor> 294 static inline void IterateBody(HeapObject* obj, int object_size, 295 ObjectVisitor* v) { 296 v->VisitExternalReference(reinterpret_cast<Address*>( 297 HeapObject::RawField(obj, kForeignAddressOffset))); 298 } 299 300 template <typename StaticVisitor> 301 static inline void IterateBody(HeapObject* obj, int object_size) { 302 StaticVisitor::VisitExternalReference(reinterpret_cast<Address*>( 303 HeapObject::RawField(obj, kForeignAddressOffset))); 304 } 305 306 static inline int SizeOf(Map* map, HeapObject* object) { return kSize; } 307 }; 308 309 310 class ExternalOneByteString::BodyDescriptor final : public BodyDescriptorBase { 311 public: 312 static bool IsValidSlot(HeapObject* obj, int offset) { return false; } 313 314 template <typename ObjectVisitor> 315 static inline void IterateBody(HeapObject* obj, int object_size, 316 ObjectVisitor* v) { 317 typedef v8::String::ExternalOneByteStringResource Resource; 318 v->VisitExternalOneByteString(reinterpret_cast<Resource**>( 319 HeapObject::RawField(obj, kResourceOffset))); 320 } 321 322 template <typename StaticVisitor> 323 static inline void IterateBody(HeapObject* obj, int object_size) { 324 typedef v8::String::ExternalOneByteStringResource Resource; 325 StaticVisitor::VisitExternalOneByteString(reinterpret_cast<Resource**>( 326 HeapObject::RawField(obj, kResourceOffset))); 327 } 328 329 static inline int SizeOf(Map* map, HeapObject* object) { return kSize; } 330 }; 331 332 333 class ExternalTwoByteString::BodyDescriptor final : public BodyDescriptorBase { 334 public: 335 static bool IsValidSlot(HeapObject* obj, int offset) { return false; } 336 337 template <typename ObjectVisitor> 338 static inline void IterateBody(HeapObject* obj, int object_size, 339 ObjectVisitor* v) { 340 typedef v8::String::ExternalStringResource Resource; 341 v->VisitExternalTwoByteString(reinterpret_cast<Resource**>( 342 HeapObject::RawField(obj, kResourceOffset))); 343 } 344 345 template <typename StaticVisitor> 346 static inline void IterateBody(HeapObject* obj, int object_size) { 347 typedef v8::String::ExternalStringResource Resource; 348 StaticVisitor::VisitExternalTwoByteString(reinterpret_cast<Resource**>( 349 HeapObject::RawField(obj, kResourceOffset))); 350 } 351 352 static inline int SizeOf(Map* map, HeapObject* object) { return kSize; } 353 }; 354 355 356 class Code::BodyDescriptor final : public BodyDescriptorBase { 357 public: 358 STATIC_ASSERT(kRelocationInfoOffset + kPointerSize == kHandlerTableOffset); 359 STATIC_ASSERT(kHandlerTableOffset + kPointerSize == 360 kDeoptimizationDataOffset); 361 STATIC_ASSERT(kDeoptimizationDataOffset + kPointerSize == 362 kSourcePositionTableOffset); 363 STATIC_ASSERT(kSourcePositionTableOffset + kPointerSize == 364 kTypeFeedbackInfoOffset); 365 STATIC_ASSERT(kTypeFeedbackInfoOffset + kPointerSize == 366 kNextCodeLinkOffset); 367 368 static bool IsValidSlot(HeapObject* obj, int offset) { 369 // Slots in code can't be invalid because we never trim code objects. 370 return true; 371 } 372 373 template <typename ObjectVisitor> 374 static inline void IterateBody(HeapObject* obj, ObjectVisitor* v) { 375 int mode_mask = RelocInfo::kCodeTargetMask | 376 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | 377 RelocInfo::ModeMask(RelocInfo::CELL) | 378 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | 379 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) | 380 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED) | 381 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) | 382 RelocInfo::kDebugBreakSlotMask; 383 384 IteratePointers(obj, kRelocationInfoOffset, kNextCodeLinkOffset, v); 385 v->VisitNextCodeLink(HeapObject::RawField(obj, kNextCodeLinkOffset)); 386 387 RelocIterator it(reinterpret_cast<Code*>(obj), mode_mask); 388 Isolate* isolate = obj->GetIsolate(); 389 for (; !it.done(); it.next()) { 390 it.rinfo()->Visit(isolate, v); 391 } 392 } 393 394 template <typename ObjectVisitor> 395 static inline void IterateBody(HeapObject* obj, int object_size, 396 ObjectVisitor* v) { 397 IterateBody(obj, v); 398 } 399 400 template <typename StaticVisitor> 401 static inline void IterateBody(HeapObject* obj) { 402 int mode_mask = RelocInfo::kCodeTargetMask | 403 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | 404 RelocInfo::ModeMask(RelocInfo::CELL) | 405 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | 406 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) | 407 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED) | 408 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) | 409 RelocInfo::kDebugBreakSlotMask; 410 411 Heap* heap = obj->GetHeap(); 412 IteratePointers<StaticVisitor>(heap, obj, kRelocationInfoOffset, 413 kNextCodeLinkOffset); 414 StaticVisitor::VisitNextCodeLink( 415 heap, HeapObject::RawField(obj, kNextCodeLinkOffset)); 416 417 RelocIterator it(reinterpret_cast<Code*>(obj), mode_mask); 418 for (; !it.done(); it.next()) { 419 it.rinfo()->template Visit<StaticVisitor>(heap); 420 } 421 } 422 423 template <typename StaticVisitor> 424 static inline void IterateBody(HeapObject* obj, int object_size) { 425 IterateBody<StaticVisitor>(obj); 426 } 427 428 static inline int SizeOf(Map* map, HeapObject* object) { 429 return reinterpret_cast<Code*>(object)->CodeSize(); 430 } 431 }; 432 433 434 template <typename Op, typename ReturnType, typename T1, typename T2, 435 typename T3> 436 ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3) { 437 if (type < FIRST_NONSTRING_TYPE) { 438 switch (type & kStringRepresentationMask) { 439 case kSeqStringTag: 440 return ReturnType(); 441 case kConsStringTag: 442 return Op::template apply<ConsString::BodyDescriptor>(p1, p2, p3); 443 case kThinStringTag: 444 return Op::template apply<ThinString::BodyDescriptor>(p1, p2, p3); 445 case kSlicedStringTag: 446 return Op::template apply<SlicedString::BodyDescriptor>(p1, p2, p3); 447 case kExternalStringTag: 448 if ((type & kStringEncodingMask) == kOneByteStringTag) { 449 return Op::template apply<ExternalOneByteString::BodyDescriptor>( 450 p1, p2, p3); 451 } else { 452 return Op::template apply<ExternalTwoByteString::BodyDescriptor>( 453 p1, p2, p3); 454 } 455 } 456 UNREACHABLE(); 457 return ReturnType(); 458 } 459 460 switch (type) { 461 case FIXED_ARRAY_TYPE: 462 return Op::template apply<FixedArray::BodyDescriptor>(p1, p2, p3); 463 case FIXED_DOUBLE_ARRAY_TYPE: 464 return ReturnType(); 465 case TRANSITION_ARRAY_TYPE: 466 return Op::template apply<TransitionArray::BodyDescriptor>(p1, p2, p3); 467 case JS_OBJECT_TYPE: 468 case JS_ERROR_TYPE: 469 case JS_ARGUMENTS_TYPE: 470 case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE: 471 case JS_PROMISE_CAPABILITY_TYPE: 472 case JS_PROMISE_TYPE: 473 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: 474 case JS_GENERATOR_OBJECT_TYPE: 475 case JS_VALUE_TYPE: 476 case JS_DATE_TYPE: 477 case JS_ARRAY_TYPE: 478 case JS_MODULE_NAMESPACE_TYPE: 479 case JS_TYPED_ARRAY_TYPE: 480 case JS_DATA_VIEW_TYPE: 481 case JS_SET_TYPE: 482 case JS_MAP_TYPE: 483 case JS_SET_ITERATOR_TYPE: 484 case JS_MAP_ITERATOR_TYPE: 485 case JS_STRING_ITERATOR_TYPE: 486 487 case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE: 488 case JS_FAST_ARRAY_KEY_ITERATOR_TYPE: 489 case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE: 490 case JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE: 491 case JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE: 492 case JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE: 493 case JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE: 494 case JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE: 495 case JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE: 496 case JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE: 497 case JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE: 498 case JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE: 499 case JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE: 500 case JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE: 501 case JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE: 502 case JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE: 503 case JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE: 504 case JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE: 505 case JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE: 506 case JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE: 507 case JS_INT8_ARRAY_VALUE_ITERATOR_TYPE: 508 case JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE: 509 case JS_INT16_ARRAY_VALUE_ITERATOR_TYPE: 510 case JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE: 511 case JS_INT32_ARRAY_VALUE_ITERATOR_TYPE: 512 case JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE: 513 case JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE: 514 case JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE: 515 case JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE: 516 case JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE: 517 case JS_FAST_ARRAY_VALUE_ITERATOR_TYPE: 518 case JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE: 519 case JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE: 520 case JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE: 521 case JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE: 522 523 case JS_REGEXP_TYPE: 524 case JS_GLOBAL_PROXY_TYPE: 525 case JS_GLOBAL_OBJECT_TYPE: 526 case JS_API_OBJECT_TYPE: 527 case JS_SPECIAL_API_OBJECT_TYPE: 528 case JS_MESSAGE_OBJECT_TYPE: 529 case JS_BOUND_FUNCTION_TYPE: 530 return Op::template apply<JSObject::BodyDescriptor>(p1, p2, p3); 531 case JS_WEAK_MAP_TYPE: 532 case JS_WEAK_SET_TYPE: 533 return Op::template apply<JSWeakCollection::BodyDescriptor>(p1, p2, p3); 534 case JS_ARRAY_BUFFER_TYPE: 535 return Op::template apply<JSArrayBuffer::BodyDescriptor>(p1, p2, p3); 536 case JS_FUNCTION_TYPE: 537 return Op::template apply<JSFunction::BodyDescriptor>(p1, p2, p3); 538 case ODDBALL_TYPE: 539 return Op::template apply<Oddball::BodyDescriptor>(p1, p2, p3); 540 case JS_PROXY_TYPE: 541 return Op::template apply<JSProxy::BodyDescriptor>(p1, p2, p3); 542 case FOREIGN_TYPE: 543 return Op::template apply<Foreign::BodyDescriptor>(p1, p2, p3); 544 case MAP_TYPE: 545 return Op::template apply<Map::BodyDescriptor>(p1, p2, p3); 546 case CODE_TYPE: 547 return Op::template apply<Code::BodyDescriptor>(p1, p2, p3); 548 case CELL_TYPE: 549 return Op::template apply<Cell::BodyDescriptor>(p1, p2, p3); 550 case PROPERTY_CELL_TYPE: 551 return Op::template apply<PropertyCell::BodyDescriptor>(p1, p2, p3); 552 case WEAK_CELL_TYPE: 553 return Op::template apply<WeakCell::BodyDescriptor>(p1, p2, p3); 554 case SYMBOL_TYPE: 555 return Op::template apply<Symbol::BodyDescriptor>(p1, p2, p3); 556 case BYTECODE_ARRAY_TYPE: 557 return Op::template apply<BytecodeArray::BodyDescriptor>(p1, p2, p3); 558 559 case HEAP_NUMBER_TYPE: 560 case MUTABLE_HEAP_NUMBER_TYPE: 561 case FILLER_TYPE: 562 case BYTE_ARRAY_TYPE: 563 case FREE_SPACE_TYPE: 564 return ReturnType(); 565 566 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ 567 case FIXED_##TYPE##_ARRAY_TYPE: \ 568 return Op::template apply<FixedTypedArrayBase::BodyDescriptor>(p1, p2, p3); 569 TYPED_ARRAYS(TYPED_ARRAY_CASE) 570 #undef TYPED_ARRAY_CASE 571 572 case SHARED_FUNCTION_INFO_TYPE: { 573 return Op::template apply<SharedFunctionInfo::BodyDescriptor>(p1, p2, p3); 574 } 575 576 #define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: 577 STRUCT_LIST(MAKE_STRUCT_CASE) 578 #undef MAKE_STRUCT_CASE 579 if (type == ALLOCATION_SITE_TYPE) { 580 return Op::template apply<AllocationSite::BodyDescriptor>(p1, p2, p3); 581 } else { 582 return Op::template apply<StructBodyDescriptor>(p1, p2, p3); 583 } 584 default: 585 PrintF("Unknown type: %d\n", type); 586 UNREACHABLE(); 587 return ReturnType(); 588 } 589 } 590 591 592 template <typename ObjectVisitor> 593 void HeapObject::IterateFast(ObjectVisitor* v) { 594 BodyDescriptorBase::IteratePointer(this, kMapOffset, v); 595 IterateBodyFast(v); 596 } 597 598 599 template <typename ObjectVisitor> 600 void HeapObject::IterateBodyFast(ObjectVisitor* v) { 601 Map* m = map(); 602 IterateBodyFast(m->instance_type(), SizeFromMap(m), v); 603 } 604 605 606 struct CallIterateBody { 607 template <typename BodyDescriptor, typename ObjectVisitor> 608 static void apply(HeapObject* obj, int object_size, ObjectVisitor* v) { 609 BodyDescriptor::IterateBody(obj, object_size, v); 610 } 611 }; 612 613 template <typename ObjectVisitor> 614 void HeapObject::IterateBodyFast(InstanceType type, int object_size, 615 ObjectVisitor* v) { 616 BodyDescriptorApply<CallIterateBody, void>(type, this, object_size, v); 617 } 618 } // namespace internal 619 } // namespace v8 620 621 #endif // V8_OBJECTS_BODY_DESCRIPTORS_INL_H_ 622