LCOV - code coverage report
Current view: top level - src/runtime - runtime-literals.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 154 159 96.9 %
Date: 2017-10-20 Functions: 18 21 85.7 %

          Line data    Source code
       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/runtime/runtime-utils.h"
       6             : 
       7             : #include "src/allocation-site-scopes.h"
       8             : #include "src/arguments.h"
       9             : #include "src/ast/ast.h"
      10             : #include "src/ast/compile-time-value.h"
      11             : #include "src/isolate-inl.h"
      12             : #include "src/runtime/runtime.h"
      13             : 
      14             : namespace v8 {
      15             : namespace internal {
      16             : 
      17             : namespace {
      18             : 
      19       97576 : bool IsUninitializedLiteralSite(Object* literal_site) {
      20       97576 :   return literal_site == Smi::kZero;
      21             : }
      22             : 
      23       99831 : bool HasBoilerplate(Isolate* isolate, Handle<Object> literal_site) {
      24       99831 :   return !literal_site->IsSmi();
      25             : }
      26             : 
      27       81822 : void PreInitializeLiteralSite(Handle<FeedbackVector> vector,
      28             :                               FeedbackSlot slot) {
      29             :   vector->Set(slot, Smi::FromInt(1));
      30       81822 : }
      31             : 
      32             : Handle<Object> InnerCreateBoilerplate(Isolate* isolate,
      33             :                                       Handle<FixedArray> compile_time_value,
      34             :                                       PretenureFlag pretenure_flag);
      35             : 
      36             : enum DeepCopyHints { kNoHints = 0, kObjectIsShallow = 1 };
      37             : 
      38             : template <class ContextObject>
      39             : class JSObjectWalkVisitor {
      40             :  public:
      41             :   JSObjectWalkVisitor(ContextObject* site_context, DeepCopyHints hints)
      42     1210169 :       : site_context_(site_context), hints_(hints) {}
      43             : 
      44             :   MUST_USE_RESULT MaybeHandle<JSObject> StructureWalk(Handle<JSObject> object);
      45             : 
      46             :  protected:
      47     1331571 :   MUST_USE_RESULT inline MaybeHandle<JSObject> VisitElementOrProperty(
      48     1317946 :       Handle<JSObject> object, Handle<JSObject> value) {
      49     1317946 :     Handle<AllocationSite> current_site = site_context()->EnterNewScope();
      50     1331571 :     MaybeHandle<JSObject> copy_of_value = StructureWalk(value);
      51             :     site_context()->ExitScope(current_site, value);
      52     1331571 :     return copy_of_value;
      53             :   }
      54             : 
      55             :   inline ContextObject* site_context() { return site_context_; }
      56     2541740 :   inline Isolate* isolate() { return site_context()->isolate(); }
      57             : 
      58             :  private:
      59             :   ContextObject* site_context_;
      60             :   const DeepCopyHints hints_;
      61             : };
      62             : 
      63             : template <class ContextObject>
      64     2541740 : MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
      65     4388486 :     Handle<JSObject> object) {
      66             :   Isolate* isolate = this->isolate();
      67             :   bool copying = ContextObject::kCopying;
      68     2541740 :   bool shallow = hints_ == kObjectIsShallow;
      69             : 
      70     2541740 :   if (!shallow) {
      71             :     StackLimitCheck check(isolate);
      72             : 
      73     2362097 :     if (check.HasOverflowed()) {
      74          34 :       isolate->StackOverflow();
      75          34 :       return MaybeHandle<JSObject>();
      76             :     }
      77             :   }
      78             : 
      79     2541706 :   if (object->map()->is_deprecated()) {
      80         750 :     JSObject::MigrateInstance(object);
      81             :   }
      82             : 
      83             :   Handle<JSObject> copy;
      84             :   if (copying) {
      85             :     // JSFunction objects are not allowed to be in normal boilerplates at all.
      86             :     DCHECK(!object->IsJSFunction());
      87             :     Handle<AllocationSite> site_to_pass;
      88     2267681 :     if (site_context()->ShouldCreateMemento(object)) {
      89     2120805 :       site_to_pass = site_context()->current();
      90             :     }
      91     2267681 :     copy = isolate->factory()->CopyJSObjectWithAllocationSite(object,
      92             :                                                               site_to_pass);
      93             :   } else {
      94             :     copy = object;
      95             :   }
      96             : 
      97             :   DCHECK(copying || copy.is_identical_to(object));
      98             : 
      99     2541706 :   if (shallow) return copy;
     100             : 
     101             :   HandleScope scope(isolate);
     102             : 
     103             :   // Deep copy own properties. Arrays only have 1 property "length".
     104     2362063 :   if (!copy->IsJSArray()) {
     105      835727 :     if (copy->HasFastProperties()) {
     106             :       Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors());
     107             :       int limit = copy->map()->NumberOfOwnDescriptors();
     108     1825308 :       for (int i = 0; i < limit; i++) {
     109             :         DCHECK_EQ(kField, descriptors->GetDetails(i).location());
     110             :         DCHECK_EQ(kData, descriptors->GetDetails(i).kind());
     111     1001416 :         FieldIndex index = FieldIndex::ForDescriptor(copy->map(), i);
     112     1004728 :         if (copy->IsUnboxedDoubleField(index)) continue;
     113      998104 :         Object* raw = copy->RawFastPropertyAt(index);
     114      998104 :         if (raw->IsJSObject()) {
     115             :           Handle<JSObject> value(JSObject::cast(raw), isolate);
     116      956986 :           ASSIGN_RETURN_ON_EXCEPTION(
     117             :               isolate, value, VisitElementOrProperty(copy, value), JSObject);
     118      454393 :           if (copying) copy->FastPropertyAtPut(index, *value);
     119      278189 :         } else if (copying && raw->IsMutableHeapNumber()) {
     120             :           DCHECK(descriptors->GetDetails(i).representation().IsDouble());
     121             :           uint64_t double_value = HeapNumber::cast(raw)->value_as_bits();
     122           0 :           Handle<HeapNumber> value = isolate->factory()->NewHeapNumber(MUTABLE);
     123             :           value->set_value_as_bits(double_value);
     124           0 :           copy->FastPropertyAtPut(index, *value);
     125             :         }
     126             :       }
     127             :     } else {
     128             :       Handle<NameDictionary> dict(copy->property_dictionary());
     129     1766186 :       for (int i = 0; i < dict->Capacity(); i++) {
     130      871268 :         Object* raw = dict->ValueAt(i);
     131     1732663 :         if (!raw->IsJSObject()) continue;
     132             :         DCHECK(dict->KeyAt(i)->IsName());
     133             :         Handle<JSObject> value(JSObject::cast(raw), isolate);
     134       12876 :         ASSIGN_RETURN_ON_EXCEPTION(
     135             :             isolate, value, VisitElementOrProperty(copy, value), JSObject);
     136             :         if (copying) dict->ValueAtPut(i, *value);
     137             :       }
     138             :     }
     139             : 
     140             :     // Assume non-arrays don't end up having elements.
     141      835717 :     if (copy->elements()->length() == 0) return copy;
     142             :   }
     143             : 
     144             :   // Deep copy own elements.
     145     1527624 :   switch (copy->GetElementsKind()) {
     146             :     case PACKED_ELEMENTS:
     147             :     case HOLEY_ELEMENTS: {
     148             :       Handle<FixedArray> elements(FixedArray::cast(copy->elements()));
     149      688554 :       if (elements->map() == isolate->heap()->fixed_cow_array_map()) {
     150             : #ifdef DEBUG
     151             :         for (int i = 0; i < elements->length(); i++) {
     152             :           DCHECK(!elements->get(i)->IsJSObject());
     153             :         }
     154             : #endif
     155             :       } else {
     156     9053111 :         for (int i = 0; i < elements->length(); i++) {
     157             :           Object* raw = elements->get(i);
     158     6271315 :           if (!raw->IsJSObject()) continue;
     159             :           Handle<JSObject> value(JSObject::cast(raw), isolate);
     160     1692980 :           ASSIGN_RETURN_ON_EXCEPTION(
     161             :               isolate, value, VisitElementOrProperty(copy, value), JSObject);
     162      814909 :           if (copying) elements->set(i, *value);
     163             :         }
     164             :       }
     165             :       break;
     166             :     }
     167             :     case DICTIONARY_ELEMENTS: {
     168             :       Handle<SeededNumberDictionary> element_dictionary(
     169             :           copy->element_dictionary());
     170             :       int capacity = element_dictionary->Capacity();
     171        7165 :       for (int i = 0; i < capacity; i++) {
     172        6932 :         Object* raw = element_dictionary->ValueAt(i);
     173       13694 :         if (!raw->IsJSObject()) continue;
     174             :         Handle<JSObject> value(JSObject::cast(raw), isolate);
     175         300 :         ASSIGN_RETURN_ON_EXCEPTION(
     176             :             isolate, value, VisitElementOrProperty(copy, value), JSObject);
     177             :         if (copying) element_dictionary->ValueAtPut(i, *value);
     178             :       }
     179             :       break;
     180             :     }
     181             :     case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
     182             :     case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
     183           0 :       UNIMPLEMENTED();
     184             :       break;
     185             :     case FAST_STRING_WRAPPER_ELEMENTS:
     186             :     case SLOW_STRING_WRAPPER_ELEMENTS:
     187           0 :       UNREACHABLE();
     188             :       break;
     189             : 
     190             : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) case TYPE##_ELEMENTS:
     191             : 
     192             :       TYPED_ARRAYS(TYPED_ARRAY_CASE)
     193             : #undef TYPED_ARRAY_CASE
     194             :       // Typed elements cannot be created using an object literal.
     195           0 :       UNREACHABLE();
     196             :       break;
     197             : 
     198             :     case PACKED_SMI_ELEMENTS:
     199             :     case HOLEY_SMI_ELEMENTS:
     200             :     case PACKED_DOUBLE_ELEMENTS:
     201             :     case HOLEY_DOUBLE_ELEMENTS:
     202             :     case NO_ELEMENTS:
     203             :       // No contained objects, nothing to do.
     204             :       break;
     205             :   }
     206             : 
     207     1527604 :   return copy;
     208             : }
     209             : 
     210             : class DeprecationUpdateContext {
     211             :  public:
     212       14357 :   explicit DeprecationUpdateContext(Isolate* isolate) { isolate_ = isolate; }
     213       27982 :   Isolate* isolate() { return isolate_; }
     214             :   bool ShouldCreateMemento(Handle<JSObject> object) { return false; }
     215             :   inline void ExitScope(Handle<AllocationSite> scope_site,
     216             :                         Handle<JSObject> object) {}
     217             :   Handle<AllocationSite> EnterNewScope() { return Handle<AllocationSite>(); }
     218             :   Handle<AllocationSite> current() {
     219             :     UNREACHABLE();
     220             :     return Handle<AllocationSite>();
     221             :   }
     222             : 
     223             :   static const bool kCopying = false;
     224             : 
     225             :  private:
     226             :   Isolate* isolate_;
     227             : };
     228             : 
     229             : // AllocationSiteCreationContext aids in the creation of AllocationSites to
     230             : // accompany object literals.
     231             : class AllocationSiteCreationContext : public AllocationSiteContext {
     232             :  public:
     233             :   explicit AllocationSiteCreationContext(Isolate* isolate)
     234             :       : AllocationSiteContext(isolate) {}
     235             : 
     236      246057 :   Handle<AllocationSite> EnterNewScope() {
     237             :     Handle<AllocationSite> scope_site;
     238      492114 :     if (top().is_null()) {
     239             :       // We are creating the top level AllocationSite as opposed to a nested
     240             :       // AllocationSite.
     241      197948 :       InitializeTraversal(isolate()->factory()->NewAllocationSite());
     242             :       scope_site = Handle<AllocationSite>(*top(), isolate());
     243             :       if (FLAG_trace_creation_allocation_sites) {
     244             :         PrintF("*** Creating top level AllocationSite %p\n",
     245             :                static_cast<void*>(*scope_site));
     246             :       }
     247             :     } else {
     248             :       DCHECK(!current().is_null());
     249       48109 :       scope_site = isolate()->factory()->NewAllocationSite();
     250             :       if (FLAG_trace_creation_allocation_sites) {
     251             :         PrintF("Creating nested site (top, current, new) (%p, %p, %p)\n",
     252             :                static_cast<void*>(*top()), static_cast<void*>(*current()),
     253             :                static_cast<void*>(*scope_site));
     254             :       }
     255       48109 :       current()->set_nested_site(*scope_site);
     256             :       update_current_site(*scope_site);
     257             :     }
     258             :     DCHECK(!scope_site.is_null());
     259      246057 :     return scope_site;
     260             :   }
     261             :   void ExitScope(Handle<AllocationSite> scope_site, Handle<JSObject> object) {
     262      246043 :     if (object.is_null()) return;
     263             :     scope_site->set_boilerplate(*object);
     264             :     if (FLAG_trace_creation_allocation_sites) {
     265             :       bool top_level =
     266             :           !scope_site.is_null() && top().is_identical_to(scope_site);
     267             :       if (top_level) {
     268             :         PrintF("*** Setting AllocationSite %p transition_info %p\n",
     269             :                static_cast<void*>(*scope_site), static_cast<void*>(*object));
     270             :       } else {
     271             :         PrintF("Setting AllocationSite (%p, %p) transition_info %p\n",
     272             :                static_cast<void*>(*top()), static_cast<void*>(*scope_site),
     273             :                static_cast<void*>(*object));
     274             :       }
     275             :     }
     276             :   }
     277             :   static const bool kCopying = false;
     278             : };
     279             : 
     280             : MaybeHandle<JSObject> DeepWalk(Handle<JSObject> object,
     281             :                                DeprecationUpdateContext* site_context) {
     282             :   JSObjectWalkVisitor<DeprecationUpdateContext> v(site_context, kNoHints);
     283       14357 :   MaybeHandle<JSObject> result = v.StructureWalk(object);
     284             :   Handle<JSObject> for_assert;
     285             :   DCHECK(!result.ToHandle(&for_assert) || for_assert.is_identical_to(object));
     286       14357 :   return result;
     287             : }
     288             : 
     289             : MaybeHandle<JSObject> DeepWalk(Handle<JSObject> object,
     290             :                                AllocationSiteCreationContext* site_context) {
     291             :   JSObjectWalkVisitor<AllocationSiteCreationContext> v(site_context, kNoHints);
     292      197948 :   MaybeHandle<JSObject> result = v.StructureWalk(object);
     293             :   Handle<JSObject> for_assert;
     294             :   DCHECK(!result.ToHandle(&for_assert) || for_assert.is_identical_to(object));
     295      197948 :   return result;
     296             : }
     297             : 
     298             : MaybeHandle<JSObject> DeepCopy(Handle<JSObject> object,
     299             :                                AllocationSiteUsageContext* site_context,
     300             :                                DeepCopyHints hints) {
     301             :   JSObjectWalkVisitor<AllocationSiteUsageContext> v(site_context, hints);
     302      997864 :   MaybeHandle<JSObject> copy = v.StructureWalk(object);
     303             :   Handle<JSObject> for_assert;
     304             :   DCHECK(!copy.ToHandle(&for_assert) || !for_assert.is_identical_to(object));
     305      997864 :   return copy;
     306             : }
     307             : 
     308             : struct ObjectBoilerplate {
     309      398525 :   static Handle<JSObject> Create(Isolate* isolate,
     310             :                                  Handle<HeapObject> description, int flags,
     311             :                                  PretenureFlag pretenure_flag) {
     312      398525 :     Handle<Context> native_context = isolate->native_context();
     313             :     Handle<BoilerplateDescription> boilerplate_description =
     314             :         Handle<BoilerplateDescription>::cast(description);
     315      398525 :     bool use_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
     316      398525 :     bool has_null_prototype = (flags & ObjectLiteral::kHasNullPrototype) != 0;
     317             : 
     318             :     // In case we have function literals, we want the object to be in
     319             :     // slow properties mode for now. We don't go in the map cache because
     320             :     // maps with constant functions can't be shared if the functions are
     321             :     // not the same (which is the common case).
     322      398525 :     int number_of_properties = boilerplate_description->backing_store_size();
     323             : 
     324             :     // Ignoring number_of_properties for force dictionary map with
     325             :     // __proto__:null.
     326             :     Handle<Map> map =
     327             :         has_null_prototype
     328             :             ? handle(native_context->slow_object_with_null_prototype_map(),
     329             :                      isolate)
     330             :             : isolate->factory()->ObjectLiteralMapFromCache(
     331      769412 :                   native_context, number_of_properties);
     332             : 
     333             :     Handle<JSObject> boilerplate =
     334             :         map->is_dictionary_map()
     335             :             ? isolate->factory()->NewSlowJSObjectFromMap(
     336             :                   map, number_of_properties, pretenure_flag)
     337      398525 :             : isolate->factory()->NewJSObjectFromMap(map, pretenure_flag);
     338             : 
     339             :     // Normalize the elements of the boilerplate to save space if needed.
     340      398525 :     if (!use_fast_elements) JSObject::NormalizeElements(boilerplate);
     341             : 
     342             :     // Add the constant properties to the boilerplate.
     343      398525 :     int length = boilerplate_description->size();
     344             :     // TODO(verwaest): Support tracking representations in the boilerplate.
     345     5704833 :     for (int index = 0; index < length; index++) {
     346     5306308 :       Handle<Object> key(boilerplate_description->name(index), isolate);
     347     5306308 :       Handle<Object> value(boilerplate_description->value(index), isolate);
     348     5306308 :       if (value->IsFixedArray()) {
     349             :         // The value contains the CompileTimeValue with the boilerplate
     350             :         // properties of a simple object or array literal.
     351       30344 :         Handle<FixedArray> compile_time_value = Handle<FixedArray>::cast(value);
     352             :         value =
     353       30344 :             InnerCreateBoilerplate(isolate, compile_time_value, pretenure_flag);
     354             :       }
     355     5306308 :       uint32_t element_index = 0;
     356     5306308 :       if (key->ToArrayIndex(&element_index)) {
     357             :         // Array index (uint32).
     358     2577467 :         if (value->IsUninitialized(isolate)) {
     359             :           value = handle(Smi::kZero, isolate);
     360             :         }
     361             :         JSObject::SetOwnElementIgnoreAttributes(boilerplate, element_index,
     362     2577467 :                                                 value, NONE)
     363     5154934 :             .Check();
     364             :       } else {
     365             :         Handle<String> name = Handle<String>::cast(key);
     366             :         DCHECK(!name->AsArrayIndex(&element_index));
     367     2728841 :         JSObject::SetOwnPropertyIgnoreAttributes(boilerplate, name, value, NONE)
     368     5457682 :             .Check();
     369             :       }
     370             :     }
     371             : 
     372      398525 :     if (map->is_dictionary_map() && !has_null_prototype) {
     373             :       // TODO(cbruni): avoid making the boilerplate fast again, the clone stub
     374             :       // supports dict-mode objects directly.
     375             :       JSObject::MigrateSlowToFast(boilerplate,
     376             :                                   boilerplate->map()->UnusedPropertyFields(),
     377         213 :                                   "FastLiteral");
     378             :     }
     379      398525 :     return boilerplate;
     380             :   }
     381             : };
     382             : 
     383             : struct ArrayBoilerplate {
     384      186934 :   static Handle<JSObject> Create(Isolate* isolate,
     385             :                                  Handle<HeapObject> description, int flags,
     386             :                                  PretenureFlag pretenure_flag) {
     387             :     Handle<ConstantElementsPair> elements =
     388             :         Handle<ConstantElementsPair>::cast(description);
     389             :     // Create the JSArray.
     390             :     ElementsKind constant_elements_kind =
     391      186934 :         static_cast<ElementsKind>(elements->elements_kind());
     392             : 
     393             :     Handle<FixedArrayBase> constant_elements_values(
     394             :         elements->constant_values());
     395             :     Handle<FixedArrayBase> copied_elements_values;
     396      186934 :     if (IsDoubleElementsKind(constant_elements_kind)) {
     397             :       copied_elements_values = isolate->factory()->CopyFixedDoubleArray(
     398        3787 :           Handle<FixedDoubleArray>::cast(constant_elements_values));
     399             :     } else {
     400             :       DCHECK(IsSmiOrObjectElementsKind(constant_elements_kind));
     401             :       const bool is_cow = (constant_elements_values->map() ==
     402      183147 :                            isolate->heap()->fixed_cow_array_map());
     403      183147 :       if (is_cow) {
     404             :         copied_elements_values = constant_elements_values;
     405             : #if DEBUG
     406             :         Handle<FixedArray> fixed_array_values =
     407             :             Handle<FixedArray>::cast(copied_elements_values);
     408             :         for (int i = 0; i < fixed_array_values->length(); i++) {
     409             :           DCHECK(!fixed_array_values->get(i)->IsFixedArray());
     410             :         }
     411             : #endif
     412             :       } else {
     413             :         Handle<FixedArray> fixed_array_values =
     414             :             Handle<FixedArray>::cast(constant_elements_values);
     415             :         Handle<FixedArray> fixed_array_values_copy =
     416      102140 :             isolate->factory()->CopyFixedArray(fixed_array_values);
     417             :         copied_elements_values = fixed_array_values_copy;
     418     4283650 :         FOR_WITH_HANDLE_SCOPE(
     419             :             isolate, int, i = 0, i, i < fixed_array_values->length(), i++, {
     420             :               if (fixed_array_values->get(i)->IsFixedArray()) {
     421             :                 // The value contains the CompileTimeValue with the
     422             :                 // boilerplate description of a simple object or
     423             :                 // array literal.
     424             :                 Handle<FixedArray> compile_time_value(
     425             :                     FixedArray::cast(fixed_array_values->get(i)));
     426             :                 Handle<Object> result = InnerCreateBoilerplate(
     427             :                     isolate, compile_time_value, pretenure_flag);
     428             :                 fixed_array_values_copy->set(i, *result);
     429             :               }
     430             :             });
     431             :       }
     432             :     }
     433             : 
     434             :     return isolate->factory()->NewJSArrayWithElements(
     435             :         copied_elements_values, constant_elements_kind,
     436      186934 :         copied_elements_values->length(), pretenure_flag);
     437             :   }
     438             : };
     439             : 
     440       61744 : Handle<Object> InnerCreateBoilerplate(Isolate* isolate,
     441             :                                       Handle<FixedArray> compile_time_value,
     442             :                                       PretenureFlag pretenure_flag) {
     443             :   Handle<HeapObject> elements =
     444       61744 :       CompileTimeValue::GetElements(compile_time_value);
     445       61744 :   int flags = CompileTimeValue::GetLiteralTypeFlags(compile_time_value);
     446       61744 :   if (flags == CompileTimeValue::kArrayLiteralFlag) {
     447       24966 :     return ArrayBoilerplate::Create(isolate, elements, flags, pretenure_flag);
     448             :   }
     449       36778 :   return ObjectBoilerplate::Create(isolate, elements, flags, pretenure_flag);
     450             : }
     451             : 
     452             : template <typename Boilerplate>
     453     1323645 : MaybeHandle<JSObject> CreateLiteral(Isolate* isolate,
     454             :                                     Handle<FeedbackVector> vector,
     455             :                                     int literals_index,
     456             :                                     Handle<HeapObject> description, int flags) {
     457             :   FeedbackSlot literals_slot(FeedbackVector::ToSlot(literals_index));
     458     1323645 :   CHECK(literals_slot.ToInt() < vector->length());
     459             :   Handle<Object> literal_site(vector->Get(literals_slot), isolate);
     460             :   DeepCopyHints copy_hints =
     461     1323645 :       (flags & AggregateLiteral::kIsShallow) ? kObjectIsShallow : kNoHints;
     462             :   if (FLAG_track_double_fields && !FLAG_unbox_double_fields) {
     463             :     // Make sure we properly clone mutable heap numbers on 32-bit platforms.
     464             :     copy_hints = kNoHints;
     465             :   }
     466             : 
     467             :   Handle<AllocationSite> site;
     468             :   Handle<JSObject> boilerplate;
     469             : 
     470     1323645 :   if (HasBoilerplate(isolate, literal_site)) {
     471             :     site = Handle<AllocationSite>::cast(literal_site);
     472             :     boilerplate = Handle<JSObject>(site->boilerplate(), isolate);
     473             :   } else {
     474             :     // Eagerly create AllocationSites for literals that contain an Array.
     475             :     bool needs_initial_allocation_site =
     476      523715 :         (flags & AggregateLiteral::kNeedsInitialAllocationSite) != 0;
     477             :     // TODO(cbruni): Even in the case where we need an initial allocation site
     478             :     // we could still create the boilerplate lazily to save memory.
     479      523715 :     if (!needs_initial_allocation_site &&
     480             :         IsUninitializedLiteralSite(*literal_site)) {
     481             :       PreInitializeLiteralSite(vector, literals_slot);
     482      325767 :       boilerplate =
     483             :           Boilerplate::Create(isolate, description, flags, NOT_TENURED);
     484      325767 :       if (copy_hints == kNoHints) {
     485             :         DeprecationUpdateContext update_context(isolate);
     486       14357 :         RETURN_ON_EXCEPTION(isolate, DeepWalk(boilerplate, &update_context),
     487             :                             JSObject);
     488             :       }
     489      325767 :       return boilerplate;
     490             :     } else {
     491             :       PretenureFlag pretenure_flag =
     492      197948 :           isolate->heap()->InNewSpace(*vector) ? NOT_TENURED : TENURED;
     493      197948 :       boilerplate =
     494             :           Boilerplate::Create(isolate, description, flags, pretenure_flag);
     495             :     }
     496             :     // Install AllocationSite objects.
     497             :     AllocationSiteCreationContext creation_context(isolate);
     498      197948 :     site = creation_context.EnterNewScope();
     499      197948 :     RETURN_ON_EXCEPTION(isolate, DeepWalk(boilerplate, &creation_context),
     500             :                         JSObject);
     501             :     creation_context.ExitScope(site, boilerplate);
     502             : 
     503             :     vector->Set(literals_slot, *site);
     504             :   }
     505             : 
     506             :   STATIC_ASSERT(static_cast<int>(ObjectLiteral::kDisableMementos) ==
     507             :                 static_cast<int>(ArrayLiteral::kDisableMementos));
     508      997864 :   bool enable_mementos = (flags & ObjectLiteral::kDisableMementos) == 0;
     509             : 
     510             :   // Copy the existing boilerplate.
     511             :   AllocationSiteUsageContext usage_context(isolate, site, enable_mementos);
     512      997864 :   usage_context.EnterNewScope();
     513             :   MaybeHandle<JSObject> copy =
     514             :       DeepCopy(boilerplate, &usage_context, copy_hints);
     515             :   usage_context.ExitScope(site, boilerplate);
     516      997864 :   return copy;
     517             : }
     518             : }  // namespace
     519             : 
     520     1351222 : RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) {
     521      675611 :   HandleScope scope(isolate);
     522             :   DCHECK_EQ(4, args.length());
     523     1351222 :   CONVERT_ARG_HANDLE_CHECKED(FeedbackVector, vector, 0);
     524     1351222 :   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
     525     1351222 :   CONVERT_ARG_HANDLE_CHECKED(BoilerplateDescription, description, 2);
     526     1351222 :   CONVERT_SMI_ARG_CHECKED(flags, 3);
     527     1351222 :   RETURN_RESULT_OR_FAILURE(
     528             :       isolate, CreateLiteral<ObjectBoilerplate>(isolate, vector, literals_index,
     529      675611 :                                                 description, flags));
     530             : }
     531             : 
     532     1296068 : RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) {
     533      648034 :   HandleScope scope(isolate);
     534             :   DCHECK_EQ(4, args.length());
     535     1296068 :   CONVERT_ARG_HANDLE_CHECKED(FeedbackVector, vector, 0);
     536     1296068 :   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
     537     1296068 :   CONVERT_ARG_HANDLE_CHECKED(ConstantElementsPair, elements, 2);
     538     1296068 :   CONVERT_SMI_ARG_CHECKED(flags, 3);
     539     1296068 :   RETURN_RESULT_OR_FAILURE(
     540             :       isolate, CreateLiteral<ArrayBoilerplate>(isolate, vector, literals_index,
     541      648034 :                                                elements, flags));
     542             : }
     543             : 
     544      199662 : RUNTIME_FUNCTION(Runtime_CreateRegExpLiteral) {
     545       99831 :   HandleScope scope(isolate);
     546             :   DCHECK_EQ(4, args.length());
     547      199662 :   CONVERT_ARG_HANDLE_CHECKED(FeedbackVector, vector, 0);
     548      199662 :   CONVERT_SMI_ARG_CHECKED(index, 1);
     549      199662 :   CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2);
     550      199662 :   CONVERT_SMI_ARG_CHECKED(flags, 3);
     551             : 
     552       99831 :   FeedbackSlot literal_slot(FeedbackVector::ToSlot(index));
     553             : 
     554             :   // Check if boilerplate exists. If not, create it first.
     555       99831 :   Handle<Object> literal_site(vector->Get(literal_slot), isolate);
     556             :   Handle<Object> boilerplate;
     557       99831 :   if (!HasBoilerplate(isolate, literal_site)) {
     558      199662 :     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
     559             :         isolate, boilerplate, JSRegExp::New(pattern, JSRegExp::Flags(flags)));
     560       97576 :     if (IsUninitializedLiteralSite(*literal_site)) {
     561       81822 :       PreInitializeLiteralSite(vector, literal_slot);
     562             :       return *boilerplate;
     563             :     }
     564       15754 :     vector->Set(literal_slot, *boilerplate);
     565             :   }
     566       31508 :   return *JSRegExp::Copy(Handle<JSRegExp>::cast(boilerplate));
     567             : }
     568             : 
     569             : }  // namespace internal
     570             : }  // namespace v8

Generated by: LCOV version 1.10