| 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 2230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2241 HStackCheckEliminator sce(graph()); | 2241 HStackCheckEliminator sce(graph()); |
| 2242 sce.Process(); | 2242 sce.Process(); |
| 2243 | 2243 |
| 2244 // Perform common subexpression elimination and loop-invariant code motion. | 2244 // Perform common subexpression elimination and loop-invariant code motion. |
| 2245 if (FLAG_use_gvn) { | 2245 if (FLAG_use_gvn) { |
| 2246 HPhase phase("Global value numbering", graph()); | 2246 HPhase phase("Global value numbering", graph()); |
| 2247 HGlobalValueNumberer gvn(graph(), info()); | 2247 HGlobalValueNumberer gvn(graph(), info()); |
| 2248 gvn.Analyze(); | 2248 gvn.Analyze(); |
| 2249 } | 2249 } |
| 2250 | 2250 |
| 2251 // Replace the results of check instructions with the original value, if the |
| 2252 // result is used. This is safe now, since we don't do code motion after this |
| 2253 // point. It enables better register allocation since the value produced by |
| 2254 // check instructions is really a copy of the original value. |
| 2255 graph()->ReplaceCheckedValues(); |
| 2256 |
| 2251 return graph(); | 2257 return graph(); |
| 2252 } | 2258 } |
| 2253 | 2259 |
| 2254 | 2260 |
| 2261 void HGraph::ReplaceCheckedValues() { |
| 2262 HPhase phase("Replace checked values", this); |
| 2263 for (int i = 0; i < blocks()->length(); ++i) { |
| 2264 HInstruction* instr = blocks()->at(i)->first(); |
| 2265 while (instr != NULL) { |
| 2266 if (instr->IsBoundsCheck()) { |
| 2267 // Replace all uses of the checked value with the original input. |
| 2268 ASSERT(instr->uses()->length() > 0); |
| 2269 instr->ReplaceValue(HBoundsCheck::cast(instr)->index()); |
| 2270 } |
| 2271 instr = instr->next(); |
| 2272 } |
| 2273 } |
| 2274 } |
| 2275 |
| 2276 |
| 2255 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { | 2277 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { |
| 2256 ASSERT(current_block() != NULL); | 2278 ASSERT(current_block() != NULL); |
| 2257 current_block()->AddInstruction(instr); | 2279 current_block()->AddInstruction(instr); |
| 2258 return instr; | 2280 return instr; |
| 2259 } | 2281 } |
| 2260 | 2282 |
| 2261 | 2283 |
| 2262 void HGraphBuilder::AddSimulate(int id) { | 2284 void HGraphBuilder::AddSimulate(int id) { |
| 2263 ASSERT(current_block() != NULL); | 2285 ASSERT(current_block() != NULL); |
| 2264 current_block()->AddSimulate(id); | 2286 current_block()->AddSimulate(id); |
| (...skipping 1308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3573 HValue* key, | 3595 HValue* key, |
| 3574 Property* expr) { | 3596 Property* expr) { |
| 3575 ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic()); | 3597 ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic()); |
| 3576 AddInstruction(new(zone()) HCheckNonSmi(object)); | 3598 AddInstruction(new(zone()) HCheckNonSmi(object)); |
| 3577 Handle<Map> map = expr->GetMonomorphicReceiverType(); | 3599 Handle<Map> map = expr->GetMonomorphicReceiverType(); |
| 3578 ASSERT(map->has_fast_elements()); | 3600 ASSERT(map->has_fast_elements()); |
| 3579 AddInstruction(new(zone()) HCheckMap(object, map)); | 3601 AddInstruction(new(zone()) HCheckMap(object, map)); |
| 3580 bool is_array = (map->instance_type() == JS_ARRAY_TYPE); | 3602 bool is_array = (map->instance_type() == JS_ARRAY_TYPE); |
| 3581 HLoadElements* elements = new(zone()) HLoadElements(object); | 3603 HLoadElements* elements = new(zone()) HLoadElements(object); |
| 3582 HInstruction* length = NULL; | 3604 HInstruction* length = NULL; |
| 3605 HInstruction* checked_key = NULL; |
| 3583 if (is_array) { | 3606 if (is_array) { |
| 3584 length = AddInstruction(new(zone()) HJSArrayLength(object)); | 3607 length = AddInstruction(new(zone()) HJSArrayLength(object)); |
| 3585 AddInstruction(new(zone()) HBoundsCheck(key, length)); | 3608 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
| 3586 AddInstruction(elements); | 3609 AddInstruction(elements); |
| 3587 } else { | 3610 } else { |
| 3588 AddInstruction(elements); | 3611 AddInstruction(elements); |
| 3589 length = AddInstruction(new(zone()) HFixedArrayLength(elements)); | 3612 length = AddInstruction(new(zone()) HFixedArrayLength(elements)); |
| 3590 AddInstruction(new(zone()) HBoundsCheck(key, length)); | 3613 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
| 3591 } | 3614 } |
| 3592 return new(zone()) HLoadKeyedFastElement(elements, key); | 3615 return new(zone()) HLoadKeyedFastElement(elements, checked_key); |
| 3593 } | 3616 } |
| 3594 | 3617 |
| 3595 | 3618 |
| 3596 HInstruction* HGraphBuilder::BuildLoadKeyedSpecializedArrayElement( | 3619 HInstruction* HGraphBuilder::BuildLoadKeyedSpecializedArrayElement( |
| 3597 HValue* object, | 3620 HValue* object, |
| 3598 HValue* key, | 3621 HValue* key, |
| 3599 Property* expr) { | 3622 Property* expr) { |
| 3600 ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic()); | 3623 ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic()); |
| 3601 AddInstruction(new(zone()) HCheckNonSmi(object)); | 3624 AddInstruction(new(zone()) HCheckNonSmi(object)); |
| 3602 Handle<Map> map = expr->GetMonomorphicReceiverType(); | 3625 Handle<Map> map = expr->GetMonomorphicReceiverType(); |
| 3603 ASSERT(!map->has_fast_elements()); | 3626 ASSERT(!map->has_fast_elements()); |
| 3604 ASSERT(map->has_external_array_elements()); | 3627 ASSERT(map->has_external_array_elements()); |
| 3605 AddInstruction(new(zone()) HCheckMap(object, map)); | 3628 AddInstruction(new(zone()) HCheckMap(object, map)); |
| 3606 HLoadElements* elements = new(zone()) HLoadElements(object); | 3629 HLoadElements* elements = new(zone()) HLoadElements(object); |
| 3607 AddInstruction(elements); | 3630 AddInstruction(elements); |
| 3608 HInstruction* length = new(zone()) HExternalArrayLength(elements); | 3631 HInstruction* length = new(zone()) HExternalArrayLength(elements); |
| 3609 AddInstruction(length); | 3632 AddInstruction(length); |
| 3610 AddInstruction(new(zone()) HBoundsCheck(key, length)); | 3633 HInstruction* checked_key = |
| 3634 AddInstruction(new(zone()) HBoundsCheck(key, length)); |
| 3611 HLoadExternalArrayPointer* external_elements = | 3635 HLoadExternalArrayPointer* external_elements = |
| 3612 new(zone()) HLoadExternalArrayPointer(elements); | 3636 new(zone()) HLoadExternalArrayPointer(elements); |
| 3613 AddInstruction(external_elements); | 3637 AddInstruction(external_elements); |
| 3614 HLoadKeyedSpecializedArrayElement* pixel_array_value = | 3638 HLoadKeyedSpecializedArrayElement* pixel_array_value = |
| 3615 new(zone()) HLoadKeyedSpecializedArrayElement( | 3639 new(zone()) HLoadKeyedSpecializedArrayElement( |
| 3616 external_elements, key, expr->external_array_type()); | 3640 external_elements, checked_key, expr->external_array_type()); |
| 3617 return pixel_array_value; | 3641 return pixel_array_value; |
| 3618 } | 3642 } |
| 3619 | 3643 |
| 3620 | 3644 |
| 3621 HInstruction* HGraphBuilder::BuildLoadKeyed(HValue* obj, | 3645 HInstruction* HGraphBuilder::BuildLoadKeyed(HValue* obj, |
| 3622 HValue* key, | 3646 HValue* key, |
| 3623 Property* prop) { | 3647 Property* prop) { |
| 3624 if (prop->IsMonomorphic()) { | 3648 if (prop->IsMonomorphic()) { |
| 3625 Handle<Map> receiver_type(prop->GetMonomorphicReceiverType()); | 3649 Handle<Map> receiver_type(prop->GetMonomorphicReceiverType()); |
| 3626 // An object has either fast elements or pixel array elements, but never | 3650 // An object has either fast elements or pixel array elements, but never |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3662 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); | 3686 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); |
| 3663 AddInstruction(new(zone()) HCheckMap( | 3687 AddInstruction(new(zone()) HCheckMap( |
| 3664 elements, isolate()->factory()->fixed_array_map())); | 3688 elements, isolate()->factory()->fixed_array_map())); |
| 3665 bool is_array = (map->instance_type() == JS_ARRAY_TYPE); | 3689 bool is_array = (map->instance_type() == JS_ARRAY_TYPE); |
| 3666 HInstruction* length = NULL; | 3690 HInstruction* length = NULL; |
| 3667 if (is_array) { | 3691 if (is_array) { |
| 3668 length = AddInstruction(new(zone()) HJSArrayLength(object)); | 3692 length = AddInstruction(new(zone()) HJSArrayLength(object)); |
| 3669 } else { | 3693 } else { |
| 3670 length = AddInstruction(new(zone()) HFixedArrayLength(elements)); | 3694 length = AddInstruction(new(zone()) HFixedArrayLength(elements)); |
| 3671 } | 3695 } |
| 3672 AddInstruction(new(zone()) HBoundsCheck(key, length)); | 3696 HInstruction* checked_key = |
| 3673 return new(zone()) HStoreKeyedFastElement(elements, key, val); | 3697 AddInstruction(new(zone()) HBoundsCheck(key, length)); |
| 3698 return new(zone()) HStoreKeyedFastElement(elements, checked_key, val); |
| 3674 } | 3699 } |
| 3675 | 3700 |
| 3676 | 3701 |
| 3677 HInstruction* HGraphBuilder::BuildStoreKeyedSpecializedArrayElement( | 3702 HInstruction* HGraphBuilder::BuildStoreKeyedSpecializedArrayElement( |
| 3678 HValue* object, | 3703 HValue* object, |
| 3679 HValue* key, | 3704 HValue* key, |
| 3680 HValue* val, | 3705 HValue* val, |
| 3681 Expression* expr) { | 3706 Expression* expr) { |
| 3682 ASSERT(expr->IsMonomorphic()); | 3707 ASSERT(expr->IsMonomorphic()); |
| 3683 AddInstruction(new(zone()) HCheckNonSmi(object)); | 3708 AddInstruction(new(zone()) HCheckNonSmi(object)); |
| 3684 Handle<Map> map = expr->GetMonomorphicReceiverType(); | 3709 Handle<Map> map = expr->GetMonomorphicReceiverType(); |
| 3685 ASSERT(!map->has_fast_elements()); | 3710 ASSERT(!map->has_fast_elements()); |
| 3686 ASSERT(map->has_external_array_elements()); | 3711 ASSERT(map->has_external_array_elements()); |
| 3687 AddInstruction(new(zone()) HCheckMap(object, map)); | 3712 AddInstruction(new(zone()) HCheckMap(object, map)); |
| 3688 HLoadElements* elements = new(zone()) HLoadElements(object); | 3713 HLoadElements* elements = new(zone()) HLoadElements(object); |
| 3689 AddInstruction(elements); | 3714 AddInstruction(elements); |
| 3690 HInstruction* length = AddInstruction( | 3715 HInstruction* length = AddInstruction( |
| 3691 new(zone()) HExternalArrayLength(elements)); | 3716 new(zone()) HExternalArrayLength(elements)); |
| 3692 AddInstruction(new(zone()) HBoundsCheck(key, length)); | 3717 HInstruction* checked_key = |
| 3718 AddInstruction(new(zone()) HBoundsCheck(key, length)); |
| 3693 HLoadExternalArrayPointer* external_elements = | 3719 HLoadExternalArrayPointer* external_elements = |
| 3694 new(zone()) HLoadExternalArrayPointer(elements); | 3720 new(zone()) HLoadExternalArrayPointer(elements); |
| 3695 AddInstruction(external_elements); | 3721 AddInstruction(external_elements); |
| 3696 return new(zone()) HStoreKeyedSpecializedArrayElement( | 3722 return new(zone()) HStoreKeyedSpecializedArrayElement( |
| 3697 external_elements, | 3723 external_elements, |
| 3698 key, | 3724 checked_key, |
| 3699 val, | 3725 val, |
| 3700 expr->external_array_type()); | 3726 expr->external_array_type()); |
| 3701 } | 3727 } |
| 3702 | 3728 |
| 3703 | 3729 |
| 3704 HInstruction* HGraphBuilder::BuildStoreKeyed(HValue* object, | 3730 HInstruction* HGraphBuilder::BuildStoreKeyed(HValue* object, |
| 3705 HValue* key, | 3731 HValue* key, |
| 3706 HValue* value, | 3732 HValue* value, |
| 3707 Expression* expr) { | 3733 Expression* expr) { |
| 3708 if (expr->IsMonomorphic()) { | 3734 if (expr->IsMonomorphic()) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 3739 result = new(zone()) HArgumentsLength(elements); | 3765 result = new(zone()) HArgumentsLength(elements); |
| 3740 } else { | 3766 } else { |
| 3741 Push(graph()->GetArgumentsObject()); | 3767 Push(graph()->GetArgumentsObject()); |
| 3742 VisitForValue(expr->key()); | 3768 VisitForValue(expr->key()); |
| 3743 if (HasStackOverflow()) return false; | 3769 if (HasStackOverflow()) return false; |
| 3744 HValue* key = Pop(); | 3770 HValue* key = Pop(); |
| 3745 Drop(1); // Arguments object. | 3771 Drop(1); // Arguments object. |
| 3746 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements); | 3772 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements); |
| 3747 HInstruction* length = AddInstruction( | 3773 HInstruction* length = AddInstruction( |
| 3748 new(zone()) HArgumentsLength(elements)); | 3774 new(zone()) HArgumentsLength(elements)); |
| 3749 AddInstruction(new(zone()) HBoundsCheck(key, length)); | 3775 HInstruction* checked_key = |
| 3750 result = new(zone()) HAccessArgumentsAt(elements, length, key); | 3776 AddInstruction(new(zone()) HBoundsCheck(key, length)); |
| 3777 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); |
| 3751 } | 3778 } |
| 3752 ast_context()->ReturnInstruction(result, expr->id()); | 3779 ast_context()->ReturnInstruction(result, expr->id()); |
| 3753 return true; | 3780 return true; |
| 3754 } | 3781 } |
| 3755 | 3782 |
| 3756 | 3783 |
| 3757 void HGraphBuilder::VisitProperty(Property* expr) { | 3784 void HGraphBuilder::VisitProperty(Property* expr) { |
| 3758 expr->RecordTypeFeedback(oracle()); | 3785 expr->RecordTypeFeedback(oracle()); |
| 3759 | 3786 |
| 3760 if (TryArgumentsAccess(expr)) return; | 3787 if (TryArgumentsAccess(expr)) return; |
| (...skipping 1010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4771 } | 4798 } |
| 4772 | 4799 |
| 4773 | 4800 |
| 4774 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* string, | 4801 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* string, |
| 4775 HValue* index) { | 4802 HValue* index) { |
| 4776 AddInstruction(new(zone()) HCheckNonSmi(string)); | 4803 AddInstruction(new(zone()) HCheckNonSmi(string)); |
| 4777 AddInstruction(new(zone()) HCheckInstanceType( | 4804 AddInstruction(new(zone()) HCheckInstanceType( |
| 4778 string, FIRST_STRING_TYPE, LAST_STRING_TYPE)); | 4805 string, FIRST_STRING_TYPE, LAST_STRING_TYPE)); |
| 4779 HStringLength* length = new(zone()) HStringLength(string); | 4806 HStringLength* length = new(zone()) HStringLength(string); |
| 4780 AddInstruction(length); | 4807 AddInstruction(length); |
| 4781 AddInstruction(new(zone()) HBoundsCheck(index, length)); | 4808 HInstruction* checked_index = |
| 4782 return new(zone()) HStringCharCodeAt(string, index); | 4809 AddInstruction(new(zone()) HBoundsCheck(index, length)); |
| 4810 return new(zone()) HStringCharCodeAt(string, checked_index); |
| 4783 } | 4811 } |
| 4784 | 4812 |
| 4785 | 4813 |
| 4786 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, | 4814 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, |
| 4787 HValue* left, | 4815 HValue* left, |
| 4788 HValue* right) { | 4816 HValue* right) { |
| 4789 HInstruction* instr = NULL; | 4817 HInstruction* instr = NULL; |
| 4790 switch (expr->op()) { | 4818 switch (expr->op()) { |
| 4791 case Token::ADD: | 4819 case Token::ADD: |
| 4792 instr = new(zone()) HAdd(left, right); | 4820 instr = new(zone()) HAdd(left, right); |
| (...skipping 1216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6009 } | 6037 } |
| 6010 } | 6038 } |
| 6011 | 6039 |
| 6012 #ifdef DEBUG | 6040 #ifdef DEBUG |
| 6013 if (graph_ != NULL) graph_->Verify(); | 6041 if (graph_ != NULL) graph_->Verify(); |
| 6014 if (allocator_ != NULL) allocator_->Verify(); | 6042 if (allocator_ != NULL) allocator_->Verify(); |
| 6015 #endif | 6043 #endif |
| 6016 } | 6044 } |
| 6017 | 6045 |
| 6018 } } // namespace v8::internal | 6046 } } // namespace v8::internal |
| OLD | NEW |