Commit 9f18e55f authored by Mythri A's avatar Mythri A Committed by Commit Bot

[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/+/1955596Reviewed-by: 's avatarMichael Stanton <mvstanton@chromium.org>
Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Commit-Queue: Mythri Alle <mythria@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65490}
parent 3a0a4c13
...@@ -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,16 @@ class ObjectData : public ZoneObject { ...@@ -74,7 +130,16 @@ 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(broker->isolate()->handle_scope_data()->canonical_scope != nullptr ||
ReadOnlyHeap::Contains(HeapObject::cast(*object)) ||
(Code::cast(*object).is_builtin()));
} }
#define DECLARE_IS_AND_AS(Name) \ #define DECLARE_IS_AND_AS(Name) \
...@@ -86,6 +151,10 @@ class ObjectData : public ZoneObject { ...@@ -86,6 +151,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 +172,15 @@ class HeapObjectData : public ObjectData { ...@@ -103,14 +172,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 +342,12 @@ class JSObjectData : public JSReceiverData { ...@@ -272,11 +342,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 +369,7 @@ class JSObjectData : public JSReceiverData { ...@@ -298,7 +369,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 +379,7 @@ class JSObjectData : public JSReceiverData { ...@@ -308,7 +379,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 +411,7 @@ void JSObjectData::SerializeObjectCreateMap(JSHeapBroker* broker) { ...@@ -340,7 +411,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 +572,14 @@ class JSBoundFunctionData : public JSObjectData { ...@@ -501,14 +572,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 +599,7 @@ class JSFunctionData : public JSObjectData { ...@@ -528,7 +599,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 +618,7 @@ class JSFunctionData : public JSObjectData { ...@@ -547,7 +618,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 +1164,19 @@ HeapObjectData::HeapObjectData(JSHeapBroker* broker, ObjectData** storage, ...@@ -1093,10 +1164,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 +1272,16 @@ void JSFunctionData::Serialize(JSHeapBroker* broker) { ...@@ -1192,14 +1272,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 +1446,10 @@ void JSBoundFunctionData::Serialize(JSHeapBroker* broker) { ...@@ -1364,9 +1446,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 +1994,20 @@ class CodeData : public HeapObjectData { ...@@ -1911,21 +1994,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 +2021,7 @@ bool JSObjectData::cow_or_empty_elements_tenured() const { ...@@ -1939,7 +2021,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 +2036,8 @@ void JSObjectData::SerializeElements(JSHeapBroker* broker) { ...@@ -1954,7 +2036,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 +2191,10 @@ void JSObjectData::SerializeRecursiveAsBoilerplate(JSHeapBroker* broker, ...@@ -2108,9 +2191,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 +2265,9 @@ void JSObjectData::SerializeRecursiveAsBoilerplate(JSHeapBroker* broker, ...@@ -2181,7 +2265,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 +2304,11 @@ Isolate* ObjectRef::isolate() const { return broker()->isolate(); } ...@@ -2218,9 +2304,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 +2322,11 @@ ContextRef ContextRef::previous(size_t* depth, ...@@ -2234,9 +2322,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 +2341,10 @@ base::Optional<ObjectRef> ContextRef::get(int index, ...@@ -2251,10 +2341,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 +2414,14 @@ void JSHeapBroker::PrintRefsAnalysis() const { ...@@ -2324,10 +2414,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 +2488,6 @@ bool IsShareable(Handle<Object> object, Isolate* isolate) { ...@@ -2394,85 +2488,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);
...@@ -2563,7 +2578,8 @@ void JSHeapBroker::InitializeAndStartSerializing( ...@@ -2563,7 +2578,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();
...@@ -2571,60 +2587,8 @@ void JSHeapBroker::InitializeAndStartSerializing( ...@@ -2571,60 +2587,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);
...@@ -2660,24 +2624,25 @@ void JSHeapBroker::InitializeAndStartSerializing( ...@@ -2660,24 +2624,25 @@ void JSHeapBroker::InitializeAndStartSerializing(
TRACE(this, "Finished serializing standard objects"); TRACE(this, "Finished serializing standard objects");
} }
ObjectData* JSHeapBroker::GetData(Handle<Object> object) const {
RefsMap::Entry* entry = refs_->Lookup(object.address());
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 (ReadOnlyHeap::Contains(HeapObject::cast(*object))) {
new (zone()) ObjectData(this, data_storage, object,
kUnserializedReadOnlyHeapObject);
} else if (object->IsCode() && Code::cast(*object).builtin_index() != -1) {
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
...@@ -2712,10 +2677,14 @@ int ObjectRef::AsSmi() const { ...@@ -2712,10 +2677,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)) {
...@@ -2724,9 +2693,12 @@ base::Optional<MapRef> JSObjectRef::GetObjectCreateMap() const { ...@@ -2724,9 +2693,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, ...) \
...@@ -2737,10 +2709,13 @@ INSTANCE_TYPE_CHECKERS(DEF_TESTER) ...@@ -2737,10 +2709,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));
} }
...@@ -2756,11 +2731,13 @@ base::Optional<MapRef> MapRef::AsElementsKind(ElementsKind kind) const { ...@@ -2756,11 +2731,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());
} }
...@@ -2817,27 +2794,34 @@ bool MapRef::HasOnlyStablePrototypesWithFastElements( ...@@ -2817,27 +2794,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();
...@@ -2846,8 +2830,10 @@ int JSFunctionRef::InitialMapInstanceSizeWithMinSlack() const { ...@@ -2846,8 +2830,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();
...@@ -2891,9 +2877,12 @@ OddballType MapRef::oddball_type() const { ...@@ -2891,9 +2877,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));
} }
...@@ -2903,8 +2892,10 @@ FeedbackCellRef FeedbackVectorRef::GetClosureFeedbackCell(int index) const { ...@@ -2903,8 +2892,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();
...@@ -2913,8 +2904,10 @@ double JSObjectRef::RawFastDoublePropertyAt(FieldIndex index) const { ...@@ -2913,8 +2904,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();
...@@ -2923,9 +2916,12 @@ uint64_t JSObjectRef::RawFastDoublePropertyAsBitsAt(FieldIndex index) const { ...@@ -2923,9 +2916,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()));
} }
...@@ -2937,10 +2933,14 @@ ObjectRef JSObjectRef::RawFastPropertyAt(FieldIndex index) const { ...@@ -2937,10 +2933,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()));
} }
...@@ -2958,10 +2958,14 @@ void JSObjectRef::SerializeElements() { ...@@ -2958,10 +2958,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)) {
...@@ -2979,8 +2983,9 @@ void JSObjectRef::EnsureElementsTenured() { ...@@ -2979,8 +2983,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();
...@@ -2988,8 +2993,9 @@ FieldIndex MapRef::GetFieldIndexFor(InternalIndex descriptor_index) const { ...@@ -2988,8 +2993,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;
...@@ -2997,8 +3003,9 @@ int MapRef::GetInObjectPropertyOffset(int i) const { ...@@ -2997,8 +3003,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();
...@@ -3006,9 +3013,11 @@ PropertyDetails MapRef::GetPropertyDetails( ...@@ -3006,9 +3013,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),
...@@ -3030,9 +3039,11 @@ bool MapRef::IsPrimitiveMap() const { ...@@ -3030,9 +3039,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());
...@@ -3045,9 +3056,11 @@ MapRef MapRef::FindFieldOwner(InternalIndex descriptor_index) const { ...@@ -3045,9 +3056,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());
...@@ -3060,8 +3073,9 @@ ObjectRef MapRef::GetFieldType(InternalIndex descriptor_index) const { ...@@ -3060,8 +3073,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));
} }
...@@ -3072,18 +3086,22 @@ bool MapRef::IsUnboxedDoubleField(InternalIndex descriptor_index) const { ...@@ -3072,18 +3086,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);
} }
...@@ -3091,41 +3109,47 @@ base::Optional<double> StringRef::ToNumber() { ...@@ -3091,41 +3109,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());
...@@ -3133,27 +3157,36 @@ double FixedDoubleArrayRef::get_scalar(int i) const { ...@@ -3133,27 +3157,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,
...@@ -3161,47 +3194,60 @@ Handle<Object> BytecodeArrayRef::GetConstantAtIndex(int index) const { ...@@ -3161,47 +3194,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());
} }
...@@ -3209,47 +3255,71 @@ Address BytecodeArrayRef::handler_table_address() const { ...@@ -3209,47 +3255,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()); \
} }
...@@ -3330,7 +3400,8 @@ BIMODAL_ACCESSOR(PropertyCell, Object, value) ...@@ -3330,7 +3400,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()));
} }
...@@ -3341,9 +3412,12 @@ base::Optional<CallHandlerInfoRef> FunctionTemplateInfoRef::call_code() const { ...@@ -3341,9 +3412,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());
} }
...@@ -3351,9 +3425,12 @@ bool FunctionTemplateInfoRef::is_signature_undefined() const { ...@@ -3351,9 +3425,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();
...@@ -3367,9 +3444,12 @@ HolderLookupResult FunctionTemplateInfoRef::LookupHolderOfExpectedType( ...@@ -3367,9 +3444,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());
...@@ -3448,8 +3528,9 @@ BIMODAL_ACCESSOR(FeedbackCell, HeapObject, value) ...@@ -3448,8 +3528,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());
return ObjectRef(broker(), return ObjectRef(broker(),
handle(object()->instance_descriptors().GetStrongValue( handle(object()->instance_descriptors().GetStrongValue(
descriptor_index), descriptor_index),
...@@ -3463,16 +3544,22 @@ base::Optional<ObjectRef> MapRef::GetStrongValue( ...@@ -3463,16 +3544,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) {
...@@ -3483,58 +3570,59 @@ base::Optional<MapRef> MapRef::FindRootMap() const { ...@@ -3483,58 +3570,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();
} }
...@@ -3543,14 +3631,17 @@ bool ScopeInfoRef::HasContextExtension() const { ...@@ -3543,14 +3631,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()));
} }
...@@ -3563,26 +3654,29 @@ void ScopeInfoRef::SerializeScopeInfoChain() { ...@@ -3563,26 +3654,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()));
} }
...@@ -3592,7 +3686,7 @@ ScopeInfoRef NativeContextRef::scope_info() const { ...@@ -3592,7 +3686,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(
...@@ -3646,8 +3740,9 @@ bool ObjectRef::IsNullOrUndefined() const { ...@@ -3646,8 +3740,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();
...@@ -3684,6 +3779,14 @@ base::Optional<ObjectRef> ObjectRef::GetOwnConstantElement( ...@@ -3684,6 +3779,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()) {
...@@ -3699,7 +3802,8 @@ base::Optional<ObjectRef> ObjectRef::GetOwnConstantElement( ...@@ -3699,7 +3802,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);
...@@ -3712,7 +3816,7 @@ base::Optional<ObjectRef> JSObjectRef::GetOwnDataProperty( ...@@ -3712,7 +3816,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);
} }
...@@ -3732,19 +3836,22 @@ base::Optional<ObjectRef> JSArrayRef::GetOwnCowElement( ...@@ -3732,19 +3836,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()));
} }
...@@ -3757,9 +3864,10 @@ ObjectRef::ObjectRef(JSHeapBroker* broker, Handle<Object> object, ...@@ -3757,9 +3864,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;
...@@ -3768,7 +3876,8 @@ ObjectRef::ObjectRef(JSHeapBroker* broker, Handle<Object> object, ...@@ -3768,7 +3876,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);
...@@ -3780,7 +3889,8 @@ ObjectRef::ObjectRef(JSHeapBroker* broker, Handle<Object> object, ...@@ -3780,7 +3889,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");
...@@ -3815,8 +3925,9 @@ OddballType GetOddballType(Isolate* isolate, Map map) { ...@@ -3815,8 +3925,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;
...@@ -3830,9 +3941,12 @@ HeapObjectType HeapObjectRef::GetHeapObjectType() const { ...@@ -3830,9 +3941,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()));
} }
...@@ -3849,17 +3963,25 @@ ElementsKind JSObjectRef::GetElementsKind() const { ...@@ -3849,17 +3963,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();
} }
...@@ -3884,28 +4006,28 @@ bool NameRef::IsUniqueName() const { ...@@ -3884,28 +4006,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());
} }
...@@ -4010,18 +4132,21 @@ void NativeContextData::Serialize(JSHeapBroker* broker) { ...@@ -4010,18 +4132,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();
} }
...@@ -4039,9 +4164,12 @@ JSArrayRef SharedFunctionInfoRef::GetTemplateObject( ...@@ -4039,9 +4164,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(),
...@@ -4077,7 +4205,8 @@ void SharedFunctionInfoRef::SerializeScopeInfoChain() { ...@@ -4077,7 +4205,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()));
...@@ -4091,15 +4220,17 @@ SharedFunctionInfoRef::function_template_info() const { ...@@ -4091,15 +4220,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()));
} }
...@@ -4107,26 +4238,27 @@ ScopeInfoRef SharedFunctionInfoRef::scope_info() const { ...@@ -4107,26 +4238,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;
...@@ -4135,36 +4267,39 @@ bool MapRef::serialized_own_descriptor(InternalIndex descriptor_index) const { ...@@ -4135,36 +4267,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());
} }
...@@ -4175,26 +4310,30 @@ bool JSTypedArrayRef::serialized() const { ...@@ -4175,26 +4310,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 =
...@@ -4902,7 +5041,8 @@ std::ostream& operator<<(std::ostream& os, const ObjectRef& ref) { ...@@ -4902,7 +5041,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();
...@@ -5002,7 +5142,7 @@ TemplateObjectFeedback const& ProcessedFeedback::AsTemplateObject() const { ...@@ -5002,7 +5142,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);
...@@ -5062,8 +5202,8 @@ Smi OffHeapBytecodeArray::GetConstantAtIndexAsSmi(int index) const { ...@@ -5062,8 +5202,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,16 @@ class V8_EXPORT_PRIVATE JSHeapBroker { ...@@ -221,17 +225,16 @@ 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_; }
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