1// Copyright 2019 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_HEAP_REFS_H_ 6#define V8_COMPILER_HEAP_REFS_H_ 7 8#include "src/base/optional.h" 9#include "src/ic/call-optimization.h" 10#include "src/objects/elements-kind.h" 11#include "src/objects/feedback-vector.h" 12#include "src/objects/instance-type.h" 13#include "src/utils/boxed-float.h" 14 15namespace v8 { 16 17class CFunctionInfo; 18 19namespace internal { 20 21class BytecodeArray; 22class CallHandlerInfo; 23class FixedDoubleArray; 24class FunctionTemplateInfo; 25class HeapNumber; 26class InternalizedString; 27class JSBoundFunction; 28class JSDataView; 29class JSGlobalProxy; 30class JSTypedArray; 31class NativeContext; 32class ScriptContextTable; 33template <typename> 34class Signature; 35 36namespace wasm { 37class ValueType; 38struct WasmModule; 39} // namespace wasm 40 41namespace compiler { 42 43class CompilationDependencies; 44struct FeedbackSource; 45class JSHeapBroker; 46class ObjectData; 47class PerIsolateCompilerCache; 48class PropertyAccessInfo; 49 50// Whether we are loading a property or storing to a property. 51// For a store during literal creation, do not walk up the prototype chain. 52// For a define operation, we behave similarly to kStoreInLiteral, but with 53// distinct semantics for private class fields (in which private field 54// accesses must throw when storing a field which does not exist, or 55// adding/defining a field which already exists). 56enum class AccessMode { kLoad, kStore, kStoreInLiteral, kHas, kDefine }; 57 58inline bool IsAnyStore(AccessMode mode) { 59 return mode == AccessMode::kStore || mode == AccessMode::kStoreInLiteral || 60 mode == AccessMode::kDefine; 61} 62 63enum class OddballType : uint8_t { 64 kNone, // Not an Oddball. 65 kBoolean, // True or False. 66 kUndefined, 67 kNull, 68 kHole, 69 kUninitialized, 70 kOther // Oddball, but none of the above. 71}; 72 73enum class RefSerializationKind { 74 // Skips serialization. 75 kNeverSerialized, 76 // Can be serialized on demand from the background thread. 77 kBackgroundSerialized, 78}; 79 80// This list is sorted such that subtypes appear before their supertypes. 81// DO NOT VIOLATE THIS PROPERTY! 82#define HEAP_BROKER_OBJECT_LIST_BASE(BACKGROUND_SERIALIZED, NEVER_SERIALIZED) \ 83 /* Subtypes of JSObject */ \ 84 BACKGROUND_SERIALIZED(JSArray) \ 85 BACKGROUND_SERIALIZED(JSBoundFunction) \ 86 BACKGROUND_SERIALIZED(JSDataView) \ 87 BACKGROUND_SERIALIZED(JSFunction) \ 88 BACKGROUND_SERIALIZED(JSGlobalObject) \ 89 BACKGROUND_SERIALIZED(JSGlobalProxy) \ 90 BACKGROUND_SERIALIZED(JSTypedArray) \ 91 /* Subtypes of Context */ \ 92 NEVER_SERIALIZED(NativeContext) \ 93 /* Subtypes of FixedArray */ \ 94 NEVER_SERIALIZED(ObjectBoilerplateDescription) \ 95 BACKGROUND_SERIALIZED(ScriptContextTable) \ 96 /* Subtypes of String */ \ 97 NEVER_SERIALIZED(InternalizedString) \ 98 /* Subtypes of FixedArrayBase */ \ 99 NEVER_SERIALIZED(BytecodeArray) \ 100 BACKGROUND_SERIALIZED(FixedArray) \ 101 NEVER_SERIALIZED(FixedDoubleArray) \ 102 /* Subtypes of Name */ \ 103 NEVER_SERIALIZED(String) \ 104 NEVER_SERIALIZED(Symbol) \ 105 /* Subtypes of JSReceiver */ \ 106 BACKGROUND_SERIALIZED(JSObject) \ 107 /* Subtypes of HeapObject */ \ 108 NEVER_SERIALIZED(AccessorInfo) \ 109 NEVER_SERIALIZED(AllocationSite) \ 110 NEVER_SERIALIZED(ArrayBoilerplateDescription) \ 111 BACKGROUND_SERIALIZED(BigInt) \ 112 NEVER_SERIALIZED(CallHandlerInfo) \ 113 NEVER_SERIALIZED(Cell) \ 114 NEVER_SERIALIZED(Code) \ 115 NEVER_SERIALIZED(CodeDataContainer) \ 116 NEVER_SERIALIZED(Context) \ 117 NEVER_SERIALIZED(DescriptorArray) \ 118 NEVER_SERIALIZED(FeedbackCell) \ 119 NEVER_SERIALIZED(FeedbackVector) \ 120 BACKGROUND_SERIALIZED(FixedArrayBase) \ 121 NEVER_SERIALIZED(FunctionTemplateInfo) \ 122 NEVER_SERIALIZED(HeapNumber) \ 123 BACKGROUND_SERIALIZED(JSReceiver) \ 124 BACKGROUND_SERIALIZED(Map) \ 125 NEVER_SERIALIZED(Name) \ 126 BACKGROUND_SERIALIZED(PropertyCell) \ 127 NEVER_SERIALIZED(RegExpBoilerplateDescription) \ 128 NEVER_SERIALIZED(ScopeInfo) \ 129 NEVER_SERIALIZED(SharedFunctionInfo) \ 130 NEVER_SERIALIZED(SourceTextModule) \ 131 NEVER_SERIALIZED(TemplateObjectDescription) \ 132 /* Subtypes of Object */ \ 133 BACKGROUND_SERIALIZED(HeapObject) 134 135#define HEAP_BROKER_OBJECT_LIST(V) HEAP_BROKER_OBJECT_LIST_BASE(V, V) 136#define IGNORE_CASE(...) 137#define HEAP_BROKER_BACKGROUND_SERIALIZED_OBJECT_LIST(V) \ 138 HEAP_BROKER_OBJECT_LIST_BASE(V, IGNORE_CASE) 139 140#define FORWARD_DECL(Name) class Name##Ref; 141HEAP_BROKER_OBJECT_LIST(FORWARD_DECL) 142#undef FORWARD_DECL 143 144class ObjectRef; 145 146template <class T> 147struct ref_traits; 148 149#define FORWARD_DECL(Name) class Name##Data; 150HEAP_BROKER_BACKGROUND_SERIALIZED_OBJECT_LIST(FORWARD_DECL) 151#undef FORWARD_DECL 152 153#define BACKGROUND_SERIALIZED_REF_TRAITS(Name) \ 154 template <> \ 155 struct ref_traits<Name> { \ 156 using ref_type = Name##Ref; \ 157 using data_type = Name##Data; \ 158 static constexpr RefSerializationKind ref_serialization_kind = \ 159 RefSerializationKind::kBackgroundSerialized; \ 160 }; 161 162#define NEVER_SERIALIZED_REF_TRAITS(Name) \ 163 template <> \ 164 struct ref_traits<Name> { \ 165 using ref_type = Name##Ref; \ 166 using data_type = ObjectData; \ 167 static constexpr RefSerializationKind ref_serialization_kind = \ 168 RefSerializationKind::kNeverSerialized; \ 169 }; 170 171HEAP_BROKER_OBJECT_LIST_BASE(BACKGROUND_SERIALIZED_REF_TRAITS, 172 NEVER_SERIALIZED_REF_TRAITS) 173#undef NEVER_SERIALIZED_REF_TRAITS 174#undef BACKGROUND_SERIALIZED_REF_TRAITS 175 176template <> 177struct ref_traits<Object> { 178 using ref_type = ObjectRef; 179 // Note: While a bit awkward, this artificial ref serialization kind value is 180 // okay: smis are never-serialized, and we never create raw non-smi 181 // ObjectRefs (they would at least be HeapObjectRefs instead). 182 static constexpr RefSerializationKind ref_serialization_kind = 183 RefSerializationKind::kNeverSerialized; 184}; 185 186// A ref without the broker_ field, used when storage size is important. 187template <class T> 188class TinyRef { 189 private: 190 using RefType = typename ref_traits<T>::ref_type; 191 192 public: 193 explicit TinyRef(const RefType& ref) : TinyRef(ref.data_) {} 194 RefType AsRef(JSHeapBroker* broker) const; 195 static base::Optional<RefType> AsOptionalRef(JSHeapBroker* broker, 196 base::Optional<TinyRef<T>> ref) { 197 if (!ref.has_value()) return {}; 198 return ref->AsRef(broker); 199 } 200 Handle<T> object() const; 201 202 private: 203 explicit TinyRef(ObjectData* data) : data_(data) { DCHECK_NOT_NULL(data); } 204 ObjectData* const data_; 205}; 206 207#define V(Name) using Name##TinyRef = TinyRef<Name>; 208HEAP_BROKER_OBJECT_LIST(V) 209#undef V 210 211#ifdef V8_EXTERNAL_CODE_SPACE 212using CodeTRef = CodeDataContainerRef; 213using CodeTTinyRef = CodeDataContainerTinyRef; 214#else 215using CodeTRef = CodeRef; 216using CodeTTinyRef = CodeTinyRef; 217#endif 218 219class V8_EXPORT_PRIVATE ObjectRef { 220 public: 221 ObjectRef(JSHeapBroker* broker, ObjectData* data, bool check_type = true) 222 : data_(data), broker_(broker) { 223 CHECK_NOT_NULL(data_); 224 } 225 226 Handle<Object> object() const; 227 228 bool equals(const ObjectRef& other) const; 229 230 bool IsSmi() const; 231 int AsSmi() const; 232 233#define HEAP_IS_METHOD_DECL(Name) bool Is##Name() const; 234 HEAP_BROKER_OBJECT_LIST(HEAP_IS_METHOD_DECL) 235#undef HEAP_IS_METHOD_DECL 236 237#define HEAP_AS_METHOD_DECL(Name) Name##Ref As##Name() const; 238 HEAP_BROKER_OBJECT_LIST(HEAP_AS_METHOD_DECL) 239#undef HEAP_AS_METHOD_DECL 240 241 bool IsNull() const; 242 bool IsNullOrUndefined() const; 243 bool IsTheHole() const; 244 245 base::Optional<bool> TryGetBooleanValue() const; 246 Maybe<double> OddballToNumber() const; 247 248 bool should_access_heap() const; 249 250 Isolate* isolate() const; 251 252 struct Hash { 253 size_t operator()(const ObjectRef& ref) const { 254 return base::hash_combine(ref.object().address()); 255 } 256 }; 257 struct Equal { 258 bool operator()(const ObjectRef& lhs, const ObjectRef& rhs) const { 259 return lhs.equals(rhs); 260 } 261 }; 262 263 protected: 264 JSHeapBroker* broker() const; 265 ObjectData* data() const; 266 ObjectData* data_; // Should be used only by object() getters. 267 268 private: 269 friend class FunctionTemplateInfoRef; 270 friend class JSArrayData; 271 friend class JSFunctionData; 272 friend class JSGlobalObjectData; 273 friend class JSGlobalObjectRef; 274 friend class JSHeapBroker; 275 friend class JSObjectData; 276 friend class StringData; 277 template <class T> 278 friend class TinyRef; 279 280 friend std::ostream& operator<<(std::ostream& os, const ObjectRef& ref); 281 282 JSHeapBroker* broker_; 283}; 284 285template <class T> 286using ZoneRefUnorderedSet = 287 ZoneUnorderedSet<T, ObjectRef::Hash, ObjectRef::Equal>; 288 289// Temporary class that carries information from a Map. We'd like to remove 290// this class and use MapRef instead, but we can't as long as we support the 291// kDisabled broker mode. That's because obtaining the MapRef via 292// HeapObjectRef::map() requires a HandleScope when the broker is disabled. 293// During OptimizeGraph we generally don't have a HandleScope, however. There 294// are two places where we therefore use GetHeapObjectType() instead. Both that 295// function and this class should eventually be removed. 296class HeapObjectType { 297 public: 298 enum Flag : uint8_t { kUndetectable = 1 << 0, kCallable = 1 << 1 }; 299 300 using Flags = base::Flags<Flag>; 301 302 HeapObjectType(InstanceType instance_type, Flags flags, 303 OddballType oddball_type) 304 : instance_type_(instance_type), 305 oddball_type_(oddball_type), 306 flags_(flags) { 307 DCHECK_EQ(instance_type == ODDBALL_TYPE, 308 oddball_type != OddballType::kNone); 309 } 310 311 OddballType oddball_type() const { return oddball_type_; } 312 InstanceType instance_type() const { return instance_type_; } 313 Flags flags() const { return flags_; } 314 315 bool is_callable() const { return flags_ & kCallable; } 316 bool is_undetectable() const { return flags_ & kUndetectable; } 317 318 private: 319 InstanceType const instance_type_; 320 OddballType const oddball_type_; 321 Flags const flags_; 322}; 323 324// Constructors are carefully defined such that we do a type check on 325// the outermost Ref class in the inheritance chain only. 326#define DEFINE_REF_CONSTRUCTOR(Name, Base) \ 327 Name##Ref(JSHeapBroker* broker, ObjectData* data, bool check_type = true) \ 328 : Base(broker, data, false) { \ 329 if (check_type) { \ 330 CHECK(Is##Name()); \ 331 } \ 332 } 333 334class HeapObjectRef : public ObjectRef { 335 public: 336 DEFINE_REF_CONSTRUCTOR(HeapObject, ObjectRef) 337 338 Handle<HeapObject> object() const; 339 340 MapRef map() const; 341 342 // Only for use in special situations where we need to read the object's 343 // current map (instead of returning the cached map). Use with care. 344 base::Optional<MapRef> map_direct_read() const; 345 346 // See the comment on the HeapObjectType class. 347 HeapObjectType GetHeapObjectType() const; 348}; 349 350class PropertyCellRef : public HeapObjectRef { 351 public: 352 DEFINE_REF_CONSTRUCTOR(PropertyCell, HeapObjectRef) 353 354 Handle<PropertyCell> object() const; 355 356 V8_WARN_UNUSED_RESULT bool Cache() const; 357 void CacheAsProtector() const { 358 bool cached = Cache(); 359 // A protector always holds a Smi value and its cell type never changes, so 360 // Cache can't fail. 361 CHECK(cached); 362 } 363 364 PropertyDetails property_details() const; 365 ObjectRef value() const; 366}; 367 368class JSReceiverRef : public HeapObjectRef { 369 public: 370 DEFINE_REF_CONSTRUCTOR(JSReceiver, HeapObjectRef) 371 372 Handle<JSReceiver> object() const; 373}; 374 375class JSObjectRef : public JSReceiverRef { 376 public: 377 DEFINE_REF_CONSTRUCTOR(JSObject, JSReceiverRef) 378 379 Handle<JSObject> object() const; 380 381 base::Optional<ObjectRef> raw_properties_or_hash() const; 382 383 // Usable only for in-object properties. Only use this if the underlying 384 // value can be an uninitialized-sentinel, or if HeapNumber construction must 385 // be avoided for some reason. Otherwise, use the higher-level 386 // GetOwnFastDataProperty. 387 base::Optional<ObjectRef> RawInobjectPropertyAt(FieldIndex index) const; 388 389 // Return the element at key {index} if {index} is known to be an own data 390 // property of the object that is non-writable and non-configurable. If 391 // {dependencies} is non-null, a dependency will be taken to protect 392 // against inconsistency due to weak memory concurrency. 393 base::Optional<ObjectRef> GetOwnConstantElement( 394 const FixedArrayBaseRef& elements_ref, uint32_t index, 395 CompilationDependencies* dependencies) const; 396 // The direct-read implementation of the above, extracted into a helper since 397 // it's also called from compilation-dependency validation. This helper is 398 // guaranteed to not create new Ref instances. 399 base::Optional<Object> GetOwnConstantElementFromHeap( 400 FixedArrayBase elements, ElementsKind elements_kind, 401 uint32_t index) const; 402 403 // Return the value of the property identified by the field {index} 404 // if {index} is known to be an own data property of the object. 405 // If {dependencies} is non-null, and a property was successfully read, 406 // then the function will take a dependency to check the value of the 407 // property at code finalization time. 408 base::Optional<ObjectRef> GetOwnFastDataProperty( 409 Representation field_representation, FieldIndex index, 410 CompilationDependencies* dependencies) const; 411 412 // Return the value of the dictionary property at {index} in the dictionary 413 // if {index} is known to be an own data property of the object. 414 base::Optional<ObjectRef> GetOwnDictionaryProperty( 415 InternalIndex index, CompilationDependencies* dependencies) const; 416 417 // When concurrent inlining is enabled, reads the elements through a direct 418 // relaxed read. This is to ease the transition to unserialized (or 419 // background-serialized) elements. 420 base::Optional<FixedArrayBaseRef> elements(RelaxedLoadTag) const; 421 bool IsElementsTenured(const FixedArrayBaseRef& elements); 422 423 base::Optional<MapRef> GetObjectCreateMap() const; 424}; 425 426class JSDataViewRef : public JSObjectRef { 427 public: 428 DEFINE_REF_CONSTRUCTOR(JSDataView, JSObjectRef) 429 430 Handle<JSDataView> object() const; 431 432 size_t byte_length() const; 433}; 434 435class JSBoundFunctionRef : public JSObjectRef { 436 public: 437 DEFINE_REF_CONSTRUCTOR(JSBoundFunction, JSObjectRef) 438 439 Handle<JSBoundFunction> object() const; 440 441 JSReceiverRef bound_target_function() const; 442 ObjectRef bound_this() const; 443 FixedArrayRef bound_arguments() const; 444}; 445 446class V8_EXPORT_PRIVATE JSFunctionRef : public JSObjectRef { 447 public: 448 DEFINE_REF_CONSTRUCTOR(JSFunction, JSObjectRef) 449 450 Handle<JSFunction> object() const; 451 452 // Returns true, iff the serialized JSFunctionData contents are consistent 453 // with the state of the underlying JSFunction object. Must be called from 454 // the main thread. 455 bool IsConsistentWithHeapState() const; 456 457 ContextRef context() const; 458 NativeContextRef native_context() const; 459 SharedFunctionInfoRef shared() const; 460 CodeRef code() const; 461 462 bool has_initial_map(CompilationDependencies* dependencies) const; 463 bool PrototypeRequiresRuntimeLookup( 464 CompilationDependencies* dependencies) const; 465 bool has_instance_prototype(CompilationDependencies* dependencies) const; 466 ObjectRef instance_prototype(CompilationDependencies* dependencies) const; 467 MapRef initial_map(CompilationDependencies* dependencies) const; 468 int InitialMapInstanceSizeWithMinSlack( 469 CompilationDependencies* dependencies) const; 470 FeedbackCellRef raw_feedback_cell( 471 CompilationDependencies* dependencies) const; 472 base::Optional<FeedbackVectorRef> feedback_vector( 473 CompilationDependencies* dependencies) const; 474}; 475 476class RegExpBoilerplateDescriptionRef : public HeapObjectRef { 477 public: 478 DEFINE_REF_CONSTRUCTOR(RegExpBoilerplateDescription, HeapObjectRef) 479 480 Handle<RegExpBoilerplateDescription> object() const; 481 482 FixedArrayRef data() const; 483 StringRef source() const; 484 int flags() const; 485}; 486 487// HeapNumberRef is only created for immutable HeapNumbers. Mutable 488// HeapNumbers (those owned by in-object or backing store fields with 489// representation type Double are not exposed to the compiler through 490// HeapNumberRef. Instead, we read their value, and protect that read 491// with a field-constness Dependency. 492class HeapNumberRef : public HeapObjectRef { 493 public: 494 DEFINE_REF_CONSTRUCTOR(HeapNumber, HeapObjectRef) 495 496 Handle<HeapNumber> object() const; 497 498 double value() const; 499 uint64_t value_as_bits() const; 500}; 501 502class ContextRef : public HeapObjectRef { 503 public: 504 DEFINE_REF_CONSTRUCTOR(Context, HeapObjectRef) 505 506 Handle<Context> object() const; 507 508 // {previous} decrements {depth} by 1 for each previous link successfully 509 // followed. If {depth} != 0 on function return, then it only got partway to 510 // the desired depth. 511 ContextRef previous(size_t* depth) const; 512 513 // Only returns a value if the index is valid for this ContextRef. 514 base::Optional<ObjectRef> get(int index) const; 515}; 516 517#define BROKER_NATIVE_CONTEXT_FIELDS(V) \ 518 V(JSFunction, array_function) \ 519 V(JSFunction, bigint_function) \ 520 V(JSFunction, boolean_function) \ 521 V(JSFunction, function_prototype_apply) \ 522 V(JSFunction, number_function) \ 523 V(JSFunction, object_function) \ 524 V(JSFunction, promise_function) \ 525 V(JSFunction, promise_then) \ 526 V(JSFunction, regexp_exec_function) \ 527 V(JSFunction, regexp_function) \ 528 V(JSFunction, string_function) \ 529 V(JSFunction, symbol_function) \ 530 V(JSGlobalObject, global_object) \ 531 V(JSGlobalProxy, global_proxy_object) \ 532 V(JSObject, initial_array_prototype) \ 533 V(JSObject, promise_prototype) \ 534 V(Map, async_function_object_map) \ 535 V(Map, block_context_map) \ 536 V(Map, bound_function_with_constructor_map) \ 537 V(Map, bound_function_without_constructor_map) \ 538 V(Map, catch_context_map) \ 539 V(Map, eval_context_map) \ 540 V(Map, fast_aliased_arguments_map) \ 541 V(Map, function_context_map) \ 542 V(Map, initial_array_iterator_map) \ 543 V(Map, initial_string_iterator_map) \ 544 V(Map, iterator_result_map) \ 545 V(Map, js_array_holey_double_elements_map) \ 546 V(Map, js_array_holey_elements_map) \ 547 V(Map, js_array_holey_smi_elements_map) \ 548 V(Map, js_array_packed_double_elements_map) \ 549 V(Map, js_array_packed_elements_map) \ 550 V(Map, js_array_packed_smi_elements_map) \ 551 V(Map, map_key_iterator_map) \ 552 V(Map, map_key_value_iterator_map) \ 553 V(Map, map_value_iterator_map) \ 554 V(Map, set_key_value_iterator_map) \ 555 V(Map, set_value_iterator_map) \ 556 V(Map, sloppy_arguments_map) \ 557 V(Map, slow_object_with_null_prototype_map) \ 558 V(Map, strict_arguments_map) \ 559 V(Map, with_context_map) \ 560 V(ScriptContextTable, script_context_table) 561 562class NativeContextRef : public ContextRef { 563 public: 564 DEFINE_REF_CONSTRUCTOR(NativeContext, ContextRef) 565 566 Handle<NativeContext> object() const; 567 568#define DECL_ACCESSOR(type, name) type##Ref name() const; 569 BROKER_NATIVE_CONTEXT_FIELDS(DECL_ACCESSOR) 570#undef DECL_ACCESSOR 571 572 ScopeInfoRef scope_info() const; 573 MapRef GetFunctionMapFromIndex(int index) const; 574 MapRef GetInitialJSArrayMap(ElementsKind kind) const; 575 base::Optional<JSFunctionRef> GetConstructorFunction(const MapRef& map) const; 576 bool GlobalIsDetached() const; 577}; 578 579class NameRef : public HeapObjectRef { 580 public: 581 DEFINE_REF_CONSTRUCTOR(Name, HeapObjectRef) 582 583 Handle<Name> object() const; 584 585 bool IsUniqueName() const; 586}; 587 588class DescriptorArrayRef : public HeapObjectRef { 589 public: 590 DEFINE_REF_CONSTRUCTOR(DescriptorArray, HeapObjectRef) 591 592 Handle<DescriptorArray> object() const; 593 594 PropertyDetails GetPropertyDetails(InternalIndex descriptor_index) const; 595 NameRef GetPropertyKey(InternalIndex descriptor_index) const; 596 base::Optional<ObjectRef> GetStrongValue( 597 InternalIndex descriptor_index) const; 598}; 599 600class FeedbackCellRef : public HeapObjectRef { 601 public: 602 DEFINE_REF_CONSTRUCTOR(FeedbackCell, HeapObjectRef) 603 604 Handle<FeedbackCell> object() const; 605 606 ObjectRef value() const; 607 608 // Convenience wrappers around {value()}: 609 base::Optional<FeedbackVectorRef> feedback_vector() const; 610 base::Optional<SharedFunctionInfoRef> shared_function_info() const; 611}; 612 613class FeedbackVectorRef : public HeapObjectRef { 614 public: 615 DEFINE_REF_CONSTRUCTOR(FeedbackVector, HeapObjectRef) 616 617 Handle<FeedbackVector> object() const; 618 619 SharedFunctionInfoRef shared_function_info() const; 620 621 FeedbackCellRef GetClosureFeedbackCell(int index) const; 622}; 623 624class CallHandlerInfoRef : public HeapObjectRef { 625 public: 626 DEFINE_REF_CONSTRUCTOR(CallHandlerInfo, HeapObjectRef) 627 628 Handle<CallHandlerInfo> object() const; 629 630 Address callback() const; 631 ObjectRef data() const; 632}; 633 634class AccessorInfoRef : public HeapObjectRef { 635 public: 636 DEFINE_REF_CONSTRUCTOR(AccessorInfo, HeapObjectRef) 637 638 Handle<AccessorInfo> object() const; 639}; 640 641class AllocationSiteRef : public HeapObjectRef { 642 public: 643 DEFINE_REF_CONSTRUCTOR(AllocationSite, HeapObjectRef) 644 645 Handle<AllocationSite> object() const; 646 647 bool PointsToLiteral() const; 648 AllocationType GetAllocationType() const; 649 ObjectRef nested_site() const; 650 651 base::Optional<JSObjectRef> boilerplate() const; 652 ElementsKind GetElementsKind() const; 653 bool CanInlineCall() const; 654}; 655 656class BigIntRef : public HeapObjectRef { 657 public: 658 DEFINE_REF_CONSTRUCTOR(BigInt, HeapObjectRef) 659 660 Handle<BigInt> object() const; 661 662 uint64_t AsUint64() const; 663}; 664 665class V8_EXPORT_PRIVATE MapRef : public HeapObjectRef { 666 public: 667 DEFINE_REF_CONSTRUCTOR(Map, HeapObjectRef) 668 669 Handle<Map> object() const; 670 671 int instance_size() const; 672 InstanceType instance_type() const; 673 int GetInObjectProperties() const; 674 int GetInObjectPropertiesStartInWords() const; 675 int NumberOfOwnDescriptors() const; 676 int GetInObjectPropertyOffset(int index) const; 677 int constructor_function_index() const; 678 int NextFreePropertyIndex() const; 679 int UnusedPropertyFields() const; 680 ElementsKind elements_kind() const; 681 bool is_stable() const; 682 bool is_constructor() const; 683 bool has_prototype_slot() const; 684 bool is_access_check_needed() const; 685 bool is_deprecated() const; 686 bool CanBeDeprecated() const; 687 bool CanTransition() const; 688 bool IsInobjectSlackTrackingInProgress() const; 689 bool is_dictionary_map() const; 690 bool IsFixedCowArrayMap() const; 691 bool IsPrimitiveMap() const; 692 bool is_undetectable() const; 693 bool is_callable() const; 694 bool has_indexed_interceptor() const; 695 bool is_migration_target() const; 696 bool supports_fast_array_iteration() const; 697 bool supports_fast_array_resize() const; 698 bool is_abandoned_prototype_map() const; 699 700 OddballType oddball_type() const; 701 702 bool CanInlineElementAccess() const; 703 704 // Note: Only returns a value if the requested elements kind matches the 705 // current kind, or if the current map is an unmodified JSArray initial map. 706 base::Optional<MapRef> AsElementsKind(ElementsKind kind) const; 707 708#define DEF_TESTER(Type, ...) bool Is##Type##Map() const; 709 INSTANCE_TYPE_CHECKERS(DEF_TESTER) 710#undef DEF_TESTER 711 712 HeapObjectRef GetBackPointer() const; 713 714 HeapObjectRef prototype() const; 715 716 bool HasOnlyStablePrototypesWithFastElements( 717 ZoneVector<MapRef>* prototype_maps); 718 719 // Concerning the underlying instance_descriptors: 720 DescriptorArrayRef instance_descriptors() const; 721 MapRef FindFieldOwner(InternalIndex descriptor_index) const; 722 PropertyDetails GetPropertyDetails(InternalIndex descriptor_index) const; 723 NameRef GetPropertyKey(InternalIndex descriptor_index) const; 724 FieldIndex GetFieldIndexFor(InternalIndex descriptor_index) const; 725 base::Optional<ObjectRef> GetStrongValue( 726 InternalIndex descriptor_number) const; 727 728 MapRef FindRootMap() const; 729 ObjectRef GetConstructor() const; 730}; 731 732struct HolderLookupResult { 733 HolderLookupResult(CallOptimization::HolderLookup lookup_ = 734 CallOptimization::kHolderNotFound, 735 base::Optional<JSObjectRef> holder_ = base::nullopt) 736 : lookup(lookup_), holder(holder_) {} 737 CallOptimization::HolderLookup lookup; 738 base::Optional<JSObjectRef> holder; 739}; 740 741class FunctionTemplateInfoRef : public HeapObjectRef { 742 public: 743 DEFINE_REF_CONSTRUCTOR(FunctionTemplateInfo, HeapObjectRef) 744 745 Handle<FunctionTemplateInfo> object() const; 746 747 bool is_signature_undefined() const; 748 bool accept_any_receiver() const; 749 base::Optional<CallHandlerInfoRef> call_code() const; 750 ZoneVector<Address> c_functions() const; 751 ZoneVector<const CFunctionInfo*> c_signatures() const; 752 HolderLookupResult LookupHolderOfExpectedType(MapRef receiver_map); 753}; 754 755class FixedArrayBaseRef : public HeapObjectRef { 756 public: 757 DEFINE_REF_CONSTRUCTOR(FixedArrayBase, HeapObjectRef) 758 759 Handle<FixedArrayBase> object() const; 760 761 int length() const; 762}; 763 764class ArrayBoilerplateDescriptionRef : public HeapObjectRef { 765 public: 766 using HeapObjectRef::HeapObjectRef; 767 Handle<ArrayBoilerplateDescription> object() const; 768 769 int constants_elements_length() const; 770}; 771 772class FixedArrayRef : public FixedArrayBaseRef { 773 public: 774 DEFINE_REF_CONSTRUCTOR(FixedArray, FixedArrayBaseRef) 775 776 Handle<FixedArray> object() const; 777 778 base::Optional<ObjectRef> TryGet(int i) const; 779}; 780 781class FixedDoubleArrayRef : public FixedArrayBaseRef { 782 public: 783 DEFINE_REF_CONSTRUCTOR(FixedDoubleArray, FixedArrayBaseRef) 784 785 Handle<FixedDoubleArray> object() const; 786 787 // Due to 64-bit unaligned reads, only usable for 788 // immutable-after-initialization FixedDoubleArrays protected by 789 // acquire-release semantics (such as boilerplate elements). 790 Float64 GetFromImmutableFixedDoubleArray(int i) const; 791}; 792 793class BytecodeArrayRef : public FixedArrayBaseRef { 794 public: 795 DEFINE_REF_CONSTRUCTOR(BytecodeArray, FixedArrayBaseRef) 796 797 Handle<BytecodeArray> object() const; 798 799 // NOTE: Concurrent reads of the actual bytecodes as well as the constant pool 800 // (both immutable) do not go through BytecodeArrayRef but are performed 801 // directly through the handle by BytecodeArrayIterator. 802 803 int register_count() const; 804 int parameter_count() const; 805 interpreter::Register incoming_new_target_or_generator_register() const; 806 807 Handle<ByteArray> SourcePositionTable() const; 808 809 // Exception handler table. 810 Address handler_table_address() const; 811 int handler_table_size() const; 812}; 813 814class ScriptContextTableRef : public FixedArrayRef { 815 public: 816 DEFINE_REF_CONSTRUCTOR(ScriptContextTable, FixedArrayRef) 817 818 Handle<ScriptContextTable> object() const; 819}; 820 821class ObjectBoilerplateDescriptionRef : public FixedArrayRef { 822 public: 823 DEFINE_REF_CONSTRUCTOR(ObjectBoilerplateDescription, FixedArrayRef) 824 825 Handle<ObjectBoilerplateDescription> object() const; 826 827 int size() const; 828}; 829 830class JSArrayRef : public JSObjectRef { 831 public: 832 DEFINE_REF_CONSTRUCTOR(JSArray, JSObjectRef) 833 834 Handle<JSArray> object() const; 835 836 // The `length` property of boilerplate JSArray objects. Boilerplates are 837 // immutable after initialization. Must not be used for non-boilerplate 838 // JSArrays. 839 ObjectRef GetBoilerplateLength() const; 840 841 // Return the element at key {index} if the array has a copy-on-write elements 842 // storage and {index} is known to be an own data property. 843 // Note the value returned by this function is only valid if we ensure at 844 // runtime that the backing store has not changed. 845 base::Optional<ObjectRef> GetOwnCowElement(FixedArrayBaseRef elements_ref, 846 uint32_t index) const; 847 848 // The `JSArray::length` property; not safe to use in general, but can be 849 // used in some special cases that guarantee a valid `length` value despite 850 // concurrent reads. The result needs to be optional in case the 851 // return value was created too recently to pass the gc predicate. 852 base::Optional<ObjectRef> length_unsafe() const; 853}; 854 855class ScopeInfoRef : public HeapObjectRef { 856 public: 857 DEFINE_REF_CONSTRUCTOR(ScopeInfo, HeapObjectRef) 858 859 Handle<ScopeInfo> object() const; 860 861 int ContextLength() const; 862 bool HasOuterScopeInfo() const; 863 bool HasContextExtensionSlot() const; 864 865 ScopeInfoRef OuterScopeInfo() const; 866}; 867 868#define BROKER_SFI_FIELDS(V) \ 869 V(int, internal_formal_parameter_count_without_receiver) \ 870 V(bool, IsDontAdaptArguments) \ 871 V(bool, has_simple_parameters) \ 872 V(bool, has_duplicate_parameters) \ 873 V(int, function_map_index) \ 874 V(FunctionKind, kind) \ 875 V(LanguageMode, language_mode) \ 876 V(bool, native) \ 877 V(bool, HasBreakInfo) \ 878 V(bool, HasBuiltinId) \ 879 V(bool, construct_as_builtin) \ 880 V(bool, HasBytecodeArray) \ 881 V(int, StartPosition) \ 882 V(bool, is_compiled) \ 883 V(bool, IsUserJavaScript) \ 884 IF_WASM(V, const wasm::WasmModule*, wasm_module) \ 885 IF_WASM(V, const wasm::FunctionSig*, wasm_function_signature) 886 887class V8_EXPORT_PRIVATE SharedFunctionInfoRef : public HeapObjectRef { 888 public: 889 DEFINE_REF_CONSTRUCTOR(SharedFunctionInfo, HeapObjectRef) 890 891 Handle<SharedFunctionInfo> object() const; 892 893 Builtin builtin_id() const; 894 int context_header_size() const; 895 int context_parameters_start() const; 896 BytecodeArrayRef GetBytecodeArray() const; 897 SharedFunctionInfo::Inlineability GetInlineability() const; 898 base::Optional<FunctionTemplateInfoRef> function_template_info() const; 899 ScopeInfoRef scope_info() const; 900 901#define DECL_ACCESSOR(type, name) type name() const; 902 BROKER_SFI_FIELDS(DECL_ACCESSOR) 903#undef DECL_ACCESSOR 904 905 bool IsInlineable() const { 906 return GetInlineability() == SharedFunctionInfo::kIsInlineable; 907 } 908}; 909 910class StringRef : public NameRef { 911 public: 912 DEFINE_REF_CONSTRUCTOR(String, NameRef) 913 914 Handle<String> object() const; 915 916 // With concurrent inlining on, we return base::nullopt due to not being able 917 // to use LookupIterator in a thread-safe way. 918 base::Optional<ObjectRef> GetCharAsStringOrUndefined(uint32_t index) const; 919 920 // When concurrently accessing non-read-only non-supported strings, we return 921 // base::nullopt for these methods. 922 base::Optional<Handle<String>> ObjectIfContentAccessible(); 923 base::Optional<int> length() const; 924 base::Optional<uint16_t> GetFirstChar() const; 925 base::Optional<uint16_t> GetChar(int index) const; 926 base::Optional<double> ToNumber(); 927 928 bool IsSeqString() const; 929 bool IsExternalString() const; 930 931 private: 932 // With concurrent inlining on, we currently support reading directly 933 // internalized strings, and thin strings (which are pointers to internalized 934 // strings). 935 bool SupportedStringKind() const; 936}; 937 938class SymbolRef : public NameRef { 939 public: 940 DEFINE_REF_CONSTRUCTOR(Symbol, NameRef) 941 942 Handle<Symbol> object() const; 943}; 944 945class JSTypedArrayRef : public JSObjectRef { 946 public: 947 DEFINE_REF_CONSTRUCTOR(JSTypedArray, JSObjectRef) 948 949 Handle<JSTypedArray> object() const; 950 951 bool is_on_heap() const; 952 size_t length() const; 953 void* data_ptr() const; 954 HeapObjectRef buffer() const; 955}; 956 957class SourceTextModuleRef : public HeapObjectRef { 958 public: 959 DEFINE_REF_CONSTRUCTOR(SourceTextModule, HeapObjectRef) 960 961 Handle<SourceTextModule> object() const; 962 963 base::Optional<CellRef> GetCell(int cell_index) const; 964 base::Optional<ObjectRef> import_meta() const; 965}; 966 967class TemplateObjectDescriptionRef : public HeapObjectRef { 968 public: 969 DEFINE_REF_CONSTRUCTOR(TemplateObjectDescription, HeapObjectRef) 970 971 Handle<TemplateObjectDescription> object() const; 972}; 973 974class CellRef : public HeapObjectRef { 975 public: 976 DEFINE_REF_CONSTRUCTOR(Cell, HeapObjectRef) 977 978 Handle<Cell> object() const; 979}; 980 981class JSGlobalObjectRef : public JSObjectRef { 982 public: 983 DEFINE_REF_CONSTRUCTOR(JSGlobalObject, JSObjectRef) 984 985 Handle<JSGlobalObject> object() const; 986 987 bool IsDetachedFrom(JSGlobalProxyRef const& proxy) const; 988 989 // Can be called even when there is no property cell for the given name. 990 base::Optional<PropertyCellRef> GetPropertyCell(NameRef const& name) const; 991}; 992 993class JSGlobalProxyRef : public JSObjectRef { 994 public: 995 DEFINE_REF_CONSTRUCTOR(JSGlobalProxy, JSObjectRef) 996 997 Handle<JSGlobalProxy> object() const; 998}; 999 1000class CodeRef : public HeapObjectRef { 1001 public: 1002 DEFINE_REF_CONSTRUCTOR(Code, HeapObjectRef) 1003 1004 Handle<Code> object() const; 1005 1006 unsigned GetInlinedBytecodeSize() const; 1007}; 1008 1009// CodeDataContainerRef doesn't appear to be used directly, but it is used via 1010// CodeTRef when V8_EXTERNAL_CODE_SPACE is enabled. 1011class CodeDataContainerRef : public HeapObjectRef { 1012 public: 1013 DEFINE_REF_CONSTRUCTOR(CodeDataContainer, HeapObjectRef) 1014 1015 Handle<CodeDataContainer> object() const; 1016}; 1017 1018class InternalizedStringRef : public StringRef { 1019 public: 1020 DEFINE_REF_CONSTRUCTOR(InternalizedString, StringRef) 1021 1022 Handle<InternalizedString> object() const; 1023}; 1024 1025#undef DEFINE_REF_CONSTRUCTOR 1026 1027} // namespace compiler 1028} // namespace internal 1029} // namespace v8 1030 1031#endif // V8_COMPILER_HEAP_REFS_H_ 1032