runtime-literals.cc revision 014dc512cdd3e367bee49a713fdc5ed92584a3e5
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,
19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool is_strong, 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(
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      context, number_of_properties, is_strong, is_result_from_cache);
34958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
35958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierMUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Isolate* isolate, Handle<LiteralsArray> literals,
38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<FixedArray> constant_properties, bool is_strong);
39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
40958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
41958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierMUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate(
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Isolate* isolate, Handle<LiteralsArray> literals,
43958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Handle<FixedArray> constant_properties, bool should_have_fast_elements,
44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool has_function_literal, bool is_strong) {
45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Context> context = isolate->native_context();
46958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
47958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // In case we have function literals, we want the object to be in
48958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // slow properties mode for now. We don't go in the map cache because
49958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // maps with constant functions can't be shared if the functions are
50958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // not the same (which is the common case).
51958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool is_result_from_cache = false;
52958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<Map> map = has_function_literal
53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ? Handle<Map>(is_strong
54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                        ? context->js_object_strong_map()
55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                        : context->object_function()->initial_map())
56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : ComputeObjectLiteralMap(context, constant_properties, is_strong,
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                &is_result_from_cache);
58958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
59958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  PretenureFlag pretenure_flag =
60958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED;
61958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
62958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<JSObject> boilerplate =
63958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      isolate->factory()->NewJSObjectFromMap(map, pretenure_flag);
64958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
65958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Normalize the elements of the boilerplate to save space if needed.
66958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate);
67958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
68958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Add the constant properties to the boilerplate.
69958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int length = constant_properties->length();
70958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool should_transform =
71958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      !is_result_from_cache && boilerplate->HasFastProperties();
72958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool should_normalize = should_transform || has_function_literal;
73958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (should_normalize) {
74958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // TODO(verwaest): We might not want to ever normalize here.
75958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    JSObject::NormalizeProperties(boilerplate, KEEP_INOBJECT_PROPERTIES,
76958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                  length / 2, "Boilerplate");
77958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
78958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // TODO(verwaest): Support tracking representations in the boilerplate.
79958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (int index = 0; index < length; index += 2) {
80958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Handle<Object> key(constant_properties->get(index + 0), isolate);
81958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Handle<Object> value(constant_properties->get(index + 1), isolate);
82958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (value->IsFixedArray()) {
83958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // The value contains the constant_properties of a
84958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // simple object or array literal.
85958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Handle<FixedArray> array = Handle<FixedArray>::cast(value);
86958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSIGN_RETURN_ON_EXCEPTION(
87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          isolate, value,
88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          CreateLiteralBoilerplate(isolate, literals, array, is_strong),
89958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          Object);
90958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
91958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    MaybeHandle<Object> maybe_result;
92958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    uint32_t element_index = 0;
93958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (key->IsInternalizedString()) {
94958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) {
95958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        // Array index as string (uint32).
96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        if (value->IsUninitialized()) value = handle(Smi::FromInt(0), isolate);
97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        maybe_result = JSObject::SetOwnElementIgnoreAttributes(
98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            boilerplate, element_index, value, NONE);
99958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Handle<String> name(String::cast(*key));
101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        DCHECK(!name->AsArrayIndex(&element_index));
102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(
103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            boilerplate, name, value, NONE);
104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else if (key->ToArrayIndex(&element_index)) {
106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // Array index (uint32).
107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (value->IsUninitialized()) value = handle(Smi::FromInt(0), isolate);
108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      maybe_result = JSObject::SetOwnElementIgnoreAttributes(
109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          boilerplate, element_index, value, NONE);
110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // Non-uint32 number.
112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      DCHECK(key->IsNumber());
113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      double num = key->Number();
114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      char arr[100];
115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Vector<char> buffer(arr, arraysize(arr));
116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      const char* str = DoubleToCString(num, buffer);
117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Handle<String> name = isolate->factory()->NewStringFromAsciiChecked(str);
118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(boilerplate, name,
119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                              value, NONE);
120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // If setting the property on the boilerplate throws an
122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // exception, the exception is converted to an empty handle in
123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // the handle based operations.  In that case, we need to
124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // convert back to an exception.
125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    RETURN_ON_EXCEPTION(isolate, maybe_result, Object);
126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Transform to fast properties if necessary. For object literals with
129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // containing function literals we defer this operation until after all
130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // computed properties have been assigned so that we can generate
131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // constant function properties.
132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (should_transform && !has_function_literal) {
133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    JSObject::MigrateSlowToFast(boilerplate,
134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                boilerplate->map()->unused_property_fields(),
135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                "FastLiteral");
136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return boilerplate;
138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierMaybeHandle<Object> Runtime::CreateArrayLiteralBoilerplate(
142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Isolate* isolate, Handle<LiteralsArray> literals,
143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<FixedArray> elements, bool is_strong) {
144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Create the JSArray.
145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<JSFunction> constructor = isolate->array_function();
146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  PretenureFlag pretenure_flag =
148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED;
149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<JSArray> object = Handle<JSArray>::cast(
151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      isolate->factory()->NewJSObject(constructor, pretenure_flag));
152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  ElementsKind constant_elements_kind =
154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      static_cast<ElementsKind>(Smi::cast(elements->get(0))->value());
155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<FixedArrayBase> constant_elements_values(
156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      FixedArrayBase::cast(elements->get(1)));
157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  {
159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DisallowHeapAllocation no_gc;
160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(IsFastElementsKind(constant_elements_kind));
161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Context* native_context = isolate->context()->native_context();
162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Strength strength = is_strong ? Strength::STRONG : Strength::WEAK;
163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Object* map = native_context->get(
164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Context::ArrayMapIndex(constant_elements_kind, strength));
165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    object->set_map(Map::cast(map));
166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<FixedArrayBase> copied_elements_values;
169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (IsFastDoubleElementsKind(constant_elements_kind)) {
170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    copied_elements_values = isolate->factory()->CopyFixedDoubleArray(
171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Handle<FixedDoubleArray>::cast(constant_elements_values));
172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(IsFastSmiOrObjectElementsKind(constant_elements_kind));
174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    const bool is_cow = (constant_elements_values->map() ==
175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                         isolate->heap()->fixed_cow_array_map());
176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (is_cow) {
177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      copied_elements_values = constant_elements_values;
178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if DEBUG
179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Handle<FixedArray> fixed_array_values =
180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          Handle<FixedArray>::cast(copied_elements_values);
181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      for (int i = 0; i < fixed_array_values->length(); i++) {
182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        DCHECK(!fixed_array_values->get(i)->IsFixedArray());
183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif
185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Handle<FixedArray> fixed_array_values =
187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          Handle<FixedArray>::cast(constant_elements_values);
188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Handle<FixedArray> fixed_array_values_copy =
189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          isolate->factory()->CopyFixedArray(fixed_array_values);
190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      copied_elements_values = fixed_array_values_copy;
191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      for (int i = 0; i < fixed_array_values->length(); i++) {
192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        HandleScope scope(isolate);
193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        if (fixed_array_values->get(i)->IsFixedArray()) {
194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          // The value contains the constant_properties of a
195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          // simple object or array literal.
196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          Handle<FixedArray> fa(FixedArray::cast(fixed_array_values->get(i)));
197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          Handle<Object> result;
198958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          ASSIGN_RETURN_ON_EXCEPTION(
199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              isolate, result,
200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              CreateLiteralBoilerplate(isolate, literals, fa, is_strong),
201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              Object);
202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          fixed_array_values_copy->set(i, *result);
203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }
204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
207958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  object->set_elements(*copied_elements_values);
208958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  object->set_length(Smi::FromInt(copied_elements_values->length()));
209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  JSObject::ValidateElements(object);
211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return object;
212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierMUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Isolate* isolate, Handle<LiteralsArray> literals, Handle<FixedArray> array,
217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool is_strong) {
218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const bool kHasNoFunctionLiteral = false;
220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  switch (CompileTimeValue::GetLiteralType(array)) {
221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS:
222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return CreateObjectLiteralBoilerplate(isolate, literals, elements, true,
223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            kHasNoFunctionLiteral, is_strong);
224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS:
225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return CreateObjectLiteralBoilerplate(isolate, literals, elements, false,
226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            kHasNoFunctionLiteral, is_strong);
227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case CompileTimeValue::ARRAY_LITERAL:
228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return Runtime::CreateArrayLiteralBoilerplate(isolate, literals,
229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                    elements, is_strong);
230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    default:
231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      UNREACHABLE();
232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return MaybeHandle<Object>();
233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRUNTIME_FUNCTION(Runtime_CreateRegExpLiteral) {
238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HandleScope scope(isolate);
239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(4, args.length());
240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0);
241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CONVERT_SMI_ARG_CHECKED(index, 1);
242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2);
243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CONVERT_SMI_ARG_CHECKED(flags, 3);
244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Check if boilerplate exists. If not, create it first.
246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Object> boilerplate(closure->literals()->literal(index), isolate);
247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (boilerplate->IsUndefined()) {
248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        isolate, boilerplate, JSRegExp::New(pattern, JSRegExp::Flags(flags)));
250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    closure->literals()->set_literal(index, *boilerplate);
251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return *JSRegExp::Copy(Handle<JSRegExp>::cast(boilerplate));
253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_CreateObjectLiteral) {
257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  HandleScope scope(isolate);
258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(4, args.length());
259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0);
260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2);
262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CONVERT_SMI_ARG_CHECKED(flags, 3);
263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<LiteralsArray> literals(closure->literals(), isolate);
264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool enable_mementos = (flags & ObjectLiteral::kDisableMementos) == 0;
267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is_strong = (flags & ObjectLiteral::kIsStrong) != 0;
268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RUNTIME_ASSERT(literals_index >= 0 &&
270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 literals_index < literals->literals_count());
271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Check if boilerplate exists. If not, create it first.
273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Object> literal_site(literals->literal(literals_index), isolate);
274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<AllocationSite> site;
275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<JSObject> boilerplate;
276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (*literal_site == isolate->heap()->undefined_value()) {
277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Handle<Object> raw_boilerplate;
278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        isolate, raw_boilerplate,
280958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        CreateObjectLiteralBoilerplate(isolate, literals, constant_properties,
281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                       should_have_fast_elements,
282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       has_function_literal, is_strong));
283958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    boilerplate = Handle<JSObject>::cast(raw_boilerplate);
284958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
285958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    AllocationSiteCreationContext creation_context(isolate);
286958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    site = creation_context.EnterNewScope();
287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    RETURN_FAILURE_ON_EXCEPTION(
288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        isolate, JSObject::DeepWalk(boilerplate, &creation_context));
289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    creation_context.ExitScope(site, boilerplate);
290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Update the functions literal and return the boilerplate.
292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    literals->set_literal(literals_index, *site);
293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    site = Handle<AllocationSite>::cast(literal_site);
295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    boilerplate =
296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Handle<JSObject>(JSObject::cast(site->transition_info()), isolate);
297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocationSiteUsageContext usage_context(isolate, site, enable_mementos);
300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  usage_context.EnterNewScope();
301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MaybeHandle<Object> maybe_copy =
302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      JSObject::DeepCopy(boilerplate, &usage_context);
303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  usage_context.ExitScope(site, boilerplate);
304958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<Object> copy;
305958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, copy, maybe_copy);
306958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return *copy;
307958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierMUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite(
311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Isolate* isolate, Handle<LiteralsArray> literals, int literals_index,
312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<FixedArray> elements, bool is_strong) {
313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Check if boilerplate exists. If not, create it first.
314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Object> literal_site(literals->literal(literals_index), isolate);
315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<AllocationSite> site;
316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (*literal_site == isolate->heap()->undefined_value()) {
317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(*elements != isolate->heap()->empty_fixed_array());
318958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Handle<Object> boilerplate;
319958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    ASSIGN_RETURN_ON_EXCEPTION(
320958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        isolate, boilerplate,
321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements,
322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                               is_strong),
323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        AllocationSite);
324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    AllocationSiteCreationContext creation_context(isolate);
326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    site = creation_context.EnterNewScope();
327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (JSObject::DeepWalk(Handle<JSObject>::cast(boilerplate),
328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                           &creation_context).is_null()) {
329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return Handle<AllocationSite>::null();
330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    creation_context.ExitScope(site, Handle<JSObject>::cast(boilerplate));
332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    literals->set_literal(literals_index, *site);
334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    site = Handle<AllocationSite>::cast(literal_site);
336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
338958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return site;
339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic MaybeHandle<JSObject> CreateArrayLiteralImpl(
343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Isolate* isolate, Handle<LiteralsArray> literals, int literals_index,
344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<FixedArray> elements, int flags) {
345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  RUNTIME_ASSERT_HANDLIFIED(
346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      literals_index >= 0 && literals_index < literals->literals_count(),
347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      JSObject);
348958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<AllocationSite> site;
349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is_strong = (flags & ArrayLiteral::kIsStrong) != 0;
350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  ASSIGN_RETURN_ON_EXCEPTION(
351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      isolate, site,
352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      GetLiteralAllocationSite(isolate, literals, literals_index, elements,
353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               is_strong),
354958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      JSObject);
355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0;
357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<JSObject> boilerplate(JSObject::cast(site->transition_info()));
358958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  AllocationSiteUsageContext usage_context(isolate, site, enable_mementos);
359958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  usage_context.EnterNewScope();
360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  JSObject::DeepCopyHints hints = (flags & ArrayLiteral::kShallowElements) == 0
361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                      ? JSObject::kNoHints
362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                      : JSObject::kObjectIsShallow;
363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MaybeHandle<JSObject> copy =
364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      JSObject::DeepCopy(boilerplate, &usage_context, hints);
365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  usage_context.ExitScope(site, boilerplate);
366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return copy;
367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
368958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_CreateArrayLiteral) {
371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  HandleScope scope(isolate);
372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(4, args.length());
373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0);
374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CONVERT_SMI_ARG_CHECKED(flags, 3);
377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<JSObject> result;
379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<LiteralsArray> literals(closure->literals(), isolate);
380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      isolate, result, CreateArrayLiteralImpl(isolate, literals, literals_index,
382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                              elements, flags));
383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return *result;
384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
386958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
387958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_CreateArrayLiteralStubBailout) {
388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  HandleScope scope(isolate);
389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(3, args.length());
390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0);
391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<JSObject> result;
395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<LiteralsArray> literals(closure->literals(), isolate);
396958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
397958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      isolate, result,
398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
399958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                             ArrayLiteral::kShallowElements));
400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return *result;
401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
402958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
403958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
404958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_StoreArrayLiteralElement) {
405958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  HandleScope scope(isolate);
406958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  RUNTIME_ASSERT(args.length() == 5);
407958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
408958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CONVERT_SMI_ARG_CHECKED(store_index, 1);
409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CONVERT_ARG_HANDLE_CHECKED(LiteralsArray, literals, 3);
411958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CONVERT_SMI_ARG_CHECKED(literal_index, 4);
412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Object* raw_literal_cell = literals->literal(literal_index);
414958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  JSArray* boilerplate = NULL;
415958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (raw_literal_cell->IsAllocationSite()) {
416958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    AllocationSite* site = AllocationSite::cast(raw_literal_cell);
417958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    boilerplate = JSArray::cast(site->transition_info());
418958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
419958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    boilerplate = JSArray::cast(raw_literal_cell);
420958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<JSArray> boilerplate_object(boilerplate);
422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  ElementsKind elements_kind = object->GetElementsKind();
423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(IsFastElementsKind(elements_kind));
424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Smis should never trigger transitions.
425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(!value->IsSmi());
426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
427958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (value->IsNumber()) {
428958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(IsFastSmiElementsKind(elements_kind));
429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
430958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                         ? FAST_HOLEY_DOUBLE_ELEMENTS
431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                         : FAST_DOUBLE_ELEMENTS;
432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (IsMoreGeneralElementsKindTransition(
433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            boilerplate_object->GetElementsKind(), transitioned_kind)) {
434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
435958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
436958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    JSObject::TransitionElementsKind(object, transitioned_kind);
437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(IsFastDoubleElementsKind(object->GetElementsKind()));
438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements());
439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    HeapNumber* number = HeapNumber::cast(*value);
440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    double_array->set(store_index, number->Number());
441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (!IsFastObjectElementsKind(elements_kind)) {
443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                           ? FAST_HOLEY_ELEMENTS
445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                           : FAST_ELEMENTS;
446958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      JSObject::TransitionElementsKind(object, transitioned_kind);
447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (IsMoreGeneralElementsKindTransition(
448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              boilerplate_object->GetElementsKind(), transitioned_kind)) {
449958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
450958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
452958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    FixedArray* object_array = FixedArray::cast(object->elements());
453958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    object_array->set(store_index, *value);
454958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
455958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return *object;
456958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
459