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

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

Issue 2084017: Version 2.2.11... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 10 years, 7 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/x64/virtual-frame-x64.h ('k') | test/cctest/test-cpu-profiler.cc » ('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 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
11 // with the distribution. 11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its 12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived 13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission. 14 // from this software without specific prior written permission.
15 // 15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
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 #if defined(V8_TARGET_ARCH_X64)
31
30 #include "codegen-inl.h" 32 #include "codegen-inl.h"
31 #include "register-allocator-inl.h" 33 #include "register-allocator-inl.h"
32 #include "scopes.h" 34 #include "scopes.h"
33 #include "virtual-frame-inl.h" 35 #include "virtual-frame-inl.h"
34 36
35 namespace v8 { 37 namespace v8 {
36 namespace internal { 38 namespace internal {
37 39
38 #define __ ACCESS_MASM(masm()) 40 #define __ ACCESS_MASM(masm())
39 41
(...skipping 982 matching lines...) Expand 10 before | Expand all | Expand 10 after
1022 void VirtualFrame::DebugBreak() { 1024 void VirtualFrame::DebugBreak() {
1023 PrepareForCall(0, 0); 1025 PrepareForCall(0, 0);
1024 ASSERT(cgen()->HasValidEntryRegisters()); 1026 ASSERT(cgen()->HasValidEntryRegisters());
1025 __ DebugBreak(); 1027 __ DebugBreak();
1026 Result result = cgen()->allocator()->Allocate(rax); 1028 Result result = cgen()->allocator()->Allocate(rax);
1027 ASSERT(result.is_valid()); 1029 ASSERT(result.is_valid());
1028 } 1030 }
1029 #endif 1031 #endif
1030 1032
1031 1033
1034 // This function assumes that the only results that could be in a_reg or b_reg
1035 // are a and b. Other results can be live, but must not be in a_reg or b_reg.
1036 void VirtualFrame::MoveResultsToRegisters(Result* a,
1037 Result* b,
1038 Register a_reg,
1039 Register b_reg) {
1040 ASSERT(!a_reg.is(b_reg));
1041 // Assert that cgen()->allocator()->count(a_reg) is accounted for by a and b.
1042 ASSERT(cgen()->allocator()->count(a_reg) <= 2);
1043 ASSERT(cgen()->allocator()->count(a_reg) != 2 || a->reg().is(a_reg));
1044 ASSERT(cgen()->allocator()->count(a_reg) != 2 || b->reg().is(a_reg));
1045 ASSERT(cgen()->allocator()->count(a_reg) != 1 ||
1046 (a->is_register() && a->reg().is(a_reg)) ||
1047 (b->is_register() && b->reg().is(a_reg)));
1048 // Assert that cgen()->allocator()->count(b_reg) is accounted for by a and b.
1049 ASSERT(cgen()->allocator()->count(b_reg) <= 2);
1050 ASSERT(cgen()->allocator()->count(b_reg) != 2 || a->reg().is(b_reg));
1051 ASSERT(cgen()->allocator()->count(b_reg) != 2 || b->reg().is(b_reg));
1052 ASSERT(cgen()->allocator()->count(b_reg) != 1 ||
1053 (a->is_register() && a->reg().is(b_reg)) ||
1054 (b->is_register() && b->reg().is(b_reg)));
1055
1056 if (a->is_register() && a->reg().is(a_reg)) {
1057 b->ToRegister(b_reg);
1058 } else if (!cgen()->allocator()->is_used(a_reg)) {
1059 a->ToRegister(a_reg);
1060 b->ToRegister(b_reg);
1061 } else if (cgen()->allocator()->is_used(b_reg)) {
1062 // a must be in b_reg, b in a_reg.
1063 __ xchg(a_reg, b_reg);
1064 // Results a and b will be invalidated, so it is ok if they are switched.
1065 } else {
1066 b->ToRegister(b_reg);
1067 a->ToRegister(a_reg);
1068 }
1069 a->Unuse();
1070 b->Unuse();
1071 }
1072
1073
1032 Result VirtualFrame::CallLoadIC(RelocInfo::Mode mode) { 1074 Result VirtualFrame::CallLoadIC(RelocInfo::Mode mode) {
1033 // Name and receiver are on the top of the frame. The IC expects 1075 // Name and receiver are on the top of the frame. The IC expects
1034 // name in rcx and receiver on the stack. It does not drop the 1076 // name in rcx and receiver on the stack. It does not drop the
1035 // receiver. 1077 // receiver.
1036 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1078 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1037 Result name = Pop(); 1079 Result name = Pop();
1038 PrepareForCall(1, 0); // One stack arg, not callee-dropped. 1080 PrepareForCall(1, 0); // One stack arg, not callee-dropped.
1039 name.ToRegister(rcx); 1081 name.ToRegister(rcx);
1040 name.Unuse(); 1082 name.Unuse();
1041 return RawCallCodeObject(ic, mode); 1083 return RawCallCodeObject(ic, mode);
1042 } 1084 }
1043 1085
1044 1086
1045 Result VirtualFrame::CallKeyedLoadIC(RelocInfo::Mode mode) { 1087 Result VirtualFrame::CallKeyedLoadIC(RelocInfo::Mode mode) {
1046 // Key and receiver are on top of the frame. The IC expects them on 1088 // Key and receiver are on top of the frame. The IC expects them on
1047 // the stack. It does not drop them. 1089 // the stack. It does not drop them.
1048 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 1090 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1049 PrepareForCall(2, 0); // Two stack args, neither callee-dropped. 1091 PrepareForCall(2, 0); // Two stack args, neither callee-dropped.
1050 return RawCallCodeObject(ic, mode); 1092 return RawCallCodeObject(ic, mode);
1051 } 1093 }
1052 1094
1053 1095
1054 Result VirtualFrame::CallKeyedStoreIC() { 1096 Result VirtualFrame::CallCommonStoreIC(Handle<Code> ic,
1055 // Value, key, and receiver are on the top of the frame. The IC 1097 Result* value,
1056 // expects value in rax and key and receiver on the stack. It does 1098 Result* key,
1057 // not drop the key and receiver. 1099 Result* receiver) {
1058 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 1100 // The IC expects value in rax, key in rcx, and receiver in rdx.
1059 Result value = Pop(); 1101 PrepareForCall(0, 0);
1060 PrepareForCall(2, 0); // Two stack args, neither callee-dropped. 1102 // If one of the three registers is free, or a value is already
1061 value.ToRegister(rax); 1103 // in the correct register, move the remaining two values using
1062 value.Unuse(); 1104 // MoveResultsToRegisters().
1105 if (!cgen()->allocator()->is_used(rax) ||
1106 (value->is_register() && value->reg().is(rax))) {
1107 if (!cgen()->allocator()->is_used(rax)) {
1108 value->ToRegister(rax);
1109 }
1110 MoveResultsToRegisters(key, receiver, rcx, rdx);
1111 value->Unuse();
1112 } else if (!cgen()->allocator()->is_used(rcx) ||
1113 (key->is_register() && key->reg().is(rcx))) {
1114 if (!cgen()->allocator()->is_used(rcx)) {
1115 key->ToRegister(rcx);
1116 }
1117 MoveResultsToRegisters(value, receiver, rax, rdx);
1118 key->Unuse();
1119 } else if (!cgen()->allocator()->is_used(rdx) ||
1120 (receiver->is_register() && receiver->reg().is(rdx))) {
1121 if (!cgen()->allocator()->is_used(rdx)) {
1122 receiver->ToRegister(rdx);
1123 }
1124 MoveResultsToRegisters(key, value, rcx, rax);
1125 receiver->Unuse();
1126 } else {
1127 // Otherwise, no register is free, and no value is in the correct place.
1128 // We have one of the two circular permutations of eax, ecx, edx.
1129 ASSERT(value->is_register());
1130 if (value->reg().is(rcx)) {
1131 __ xchg(rax, rdx);
1132 __ xchg(rax, rcx);
1133 } else {
1134 __ xchg(rax, rcx);
1135 __ xchg(rax, rdx);
1136 }
1137 value->Unuse();
1138 key->Unuse();
1139 receiver->Unuse();
1140 }
1141
1063 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET); 1142 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
1064 } 1143 }
1065 1144
1066 1145
1067 Result VirtualFrame::CallCallIC(RelocInfo::Mode mode, 1146 Result VirtualFrame::CallCallIC(RelocInfo::Mode mode,
1068 int arg_count, 1147 int arg_count,
1069 int loop_nesting) { 1148 int loop_nesting) {
1070 // Function name, arguments, and receiver are found on top of the frame 1149 // Function name, arguments, and receiver are found on top of the frame
1071 // and dropped by the call. The IC expects the name in rcx and the rest 1150 // and dropped by the call. The IC expects the name in rcx and the rest
1072 // on the stack, and drops them all. 1151 // on the stack, and drops them all.
(...skipping 26 matching lines...) Expand all
1099 Result num_args = cgen()->allocator()->Allocate(rax); 1178 Result num_args = cgen()->allocator()->Allocate(rax);
1100 ASSERT(num_args.is_valid()); 1179 ASSERT(num_args.is_valid());
1101 __ movq(num_args.reg(), Immediate(arg_count)); 1180 __ movq(num_args.reg(), Immediate(arg_count));
1102 1181
1103 function.Unuse(); 1182 function.Unuse();
1104 num_args.Unuse(); 1183 num_args.Unuse();
1105 return RawCallCodeObject(ic, RelocInfo::CONSTRUCT_CALL); 1184 return RawCallCodeObject(ic, RelocInfo::CONSTRUCT_CALL);
1106 } 1185 }
1107 1186
1108 1187
1109 Result VirtualFrame::CallStoreIC() {
1110 // Name, value, and receiver are on top of the frame. The IC
1111 // expects name in rcx, value in rax, and receiver in edx.
1112 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
1113 Result name = Pop();
1114 Result value = Pop();
1115 Result receiver = Pop();
1116 PrepareForCall(0, 0);
1117
1118 // Optimized for case in which name is a constant value.
1119 if (name.is_register() && (name.reg().is(rdx) || name.reg().is(rax))) {
1120 if (!is_used(rcx)) {
1121 name.ToRegister(rcx);
1122 } else if (!is_used(rbx)) {
1123 name.ToRegister(rbx);
1124 } else {
1125 ASSERT(!is_used(rdi)); // Only three results are live, so rdi is free.
1126 name.ToRegister(rdi);
1127 }
1128 }
1129 // Now name is not in edx or eax, so we can fix them, then move name to ecx.
1130 if (value.is_register() && value.reg().is(rdx)) {
1131 if (receiver.is_register() && receiver.reg().is(rax)) {
1132 // Wrong registers.
1133 __ xchg(rax, rdx);
1134 } else {
1135 // Register rax is free for value, which frees rcx for receiver.
1136 value.ToRegister(rax);
1137 receiver.ToRegister(rdx);
1138 }
1139 } else {
1140 // Register rcx is free for receiver, which guarantees rax is free for
1141 // value.
1142 receiver.ToRegister(rdx);
1143 value.ToRegister(rax);
1144 }
1145 // Receiver and value are in the right place, so rcx is free for name.
1146 name.ToRegister(rcx);
1147 name.Unuse();
1148 value.Unuse();
1149 receiver.Unuse();
1150 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
1151 }
1152
1153
1154 void VirtualFrame::PushTryHandler(HandlerType type) { 1188 void VirtualFrame::PushTryHandler(HandlerType type) {
1155 ASSERT(cgen()->HasValidEntryRegisters()); 1189 ASSERT(cgen()->HasValidEntryRegisters());
1156 // Grow the expression stack by handler size less one (the return 1190 // Grow the expression stack by handler size less one (the return
1157 // address is already pushed by a call instruction). 1191 // address is already pushed by a call instruction).
1158 Adjust(kHandlerSize - 1); 1192 Adjust(kHandlerSize - 1);
1159 __ PushTryHandler(IN_JAVASCRIPT, type); 1193 __ PushTryHandler(IN_JAVASCRIPT, type);
1160 } 1194 }
1161 1195
1162 1196
1163 #undef __ 1197 #undef __
1164 1198
1165 } } // namespace v8::internal 1199 } } // namespace v8::internal
1200
1201 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/virtual-frame-x64.h ('k') | test/cctest/test-cpu-profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698