5 #include "src/compiler/js-heap-broker.h" 7 #include "src/ast/modules.h" 8 #include "src/bootstrapper.h" 9 #include "src/boxed-float.h" 10 #include "src/code-factory.h" 11 #include "src/compiler/graph-reducer.h" 12 #include "src/compiler/per-isolate-compiler-cache.h" 13 #include "src/objects-inl.h" 14 #include "src/objects/instance-type-inl.h" 15 #include "src/objects/js-array-buffer-inl.h" 16 #include "src/objects/js-array-inl.h" 17 #include "src/objects/js-regexp-inl.h" 18 #include "src/objects/module-inl.h" 19 #include "src/utils.h" 25 #define FORWARD_DECL(Name) class Name##Data; 26 HEAP_BROKER_OBJECT_LIST(FORWARD_DECL)
44 enum ObjectDataKind { kSmi, kSerializedHeapObject, kUnserializedHeapObject };
50 : object_(
object), kind_(kind) {
55 broker->Trace(
"Creating data %p for handle %" V8PRIuPTR
" (",
this,
57 if (FLAG_trace_heap_broker) {
61 CHECK_NOT_NULL(broker->isolate()->handle_scope_data()->canonical_scope);
64 #define DECLARE_IS_AND_AS(Name) \ 65 bool Is##Name() const; \ 66 Name##Data* As##Name(); 67 HEAP_BROKER_OBJECT_LIST(DECLARE_IS_AND_AS)
68 #undef DECLARE_IS_AND_AS 71 ObjectDataKind kind()
const {
return kind_; }
72 bool is_smi()
const {
return kind_ == kSmi; }
76 ObjectDataKind
const kind_;
84 bool boolean_value()
const {
return boolean_value_; }
85 MapData* map()
const {
return map_; }
91 bool const boolean_value_;
108 bool serialized_ =
false;
112 void JSHeapBroker::IncrementTracingIndentation() { ++tracing_indentation_; }
114 void JSHeapBroker::DecrementTracingIndentation() { --tracing_indentation_; }
119 :
TraceScope(broker, static_cast<void*>(broker), label) {}
122 :
TraceScope(broker, static_cast<void*>(data), label) {}
124 ~
TraceScope() { broker_->DecrementTracingIndentation(); }
131 broker_->Trace(
"Running %s on %p.\n", label,
self);
132 broker_->IncrementTracingIndentation();
139 property_details_(object->property_details()) {}
141 void PropertyCellData::Serialize(JSHeapBroker* broker) {
142 if (serialized_)
return;
145 TraceScope tracer(broker,
this,
"PropertyCellData::Serialize");
148 value_ = broker->GetOrCreateData(cell->value());
153 bool IsDouble()
const {
return object_ ==
nullptr; }
154 double AsDouble()
const {
159 bool IsObject()
const {
return object_ !=
nullptr; }
183 const JSObjectField& GetInobjectField(
int property_index)
const;
187 bool cow_or_empty_elements_tenured()
const;
190 MapData* object_create_map()
const {
191 CHECK(serialized_object_create_map_);
192 return object_create_map_;
196 void SerializeRecursive(
JSHeapBroker* broker,
int max_depths);
199 bool cow_or_empty_elements_tenured_ =
false;
202 bool serialized_as_boilerplate_ =
false;
203 bool serialized_elements_ =
false;
207 bool serialized_object_create_map_ =
false;
208 MapData* object_create_map_ =
nullptr;
211 void JSObjectData::SerializeObjectCreateMap(
JSHeapBroker* broker) {
212 if (serialized_object_create_map_)
return;
213 serialized_object_create_map_ =
true;
215 TraceScope tracer(broker,
this,
"JSObjectData::SerializeObjectCreateMap");
218 if (jsobject->map()->is_prototype_map()) {
219 Handle<Object> maybe_proto_info(jsobject->map()->prototype_info(),
221 if (maybe_proto_info->IsPrototypeInfo()) {
223 if (proto_info->HasObjectCreateMap()) {
224 DCHECK_NULL(object_create_map_);
226 broker->GetOrCreateData(proto_info->ObjectCreateMap())->AsMap();
237 bool is_on_heap()
const {
return is_on_heap_; }
238 size_t length_value()
const {
return length_value_; }
239 void* elements_external_pointer()
const {
return elements_external_pointer_; }
246 bool const is_on_heap_;
247 size_t const length_value_;
248 void*
const elements_external_pointer_;
250 bool serialized_ =
false;
257 is_on_heap_(object->is_on_heap()),
258 length_value_(object->length_value()),
259 elements_external_pointer_(
262 void JSTypedArrayData::Serialize(JSHeapBroker* broker) {
263 if (serialized_)
return;
266 TraceScope tracer(broker,
this,
"JSTypedArrayData::Serialize");
270 DCHECK_NULL(buffer_);
271 buffer_ = broker->GetOrCreateData(typed_array->buffer())->AsHeapObject();
280 size_t byte_length()
const {
return byte_length_; }
281 size_t byte_offset()
const {
return byte_offset_; }
284 size_t const byte_length_;
285 size_t const byte_offset_;
295 ObjectData* bound_target_function()
const {
return bound_target_function_; }
296 ObjectData* bound_this()
const {
return bound_this_; }
297 FixedArrayData* bound_arguments()
const {
return bound_arguments_; }
300 bool serialized_ =
false;
312 bool has_initial_map()
const {
return has_initial_map_; }
313 bool has_prototype()
const {
return has_prototype_; }
314 bool PrototypeRequiresRuntimeLookup()
const {
315 return PrototypeRequiresRuntimeLookup_;
322 MapData* initial_map()
const {
return initial_map_; }
323 ObjectData* prototype()
const {
return prototype_; }
325 int initial_map_instance_size_with_min_slack()
const {
327 return initial_map_instance_size_with_min_slack_;
331 bool has_initial_map_;
333 bool PrototypeRequiresRuntimeLookup_;
335 bool serialized_ =
false;
339 MapData* initial_map_ =
nullptr;
342 int initial_map_instance_size_with_min_slack_;
351 void SerializeAsRegExpBoilerplate(
JSHeapBroker* broker);
353 ObjectData* raw_properties_or_hash()
const {
return raw_properties_or_hash_; }
355 ObjectData* source()
const {
return source_; }
357 ObjectData* last_index()
const {
return last_index_; }
360 bool serialized_as_reg_exp_boilerplate_ =
false;
362 ObjectData* raw_properties_or_hash_ =
nullptr;
373 :
HeapObjectData(broker, storage,
object), value_(object->value()) {}
375 double value()
const {
return value_; }
385 :
HeapObjectData(broker, storage,
object), value_(object->value()) {}
387 double value()
const {
return value_; }
405 bool serialized_ =
false;
413 void ContextData::Serialize(JSHeapBroker* broker) {
414 if (serialized_)
return;
417 TraceScope tracer(broker,
this,
"ContextData::Serialize");
420 DCHECK_NULL(previous_);
422 if (!context->IsNativeContext()) {
423 previous_ = broker->GetOrCreateData(context->previous())->AsContext();
424 previous_->Serialize(broker);
430 #define DECL_ACCESSOR(type, name) \ 431 type##Data* name() const { return name##_; } 432 BROKER_NATIVE_CONTEXT_FIELDS(DECL_ACCESSOR)
437 return function_maps_;
445 bool serialized_ =
false;
446 #define DECL_MEMBER(type, name) type##Data* name##_ = nullptr; 447 BROKER_NATIVE_CONTEXT_FIELDS(DECL_MEMBER)
462 int length()
const {
return length_; }
463 uint16_t first_char()
const {
return first_char_; }
465 bool is_external_string()
const {
return is_external_string_; }
466 bool is_seq_string()
const {
return is_seq_string_; }
470 uint16_t
const first_char_;
472 bool const is_external_string_;
473 bool const is_seq_string_;
475 static constexpr
int kMaxLengthForDoubleConversion = 23;
480 :
NameData(broker, storage, object),
481 length_(object->length()),
482 first_char_(length_ > 0 ? object->Get(0) : 0),
483 is_external_string_(object->IsExternalString()),
484 is_seq_string_(object->IsSeqString()) {
485 int flags = ALLOW_HEX | ALLOW_OCTAL | ALLOW_BINARY;
486 if (length_ <= kMaxLengthForDoubleConversion) {
487 to_number_ = StringToDouble(broker->isolate(), object, flags);
501 int* max_properties) {
502 DCHECK_GE(max_depth, 0);
503 DCHECK_GE(*max_properties, 0);
506 if (!JSObject::TryMigrateInstance(boilerplate))
return false;
509 if (max_depth == 0)
return false;
512 Isolate*
const isolate = boilerplate->GetIsolate();
514 if (elements->length() > 0 &&
515 elements->map() !=
ReadOnlyRoots(isolate).fixed_cow_array_map()) {
516 if (boilerplate->HasSmiOrObjectElements()) {
518 int length = elements->length();
519 for (
int i = 0;
i < length;
i++) {
520 if ((*max_properties)-- == 0)
return false;
522 if (value->IsJSObject()) {
524 if (!IsFastLiteralHelper(value_object, max_depth - 1,
530 }
else if (boilerplate->HasDoubleElements()) {
531 if (elements->Size() > kMaxRegularHeapObjectSize)
return false;
538 if (!(boilerplate->HasFastProperties() &&
539 boilerplate->property_array()->length() == 0)) {
544 Handle<DescriptorArray> descriptors(
545 boilerplate->map()->instance_descriptors(), isolate);
546 int limit = boilerplate->map()->NumberOfOwnDescriptors();
547 for (
int i = 0;
i < limit;
i++) {
548 PropertyDetails details = descriptors->GetDetails(
i);
549 if (details.location() != kField)
continue;
550 DCHECK_EQ(kData, details.kind());
551 if ((*max_properties)-- == 0)
return false;
552 FieldIndex field_index = FieldIndex::ForDescriptor(boilerplate->map(),
i);
553 if (boilerplate->IsUnboxedDoubleField(field_index))
continue;
554 Handle<Object> value(boilerplate->RawFastPropertyAt(field_index), isolate);
555 if (value->IsJSObject()) {
556 Handle<JSObject> value_object = Handle<JSObject>::cast(value);
557 if (!IsFastLiteralHelper(value_object, max_depth - 1, max_properties)) {
570 const int kMaxFastLiteralDepth = 3;
571 const int kMaxFastLiteralProperties = JSObject::kMaxInObjectProperties;
576 bool IsInlinableFastLiteral(Handle<JSObject> boilerplate) {
577 int max_properties = kMaxFastLiteralProperties;
578 return IsFastLiteralHelper(boilerplate, kMaxFastLiteralDepth,
590 bool PointsToLiteral()
const {
return PointsToLiteral_; }
591 PretenureFlag GetPretenureMode()
const {
return GetPretenureMode_; }
592 ObjectData* nested_site()
const {
return nested_site_; }
593 bool IsFastLiteral()
const {
return IsFastLiteral_; }
594 JSObjectData* boilerplate()
const {
return boilerplate_; }
597 ElementsKind GetElementsKind()
const {
return GetElementsKind_; }
598 bool CanInlineCall()
const {
return CanInlineCall_; }
601 bool const PointsToLiteral_;
602 PretenureFlag
const GetPretenureMode_;
604 bool IsFastLiteral_ =
false;
606 ElementsKind GetElementsKind_ = NO_ELEMENTS;
607 bool CanInlineCall_ =
false;
608 bool serialized_boilerplate_ =
false;
623 MapData* field_owner =
nullptr;
625 bool is_unboxed_double_field =
false;
632 InstanceType instance_type()
const {
return instance_type_; }
633 int instance_size()
const {
return instance_size_; }
634 byte bit_field()
const {
return bit_field_; }
635 byte bit_field2()
const {
return bit_field2_; }
636 uint32_t bit_field3()
const {
return bit_field3_; }
637 bool can_be_deprecated()
const {
return can_be_deprecated_; }
638 bool can_transition()
const {
return can_transition_; }
639 int in_object_properties_start_in_words()
const {
640 CHECK(InstanceTypeChecker::IsJSObject(instance_type()));
641 return in_object_properties_start_in_words_;
643 int in_object_properties()
const {
644 CHECK(InstanceTypeChecker::IsJSObject(instance_type()));
645 return in_object_properties_;
647 int constructor_function_index()
const {
return constructor_function_index_; }
651 void SerializeElementsKindGeneralizations(
JSHeapBroker* broker);
653 CHECK(serialized_elements_kind_generalizations_);
654 return elements_kind_generalizations_;
661 CHECK(serialized_own_descriptors_);
662 return instance_descriptors_;
667 CHECK(serialized_constructor_);
673 CHECK(serialized_prototype_);
678 InstanceType
const instance_type_;
679 int const instance_size_;
680 byte
const bit_field_;
681 byte
const bit_field2_;
683 bool const can_be_deprecated_;
684 bool const can_transition_;
685 int const in_object_properties_start_in_words_;
686 int const in_object_properties_;
687 int const constructor_function_index_;
689 bool serialized_elements_kind_generalizations_ =
false;
692 bool serialized_own_descriptors_ =
false;
695 bool serialized_constructor_ =
false;
698 bool serialized_prototype_ =
false;
702 AllocationSiteData::AllocationSiteData(
JSHeapBroker* broker,
706 PointsToLiteral_(object->PointsToLiteral()),
707 GetPretenureMode_(object->GetPretenureMode()) {
708 if (PointsToLiteral_) {
709 IsFastLiteral_ = IsInlinableFastLiteral(
710 handle(object->boilerplate(), broker->isolate()));
712 GetElementsKind_ =
object->GetElementsKind();
713 CanInlineCall_ =
object->CanInlineCall();
717 void AllocationSiteData::SerializeBoilerplate(JSHeapBroker* broker) {
718 if (serialized_boilerplate_)
return;
719 serialized_boilerplate_ =
true;
721 TraceScope tracer(broker,
this,
"AllocationSiteData::SerializeBoilerplate");
722 Handle<AllocationSite> site = Handle<AllocationSite>::cast(
object());
724 CHECK(IsFastLiteral_);
725 DCHECK_NULL(boilerplate_);
726 boilerplate_ = broker->GetOrCreateData(site->boilerplate())->AsJSObject();
727 boilerplate_->SerializeAsBoilerplate(broker);
729 DCHECK_NULL(nested_site_);
730 nested_site_ = broker->GetOrCreateData(site->nested_site());
731 if (nested_site_->IsAllocationSite()) {
732 nested_site_->AsAllocationSite()->SerializeBoilerplate(broker);
736 HeapObjectData::HeapObjectData(JSHeapBroker* broker, ObjectData** storage,
737 Handle<HeapObject>
object)
738 : ObjectData(broker, storage, object, kSerializedHeapObject),
739 boolean_value_(object->BooleanValue(broker->isolate())),
745 map_(static_cast<MapData*>(broker->GetOrCreateData(object->map()))) {
746 CHECK(broker->SerializingAllowed());
749 MapData::MapData(JSHeapBroker* broker, ObjectData** storage, Handle<Map>
object)
750 : HeapObjectData(broker, storage, object),
751 instance_type_(object->instance_type()),
752 instance_size_(object->instance_size()),
753 bit_field_(object->bit_field()),
754 bit_field2_(object->bit_field2()),
755 bit_field3_(object->bit_field3()),
756 can_be_deprecated_(object->NumberOfOwnDescriptors() > 0
757 ? object->CanBeDeprecated()
759 can_transition_(object->CanTransition()),
760 in_object_properties_start_in_words_(
761 object->IsJSObjectMap() ? object->GetInObjectPropertiesStartInWords()
763 in_object_properties_(
764 object->IsJSObjectMap() ? object->GetInObjectProperties() : 0),
765 constructor_function_index_(object->IsPrimitiveMap()
766 ? object->GetConstructorFunctionIndex()
767 : Map::kNoConstructorFunctionIndex),
768 elements_kind_generalizations_(broker->zone()) {}
770 JSFunctionData::JSFunctionData(JSHeapBroker* broker, ObjectData** storage,
771 Handle<JSFunction>
object)
772 : JSObjectData(broker, storage, object),
773 has_initial_map_(object->has_prototype_slot() &&
774 object->has_initial_map()),
775 has_prototype_(object->has_prototype_slot() && object->has_prototype()),
776 PrototypeRequiresRuntimeLookup_(
777 object->PrototypeRequiresRuntimeLookup()) {}
779 void JSFunctionData::Serialize(JSHeapBroker* broker) {
780 if (serialized_)
return;
783 TraceScope tracer(broker,
this,
"JSFunctionData::Serialize");
784 Handle<JSFunction>
function = Handle<JSFunction>::cast(
object());
786 DCHECK_NULL(context_);
787 DCHECK_NULL(native_context_);
788 DCHECK_NULL(initial_map_);
789 DCHECK_NULL(prototype_);
790 DCHECK_NULL(shared_);
792 context_ = broker->GetOrCreateData(function->context())->AsContext();
794 broker->GetOrCreateData(function->native_context())->AsNativeContext();
795 shared_ = broker->GetOrCreateData(function->shared())->AsSharedFunctionInfo();
796 initial_map_ = has_initial_map()
797 ? broker->GetOrCreateData(function->initial_map())->AsMap()
799 prototype_ = has_prototype() ? broker->GetOrCreateData(function->prototype())
802 if (initial_map_ !=
nullptr) {
803 initial_map_instance_size_with_min_slack_ =
804 function->ComputeInstanceSizeWithMinSlack(broker->isolate());
805 if (initial_map_->instance_type() == JS_ARRAY_TYPE) {
806 initial_map_->SerializeElementsKindGeneralizations(broker);
808 initial_map_->SerializeConstructor(broker);
812 initial_map_->SerializePrototype(broker);
816 void MapData::SerializeElementsKindGeneralizations(JSHeapBroker* broker) {
817 if (serialized_elements_kind_generalizations_)
return;
818 serialized_elements_kind_generalizations_ =
true;
820 TraceScope tracer(broker,
this,
821 "MapData::SerializeElementsKindGeneralizations");
822 DCHECK_EQ(instance_type(), JS_ARRAY_TYPE);
823 MapRef
self(broker,
this);
824 ElementsKind from_kind =
self.elements_kind();
825 DCHECK(elements_kind_generalizations_.empty());
826 for (
int i = FIRST_FAST_ELEMENTS_KIND;
i <= LAST_FAST_ELEMENTS_KIND;
i++) {
827 ElementsKind to_kind =
static_cast<ElementsKind
>(
i);
828 if (IsMoreGeneralElementsKindTransition(from_kind, to_kind)) {
830 Map::AsElementsKind(broker->isolate(),
self.object(), to_kind);
831 elements_kind_generalizations_.push_back(
832 broker->GetOrCreateData(target)->AsMap());
841 :
HeapObjectData(broker, storage,
object), contents_(broker->zone()) {}
859 bool serialized_ =
false;
863 FeedbackVectorData::FeedbackVectorData(
JSHeapBroker* broker,
866 :
HeapObjectData(broker, storage, object), feedback_(broker->zone()) {}
868 void FeedbackVectorData::SerializeSlots(JSHeapBroker* broker) {
869 if (serialized_)
return;
872 TraceScope tracer(broker,
this,
"FeedbackVectorData::SerializeSlots");
874 DCHECK(feedback_.empty());
875 feedback_.reserve(vector->length());
876 for (
int i = 0;
i < vector->length(); ++
i) {
878 ObjectData* slot_value =
879 value->IsObject() ? broker->GetOrCreateData(value->cast<
Object>())
881 feedback_.push_back(slot_value);
882 if (slot_value ==
nullptr)
continue;
884 if (slot_value->IsAllocationSite() &&
885 slot_value->AsAllocationSite()->IsFastLiteral()) {
886 slot_value->AsAllocationSite()->SerializeBoilerplate(broker);
887 }
else if (slot_value->IsJSRegExp()) {
888 slot_value->AsJSRegExp()->SerializeAsRegExpBoilerplate(broker);
891 DCHECK_EQ(vector->length(), feedback_.size());
892 broker->Trace(
"Copied %zu slots.\n", feedback_.size());
901 length_(object->length()) {}
903 int length()
const {
return length_; }
920 bool serialized_contents_ =
false;
927 byte_length_(object->byte_length()),
928 byte_offset_(object->byte_offset()) {}
930 JSBoundFunctionData::JSBoundFunctionData(JSHeapBroker* broker,
931 ObjectData** storage,
933 : JSObjectData(broker, storage, object) {}
935 void JSBoundFunctionData::Serialize(JSHeapBroker* broker) {
936 if (serialized_)
return;
939 TraceScope tracer(broker,
this,
"JSBoundFunctionData::Serialize");
942 DCHECK_NULL(bound_target_function_);
943 DCHECK_NULL(bound_this_);
944 DCHECK_NULL(bound_arguments_);
946 bound_target_function_ =
947 broker->GetOrCreateData(function->bound_target_function());
948 bound_this_ = broker->GetOrCreateData(function->bound_this());
950 broker->GetOrCreateData(function->bound_arguments())->AsFixedArray();
952 bound_arguments_->SerializeContents(broker);
955 JSObjectData::JSObjectData(JSHeapBroker* broker, ObjectData** storage,
956 Handle<JSObject>
object)
957 : HeapObjectData(broker, storage, object),
958 inobject_fields_(broker->zone()) {}
960 FixedArrayData::FixedArrayData(JSHeapBroker* broker, ObjectData** storage,
961 Handle<FixedArray>
object)
962 : FixedArrayBaseData(broker, storage, object), contents_(broker->zone()) {}
964 void FixedArrayData::SerializeContents(JSHeapBroker* broker) {
965 if (serialized_contents_)
return;
966 serialized_contents_ =
true;
968 TraceScope tracer(broker,
this,
"FixedArrayData::SerializeContents");
969 Handle<FixedArray> array = Handle<FixedArray>::cast(
object());
970 CHECK_EQ(array->length(), length());
971 CHECK(contents_.empty());
972 contents_.reserve(static_cast<size_t>(length()));
974 for (
int i = 0;
i < length();
i++) {
975 Handle<Object> value(array->get(
i), broker->isolate());
976 contents_.push_back(broker->GetOrCreateData(value));
978 broker->Trace(
"Copied %zu elements.\n", contents_.size());
992 bool serialized_contents_ =
false;
996 FixedDoubleArrayData::FixedDoubleArrayData(
JSHeapBroker* broker,
1001 void FixedDoubleArrayData::SerializeContents(JSHeapBroker* broker) {
1002 if (serialized_contents_)
return;
1003 serialized_contents_ =
true;
1005 TraceScope tracer(broker,
this,
"FixedDoubleArrayData::SerializeContents");
1007 CHECK_EQ(self->length(), length());
1008 CHECK(contents_.empty());
1009 contents_.reserve(static_cast<size_t>(length()));
1011 for (
int i = 0;
i < length();
i++) {
1012 contents_.push_back(Float64::FromBits(self->get_representation(
i)));
1014 broker->Trace(
"Copied %zu elements.\n", contents_.size());
1019 int register_count()
const {
return register_count_; }
1024 register_count_(object->register_count()) {}
1027 int const register_count_;
1036 ObjectData* length()
const {
return length_; }
1039 bool serialized_ =
false;
1047 void JSArrayData::Serialize(JSHeapBroker* broker) {
1048 if (serialized_)
return;
1051 TraceScope tracer(broker,
this,
"JSArrayData::Serialize");
1053 DCHECK_NULL(length_);
1054 length_ = broker->GetOrCreateData(jsarray->length());
1062 int context_length()
const {
return context_length_; }
1065 int const context_length_;
1071 context_length_(object->ContextLength()) {}
1075 int builtin_id()
const {
return builtin_id_; }
1077 #define DECL_ACCESSOR(type, name) \ 1078 type name() const { return name##_; } 1079 BROKER_SFI_FIELDS(DECL_ACCESSOR)
1080 #undef DECL_ACCESSOR 1085 builtin_id_(object->HasBuiltinId() ?
object->builtin_id()
1086 : Builtins::kNoBuiltinId),
1088 object->HasBytecodeArray()
1089 ? broker->GetOrCreateData(object->GetBytecodeArray())
1092 #define INIT_MEMBER(
type, name) , name##_(object->name())
1093 BROKER_SFI_FIELDS(INIT_MEMBER)
1096 DCHECK_EQ(HasBuiltinId_, builtin_id_ != Builtins::kNoBuiltinId);
1097 DCHECK_EQ(HasBytecodeArray_, GetBytecodeArray_ !=
nullptr);
1101 int const builtin_id_;
1103 #define DECL_MEMBER(type, name) type const name##_; 1104 BROKER_SFI_FIELDS(DECL_MEMBER)
1113 CellData* GetCell(
int cell_index)
const;
1116 bool serialized_ =
false;
1124 imports_(broker->zone()),
1125 exports_(broker->zone()) {}
1127 CellData* ModuleData::GetCell(
int cell_index)
const {
1130 switch (ModuleDescriptor::GetCellIndexKind(cell_index)) {
1131 case ModuleDescriptor::kImport:
1132 cell = imports_.at(Module::ImportIndex(cell_index));
1134 case ModuleDescriptor::kExport:
1135 cell = exports_.at(Module::ExportIndex(cell_index));
1137 case ModuleDescriptor::kInvalid:
1141 CHECK_NOT_NULL(cell);
1145 void ModuleData::Serialize(JSHeapBroker* broker) {
1146 if (serialized_)
return;
1149 TraceScope tracer(broker,
this,
"ModuleData::Serialize");
1150 Handle<Module> module = Handle<Module>::cast(
object());
1155 DCHECK(imports_.empty());
1156 Handle<FixedArray> imports(module->regular_imports(), broker->isolate());
1157 int const imports_length = imports->length();
1158 imports_.reserve(imports_length);
1159 for (
int i = 0;
i < imports_length; ++
i) {
1160 imports_.push_back(broker->GetOrCreateData(imports->get(
i))->AsCell());
1162 broker->Trace(
"Copied %zu imports.\n", imports_.size());
1164 DCHECK(exports_.empty());
1165 Handle<FixedArray> exports(module->regular_exports(), broker->isolate());
1166 int const exports_length = exports->length();
1167 exports_.reserve(exports_length);
1168 for (
int i = 0;
i < exports_length; ++
i) {
1169 exports_.push_back(broker->GetOrCreateData(exports->get(
i))->AsCell());
1171 broker->Trace(
"Copied %zu exports.\n", exports_.size());
1182 bool serialized_ =
false;
1190 void CellData::Serialize(JSHeapBroker* broker) {
1191 if (serialized_)
return;
1194 TraceScope tracer(broker,
this,
"CellData::Serialize");
1196 DCHECK_NULL(value_);
1197 value_ = broker->GetOrCreateData(cell->value());
1213 #define DEFINE_IS_AND_AS(Name) \ 1214 bool ObjectData::Is##Name() const { \ 1215 if (kind() == kUnserializedHeapObject) { \ 1216 AllowHandleDereference allow_handle_dereference; \ 1217 return object()->Is##Name(); \ 1219 if (is_smi()) return false; \ 1220 InstanceType instance_type = \ 1221 static_cast<const HeapObjectData*>(this)->map()->instance_type(); \ 1222 return InstanceTypeChecker::Is##Name(instance_type); \ 1224 Name##Data* ObjectData::As##Name() { \ 1225 CHECK_EQ(kind(), kSerializedHeapObject); \ 1226 CHECK(Is##Name()); \ 1227 return static_cast<Name##Data*>(this); \ 1229 HEAP_BROKER_OBJECT_LIST(DEFINE_IS_AND_AS)
1230 #undef DEFINE_IS_AND_AS 1232 const JSObjectField& JSObjectData::GetInobjectField(
int property_index)
const {
1233 CHECK_LT(static_cast<size_t>(property_index), inobject_fields_.size());
1234 return inobject_fields_[property_index];
1237 bool JSObjectData::cow_or_empty_elements_tenured()
const {
1238 return cow_or_empty_elements_tenured_;
1241 FixedArrayBaseData* JSObjectData::elements()
const {
return elements_; }
1243 void JSObjectData::SerializeAsBoilerplate(JSHeapBroker* broker) {
1244 SerializeRecursive(broker, kMaxFastLiteralDepth);
1247 void JSObjectData::SerializeElements(JSHeapBroker* broker) {
1248 if (serialized_elements_)
return;
1249 serialized_elements_ =
true;
1251 TraceScope tracer(broker,
this,
"JSObjectData::SerializeElements");
1252 Handle<JSObject> boilerplate = Handle<JSObject>::cast(
object());
1253 Handle<FixedArrayBase> elements_object(boilerplate->elements(),
1255 DCHECK_NULL(elements_);
1256 elements_ = broker->GetOrCreateData(elements_object)->AsFixedArrayBase();
1259 void MapData::SerializeConstructor(JSHeapBroker* broker) {
1260 if (serialized_constructor_)
return;
1261 serialized_constructor_ =
true;
1263 TraceScope tracer(broker,
this,
"MapData::SerializeConstructor");
1264 Handle<Map> map = Handle<Map>::cast(
object());
1265 DCHECK_NULL(constructor_);
1266 constructor_ = broker->GetOrCreateData(map->GetConstructor());
1269 void MapData::SerializePrototype(JSHeapBroker* broker) {
1270 if (serialized_prototype_)
return;
1271 serialized_prototype_ =
true;
1273 TraceScope tracer(broker,
this,
"MapData::SerializePrototype");
1274 Handle<Map> map = Handle<Map>::cast(
object());
1275 DCHECK_NULL(prototype_);
1276 prototype_ = broker->GetOrCreateData(map->prototype());
1279 void MapData::SerializeOwnDescriptors(JSHeapBroker* broker) {
1280 if (serialized_own_descriptors_)
return;
1281 serialized_own_descriptors_ =
true;
1283 TraceScope tracer(broker,
this,
"MapData::SerializeOwnDescriptors");
1284 Handle<Map> map = Handle<Map>::cast(
object());
1286 DCHECK_NULL(instance_descriptors_);
1287 instance_descriptors_ =
1288 broker->GetOrCreateData(map->instance_descriptors())->AsDescriptorArray();
1290 int const number_of_own = map->NumberOfOwnDescriptors();
1291 ZoneVector<PropertyDescriptor>& contents = instance_descriptors_->contents();
1292 int const current_size =
static_cast<int>(contents.size());
1293 if (number_of_own <= current_size)
return;
1295 Isolate*
const isolate = broker->isolate();
1297 Handle<DescriptorArray>::cast(instance_descriptors_->object());
1298 CHECK_EQ(*descriptors, map->instance_descriptors());
1299 contents.reserve(number_of_own);
1302 for (
int i = current_size;
i < number_of_own; ++
i) {
1303 PropertyDescriptor d;
1304 d.key = broker->GetOrCreateData(descriptors->GetKey(
i))->AsName();
1305 d.details = descriptors->GetDetails(
i);
1306 if (d.details.location() == kField) {
1307 d.field_index = FieldIndex::ForDescriptor(*map,
i);
1309 broker->GetOrCreateData(map->FindFieldOwner(isolate,
i))->AsMap();
1310 d.field_type = broker->GetOrCreateData(descriptors->GetFieldType(
i));
1311 d.is_unboxed_double_field = map->IsUnboxedDoubleField(d.field_index);
1314 contents.push_back(d);
1316 CHECK_EQ(number_of_own, contents.size());
1319 for (
int i = current_size;
i < number_of_own; ++
i) {
1320 const PropertyDescriptor& d = contents[
i];
1321 if (d.details.location() == kField) {
1323 Handle<Map>::cast(d.field_owner->object())->NumberOfOwnDescriptors(),
1325 d.field_owner->SerializeOwnDescriptors(broker);
1329 broker->Trace(
"Copied %zu descriptors into %p (%zu total).\n",
1330 number_of_own - current_size, instance_descriptors_,
1334 void JSObjectData::SerializeRecursive(JSHeapBroker* broker,
int depth) {
1335 if (serialized_as_boilerplate_)
return;
1336 serialized_as_boilerplate_ =
true;
1338 TraceScope tracer(broker,
this,
"JSObjectData::SerializeRecursive");
1339 Handle<JSObject> boilerplate = Handle<JSObject>::cast(
object());
1344 CHECK(!boilerplate->map()->is_deprecated());
1347 Isolate*
const isolate = broker->isolate();
1348 Handle<FixedArrayBase> elements_object(boilerplate->elements(), isolate);
1355 bool const empty_or_cow =
1356 elements_object->length() == 0 ||
1357 elements_object->map() == ReadOnlyRoots(isolate).fixed_cow_array_map();
1360 if (Heap::InNewSpace(*elements_object)) {
1361 elements_object = isolate->factory()->CopyAndTenureFixedCOWArray(
1362 Handle<FixedArray>::cast(elements_object));
1363 boilerplate->set_elements(*elements_object);
1365 cow_or_empty_elements_tenured_ =
true;
1368 DCHECK_NULL(elements_);
1369 elements_ = broker->GetOrCreateData(elements_object)->AsFixedArrayBase();
1375 }
else if (boilerplate->HasSmiOrObjectElements()) {
1376 elements_->AsFixedArray()->SerializeContents(broker);
1377 Handle<FixedArray> fast_elements =
1378 Handle<FixedArray>::cast(elements_object);
1379 int length = elements_object->length();
1380 for (
int i = 0;
i < length;
i++) {
1381 Handle<Object> value(fast_elements->get(
i), isolate);
1382 if (value->IsJSObject()) {
1383 ObjectData* value_data = broker->GetOrCreateData(value);
1384 value_data->AsJSObject()->SerializeRecursive(broker, depth - 1);
1388 CHECK(boilerplate->HasDoubleElements());
1389 CHECK_LE(elements_object->Size(), kMaxRegularHeapObjectSize);
1390 elements_->AsFixedDoubleArray()->SerializeContents(broker);
1394 CHECK(boilerplate->HasFastProperties() &&
1395 boilerplate->property_array()->length() == 0);
1396 CHECK_EQ(inobject_fields_.size(), 0u);
1399 Handle<DescriptorArray> descriptors(
1400 boilerplate->map()->instance_descriptors(), isolate);
1401 int const limit = boilerplate->map()->NumberOfOwnDescriptors();
1402 for (
int i = 0;
i < limit;
i++) {
1403 PropertyDetails details = descriptors->GetDetails(
i);
1404 if (details.location() != kField)
continue;
1405 DCHECK_EQ(kData, details.kind());
1407 FieldIndex field_index = FieldIndex::ForDescriptor(boilerplate->map(),
i);
1410 DCHECK_EQ(field_index.property_index(),
1411 static_cast<int>(inobject_fields_.size()));
1412 if (boilerplate->IsUnboxedDoubleField(field_index)) {
1413 double value = boilerplate->RawFastDoublePropertyAt(field_index);
1414 inobject_fields_.push_back(JSObjectField{value});
1416 Handle<Object> value(boilerplate->RawFastPropertyAt(field_index),
1418 ObjectData* value_data = broker->GetOrCreateData(value);
1419 if (value->IsJSObject()) {
1420 value_data->AsJSObject()->SerializeRecursive(broker, depth - 1);
1422 inobject_fields_.push_back(JSObjectField{value_data});
1425 broker->Trace(
"Copied %zu in-object fields.\n", inobject_fields_.size());
1427 map()->SerializeOwnDescriptors(broker);
1429 if (IsJSArray()) AsJSArray()->Serialize(broker);
1432 void JSRegExpData::SerializeAsRegExpBoilerplate(JSHeapBroker* broker) {
1433 if (serialized_as_reg_exp_boilerplate_)
return;
1434 serialized_as_reg_exp_boilerplate_ =
true;
1436 TraceScope tracer(broker,
this,
"JSRegExpData::SerializeAsRegExpBoilerplate");
1437 Handle<JSRegExp> boilerplate = Handle<JSRegExp>::cast(
object());
1439 SerializeElements(broker);
1441 raw_properties_or_hash_ =
1442 broker->GetOrCreateData(boilerplate->raw_properties_or_hash());
1443 data_ = broker->GetOrCreateData(boilerplate->data());
1444 source_ = broker->GetOrCreateData(boilerplate->source());
1445 flags_ = broker->GetOrCreateData(boilerplate->flags());
1446 last_index_ = broker->GetOrCreateData(boilerplate->last_index());
1449 bool ObjectRef::equals(
const ObjectRef& other)
const {
1450 return data_ == other.data_;
1453 Isolate* ObjectRef::isolate()
const {
return broker()->isolate(); }
1455 ContextRef ContextRef::previous()
const {
1456 if (broker()->mode() == JSHeapBroker::kDisabled) {
1457 AllowHandleAllocation handle_allocation;
1458 AllowHandleDereference handle_dereference;
1459 return ContextRef(broker(),
1460 handle(
object()->previous(), broker()->isolate()));
1462 return ContextRef(broker(), data()->AsContext()->previous());
1466 ObjectRef ContextRef::get(
int index)
const {
1467 AllowHandleAllocation handle_allocation;
1468 AllowHandleDereference handle_dereference;
1469 Handle<Object> value(
object()->
get(index), broker()->isolate());
1470 return ObjectRef(broker(), value);
1473 JSHeapBroker::JSHeapBroker(Isolate* isolate, Zone* broker_zone)
1474 : isolate_(isolate),
1475 broker_zone_(broker_zone),
1476 current_zone_(broker_zone),
1478 RefsMap(kMinimalRefsBucketCount, AddressMatcher(), zone())),
1479 array_and_object_prototypes_(zone()) {
1485 Trace(
"Constructing heap broker.\n");
1488 void JSHeapBroker::Trace(
const char* format, ...)
const {
1489 if (FLAG_trace_heap_broker) {
1490 PrintF(
"[%p] ",
this);
1491 for (
unsigned i = 0;
i < tracing_indentation_; ++
i) PrintF(
" ");
1493 va_start(arguments, format);
1494 base::OS::VPrint(format, arguments);
1499 void JSHeapBroker::StartSerializing() {
1500 CHECK_EQ(mode_, kDisabled);
1501 Trace(
"Starting serialization.\n");
1502 mode_ = kSerializing;
1506 void JSHeapBroker::StopSerializing() {
1507 CHECK_EQ(mode_, kSerializing);
1508 Trace(
"Stopping serialization.\n");
1509 mode_ = kSerialized;
1512 void JSHeapBroker::Retire() {
1513 CHECK_EQ(mode_, kSerialized);
1514 Trace(
"Retiring.\n");
1518 bool JSHeapBroker::SerializingAllowed()
const {
return mode() == kSerializing; }
1520 void JSHeapBroker::SetNativeContextRef() {
1521 native_context_ = NativeContextRef(
this, isolate()->native_context());
1524 bool IsShareable(Handle<Object>
object, Isolate* isolate) {
1525 Builtins*
const b = isolate->builtins();
1528 RootIndex root_index;
1529 return (object->IsHeapObject() &&
1530 b->IsBuiltinHandle(Handle<HeapObject>::cast(
object), &index)) ||
1531 isolate->roots_table().IsRootHandle(
object, &root_index);
1534 void JSHeapBroker::SerializeShareableObjects() {
1535 PerIsolateCompilerCache::Setup(isolate());
1536 compiler_cache_ = isolate()->compiler_cache();
1538 if (compiler_cache_->HasSnapshot()) {
1539 RefsMap* snapshot = compiler_cache_->GetSnapshot();
1541 refs_ =
new (zone()) RefsMap(snapshot, zone());
1546 this,
"JSHeapBroker::SerializeShareableObjects (building snapshot)");
1549 new (zone()) RefsMap(kInitialRefsBucketCount, AddressMatcher(), zone());
1551 current_zone_ = compiler_cache_->zone();
1553 Builtins*
const b = isolate()->builtins();
1555 Builtins::Name builtins[] = {
1556 Builtins::kAllocateInNewSpace,
1557 Builtins::kAllocateInOldSpace,
1558 Builtins::kArgumentsAdaptorTrampoline,
1559 Builtins::kArrayConstructorImpl,
1560 Builtins::kCallFunctionForwardVarargs,
1561 Builtins::kCallFunction_ReceiverIsAny,
1562 Builtins::kCallFunction_ReceiverIsNotNullOrUndefined,
1563 Builtins::kCallFunction_ReceiverIsNullOrUndefined,
1564 Builtins::kConstructFunctionForwardVarargs,
1565 Builtins::kForInFilter,
1566 Builtins::kJSBuiltinsConstructStub,
1567 Builtins::kJSConstructStubGeneric,
1568 Builtins::kStringAdd_CheckNone,
1569 Builtins::kStringAdd_ConvertLeft,
1570 Builtins::kStringAdd_ConvertRight,
1571 Builtins::kToNumber,
1572 Builtins::kToObject,
1574 for (
auto id : builtins) {
1575 GetOrCreateData(b->builtin_handle(
id));
1578 for (int32_t
id = 0;
id < Builtins::builtin_count; ++id) {
1579 if (Builtins::KindOf(
id) == Builtins::TFJ) {
1580 GetOrCreateData(b->builtin_handle(
id));
1584 for (RefsMap::Entry* p = refs_->Start(); p !=
nullptr; p = refs_->Next(p)) {
1585 CHECK(IsShareable(p->value->object(), isolate()));
1590 compiler_cache()->SetSnapshot(refs_);
1591 current_zone_ = broker_zone_;
1594 void JSHeapBroker::CollectArrayAndObjectPrototypes() {
1595 DisallowHeapAllocation no_gc;
1596 CHECK_EQ(mode(), kSerializing);
1597 CHECK(array_and_object_prototypes_.empty());
1599 Object* maybe_context = isolate()->heap()->native_contexts_list();
1600 while (!maybe_context->IsUndefined(isolate())) {
1601 Context context = Context::cast(maybe_context);
1602 Object* array_prot = context->get(Context::INITIAL_ARRAY_PROTOTYPE_INDEX);
1603 Object* object_prot = context->get(Context::INITIAL_OBJECT_PROTOTYPE_INDEX);
1604 array_and_object_prototypes_.emplace(JSObject::cast(array_prot), isolate());
1605 array_and_object_prototypes_.emplace(JSObject::cast(object_prot),
1607 maybe_context = context->next_context_link();
1610 CHECK(!array_and_object_prototypes_.empty());
1613 bool JSHeapBroker::IsArrayOrObjectPrototype(
const JSObjectRef&
object)
const {
1614 if (mode() == kDisabled) {
1615 return isolate()->IsInAnyContext(*
object.
object(),
1616 Context::INITIAL_ARRAY_PROTOTYPE_INDEX) ||
1617 isolate()->IsInAnyContext(*
object.
object(),
1618 Context::INITIAL_OBJECT_PROTOTYPE_INDEX);
1620 CHECK(!array_and_object_prototypes_.empty());
1621 return array_and_object_prototypes_.find(
object.
object()) !=
1622 array_and_object_prototypes_.end();
1625 void JSHeapBroker::SerializeStandardObjects() {
1626 if (mode() == kDisabled)
return;
1627 CHECK_EQ(mode(), kSerializing);
1629 SerializeShareableObjects();
1631 TraceScope tracer(
this,
"JSHeapBroker::SerializeStandardObjects");
1633 CollectArrayAndObjectPrototypes();
1635 SetNativeContextRef();
1636 native_context().Serialize();
1638 Factory*
const f = isolate()->factory();
1641 GetOrCreateData(f->arguments_marker_map());
1642 GetOrCreateData(f->bigint_string());
1643 GetOrCreateData(f->block_context_map());
1644 GetOrCreateData(f->boolean_map());
1645 GetOrCreateData(f->boolean_string());
1646 GetOrCreateData(f->catch_context_map());
1647 GetOrCreateData(f->empty_fixed_array());
1648 GetOrCreateData(f->empty_string());
1649 GetOrCreateData(f->eval_context_map());
1650 GetOrCreateData(f->false_string());
1651 GetOrCreateData(f->false_value());
1652 GetOrCreateData(f->fixed_array_map());
1653 GetOrCreateData(f->fixed_cow_array_map());
1654 GetOrCreateData(f->fixed_double_array_map());
1655 GetOrCreateData(f->function_context_map());
1656 GetOrCreateData(f->function_string());
1657 GetOrCreateData(f->heap_number_map());
1658 GetOrCreateData(f->length_string());
1659 GetOrCreateData(f->many_closures_cell_map());
1660 GetOrCreateData(f->minus_zero_value());
1661 GetOrCreateData(f->mutable_heap_number_map());
1662 GetOrCreateData(f->name_dictionary_map());
1663 GetOrCreateData(f->NaN_string());
1664 GetOrCreateData(f->null_map());
1665 GetOrCreateData(f->null_string());
1666 GetOrCreateData(f->null_value());
1667 GetOrCreateData(f->number_string());
1668 GetOrCreateData(f->object_string());
1669 GetOrCreateData(f->one_pointer_filler_map());
1670 GetOrCreateData(f->optimized_out());
1671 GetOrCreateData(f->optimized_out_map());
1672 GetOrCreateData(f->property_array_map());
1673 GetOrCreateData(f->sloppy_arguments_elements_map());
1674 GetOrCreateData(f->stale_register());
1675 GetOrCreateData(f->stale_register_map());
1676 GetOrCreateData(f->string_string());
1677 GetOrCreateData(f->symbol_string());
1678 GetOrCreateData(f->termination_exception_map());
1679 GetOrCreateData(f->the_hole_map());
1680 GetOrCreateData(f->the_hole_value());
1681 GetOrCreateData(f->true_string());
1682 GetOrCreateData(f->true_value());
1683 GetOrCreateData(f->undefined_map());
1684 GetOrCreateData(f->undefined_string());
1685 GetOrCreateData(f->undefined_value());
1686 GetOrCreateData(f->uninitialized_map());
1687 GetOrCreateData(f->with_context_map());
1688 GetOrCreateData(f->zero_string());
1691 GetOrCreateData(f->array_buffer_neutering_protector())
1694 GetOrCreateData(f->array_constructor_protector())->AsCell()->Serialize(
this);
1695 GetOrCreateData(f->array_iterator_protector())
1698 GetOrCreateData(f->array_species_protector())
1701 GetOrCreateData(f->no_elements_protector())
1704 GetOrCreateData(f->promise_hook_protector())
1707 GetOrCreateData(f->promise_species_protector())
1710 GetOrCreateData(f->promise_then_protector())
1713 GetOrCreateData(f->string_length_protector())->AsCell()->Serialize(
this);
1717 CodeFactory::CEntry(isolate(), 1, kDontSaveFPRegs, kArgvOnStack,
true));
1719 Trace(
"Finished serializing standard objects.\n");
1722 ObjectData* JSHeapBroker::GetData(Handle<Object>
object)
const {
1723 RefsMap::Entry* entry = refs_->Lookup(
object.address());
1724 return entry ? entry->value :
nullptr;
1728 ObjectData* JSHeapBroker::GetOrCreateData(Handle<Object>
object) {
1729 CHECK(SerializingAllowed());
1730 RefsMap::Entry* entry = refs_->LookupOrInsert(
object.address(), zone());
1731 ObjectData** data_storage = &(entry->value);
1732 if (*data_storage ==
nullptr) {
1734 AllowHandleAllocation handle_allocation;
1735 AllowHandleDereference handle_dereference;
1736 if (object->IsSmi()) {
1737 new (zone()) ObjectData(
this, data_storage,
object, kSmi);
1738 #define CREATE_DATA_IF_MATCH(name) \ 1739 } else if (object->Is##name()) { \ 1740 new (zone()) name##Data(this, data_storage, Handle<name>::cast(object)); 1741 HEAP_BROKER_OBJECT_LIST(CREATE_DATA_IF_MATCH)
1742 #undef CREATE_DATA_IF_MATCH 1747 CHECK_NOT_NULL(*data_storage);
1748 return (*data_storage);
1752 ObjectData* JSHeapBroker::GetOrCreateData(Object*
object) {
1753 return GetOrCreateData(handle(
object, isolate()));
1756 #define DEFINE_IS_AND_AS(Name) \ 1757 bool ObjectRef::Is##Name() const { return data()->Is##Name(); } \ 1758 Name##Ref ObjectRef::As##Name() const { \ 1759 DCHECK(Is##Name()); \ 1760 return Name##Ref(broker(), data()); \ 1762 HEAP_BROKER_OBJECT_LIST(DEFINE_IS_AND_AS)
1763 #undef DEFINE_IS_AND_AS 1765 bool ObjectRef::IsSmi()
const {
return data()->is_smi(); }
1767 int ObjectRef::AsSmi()
const {
1770 return Handle<Smi>::cast(
object())->value();
1773 base::Optional<MapRef> JSObjectRef::GetObjectCreateMap()
const {
1774 if (broker()->mode() == JSHeapBroker::kDisabled) {
1775 AllowHandleAllocation handle_allocation;
1776 AllowHandleDereference allow_handle_dereference;
1777 AllowHeapAllocation heap_allocation;
1778 Handle<Map> instance_map;
1779 if (Map::TryGetObjectCreateMap(broker()->isolate(),
object())
1780 .ToHandle(&instance_map)) {
1781 return MapRef(broker(), instance_map);
1783 return base::Optional<MapRef>();
1786 MapData* map_data = data()->AsJSObject()->object_create_map();
1787 return map_data !=
nullptr ? MapRef(broker(), map_data)
1788 : base::Optional<MapRef>();
1791 #define DEF_TESTER(Type, ...) \ 1792 bool MapRef::Is##Type##Map() const { \ 1793 return InstanceTypeChecker::Is##Type(instance_type()); \ 1795 INSTANCE_TYPE_CHECKERS(DEF_TESTER)
1798 base::Optional<MapRef> MapRef::AsElementsKind(ElementsKind kind)
const {
1799 if (broker()->mode() == JSHeapBroker::kDisabled) {
1800 AllowHandleAllocation handle_allocation;
1801 AllowHeapAllocation heap_allocation;
1802 AllowHandleDereference allow_handle_dereference;
1803 return MapRef(broker(),
1804 Map::AsElementsKind(broker()->isolate(),
object(), kind));
1806 if (kind == elements_kind())
return *
this;
1807 const ZoneVector<MapData*>& elements_kind_generalizations =
1808 data()->AsMap()->elements_kind_generalizations();
1809 for (
auto data : elements_kind_generalizations) {
1810 MapRef map(broker(), data);
1811 if (map.elements_kind() == kind)
return map;
1813 return base::Optional<MapRef>();
1816 int JSFunctionRef::InitialMapInstanceSizeWithMinSlack()
const {
1817 if (broker()->mode() == JSHeapBroker::kDisabled) {
1818 AllowHandleDereference allow_handle_dereference;
1819 AllowHandleAllocation handle_allocation;
1820 return object()->ComputeInstanceSizeWithMinSlack(broker()->isolate());
1822 return data()->AsJSFunction()->initial_map_instance_size_with_min_slack();
1826 base::Optional<ScriptContextTableRef::LookupResult>
1827 ScriptContextTableRef::lookup(
const NameRef& name)
const {
1828 AllowHandleAllocation handle_allocation;
1829 AllowHandleDereference handle_dereference;
1830 if (!name.IsString())
return {};
1831 ScriptContextTable::LookupResult lookup_result;
1832 auto table = object();
1833 if (!ScriptContextTable::Lookup(broker()->isolate(), table,
1834 name.AsString().object(), &lookup_result)) {
1837 Handle<Context> script_context = ScriptContextTable::GetContext(
1838 broker()->isolate(), table, lookup_result.context_index);
1839 LookupResult result{ContextRef(broker(), script_context),
1840 lookup_result.mode == VariableMode::kConst,
1841 lookup_result.slot_index};
1845 OddballType MapRef::oddball_type()
const {
1846 if (instance_type() != ODDBALL_TYPE) {
1847 return OddballType::kNone;
1849 Factory* f = broker()->isolate()->factory();
1850 if (equals(MapRef(broker(), f->undefined_map()))) {
1851 return OddballType::kUndefined;
1853 if (equals(MapRef(broker(), f->null_map()))) {
1854 return OddballType::kNull;
1856 if (equals(MapRef(broker(), f->boolean_map()))) {
1857 return OddballType::kBoolean;
1859 if (equals(MapRef(broker(), f->the_hole_map()))) {
1860 return OddballType::kHole;
1862 if (equals(MapRef(broker(), f->uninitialized_map()))) {
1863 return OddballType::kUninitialized;
1865 DCHECK(equals(MapRef(broker(), f->termination_exception_map())) ||
1866 equals(MapRef(broker(), f->arguments_marker_map())) ||
1867 equals(MapRef(broker(), f->optimized_out_map())) ||
1868 equals(MapRef(broker(), f->stale_register_map())));
1869 return OddballType::kOther;
1872 ObjectRef FeedbackVectorRef::get(FeedbackSlot slot)
const {
1873 if (broker()->mode() == JSHeapBroker::kDisabled) {
1874 AllowHandleAllocation handle_allocation;
1875 AllowHandleDereference handle_dereference;
1876 Handle<Object> value(
object()->Get(slot)->cast<Object>(),
1877 broker()->isolate());
1878 return ObjectRef(broker(), value);
1880 int i = FeedbackVector::GetIndex(slot);
1881 return ObjectRef(broker(), data()->AsFeedbackVector()->feedback().at(
i));
1884 double JSObjectRef::RawFastDoublePropertyAt(FieldIndex index)
const {
1885 if (broker()->mode() == JSHeapBroker::kDisabled) {
1886 AllowHandleDereference handle_dereference;
1887 return object()->RawFastDoublePropertyAt(index);
1889 JSObjectData* object_data = data()->AsJSObject();
1890 CHECK(index.is_inobject());
1891 return object_data->GetInobjectField(index.property_index()).AsDouble();
1894 ObjectRef JSObjectRef::RawFastPropertyAt(FieldIndex index)
const {
1895 if (broker()->mode() == JSHeapBroker::kDisabled) {
1896 AllowHandleAllocation handle_allocation;
1897 AllowHandleDereference handle_dereference;
1898 return ObjectRef(broker(), handle(
object()->RawFastPropertyAt(index),
1899 broker()->isolate()));
1901 JSObjectData* object_data = data()->AsJSObject();
1902 CHECK(index.is_inobject());
1905 object_data->GetInobjectField(index.property_index()).AsObject());
1908 bool AllocationSiteRef::IsFastLiteral()
const {
1909 if (broker()->mode() == JSHeapBroker::kDisabled) {
1910 AllowHeapAllocation allow_heap_allocation;
1911 AllowHandleAllocation allow_handle_allocation;
1912 AllowHandleDereference allow_handle_dereference;
1913 return IsInlinableFastLiteral(
1914 handle(
object()->boilerplate(), broker()->isolate()));
1916 return data()->AsAllocationSite()->IsFastLiteral();
1919 void JSObjectRef::EnsureElementsTenured() {
1920 if (broker()->mode() == JSHeapBroker::kDisabled) {
1921 AllowHandleAllocation allow_handle_allocation;
1922 AllowHandleDereference allow_handle_dereference;
1923 AllowHeapAllocation allow_heap_allocation;
1925 Handle<FixedArrayBase> object_elements = elements().object();
1926 if (Heap::InNewSpace(*object_elements)) {
1931 broker()->isolate()->factory()->CopyAndTenureFixedCOWArray(
1932 Handle<FixedArray>::cast(object_elements));
1933 object()->set_elements(*object_elements);
1937 CHECK(data()->AsJSObject()->cow_or_empty_elements_tenured());
1940 FieldIndex MapRef::GetFieldIndexFor(
int descriptor_index)
const {
1941 if (broker()->mode() == JSHeapBroker::kDisabled) {
1942 AllowHandleDereference allow_handle_dereference;
1943 return FieldIndex::ForDescriptor(*
object(), descriptor_index);
1945 DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors();
1946 return descriptors->contents().at(descriptor_index).field_index;
1949 int MapRef::GetInObjectPropertyOffset(
int i)
const {
1950 if (broker()->mode() == JSHeapBroker::kDisabled) {
1951 AllowHandleDereference allow_handle_dereference;
1952 return object()->GetInObjectPropertyOffset(
i);
1954 return (GetInObjectPropertiesStartInWords() +
i) * kPointerSize;
1957 PropertyDetails MapRef::GetPropertyDetails(
int descriptor_index)
const {
1958 if (broker()->mode() == JSHeapBroker::kDisabled) {
1959 AllowHandleDereference allow_handle_dereference;
1960 return object()->instance_descriptors()->GetDetails(descriptor_index);
1962 DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors();
1963 return descriptors->contents().at(descriptor_index).details;
1966 NameRef MapRef::GetPropertyKey(
int descriptor_index)
const {
1967 if (broker()->mode() == JSHeapBroker::kDisabled) {
1968 AllowHandleAllocation handle_allocation;
1969 AllowHandleDereference allow_handle_dereference;
1972 handle(
object()->instance_descriptors()->GetKey(descriptor_index),
1973 broker()->isolate()));
1975 DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors();
1976 return NameRef(broker(), descriptors->contents().at(descriptor_index).key);
1979 bool MapRef::IsFixedCowArrayMap()
const {
1980 Handle<Map> fixed_cow_array_map =
1981 ReadOnlyRoots(broker()->isolate()).fixed_cow_array_map_handle();
1982 return equals(MapRef(broker(), fixed_cow_array_map));
1985 bool MapRef::IsPrimitiveMap()
const {
1986 return instance_type() <= LAST_PRIMITIVE_TYPE;
1989 MapRef MapRef::FindFieldOwner(
int descriptor_index)
const {
1990 if (broker()->mode() == JSHeapBroker::kDisabled) {
1991 AllowHandleAllocation handle_allocation;
1992 AllowHandleDereference allow_handle_dereference;
1994 object()->FindFieldOwner(broker()->isolate(), descriptor_index),
1995 broker()->isolate());
1996 return MapRef(broker(), owner);
1998 DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors();
1999 return MapRef(broker(),
2000 descriptors->contents().at(descriptor_index).field_owner);
2003 ObjectRef MapRef::GetFieldType(
int descriptor_index)
const {
2004 if (broker()->mode() == JSHeapBroker::kDisabled) {
2005 AllowHandleAllocation handle_allocation;
2006 AllowHandleDereference allow_handle_dereference;
2007 Handle<FieldType> field_type(
2008 object()->instance_descriptors()->GetFieldType(descriptor_index),
2009 broker()->isolate());
2010 return ObjectRef(broker(), field_type);
2012 DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors();
2013 return ObjectRef(broker(),
2014 descriptors->contents().at(descriptor_index).field_type);
2017 bool MapRef::IsUnboxedDoubleField(
int descriptor_index)
const {
2018 if (broker()->mode() == JSHeapBroker::kDisabled) {
2019 AllowHandleDereference allow_handle_dereference;
2020 return object()->IsUnboxedDoubleField(
2021 FieldIndex::ForDescriptor(*
object(), descriptor_index));
2023 DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors();
2024 return descriptors->contents().at(descriptor_index).is_unboxed_double_field;
2027 uint16_t StringRef::GetFirstChar() {
2028 if (broker()->mode() == JSHeapBroker::kDisabled) {
2029 AllowHandleDereference allow_handle_dereference;
2030 return object()->Get(0);
2032 return data()->AsString()->first_char();
2035 base::Optional<double> StringRef::ToNumber() {
2036 if (broker()->mode() == JSHeapBroker::kDisabled) {
2037 AllowHandleDereference allow_handle_dereference;
2038 AllowHandleAllocation allow_handle_allocation;
2039 AllowHeapAllocation allow_heap_allocation;
2040 int flags = ALLOW_HEX | ALLOW_OCTAL | ALLOW_BINARY;
2041 return StringToDouble(broker()->isolate(),
object(), flags);
2043 return data()->AsString()->to_number();
2046 ObjectRef FixedArrayRef::get(
int i)
const {
2047 if (broker()->mode() == JSHeapBroker::kDisabled) {
2048 AllowHandleAllocation handle_allocation;
2049 AllowHandleDereference allow_handle_dereference;
2050 return ObjectRef(broker(), handle(
object()->
get(
i), broker()->isolate()));
2052 return ObjectRef(broker(), data()->AsFixedArray()->Get(
i));
2055 bool FixedDoubleArrayRef::is_the_hole(
int i)
const {
2056 if (broker()->mode() == JSHeapBroker::kDisabled) {
2057 AllowHandleDereference allow_handle_dereference;
2058 return object()->is_the_hole(
i);
2060 return data()->AsFixedDoubleArray()->Get(
i).is_hole_nan();
2063 double FixedDoubleArrayRef::get_scalar(
int i)
const {
2064 if (broker()->mode() == JSHeapBroker::kDisabled) {
2065 AllowHandleDereference allow_handle_dereference;
2066 return object()->get_scalar(
i);
2068 CHECK(!data()->AsFixedDoubleArray()->Get(
i).is_hole_nan());
2069 return data()->AsFixedDoubleArray()->Get(
i).get_scalar();
2072 #define IF_BROKER_DISABLED_ACCESS_HANDLE_C(holder, name) \ 2073 if (broker()->mode() == JSHeapBroker::kDisabled) { \ 2074 AllowHandleAllocation handle_allocation; \ 2075 AllowHandleDereference allow_handle_dereference; \ 2076 return object()->name(); \ 2079 #define IF_BROKER_DISABLED_ACCESS_HANDLE(holder, result, name) \ 2080 if (broker()->mode() == JSHeapBroker::kDisabled) { \ 2081 AllowHandleAllocation handle_allocation; \ 2082 AllowHandleDereference allow_handle_dereference; \ 2083 return result##Ref(broker(), \ 2084 handle(object()->name(), broker()->isolate())); \ 2089 #define BIMODAL_ACCESSOR(holder, result, name) \ 2090 result##Ref holder##Ref::name() const { \ 2091 IF_BROKER_DISABLED_ACCESS_HANDLE(holder, result, name); \ 2092 return result##Ref(broker(), ObjectRef::data()->As##holder()->name()); \ 2096 #define BIMODAL_ACCESSOR_C(holder, result, name) \ 2097 result holder##Ref::name() const { \ 2098 IF_BROKER_DISABLED_ACCESS_HANDLE_C(holder, name); \ 2099 return ObjectRef::data()->As##holder()->name(); \ 2103 #define BIMODAL_ACCESSOR_B(holder, field, name, BitField) \ 2104 typename BitField::FieldType holder##Ref::name() const { \ 2105 IF_BROKER_DISABLED_ACCESS_HANDLE_C(holder, name); \ 2106 return BitField::decode(ObjectRef::data()->As##holder()->field()); \ 2109 BIMODAL_ACCESSOR(AllocationSite, Object, nested_site)
2110 BIMODAL_ACCESSOR_C(AllocationSite,
bool, CanInlineCall)
2111 BIMODAL_ACCESSOR_C(AllocationSite,
bool, PointsToLiteral)
2112 BIMODAL_ACCESSOR_C(AllocationSite, ElementsKind, GetElementsKind)
2113 BIMODAL_ACCESSOR_C(AllocationSite, PretenureFlag, GetPretenureMode)
2115 BIMODAL_ACCESSOR_C(BytecodeArray,
int, register_count)
2117 BIMODAL_ACCESSOR(Cell, Object, value)
2119 BIMODAL_ACCESSOR(HeapObject, Map, map)
2121 BIMODAL_ACCESSOR(JSArray, Object, length)
2123 BIMODAL_ACCESSOR(JSBoundFunction, Object, bound_target_function)
2124 BIMODAL_ACCESSOR(JSBoundFunction, Object, bound_this)
2125 BIMODAL_ACCESSOR(JSBoundFunction, FixedArray, bound_arguments)
2127 BIMODAL_ACCESSOR_C(JSDataView,
size_t, byte_length)
2128 BIMODAL_ACCESSOR_C(JSDataView,
size_t, byte_offset)
2130 BIMODAL_ACCESSOR_C(JSFunction,
bool, has_prototype)
2131 BIMODAL_ACCESSOR_C(JSFunction,
bool, has_initial_map)
2132 BIMODAL_ACCESSOR_C(JSFunction,
bool, PrototypeRequiresRuntimeLookup)
2133 BIMODAL_ACCESSOR(JSFunction, Context, context)
2134 BIMODAL_ACCESSOR(JSFunction, NativeContext, native_context)
2135 BIMODAL_ACCESSOR(JSFunction, Map, initial_map)
2136 BIMODAL_ACCESSOR(JSFunction, Object, prototype)
2137 BIMODAL_ACCESSOR(JSFunction, SharedFunctionInfo, shared)
2139 BIMODAL_ACCESSOR_C(JSTypedArray,
bool, is_on_heap)
2140 BIMODAL_ACCESSOR_C(JSTypedArray,
size_t, length_value)
2141 BIMODAL_ACCESSOR(JSTypedArray, HeapObject, buffer)
2143 BIMODAL_ACCESSOR_B(Map, bit_field2, elements_kind, Map::ElementsKindBits)
2144 BIMODAL_ACCESSOR_B(Map, bit_field2, is_extensible, Map::IsExtensibleBit)
2145 BIMODAL_ACCESSOR_B(Map, bit_field3, is_deprecated, Map::IsDeprecatedBit)
2146 BIMODAL_ACCESSOR_B(Map, bit_field3, is_dictionary_map, Map::IsDictionaryMapBit)
2147 BIMODAL_ACCESSOR_B(Map, bit_field3, NumberOfOwnDescriptors,
2148 Map::NumberOfOwnDescriptorsBits)
2149 BIMODAL_ACCESSOR_B(Map, bit_field3, has_hidden_prototype,
2150 Map::HasHiddenPrototypeBit)
2151 BIMODAL_ACCESSOR_B(Map, bit_field, has_prototype_slot, Map::HasPrototypeSlotBit)
2152 BIMODAL_ACCESSOR_B(Map, bit_field, is_access_check_needed,
2153 Map::IsAccessCheckNeededBit)
2154 BIMODAL_ACCESSOR_B(Map, bit_field, is_callable, Map::IsCallableBit)
2155 BIMODAL_ACCESSOR_B(Map, bit_field, is_constructor, Map::IsConstructorBit)
2156 BIMODAL_ACCESSOR_B(Map, bit_field, is_undetectable, Map::IsUndetectableBit)
2157 BIMODAL_ACCESSOR_C(Map,
int, instance_size)
2158 BIMODAL_ACCESSOR(Map, Object, prototype)
2159 BIMODAL_ACCESSOR_C(Map, InstanceType, instance_type)
2160 BIMODAL_ACCESSOR(Map, Object, GetConstructor)
2162 #define DEF_NATIVE_CONTEXT_ACCESSOR(type, name) \ 2163 BIMODAL_ACCESSOR(NativeContext, type, name) 2164 BROKER_NATIVE_CONTEXT_FIELDS(DEF_NATIVE_CONTEXT_ACCESSOR)
2165 #undef DEF_NATIVE_CONTEXT_ACCESSOR 2167 BIMODAL_ACCESSOR(PropertyCell, Object, value)
2168 BIMODAL_ACCESSOR_C(PropertyCell, PropertyDetails, property_details)
2170 BIMODAL_ACCESSOR_C(SharedFunctionInfo,
int, builtin_id)
2171 BIMODAL_ACCESSOR(SharedFunctionInfo, BytecodeArray, GetBytecodeArray)
2172 #define DEF_SFI_ACCESSOR(type, name) \ 2173 BIMODAL_ACCESSOR_C(SharedFunctionInfo, type, name) 2174 BROKER_SFI_FIELDS(DEF_SFI_ACCESSOR)
2175 #undef DEF_SFI_ACCESSOR 2177 BIMODAL_ACCESSOR_C(String,
int, length)
2179 void* JSTypedArrayRef::elements_external_pointer()
const {
2180 if (broker()->mode() == JSHeapBroker::kDisabled) {
2181 AllowHandleDereference allow_handle_dereference;
2182 return FixedTypedArrayBase::cast(
object()->elements())->external_pointer();
2184 return data()->AsJSTypedArray()->elements_external_pointer();
2187 bool MapRef::IsInobjectSlackTrackingInProgress()
const {
2188 IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, IsInobjectSlackTrackingInProgress);
2189 return Map::ConstructionCounterBits::decode(data()->AsMap()->bit_field3()) !=
2190 Map::kNoSlackTracking;
2193 int MapRef::constructor_function_index()
const {
2194 IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, GetConstructorFunctionIndex);
2195 CHECK(IsPrimitiveMap());
2196 return data()->AsMap()->constructor_function_index();
2199 bool MapRef::is_stable()
const {
2200 IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, is_stable);
2201 return !Map::IsUnstableBit::decode(data()->AsMap()->bit_field3());
2204 bool MapRef::CanBeDeprecated()
const {
2205 IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, CanBeDeprecated);
2206 CHECK_GT(NumberOfOwnDescriptors(), 0);
2207 return data()->AsMap()->can_be_deprecated();
2210 bool MapRef::CanTransition()
const {
2211 IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, CanTransition);
2212 return data()->AsMap()->can_transition();
2215 int MapRef::GetInObjectPropertiesStartInWords()
const {
2216 IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, GetInObjectPropertiesStartInWords);
2217 return data()->AsMap()->in_object_properties_start_in_words();
2220 int MapRef::GetInObjectProperties()
const {
2221 IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, GetInObjectProperties);
2222 return data()->AsMap()->in_object_properties();
2225 int ScopeInfoRef::ContextLength()
const {
2226 IF_BROKER_DISABLED_ACCESS_HANDLE_C(ScopeInfo, ContextLength);
2227 return data()->AsScopeInfo()->context_length();
2230 bool StringRef::IsExternalString()
const {
2231 IF_BROKER_DISABLED_ACCESS_HANDLE_C(String, IsExternalString);
2232 return data()->AsString()->is_external_string();
2235 bool StringRef::IsSeqString()
const {
2236 IF_BROKER_DISABLED_ACCESS_HANDLE_C(String, IsSeqString);
2237 return data()->AsString()->is_seq_string();
2240 MapRef NativeContextRef::GetFunctionMapFromIndex(
int index)
const {
2241 DCHECK_GE(index, Context::FIRST_FUNCTION_MAP_INDEX);
2242 DCHECK_LE(index, Context::LAST_FUNCTION_MAP_INDEX);
2243 if (broker()->mode() == JSHeapBroker::kDisabled) {
2244 return get(index).AsMap();
2246 return MapRef(broker(), data()->AsNativeContext()->function_maps().at(
2247 index - Context::FIRST_FUNCTION_MAP_INDEX));
2250 MapRef NativeContextRef::GetInitialJSArrayMap(ElementsKind kind)
const {
2252 case PACKED_SMI_ELEMENTS:
2253 return js_array_packed_smi_elements_map();
2254 case HOLEY_SMI_ELEMENTS:
2255 return js_array_holey_smi_elements_map();
2256 case PACKED_DOUBLE_ELEMENTS:
2257 return js_array_packed_double_elements_map();
2258 case HOLEY_DOUBLE_ELEMENTS:
2259 return js_array_holey_double_elements_map();
2260 case PACKED_ELEMENTS:
2261 return js_array_packed_elements_map();
2262 case HOLEY_ELEMENTS:
2263 return js_array_holey_elements_map();
2269 base::Optional<JSFunctionRef> NativeContextRef::GetConstructorFunction(
2270 const MapRef& map)
const {
2271 CHECK(map.IsPrimitiveMap());
2272 switch (map.constructor_function_index()) {
2273 case Map::kNoConstructorFunctionIndex:
2274 return base::nullopt;
2275 case Context::BIGINT_FUNCTION_INDEX:
2276 return bigint_function();
2277 case Context::BOOLEAN_FUNCTION_INDEX:
2278 return boolean_function();
2279 case Context::NUMBER_FUNCTION_INDEX:
2280 return number_function();
2281 case Context::STRING_FUNCTION_INDEX:
2282 return string_function();
2283 case Context::SYMBOL_FUNCTION_INDEX:
2284 return symbol_function();
2290 bool ObjectRef::IsNullOrUndefined()
const {
2291 if (IsSmi())
return false;
2292 OddballType type = AsHeapObject().map().oddball_type();
2293 return type == OddballType::kNull || type == OddballType::kUndefined;
2296 bool ObjectRef::BooleanValue()
const {
2297 if (broker()->mode() == JSHeapBroker::kDisabled) {
2298 AllowHandleDereference allow_handle_dereference;
2299 return object()->BooleanValue(broker()->isolate());
2301 return IsSmi() ? (AsSmi() != 0) : data()->AsHeapObject()->boolean_value();
2304 double ObjectRef::OddballToNumber()
const {
2305 OddballType type = AsHeapObject().map().oddball_type();
2308 case OddballType::kBoolean: {
2309 ObjectRef true_ref(broker(),
2310 broker()->isolate()->factory()->true_value());
2311 return this->equals(true_ref) ? 1 : 0;
2314 case OddballType::kUndefined: {
2315 return std::numeric_limits<double>::quiet_NaN();
2318 case OddballType::kNull: {
2329 double HeapNumberRef::value()
const {
2330 IF_BROKER_DISABLED_ACCESS_HANDLE_C(HeapNumber, value);
2331 return data()->AsHeapNumber()->value();
2334 double MutableHeapNumberRef::value()
const {
2335 IF_BROKER_DISABLED_ACCESS_HANDLE_C(MutableHeapNumber, value);
2336 return data()->AsMutableHeapNumber()->value();
2339 CellRef ModuleRef::GetCell(
int cell_index)
const {
2340 if (broker()->mode() == JSHeapBroker::kDisabled) {
2341 AllowHandleAllocation handle_allocation;
2342 AllowHandleDereference allow_handle_dereference;
2343 return CellRef(broker(),
2344 handle(
object()->GetCell(cell_index), broker()->isolate()));
2346 return CellRef(broker(), data()->AsModule()->GetCell(cell_index));
2349 ObjectRef::ObjectRef(JSHeapBroker* broker, Handle<Object>
object)
2351 switch (broker->mode()) {
2352 case JSHeapBroker::kSerialized:
2353 data_ = broker->GetData(
object);
2355 case JSHeapBroker::kSerializing:
2356 data_ = broker->GetOrCreateData(
object);
2358 case JSHeapBroker::kDisabled: {
2359 RefsMap::Entry* entry =
2360 broker->refs_->LookupOrInsert(
object.address(), broker->zone());
2361 ObjectData** storage = &(entry->value);
2362 if (*storage ==
nullptr) {
2363 AllowHandleDereference handle_dereference;
2364 entry->value =
new (broker->zone())
2365 ObjectData(broker, storage,
object,
2366 object->IsSmi() ? kSmi : kUnserializedHeapObject);
2371 case JSHeapBroker::kRetired:
2374 CHECK_NOT_NULL(data_);
2378 OddballType GetOddballType(Isolate* isolate, Map map) {
2379 if (map->instance_type() != ODDBALL_TYPE) {
2380 return OddballType::kNone;
2382 ReadOnlyRoots roots(isolate);
2383 if (map == roots.undefined_map()) {
2384 return OddballType::kUndefined;
2386 if (map == roots.null_map()) {
2387 return OddballType::kNull;
2389 if (map == roots.boolean_map()) {
2390 return OddballType::kBoolean;
2392 if (map == roots.the_hole_map()) {
2393 return OddballType::kHole;
2395 if (map == roots.uninitialized_map()) {
2396 return OddballType::kUninitialized;
2398 DCHECK(map == roots.termination_exception_map() ||
2399 map == roots.arguments_marker_map() ||
2400 map == roots.optimized_out_map() || map == roots.stale_register_map());
2401 return OddballType::kOther;
2405 HeapObjectType HeapObjectRef::GetHeapObjectType()
const {
2406 if (broker()->mode() == JSHeapBroker::kDisabled) {
2407 AllowHandleDereference handle_dereference;
2408 Map map = Handle<HeapObject>::cast(
object())->map();
2409 HeapObjectType::Flags flags(0);
2410 if (map->is_undetectable()) flags |= HeapObjectType::kUndetectable;
2411 if (map->is_callable()) flags |= HeapObjectType::kCallable;
2412 return HeapObjectType(map->instance_type(), flags,
2413 GetOddballType(broker()->isolate(), map));
2415 HeapObjectType::Flags flags(0);
2416 if (map().is_undetectable()) flags |= HeapObjectType::kUndetectable;
2417 if (map().is_callable()) flags |= HeapObjectType::kCallable;
2418 return HeapObjectType(map().instance_type(), flags, map().oddball_type());
2420 base::Optional<JSObjectRef> AllocationSiteRef::boilerplate()
const {
2421 if (broker()->mode() == JSHeapBroker::kDisabled) {
2422 AllowHandleAllocation handle_allocation;
2423 AllowHandleDereference allow_handle_dereference;
2424 return JSObjectRef(broker(),
2425 handle(
object()->boilerplate(), broker()->isolate()));
2427 JSObjectData* boilerplate = data()->AsAllocationSite()->boilerplate();
2429 return JSObjectRef(broker(), boilerplate);
2431 return base::nullopt;
2435 ElementsKind JSObjectRef::GetElementsKind()
const {
2436 return map().elements_kind();
2439 FixedArrayBaseRef JSObjectRef::elements()
const {
2440 if (broker()->mode() == JSHeapBroker::kDisabled) {
2441 AllowHandleAllocation handle_allocation;
2442 AllowHandleDereference allow_handle_dereference;
2443 return FixedArrayBaseRef(broker(),
2444 handle(
object()->elements(), broker()->isolate()));
2446 return FixedArrayBaseRef(broker(), data()->AsJSObject()->elements());
2449 int FixedArrayBaseRef::length()
const {
2450 IF_BROKER_DISABLED_ACCESS_HANDLE_C(FixedArrayBase, length);
2451 return data()->AsFixedArrayBase()->length();
2454 ObjectData* FixedArrayData::Get(
int i)
const {
2455 CHECK_LT(
i, static_cast<int>(contents_.size()));
2456 CHECK_NOT_NULL(contents_[
i]);
2457 return contents_[
i];
2460 Float64 FixedDoubleArrayData::Get(
int i)
const {
2461 CHECK_LT(
i, static_cast<int>(contents_.size()));
2462 return contents_[
i];
2465 void FeedbackVectorRef::SerializeSlots() {
2466 data()->AsFeedbackVector()->SerializeSlots(broker());
2469 ObjectRef JSRegExpRef::data()
const {
2470 IF_BROKER_DISABLED_ACCESS_HANDLE(JSRegExp, Object, data);
2471 return ObjectRef(broker(), ObjectRef::data()->AsJSRegExp()->data());
2474 ObjectRef JSRegExpRef::flags()
const {
2475 IF_BROKER_DISABLED_ACCESS_HANDLE(JSRegExp, Object, flags);
2476 return ObjectRef(broker(), ObjectRef::data()->AsJSRegExp()->flags());
2479 ObjectRef JSRegExpRef::last_index()
const {
2480 IF_BROKER_DISABLED_ACCESS_HANDLE(JSRegExp, Object, last_index);
2481 return ObjectRef(broker(), ObjectRef::data()->AsJSRegExp()->last_index());
2484 ObjectRef JSRegExpRef::raw_properties_or_hash()
const {
2485 IF_BROKER_DISABLED_ACCESS_HANDLE(JSRegExp, Object, raw_properties_or_hash);
2486 return ObjectRef(broker(),
2487 ObjectRef::data()->AsJSRegExp()->raw_properties_or_hash());
2490 ObjectRef JSRegExpRef::source()
const {
2491 IF_BROKER_DISABLED_ACCESS_HANDLE(JSRegExp, Object, source);
2492 return ObjectRef(broker(), ObjectRef::data()->AsJSRegExp()->source());
2495 Handle<Object> ObjectRef::object()
const {
return data_->object(); }
2497 #define DEF_OBJECT_GETTER(T) \ 2498 Handle<T> T##Ref::object() const { \ 2499 return Handle<T>(reinterpret_cast<Address*>(data_->object().address())); \ 2501 HEAP_BROKER_OBJECT_LIST(DEF_OBJECT_GETTER)
2502 #undef DEF_OBJECT_GETTER 2504 JSHeapBroker* ObjectRef::broker()
const {
return broker_; }
2506 ObjectData* ObjectRef::data()
const {
2507 switch (broker()->mode()) {
2508 case JSHeapBroker::kDisabled:
2509 CHECK_NE(data_->kind(), kSerializedHeapObject);
2511 case JSHeapBroker::kSerializing:
2512 case JSHeapBroker::kSerialized:
2513 CHECK_NE(data_->kind(), kUnserializedHeapObject);
2515 case JSHeapBroker::kRetired:
2520 Reduction NoChangeBecauseOfMissingData(JSHeapBroker* broker,
2521 const char*
function,
int line) {
2522 if (FLAG_trace_heap_broker) {
2523 PrintF(
"[%p] Skipping optimization in %s at line %d due to missing data\n",
2524 broker,
function, line);
2526 return AdvancedReducer::NoChange();
2529 NativeContextData::NativeContextData(JSHeapBroker* broker, ObjectData** storage,
2530 Handle<NativeContext>
object)
2531 : ContextData(broker, storage, object), function_maps_(broker->zone()) {}
2533 void NativeContextData::Serialize(JSHeapBroker* broker) {
2534 if (serialized_)
return;
2537 TraceScope tracer(broker,
this,
"NativeContextData::Serialize");
2538 Handle<NativeContext> context = Handle<NativeContext>::cast(
object());
2540 #define SERIALIZE_MEMBER(type, name) \ 2541 DCHECK_NULL(name##_); \ 2542 name##_ = broker->GetOrCreateData(context->name())->As##type(); \ 2543 if (name##_->IsJSFunction()) name##_->AsJSFunction()->Serialize(broker); \ 2544 if (name##_->IsMap()) name##_->AsMap()->SerializeConstructor(broker); 2545 BROKER_COMPULSORY_NATIVE_CONTEXT_FIELDS(SERIALIZE_MEMBER)
2546 if (!broker->isolate()->bootstrapper()->IsActive()) {
2547 BROKER_OPTIONAL_NATIVE_CONTEXT_FIELDS(SERIALIZE_MEMBER)
2549 #undef SERIALIZE_MEMBER 2551 bound_function_with_constructor_map_->SerializePrototype(broker);
2552 bound_function_without_constructor_map_->SerializePrototype(broker);
2554 DCHECK(function_maps_.empty());
2555 int const first = Context::FIRST_FUNCTION_MAP_INDEX;
2556 int const last = Context::LAST_FUNCTION_MAP_INDEX;
2557 function_maps_.reserve(last + 1 - first);
2558 for (
int i = first;
i <= last; ++
i) {
2559 function_maps_.push_back(broker->GetOrCreateData(context->get(
i))->AsMap());
2563 void JSFunctionRef::Serialize() {
2564 if (broker()->mode() == JSHeapBroker::kDisabled)
return;
2565 CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
2566 data()->AsJSFunction()->Serialize(broker());
2569 void JSObjectRef::SerializeObjectCreateMap() {
2570 if (broker()->mode() == JSHeapBroker::kDisabled)
return;
2571 CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
2572 data()->AsJSObject()->SerializeObjectCreateMap(broker());
2575 void MapRef::SerializeOwnDescriptors() {
2576 if (broker()->mode() == JSHeapBroker::kDisabled)
return;
2577 CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
2578 data()->AsMap()->SerializeOwnDescriptors(broker());
2581 void MapRef::SerializePrototype() {
2582 if (broker()->mode() == JSHeapBroker::kDisabled)
return;
2583 CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
2584 data()->AsMap()->SerializePrototype(broker());
2587 void ModuleRef::Serialize() {
2588 if (broker()->mode() == JSHeapBroker::kDisabled)
return;
2589 CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
2590 data()->AsModule()->Serialize(broker());
2593 void ContextRef::Serialize() {
2594 if (broker()->mode() == JSHeapBroker::kDisabled)
return;
2595 CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
2596 data()->AsContext()->Serialize(broker());
2599 void NativeContextRef::Serialize() {
2600 if (broker()->mode() == JSHeapBroker::kDisabled)
return;
2601 CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
2602 data()->AsNativeContext()->Serialize(broker());
2605 void JSTypedArrayRef::Serialize() {
2606 if (broker()->mode() == JSHeapBroker::kDisabled)
return;
2607 CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
2608 data()->AsJSTypedArray()->Serialize(broker());
2611 void JSBoundFunctionRef::Serialize() {
2612 if (broker()->mode() == JSHeapBroker::kDisabled)
return;
2613 CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
2614 data()->AsJSBoundFunction()->Serialize(broker());
2617 #undef BIMODAL_ACCESSOR 2618 #undef BIMODAL_ACCESSOR_B 2619 #undef BIMODAL_ACCESSOR_C 2620 #undef IF_BROKER_DISABLED_ACCESS_HANDLE 2621 #undef IF_BROKER_DISABLED_ACCESS_HANDLE_C