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