v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
heap-refs.h
Go to the documentation of this file.
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 <optional>
9#include <type_traits>
10
18
19namespace v8 {
20
21class CFunctionInfo;
22
23namespace internal {
24
25class BytecodeArray;
26class FixedDoubleArray;
27class FunctionTemplateInfo;
28class HeapNumber;
29class InternalizedString;
30class JSBoundFunction;
31class JSDataView;
32class JSGlobalProxy;
33class JSTypedArray;
34class NativeContext;
35class ScriptContextTable;
36template <typename>
37class Signature;
38
39namespace interpreter {
40class Register;
41} // namespace interpreter
42
43namespace wasm {
44class ValueType;
45struct WasmModule;
46} // namespace wasm
47
48namespace compiler {
49
50class CompilationDependencies;
51struct FeedbackSource;
52class JSHeapBroker;
53class ObjectData;
54class PerIsolateCompilerCache;
55class PropertyAccessInfo;
56
57// Whether we are loading a property or storing to a property.
58// For a store during literal creation, do not walk up the prototype chain.
59// For a define operation, we behave similarly to kStoreInLiteral, but with
60// distinct semantics for private class fields (in which private field
61// accesses must throw when storing a field which does not exist, or
62// adding/defining a field which already exists).
64
65inline bool IsAnyStore(AccessMode mode) {
66 return mode == AccessMode::kStore || mode == AccessMode::kStoreInLiteral ||
67 mode == AccessMode::kDefine;
68}
69
70inline bool IsDefiningStore(AccessMode mode) {
71 return mode == AccessMode::kStoreInLiteral || mode == AccessMode::kDefine;
72}
73
74enum class OddballType : uint8_t {
75 kNone, // Not an Oddball.
76 kBoolean, // True or False.
78 kNull,
79};
80
81enum class HoleType : uint8_t {
82 kNone, // Not a Hole.
83
84#define FOR_HOLE(Name, name, Root) k##Name,
86#undef FOR_HOLE
87
89};
90
92 // Skips serialization.
94 // Can be serialized on demand from the background thread.
96};
97
98// This list is sorted such that subtypes appear before their supertypes.
99// DO NOT VIOLATE THIS PROPERTY!
100#define HEAP_BROKER_OBJECT_LIST_BASE(BACKGROUND_SERIALIZED, NEVER_SERIALIZED) \
101 /* Subtypes of JSObject */ \
102 BACKGROUND_SERIALIZED(JSArray) \
103 BACKGROUND_SERIALIZED(JSBoundFunction) \
104 BACKGROUND_SERIALIZED(JSDataView) \
105 BACKGROUND_SERIALIZED(JSFunction) \
106 BACKGROUND_SERIALIZED(JSGlobalObject) \
107 BACKGROUND_SERIALIZED(JSGlobalProxy) \
108 BACKGROUND_SERIALIZED(JSTypedArray) \
109 BACKGROUND_SERIALIZED(JSPrimitiveWrapper) \
110 /* Subtypes of Context */ \
111 NEVER_SERIALIZED(NativeContext) \
112 /* Subtypes of FixedArray */ \
113 NEVER_SERIALIZED(ObjectBoilerplateDescription) \
114 BACKGROUND_SERIALIZED(ScriptContextTable) \
115 /* Subtypes of String */ \
116 NEVER_SERIALIZED(InternalizedString) \
117 /* Subtypes of FixedArrayBase */ \
118 BACKGROUND_SERIALIZED(FixedArray) \
119 NEVER_SERIALIZED(FixedDoubleArray) \
120 /* Subtypes of Name */ \
121 NEVER_SERIALIZED(String) \
122 NEVER_SERIALIZED(Symbol) \
123 /* Subtypes of JSReceiver */ \
124 BACKGROUND_SERIALIZED(JSObject) \
125 /* Subtypes of HeapObject */ \
126 NEVER_SERIALIZED(AccessorInfo) \
127 NEVER_SERIALIZED(AllocationSite) \
128 NEVER_SERIALIZED(ArrayBoilerplateDescription) \
129 BACKGROUND_SERIALIZED(BigInt) \
130 NEVER_SERIALIZED(BytecodeArray) \
131 NEVER_SERIALIZED(Cell) \
132 NEVER_SERIALIZED(Code) \
133 NEVER_SERIALIZED(Context) \
134 NEVER_SERIALIZED(DescriptorArray) \
135 NEVER_SERIALIZED(FeedbackCell) \
136 NEVER_SERIALIZED(FeedbackVector) \
137 BACKGROUND_SERIALIZED(FixedArrayBase) \
138 NEVER_SERIALIZED(FunctionTemplateInfo) \
139 NEVER_SERIALIZED(HeapNumber) \
140 BACKGROUND_SERIALIZED(JSReceiver) \
141 BACKGROUND_SERIALIZED(Map) \
142 NEVER_SERIALIZED(Name) \
143 BACKGROUND_SERIALIZED(PropertyCell) \
144 NEVER_SERIALIZED(RegExpBoilerplateDescription) \
145 NEVER_SERIALIZED(ScopeInfo) \
146 NEVER_SERIALIZED(SharedFunctionInfo) \
147 NEVER_SERIALIZED(SourceTextModule) \
148 NEVER_SERIALIZED(TemplateObjectDescription) \
149 /* Subtypes of Object */ \
150 BACKGROUND_SERIALIZED(HeapObject)
151
152#define HEAP_BROKER_OBJECT_LIST(V) HEAP_BROKER_OBJECT_LIST_BASE(V, V)
153#define IGNORE_CASE(...)
154#define HEAP_BROKER_BACKGROUND_SERIALIZED_OBJECT_LIST(V) \
155 HEAP_BROKER_OBJECT_LIST_BASE(V, IGNORE_CASE)
156
157#define FORWARD_DECL(Name) class Name##Ref;
159FORWARD_DECL(Object)
160#undef FORWARD_DECL
161
162template <class T>
163struct is_ref : public std::false_type {};
164
165#define DEFINE_IS_REF(Name) \
166 template <> \
167 struct is_ref<Name##Ref> : public std::true_type {};
169DEFINE_IS_REF(Object)
170#undef DEFINE_IS_REF
171
172template <class T>
174
175#define FORWARD_DECL(Name) class Name##Data;
177#undef FORWARD_DECL
178
179#define BACKGROUND_SERIALIZED_REF_TRAITS(Name) \
180 template <> \
181 struct ref_traits<Name> { \
182 using ref_type = Name##Ref; \
183 using data_type = Name##Data; \
184 static constexpr RefSerializationKind ref_serialization_kind = \
185 RefSerializationKind::kBackgroundSerialized; \
186 };
187
188#define NEVER_SERIALIZED_REF_TRAITS(Name) \
189 template <> \
190 struct ref_traits<Name> { \
191 using ref_type = Name##Ref; \
192 using data_type = ObjectData; \
193 static constexpr RefSerializationKind ref_serialization_kind = \
194 RefSerializationKind::kNeverSerialized; \
195 };
196
199#undef NEVER_SERIALIZED_REF_TRAITS
200#undef BACKGROUND_SERIALIZED_REF_TRAITS
201
202template <>
203struct ref_traits<Object> {
204 using ref_type = ObjectRef;
205 using data_type = ObjectData;
206 // Note: While a bit awkward, this artificial ref serialization kind value is
207 // okay: smis are never-serialized, and we never create raw non-smi
208 // ObjectRefs (they would at least be HeapObjectRefs instead).
209 static constexpr RefSerializationKind ref_serialization_kind =
211};
212
213// For types which don't have a corresponding Ref type, use the next best
214// existing Ref.
215template <>
216struct ref_traits<Oddball> : public ref_traits<HeapObject> {};
217template <>
218struct ref_traits<Null> : public ref_traits<HeapObject> {};
219template <>
220struct ref_traits<Undefined> : public ref_traits<HeapObject> {};
221template <>
222struct ref_traits<True> : public ref_traits<HeapObject> {};
223template <>
224struct ref_traits<False> : public ref_traits<HeapObject> {};
225template <>
226struct ref_traits<Hole> : public ref_traits<HeapObject> {};
227template <>
228struct ref_traits<EnumCache> : public ref_traits<HeapObject> {};
229template <>
230struct ref_traits<PropertyArray> : public ref_traits<HeapObject> {};
231template <>
232struct ref_traits<ByteArray> : public ref_traits<HeapObject> {};
233template <>
234struct ref_traits<TrustedFixedArray> : public ref_traits<HeapObject> {};
235template <>
236struct ref_traits<ClosureFeedbackCellArray> : public ref_traits<HeapObject> {};
237template <>
238struct ref_traits<NumberDictionary> : public ref_traits<HeapObject> {};
239template <>
240struct ref_traits<OrderedHashMap> : public ref_traits<HeapObject> {};
241template <>
242struct ref_traits<OrderedHashSet> : public ref_traits<HeapObject> {};
243template <>
244struct ref_traits<FeedbackMetadata> : public ref_traits<HeapObject> {};
245template <>
246struct ref_traits<NameDictionary> : public ref_traits<HeapObject> {};
247template <>
248struct ref_traits<OrderedNameDictionary> : public ref_traits<HeapObject> {};
249template <>
250struct ref_traits<SwissNameDictionary> : public ref_traits<HeapObject> {};
251template <>
252struct ref_traits<InterceptorInfo> : public ref_traits<HeapObject> {};
253template <>
254struct ref_traits<ArrayList> : public ref_traits<HeapObject> {};
255template <>
256struct ref_traits<WeakFixedArray> : public ref_traits<HeapObject> {};
257template <>
258struct ref_traits<WeakArrayList> : public ref_traits<HeapObject> {};
259template <>
260struct ref_traits<RegisteredSymbolTable> : public ref_traits<HeapObject> {};
261#if V8_ENABLE_WEBASSEMBLY
262template <>
263struct ref_traits<WasmNull> : public ref_traits<HeapObject> {};
264#endif // V8_ENABLE_WEBASSEMBLY
265template <>
266struct ref_traits<Smi> : public ref_traits<Object> {};
267template <>
268struct ref_traits<Boolean> : public ref_traits<HeapObject> {};
269template <>
270struct ref_traits<JSProxy> : public ref_traits<JSReceiver> {};
271template <>
272struct ref_traits<JSWrappedFunction> : public ref_traits<JSFunction> {};
273
274template <class... T>
275struct ref_traits<Union<T...>> {
276 // There's no good way in C++ to find a common base class, so just test a few
277 // common cases.
278 static constexpr bool kAllJSReceiverRef =
279 (std::is_base_of_v<JSReceiverRef, typename ref_traits<T>::ref_type> &&
280 ...);
281 static constexpr bool kAllHeapObjectRef =
282 (std::is_base_of_v<JSReceiverRef, typename ref_traits<T>::ref_type> &&
283 ...);
284
285 using ref_type = std::conditional_t<
286 kAllJSReceiverRef, JSReceiverRef,
287 std::conditional_t<kAllHeapObjectRef, HeapObjectRef, ObjectRef>>;
288 using data_type = std::conditional_t<
289 kAllJSReceiverRef, JSReceiverData,
290 std::conditional_t<kAllHeapObjectRef, HeapObjectData, ObjectData>>;
291
292 static constexpr RefSerializationKind ref_serialization_kind =
295 ...)
298};
299
300// Wrapper around heap refs which works roughly like a std::optional, but
301// doesn't use extra storage for a boolean, but instead uses a null data pointer
302// as a sentinel no value.
303template <typename TRef>
305 public:
306 // {ArrowOperatorHelper} is returned by {OptionalRef::operator->}. It should
307 // never be stored anywhere or used in any other code; no one should ever have
308 // to spell out {ArrowOperatorHelper} in code. Its only purpose is to be
309 // dereferenced immediately by "operator-> chaining". Returning the address of
310 // the field is valid because this objects lifetime only ends at the end of
311 // the full statement.
313 public:
314 TRef* operator->() { return &object_; }
315
316 private:
317 friend class OptionalRef<TRef>;
318 explicit ArrowOperatorHelper(TRef object) : object_(object) {}
319
321 };
322
323 OptionalRef() = default;
324 // NOLINTNEXTLINE
325 OptionalRef(std::nullopt_t) : OptionalRef() {}
326
327 // Allow implicit upcasting from OptionalRefs with compatible refs.
328 template <typename SRef>
329 // NOLINTNEXTLINE
331 requires std::is_convertible_v<SRef*, TRef*>
332 : data_(ref.data_) {}
333
334 // Allow implicit upcasting from compatible refs.
335 template <typename SRef>
336 // NOLINTNEXTLINE
338 requires std::is_convertible_v<SRef*, TRef*>
339 : data_(ref.data_) {}
340
341 constexpr bool has_value() const { return data_ != nullptr; }
342 constexpr explicit operator bool() const { return has_value(); }
343
344 TRef value() const {
345 DCHECK(has_value());
346 return TRef(data_, false);
347 }
348 TRef operator*() const { return value(); }
352
353 bool equals(OptionalRef other) const { return data_ == other.data_; }
354
355 size_t hash_value() const {
356 return has_value() ? value().hash_value() : base::hash_value(0);
357 }
358
359 private:
360 explicit OptionalRef(ObjectData* data) : data_(data) {
362 }
363 ObjectData* data_ = nullptr;
364
365 template <typename SRef>
366 friend class OptionalRef;
367};
368
369template <typename T>
371 return lhs.equals(rhs);
372}
373
374template <typename T>
375inline size_t hash_value(OptionalRef<T> ref) {
376 return ref.hash_value();
377}
378
379// Define aliases for OptionalFooRef = OptionalRef<FooRef>.
380#define V(Name) using Optional##Name##Ref = OptionalRef<Name##Ref>;
383#undef V
384
385class V8_EXPORT_PRIVATE ObjectRef {
386 public:
387 explicit ObjectRef(ObjectData* data, bool check_type = true) : data_(data) {
389 }
390
391 IndirectHandle<Object> object() const;
392
393 bool equals(ObjectRef other) const;
394
395 size_t hash_value() const { return base::hash_combine(object().address()); }
396
397 bool IsSmi() const;
398 int AsSmi() const;
399
400#define HEAP_IS_METHOD_DECL(Name) bool Is##Name() const;
402#undef HEAP_IS_METHOD_DECL
403
404#define HEAP_AS_METHOD_DECL(Name) Name##Ref As##Name() const;
406#undef HEAP_AS_METHOD_DECL
407
408 bool IsNull() const;
409 bool IsUndefined() const;
410 enum HoleType HoleType() const;
411 bool IsTheHole() const;
412 bool IsPropertyCellHole() const;
413 bool IsHashTableHole() const;
414 bool IsPromiseHole() const;
415 bool IsNullOrUndefined() const;
416
417 std::optional<bool> TryGetBooleanValue(JSHeapBroker* broker) const;
418 Maybe<double> OddballToNumber(JSHeapBroker* broker) const;
419
420 bool should_access_heap() const;
421
422 ObjectData* data() const;
423
424 struct Hash {
425 size_t operator()(ObjectRef ref) const { return ref.hash_value(); }
426 };
427
428 protected:
429 ObjectData* data_; // Should be used only by object() getters.
430
431 private:
432 friend class FunctionTemplateInfoRef;
433 friend class JSArrayData;
434 friend class JSFunctionData;
435 friend class JSGlobalObjectData;
436 friend class JSGlobalObjectRef;
437 friend class JSHeapBroker;
438 friend class JSObjectData;
439 friend class StringData;
440
441 template <typename TRef>
442 friend class OptionalRef;
443
444 friend std::ostream& operator<<(std::ostream& os, ObjectRef ref);
445 friend bool operator<(ObjectRef lhs, ObjectRef rhs);
446 template <typename T, typename Enable>
447 friend struct ::v8::internal::ZoneCompactSetTraits;
448};
449
450inline bool operator==(ObjectRef lhs, ObjectRef rhs) { return lhs.equals(rhs); }
451
452inline bool operator!=(ObjectRef lhs, ObjectRef rhs) {
453 return !lhs.equals(rhs);
454}
455
456inline bool operator<(ObjectRef lhs, ObjectRef rhs) {
457 return lhs.data_ < rhs.data_;
458}
459
460inline size_t hash_value(ObjectRef ref) { return ref.hash_value(); }
461
462template <class T>
464
465template <class K, class V>
467
468// Temporary class that carries information from a Map. We'd like to remove
469// this class and use MapRef instead, but we can't as long as we support the
470// kDisabled broker mode. That's because obtaining the MapRef via
471// HeapObjectRef::map() requires a HandleScope when the broker is disabled.
472// During OptimizeGraph we generally don't have a HandleScope, however. There
473// are two places where we therefore use GetHeapObjectType() instead. Both that
474// function and this class should eventually be removed.
511
512// Constructors are carefully defined such that we do a type check on
513// the outermost Ref class in the inheritance chain only.
514#define DEFINE_REF_CONSTRUCTOR(Name, Base) \
515 explicit Name##Ref(ObjectData* data, bool check_type = true) \
516 : Base(data, false) { \
517 if (check_type) { \
518 CHECK(Is##Name()); \
519 } \
520 }
521
522class HeapObjectRef : public ObjectRef {
523 public:
525
526 IndirectHandle<HeapObject> object() const;
527
529
530 // Only for use in special situations where we need to read the object's
531 // current map (instead of returning the cached map). Use with care.
532 OptionalMapRef map_direct_read(JSHeapBroker* broker) const;
533
534 // See the comment on the HeapObjectType class.
536};
537
539 public:
541
543
544 V8_WARN_UNUSED_RESULT bool Cache(JSHeapBroker* broker) const;
545 void CacheAsProtector(JSHeapBroker* broker) const {
546 bool cached = Cache(broker);
547 // A protector always holds a Smi value and its cell type never changes, so
548 // Cache can't fail.
549 CHECK(cached);
550 }
551
553 ObjectRef value(JSHeapBroker* broker) const;
554};
555
557 public:
559
560 IndirectHandle<JSReceiver> object() const;
561};
562
564 public:
566
567 IndirectHandle<JSObject> object() const;
568
569 OptionalObjectRef raw_properties_or_hash(JSHeapBroker* broker) const;
570
571 // Usable only for in-object properties. Only use this if the underlying
572 // value can be an uninitialized-sentinel. Otherwise, use the higher-level
573 // GetOwnFastConstantDataProperty/GetOwnFastConstantDoubleProperty.
574 OptionalObjectRef RawInobjectPropertyAt(JSHeapBroker* broker,
575 FieldIndex index) const;
576
577 // Return the element at key {index} if {index} is known to be an own data
578 // property of the object that is non-writable and non-configurable. If
579 // {dependencies} is non-null, a dependency will be taken to protect
580 // against inconsistency due to weak memory concurrency.
581 OptionalObjectRef GetOwnConstantElement(
582 JSHeapBroker* broker, FixedArrayBaseRef elements_ref, uint32_t index,
583 CompilationDependencies* dependencies) const;
584 // The direct-read implementation of the above, extracted into a helper since
585 // it's also called from compilation-dependency validation. This helper is
586 // guaranteed to not create new Ref instances.
587 std::optional<Tagged<Object>> GetOwnConstantElementFromHeap(
589 ElementsKind elements_kind, uint32_t index) const;
590
591 // Return the value of the property identified by the field {index}
592 // if {index} is known to be an own data property of the object and the field
593 // is constant.
594 // If a property was successfully read, then the function will take a
595 // dependency to check the value of the property at code finalization time.
596 //
597 // This is *not* allowed to be a double representation field. Those should use
598 // GetOwnFastDoubleProperty, to avoid unnecessary HeapNumber allocation.
599 OptionalObjectRef GetOwnFastConstantDataProperty(
600 JSHeapBroker* broker, Representation field_representation,
601 FieldIndex index, CompilationDependencies* dependencies) const;
602
603 // Return the value of the double property identified by the field {index}
604 // if {index} is known to be an own data property of the object and the field
605 // is constant.
606 // If a property was successfully read, then the function will take a
607 // dependency to check the value of the property at code finalization time.
608 std::optional<Float64> GetOwnFastConstantDoubleProperty(
610 CompilationDependencies* dependencies) const;
611
612 // Return the value of the dictionary property at {index} in the dictionary
613 // if {index} is known to be an own data property of the object.
614 OptionalObjectRef GetOwnDictionaryProperty(
616 CompilationDependencies* dependencies) const;
617
618 // When concurrent inlining is enabled, reads the elements through a direct
619 // relaxed read. This is to ease the transition to unserialized (or
620 // background-serialized) elements.
621 OptionalFixedArrayBaseRef elements(JSHeapBroker* broker,
622 RelaxedLoadTag) const;
623 bool IsElementsTenured(FixedArrayBaseRef elements);
624
625 OptionalMapRef GetObjectCreateMap(JSHeapBroker* broker) const;
626};
627
629 public:
631
632 IndirectHandle<JSDataView> object() const;
633
634 size_t byte_length() const;
635};
636
638 public:
640
642
643 JSReceiverRef bound_target_function(JSHeapBroker* broker) const;
644 ObjectRef bound_this(JSHeapBroker* broker) const;
645 FixedArrayRef bound_arguments(JSHeapBroker* broker) const;
646};
647
649 public:
651
652 IndirectHandle<JSFunction> object() const;
653
654 // Returns true, iff the serialized JSFunctionData contents are consistent
655 // with the state of the underlying JSFunction object. Must be called from
656 // the main thread.
657 bool IsConsistentWithHeapState(JSHeapBroker* broker) const;
658
660 NativeContextRef native_context(JSHeapBroker* broker) const;
662 OptionalCodeRef code(JSHeapBroker* broker) const;
663
664 bool has_initial_map(JSHeapBroker* broker) const;
665 bool PrototypeRequiresRuntimeLookup(JSHeapBroker* broker) const;
666 bool has_instance_prototype(JSHeapBroker* broker) const;
667 HeapObjectRef instance_prototype(JSHeapBroker* broker) const;
668 MapRef initial_map(JSHeapBroker* broker) const;
669 int InitialMapInstanceSizeWithMinSlack(JSHeapBroker* broker) const;
670 FeedbackCellRef raw_feedback_cell(JSHeapBroker* broker) const;
671 OptionalFeedbackVectorRef feedback_vector(JSHeapBroker* broker) const;
672#ifdef V8_ENABLE_LEAPTIERING
673 JSDispatchHandle dispatch_handle() const;
674#endif
675};
676
687
688// HeapNumberRef is only created for immutable HeapNumbers. Mutable
689// HeapNumbers (those owned by in-object or backing store fields with
690// representation type Double are not exposed to the compiler through
691// HeapNumberRef. Instead, we read their value, and protect that read
692// with a field-constness Dependency.
694 public:
696
697 IndirectHandle<HeapNumber> object() const;
698
699 double value() const;
700 uint64_t value_as_bits() const;
701};
702
703class ContextRef : public HeapObjectRef {
704 public:
706
707 IndirectHandle<Context> object() const;
708
709 // {previous} decrements {depth} by 1 for each previous link successfully
710 // followed. If {depth} != 0 on function return, then it only got partway to
711 // the desired depth.
712 ContextRef previous(JSHeapBroker* broker, size_t* depth) const;
713
714 // Only returns a value if the index is valid for this ContextRef.
715 OptionalObjectRef get(JSHeapBroker* broker, int index) const;
716
717 ScopeInfoRef scope_info(JSHeapBroker* broker) const;
718
719 // Only returns a value if the index is valid for this ContextRef.
720 OptionalObjectRef TryGetSideData(JSHeapBroker* broker, int index) const;
721};
722
723#define BROKER_NATIVE_CONTEXT_FIELDS(V) \
724 V(JSFunction, array_function) \
725 V(JSFunction, bigint_function) \
726 V(JSFunction, boolean_function) \
727 V(JSFunction, function_prototype_apply) \
728 V(JSFunction, number_function) \
729 V(JSFunction, object_function) \
730 V(JSFunction, promise_function) \
731 V(JSFunction, promise_then) \
732 V(JSFunction, regexp_exec_function) \
733 V(JSFunction, regexp_function) \
734 V(JSFunction, string_function) \
735 V(JSFunction, symbol_function) \
736 V(JSGlobalObject, global_object) \
737 V(JSGlobalProxy, global_proxy_object) \
738 V(JSObject, initial_array_prototype) \
739 V(JSObject, promise_prototype) \
740 V(Map, async_function_object_map) \
741 V(Map, block_context_map) \
742 V(Map, bound_function_with_constructor_map) \
743 V(Map, bound_function_without_constructor_map) \
744 V(Map, catch_context_map) \
745 V(Map, eval_context_map) \
746 V(Map, fast_aliased_arguments_map) \
747 V(Map, function_context_map) \
748 V(Map, initial_array_iterator_map) \
749 V(Map, initial_string_iterator_map) \
750 V(Map, iterator_result_map) \
751 V(Map, js_array_holey_double_elements_map) \
752 V(Map, js_array_holey_elements_map) \
753 V(Map, js_array_holey_smi_elements_map) \
754 V(Map, js_array_packed_double_elements_map) \
755 V(Map, js_array_packed_elements_map) \
756 V(Map, js_array_packed_smi_elements_map) \
757 V(Map, map_key_iterator_map) \
758 V(Map, map_key_value_iterator_map) \
759 V(Map, map_value_iterator_map) \
760 V(Map, meta_map) \
761 V(Map, set_key_value_iterator_map) \
762 V(Map, set_value_iterator_map) \
763 V(Map, sloppy_arguments_map) \
764 V(Map, slow_object_with_null_prototype_map) \
765 V(Map, strict_arguments_map) \
766 V(Map, with_context_map) \
767 V(ScriptContextTable, script_context_table)
768
770 public:
772
774
775#define DECL_ACCESSOR(type, name) type##Ref name(JSHeapBroker* broker) const;
777#undef DECL_ACCESSOR
778
779 MapRef GetFunctionMapFromIndex(JSHeapBroker* broker, int index) const;
780 MapRef GetInitialJSArrayMap(JSHeapBroker* broker, ElementsKind kind) const;
781 OptionalJSFunctionRef GetConstructorFunction(JSHeapBroker* broker,
782 MapRef map) const;
783 bool GlobalIsDetached(JSHeapBroker* broker) const;
784};
785
786class NameRef : public HeapObjectRef {
787 public:
789
790 IndirectHandle<Name> object() const;
791
792 bool IsUniqueName() const;
793};
794
796 public:
798
800
801 PropertyDetails GetPropertyDetails(InternalIndex descriptor_index) const;
802 NameRef GetPropertyKey(JSHeapBroker* broker,
803 InternalIndex descriptor_index) const;
804 OptionalObjectRef GetStrongValue(JSHeapBroker* broker,
805 InternalIndex descriptor_index) const;
806};
807
809 public:
811
813
814 ObjectRef value(JSHeapBroker* broker) const;
815
816 // Convenience wrappers around {value()}:
817 OptionalFeedbackVectorRef feedback_vector(JSHeapBroker* broker) const;
818 OptionalSharedFunctionInfoRef shared_function_info(
819 JSHeapBroker* broker) const;
820#ifdef V8_ENABLE_LEAPTIERING
821 JSDispatchHandle dispatch_handle() const;
822#endif
823};
824
826 public:
828
830
831 SharedFunctionInfoRef shared_function_info(JSHeapBroker* broker) const;
832
833 FeedbackCellRef GetClosureFeedbackCell(JSHeapBroker* broker, int index) const;
834
835 bool was_once_deoptimized() const;
836};
837
844
846 public:
848
850
851 bool PointsToLiteral() const;
852 AllocationType GetAllocationType() const;
853 ObjectRef nested_site(JSHeapBroker* broker) const;
854
855 OptionalJSObjectRef boilerplate(JSHeapBroker* broker) const;
856 ElementsKind GetElementsKind() const;
857 bool CanInlineCall() const;
858};
859
860class BigIntRef : public HeapObjectRef {
861 public:
863
864 IndirectHandle<BigInt> object() const;
865
866 uint64_t AsUint64() const;
867 int64_t AsInt64(bool* lossless) const;
868};
869
871 public:
873
874 IndirectHandle<Map> object() const;
875
876 int instance_size() const;
877 InstanceType instance_type() const;
878 int GetInObjectProperties() const;
879 int GetInObjectPropertiesStartInWords() const;
880 int NumberOfOwnDescriptors() const;
881 int GetInObjectPropertyOffset(int index) const;
882 int constructor_function_index() const;
883 int NextFreePropertyIndex() const;
884 int UnusedPropertyFields() const;
885 ElementsKind elements_kind() const;
886 bool is_stable() const;
887 bool is_constructor() const;
888 bool has_prototype_slot() const;
889 bool is_access_check_needed() const;
890 bool is_deprecated() const;
891 bool CanBeDeprecated() const;
892 bool CanTransition() const;
893 bool IsInobjectSlackTrackingInProgress() const;
894 bool is_dictionary_map() const;
895 bool IsFixedCowArrayMap(JSHeapBroker* broker) const;
896 bool IsPrimitiveMap() const;
897 bool is_undetectable() const;
898 bool is_callable() const;
899 bool has_indexed_interceptor() const;
900 int construction_counter() const;
901 bool is_migration_target() const;
902 bool supports_fast_array_iteration(JSHeapBroker* broker) const;
903 bool supports_fast_array_resize(JSHeapBroker* broker) const;
904 bool is_abandoned_prototype_map() const;
905 bool IsTwoByteStringMap() const;
906 bool IsThinStringMap() const;
907 bool IsStringWrapperMap() const;
908
909 OddballType oddball_type(JSHeapBroker* broker) const;
910
911 bool CanInlineElementAccess() const;
912
913 // Note: Only returns a value if the requested elements kind matches the
914 // current kind, or if the current map is an unmodified JSArray initial map.
915 OptionalMapRef AsElementsKind(JSHeapBroker* broker, ElementsKind kind) const;
916
917#define DEF_TESTER(Type, ...) bool Is##Type##Map() const;
919#undef DEF_TESTER
920
921 bool IsBooleanMap(JSHeapBroker* broker) const;
922
923 HeapObjectRef GetBackPointer(JSHeapBroker* broker) const;
924
925 HeapObjectRef prototype(JSHeapBroker* broker) const;
926
927 bool PrototypesElementsDoNotHaveAccessorsOrThrow(
928 JSHeapBroker* broker, ZoneVector<MapRef>* prototype_maps);
929
930 // Concerning the underlying instance_descriptors:
931 DescriptorArrayRef instance_descriptors(JSHeapBroker* broker) const;
932 MapRef FindFieldOwner(JSHeapBroker* broker,
933 InternalIndex descriptor_index) const;
934 PropertyDetails GetPropertyDetails(JSHeapBroker* broker,
935 InternalIndex descriptor_index) const;
936 NameRef GetPropertyKey(JSHeapBroker* broker,
937 InternalIndex descriptor_index) const;
938 FieldIndex GetFieldIndexFor(InternalIndex descriptor_index) const;
939 OptionalObjectRef GetStrongValue(JSHeapBroker* broker,
940 InternalIndex descriptor_number) const;
941
942 MapRef FindRootMap(JSHeapBroker* broker) const;
943 ObjectRef GetConstructor(JSHeapBroker* broker) const;
944};
945
948 CallOptimization::kHolderNotFound,
949 OptionalJSObjectRef holder_ = std::nullopt)
950 : lookup(lookup_), holder(holder_) {}
952 OptionalJSObjectRef holder;
953};
954
956 public:
958
960
961 bool is_signature_undefined(JSHeapBroker* broker) const;
962 bool accept_any_receiver() const;
963 int16_t allowed_receiver_instance_type_range_start() const;
964 int16_t allowed_receiver_instance_type_range_end() const;
965
966 // Function pointer and a data value that should be passed to the callback.
967 // The |callback_data| must be read before the |callback|.
968 Address callback(JSHeapBroker* broker) const;
969 OptionalObjectRef callback_data(JSHeapBroker* broker) const;
970
971 ZoneVector<Address> c_functions(JSHeapBroker* broker) const;
972 ZoneVector<const CFunctionInfo*> c_signatures(JSHeapBroker* broker) const;
973 HolderLookupResult LookupHolderOfExpectedType(JSHeapBroker* broker,
974 MapRef receiver_map);
975};
976
978 public:
980
982
983 uint32_t length() const;
984};
985
987 public:
988 using HeapObjectRef::HeapObjectRef;
990
991 int constants_elements_length() const;
992};
993
995 public:
997
998 IndirectHandle<FixedArray> object() const;
999
1000 OptionalObjectRef TryGet(JSHeapBroker* broker, int i) const;
1001};
1002
1004 public:
1006
1008
1009 // Due to 64-bit unaligned reads, only usable for
1010 // immutable-after-initialization FixedDoubleArrays protected by
1011 // acquire-release semantics (such as boilerplate elements).
1012 Float64 GetFromImmutableFixedDoubleArray(int i) const;
1013};
1014
1016 public:
1018
1020
1021 // NOTE: Concurrent reads of the actual bytecodes as well as the constant pool
1022 // (both immutable) do not go through BytecodeArrayRef but are performed
1023 // directly through the handle by BytecodeArrayIterator.
1024
1025 int length() const;
1026
1027 int register_count() const;
1028 uint16_t parameter_count() const;
1029 uint16_t parameter_count_without_receiver() const;
1030 uint16_t max_arguments() const;
1031 interpreter::Register incoming_new_target_or_generator_register() const;
1032
1034 JSHeapBroker* broker) const;
1035
1036 // Exception handler table.
1037 Address handler_table_address() const;
1038 int handler_table_size() const;
1039};
1040
1047
1049 public:
1051
1053
1054 int boilerplate_properties_count() const;
1055};
1056
1057class JSArrayRef : public JSObjectRef {
1058 public:
1060
1061 IndirectHandle<JSArray> object() const;
1062
1063 // The `length` property of boilerplate JSArray objects. Boilerplates are
1064 // immutable after initialization. Must not be used for non-boilerplate
1065 // JSArrays.
1066 ObjectRef GetBoilerplateLength(JSHeapBroker* broker) const;
1067
1068 // Return the element at key {index} if the array has a copy-on-write elements
1069 // storage and {index} is known to be an own data property.
1070 // Note the value returned by this function is only valid if we ensure at
1071 // runtime that the backing store has not changed.
1072 OptionalObjectRef GetOwnCowElement(JSHeapBroker* broker,
1073 FixedArrayBaseRef elements_ref,
1074 uint32_t index) const;
1075
1076 // The `JSArray::length` property; not safe to use in general, but can be
1077 // used in some special cases that guarantee a valid `length` value despite
1078 // concurrent reads. The result needs to be optional in case the
1079 // return value was created too recently to pass the gc predicate.
1080 OptionalObjectRef length_unsafe(JSHeapBroker* broker) const;
1081};
1082
1084 public:
1086
1087 IndirectHandle<ScopeInfo> object() const;
1088
1089 int ContextLength() const;
1090 bool HasContext() const;
1091 bool HasOuterScopeInfo() const;
1092 bool HasContextExtensionSlot() const;
1093 bool SomeContextHasExtension() const;
1094 bool ClassScopeHasPrivateBrand() const;
1095 bool SloppyEvalCanExtendVars() const;
1096 ScopeType scope_type() const;
1097
1098 ScopeInfoRef OuterScopeInfo(JSHeapBroker* broker) const;
1099};
1100
1101#define BROKER_SFI_FIELDS(V) \
1102 V(int, internal_formal_parameter_count_with_receiver) \
1103 V(int, internal_formal_parameter_count_without_receiver) \
1104 V(bool, IsDontAdaptArguments) \
1105 V(bool, has_simple_parameters) \
1106 V(bool, has_duplicate_parameters) \
1107 V(int, function_map_index) \
1108 V(FunctionKind, kind) \
1109 V(LanguageMode, language_mode) \
1110 V(bool, native) \
1111 V(bool, HasBuiltinId) \
1112 V(bool, construct_as_builtin) \
1113 V(bool, HasBytecodeArray) \
1114 V(int, StartPosition) \
1115 V(bool, is_compiled) \
1116 V(bool, IsUserJavaScript) \
1117 V(bool, requires_instance_members_initializer)
1118
1120 public:
1122
1124
1125 Builtin builtin_id() const;
1126 int context_header_size() const;
1127 int context_parameters_start() const;
1128 BytecodeArrayRef GetBytecodeArray(JSHeapBroker* broker) const;
1129 bool HasBreakInfo(JSHeapBroker* broker) const;
1130 SharedFunctionInfo::Inlineability GetInlineability(
1131 JSHeapBroker* broker) const;
1132 OptionalFunctionTemplateInfoRef function_template_info(
1133 JSHeapBroker* broker) const;
1134 ScopeInfoRef scope_info(JSHeapBroker* broker) const;
1135
1136#define DECL_ACCESSOR(type, name) type name() const;
1138#undef DECL_ACCESSOR
1139
1141 return GetInlineability(broker) == SharedFunctionInfo::kIsInlineable;
1142 }
1143};
1144
1145class StringRef : public NameRef {
1146 public:
1148
1149 IndirectHandle<String> object() const;
1150
1151 // With concurrent inlining on, we return std::nullopt due to not being able
1152 // to use LookupIterator in a thread-safe way.
1153 OptionalObjectRef GetCharAsStringOrUndefined(JSHeapBroker* broker,
1154 uint32_t index) const;
1155
1156 // When concurrently accessing non-read-only non-supported strings, we return
1157 // std::nullopt for these methods.
1158 std::optional<Handle<String>> ObjectIfContentAccessible(JSHeapBroker* broker);
1159 uint32_t length() const;
1160 std::optional<uint16_t> GetFirstChar(JSHeapBroker* broker) const;
1161 std::optional<uint16_t> GetChar(JSHeapBroker* broker, uint32_t index) const;
1162 std::optional<double> ToNumber(JSHeapBroker* broker);
1163 std::optional<double> ToInt(JSHeapBroker* broker, int radix);
1164
1165 bool IsSeqString() const;
1166 bool IsExternalString() const;
1167
1168 bool IsContentAccessible() const;
1169 bool IsOneByteRepresentation() const;
1170
1171 private:
1172 // With concurrent inlining on, we currently support reading directly
1173 // internalized strings, and thin strings (which are pointers to internalized
1174 // strings).
1175 bool SupportedStringKind() const;
1176};
1177
1178class SymbolRef : public NameRef {
1179 public:
1181
1182 IndirectHandle<Symbol> object() const;
1183};
1184
1186 public:
1188
1190
1191 bool is_on_heap() const;
1192 size_t length() const;
1193 size_t byte_length() const;
1194 ElementsKind elements_kind(JSHeapBroker* broker) const;
1195 void* data_ptr() const;
1196 HeapObjectRef buffer(JSHeapBroker* broker) const;
1197};
1198
1200 public:
1202
1203 bool IsStringWrapper(JSHeapBroker* broker) const;
1204
1206};
1207
1209 public:
1211
1213
1214 OptionalCellRef GetCell(JSHeapBroker* broker, int cell_index) const;
1215 OptionalObjectRef import_meta(JSHeapBroker* broker) const;
1216};
1217
1224
1225class CellRef : public HeapObjectRef {
1226 public:
1228
1229 IndirectHandle<Cell> object() const;
1230};
1231
1233 public:
1235
1237
1238 bool IsDetachedFrom(JSGlobalProxyRef proxy) const;
1239
1240 // Can be called even when there is no property cell for the given name.
1241 OptionalPropertyCellRef GetPropertyCell(JSHeapBroker* broker,
1242 NameRef name) const;
1243};
1244
1251
1252class CodeRef : public HeapObjectRef {
1253 public:
1255
1256 IndirectHandle<Code> object() const;
1257
1258 unsigned GetInlinedBytecodeSize() const;
1259};
1260
1267
1268#undef DEFINE_REF_CONSTRUCTOR
1269
1270#define V(Name) \
1271 /* Refs should contain only one pointer. */ \
1272 static_assert(sizeof(Name##Ref) == kSystemPointerSize); \
1273 static_assert(sizeof(OptionalName##Ref) == kSystemPointerSize); \
1274 /* Refs should be trivial to copy, move and destroy. */ \
1275 static_assert(std::is_trivially_copyable_v<Name##Ref>); \
1276 static_assert(std::is_trivially_copyable_v<OptionalName##Ref>); \
1277 static_assert(std::is_trivially_destructible_v<Name##Ref>); \
1278 static_assert(std::is_trivially_destructible_v<OptionalName##Ref>);
1279
1281#undef V
1282
1283} // namespace compiler
1284
1285template <typename T>
1286struct ZoneCompactSetTraits<T, std::enable_if_t<compiler::is_ref<T>::value>> {
1289
1291 return handle.data();
1292 }
1294 return handle_type(ptr);
1295 }
1296};
1297
1298namespace compiler {
1299
1300template <typename T>
1302
1303inline bool AnyMapIsHeapNumber(const ZoneRefSet<Map>& maps) {
1304 return std::any_of(maps.begin(), maps.end(),
1305 [](MapRef map) { return map.IsHeapNumberMap(); });
1306}
1307
1309 return std::any_of(maps.begin(), maps.end(),
1310 [](MapRef map) { return map.IsHeapNumberMap(); });
1311}
1312
1313} // namespace compiler
1314
1315} // namespace internal
1316} // namespace v8
1317
1318#endif // V8_COMPILER_HEAP_REFS_H_
#define V(Name)
#define T
uint8_t data_[MAX_STACK_LENGTH]
int16_t parameter_count
Definition builtins.cc:67
union v8::internal::@341::BuiltinMetadata::KindSpecificData data
Builtins::Kind kind
Definition builtins.cc:40
IndirectHandle< ArrayBoilerplateDescription > object() const
OptionalMapRef map_direct_read(JSHeapBroker *broker) const
HeapObjectType GetHeapObjectType(JSHeapBroker *broker) const
HoleType hole_type(JSHeapBroker *broker) const
Definition heap-refs.h:496
OddballType oddball_type(JSHeapBroker *broker) const
Definition heap-refs.h:495
HeapObjectType(InstanceType instance_type, ElementsKind elements_kind, Flags flags, OddballType oddball_type, HoleType hole_type)
Definition heap-refs.h:481
IndirectHandle< JSPrimitiveWrapper > object() const
ArrowOperatorHelper operator->() const
Definition heap-refs.h:349
constexpr bool has_value() const
Definition heap-refs.h:341
V8_INLINE OptionalRef(OptionalRef< SRef > ref)
Definition heap-refs.h:330
V8_INLINE OptionalRef(SRef ref)
Definition heap-refs.h:337
bool equals(OptionalRef other) const
Definition heap-refs.h:353
PropertyDetails property_details() const
ObjectRef value(JSHeapBroker *broker) const
bool IsInlineable(JSHeapBroker *broker) const
Definition heap-refs.h:1140
JSObjectRef const holder_
LineAndColumn previous
JSHeapBroker * broker
#define DEF_TESTER(Type,...)
#define BACKGROUND_SERIALIZED_REF_TRAITS(Name)
Definition heap-refs.h:179
#define HEAP_BROKER_OBJECT_LIST_BASE(BACKGROUND_SERIALIZED, NEVER_SERIALIZED)
Definition heap-refs.h:100
#define HEAP_IS_METHOD_DECL(Name)
#define DECL_ACCESSOR(type, name)
Definition heap-refs.h:775
#define NEVER_SERIALIZED_REF_TRAITS(Name)
Definition heap-refs.h:188
#define DEFINE_IS_REF(Name)
Definition heap-refs.h:165
#define HEAP_BROKER_OBJECT_LIST(V)
Definition heap-refs.h:152
#define FORWARD_DECL(Name)
Definition heap-refs.h:157
#define HEAP_AS_METHOD_DECL(Name)
#define HEAP_BROKER_BACKGROUND_SERIALIZED_OBJECT_LIST(V)
Definition heap-refs.h:154
#define BROKER_SFI_FIELDS(V)
Definition heap-refs.h:1101
#define BROKER_NATIVE_CONTEXT_FIELDS(V)
Definition heap-refs.h:723
#define DEFINE_REF_CONSTRUCTOR(Name, Base)
Definition heap-refs.h:514
#define INSTANCE_TYPE_CHECKERS(V)
TNode< Object > callback
STL namespace.
V8_INLINE size_t hash_value(unsigned int v)
Definition hashing.h:205
template const Signature< wasm::ValueType > bool
bool operator<(const CaseInfoT &l, const CaseInfoT &r)
bool IsAnyStore(AccessMode mode)
Definition heap-refs.h:65
size_t hash_value(const BranchParameters &p)
bool operator!=(DeoptimizeParameters lhs, DeoptimizeParameters rhs)
bool operator==(const BranchParameters &lhs, const BranchParameters &rhs)
bool IsDefiningStore(AccessMode mode)
Definition heap-refs.h:70
bool AnyMapIsHeapNumber(const ZoneRefSet< Map > &maps)
Definition heap-refs.h:1303
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
Definition handles-inl.h:72
wasm::WasmModule WasmModule
V8_INLINE constexpr bool IsSmi(TaggedImpl< kRefType, StorageType > obj)
Definition objects.h:665
bool IsNullOrUndefined(Tagged< Object > obj, Isolate *isolate)
V8_INLINE constexpr bool operator<(Builtin a, Builtin b)
Definition builtins.h:75
kInstanceDescriptorsOffset kTransitionsOrPrototypeInfoOffset IsNull(value)||IsJSProxy(value)||IsWasmObject(value)||(IsJSObject(value) &&(HeapLayout
Definition map-inl.h:70
Definition c-api.cc:87
#define HOLE_LIST(V)
std::ostream & operator<<(std::ostream &os, const Operation &operation)
Definition operation.h:49
uint32_t equals
#define CHECK(condition)
Definition logging.h:124
#define CHECK_NOT_NULL(val)
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define V8_EXPORT_PRIVATE
Definition macros.h:460
HolderLookupResult(CallOptimization::HolderLookup lookup_=CallOptimization::kHolderNotFound, OptionalJSObjectRef holder_=std::nullopt)
Definition heap-refs.h:947
CallOptimization::HolderLookup lookup
Definition heap-refs.h:951
std::conditional_t< kAllJSReceiverRef, JSReceiverData, std::conditional_t< kAllHeapObjectRef, HeapObjectData, ObjectData > > data_type
Definition heap-refs.h:288
std::conditional_t< kAllJSReceiverRef, JSReceiverRef, std::conditional_t< kAllHeapObjectRef, HeapObjectRef, ObjectRef > > ref_type
Definition heap-refs.h:285
#define V8_INLINE
Definition v8config.h:500
#define V8_WARN_UNUSED_RESULT
Definition v8config.h:671