v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
runtime-literals.cc
Go to the documentation of this file.
1// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/ast/ast.h"
14#include "src/runtime/runtime.h"
15
16namespace v8 {
17namespace internal {
18
19namespace {
20
21bool IsUninitializedLiteralSite(Tagged<Object> literal_site) {
22 return literal_site == Smi::zero();
23}
24
25bool HasBoilerplate(DirectHandle<Object> literal_site) {
26 return !IsSmi(*literal_site);
27}
28
29void PreInitializeLiteralSite(DirectHandle<FeedbackVector> vector,
30 FeedbackSlot slot) {
31 vector->SynchronizedSet(slot, Smi::FromInt(1));
32}
33
34template <class ContextObject>
35class JSObjectWalkVisitor {
36 public:
37 explicit JSObjectWalkVisitor(ContextObject* site_context)
38 : site_context_(site_context) {}
39
40 V8_WARN_UNUSED_RESULT MaybeHandle<JSObject> StructureWalk(
41 Handle<JSObject> object);
42
43 protected:
44 V8_WARN_UNUSED_RESULT inline MaybeHandle<JSObject> VisitElementOrProperty(
45 DirectHandle<JSObject> object, Handle<JSObject> value) {
46 // Dont create allocation sites for nested object literals
47 if (!IsJSArray(*value)) {
48 return StructureWalk(value);
49 }
50
51 DirectHandle<AllocationSite> current_site = site_context()->EnterNewScope();
52 MaybeHandle<JSObject> copy_of_value = StructureWalk(value);
53 site_context()->ExitScope(current_site, value);
54 return copy_of_value;
55 }
56
57 inline ContextObject* site_context() { return site_context_; }
58 inline Isolate* isolate() { return site_context()->isolate(); }
59
60 private:
61 ContextObject* site_context_;
62};
63
64template <class ContextObject>
65MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
66 Handle<JSObject> object) {
67 Isolate* isolate = this->isolate();
68 bool copying = ContextObject::kCopying;
69
70 {
71 StackLimitCheck check(isolate);
72
73 if (check.HasOverflowed()) {
74 isolate->StackOverflow();
75 return MaybeHandle<JSObject>();
76 }
77 }
78
79 if (object->map(isolate)->is_deprecated()) {
80 base::MutexGuard mutex_guard(isolate->boilerplate_migration_access());
81 JSObject::MigrateInstance(isolate, object);
82 }
83
85 if (copying) {
86 // JSFunction objects are not allowed to be in normal boilerplates at all.
87 DCHECK(!IsJSFunction(*object, isolate));
88 DirectHandle<AllocationSite> site_to_pass;
89 if (site_context()->ShouldCreateMemento(object)) {
90 site_to_pass = site_context()->current();
91 }
92 copy = isolate->factory()->CopyJSObjectWithAllocationSite(object,
93 site_to_pass);
94 } else {
95 copy = object;
96 }
97
98 DCHECK(copying || copy.is_identical_to(object));
99
100 HandleScope scope(isolate);
101
102 // Deep copy own properties. Arrays only have 1 property "length".
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);
109 DCHECK_EQ(PropertyLocation::kField, details.location());
110 DCHECK_EQ(PropertyKind::kData, details.kind());
111 FieldIndex index = FieldIndex::ForPropertyIndex(
112 copy->map(isolate), details.field_index(),
113 details.representation());
114 Tagged<Object> raw = copy->RawFastPropertyAt(isolate, index);
115 if (IsJSObject(raw, isolate)) {
117 ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
118 VisitElementOrProperty(copy, value));
119 if (copying) copy->FastPropertyAtPut(index, *value);
120 } else if (copying && details.representation().IsDouble()) {
121 uint64_t double_value = Cast<HeapNumber>(raw)->value_as_bits();
122 auto value = isolate->factory()->NewHeapNumberFromBits(double_value);
123 copy->FastPropertyAtPut(index, *value);
124 }
125 }
126 } else {
128 DirectHandle<SwissNameDictionary> dict(
129 copy->property_dictionary_swiss(isolate), isolate);
130 for (InternalIndex i : dict->IterateEntries()) {
131 Tagged<Object> raw = dict->ValueAt(i);
132 if (!IsJSObject(raw, isolate)) continue;
133 DCHECK(IsName(dict->KeyAt(i)));
135 ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
136 VisitElementOrProperty(copy, value));
137 if (copying) dict->ValueAtPut(i, *value);
138 }
139 } else {
140 DirectHandle<NameDictionary> dict(copy->property_dictionary(isolate),
141 isolate);
142 for (InternalIndex i : dict->IterateEntries()) {
143 Tagged<Object> raw = dict->ValueAt(isolate, i);
144 if (!IsJSObject(raw, isolate)) continue;
145 DCHECK(IsName(dict->KeyAt(isolate, i)));
147 ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
148 VisitElementOrProperty(copy, value));
149 if (copying) dict->ValueAtPut(i, *value);
150 }
151 }
152 }
153
154 // Assume non-arrays don't end up having elements.
155 if (copy->elements(isolate)->length() == 0) return copy;
156 }
157
158 // Deep copy own elements.
159 switch (copy->GetElementsKind(isolate)) {
160 case PACKED_ELEMENTS:
167 case HOLEY_ELEMENTS:
169 DirectHandle<FixedArray> elements(
170 Cast<FixedArray>(copy->elements(isolate)), isolate);
171 if (elements->map() == ReadOnlyRoots(isolate).fixed_cow_array_map()) {
172#ifdef DEBUG
173 for (int i = 0; i < elements->length(); i++) {
174 DCHECK(!IsJSObject(elements->get(i)));
175 }
176#endif
177 } else {
178 for (int i = 0; i < elements->length(); i++) {
179 Tagged<Object> raw = elements->get(i);
180 if (!IsJSObject(raw, isolate)) continue;
182 ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
183 VisitElementOrProperty(copy, value));
184 if (copying) elements->set(i, *value);
185 }
186 }
187 break;
188 }
189 case DICTIONARY_ELEMENTS: {
190 DirectHandle<NumberDictionary> element_dictionary(
191 copy->element_dictionary(isolate), isolate);
192 for (InternalIndex i : element_dictionary->IterateEntries()) {
193 Tagged<Object> raw = element_dictionary->ValueAt(isolate, i);
194 if (!IsJSObject(raw, isolate)) continue;
196 ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
197 VisitElementOrProperty(copy, value));
198 if (copying) element_dictionary->ValueAtPut(i, *value);
199 }
200 break;
201 }
205 break;
209 UNREACHABLE();
210
211#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) case TYPE##_ELEMENTS:
212
215#undef TYPED_ARRAY_CASE
216 // Typed elements cannot be created using an object literal.
217 UNREACHABLE();
218
223 case NO_ELEMENTS:
224 // No contained objects, nothing to do.
225 break;
226 }
227
228 return copy;
229}
230
231class DeprecationUpdateContext {
232 public:
233 explicit DeprecationUpdateContext(Isolate* isolate) { isolate_ = isolate; }
234 Isolate* isolate() { return 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>();
240 }
241 DirectHandle<AllocationSite> current() { UNREACHABLE(); }
242
243 static const bool kCopying = false;
244
245 private:
246 Isolate* isolate_;
247};
248
249// AllocationSiteCreationContext aids in the creation of AllocationSites to
250// accompany object literals.
251class AllocationSiteCreationContext : public AllocationSiteContext {
252 public:
253 explicit AllocationSiteCreationContext(Isolate* isolate)
254 : AllocationSiteContext(isolate) {}
255
256 Handle<AllocationSite> EnterNewScope() {
257 Handle<AllocationSite> scope_site;
258 if (top().is_null()) {
259 // We are creating the top level AllocationSite as opposed to a nested
260 // AllocationSite.
261 InitializeTraversal(isolate()->factory()->NewAllocationSite(true));
262 scope_site = Handle<AllocationSite>(*top(), isolate());
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()));
266 }
267 } else {
268 DCHECK(!current().is_null());
269 scope_site = isolate()->factory()->NewAllocationSite(false);
270 if (v8_flags.trace_creation_allocation_sites) {
271 PrintF(
272 "*** Creating nested %s AllocationSite (top, current, new) (%p, "
273 "%p, "
274 "%p)\n",
275 "Slim", reinterpret_cast<void*>(top()->ptr()),
276 reinterpret_cast<void*>(current()->ptr()),
277 reinterpret_cast<void*>(scope_site->ptr()));
278 }
279 current()->set_nested_site(*scope_site);
280 update_current_site(*scope_site);
281 }
282 DCHECK(!scope_site.is_null());
283 return scope_site;
284 }
285 void ExitScope(DirectHandle<AllocationSite> scope_site,
286 DirectHandle<JSObject> object) {
287 if (object.is_null()) return;
288 scope_site->set_boilerplate(*object, kReleaseStore);
289 if (v8_flags.trace_creation_allocation_sites) {
290 bool top_level =
291 !scope_site.is_null() && top().is_identical_to(scope_site);
292 if (top_level) {
293 PrintF("*** Setting AllocationSite %p transition_info %p\n",
294 reinterpret_cast<void*>(scope_site->ptr()),
295 reinterpret_cast<void*>(object->ptr()));
296 } else {
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()));
301 }
302 }
303 }
304 static const bool kCopying = false;
305};
306
307MaybeDirectHandle<JSObject> DeepWalk(Handle<JSObject> object,
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));
313 return result;
314}
315
316MaybeDirectHandle<JSObject> DeepWalk(
317 Handle<JSObject> object, AllocationSiteCreationContext* site_context) {
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));
322 return result;
323}
324
325MaybeDirectHandle<JSObject> DeepCopy(Handle<JSObject> 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));
331 return copy;
332}
333
334Handle<JSObject> CreateObjectLiteral(
335 Isolate* isolate,
336 DirectHandle<ObjectBoilerplateDescription> object_boilerplate_description,
337 int flags, AllocationType allocation);
338
339Handle<JSObject> CreateArrayLiteral(
340 Isolate* isolate,
341 DirectHandle<ArrayBoilerplateDescription> array_boilerplate_description,
342 AllocationType allocation);
343
344struct ObjectLiteralHelper {
345 static inline Handle<JSObject> Create(Isolate* isolate,
346 Handle<HeapObject> description,
347 int flags, AllocationType allocation) {
348 auto object_boilerplate_description =
350 return CreateObjectLiteral(isolate, object_boilerplate_description, flags,
351 allocation);
352 }
353};
354
355struct ArrayLiteralHelper {
356 static inline Handle<JSObject> Create(Isolate* isolate,
357 Handle<HeapObject> description,
358 int flags_not_used,
359 AllocationType allocation) {
360 auto array_boilerplate_description =
362 return CreateArrayLiteral(isolate, array_boilerplate_description,
363 allocation);
364 }
365};
366
367Handle<JSObject> CreateObjectLiteral(
368 Isolate* isolate,
369 DirectHandle<ObjectBoilerplateDescription> object_boilerplate_description,
370 int flags, AllocationType allocation) {
371 DirectHandle<NativeContext> native_context = isolate->native_context();
372 bool use_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
373 bool has_null_prototype = (flags & ObjectLiteral::kHasNullPrototype) != 0;
374
375 // In case we have function literals, we want the object to be in
376 // slow properties mode for now. We don't go in the map cache because
377 // maps with constant functions can't be shared if the functions are
378 // not the same (which is the common case).
379 int number_of_properties =
380 object_boilerplate_description->backing_store_size();
381
382 // Ignoring number_of_properties for force dictionary map with
383 // __proto__:null.
384 DirectHandle<Map> map =
385 has_null_prototype
386 ? direct_handle(native_context->slow_object_with_null_prototype_map(),
387 isolate)
388 : isolate->factory()->ObjectLiteralMapFromCache(native_context,
389 number_of_properties);
390
391 Handle<JSObject> boilerplate =
392 isolate->factory()->NewFastOrSlowJSObjectFromMap(
393 map, number_of_properties, allocation);
394
395 // Normalize the elements of the boilerplate to save space if needed.
396 if (!use_fast_elements) JSObject::NormalizeElements(boilerplate);
397
398 // Add the constant properties to the boilerplate.
399 int length = object_boilerplate_description->boilerplate_properties_count();
400 // TODO(verwaest): Support tracking representations in the boilerplate.
401 for (int index = 0; index < length; index++) {
402 DirectHandle<Object> key(object_boilerplate_description->name(index),
403 isolate);
404 Handle<Object> value(object_boilerplate_description->value(index), isolate);
405
406 if (IsHeapObject(*value)) {
407 if (IsArrayBoilerplateDescription(Cast<HeapObject>(*value), isolate)) {
408 auto array_boilerplate = Cast<ArrayBoilerplateDescription>(value);
409 value = CreateArrayLiteral(isolate, array_boilerplate, allocation);
410
411 } else if (IsObjectBoilerplateDescription(Cast<HeapObject>(*value),
412 isolate)) {
413 auto object_boilerplate = Cast<ObjectBoilerplateDescription>(value);
414 value = CreateObjectLiteral(isolate, object_boilerplate,
415 object_boilerplate->flags(), allocation);
416 }
417 }
418
419 uint32_t element_index = 0;
420 if (Object::ToArrayIndex(*key, &element_index)) {
421 // Array index (uint32).
422 if (IsUninitialized(*value, isolate)) {
423 value = handle(Smi::zero(), isolate);
424 }
425 JSObject::SetOwnElementIgnoreAttributes(boilerplate, element_index, value,
426 NONE)
427 .Check();
428 } else {
429 DirectHandle<String> name = Cast<String>(key);
430 DCHECK(!name->AsArrayIndex(&element_index));
431 JSObject::SetOwnPropertyIgnoreAttributes(boilerplate, name, value, NONE)
432 .Check();
433 }
434 }
435
436 if (map->is_dictionary_map() && !has_null_prototype) {
437 // TODO(cbruni): avoid making the boilerplate fast again, the clone stub
438 // supports dict-mode objects directly.
439 JSObject::MigrateSlowToFast(
440 boilerplate, boilerplate->map()->UnusedPropertyFields(), "FastLiteral");
441 }
442 return boilerplate;
443}
444
445Handle<JSObject> CreateArrayLiteral(
446 Isolate* isolate,
447 DirectHandle<ArrayBoilerplateDescription> array_boilerplate_description,
448 AllocationType allocation) {
449 ElementsKind constant_elements_kind =
450 array_boilerplate_description->elements_kind();
451
452 Handle<FixedArrayBase> constant_elements_values(
453 array_boilerplate_description->constant_elements(isolate), isolate);
454
455 // Create the JSArray.
456 Handle<FixedArrayBase> copied_elements_values;
457 if (IsDoubleElementsKind(constant_elements_kind)) {
458 copied_elements_values = isolate->factory()->CopyFixedDoubleArray(
459 Cast<FixedDoubleArray>(constant_elements_values));
460 } else {
461 DCHECK(IsSmiOrObjectElementsKind(constant_elements_kind));
462 const bool is_cow = (constant_elements_values->map() ==
463 ReadOnlyRoots(isolate).fixed_cow_array_map());
464 if (is_cow) {
465 copied_elements_values = constant_elements_values;
466 if (DEBUG_BOOL) {
467 auto fixed_array_values = Cast<FixedArray>(copied_elements_values);
468 for (int i = 0; i < fixed_array_values->length(); i++) {
469 DCHECK(!IsFixedArray(fixed_array_values->get(i)));
470 }
471 }
472 } else {
473 Handle<FixedArray> fixed_array_values =
474 Cast<FixedArray>(constant_elements_values);
475 Handle<FixedArray> fixed_array_values_copy =
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++) {
479 Tagged<Object> value = fixed_array_values_copy->get(i);
480 Tagged<HeapObject> value_heap_object;
481 if (value.GetHeapObject(isolate, &value_heap_object)) {
482 if (IsArrayBoilerplateDescription(value_heap_object, isolate)) {
483 HandleScope sub_scope(isolate);
484 DirectHandle<ArrayBoilerplateDescription> boilerplate(
485 Cast<ArrayBoilerplateDescription>(value_heap_object), isolate);
486 DirectHandle<JSObject> result =
487 CreateArrayLiteral(isolate, boilerplate, allocation);
488 fixed_array_values_copy->set(i, *result);
489
490 } else if (IsObjectBoilerplateDescription(value_heap_object,
491 isolate)) {
492 HandleScope sub_scope(isolate);
493 DirectHandle<ObjectBoilerplateDescription> boilerplate(
494 Cast<ObjectBoilerplateDescription>(value_heap_object), isolate);
495 DirectHandle<JSObject> result = CreateObjectLiteral(
496 isolate, boilerplate, boilerplate->flags(), allocation);
497 fixed_array_values_copy->set(i, *result);
498 }
499 }
500 }
501 }
502 }
503 return isolate->factory()->NewJSArrayWithElements(
504 copied_elements_values, constant_elements_kind,
505 copied_elements_values->length(), allocation);
506}
507
508template <typename LiteralHelper>
509MaybeDirectHandle<JSObject> CreateLiteralWithoutAllocationSite(
510 Isolate* isolate, Handle<HeapObject> description, int flags) {
511 Handle<JSObject> literal = LiteralHelper::Create(isolate, description, flags,
513 DeprecationUpdateContext update_context(isolate);
514 RETURN_ON_EXCEPTION(isolate, DeepWalk(literal, &update_context));
515 return literal;
516}
517
518template <typename LiteralHelper>
519MaybeDirectHandle<JSObject> CreateLiteral(Isolate* isolate,
520 Handle<HeapObject> maybe_vector,
521 int literals_index,
522 Handle<HeapObject> description,
523 int flags) {
524 if (!IsFeedbackVector(*maybe_vector)) {
525 DCHECK(IsUndefined(*maybe_vector));
526 return CreateLiteralWithoutAllocationSite<LiteralHelper>(
527 isolate, description, flags);
528 }
529 auto vector = Cast<FeedbackVector>(maybe_vector);
530 FeedbackSlot literals_slot(FeedbackVector::ToSlot(literals_index));
531 CHECK(literals_slot.ToInt() < vector->length());
532 Handle<Object> literal_site(Cast<Object>(vector->Get(literals_slot)),
533 isolate);
535 Handle<JSObject> boilerplate;
536
537 if (HasBoilerplate(literal_site)) {
538 site = Cast<AllocationSite>(literal_site);
539 boilerplate = Handle<JSObject>(site->boilerplate(), isolate);
540 } else {
541 // Eagerly create AllocationSites for literals that contain an Array.
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);
549 } else {
550 boilerplate = LiteralHelper::Create(isolate, description, flags,
552 }
553 // Install AllocationSite objects.
554 AllocationSiteCreationContext creation_context(isolate);
555 site = creation_context.EnterNewScope();
556 RETURN_ON_EXCEPTION(isolate, DeepWalk(boilerplate, &creation_context));
557 creation_context.ExitScope(site, boilerplate);
558
559 vector->SynchronizedSet(literals_slot, *site);
560 }
561
562 static_assert(static_cast<int>(ObjectLiteral::kDisableMementos) ==
563 static_cast<int>(ArrayLiteral::kDisableMementos));
564 bool enable_mementos = (flags & ObjectLiteral::kDisableMementos) == 0;
565
566 // Copy the existing boilerplate.
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);
571 return copy;
572}
573
574} // namespace
575
576RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) {
577 HandleScope scope(isolate);
578 DCHECK_EQ(4, args.length());
579 Handle<HeapObject> maybe_vector = args.at<HeapObject>(0);
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));
587}
588
589RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) {
590 HandleScope scope(isolate);
591 DCHECK_EQ(4, args.length());
592 Handle<HeapObject> maybe_vector = args.at<HeapObject>(0);
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));
600}
601
602RUNTIME_FUNCTION(Runtime_CreateRegExpLiteral) {
603 HandleScope scope(isolate);
604 DCHECK_EQ(4, args.length());
605 Handle<HeapObject> maybe_vector = args.at<HeapObject>(0);
606 int index = args.tagged_index_value_at(1);
608 int flags = args.smi_value_at(3);
609
610 if (IsUndefined(*maybe_vector)) {
611 // We don't have a vector; don't create a boilerplate, simply construct a
612 // plain JSRegExp instance and return it.
614 isolate, JSRegExp::New(isolate, pattern, JSRegExp::Flags(flags)));
615 }
616
617 auto vector = Cast<FeedbackVector>(maybe_vector);
618 FeedbackSlot literal_slot(FeedbackVector::ToSlot(index));
619 DirectHandle<Object> literal_site(Cast<Object>(vector->Get(literal_slot)),
620 isolate);
621
622 // This function must not be called when a boilerplate already exists (if it
623 // exists, callers should instead copy the boilerplate into a new JSRegExp
624 // instance).
625 CHECK(!HasBoilerplate(literal_site));
626
627 DirectHandle<JSRegExp> regexp_instance;
629 isolate, regexp_instance,
630 JSRegExp::New(isolate, pattern, JSRegExp::Flags(flags)));
631
632 // JSRegExp literal sites are initialized in a two-step process:
633 // Uninitialized-Preinitialized, and Preinitialized-Initialized.
634 if (IsUninitializedLiteralSite(*literal_site)) {
635 PreInitializeLiteralSite(vector, literal_slot);
636 return *regexp_instance;
637 }
638
639 DirectHandle<RegExpData> data(regexp_instance->data(isolate), isolate);
640 DirectHandle<String> source(Cast<String>(regexp_instance->source()), isolate);
642 isolate->factory()->NewRegExpBoilerplateDescription(
643 data, source,
644 Smi::FromInt(static_cast<int>(regexp_instance->flags())));
645
646 vector->SynchronizedSet(literal_slot, *boilerplate);
647 DCHECK(HasBoilerplate(
648 direct_handle(Cast<Object>(vector->Get(literal_slot)), isolate)));
649
650 return *regexp_instance;
651}
652
653} // namespace internal
654} // namespace v8
Isolate * isolate_
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype)
ThreadLocalTop * top
union v8::internal::@341::BuiltinMetadata::KindSpecificData data
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)
Definition js-regexp.cc:152
static V8_WARN_UNUSED_RESULT bool ToArrayIndex(Tagged< Object > obj, uint32_t *index)
static constexpr Tagged< Smi > FromInt(int value)
Definition smi.h:38
static constexpr Tagged< Smi > zero()
Definition smi.h:99
#define V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL
Definition globals.h:242
#define DEBUG_BOOL
Definition globals.h:87
LineAndColumn current
#define RAB_GSAB_TYPED_ARRAYS(V)
#define TYPED_ARRAYS(V)
#define RUNTIME_FUNCTION(Name)
Definition arguments.h:162
#define RETURN_ON_EXCEPTION(isolate, call)
Definition isolate.h:395
#define ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, dst, call)
Definition isolate.h:284
#define ASSIGN_RETURN_ON_EXCEPTION(isolate, dst, call)
Definition isolate.h:291
#define RETURN_RESULT_OR_FAILURE(isolate, call)
Definition isolate.h:264
base::Vector< const DirectHandle< Object > > args
Definition execution.cc:74
Isolate * isolate
std::string pattern
ZoneVector< RpoNumber > & result
FunctionLiteral * literal
Definition liveedit.cc:294
InstructionOperand source
LockGuard< Mutex > MutexGuard
Definition mutex.h:219
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
Definition handles-inl.h:72
void PrintF(const char *format,...)
Definition utils.cc:39
V8_INLINE constexpr bool IsSmi(TaggedImpl< kRefType, StorageType > obj)
Definition objects.h:665
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)
Definition objects.h:669
V8_EXPORT_PRIVATE FlagValues v8_flags
return value
Definition map-inl.h:893
constexpr bool IsDoubleElementsKind(ElementsKind kind)
!IsContextMap !IsContextMap native_context
Definition map-inl.h:877
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
static constexpr ReleaseStoreTag kReleaseStore
Definition globals.h:2910
Local< T > Handle
ContextObject * site_context_
static const bool kCopying
#define CHECK(condition)
Definition logging.h:124
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define V8_WARN_UNUSED_RESULT
Definition v8config.h:671