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

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

Issue 18495: Move SpilledFrame inside cases of SmiOperation.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: '' Created 11 years, 11 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 | « no previous file | 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-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 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 } 182 }
183 183
184 if (scope_->num_heap_slots() > 0) { 184 if (scope_->num_heap_slots() > 0) {
185 Comment cmnt(masm_, "[ allocate local context"); 185 Comment cmnt(masm_, "[ allocate local context");
186 // Allocate local context. 186 // Allocate local context.
187 // Get outer context and create a new context based on it. 187 // Get outer context and create a new context based on it.
188 frame_->PushFunction(); 188 frame_->PushFunction();
189 Result context = frame_->CallRuntime(Runtime::kNewContext, 1); 189 Result context = frame_->CallRuntime(Runtime::kNewContext, 1);
190 190
191 if (kDebug) { 191 if (kDebug) {
192 frame_->SpillAll(); // Needed for breakpoint below.
193 JumpTarget verified_true(this); 192 JumpTarget verified_true(this);
194 // Verify eax and esi are the same in debug mode 193 // Verify eax and esi are the same in debug mode
195 __ cmp(context.reg(), Operand(esi)); 194 __ cmp(context.reg(), Operand(esi));
196 context.Unuse(); 195 context.Unuse();
197 verified_true.Branch(equal); 196 verified_true.Branch(equal);
197 frame_->SpillAll();
198 __ int3(); 198 __ int3();
199 verified_true.Bind(); 199 verified_true.Bind();
200 } 200 }
201 // Update context local. 201 // Update context local.
202 frame_->SaveContextRegister(); 202 frame_->SaveContextRegister();
203 } 203 }
204 204
205 // TODO(1241774): Improve this code: 205 // TODO(1241774): Improve this code:
206 // 1) only needed if we have a context 206 // 1) only needed if we have a context
207 // 2) no need to recompute context ptr every single time 207 // 2) no need to recompute context ptr every single time
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 848
849 private: 849 private:
850 Token::Value op_; 850 Token::Value op_;
851 int value_; 851 int value_;
852 OverwriteMode overwrite_mode_; 852 OverwriteMode overwrite_mode_;
853 }; 853 };
854 854
855 855
856 class DeferredInlinedSmiAdd: public DeferredCode { 856 class DeferredInlinedSmiAdd: public DeferredCode {
857 public: 857 public:
858 DeferredInlinedSmiAdd(CodeGenerator* generator, int value, 858 DeferredInlinedSmiAdd(CodeGenerator* generator, Smi* value,
859 OverwriteMode overwrite_mode) : 859 OverwriteMode overwrite_mode) :
860 DeferredCode(generator), value_(value), overwrite_mode_(overwrite_mode) { 860 DeferredCode(generator), value_(value), overwrite_mode_(overwrite_mode) {
861 set_comment("[ DeferredInlinedSmiAdd"); 861 set_comment("[ DeferredInlinedSmiAdd");
862 } 862 }
863 863
864 virtual void Generate() { 864 virtual void Generate() {
865 Result arg(generator()); 865 Result arg(generator());
866 enter()->Bind(&arg); 866 enter()->Bind(&arg);
867 arg.ToRegister(); 867 arg.ToRegister();
868 generator()->frame()->Spill(arg.reg()); 868 generator()->frame()->Spill(arg.reg());
869 // Undo the optimistic add operation and call the shared stub. 869 // Undo the optimistic add operation and call the shared stub.
870 __ sub(Operand(arg.reg()), Immediate(Smi::FromInt(value_))); 870 __ sub(Operand(arg.reg()), Immediate(value_));
871 generator()->frame()->Push(&arg); 871 generator()->frame()->Push(&arg);
872 generator()->frame()->Push(Smi::FromInt(value_)); 872 generator()->frame()->Push(value_);
873 GenericBinaryOpStub igostub(Token::ADD, overwrite_mode_, SMI_CODE_INLINED); 873 GenericBinaryOpStub igostub(Token::ADD, overwrite_mode_, SMI_CODE_INLINED);
874 Result result = generator()->frame()->CallStub(&igostub, 2); 874 Result result = generator()->frame()->CallStub(&igostub, 2);
875 exit()->Jump(&result); 875 exit()->Jump(&result);
876 } 876 }
877 877
878 private: 878 private:
879 int value_; 879 Smi* value_;
880 OverwriteMode overwrite_mode_; 880 OverwriteMode overwrite_mode_;
881 }; 881 };
882 882
883 883
884 class DeferredInlinedSmiAddReversed: public DeferredCode { 884 class DeferredInlinedSmiAddReversed: public DeferredCode {
885 public: 885 public:
886 DeferredInlinedSmiAddReversed(CodeGenerator* generator, int value, 886 DeferredInlinedSmiAddReversed(CodeGenerator* generator, Smi* value,
887 OverwriteMode overwrite_mode) : 887 OverwriteMode overwrite_mode) :
888 DeferredCode(generator), value_(value), overwrite_mode_(overwrite_mode) { 888 DeferredCode(generator), value_(value), overwrite_mode_(overwrite_mode) {
889 set_comment("[ DeferredInlinedSmiAddReversed"); 889 set_comment("[ DeferredInlinedSmiAddReversed");
890 } 890 }
891 891
892 virtual void Generate() { 892 virtual void Generate() {
893 Result arg(generator()); 893 Result arg(generator());
894 enter()->Bind(&arg); 894 enter()->Bind(&arg);
895 arg.ToRegister(); 895 arg.ToRegister();
896 generator()->frame()->Spill(arg.reg()); // Should not be needed. 896 generator()->frame()->Spill(arg.reg());
897 // Undo the optimistic add operation and call the shared stub. 897 // Undo the optimistic add operation and call the shared stub.
898 Immediate immediate(Smi::FromInt(value_)); 898 __ sub(Operand(arg.reg()), Immediate(value_));
899 __ sub(Operand(arg.reg()), immediate); 899 generator()->frame()->Push(value_);
900 generator()->frame()->Push(Smi::FromInt(value_));
901 generator()->frame()->Push(&arg); 900 generator()->frame()->Push(&arg);
902 GenericBinaryOpStub igostub(Token::ADD, overwrite_mode_, SMI_CODE_INLINED); 901 GenericBinaryOpStub igostub(Token::ADD, overwrite_mode_, SMI_CODE_INLINED);
903 arg = generator()->frame()->CallStub(&igostub, 2); 902 arg = generator()->frame()->CallStub(&igostub, 2);
904 exit()->Jump(&arg); 903 exit()->Jump(&arg);
905 } 904 }
906 905
907 private: 906 private:
908 int value_; 907 Smi* value_;
909 OverwriteMode overwrite_mode_; 908 OverwriteMode overwrite_mode_;
910 }; 909 };
911 910
912 911
913 class DeferredInlinedSmiSub: public DeferredCode { 912 class DeferredInlinedSmiSub: public DeferredCode {
914 public: 913 public:
915 DeferredInlinedSmiSub(CodeGenerator* generator, int value, 914 DeferredInlinedSmiSub(CodeGenerator* generator,
915 Smi* value,
916 OverwriteMode overwrite_mode) : 916 OverwriteMode overwrite_mode) :
917 DeferredCode(generator), value_(value), overwrite_mode_(overwrite_mode) { 917 DeferredCode(generator), value_(value), overwrite_mode_(overwrite_mode) {
918 set_comment("[ DeferredInlinedSmiSub"); 918 set_comment("[ DeferredInlinedSmiSub");
919 } 919 }
920 920
921 virtual void Generate() { 921 virtual void Generate() {
922 // The argument is actually passed in eax. 922 Result argument(generator());
923 enter()->Bind(); 923 enter()->Bind(&argument);
924 VirtualFrame::SpilledScope spilled_scope(generator()); 924 argument.ToRegister();
925 generator()->frame()->Spill(argument.reg());
925 // Undo the optimistic sub operation and call the shared stub. 926 // Undo the optimistic sub operation and call the shared stub.
926 Immediate immediate(Smi::FromInt(value_)); 927 __ add(Operand(argument.reg()), Immediate(value_));
927 __ add(Operand(eax), immediate); 928 generator()->frame()->Push(&argument);
928 generator()->frame()->EmitPush(eax); 929 generator()->frame()->Push(value_);
929 generator()->frame()->EmitPush(immediate);
930 GenericBinaryOpStub igostub(Token::SUB, overwrite_mode_, SMI_CODE_INLINED); 930 GenericBinaryOpStub igostub(Token::SUB, overwrite_mode_, SMI_CODE_INLINED);
931 generator()->frame()->CallStub(&igostub, 2); 931 Result answer = generator()->frame()->CallStub(&igostub, 2);
932 // The result is actually returned in eax. 932 // The result is actually returned in eax.
933 exit()->Jump(); 933 exit()->Jump(&answer);
934 } 934 }
935 935
936 private: 936 private:
937 int value_; 937 Smi* value_;
938 OverwriteMode overwrite_mode_; 938 OverwriteMode overwrite_mode_;
939 }; 939 };
940 940
941 941
942 class DeferredInlinedSmiSubReversed: public DeferredCode { 942 class DeferredInlinedSmiSubReversed: public DeferredCode {
943 public: 943 public:
944 // tos_reg is used to save the TOS value before reversing the operands 944 DeferredInlinedSmiSubReversed(CodeGenerator* generator,
945 // eax will contain the immediate value after undoing the optimistic sub. 945 Smi* value,
946 DeferredInlinedSmiSubReversed(CodeGenerator* generator, Register tos_reg,
947 OverwriteMode overwrite_mode) : 946 OverwriteMode overwrite_mode) :
948 DeferredCode(generator), tos_reg_(tos_reg), 947 DeferredCode(generator), value_(value),
949 overwrite_mode_(overwrite_mode) { 948 overwrite_mode_(overwrite_mode) {
950 set_comment("[ DeferredInlinedSmiSubReversed"); 949 set_comment("[ DeferredInlinedSmiSubReversed");
951 } 950 }
952 951
953 virtual void Generate() { 952 virtual void Generate() {
954 // The arguments are actually passed in eax and tos_reg. 953 Result rhs(generator());
955 enter()->Bind(); 954 enter()->Bind(&rhs);
956 VirtualFrame::SpilledScope spilled_scope(generator()); 955 generator()->frame()->Push(value_);
957 // Undo the optimistic sub operation and call the shared stub. 956 generator()->frame()->Push(&rhs);
958 __ add(eax, Operand(tos_reg_));
959 generator()->frame()->EmitPush(eax);
960 generator()->frame()->EmitPush(tos_reg_);
961 GenericBinaryOpStub igostub(Token::SUB, overwrite_mode_, SMI_CODE_INLINED); 957 GenericBinaryOpStub igostub(Token::SUB, overwrite_mode_, SMI_CODE_INLINED);
962 generator()->frame()->CallStub(&igostub, 2); 958 Result answer = generator()->frame()->CallStub(&igostub, 2);
963 // The result is actually returned in eax. 959 exit()->Jump(&answer);
964 exit()->Jump();
965 } 960 }
966 961
967 private: 962 private:
968 Register tos_reg_; 963 Smi* value_;
969 OverwriteMode overwrite_mode_; 964 OverwriteMode overwrite_mode_;
970 }; 965 };
971 966
972 967
973 void CodeGenerator::SmiOperation(Token::Value op, 968 void CodeGenerator::SmiOperation(Token::Value op,
974 StaticType* type, 969 StaticType* type,
975 Handle<Object> value, 970 Handle<Object> value,
976 bool reversed, 971 bool reversed,
977 OverwriteMode overwrite_mode) { 972 OverwriteMode overwrite_mode) {
978 // NOTE: This is an attempt to inline (a bit) more of the code for 973 // NOTE: This is an attempt to inline (a bit) more of the code for
979 // some possible smi operations (like + and -) when (at least) one 974 // some possible smi operations (like + and -) when (at least) one
980 // of the operands is a literal smi. With this optimization, the 975 // of the operands is a literal smi. With this optimization, the
981 // performance of the system is increased by ~15%, and the generated 976 // performance of the system is increased by ~15%, and the generated
982 // code size is increased by ~1% (measured on a combination of 977 // code size is increased by ~1% (measured on a combination of
983 // different benchmarks). 978 // different benchmarks).
984 979
985 // TODO(1217802): Optimize some special cases of operations 980 // TODO(1217802): Optimize some special cases of operations
986 // involving a smi literal (multiply by 2, shift by 0, etc.). 981 // involving a smi literal (multiply by 2, shift by 0, etc.).
987 VirtualFrame::SpilledScope spilled_scope(this);
988 982
989 // Get the literal value. 983 // Get the literal value.
990 int int_value = Smi::cast(*value)->value(); 984 Smi* smi_value = Smi::cast(*value);
985 int int_value = smi_value->value();
991 ASSERT(is_intn(int_value, kMaxSmiInlinedBits)); 986 ASSERT(is_intn(int_value, kMaxSmiInlinedBits));
992 987
993 switch (op) { 988 switch (op) {
994 case Token::ADD: { 989 case Token::ADD: {
995 DeferredCode* deferred = NULL; 990 DeferredCode* deferred = NULL;
996 if (!reversed) { 991 if (!reversed) {
997 deferred = new DeferredInlinedSmiAdd(this, int_value, overwrite_mode); 992 deferred = new DeferredInlinedSmiAdd(this, smi_value, overwrite_mode);
998 } else { 993 } else {
999 deferred = new DeferredInlinedSmiAddReversed(this, int_value, 994 deferred = new DeferredInlinedSmiAddReversed(this, smi_value,
1000 overwrite_mode); 995 overwrite_mode);
1001 } 996 }
1002 Result operand = frame_->Pop(); 997 Result operand = frame_->Pop();
1003 operand.ToRegister(); 998 operand.ToRegister();
1004 frame_->Spill(operand.reg()); 999 frame_->Spill(operand.reg());
1005 __ add(Operand(operand.reg()), Immediate(value)); 1000 __ add(Operand(operand.reg()), Immediate(value));
1006 deferred->enter()->Branch(overflow, &operand, not_taken); 1001 deferred->enter()->Branch(overflow, &operand, not_taken);
1007 __ test(Operand(operand.reg()), Immediate(kSmiTagMask)); 1002 __ test(Operand(operand.reg()), Immediate(kSmiTagMask));
1008 deferred->enter()->Branch(not_zero, &operand, not_taken); 1003 deferred->enter()->Branch(not_zero, &operand, not_taken);
1009 deferred->exit()->Bind(&operand); 1004 deferred->exit()->Bind(&operand);
1010 frame_->Push(&operand); 1005 frame_->Push(&operand);
1011 break; 1006 break;
1012 } 1007 }
1013 1008
1014 case Token::SUB: { 1009 case Token::SUB: {
1015 DeferredCode* deferred = NULL; 1010 DeferredCode* deferred = NULL;
1016 frame_->EmitPop(eax); 1011 Result operand = frame_->Pop();
1012 Result answer(this); // Only allocated a new register if reversed.
1017 if (!reversed) { 1013 if (!reversed) {
1018 deferred = new DeferredInlinedSmiSub(this, int_value, overwrite_mode); 1014 operand.ToRegister();
1019 __ sub(Operand(eax), Immediate(value)); 1015 frame_->Spill(operand.reg());
1016 deferred = new DeferredInlinedSmiSub(this,
1017 smi_value,
1018 overwrite_mode);
1019 __ sub(Operand(operand.reg()), Immediate(value));
1020 answer = operand;
1020 } else { 1021 } else {
1021 deferred = new DeferredInlinedSmiSubReversed(this, edx, overwrite_mode); 1022 answer = allocator()->Allocate();
1022 __ mov(edx, Operand(eax)); 1023 ASSERT(answer.is_valid());
1023 __ mov(eax, Immediate(value)); 1024 deferred = new DeferredInlinedSmiSubReversed(this,
1024 __ sub(eax, Operand(edx)); 1025 smi_value,
1026 overwrite_mode);
1027 __ mov(answer.reg(), Immediate(value));
1028 if (operand.is_register()) {
1029 __ sub(answer.reg(), Operand(operand.reg()));
1030 } else {
1031 ASSERT(operand.is_constant());
1032 __ sub(Operand(answer.reg()), Immediate(operand.handle()));
1033 }
1025 } 1034 }
1026 deferred->enter()->Branch(overflow, not_taken); 1035 deferred->enter()->Branch(overflow, &operand, not_taken);
1027 __ test(eax, Immediate(kSmiTagMask)); 1036 __ test(answer.reg(), Immediate(kSmiTagMask));
1028 deferred->enter()->Branch(not_zero, not_taken); 1037 deferred->enter()->Branch(not_zero, &operand, not_taken);
1029 deferred->exit()->Bind(); 1038 operand.Unuse();
1030 frame_->EmitPush(eax); 1039 deferred->exit()->Bind(&answer);
1040 frame_->Push(&answer);
1031 break; 1041 break;
1032 } 1042 }
1033 1043
1034 case Token::SAR: { 1044 case Token::SAR: {
1035 if (reversed) { 1045 if (reversed) {
1036 frame_->EmitPop(eax); 1046 Result top = frame_->Pop();
1037 frame_->EmitPush(Immediate(value)); 1047 frame_->Push(value);
1038 frame_->EmitPush(eax); 1048 frame_->Push(&top);
1039 GenericBinaryOperation(op, type, overwrite_mode); 1049 GenericBinaryOperation(op, type, overwrite_mode);
1040 } else { 1050 } else {
1051 VirtualFrame::SpilledScope spilled_scope(this);
1041 int shift_value = int_value & 0x1f; // only least significant 5 bits 1052 int shift_value = int_value & 0x1f; // only least significant 5 bits
1042 DeferredCode* deferred = 1053 DeferredCode* deferred =
1043 new DeferredInlinedSmiOperation(this, Token::SAR, shift_value, 1054 new DeferredInlinedSmiOperation(this, Token::SAR, shift_value,
1044 overwrite_mode); 1055 overwrite_mode);
1045 frame_->EmitPop(eax); 1056 frame_->EmitPop(eax);
1046 __ test(eax, Immediate(kSmiTagMask)); 1057 __ test(eax, Immediate(kSmiTagMask));
1047 deferred->enter()->Branch(not_zero, not_taken); 1058 deferred->enter()->Branch(not_zero, not_taken);
1048 __ sar(eax, shift_value); 1059 __ sar(eax, shift_value);
1049 __ and_(eax, ~kSmiTagMask); 1060 __ and_(eax, ~kSmiTagMask);
1050 deferred->exit()->Bind(); 1061 deferred->exit()->Bind();
1051 frame_->EmitPush(eax); 1062 frame_->EmitPush(eax);
1052 } 1063 }
1053 break; 1064 break;
1054 } 1065 }
1055 1066
1056 case Token::SHR: { 1067 case Token::SHR: {
1057 if (reversed) { 1068 if (reversed) {
1058 frame_->EmitPop(eax); 1069 Result top = frame_->Pop();
1059 frame_->EmitPush(Immediate(value)); 1070 frame_->Push(value);
1060 frame_->EmitPush(eax); 1071 frame_->Push(&top);
1061 GenericBinaryOperation(op, type, overwrite_mode); 1072 GenericBinaryOperation(op, type, overwrite_mode);
1062 } else { 1073 } else {
1074 VirtualFrame::SpilledScope spilled_scope(this);
1063 int shift_value = int_value & 0x1f; // only least significant 5 bits 1075 int shift_value = int_value & 0x1f; // only least significant 5 bits
1064 DeferredCode* deferred = 1076 DeferredCode* deferred =
1065 new DeferredInlinedSmiOperation(this, Token::SHR, shift_value, 1077 new DeferredInlinedSmiOperation(this, Token::SHR, shift_value,
1066 overwrite_mode); 1078 overwrite_mode);
1067 frame_->EmitPop(eax); 1079 frame_->EmitPop(eax);
1068 __ test(eax, Immediate(kSmiTagMask)); 1080 __ test(eax, Immediate(kSmiTagMask));
1069 __ mov(ebx, Operand(eax)); 1081 __ mov(ebx, Operand(eax));
1070 deferred->enter()->Branch(not_zero, not_taken); 1082 deferred->enter()->Branch(not_zero, not_taken);
1071 __ sar(ebx, kSmiTagSize); 1083 __ sar(ebx, kSmiTagSize);
1072 __ shr(ebx, shift_value); 1084 __ shr(ebx, shift_value);
1073 __ test(ebx, Immediate(0xc0000000)); 1085 __ test(ebx, Immediate(0xc0000000));
1074 deferred->enter()->Branch(not_zero, not_taken); 1086 deferred->enter()->Branch(not_zero, not_taken);
1075 // tag result and store it in TOS (eax) 1087 // tag result and store it in TOS (eax)
1076 ASSERT(kSmiTagSize == times_2); // adjust code if not the case 1088 ASSERT(kSmiTagSize == times_2); // adjust code if not the case
1077 __ lea(eax, Operand(ebx, ebx, times_1, kSmiTag)); 1089 __ lea(eax, Operand(ebx, ebx, times_1, kSmiTag));
1078 deferred->exit()->Bind(); 1090 deferred->exit()->Bind();
1079 frame_->EmitPush(eax); 1091 frame_->EmitPush(eax);
1080 } 1092 }
1081 break; 1093 break;
1082 } 1094 }
1083 1095
1084 case Token::SHL: { 1096 case Token::SHL: {
1097 VirtualFrame::SpilledScope spilled_scope(this);
1085 if (reversed) { 1098 if (reversed) {
1086 frame_->EmitPop(eax); 1099 frame_->EmitPop(eax);
1087 frame_->EmitPush(Immediate(value)); 1100 frame_->EmitPush(Immediate(value));
1088 frame_->EmitPush(eax); 1101 frame_->EmitPush(eax);
1089 GenericBinaryOperation(op, type, overwrite_mode); 1102 GenericBinaryOperation(op, type, overwrite_mode);
1090 } else { 1103 } else {
1091 int shift_value = int_value & 0x1f; // only least significant 5 bits 1104 int shift_value = int_value & 0x1f; // only least significant 5 bits
1092 DeferredCode* deferred = 1105 DeferredCode* deferred =
1093 new DeferredInlinedSmiOperation(this, Token::SHL, shift_value, 1106 new DeferredInlinedSmiOperation(this, Token::SHL, shift_value,
1094 overwrite_mode); 1107 overwrite_mode);
(...skipping 11 matching lines...) Expand all
1106 __ lea(eax, Operand(ebx, ebx, times_1, kSmiTag)); 1119 __ lea(eax, Operand(ebx, ebx, times_1, kSmiTag));
1107 deferred->exit()->Bind(); 1120 deferred->exit()->Bind();
1108 frame_->EmitPush(eax); 1121 frame_->EmitPush(eax);
1109 } 1122 }
1110 break; 1123 break;
1111 } 1124 }
1112 1125
1113 case Token::BIT_OR: 1126 case Token::BIT_OR:
1114 case Token::BIT_XOR: 1127 case Token::BIT_XOR:
1115 case Token::BIT_AND: { 1128 case Token::BIT_AND: {
1129 VirtualFrame::SpilledScope spilled_scope(this);
1116 DeferredCode* deferred = NULL; 1130 DeferredCode* deferred = NULL;
1117 if (!reversed) { 1131 if (!reversed) {
1118 deferred = new DeferredInlinedSmiOperation(this, op, int_value, 1132 deferred = new DeferredInlinedSmiOperation(this, op, int_value,
1119 overwrite_mode); 1133 overwrite_mode);
1120 } else { 1134 } else {
1121 deferred = new DeferredInlinedSmiOperationReversed(this, op, int_value, 1135 deferred = new DeferredInlinedSmiOperationReversed(this, op, int_value,
1122 overwrite_mode); 1136 overwrite_mode);
1123 } 1137 }
1124 frame_->EmitPop(eax); 1138 frame_->EmitPop(eax);
1125 __ test(eax, Immediate(kSmiTagMask)); 1139 __ test(eax, Immediate(kSmiTagMask));
1126 deferred->enter()->Branch(not_zero, not_taken); 1140 deferred->enter()->Branch(not_zero, not_taken);
1127 if (op == Token::BIT_AND) { 1141 if (op == Token::BIT_AND) {
1128 __ and_(Operand(eax), Immediate(value)); 1142 __ and_(Operand(eax), Immediate(value));
1129 } else if (op == Token::BIT_XOR) { 1143 } else if (op == Token::BIT_XOR) {
1130 __ xor_(Operand(eax), Immediate(value)); 1144 __ xor_(Operand(eax), Immediate(value));
1131 } else { 1145 } else {
1132 ASSERT(op == Token::BIT_OR); 1146 ASSERT(op == Token::BIT_OR);
1133 __ or_(Operand(eax), Immediate(value)); 1147 __ or_(Operand(eax), Immediate(value));
1134 } 1148 }
1135 deferred->exit()->Bind(); 1149 deferred->exit()->Bind();
1136 frame_->EmitPush(eax); 1150 frame_->EmitPush(eax);
1137 break; 1151 break;
1138 } 1152 }
1139 1153
1140 default: { 1154 default: {
1141 if (!reversed) { 1155 if (!reversed) {
1142 frame_->EmitPush(Immediate(value)); 1156 frame_->Push(value);
1143 } else { 1157 } else {
1144 frame_->EmitPop(eax); 1158 Result top = frame_->Pop();
1145 frame_->EmitPush(Immediate(value)); 1159 frame_->Push(value);
1146 frame_->EmitPush(eax); 1160 frame_->Push(&top);
1147 } 1161 }
1148 GenericBinaryOperation(op, type, overwrite_mode); 1162 GenericBinaryOperation(op, type, overwrite_mode);
1149 break; 1163 break;
1150 } 1164 }
1151 } 1165 }
1152 } 1166 }
1153 1167
1154 1168
1155 class CompareStub: public CodeStub { 1169 class CompareStub: public CodeStub {
1156 public: 1170 public:
(...skipping 4969 matching lines...) Expand 10 before | Expand all | Expand 10 after
6126 6140
6127 // Slow-case: Go through the JavaScript implementation. 6141 // Slow-case: Go through the JavaScript implementation.
6128 __ bind(&slow); 6142 __ bind(&slow);
6129 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 6143 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
6130 } 6144 }
6131 6145
6132 6146
6133 #undef __ 6147 #undef __
6134 6148
6135 } } // namespace v8::internal 6149 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698