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 3246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3257 instr = BuildStoreNamedGeneric(object, name, value); | 3257 instr = BuildStoreNamedGeneric(object, name, value); |
3258 } | 3258 } |
3259 | 3259 |
3260 } else { | 3260 } else { |
3261 // Keyed store. | 3261 // Keyed store. |
3262 VISIT_FOR_VALUE(prop->key()); | 3262 VISIT_FOR_VALUE(prop->key()); |
3263 VISIT_FOR_VALUE(expr->value()); | 3263 VISIT_FOR_VALUE(expr->value()); |
3264 value = Pop(); | 3264 value = Pop(); |
3265 HValue* key = Pop(); | 3265 HValue* key = Pop(); |
3266 HValue* object = Pop(); | 3266 HValue* object = Pop(); |
3267 | 3267 instr = BuildStoreKeyed(object, key, value, expr); |
3268 if (expr->IsMonomorphic()) { | |
3269 Handle<Map> receiver_type(expr->GetMonomorphicReceiverType()); | |
3270 // An object has either fast elements or external array elements, but | |
3271 // never both. Pixel array maps that are assigned to pixel array elements | |
3272 // are always created with the fast elements flag cleared. | |
3273 if (receiver_type->has_external_array_elements()) { | |
3274 instr = BuildStoreKeyedSpecializedArrayElement(object, | |
3275 key, | |
3276 value, | |
3277 expr); | |
3278 } else if (receiver_type->has_fast_elements()) { | |
3279 instr = BuildStoreKeyedFastElement(object, key, value, expr); | |
3280 } | |
3281 } | |
3282 if (instr == NULL) { | |
3283 instr = BuildStoreKeyedGeneric(object, key, value); | |
3284 } | |
3285 } | 3268 } |
3286 | |
3287 Push(value); | 3269 Push(value); |
3288 instr->set_position(expr->position()); | 3270 instr->set_position(expr->position()); |
3289 AddInstruction(instr); | 3271 AddInstruction(instr); |
3290 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 3272 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
3291 ast_context()->ReturnValue(Pop()); | 3273 ast_context()->ReturnValue(Pop()); |
3292 } | 3274 } |
3293 | 3275 |
3294 | 3276 |
3295 // Because not every expression has a position and there is not common | 3277 // Because not every expression has a position and there is not common |
3296 // superclass of Assignment and CountOperation, we cannot just pass the | 3278 // superclass of Assignment and CountOperation, we cannot just pass the |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3395 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 3377 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
3396 ast_context()->ReturnValue(Pop()); | 3378 ast_context()->ReturnValue(Pop()); |
3397 | 3379 |
3398 } else { | 3380 } else { |
3399 // Keyed property. | 3381 // Keyed property. |
3400 VISIT_FOR_VALUE(prop->obj()); | 3382 VISIT_FOR_VALUE(prop->obj()); |
3401 VISIT_FOR_VALUE(prop->key()); | 3383 VISIT_FOR_VALUE(prop->key()); |
3402 HValue* obj = environment()->ExpressionStackAt(1); | 3384 HValue* obj = environment()->ExpressionStackAt(1); |
3403 HValue* key = environment()->ExpressionStackAt(0); | 3385 HValue* key = environment()->ExpressionStackAt(0); |
3404 | 3386 |
3405 bool is_fast_elements = prop->IsMonomorphic() && | 3387 HInstruction* load = BuildLoadKeyed(obj, key, prop); |
3406 prop->GetMonomorphicReceiverType()->has_fast_elements(); | |
3407 HInstruction* load = is_fast_elements | |
3408 ? BuildLoadKeyedFastElement(obj, key, prop) | |
3409 : BuildLoadKeyedGeneric(obj, key); | |
3410 PushAndAdd(load); | 3388 PushAndAdd(load); |
3411 if (load->HasSideEffects()) AddSimulate(expr->CompoundLoadId()); | 3389 if (load->HasSideEffects()) AddSimulate(expr->CompoundLoadId()); |
3412 | 3390 |
3413 VISIT_FOR_VALUE(expr->value()); | 3391 VISIT_FOR_VALUE(expr->value()); |
3414 HValue* right = Pop(); | 3392 HValue* right = Pop(); |
3415 HValue* left = Pop(); | 3393 HValue* left = Pop(); |
3416 | 3394 |
3417 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 3395 HInstruction* instr = BuildBinaryOperation(operation, left, right); |
3418 PushAndAdd(instr); | 3396 PushAndAdd(instr); |
3419 if (instr->HasSideEffects()) AddSimulate(operation->id()); | 3397 if (instr->HasSideEffects()) AddSimulate(operation->id()); |
3420 | 3398 |
3421 HInstruction* store = is_fast_elements | 3399 expr->RecordTypeFeedback(oracle()); |
3422 ? BuildStoreKeyedFastElement(obj, key, instr, prop) | 3400 HInstruction* store = BuildStoreKeyed(obj, key, instr, expr); |
3423 : BuildStoreKeyedGeneric(obj, key, instr); | |
3424 AddInstruction(store); | 3401 AddInstruction(store); |
3425 // Drop the simulated receiver, key, and value. Return the value. | 3402 // Drop the simulated receiver, key, and value. Return the value. |
3426 Drop(3); | 3403 Drop(3); |
3427 Push(instr); | 3404 Push(instr); |
3428 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 3405 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
3429 ast_context()->ReturnValue(Pop()); | 3406 ast_context()->ReturnValue(Pop()); |
3430 } | 3407 } |
3431 | 3408 |
3432 } else { | 3409 } else { |
3433 BAILOUT("invalid lhs in compound assignment"); | 3410 BAILOUT("invalid lhs in compound assignment"); |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3616 HLoadElements* elements = new(zone()) HLoadElements(object); | 3593 HLoadElements* elements = new(zone()) HLoadElements(object); |
3617 AddInstruction(elements); | 3594 AddInstruction(elements); |
3618 HInstruction* length = new(zone()) HExternalArrayLength(elements); | 3595 HInstruction* length = new(zone()) HExternalArrayLength(elements); |
3619 AddInstruction(length); | 3596 AddInstruction(length); |
3620 AddInstruction(new(zone()) HBoundsCheck(key, length)); | 3597 AddInstruction(new(zone()) HBoundsCheck(key, length)); |
3621 HLoadExternalArrayPointer* external_elements = | 3598 HLoadExternalArrayPointer* external_elements = |
3622 new(zone()) HLoadExternalArrayPointer(elements); | 3599 new(zone()) HLoadExternalArrayPointer(elements); |
3623 AddInstruction(external_elements); | 3600 AddInstruction(external_elements); |
3624 HLoadKeyedSpecializedArrayElement* pixel_array_value = | 3601 HLoadKeyedSpecializedArrayElement* pixel_array_value = |
3625 new(zone()) HLoadKeyedSpecializedArrayElement( | 3602 new(zone()) HLoadKeyedSpecializedArrayElement( |
3626 external_elements, key, expr->GetExternalArrayType()); | 3603 external_elements, key, expr->external_array_type()); |
3627 return pixel_array_value; | 3604 return pixel_array_value; |
3628 } | 3605 } |
3629 | 3606 |
3630 | 3607 |
| 3608 HInstruction* HGraphBuilder::BuildLoadKeyed(HValue* obj, |
| 3609 HValue* key, |
| 3610 Property* prop) { |
| 3611 if (prop->IsMonomorphic()) { |
| 3612 Handle<Map> receiver_type(prop->GetMonomorphicReceiverType()); |
| 3613 // An object has either fast elements or pixel array elements, but never |
| 3614 // both. Pixel array maps that are assigned to pixel array elements are |
| 3615 // always created with the fast elements flag cleared. |
| 3616 if (receiver_type->has_external_array_elements()) { |
| 3617 return BuildLoadKeyedSpecializedArrayElement(obj, key, prop); |
| 3618 } else if (receiver_type->has_fast_elements()) { |
| 3619 return BuildLoadKeyedFastElement(obj, key, prop); |
| 3620 } |
| 3621 } |
| 3622 return BuildLoadKeyedGeneric(obj, key); |
| 3623 } |
| 3624 |
| 3625 |
3631 HInstruction* HGraphBuilder::BuildStoreKeyedGeneric(HValue* object, | 3626 HInstruction* HGraphBuilder::BuildStoreKeyedGeneric(HValue* object, |
3632 HValue* key, | 3627 HValue* key, |
3633 HValue* value) { | 3628 HValue* value) { |
3634 HContext* context = new(zone()) HContext; | 3629 HContext* context = new(zone()) HContext; |
3635 AddInstruction(context); | 3630 AddInstruction(context); |
3636 return new(zone()) HStoreKeyedGeneric(context, object, key, value); | 3631 return new(zone()) HStoreKeyedGeneric(context, object, key, value); |
3637 } | 3632 } |
3638 | 3633 |
3639 | 3634 |
3640 HInstruction* HGraphBuilder::BuildStoreKeyedFastElement(HValue* object, | 3635 HInstruction* HGraphBuilder::BuildStoreKeyedFastElement(HValue* object, |
(...skipping 17 matching lines...) Expand all Loading... |
3658 } | 3653 } |
3659 AddInstruction(new(zone()) HBoundsCheck(key, length)); | 3654 AddInstruction(new(zone()) HBoundsCheck(key, length)); |
3660 return new(zone()) HStoreKeyedFastElement(elements, key, val); | 3655 return new(zone()) HStoreKeyedFastElement(elements, key, val); |
3661 } | 3656 } |
3662 | 3657 |
3663 | 3658 |
3664 HInstruction* HGraphBuilder::BuildStoreKeyedSpecializedArrayElement( | 3659 HInstruction* HGraphBuilder::BuildStoreKeyedSpecializedArrayElement( |
3665 HValue* object, | 3660 HValue* object, |
3666 HValue* key, | 3661 HValue* key, |
3667 HValue* val, | 3662 HValue* val, |
3668 Assignment* expr) { | 3663 Expression* expr) { |
3669 ASSERT(expr->IsMonomorphic()); | 3664 ASSERT(expr->IsMonomorphic()); |
3670 AddInstruction(new(zone()) HCheckNonSmi(object)); | 3665 AddInstruction(new(zone()) HCheckNonSmi(object)); |
3671 Handle<Map> map = expr->GetMonomorphicReceiverType(); | 3666 Handle<Map> map = expr->GetMonomorphicReceiverType(); |
3672 ASSERT(!map->has_fast_elements()); | 3667 ASSERT(!map->has_fast_elements()); |
3673 ASSERT(map->has_external_array_elements()); | 3668 ASSERT(map->has_external_array_elements()); |
3674 AddInstruction(new(zone()) HCheckMap(object, map)); | 3669 AddInstruction(new(zone()) HCheckMap(object, map)); |
3675 HLoadElements* elements = new(zone()) HLoadElements(object); | 3670 HLoadElements* elements = new(zone()) HLoadElements(object); |
3676 AddInstruction(elements); | 3671 AddInstruction(elements); |
3677 HInstruction* length = AddInstruction( | 3672 HInstruction* length = AddInstruction( |
3678 new(zone()) HExternalArrayLength(elements)); | 3673 new(zone()) HExternalArrayLength(elements)); |
3679 AddInstruction(new(zone()) HBoundsCheck(key, length)); | 3674 AddInstruction(new(zone()) HBoundsCheck(key, length)); |
3680 HLoadExternalArrayPointer* external_elements = | 3675 HLoadExternalArrayPointer* external_elements = |
3681 new(zone()) HLoadExternalArrayPointer(elements); | 3676 new(zone()) HLoadExternalArrayPointer(elements); |
3682 AddInstruction(external_elements); | 3677 AddInstruction(external_elements); |
3683 return new(zone()) HStoreKeyedSpecializedArrayElement( | 3678 return new(zone()) HStoreKeyedSpecializedArrayElement( |
3684 external_elements, | 3679 external_elements, |
3685 key, | 3680 key, |
3686 val, | 3681 val, |
3687 expr->GetExternalArrayType()); | 3682 expr->external_array_type()); |
3688 } | 3683 } |
3689 | 3684 |
3690 | 3685 |
| 3686 HInstruction* HGraphBuilder::BuildStoreKeyed(HValue* object, |
| 3687 HValue* key, |
| 3688 HValue* value, |
| 3689 Expression* expr) { |
| 3690 if (expr->IsMonomorphic()) { |
| 3691 Handle<Map> receiver_type(expr->GetMonomorphicReceiverType()); |
| 3692 // An object has either fast elements or external array elements, but |
| 3693 // never both. Pixel array maps that are assigned to pixel array elements |
| 3694 // are always created with the fast elements flag cleared. |
| 3695 if (receiver_type->has_external_array_elements()) { |
| 3696 return BuildStoreKeyedSpecializedArrayElement(object, |
| 3697 key, |
| 3698 value, |
| 3699 expr); |
| 3700 } else if (receiver_type->has_fast_elements()) { |
| 3701 return BuildStoreKeyedFastElement(object, key, value, expr); |
| 3702 } |
| 3703 } |
| 3704 return BuildStoreKeyedGeneric(object, key, value); |
| 3705 } |
| 3706 |
| 3707 |
3691 bool HGraphBuilder::TryArgumentsAccess(Property* expr) { | 3708 bool HGraphBuilder::TryArgumentsAccess(Property* expr) { |
3692 VariableProxy* proxy = expr->obj()->AsVariableProxy(); | 3709 VariableProxy* proxy = expr->obj()->AsVariableProxy(); |
3693 if (proxy == NULL) return false; | 3710 if (proxy == NULL) return false; |
3694 if (!proxy->var()->IsStackAllocated()) return false; | 3711 if (!proxy->var()->IsStackAllocated()) return false; |
3695 if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) { | 3712 if (!environment()->Lookup(proxy->var())->CheckFlag(HValue::kIsArguments)) { |
3696 return false; | 3713 return false; |
3697 } | 3714 } |
3698 | 3715 |
3699 HInstruction* result = NULL; | 3716 HInstruction* result = NULL; |
3700 if (expr->key()->IsPropertyName()) { | 3717 if (expr->key()->IsPropertyName()) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3768 instr = new(zone()) HLoadNamedFieldPolymorphic(obj, types, name); | 3785 instr = new(zone()) HLoadNamedFieldPolymorphic(obj, types, name); |
3769 } else { | 3786 } else { |
3770 instr = BuildLoadNamedGeneric(obj, expr); | 3787 instr = BuildLoadNamedGeneric(obj, expr); |
3771 } | 3788 } |
3772 | 3789 |
3773 } else { | 3790 } else { |
3774 VISIT_FOR_VALUE(expr->key()); | 3791 VISIT_FOR_VALUE(expr->key()); |
3775 | 3792 |
3776 HValue* key = Pop(); | 3793 HValue* key = Pop(); |
3777 HValue* obj = Pop(); | 3794 HValue* obj = Pop(); |
3778 | 3795 instr = BuildLoadKeyed(obj, key, expr); |
3779 if (expr->IsMonomorphic()) { | |
3780 Handle<Map> receiver_type(expr->GetMonomorphicReceiverType()); | |
3781 // An object has either fast elements or pixel array elements, but never | |
3782 // both. Pixel array maps that are assigned to pixel array elements are | |
3783 // always created with the fast elements flag cleared. | |
3784 if (receiver_type->has_external_array_elements()) { | |
3785 instr = BuildLoadKeyedSpecializedArrayElement(obj, key, expr); | |
3786 } else if (receiver_type->has_fast_elements()) { | |
3787 instr = BuildLoadKeyedFastElement(obj, key, expr); | |
3788 } | |
3789 } | |
3790 if (instr == NULL) { | |
3791 instr = BuildLoadKeyedGeneric(obj, key); | |
3792 } | |
3793 } | 3796 } |
3794 instr->set_position(expr->position()); | 3797 instr->set_position(expr->position()); |
3795 ast_context()->ReturnInstruction(instr, expr->id()); | 3798 ast_context()->ReturnInstruction(instr, expr->id()); |
3796 } | 3799 } |
3797 | 3800 |
3798 | 3801 |
3799 void HGraphBuilder::AddCheckConstantFunction(Call* expr, | 3802 void HGraphBuilder::AddCheckConstantFunction(Call* expr, |
3800 HValue* receiver, | 3803 HValue* receiver, |
3801 Handle<Map> receiver_map, | 3804 Handle<Map> receiver_map, |
3802 bool smi_and_map_check) { | 3805 bool smi_and_map_check) { |
(...skipping 908 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4711 // Match the full code generator stack by simulate an extra stack element | 4714 // Match the full code generator stack by simulate an extra stack element |
4712 // for postfix operations in a non-effect context. | 4715 // for postfix operations in a non-effect context. |
4713 bool has_extra = expr->is_postfix() && !ast_context()->IsEffect(); | 4716 bool has_extra = expr->is_postfix() && !ast_context()->IsEffect(); |
4714 if (has_extra) Push(graph_->GetConstantUndefined()); | 4717 if (has_extra) Push(graph_->GetConstantUndefined()); |
4715 | 4718 |
4716 VISIT_FOR_VALUE(prop->obj()); | 4719 VISIT_FOR_VALUE(prop->obj()); |
4717 VISIT_FOR_VALUE(prop->key()); | 4720 VISIT_FOR_VALUE(prop->key()); |
4718 HValue* obj = environment()->ExpressionStackAt(1); | 4721 HValue* obj = environment()->ExpressionStackAt(1); |
4719 HValue* key = environment()->ExpressionStackAt(0); | 4722 HValue* key = environment()->ExpressionStackAt(0); |
4720 | 4723 |
4721 bool is_fast_elements = prop->IsMonomorphic() && | 4724 HInstruction* load = BuildLoadKeyed(obj, key, prop); |
4722 prop->GetMonomorphicReceiverType()->has_fast_elements(); | |
4723 | |
4724 HInstruction* load = is_fast_elements | |
4725 ? BuildLoadKeyedFastElement(obj, key, prop) | |
4726 : BuildLoadKeyedGeneric(obj, key); | |
4727 PushAndAdd(load); | 4725 PushAndAdd(load); |
4728 if (load->HasSideEffects()) AddSimulate(expr->CountId()); | 4726 if (load->HasSideEffects()) AddSimulate(expr->CountId()); |
4729 | 4727 |
4730 HValue* before = Pop(); | 4728 HValue* before = Pop(); |
4731 // There is no deoptimization to after the increment, so we don't need | 4729 // There is no deoptimization to after the increment, so we don't need |
4732 // to simulate the expression stack after this instruction. | 4730 // to simulate the expression stack after this instruction. |
4733 HInstruction* after = BuildIncrement(before, inc); | 4731 HInstruction* after = BuildIncrement(before, inc); |
4734 AddInstruction(after); | 4732 AddInstruction(after); |
4735 | 4733 |
4736 HInstruction* store = is_fast_elements | 4734 expr->RecordTypeFeedback(oracle()); |
4737 ? BuildStoreKeyedFastElement(obj, key, after, prop) | 4735 HInstruction* store = BuildStoreKeyed(obj, key, after, expr); |
4738 : BuildStoreKeyedGeneric(obj, key, after); | |
4739 AddInstruction(store); | 4736 AddInstruction(store); |
4740 | 4737 |
4741 // Drop the key from the bailout environment. Overwrite the receiver | 4738 // Drop the key from the bailout environment. Overwrite the receiver |
4742 // with the result of the operation, and the placeholder with the | 4739 // with the result of the operation, and the placeholder with the |
4743 // original value if necessary. | 4740 // original value if necessary. |
4744 Drop(1); | 4741 Drop(1); |
4745 environment()->SetExpressionStackAt(0, after); | 4742 environment()->SetExpressionStackAt(0, after); |
4746 if (has_extra) environment()->SetExpressionStackAt(1, before); | 4743 if (has_extra) environment()->SetExpressionStackAt(1, before); |
4747 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 4744 if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
4748 Drop(has_extra ? 2 : 1); | 4745 Drop(has_extra ? 2 : 1); |
(...skipping 1245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5994 } | 5991 } |
5995 } | 5992 } |
5996 | 5993 |
5997 #ifdef DEBUG | 5994 #ifdef DEBUG |
5998 if (graph_ != NULL) graph_->Verify(); | 5995 if (graph_ != NULL) graph_->Verify(); |
5999 if (allocator_ != NULL) allocator_->Verify(); | 5996 if (allocator_ != NULL) allocator_->Verify(); |
6000 #endif | 5997 #endif |
6001 } | 5998 } |
6002 | 5999 |
6003 } } // namespace v8::internal | 6000 } } // namespace v8::internal |
OLD | NEW |