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

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

Issue 51007: Formatting changes and some slight improvements to revision 1621, issue 42006... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 9 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/codegen-ia32.h ('k') | no next file » | 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-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 681 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 // Allocate a heap number in new space with undefined value. 692 // Allocate a heap number in new space with undefined value.
693 // Returns tagged pointer in eax, or jumps to need_gc if new space is full. 693 // Returns tagged pointer in eax, or jumps to need_gc if new space is full.
694 static void AllocateHeapNumber(MacroAssembler* masm, 694 static void AllocateHeapNumber(MacroAssembler* masm,
695 Label* need_gc, 695 Label* need_gc,
696 Register scratch1, 696 Register scratch1,
697 Register scratch2); 697 Register scratch2);
698 }; 698 };
699 699
700 700
701 // Flag that indicates whether or not the code that handles smi arguments 701 // Flag that indicates whether or not the code that handles smi arguments
702 // should be inlined, placed in the stub, or omitted entirely. 702 // should be placed in the stub, inlined, or omitted entirely.
703 enum GenericBinaryFlags { 703 enum GenericBinaryFlags {
704 SMI_CODE_IN_STUB, 704 SMI_CODE_IN_STUB,
705 SMI_CODE_INLINED, 705 SMI_CODE_INLINED
706 // It is known at compile time that at least one argument is not a smi.
707 NO_SMI_CODE
708 }; 706 };
709 707
710 708
711 class GenericBinaryOpStub: public CodeStub { 709 class GenericBinaryOpStub: public CodeStub {
712 public: 710 public:
713 GenericBinaryOpStub(Token::Value op, 711 GenericBinaryOpStub(Token::Value op,
714 OverwriteMode mode, 712 OverwriteMode mode,
715 GenericBinaryFlags flags) 713 GenericBinaryFlags flags)
716 : op_(op), mode_(mode), flags_(flags) { } 714 : op_(op), mode_(mode), flags_(flags) {
715 ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
716 }
717 717
718 void GenerateSmiCode(MacroAssembler* masm, Label* slow); 718 void GenerateSmiCode(MacroAssembler* masm, Label* slow);
719 719
720 private: 720 private:
721 Token::Value op_; 721 Token::Value op_;
722 OverwriteMode mode_; 722 OverwriteMode mode_;
723 GenericBinaryFlags flags_; 723 GenericBinaryFlags flags_;
724 724
725 const char* GetName(); 725 const char* GetName();
726 726
727 #ifdef DEBUG 727 #ifdef DEBUG
728 void Print() { 728 void Print() {
729 PrintF("GenericBinaryOpStub (op %s), (mode %d, flags %d)\n", 729 PrintF("GenericBinaryOpStub (op %s), (mode %d, flags %d)\n",
730 Token::String(op_), 730 Token::String(op_),
731 static_cast<int>(mode_), 731 static_cast<int>(mode_),
732 static_cast<int>(flags_)); 732 static_cast<int>(flags_));
733 } 733 }
734 #endif 734 #endif
735 735
736 // Minor key encoding in 16 bits FOOOOOOOOOOOOOMM. 736 // Minor key encoding in 16 bits FOOOOOOOOOOOOOMM.
737 class ModeBits: public BitField<OverwriteMode, 0, 2> {}; 737 class ModeBits: public BitField<OverwriteMode, 0, 2> {};
738 class OpBits: public BitField<Token::Value, 2, 12> {}; 738 class OpBits: public BitField<Token::Value, 2, 13> {};
739 class FlagBits: public BitField<GenericBinaryFlags, 14, 2> {}; 739 class FlagBits: public BitField<GenericBinaryFlags, 15, 1> {};
740 740
741 Major MajorKey() { return GenericBinaryOp; } 741 Major MajorKey() { return GenericBinaryOp; }
742 int MinorKey() { 742 int MinorKey() {
743 // Encode the parameters in a unique 16 bit value. 743 // Encode the parameters in a unique 16 bit value.
744 return OpBits::encode(op_) 744 return OpBits::encode(op_)
745 | ModeBits::encode(mode_) 745 | ModeBits::encode(mode_)
746 | FlagBits::encode(flags_); 746 | FlagBits::encode(flags_);
747 } 747 }
748 void Generate(MacroAssembler* masm); 748 void Generate(MacroAssembler* masm);
749 }; 749 };
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 : SMI_CODE_IN_STUB; 838 : SMI_CODE_IN_STUB;
839 break; 839 break;
840 } 840 }
841 841
842 Result right = frame_->Pop(); 842 Result right = frame_->Pop();
843 Result left = frame_->Pop(); 843 Result left = frame_->Pop();
844 bool left_is_smi = left.is_constant() && left.handle()->IsSmi(); 844 bool left_is_smi = left.is_constant() && left.handle()->IsSmi();
845 bool left_is_non_smi = left.is_constant() && !left.handle()->IsSmi(); 845 bool left_is_non_smi = left.is_constant() && !left.handle()->IsSmi();
846 bool right_is_smi = right.is_constant() && right.handle()->IsSmi(); 846 bool right_is_smi = right.is_constant() && right.handle()->IsSmi();
847 bool right_is_non_smi = right.is_constant() && !right.handle()->IsSmi(); 847 bool right_is_non_smi = right.is_constant() && !right.handle()->IsSmi();
848 bool generate_no_smi_code = false; // No smi code at all, inline or in stub.
848 849
849 if (left_is_smi && right_is_smi) { 850 if (left_is_smi && right_is_smi) {
850 // Compute the result, and return that as a constant on the frame. 851 // Compute the constant result at compile time, and leave it on the frame.
851 int left_int = Smi::cast(*left.handle())->value(); 852 int left_int = Smi::cast(*left.handle())->value();
852 int right_int = Smi::cast(*right.handle())->value(); 853 int right_int = Smi::cast(*right.handle())->value();
853 if (FoldConstantSmis(op, left_int, right_int)) return; 854 if (FoldConstantSmis(op, left_int, right_int)) return;
854 } 855 }
855 856
856 if (left_is_non_smi || right_is_non_smi) { 857 if (left_is_non_smi || right_is_non_smi) {
857 // Set flag so that we go straight to the slow case, with no smi code. 858 // Set flag so that we go straight to the slow case, with no smi code.
858 flags = NO_SMI_CODE; 859 generate_no_smi_code = true;
859 } else if (right_is_smi) { 860 } else if (right_is_smi) {
860 ConstantSmiBinaryOperation(op, &left, right.handle(), type, 861 ConstantSmiBinaryOperation(op, &left, right.handle(),
861 false, overwrite_mode); 862 type, false, overwrite_mode);
862 return; 863 return;
863 } else if (left_is_smi) { 864 } else if (left_is_smi) {
864 ConstantSmiBinaryOperation(op, &right, left.handle(), type, 865 ConstantSmiBinaryOperation(op, &right, left.handle(),
865 true, overwrite_mode); 866 type, true, overwrite_mode);
866 return; 867 return;
867 } 868 }
868 869
869 if (flags == SMI_CODE_INLINED) { 870 if (flags == SMI_CODE_INLINED && !generate_no_smi_code) {
870 LikelySmiBinaryOperation(op, &left, &right, overwrite_mode); 871 LikelySmiBinaryOperation(op, &left, &right, overwrite_mode);
871 } else { 872 } else {
872 frame_->Push(&left); 873 frame_->Push(&left);
873 frame_->Push(&right); 874 frame_->Push(&right);
874 // If we know the arguments aren't smis, use the binary operation stub 875 // If we know the arguments aren't smis, use the binary operation stub
875 // that does not check for the fast smi case. 876 // that does not check for the fast smi case.
876 // The same stub is used for NO_SMI_CODE and SMI_CODE_INLINED. 877 // The same stub is used for NO_SMI_CODE and SMI_CODE_INLINED.
877 if (flags == NO_SMI_CODE) { 878 if (generate_no_smi_code) {
878 flags = SMI_CODE_INLINED; 879 flags = SMI_CODE_INLINED;
879 } 880 }
880 GenericBinaryOpStub stub(op, overwrite_mode, flags); 881 GenericBinaryOpStub stub(op, overwrite_mode, flags);
881 Result answer = frame_->CallStub(&stub, 2); 882 Result answer = frame_->CallStub(&stub, 2);
882 frame_->Push(&answer); 883 frame_->Push(&answer);
883 } 884 }
884 } 885 }
885 886
886 887
887 bool CodeGenerator::FoldConstantSmis(Token::Value op, int left, int right) { 888 bool CodeGenerator::FoldConstantSmis(Token::Value op, int left, int right) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 } 963 }
963 frame_->Push(Handle<Object>(answer_object)); 964 frame_->Push(Handle<Object>(answer_object));
964 return true; 965 return true;
965 } 966 }
966 967
967 968
968 void CodeGenerator::LikelySmiBinaryOperation(Token::Value op, 969 void CodeGenerator::LikelySmiBinaryOperation(Token::Value op,
969 Result* left, 970 Result* left,
970 Result* right, 971 Result* right,
971 OverwriteMode overwrite_mode) { 972 OverwriteMode overwrite_mode) {
972 // Create a new deferred code object that calls GenericBinaryOpStub 973 // Implements a binary operation using a deferred code object
973 // in the slow case. 974 // and some inline code to operate on smis quickly.
974 DeferredInlineBinaryOperation* deferred = 975 DeferredInlineBinaryOperation* deferred =
975 new DeferredInlineBinaryOperation(this, op, overwrite_mode, 976 new DeferredInlineBinaryOperation(this, op, overwrite_mode,
976 SMI_CODE_INLINED); 977 SMI_CODE_INLINED);
977 // Generate the inline code that handles some smi operations, 978 // Generate the inline code that handles some smi operations,
978 // and jumps to the deferred code for everything else. 979 // and jumps to the deferred code for everything else.
979 Result answer = deferred->GenerateInlineCode(left, right); 980 Result answer = deferred->GenerateInlineCode(left, right);
980 deferred->BindExit(&answer); 981 deferred->BindExit(&answer);
981 frame_->Push(&answer); 982 frame_->Push(&answer);
982 } 983 }
983 984
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
1226 deferred->enter()->Branch(overflow, operand, not_taken); 1227 deferred->enter()->Branch(overflow, operand, not_taken);
1227 __ test(operand->reg(), Immediate(kSmiTagMask)); 1228 __ test(operand->reg(), Immediate(kSmiTagMask));
1228 deferred->enter()->Branch(not_zero, operand, not_taken); 1229 deferred->enter()->Branch(not_zero, operand, not_taken);
1229 deferred->BindExit(operand); 1230 deferred->BindExit(operand);
1230 frame_->Push(operand); 1231 frame_->Push(operand);
1231 break; 1232 break;
1232 } 1233 }
1233 1234
1234 case Token::SUB: { 1235 case Token::SUB: {
1235 DeferredCode* deferred = NULL; 1236 DeferredCode* deferred = NULL;
1236 Result answer(this); // Only allocated a new register if reversed. 1237 Result answer(this); // Only allocate a new register if reversed.
1237 if (reversed) { 1238 if (reversed) {
1238 answer = allocator()->Allocate(); 1239 answer = allocator()->Allocate();
1239 ASSERT(answer.is_valid()); 1240 ASSERT(answer.is_valid());
1240 deferred = new DeferredInlineSmiSubReversed(this, 1241 deferred = new DeferredInlineSmiSubReversed(this,
1241 smi_value, 1242 smi_value,
1242 overwrite_mode); 1243 overwrite_mode);
1243 __ Set(answer.reg(), Immediate(value)); 1244 __ Set(answer.reg(), Immediate(value));
1244 if (operand->is_register()) { 1245 if (operand->is_register()) {
1245 __ sub(answer.reg(), Operand(operand->reg())); 1246 __ sub(answer.reg(), Operand(operand->reg()));
1246 } else { 1247 } else {
(...skipping 4316 matching lines...) Expand 10 before | Expand all | Expand 10 after
5563 5564
5564 left->ToRegister(); 5565 left->ToRegister();
5565 right->ToRegister(); 5566 right->ToRegister();
5566 // A newly allocated register answer is used to hold the answer. 5567 // A newly allocated register answer is used to hold the answer.
5567 // The registers containing left and right are not modified in 5568 // The registers containing left and right are not modified in
5568 // most cases, so they usually don't need to be spilled in the fast case. 5569 // most cases, so they usually don't need to be spilled in the fast case.
5569 Result answer = generator()->allocator()->Allocate(); 5570 Result answer = generator()->allocator()->Allocate();
5570 5571
5571 ASSERT(answer.is_valid()); 5572 ASSERT(answer.is_valid());
5572 // Perform the smi check. 5573 // Perform the smi check.
5573 __ mov(answer.reg(), left->reg()); 5574 if (left->reg().is(right->reg())) {
5574 __ or_(answer.reg(), Operand(right->reg())); 5575 __ test(left->reg(), Immediate(kSmiTagMask));
5575 ASSERT(kSmiTag == 0); // adjust zero check if not the case 5576 } else {
5576 __ test(answer.reg(), Immediate(kSmiTagMask)); 5577 __ mov(answer.reg(), left->reg());
5578 __ or_(answer.reg(), Operand(right->reg()));
5579 ASSERT(kSmiTag == 0); // adjust zero check if not the case
5580 __ test(answer.reg(), Immediate(kSmiTagMask));
5581 }
5577 enter()->Branch(not_zero, left, right, not_taken); 5582 enter()->Branch(not_zero, left, right, not_taken);
5578 5583
5579 // All operations start by copying the left argument into answer. 5584 // All operations start by copying the left argument into answer.
5580 __ mov(answer.reg(), left->reg()); 5585 __ mov(answer.reg(), left->reg());
5581 switch (op_) { 5586 switch (op_) {
5582 case Token::ADD: 5587 case Token::ADD:
5583 __ add(answer.reg(), Operand(right->reg())); // add optimistically 5588 __ add(answer.reg(), Operand(right->reg())); // add optimistically
5584 enter()->Branch(overflow, left, right, not_taken); 5589 enter()->Branch(overflow, left, right, not_taken);
5585 break; 5590 break;
5586 5591
(...skipping 1481 matching lines...) Expand 10 before | Expand all | Expand 10 after
7068 7073
7069 // Slow-case: Go through the JavaScript implementation. 7074 // Slow-case: Go through the JavaScript implementation.
7070 __ bind(&slow); 7075 __ bind(&slow);
7071 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 7076 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
7072 } 7077 }
7073 7078
7074 7079
7075 #undef __ 7080 #undef __
7076 7081
7077 } } // namespace v8::internal 7082 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/codegen-ia32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698