Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/hydrogen.cc

Issue 6805005: Fix opmitized external array access for compound assignments (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: final version Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/type-info.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/type-info.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698