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

Side by Side Diff: src/parser.cc

Issue 805004: Do not waste space for the fast-case elements backing storage for ... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « src/parser.h ('k') | src/runtime.h » ('j') | src/runtime.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 Expression* ParseArrayLiteral(bool* ok); 204 Expression* ParseArrayLiteral(bool* ok);
205 Expression* ParseObjectLiteral(bool* ok); 205 Expression* ParseObjectLiteral(bool* ok);
206 Expression* ParseRegExpLiteral(bool seen_equal, bool* ok); 206 Expression* ParseRegExpLiteral(bool seen_equal, bool* ok);
207 207
208 // Populate the constant properties fixed array for a materialized object 208 // Populate the constant properties fixed array for a materialized object
209 // literal. 209 // literal.
210 void BuildObjectLiteralConstantProperties( 210 void BuildObjectLiteralConstantProperties(
211 ZoneList<ObjectLiteral::Property*>* properties, 211 ZoneList<ObjectLiteral::Property*>* properties,
212 Handle<FixedArray> constants, 212 Handle<FixedArray> constants,
213 bool* is_simple, 213 bool* is_simple,
214 bool* fast_elements,
214 int* depth); 215 int* depth);
215 216
216 // Populate the literals fixed array for a materialized array literal. 217 // Populate the literals fixed array for a materialized array literal.
217 void BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* properties, 218 void BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* properties,
218 Handle<FixedArray> constants, 219 Handle<FixedArray> constants,
219 bool* is_simple, 220 bool* is_simple,
220 int* depth); 221 int* depth);
221 222
222 // Decide if a property should be in the object boilerplate. 223 // Decide if a property should be in the object boilerplate.
223 bool IsBoilerplateProperty(ObjectLiteral::Property* property); 224 bool IsBoilerplateProperty(ObjectLiteral::Property* property);
(...skipping 3214 matching lines...) Expand 10 before | Expand all | Expand 10 after
3438 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); 3439 MaterializedLiteral* lit = expression->AsMaterializedLiteral();
3439 return lit != NULL && lit->is_simple(); 3440 return lit != NULL && lit->is_simple();
3440 } 3441 }
3441 3442
3442 Handle<FixedArray> CompileTimeValue::GetValue(Expression* expression) { 3443 Handle<FixedArray> CompileTimeValue::GetValue(Expression* expression) {
3443 ASSERT(IsCompileTimeValue(expression)); 3444 ASSERT(IsCompileTimeValue(expression));
3444 Handle<FixedArray> result = Factory::NewFixedArray(2, TENURED); 3445 Handle<FixedArray> result = Factory::NewFixedArray(2, TENURED);
3445 ObjectLiteral* object_literal = expression->AsObjectLiteral(); 3446 ObjectLiteral* object_literal = expression->AsObjectLiteral();
3446 if (object_literal != NULL) { 3447 if (object_literal != NULL) {
3447 ASSERT(object_literal->is_simple()); 3448 ASSERT(object_literal->is_simple());
3448 result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL)); 3449 if (object_literal->fast_elements()) {
3450 result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS));
3451 } else {
3452 result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS));
3453 }
3449 result->set(kElementsSlot, *object_literal->constant_properties()); 3454 result->set(kElementsSlot, *object_literal->constant_properties());
3450 } else { 3455 } else {
3451 ArrayLiteral* array_literal = expression->AsArrayLiteral(); 3456 ArrayLiteral* array_literal = expression->AsArrayLiteral();
3452 ASSERT(array_literal != NULL && array_literal->is_simple()); 3457 ASSERT(array_literal != NULL && array_literal->is_simple());
3453 result->set(kTypeSlot, Smi::FromInt(ARRAY_LITERAL)); 3458 result->set(kTypeSlot, Smi::FromInt(ARRAY_LITERAL));
3454 result->set(kElementsSlot, *array_literal->constant_elements()); 3459 result->set(kElementsSlot, *array_literal->constant_elements());
3455 } 3460 }
3456 return result; 3461 return result;
3457 } 3462 }
3458 3463
(...skipping 17 matching lines...) Expand all
3476 return CompileTimeValue::GetValue(expression); 3481 return CompileTimeValue::GetValue(expression);
3477 } 3482 }
3478 return Factory::undefined_value(); 3483 return Factory::undefined_value();
3479 } 3484 }
3480 3485
3481 3486
3482 void Parser::BuildObjectLiteralConstantProperties( 3487 void Parser::BuildObjectLiteralConstantProperties(
3483 ZoneList<ObjectLiteral::Property*>* properties, 3488 ZoneList<ObjectLiteral::Property*>* properties,
3484 Handle<FixedArray> constant_properties, 3489 Handle<FixedArray> constant_properties,
3485 bool* is_simple, 3490 bool* is_simple,
3491 bool* fast_elements,
3486 int* depth) { 3492 int* depth) {
3487 int position = 0; 3493 int position = 0;
3488 // Accumulate the value in local variables and store it at the end. 3494 // Accumulate the value in local variables and store it at the end.
3489 bool is_simple_acc = true; 3495 bool is_simple_acc = true;
3490 int depth_acc = 1; 3496 int depth_acc = 1;
3497 uint32_t max_element_index = 0;
3498 uint32_t elements = 0;
3491 for (int i = 0; i < properties->length(); i++) { 3499 for (int i = 0; i < properties->length(); i++) {
3492 ObjectLiteral::Property* property = properties->at(i); 3500 ObjectLiteral::Property* property = properties->at(i);
3493 if (!IsBoilerplateProperty(property)) { 3501 if (!IsBoilerplateProperty(property)) {
3494 is_simple_acc = false; 3502 is_simple_acc = false;
3495 continue; 3503 continue;
3496 } 3504 }
3497 MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral(); 3505 MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral();
3498 if (m_literal != NULL && m_literal->depth() >= depth_acc) { 3506 if (m_literal != NULL && m_literal->depth() >= depth_acc) {
3499 depth_acc = m_literal->depth() + 1; 3507 depth_acc = m_literal->depth() + 1;
3500 } 3508 }
3501 3509
3502 // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined 3510 // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined
3503 // value for COMPUTED properties, the real value is filled in at 3511 // value for COMPUTED properties, the real value is filled in at
3504 // runtime. The enumeration order is maintained. 3512 // runtime. The enumeration order is maintained.
3505 Handle<Object> key = property->key()->handle(); 3513 Handle<Object> key = property->key()->handle();
3506 Handle<Object> value = GetBoilerplateValue(property->value()); 3514 Handle<Object> value = GetBoilerplateValue(property->value());
3507 is_simple_acc = is_simple_acc && !value->IsUndefined(); 3515 is_simple_acc = is_simple_acc && !value->IsUndefined();
3508 3516
3517 // Keep track of the number of elements in the object literal and
3518 // the largest element index. If the largest element index is
3519 // much larger than the number of elements, creating an object
3520 // literal with fast elements will be a waste of space.
3521 uint32_t element_index = 0;
3522 if (key->IsString()
3523 && Handle<String>::cast(key)->AsArrayIndex(&element_index)
3524 && element_index > max_element_index) {
3525 max_element_index = element_index;
3526 elements++;
3527 } else if (key->IsSmi()) {
3528 int key_value = Smi::cast(*key)->value();
3529 if (key_value > 0
3530 && static_cast<uint32_t>(key_value) > max_element_index) {
3531 max_element_index = key_value;
3532 }
3533 elements++;
3534 }
3535
3509 // Add name, value pair to the fixed array. 3536 // Add name, value pair to the fixed array.
3510 constant_properties->set(position++, *key); 3537 constant_properties->set(position++, *key);
3511 constant_properties->set(position++, *value); 3538 constant_properties->set(position++, *value);
3512 } 3539 }
3513 3540 *fast_elements =
3541 (max_element_index <= 32) || ((2 * elements) >= max_element_index);
3514 *is_simple = is_simple_acc; 3542 *is_simple = is_simple_acc;
3515 *depth = depth_acc; 3543 *depth = depth_acc;
3516 } 3544 }
3517 3545
3518 3546
3519 Expression* Parser::ParseObjectLiteral(bool* ok) { 3547 Expression* Parser::ParseObjectLiteral(bool* ok) {
3520 // ObjectLiteral :: 3548 // ObjectLiteral ::
3521 // '{' ( 3549 // '{' (
3522 // ((Identifier | String | Number) ':' AssignmentExpression) 3550 // ((Identifier | String | Number) ':' AssignmentExpression)
3523 // | (('get' | 'set') FunctionLiteral) 3551 // | (('get' | 'set') FunctionLiteral)
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
3601 } 3629 }
3602 Expect(Token::RBRACE, CHECK_OK); 3630 Expect(Token::RBRACE, CHECK_OK);
3603 // Computation of literal_index must happen before pre parse bailout. 3631 // Computation of literal_index must happen before pre parse bailout.
3604 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); 3632 int literal_index = temp_scope_->NextMaterializedLiteralIndex();
3605 if (is_pre_parsing_) return NULL; 3633 if (is_pre_parsing_) return NULL;
3606 3634
3607 Handle<FixedArray> constant_properties = 3635 Handle<FixedArray> constant_properties =
3608 Factory::NewFixedArray(number_of_boilerplate_properties * 2, TENURED); 3636 Factory::NewFixedArray(number_of_boilerplate_properties * 2, TENURED);
3609 3637
3610 bool is_simple = true; 3638 bool is_simple = true;
3639 bool fast_elements = true;
3611 int depth = 1; 3640 int depth = 1;
3612 BuildObjectLiteralConstantProperties(properties.elements(), 3641 BuildObjectLiteralConstantProperties(properties.elements(),
3613 constant_properties, 3642 constant_properties,
3614 &is_simple, 3643 &is_simple,
3644 &fast_elements,
3615 &depth); 3645 &depth);
3616 return new ObjectLiteral(constant_properties, 3646 return new ObjectLiteral(constant_properties,
3617 properties.elements(), 3647 properties.elements(),
3618 literal_index, 3648 literal_index,
3619 is_simple, 3649 is_simple,
3650 fast_elements,
3620 depth); 3651 depth);
3621 } 3652 }
3622 3653
3623 3654
3624 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { 3655 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) {
3625 if (!scanner_.ScanRegExpPattern(seen_equal)) { 3656 if (!scanner_.ScanRegExpPattern(seen_equal)) {
3626 Next(); 3657 Next();
3627 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); 3658 ReportMessage("unterminated_regexp", Vector<const char*>::empty());
3628 *ok = false; 3659 *ok = false;
3629 return NULL; 3660 return NULL;
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
4116 } while (Check(Token::COMMA)); 4147 } while (Check(Token::COMMA));
4117 } 4148 }
4118 Expect(Token::RBRACE, CHECK_OK); 4149 Expect(Token::RBRACE, CHECK_OK);
4119 4150
4120 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); 4151 int literal_index = temp_scope_->NextMaterializedLiteralIndex();
4121 if (is_pre_parsing_) return NULL; 4152 if (is_pre_parsing_) return NULL;
4122 4153
4123 Handle<FixedArray> constant_properties = 4154 Handle<FixedArray> constant_properties =
4124 Factory::NewFixedArray(boilerplate_properties * 2, TENURED); 4155 Factory::NewFixedArray(boilerplate_properties * 2, TENURED);
4125 bool is_simple = true; 4156 bool is_simple = true;
4157 bool fast_elements = true;
4126 int depth = 1; 4158 int depth = 1;
4127 BuildObjectLiteralConstantProperties(properties.elements(), 4159 BuildObjectLiteralConstantProperties(properties.elements(),
4128 constant_properties, 4160 constant_properties,
4129 &is_simple, 4161 &is_simple,
4162 &fast_elements,
4130 &depth); 4163 &depth);
4131 return new ObjectLiteral(constant_properties, 4164 return new ObjectLiteral(constant_properties,
4132 properties.elements(), 4165 properties.elements(),
4133 literal_index, 4166 literal_index,
4134 is_simple, 4167 is_simple,
4168 fast_elements,
4135 depth); 4169 depth);
4136 } 4170 }
4137 4171
4138 4172
4139 // Parse a JSON array. Scanner must be right after '[' token. 4173 // Parse a JSON array. Scanner must be right after '[' token.
4140 Expression* Parser::ParseJsonArray(bool* ok) { 4174 Expression* Parser::ParseJsonArray(bool* ok) {
4141 Consume(Token::LBRACK); 4175 Consume(Token::LBRACK);
4142 4176
4143 ZoneListWrapper<Expression> values = factory()->NewList<Expression>(4); 4177 ZoneListWrapper<Expression> values = factory()->NewList<Expression>(4);
4144 if (peek() != Token::RBRACK) { 4178 if (peek() != Token::RBRACK) {
(...skipping 944 matching lines...) Expand 10 before | Expand all | Expand 10 after
5089 parser.ParseLazy(script_source, name, 5123 parser.ParseLazy(script_source, name,
5090 start_position, end_position, is_expression); 5124 start_position, end_position, is_expression);
5091 return result; 5125 return result;
5092 } 5126 }
5093 5127
5094 5128
5095 #undef NEW 5129 #undef NEW
5096 5130
5097 5131
5098 } } // namespace v8::internal 5132 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/runtime.h » ('j') | src/runtime.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698