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

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,
Kevin Millikin (Chromium) 2009/01/23 08:49:25 While you're changing this code, you could clean i
William Hesse 2012/05/07 09:35:10 Done.
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() {
Kevin Millikin (Chromium) 2009/01/23 08:49:25 I also don't care for these inline-looking Generat
William Hesse 2012/05/07 09:35:10 Done.
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.
Kevin Millikin (Chromium) 2009/01/23 08:49:25 Remove this comment.
William Hesse 2012/05/07 09:35:10 Done.
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 // tos_reg is used to save the TOS value before reversing the operands
945 // eax will contain the immediate value after undoing the optimistic sub. 945 // eax will contain the immediate value after undoing the optimistic sub.
946 DeferredInlinedSmiSubReversed(CodeGenerator* generator, Register tos_reg, 946 DeferredInlinedSmiSubReversed(CodeGenerator* generator,
947 Smi* value,
947 OverwriteMode overwrite_mode) : 948 OverwriteMode overwrite_mode) :
948 DeferredCode(generator), tos_reg_(tos_reg), 949 DeferredCode(generator), value_(value),
949 overwrite_mode_(overwrite_mode) { 950 overwrite_mode_(overwrite_mode) {
950 set_comment("[ DeferredInlinedSmiSubReversed"); 951 set_comment("[ DeferredInlinedSmiSubReversed");
951 } 952 }
952 953
953 virtual void Generate() { 954 virtual void Generate() {
954 // The arguments are actually passed in eax and tos_reg. 955 Result argument(generator());
955 enter()->Bind(); 956 enter()->Bind(&argument); // argument contains lhs - rhs. lhs is value.
Kevin Millikin (Chromium) 2009/01/23 08:49:25 Try to make comments look like English sentences.
956 VirtualFrame::SpilledScope spilled_scope(generator()); 957 argument.ToRegister();
958 generator()->frame()->Spill(argument.reg());
Kevin Millikin (Chromium) 2009/01/23 08:49:25 I'm confused by this spill. Since argument is not
957 // Undo the optimistic sub operation and call the shared stub. 959 // Undo the optimistic sub operation and call the shared stub.
958 __ add(eax, Operand(tos_reg_)); 960 Result temp = generator()->allocator()->Allocate();
959 generator()->frame()->EmitPush(eax); 961 ASSERT(temp.is_valid());
960 generator()->frame()->EmitPush(tos_reg_); 962 __ mov(temp.reg(), Immediate(value_));
963 __ sub(temp.reg(), Operand(argument.reg())); // lhs - (lhs - rhs) gives us r hs.
Kevin Millikin (Chromium) 2009/01/23 08:49:25 Line seems too long. There should be two spaces b
964 argument.Unuse();
965 generator()->frame()->Push(value_);
966 generator()->frame()->Push(&temp);
961 GenericBinaryOpStub igostub(Token::SUB, overwrite_mode_, SMI_CODE_INLINED); 967 GenericBinaryOpStub igostub(Token::SUB, overwrite_mode_, SMI_CODE_INLINED);
962 generator()->frame()->CallStub(&igostub, 2); 968 Result answer = generator()->frame()->CallStub(&igostub, 2);
963 // The result is actually returned in eax. 969 exit()->Jump(&answer);
964 exit()->Jump();
965 } 970 }
966 971
967 private: 972 private:
968 Register tos_reg_; 973 Smi* value_;
969 OverwriteMode overwrite_mode_; 974 OverwriteMode overwrite_mode_;
970 }; 975 };
971 976
972 977
973 void CodeGenerator::SmiOperation(Token::Value op, 978 void CodeGenerator::SmiOperation(Token::Value op,
974 StaticType* type, 979 StaticType* type,
975 Handle<Object> value, 980 Handle<Object> value,
976 bool reversed, 981 bool reversed,
977 OverwriteMode overwrite_mode) { 982 OverwriteMode overwrite_mode) {
978 // NOTE: This is an attempt to inline (a bit) more of the code for 983 // 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 984 // some possible smi operations (like + and -) when (at least) one
980 // of the operands is a literal smi. With this optimization, the 985 // of the operands is a literal smi. With this optimization, the
981 // performance of the system is increased by ~15%, and the generated 986 // performance of the system is increased by ~15%, and the generated
982 // code size is increased by ~1% (measured on a combination of 987 // code size is increased by ~1% (measured on a combination of
983 // different benchmarks). 988 // different benchmarks).
984 989
985 // TODO(1217802): Optimize some special cases of operations 990 // TODO(1217802): Optimize some special cases of operations
986 // involving a smi literal (multiply by 2, shift by 0, etc.). 991 // involving a smi literal (multiply by 2, shift by 0, etc.).
987 VirtualFrame::SpilledScope spilled_scope(this);
988 992
989 // Get the literal value. 993 // Get the literal value.
990 int int_value = Smi::cast(*value)->value(); 994 Smi* smi_value = Smi::cast(*value);
995 int int_value = smi_value->value();
991 ASSERT(is_intn(int_value, kMaxSmiInlinedBits)); 996 ASSERT(is_intn(int_value, kMaxSmiInlinedBits));
992 997
993 switch (op) { 998 switch (op) {
994 case Token::ADD: { 999 case Token::ADD: {
995 DeferredCode* deferred = NULL; 1000 DeferredCode* deferred = NULL;
996 if (!reversed) { 1001 if (!reversed) {
Kevin Millikin (Chromium) 2009/01/23 08:49:25 Since this is a two-armed if anyway, it might read
William Hesse 2012/05/07 09:35:10 Done.
997 deferred = new DeferredInlinedSmiAdd(this, int_value, overwrite_mode); 1002 deferred = new DeferredInlinedSmiAdd(this, smi_value, overwrite_mode);
998 } else { 1003 } else {
999 deferred = new DeferredInlinedSmiAddReversed(this, int_value, 1004 deferred = new DeferredInlinedSmiAddReversed(this, smi_value,
1000 overwrite_mode); 1005 overwrite_mode);
1001 } 1006 }
1002 Result operand = frame_->Pop(); 1007 Result operand = frame_->Pop();
1003 operand.ToRegister(); 1008 operand.ToRegister();
1004 frame_->Spill(operand.reg()); 1009 frame_->Spill(operand.reg());
1005 __ add(Operand(operand.reg()), Immediate(value)); 1010 __ add(Operand(operand.reg()), Immediate(value));
1006 deferred->enter()->Branch(overflow, &operand, not_taken); 1011 deferred->enter()->Branch(overflow, &operand, not_taken);
1007 __ test(Operand(operand.reg()), Immediate(kSmiTagMask)); 1012 __ test(Operand(operand.reg()), Immediate(kSmiTagMask));
1008 deferred->enter()->Branch(not_zero, &operand, not_taken); 1013 deferred->enter()->Branch(not_zero, &operand, not_taken);
1009 deferred->exit()->Bind(&operand); 1014 deferred->exit()->Bind(&operand);
1010 frame_->Push(&operand); 1015 frame_->Push(&operand);
1011 break; 1016 break;
1012 } 1017 }
1013 1018
1014 case Token::SUB: { 1019 case Token::SUB: {
1015 DeferredCode* deferred = NULL; 1020 DeferredCode* deferred = NULL;
1016 frame_->EmitPop(eax); 1021 Result operand = frame_->Pop();
1022 Result answer(this); // Only allocated a new register if reversed.
Kevin Millikin (Chromium) 2009/01/23 08:49:25 allocated ==> allocate
William Hesse 2012/05/07 09:35:10 Done.
1023 operand.ToRegister();
1024 frame_->Spill(operand.reg());
Kevin Millikin (Chromium) 2009/01/23 08:49:25 It looks like operand is only clobbered in the not
William Hesse 2012/05/07 09:35:10 Done.
1017 if (!reversed) { 1025 if (!reversed) {
1018 deferred = new DeferredInlinedSmiSub(this, int_value, overwrite_mode); 1026 deferred = new DeferredInlinedSmiSub(this,
1019 __ sub(Operand(eax), Immediate(value)); 1027 smi_value,
1028 overwrite_mode);
1029 __ sub(Operand(operand.reg()), Immediate(value));
1030 answer = operand;
1020 } else { 1031 } else {
1021 deferred = new DeferredInlinedSmiSubReversed(this, edx, overwrite_mode); 1032 answer = allocator()->Allocate();
1022 __ mov(edx, Operand(eax)); 1033 ASSERT(answer.is_valid());
1023 __ mov(eax, Immediate(value)); 1034 deferred = new DeferredInlinedSmiSubReversed(this,
1024 __ sub(eax, Operand(edx)); 1035 smi_value,
1036 overwrite_mode);
1037 __ mov(answer.reg(), Immediate(value));
1038 __ sub(answer.reg(), Operand(operand.reg()));
1025 } 1039 }
1026 deferred->enter()->Branch(overflow, not_taken); 1040 operand.Unuse();
1027 __ test(eax, Immediate(kSmiTagMask)); 1041 deferred->enter()->Branch(overflow, &answer, not_taken);
Kevin Millikin (Chromium) 2009/01/23 08:49:25 Maybe it makes this code uglier, but can't we pass
William Hesse 2012/05/07 09:35:10 Done.
1028 deferred->enter()->Branch(not_zero, not_taken); 1042 __ test(answer.reg(), Immediate(kSmiTagMask));
1029 deferred->exit()->Bind(); 1043 deferred->enter()->Branch(not_zero, &answer, not_taken);
1030 frame_->EmitPush(eax); 1044 deferred->exit()->Bind(&answer);
1045 frame_->Push(&answer);
1031 break; 1046 break;
1032 } 1047 }
1033 1048
1034 case Token::SAR: { 1049 case Token::SAR: {
1035 if (reversed) { 1050 if (reversed) {
1036 frame_->EmitPop(eax); 1051 Result top = frame_->Pop();
1037 frame_->EmitPush(Immediate(value)); 1052 frame_->Push(value);
1038 frame_->EmitPush(eax); 1053 frame_->Push(&top);
1039 GenericBinaryOperation(op, type, overwrite_mode); 1054 GenericBinaryOperation(op, type, overwrite_mode);
1040 } else { 1055 } else {
1056 VirtualFrame::SpilledScope spilled_scope(this);
1041 int shift_value = int_value & 0x1f; // only least significant 5 bits 1057 int shift_value = int_value & 0x1f; // only least significant 5 bits
1042 DeferredCode* deferred = 1058 DeferredCode* deferred =
1043 new DeferredInlinedSmiOperation(this, Token::SAR, shift_value, 1059 new DeferredInlinedSmiOperation(this, Token::SAR, shift_value,
1044 overwrite_mode); 1060 overwrite_mode);
1045 frame_->EmitPop(eax); 1061 frame_->EmitPop(eax);
1046 __ test(eax, Immediate(kSmiTagMask)); 1062 __ test(eax, Immediate(kSmiTagMask));
1047 deferred->enter()->Branch(not_zero, not_taken); 1063 deferred->enter()->Branch(not_zero, not_taken);
1048 __ sar(eax, shift_value); 1064 __ sar(eax, shift_value);
1049 __ and_(eax, ~kSmiTagMask); 1065 __ and_(eax, ~kSmiTagMask);
1050 deferred->exit()->Bind(); 1066 deferred->exit()->Bind();
1051 frame_->EmitPush(eax); 1067 frame_->EmitPush(eax);
1052 } 1068 }
1053 break; 1069 break;
1054 } 1070 }
1055 1071
1056 case Token::SHR: { 1072 case Token::SHR: {
1057 if (reversed) { 1073 if (reversed) {
1058 frame_->EmitPop(eax); 1074 Result top = frame_->Pop();
1059 frame_->EmitPush(Immediate(value)); 1075 frame_->Push(value);
1060 frame_->EmitPush(eax); 1076 frame_->Push(&top);
1061 GenericBinaryOperation(op, type, overwrite_mode); 1077 GenericBinaryOperation(op, type, overwrite_mode);
1062 } else { 1078 } else {
1079 VirtualFrame::SpilledScope spilled_scope(this);
1063 int shift_value = int_value & 0x1f; // only least significant 5 bits 1080 int shift_value = int_value & 0x1f; // only least significant 5 bits
1064 DeferredCode* deferred = 1081 DeferredCode* deferred =
1065 new DeferredInlinedSmiOperation(this, Token::SHR, shift_value, 1082 new DeferredInlinedSmiOperation(this, Token::SHR, shift_value,
1066 overwrite_mode); 1083 overwrite_mode);
1067 frame_->EmitPop(eax); 1084 frame_->EmitPop(eax);
1068 __ test(eax, Immediate(kSmiTagMask)); 1085 __ test(eax, Immediate(kSmiTagMask));
1069 __ mov(ebx, Operand(eax)); 1086 __ mov(ebx, Operand(eax));
1070 deferred->enter()->Branch(not_zero, not_taken); 1087 deferred->enter()->Branch(not_zero, not_taken);
1071 __ sar(ebx, kSmiTagSize); 1088 __ sar(ebx, kSmiTagSize);
1072 __ shr(ebx, shift_value); 1089 __ shr(ebx, shift_value);
1073 __ test(ebx, Immediate(0xc0000000)); 1090 __ test(ebx, Immediate(0xc0000000));
1074 deferred->enter()->Branch(not_zero, not_taken); 1091 deferred->enter()->Branch(not_zero, not_taken);
1075 // tag result and store it in TOS (eax) 1092 // tag result and store it in TOS (eax)
1076 ASSERT(kSmiTagSize == times_2); // adjust code if not the case 1093 ASSERT(kSmiTagSize == times_2); // adjust code if not the case
1077 __ lea(eax, Operand(ebx, ebx, times_1, kSmiTag)); 1094 __ lea(eax, Operand(ebx, ebx, times_1, kSmiTag));
1078 deferred->exit()->Bind(); 1095 deferred->exit()->Bind();
1079 frame_->EmitPush(eax); 1096 frame_->EmitPush(eax);
1080 } 1097 }
1081 break; 1098 break;
1082 } 1099 }
1083 1100
1084 case Token::SHL: { 1101 case Token::SHL: {
1102 VirtualFrame::SpilledScope spilled_scope(this);
1085 if (reversed) { 1103 if (reversed) {
1086 frame_->EmitPop(eax); 1104 frame_->EmitPop(eax);
1087 frame_->EmitPush(Immediate(value)); 1105 frame_->EmitPush(Immediate(value));
1088 frame_->EmitPush(eax); 1106 frame_->EmitPush(eax);
1089 GenericBinaryOperation(op, type, overwrite_mode); 1107 GenericBinaryOperation(op, type, overwrite_mode);
1090 } else { 1108 } else {
1091 int shift_value = int_value & 0x1f; // only least significant 5 bits 1109 int shift_value = int_value & 0x1f; // only least significant 5 bits
1092 DeferredCode* deferred = 1110 DeferredCode* deferred =
1093 new DeferredInlinedSmiOperation(this, Token::SHL, shift_value, 1111 new DeferredInlinedSmiOperation(this, Token::SHL, shift_value,
1094 overwrite_mode); 1112 overwrite_mode);
(...skipping 11 matching lines...) Expand all
1106 __ lea(eax, Operand(ebx, ebx, times_1, kSmiTag)); 1124 __ lea(eax, Operand(ebx, ebx, times_1, kSmiTag));
1107 deferred->exit()->Bind(); 1125 deferred->exit()->Bind();
1108 frame_->EmitPush(eax); 1126 frame_->EmitPush(eax);
1109 } 1127 }
1110 break; 1128 break;
1111 } 1129 }
1112 1130
1113 case Token::BIT_OR: 1131 case Token::BIT_OR:
1114 case Token::BIT_XOR: 1132 case Token::BIT_XOR:
1115 case Token::BIT_AND: { 1133 case Token::BIT_AND: {
1134 VirtualFrame::SpilledScope spilled_scope(this);
1116 DeferredCode* deferred = NULL; 1135 DeferredCode* deferred = NULL;
1117 if (!reversed) { 1136 if (!reversed) {
1118 deferred = new DeferredInlinedSmiOperation(this, op, int_value, 1137 deferred = new DeferredInlinedSmiOperation(this, op, int_value,
1119 overwrite_mode); 1138 overwrite_mode);
1120 } else { 1139 } else {
1121 deferred = new DeferredInlinedSmiOperationReversed(this, op, int_value, 1140 deferred = new DeferredInlinedSmiOperationReversed(this, op, int_value,
1122 overwrite_mode); 1141 overwrite_mode);
1123 } 1142 }
1124 frame_->EmitPop(eax); 1143 frame_->EmitPop(eax);
1125 __ test(eax, Immediate(kSmiTagMask)); 1144 __ test(eax, Immediate(kSmiTagMask));
1126 deferred->enter()->Branch(not_zero, not_taken); 1145 deferred->enter()->Branch(not_zero, not_taken);
1127 if (op == Token::BIT_AND) { 1146 if (op == Token::BIT_AND) {
1128 __ and_(Operand(eax), Immediate(value)); 1147 __ and_(Operand(eax), Immediate(value));
1129 } else if (op == Token::BIT_XOR) { 1148 } else if (op == Token::BIT_XOR) {
1130 __ xor_(Operand(eax), Immediate(value)); 1149 __ xor_(Operand(eax), Immediate(value));
1131 } else { 1150 } else {
1132 ASSERT(op == Token::BIT_OR); 1151 ASSERT(op == Token::BIT_OR);
1133 __ or_(Operand(eax), Immediate(value)); 1152 __ or_(Operand(eax), Immediate(value));
1134 } 1153 }
1135 deferred->exit()->Bind(); 1154 deferred->exit()->Bind();
1136 frame_->EmitPush(eax); 1155 frame_->EmitPush(eax);
1137 break; 1156 break;
1138 } 1157 }
1139 1158
1140 default: { 1159 default: {
1141 if (!reversed) { 1160 if (!reversed) {
Kevin Millikin (Chromium) 2009/01/23 08:49:25 Reverse the arms of the if?
William Hesse 2012/05/07 09:35:10 Done.
1142 frame_->EmitPush(Immediate(value)); 1161 frame_->Push(value);
1143 } else { 1162 } else {
1144 frame_->EmitPop(eax); 1163 Result top = frame_->Pop();
1145 frame_->EmitPush(Immediate(value)); 1164 frame_->Push(value);
1146 frame_->EmitPush(eax); 1165 frame_->Push(&top);
1147 } 1166 }
1148 GenericBinaryOperation(op, type, overwrite_mode); 1167 GenericBinaryOperation(op, type, overwrite_mode);
1149 break; 1168 break;
1150 } 1169 }
1151 } 1170 }
1152 } 1171 }
1153 1172
1154 1173
1155 class CompareStub: public CodeStub { 1174 class CompareStub: public CodeStub {
1156 public: 1175 public:
(...skipping 4952 matching lines...) Expand 10 before | Expand all | Expand 10 after
6109 6128
6110 // Slow-case: Go through the JavaScript implementation. 6129 // Slow-case: Go through the JavaScript implementation.
6111 __ bind(&slow); 6130 __ bind(&slow);
6112 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 6131 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
6113 } 6132 }
6114 6133
6115 6134
6116 #undef __ 6135 #undef __
6117 6136
6118 } } // namespace v8::internal 6137 } } // 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