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 |