v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
js-heap-broker.h
Go to the documentation of this file.
1// Copyright 2018 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_JS_HEAP_BROKER_H_
6#define V8_COMPILER_JS_HEAP_BROKER_H_
7
8#include <optional>
9
11#include "src/base/macros.h"
14#include "src/common/globals.h"
21#include "src/handles/handles.h"
23#include "src/heap/local-heap.h"
27#include "src/objects/objects.h"
28#include "src/objects/tagged.h"
29#include "src/roots/roots.h"
32#include "src/utils/ostreams.h"
34
35namespace v8 {
36namespace internal {
37
38namespace maglev {
39class MaglevCompilationInfo;
40}
41
42namespace compiler {
43
44class ObjectRef;
45
46std::ostream& operator<<(std::ostream& os, ObjectRef ref);
47
48#define TRACE_BROKER(broker, x) \
49 do { \
50 if (broker->tracing_enabled() && v8_flags.trace_heap_broker_verbose) \
51 StdoutStream{} << broker->Trace() << x << '\n'; \
52 } while (false)
53
54#define TRACE_BROKER_MISSING(broker, x) \
55 do { \
56 if (broker->tracing_enabled()) \
57 StdoutStream{} << broker->Trace() << "Missing " << x << " (" << __FILE__ \
58 << ":" << __LINE__ << ")" << std::endl; \
59 } while (false)
60
65
66 struct Hash {
67 size_t operator()(const PropertyAccessTarget& pair) const {
68 return base::hash_combine(
69 base::hash_combine(pair.map.object().address(),
70 pair.name.object().address()),
71 static_cast<int>(pair.mode));
72 }
73 };
74 struct Equal {
76 const PropertyAccessTarget& rhs) const {
77 return lhs.map.equals(rhs.map) && lhs.name.equals(rhs.name) &&
78 lhs.mode == rhs.mode;
79 }
80 };
81};
82
84 // If set, a failure to create the data object results in a crash.
85 kCrashOnError = 1 << 0,
86 // If set, data construction assumes that the given object is protected by
87 // a memory fence (e.g. acquire-release) and thus fields required for
88 // construction (like Object::map) are safe to read. The protection can
89 // extend to some other situations as well.
91};
94
96 public:
97 JSHeapBroker(Isolate* isolate, Zone* broker_zone, bool tracing_enabled,
98 CodeKind code_kind);
99
100 // For use only in tests, sets default values for some arguments. Avoids
101 // churn when new flags are added.
102 JSHeapBroker(Isolate* isolate, Zone* broker_zone)
103 : JSHeapBroker(isolate, broker_zone, v8_flags.trace_heap_broker,
104 CodeKind::TURBOFAN_JS) {}
105
107
108 // The compilation target's native context. We need the setter because at
109 // broker construction time we don't yet have the canonical handle.
111 return target_native_context_.value();
112 }
113 void SetTargetNativeContextRef(DirectHandle<NativeContext> native_context);
114
115 void InitializeAndStartSerializing(
117
118 Isolate* isolate() const { return isolate_; }
119
120 // The pointer compression cage base value used for decompression of all
121 // tagged values except references to InstructionStream objects.
123#if V8_COMPRESS_POINTERS
124 return cage_base_;
125#else
126 return PtrComprCageBase{};
127#endif // V8_COMPRESS_POINTERS
128 }
129
130 Zone* zone() const { return zone_; }
131 bool tracing_enabled() const { return tracing_enabled_; }
132
134 return IsMainThread() ? NexusConfig::FromMainThread(isolate())
136 isolate(), local_isolate()->heap());
137 }
138
139 enum BrokerMode { kDisabled, kSerializing, kSerialized, kRetired };
140 BrokerMode mode() const { return mode_; }
141
142 void StopSerializing();
143 void Retire();
144 bool SerializingAllowed() const;
145
146#ifdef DEBUG
147 // Get the current heap broker for this thread. Only to be used for DCHECKs.
148 static JSHeapBroker* Current();
149#endif
150
151 // Remember the local isolate and initialize its local heap with the
152 // persistent and canonical handles provided by {info}.
153 void AttachLocalIsolate(OptimizedCompilationInfo* info,
154 LocalIsolate* local_isolate);
155 // Forget about the local isolate and pass the persistent and canonical
156 // handles provided back to {info}. {info} is responsible for disposing of
157 // them.
158 void DetachLocalIsolate(OptimizedCompilationInfo* info);
159
160 // TODO(v8:7700): Refactor this once the broker is no longer
161 // Turbofan-specific.
162 void AttachLocalIsolateForMaglev(maglev::MaglevCompilationInfo* info,
163 LocalIsolate* local_isolate);
164 void DetachLocalIsolateForMaglev(maglev::MaglevCompilationInfo* info);
165
166 // Attaches the canonical handles map from the compilation info to the broker.
167 // Ownership of the map remains in the compilation info.
168 template <typename CompilationInfoT>
169 void AttachCompilationInfo(CompilationInfoT* info) {
170 set_canonical_handles(info->canonical_handles());
171 }
172
173 bool StackHasOverflowed() const;
174
175#ifdef DEBUG
176 void PrintRefsAnalysis() const;
177#endif // DEBUG
178
179 // Returns the handle from root index table for read only heap objects.
181
182 // Never returns nullptr.
183 ObjectData* GetOrCreateData(Handle<Object> object,
184 GetOrCreateDataFlags flags = {});
185 ObjectData* GetOrCreateData(Tagged<Object> object,
186 GetOrCreateDataFlags flags = {});
187
188 // Gets data only if we have it. However, thin wrappers will be created for
189 // smis, read-only objects and never-serialized objects.
191 GetOrCreateDataFlags flags = {});
192 ObjectData* TryGetOrCreateData(Tagged<Object> object,
193 GetOrCreateDataFlags flags = {});
194
195 // Check if {object} is any native context's %ArrayPrototype% or
196 // %ObjectPrototype%.
197 bool IsArrayOrObjectPrototype(JSObjectRef object) const;
198 bool IsArrayOrObjectPrototype(Handle<JSObject> object) const;
199
200 bool HasFeedback(FeedbackSource const& source) const;
201 void SetFeedback(FeedbackSource const& source,
202 ProcessedFeedback const* feedback);
203 FeedbackSlotKind GetFeedbackSlotKind(FeedbackSource const& source) const;
204
205 ElementAccessFeedback const& ProcessFeedbackMapsForElementAccess(
206 ZoneVector<MapRef>& maps, KeyedAccessMode const& keyed_mode,
207 FeedbackSlotKind slot_kind);
208
209 // Binary, comparison and for-in hints can be fully expressed via
210 // an enum. Insufficient feedback is signaled by <Hint enum>::kNone.
211 BinaryOperationHint GetFeedbackForBinaryOperation(
212 FeedbackSource const& source);
213 CompareOperationHint GetFeedbackForCompareOperation(
214 FeedbackSource const& source);
215 ForInHint GetFeedbackForForIn(FeedbackSource const& source);
216
217 ProcessedFeedback const& GetFeedbackForCall(FeedbackSource const& source);
218 ProcessedFeedback const& GetFeedbackForGlobalAccess(
219 FeedbackSource const& source);
220 ProcessedFeedback const& GetFeedbackForInstanceOf(
221 FeedbackSource const& source);
222 TypeOfFeedback::Result GetFeedbackForTypeOf(FeedbackSource const& source);
223 ProcessedFeedback const& GetFeedbackForArrayOrObjectLiteral(
224 FeedbackSource const& source);
225 ProcessedFeedback const& GetFeedbackForRegExpLiteral(
226 FeedbackSource const& source);
227 ProcessedFeedback const& GetFeedbackForTemplateObject(
228 FeedbackSource const& source);
229 ProcessedFeedback const& GetFeedbackForPropertyAccess(
230 FeedbackSource const& source, AccessMode mode,
231 OptionalNameRef static_name);
232
233 ProcessedFeedback const& ProcessFeedbackForBinaryOperation(
234 FeedbackSource const& source);
235 ProcessedFeedback const& ProcessFeedbackForCompareOperation(
236 FeedbackSource const& source);
237 ProcessedFeedback const& ProcessFeedbackForForIn(
238 FeedbackSource const& source);
239 ProcessedFeedback const& ProcessFeedbackForTypeOf(
240 FeedbackSource const& source);
241
242 bool FeedbackIsInsufficient(FeedbackSource const& source) const;
243
244 OptionalNameRef GetNameFeedback(FeedbackNexus const& nexus);
245
246 PropertyAccessInfo GetPropertyAccessInfo(MapRef map, NameRef name,
247 AccessMode access_mode);
248
249 StringRef GetTypedArrayStringTag(ElementsKind kind);
250
251 bool IsMainThread() const {
252 return local_isolate() == nullptr || local_isolate()->is_main_thread();
253 }
254
256
257 // TODO(jgruber): Consider always having local_isolate_ set to a real value.
258 // This seems not entirely trivial since we currently reset local_isolate_ to
259 // nullptr at some point in the JSHeapBroker lifecycle.
261 return local_isolate() != nullptr ? local_isolate()
262 : isolate()->AsLocalIsolate();
263 }
264
265 std::optional<RootIndex> FindRootIndex(HeapObjectRef object) {
266 // No root constant is a JSReceiver.
267 if (object.IsJSReceiver()) return {};
268 RootIndex root_index;
269 if (root_index_map_.Lookup(*object.object(), &root_index)) {
270 return root_index;
271 }
272 return {};
273 }
274
275 // Return the corresponding canonical persistent handle for {object}. Create
276 // one if it does not exist.
277 // If a local isolate is attached, we can create the persistent handle through
278 // it. This commonly happens during the Execute phase.
279 // If we don't, that means we are calling this method from serialization. If
280 // that happens, we should be inside a persistent handle scope. Then, we would
281 // just use the regular handle creation.
282 template <typename T>
284 DCHECK_NOT_NULL(canonical_handles_);
285 if (Tagged<HeapObject> heap_object;
286 TryCast<HeapObject>(object, &heap_object)) {
287 RootIndex root_index;
288 // CollectArrayAndObjectPrototypes calls this function often with T equal
289 // to JSObject. The root index map only contains immortal, immutable
290 // objects; it never contains any instances of type JSObject, since
291 // JSObjects must exist within a NativeContext, and NativeContexts can be
292 // created and destroyed. Thus, we can skip the lookup in the root index
293 // map for those values and save a little time.
294 if constexpr (std::is_convertible_v<T, JSObject>) {
295 DCHECK(!root_index_map_.Lookup(heap_object, &root_index));
296 } else if (root_index_map_.Lookup(heap_object, &root_index)) {
297 return Handle<T>(isolate_->root_handle(root_index).location());
298 }
299 }
300
301 auto find_result = canonical_handles_->FindOrInsert(object);
302 if (find_result.already_exists) return Handle<T>(*find_result.entry);
303
304 // Allocate new PersistentHandle if one wasn't created before.
305 if (local_isolate()) {
306 *find_result.entry =
307 local_isolate()->heap()->NewPersistentHandle(object).location();
308 } else {
310 *find_result.entry = IndirectHandle<T>(object, isolate()).location();
311 }
312 return Handle<T>(*find_result.entry);
313 }
314
315 template <typename T>
317 if (object.is_null()) return object; // Can't deref a null handle.
318 return CanonicalPersistentHandle<T>(*object);
319 }
320
321 // Checks if a canonical persistent handle for {object} exists.
322 template <typename T>
324 DCHECK_NOT_NULL(canonical_handles_);
325 if (Tagged<HeapObject> heap_object;
326 TryCast<HeapObject>(*handle, &heap_object)) {
327 RootIndex root_index;
328 if (root_index_map_.Lookup(heap_object, &root_index)) {
329 return true;
330 }
331 // Builtins use pseudo handles that are canonical and persistent by
332 // design.
333 if (isolate()->IsBuiltinTableHandleLocation(handle.location())) {
334 return true;
335 }
336 }
337 return canonical_handles_->Find(*handle) != nullptr;
338 }
339
340 std::string Trace() const;
341 void IncrementTracingIndentation();
342 void DecrementTracingIndentation();
343
344 // Locks {mutex} through the duration of this scope iff it is the first
345 // occurrence. This is done to have a recursive shared lock on {mutex}.
347 protected:
350 int* mutex_depth_address);
351
353 DCHECK_GE((*mutex_depth_address_), 1);
354 (*mutex_depth_address_)--;
355 DCHECK_EQ(initial_mutex_depth_, (*mutex_depth_address_));
356 }
357
358 private:
362 };
363
368
374
375 // If this returns false, the object is guaranteed to be fully initialized and
376 // thus safe to read from a memory safety perspective. The converse does not
377 // necessarily hold.
378 bool ObjectMayBeUninitialized(DirectHandle<Object> object) const;
379 bool ObjectMayBeUninitialized(Tagged<Object> object) const;
380 bool ObjectMayBeUninitialized(Tagged<HeapObject> object) const;
381
383 DCHECK_NOT_NULL(dependencies);
384 DCHECK_NULL(dependencies_);
385 dependencies_ = dependencies;
386 }
388 DCHECK_NOT_NULL(dependencies_);
389 return dependencies_;
390 }
391
392#define V(Type, name, Name) inline typename ref_traits<Type>::ref_type name();
394#undef V
395
396 private:
398 friend class HeapObjectRef;
399 friend class ObjectRef;
400 friend class ObjectData;
401 friend class PropertyCellData;
402
403 ProcessedFeedback const& GetFeedback(FeedbackSource const& source) const;
404 const ProcessedFeedback& NewInsufficientFeedback(FeedbackSlotKind kind) const;
405
406 // Bottleneck FeedbackNexus access here, for storage in the broker
407 // or on-the-fly usage elsewhere in the compiler.
408 ProcessedFeedback const& ReadFeedbackForArrayOrObjectLiteral(
409 FeedbackSource const& source);
410 ProcessedFeedback const& ReadFeedbackForBinaryOperation(
411 FeedbackSource const& source) const;
412 ProcessedFeedback const& ReadFeedbackForTypeOf(
413 FeedbackSource const& source) const;
414 ProcessedFeedback const& ReadFeedbackForCall(FeedbackSource const& source);
415 ProcessedFeedback const& ReadFeedbackForCompareOperation(
416 FeedbackSource const& source) const;
417 ProcessedFeedback const& ReadFeedbackForForIn(
418 FeedbackSource const& source) const;
419 ProcessedFeedback const& ReadFeedbackForGlobalAccess(
420 JSHeapBroker* broker, FeedbackSource const& source);
421 ProcessedFeedback const& ReadFeedbackForInstanceOf(
422 FeedbackSource const& source);
423 ProcessedFeedback const& ReadFeedbackForPropertyAccess(
424 FeedbackSource const& source, AccessMode mode,
425 OptionalNameRef static_name);
426 ProcessedFeedback const& ReadFeedbackForRegExpLiteral(
427 FeedbackSource const& source);
428 ProcessedFeedback const& ReadFeedbackForTemplateObject(
429 FeedbackSource const& source);
430
431 void CollectArrayAndObjectPrototypes();
432
434 std::unique_ptr<PersistentHandles> persistent_handles) {
435 DCHECK_NULL(ph_);
436 ph_ = std::move(persistent_handles);
437 DCHECK_NOT_NULL(ph_);
438 }
439 std::unique_ptr<PersistentHandles> DetachPersistentHandles() {
440 DCHECK_NOT_NULL(ph_);
441 return std::move(ph_);
442 }
443
445 canonical_handles_ = canonical_handles;
446 }
447
448#define V(Type, name, Name) void Init##Name();
450#undef V
451
453#if V8_COMPRESS_POINTERS
454 const PtrComprCageBase cage_base_;
455#endif // V8_COMPRESS_POINTERS
456 Zone* const zone_;
457 OptionalNativeContextRef target_native_context_;
463 BrokerMode mode_ = kDisabled;
466 std::unique_ptr<PersistentHandles> ph_;
468 // The CanonicalHandlesMap is owned by the compilation info.
470 unsigned trace_indentation_ = 0;
477
478 // Cache read only roots to avoid needing to look them up via the map.
479#define V(Type, name, Name) \
480 OptionalRef<typename ref_traits<Type>::ref_type> name##_;
482#undef V
483
484 CompilationDependencies* dependencies_ = nullptr;
485
486 // The MapUpdater mutex is used in recursive patterns; for example,
487 // ComputePropertyAccessInfo may call itself recursively. Thus we need to
488 // emulate a recursive mutex, which we do by checking if this heap broker
489 // instance already holds the mutex when a lock is requested. This field
490 // holds the locking depth, i.e. how many times the mutex has been
491 // recursively locked. Only the outermost locker actually locks underneath.
492 int map_updater_mutex_depth_ = 0;
493 // Likewise for boilerplate migrations.
494 int boilerplate_migration_mutex_depth_ = 0;
495
496 static constexpr uint32_t kMinimalRefsBucketCount = 8;
497 static_assert(base::bits::IsPowerOfTwo(kMinimalRefsBucketCount));
498 static constexpr uint32_t kInitialRefsBucketCount = 1024;
499 static_assert(base::bits::IsPowerOfTwo(kInitialRefsBucketCount));
500};
501
502#ifdef DEBUG
503// In debug builds, store the current heap broker on a thread local, for
504// DCHECKs to access it via JSHeapBroker::Current();
506 public:
509
510 private:
511 JSHeapBroker* const prev_broker_;
512};
513#else
519#endif
520
522 public:
524 : TraceScope(broker, static_cast<void*>(broker), label) {}
525
527 : TraceScope(broker, static_cast<void*>(data), label) {}
528
529 TraceScope(JSHeapBroker* broker, void* subject, const char* label)
530 : broker_(broker) {
531 TRACE_BROKER(broker_, "Running " << label << " on " << subject);
532 broker_->IncrementTracingIndentation();
533 }
534
535 ~TraceScope() { broker_->DecrementTracingIndentation(); }
536
537 private:
539};
540
541// Scope that unparks the LocalHeap, if:
542// a) We have a JSHeapBroker,
543// b) Said JSHeapBroker has a LocalIsolate and thus a LocalHeap,
544// c) Said LocalHeap has been parked and
545// d) The given condition evaluates to true.
546// Used, for example, when printing the graph with --trace-turbo with a
547// previously parked LocalHeap.
549 public:
551 bool extra_condition = true) {
552 if (broker != nullptr && extra_condition) {
553 LocalIsolate* local_isolate = broker->local_isolate();
554 if (local_isolate != nullptr && local_isolate->heap()->IsParked()) {
555 unparked_scope.emplace(local_isolate->heap());
556 }
557 }
558 }
559
560 private:
561 std::optional<UnparkedScope> unparked_scope;
562};
563
565 public:
573 std::unique_ptr<CanonicalHandlesMap> canonical_handles)
574 : canonical_handles_(std::move(canonical_handles)), broker_(broker) {
575 broker_->set_canonical_handles(canonical_handles_.get());
576 }
577 ~JSHeapBrokerScopeForTesting() { broker_->set_canonical_handles(nullptr); }
578
579 private:
580 std::unique_ptr<CanonicalHandlesMap> canonical_handles_;
582};
583
584template <class T>
586 ObjectData* data)
588{
589 if (data == nullptr) return {};
590 return {typename ref_traits<T>::ref_type(data)};
591}
592
593// Usage:
594//
595// OptionalFooRef ref = TryMakeRef(broker, o);
596// if (!ref.has_value()) return {}; // bailout
597//
598// or
599//
600// FooRef ref = MakeRef(broker, o);
601template <class T>
605{
606 ObjectData* data = broker->TryGetOrCreateData(object, flags);
607 if (data == nullptr) {
608 TRACE_BROKER_MISSING(broker, "ObjectData for " << Brief(object));
609 }
610 return TryMakeRef<T>(broker, data);
611}
612
613template <class T>
617{
618 ObjectData* data = broker->TryGetOrCreateData(object, flags);
619 if (data == nullptr) {
620 DCHECK_EQ(flags & kCrashOnError, 0);
621 TRACE_BROKER_MISSING(broker, "ObjectData for " << Brief(*object));
622 }
623 return TryMakeRef<T>(broker, data);
624}
625
626template <class T>
629{
630 return TryMakeRef(broker, object, kCrashOnError).value();
631}
632
633template <class T>
636{
637 return TryMakeRef(broker, object, kCrashOnError).value();
638}
639
640template <class T>
647
648template <class T>
655
656#define V(Type, name, Name) \
657 inline typename ref_traits<Type>::ref_type JSHeapBroker::name() { \
658 if (!name##_) { \
659 Init##Name(); \
660 } \
661 return name##_.value(); \
662 }
664#undef V
665
666} // namespace compiler
667} // namespace internal
668} // namespace v8
669
670#endif // V8_COMPILER_JS_HEAP_BROKER_H_
Isolate * isolate_
#define DEFINE_OPERATORS_FOR_FLAGS(Type)
Definition flags.h:100
Builtins::Kind kind
Definition builtins.cc:40
static NexusConfig FromMainThread(Isolate *isolate)
static NexusConfig FromBackgroundThread(Isolate *isolate, LocalHeap *local_heap)
static V8_EXPORT_PRIVATE bool IsActive(Isolate *isolate)
JSHeapBrokerScopeForTesting(JSHeapBroker *broker, Isolate *isolate, Zone *zone)
std::unique_ptr< CanonicalHandlesMap > canonical_handles_
JSHeapBrokerScopeForTesting(JSHeapBroker *broker, std::unique_ptr< CanonicalHandlesMap > canonical_handles)
LocalIsolate * local_isolate_or_isolate() const
PtrComprCageBase cage_base() const
Handle< T > CanonicalPersistentHandle(Tagged< T > object)
CompilationDependencies * dependencies() const
std::optional< RootIndex > FindRootIndex(HeapObjectRef object)
std::unique_ptr< PersistentHandles > ph_
void AttachCompilationInfo(CompilationInfoT *info)
ZoneUnorderedMap< FeedbackSource, ProcessedFeedback const *, FeedbackSource::Hash, FeedbackSource::Equal > feedback_
void set_persistent_handles(std::unique_ptr< PersistentHandles > persistent_handles)
ZoneUnorderedMap< PropertyAccessTarget, PropertyAccessInfo, PropertyAccessTarget::Hash, PropertyAccessTarget::Equal > property_access_infos_
Handle< T > CanonicalPersistentHandle(Handle< T > object)
NativeContextRef target_native_context() const
void set_dependencies(CompilationDependencies *dependencies)
ObjectData * TryGetOrCreateData(Handle< Object > object, GetOrCreateDataFlags flags={})
CanonicalHandlesMap * canonical_handles_
OptionalNativeContextRef target_native_context_
ZoneUnorderedSet< IndirectHandle< JSObject >, IndirectHandle< JSObject >::hash, IndirectHandle< JSObject >::equal_to > array_and_object_prototypes_
JSHeapBroker(Isolate *isolate, Zone *broker_zone)
bool IsCanonicalHandle(Handle< T > handle)
void set_canonical_handles(CanonicalHandlesMap *canonical_handles)
DirectHandle< Object > GetRootHandle(Tagged< Object > object)
std::unique_ptr< PersistentHandles > DetachPersistentHandles()
IndirectHandle< Map > object() const
IndirectHandle< Name > object() const
TraceScope(JSHeapBroker *broker, void *subject, const char *label)
TraceScope(JSHeapBroker *broker, const char *label)
TraceScope(JSHeapBroker *broker, ObjectData *data, const char *label)
UnparkedScopeIfNeeded(JSHeapBroker *broker, bool extra_condition=true)
std::optional< UnparkedScope > unparked_scope
Zone * zone_
RecordWriteMode const mode_
JSHeapBroker *const broker_
Label label
Isolate * isolate
JSHeapBroker * broker
#define TRACE_BROKER_MISSING(broker, x)
#define TRACE_BROKER(broker, x)
LocalIsolate * local_isolate_
base::Mutex mutex
STL namespace.
constexpr bool IsPowerOfTwo(T value)
Definition bits.h:187
V8_INLINE size_t hash_combine(size_t seed, size_t hash)
Definition hashing.h:77
ref_traits< T >::ref_type MakeRefAssumeMemoryFence(JSHeapBroker *broker, Tagged< T > object)
OptionalRef< typename ref_traits< T >::ref_type > TryMakeRef(JSHeapBroker *broker, ObjectData *data)
std::ostream & operator<<(std::ostream &os, AccessMode access_mode)
ref_traits< T >::ref_type MakeRef(JSHeapBroker *broker, Tagged< T > object)
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
Definition handles-inl.h:72
bool TryCast(Tagged< From > value, Tagged< To > *out)
Definition casting.h:77
static constexpr bool is_subtype_v
Definition tagged.h:121
Handle< T > IndirectHandle
Definition globals.h:1086
V8_EXPORT_PRIVATE FlagValues v8_flags
!IsContextMap !IsContextMap native_context
Definition map-inl.h:877
#define READ_ONLY_ROOT_LIST(V)
Definition roots.h:468
#define DCHECK_NULL(val)
Definition logging.h:491
#define DCHECK_NOT_NULL(val)
Definition logging.h:492
#define DCHECK_GE(v1, v2)
Definition logging.h:488
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define V8_EXPORT_PRIVATE
Definition macros.h:460
bool operator()(const PropertyAccessTarget &lhs, const PropertyAccessTarget &rhs) const
size_t operator()(const PropertyAccessTarget &pair) const
#define V8_INLINE
Definition v8config.h:500
#define V8_NODISCARD
Definition v8config.h:693