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

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

Issue 21447: Experimental: introduce a simple mechanism to allow jump targets with... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: '' Created 11 years, 10 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
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 720 matching lines...) Expand 10 before | Expand all | Expand 10 after
731 }; 731 };
732 732
733 733
734 void DeferredInlineBinaryOperation::Generate() { 734 void DeferredInlineBinaryOperation::Generate() {
735 Result left(generator()); 735 Result left(generator());
736 Result right(generator()); 736 Result right(generator());
737 enter()->Bind(&left, &right); 737 enter()->Bind(&left, &right);
738 generator()->frame()->Push(&left); 738 generator()->frame()->Push(&left);
739 generator()->frame()->Push(&right); 739 generator()->frame()->Push(&right);
740 Result answer = generator()->frame()->CallStub(&stub_, 2); 740 Result answer = generator()->frame()->CallStub(&stub_, 2);
741 exit()->Jump(&answer); 741 exit_.Jump(&answer);
742 } 742 }
743 743
744 744
745 void CodeGenerator::GenericBinaryOperation(Token::Value op, 745 void CodeGenerator::GenericBinaryOperation(Token::Value op,
746 StaticType* type, 746 StaticType* type,
747 OverwriteMode overwrite_mode) { 747 OverwriteMode overwrite_mode) {
748 Comment cmnt(masm_, "[ BinaryOperation"); 748 Comment cmnt(masm_, "[ BinaryOperation");
749 Comment cmnt_token(masm_, Token::String(op)); 749 Comment cmnt_token(masm_, Token::String(op));
750 750
751 if (op == Token::COMMA) { 751 if (op == Token::COMMA) {
(...skipping 27 matching lines...) Expand all
779 break; 779 break;
780 } 780 }
781 781
782 if (flags == SMI_CODE_INLINED) { 782 if (flags == SMI_CODE_INLINED) {
783 // Create a new deferred code for the slow-case part. 783 // Create a new deferred code for the slow-case part.
784 DeferredInlineBinaryOperation* deferred = 784 DeferredInlineBinaryOperation* deferred =
785 new DeferredInlineBinaryOperation(this, op, overwrite_mode, flags); 785 new DeferredInlineBinaryOperation(this, op, overwrite_mode, flags);
786 // Generate the inline part of the code. 786 // Generate the inline part of the code.
787 // The operands are on the frame. 787 // The operands are on the frame.
788 Result answer = deferred->GenerateInlineCode(); 788 Result answer = deferred->GenerateInlineCode();
789 deferred->exit()->Bind(&answer); 789 deferred->BindExit(&answer);
790 frame_->Push(&answer); 790 frame_->Push(&answer);
791 } else { 791 } else {
792 // Call the stub and push the result to the stack. 792 // Call the stub and push the result to the stack.
793 GenericBinaryOpStub stub(op, overwrite_mode, flags); 793 GenericBinaryOpStub stub(op, overwrite_mode, flags);
794 Result answer = frame_->CallStub(&stub, 2); 794 Result answer = frame_->CallStub(&stub, 2);
795 frame_->Push(&answer); 795 frame_->Push(&answer);
796 } 796 }
797 } 797 }
798 798
799 799
(...skipping 19 matching lines...) Expand all
819 }; 819 };
820 820
821 821
822 void DeferredInlineSmiOperation::Generate() { 822 void DeferredInlineSmiOperation::Generate() {
823 Result left(generator()); 823 Result left(generator());
824 enter()->Bind(&left); 824 enter()->Bind(&left);
825 generator()->frame()->Push(&left); 825 generator()->frame()->Push(&left);
826 generator()->frame()->Push(value_); 826 generator()->frame()->Push(value_);
827 GenericBinaryOpStub igostub(op_, overwrite_mode_, SMI_CODE_INLINED); 827 GenericBinaryOpStub igostub(op_, overwrite_mode_, SMI_CODE_INLINED);
828 Result answer = generator()->frame()->CallStub(&igostub, 2); 828 Result answer = generator()->frame()->CallStub(&igostub, 2);
829 exit()->Jump(&answer); 829 exit_.Jump(&answer);
830 } 830 }
831 831
832 832
833 class DeferredInlineSmiOperationReversed: public DeferredCode { 833 class DeferredInlineSmiOperationReversed: public DeferredCode {
834 public: 834 public:
835 DeferredInlineSmiOperationReversed(CodeGenerator* generator, 835 DeferredInlineSmiOperationReversed(CodeGenerator* generator,
836 Token::Value op, 836 Token::Value op,
837 Smi* value, 837 Smi* value,
838 OverwriteMode overwrite_mode) 838 OverwriteMode overwrite_mode)
839 : DeferredCode(generator), 839 : DeferredCode(generator),
(...skipping 12 matching lines...) Expand all
852 }; 852 };
853 853
854 854
855 void DeferredInlineSmiOperationReversed::Generate() { 855 void DeferredInlineSmiOperationReversed::Generate() {
856 Result right(generator()); 856 Result right(generator());
857 enter()->Bind(&right); 857 enter()->Bind(&right);
858 generator()->frame()->Push(value_); 858 generator()->frame()->Push(value_);
859 generator()->frame()->Push(&right); 859 generator()->frame()->Push(&right);
860 GenericBinaryOpStub igostub(op_, overwrite_mode_, SMI_CODE_INLINED); 860 GenericBinaryOpStub igostub(op_, overwrite_mode_, SMI_CODE_INLINED);
861 Result answer = generator()->frame()->CallStub(&igostub, 2); 861 Result answer = generator()->frame()->CallStub(&igostub, 2);
862 exit()->Jump(&answer); 862 exit_.Jump(&answer);
863 } 863 }
864 864
865 865
866 class DeferredInlineSmiAdd: public DeferredCode { 866 class DeferredInlineSmiAdd: public DeferredCode {
867 public: 867 public:
868 DeferredInlineSmiAdd(CodeGenerator* generator, 868 DeferredInlineSmiAdd(CodeGenerator* generator,
869 Smi* value, 869 Smi* value,
870 OverwriteMode overwrite_mode) 870 OverwriteMode overwrite_mode)
871 : DeferredCode(generator), 871 : DeferredCode(generator),
872 value_(value), 872 value_(value),
(...skipping 13 matching lines...) Expand all
886 // Undo the optimistic add operation and call the shared stub. 886 // Undo the optimistic add operation and call the shared stub.
887 Result left(generator()); // Initially left + value_. 887 Result left(generator()); // Initially left + value_.
888 enter()->Bind(&left); 888 enter()->Bind(&left);
889 left.ToRegister(); 889 left.ToRegister();
890 generator()->frame()->Spill(left.reg()); 890 generator()->frame()->Spill(left.reg());
891 __ sub(Operand(left.reg()), Immediate(value_)); 891 __ sub(Operand(left.reg()), Immediate(value_));
892 generator()->frame()->Push(&left); 892 generator()->frame()->Push(&left);
893 generator()->frame()->Push(value_); 893 generator()->frame()->Push(value_);
894 GenericBinaryOpStub igostub(Token::ADD, overwrite_mode_, SMI_CODE_INLINED); 894 GenericBinaryOpStub igostub(Token::ADD, overwrite_mode_, SMI_CODE_INLINED);
895 Result answer = generator()->frame()->CallStub(&igostub, 2); 895 Result answer = generator()->frame()->CallStub(&igostub, 2);
896 exit()->Jump(&answer); 896 exit_.Jump(&answer);
897 } 897 }
898 898
899 899
900 class DeferredInlineSmiAddReversed: public DeferredCode { 900 class DeferredInlineSmiAddReversed: public DeferredCode {
901 public: 901 public:
902 DeferredInlineSmiAddReversed(CodeGenerator* generator, 902 DeferredInlineSmiAddReversed(CodeGenerator* generator,
903 Smi* value, 903 Smi* value,
904 OverwriteMode overwrite_mode) 904 OverwriteMode overwrite_mode)
905 : DeferredCode(generator), 905 : DeferredCode(generator),
906 value_(value), 906 value_(value),
(...skipping 13 matching lines...) Expand all
920 // Undo the optimistic add operation and call the shared stub. 920 // Undo the optimistic add operation and call the shared stub.
921 Result right(generator()); // Initially value_ + right. 921 Result right(generator()); // Initially value_ + right.
922 enter()->Bind(&right); 922 enter()->Bind(&right);
923 right.ToRegister(); 923 right.ToRegister();
924 generator()->frame()->Spill(right.reg()); 924 generator()->frame()->Spill(right.reg());
925 __ sub(Operand(right.reg()), Immediate(value_)); 925 __ sub(Operand(right.reg()), Immediate(value_));
926 generator()->frame()->Push(value_); 926 generator()->frame()->Push(value_);
927 generator()->frame()->Push(&right); 927 generator()->frame()->Push(&right);
928 GenericBinaryOpStub igostub(Token::ADD, overwrite_mode_, SMI_CODE_INLINED); 928 GenericBinaryOpStub igostub(Token::ADD, overwrite_mode_, SMI_CODE_INLINED);
929 Result answer = generator()->frame()->CallStub(&igostub, 2); 929 Result answer = generator()->frame()->CallStub(&igostub, 2);
930 exit()->Jump(&answer); 930 exit_.Jump(&answer);
931 } 931 }
932 932
933 933
934 class DeferredInlineSmiSub: public DeferredCode { 934 class DeferredInlineSmiSub: public DeferredCode {
935 public: 935 public:
936 DeferredInlineSmiSub(CodeGenerator* generator, 936 DeferredInlineSmiSub(CodeGenerator* generator,
937 Smi* value, 937 Smi* value,
938 OverwriteMode overwrite_mode) 938 OverwriteMode overwrite_mode)
939 : DeferredCode(generator), 939 : DeferredCode(generator),
940 value_(value), 940 value_(value),
(...skipping 13 matching lines...) Expand all
954 // Undo the optimistic sub operation and call the shared stub. 954 // Undo the optimistic sub operation and call the shared stub.
955 Result left(generator()); // Initially left - value_. 955 Result left(generator()); // Initially left - value_.
956 enter()->Bind(&left); 956 enter()->Bind(&left);
957 left.ToRegister(); 957 left.ToRegister();
958 generator()->frame()->Spill(left.reg()); 958 generator()->frame()->Spill(left.reg());
959 __ add(Operand(left.reg()), Immediate(value_)); 959 __ add(Operand(left.reg()), Immediate(value_));
960 generator()->frame()->Push(&left); 960 generator()->frame()->Push(&left);
961 generator()->frame()->Push(value_); 961 generator()->frame()->Push(value_);
962 GenericBinaryOpStub igostub(Token::SUB, overwrite_mode_, SMI_CODE_INLINED); 962 GenericBinaryOpStub igostub(Token::SUB, overwrite_mode_, SMI_CODE_INLINED);
963 Result answer = generator()->frame()->CallStub(&igostub, 2); 963 Result answer = generator()->frame()->CallStub(&igostub, 2);
964 exit()->Jump(&answer); 964 exit_.Jump(&answer);
965 } 965 }
966 966
967 967
968 class DeferredInlineSmiSubReversed: public DeferredCode { 968 class DeferredInlineSmiSubReversed: public DeferredCode {
969 public: 969 public:
970 DeferredInlineSmiSubReversed(CodeGenerator* generator, 970 DeferredInlineSmiSubReversed(CodeGenerator* generator,
971 Smi* value, 971 Smi* value,
972 OverwriteMode overwrite_mode) 972 OverwriteMode overwrite_mode)
973 : DeferredCode(generator), 973 : DeferredCode(generator),
974 value_(value), 974 value_(value),
(...skipping 10 matching lines...) Expand all
985 985
986 986
987 void DeferredInlineSmiSubReversed::Generate() { 987 void DeferredInlineSmiSubReversed::Generate() {
988 // Call the shared stub. 988 // Call the shared stub.
989 Result right(generator()); 989 Result right(generator());
990 enter()->Bind(&right); 990 enter()->Bind(&right);
991 generator()->frame()->Push(value_); 991 generator()->frame()->Push(value_);
992 generator()->frame()->Push(&right); 992 generator()->frame()->Push(&right);
993 GenericBinaryOpStub igostub(Token::SUB, overwrite_mode_, SMI_CODE_INLINED); 993 GenericBinaryOpStub igostub(Token::SUB, overwrite_mode_, SMI_CODE_INLINED);
994 Result answer = generator()->frame()->CallStub(&igostub, 2); 994 Result answer = generator()->frame()->CallStub(&igostub, 2);
995 exit()->Jump(&answer); 995 exit_.Jump(&answer);
996 } 996 }
997 997
998 998
999 void CodeGenerator::SmiOperation(Token::Value op, 999 void CodeGenerator::SmiOperation(Token::Value op,
1000 StaticType* type, 1000 StaticType* type,
1001 Handle<Object> value, 1001 Handle<Object> value,
1002 bool reversed, 1002 bool reversed,
1003 OverwriteMode overwrite_mode) { 1003 OverwriteMode overwrite_mode) {
1004 // NOTE: This is an attempt to inline (a bit) more of the code for 1004 // NOTE: This is an attempt to inline (a bit) more of the code for
1005 // some possible smi operations (like + and -) when (at least) one 1005 // some possible smi operations (like + and -) when (at least) one
(...skipping 19 matching lines...) Expand all
1025 deferred = new DeferredInlineSmiAddReversed(this, smi_value, 1025 deferred = new DeferredInlineSmiAddReversed(this, smi_value,
1026 overwrite_mode); 1026 overwrite_mode);
1027 } 1027 }
1028 Result operand = frame_->Pop(); 1028 Result operand = frame_->Pop();
1029 operand.ToRegister(); 1029 operand.ToRegister();
1030 frame_->Spill(operand.reg()); 1030 frame_->Spill(operand.reg());
1031 __ add(Operand(operand.reg()), Immediate(value)); 1031 __ add(Operand(operand.reg()), Immediate(value));
1032 deferred->enter()->Branch(overflow, &operand, not_taken); 1032 deferred->enter()->Branch(overflow, &operand, not_taken);
1033 __ test(Operand(operand.reg()), Immediate(kSmiTagMask)); 1033 __ test(Operand(operand.reg()), Immediate(kSmiTagMask));
1034 deferred->enter()->Branch(not_zero, &operand, not_taken); 1034 deferred->enter()->Branch(not_zero, &operand, not_taken);
1035 deferred->exit()->Bind(&operand); 1035 deferred->BindExit(&operand);
1036 frame_->Push(&operand); 1036 frame_->Push(&operand);
1037 break; 1037 break;
1038 } 1038 }
1039 1039
1040 case Token::SUB: { 1040 case Token::SUB: {
1041 DeferredCode* deferred = NULL; 1041 DeferredCode* deferred = NULL;
1042 Result operand = frame_->Pop(); 1042 Result operand = frame_->Pop();
1043 Result answer(this); // Only allocated a new register if reversed. 1043 Result answer(this); // Only allocated a new register if reversed.
1044 if (!reversed) { 1044 if (!reversed) {
1045 operand.ToRegister(); 1045 operand.ToRegister();
(...skipping 14 matching lines...) Expand all
1060 __ sub(answer.reg(), Operand(operand.reg())); 1060 __ sub(answer.reg(), Operand(operand.reg()));
1061 } else { 1061 } else {
1062 ASSERT(operand.is_constant()); 1062 ASSERT(operand.is_constant());
1063 __ sub(Operand(answer.reg()), Immediate(operand.handle())); 1063 __ sub(Operand(answer.reg()), Immediate(operand.handle()));
1064 } 1064 }
1065 } 1065 }
1066 deferred->enter()->Branch(overflow, &operand, not_taken); 1066 deferred->enter()->Branch(overflow, &operand, not_taken);
1067 __ test(answer.reg(), Immediate(kSmiTagMask)); 1067 __ test(answer.reg(), Immediate(kSmiTagMask));
1068 deferred->enter()->Branch(not_zero, &operand, not_taken); 1068 deferred->enter()->Branch(not_zero, &operand, not_taken);
1069 operand.Unuse(); 1069 operand.Unuse();
1070 deferred->exit()->Bind(&answer); 1070 deferred->BindExit(&answer);
1071 frame_->Push(&answer); 1071 frame_->Push(&answer);
1072 break; 1072 break;
1073 } 1073 }
1074 1074
1075 case Token::SAR: { 1075 case Token::SAR: {
1076 if (reversed) { 1076 if (reversed) {
1077 Result top = frame_->Pop(); 1077 Result top = frame_->Pop();
1078 frame_->Push(value); 1078 frame_->Push(value);
1079 frame_->Push(&top); 1079 frame_->Push(&top);
1080 GenericBinaryOperation(op, type, overwrite_mode); 1080 GenericBinaryOperation(op, type, overwrite_mode);
1081 } else { 1081 } else {
1082 // Only the least significant 5 bits of the shift value are used. 1082 // Only the least significant 5 bits of the shift value are used.
1083 // In the slow case, this masking is done inside the runtime call. 1083 // In the slow case, this masking is done inside the runtime call.
1084 int shift_value = int_value & 0x1f; 1084 int shift_value = int_value & 0x1f;
1085 DeferredCode* deferred = 1085 DeferredCode* deferred =
1086 new DeferredInlineSmiOperation(this, Token::SAR, smi_value, 1086 new DeferredInlineSmiOperation(this, Token::SAR, smi_value,
1087 overwrite_mode); 1087 overwrite_mode);
1088 Result result = frame_->Pop(); 1088 Result result = frame_->Pop();
1089 result.ToRegister(); 1089 result.ToRegister();
1090 __ test(result.reg(), Immediate(kSmiTagMask)); 1090 __ test(result.reg(), Immediate(kSmiTagMask));
1091 deferred->enter()->Branch(not_zero, &result, not_taken); 1091 deferred->enter()->Branch(not_zero, &result, not_taken);
1092 frame_->Spill(result.reg()); 1092 frame_->Spill(result.reg());
1093 __ sar(result.reg(), shift_value); 1093 __ sar(result.reg(), shift_value);
1094 __ and_(result.reg(), ~kSmiTagMask); 1094 __ and_(result.reg(), ~kSmiTagMask);
1095 deferred->exit()->Bind(&result); 1095 deferred->BindExit(&result);
1096 frame_->Push(&result); 1096 frame_->Push(&result);
1097 } 1097 }
1098 break; 1098 break;
1099 } 1099 }
1100 1100
1101 case Token::SHR: { 1101 case Token::SHR: {
1102 if (reversed) { 1102 if (reversed) {
1103 Result top = frame_->Pop(); 1103 Result top = frame_->Pop();
1104 frame_->Push(value); 1104 frame_->Push(value);
1105 frame_->Push(&top); 1105 frame_->Push(&top);
(...skipping 16 matching lines...) Expand all
1122 __ shr(answer.reg(), shift_value); 1122 __ shr(answer.reg(), shift_value);
1123 // A negative Smi shifted right two is in the positive Smi range. 1123 // A negative Smi shifted right two is in the positive Smi range.
1124 if (shift_value < 2) { 1124 if (shift_value < 2) {
1125 __ test(answer.reg(), Immediate(0xc0000000)); 1125 __ test(answer.reg(), Immediate(0xc0000000));
1126 deferred->enter()->Branch(not_zero, &operand, not_taken); 1126 deferred->enter()->Branch(not_zero, &operand, not_taken);
1127 } 1127 }
1128 operand.Unuse(); 1128 operand.Unuse();
1129 ASSERT(kSmiTagSize == times_2); // Adjust the code if not true. 1129 ASSERT(kSmiTagSize == times_2); // Adjust the code if not true.
1130 __ lea(answer.reg(), 1130 __ lea(answer.reg(),
1131 Operand(answer.reg(), answer.reg(), times_1, kSmiTag)); 1131 Operand(answer.reg(), answer.reg(), times_1, kSmiTag));
1132 deferred->exit()->Bind(&answer); 1132 deferred->BindExit(&answer);
1133 frame_->Push(&answer); 1133 frame_->Push(&answer);
1134 } 1134 }
1135 break; 1135 break;
1136 } 1136 }
1137 1137
1138 case Token::SHL: { 1138 case Token::SHL: {
1139 if (reversed) { 1139 if (reversed) {
1140 Result top = frame_->Pop(); 1140 Result top = frame_->Pop();
1141 frame_->Push(value); 1141 frame_->Push(value);
1142 frame_->Push(&top); 1142 frame_->Push(&top);
(...skipping 17 matching lines...) Expand all
1160 if (shift_value == 0) { 1160 if (shift_value == 0) {
1161 __ sar(answer.reg(), kSmiTagSize); 1161 __ sar(answer.reg(), kSmiTagSize);
1162 } else if (shift_value > 1) { 1162 } else if (shift_value > 1) {
1163 __ shl(answer.reg(), shift_value - 1); 1163 __ shl(answer.reg(), shift_value - 1);
1164 } 1164 }
1165 // Convert int result to Smi, checking that it is in int range. 1165 // Convert int result to Smi, checking that it is in int range.
1166 ASSERT(kSmiTagSize == times_2); // adjust code if not the case 1166 ASSERT(kSmiTagSize == times_2); // adjust code if not the case
1167 __ add(answer.reg(), Operand(answer.reg())); 1167 __ add(answer.reg(), Operand(answer.reg()));
1168 deferred->enter()->Branch(overflow, &operand, not_taken); 1168 deferred->enter()->Branch(overflow, &operand, not_taken);
1169 operand.Unuse(); 1169 operand.Unuse();
1170 deferred->exit()->Bind(&answer); 1170 deferred->BindExit(&answer);
1171 frame_->Push(&answer); 1171 frame_->Push(&answer);
1172 } 1172 }
1173 break; 1173 break;
1174 } 1174 }
1175 1175
1176 case Token::BIT_OR: 1176 case Token::BIT_OR:
1177 case Token::BIT_XOR: 1177 case Token::BIT_XOR:
1178 case Token::BIT_AND: { 1178 case Token::BIT_AND: {
1179 DeferredCode* deferred = NULL; 1179 DeferredCode* deferred = NULL;
1180 if (!reversed) { 1180 if (!reversed) {
1181 deferred = new DeferredInlineSmiOperation(this, op, smi_value, 1181 deferred = new DeferredInlineSmiOperation(this, op, smi_value,
1182 overwrite_mode); 1182 overwrite_mode);
1183 } else { 1183 } else {
1184 deferred = new DeferredInlineSmiOperationReversed(this, op, smi_value, 1184 deferred = new DeferredInlineSmiOperationReversed(this, op, smi_value,
1185 overwrite_mode); 1185 overwrite_mode);
1186 } 1186 }
1187 Result operand = frame_->Pop(); 1187 Result operand = frame_->Pop();
1188 operand.ToRegister(); 1188 operand.ToRegister();
1189 __ test(operand.reg(), Immediate(kSmiTagMask)); 1189 __ test(operand.reg(), Immediate(kSmiTagMask));
1190 deferred->enter()->Branch(not_zero, &operand, not_taken); 1190 deferred->enter()->Branch(not_zero, &operand, not_taken);
1191 frame_->Spill(operand.reg()); 1191 frame_->Spill(operand.reg());
1192 if (op == Token::BIT_AND) { 1192 if (op == Token::BIT_AND) {
1193 __ and_(Operand(operand.reg()), Immediate(value)); 1193 __ and_(Operand(operand.reg()), Immediate(value));
1194 } else if (op == Token::BIT_XOR) { 1194 } else if (op == Token::BIT_XOR) {
1195 __ xor_(Operand(operand.reg()), Immediate(value)); 1195 __ xor_(Operand(operand.reg()), Immediate(value));
1196 } else { 1196 } else {
1197 ASSERT(op == Token::BIT_OR); 1197 ASSERT(op == Token::BIT_OR);
1198 __ or_(Operand(operand.reg()), Immediate(value)); 1198 __ or_(Operand(operand.reg()), Immediate(value));
1199 } 1199 }
1200 deferred->exit()->Bind(&operand); 1200 deferred->BindExit(&operand);
1201 frame_->Push(&operand); 1201 frame_->Push(&operand);
1202 break; 1202 break;
1203 } 1203 }
1204 1204
1205 default: { 1205 default: {
1206 if (!reversed) { 1206 if (!reversed) {
1207 frame_->Push(value); 1207 frame_->Push(value);
1208 } else { 1208 } else {
1209 Result top = frame_->Pop(); 1209 Result top = frame_->Pop();
1210 frame_->Push(value); 1210 frame_->Push(value);
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
1465 } 1465 }
1466 1466
1467 virtual void Generate(); 1467 virtual void Generate();
1468 }; 1468 };
1469 1469
1470 1470
1471 void DeferredStackCheck::Generate() { 1471 void DeferredStackCheck::Generate() {
1472 enter()->Bind(); 1472 enter()->Bind();
1473 // The stack check can trigger the debugger. Before calling it, all 1473 // The stack check can trigger the debugger. Before calling it, all
1474 // values including constants must be spilled to the frame. 1474 // values including constants must be spilled to the frame.
1475 generator()->frame()->SpillAll(); 1475 // generator()->frame()->SpillAll();
Kasper Lund 2009/02/18 12:11:17 Remove?
Kevin Millikin (Chromium) 2009/02/18 12:26:22 Yes.
1476 StackCheckStub stub; 1476 StackCheckStub stub;
1477 Result ignored = generator()->frame()->CallStub(&stub, 0); 1477 Result ignored = generator()->frame()->CallStub(&stub, 0);
1478 ignored.Unuse(); 1478 ignored.Unuse();
1479 exit()->Jump(); 1479 exit_.Jump();
1480 } 1480 }
1481 1481
1482 1482
1483 void CodeGenerator::CheckStack() { 1483 void CodeGenerator::CheckStack() {
1484 if (FLAG_check_stack) { 1484 if (FLAG_check_stack) {
1485 DeferredStackCheck* deferred = new DeferredStackCheck(this); 1485 DeferredStackCheck* deferred = new DeferredStackCheck(this);
1486 ExternalReference stack_guard_limit = 1486 ExternalReference stack_guard_limit =
1487 ExternalReference::address_of_stack_guard_limit(); 1487 ExternalReference::address_of_stack_guard_limit();
1488 __ cmp(esp, Operand::StaticVariable(stack_guard_limit)); 1488 __ cmp(esp, Operand::StaticVariable(stack_guard_limit));
1489 deferred->enter()->Branch(below, not_taken); 1489 deferred->enter()->Branch(below, not_taken);
1490 deferred->exit()->Bind(); 1490 deferred->BindExit();
1491 } 1491 }
1492 } 1492 }
1493 1493
1494 1494
1495 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { 1495 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) {
1496 ASSERT(!in_spilled_code()); 1496 ASSERT(!in_spilled_code());
1497 for (int i = 0; has_valid_frame() && i < statements->length(); i++) { 1497 for (int i = 0; has_valid_frame() && i < statements->length(); i++) {
1498 Visit(statements->at(i)); 1498 Visit(statements->at(i));
1499 } 1499 }
1500 } 1500 }
(...skipping 1594 matching lines...) Expand 10 before | Expand all | Expand 10 after
3095 // Literal array (0). 3095 // Literal array (0).
3096 frame->Push(&literals); 3096 frame->Push(&literals);
3097 // Literal index (1). 3097 // Literal index (1).
3098 frame->Push(Smi::FromInt(node_->literal_index())); 3098 frame->Push(Smi::FromInt(node_->literal_index()));
3099 // RegExp pattern (2). 3099 // RegExp pattern (2).
3100 frame->Push(node_->pattern()); 3100 frame->Push(node_->pattern());
3101 // RegExp flags (3). 3101 // RegExp flags (3).
3102 frame->Push(node_->flags()); 3102 frame->Push(node_->flags());
3103 Result boilerplate = 3103 Result boilerplate =
3104 frame->CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); 3104 frame->CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
3105 exit()->Jump(&boilerplate); 3105 exit_.Jump(&boilerplate);
3106 } 3106 }
3107 3107
3108 3108
3109 void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) { 3109 void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) {
3110 Comment cmnt(masm_, "[ RegExp Literal"); 3110 Comment cmnt(masm_, "[ RegExp Literal");
3111 DeferredRegExpLiteral* deferred = new DeferredRegExpLiteral(this, node); 3111 DeferredRegExpLiteral* deferred = new DeferredRegExpLiteral(this, node);
3112 3112
3113 // Retrieve the literals array and check the allocated entry. Begin 3113 // Retrieve the literals array and check the allocated entry. Begin
3114 // with a writable copy of the function of this activation in a 3114 // with a writable copy of the function of this activation in a
3115 // register. 3115 // register.
(...skipping 13 matching lines...) Expand all
3129 ASSERT(boilerplate.is_valid()); 3129 ASSERT(boilerplate.is_valid());
3130 __ mov(boilerplate.reg(), FieldOperand(literals.reg(), literal_offset)); 3130 __ mov(boilerplate.reg(), FieldOperand(literals.reg(), literal_offset));
3131 3131
3132 // Check whether we need to materialize the RegExp object. If so, 3132 // Check whether we need to materialize the RegExp object. If so,
3133 // jump to the deferred code passing the literals array. 3133 // jump to the deferred code passing the literals array.
3134 __ cmp(boilerplate.reg(), Factory::undefined_value()); 3134 __ cmp(boilerplate.reg(), Factory::undefined_value());
3135 deferred->enter()->Branch(equal, &literals, not_taken); 3135 deferred->enter()->Branch(equal, &literals, not_taken);
3136 3136
3137 literals.Unuse(); 3137 literals.Unuse();
3138 // The deferred code returns the boilerplate object. 3138 // The deferred code returns the boilerplate object.
3139 deferred->exit()->Bind(&boilerplate); 3139 deferred->BindExit(&boilerplate);
3140 3140
3141 // Push the boilerplate object. 3141 // Push the boilerplate object.
3142 frame_->Push(&boilerplate); 3142 frame_->Push(&boilerplate);
3143 } 3143 }
3144 3144
3145 3145
3146 // This deferred code stub will be used for creating the boilerplate 3146 // This deferred code stub will be used for creating the boilerplate
3147 // by calling Runtime_CreateObjectLiteral. 3147 // by calling Runtime_CreateObjectLiteral.
3148 // Each created boilerplate is stored in the JSFunction and they are 3148 // Each created boilerplate is stored in the JSFunction and they are
3149 // therefore context dependent. 3149 // therefore context dependent.
(...skipping 20 matching lines...) Expand all
3170 3170
3171 VirtualFrame* frame = generator()->frame(); 3171 VirtualFrame* frame = generator()->frame();
3172 // Literal array (0). 3172 // Literal array (0).
3173 frame->Push(&literals); 3173 frame->Push(&literals);
3174 // Literal index (1). 3174 // Literal index (1).
3175 frame->Push(Smi::FromInt(node_->literal_index())); 3175 frame->Push(Smi::FromInt(node_->literal_index()));
3176 // Constant properties (2). 3176 // Constant properties (2).
3177 frame->Push(node_->constant_properties()); 3177 frame->Push(node_->constant_properties());
3178 Result boilerplate = 3178 Result boilerplate =
3179 frame->CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3); 3179 frame->CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3);
3180 exit()->Jump(&boilerplate); 3180 exit_.Jump(&boilerplate);
3181 } 3181 }
3182 3182
3183 3183
3184 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { 3184 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) {
3185 Comment cmnt(masm_, "[ ObjectLiteral"); 3185 Comment cmnt(masm_, "[ ObjectLiteral");
3186 DeferredObjectLiteral* deferred = new DeferredObjectLiteral(this, node); 3186 DeferredObjectLiteral* deferred = new DeferredObjectLiteral(this, node);
3187 3187
3188 // Retrieve the literals array and check the allocated entry. Begin 3188 // Retrieve the literals array and check the allocated entry. Begin
3189 // with a writable copy of the function of this activation in a 3189 // with a writable copy of the function of this activation in a
3190 // register. 3190 // register.
(...skipping 13 matching lines...) Expand all
3204 ASSERT(boilerplate.is_valid()); 3204 ASSERT(boilerplate.is_valid());
3205 __ mov(boilerplate.reg(), FieldOperand(literals.reg(), literal_offset)); 3205 __ mov(boilerplate.reg(), FieldOperand(literals.reg(), literal_offset));
3206 3206
3207 // Check whether we need to materialize the object literal boilerplate. 3207 // Check whether we need to materialize the object literal boilerplate.
3208 // If so, jump to the deferred code passing the literals array. 3208 // If so, jump to the deferred code passing the literals array.
3209 __ cmp(boilerplate.reg(), Factory::undefined_value()); 3209 __ cmp(boilerplate.reg(), Factory::undefined_value());
3210 deferred->enter()->Branch(equal, &literals, not_taken); 3210 deferred->enter()->Branch(equal, &literals, not_taken);
3211 3211
3212 literals.Unuse(); 3212 literals.Unuse();
3213 // The deferred code returns the boilerplate object. 3213 // The deferred code returns the boilerplate object.
3214 deferred->exit()->Bind(&boilerplate); 3214 deferred->BindExit(&boilerplate);
3215 3215
3216 // Push the boilerplate object. 3216 // Push the boilerplate object.
3217 frame_->Push(&boilerplate); 3217 frame_->Push(&boilerplate);
3218 // Clone the boilerplate object. 3218 // Clone the boilerplate object.
3219 Result clone = 3219 Result clone =
3220 frame_->CallRuntime(Runtime::kCloneObjectLiteralBoilerplate, 1); 3220 frame_->CallRuntime(Runtime::kCloneObjectLiteralBoilerplate, 1);
3221 // Push the newly cloned literal object as the result. 3221 // Push the newly cloned literal object as the result.
3222 frame_->Push(&clone); 3222 frame_->Push(&clone);
3223 3223
3224 for (int i = 0; i < node->properties()->length(); i++) { 3224 for (int i = 0; i < node->properties()->length(); i++) {
(...skipping 1053 matching lines...) Expand 10 before | Expand all | Expand 10 after
4278 enter()->Bind(&value); 4278 enter()->Bind(&value);
4279 value.ToRegister(eax); // The stubs below expect their argument in eax. 4279 value.ToRegister(eax); // The stubs below expect their argument in eax.
4280 4280
4281 if (is_postfix_) { 4281 if (is_postfix_) {
4282 RevertToNumberStub to_number_stub(is_increment_); 4282 RevertToNumberStub to_number_stub(is_increment_);
4283 value = generator()->frame()->CallStub(&to_number_stub, &value, 0); 4283 value = generator()->frame()->CallStub(&to_number_stub, &value, 0);
4284 } 4284 }
4285 4285
4286 CounterOpStub stub(result_offset_, is_postfix_, is_increment_); 4286 CounterOpStub stub(result_offset_, is_postfix_, is_increment_);
4287 value = generator()->frame()->CallStub(&stub, &value, 0); 4287 value = generator()->frame()->CallStub(&stub, &value, 0);
4288 exit()->Jump(&value); 4288 exit_.Jump(&value);
4289 } 4289 }
4290 4290
4291 4291
4292 void CodeGenerator::VisitCountOperation(CountOperation* node) { 4292 void CodeGenerator::VisitCountOperation(CountOperation* node) {
4293 Comment cmnt(masm_, "[ CountOperation"); 4293 Comment cmnt(masm_, "[ CountOperation");
4294 4294
4295 bool is_postfix = node->is_postfix(); 4295 bool is_postfix = node->is_postfix();
4296 bool is_increment = node->op() == Token::INC; 4296 bool is_increment = node->op() == Token::INC;
4297 4297
4298 Variable* var = node->expression()->AsVariableProxy()->AsVariable(); 4298 Variable* var = node->expression()->AsVariableProxy()->AsVariable();
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
4364 tmp.Unuse(); 4364 tmp.Unuse();
4365 __ test(value.reg(), Immediate(kSmiTagMask)); 4365 __ test(value.reg(), Immediate(kSmiTagMask));
4366 deferred->enter()->Branch(not_zero, &value, not_taken); 4366 deferred->enter()->Branch(not_zero, &value, not_taken);
4367 } else { 4367 } else {
4368 deferred->enter()->Branch(overflow, &value, not_taken); 4368 deferred->enter()->Branch(overflow, &value, not_taken);
4369 __ test(value.reg(), Immediate(kSmiTagMask)); 4369 __ test(value.reg(), Immediate(kSmiTagMask));
4370 deferred->enter()->Branch(not_zero, &value, not_taken); 4370 deferred->enter()->Branch(not_zero, &value, not_taken);
4371 } 4371 }
4372 4372
4373 // Store the new value in the target if not const. 4373 // Store the new value in the target if not const.
4374 deferred->exit()->Bind(&value); 4374 deferred->BindExit(&value);
4375 frame_->Push(&value); 4375 frame_->Push(&value);
4376 if (!is_const) { 4376 if (!is_const) {
4377 target.SetValue(NOT_CONST_INIT); 4377 target.SetValue(NOT_CONST_INIT);
4378 } 4378 }
4379 } 4379 }
4380 4380
4381 // Postfix: Discard the new value and use the old. 4381 // Postfix: Discard the new value and use the old.
4382 if (is_postfix) { 4382 if (is_postfix) {
4383 frame_->Drop(); 4383 frame_->Drop();
4384 } 4384 }
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
4815 } 4815 }
4816 // The result needs to be specifically the eax register because the 4816 // The result needs to be specifically the eax register because the
4817 // offset to the patch site will be expected in a test eax 4817 // offset to the patch site will be expected in a test eax
4818 // instruction. 4818 // instruction.
4819 ASSERT(value.is_register() && value.reg().is(eax)); 4819 ASSERT(value.is_register() && value.reg().is(eax));
4820 // The delta from the start of the map-compare instruction to the 4820 // The delta from the start of the map-compare instruction to the
4821 // test eax instruction. 4821 // test eax instruction.
4822 int delta_to_patch_site = __ SizeOfCodeGeneratedSince(patch_site()); 4822 int delta_to_patch_site = __ SizeOfCodeGeneratedSince(patch_site());
4823 __ test(value.reg(), Immediate(-delta_to_patch_site)); 4823 __ test(value.reg(), Immediate(-delta_to_patch_site));
4824 __ IncrementCounter(&Counters::keyed_load_inline_miss, 1); 4824 __ IncrementCounter(&Counters::keyed_load_inline_miss, 1);
4825 exit()->Jump(&value); 4825
4826 // The receiver and key were spilled by the call, so their state as
4827 // constants or copies has been changed. Thus, they need to be
4828 // "mergable" in the block at the exit label and are therefore
4829 // passed as return results here.
4830 key = cgen->frame()->Pop();
4831 receiver = cgen->frame()->Pop();
4832 exit_.Jump(&receiver, &key, &value);
4826 } 4833 }
4827 4834
4828 4835
4829 #undef __ 4836 #undef __
4830 #define __ masm-> 4837 #define __ masm->
4831 4838
4832 Handle<String> Reference::GetName() { 4839 Handle<String> Reference::GetName() {
4833 ASSERT(type_ == NAMED); 4840 ASSERT(type_ == NAMED);
4834 Property* property = expression_->AsProperty(); 4841 Property* property = expression_->AsProperty();
4835 if (property == NULL) { 4842 if (property == NULL) {
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
4958 times_4, 4965 times_4,
4959 Array::kHeaderSize - kHeapObjectTag)); 4966 Array::kHeaderSize - kHeapObjectTag));
4960 elements.Unuse(); 4967 elements.Unuse();
4961 index.Unuse(); 4968 index.Unuse();
4962 __ cmp(Operand(value.reg()), Immediate(Factory::the_hole_value())); 4969 __ cmp(Operand(value.reg()), Immediate(Factory::the_hole_value()));
4963 deferred->enter()->Branch(equal, &receiver, &key, not_taken); 4970 deferred->enter()->Branch(equal, &receiver, &key, not_taken);
4964 __ IncrementCounter(&Counters::keyed_load_inline, 1); 4971 __ IncrementCounter(&Counters::keyed_load_inline, 1);
4965 4972
4966 // Restore the receiver and key to the frame and push the 4973 // Restore the receiver and key to the frame and push the
4967 // result on top of it. 4974 // result on top of it.
4975 deferred->BindExit(&receiver, &key, &value);
4968 cgen_->frame()->Push(&receiver); 4976 cgen_->frame()->Push(&receiver);
4969 cgen_->frame()->Push(&key); 4977 cgen_->frame()->Push(&key);
4970 deferred->exit()->Bind(&value);
4971 cgen_->frame()->Push(&value); 4978 cgen_->frame()->Push(&value);
4972 4979
4973 } else { 4980 } else {
4974 VirtualFrame* frame = cgen_->frame(); 4981 VirtualFrame* frame = cgen_->frame();
4975 Comment cmnt(masm, "[ Load from keyed Property"); 4982 Comment cmnt(masm, "[ Load from keyed Property");
4976 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 4983 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
4977 RelocInfo::Mode rmode = is_global 4984 RelocInfo::Mode rmode = is_global
4978 ? RelocInfo::CODE_TARGET_CONTEXT 4985 ? RelocInfo::CODE_TARGET_CONTEXT
4979 : RelocInfo::CODE_TARGET; 4986 : RelocInfo::CODE_TARGET;
4980 Result answer = frame->CallCodeObject(ic, rmode, 0); 4987 Result answer = frame->CallCodeObject(ic, rmode, 0);
(...skipping 1582 matching lines...) Expand 10 before | Expand all | Expand 10 after
6563 6570
6564 // Slow-case: Go through the JavaScript implementation. 6571 // Slow-case: Go through the JavaScript implementation.
6565 __ bind(&slow); 6572 __ bind(&slow);
6566 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 6573 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
6567 } 6574 }
6568 6575
6569 6576
6570 #undef __ 6577 #undef __
6571 6578
6572 } } // namespace v8::internal 6579 } } // namespace v8::internal
OLDNEW
« src/codegen.h ('K') | « src/codegen-arm.cc ('k') | src/jump-target.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698