OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <assert.h> // For assert | 5 #include <assert.h> // For assert |
6 #include <limits.h> // For LONG_MIN, LONG_MAX. | 6 #include <limits.h> // For LONG_MIN, LONG_MAX. |
7 | 7 |
8 #if V8_TARGET_ARCH_PPC | 8 #if V8_TARGET_ARCH_PPC |
9 | 9 |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 1068 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1079 b(done); | 1079 b(done); |
1080 } | 1080 } |
1081 } else { | 1081 } else { |
1082 Jump(adaptor, RelocInfo::CODE_TARGET); | 1082 Jump(adaptor, RelocInfo::CODE_TARGET); |
1083 } | 1083 } |
1084 bind(®ular_invoke); | 1084 bind(®ular_invoke); |
1085 } | 1085 } |
1086 } | 1086 } |
1087 | 1087 |
1088 | 1088 |
1089 void MacroAssembler::InvokeCode(Register code, Register new_target, | 1089 void MacroAssembler::FloodFunctionIfStepping(Register fun, Register new_target, |
1090 const ParameterCount& expected, | 1090 const ParameterCount& expected, |
1091 const ParameterCount& actual, InvokeFlag flag, | 1091 const ParameterCount& actual) { |
1092 const CallWrapper& call_wrapper) { | 1092 Label skip_flooding; |
| 1093 ExternalReference debug_step_action = |
| 1094 ExternalReference::debug_last_step_action_address(isolate()); |
| 1095 mov(r7, Operand(debug_step_action)); |
| 1096 lbz(r7, MemOperand(r7)); |
| 1097 cmpi(r7, Operand(StepIn)); |
| 1098 bne(&skip_flooding); |
| 1099 { |
| 1100 FrameScope frame(this, |
| 1101 has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); |
| 1102 if (expected.is_reg()) { |
| 1103 SmiTag(expected.reg()); |
| 1104 Push(expected.reg()); |
| 1105 } |
| 1106 if (actual.is_reg()) { |
| 1107 SmiTag(actual.reg()); |
| 1108 Push(actual.reg()); |
| 1109 } |
| 1110 if (new_target.is_valid()) { |
| 1111 Push(new_target); |
| 1112 } |
| 1113 Push(fun, fun); |
| 1114 CallRuntime(Runtime::kDebugPrepareStepInIfStepping, 1); |
| 1115 Pop(fun); |
| 1116 if (new_target.is_valid()) { |
| 1117 Pop(new_target); |
| 1118 } |
| 1119 if (actual.is_reg()) { |
| 1120 Pop(actual.reg()); |
| 1121 SmiUntag(actual.reg()); |
| 1122 } |
| 1123 if (expected.is_reg()) { |
| 1124 Pop(expected.reg()); |
| 1125 SmiUntag(expected.reg()); |
| 1126 } |
| 1127 } |
| 1128 bind(&skip_flooding); |
| 1129 } |
| 1130 |
| 1131 |
| 1132 void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, |
| 1133 const ParameterCount& expected, |
| 1134 const ParameterCount& actual, |
| 1135 InvokeFlag flag, |
| 1136 const CallWrapper& call_wrapper) { |
1093 // You can't call a function without a valid frame. | 1137 // You can't call a function without a valid frame. |
1094 DCHECK(flag == JUMP_FUNCTION || has_frame()); | 1138 DCHECK(flag == JUMP_FUNCTION || has_frame()); |
| 1139 DCHECK(function.is(r4)); |
| 1140 DCHECK_IMPLIES(new_target.is_valid(), new_target.is(r6)); |
1095 | 1141 |
1096 // Ensure new target is passed in the correct register. Otherwise clear the | 1142 if (call_wrapper.NeedsDebugStepCheck()) { |
1097 // appropriate register in case new target is not given. | 1143 FloodFunctionIfStepping(function, new_target, expected, actual); |
1098 DCHECK_IMPLIES(new_target.is_valid(), new_target.is(r6)); | 1144 } |
| 1145 |
| 1146 // Clear the new.target register if not given. |
1099 if (!new_target.is_valid()) { | 1147 if (!new_target.is_valid()) { |
1100 LoadRoot(r6, Heap::kUndefinedValueRootIndex); | 1148 LoadRoot(r6, Heap::kUndefinedValueRootIndex); |
1101 } | 1149 } |
1102 | 1150 |
1103 Label done; | 1151 Label done; |
1104 bool definitely_mismatches = false; | 1152 bool definitely_mismatches = false; |
1105 InvokePrologue(expected, actual, &done, &definitely_mismatches, flag, | 1153 InvokePrologue(expected, actual, &done, &definitely_mismatches, flag, |
1106 call_wrapper); | 1154 call_wrapper); |
1107 if (!definitely_mismatches) { | 1155 if (!definitely_mismatches) { |
| 1156 // We call indirectly through the code field in the function to |
| 1157 // allow recompilation to take effect without changing any of the |
| 1158 // call sites. |
| 1159 Register code = ip; |
| 1160 LoadP(code, FieldMemOperand(function, JSFunction::kCodeEntryOffset)); |
1108 if (flag == CALL_FUNCTION) { | 1161 if (flag == CALL_FUNCTION) { |
1109 call_wrapper.BeforeCall(CallSize(code)); | 1162 call_wrapper.BeforeCall(CallSize(code)); |
1110 CallJSEntry(code); | 1163 CallJSEntry(code); |
1111 call_wrapper.AfterCall(); | 1164 call_wrapper.AfterCall(); |
1112 } else { | 1165 } else { |
1113 DCHECK(flag == JUMP_FUNCTION); | 1166 DCHECK(flag == JUMP_FUNCTION); |
1114 JumpToJSEntry(code); | 1167 JumpToJSEntry(code); |
1115 } | 1168 } |
1116 | 1169 |
1117 // Continue here if InvokePrologue does handle the invocation due to | 1170 // Continue here if InvokePrologue does handle the invocation due to |
1118 // mismatched parameter counts. | 1171 // mismatched parameter counts. |
1119 bind(&done); | 1172 bind(&done); |
1120 } | 1173 } |
1121 } | 1174 } |
1122 | 1175 |
1123 | 1176 |
1124 void MacroAssembler::InvokeFunction(Register fun, Register new_target, | 1177 void MacroAssembler::InvokeFunction(Register fun, Register new_target, |
1125 const ParameterCount& actual, | 1178 const ParameterCount& actual, |
1126 InvokeFlag flag, | 1179 InvokeFlag flag, |
1127 const CallWrapper& call_wrapper) { | 1180 const CallWrapper& call_wrapper) { |
1128 // You can't call a function without a valid frame. | 1181 // You can't call a function without a valid frame. |
1129 DCHECK(flag == JUMP_FUNCTION || has_frame()); | 1182 DCHECK(flag == JUMP_FUNCTION || has_frame()); |
1130 | 1183 |
1131 // Contract with called JS functions requires that function is passed in r4. | 1184 // Contract with called JS functions requires that function is passed in r4. |
1132 DCHECK(fun.is(r4)); | 1185 DCHECK(fun.is(r4)); |
1133 | 1186 |
1134 Register expected_reg = r5; | 1187 Register expected_reg = r5; |
1135 Register code_reg = ip; | 1188 Register temp_reg = r7; |
1136 | 1189 |
1137 LoadP(code_reg, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); | 1190 LoadP(temp_reg, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); |
1138 LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset)); | 1191 LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset)); |
1139 LoadWordArith(expected_reg, | 1192 LoadWordArith(expected_reg, |
1140 FieldMemOperand( | 1193 FieldMemOperand( |
1141 code_reg, SharedFunctionInfo::kFormalParameterCountOffset)); | 1194 temp_reg, SharedFunctionInfo::kFormalParameterCountOffset)); |
1142 #if !defined(V8_TARGET_ARCH_PPC64) | 1195 #if !defined(V8_TARGET_ARCH_PPC64) |
1143 SmiUntag(expected_reg); | 1196 SmiUntag(expected_reg); |
1144 #endif | 1197 #endif |
1145 LoadP(code_reg, FieldMemOperand(r4, JSFunction::kCodeEntryOffset)); | |
1146 | 1198 |
1147 ParameterCount expected(expected_reg); | 1199 ParameterCount expected(expected_reg); |
1148 InvokeCode(code_reg, new_target, expected, actual, flag, call_wrapper); | 1200 InvokeFunctionCode(fun, new_target, expected, actual, flag, call_wrapper); |
1149 } | 1201 } |
1150 | 1202 |
1151 | 1203 |
1152 void MacroAssembler::InvokeFunction(Register function, | 1204 void MacroAssembler::InvokeFunction(Register function, |
1153 const ParameterCount& expected, | 1205 const ParameterCount& expected, |
1154 const ParameterCount& actual, | 1206 const ParameterCount& actual, |
1155 InvokeFlag flag, | 1207 InvokeFlag flag, |
1156 const CallWrapper& call_wrapper) { | 1208 const CallWrapper& call_wrapper) { |
1157 // You can't call a function without a valid frame. | 1209 // You can't call a function without a valid frame. |
1158 DCHECK(flag == JUMP_FUNCTION || has_frame()); | 1210 DCHECK(flag == JUMP_FUNCTION || has_frame()); |
1159 | 1211 |
1160 // Contract with called JS functions requires that function is passed in r4. | 1212 // Contract with called JS functions requires that function is passed in r4. |
1161 DCHECK(function.is(r4)); | 1213 DCHECK(function.is(r4)); |
1162 | 1214 |
1163 // Get the function and setup the context. | 1215 // Get the function and setup the context. |
1164 LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset)); | 1216 LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset)); |
1165 | 1217 |
1166 // We call indirectly through the code field in the function to | 1218 InvokeFunctionCode(r4, no_reg, expected, actual, flag, call_wrapper); |
1167 // allow recompilation to take effect without changing any of the | |
1168 // call sites. | |
1169 LoadP(ip, FieldMemOperand(r4, JSFunction::kCodeEntryOffset)); | |
1170 InvokeCode(ip, no_reg, expected, actual, flag, call_wrapper); | |
1171 } | 1219 } |
1172 | 1220 |
1173 | 1221 |
1174 void MacroAssembler::InvokeFunction(Handle<JSFunction> function, | 1222 void MacroAssembler::InvokeFunction(Handle<JSFunction> function, |
1175 const ParameterCount& expected, | 1223 const ParameterCount& expected, |
1176 const ParameterCount& actual, | 1224 const ParameterCount& actual, |
1177 InvokeFlag flag, | 1225 InvokeFlag flag, |
1178 const CallWrapper& call_wrapper) { | 1226 const CallWrapper& call_wrapper) { |
1179 Move(r4, function); | 1227 Move(r4, function); |
1180 InvokeFunction(r4, expected, actual, flag, call_wrapper); | 1228 InvokeFunction(r4, expected, actual, flag, call_wrapper); |
(...skipping 3222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4403 } | 4451 } |
4404 if (mag.shift > 0) srawi(result, result, mag.shift); | 4452 if (mag.shift > 0) srawi(result, result, mag.shift); |
4405 ExtractBit(r0, dividend, 31); | 4453 ExtractBit(r0, dividend, 31); |
4406 add(result, result, r0); | 4454 add(result, result, r0); |
4407 } | 4455 } |
4408 | 4456 |
4409 } // namespace internal | 4457 } // namespace internal |
4410 } // namespace v8 | 4458 } // namespace v8 |
4411 | 4459 |
4412 #endif // V8_TARGET_ARCH_PPC | 4460 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |