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

Side by Side Diff: src/codegen-ia32.cc

Issue 10945: Experimental: periodic merge to the experimental branch from... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: Created 12 years, 1 month 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/codegen-arm.cc ('k') | src/ic-arm.cc » ('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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 3674 matching lines...) Expand 10 before | Expand all | Expand 10 after
3685 3685
3686 3686
3687 void CodeGenerator::VisitCompareOperation(CompareOperation* node) { 3687 void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
3688 Comment cmnt(masm_, "[ CompareOperation"); 3688 Comment cmnt(masm_, "[ CompareOperation");
3689 3689
3690 // Get the expressions from the node. 3690 // Get the expressions from the node.
3691 Expression* left = node->left(); 3691 Expression* left = node->left();
3692 Expression* right = node->right(); 3692 Expression* right = node->right();
3693 Token::Value op = node->op(); 3693 Token::Value op = node->op();
3694 3694
3695 // NOTE: To make null checks efficient, we check if either left or 3695 // To make null checks efficient, we check if either left or right is the
3696 // right is the literal 'null'. If so, we optimize the code by 3696 // literal 'null'. If so, we optimize the code by inlining a null check
3697 // inlining a null check instead of calling the (very) general 3697 // instead of calling the (very) general runtime routine for checking
3698 // runtime routine for checking equality. 3698 // equality.
3699
3700 if (op == Token::EQ || op == Token::EQ_STRICT) { 3699 if (op == Token::EQ || op == Token::EQ_STRICT) {
3701 bool left_is_null = 3700 bool left_is_null =
3702 left->AsLiteral() != NULL && left->AsLiteral()->IsNull(); 3701 left->AsLiteral() != NULL && left->AsLiteral()->IsNull();
3703 bool right_is_null = 3702 bool right_is_null =
3704 right->AsLiteral() != NULL && right->AsLiteral()->IsNull(); 3703 right->AsLiteral() != NULL && right->AsLiteral()->IsNull();
3705 // The 'null' value is only equal to 'null' or 'undefined'. 3704 // The 'null' value can only be equal to 'null' or 'undefined'.
3706 if (left_is_null || right_is_null) { 3705 if (left_is_null || right_is_null) {
3707 Load(left_is_null ? right : left); 3706 Load(left_is_null ? right : left);
3708 JumpTarget exit(this);
3709 JumpTarget undetectable(this);
3710 frame_->Pop(eax); 3707 frame_->Pop(eax);
3711 __ cmp(eax, Factory::null_value()); 3708 __ cmp(eax, Factory::null_value());
3712 3709
3713 // The 'null' value is only equal to 'undefined' if using 3710 // The 'null' value is only equal to 'undefined' if using non-strict
3714 // non-strict comparisons. 3711 // comparisons.
3715 if (op != Token::EQ_STRICT) { 3712 if (op != Token::EQ_STRICT) {
3716 exit.Branch(equal); 3713 true_target()->Branch(equal);
3714
3717 __ cmp(eax, Factory::undefined_value()); 3715 __ cmp(eax, Factory::undefined_value());
3716 true_target()->Branch(equal);
3718 3717
3719 // NOTE: it can be an undetectable object.
3720 exit.Branch(equal);
3721 __ test(eax, Immediate(kSmiTagMask)); 3718 __ test(eax, Immediate(kSmiTagMask));
3719 false_target()->Branch(equal);
3722 3720
3723 undetectable.Branch(not_equal); 3721 // It can be an undetectable object.
3724 false_target()->Jump(); 3722 __ mov(eax, FieldOperand(eax, HeapObject::kMapOffset));
3725 3723 __ movzx_b(eax, FieldOperand(eax, Map::kBitFieldOffset));
3726 undetectable.Bind(); 3724 __ and_(eax, 1 << Map::kIsUndetectable);
3727 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); 3725 __ cmp(eax, 1 << Map::kIsUndetectable);
3728 __ movzx_b(ecx, FieldOperand(edx, Map::kBitFieldOffset));
3729 __ and_(ecx, 1 << Map::kIsUndetectable);
3730 __ cmp(ecx, 1 << Map::kIsUndetectable);
3731 } 3726 }
3732 3727
3733 exit.Bind();
3734
3735 cc_reg_ = equal; 3728 cc_reg_ = equal;
3736 return; 3729 return;
3737 } 3730 }
3738 } 3731 }
3739 3732
3740 // NOTE: To make typeof testing for natives implemented in 3733 // To make typeof testing for natives implemented in JavaScript really
3741 // JavaScript really efficient, we generate special code for 3734 // efficient, we generate special code for expressions of the form:
3742 // expressions of the form: 'typeof <expression> == <string>'. 3735 // 'typeof <expression> == <string>'.
3743
3744 UnaryOperation* operation = left->AsUnaryOperation(); 3736 UnaryOperation* operation = left->AsUnaryOperation();
3745 if ((op == Token::EQ || op == Token::EQ_STRICT) && 3737 if ((op == Token::EQ || op == Token::EQ_STRICT) &&
3746 (operation != NULL && operation->op() == Token::TYPEOF) && 3738 (operation != NULL && operation->op() == Token::TYPEOF) &&
3747 (right->AsLiteral() != NULL && 3739 (right->AsLiteral() != NULL &&
3748 right->AsLiteral()->handle()->IsString())) { 3740 right->AsLiteral()->handle()->IsString())) {
3749 Handle<String> check(String::cast(*right->AsLiteral()->handle())); 3741 Handle<String> check(String::cast(*right->AsLiteral()->handle()));
3750 3742
3751 // Load the operand, move it to register edx, and restore TOS. 3743 // Load the operand and move it to register edx.
3752 LoadTypeofExpression(operation->expression()); 3744 LoadTypeofExpression(operation->expression());
3753 frame_->Pop(edx); 3745 frame_->Pop(edx);
3754 3746
3755 if (check->Equals(Heap::number_symbol())) { 3747 if (check->Equals(Heap::number_symbol())) {
3756 __ test(edx, Immediate(kSmiTagMask)); 3748 __ test(edx, Immediate(kSmiTagMask));
3757 true_target()->Branch(zero); 3749 true_target()->Branch(zero);
3758 __ mov(edx, FieldOperand(edx, HeapObject::kMapOffset)); 3750 __ mov(edx, FieldOperand(edx, HeapObject::kMapOffset));
3759 __ cmp(edx, Factory::heap_number_map()); 3751 __ cmp(edx, Factory::heap_number_map());
3760 cc_reg_ = equal; 3752 cc_reg_ = equal;
3761 3753
3762 } else if (check->Equals(Heap::string_symbol())) { 3754 } else if (check->Equals(Heap::string_symbol())) {
3763 __ test(edx, Immediate(kSmiTagMask)); 3755 __ test(edx, Immediate(kSmiTagMask));
3764 false_target()->Branch(zero); 3756 false_target()->Branch(zero);
3765 3757
3766 __ mov(edx, FieldOperand(edx, HeapObject::kMapOffset)); 3758 __ mov(edx, FieldOperand(edx, HeapObject::kMapOffset));
3767 3759
3768 // NOTE: it might be an undetectable string object 3760 // It can be an undetectable string object.
3769 __ movzx_b(ecx, FieldOperand(edx, Map::kBitFieldOffset)); 3761 __ movzx_b(ecx, FieldOperand(edx, Map::kBitFieldOffset));
3770 __ and_(ecx, 1 << Map::kIsUndetectable); 3762 __ and_(ecx, 1 << Map::kIsUndetectable);
3771 __ cmp(ecx, 1 << Map::kIsUndetectable); 3763 __ cmp(ecx, 1 << Map::kIsUndetectable);
3772 false_target()->Branch(equal); 3764 false_target()->Branch(equal);
3773 3765
3774 __ movzx_b(ecx, FieldOperand(edx, Map::kInstanceTypeOffset)); 3766 __ movzx_b(ecx, FieldOperand(edx, Map::kInstanceTypeOffset));
3775 __ cmp(ecx, FIRST_NONSTRING_TYPE); 3767 __ cmp(ecx, FIRST_NONSTRING_TYPE);
3776 cc_reg_ = less; 3768 cc_reg_ = less;
3777 3769
3778 } else if (check->Equals(Heap::boolean_symbol())) { 3770 } else if (check->Equals(Heap::boolean_symbol())) {
3779 __ cmp(edx, Factory::true_value()); 3771 __ cmp(edx, Factory::true_value());
3780 true_target()->Branch(equal); 3772 true_target()->Branch(equal);
3781 __ cmp(edx, Factory::false_value()); 3773 __ cmp(edx, Factory::false_value());
3782 cc_reg_ = equal; 3774 cc_reg_ = equal;
3783 3775
3784 } else if (check->Equals(Heap::undefined_symbol())) { 3776 } else if (check->Equals(Heap::undefined_symbol())) {
3785 __ cmp(edx, Factory::undefined_value()); 3777 __ cmp(edx, Factory::undefined_value());
3786 true_target()->Branch(equal); 3778 true_target()->Branch(equal);
3787 3779
3788 __ test(edx, Immediate(kSmiTagMask)); 3780 __ test(edx, Immediate(kSmiTagMask));
3789 false_target()->Branch(zero); 3781 false_target()->Branch(zero);
3790 3782
3791 // NOTE: it can be an undetectable object. 3783 // It can be an undetectable object.
3792 __ mov(edx, FieldOperand(edx, HeapObject::kMapOffset)); 3784 __ mov(edx, FieldOperand(edx, HeapObject::kMapOffset));
3793 __ movzx_b(ecx, FieldOperand(edx, Map::kBitFieldOffset)); 3785 __ movzx_b(ecx, FieldOperand(edx, Map::kBitFieldOffset));
3794 __ and_(ecx, 1 << Map::kIsUndetectable); 3786 __ and_(ecx, 1 << Map::kIsUndetectable);
3795 __ cmp(ecx, 1 << Map::kIsUndetectable); 3787 __ cmp(ecx, 1 << Map::kIsUndetectable);
3796 3788
3797 cc_reg_ = equal; 3789 cc_reg_ = equal;
3798 3790
3799 } else if (check->Equals(Heap::function_symbol())) { 3791 } else if (check->Equals(Heap::function_symbol())) {
3800 __ test(edx, Immediate(kSmiTagMask)); 3792 __ test(edx, Immediate(kSmiTagMask));
3801 false_target()->Branch(zero); 3793 false_target()->Branch(zero);
3802 __ mov(edx, FieldOperand(edx, HeapObject::kMapOffset)); 3794 __ mov(edx, FieldOperand(edx, HeapObject::kMapOffset));
3803 __ movzx_b(edx, FieldOperand(edx, Map::kInstanceTypeOffset)); 3795 __ movzx_b(edx, FieldOperand(edx, Map::kInstanceTypeOffset));
3804 __ cmp(edx, JS_FUNCTION_TYPE); 3796 __ cmp(edx, JS_FUNCTION_TYPE);
3805 cc_reg_ = equal; 3797 cc_reg_ = equal;
3806 3798
3807 } else if (check->Equals(Heap::object_symbol())) { 3799 } else if (check->Equals(Heap::object_symbol())) {
3808 __ test(edx, Immediate(kSmiTagMask)); 3800 __ test(edx, Immediate(kSmiTagMask));
3809 false_target()->Branch(zero); 3801 false_target()->Branch(zero);
3810 3802
3811 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 3803 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
3812 __ cmp(edx, Factory::null_value()); 3804 __ cmp(edx, Factory::null_value());
3813 true_target()->Branch(equal); 3805 true_target()->Branch(equal);
3814 3806
3815 // NOTE: it might be an undetectable object 3807 // It can be an undetectable object.
3816 __ movzx_b(edx, FieldOperand(ecx, Map::kBitFieldOffset)); 3808 __ movzx_b(edx, FieldOperand(ecx, Map::kBitFieldOffset));
3817 __ and_(edx, 1 << Map::kIsUndetectable); 3809 __ and_(edx, 1 << Map::kIsUndetectable);
3818 __ cmp(edx, 1 << Map::kIsUndetectable); 3810 __ cmp(edx, 1 << Map::kIsUndetectable);
3819 false_target()->Branch(equal); 3811 false_target()->Branch(equal);
3820 3812
3821 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); 3813 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
3822 __ cmp(ecx, FIRST_JS_OBJECT_TYPE); 3814 __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
3823 false_target()->Branch(less); 3815 false_target()->Branch(less);
3824 __ cmp(ecx, LAST_JS_OBJECT_TYPE); 3816 __ cmp(ecx, LAST_JS_OBJECT_TYPE);
3825 cc_reg_ = less_equal; 3817 cc_reg_ = less_equal;
3826 3818
3827 } else { 3819 } else {
3828 // Uncommon case: Typeof testing against a string literal that 3820 // Uncommon case: typeof testing against a string literal that is
3829 // is never returned from the typeof operator. 3821 // never returned from the typeof operator.
3830 false_target()->Jump(); 3822 false_target()->Jump();
3831 // TODO(): Can this cause a problem because it is an expression that 3823 // TODO(): Can this cause a problem because it is an expression that
3832 // exits without a virtual frame in place? 3824 // exits without a virtual frame in place?
3833 } 3825 }
3834 return; 3826 return;
3835 } 3827 }
3836 3828
3837 Condition cc = no_condition; 3829 Condition cc = no_condition;
3838 bool strict = false; 3830 bool strict = false;
3839 switch (op) { 3831 switch (op) {
(...skipping 1489 matching lines...) Expand 10 before | Expand all | Expand 10 after
5329 5321
5330 // Slow-case: Go through the JavaScript implementation. 5322 // Slow-case: Go through the JavaScript implementation.
5331 __ bind(&slow); 5323 __ bind(&slow);
5332 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 5324 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
5333 } 5325 }
5334 5326
5335 5327
5336 #undef __ 5328 #undef __
5337 5329
5338 } } // namespace v8::internal 5330 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/codegen-arm.cc ('k') | src/ic-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698