Commit 82516af9 authored by Mythri A's avatar Mythri A Committed by Commit Bot

Reland^2 "[TurboFan] Don't serialize read-only heap objects"

Reland after disabling flaky test-cpu-profiler tests

Reland the cl with fixes to TSAN failures.

This reverts commit 03c9de73.

Original change's description:
> Revert "[TurboFan] Don't serialize read-only heap objects"
>
> This reverts commit 9f18e55f.
>
> Reason for revert: https://ci.chromium.org/p/v8/builders/ci/V8%20Linux64%20TSAN/29660
>
> Original change's description:
> > [TurboFan] Don't serialize read-only heap objects
> >
> > Read-only heap objects are immutable and immovable. It is safe to access
> > these objects directly from the heap. Not having to serialize them
> > reduces the time we spend on main thread especially for TurboProp.
> >
> > Bug: v8:9684
> > Change-Id: Ibabb7076af50c9007d2a8ed57fe257406958fb6a
> > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1955596
> > Reviewed-by: Michael Stanton <mvstanton@chromium.org>
> > Reviewed-by: Maya Lekova <mslekova@chromium.org>
> > Commit-Queue: Mythri Alle <mythria@chromium.org>
> > Cr-Commit-Position: refs/heads/master@{#65490}
>
> TBR=mvstanton@chromium.org,neis@chromium.org,mythria@chromium.org,mslekova@chromium.org
>
> Change-Id: If2d8649cdc083f7d064684352501320a96a1ba2c
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: v8:9684
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1973732
> Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
> Commit-Queue: Nico Hartmann <nicohartmann@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#65492}

TBR=mvstanton@chromium.org,neis@chromium.org,mythria@chromium.org,mslekova@chromium.org,nicohartmann@chromium.org


Bug: v8:9684
Change-Id: I71fb438b9387f7fef8b36629bb947335065474f0
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1980573Reviewed-by: 's avatarMythri Alle <mythria@chromium.org>
Reviewed-by: 's avatarMichael Stanton <mvstanton@chromium.org>
Commit-Queue: Mythri Alle <mythria@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#65584}
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1981163Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65631}
parent 50a80c93
...@@ -60,7 +60,63 @@ HEAP_BROKER_OBJECT_LIST(FORWARD_DECL) ...@@ -60,7 +60,63 @@ HEAP_BROKER_OBJECT_LIST(FORWARD_DECL)
// data is an instance of the base class (ObjectData), i.e. it basically // data is an instance of the base class (ObjectData), i.e. it basically
// carries no information other than the handle. // carries no information other than the handle.
// //
enum ObjectDataKind { kSmi, kSerializedHeapObject, kUnserializedHeapObject }; // kUnserializedReadOnlyHeapObject: The underlying V8 object is a read-only
// HeapObject and the data is an instance of ObjectData. For
// ReadOnlyHeapObjects, it is OK to access heap even from off-thread, so
// these objects need not be serialized.
enum ObjectDataKind {
kSmi,
kSerializedHeapObject,
kUnserializedHeapObject,
kUnserializedReadOnlyHeapObject
};
class AllowHandleAllocationIf {
public:
explicit AllowHandleAllocationIf(ObjectDataKind kind,
JSHeapBroker::BrokerMode mode) {
DCHECK_IMPLIES(mode == JSHeapBroker::BrokerMode::kSerialized,
kind == kUnserializedReadOnlyHeapObject);
if (kind == kUnserializedHeapObject) maybe_allow_handle_.emplace();
}
private:
base::Optional<AllowHandleAllocation> maybe_allow_handle_;
};
class AllowHandleDereferenceIf {
public:
explicit AllowHandleDereferenceIf(ObjectDataKind kind,
JSHeapBroker::BrokerMode mode) {
DCHECK_IMPLIES(mode == JSHeapBroker::BrokerMode::kSerialized,
kind == kUnserializedReadOnlyHeapObject);
if (kind == kUnserializedHeapObject ||
kind == kUnserializedReadOnlyHeapObject)
maybe_allow_handle_.emplace();
}
explicit AllowHandleDereferenceIf(ObjectDataKind kind) {
if (kind == kUnserializedHeapObject ||
kind == kUnserializedReadOnlyHeapObject)
maybe_allow_handle_.emplace();
}
private:
base::Optional<AllowHandleDereference> maybe_allow_handle_;
};
class AllowHeapAllocationIf {
public:
explicit AllowHeapAllocationIf(ObjectDataKind kind,
JSHeapBroker::BrokerMode mode) {
DCHECK_IMPLIES(mode == JSHeapBroker::BrokerMode::kSerialized,
kind == kUnserializedReadOnlyHeapObject);
if (kind == kUnserializedHeapObject) maybe_allow_handle_.emplace();
}
private:
base::Optional<AllowHeapAllocation> maybe_allow_handle_;
};
class ObjectData : public ZoneObject { class ObjectData : public ZoneObject {
public: public:
...@@ -74,7 +130,20 @@ class ObjectData : public ZoneObject { ...@@ -74,7 +130,20 @@ class ObjectData : public ZoneObject {
TRACE(broker, "Creating data " << this << " for handle " << object.address() TRACE(broker, "Creating data " << this << " for handle " << object.address()
<< " (" << Brief(*object) << ")"); << " (" << Brief(*object) << ")");
CHECK_NOT_NULL(broker->isolate()->handle_scope_data()->canonical_scope); // It is safe to access read only heap objects and builtins from a
// background thread. When we read fileds of these objects, we may create
// ObjectData on the background thread even without a canonical handle
// scope. This is safe too since we don't create handles but just get
// handles from read only root table or builtins table which is what
// canonical scope uses as well. For all other objects we should have
// created ObjectData in canonical handle scope on the main thread.
CHECK_IMPLIES(
broker->mode() == JSHeapBroker::kDisabled ||
broker->mode() == JSHeapBroker::kSerializing,
broker->isolate()->handle_scope_data()->canonical_scope != nullptr);
CHECK_IMPLIES(broker->mode() == JSHeapBroker::kSerialized,
(broker->is_builtin_code(*object) ||
ReadOnlyHeap::Contains(HeapObject::cast(*object))));
} }
#define DECLARE_IS_AND_AS(Name) \ #define DECLARE_IS_AND_AS(Name) \
...@@ -86,6 +155,10 @@ class ObjectData : public ZoneObject { ...@@ -86,6 +155,10 @@ class ObjectData : public ZoneObject {
Handle<Object> object() const { return object_; } Handle<Object> object() const { return object_; }
ObjectDataKind kind() const { return kind_; } ObjectDataKind kind() const { return kind_; }
bool is_smi() const { return kind_ == kSmi; } bool is_smi() const { return kind_ == kSmi; }
bool should_access_heap() const {
return kind_ == kUnserializedHeapObject ||
kind_ == kUnserializedReadOnlyHeapObject;
}
#ifdef DEBUG #ifdef DEBUG
enum class Usage{kUnused, kOnlyIdentityUsed, kDataUsed}; enum class Usage{kUnused, kOnlyIdentityUsed, kDataUsed};
...@@ -103,14 +176,15 @@ class HeapObjectData : public ObjectData { ...@@ -103,14 +176,15 @@ class HeapObjectData : public ObjectData {
Handle<HeapObject> object); Handle<HeapObject> object);
bool boolean_value() const { return boolean_value_; } bool boolean_value() const { return boolean_value_; }
MapData* map() const { return map_; } ObjectData* map() const { return map_; }
InstanceType GetMapInstanceType() const;
static HeapObjectData* Serialize(JSHeapBroker* broker, static HeapObjectData* Serialize(JSHeapBroker* broker,
Handle<HeapObject> object); Handle<HeapObject> object);
private: private:
bool const boolean_value_; bool const boolean_value_;
MapData* const map_; ObjectData* const map_;
}; };
class PropertyCellData : public HeapObjectData { class PropertyCellData : public HeapObjectData {
...@@ -272,11 +346,12 @@ class JSObjectData : public JSReceiverData { ...@@ -272,11 +346,12 @@ class JSObjectData : public JSReceiverData {
// Shallow serialization of {elements}. // Shallow serialization of {elements}.
void SerializeElements(JSHeapBroker* broker); void SerializeElements(JSHeapBroker* broker);
bool serialized_elements() const { return serialized_elements_; } bool serialized_elements() const { return serialized_elements_; }
FixedArrayBaseData* elements() const; ObjectData* elements() const;
void SerializeObjectCreateMap(JSHeapBroker* broker); void SerializeObjectCreateMap(JSHeapBroker* broker);
MapData* object_create_map(JSHeapBroker* broker) const { // Can be nullptr. ObjectData* object_create_map(
JSHeapBroker* broker) const { // Can be nullptr.
if (!serialized_object_create_map_) { if (!serialized_object_create_map_) {
DCHECK_NULL(object_create_map_); DCHECK_NULL(object_create_map_);
TRACE_MISSING(broker, "object_create_map on " << this); TRACE_MISSING(broker, "object_create_map on " << this);
...@@ -298,7 +373,7 @@ class JSObjectData : public JSReceiverData { ...@@ -298,7 +373,7 @@ class JSObjectData : public JSReceiverData {
private: private:
void SerializeRecursiveAsBoilerplate(JSHeapBroker* broker, int max_depths); void SerializeRecursiveAsBoilerplate(JSHeapBroker* broker, int max_depths);
FixedArrayBaseData* elements_ = nullptr; ObjectData* elements_ = nullptr;
bool cow_or_empty_elements_tenured_ = false; bool cow_or_empty_elements_tenured_ = false;
// The {serialized_as_boilerplate} flag is set when all recursively // The {serialized_as_boilerplate} flag is set when all recursively
// reachable JSObjects are serialized. // reachable JSObjects are serialized.
...@@ -308,7 +383,7 @@ class JSObjectData : public JSReceiverData { ...@@ -308,7 +383,7 @@ class JSObjectData : public JSReceiverData {
ZoneVector<JSObjectField> inobject_fields_; ZoneVector<JSObjectField> inobject_fields_;
bool serialized_object_create_map_ = false; bool serialized_object_create_map_ = false;
MapData* object_create_map_ = nullptr; ObjectData* object_create_map_ = nullptr;
// Elements (indexed properties) that either // Elements (indexed properties) that either
// (1) are known to exist directly on the object as non-writable and // (1) are known to exist directly on the object as non-writable and
...@@ -340,7 +415,7 @@ void JSObjectData::SerializeObjectCreateMap(JSHeapBroker* broker) { ...@@ -340,7 +415,7 @@ void JSObjectData::SerializeObjectCreateMap(JSHeapBroker* broker) {
if (proto_info->HasObjectCreateMap()) { if (proto_info->HasObjectCreateMap()) {
DCHECK_NULL(object_create_map_); DCHECK_NULL(object_create_map_);
object_create_map_ = object_create_map_ =
broker->GetOrCreateData(proto_info->ObjectCreateMap())->AsMap(); broker->GetOrCreateData(proto_info->ObjectCreateMap());
} }
} }
} }
...@@ -501,14 +576,14 @@ class JSBoundFunctionData : public JSObjectData { ...@@ -501,14 +576,14 @@ class JSBoundFunctionData : public JSObjectData {
ObjectData* bound_target_function() const { return bound_target_function_; } ObjectData* bound_target_function() const { return bound_target_function_; }
ObjectData* bound_this() const { return bound_this_; } ObjectData* bound_this() const { return bound_this_; }
FixedArrayData* bound_arguments() const { return bound_arguments_; } ObjectData* bound_arguments() const { return bound_arguments_; }
private: private:
bool serialized_ = false; bool serialized_ = false;
ObjectData* bound_target_function_ = nullptr; ObjectData* bound_target_function_ = nullptr;
ObjectData* bound_this_ = nullptr; ObjectData* bound_this_ = nullptr;
FixedArrayData* bound_arguments_ = nullptr; ObjectData* bound_arguments_ = nullptr;
}; };
class JSFunctionData : public JSObjectData { class JSFunctionData : public JSObjectData {
...@@ -528,7 +603,7 @@ class JSFunctionData : public JSObjectData { ...@@ -528,7 +603,7 @@ class JSFunctionData : public JSObjectData {
ContextData* context() const { return context_; } ContextData* context() const { return context_; }
NativeContextData* native_context() const { return native_context_; } NativeContextData* native_context() const { return native_context_; }
MapData* initial_map() const { return initial_map_; } ObjectData* initial_map() const { return initial_map_; }
ObjectData* prototype() const { return prototype_; } ObjectData* prototype() const { return prototype_; }
SharedFunctionInfoData* shared() const { return shared_; } SharedFunctionInfoData* shared() const { return shared_; }
FeedbackVectorData* feedback_vector() const { return feedback_vector_; } FeedbackVectorData* feedback_vector() const { return feedback_vector_; }
...@@ -547,7 +622,7 @@ class JSFunctionData : public JSObjectData { ...@@ -547,7 +622,7 @@ class JSFunctionData : public JSObjectData {
ContextData* context_ = nullptr; ContextData* context_ = nullptr;
NativeContextData* native_context_ = nullptr; NativeContextData* native_context_ = nullptr;
MapData* initial_map_ = nullptr; ObjectData* initial_map_ = nullptr;
ObjectData* prototype_ = nullptr; ObjectData* prototype_ = nullptr;
SharedFunctionInfoData* shared_ = nullptr; SharedFunctionInfoData* shared_ = nullptr;
FeedbackVectorData* feedback_vector_ = nullptr; FeedbackVectorData* feedback_vector_ = nullptr;
...@@ -1093,10 +1168,19 @@ HeapObjectData::HeapObjectData(JSHeapBroker* broker, ObjectData** storage, ...@@ -1093,10 +1168,19 @@ HeapObjectData::HeapObjectData(JSHeapBroker* broker, ObjectData** storage,
// instance_type_ member. In the case of constructing the MapData for the // instance_type_ member. In the case of constructing the MapData for the
// meta map (whose map is itself), this member has not yet been // meta map (whose map is itself), this member has not yet been
// initialized. // initialized.
map_(static_cast<MapData*>(broker->GetOrCreateData(object->map()))) { map_(broker->GetOrCreateData(object->map())) {
CHECK(broker->SerializingAllowed()); CHECK(broker->SerializingAllowed());
} }
InstanceType HeapObjectData::GetMapInstanceType() const {
ObjectData* map_data = map();
if (map_data->should_access_heap()) {
AllowHandleDereferenceIf allow_handle_dereference(kind());
return Handle<Map>::cast(map_data->object())->instance_type();
}
return map_data->AsMap()->instance_type();
}
namespace { namespace {
bool IsReadOnlyLengthDescriptor(Isolate* isolate, Handle<Map> jsarray_map) { bool IsReadOnlyLengthDescriptor(Isolate* isolate, Handle<Map> jsarray_map) {
DCHECK(!jsarray_map->is_dictionary_map()); DCHECK(!jsarray_map->is_dictionary_map());
...@@ -1192,14 +1276,16 @@ void JSFunctionData::Serialize(JSHeapBroker* broker) { ...@@ -1192,14 +1276,16 @@ void JSFunctionData::Serialize(JSHeapBroker* broker) {
if (initial_map_ != nullptr) { if (initial_map_ != nullptr) {
initial_map_instance_size_with_min_slack_ = initial_map_instance_size_with_min_slack_ =
function->ComputeInstanceSizeWithMinSlack(broker->isolate()); function->ComputeInstanceSizeWithMinSlack(broker->isolate());
if (initial_map_->instance_type() == JS_ARRAY_TYPE) { }
initial_map_->SerializeElementsKindGeneralizations(broker); if (initial_map_ != nullptr && !initial_map_->should_access_heap()) {
if (initial_map_->AsMap()->instance_type() == JS_ARRAY_TYPE) {
initial_map_->AsMap()->SerializeElementsKindGeneralizations(broker);
} }
initial_map_->SerializeConstructor(broker); initial_map_->AsMap()->SerializeConstructor(broker);
// TODO(neis): This is currently only needed for native_context's // TODO(neis): This is currently only needed for native_context's
// object_function, as used by GetObjectCreateMap. If no further use sites // object_function, as used by GetObjectCreateMap. If no further use sites
// show up, we should move this into NativeContextData::Serialize. // show up, we should move this into NativeContextData::Serialize.
initial_map_->SerializePrototype(broker); initial_map_->AsMap()->SerializePrototype(broker);
} }
} }
...@@ -1364,9 +1450,10 @@ void JSBoundFunctionData::Serialize(JSHeapBroker* broker) { ...@@ -1364,9 +1450,10 @@ void JSBoundFunctionData::Serialize(JSHeapBroker* broker) {
} }
DCHECK_NULL(bound_arguments_); DCHECK_NULL(bound_arguments_);
bound_arguments_ = bound_arguments_ = broker->GetOrCreateData(function->bound_arguments());
broker->GetOrCreateData(function->bound_arguments())->AsFixedArray(); if (!bound_arguments_->should_access_heap()) {
bound_arguments_->SerializeContents(broker); bound_arguments_->AsFixedArray()->SerializeContents(broker);
}
DCHECK_NULL(bound_this_); DCHECK_NULL(bound_this_);
bound_this_ = broker->GetOrCreateData(function->bound_this()); bound_this_ = broker->GetOrCreateData(function->bound_this());
...@@ -1911,21 +1998,20 @@ class CodeData : public HeapObjectData { ...@@ -1911,21 +1998,20 @@ class CodeData : public HeapObjectData {
: HeapObjectData(broker, storage, object) {} : HeapObjectData(broker, storage, object) {}
}; };
#define DEFINE_IS_AND_AS(Name) \ #define DEFINE_IS_AND_AS(Name) \
bool ObjectData::Is##Name() const { \ bool ObjectData::Is##Name() const { \
if (kind() == kUnserializedHeapObject) { \ if (should_access_heap()) { \
AllowHandleDereference allow_handle_dereference; \ AllowHandleDereferenceIf allow_handle_dereference(kind()); \
return object()->Is##Name(); \ return object()->Is##Name(); \
} \ } \
if (is_smi()) return false; \ if (is_smi()) return false; \
InstanceType instance_type = \ InstanceType instance_type = \
static_cast<const HeapObjectData*>(this)->map()->instance_type(); \ static_cast<const HeapObjectData*>(this)->GetMapInstanceType(); \
return InstanceTypeChecker::Is##Name(instance_type); \ return InstanceTypeChecker::Is##Name(instance_type); \
} \ } \
Name##Data* ObjectData::As##Name() { \ Name##Data* ObjectData::As##Name() { \
CHECK_EQ(kind(), kSerializedHeapObject); \ CHECK(Is##Name()); \
CHECK(Is##Name()); \ return static_cast<Name##Data*>(this); \
return static_cast<Name##Data*>(this); \
} }
HEAP_BROKER_OBJECT_LIST(DEFINE_IS_AND_AS) HEAP_BROKER_OBJECT_LIST(DEFINE_IS_AND_AS)
#undef DEFINE_IS_AND_AS #undef DEFINE_IS_AND_AS
...@@ -1939,7 +2025,7 @@ bool JSObjectData::cow_or_empty_elements_tenured() const { ...@@ -1939,7 +2025,7 @@ bool JSObjectData::cow_or_empty_elements_tenured() const {
return cow_or_empty_elements_tenured_; return cow_or_empty_elements_tenured_;
} }
FixedArrayBaseData* JSObjectData::elements() const { return elements_; } ObjectData* JSObjectData::elements() const { return elements_; }
void JSObjectData::SerializeAsBoilerplate(JSHeapBroker* broker) { void JSObjectData::SerializeAsBoilerplate(JSHeapBroker* broker) {
SerializeRecursiveAsBoilerplate(broker, kMaxFastLiteralDepth); SerializeRecursiveAsBoilerplate(broker, kMaxFastLiteralDepth);
...@@ -1954,7 +2040,8 @@ void JSObjectData::SerializeElements(JSHeapBroker* broker) { ...@@ -1954,7 +2040,8 @@ void JSObjectData::SerializeElements(JSHeapBroker* broker) {
Handle<FixedArrayBase> elements_object(boilerplate->elements(), Handle<FixedArrayBase> elements_object(boilerplate->elements(),
broker->isolate()); broker->isolate());
DCHECK_NULL(elements_); DCHECK_NULL(elements_);
elements_ = broker->GetOrCreateData(elements_object)->AsFixedArrayBase(); elements_ = broker->GetOrCreateData(elements_object);
DCHECK(elements_->IsFixedArrayBase());
} }
void MapData::SerializeConstructor(JSHeapBroker* broker) { void MapData::SerializeConstructor(JSHeapBroker* broker) {
...@@ -2108,9 +2195,10 @@ void JSObjectData::SerializeRecursiveAsBoilerplate(JSHeapBroker* broker, ...@@ -2108,9 +2195,10 @@ void JSObjectData::SerializeRecursiveAsBoilerplate(JSHeapBroker* broker,
} }
DCHECK_NULL(elements_); DCHECK_NULL(elements_);
elements_ = broker->GetOrCreateData(elements_object)->AsFixedArrayBase(); elements_ = broker->GetOrCreateData(elements_object);
DCHECK(elements_->IsFixedArrayBase());
if (empty_or_cow) { if (empty_or_cow || elements_->should_access_heap()) {
// No need to do anything here. Empty or copy-on-write elements // No need to do anything here. Empty or copy-on-write elements
// do not need to be serialized because we only need to store the elements // do not need to be serialized because we only need to store the elements
// reference to the allocated object. // reference to the allocated object.
...@@ -2181,7 +2269,9 @@ void JSObjectData::SerializeRecursiveAsBoilerplate(JSHeapBroker* broker, ...@@ -2181,7 +2269,9 @@ void JSObjectData::SerializeRecursiveAsBoilerplate(JSHeapBroker* broker,
} }
TRACE(broker, "Copied " << inobject_fields_.size() << " in-object fields"); TRACE(broker, "Copied " << inobject_fields_.size() << " in-object fields");
map()->SerializeOwnDescriptors(broker); if (!map()->should_access_heap()) {
map()->AsMap()->SerializeOwnDescriptors(broker);
}
if (IsJSArray()) AsJSArray()->Serialize(broker); if (IsJSArray()) AsJSArray()->Serialize(broker);
} }
...@@ -2218,9 +2308,11 @@ Isolate* ObjectRef::isolate() const { return broker()->isolate(); } ...@@ -2218,9 +2308,11 @@ Isolate* ObjectRef::isolate() const { return broker()->isolate(); }
ContextRef ContextRef::previous(size_t* depth, ContextRef ContextRef::previous(size_t* depth,
SerializationPolicy policy) const { SerializationPolicy policy) const {
DCHECK_NOT_NULL(depth); DCHECK_NOT_NULL(depth);
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleAllocation handle_allocation; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
AllowHandleDereference handle_dereference; broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
Context current = *object(); Context current = *object();
while (*depth != 0 && current.unchecked_previous().IsContext()) { while (*depth != 0 && current.unchecked_previous().IsContext()) {
current = Context::cast(current.unchecked_previous()); current = Context::cast(current.unchecked_previous());
...@@ -2234,9 +2326,11 @@ ContextRef ContextRef::previous(size_t* depth, ...@@ -2234,9 +2326,11 @@ ContextRef ContextRef::previous(size_t* depth,
base::Optional<ObjectRef> ContextRef::get(int index, base::Optional<ObjectRef> ContextRef::get(int index,
SerializationPolicy policy) const { SerializationPolicy policy) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleAllocation handle_allocation; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
AllowHandleDereference handle_dereference; broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
Handle<Object> value(object()->get(index), broker()->isolate()); Handle<Object> value(object()->get(index), broker()->isolate());
return ObjectRef(broker(), value); return ObjectRef(broker(), value);
} }
...@@ -2251,10 +2345,10 @@ base::Optional<ObjectRef> ContextRef::get(int index, ...@@ -2251,10 +2345,10 @@ base::Optional<ObjectRef> ContextRef::get(int index,
JSHeapBroker::JSHeapBroker(Isolate* isolate, Zone* broker_zone, JSHeapBroker::JSHeapBroker(Isolate* isolate, Zone* broker_zone,
bool tracing_enabled) bool tracing_enabled)
: isolate_(isolate), : isolate_(isolate),
broker_zone_(broker_zone), zone_(broker_zone),
current_zone_(broker_zone),
refs_(new (zone()) refs_(new (zone())
RefsMap(kMinimalRefsBucketCount, AddressMatcher(), zone())), RefsMap(kMinimalRefsBucketCount, AddressMatcher(), zone())),
root_index_map_(isolate),
array_and_object_prototypes_(zone()), array_and_object_prototypes_(zone()),
tracing_enabled_(tracing_enabled), tracing_enabled_(tracing_enabled),
feedback_(zone()), feedback_(zone()),
...@@ -2324,10 +2418,14 @@ void JSHeapBroker::PrintRefsAnalysis() const { ...@@ -2324,10 +2418,14 @@ void JSHeapBroker::PrintRefsAnalysis() const {
break; break;
} }
} else { } else {
InstanceType instance_type = InstanceType instance_type;
static_cast<const HeapObjectData*>(ref->value) if (ref->value->should_access_heap()) {
->map() instance_type = Handle<HeapObject>::cast(ref->value->object())
->instance_type(); ->map()
.instance_type();
} else {
instance_type = ref->value->AsHeapObject()->GetMapInstanceType();
}
CHECK_LE(FIRST_TYPE, instance_type); CHECK_LE(FIRST_TYPE, instance_type);
CHECK_LE(instance_type, LAST_TYPE); CHECK_LE(instance_type, LAST_TYPE);
switch (ref->value->used_status) { switch (ref->value->used_status) {
...@@ -2394,85 +2492,6 @@ bool IsShareable(Handle<Object> object, Isolate* isolate) { ...@@ -2394,85 +2492,6 @@ bool IsShareable(Handle<Object> object, Isolate* isolate) {
isolate->roots_table().IsRootHandle(object, &root_index); isolate->roots_table().IsRootHandle(object, &root_index);
} }
void JSHeapBroker::InitializeRefsMap() {
TraceScope tracer(this, "JSHeapBroker::InitializeRefsMap");
DCHECK_NULL(compiler_cache_);
PerIsolateCompilerCache::Setup(isolate());
compiler_cache_ = isolate()->compiler_cache();
if (compiler_cache_->HasSnapshot()) {
TRACE(this, "Importing existing RefsMap snapshot");
DCHECK_NULL(refs_);
refs_ = new (zone()) RefsMap(compiler_cache_->GetSnapshot(), zone());
return;
}
TRACE(this, "Building RefsMap snapshot");
DCHECK_NULL(refs_);
refs_ =
new (zone()) RefsMap(kInitialRefsBucketCount, AddressMatcher(), zone());
// Temporarily use the "compiler zone" for serialization, such that the
// serialized data survives this compilation.
DCHECK_EQ(current_zone_, broker_zone_);
current_zone_ = compiler_cache_->zone();
// Serialize various builtins.
Builtins* const b = isolate()->builtins();
{
Builtins::Name builtins[] = {
Builtins::kAllocateInYoungGeneration,
Builtins::kAllocateRegularInYoungGeneration,
Builtins::kAllocateInOldGeneration,
Builtins::kAllocateRegularInOldGeneration,
Builtins::kArgumentsAdaptorTrampoline,
Builtins::kArrayConstructorImpl,
Builtins::kArrayIncludesHoleyDoubles,
Builtins::kArrayIncludesPackedDoubles,
Builtins::kArrayIncludesSmiOrObject,
Builtins::kArrayIndexOfHoleyDoubles,
Builtins::kArrayIndexOfPackedDoubles,
Builtins::kArrayIndexOfSmiOrObject,
Builtins::kCallApiCallback,
Builtins::kCallFunctionForwardVarargs,
Builtins::kCallFunction_ReceiverIsAny,
Builtins::kCallFunction_ReceiverIsNotNullOrUndefined,
Builtins::kCallFunction_ReceiverIsNullOrUndefined,
Builtins::kCloneFastJSArray,
Builtins::kConstructFunctionForwardVarargs,
Builtins::kForInFilter,
Builtins::kGetProperty,
Builtins::kIncBlockCounter,
Builtins::kJSBuiltinsConstructStub,
Builtins::kJSConstructStubGeneric,
Builtins::kStringAdd_CheckNone,
Builtins::kStringAddConvertLeft,
Builtins::kStringAddConvertRight,
Builtins::kToNumber,
Builtins::kToObject,
};
for (auto id : builtins) {
GetOrCreateData(b->builtin_handle(id));
}
}
for (int32_t id = 0; id < Builtins::kFirstBytecodeHandler; ++id) {
if (Builtins::HasJSLinkage(id)) {
GetOrCreateData(b->builtin_handle(id));
}
}
// TODO(mslekova): Serialize root objects (from factory).
// Verify.
for (RefsMap::Entry* p = refs_->Start(); p != nullptr; p = refs_->Next(p)) {
CHECK(IsShareable(p->value->object(), isolate()));
}
compiler_cache()->SetSnapshot(refs_);
current_zone_ = broker_zone_;
}
void JSHeapBroker::CollectArrayAndObjectPrototypes() { void JSHeapBroker::CollectArrayAndObjectPrototypes() {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
CHECK_EQ(mode(), kSerializing); CHECK_EQ(mode(), kSerializing);
...@@ -2568,7 +2587,8 @@ void JSHeapBroker::InitializeAndStartSerializing( ...@@ -2568,7 +2587,8 @@ void JSHeapBroker::InitializeAndStartSerializing(
refs_->Clear(); refs_->Clear();
refs_ = nullptr; refs_ = nullptr;
InitializeRefsMap(); refs_ =
new (zone()) RefsMap(kInitialRefsBucketCount, AddressMatcher(), zone());
SetTargetNativeContextRef(native_context); SetTargetNativeContextRef(native_context);
target_native_context().Serialize(); target_native_context().Serialize();
...@@ -2576,60 +2596,8 @@ void JSHeapBroker::InitializeAndStartSerializing( ...@@ -2576,60 +2596,8 @@ void JSHeapBroker::InitializeAndStartSerializing(
CollectArrayAndObjectPrototypes(); CollectArrayAndObjectPrototypes();
SerializeTypedArrayStringTags(); SerializeTypedArrayStringTags();
// Serialize standard objects. // Serialize Cells
//
// - Maps, strings, oddballs
Factory* const f = isolate()->factory(); Factory* const f = isolate()->factory();
GetOrCreateData(f->arguments_marker_map());
GetOrCreateData(f->bigint_string());
GetOrCreateData(f->boolean_map());
GetOrCreateData(f->boolean_string());
GetOrCreateData(f->empty_fixed_array());
GetOrCreateData(f->empty_string());
GetOrCreateData(f->exec_string());
GetOrCreateData(f->false_string());
GetOrCreateData(f->false_value());
GetOrCreateData(f->fixed_array_map());
GetOrCreateData(f->fixed_cow_array_map());
GetOrCreateData(f->fixed_double_array_map());
GetOrCreateData(f->function_string());
GetOrCreateData(f->has_instance_symbol());
GetOrCreateData(f->heap_number_map());
GetOrCreateData(f->length_string());
GetOrCreateData(f->many_closures_cell_map());
GetOrCreateData(f->minus_zero_value());
GetOrCreateData(f->name_dictionary_map());
GetOrCreateData(f->name_string());
GetOrCreateData(f->NaN_string());
GetOrCreateData(f->null_map());
GetOrCreateData(f->null_string());
GetOrCreateData(f->null_value());
GetOrCreateData(f->number_string());
GetOrCreateData(f->object_string());
GetOrCreateData(f->one_pointer_filler_map());
GetOrCreateData(f->optimized_out());
GetOrCreateData(f->optimized_out_map());
GetOrCreateData(f->property_array_map());
GetOrCreateData(f->prototype_string());
GetOrCreateData(f->ReflectHas_string());
GetOrCreateData(f->ReflectGet_string());
GetOrCreateData(f->sloppy_arguments_elements_map());
GetOrCreateData(f->stale_register());
GetOrCreateData(f->stale_register_map());
GetOrCreateData(f->string_string());
GetOrCreateData(f->symbol_string());
GetOrCreateData(f->termination_exception_map());
GetOrCreateData(f->the_hole_map());
GetOrCreateData(f->the_hole_value());
GetOrCreateData(f->then_string());
GetOrCreateData(f->true_string());
GetOrCreateData(f->true_value());
GetOrCreateData(f->undefined_map());
GetOrCreateData(f->undefined_string());
GetOrCreateData(f->undefined_value());
GetOrCreateData(f->uninitialized_map());
GetOrCreateData(f->zero_string());
// - Cells
GetOrCreateData(f->array_buffer_detaching_protector()) GetOrCreateData(f->array_buffer_detaching_protector())
->AsPropertyCell() ->AsPropertyCell()
->Serialize(this); ->Serialize(this);
...@@ -2665,24 +2633,29 @@ void JSHeapBroker::InitializeAndStartSerializing( ...@@ -2665,24 +2633,29 @@ void JSHeapBroker::InitializeAndStartSerializing(
TRACE(this, "Finished serializing standard objects"); TRACE(this, "Finished serializing standard objects");
} }
ObjectData* JSHeapBroker::GetData(Handle<Object> object) const { bool JSHeapBroker::is_builtin_code(Object object) {
RefsMap::Entry* entry = refs_->Lookup(object.address()); return (object.IsCode() && Code::cast(object).is_builtin());
return entry ? entry->value : nullptr;
} }
// clang-format off // clang-format off
ObjectData* JSHeapBroker::GetOrCreateData(Handle<Object> object) { ObjectData* JSHeapBroker::GetOrCreateData(Handle<Object> object) {
CHECK(SerializingAllowed());
RefsMap::Entry* entry = refs_->LookupOrInsert(object.address(), zone()); RefsMap::Entry* entry = refs_->LookupOrInsert(object.address(), zone());
ObjectData** data_storage = &(entry->value); ObjectData** data_storage = &(entry->value);
if (*data_storage == nullptr) { if (*data_storage == nullptr) {
// TODO(neis): Remove these Allow* once we serialize everything upfront. // TODO(neis): Remove these Allow* once we serialize everything upfront.
AllowHandleAllocation handle_allocation;
AllowHandleDereference handle_dereference; AllowHandleDereference handle_dereference;
if (object->IsSmi()) { if (object->IsSmi()) {
new (zone()) ObjectData(this, data_storage, object, kSmi); new (zone()) ObjectData(this, data_storage, object, kSmi);
} else if (is_builtin_code(*object)) {
new (zone()) ObjectData(this, data_storage, object,
kUnserializedReadOnlyHeapObject);
} else if (ReadOnlyHeap::Contains(HeapObject::cast(*object))) {
new (zone()) ObjectData(this, data_storage, object,
kUnserializedReadOnlyHeapObject);
#define CREATE_DATA_IF_MATCH(name) \ #define CREATE_DATA_IF_MATCH(name) \
} else if (object->Is##name()) { \ } else if (object->Is##name()) { \
CHECK(SerializingAllowed()); \
AllowHandleAllocation handle_allocation; \
new (zone()) name##Data(this, data_storage, Handle<name>::cast(object)); new (zone()) name##Data(this, data_storage, Handle<name>::cast(object));
HEAP_BROKER_OBJECT_LIST(CREATE_DATA_IF_MATCH) HEAP_BROKER_OBJECT_LIST(CREATE_DATA_IF_MATCH)
#undef CREATE_DATA_IF_MATCH #undef CREATE_DATA_IF_MATCH
...@@ -2717,10 +2690,14 @@ int ObjectRef::AsSmi() const { ...@@ -2717,10 +2690,14 @@ int ObjectRef::AsSmi() const {
} }
base::Optional<MapRef> JSObjectRef::GetObjectCreateMap() const { base::Optional<MapRef> JSObjectRef::GetObjectCreateMap() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleAllocation handle_allocation; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleDereference allow_handle_dereference; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
AllowHeapAllocation heap_allocation; broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
AllowHeapAllocationIf allow_heap_allocation(data()->kind(),
broker()->mode());
Handle<Map> instance_map; Handle<Map> instance_map;
if (Map::TryGetObjectCreateMap(broker()->isolate(), object()) if (Map::TryGetObjectCreateMap(broker()->isolate(), object())
.ToHandle(&instance_map)) { .ToHandle(&instance_map)) {
...@@ -2729,9 +2706,12 @@ base::Optional<MapRef> JSObjectRef::GetObjectCreateMap() const { ...@@ -2729,9 +2706,12 @@ base::Optional<MapRef> JSObjectRef::GetObjectCreateMap() const {
return base::Optional<MapRef>(); return base::Optional<MapRef>();
} }
} }
MapData* map_data = data()->AsJSObject()->object_create_map(broker()); ObjectData* map_data = data()->AsJSObject()->object_create_map(broker());
return map_data != nullptr ? MapRef(broker(), map_data) if (map_data == nullptr) return base::Optional<MapRef>();
: base::Optional<MapRef>(); if (map_data->should_access_heap()) {
return MapRef(broker(), map_data->object());
}
return MapRef(broker(), map_data->AsMap());
} }
#define DEF_TESTER(Type, ...) \ #define DEF_TESTER(Type, ...) \
...@@ -2742,10 +2722,13 @@ INSTANCE_TYPE_CHECKERS(DEF_TESTER) ...@@ -2742,10 +2722,13 @@ INSTANCE_TYPE_CHECKERS(DEF_TESTER)
#undef DEF_TESTER #undef DEF_TESTER
base::Optional<MapRef> MapRef::AsElementsKind(ElementsKind kind) const { base::Optional<MapRef> MapRef::AsElementsKind(ElementsKind kind) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleAllocation handle_allocation; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
AllowHeapAllocation heap_allocation; broker()->mode());
AllowHandleDereference allow_handle_dereference; AllowHeapAllocationIf allow_heap_allocation(data()->kind(),
broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return MapRef(broker(), return MapRef(broker(),
Map::AsElementsKind(broker()->isolate(), object(), kind)); Map::AsElementsKind(broker()->isolate(), object(), kind));
} }
...@@ -2761,11 +2744,13 @@ base::Optional<MapRef> MapRef::AsElementsKind(ElementsKind kind) const { ...@@ -2761,11 +2744,13 @@ base::Optional<MapRef> MapRef::AsElementsKind(ElementsKind kind) const {
void MapRef::SerializeForElementLoad() { void MapRef::SerializeForElementLoad() {
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
if (data()->kind() == ObjectDataKind::kUnserializedReadOnlyHeapObject) return;
data()->AsMap()->SerializeForElementLoad(broker()); data()->AsMap()->SerializeForElementLoad(broker());
} }
void MapRef::SerializeForElementStore() { void MapRef::SerializeForElementStore() {
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
if (data()->kind() == ObjectDataKind::kUnserializedReadOnlyHeapObject) return;
data()->AsMap()->SerializeForElementStore(broker()); data()->AsMap()->SerializeForElementStore(broker());
} }
...@@ -2822,27 +2807,34 @@ bool MapRef::HasOnlyStablePrototypesWithFastElements( ...@@ -2822,27 +2807,34 @@ bool MapRef::HasOnlyStablePrototypesWithFastElements(
} }
bool MapRef::supports_fast_array_iteration() const { bool MapRef::supports_fast_array_iteration() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference allow_handle_dereference; AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
AllowHandleAllocation handle_allocation; broker()->mode());
AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
broker()->mode());
return SupportsFastArrayIteration(broker()->isolate(), object()); return SupportsFastArrayIteration(broker()->isolate(), object());
} }
return data()->AsMap()->supports_fast_array_iteration(); return data()->AsMap()->supports_fast_array_iteration();
} }
bool MapRef::supports_fast_array_resize() const { bool MapRef::supports_fast_array_resize() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference allow_handle_dereference; AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
AllowHandleAllocation handle_allocation; broker()->mode());
AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
broker()->mode());
return SupportsFastArrayResize(broker()->isolate(), object()); return SupportsFastArrayResize(broker()->isolate(), object());
} }
return data()->AsMap()->supports_fast_array_resize(); return data()->AsMap()->supports_fast_array_resize();
} }
int JSFunctionRef::InitialMapInstanceSizeWithMinSlack() const { int JSFunctionRef::InitialMapInstanceSizeWithMinSlack() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference allow_handle_dereference; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleAllocation handle_allocation; AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
broker()->mode());
return object()->ComputeInstanceSizeWithMinSlack(broker()->isolate()); return object()->ComputeInstanceSizeWithMinSlack(broker()->isolate());
} }
return data()->AsJSFunction()->initial_map_instance_size_with_min_slack(); return data()->AsJSFunction()->initial_map_instance_size_with_min_slack();
...@@ -2851,8 +2843,10 @@ int JSFunctionRef::InitialMapInstanceSizeWithMinSlack() const { ...@@ -2851,8 +2843,10 @@ int JSFunctionRef::InitialMapInstanceSizeWithMinSlack() const {
// Not needed for TypedLowering. // Not needed for TypedLowering.
base::Optional<ScriptContextTableRef::LookupResult> base::Optional<ScriptContextTableRef::LookupResult>
ScriptContextTableRef::lookup(const NameRef& name) const { ScriptContextTableRef::lookup(const NameRef& name) const {
AllowHandleAllocation handle_allocation; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
AllowHandleDereference handle_dereference; broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
if (!name.IsString()) return {}; if (!name.IsString()) return {};
ScriptContextTable::LookupResult lookup_result; ScriptContextTable::LookupResult lookup_result;
auto table = object(); auto table = object();
...@@ -2896,9 +2890,12 @@ OddballType MapRef::oddball_type() const { ...@@ -2896,9 +2890,12 @@ OddballType MapRef::oddball_type() const {
} }
FeedbackCellRef FeedbackVectorRef::GetClosureFeedbackCell(int index) const { FeedbackCellRef FeedbackVectorRef::GetClosureFeedbackCell(int index) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleAllocation handle_allocation; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleDereference handle_dereference; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return FeedbackCellRef(broker(), object()->GetClosureFeedbackCell(index)); return FeedbackCellRef(broker(), object()->GetClosureFeedbackCell(index));
} }
...@@ -2908,8 +2905,10 @@ FeedbackCellRef FeedbackVectorRef::GetClosureFeedbackCell(int index) const { ...@@ -2908,8 +2905,10 @@ FeedbackCellRef FeedbackVectorRef::GetClosureFeedbackCell(int index) const {
} }
double JSObjectRef::RawFastDoublePropertyAt(FieldIndex index) const { double JSObjectRef::RawFastDoublePropertyAt(FieldIndex index) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference handle_dereference; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return object()->RawFastDoublePropertyAt(index); return object()->RawFastDoublePropertyAt(index);
} }
JSObjectData* object_data = data()->AsJSObject(); JSObjectData* object_data = data()->AsJSObject();
...@@ -2918,8 +2917,10 @@ double JSObjectRef::RawFastDoublePropertyAt(FieldIndex index) const { ...@@ -2918,8 +2917,10 @@ double JSObjectRef::RawFastDoublePropertyAt(FieldIndex index) const {
} }
uint64_t JSObjectRef::RawFastDoublePropertyAsBitsAt(FieldIndex index) const { uint64_t JSObjectRef::RawFastDoublePropertyAsBitsAt(FieldIndex index) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference handle_dereference; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return object()->RawFastDoublePropertyAsBitsAt(index); return object()->RawFastDoublePropertyAsBitsAt(index);
} }
JSObjectData* object_data = data()->AsJSObject(); JSObjectData* object_data = data()->AsJSObject();
...@@ -2928,9 +2929,12 @@ uint64_t JSObjectRef::RawFastDoublePropertyAsBitsAt(FieldIndex index) const { ...@@ -2928,9 +2929,12 @@ uint64_t JSObjectRef::RawFastDoublePropertyAsBitsAt(FieldIndex index) const {
} }
ObjectRef JSObjectRef::RawFastPropertyAt(FieldIndex index) const { ObjectRef JSObjectRef::RawFastPropertyAt(FieldIndex index) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleAllocation handle_allocation; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleDereference handle_dereference; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return ObjectRef(broker(), handle(object()->RawFastPropertyAt(index), return ObjectRef(broker(), handle(object()->RawFastPropertyAt(index),
broker()->isolate())); broker()->isolate()));
} }
...@@ -2942,10 +2946,14 @@ ObjectRef JSObjectRef::RawFastPropertyAt(FieldIndex index) const { ...@@ -2942,10 +2946,14 @@ ObjectRef JSObjectRef::RawFastPropertyAt(FieldIndex index) const {
} }
bool AllocationSiteRef::IsFastLiteral() const { bool AllocationSiteRef::IsFastLiteral() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHeapAllocation allow_heap_allocation; // For TryMigrateInstance. DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleAllocation allow_handle_allocation; AllowHeapAllocationIf allow_heap_allocation(
AllowHandleDereference allow_handle_dereference; data()->kind(), broker()->mode()); // For TryMigrateInstance.
AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return IsInlinableFastLiteral( return IsInlinableFastLiteral(
handle(object()->boilerplate(), broker()->isolate())); handle(object()->boilerplate(), broker()->isolate()));
} }
...@@ -2963,10 +2971,14 @@ void JSObjectRef::SerializeElements() { ...@@ -2963,10 +2971,14 @@ void JSObjectRef::SerializeElements() {
} }
void JSObjectRef::EnsureElementsTenured() { void JSObjectRef::EnsureElementsTenured() {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleAllocation allow_handle_allocation; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleDereference allow_handle_dereference; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
AllowHeapAllocation allow_heap_allocation; broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
AllowHeapAllocationIf allow_heap_allocation(data()->kind(),
broker()->mode());
Handle<FixedArrayBase> object_elements = elements().object(); Handle<FixedArrayBase> object_elements = elements().object();
if (ObjectInYoungGeneration(*object_elements)) { if (ObjectInYoungGeneration(*object_elements)) {
...@@ -2984,8 +2996,9 @@ void JSObjectRef::EnsureElementsTenured() { ...@@ -2984,8 +2996,9 @@ void JSObjectRef::EnsureElementsTenured() {
} }
FieldIndex MapRef::GetFieldIndexFor(InternalIndex descriptor_index) const { FieldIndex MapRef::GetFieldIndexFor(InternalIndex descriptor_index) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference allow_handle_dereference; AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return FieldIndex::ForDescriptor(*object(), descriptor_index); return FieldIndex::ForDescriptor(*object(), descriptor_index);
} }
DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors(); DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors();
...@@ -2993,8 +3006,9 @@ FieldIndex MapRef::GetFieldIndexFor(InternalIndex descriptor_index) const { ...@@ -2993,8 +3006,9 @@ FieldIndex MapRef::GetFieldIndexFor(InternalIndex descriptor_index) const {
} }
int MapRef::GetInObjectPropertyOffset(int i) const { int MapRef::GetInObjectPropertyOffset(int i) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference allow_handle_dereference; AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return object()->GetInObjectPropertyOffset(i); return object()->GetInObjectPropertyOffset(i);
} }
return (GetInObjectPropertiesStartInWords() + i) * kTaggedSize; return (GetInObjectPropertiesStartInWords() + i) * kTaggedSize;
...@@ -3002,8 +3016,9 @@ int MapRef::GetInObjectPropertyOffset(int i) const { ...@@ -3002,8 +3016,9 @@ int MapRef::GetInObjectPropertyOffset(int i) const {
PropertyDetails MapRef::GetPropertyDetails( PropertyDetails MapRef::GetPropertyDetails(
InternalIndex descriptor_index) const { InternalIndex descriptor_index) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference allow_handle_dereference; AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return object()->instance_descriptors().GetDetails(descriptor_index); return object()->instance_descriptors().GetDetails(descriptor_index);
} }
DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors(); DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors();
...@@ -3011,9 +3026,11 @@ PropertyDetails MapRef::GetPropertyDetails( ...@@ -3011,9 +3026,11 @@ PropertyDetails MapRef::GetPropertyDetails(
} }
NameRef MapRef::GetPropertyKey(InternalIndex descriptor_index) const { NameRef MapRef::GetPropertyKey(InternalIndex descriptor_index) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleAllocation handle_allocation; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
AllowHandleDereference allow_handle_dereference; broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return NameRef( return NameRef(
broker(), broker(),
handle(object()->instance_descriptors().GetKey(descriptor_index), handle(object()->instance_descriptors().GetKey(descriptor_index),
...@@ -3035,9 +3052,11 @@ bool MapRef::IsPrimitiveMap() const { ...@@ -3035,9 +3052,11 @@ bool MapRef::IsPrimitiveMap() const {
} }
MapRef MapRef::FindFieldOwner(InternalIndex descriptor_index) const { MapRef MapRef::FindFieldOwner(InternalIndex descriptor_index) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleAllocation handle_allocation; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
AllowHandleDereference allow_handle_dereference; broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
Handle<Map> owner( Handle<Map> owner(
object()->FindFieldOwner(broker()->isolate(), descriptor_index), object()->FindFieldOwner(broker()->isolate(), descriptor_index),
broker()->isolate()); broker()->isolate());
...@@ -3050,9 +3069,11 @@ MapRef MapRef::FindFieldOwner(InternalIndex descriptor_index) const { ...@@ -3050,9 +3069,11 @@ MapRef MapRef::FindFieldOwner(InternalIndex descriptor_index) const {
} }
ObjectRef MapRef::GetFieldType(InternalIndex descriptor_index) const { ObjectRef MapRef::GetFieldType(InternalIndex descriptor_index) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleAllocation handle_allocation; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
AllowHandleDereference allow_handle_dereference; broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
Handle<FieldType> field_type( Handle<FieldType> field_type(
object()->instance_descriptors().GetFieldType(descriptor_index), object()->instance_descriptors().GetFieldType(descriptor_index),
broker()->isolate()); broker()->isolate());
...@@ -3065,8 +3086,9 @@ ObjectRef MapRef::GetFieldType(InternalIndex descriptor_index) const { ...@@ -3065,8 +3086,9 @@ ObjectRef MapRef::GetFieldType(InternalIndex descriptor_index) const {
} }
bool MapRef::IsUnboxedDoubleField(InternalIndex descriptor_index) const { bool MapRef::IsUnboxedDoubleField(InternalIndex descriptor_index) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference allow_handle_dereference; AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return object()->IsUnboxedDoubleField( return object()->IsUnboxedDoubleField(
FieldIndex::ForDescriptor(*object(), descriptor_index)); FieldIndex::ForDescriptor(*object(), descriptor_index));
} }
...@@ -3077,18 +3099,22 @@ bool MapRef::IsUnboxedDoubleField(InternalIndex descriptor_index) const { ...@@ -3077,18 +3099,22 @@ bool MapRef::IsUnboxedDoubleField(InternalIndex descriptor_index) const {
} }
uint16_t StringRef::GetFirstChar() { uint16_t StringRef::GetFirstChar() {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference allow_handle_dereference; AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return object()->Get(0); return object()->Get(0);
} }
return data()->AsString()->first_char(); return data()->AsString()->first_char();
} }
base::Optional<double> StringRef::ToNumber() { base::Optional<double> StringRef::ToNumber() {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference allow_handle_dereference; AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
AllowHandleAllocation allow_handle_allocation; broker()->mode());
AllowHeapAllocation allow_heap_allocation; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
broker()->mode());
AllowHeapAllocationIf allow_heap_allocation(data()->kind(),
broker()->mode());
int flags = ALLOW_HEX | ALLOW_OCTAL | ALLOW_BINARY; int flags = ALLOW_HEX | ALLOW_OCTAL | ALLOW_BINARY;
return StringToDouble(broker()->isolate(), object(), flags); return StringToDouble(broker()->isolate(), object(), flags);
} }
...@@ -3096,41 +3122,47 @@ base::Optional<double> StringRef::ToNumber() { ...@@ -3096,41 +3122,47 @@ base::Optional<double> StringRef::ToNumber() {
} }
int ArrayBoilerplateDescriptionRef::constants_elements_length() const { int ArrayBoilerplateDescriptionRef::constants_elements_length() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference allow_handle_dereference; AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return object()->constant_elements().length(); return object()->constant_elements().length();
} }
return data()->AsArrayBoilerplateDescription()->constants_elements_length(); return data()->AsArrayBoilerplateDescription()->constants_elements_length();
} }
int ObjectBoilerplateDescriptionRef::size() const { int ObjectBoilerplateDescriptionRef::size() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference allow_handle_dereference; AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return object()->size(); return object()->size();
} }
return data()->AsObjectBoilerplateDescription()->size(); return data()->AsObjectBoilerplateDescription()->size();
} }
ObjectRef FixedArrayRef::get(int i) const { ObjectRef FixedArrayRef::get(int i) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleAllocation handle_allocation; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
AllowHandleDereference allow_handle_dereference; broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return ObjectRef(broker(), handle(object()->get(i), broker()->isolate())); return ObjectRef(broker(), handle(object()->get(i), broker()->isolate()));
} }
return ObjectRef(broker(), data()->AsFixedArray()->Get(i)); return ObjectRef(broker(), data()->AsFixedArray()->Get(i));
} }
bool FixedDoubleArrayRef::is_the_hole(int i) const { bool FixedDoubleArrayRef::is_the_hole(int i) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference allow_handle_dereference; AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return object()->is_the_hole(i); return object()->is_the_hole(i);
} }
return data()->AsFixedDoubleArray()->Get(i).is_hole_nan(); return data()->AsFixedDoubleArray()->Get(i).is_hole_nan();
} }
double FixedDoubleArrayRef::get_scalar(int i) const { double FixedDoubleArrayRef::get_scalar(int i) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference allow_handle_dereference; AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return object()->get_scalar(i); return object()->get_scalar(i);
} }
CHECK(!data()->AsFixedDoubleArray()->Get(i).is_hole_nan()); CHECK(!data()->AsFixedDoubleArray()->Get(i).is_hole_nan());
...@@ -3138,27 +3170,36 @@ double FixedDoubleArrayRef::get_scalar(int i) const { ...@@ -3138,27 +3170,36 @@ double FixedDoubleArrayRef::get_scalar(int i) const {
} }
uint8_t BytecodeArrayRef::get(int index) const { uint8_t BytecodeArrayRef::get(int index) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleAllocation handle_allocation; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleDereference allow_handle_dereference; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return object()->get(index); return object()->get(index);
} }
return data()->AsBytecodeArray()->get(index); return data()->AsBytecodeArray()->get(index);
} }
Address BytecodeArrayRef::GetFirstBytecodeAddress() const { Address BytecodeArrayRef::GetFirstBytecodeAddress() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleAllocation handle_allocation; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleDereference allow_handle_dereference; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return object()->GetFirstBytecodeAddress(); return object()->GetFirstBytecodeAddress();
} }
return data()->AsBytecodeArray()->GetFirstBytecodeAddress(); return data()->AsBytecodeArray()->GetFirstBytecodeAddress();
} }
Handle<Object> BytecodeArrayRef::GetConstantAtIndex(int index) const { Handle<Object> BytecodeArrayRef::GetConstantAtIndex(int index) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleAllocation handle_allocation; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleDereference allow_handle_dereference; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return handle(object()->constant_pool().get(index), broker()->isolate()); return handle(object()->constant_pool().get(index), broker()->isolate());
} }
return data()->AsBytecodeArray()->GetConstantAtIndex(index, return data()->AsBytecodeArray()->GetConstantAtIndex(index,
...@@ -3166,47 +3207,60 @@ Handle<Object> BytecodeArrayRef::GetConstantAtIndex(int index) const { ...@@ -3166,47 +3207,60 @@ Handle<Object> BytecodeArrayRef::GetConstantAtIndex(int index) const {
} }
bool BytecodeArrayRef::IsConstantAtIndexSmi(int index) const { bool BytecodeArrayRef::IsConstantAtIndexSmi(int index) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleAllocation handle_allocation; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleDereference allow_handle_dereference; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return object()->constant_pool().get(index).IsSmi(); return object()->constant_pool().get(index).IsSmi();
} }
return data()->AsBytecodeArray()->IsConstantAtIndexSmi(index); return data()->AsBytecodeArray()->IsConstantAtIndexSmi(index);
} }
Smi BytecodeArrayRef::GetConstantAtIndexAsSmi(int index) const { Smi BytecodeArrayRef::GetConstantAtIndexAsSmi(int index) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleAllocation handle_allocation; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleDereference allow_handle_dereference; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return Smi::cast(object()->constant_pool().get(index)); return Smi::cast(object()->constant_pool().get(index));
} }
return data()->AsBytecodeArray()->GetConstantAtIndexAsSmi(index); return data()->AsBytecodeArray()->GetConstantAtIndexAsSmi(index);
} }
void BytecodeArrayRef::SerializeForCompilation() { void BytecodeArrayRef::SerializeForCompilation() {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
if (data_->should_access_heap()) return;
data()->AsBytecodeArray()->SerializeForCompilation(broker()); data()->AsBytecodeArray()->SerializeForCompilation(broker());
} }
const byte* BytecodeArrayRef::source_positions_address() const { const byte* BytecodeArrayRef::source_positions_address() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference allow_handle_dereference; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return object()->SourcePositionTableIfCollected().GetDataStartAddress(); return object()->SourcePositionTableIfCollected().GetDataStartAddress();
} }
return data()->AsBytecodeArray()->source_positions_address(); return data()->AsBytecodeArray()->source_positions_address();
} }
int BytecodeArrayRef::source_positions_size() const { int BytecodeArrayRef::source_positions_size() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference allow_handle_dereference; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return object()->SourcePositionTableIfCollected().length(); return object()->SourcePositionTableIfCollected().length();
} }
return static_cast<int>(data()->AsBytecodeArray()->source_positions_size()); return static_cast<int>(data()->AsBytecodeArray()->source_positions_size());
} }
Address BytecodeArrayRef::handler_table_address() const { Address BytecodeArrayRef::handler_table_address() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference allow_handle_dereference; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return reinterpret_cast<Address>( return reinterpret_cast<Address>(
object()->handler_table().GetDataStartAddress()); object()->handler_table().GetDataStartAddress());
} }
...@@ -3214,47 +3268,71 @@ Address BytecodeArrayRef::handler_table_address() const { ...@@ -3214,47 +3268,71 @@ Address BytecodeArrayRef::handler_table_address() const {
} }
int BytecodeArrayRef::handler_table_size() const { int BytecodeArrayRef::handler_table_size() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference allow_handle_dereference; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return object()->handler_table().length(); return object()->handler_table().length();
} }
return data()->AsBytecodeArray()->handler_table_size(); return data()->AsBytecodeArray()->handler_table_size();
} }
#define IF_BROKER_DISABLED_ACCESS_HANDLE_C(holder, name) \ Handle<Object> JSHeapBroker::GetRootHandle(Object object) {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { \ RootIndex root_index;
AllowHandleAllocation handle_allocation; \ CHECK(root_index_map().Lookup(object.ptr(), &root_index));
AllowHandleDereference allow_handle_dereference; \ return Handle<Object>(isolate()->root_handle(root_index).location());
return object()->name(); \ }
}
#define IF_ACCESS_FROM_HEAP_C(holder, name) \
#define IF_BROKER_DISABLED_ACCESS_HANDLE(holder, result, name) \ if (data_->should_access_heap()) { \
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { \ CHECK(broker()->mode() == JSHeapBroker::kDisabled || \
AllowHandleAllocation handle_allocation; \ ReadOnlyHeap::Contains(HeapObject::cast(*object()))); \
AllowHandleDereference allow_handle_dereference; \ AllowHandleAllocationIf handle_allocation(data_->kind(), \
return result##Ref(broker(), \ broker()->mode()); \
handle(object()->name(), broker()->isolate())); \ AllowHandleDereferenceIf allow_handle_dereference(data_->kind(), \
broker()->mode()); \
return object()->name(); \
}
#define IF_ACCESS_FROM_HEAP(holder, result, name) \
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { \
AllowHandleAllocationIf handle_allocation(data_->kind(), \
broker()->mode()); \
AllowHandleDereferenceIf handle_dereference(data_->kind(), \
broker()->mode()); \
return result##Ref(broker(), \
handle(object()->name(), broker()->isolate())); \
} else if (data_->kind() == \
ObjectDataKind::kUnserializedReadOnlyHeapObject) { \
AllowHandleDereferenceIf handle_dereference(data_->kind(), \
broker()->mode()); \
return result##Ref(broker(), broker()->GetRootHandle(object()->name())); \
} }
// Macros for definining a const getter that, depending on the broker mode, // Macros for definining a const getter that, depending on the broker mode,
// either looks into the handle or into the serialized data. // either looks into the handle or into the serialized data.
#define BIMODAL_ACCESSOR(holder, result, name) \ #define BIMODAL_ACCESSOR(holder, result, name) \
result##Ref holder##Ref::name() const { \ result##Ref holder##Ref::name() const { \
IF_BROKER_DISABLED_ACCESS_HANDLE(holder, result, name); \ IF_ACCESS_FROM_HEAP(holder, result, name); \
return result##Ref(broker(), ObjectRef::data()->As##holder()->name()); \ ObjectData* data = ObjectRef::data()->As##holder()->name(); \
if (data->kind() == ObjectDataKind::kUnserializedHeapObject) { \
return result##Ref(broker(), data->object()); \
} else { \
return result##Ref(broker(), ObjectRef::data()->As##holder()->name()); \
} \
} }
// Like above except that the result type is not an XYZRef. // Like above except that the result type is not an XYZRef.
#define BIMODAL_ACCESSOR_C(holder, result, name) \ #define BIMODAL_ACCESSOR_C(holder, result, name) \
result holder##Ref::name() const { \ result holder##Ref::name() const { \
IF_BROKER_DISABLED_ACCESS_HANDLE_C(holder, name); \ IF_ACCESS_FROM_HEAP_C(holder, name); \
return ObjectRef::data()->As##holder()->name(); \ return ObjectRef::data()->As##holder()->name(); \
} }
// Like above but for BitFields. // Like above but for BitFields.
#define BIMODAL_ACCESSOR_B(holder, field, name, BitField) \ #define BIMODAL_ACCESSOR_B(holder, field, name, BitField) \
typename BitField::FieldType holder##Ref::name() const { \ typename BitField::FieldType holder##Ref::name() const { \
IF_BROKER_DISABLED_ACCESS_HANDLE_C(holder, name); \ IF_ACCESS_FROM_HEAP_C(holder, name); \
return BitField::decode(ObjectRef::data()->As##holder()->field()); \ return BitField::decode(ObjectRef::data()->As##holder()->field()); \
} }
...@@ -3335,7 +3413,8 @@ BIMODAL_ACCESSOR(PropertyCell, Object, value) ...@@ -3335,7 +3413,8 @@ BIMODAL_ACCESSOR(PropertyCell, Object, value)
BIMODAL_ACCESSOR_C(PropertyCell, PropertyDetails, property_details) BIMODAL_ACCESSOR_C(PropertyCell, PropertyDetails, property_details)
base::Optional<CallHandlerInfoRef> FunctionTemplateInfoRef::call_code() const { base::Optional<CallHandlerInfoRef> FunctionTemplateInfoRef::call_code() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
return CallHandlerInfoRef( return CallHandlerInfoRef(
broker(), handle(object()->call_code(), broker()->isolate())); broker(), handle(object()->call_code(), broker()->isolate()));
} }
...@@ -3346,9 +3425,12 @@ base::Optional<CallHandlerInfoRef> FunctionTemplateInfoRef::call_code() const { ...@@ -3346,9 +3425,12 @@ base::Optional<CallHandlerInfoRef> FunctionTemplateInfoRef::call_code() const {
} }
bool FunctionTemplateInfoRef::is_signature_undefined() const { bool FunctionTemplateInfoRef::is_signature_undefined() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference allow_handle_dereference; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleAllocation allow_handle_allocation; AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
broker()->mode());
return object()->signature().IsUndefined(broker()->isolate()); return object()->signature().IsUndefined(broker()->isolate());
} }
...@@ -3356,9 +3438,12 @@ bool FunctionTemplateInfoRef::is_signature_undefined() const { ...@@ -3356,9 +3438,12 @@ bool FunctionTemplateInfoRef::is_signature_undefined() const {
} }
bool FunctionTemplateInfoRef::has_call_code() const { bool FunctionTemplateInfoRef::has_call_code() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference allow_handle_dereference; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleAllocation allow_handle_allocation; AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
broker()->mode());
CallOptimization call_optimization(broker()->isolate(), object()); CallOptimization call_optimization(broker()->isolate(), object());
return call_optimization.is_simple_api_call(); return call_optimization.is_simple_api_call();
...@@ -3372,9 +3457,12 @@ HolderLookupResult FunctionTemplateInfoRef::LookupHolderOfExpectedType( ...@@ -3372,9 +3457,12 @@ HolderLookupResult FunctionTemplateInfoRef::LookupHolderOfExpectedType(
MapRef receiver_map, SerializationPolicy policy) { MapRef receiver_map, SerializationPolicy policy) {
const HolderLookupResult not_found; const HolderLookupResult not_found;
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference allow_handle_dereference; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleAllocation allow_handle_allocation; AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
broker()->mode());
CallOptimization call_optimization(broker()->isolate(), object()); CallOptimization call_optimization(broker()->isolate(), object());
Handle<Map> receiver_map_ref(receiver_map.object()); Handle<Map> receiver_map_ref(receiver_map.object());
...@@ -3453,8 +3541,9 @@ BIMODAL_ACCESSOR(FeedbackCell, HeapObject, value) ...@@ -3453,8 +3541,9 @@ BIMODAL_ACCESSOR(FeedbackCell, HeapObject, value)
base::Optional<ObjectRef> MapRef::GetStrongValue( base::Optional<ObjectRef> MapRef::GetStrongValue(
InternalIndex descriptor_index) const { InternalIndex descriptor_index) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference allow_handle_dereference; AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
MaybeObject value = MaybeObject value =
object()->instance_descriptors().GetValue(descriptor_index); object()->instance_descriptors().GetValue(descriptor_index);
HeapObject object; HeapObject object;
...@@ -3471,16 +3560,22 @@ base::Optional<ObjectRef> MapRef::GetStrongValue( ...@@ -3471,16 +3560,22 @@ base::Optional<ObjectRef> MapRef::GetStrongValue(
} }
void MapRef::SerializeRootMap() { void MapRef::SerializeRootMap() {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; if (data_->should_access_heap()) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsMap()->SerializeRootMap(broker()); data()->AsMap()->SerializeRootMap(broker());
} }
base::Optional<MapRef> MapRef::FindRootMap() const { base::Optional<MapRef> MapRef::FindRootMap() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) {
AllowHandleDereference allow_handle_dereference; AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return MapRef(broker(), handle(object()->FindRootMap(broker()->isolate()), return MapRef(broker(), handle(object()->FindRootMap(broker()->isolate()),
broker()->isolate())); broker()->isolate()));
} else if (data_->kind() == ObjectDataKind::kUnserializedReadOnlyHeapObject) {
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return MapRef(broker(), broker()->GetRootHandle(
object()->FindRootMap(broker()->isolate())));
} }
MapData* map_data = data()->AsMap()->FindRootMap(); MapData* map_data = data()->AsMap()->FindRootMap();
if (map_data) { if (map_data) {
...@@ -3491,58 +3586,59 @@ base::Optional<MapRef> MapRef::FindRootMap() const { ...@@ -3491,58 +3586,59 @@ base::Optional<MapRef> MapRef::FindRootMap() const {
} }
void* JSTypedArrayRef::data_ptr() const { void* JSTypedArrayRef::data_ptr() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference allow_handle_dereference; AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return object()->DataPtr(); return object()->DataPtr();
} }
return data()->AsJSTypedArray()->data_ptr(); return data()->AsJSTypedArray()->data_ptr();
} }
bool MapRef::IsInobjectSlackTrackingInProgress() const { bool MapRef::IsInobjectSlackTrackingInProgress() const {
IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, IsInobjectSlackTrackingInProgress); IF_ACCESS_FROM_HEAP_C(Map, IsInobjectSlackTrackingInProgress);
return Map::ConstructionCounterBits::decode(data()->AsMap()->bit_field3()) != return Map::ConstructionCounterBits::decode(data()->AsMap()->bit_field3()) !=
Map::kNoSlackTracking; Map::kNoSlackTracking;
} }
int MapRef::constructor_function_index() const { int MapRef::constructor_function_index() const {
IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, GetConstructorFunctionIndex); IF_ACCESS_FROM_HEAP_C(Map, GetConstructorFunctionIndex);
CHECK(IsPrimitiveMap()); CHECK(IsPrimitiveMap());
return data()->AsMap()->constructor_function_index(); return data()->AsMap()->constructor_function_index();
} }
bool MapRef::is_stable() const { bool MapRef::is_stable() const {
IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, is_stable); IF_ACCESS_FROM_HEAP_C(Map, is_stable);
return !Map::IsUnstableBit::decode(data()->AsMap()->bit_field3()); return !Map::IsUnstableBit::decode(data()->AsMap()->bit_field3());
} }
bool MapRef::CanBeDeprecated() const { bool MapRef::CanBeDeprecated() const {
IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, CanBeDeprecated); IF_ACCESS_FROM_HEAP_C(Map, CanBeDeprecated);
CHECK_GT(NumberOfOwnDescriptors(), 0); CHECK_GT(NumberOfOwnDescriptors(), 0);
return data()->AsMap()->can_be_deprecated(); return data()->AsMap()->can_be_deprecated();
} }
bool MapRef::CanTransition() const { bool MapRef::CanTransition() const {
IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, CanTransition); IF_ACCESS_FROM_HEAP_C(Map, CanTransition);
return data()->AsMap()->can_transition(); return data()->AsMap()->can_transition();
} }
int MapRef::GetInObjectPropertiesStartInWords() const { int MapRef::GetInObjectPropertiesStartInWords() const {
IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, GetInObjectPropertiesStartInWords); IF_ACCESS_FROM_HEAP_C(Map, GetInObjectPropertiesStartInWords);
return data()->AsMap()->in_object_properties_start_in_words(); return data()->AsMap()->in_object_properties_start_in_words();
} }
int MapRef::GetInObjectProperties() const { int MapRef::GetInObjectProperties() const {
IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, GetInObjectProperties); IF_ACCESS_FROM_HEAP_C(Map, GetInObjectProperties);
return data()->AsMap()->in_object_properties(); return data()->AsMap()->in_object_properties();
} }
int ScopeInfoRef::ContextLength() const { int ScopeInfoRef::ContextLength() const {
IF_BROKER_DISABLED_ACCESS_HANDLE_C(ScopeInfo, ContextLength); IF_ACCESS_FROM_HEAP_C(ScopeInfo, ContextLength);
return data()->AsScopeInfo()->context_length(); return data()->AsScopeInfo()->context_length();
} }
int ScopeInfoRef::Flags() const { int ScopeInfoRef::Flags() const {
IF_BROKER_DISABLED_ACCESS_HANDLE_C(ScopeInfo, Flags); IF_ACCESS_FROM_HEAP_C(ScopeInfo, Flags);
return data()->AsScopeInfo()->flags(); return data()->AsScopeInfo()->flags();
} }
...@@ -3551,14 +3647,17 @@ bool ScopeInfoRef::HasContextExtension() const { ...@@ -3551,14 +3647,17 @@ bool ScopeInfoRef::HasContextExtension() const {
} }
bool ScopeInfoRef::HasOuterScopeInfo() const { bool ScopeInfoRef::HasOuterScopeInfo() const {
IF_BROKER_DISABLED_ACCESS_HANDLE_C(ScopeInfo, HasOuterScopeInfo); IF_ACCESS_FROM_HEAP_C(ScopeInfo, HasOuterScopeInfo);
return data()->AsScopeInfo()->has_outer_scope_info(); return data()->AsScopeInfo()->has_outer_scope_info();
} }
ScopeInfoRef ScopeInfoRef::OuterScopeInfo() const { ScopeInfoRef ScopeInfoRef::OuterScopeInfo() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleAllocation handle_allocation; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleDereference handle_dereference; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return ScopeInfoRef( return ScopeInfoRef(
broker(), handle(object()->OuterScopeInfo(), broker()->isolate())); broker(), handle(object()->OuterScopeInfo(), broker()->isolate()));
} }
...@@ -3571,26 +3670,29 @@ void ScopeInfoRef::SerializeScopeInfoChain() { ...@@ -3571,26 +3670,29 @@ void ScopeInfoRef::SerializeScopeInfoChain() {
} }
bool StringRef::IsExternalString() const { bool StringRef::IsExternalString() const {
IF_BROKER_DISABLED_ACCESS_HANDLE_C(String, IsExternalString); IF_ACCESS_FROM_HEAP_C(String, IsExternalString);
return data()->AsString()->is_external_string(); return data()->AsString()->is_external_string();
} }
Address CallHandlerInfoRef::callback() const { Address CallHandlerInfoRef::callback() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
return v8::ToCData<Address>(object()->callback()); return v8::ToCData<Address>(object()->callback());
} }
return HeapObjectRef::data()->AsCallHandlerInfo()->callback(); return HeapObjectRef::data()->AsCallHandlerInfo()->callback();
} }
bool StringRef::IsSeqString() const { bool StringRef::IsSeqString() const {
IF_BROKER_DISABLED_ACCESS_HANDLE_C(String, IsSeqString); IF_ACCESS_FROM_HEAP_C(String, IsSeqString);
return data()->AsString()->is_seq_string(); return data()->AsString()->is_seq_string();
} }
ScopeInfoRef NativeContextRef::scope_info() const { ScopeInfoRef NativeContextRef::scope_info() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleAllocation handle_allocation; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleDereference handle_dereference; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return ScopeInfoRef(broker(), return ScopeInfoRef(broker(),
handle(object()->scope_info(), broker()->isolate())); handle(object()->scope_info(), broker()->isolate()));
} }
...@@ -3600,7 +3702,7 @@ ScopeInfoRef NativeContextRef::scope_info() const { ...@@ -3600,7 +3702,7 @@ ScopeInfoRef NativeContextRef::scope_info() const {
MapRef NativeContextRef::GetFunctionMapFromIndex(int index) const { MapRef NativeContextRef::GetFunctionMapFromIndex(int index) const {
DCHECK_GE(index, Context::FIRST_FUNCTION_MAP_INDEX); DCHECK_GE(index, Context::FIRST_FUNCTION_MAP_INDEX);
DCHECK_LE(index, Context::LAST_FUNCTION_MAP_INDEX); DCHECK_LE(index, Context::LAST_FUNCTION_MAP_INDEX);
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
return get(index).value().AsMap(); return get(index).value().AsMap();
} }
return MapRef(broker(), data()->AsNativeContext()->function_maps().at( return MapRef(broker(), data()->AsNativeContext()->function_maps().at(
...@@ -3654,8 +3756,9 @@ bool ObjectRef::IsNullOrUndefined() const { ...@@ -3654,8 +3756,9 @@ bool ObjectRef::IsNullOrUndefined() const {
} }
bool ObjectRef::BooleanValue() const { bool ObjectRef::BooleanValue() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference allow_handle_dereference; AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return object()->BooleanValue(broker()->isolate()); return object()->BooleanValue(broker()->isolate());
} }
return IsSmi() ? (AsSmi() != 0) : data()->AsHeapObject()->boolean_value(); return IsSmi() ? (AsSmi() != 0) : data()->AsHeapObject()->boolean_value();
...@@ -3692,6 +3795,14 @@ base::Optional<ObjectRef> ObjectRef::GetOwnConstantElement( ...@@ -3692,6 +3795,14 @@ base::Optional<ObjectRef> ObjectRef::GetOwnConstantElement(
return (IsJSObject() || IsString()) return (IsJSObject() || IsString())
? GetOwnElementFromHeap(broker(), object(), index, true) ? GetOwnElementFromHeap(broker(), object(), index, true)
: base::nullopt; : base::nullopt;
} else if (data_->kind() == ObjectDataKind::kUnserializedReadOnlyHeapObject) {
DCHECK(!IsJSObject());
// TODO(mythria): For ReadOnly strings, currently we cannot access data from
// heap without creating handles since we use LookupIterator. We should have
// a custom implementation for read only strings that doesn't create
// handles. Till then it is OK to disable this optimization since this only
// impacts keyed accesses on read only strings.
return base::nullopt;
} }
ObjectData* element = nullptr; ObjectData* element = nullptr;
if (IsJSObject()) { if (IsJSObject()) {
...@@ -3707,7 +3818,8 @@ base::Optional<ObjectRef> ObjectRef::GetOwnConstantElement( ...@@ -3707,7 +3818,8 @@ base::Optional<ObjectRef> ObjectRef::GetOwnConstantElement(
base::Optional<ObjectRef> JSObjectRef::GetOwnDataProperty( base::Optional<ObjectRef> JSObjectRef::GetOwnDataProperty(
Representation field_representation, FieldIndex index, Representation field_representation, FieldIndex index,
SerializationPolicy policy) const { SerializationPolicy policy) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
return GetOwnDataPropertyFromHeap(broker(), return GetOwnDataPropertyFromHeap(broker(),
Handle<JSObject>::cast(object()), Handle<JSObject>::cast(object()),
field_representation, index); field_representation, index);
...@@ -3720,7 +3832,7 @@ base::Optional<ObjectRef> JSObjectRef::GetOwnDataProperty( ...@@ -3720,7 +3832,7 @@ base::Optional<ObjectRef> JSObjectRef::GetOwnDataProperty(
base::Optional<ObjectRef> JSArrayRef::GetOwnCowElement( base::Optional<ObjectRef> JSArrayRef::GetOwnCowElement(
uint32_t index, SerializationPolicy policy) const { uint32_t index, SerializationPolicy policy) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
if (!object()->elements().IsCowArray()) return base::nullopt; if (!object()->elements().IsCowArray()) return base::nullopt;
return GetOwnElementFromHeap(broker(), object(), index, false); return GetOwnElementFromHeap(broker(), object(), index, false);
} }
...@@ -3740,19 +3852,22 @@ base::Optional<ObjectRef> JSArrayRef::GetOwnCowElement( ...@@ -3740,19 +3852,22 @@ base::Optional<ObjectRef> JSArrayRef::GetOwnCowElement(
} }
double HeapNumberRef::value() const { double HeapNumberRef::value() const {
IF_BROKER_DISABLED_ACCESS_HANDLE_C(HeapNumber, value); IF_ACCESS_FROM_HEAP_C(HeapNumber, value);
return data()->AsHeapNumber()->value(); return data()->AsHeapNumber()->value();
} }
uint64_t BigIntRef::AsUint64() const { uint64_t BigIntRef::AsUint64() const {
IF_BROKER_DISABLED_ACCESS_HANDLE_C(BigInt, AsUint64); IF_ACCESS_FROM_HEAP_C(BigInt, AsUint64);
return data()->AsBigInt()->AsUint64(); return data()->AsBigInt()->AsUint64();
} }
base::Optional<CellRef> SourceTextModuleRef::GetCell(int cell_index) const { base::Optional<CellRef> SourceTextModuleRef::GetCell(int cell_index) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleAllocation handle_allocation; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleDereference allow_handle_dereference; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return CellRef(broker(), return CellRef(broker(),
handle(object()->GetCell(cell_index), broker()->isolate())); handle(object()->GetCell(cell_index), broker()->isolate()));
} }
...@@ -3765,9 +3880,10 @@ ObjectRef::ObjectRef(JSHeapBroker* broker, Handle<Object> object, ...@@ -3765,9 +3880,10 @@ ObjectRef::ObjectRef(JSHeapBroker* broker, Handle<Object> object,
bool check_type) bool check_type)
: broker_(broker) { : broker_(broker) {
switch (broker->mode()) { switch (broker->mode()) {
// We may have to create data in JSHeapBroker::kSerialized as well since we
// read the data from read only heap objects directly instead of serializing
// them.
case JSHeapBroker::kSerialized: case JSHeapBroker::kSerialized:
data_ = broker->GetData(object);
break;
case JSHeapBroker::kSerializing: case JSHeapBroker::kSerializing:
data_ = broker->GetOrCreateData(object); data_ = broker->GetOrCreateData(object);
break; break;
...@@ -3776,7 +3892,8 @@ ObjectRef::ObjectRef(JSHeapBroker* broker, Handle<Object> object, ...@@ -3776,7 +3892,8 @@ ObjectRef::ObjectRef(JSHeapBroker* broker, Handle<Object> object,
broker->refs_->LookupOrInsert(object.address(), broker->zone()); broker->refs_->LookupOrInsert(object.address(), broker->zone());
ObjectData** storage = &(entry->value); ObjectData** storage = &(entry->value);
if (*storage == nullptr) { if (*storage == nullptr) {
AllowHandleDereference handle_dereference; AllowHandleDereferenceIf allow_handle_dereference(
kUnserializedHeapObject, broker->mode());
entry->value = new (broker->zone()) entry->value = new (broker->zone())
ObjectData(broker, storage, object, ObjectData(broker, storage, object,
object->IsSmi() ? kSmi : kUnserializedHeapObject); object->IsSmi() ? kSmi : kUnserializedHeapObject);
...@@ -3788,7 +3905,8 @@ ObjectRef::ObjectRef(JSHeapBroker* broker, Handle<Object> object, ...@@ -3788,7 +3905,8 @@ ObjectRef::ObjectRef(JSHeapBroker* broker, Handle<Object> object,
UNREACHABLE(); UNREACHABLE();
} }
if (!data_) { // TODO(mslekova): Remove once we're on the background thread. if (!data_) { // TODO(mslekova): Remove once we're on the background thread.
AllowHandleDereference handle_dereference; AllowHandleDereferenceIf allow_handle_dereference(data_->kind(),
broker->mode());
object->Print(); object->Print();
} }
CHECK_WITH_MSG(data_ != nullptr, "Object is not known to the heap broker"); CHECK_WITH_MSG(data_ != nullptr, "Object is not known to the heap broker");
...@@ -3823,8 +3941,9 @@ OddballType GetOddballType(Isolate* isolate, Map map) { ...@@ -3823,8 +3941,9 @@ OddballType GetOddballType(Isolate* isolate, Map map) {
} // namespace } // namespace
HeapObjectType HeapObjectRef::GetHeapObjectType() const { HeapObjectType HeapObjectRef::GetHeapObjectType() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleDereference handle_dereference; AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
Map map = Handle<HeapObject>::cast(object())->map(); Map map = Handle<HeapObject>::cast(object())->map();
HeapObjectType::Flags flags(0); HeapObjectType::Flags flags(0);
if (map.is_undetectable()) flags |= HeapObjectType::kUndetectable; if (map.is_undetectable()) flags |= HeapObjectType::kUndetectable;
...@@ -3838,9 +3957,12 @@ HeapObjectType HeapObjectRef::GetHeapObjectType() const { ...@@ -3838,9 +3957,12 @@ HeapObjectType HeapObjectRef::GetHeapObjectType() const {
return HeapObjectType(map().instance_type(), flags, map().oddball_type()); return HeapObjectType(map().instance_type(), flags, map().oddball_type());
} }
base::Optional<JSObjectRef> AllocationSiteRef::boilerplate() const { base::Optional<JSObjectRef> AllocationSiteRef::boilerplate() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleAllocation handle_allocation; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleDereference allow_handle_dereference; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return JSObjectRef(broker(), return JSObjectRef(broker(),
handle(object()->boilerplate(), broker()->isolate())); handle(object()->boilerplate(), broker()->isolate()));
} }
...@@ -3857,17 +3979,25 @@ ElementsKind JSObjectRef::GetElementsKind() const { ...@@ -3857,17 +3979,25 @@ ElementsKind JSObjectRef::GetElementsKind() const {
} }
FixedArrayBaseRef JSObjectRef::elements() const { FixedArrayBaseRef JSObjectRef::elements() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleAllocation handle_allocation; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleDereference allow_handle_dereference; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return FixedArrayBaseRef(broker(), return FixedArrayBaseRef(broker(),
handle(object()->elements(), broker()->isolate())); handle(object()->elements(), broker()->isolate()));
} }
return FixedArrayBaseRef(broker(), data()->AsJSObject()->elements()); ObjectData* elements_data = data()->AsJSObject()->elements();
if (elements_data->kind() ==
ObjectDataKind::kUnserializedReadOnlyHeapObject) {
return FixedArrayBaseRef(broker(), elements_data->object());
}
return FixedArrayBaseRef(broker(), elements_data->AsFixedArrayBase());
} }
int FixedArrayBaseRef::length() const { int FixedArrayBaseRef::length() const {
IF_BROKER_DISABLED_ACCESS_HANDLE_C(FixedArrayBase, length); IF_ACCESS_FROM_HEAP_C(FixedArrayBase, length);
return data()->AsFixedArrayBase()->length(); return data()->AsFixedArrayBase()->length();
} }
...@@ -3892,28 +4022,28 @@ bool NameRef::IsUniqueName() const { ...@@ -3892,28 +4022,28 @@ bool NameRef::IsUniqueName() const {
} }
ObjectRef JSRegExpRef::data() const { ObjectRef JSRegExpRef::data() const {
IF_BROKER_DISABLED_ACCESS_HANDLE(JSRegExp, Object, data); IF_ACCESS_FROM_HEAP(JSRegExp, Object, data);
return ObjectRef(broker(), ObjectRef::data()->AsJSRegExp()->data()); return ObjectRef(broker(), ObjectRef::data()->AsJSRegExp()->data());
} }
ObjectRef JSRegExpRef::flags() const { ObjectRef JSRegExpRef::flags() const {
IF_BROKER_DISABLED_ACCESS_HANDLE(JSRegExp, Object, flags); IF_ACCESS_FROM_HEAP(JSRegExp, Object, flags);
return ObjectRef(broker(), ObjectRef::data()->AsJSRegExp()->flags()); return ObjectRef(broker(), ObjectRef::data()->AsJSRegExp()->flags());
} }
ObjectRef JSRegExpRef::last_index() const { ObjectRef JSRegExpRef::last_index() const {
IF_BROKER_DISABLED_ACCESS_HANDLE(JSRegExp, Object, last_index); IF_ACCESS_FROM_HEAP(JSRegExp, Object, last_index);
return ObjectRef(broker(), ObjectRef::data()->AsJSRegExp()->last_index()); return ObjectRef(broker(), ObjectRef::data()->AsJSRegExp()->last_index());
} }
ObjectRef JSRegExpRef::raw_properties_or_hash() const { ObjectRef JSRegExpRef::raw_properties_or_hash() const {
IF_BROKER_DISABLED_ACCESS_HANDLE(JSRegExp, Object, raw_properties_or_hash); IF_ACCESS_FROM_HEAP(JSRegExp, Object, raw_properties_or_hash);
return ObjectRef(broker(), return ObjectRef(broker(),
ObjectRef::data()->AsJSRegExp()->raw_properties_or_hash()); ObjectRef::data()->AsJSRegExp()->raw_properties_or_hash());
} }
ObjectRef JSRegExpRef::source() const { ObjectRef JSRegExpRef::source() const {
IF_BROKER_DISABLED_ACCESS_HANDLE(JSRegExp, Object, source); IF_ACCESS_FROM_HEAP(JSRegExp, Object, source);
return ObjectRef(broker(), ObjectRef::data()->AsJSRegExp()->source()); return ObjectRef(broker(), ObjectRef::data()->AsJSRegExp()->source());
} }
...@@ -4018,18 +4148,21 @@ void NativeContextData::Serialize(JSHeapBroker* broker) { ...@@ -4018,18 +4148,21 @@ void NativeContextData::Serialize(JSHeapBroker* broker) {
} }
void JSFunctionRef::Serialize() { void JSFunctionRef::Serialize() {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
if (data_->should_access_heap()) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsJSFunction()->Serialize(broker()); data()->AsJSFunction()->Serialize(broker());
} }
bool JSBoundFunctionRef::serialized() const { bool JSBoundFunctionRef::serialized() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return true; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
if (data_->should_access_heap()) return true;
return data()->AsJSBoundFunction()->serialized(); return data()->AsJSBoundFunction()->serialized();
} }
bool JSFunctionRef::serialized() const { bool JSFunctionRef::serialized() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return true; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
if (data_->should_access_heap()) return true;
return data()->AsJSFunction()->serialized(); return data()->AsJSFunction()->serialized();
} }
...@@ -4047,9 +4180,12 @@ JSArrayRef SharedFunctionInfoRef::GetTemplateObject( ...@@ -4047,9 +4180,12 @@ JSArrayRef SharedFunctionInfoRef::GetTemplateObject(
return feedback.AsTemplateObject().value(); return feedback.AsTemplateObject().value();
} }
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleAllocation handle_allocation; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleDereference allow_handle_dereference; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
Handle<JSArray> template_object = Handle<JSArray> template_object =
TemplateObjectDescription::GetTemplateObject( TemplateObjectDescription::GetTemplateObject(
isolate(), broker()->target_native_context().object(), isolate(), broker()->target_native_context().object(),
...@@ -4085,7 +4221,8 @@ void SharedFunctionInfoRef::SerializeScopeInfoChain() { ...@@ -4085,7 +4221,8 @@ void SharedFunctionInfoRef::SerializeScopeInfoChain() {
base::Optional<FunctionTemplateInfoRef> base::Optional<FunctionTemplateInfoRef>
SharedFunctionInfoRef::function_template_info() const { SharedFunctionInfoRef::function_template_info() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
if (object()->IsApiFunction()) { if (object()->IsApiFunction()) {
return FunctionTemplateInfoRef( return FunctionTemplateInfoRef(
broker(), handle(object()->function_data(), broker()->isolate())); broker(), handle(object()->function_data(), broker()->isolate()));
...@@ -4099,15 +4236,17 @@ SharedFunctionInfoRef::function_template_info() const { ...@@ -4099,15 +4236,17 @@ SharedFunctionInfoRef::function_template_info() const {
} }
int SharedFunctionInfoRef::context_header_size() const { int SharedFunctionInfoRef::context_header_size() const {
IF_BROKER_DISABLED_ACCESS_HANDLE_C(SharedFunctionInfo, IF_ACCESS_FROM_HEAP_C(SharedFunctionInfo, scope_info().ContextHeaderLength);
scope_info().ContextHeaderLength);
return data()->AsSharedFunctionInfo()->context_header_size(); return data()->AsSharedFunctionInfo()->context_header_size();
} }
ScopeInfoRef SharedFunctionInfoRef::scope_info() const { ScopeInfoRef SharedFunctionInfoRef::scope_info() const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
AllowHandleAllocation handle_allocation; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
AllowHandleDereference handle_dereference; AllowHandleAllocationIf allow_handle_allocation(data()->kind(),
broker()->mode());
AllowHandleDereferenceIf allow_handle_dereference(data()->kind(),
broker()->mode());
return ScopeInfoRef(broker(), return ScopeInfoRef(broker(),
handle(object()->scope_info(), broker()->isolate())); handle(object()->scope_info(), broker()->isolate()));
} }
...@@ -4115,26 +4254,27 @@ ScopeInfoRef SharedFunctionInfoRef::scope_info() const { ...@@ -4115,26 +4254,27 @@ ScopeInfoRef SharedFunctionInfoRef::scope_info() const {
} }
void JSObjectRef::SerializeObjectCreateMap() { void JSObjectRef::SerializeObjectCreateMap() {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
if (data_->should_access_heap()) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsJSObject()->SerializeObjectCreateMap(broker()); data()->AsJSObject()->SerializeObjectCreateMap(broker());
} }
void MapRef::SerializeOwnDescriptors() { void MapRef::SerializeOwnDescriptors() {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; if (data_->should_access_heap()) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsMap()->SerializeOwnDescriptors(broker()); data()->AsMap()->SerializeOwnDescriptors(broker());
} }
void MapRef::SerializeOwnDescriptor(InternalIndex descriptor_index) { void MapRef::SerializeOwnDescriptor(InternalIndex descriptor_index) {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; if (data_->should_access_heap()) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsMap()->SerializeOwnDescriptor(broker(), descriptor_index); data()->AsMap()->SerializeOwnDescriptor(broker(), descriptor_index);
} }
bool MapRef::serialized_own_descriptor(InternalIndex descriptor_index) const { bool MapRef::serialized_own_descriptor(InternalIndex descriptor_index) const {
CHECK_LT(descriptor_index.as_int(), NumberOfOwnDescriptors()); CHECK_LT(descriptor_index.as_int(), NumberOfOwnDescriptors());
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return true; if (data_->should_access_heap()) return true;
DescriptorArrayData* desc_array_data = DescriptorArrayData* desc_array_data =
data()->AsMap()->instance_descriptors(); data()->AsMap()->instance_descriptors();
if (!desc_array_data) return false; if (!desc_array_data) return false;
...@@ -4143,36 +4283,39 @@ bool MapRef::serialized_own_descriptor(InternalIndex descriptor_index) const { ...@@ -4143,36 +4283,39 @@ bool MapRef::serialized_own_descriptor(InternalIndex descriptor_index) const {
} }
void MapRef::SerializeBackPointer() { void MapRef::SerializeBackPointer() {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; if (data_->should_access_heap()) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsMap()->SerializeBackPointer(broker()); data()->AsMap()->SerializeBackPointer(broker());
} }
void MapRef::SerializePrototype() { void MapRef::SerializePrototype() {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; if (data_->should_access_heap()) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsMap()->SerializePrototype(broker()); data()->AsMap()->SerializePrototype(broker());
} }
bool MapRef::serialized_prototype() const { bool MapRef::serialized_prototype() const {
CHECK_NE(broker()->mode(), JSHeapBroker::kDisabled); CHECK_NE(broker()->mode(), JSHeapBroker::kDisabled);
if (data_->should_access_heap()) return true;
return data()->AsMap()->serialized_prototype(); return data()->AsMap()->serialized_prototype();
} }
void SourceTextModuleRef::Serialize() { void SourceTextModuleRef::Serialize() {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
if (data_->should_access_heap()) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsSourceTextModule()->Serialize(broker()); data()->AsSourceTextModule()->Serialize(broker());
} }
void NativeContextRef::Serialize() { void NativeContextRef::Serialize() {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
if (data_->should_access_heap()) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsNativeContext()->Serialize(broker()); data()->AsNativeContext()->Serialize(broker());
} }
void JSTypedArrayRef::Serialize() { void JSTypedArrayRef::Serialize() {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; if (data_->should_access_heap()) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsJSTypedArray()->Serialize(broker()); data()->AsJSTypedArray()->Serialize(broker());
} }
...@@ -4183,26 +4326,30 @@ bool JSTypedArrayRef::serialized() const { ...@@ -4183,26 +4326,30 @@ bool JSTypedArrayRef::serialized() const {
} }
void JSBoundFunctionRef::Serialize() { void JSBoundFunctionRef::Serialize() {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
if (data_->should_access_heap()) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsJSBoundFunction()->Serialize(broker()); data()->AsJSBoundFunction()->Serialize(broker());
} }
void PropertyCellRef::Serialize() { void PropertyCellRef::Serialize() {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
if (data_->should_access_heap()) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsPropertyCell()->Serialize(broker()); data()->AsPropertyCell()->Serialize(broker());
} }
void FunctionTemplateInfoRef::SerializeCallCode() { void FunctionTemplateInfoRef::SerializeCallCode() {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
if (data_->should_access_heap()) return;
CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
data()->AsFunctionTemplateInfo()->SerializeCallCode(broker()); data()->AsFunctionTemplateInfo()->SerializeCallCode(broker());
} }
base::Optional<PropertyCellRef> JSGlobalObjectRef::GetPropertyCell( base::Optional<PropertyCellRef> JSGlobalObjectRef::GetPropertyCell(
NameRef const& name, SerializationPolicy policy) const { NameRef const& name, SerializationPolicy policy) const {
if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (data_->should_access_heap()) {
DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject);
return GetPropertyCellFromHeap(broker(), name.object()); return GetPropertyCellFromHeap(broker(), name.object());
} }
PropertyCellData* property_cell_data = PropertyCellData* property_cell_data =
...@@ -4910,7 +5057,8 @@ std::ostream& operator<<(std::ostream& os, const ObjectRef& ref) { ...@@ -4910,7 +5057,8 @@ std::ostream& operator<<(std::ostream& os, const ObjectRef& ref) {
if (ref.data_->kind() == ObjectDataKind::kUnserializedHeapObject || if (ref.data_->kind() == ObjectDataKind::kUnserializedHeapObject ||
!FLAG_concurrent_recompilation) { !FLAG_concurrent_recompilation) {
// We cannot be in a background thread so it's safe to read the heap. // We cannot be in a background thread so it's safe to read the heap.
AllowHandleDereference allow_handle_dereference; AllowHandleDereferenceIf allow_handle_dereference(ref.data()->kind(),
ref.broker()->mode());
return os << ref.data() << " {" << ref.object() << "}"; return os << ref.data() << " {" << ref.object() << "}";
} else { } else {
return os << ref.data(); return os << ref.data();
...@@ -5010,7 +5158,7 @@ TemplateObjectFeedback const& ProcessedFeedback::AsTemplateObject() const { ...@@ -5010,7 +5158,7 @@ TemplateObjectFeedback const& ProcessedFeedback::AsTemplateObject() const {
BytecodeAnalysis const& JSHeapBroker::GetBytecodeAnalysis( BytecodeAnalysis const& JSHeapBroker::GetBytecodeAnalysis(
Handle<BytecodeArray> bytecode_array, BailoutId osr_bailout_id, Handle<BytecodeArray> bytecode_array, BailoutId osr_bailout_id,
bool analyze_liveness, SerializationPolicy policy) { bool analyze_liveness, SerializationPolicy policy) {
ObjectData* bytecode_array_data = GetData(bytecode_array); ObjectData* bytecode_array_data = GetOrCreateData(bytecode_array);
CHECK_NOT_NULL(bytecode_array_data); CHECK_NOT_NULL(bytecode_array_data);
auto it = bytecode_analyses_.find(bytecode_array_data); auto it = bytecode_analyses_.find(bytecode_array_data);
...@@ -5070,8 +5218,8 @@ Smi OffHeapBytecodeArray::GetConstantAtIndexAsSmi(int index) const { ...@@ -5070,8 +5218,8 @@ Smi OffHeapBytecodeArray::GetConstantAtIndexAsSmi(int index) const {
#undef BIMODAL_ACCESSOR #undef BIMODAL_ACCESSOR
#undef BIMODAL_ACCESSOR_B #undef BIMODAL_ACCESSOR_B
#undef BIMODAL_ACCESSOR_C #undef BIMODAL_ACCESSOR_C
#undef IF_BROKER_DISABLED_ACCESS_HANDLE #undef IF_ACCESS_FROM_HEAP
#undef IF_BROKER_DISABLED_ACCESS_HANDLE_C #undef IF_ACCESS_FROM_HEAP_C
#undef TRACE #undef TRACE
#undef TRACE_MISSING #undef TRACE_MISSING
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "src/objects/feedback-vector.h" #include "src/objects/feedback-vector.h"
#include "src/objects/function-kind.h" #include "src/objects/function-kind.h"
#include "src/objects/objects.h" #include "src/objects/objects.h"
#include "src/utils/address-map.h"
#include "src/utils/ostreams.h" #include "src/utils/ostreams.h"
#include "src/zone/zone-containers.h" #include "src/zone/zone-containers.h"
...@@ -84,7 +85,7 @@ class V8_EXPORT_PRIVATE JSHeapBroker { ...@@ -84,7 +85,7 @@ class V8_EXPORT_PRIVATE JSHeapBroker {
void InitializeAndStartSerializing(Handle<NativeContext> native_context); void InitializeAndStartSerializing(Handle<NativeContext> native_context);
Isolate* isolate() const { return isolate_; } Isolate* isolate() const { return isolate_; }
Zone* zone() const { return current_zone_; } Zone* zone() const { return zone_; }
bool tracing_enabled() const { return tracing_enabled_; } bool tracing_enabled() const { return tracing_enabled_; }
enum BrokerMode { kDisabled, kSerializing, kSerialized, kRetired }; enum BrokerMode { kDisabled, kSerializing, kSerialized, kRetired };
...@@ -97,8 +98,9 @@ class V8_EXPORT_PRIVATE JSHeapBroker { ...@@ -97,8 +98,9 @@ class V8_EXPORT_PRIVATE JSHeapBroker {
void PrintRefsAnalysis() const; void PrintRefsAnalysis() const;
#endif // DEBUG #endif // DEBUG
// Returns nullptr iff handle unknown. // Retruns the handle from root index table for read only heap objects.
ObjectData* GetData(Handle<Object>) const; Handle<Object> GetRootHandle(Object object);
// Never returns nullptr. // Never returns nullptr.
ObjectData* GetOrCreateData(Handle<Object>); ObjectData* GetOrCreateData(Handle<Object>);
// Like the previous but wraps argument in handle first (for convenience). // Like the previous but wraps argument in handle first (for convenience).
...@@ -193,6 +195,8 @@ class V8_EXPORT_PRIVATE JSHeapBroker { ...@@ -193,6 +195,8 @@ class V8_EXPORT_PRIVATE JSHeapBroker {
void IncrementTracingIndentation(); void IncrementTracingIndentation();
void DecrementTracingIndentation(); void DecrementTracingIndentation();
RootIndexMap const& root_index_map() { return root_index_map_; }
private: private:
friend class HeapObjectRef; friend class HeapObjectRef;
friend class ObjectRef; friend class ObjectRef;
...@@ -221,17 +225,18 @@ class V8_EXPORT_PRIVATE JSHeapBroker { ...@@ -221,17 +225,18 @@ class V8_EXPORT_PRIVATE JSHeapBroker {
ProcessedFeedback const& ReadFeedbackForTemplateObject( ProcessedFeedback const& ReadFeedbackForTemplateObject(
FeedbackSource const& source); FeedbackSource const& source);
void InitializeRefsMap();
void CollectArrayAndObjectPrototypes(); void CollectArrayAndObjectPrototypes();
void SerializeTypedArrayStringTags(); void SerializeTypedArrayStringTags();
PerIsolateCompilerCache* compiler_cache() const { return compiler_cache_; } PerIsolateCompilerCache* compiler_cache() const { return compiler_cache_; }
bool is_builtin_code(Object object);
Isolate* const isolate_; Isolate* const isolate_;
Zone* const broker_zone_; Zone* const zone_ = nullptr;
Zone* current_zone_ = nullptr;
base::Optional<NativeContextRef> target_native_context_; base::Optional<NativeContextRef> target_native_context_;
RefsMap* refs_; RefsMap* refs_;
RootIndexMap root_index_map_;
ZoneUnorderedSet<Handle<JSObject>, Handle<JSObject>::hash, ZoneUnorderedSet<Handle<JSObject>, Handle<JSObject>::hash,
Handle<JSObject>::equal_to> Handle<JSObject>::equal_to>
array_and_object_prototypes_; array_and_object_prototypes_;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment