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