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

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

Issue 3060002: Remove VirtualFrame::CallStoreIC(void) and CallCommonStoreIC from virtual-fra... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 5 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
« src/x64/codegen-x64.cc ('K') | « src/x64/virtual-frame-x64.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 979 matching lines...) Expand 10 before | Expand all | Expand 10 after
990 if (!elements_[i].is_synced()) SyncElementBelowStackPointer(i); 990 if (!elements_[i].is_synced()) SyncElementBelowStackPointer(i);
991 i++; 991 i++;
992 } 992 }
993 while (i <= end) { 993 while (i <= end) {
994 SyncElementByPushing(i); 994 SyncElementByPushing(i);
995 i++; 995 i++;
996 } 996 }
997 } 997 }
998 998
999 999
1000 Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id,
1001 InvokeFlag flag,
1002 int arg_count) {
1003 PrepareForCall(arg_count, arg_count);
1004 ASSERT(cgen()->HasValidEntryRegisters());
1005 __ InvokeBuiltin(id, flag);
1006 Result result = cgen()->allocator()->Allocate(rax);
1007 ASSERT(result.is_valid());
1008 return result;
1009 }
1010
1011
1012 //------------------------------------------------------------------------------ 1000 //------------------------------------------------------------------------------
1013 // Virtual frame stub and IC calling functions. 1001 // Virtual frame stub and IC calling functions.
1014 1002
1015 Result VirtualFrame::RawCallCodeObject(Handle<Code> code,
1016 RelocInfo::Mode rmode) {
1017 ASSERT(cgen()->HasValidEntryRegisters());
1018 __ Call(code, rmode);
1019 Result result = cgen()->allocator()->Allocate(rax);
1020 ASSERT(result.is_valid());
1021 return result;
1022 }
1023
1024
1025 Result VirtualFrame::CallRuntime(Runtime::Function* f, int arg_count) { 1003 Result VirtualFrame::CallRuntime(Runtime::Function* f, int arg_count) {
1026 PrepareForCall(arg_count, arg_count); 1004 PrepareForCall(arg_count, arg_count);
1027 ASSERT(cgen()->HasValidEntryRegisters()); 1005 ASSERT(cgen()->HasValidEntryRegisters());
1028 __ CallRuntime(f, arg_count); 1006 __ CallRuntime(f, arg_count);
1029 Result result = cgen()->allocator()->Allocate(rax); 1007 Result result = cgen()->allocator()->Allocate(rax);
1030 ASSERT(result.is_valid()); 1008 ASSERT(result.is_valid());
1031 return result; 1009 return result;
1032 } 1010 }
1033 1011
1034 1012
(...skipping 11 matching lines...) Expand all
1046 void VirtualFrame::DebugBreak() { 1024 void VirtualFrame::DebugBreak() {
1047 PrepareForCall(0, 0); 1025 PrepareForCall(0, 0);
1048 ASSERT(cgen()->HasValidEntryRegisters()); 1026 ASSERT(cgen()->HasValidEntryRegisters());
1049 __ DebugBreak(); 1027 __ DebugBreak();
1050 Result result = cgen()->allocator()->Allocate(rax); 1028 Result result = cgen()->allocator()->Allocate(rax);
1051 ASSERT(result.is_valid()); 1029 ASSERT(result.is_valid());
1052 } 1030 }
1053 #endif 1031 #endif
1054 1032
1055 1033
1034 Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id,
1035 InvokeFlag flag,
1036 int arg_count) {
1037 PrepareForCall(arg_count, arg_count);
1038 ASSERT(cgen()->HasValidEntryRegisters());
1039 __ InvokeBuiltin(id, flag);
1040 Result result = cgen()->allocator()->Allocate(rax);
1041 ASSERT(result.is_valid());
1042 return result;
1043 }
1044
1045
1046 Result VirtualFrame::RawCallCodeObject(Handle<Code> code,
1047 RelocInfo::Mode rmode) {
1048 ASSERT(cgen()->HasValidEntryRegisters());
1049 __ Call(code, rmode);
1050 Result result = cgen()->allocator()->Allocate(rax);
1051 ASSERT(result.is_valid());
1052 return result;
1053 }
1054
1055
1056 // This function assumes that the only results that could be in a_reg or b_reg 1056 // This function assumes that the only results that could be in a_reg or b_reg
1057 // are a and b. Other results can be live, but must not be in a_reg or b_reg. 1057 // are a and b. Other results can be live, but must not be in a_reg or b_reg.
1058 void VirtualFrame::MoveResultsToRegisters(Result* a, 1058 void VirtualFrame::MoveResultsToRegisters(Result* a,
1059 Result* b, 1059 Result* b,
1060 Register a_reg, 1060 Register a_reg,
1061 Register b_reg) { 1061 Register b_reg) {
1062 ASSERT(!a_reg.is(b_reg)); 1062 ASSERT(!a_reg.is(b_reg));
1063 // Assert that cgen()->allocator()->count(a_reg) is accounted for by a and b. 1063 // Assert that cgen()->allocator()->count(a_reg) is accounted for by a and b.
1064 ASSERT(cgen()->allocator()->count(a_reg) <= 2); 1064 ASSERT(cgen()->allocator()->count(a_reg) <= 2);
1065 ASSERT(cgen()->allocator()->count(a_reg) != 2 || a->reg().is(a_reg)); 1065 ASSERT(cgen()->allocator()->count(a_reg) != 2 || a->reg().is(a_reg));
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1100 Result name = Pop(); 1100 Result name = Pop();
1101 Result receiver = Pop(); 1101 Result receiver = Pop();
1102 PrepareForCall(0, 0); 1102 PrepareForCall(0, 0);
1103 MoveResultsToRegisters(&name, &receiver, rcx, rax); 1103 MoveResultsToRegisters(&name, &receiver, rcx, rax);
1104 1104
1105 return RawCallCodeObject(ic, mode); 1105 return RawCallCodeObject(ic, mode);
1106 } 1106 }
1107 1107
1108 1108
1109 Result VirtualFrame::CallKeyedLoadIC(RelocInfo::Mode mode) { 1109 Result VirtualFrame::CallKeyedLoadIC(RelocInfo::Mode mode) {
1110 // Key and receiver are on top of the frame. The IC expects them on 1110 // Key and receiver are on top of the frame. Put them in rax and rdx.
1111 // the stack. It does not drop them. 1111 Result key = Pop();
1112 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1113 Result name = Pop();
1114 Result receiver = Pop(); 1112 Result receiver = Pop();
1115 PrepareForCall(0, 0); 1113 PrepareForCall(0, 0);
1116 MoveResultsToRegisters(&name, &receiver, rax, rdx); 1114 MoveResultsToRegisters(&key, &receiver, rax, rdx);
1115
1116 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1117 return RawCallCodeObject(ic, mode); 1117 return RawCallCodeObject(ic, mode);
1118 } 1118 }
1119 1119
1120 1120
1121 Result VirtualFrame::CallCommonStoreIC(Handle<Code> ic,
1122 Result* value,
1123 Result* key,
1124 Result* receiver) {
1125 // The IC expects value in rax, key in rcx, and receiver in rdx.
1126 PrepareForCall(0, 0);
1127 // If one of the three registers is free, or a value is already
1128 // in the correct register, move the remaining two values using
1129 // MoveResultsToRegisters().
1130 if (!cgen()->allocator()->is_used(rax) ||
1131 (value->is_register() && value->reg().is(rax))) {
1132 if (!cgen()->allocator()->is_used(rax)) {
1133 value->ToRegister(rax);
1134 }
1135 MoveResultsToRegisters(key, receiver, rcx, rdx);
1136 value->Unuse();
1137 } else if (!cgen()->allocator()->is_used(rcx) ||
1138 (key->is_register() && key->reg().is(rcx))) {
1139 if (!cgen()->allocator()->is_used(rcx)) {
1140 key->ToRegister(rcx);
1141 }
1142 MoveResultsToRegisters(value, receiver, rax, rdx);
1143 key->Unuse();
1144 } else if (!cgen()->allocator()->is_used(rdx) ||
1145 (receiver->is_register() && receiver->reg().is(rdx))) {
1146 if (!cgen()->allocator()->is_used(rdx)) {
1147 receiver->ToRegister(rdx);
1148 }
1149 MoveResultsToRegisters(key, value, rcx, rax);
1150 receiver->Unuse();
1151 } else {
1152 // Otherwise, no register is free, and no value is in the correct place.
1153 // We have one of the two circular permutations of eax, ecx, edx.
1154 ASSERT(value->is_register());
1155 if (value->reg().is(rcx)) {
1156 __ xchg(rax, rdx);
1157 __ xchg(rax, rcx);
1158 } else {
1159 __ xchg(rax, rcx);
1160 __ xchg(rax, rdx);
1161 }
1162 value->Unuse();
1163 key->Unuse();
1164 receiver->Unuse();
1165 }
1166
1167 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
1168 }
1169
1170
1171 Result VirtualFrame::CallStoreIC(Handle<String> name, bool is_contextual) { 1121 Result VirtualFrame::CallStoreIC(Handle<String> name, bool is_contextual) {
1172 // Value and (if not contextual) receiver are on top of the frame. 1122 // Value and (if not contextual) receiver are on top of the frame.
1173 // The IC expects name in rcx, value in rax, and receiver in rdx. 1123 // The IC expects name in rcx, value in rax, and receiver in rdx.
1174 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 1124 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
1175 Result value = Pop(); 1125 Result value = Pop();
1176 if (is_contextual) { 1126 if (is_contextual) {
1177 PrepareForCall(0, 0); 1127 PrepareForCall(0, 0);
1178 value.ToRegister(rax); 1128 value.ToRegister(rax);
1179 __ movq(rdx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); 1129 __ movq(rdx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
1180 value.Unuse(); 1130 value.Unuse();
1181 } else { 1131 } else {
1182 Result receiver = Pop(); 1132 Result receiver = Pop();
1183 PrepareForCall(0, 0); 1133 PrepareForCall(0, 0);
1184 MoveResultsToRegisters(&value, &receiver, rax, rdx); 1134 MoveResultsToRegisters(&value, &receiver, rax, rdx);
1185 } 1135 }
1186 __ Move(rcx, name); 1136 __ Move(rcx, name);
1187 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET); 1137 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
1188 } 1138 }
1189 1139
1190 1140
1141 Result VirtualFrame::CallKeyedStoreIC() {
1142 // Value, key, and receiver are on the top of the frame. The IC
1143 // expects value in rax, key in rcx, and receiver in rdx.
1144 Result value = Pop();
1145 Result key = Pop();
1146 Result receiver = Pop();
1147 PrepareForCall(0, 0);
1148 if (!cgen()->allocator()->is_used(rax) ||
1149 (value.is_register() && value.reg().is(rax))) {
1150 if (!cgen()->allocator()->is_used(rax)) {
1151 value.ToRegister(rax);
1152 }
1153 MoveResultsToRegisters(&key, &receiver, rcx, rdx);
1154 value.Unuse();
1155 } else if (!cgen()->allocator()->is_used(rcx) ||
1156 (key.is_register() && key.reg().is(rcx))) {
1157 if (!cgen()->allocator()->is_used(rcx)) {
1158 key.ToRegister(rcx);
1159 }
1160 MoveResultsToRegisters(&value, &receiver, rax, rdx);
1161 key.Unuse();
1162 } else if (!cgen()->allocator()->is_used(rdx) ||
1163 (receiver.is_register() && receiver.reg().is(rdx))) {
1164 if (!cgen()->allocator()->is_used(rdx)) {
1165 receiver.ToRegister(rdx);
1166 }
1167 MoveResultsToRegisters(&key, &value, rcx, rax);
1168 receiver.Unuse();
1169 } else {
1170 // All three registers are used, and no value is in the correct place.
1171 // We have one of the two circular permutations of rax, rcx, rdx.
1172 ASSERT(value.is_register());
1173 if (value.reg().is(rcx)) {
1174 __ xchg(rax, rdx);
1175 __ xchg(rax, rcx);
1176 } else {
1177 __ xchg(rax, rcx);
1178 __ xchg(rax, rdx);
1179 }
1180 value.Unuse();
1181 key.Unuse();
1182 receiver.Unuse();
1183 }
1184
1185 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
1186 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
1187 }
1188
1189
1191 Result VirtualFrame::CallCallIC(RelocInfo::Mode mode, 1190 Result VirtualFrame::CallCallIC(RelocInfo::Mode mode,
1192 int arg_count, 1191 int arg_count,
1193 int loop_nesting) { 1192 int loop_nesting) {
1194 // Function name, arguments, and receiver are found on top of the frame 1193 // Function name, arguments, and receiver are found on top of the frame
1195 // and dropped by the call. The IC expects the name in rcx and the rest 1194 // and dropped by the call. The IC expects the name in rcx and the rest
1196 // on the stack, and drops them all. 1195 // on the stack, and drops them all.
1197 InLoopFlag in_loop = loop_nesting > 0 ? IN_LOOP : NOT_IN_LOOP; 1196 InLoopFlag in_loop = loop_nesting > 0 ? IN_LOOP : NOT_IN_LOOP;
1198 Handle<Code> ic = cgen()->ComputeCallInitialize(arg_count, in_loop); 1197 Handle<Code> ic = cgen()->ComputeCallInitialize(arg_count, in_loop);
1199 Result name = Pop(); 1198 Result name = Pop();
1200 // Spill args, receiver, and function. The call will drop args and 1199 // Spill args, receiver, and function. The call will drop args and
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1256 Adjust(kHandlerSize - 1); 1255 Adjust(kHandlerSize - 1);
1257 __ PushTryHandler(IN_JAVASCRIPT, type); 1256 __ PushTryHandler(IN_JAVASCRIPT, type);
1258 } 1257 }
1259 1258
1260 1259
1261 #undef __ 1260 #undef __
1262 1261
1263 } } // namespace v8::internal 1262 } } // namespace v8::internal
1264 1263
1265 #endif // V8_TARGET_ARCH_X64 1264 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/x64/codegen-x64.cc ('K') | « src/x64/virtual-frame-x64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698