| 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/isolate-inl.h" | 10 #include "src/isolate-inl.h" |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 return isolate->factory()->ObjectLiteralMapFromCache( | 32 return isolate->factory()->ObjectLiteralMapFromCache( |
| 33 context, number_of_properties, is_result_from_cache); | 33 context, number_of_properties, is_result_from_cache); |
| 34 } | 34 } |
| 35 | 35 |
| 36 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( | 36 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( |
| 37 Isolate* isolate, Handle<LiteralsArray> literals, | 37 Isolate* isolate, Handle<LiteralsArray> literals, |
| 38 Handle<FixedArray> constant_properties); | 38 Handle<FixedArray> constant_properties); |
| 39 | 39 |
| 40 MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate( | 40 MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate( |
| 41 Isolate* isolate, Handle<LiteralsArray> literals, | 41 Isolate* isolate, Handle<LiteralsArray> literals, |
| 42 Handle<FixedArray> constant_properties, bool should_have_fast_elements, | 42 Handle<FixedArray> constant_properties, bool should_have_fast_elements) { |
| 43 bool has_function_literal) { | |
| 44 Handle<Context> context = isolate->native_context(); | 43 Handle<Context> context = isolate->native_context(); |
| 45 | 44 |
| 46 // In case we have function literals, we want the object to be in | 45 // In case we have function literals, we want the object to be in |
| 47 // slow properties mode for now. We don't go in the map cache because | 46 // slow properties mode for now. We don't go in the map cache because |
| 48 // maps with constant functions can't be shared if the functions are | 47 // maps with constant functions can't be shared if the functions are |
| 49 // not the same (which is the common case). | 48 // not the same (which is the common case). |
| 50 bool is_result_from_cache = false; | 49 bool is_result_from_cache = false; |
| 51 Handle<Map> map = has_function_literal | 50 Handle<Map> map = ComputeObjectLiteralMap(context, constant_properties, |
| 52 ? Handle<Map>(context->object_function()->initial_map()) | 51 &is_result_from_cache); |
| 53 : ComputeObjectLiteralMap(context, constant_properties, | |
| 54 &is_result_from_cache); | |
| 55 | 52 |
| 56 PretenureFlag pretenure_flag = | 53 PretenureFlag pretenure_flag = |
| 57 isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED; | 54 isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED; |
| 58 | 55 |
| 59 Handle<JSObject> boilerplate = | 56 Handle<JSObject> boilerplate = |
| 60 isolate->factory()->NewJSObjectFromMap(map, pretenure_flag); | 57 isolate->factory()->NewJSObjectFromMap(map, pretenure_flag); |
| 61 | 58 |
| 62 // Normalize the elements of the boilerplate to save space if needed. | 59 // Normalize the elements of the boilerplate to save space if needed. |
| 63 if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate); | 60 if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate); |
| 64 | 61 |
| 65 // Add the constant properties to the boilerplate. | 62 // Add the constant properties to the boilerplate. |
| 66 int length = constant_properties->length(); | 63 int length = constant_properties->length(); |
| 67 bool should_transform = | 64 bool should_transform = |
| 68 !is_result_from_cache && boilerplate->HasFastProperties(); | 65 !is_result_from_cache && boilerplate->HasFastProperties(); |
| 69 bool should_normalize = should_transform || has_function_literal; | 66 bool should_normalize = should_transform; |
| 70 if (should_normalize) { | 67 if (should_normalize) { |
| 71 // TODO(verwaest): We might not want to ever normalize here. | 68 // TODO(verwaest): We might not want to ever normalize here. |
| 72 JSObject::NormalizeProperties(boilerplate, KEEP_INOBJECT_PROPERTIES, | 69 JSObject::NormalizeProperties(boilerplate, KEEP_INOBJECT_PROPERTIES, |
| 73 length / 2, "Boilerplate"); | 70 length / 2, "Boilerplate"); |
| 74 } | 71 } |
| 75 // TODO(verwaest): Support tracking representations in the boilerplate. | 72 // TODO(verwaest): Support tracking representations in the boilerplate. |
| 76 for (int index = 0; index < length; index += 2) { | 73 for (int index = 0; index < length; index += 2) { |
| 77 Handle<Object> key(constant_properties->get(index + 0), isolate); | 74 Handle<Object> key(constant_properties->get(index + 0), isolate); |
| 78 Handle<Object> value(constant_properties->get(index + 1), isolate); | 75 Handle<Object> value(constant_properties->get(index + 1), isolate); |
| 79 if (value->IsFixedArray()) { | 76 if (value->IsFixedArray()) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 97 maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(boilerplate, name, | 94 maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(boilerplate, name, |
| 98 value, NONE); | 95 value, NONE); |
| 99 } | 96 } |
| 100 RETURN_ON_EXCEPTION(isolate, maybe_result, Object); | 97 RETURN_ON_EXCEPTION(isolate, maybe_result, Object); |
| 101 } | 98 } |
| 102 | 99 |
| 103 // Transform to fast properties if necessary. For object literals with | 100 // Transform to fast properties if necessary. For object literals with |
| 104 // containing function literals we defer this operation until after all | 101 // containing function literals we defer this operation until after all |
| 105 // computed properties have been assigned so that we can generate | 102 // computed properties have been assigned so that we can generate |
| 106 // constant function properties. | 103 // constant function properties. |
| 107 if (should_transform && !has_function_literal) { | 104 if (should_transform) { |
| 108 JSObject::MigrateSlowToFast(boilerplate, | 105 JSObject::MigrateSlowToFast(boilerplate, |
| 109 boilerplate->map()->unused_property_fields(), | 106 boilerplate->map()->unused_property_fields(), |
| 110 "FastLiteral"); | 107 "FastLiteral"); |
| 111 } | 108 } |
| 112 return boilerplate; | 109 return boilerplate; |
| 113 } | 110 } |
| 114 | 111 |
| 115 MaybeHandle<Object> Runtime::CreateArrayLiteralBoilerplate( | 112 MaybeHandle<Object> Runtime::CreateArrayLiteralBoilerplate( |
| 116 Isolate* isolate, Handle<LiteralsArray> literals, | 113 Isolate* isolate, Handle<LiteralsArray> literals, |
| 117 Handle<FixedArray> elements) { | 114 Handle<FixedArray> elements) { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 object->set_length(Smi::FromInt(copied_elements_values->length())); | 177 object->set_length(Smi::FromInt(copied_elements_values->length())); |
| 181 | 178 |
| 182 JSObject::ValidateElements(object); | 179 JSObject::ValidateElements(object); |
| 183 return object; | 180 return object; |
| 184 } | 181 } |
| 185 | 182 |
| 186 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( | 183 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( |
| 187 Isolate* isolate, Handle<LiteralsArray> literals, | 184 Isolate* isolate, Handle<LiteralsArray> literals, |
| 188 Handle<FixedArray> array) { | 185 Handle<FixedArray> array) { |
| 189 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); | 186 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); |
| 190 const bool kHasNoFunctionLiteral = false; | |
| 191 switch (CompileTimeValue::GetLiteralType(array)) { | 187 switch (CompileTimeValue::GetLiteralType(array)) { |
| 192 case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS: | 188 case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS: |
| 193 return CreateObjectLiteralBoilerplate(isolate, literals, elements, true, | 189 return CreateObjectLiteralBoilerplate(isolate, literals, elements, true); |
| 194 kHasNoFunctionLiteral); | |
| 195 case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS: | 190 case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS: |
| 196 return CreateObjectLiteralBoilerplate(isolate, literals, elements, false, | 191 return CreateObjectLiteralBoilerplate(isolate, literals, elements, false); |
| 197 kHasNoFunctionLiteral); | |
| 198 case CompileTimeValue::ARRAY_LITERAL: | 192 case CompileTimeValue::ARRAY_LITERAL: |
| 199 return Runtime::CreateArrayLiteralBoilerplate(isolate, literals, | 193 return Runtime::CreateArrayLiteralBoilerplate(isolate, literals, |
| 200 elements); | 194 elements); |
| 201 default: | 195 default: |
| 202 UNREACHABLE(); | 196 UNREACHABLE(); |
| 203 return MaybeHandle<Object>(); | 197 return MaybeHandle<Object>(); |
| 204 } | 198 } |
| 205 } | 199 } |
| 206 | 200 |
| 207 | 201 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 226 | 220 |
| 227 RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) { | 221 RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) { |
| 228 HandleScope scope(isolate); | 222 HandleScope scope(isolate); |
| 229 DCHECK_EQ(4, args.length()); | 223 DCHECK_EQ(4, args.length()); |
| 230 CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); | 224 CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); |
| 231 CONVERT_SMI_ARG_CHECKED(literals_index, 1); | 225 CONVERT_SMI_ARG_CHECKED(literals_index, 1); |
| 232 CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2); | 226 CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2); |
| 233 CONVERT_SMI_ARG_CHECKED(flags, 3); | 227 CONVERT_SMI_ARG_CHECKED(flags, 3); |
| 234 Handle<LiteralsArray> literals(closure->literals(), isolate); | 228 Handle<LiteralsArray> literals(closure->literals(), isolate); |
| 235 bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0; | 229 bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0; |
| 236 bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0; | |
| 237 bool enable_mementos = (flags & ObjectLiteral::kDisableMementos) == 0; | 230 bool enable_mementos = (flags & ObjectLiteral::kDisableMementos) == 0; |
| 238 | 231 |
| 239 RUNTIME_ASSERT(literals_index >= 0 && | 232 RUNTIME_ASSERT(literals_index >= 0 && |
| 240 literals_index < literals->literals_count()); | 233 literals_index < literals->literals_count()); |
| 241 | 234 |
| 242 // Check if boilerplate exists. If not, create it first. | 235 // Check if boilerplate exists. If not, create it first. |
| 243 Handle<Object> literal_site(literals->literal(literals_index), isolate); | 236 Handle<Object> literal_site(literals->literal(literals_index), isolate); |
| 244 Handle<AllocationSite> site; | 237 Handle<AllocationSite> site; |
| 245 Handle<JSObject> boilerplate; | 238 Handle<JSObject> boilerplate; |
| 246 if (*literal_site == isolate->heap()->undefined_value()) { | 239 if (*literal_site == isolate->heap()->undefined_value()) { |
| 247 Handle<Object> raw_boilerplate; | 240 Handle<Object> raw_boilerplate; |
| 248 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 241 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 249 isolate, raw_boilerplate, | 242 isolate, raw_boilerplate, |
| 250 CreateObjectLiteralBoilerplate(isolate, literals, constant_properties, | 243 CreateObjectLiteralBoilerplate(isolate, literals, constant_properties, |
| 251 should_have_fast_elements, | 244 should_have_fast_elements)); |
| 252 has_function_literal)); | |
| 253 boilerplate = Handle<JSObject>::cast(raw_boilerplate); | 245 boilerplate = Handle<JSObject>::cast(raw_boilerplate); |
| 254 | 246 |
| 255 AllocationSiteCreationContext creation_context(isolate); | 247 AllocationSiteCreationContext creation_context(isolate); |
| 256 site = creation_context.EnterNewScope(); | 248 site = creation_context.EnterNewScope(); |
| 257 RETURN_FAILURE_ON_EXCEPTION( | 249 RETURN_FAILURE_ON_EXCEPTION( |
| 258 isolate, JSObject::DeepWalk(boilerplate, &creation_context)); | 250 isolate, JSObject::DeepWalk(boilerplate, &creation_context)); |
| 259 creation_context.ExitScope(site, boilerplate); | 251 creation_context.ExitScope(site, boilerplate); |
| 260 | 252 |
| 261 // Update the functions literal and return the boilerplate. | 253 // Update the functions literal and return the boilerplate. |
| 262 literals->set_literal(literals_index, *site); | 254 literals->set_literal(literals_index, *site); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 Handle<LiteralsArray> literals(closure->literals(), isolate); | 353 Handle<LiteralsArray> literals(closure->literals(), isolate); |
| 362 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 354 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 363 isolate, result, | 355 isolate, result, |
| 364 CreateArrayLiteralImpl(isolate, literals, literals_index, elements, | 356 CreateArrayLiteralImpl(isolate, literals, literals_index, elements, |
| 365 ArrayLiteral::kShallowElements)); | 357 ArrayLiteral::kShallowElements)); |
| 366 return *result; | 358 return *result; |
| 367 } | 359 } |
| 368 | 360 |
| 369 } // namespace internal | 361 } // namespace internal |
| 370 } // namespace v8 | 362 } // namespace v8 |
| OLD | NEW |