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

Side by Side Diff: src/ia32/virtual-frame-ia32.cc

Issue 844006: Merge changes up to V8 version 2.1.3 into the partial snapshots (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
Patch Set: Created 10 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/ia32/virtual-frame-ia32.h ('k') | src/ic.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 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 12 matching lines...) Expand all
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "codegen-inl.h" 30 #include "codegen-inl.h"
31 #include "register-allocator-inl.h" 31 #include "register-allocator-inl.h"
32 #include "scopes.h" 32 #include "scopes.h"
33 #include "virtual-frame-inl.h"
33 34
34 namespace v8 { 35 namespace v8 {
35 namespace internal { 36 namespace internal {
36 37
37 #define __ ACCESS_MASM(masm()) 38 #define __ ACCESS_MASM(masm())
38 39
39 // -------------------------------------------------------------------------
40 // VirtualFrame implementation.
41
42 // On entry to a function, the virtual frame already contains the receiver,
43 // the parameters, and a return address. All frame elements are in memory.
44 VirtualFrame::VirtualFrame()
45 : elements_(parameter_count() + local_count() + kPreallocatedElements),
46 stack_pointer_(parameter_count() + 1) { // 0-based index of TOS.
47 for (int i = 0; i <= stack_pointer_; i++) {
48 elements_.Add(FrameElement::MemoryElement(NumberInfo::kUnknown));
49 }
50 for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
51 register_locations_[i] = kIllegalIndex;
52 }
53 }
54
55
56 void VirtualFrame::SyncElementBelowStackPointer(int index) { 40 void VirtualFrame::SyncElementBelowStackPointer(int index) {
57 // Emit code to write elements below the stack pointer to their 41 // Emit code to write elements below the stack pointer to their
58 // (already allocated) stack address. 42 // (already allocated) stack address.
59 ASSERT(index <= stack_pointer_); 43 ASSERT(index <= stack_pointer_);
60 FrameElement element = elements_[index]; 44 FrameElement element = elements_[index];
61 ASSERT(!element.is_synced()); 45 ASSERT(!element.is_synced());
62 switch (element.type()) { 46 switch (element.type()) {
63 case FrameElement::INVALID: 47 case FrameElement::INVALID:
64 break; 48 break;
65 49
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 155
172 void VirtualFrame::MakeMergable() { 156 void VirtualFrame::MakeMergable() {
173 for (int i = 0; i < element_count(); i++) { 157 for (int i = 0; i < element_count(); i++) {
174 FrameElement element = elements_[i]; 158 FrameElement element = elements_[i];
175 159
176 // All number type information is reset to unknown for a mergable frame 160 // All number type information is reset to unknown for a mergable frame
177 // because of incoming back edges. 161 // because of incoming back edges.
178 if (element.is_constant() || element.is_copy()) { 162 if (element.is_constant() || element.is_copy()) {
179 if (element.is_synced()) { 163 if (element.is_synced()) {
180 // Just spill. 164 // Just spill.
181 elements_[i] = FrameElement::MemoryElement(NumberInfo::kUnknown); 165 elements_[i] = FrameElement::MemoryElement(NumberInfo::Unknown());
182 } else { 166 } else {
183 // Allocate to a register. 167 // Allocate to a register.
184 FrameElement backing_element; // Invalid if not a copy. 168 FrameElement backing_element; // Invalid if not a copy.
185 if (element.is_copy()) { 169 if (element.is_copy()) {
186 backing_element = elements_[element.index()]; 170 backing_element = elements_[element.index()];
187 } 171 }
188 Result fresh = cgen()->allocator()->Allocate(); 172 Result fresh = cgen()->allocator()->Allocate();
189 ASSERT(fresh.is_valid()); // A register was spilled if all were in use. 173 ASSERT(fresh.is_valid()); // A register was spilled if all were in use.
190 elements_[i] = 174 elements_[i] =
191 FrameElement::RegisterElement(fresh.reg(), 175 FrameElement::RegisterElement(fresh.reg(),
192 FrameElement::NOT_SYNCED, 176 FrameElement::NOT_SYNCED,
193 NumberInfo::kUnknown); 177 NumberInfo::Unknown());
194 Use(fresh.reg(), i); 178 Use(fresh.reg(), i);
195 179
196 // Emit a move. 180 // Emit a move.
197 if (element.is_constant()) { 181 if (element.is_constant()) {
198 if (cgen()->IsUnsafeSmi(element.handle())) { 182 if (cgen()->IsUnsafeSmi(element.handle())) {
199 cgen()->MoveUnsafeSmi(fresh.reg(), element.handle()); 183 cgen()->MoveUnsafeSmi(fresh.reg(), element.handle());
200 } else { 184 } else {
201 __ Set(fresh.reg(), Immediate(element.handle())); 185 __ Set(fresh.reg(), Immediate(element.handle()));
202 } 186 }
203 } else { 187 } else {
(...skipping 12 matching lines...) Expand all
216 } 200 }
217 } 201 }
218 } 202 }
219 // No need to set the copied flag --- there are no copies. 203 // No need to set the copied flag --- there are no copies.
220 } else { 204 } else {
221 // Clear the copy flag of non-constant, non-copy elements. 205 // Clear the copy flag of non-constant, non-copy elements.
222 // They cannot be copied because copies are not allowed. 206 // They cannot be copied because copies are not allowed.
223 // The copy flag is not relied on before the end of this loop, 207 // The copy flag is not relied on before the end of this loop,
224 // including when registers are spilled. 208 // including when registers are spilled.
225 elements_[i].clear_copied(); 209 elements_[i].clear_copied();
226 elements_[i].set_number_info(NumberInfo::kUnknown); 210 elements_[i].set_number_info(NumberInfo::Unknown());
227 } 211 }
228 } 212 }
229 } 213 }
230 214
231 215
232 void VirtualFrame::MergeTo(VirtualFrame* expected) { 216 void VirtualFrame::MergeTo(VirtualFrame* expected) {
233 Comment cmnt(masm(), "[ Merge frame"); 217 Comment cmnt(masm(), "[ Merge frame");
234 // We should always be merging the code generator's current frame to an 218 // We should always be merging the code generator's current frame to an
235 // expected frame. 219 // expected frame.
236 ASSERT(cgen()->frame() == this); 220 ASSERT(cgen()->frame() == this);
(...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after
888 Result VirtualFrame::RawCallCodeObject(Handle<Code> code, 872 Result VirtualFrame::RawCallCodeObject(Handle<Code> code,
889 RelocInfo::Mode rmode) { 873 RelocInfo::Mode rmode) {
890 ASSERT(cgen()->HasValidEntryRegisters()); 874 ASSERT(cgen()->HasValidEntryRegisters());
891 __ call(code, rmode); 875 __ call(code, rmode);
892 Result result = cgen()->allocator()->Allocate(eax); 876 Result result = cgen()->allocator()->Allocate(eax);
893 ASSERT(result.is_valid()); 877 ASSERT(result.is_valid());
894 return result; 878 return result;
895 } 879 }
896 880
897 881
882 // This function assumes that the only results that could be in a_reg or b_reg
883 // are a and b. Other results can be live, but must not be in a_reg or b_reg.
884 void VirtualFrame::MoveResultsToRegisters(Result* a,
885 Result* b,
886 Register a_reg,
887 Register b_reg) {
888 if (a->is_register() && a->reg().is(a_reg)) {
889 b->ToRegister(b_reg);
890 } else if (!cgen()->allocator()->is_used(a_reg)) {
891 a->ToRegister(a_reg);
892 b->ToRegister(b_reg);
893 } else if (cgen()->allocator()->is_used(b_reg)) {
894 // a must be in b_reg, b in a_reg.
895 __ xchg(a_reg, b_reg);
896 // Results a and b will be invalidated, so it is ok if they are switched.
897 } else {
898 b->ToRegister(b_reg);
899 a->ToRegister(a_reg);
900 }
901 a->Unuse();
902 b->Unuse();
903 }
904
905
898 Result VirtualFrame::CallLoadIC(RelocInfo::Mode mode) { 906 Result VirtualFrame::CallLoadIC(RelocInfo::Mode mode) {
899 // Name and receiver are on the top of the frame. The IC expects 907 // Name and receiver are on the top of the frame. The IC expects
900 // name in ecx and receiver in eax. 908 // name in ecx and receiver in eax.
901 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
902 Result name = Pop(); 909 Result name = Pop();
903 Result receiver = Pop(); 910 Result receiver = Pop();
904 PrepareForCall(0, 0); // No stack arguments. 911 PrepareForCall(0, 0); // No stack arguments.
905 // Move results to the right registers: 912 MoveResultsToRegisters(&name, &receiver, ecx, eax);
906 if (name.is_register() && name.reg().is(eax)) { 913
907 if (receiver.is_register() && receiver.reg().is(ecx)) { 914 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
908 // Wrong registers.
909 __ xchg(eax, ecx);
910 } else {
911 // Register ecx is free for name, which frees eax for receiver.
912 name.ToRegister(ecx);
913 receiver.ToRegister(eax);
914 }
915 } else {
916 // Register eax is free for receiver, which frees ecx for name.
917 receiver.ToRegister(eax);
918 name.ToRegister(ecx);
919 }
920 name.Unuse();
921 receiver.Unuse();
922 return RawCallCodeObject(ic, mode); 915 return RawCallCodeObject(ic, mode);
923 } 916 }
924 917
925 918
926 Result VirtualFrame::CallKeyedLoadIC(RelocInfo::Mode mode) { 919 Result VirtualFrame::CallKeyedLoadIC(RelocInfo::Mode mode) {
927 // Key and receiver are on top of the frame. Put them in eax and edx. 920 // Key and receiver are on top of the frame. Put them in eax and edx.
928 Result key = Pop(); 921 Result key = Pop();
929 Result receiver = Pop(); 922 Result receiver = Pop();
930 PrepareForCall(0, 0); 923 PrepareForCall(0, 0);
931 924 MoveResultsToRegisters(&key, &receiver, eax, edx);
932 if (!key.is_register() || !key.reg().is(edx)) {
933 // Register edx is available for receiver.
934 receiver.ToRegister(edx);
935 key.ToRegister(eax);
936 } else if (!receiver.is_register() || !receiver.reg().is(eax)) {
937 // Register eax is available for key.
938 key.ToRegister(eax);
939 receiver.ToRegister(edx);
940 } else {
941 __ xchg(edx, eax);
942 }
943 key.Unuse();
944 receiver.Unuse();
945 925
946 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 926 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
947 return RawCallCodeObject(ic, mode); 927 return RawCallCodeObject(ic, mode);
948 } 928 }
949 929
950 930
951 Result VirtualFrame::CallStoreIC(Handle<String> name, bool is_contextual) { 931 Result VirtualFrame::CallStoreIC(Handle<String> name, bool is_contextual) {
952 // Value and (if not contextual) receiver are on top of the frame. 932 // Value and (if not contextual) receiver are on top of the frame.
953 // The IC expects name in ecx, value in eax, and receiver in edx. 933 // The IC expects name in ecx, value in eax, and receiver in edx.
954 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 934 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
955 Result value = Pop(); 935 Result value = Pop();
956 if (is_contextual) { 936 if (is_contextual) {
957 PrepareForCall(0, 0); 937 PrepareForCall(0, 0);
958 value.ToRegister(eax); 938 value.ToRegister(eax);
959 __ mov(edx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); 939 __ mov(edx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
960 __ mov(ecx, name); 940 value.Unuse();
961 } else { 941 } else {
962 Result receiver = Pop(); 942 Result receiver = Pop();
963 PrepareForCall(0, 0); 943 PrepareForCall(0, 0);
964 944 MoveResultsToRegisters(&value, &receiver, eax, edx);
965 if (value.is_register() && value.reg().is(edx)) {
966 if (receiver.is_register() && receiver.reg().is(eax)) {
967 // Wrong registers.
968 __ xchg(eax, edx);
969 } else {
970 // Register eax is free for value, which frees edx for receiver.
971 value.ToRegister(eax);
972 receiver.ToRegister(edx);
973 }
974 } else {
975 // Register edx is free for receiver, which guarantees eax is free for
976 // value.
977 receiver.ToRegister(edx);
978 value.ToRegister(eax);
979 }
980 } 945 }
981 __ mov(ecx, name); 946 __ mov(ecx, name);
982 value.Unuse();
983 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET); 947 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
984 } 948 }
985 949
986 950
987 Result VirtualFrame::CallKeyedStoreIC() { 951 Result VirtualFrame::CallKeyedStoreIC() {
988 // Value, key, and receiver are on the top of the frame. The IC 952 // Value, key, and receiver are on the top of the frame. The IC
989 // expects value in eax and key and receiver on the stack. It does 953 // expects value in eax, key in ecx, and receiver in edx.
990 // not drop the key and receiver. 954 Result value = Pop();
955 Result key = Pop();
956 Result receiver = Pop();
957 PrepareForCall(0, 0);
958 if (!cgen()->allocator()->is_used(eax) ||
959 (value.is_register() && value.reg().is(eax))) {
960 value.ToRegister(eax); // No effect if value is in eax already.
961 MoveResultsToRegisters(&key, &receiver, ecx, edx);
962 value.Unuse();
963 } else if (!cgen()->allocator()->is_used(ecx) ||
964 (key.is_register() && key.reg().is(ecx))) {
965 // Receiver and/or key are in eax.
966 key.ToRegister(ecx);
967 MoveResultsToRegisters(&value, &receiver, eax, edx);
968 key.Unuse();
969 } else if (!cgen()->allocator()->is_used(edx) ||
970 (receiver.is_register() && receiver.reg().is(edx))) {
971 receiver.ToRegister(edx);
972 MoveResultsToRegisters(&key, &value, ecx, eax);
973 receiver.Unuse();
974 } else {
975 // All three registers are used, and no value is in the correct place.
976 // We have one of the two circular permutations of eax, ecx, edx.
977 ASSERT(value.is_register());
978 if (value.reg().is(ecx)) {
979 __ xchg(eax, edx);
980 __ xchg(eax, ecx);
981 } else {
982 __ xchg(eax, ecx);
983 __ xchg(eax, edx);
984 }
985 value.Unuse();
986 key.Unuse();
987 receiver.Unuse();
988 }
989
991 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 990 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
992 Result value = Pop();
993 PrepareForCall(2, 0); // Two stack args, neither callee-dropped.
994 value.ToRegister(eax);
995 value.Unuse();
996 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET); 991 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
997 } 992 }
998 993
999 994
1000 Result VirtualFrame::CallCallIC(RelocInfo::Mode mode, 995 Result VirtualFrame::CallCallIC(RelocInfo::Mode mode,
1001 int arg_count, 996 int arg_count,
1002 int loop_nesting) { 997 int loop_nesting) {
1003 // Function name, arguments, and receiver are on top of the frame. 998 // Function name, arguments, and receiver are on top of the frame.
1004 // The IC expects the name in ecx and the rest on the stack and 999 // The IC expects the name in ecx and the rest on the stack and
1005 // drops them all. 1000 // drops them all.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1060 } 1055 }
1061 } 1056 }
1062 1057
1063 1058
1064 Result VirtualFrame::Pop() { 1059 Result VirtualFrame::Pop() {
1065 FrameElement element = elements_.RemoveLast(); 1060 FrameElement element = elements_.RemoveLast();
1066 int index = element_count(); 1061 int index = element_count();
1067 ASSERT(element.is_valid()); 1062 ASSERT(element.is_valid());
1068 1063
1069 // Get number type information of the result. 1064 // Get number type information of the result.
1070 NumberInfo::Type info; 1065 NumberInfo info;
1071 if (!element.is_copy()) { 1066 if (!element.is_copy()) {
1072 info = element.number_info(); 1067 info = element.number_info();
1073 } else { 1068 } else {
1074 info = elements_[element.index()].number_info(); 1069 info = elements_[element.index()].number_info();
1075 } 1070 }
1076 1071
1077 bool pop_needed = (stack_pointer_ == index); 1072 bool pop_needed = (stack_pointer_ == index);
1078 if (pop_needed) { 1073 if (pop_needed) {
1079 stack_pointer_--; 1074 stack_pointer_--;
1080 if (element.is_memory()) { 1075 if (element.is_memory()) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1135 1130
1136 1131
1137 void VirtualFrame::EmitPop(Operand operand) { 1132 void VirtualFrame::EmitPop(Operand operand) {
1138 ASSERT(stack_pointer_ == element_count() - 1); 1133 ASSERT(stack_pointer_ == element_count() - 1);
1139 stack_pointer_--; 1134 stack_pointer_--;
1140 elements_.RemoveLast(); 1135 elements_.RemoveLast();
1141 __ pop(operand); 1136 __ pop(operand);
1142 } 1137 }
1143 1138
1144 1139
1145 void VirtualFrame::EmitPush(Register reg, NumberInfo::Type info) { 1140 void VirtualFrame::EmitPush(Register reg, NumberInfo info) {
1146 ASSERT(stack_pointer_ == element_count() - 1); 1141 ASSERT(stack_pointer_ == element_count() - 1);
1147 elements_.Add(FrameElement::MemoryElement(info)); 1142 elements_.Add(FrameElement::MemoryElement(info));
1148 stack_pointer_++; 1143 stack_pointer_++;
1149 __ push(reg); 1144 __ push(reg);
1150 } 1145 }
1151 1146
1152 1147
1153 void VirtualFrame::EmitPush(Operand operand, NumberInfo::Type info) { 1148 void VirtualFrame::EmitPush(Operand operand, NumberInfo info) {
1154 ASSERT(stack_pointer_ == element_count() - 1); 1149 ASSERT(stack_pointer_ == element_count() - 1);
1155 elements_.Add(FrameElement::MemoryElement(info)); 1150 elements_.Add(FrameElement::MemoryElement(info));
1156 stack_pointer_++; 1151 stack_pointer_++;
1157 __ push(operand); 1152 __ push(operand);
1158 } 1153 }
1159 1154
1160 1155
1161 void VirtualFrame::EmitPush(Immediate immediate, NumberInfo::Type info) { 1156 void VirtualFrame::EmitPush(Immediate immediate, NumberInfo info) {
1162 ASSERT(stack_pointer_ == element_count() - 1); 1157 ASSERT(stack_pointer_ == element_count() - 1);
1163 elements_.Add(FrameElement::MemoryElement(info)); 1158 elements_.Add(FrameElement::MemoryElement(info));
1164 stack_pointer_++; 1159 stack_pointer_++;
1165 __ push(immediate); 1160 __ push(immediate);
1166 } 1161 }
1167 1162
1168 1163
1169 void VirtualFrame::Push(Expression* expr) { 1164 void VirtualFrame::Push(Expression* expr) {
1170 ASSERT(expr->IsTrivial()); 1165 ASSERT(expr->IsTrivial());
1171 1166
1172 Literal* lit = expr->AsLiteral(); 1167 Literal* lit = expr->AsLiteral();
1173 if (lit != NULL) { 1168 if (lit != NULL) {
1174 Push(lit->handle()); 1169 Push(lit->handle());
1175 return; 1170 return;
1176 } 1171 }
1177 1172
1178 VariableProxy* proxy = expr->AsVariableProxy(); 1173 VariableProxy* proxy = expr->AsVariableProxy();
1179 if (proxy != NULL && proxy->is_this()) { 1174 if (proxy != NULL && proxy->is_this()) {
1180 PushParameterAt(-1); 1175 PushParameterAt(-1);
1181 return; 1176 return;
1182 } 1177 }
1183 1178
1184 UNREACHABLE(); 1179 UNREACHABLE();
1185 } 1180 }
1186 1181
1187 1182
1188 #undef __ 1183 #undef __
1189 1184
1190 } } // namespace v8::internal 1185 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/virtual-frame-ia32.h ('k') | src/ic.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698