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/v8.h" | 5 #include "src/v8.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.h" | 9 #include "src/ast.h" |
10 #include "src/parser.h" | 10 #include "src/parser.h" |
11 #include "src/runtime/runtime.h" | 11 #include "src/runtime/runtime.h" |
12 #include "src/runtime/runtime-utils.h" | 12 #include "src/runtime/runtime-utils.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, Handle<FixedArray> constant_properties, |
19 bool* is_result_from_cache) { | 19 bool* is_result_from_cache) { |
20 Isolate* isolate = context->GetIsolate(); | |
21 int properties_length = constant_properties->length(); | 20 int properties_length = constant_properties->length(); |
22 int number_of_properties = properties_length / 2; | 21 int number_of_properties = properties_length / 2; |
23 // Check that there are only internal strings and array indices among keys. | 22 |
24 int number_of_string_keys = 0; | |
25 for (int p = 0; p != properties_length; p += 2) { | 23 for (int p = 0; p != properties_length; p += 2) { |
26 Object* key = constant_properties->get(p); | 24 Object* key = constant_properties->get(p); |
27 uint32_t element_index = 0; | 25 uint32_t element_index = 0; |
28 if (key->IsInternalizedString()) { | 26 if (key->ToArrayIndex(&element_index)) { |
29 number_of_string_keys++; | |
30 } else if (key->ToArrayIndex(&element_index)) { | |
31 // 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. |
32 number_of_properties--; | 28 number_of_properties--; |
33 } else { | |
34 // Bail out as a non-internalized-string non-index key makes caching | |
35 // impossible. | |
36 // DCHECK to make sure that the if condition after the loop is false. | |
37 DCHECK(number_of_string_keys != number_of_properties); | |
38 break; | |
39 } | 29 } |
40 } | 30 } |
41 // If we only have internalized strings and array indices among keys then we | 31 Isolate* isolate = context->GetIsolate(); |
42 // can use the map cache in the native context. | 32 return isolate->factory()->ObjectLiteralMapFromCache( |
43 const int kMaxKeys = 10; | 33 context, number_of_properties, is_result_from_cache); |
44 if ((number_of_string_keys == number_of_properties) && | |
45 (number_of_string_keys < kMaxKeys)) { | |
46 // Create the fixed array with the key. | |
47 Handle<FixedArray> keys = | |
48 isolate->factory()->NewFixedArray(number_of_string_keys); | |
49 if (number_of_string_keys > 0) { | |
50 int index = 0; | |
51 for (int p = 0; p < properties_length; p += 2) { | |
52 Object* key = constant_properties->get(p); | |
53 if (key->IsInternalizedString()) { | |
54 keys->set(index++, key); | |
55 } | |
56 } | |
57 DCHECK(index == number_of_string_keys); | |
58 } | |
59 *is_result_from_cache = true; | |
60 return isolate->factory()->ObjectLiteralMapFromCache(context, keys); | |
61 } | |
62 *is_result_from_cache = false; | |
63 return Map::Create(isolate, number_of_properties); | |
64 } | 34 } |
65 | 35 |
66 | |
67 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( | 36 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( |
68 Isolate* isolate, Handle<FixedArray> literals, | 37 Isolate* isolate, Handle<FixedArray> literals, |
69 Handle<FixedArray> constant_properties); | 38 Handle<FixedArray> constant_properties); |
70 | 39 |
71 | 40 |
72 MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate( | 41 MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate( |
73 Isolate* isolate, Handle<FixedArray> literals, | 42 Isolate* isolate, Handle<FixedArray> literals, |
74 Handle<FixedArray> constant_properties, bool should_have_fast_elements, | 43 Handle<FixedArray> constant_properties, bool should_have_fast_elements, |
75 bool has_function_literal) { | 44 bool has_function_literal) { |
76 // Get the native context from the literals array. This is the | 45 // Get the native context from the literals array. This is the |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 | 131 |
163 // Transform to fast properties if necessary. For object literals with | 132 // Transform to fast properties if necessary. For object literals with |
164 // containing function literals we defer this operation until after all | 133 // containing function literals we defer this operation until after all |
165 // computed properties have been assigned so that we can generate | 134 // computed properties have been assigned so that we can generate |
166 // constant function properties. | 135 // constant function properties. |
167 if (should_transform && !has_function_literal) { | 136 if (should_transform && !has_function_literal) { |
168 JSObject::MigrateSlowToFast(boilerplate, | 137 JSObject::MigrateSlowToFast(boilerplate, |
169 boilerplate->map()->unused_property_fields(), | 138 boilerplate->map()->unused_property_fields(), |
170 "FastLiteral"); | 139 "FastLiteral"); |
171 } | 140 } |
172 | |
173 return boilerplate; | 141 return boilerplate; |
174 } | 142 } |
175 | 143 |
176 | 144 |
177 MaybeHandle<Object> Runtime::CreateArrayLiteralBoilerplate( | 145 MaybeHandle<Object> Runtime::CreateArrayLiteralBoilerplate( |
178 Isolate* isolate, Handle<FixedArray> literals, | 146 Isolate* isolate, Handle<FixedArray> literals, |
179 Handle<FixedArray> elements) { | 147 Handle<FixedArray> elements) { |
180 // Create the JSArray. | 148 // Create the JSArray. |
181 Handle<JSFunction> constructor( | 149 Handle<JSFunction> constructor( |
182 JSFunction::NativeContextFromLiterals(*literals)->array_function()); | 150 JSFunction::NativeContextFromLiterals(*literals)->array_function()); |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind); | 426 JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind); |
459 } | 427 } |
460 } | 428 } |
461 FixedArray* object_array = FixedArray::cast(object->elements()); | 429 FixedArray* object_array = FixedArray::cast(object->elements()); |
462 object_array->set(store_index, *value); | 430 object_array->set(store_index, *value); |
463 } | 431 } |
464 return *object; | 432 return *object; |
465 } | 433 } |
466 } | 434 } |
467 } // namespace v8::internal | 435 } // namespace v8::internal |
OLD | NEW |