runtime-literals.cc revision 3b9bc31999c9787eb726ecdbfd5796bfdec32a18
1958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Copyright 2014 the V8 project authors. All rights reserved.
2958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Use of this source code is governed by a BSD-style license that can be
3958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// found in the LICENSE file.
4958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/runtime/runtime-utils.h"
6958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
7958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/allocation-site-scopes.h"
8958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/arguments.h"
9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ast/ast.h"
10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/isolate-inl.h"
11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/parsing/parser.h"
12958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/runtime/runtime.h"
13958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
14958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace v8 {
15958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace internal {
16958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
17958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic Handle<Map> ComputeObjectLiteralMap(
18958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Handle<Context> context, Handle<FixedArray> constant_properties,
193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    bool* is_result_from_cache) {
20958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int properties_length = constant_properties->length();
21958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int number_of_properties = properties_length / 2;
22958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
23958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (int p = 0; p != properties_length; p += 2) {
24958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Object* key = constant_properties->get(p);
25958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    uint32_t element_index = 0;
26958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (key->ToArrayIndex(&element_index)) {
27958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // An index key does not require space in the property backing store.
28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      number_of_properties--;
29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
31958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Isolate* isolate = context->GetIsolate();
32958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return isolate->factory()->ObjectLiteralMapFromCache(
333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      context, number_of_properties, is_result_from_cache);
34958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
35958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierMUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Isolate* isolate, Handle<LiteralsArray> literals,
383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Handle<FixedArray> constant_properties);
39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
40958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierMUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate(
41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Isolate* isolate, Handle<LiteralsArray> literals,
423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Handle<FixedArray> constant_properties, bool should_have_fast_elements) {
43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Context> context = isolate->native_context();
44958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
45958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // In case we have function literals, we want the object to be in
46958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // slow properties mode for now. We don't go in the map cache because
47958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // maps with constant functions can't be shared if the functions are
48958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // not the same (which is the common case).
49958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool is_result_from_cache = false;
503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Handle<Map> map = ComputeObjectLiteralMap(context, constant_properties,
513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                            &is_result_from_cache);
52958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
53958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  PretenureFlag pretenure_flag =
54958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED;
55958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
56958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<JSObject> boilerplate =
57958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      isolate->factory()->NewJSObjectFromMap(map, pretenure_flag);
58958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
59958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Normalize the elements of the boilerplate to save space if needed.
60958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate);
61958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
62958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Add the constant properties to the boilerplate.
63958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int length = constant_properties->length();
64958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool should_transform =
65958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      !is_result_from_cache && boilerplate->HasFastProperties();
663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bool should_normalize = should_transform;
67958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (should_normalize) {
68958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // TODO(verwaest): We might not want to ever normalize here.
69958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    JSObject::NormalizeProperties(boilerplate, KEEP_INOBJECT_PROPERTIES,
70958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                  length / 2, "Boilerplate");
71958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
72958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // TODO(verwaest): Support tracking representations in the boilerplate.
73958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (int index = 0; index < length; index += 2) {
74958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Handle<Object> key(constant_properties->get(index + 0), isolate);
75958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Handle<Object> value(constant_properties->get(index + 1), isolate);
76958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (value->IsFixedArray()) {
77958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // The value contains the constant_properties of a
78958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // simple object or array literal.
79958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Handle<FixedArray> array = Handle<FixedArray>::cast(value);
80958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSIGN_RETURN_ON_EXCEPTION(
813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          isolate, value, CreateLiteralBoilerplate(isolate, literals, array),
82958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          Object);
83958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
84958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    MaybeHandle<Object> maybe_result;
85958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    uint32_t element_index = 0;
863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (key->ToArrayIndex(&element_index)) {
87958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // Array index (uint32).
88958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (value->IsUninitialized()) value = handle(Smi::FromInt(0), isolate);
89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      maybe_result = JSObject::SetOwnElementIgnoreAttributes(
90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          boilerplate, element_index, value, NONE);
91958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Handle<String> name = Handle<String>::cast(key);
933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(!name->AsArrayIndex(&element_index));
94958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(boilerplate, name,
95958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                              value, NONE);
96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
97958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    RETURN_ON_EXCEPTION(isolate, maybe_result, Object);
98958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
99958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Transform to fast properties if necessary. For object literals with
101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // containing function literals we defer this operation until after all
102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // computed properties have been assigned so that we can generate
103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // constant function properties.
1043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (should_transform) {
105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    JSObject::MigrateSlowToFast(boilerplate,
106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                boilerplate->map()->unused_property_fields(),
107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                "FastLiteral");
108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return boilerplate;
110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierMaybeHandle<Object> Runtime::CreateArrayLiteralBoilerplate(
113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Isolate* isolate, Handle<LiteralsArray> literals,
1143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Handle<FixedArray> elements) {
115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Create the JSArray.
116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<JSFunction> constructor = isolate->array_function();
117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  PretenureFlag pretenure_flag =
119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED;
120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<JSArray> object = Handle<JSArray>::cast(
122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      isolate->factory()->NewJSObject(constructor, pretenure_flag));
123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  ElementsKind constant_elements_kind =
125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      static_cast<ElementsKind>(Smi::cast(elements->get(0))->value());
126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<FixedArrayBase> constant_elements_values(
127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      FixedArrayBase::cast(elements->get(1)));
128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  {
130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DisallowHeapAllocation no_gc;
131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(IsFastElementsKind(constant_elements_kind));
132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Context* native_context = isolate->context()->native_context();
1333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Object* map =
1343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        native_context->get(Context::ArrayMapIndex(constant_elements_kind));
135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    object->set_map(Map::cast(map));
136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<FixedArrayBase> copied_elements_values;
139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (IsFastDoubleElementsKind(constant_elements_kind)) {
140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    copied_elements_values = isolate->factory()->CopyFixedDoubleArray(
141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Handle<FixedDoubleArray>::cast(constant_elements_values));
142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(IsFastSmiOrObjectElementsKind(constant_elements_kind));
144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    const bool is_cow = (constant_elements_values->map() ==
145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                         isolate->heap()->fixed_cow_array_map());
146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (is_cow) {
147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      copied_elements_values = constant_elements_values;
148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if DEBUG
149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Handle<FixedArray> fixed_array_values =
150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          Handle<FixedArray>::cast(copied_elements_values);
151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      for (int i = 0; i < fixed_array_values->length(); i++) {
152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        DCHECK(!fixed_array_values->get(i)->IsFixedArray());
153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif
155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Handle<FixedArray> fixed_array_values =
157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          Handle<FixedArray>::cast(constant_elements_values);
158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Handle<FixedArray> fixed_array_values_copy =
159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          isolate->factory()->CopyFixedArray(fixed_array_values);
160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      copied_elements_values = fixed_array_values_copy;
1613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      FOR_WITH_HANDLE_SCOPE(
1623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          isolate, int, i = 0, i, i < fixed_array_values->length(), i++, {
1633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            if (fixed_array_values->get(i)->IsFixedArray()) {
1643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch              // The value contains the constant_properties of a
1653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch              // simple object or array literal.
1663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch              Handle<FixedArray> fa(
1673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                  FixedArray::cast(fixed_array_values->get(i)));
1683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch              Handle<Object> result;
1693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch              ASSIGN_RETURN_ON_EXCEPTION(
1703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                  isolate, result,
1713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                  CreateLiteralBoilerplate(isolate, literals, fa), Object);
1723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch              fixed_array_values_copy->set(i, *result);
1733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            }
1743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          });
175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  object->set_elements(*copied_elements_values);
178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  object->set_length(Smi::FromInt(copied_elements_values->length()));
179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  JSObject::ValidateElements(object);
181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return object;
182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierMUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
1853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Isolate* isolate, Handle<LiteralsArray> literals,
1863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Handle<FixedArray> array) {
187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  switch (CompileTimeValue::GetLiteralType(array)) {
189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS:
1903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      return CreateObjectLiteralBoilerplate(isolate, literals, elements, true);
191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS:
1923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      return CreateObjectLiteralBoilerplate(isolate, literals, elements, false);
193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case CompileTimeValue::ARRAY_LITERAL:
194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return Runtime::CreateArrayLiteralBoilerplate(isolate, literals,
1953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                                    elements);
196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    default:
197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      UNREACHABLE();
198958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return MaybeHandle<Object>();
199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
200958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRUNTIME_FUNCTION(Runtime_CreateRegExpLiteral) {
204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HandleScope scope(isolate);
205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(4, args.length());
206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0);
207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CONVERT_SMI_ARG_CHECKED(index, 1);
208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2);
209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CONVERT_SMI_ARG_CHECKED(flags, 3);
210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Check if boilerplate exists. If not, create it first.
212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Object> boilerplate(closure->literals()->literal(index), isolate);
213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (boilerplate->IsUndefined()) {
214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        isolate, boilerplate, JSRegExp::New(pattern, JSRegExp::Flags(flags)));
216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    closure->literals()->set_literal(index, *boilerplate);
217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return *JSRegExp::Copy(Handle<JSRegExp>::cast(boilerplate));
219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_CreateObjectLiteral) {
223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  HandleScope scope(isolate);
224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(4, args.length());
225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0);
226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2);
228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CONVERT_SMI_ARG_CHECKED(flags, 3);
229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<LiteralsArray> literals(closure->literals(), isolate);
230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool enable_mementos = (flags & ObjectLiteral::kDisableMementos) == 0;
232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RUNTIME_ASSERT(literals_index >= 0 &&
234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 literals_index < literals->literals_count());
235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Check if boilerplate exists. If not, create it first.
237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Object> literal_site(literals->literal(literals_index), isolate);
238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<AllocationSite> site;
239958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<JSObject> boilerplate;
240958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (*literal_site == isolate->heap()->undefined_value()) {
241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Handle<Object> raw_boilerplate;
242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        isolate, raw_boilerplate,
244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        CreateObjectLiteralBoilerplate(isolate, literals, constant_properties,
2453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                       should_have_fast_elements));
246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    boilerplate = Handle<JSObject>::cast(raw_boilerplate);
247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    AllocationSiteCreationContext creation_context(isolate);
249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    site = creation_context.EnterNewScope();
250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    RETURN_FAILURE_ON_EXCEPTION(
251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        isolate, JSObject::DeepWalk(boilerplate, &creation_context));
252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    creation_context.ExitScope(site, boilerplate);
253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Update the functions literal and return the boilerplate.
255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    literals->set_literal(literals_index, *site);
256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    site = Handle<AllocationSite>::cast(literal_site);
258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    boilerplate =
259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Handle<JSObject>(JSObject::cast(site->transition_info()), isolate);
260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationSiteUsageContext usage_context(isolate, site, enable_mementos);
263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  usage_context.EnterNewScope();
264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MaybeHandle<Object> maybe_copy =
265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      JSObject::DeepCopy(boilerplate, &usage_context);
266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  usage_context.ExitScope(site, boilerplate);
267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<Object> copy;
268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, copy, maybe_copy);
269958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return *copy;
270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierMUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite(
273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Isolate* isolate, Handle<LiteralsArray> literals, int literals_index,
2743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Handle<FixedArray> elements) {
275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Check if boilerplate exists. If not, create it first.
276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Object> literal_site(literals->literal(literals_index), isolate);
277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<AllocationSite> site;
278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (*literal_site == isolate->heap()->undefined_value()) {
279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(*elements != isolate->heap()->empty_fixed_array());
280958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Handle<Object> boilerplate;
281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    ASSIGN_RETURN_ON_EXCEPTION(
282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        isolate, boilerplate,
2833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements),
284958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        AllocationSite);
285958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
286958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    AllocationSiteCreationContext creation_context(isolate);
287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    site = creation_context.EnterNewScope();
288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (JSObject::DeepWalk(Handle<JSObject>::cast(boilerplate),
289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                           &creation_context).is_null()) {
290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return Handle<AllocationSite>::null();
291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    creation_context.ExitScope(site, Handle<JSObject>::cast(boilerplate));
293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    literals->set_literal(literals_index, *site);
295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    site = Handle<AllocationSite>::cast(literal_site);
297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return site;
300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic MaybeHandle<JSObject> CreateArrayLiteralImpl(
304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Isolate* isolate, Handle<LiteralsArray> literals, int literals_index,
305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<FixedArray> elements, int flags) {
306958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  RUNTIME_ASSERT_HANDLIFIED(
307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      literals_index >= 0 && literals_index < literals->literals_count(),
308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      JSObject);
309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<AllocationSite> site;
310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  ASSIGN_RETURN_ON_EXCEPTION(
311958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      isolate, site,
3123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      GetLiteralAllocationSite(isolate, literals, literals_index, elements),
313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      JSObject);
314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0;
316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<JSObject> boilerplate(JSObject::cast(site->transition_info()));
317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  AllocationSiteUsageContext usage_context(isolate, site, enable_mementos);
318958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  usage_context.EnterNewScope();
319958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  JSObject::DeepCopyHints hints = (flags & ArrayLiteral::kShallowElements) == 0
320958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                      ? JSObject::kNoHints
321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                      : JSObject::kObjectIsShallow;
322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MaybeHandle<JSObject> copy =
323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      JSObject::DeepCopy(boilerplate, &usage_context, hints);
324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  usage_context.ExitScope(site, boilerplate);
325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return copy;
326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_CreateArrayLiteral) {
330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  HandleScope scope(isolate);
331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(4, args.length());
332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0);
333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CONVERT_SMI_ARG_CHECKED(flags, 3);
336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<JSObject> result;
338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<LiteralsArray> literals(closure->literals(), isolate);
339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      isolate, result, CreateArrayLiteralImpl(isolate, literals, literals_index,
341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                              elements, flags));
342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return *result;
343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_CreateArrayLiteralStubBailout) {
347958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  HandleScope scope(isolate);
348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(3, args.length());
349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0);
350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
352958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
353958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<JSObject> result;
354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<LiteralsArray> literals(closure->literals(), isolate);
355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      isolate, result,
357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
358958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                             ArrayLiteral::kShallowElements));
359958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return *result;
360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
364