25bool HasBoilerplate(DirectHandle<Object> literal_site) {
26 return !
IsSmi(*literal_site);
29void PreInitializeLiteralSite(DirectHandle<FeedbackVector> vector,
34template <
class ContextObject>
35class JSObjectWalkVisitor {
37 explicit JSObjectWalkVisitor(ContextObject* site_context)
47 if (!IsJSArray(*value)) {
48 return StructureWalk(value);
51 DirectHandle<AllocationSite> current_site = site_context()->EnterNewScope();
52 MaybeHandle<JSObject> copy_of_value = StructureWalk(value);
53 site_context()->ExitScope(current_site, value);
57 inline ContextObject* site_context() {
return site_context_; }
58 inline Isolate*
isolate() {
return site_context()->isolate(); }
64template <
class ContextObject>
65MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
67 Isolate* isolate = this->
isolate();
68 bool copying = ContextObject::kCopying;
71 StackLimitCheck check(isolate);
73 if (check.HasOverflowed()) {
74 isolate->StackOverflow();
75 return MaybeHandle<JSObject>();
79 if (object->map(isolate)->is_deprecated()) {
87 DCHECK(!IsJSFunction(*
object, isolate));
88 DirectHandle<AllocationSite> site_to_pass;
89 if (site_context()->ShouldCreateMemento(
object)) {
90 site_to_pass = site_context()->current();
92 copy = isolate->factory()->CopyJSObjectWithAllocationSite(
object,
98 DCHECK(copying || copy.is_identical_to(
object));
100 HandleScope scope(isolate);
103 if (!IsJSArray(*copy, isolate)) {
104 if (copy->HasFastProperties(isolate)) {
105 DirectHandle<DescriptorArray> descriptors(
106 copy->map(isolate)->instance_descriptors(isolate), isolate);
107 for (InternalIndex
i : copy->
map(isolate)->IterateOwnDescriptors()) {
108 PropertyDetails details = descriptors->GetDetails(
i);
112 copy->map(isolate), details.field_index(),
113 details.representation());
115 if (IsJSObject(raw, isolate)) {
118 VisitElementOrProperty(copy, value));
119 if (copying) copy->FastPropertyAtPut(index, *value);
120 }
else if (copying && details.representation().IsDouble()) {
122 auto value = isolate->factory()->NewHeapNumberFromBits(double_value);
123 copy->FastPropertyAtPut(index, *value);
128 DirectHandle<SwissNameDictionary> dict(
129 copy->property_dictionary_swiss(isolate), isolate);
130 for (InternalIndex
i : dict->IterateEntries()) {
132 if (!IsJSObject(raw, isolate))
continue;
133 DCHECK(IsName(dict->KeyAt(
i)));
136 VisitElementOrProperty(copy, value));
137 if (copying) dict->ValueAtPut(
i, *value);
140 DirectHandle<NameDictionary> dict(copy->property_dictionary(isolate),
142 for (InternalIndex
i : dict->IterateEntries()) {
144 if (!IsJSObject(raw, isolate))
continue;
145 DCHECK(IsName(dict->KeyAt(isolate,
i)));
148 VisitElementOrProperty(copy, value));
149 if (copying) dict->ValueAtPut(
i, *value);
155 if (copy->elements(isolate)->length() == 0)
return copy;
159 switch (copy->GetElementsKind(isolate)) {
169 DirectHandle<FixedArray> elements(
171 if (elements->map() == ReadOnlyRoots(isolate).fixed_cow_array_map()) {
173 for (
int i = 0;
i < elements->
length();
i++) {
174 DCHECK(!IsJSObject(elements->get(
i)));
178 for (
int i = 0;
i < elements->
length();
i++) {
180 if (!IsJSObject(raw, isolate))
continue;
183 VisitElementOrProperty(copy, value));
184 if (copying) elements->set(
i, *value);
191 copy->element_dictionary(isolate), isolate);
194 if (!IsJSObject(raw, isolate))
continue;
197 VisitElementOrProperty(copy, value));
211#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) case TYPE##_ELEMENTS:
215#undef TYPED_ARRAY_CASE
231class DeprecationUpdateContext {
233 explicit DeprecationUpdateContext(Isolate* isolate) {
isolate_ =
isolate; }
235 bool ShouldCreateMemento(DirectHandle<JSObject>
object) {
return false; }
236 inline void ExitScope(DirectHandle<AllocationSite> scope_site,
237 DirectHandle<JSObject>
object) {}
238 DirectHandle<AllocationSite> EnterNewScope() {
239 return DirectHandle<AllocationSite>();
251class AllocationSiteCreationContext :
public AllocationSiteContext {
253 explicit AllocationSiteCreationContext(Isolate* isolate)
254 : AllocationSiteContext(isolate) {}
258 if (
top().is_null()) {
261 InitializeTraversal(
isolate()->factory()->NewAllocationSite(
true));
263 if (
v8_flags.trace_creation_allocation_sites) {
264 PrintF(
"*** Creating top level %s AllocationSite %p\n",
"Fat",
265 reinterpret_cast<void*
>(scope_site->ptr()));
269 scope_site =
isolate()->factory()->NewAllocationSite(
false);
270 if (
v8_flags.trace_creation_allocation_sites) {
272 "*** Creating nested %s AllocationSite (top, current, new) (%p, "
275 "Slim",
reinterpret_cast<void*
>(
top()->ptr()),
276 reinterpret_cast<void*
>(
current()->ptr()),
277 reinterpret_cast<void*
>(scope_site->ptr()));
279 current()->set_nested_site(*scope_site);
280 update_current_site(*scope_site);
282 DCHECK(!scope_site.is_null());
285 void ExitScope(DirectHandle<AllocationSite> scope_site,
286 DirectHandle<JSObject>
object) {
287 if (
object.is_null())
return;
289 if (
v8_flags.trace_creation_allocation_sites) {
291 !scope_site.is_null() &&
top().is_identical_to(scope_site);
293 PrintF(
"*** Setting AllocationSite %p transition_info %p\n",
294 reinterpret_cast<void*
>(scope_site->ptr()),
295 reinterpret_cast<void*
>(object->ptr()));
297 PrintF(
"*** Setting AllocationSite (%p, %p) transition_info %p\n",
298 reinterpret_cast<void*
>(
top()->ptr()),
299 reinterpret_cast<void*
>(scope_site->ptr()),
300 reinterpret_cast<void*
>(object->ptr()));
308 DeprecationUpdateContext* site_context) {
309 JSObjectWalkVisitor<DeprecationUpdateContext> v(site_context);
310 MaybeDirectHandle<JSObject>
result = v.StructureWalk(
object);
311 DirectHandle<JSObject> for_assert;
312 DCHECK(!
result.ToHandle(&for_assert) || for_assert.is_identical_to(
object));
316MaybeDirectHandle<JSObject> DeepWalk(
318 JSObjectWalkVisitor<AllocationSiteCreationContext> v(site_context);
319 MaybeDirectHandle<JSObject>
result = v.StructureWalk(
object);
320 DirectHandle<JSObject> for_assert;
321 DCHECK(!
result.ToHandle(&for_assert) || for_assert.is_identical_to(
object));
326 AllocationSiteUsageContext* site_context) {
327 JSObjectWalkVisitor<AllocationSiteUsageContext> v(site_context);
328 MaybeDirectHandle<JSObject> copy = v.StructureWalk(
object);
329 DirectHandle<JSObject> for_assert;
330 DCHECK(!copy.ToHandle(&for_assert) || !for_assert.is_identical_to(
object));
336 DirectHandle<ObjectBoilerplateDescription> object_boilerplate_description,
341 DirectHandle<ArrayBoilerplateDescription> array_boilerplate_description,
344struct ObjectLiteralHelper {
346 Handle<HeapObject> description,
348 auto object_boilerplate_description =
350 return CreateObjectLiteral(isolate, object_boilerplate_description, flags,
355struct ArrayLiteralHelper {
357 Handle<HeapObject> description,
360 auto array_boilerplate_description =
362 return CreateArrayLiteral(isolate, array_boilerplate_description,
369 DirectHandle<ObjectBoilerplateDescription> object_boilerplate_description,
371 DirectHandle<NativeContext>
native_context = isolate->native_context();
379 int number_of_properties =
380 object_boilerplate_description->backing_store_size();
384 DirectHandle<Map> map =
389 number_of_properties);
392 isolate->factory()->NewFastOrSlowJSObjectFromMap(
393 map, number_of_properties, allocation);
399 int length = object_boilerplate_description->boilerplate_properties_count();
401 for (
int index = 0; index <
length; index++) {
402 DirectHandle<Object>
key(object_boilerplate_description->name(index),
404 Handle<Object>
value(object_boilerplate_description->value(index), isolate);
409 value = CreateArrayLiteral(isolate, array_boilerplate, allocation);
414 value = CreateObjectLiteral(isolate, object_boilerplate,
415 object_boilerplate->flags(), allocation);
419 uint32_t element_index = 0;
422 if (IsUninitialized(*value, isolate)) {
430 DCHECK(!name->AsArrayIndex(&element_index));
436 if (map->is_dictionary_map() && !has_null_prototype) {
439 JSObject::MigrateSlowToFast(
440 boilerplate, boilerplate->map()->UnusedPropertyFields(),
"FastLiteral");
447 DirectHandle<ArrayBoilerplateDescription> array_boilerplate_description,
450 array_boilerplate_description->elements_kind();
453 array_boilerplate_description->constant_elements(isolate), isolate);
458 copied_elements_values = isolate->factory()->CopyFixedDoubleArray(
462 const bool is_cow = (constant_elements_values->map() ==
463 ReadOnlyRoots(isolate).fixed_cow_array_map());
465 copied_elements_values = constant_elements_values;
468 for (
int i = 0;
i < fixed_array_values->
length();
i++) {
469 DCHECK(!IsFixedArray(fixed_array_values->get(
i)));
476 isolate->factory()->CopyFixedArray(fixed_array_values);
477 copied_elements_values = fixed_array_values_copy;
478 for (
int i = 0;
i < fixed_array_values->
length();
i++) {
481 if (value.GetHeapObject(isolate, &value_heap_object)) {
482 if (IsArrayBoilerplateDescription(value_heap_object, isolate)) {
483 HandleScope sub_scope(isolate);
484 DirectHandle<ArrayBoilerplateDescription> boilerplate(
486 DirectHandle<JSObject>
result =
487 CreateArrayLiteral(isolate, boilerplate, allocation);
488 fixed_array_values_copy->set(
i, *
result);
490 }
else if (IsObjectBoilerplateDescription(value_heap_object,
492 HandleScope sub_scope(isolate);
493 DirectHandle<ObjectBoilerplateDescription> boilerplate(
495 DirectHandle<JSObject>
result = CreateObjectLiteral(
496 isolate, boilerplate, boilerplate->flags(), allocation);
497 fixed_array_values_copy->set(
i, *
result);
503 return isolate->factory()->NewJSArrayWithElements(
504 copied_elements_values, constant_elements_kind,
505 copied_elements_values->length(), allocation);
508template <
typename LiteralHelper>
509MaybeDirectHandle<JSObject> CreateLiteralWithoutAllocationSite(
510 Isolate* isolate, Handle<HeapObject> description,
int flags) {
513 DeprecationUpdateContext update_context(isolate);
518template <
typename LiteralHelper>
519MaybeDirectHandle<JSObject> CreateLiteral(Isolate* isolate,
520 Handle<HeapObject> maybe_vector,
522 Handle<HeapObject> description,
524 if (!IsFeedbackVector(*maybe_vector)) {
525 DCHECK(IsUndefined(*maybe_vector));
526 return CreateLiteralWithoutAllocationSite<LiteralHelper>(
527 isolate, description, flags);
531 CHECK(literals_slot.ToInt() < vector->length());
532 Handle<Object> literal_site(
Cast<Object>(vector->Get(literals_slot)),
537 if (HasBoilerplate(literal_site)) {
542 bool needs_initial_allocation_site =
544 if (!needs_initial_allocation_site &&
545 IsUninitializedLiteralSite(*literal_site)) {
546 PreInitializeLiteralSite(vector, literals_slot);
547 return CreateLiteralWithoutAllocationSite<LiteralHelper>(
548 isolate, description, flags);
550 boilerplate = LiteralHelper::Create(isolate, description, flags,
554 AllocationSiteCreationContext creation_context(isolate);
555 site = creation_context.EnterNewScope();
557 creation_context.ExitScope(site, boilerplate);
559 vector->SynchronizedSet(literals_slot, *site);
567 AllocationSiteUsageContext usage_context(isolate, site, enable_mementos);
568 usage_context.EnterNewScope();
569 MaybeDirectHandle<JSObject> copy = DeepCopy(boilerplate, &usage_context);
570 usage_context.ExitScope(site, boilerplate);
580 int literals_index =
args.tagged_index_value_at(1);
583 int flags =
args.smi_value_at(3);
585 isolate, CreateLiteral<ObjectLiteralHelper>(
586 isolate, maybe_vector, literals_index, description, flags));
593 int literals_index =
args.tagged_index_value_at(1);
596 int flags =
args.smi_value_at(3);
598 isolate, CreateLiteral<ArrayLiteralHelper>(
599 isolate, maybe_vector, literals_index, elements, flags));
606 int index =
args.tagged_index_value_at(1);
608 int flags =
args.smi_value_at(3);
610 if (IsUndefined(*maybe_vector)) {
625 CHECK(!HasBoilerplate(literal_site));
629 isolate, regexp_instance,
634 if (IsUninitializedLiteralSite(*literal_site)) {
635 PreInitializeLiteralSite(vector, literal_slot);
636 return *regexp_instance;
642 isolate->factory()->NewRegExpBoilerplateDescription(
644 Smi::FromInt(
static_cast<int>(regexp_instance->flags())));
646 vector->SynchronizedSet(literal_slot, *boilerplate);
650 return *regexp_instance;
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype)
union v8::internal::@341::BuiltinMetadata::KindSpecificData data
@ kNeedsInitialAllocationSite
static FeedbackSlot ToSlot(intptr_t index)
static FieldIndex ForPropertyIndex(Tagged< Map > map, int index, Representation representation=Representation::Tagged())
static V8_EXPORT_PRIVATE DirectHandle< NumberDictionary > NormalizeElements(DirectHandle< JSObject > object)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > V8_EXPORT_PRIVATE SetOwnPropertyIgnoreAttributes(DirectHandle< JSObject > object, DirectHandle< Name > name, DirectHandle< Object > value, PropertyAttributes attributes)
static void MigrateInstance(Isolate *isolate, DirectHandle< JSObject > instance)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > SetOwnElementIgnoreAttributes(DirectHandle< JSObject > object, size_t index, DirectHandle< Object > value, PropertyAttributes attributes)
static V8_EXPORT_PRIVATE MaybeDirectHandle< JSRegExp > New(Isolate *isolate, DirectHandle< String > source, Flags flags, uint32_t backtrack_limit=kNoBacktrackLimit)
static V8_WARN_UNUSED_RESULT bool ToArrayIndex(Tagged< Object > obj, uint32_t *index)
static constexpr Tagged< Smi > FromInt(int value)
static constexpr Tagged< Smi > zero()
#define V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL
#define RAB_GSAB_TYPED_ARRAYS(V)
#define RUNTIME_FUNCTION(Name)
#define RETURN_ON_EXCEPTION(isolate, call)
#define ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, dst, call)
#define ASSIGN_RETURN_ON_EXCEPTION(isolate, dst, call)
#define RETURN_RESULT_OR_FAILURE(isolate, call)
base::Vector< const DirectHandle< Object > > args
ZoneVector< RpoNumber > & result
FunctionLiteral * literal
InstructionOperand source
LockGuard< Mutex > MutexGuard
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
void PrintF(const char *format,...)
V8_INLINE constexpr bool IsSmi(TaggedImpl< kRefType, StorageType > obj)
kInterpreterTrampolineOffset Tagged< HeapObject >
@ HOLEY_NONEXTENSIBLE_ELEMENTS
@ SLOW_STRING_WRAPPER_ELEMENTS
@ PACKED_NONEXTENSIBLE_ELEMENTS
@ SLOW_SLOPPY_ARGUMENTS_ELEMENTS
@ FAST_SLOPPY_ARGUMENTS_ELEMENTS
@ FAST_STRING_WRAPPER_ELEMENTS
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
bool IsSmiOrObjectElementsKind(ElementsKind kind)
DONT_OVERRIDE DISABLE_ALLOCATION_SITES HOLEY_ELEMENTS
DONT_OVERRIDE DISABLE_ALLOCATION_SITES DISABLE_ALLOCATION_SITES HOLEY_DOUBLE_ELEMENTS
V8_INLINE constexpr bool IsHeapObject(TaggedImpl< kRefType, StorageType > obj)
V8_EXPORT_PRIVATE FlagValues v8_flags
constexpr bool IsDoubleElementsKind(ElementsKind kind)
!IsContextMap !IsContextMap native_context
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
static constexpr ReleaseStoreTag kReleaseStore
ContextObject * site_context_
static const bool kCopying
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define V8_WARN_UNUSED_RESULT