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" 9f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/ast/ast.h" 10f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/ast/compile-time-value.h" 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/isolate-inl.h" 12958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/runtime/runtime.h" 13958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 14958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace v8 { 15958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace internal { 16958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 17958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic Handle<Map> ComputeObjectLiteralMap( 1862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Context> context, 1962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<BoilerplateDescription> boilerplate_description, 203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bool* is_result_from_cache) { 2162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int number_of_properties = boilerplate_description->backing_store_size(); 22958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Isolate* isolate = context->GetIsolate(); 23958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return isolate->factory()->ObjectLiteralMapFromCache( 243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch context, number_of_properties, is_result_from_cache); 25958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 26958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 27958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierMUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( 2862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Isolate* isolate, Handle<FeedbackVector> vector, 2962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<BoilerplateDescription> boilerplate_description); 30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 31958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierMUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate( 3262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Isolate* isolate, Handle<FeedbackVector> vector, 3362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<BoilerplateDescription> boilerplate_description, 3462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool should_have_fast_elements) { 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Context> context = isolate->native_context(); 36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 37958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // In case we have function literals, we want the object to be in 38958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // slow properties mode for now. We don't go in the map cache because 39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // maps with constant functions can't be shared if the functions are 40958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // not the same (which is the common case). 41958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool is_result_from_cache = false; 4262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Map> map = ComputeObjectLiteralMap(context, boilerplate_description, 433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch &is_result_from_cache); 44958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 45958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PretenureFlag pretenure_flag = 4662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate->heap()->InNewSpace(*vector) ? NOT_TENURED : TENURED; 47958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 48958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<JSObject> boilerplate = 49958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->factory()->NewJSObjectFromMap(map, pretenure_flag); 50958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 51958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Normalize the elements of the boilerplate to save space if needed. 52958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate); 53958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 54958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Add the constant properties to the boilerplate. 5562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int length = boilerplate_description->size(); 56958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool should_transform = 57958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier !is_result_from_cache && boilerplate->HasFastProperties(); 583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bool should_normalize = should_transform; 59958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (should_normalize) { 60958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // TODO(verwaest): We might not want to ever normalize here. 6162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch JSObject::NormalizeProperties(boilerplate, KEEP_INOBJECT_PROPERTIES, length, 6262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch "Boilerplate"); 63958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 64958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // TODO(verwaest): Support tracking representations in the boilerplate. 6562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch for (int index = 0; index < length; index++) { 6662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> key(boilerplate_description->name(index), isolate); 6762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> value(boilerplate_description->value(index), isolate); 6862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (value->IsBoilerplateDescription()) { 6962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // The value contains the boilerplate properties of a 70958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // simple object or array literal. 7162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<BoilerplateDescription> boilerplate = 7262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<BoilerplateDescription>::cast(value); 73958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSIGN_RETURN_ON_EXCEPTION( 7462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate, value, 7562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CreateLiteralBoilerplate(isolate, vector, boilerplate), Object); 76958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 77958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MaybeHandle<Object> maybe_result; 78958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t element_index = 0; 793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (key->ToArrayIndex(&element_index)) { 80958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Array index (uint32). 8113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (value->IsUninitialized(isolate)) { 82c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch value = handle(Smi::kZero, isolate); 8313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch maybe_result = JSObject::SetOwnElementIgnoreAttributes( 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch boilerplate, element_index, value, NONE); 86958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<String> name = Handle<String>::cast(key); 883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(!name->AsArrayIndex(&element_index)); 89958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(boilerplate, name, 90958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier value, NONE); 91958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 92958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RETURN_ON_EXCEPTION(isolate, maybe_result, Object); 93958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 94958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 95958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Transform to fast properties if necessary. For object literals with 96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // containing function literals we defer this operation until after all 97958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // computed properties have been assigned so that we can generate 98958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // constant function properties. 993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (should_transform) { 100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JSObject::MigrateSlowToFast(boilerplate, 101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier boilerplate->map()->unused_property_fields(), 102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier "FastLiteral"); 103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return boilerplate; 105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 107bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochstatic MaybeHandle<Object> CreateArrayLiteralBoilerplate( 10862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Isolate* isolate, Handle<FeedbackVector> vector, 10962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<ConstantElementsPair> elements) { 110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Create the JSArray. 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSFunction> constructor = isolate->array_function(); 112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PretenureFlag pretenure_flag = 11462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate->heap()->InNewSpace(*vector) ? NOT_TENURED : TENURED; 115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<JSArray> object = Handle<JSArray>::cast( 117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->factory()->NewJSObject(constructor, pretenure_flag)); 118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ElementsKind constant_elements_kind = 12062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static_cast<ElementsKind>(elements->elements_kind()); 12162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<FixedArrayBase> constant_elements_values(elements->constant_values()); 122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier { 124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DisallowHeapAllocation no_gc; 125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(IsFastElementsKind(constant_elements_kind)); 126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Context* native_context = isolate->context()->native_context(); 1273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Object* map = 1283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch native_context->get(Context::ArrayMapIndex(constant_elements_kind)); 129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier object->set_map(Map::cast(map)); 130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<FixedArrayBase> copied_elements_values; 133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (IsFastDoubleElementsKind(constant_elements_kind)) { 134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier copied_elements_values = isolate->factory()->CopyFixedDoubleArray( 135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<FixedDoubleArray>::cast(constant_elements_values)); 136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(IsFastSmiOrObjectElementsKind(constant_elements_kind)); 138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const bool is_cow = (constant_elements_values->map() == 139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->heap()->fixed_cow_array_map()); 140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (is_cow) { 141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier copied_elements_values = constant_elements_values; 142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if DEBUG 143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<FixedArray> fixed_array_values = 144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<FixedArray>::cast(copied_elements_values); 145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < fixed_array_values->length(); i++) { 146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!fixed_array_values->get(i)->IsFixedArray()); 147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif 149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<FixedArray> fixed_array_values = 151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<FixedArray>::cast(constant_elements_values); 152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<FixedArray> fixed_array_values_copy = 153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->factory()->CopyFixedArray(fixed_array_values); 154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier copied_elements_values = fixed_array_values_copy; 1553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FOR_WITH_HANDLE_SCOPE( 1563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch isolate, int, i = 0, i, i < fixed_array_values->length(), i++, { 15762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (fixed_array_values->get(i)->IsBoilerplateDescription()) { 15862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // The value contains the boilerplate properties of a 1593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // simple object or array literal. 16062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<BoilerplateDescription> boilerplate( 16162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch BoilerplateDescription::cast(fixed_array_values->get(i))); 1623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<Object> result; 1633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ASSIGN_RETURN_ON_EXCEPTION( 1643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch isolate, result, 16562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CreateLiteralBoilerplate(isolate, vector, boilerplate), 16662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Object); 1673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch fixed_array_values_copy->set(i, *result); 1683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 1693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch }); 170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier object->set_elements(*copied_elements_values); 173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier object->set_length(Smi::FromInt(copied_elements_values->length())); 174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JSObject::ValidateElements(object); 176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return object; 177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierMUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( 18062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Isolate* isolate, Handle<FeedbackVector> vector, 18162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<BoilerplateDescription> array) { 18262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<HeapObject> elements = CompileTimeValue::GetElements(array); 183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (CompileTimeValue::GetLiteralType(array)) { 18462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS: { 18562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<BoilerplateDescription> props = 18662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<BoilerplateDescription>::cast(elements); 18762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return CreateObjectLiteralBoilerplate(isolate, vector, props, true); 18862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 18962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS: { 19062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<BoilerplateDescription> props = 19162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<BoilerplateDescription>::cast(elements); 19262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return CreateObjectLiteralBoilerplate(isolate, vector, props, false); 19362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 19462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case CompileTimeValue::ARRAY_LITERAL: { 19562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<ConstantElementsPair> elems = 19662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<ConstantElementsPair>::cast(elements); 19762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return CreateArrayLiteralBoilerplate(isolate, vector, elems); 19862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: 200958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNREACHABLE(); 201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return MaybeHandle<Object>(); 202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRUNTIME_FUNCTION(Runtime_CreateRegExpLiteral) { 207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HandleScope scope(isolate); 208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(4, args.length()); 209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); 210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CONVERT_SMI_ARG_CHECKED(index, 1); 211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2); 212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CONVERT_SMI_ARG_CHECKED(flags, 3); 21362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FeedbackSlot literal_slot(FeedbackVector::ToSlot(index)); 214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check if boilerplate exists. If not, create it first. 21662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> boilerplate(closure->feedback_vector()->Get(literal_slot), 21762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate); 21813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (boilerplate->IsUndefined(isolate)) { 219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate, boilerplate, JSRegExp::New(pattern, JSRegExp::Flags(flags))); 22162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch closure->feedback_vector()->Set(literal_slot, *boilerplate); 222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return *JSRegExp::Copy(Handle<JSRegExp>::cast(boilerplate)); 224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_CreateObjectLiteral) { 228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(4, args.length()); 230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); 231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_SMI_ARG_CHECKED(literals_index, 1); 23262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CONVERT_ARG_HANDLE_CHECKED(BoilerplateDescription, boilerplate_description, 23362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 2); 234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_SMI_ARG_CHECKED(flags, 3); 23562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<FeedbackVector> vector(closure->feedback_vector(), isolate); 236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0; 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool enable_mementos = (flags & ObjectLiteral::kDisableMementos) == 0; 238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 23962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FeedbackSlot literals_slot(FeedbackVector::ToSlot(literals_index)); 24062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CHECK(literals_slot.ToInt() < vector->slot_count()); 241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check if boilerplate exists. If not, create it first. 24362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> literal_site(vector->Get(literals_slot), isolate); 244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<AllocationSite> site; 245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<JSObject> boilerplate; 24613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (literal_site->IsUndefined(isolate)) { 247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Object> raw_boilerplate; 248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate, raw_boilerplate, 25062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CreateObjectLiteralBoilerplate(isolate, vector, boilerplate_description, 2513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch should_have_fast_elements)); 252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier boilerplate = Handle<JSObject>::cast(raw_boilerplate); 253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AllocationSiteCreationContext creation_context(isolate); 255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier site = creation_context.EnterNewScope(); 256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RETURN_FAILURE_ON_EXCEPTION( 257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate, JSObject::DeepWalk(boilerplate, &creation_context)); 258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier creation_context.ExitScope(site, boilerplate); 259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Update the functions literal and return the boilerplate. 26162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch vector->Set(literals_slot, *site); 262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier site = Handle<AllocationSite>::cast(literal_site); 264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier boilerplate = 265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<JSObject>(JSObject::cast(site->transition_info()), isolate); 266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllocationSiteUsageContext usage_context(isolate, site, enable_mementos); 269958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier usage_context.EnterNewScope(); 270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MaybeHandle<Object> maybe_copy = 271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier JSObject::DeepCopy(boilerplate, &usage_context); 272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier usage_context.ExitScope(site, boilerplate); 27313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch RETURN_RESULT_OR_FAILURE(isolate, maybe_copy); 274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierMUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite( 27762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Isolate* isolate, Handle<FeedbackVector> vector, FeedbackSlot literals_slot, 27862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<ConstantElementsPair> elements) { 279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check if boilerplate exists. If not, create it first. 28062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> literal_site(vector->Get(literals_slot), isolate); 281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<AllocationSite> site; 28213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (literal_site->IsUndefined(isolate)) { 283958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Object> boilerplate; 284958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSIGN_RETURN_ON_EXCEPTION( 285958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate, boilerplate, 28662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CreateArrayLiteralBoilerplate(isolate, vector, elements), 287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AllocationSite); 288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AllocationSiteCreationContext creation_context(isolate); 290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier site = creation_context.EnterNewScope(); 291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (JSObject::DeepWalk(Handle<JSObject>::cast(boilerplate), 292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier &creation_context).is_null()) { 293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Handle<AllocationSite>::null(); 294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier creation_context.ExitScope(site, Handle<JSObject>::cast(boilerplate)); 296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 29762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch vector->Set(literals_slot, *site); 298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier site = Handle<AllocationSite>::cast(literal_site); 300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return site; 303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 304958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic MaybeHandle<JSObject> CreateArrayLiteralImpl( 30662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Isolate* isolate, Handle<FeedbackVector> vector, FeedbackSlot literals_slot, 30762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<ConstantElementsPair> elements, int flags) { 30862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CHECK(literals_slot.ToInt() < vector->slot_count()); 309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<AllocationSite> site; 310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSIGN_RETURN_ON_EXCEPTION( 311958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate, site, 31262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GetLiteralAllocationSite(isolate, vector, literals_slot, 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); 33462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CONVERT_ARG_HANDLE_CHECKED(ConstantElementsPair, elements, 2); 335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_SMI_ARG_CHECKED(flags, 3); 336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 33762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FeedbackSlot literals_slot(FeedbackVector::ToSlot(literals_index)); 33862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<FeedbackVector> vector(closure->feedback_vector(), isolate); 33913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch RETURN_RESULT_OR_FAILURE( 34062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate, 34162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CreateArrayLiteralImpl(isolate, vector, literals_slot, elements, flags)); 342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_CreateArrayLiteralStubBailout) { 346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(3, args.length()); 348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); 349958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_SMI_ARG_CHECKED(literals_index, 1); 35062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CONVERT_ARG_HANDLE_CHECKED(ConstantElementsPair, elements, 2); 351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 35262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<FeedbackVector> vector(closure->feedback_vector(), isolate); 35362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FeedbackSlot literals_slot(FeedbackVector::ToSlot(literals_index)); 35413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch RETURN_RESULT_OR_FAILURE( 35562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate, CreateArrayLiteralImpl(isolate, vector, literals_slot, elements, 35662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ArrayLiteral::kShallowElements)); 357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 358958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 361