Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/runtime/runtime-literals.cc

Issue 2632503003: [runtime] Allocate space for computed property names (Closed)
Patch Set: Comments and reorder. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parsing/preparser.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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, Handle<FixedArray> constant_properties, 18 Handle<Context> context,
19 Handle<BoilerplateDescription> boilerplate_description,
19 bool* is_result_from_cache) { 20 bool* is_result_from_cache) {
20 int properties_length = constant_properties->length(); 21 int number_of_properties = boilerplate_description->backing_store_size();
21 int number_of_properties = properties_length / 2;
22 22
23 for (int p = 0; p != properties_length; p += 2) { 23 for (int index = 0; index < boilerplate_description->size(); index++) {
24 Object* key = constant_properties->get(p); 24 Object* key = boilerplate_description->name(index);
25 uint32_t element_index = 0; 25 uint32_t element_index = 0;
26 if (key->ToArrayIndex(&element_index)) { 26 if (key->ToArrayIndex(&element_index)) {
27 // An index key does not require space in the property backing store. 27 // An index key does not require space in the property backing store.
28 number_of_properties--; 28 number_of_properties--;
29 } 29 }
30 } 30 }
31 Isolate* isolate = context->GetIsolate(); 31 Isolate* isolate = context->GetIsolate();
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<BoilerplateDescription> boilerplate_description);
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<BoilerplateDescription> boilerplate_description,
43 bool should_have_fast_elements) {
43 Handle<Context> context = isolate->native_context(); 44 Handle<Context> context = isolate->native_context();
44 45
45 // In case we have function literals, we want the object to be in 46 // In case we have function literals, we want the object to be in
46 // slow properties mode for now. We don't go in the map cache because 47 // slow properties mode for now. We don't go in the map cache because
47 // maps with constant functions can't be shared if the functions are 48 // maps with constant functions can't be shared if the functions are
48 // not the same (which is the common case). 49 // not the same (which is the common case).
49 bool is_result_from_cache = false; 50 bool is_result_from_cache = false;
50 Handle<Map> map = ComputeObjectLiteralMap(context, constant_properties, 51 Handle<Map> map = ComputeObjectLiteralMap(context, boilerplate_description,
51 &is_result_from_cache); 52 &is_result_from_cache);
52 53
53 PretenureFlag pretenure_flag = 54 PretenureFlag pretenure_flag =
54 isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED; 55 isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED;
55 56
56 Handle<JSObject> boilerplate = 57 Handle<JSObject> boilerplate =
57 isolate->factory()->NewJSObjectFromMap(map, pretenure_flag); 58 isolate->factory()->NewJSObjectFromMap(map, pretenure_flag);
58 59
59 // Normalize the elements of the boilerplate to save space if needed. 60 // Normalize the elements of the boilerplate to save space if needed.
60 if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate); 61 if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate);
61 62
62 // Add the constant properties to the boilerplate. 63 // Add the constant properties to the boilerplate.
63 int length = constant_properties->length(); 64 int length = boilerplate_description->size();
64 bool should_transform = 65 bool should_transform =
65 !is_result_from_cache && boilerplate->HasFastProperties(); 66 !is_result_from_cache && boilerplate->HasFastProperties();
66 bool should_normalize = should_transform; 67 bool should_normalize = should_transform;
67 if (should_normalize) { 68 if (should_normalize) {
68 // TODO(verwaest): We might not want to ever normalize here. 69 // TODO(verwaest): We might not want to ever normalize here.
69 JSObject::NormalizeProperties(boilerplate, KEEP_INOBJECT_PROPERTIES, 70 JSObject::NormalizeProperties(boilerplate, KEEP_INOBJECT_PROPERTIES, length,
70 length / 2, "Boilerplate"); 71 "Boilerplate");
71 } 72 }
72 // TODO(verwaest): Support tracking representations in the boilerplate. 73 // TODO(verwaest): Support tracking representations in the boilerplate.
73 for (int index = 0; index < length; index += 2) { 74 for (int index = 0; index < length; index++) {
74 Handle<Object> key(constant_properties->get(index + 0), isolate); 75 Handle<Object> key(boilerplate_description->name(index), isolate);
75 Handle<Object> value(constant_properties->get(index + 1), isolate); 76 Handle<Object> value(boilerplate_description->value(index), isolate);
76 if (value->IsFixedArray()) { 77 if (value->IsBoilerplateDescription()) {
77 // The value contains the constant_properties of a 78 // The value contains the boilerplate properties of a
78 // simple object or array literal. 79 // simple object or array literal.
79 Handle<FixedArray> array = Handle<FixedArray>::cast(value); 80 Handle<BoilerplateDescription> boilerplate =
81 Handle<BoilerplateDescription>::cast(value);
80 ASSIGN_RETURN_ON_EXCEPTION( 82 ASSIGN_RETURN_ON_EXCEPTION(
81 isolate, value, CreateLiteralBoilerplate(isolate, literals, array), 83 isolate, value,
82 Object); 84 CreateLiteralBoilerplate(isolate, literals, boilerplate), Object);
83 } 85 }
84 MaybeHandle<Object> maybe_result; 86 MaybeHandle<Object> maybe_result;
85 uint32_t element_index = 0; 87 uint32_t element_index = 0;
86 if (key->ToArrayIndex(&element_index)) { 88 if (key->ToArrayIndex(&element_index)) {
87 // Array index (uint32). 89 // Array index (uint32).
88 if (value->IsUninitialized(isolate)) { 90 if (value->IsUninitialized(isolate)) {
89 value = handle(Smi::kZero, isolate); 91 value = handle(Smi::kZero, isolate);
90 } 92 }
91 maybe_result = JSObject::SetOwnElementIgnoreAttributes( 93 maybe_result = JSObject::SetOwnElementIgnoreAttributes(
92 boilerplate, element_index, value, NONE); 94 boilerplate, element_index, value, NONE);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 } 156 }
155 #endif 157 #endif
156 } else { 158 } else {
157 Handle<FixedArray> fixed_array_values = 159 Handle<FixedArray> fixed_array_values =
158 Handle<FixedArray>::cast(constant_elements_values); 160 Handle<FixedArray>::cast(constant_elements_values);
159 Handle<FixedArray> fixed_array_values_copy = 161 Handle<FixedArray> fixed_array_values_copy =
160 isolate->factory()->CopyFixedArray(fixed_array_values); 162 isolate->factory()->CopyFixedArray(fixed_array_values);
161 copied_elements_values = fixed_array_values_copy; 163 copied_elements_values = fixed_array_values_copy;
162 FOR_WITH_HANDLE_SCOPE( 164 FOR_WITH_HANDLE_SCOPE(
163 isolate, int, i = 0, i, i < fixed_array_values->length(), i++, { 165 isolate, int, i = 0, i, i < fixed_array_values->length(), i++, {
164 if (fixed_array_values->get(i)->IsFixedArray()) { 166 if (fixed_array_values->get(i)->IsBoilerplateDescription()) {
165 // The value contains the constant_properties of a 167 // The value contains the boilerplate properties of a
166 // simple object or array literal. 168 // simple object or array literal.
167 Handle<FixedArray> fa( 169 Handle<BoilerplateDescription> boilerplate(
168 FixedArray::cast(fixed_array_values->get(i))); 170 BoilerplateDescription::cast(fixed_array_values->get(i)));
169 Handle<Object> result; 171 Handle<Object> result;
170 ASSIGN_RETURN_ON_EXCEPTION( 172 ASSIGN_RETURN_ON_EXCEPTION(
171 isolate, result, 173 isolate, result,
172 CreateLiteralBoilerplate(isolate, literals, fa), Object); 174 CreateLiteralBoilerplate(isolate, literals, boilerplate),
175 Object);
173 fixed_array_values_copy->set(i, *result); 176 fixed_array_values_copy->set(i, *result);
174 } 177 }
175 }); 178 });
176 } 179 }
177 } 180 }
178 object->set_elements(*copied_elements_values); 181 object->set_elements(*copied_elements_values);
179 object->set_length(Smi::FromInt(copied_elements_values->length())); 182 object->set_length(Smi::FromInt(copied_elements_values->length()));
180 183
181 JSObject::ValidateElements(object); 184 JSObject::ValidateElements(object);
182 return object; 185 return object;
183 } 186 }
184 187
185 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( 188 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
186 Isolate* isolate, Handle<LiteralsArray> literals, 189 Isolate* isolate, Handle<LiteralsArray> literals,
187 Handle<FixedArray> array) { 190 Handle<BoilerplateDescription> array) {
188 Handle<HeapObject> elements = CompileTimeValue::GetElements(array); 191 Handle<HeapObject> elements = CompileTimeValue::GetElements(array);
189 switch (CompileTimeValue::GetLiteralType(array)) { 192 switch (CompileTimeValue::GetLiteralType(array)) {
190 case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS: { 193 case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS: {
191 Handle<FixedArray> props = Handle<FixedArray>::cast(elements); 194 Handle<BoilerplateDescription> props =
195 Handle<BoilerplateDescription>::cast(elements);
192 return CreateObjectLiteralBoilerplate(isolate, literals, props, true); 196 return CreateObjectLiteralBoilerplate(isolate, literals, props, true);
193 } 197 }
194 case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS: { 198 case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS: {
195 Handle<FixedArray> props = Handle<FixedArray>::cast(elements); 199 Handle<BoilerplateDescription> props =
200 Handle<BoilerplateDescription>::cast(elements);
196 return CreateObjectLiteralBoilerplate(isolate, literals, props, false); 201 return CreateObjectLiteralBoilerplate(isolate, literals, props, false);
197 } 202 }
198 case CompileTimeValue::ARRAY_LITERAL: { 203 case CompileTimeValue::ARRAY_LITERAL: {
199 Handle<ConstantElementsPair> elems = 204 Handle<ConstantElementsPair> elems =
200 Handle<ConstantElementsPair>::cast(elements); 205 Handle<ConstantElementsPair>::cast(elements);
201 return CreateArrayLiteralBoilerplate(isolate, literals, elems); 206 return CreateArrayLiteralBoilerplate(isolate, literals, elems);
202 } 207 }
203 default: 208 default:
204 UNREACHABLE(); 209 UNREACHABLE();
205 return MaybeHandle<Object>(); 210 return MaybeHandle<Object>();
(...skipping 18 matching lines...) Expand all
224 } 229 }
225 return *JSRegExp::Copy(Handle<JSRegExp>::cast(boilerplate)); 230 return *JSRegExp::Copy(Handle<JSRegExp>::cast(boilerplate));
226 } 231 }
227 232
228 233
229 RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) { 234 RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) {
230 HandleScope scope(isolate); 235 HandleScope scope(isolate);
231 DCHECK_EQ(4, args.length()); 236 DCHECK_EQ(4, args.length());
232 CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); 237 CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0);
233 CONVERT_SMI_ARG_CHECKED(literals_index, 1); 238 CONVERT_SMI_ARG_CHECKED(literals_index, 1);
234 CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2); 239 CONVERT_ARG_HANDLE_CHECKED(BoilerplateDescription, boilerplate_description,
240 2);
235 CONVERT_SMI_ARG_CHECKED(flags, 3); 241 CONVERT_SMI_ARG_CHECKED(flags, 3);
236 Handle<LiteralsArray> literals(closure->literals(), isolate); 242 Handle<LiteralsArray> literals(closure->literals(), isolate);
237 bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0; 243 bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
238 bool enable_mementos = (flags & ObjectLiteral::kDisableMementos) == 0; 244 bool enable_mementos = (flags & ObjectLiteral::kDisableMementos) == 0;
239 245
240 CHECK(literals_index >= 0); 246 CHECK(literals_index >= 0);
241 CHECK(literals_index < literals->literals_count()); 247 CHECK(literals_index < literals->literals_count());
242 248
243 // Check if boilerplate exists. If not, create it first. 249 // Check if boilerplate exists. If not, create it first.
244 Handle<Object> literal_site(literals->literal(literals_index), isolate); 250 Handle<Object> literal_site(literals->literal(literals_index), isolate);
245 Handle<AllocationSite> site; 251 Handle<AllocationSite> site;
246 Handle<JSObject> boilerplate; 252 Handle<JSObject> boilerplate;
247 if (literal_site->IsUndefined(isolate)) { 253 if (literal_site->IsUndefined(isolate)) {
248 Handle<Object> raw_boilerplate; 254 Handle<Object> raw_boilerplate;
249 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 255 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
250 isolate, raw_boilerplate, 256 isolate, raw_boilerplate,
251 CreateObjectLiteralBoilerplate(isolate, literals, constant_properties, 257 CreateObjectLiteralBoilerplate(isolate, literals,
258 boilerplate_description,
252 should_have_fast_elements)); 259 should_have_fast_elements));
253 boilerplate = Handle<JSObject>::cast(raw_boilerplate); 260 boilerplate = Handle<JSObject>::cast(raw_boilerplate);
254 261
255 AllocationSiteCreationContext creation_context(isolate); 262 AllocationSiteCreationContext creation_context(isolate);
256 site = creation_context.EnterNewScope(); 263 site = creation_context.EnterNewScope();
257 RETURN_FAILURE_ON_EXCEPTION( 264 RETURN_FAILURE_ON_EXCEPTION(
258 isolate, JSObject::DeepWalk(boilerplate, &creation_context)); 265 isolate, JSObject::DeepWalk(boilerplate, &creation_context));
259 creation_context.ExitScope(site, boilerplate); 266 creation_context.ExitScope(site, boilerplate);
260 267
261 // Update the functions literal and return the boilerplate. 268 // Update the functions literal and return the boilerplate.
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 358
352 Handle<LiteralsArray> literals(closure->literals(), isolate); 359 Handle<LiteralsArray> literals(closure->literals(), isolate);
353 RETURN_RESULT_OR_FAILURE( 360 RETURN_RESULT_OR_FAILURE(
354 isolate, 361 isolate,
355 CreateArrayLiteralImpl(isolate, literals, literals_index, elements, 362 CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
356 ArrayLiteral::kShallowElements)); 363 ArrayLiteral::kShallowElements));
357 } 364 }
358 365
359 } // namespace internal 366 } // namespace internal
360 } // namespace v8 367 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/preparser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698