5#ifndef V8_COMPILER_JS_HEAP_BROKER_H_
6#define V8_COMPILER_JS_HEAP_BROKER_H_
39class MaglevCompilationInfo;
46std::ostream&
operator<<(std::ostream& os, ObjectRef ref);
48#define TRACE_BROKER(broker, x) \
50 if (broker->tracing_enabled() && v8_flags.trace_heap_broker_verbose) \
51 StdoutStream{} << broker->Trace() << x << '\n'; \
54#define TRACE_BROKER_MISSING(broker, x) \
56 if (broker->tracing_enabled()) \
57 StdoutStream{} << broker->Trace() << "Missing " << x << " (" << __FILE__ \
58 << ":" << __LINE__ << ")" << std::endl; \
71 static_cast<int>(pair.
mode));
111 return target_native_context_.value();
115 void InitializeAndStartSerializing(
123#if V8_COMPRESS_POINTERS
139 enum BrokerMode { kDisabled, kSerializing, kSerialized, kRetired };
142 void StopSerializing();
168 template <
typename CompilationInfoT>
170 set_canonical_handles(info->canonical_handles());
173 bool StackHasOverflowed()
const;
176 void PrintRefsAnalysis()
const;
197 bool IsArrayOrObjectPrototype(JSObjectRef
object)
const;
200 bool HasFeedback(FeedbackSource
const& source)
const;
201 void SetFeedback(FeedbackSource
const& source,
202 ProcessedFeedback
const* feedback);
205 ElementAccessFeedback
const& ProcessFeedbackMapsForElementAccess(
212 FeedbackSource
const& source);
214 FeedbackSource
const& source);
215 ForInHint GetFeedbackForForIn(FeedbackSource
const& source);
217 ProcessedFeedback
const& GetFeedbackForCall(FeedbackSource
const& source);
218 ProcessedFeedback
const& GetFeedbackForGlobalAccess(
219 FeedbackSource
const& source);
220 ProcessedFeedback
const& GetFeedbackForInstanceOf(
221 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);
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);
242 bool FeedbackIsInsufficient(FeedbackSource
const& source)
const;
246 PropertyAccessInfo GetPropertyAccessInfo(MapRef map, NameRef name,
252 return local_isolate() ==
nullptr || local_isolate()->is_main_thread();
261 return local_isolate() !=
nullptr ? local_isolate()
267 if (
object.IsJSReceiver())
return {};
269 if (root_index_map_.Lookup(*
object.object(), &root_index)) {
282 template <
typename T>
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)) {
301 auto find_result = canonical_handles_->FindOrInsert(
object);
302 if (find_result.already_exists)
return Handle<T>(*find_result.entry);
305 if (local_isolate()) {
307 local_isolate()->heap()->NewPersistentHandle(
object).location();
315 template <
typename T>
317 if (
object.is_null())
return object;
318 return CanonicalPersistentHandle<T>(*
object);
322 template <
typename T>
328 if (root_index_map_.Lookup(heap_object, &root_index)) {
333 if (
isolate()->IsBuiltinTableHandleLocation(
handle.location())) {
337 return canonical_handles_->Find(*
handle) !=
nullptr;
340 std::string
Trace()
const;
341 void IncrementTracingIndentation();
342 void DecrementTracingIndentation();
350 int* mutex_depth_address);
354 (*mutex_depth_address_)--;
355 DCHECK_EQ(initial_mutex_depth_, (*mutex_depth_address_));
385 dependencies_ = dependencies;
389 return dependencies_;
392#define V(Type, name, Name) inline typename ref_traits<Type>::ref_type name();
399 friend class ObjectRef;
425 OptionalNameRef static_name);
431 void CollectArrayAndObjectPrototypes();
434 std::unique_ptr<PersistentHandles> persistent_handles) {
436 ph_ = std::move(persistent_handles);
441 return std::move(ph_);
445 canonical_handles_ = canonical_handles;
448#define V(Type, name, Name) void Init##Name();
453#if V8_COMPRESS_POINTERS
466 std::unique_ptr<PersistentHandles>
ph_;
470 unsigned trace_indentation_ = 0;
479#define V(Type, name, Name) \
480 OptionalRef<typename ref_traits<Type>::ref_type> name##_;
492 int map_updater_mutex_depth_ = 0;
494 int boilerplate_migration_mutex_depth_ = 0;
496 static constexpr uint32_t kMinimalRefsBucketCount = 8;
498 static constexpr uint32_t kInitialRefsBucketCount = 1024;
532 broker_->IncrementTracingIndentation();
551 bool extra_condition =
true) {
552 if (
broker !=
nullptr && extra_condition) {
554 if (local_isolate !=
nullptr && local_isolate->
heap()->
IsParked()) {
555 unparked_scope.emplace(local_isolate->
heap());
573 std::unique_ptr<CanonicalHandlesMap> canonical_handles)
575 broker_->set_canonical_handles(canonical_handles_.get());
589 if (data ==
nullptr)
return {};
607 if (data ==
nullptr) {
619 if (data ==
nullptr) {
656#define V(Type, name, Name) \
657 inline typename ref_traits<Type>::ref_type JSHeapBroker::name() { \
661 return name##_.value(); \
#define DEFINE_OPERATORS_FOR_FLAGS(Type)
static NexusConfig FromMainThread(Isolate *isolate)
static NexusConfig FromBackgroundThread(Isolate *isolate, LocalHeap *local_heap)
static V8_EXPORT_PRIVATE bool IsActive(Isolate *isolate)
CurrentHeapBrokerScope(JSHeapBroker *broker)
~CurrentHeapBrokerScope()
JSHeapBrokerScopeForTesting(JSHeapBroker *broker, Isolate *isolate, Zone *zone)
~JSHeapBrokerScopeForTesting()
JSHeapBroker *const broker_
std::unique_ptr< CanonicalHandlesMap > canonical_handles_
JSHeapBrokerScopeForTesting(JSHeapBroker *broker, std::unique_ptr< CanonicalHandlesMap > canonical_handles)
int *const mutex_depth_address_
ParkedMutexGuardIf mutex_guard_
~RecursiveMutexGuardIfNeeded()
const int initial_mutex_depth_
LocalIsolate * local_isolate_or_isolate() const
PtrComprCageBase cage_base() const
Handle< T > CanonicalPersistentHandle(Tagged< T > object)
CompilationDependencies * dependencies() const
bool SerializingAllowed() const
CodeKind const code_kind_
bool IsMainThread() const
std::optional< RootIndex > FindRootIndex(HeapObjectRef object)
std::unique_ptr< PersistentHandles > ph_
void AttachCompilationInfo(CompilationInfoT *info)
bool const tracing_enabled_
ZoneUnorderedMap< FeedbackSource, ProcessedFeedback const *, FeedbackSource::Hash, FeedbackSource::Equal > feedback_
LocalIsolate * local_isolate() const
void set_persistent_handles(std::unique_ptr< PersistentHandles > persistent_handles)
ZoneUnorderedMap< PropertyAccessTarget, PropertyAccessInfo, PropertyAccessTarget::Hash, PropertyAccessTarget::Equal > property_access_infos_
bool tracing_enabled() const
Handle< T > CanonicalPersistentHandle(Handle< T > object)
NativeContextRef target_native_context() const
void set_dependencies(CompilationDependencies *dependencies)
RootIndexMap root_index_map_
ObjectData * TryGetOrCreateData(Handle< Object > object, GetOrCreateDataFlags flags={})
Isolate * isolate() const
CanonicalHandlesMap * canonical_handles_
OptionalNativeContextRef target_native_context_
ZoneUnorderedSet< IndirectHandle< JSObject >, IndirectHandle< JSObject >::hash, IndirectHandle< JSObject >::equal_to > array_and_object_prototypes_
NexusConfig feedback_nexus_config() const
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
JSHeapBroker *const broker_
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
RecordWriteMode const mode_
JSHeapBroker *const broker_
#define TRACE_BROKER_MISSING(broker, x)
#define TRACE_BROKER(broker, x)
LocalIsolate * local_isolate_
constexpr bool IsPowerOfTwo(T value)
V8_INLINE size_t hash_combine(size_t seed, size_t hash)
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)
bool TryCast(Tagged< From > value, Tagged< To > *out)
static constexpr bool is_subtype_v
Handle< T > IndirectHandle
V8_EXPORT_PRIVATE FlagValues v8_flags
!IsContextMap !IsContextMap native_context
#define READ_ONLY_ROOT_LIST(V)
#define DCHECK_NOT_NULL(val)
#define DCHECK_GE(v1, v2)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define V8_EXPORT_PRIVATE
bool operator()(const PropertyAccessTarget &lhs, const PropertyAccessTarget &rhs) const
size_t operator()(const PropertyAccessTarget &pair) const