| 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 |