OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 3270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3281 values->Add(elem); | 3281 values->Add(elem); |
3282 if (peek() != Token::RBRACK) { | 3282 if (peek() != Token::RBRACK) { |
3283 Expect(Token::COMMA, CHECK_OK); | 3283 Expect(Token::COMMA, CHECK_OK); |
3284 } | 3284 } |
3285 } | 3285 } |
3286 Expect(Token::RBRACK, CHECK_OK); | 3286 Expect(Token::RBRACK, CHECK_OK); |
3287 | 3287 |
3288 // Update the scope information before the pre-parsing bailout. | 3288 // Update the scope information before the pre-parsing bailout. |
3289 int literal_index = lexical_scope_->NextMaterializedLiteralIndex(); | 3289 int literal_index = lexical_scope_->NextMaterializedLiteralIndex(); |
3290 | 3290 |
3291 // Allocate a fixed array with all the literals. | 3291 // Allocate a fixed array to hold all the object literals. |
3292 Handle<FixedArray> literals = | 3292 Handle<FixedArray> object_literals = |
3293 isolate()->factory()->NewFixedArray(values->length(), TENURED); | 3293 isolate()->factory()->NewFixedArray(values->length(), TENURED); |
| 3294 Handle<FixedDoubleArray> double_literals; |
| 3295 ElementsKind elements_kind = FAST_SMI_ONLY_ELEMENTS; |
3294 | 3296 |
3295 // Fill in the literals. | 3297 // Fill in the literals. |
3296 bool is_simple = true; | 3298 bool is_simple = true; |
3297 int depth = 1; | 3299 int depth = 1; |
3298 for (int i = 0, n = values->length(); i < n; i++) { | 3300 for (int i = 0, n = values->length(); i < n; i++) { |
3299 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral(); | 3301 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral(); |
3300 if (m_literal != NULL && m_literal->depth() + 1 > depth) { | 3302 if (m_literal != NULL && m_literal->depth() + 1 > depth) { |
3301 depth = m_literal->depth() + 1; | 3303 depth = m_literal->depth() + 1; |
3302 } | 3304 } |
3303 Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i)); | 3305 Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i)); |
3304 if (boilerplate_value->IsUndefined()) { | 3306 if (boilerplate_value->IsUndefined()) { |
3305 literals->set_the_hole(i); | 3307 object_literals->set_the_hole(i); |
| 3308 if (elements_kind == FAST_DOUBLE_ELEMENTS) { |
| 3309 double_literals->set_the_hole(i); |
| 3310 } |
3306 is_simple = false; | 3311 is_simple = false; |
3307 } else { | 3312 } else { |
3308 literals->set(i, *boilerplate_value); | 3313 // Examine each literal element, and adjust the ElementsKind if the |
| 3314 // literal element is not of a type that can be stored in the current |
| 3315 // ElementsKind. Start with FAST_SMI_ONLY_ELEMENTS, and transitions to |
| 3316 // FAST_DOUBLE_ELEMENTS and FAST_ELEMENTS as necessary. Always remember |
| 3317 // the tagged value, no matter what the ElementsKind is in case we |
| 3318 // ultimately end up in FAST_ELEMENTS. |
| 3319 object_literals->set(i, *boilerplate_value); |
| 3320 if (elements_kind == FAST_SMI_ONLY_ELEMENTS) { |
| 3321 // Smi only elements. Notice if a transition to FAST_DOUBLE_ELEMENTS or |
| 3322 // FAST_ELEMENTS is required. |
| 3323 if (!boilerplate_value->IsSmi()) { |
| 3324 if (boilerplate_value->IsNumber() && FLAG_smi_only_arrays) { |
| 3325 // Allocate a double array on the FAST_DOUBLE_ELEMENTS transition to |
| 3326 // avoid over-allocating in TENURED space. |
| 3327 double_literals = isolate()->factory()->NewFixedDoubleArray( |
| 3328 values->length(), TENURED); |
| 3329 // Copy the contents of the FAST_SMI_ONLY_ELEMENT array to the |
| 3330 // FAST_DOUBLE_ELEMENTS array so that they are in sync. |
| 3331 for (int j = 0; j < i; ++j) { |
| 3332 Object* smi_value = object_literals->get(j); |
| 3333 if (smi_value->IsTheHole()) { |
| 3334 double_literals->set_the_hole(j); |
| 3335 } else { |
| 3336 double_literals->set(j, Smi::cast(smi_value)->value()); |
| 3337 } |
| 3338 } |
| 3339 elements_kind = FAST_DOUBLE_ELEMENTS; |
| 3340 } else { |
| 3341 elements_kind = FAST_ELEMENTS; |
| 3342 } |
| 3343 } |
| 3344 } |
| 3345 if (elements_kind == FAST_DOUBLE_ELEMENTS) { |
| 3346 // Continue to store double values in to FAST_DOUBLE_ELEMENTS arrays |
| 3347 // until the first value is seen that can't be stored as a double. |
| 3348 if (boilerplate_value->IsNumber()) { |
| 3349 double_literals->set(i, boilerplate_value->Number()); |
| 3350 } else { |
| 3351 elements_kind = FAST_ELEMENTS; |
| 3352 } |
| 3353 } |
3309 } | 3354 } |
3310 } | 3355 } |
3311 | 3356 |
3312 // Simple and shallow arrays can be lazily copied, we transform the | 3357 // Simple and shallow arrays can be lazily copied, we transform the |
3313 // elements array to a copy-on-write array. | 3358 // elements array to a copy-on-write array. |
3314 if (is_simple && depth == 1 && values->length() > 0) { | 3359 if (is_simple && depth == 1 && values->length() > 0 && |
3315 literals->set_map(isolate()->heap()->fixed_cow_array_map()); | 3360 elements_kind != FAST_DOUBLE_ELEMENTS) { |
| 3361 object_literals->set_map(isolate()->heap()->fixed_cow_array_map()); |
3316 } | 3362 } |
3317 | 3363 |
| 3364 Handle<FixedArrayBase> element_values = elements_kind == FAST_DOUBLE_ELEMENTS |
| 3365 ? Handle<FixedArrayBase>(double_literals) |
| 3366 : Handle<FixedArrayBase>(object_literals); |
| 3367 |
| 3368 // Remember both the literal's constant values as well as the ElementsKind |
| 3369 // in a 2-element FixedArray. |
| 3370 Handle<FixedArray> literals = |
| 3371 isolate()->factory()->NewFixedArray(2, TENURED); |
| 3372 |
| 3373 literals->set(0, Smi::FromInt(elements_kind)); |
| 3374 literals->set(1, *element_values); |
| 3375 |
3318 return new(zone()) ArrayLiteral( | 3376 return new(zone()) ArrayLiteral( |
3319 isolate(), literals, values, literal_index, is_simple, depth); | 3377 isolate(), literals, values, literal_index, is_simple, depth); |
3320 } | 3378 } |
3321 | 3379 |
3322 | 3380 |
3323 bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) { | 3381 bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) { |
3324 return property != NULL && | 3382 return property != NULL && |
3325 property->kind() != ObjectLiteral::Property::PROTOTYPE; | 3383 property->kind() != ObjectLiteral::Property::PROTOTYPE; |
3326 } | 3384 } |
3327 | 3385 |
(...skipping 2005 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5333 result = parser.ParseProgram(source, | 5391 result = parser.ParseProgram(source, |
5334 info->is_global(), | 5392 info->is_global(), |
5335 info->StrictMode()); | 5393 info->StrictMode()); |
5336 } | 5394 } |
5337 } | 5395 } |
5338 info->SetFunction(result); | 5396 info->SetFunction(result); |
5339 return (result != NULL); | 5397 return (result != NULL); |
5340 } | 5398 } |
5341 | 5399 |
5342 } } // namespace v8::internal | 5400 } } // namespace v8::internal |
OLD | NEW |