Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 3419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3430 HValue* context = environment()->LookupContext(); | 3430 HValue* context = environment()->LookupContext(); |
| 3431 | 3431 |
| 3432 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(context, | 3432 HRegExpLiteral* instr = new(zone()) HRegExpLiteral(context, |
| 3433 expr->pattern(), | 3433 expr->pattern(), |
| 3434 expr->flags(), | 3434 expr->flags(), |
| 3435 expr->literal_index()); | 3435 expr->literal_index()); |
| 3436 return ast_context()->ReturnInstruction(instr, expr->id()); | 3436 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 3437 } | 3437 } |
| 3438 | 3438 |
| 3439 | 3439 |
| 3440 // Determines whether the given object literal boilerplate satisfies all | 3440 // Determines whether the given array or object literal boilerplate satisfies |
| 3441 // limits to be considered for fast deep-copying and computes the total | 3441 // all limits to be considered for fast deep-copying and computes the total |
| 3442 // size of all objects that are part of the graph. | 3442 // size of all objects that are part of the graph. |
| 3443 static bool IsFastObjectLiteral(Handle<JSObject> boilerplate, | 3443 static bool IsFastLiteral(Handle<JSObject> boilerplate, |
| 3444 int max_depth, | 3444 int max_depth, |
| 3445 int* max_properties, | 3445 int* max_properties, |
| 3446 int* total_size) { | 3446 int* total_size) { |
| 3447 if (max_depth <= 0) return false; | 3447 if (max_depth <= 0) return false; |
|
danno
2012/02/16 16:09:37
Don't you want to return on 0 and assert that it's
Michael Starzinger
2012/02/16 17:34:37
Done.
| |
| 3448 | 3448 |
| 3449 Handle<FixedArrayBase> elements(boilerplate->elements()); | 3449 Handle<FixedArrayBase> elements(boilerplate->elements()); |
| 3450 if (elements->length() > 0 && | 3450 if (elements->length() > 0 && |
| 3451 elements->map() != HEAP->fixed_cow_array_map()) { | 3451 elements->map() != boilerplate->GetHeap()->fixed_cow_array_map()) { |
|
danno
2012/02/16 16:09:37
length check unnecessary.
Michael Starzinger
2012/02/16 17:34:37
See response to first comment.
| |
| 3452 return false; | 3452 if (!boilerplate->HasFastElements()) return false; |
| 3453 int length = elements->length(); | |
| 3454 for (int i = 0; i < length; i++) { | |
| 3455 if ((*max_properties)-- <= 0) return false; | |
| 3456 Handle<Object> value = JSObject::GetElement(boilerplate, i); | |
| 3457 if (value->IsJSObject()) { | |
| 3458 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | |
| 3459 if (!IsFastLiteral(value_object, | |
| 3460 max_depth - 1, | |
| 3461 max_properties, | |
| 3462 total_size)) { | |
| 3463 return false; | |
| 3464 } | |
| 3465 } | |
| 3466 } | |
| 3467 *total_size += FixedArray::SizeFor(length); | |
| 3453 } | 3468 } |
| 3454 | 3469 |
| 3455 Handle<FixedArray> properties(boilerplate->properties()); | 3470 Handle<FixedArray> properties(boilerplate->properties()); |
| 3456 if (properties->length() > 0) { | 3471 if (properties->length() > 0) { |
| 3457 return false; | 3472 return false; |
| 3458 } else { | 3473 } else { |
| 3459 int nof = boilerplate->map()->inobject_properties(); | 3474 int nof = boilerplate->map()->inobject_properties(); |
| 3460 for (int i = 0; i < nof; i++) { | 3475 for (int i = 0; i < nof; i++) { |
| 3461 if ((*max_properties)-- <= 0) return false; | 3476 if ((*max_properties)-- <= 0) return false; |
| 3462 Handle<Object> value(boilerplate->InObjectPropertyAt(i)); | 3477 Handle<Object> value(boilerplate->InObjectPropertyAt(i)); |
| 3463 if (value->IsJSObject()) { | 3478 if (value->IsJSObject()) { |
| 3464 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 3479 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
| 3465 if (!IsFastObjectLiteral(value_object, | 3480 if (!IsFastLiteral(value_object, |
| 3466 max_depth - 1, | 3481 max_depth - 1, |
| 3467 max_properties, | 3482 max_properties, |
| 3468 total_size)) { | 3483 total_size)) { |
| 3469 return false; | 3484 return false; |
| 3470 } | 3485 } |
| 3471 } | 3486 } |
| 3472 } | 3487 } |
| 3473 } | 3488 } |
| 3474 | 3489 |
| 3475 *total_size += boilerplate->map()->instance_size(); | 3490 *total_size += boilerplate->map()->instance_size(); |
| 3476 return true; | 3491 return true; |
| 3477 } | 3492 } |
| 3478 | 3493 |
| 3479 | 3494 |
| 3480 void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { | 3495 void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
| 3481 ASSERT(!HasStackOverflow()); | 3496 ASSERT(!HasStackOverflow()); |
| 3482 ASSERT(current_block() != NULL); | 3497 ASSERT(current_block() != NULL); |
| 3483 ASSERT(current_block()->HasPredecessor()); | 3498 ASSERT(current_block()->HasPredecessor()); |
| 3484 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); | 3499 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); |
| 3485 HValue* context = environment()->LookupContext(); | 3500 HValue* context = environment()->LookupContext(); |
| 3486 HInstruction* literal; | 3501 HInstruction* literal; |
| 3487 | 3502 |
| 3488 // Check whether to use fast or slow deep-copying for boilerplate. | 3503 // Check whether to use fast or slow deep-copying for boilerplate. |
| 3489 int total_size = 0; | 3504 int total_size = 0; |
| 3490 int max_properties = HObjectLiteralFast::kMaxObjectLiteralProperties; | 3505 int max_properties = HFastLiteral::kMaxLiteralProperties; |
| 3491 Handle<Object> boilerplate(closure->literals()->get(expr->literal_index())); | 3506 Handle<Object> boilerplate(closure->literals()->get(expr->literal_index())); |
| 3492 if (boilerplate->IsJSObject() && | 3507 if (boilerplate->IsJSObject() && |
| 3493 IsFastObjectLiteral(Handle<JSObject>::cast(boilerplate), | 3508 IsFastLiteral(Handle<JSObject>::cast(boilerplate), |
| 3494 HObjectLiteralFast::kMaxObjectLiteralDepth, | 3509 HFastLiteral::kMaxLiteralDepth, |
| 3495 &max_properties, | 3510 &max_properties, |
| 3496 &total_size)) { | 3511 &total_size)) { |
| 3497 Handle<JSObject> boilerplate_object = Handle<JSObject>::cast(boilerplate); | 3512 Handle<JSObject> boilerplate_object = Handle<JSObject>::cast(boilerplate); |
| 3498 literal = new(zone()) HObjectLiteralFast(context, | 3513 literal = new(zone()) HFastLiteral(context, |
| 3499 boilerplate_object, | 3514 boilerplate_object, |
| 3500 total_size, | 3515 total_size, |
| 3501 expr->literal_index(), | 3516 expr->literal_index(), |
| 3502 expr->depth()); | 3517 expr->depth()); |
| 3503 } else { | 3518 } else { |
| 3504 literal = new(zone()) HObjectLiteralGeneric(context, | 3519 literal = new(zone()) HObjectLiteral(context, |
| 3505 expr->constant_properties(), | 3520 expr->constant_properties(), |
| 3506 expr->fast_elements(), | 3521 expr->fast_elements(), |
| 3507 expr->literal_index(), | 3522 expr->literal_index(), |
| 3508 expr->depth(), | 3523 expr->depth(), |
| 3509 expr->has_function()); | 3524 expr->has_function()); |
| 3510 } | 3525 } |
| 3511 | 3526 |
| 3512 // The object is expected in the bailout environment during computation | 3527 // The object is expected in the bailout environment during computation |
| 3513 // of the property values and is the value of the entire expression. | 3528 // of the property values and is the value of the entire expression. |
| 3514 PushAndAdd(literal); | 3529 PushAndAdd(literal); |
| 3515 | 3530 |
| 3516 expr->CalculateEmitStore(); | 3531 expr->CalculateEmitStore(); |
| 3517 | 3532 |
| 3518 for (int i = 0; i < expr->properties()->length(); i++) { | 3533 for (int i = 0; i < expr->properties()->length(); i++) { |
| 3519 ObjectLiteral::Property* property = expr->properties()->at(i); | 3534 ObjectLiteral::Property* property = expr->properties()->at(i); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3570 } | 3585 } |
| 3571 | 3586 |
| 3572 | 3587 |
| 3573 void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { | 3588 void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { |
| 3574 ASSERT(!HasStackOverflow()); | 3589 ASSERT(!HasStackOverflow()); |
| 3575 ASSERT(current_block() != NULL); | 3590 ASSERT(current_block() != NULL); |
| 3576 ASSERT(current_block()->HasPredecessor()); | 3591 ASSERT(current_block()->HasPredecessor()); |
| 3577 ZoneList<Expression*>* subexprs = expr->values(); | 3592 ZoneList<Expression*>* subexprs = expr->values(); |
| 3578 int length = subexprs->length(); | 3593 int length = subexprs->length(); |
| 3579 HValue* context = environment()->LookupContext(); | 3594 HValue* context = environment()->LookupContext(); |
| 3595 HInstruction* literal; | |
| 3580 | 3596 |
| 3581 Handle<FixedArray> literals(environment()->closure()->literals()); | 3597 Handle<FixedArray> literals(environment()->closure()->literals()); |
| 3582 Handle<Object> raw_boilerplate(literals->get(expr->literal_index())); | 3598 Handle<Object> raw_boilerplate(literals->get(expr->literal_index())); |
| 3583 | 3599 |
| 3584 if (raw_boilerplate->IsUndefined()) { | 3600 if (raw_boilerplate->IsUndefined()) { |
| 3585 raw_boilerplate = Runtime::CreateArrayLiteralBoilerplate( | 3601 raw_boilerplate = Runtime::CreateArrayLiteralBoilerplate( |
| 3586 isolate(), literals, expr->constant_elements()); | 3602 isolate(), literals, expr->constant_elements()); |
| 3587 if (raw_boilerplate.is_null()) { | 3603 if (raw_boilerplate.is_null()) { |
| 3588 return Bailout("array boilerplate creation failed"); | 3604 return Bailout("array boilerplate creation failed"); |
| 3589 } | 3605 } |
| 3590 literals->set(expr->literal_index(), *raw_boilerplate); | 3606 literals->set(expr->literal_index(), *raw_boilerplate); |
| 3591 if (JSObject::cast(*raw_boilerplate)->elements()->map() == | 3607 if (JSObject::cast(*raw_boilerplate)->elements()->map() == |
| 3592 isolate()->heap()->fixed_cow_array_map()) { | 3608 isolate()->heap()->fixed_cow_array_map()) { |
| 3593 isolate()->counters()->cow_arrays_created_runtime()->Increment(); | 3609 isolate()->counters()->cow_arrays_created_runtime()->Increment(); |
| 3594 } | 3610 } |
| 3595 } | 3611 } |
| 3596 | 3612 |
| 3597 Handle<JSObject> boilerplate = Handle<JSObject>::cast(raw_boilerplate); | 3613 Handle<JSObject> boilerplate = Handle<JSObject>::cast(raw_boilerplate); |
| 3598 ElementsKind boilerplate_elements_kind = | 3614 ElementsKind boilerplate_elements_kind = |
| 3599 Handle<JSObject>::cast(boilerplate)->GetElementsKind(); | 3615 Handle<JSObject>::cast(boilerplate)->GetElementsKind(); |
| 3600 | 3616 |
| 3601 HArrayLiteral* literal = new(zone()) HArrayLiteral( | 3617 // Check whether to use fast or slow deep-copying for boilerplate. |
| 3602 context, | 3618 int total_size = 0; |
| 3603 boilerplate, | 3619 int max_properties = HFastLiteral::kMaxLiteralProperties; |
| 3604 length, | 3620 if (IsFastLiteral(boilerplate, |
| 3605 expr->literal_index(), | 3621 HFastLiteral::kMaxLiteralDepth, |
| 3606 expr->depth()); | 3622 &max_properties, |
| 3623 &total_size)) { | |
| 3624 literal = new(zone()) HFastLiteral(context, | |
| 3625 boilerplate, | |
| 3626 total_size, | |
| 3627 expr->literal_index(), | |
| 3628 expr->depth()); | |
| 3629 } else { | |
| 3630 literal = new(zone()) HArrayLiteral(context, | |
| 3631 boilerplate, | |
| 3632 length, | |
| 3633 expr->literal_index(), | |
| 3634 expr->depth()); | |
| 3635 } | |
| 3607 | 3636 |
| 3608 // The array is expected in the bailout environment during computation | 3637 // The array is expected in the bailout environment during computation |
| 3609 // of the property values and is the value of the entire expression. | 3638 // of the property values and is the value of the entire expression. |
| 3610 PushAndAdd(literal); | 3639 PushAndAdd(literal); |
| 3611 | 3640 |
| 3612 HLoadElements* elements = NULL; | 3641 HLoadElements* elements = NULL; |
| 3613 | 3642 |
| 3614 for (int i = 0; i < length; i++) { | 3643 for (int i = 0; i < length; i++) { |
| 3615 Expression* subexpr = subexprs->at(i); | 3644 Expression* subexpr = subexprs->at(i); |
| 3616 // If the subexpression is a literal or a simple materialized literal it | 3645 // If the subexpression is a literal or a simple materialized literal it |
| (...skipping 4090 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7707 } | 7736 } |
| 7708 } | 7737 } |
| 7709 | 7738 |
| 7710 #ifdef DEBUG | 7739 #ifdef DEBUG |
| 7711 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 7740 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 7712 if (allocator_ != NULL) allocator_->Verify(); | 7741 if (allocator_ != NULL) allocator_->Verify(); |
| 7713 #endif | 7742 #endif |
| 7714 } | 7743 } |
| 7715 | 7744 |
| 7716 } } // namespace v8::internal | 7745 } } // namespace v8::internal |
| OLD | NEW |