| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/runtime/runtime-utils.h" | 5 #include "src/runtime/runtime-utils.h" |
| 6 | 6 |
| 7 #include "src/allocation-site-scopes.h" | 7 #include "src/allocation-site-scopes.h" |
| 8 #include "src/arguments.h" | 8 #include "src/arguments.h" |
| 9 #include "src/ast/ast.h" | 9 #include "src/ast/ast.h" |
| 10 #include "src/ast/compile-time-value.h" | 10 #include "src/ast/compile-time-value.h" |
| 11 #include "src/isolate-inl.h" | 11 #include "src/isolate-inl.h" |
| 12 #include "src/runtime/runtime.h" | 12 #include "src/runtime/runtime.h" |
| 13 | 13 |
| 14 namespace v8 { | 14 namespace v8 { |
| 15 namespace internal { | 15 namespace internal { |
| 16 | 16 |
| 17 static Handle<Map> ComputeObjectLiteralMap( | 17 static Handle<Map> ComputeObjectLiteralMap( |
| 18 Handle<Context> context, | 18 Handle<Context> context, |
| 19 Handle<BoilerplateDescription> boilerplate_description, | 19 Handle<BoilerplateDescription> boilerplate_description, |
| 20 bool* is_result_from_cache) { | 20 bool* is_result_from_cache) { |
| 21 int number_of_properties = boilerplate_description->backing_store_size(); | 21 int number_of_properties = boilerplate_description->backing_store_size(); |
| 22 Isolate* isolate = context->GetIsolate(); | 22 Isolate* isolate = context->GetIsolate(); |
| 23 return isolate->factory()->ObjectLiteralMapFromCache( | 23 return isolate->factory()->ObjectLiteralMapFromCache( |
| 24 context, number_of_properties, is_result_from_cache); | 24 context, number_of_properties, is_result_from_cache); |
| 25 } | 25 } |
| 26 | 26 |
| 27 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( | 27 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( |
| 28 Isolate* isolate, Handle<LiteralsArray> literals, | 28 Isolate* isolate, Handle<TypeFeedbackVector> vector, |
| 29 Handle<BoilerplateDescription> boilerplate_description); | 29 Handle<BoilerplateDescription> boilerplate_description); |
| 30 | 30 |
| 31 MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate( | 31 MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate( |
| 32 Isolate* isolate, Handle<LiteralsArray> literals, | 32 Isolate* isolate, Handle<TypeFeedbackVector> vector, |
| 33 Handle<BoilerplateDescription> boilerplate_description, | 33 Handle<BoilerplateDescription> boilerplate_description, |
| 34 bool should_have_fast_elements) { | 34 bool should_have_fast_elements) { |
| 35 Handle<Context> context = isolate->native_context(); | 35 Handle<Context> context = isolate->native_context(); |
| 36 | 36 |
| 37 // In case we have function literals, we want the object to be in | 37 // In case we have function literals, we want the object to be in |
| 38 // slow properties mode for now. We don't go in the map cache because | 38 // slow properties mode for now. We don't go in the map cache because |
| 39 // maps with constant functions can't be shared if the functions are | 39 // maps with constant functions can't be shared if the functions are |
| 40 // not the same (which is the common case). | 40 // not the same (which is the common case). |
| 41 bool is_result_from_cache = false; | 41 bool is_result_from_cache = false; |
| 42 Handle<Map> map = ComputeObjectLiteralMap(context, boilerplate_description, | 42 Handle<Map> map = ComputeObjectLiteralMap(context, boilerplate_description, |
| 43 &is_result_from_cache); | 43 &is_result_from_cache); |
| 44 | 44 |
| 45 PretenureFlag pretenure_flag = | 45 PretenureFlag pretenure_flag = |
| 46 isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED; | 46 isolate->heap()->InNewSpace(*vector) ? NOT_TENURED : TENURED; |
| 47 | 47 |
| 48 Handle<JSObject> boilerplate = | 48 Handle<JSObject> boilerplate = |
| 49 isolate->factory()->NewJSObjectFromMap(map, pretenure_flag); | 49 isolate->factory()->NewJSObjectFromMap(map, pretenure_flag); |
| 50 | 50 |
| 51 // Normalize the elements of the boilerplate to save space if needed. | 51 // Normalize the elements of the boilerplate to save space if needed. |
| 52 if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate); | 52 if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate); |
| 53 | 53 |
| 54 // Add the constant properties to the boilerplate. | 54 // Add the constant properties to the boilerplate. |
| 55 int length = boilerplate_description->size(); | 55 int length = boilerplate_description->size(); |
| 56 bool should_transform = | 56 bool should_transform = |
| 57 !is_result_from_cache && boilerplate->HasFastProperties(); | 57 !is_result_from_cache && boilerplate->HasFastProperties(); |
| 58 bool should_normalize = should_transform; | 58 bool should_normalize = should_transform; |
| 59 if (should_normalize) { | 59 if (should_normalize) { |
| 60 // TODO(verwaest): We might not want to ever normalize here. | 60 // TODO(verwaest): We might not want to ever normalize here. |
| 61 JSObject::NormalizeProperties(boilerplate, KEEP_INOBJECT_PROPERTIES, length, | 61 JSObject::NormalizeProperties(boilerplate, KEEP_INOBJECT_PROPERTIES, length, |
| 62 "Boilerplate"); | 62 "Boilerplate"); |
| 63 } | 63 } |
| 64 // TODO(verwaest): Support tracking representations in the boilerplate. | 64 // TODO(verwaest): Support tracking representations in the boilerplate. |
| 65 for (int index = 0; index < length; index++) { | 65 for (int index = 0; index < length; index++) { |
| 66 Handle<Object> key(boilerplate_description->name(index), isolate); | 66 Handle<Object> key(boilerplate_description->name(index), isolate); |
| 67 Handle<Object> value(boilerplate_description->value(index), isolate); | 67 Handle<Object> value(boilerplate_description->value(index), isolate); |
| 68 if (value->IsBoilerplateDescription()) { | 68 if (value->IsBoilerplateDescription()) { |
| 69 // The value contains the boilerplate properties of a | 69 // The value contains the boilerplate properties of a |
| 70 // simple object or array literal. | 70 // simple object or array literal. |
| 71 Handle<BoilerplateDescription> boilerplate = | 71 Handle<BoilerplateDescription> boilerplate = |
| 72 Handle<BoilerplateDescription>::cast(value); | 72 Handle<BoilerplateDescription>::cast(value); |
| 73 ASSIGN_RETURN_ON_EXCEPTION( | 73 ASSIGN_RETURN_ON_EXCEPTION( |
| 74 isolate, value, | 74 isolate, value, |
| 75 CreateLiteralBoilerplate(isolate, literals, boilerplate), Object); | 75 CreateLiteralBoilerplate(isolate, vector, boilerplate), Object); |
| 76 } | 76 } |
| 77 MaybeHandle<Object> maybe_result; | 77 MaybeHandle<Object> maybe_result; |
| 78 uint32_t element_index = 0; | 78 uint32_t element_index = 0; |
| 79 if (key->ToArrayIndex(&element_index)) { | 79 if (key->ToArrayIndex(&element_index)) { |
| 80 // Array index (uint32). | 80 // Array index (uint32). |
| 81 if (value->IsUninitialized(isolate)) { | 81 if (value->IsUninitialized(isolate)) { |
| 82 value = handle(Smi::kZero, isolate); | 82 value = handle(Smi::kZero, isolate); |
| 83 } | 83 } |
| 84 maybe_result = JSObject::SetOwnElementIgnoreAttributes( | 84 maybe_result = JSObject::SetOwnElementIgnoreAttributes( |
| 85 boilerplate, element_index, value, NONE); | 85 boilerplate, element_index, value, NONE); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 98 // constant function properties. | 98 // constant function properties. |
| 99 if (should_transform) { | 99 if (should_transform) { |
| 100 JSObject::MigrateSlowToFast(boilerplate, | 100 JSObject::MigrateSlowToFast(boilerplate, |
| 101 boilerplate->map()->unused_property_fields(), | 101 boilerplate->map()->unused_property_fields(), |
| 102 "FastLiteral"); | 102 "FastLiteral"); |
| 103 } | 103 } |
| 104 return boilerplate; | 104 return boilerplate; |
| 105 } | 105 } |
| 106 | 106 |
| 107 static MaybeHandle<Object> CreateArrayLiteralBoilerplate( | 107 static MaybeHandle<Object> CreateArrayLiteralBoilerplate( |
| 108 Isolate* isolate, Handle<LiteralsArray> literals, | 108 Isolate* isolate, Handle<TypeFeedbackVector> vector, |
| 109 Handle<ConstantElementsPair> elements) { | 109 Handle<ConstantElementsPair> elements) { |
| 110 // Create the JSArray. | 110 // Create the JSArray. |
| 111 Handle<JSFunction> constructor = isolate->array_function(); | 111 Handle<JSFunction> constructor = isolate->array_function(); |
| 112 | 112 |
| 113 PretenureFlag pretenure_flag = | 113 PretenureFlag pretenure_flag = |
| 114 isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED; | 114 isolate->heap()->InNewSpace(*vector) ? NOT_TENURED : TENURED; |
| 115 | 115 |
| 116 Handle<JSArray> object = Handle<JSArray>::cast( | 116 Handle<JSArray> object = Handle<JSArray>::cast( |
| 117 isolate->factory()->NewJSObject(constructor, pretenure_flag)); | 117 isolate->factory()->NewJSObject(constructor, pretenure_flag)); |
| 118 | 118 |
| 119 ElementsKind constant_elements_kind = | 119 ElementsKind constant_elements_kind = |
| 120 static_cast<ElementsKind>(elements->elements_kind()); | 120 static_cast<ElementsKind>(elements->elements_kind()); |
| 121 Handle<FixedArrayBase> constant_elements_values(elements->constant_values()); | 121 Handle<FixedArrayBase> constant_elements_values(elements->constant_values()); |
| 122 | 122 |
| 123 { | 123 { |
| 124 DisallowHeapAllocation no_gc; | 124 DisallowHeapAllocation no_gc; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 155 FOR_WITH_HANDLE_SCOPE( | 155 FOR_WITH_HANDLE_SCOPE( |
| 156 isolate, int, i = 0, i, i < fixed_array_values->length(), i++, { | 156 isolate, int, i = 0, i, i < fixed_array_values->length(), i++, { |
| 157 if (fixed_array_values->get(i)->IsBoilerplateDescription()) { | 157 if (fixed_array_values->get(i)->IsBoilerplateDescription()) { |
| 158 // The value contains the boilerplate properties of a | 158 // The value contains the boilerplate properties of a |
| 159 // simple object or array literal. | 159 // simple object or array literal. |
| 160 Handle<BoilerplateDescription> boilerplate( | 160 Handle<BoilerplateDescription> boilerplate( |
| 161 BoilerplateDescription::cast(fixed_array_values->get(i))); | 161 BoilerplateDescription::cast(fixed_array_values->get(i))); |
| 162 Handle<Object> result; | 162 Handle<Object> result; |
| 163 ASSIGN_RETURN_ON_EXCEPTION( | 163 ASSIGN_RETURN_ON_EXCEPTION( |
| 164 isolate, result, | 164 isolate, result, |
| 165 CreateLiteralBoilerplate(isolate, literals, boilerplate), | 165 CreateLiteralBoilerplate(isolate, vector, boilerplate), |
| 166 Object); | 166 Object); |
| 167 fixed_array_values_copy->set(i, *result); | 167 fixed_array_values_copy->set(i, *result); |
| 168 } | 168 } |
| 169 }); | 169 }); |
| 170 } | 170 } |
| 171 } | 171 } |
| 172 object->set_elements(*copied_elements_values); | 172 object->set_elements(*copied_elements_values); |
| 173 object->set_length(Smi::FromInt(copied_elements_values->length())); | 173 object->set_length(Smi::FromInt(copied_elements_values->length())); |
| 174 | 174 |
| 175 JSObject::ValidateElements(object); | 175 JSObject::ValidateElements(object); |
| 176 return object; | 176 return object; |
| 177 } | 177 } |
| 178 | 178 |
| 179 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( | 179 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( |
| 180 Isolate* isolate, Handle<LiteralsArray> literals, | 180 Isolate* isolate, Handle<TypeFeedbackVector> vector, |
| 181 Handle<BoilerplateDescription> array) { | 181 Handle<BoilerplateDescription> array) { |
| 182 Handle<HeapObject> elements = CompileTimeValue::GetElements(array); | 182 Handle<HeapObject> elements = CompileTimeValue::GetElements(array); |
| 183 switch (CompileTimeValue::GetLiteralType(array)) { | 183 switch (CompileTimeValue::GetLiteralType(array)) { |
| 184 case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS: { | 184 case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS: { |
| 185 Handle<BoilerplateDescription> props = | 185 Handle<BoilerplateDescription> props = |
| 186 Handle<BoilerplateDescription>::cast(elements); | 186 Handle<BoilerplateDescription>::cast(elements); |
| 187 return CreateObjectLiteralBoilerplate(isolate, literals, props, true); | 187 return CreateObjectLiteralBoilerplate(isolate, vector, props, true); |
| 188 } | 188 } |
| 189 case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS: { | 189 case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS: { |
| 190 Handle<BoilerplateDescription> props = | 190 Handle<BoilerplateDescription> props = |
| 191 Handle<BoilerplateDescription>::cast(elements); | 191 Handle<BoilerplateDescription>::cast(elements); |
| 192 return CreateObjectLiteralBoilerplate(isolate, literals, props, false); | 192 return CreateObjectLiteralBoilerplate(isolate, vector, props, false); |
| 193 } | 193 } |
| 194 case CompileTimeValue::ARRAY_LITERAL: { | 194 case CompileTimeValue::ARRAY_LITERAL: { |
| 195 Handle<ConstantElementsPair> elems = | 195 Handle<ConstantElementsPair> elems = |
| 196 Handle<ConstantElementsPair>::cast(elements); | 196 Handle<ConstantElementsPair>::cast(elements); |
| 197 return CreateArrayLiteralBoilerplate(isolate, literals, elems); | 197 return CreateArrayLiteralBoilerplate(isolate, vector, elems); |
| 198 } | 198 } |
| 199 default: | 199 default: |
| 200 UNREACHABLE(); | 200 UNREACHABLE(); |
| 201 return MaybeHandle<Object>(); | 201 return MaybeHandle<Object>(); |
| 202 } | 202 } |
| 203 } | 203 } |
| 204 | 204 |
| 205 | 205 |
| 206 RUNTIME_FUNCTION(Runtime_CreateRegExpLiteral) { | 206 RUNTIME_FUNCTION(Runtime_CreateRegExpLiteral) { |
| 207 HandleScope scope(isolate); | 207 HandleScope scope(isolate); |
| 208 DCHECK_EQ(4, args.length()); | 208 DCHECK_EQ(4, args.length()); |
| 209 CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); | 209 CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); |
| 210 CONVERT_SMI_ARG_CHECKED(index, 1); | 210 CONVERT_SMI_ARG_CHECKED(index, 1); |
| 211 CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2); | 211 CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2); |
| 212 CONVERT_SMI_ARG_CHECKED(flags, 3); | 212 CONVERT_SMI_ARG_CHECKED(flags, 3); |
| 213 FeedbackVectorSlot literal_slot(TypeFeedbackVector::ToSlot(index)); |
| 213 | 214 |
| 214 // Check if boilerplate exists. If not, create it first. | 215 // Check if boilerplate exists. If not, create it first. |
| 215 Handle<Object> boilerplate(closure->literals()->literal(index), isolate); | 216 Handle<Object> boilerplate(closure->feedback_vector()->Get(literal_slot), |
| 217 isolate); |
| 216 if (boilerplate->IsUndefined(isolate)) { | 218 if (boilerplate->IsUndefined(isolate)) { |
| 217 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 219 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 218 isolate, boilerplate, JSRegExp::New(pattern, JSRegExp::Flags(flags))); | 220 isolate, boilerplate, JSRegExp::New(pattern, JSRegExp::Flags(flags))); |
| 219 closure->literals()->set_literal(index, *boilerplate); | 221 closure->feedback_vector()->Set(literal_slot, *boilerplate); |
| 220 } | 222 } |
| 221 return *JSRegExp::Copy(Handle<JSRegExp>::cast(boilerplate)); | 223 return *JSRegExp::Copy(Handle<JSRegExp>::cast(boilerplate)); |
| 222 } | 224 } |
| 223 | 225 |
| 224 | 226 |
| 225 RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) { | 227 RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) { |
| 226 HandleScope scope(isolate); | 228 HandleScope scope(isolate); |
| 227 DCHECK_EQ(4, args.length()); | 229 DCHECK_EQ(4, args.length()); |
| 228 CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); | 230 CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); |
| 229 CONVERT_SMI_ARG_CHECKED(literals_index, 1); | 231 CONVERT_SMI_ARG_CHECKED(literals_index, 1); |
| 230 CONVERT_ARG_HANDLE_CHECKED(BoilerplateDescription, boilerplate_description, | 232 CONVERT_ARG_HANDLE_CHECKED(BoilerplateDescription, boilerplate_description, |
| 231 2); | 233 2); |
| 232 CONVERT_SMI_ARG_CHECKED(flags, 3); | 234 CONVERT_SMI_ARG_CHECKED(flags, 3); |
| 233 Handle<LiteralsArray> literals(closure->literals(), isolate); | 235 Handle<TypeFeedbackVector> vector(closure->feedback_vector(), isolate); |
| 234 bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0; | 236 bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0; |
| 235 bool enable_mementos = (flags & ObjectLiteral::kDisableMementos) == 0; | 237 bool enable_mementos = (flags & ObjectLiteral::kDisableMementos) == 0; |
| 236 | 238 |
| 237 CHECK(literals_index >= 0); | 239 FeedbackVectorSlot literals_slot(TypeFeedbackVector::ToSlot(literals_index)); |
| 238 CHECK(literals_index < literals->literals_count()); | 240 CHECK(literals_slot.ToInt() < vector->slot_count()); |
| 239 | 241 |
| 240 // Check if boilerplate exists. If not, create it first. | 242 // Check if boilerplate exists. If not, create it first. |
| 241 Handle<Object> literal_site(literals->literal(literals_index), isolate); | 243 Handle<Object> literal_site(vector->Get(literals_slot), isolate); |
| 242 Handle<AllocationSite> site; | 244 Handle<AllocationSite> site; |
| 243 Handle<JSObject> boilerplate; | 245 Handle<JSObject> boilerplate; |
| 244 if (literal_site->IsUndefined(isolate)) { | 246 if (literal_site->IsUndefined(isolate)) { |
| 245 Handle<Object> raw_boilerplate; | 247 Handle<Object> raw_boilerplate; |
| 246 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 248 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 247 isolate, raw_boilerplate, | 249 isolate, raw_boilerplate, |
| 248 CreateObjectLiteralBoilerplate(isolate, literals, | 250 CreateObjectLiteralBoilerplate(isolate, vector, boilerplate_description, |
| 249 boilerplate_description, | |
| 250 should_have_fast_elements)); | 251 should_have_fast_elements)); |
| 251 boilerplate = Handle<JSObject>::cast(raw_boilerplate); | 252 boilerplate = Handle<JSObject>::cast(raw_boilerplate); |
| 252 | 253 |
| 253 AllocationSiteCreationContext creation_context(isolate); | 254 AllocationSiteCreationContext creation_context(isolate); |
| 254 site = creation_context.EnterNewScope(); | 255 site = creation_context.EnterNewScope(); |
| 255 RETURN_FAILURE_ON_EXCEPTION( | 256 RETURN_FAILURE_ON_EXCEPTION( |
| 256 isolate, JSObject::DeepWalk(boilerplate, &creation_context)); | 257 isolate, JSObject::DeepWalk(boilerplate, &creation_context)); |
| 257 creation_context.ExitScope(site, boilerplate); | 258 creation_context.ExitScope(site, boilerplate); |
| 258 | 259 |
| 259 // Update the functions literal and return the boilerplate. | 260 // Update the functions literal and return the boilerplate. |
| 260 literals->set_literal(literals_index, *site); | 261 vector->Set(literals_slot, *site); |
| 261 } else { | 262 } else { |
| 262 site = Handle<AllocationSite>::cast(literal_site); | 263 site = Handle<AllocationSite>::cast(literal_site); |
| 263 boilerplate = | 264 boilerplate = |
| 264 Handle<JSObject>(JSObject::cast(site->transition_info()), isolate); | 265 Handle<JSObject>(JSObject::cast(site->transition_info()), isolate); |
| 265 } | 266 } |
| 266 | 267 |
| 267 AllocationSiteUsageContext usage_context(isolate, site, enable_mementos); | 268 AllocationSiteUsageContext usage_context(isolate, site, enable_mementos); |
| 268 usage_context.EnterNewScope(); | 269 usage_context.EnterNewScope(); |
| 269 MaybeHandle<Object> maybe_copy = | 270 MaybeHandle<Object> maybe_copy = |
| 270 JSObject::DeepCopy(boilerplate, &usage_context); | 271 JSObject::DeepCopy(boilerplate, &usage_context); |
| 271 usage_context.ExitScope(site, boilerplate); | 272 usage_context.ExitScope(site, boilerplate); |
| 272 RETURN_RESULT_OR_FAILURE(isolate, maybe_copy); | 273 RETURN_RESULT_OR_FAILURE(isolate, maybe_copy); |
| 273 } | 274 } |
| 274 | 275 |
| 275 MUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite( | 276 MUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite( |
| 276 Isolate* isolate, Handle<LiteralsArray> literals, int literals_index, | 277 Isolate* isolate, Handle<TypeFeedbackVector> vector, |
| 277 Handle<ConstantElementsPair> elements) { | 278 FeedbackVectorSlot literals_slot, Handle<ConstantElementsPair> elements) { |
| 278 // Check if boilerplate exists. If not, create it first. | 279 // Check if boilerplate exists. If not, create it first. |
| 279 Handle<Object> literal_site(literals->literal(literals_index), isolate); | 280 Handle<Object> literal_site(vector->Get(literals_slot), isolate); |
| 280 Handle<AllocationSite> site; | 281 Handle<AllocationSite> site; |
| 281 if (literal_site->IsUndefined(isolate)) { | 282 if (literal_site->IsUndefined(isolate)) { |
| 282 Handle<Object> boilerplate; | 283 Handle<Object> boilerplate; |
| 283 ASSIGN_RETURN_ON_EXCEPTION( | 284 ASSIGN_RETURN_ON_EXCEPTION( |
| 284 isolate, boilerplate, | 285 isolate, boilerplate, |
| 285 CreateArrayLiteralBoilerplate(isolate, literals, elements), | 286 CreateArrayLiteralBoilerplate(isolate, vector, elements), |
| 286 AllocationSite); | 287 AllocationSite); |
| 287 | 288 |
| 288 AllocationSiteCreationContext creation_context(isolate); | 289 AllocationSiteCreationContext creation_context(isolate); |
| 289 site = creation_context.EnterNewScope(); | 290 site = creation_context.EnterNewScope(); |
| 290 if (JSObject::DeepWalk(Handle<JSObject>::cast(boilerplate), | 291 if (JSObject::DeepWalk(Handle<JSObject>::cast(boilerplate), |
| 291 &creation_context).is_null()) { | 292 &creation_context).is_null()) { |
| 292 return Handle<AllocationSite>::null(); | 293 return Handle<AllocationSite>::null(); |
| 293 } | 294 } |
| 294 creation_context.ExitScope(site, Handle<JSObject>::cast(boilerplate)); | 295 creation_context.ExitScope(site, Handle<JSObject>::cast(boilerplate)); |
| 295 | 296 |
| 296 literals->set_literal(literals_index, *site); | 297 vector->Set(literals_slot, *site); |
| 297 } else { | 298 } else { |
| 298 site = Handle<AllocationSite>::cast(literal_site); | 299 site = Handle<AllocationSite>::cast(literal_site); |
| 299 } | 300 } |
| 300 | 301 |
| 301 return site; | 302 return site; |
| 302 } | 303 } |
| 303 | 304 |
| 304 static MaybeHandle<JSObject> CreateArrayLiteralImpl( | 305 static MaybeHandle<JSObject> CreateArrayLiteralImpl( |
| 305 Isolate* isolate, Handle<LiteralsArray> literals, int literals_index, | 306 Isolate* isolate, Handle<TypeFeedbackVector> vector, |
| 306 Handle<ConstantElementsPair> elements, int flags) { | 307 FeedbackVectorSlot literals_slot, Handle<ConstantElementsPair> elements, |
| 307 CHECK(literals_index >= 0 && literals_index < literals->literals_count()); | 308 int flags) { |
| 309 CHECK(literals_slot.ToInt() < vector->slot_count()); |
| 308 Handle<AllocationSite> site; | 310 Handle<AllocationSite> site; |
| 309 ASSIGN_RETURN_ON_EXCEPTION( | 311 ASSIGN_RETURN_ON_EXCEPTION( |
| 310 isolate, site, | 312 isolate, site, |
| 311 GetLiteralAllocationSite(isolate, literals, literals_index, elements), | 313 GetLiteralAllocationSite(isolate, vector, literals_slot, elements), |
| 312 JSObject); | 314 JSObject); |
| 313 | 315 |
| 314 bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0; | 316 bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0; |
| 315 Handle<JSObject> boilerplate(JSObject::cast(site->transition_info())); | 317 Handle<JSObject> boilerplate(JSObject::cast(site->transition_info())); |
| 316 AllocationSiteUsageContext usage_context(isolate, site, enable_mementos); | 318 AllocationSiteUsageContext usage_context(isolate, site, enable_mementos); |
| 317 usage_context.EnterNewScope(); | 319 usage_context.EnterNewScope(); |
| 318 JSObject::DeepCopyHints hints = (flags & ArrayLiteral::kShallowElements) == 0 | 320 JSObject::DeepCopyHints hints = (flags & ArrayLiteral::kShallowElements) == 0 |
| 319 ? JSObject::kNoHints | 321 ? JSObject::kNoHints |
| 320 : JSObject::kObjectIsShallow; | 322 : JSObject::kObjectIsShallow; |
| 321 MaybeHandle<JSObject> copy = | 323 MaybeHandle<JSObject> copy = |
| 322 JSObject::DeepCopy(boilerplate, &usage_context, hints); | 324 JSObject::DeepCopy(boilerplate, &usage_context, hints); |
| 323 usage_context.ExitScope(site, boilerplate); | 325 usage_context.ExitScope(site, boilerplate); |
| 324 return copy; | 326 return copy; |
| 325 } | 327 } |
| 326 | 328 |
| 327 | 329 |
| 328 RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) { | 330 RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) { |
| 329 HandleScope scope(isolate); | 331 HandleScope scope(isolate); |
| 330 DCHECK_EQ(4, args.length()); | 332 DCHECK_EQ(4, args.length()); |
| 331 CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); | 333 CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); |
| 332 CONVERT_SMI_ARG_CHECKED(literals_index, 1); | 334 CONVERT_SMI_ARG_CHECKED(literals_index, 1); |
| 333 CONVERT_ARG_HANDLE_CHECKED(ConstantElementsPair, elements, 2); | 335 CONVERT_ARG_HANDLE_CHECKED(ConstantElementsPair, elements, 2); |
| 334 CONVERT_SMI_ARG_CHECKED(flags, 3); | 336 CONVERT_SMI_ARG_CHECKED(flags, 3); |
| 335 | 337 |
| 336 Handle<LiteralsArray> literals(closure->literals(), isolate); | 338 FeedbackVectorSlot literals_slot(TypeFeedbackVector::ToSlot(literals_index)); |
| 339 Handle<TypeFeedbackVector> vector(closure->feedback_vector(), isolate); |
| 337 RETURN_RESULT_OR_FAILURE( | 340 RETURN_RESULT_OR_FAILURE( |
| 338 isolate, CreateArrayLiteralImpl(isolate, literals, literals_index, | 341 isolate, |
| 339 elements, flags)); | 342 CreateArrayLiteralImpl(isolate, vector, literals_slot, elements, flags)); |
| 340 } | 343 } |
| 341 | 344 |
| 342 | 345 |
| 343 RUNTIME_FUNCTION(Runtime_CreateArrayLiteralStubBailout) { | 346 RUNTIME_FUNCTION(Runtime_CreateArrayLiteralStubBailout) { |
| 344 HandleScope scope(isolate); | 347 HandleScope scope(isolate); |
| 345 DCHECK_EQ(3, args.length()); | 348 DCHECK_EQ(3, args.length()); |
| 346 CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); | 349 CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); |
| 347 CONVERT_SMI_ARG_CHECKED(literals_index, 1); | 350 CONVERT_SMI_ARG_CHECKED(literals_index, 1); |
| 348 CONVERT_ARG_HANDLE_CHECKED(ConstantElementsPair, elements, 2); | 351 CONVERT_ARG_HANDLE_CHECKED(ConstantElementsPair, elements, 2); |
| 349 | 352 |
| 350 Handle<LiteralsArray> literals(closure->literals(), isolate); | 353 Handle<TypeFeedbackVector> vector(closure->feedback_vector(), isolate); |
| 354 FeedbackVectorSlot literals_slot(TypeFeedbackVector::ToSlot(literals_index)); |
| 351 RETURN_RESULT_OR_FAILURE( | 355 RETURN_RESULT_OR_FAILURE( |
| 352 isolate, | 356 isolate, CreateArrayLiteralImpl(isolate, vector, literals_slot, elements, |
| 353 CreateArrayLiteralImpl(isolate, literals, literals_index, elements, | 357 ArrayLiteral::kShallowElements)); |
| 354 ArrayLiteral::kShallowElements)); | |
| 355 } | 358 } |
| 356 | 359 |
| 357 } // namespace internal | 360 } // namespace internal |
| 358 } // namespace v8 | 361 } // namespace v8 |
| OLD | NEW |