| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 <limits.h> // For LONG_MIN, LONG_MAX. | 5 #include <limits.h> // For LONG_MIN, LONG_MAX. |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_ARM | 7 #if V8_TARGET_ARCH_ARM |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/base/division-by-constant.h" | 10 #include "src/base/division-by-constant.h" |
| (...skipping 1286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1297 } | 1297 } |
| 1298 } else { | 1298 } else { |
| 1299 Jump(adaptor, RelocInfo::CODE_TARGET); | 1299 Jump(adaptor, RelocInfo::CODE_TARGET); |
| 1300 } | 1300 } |
| 1301 bind(®ular_invoke); | 1301 bind(®ular_invoke); |
| 1302 } | 1302 } |
| 1303 } | 1303 } |
| 1304 | 1304 |
| 1305 | 1305 |
| 1306 void MacroAssembler::InvokeCode(Register code, | 1306 void MacroAssembler::InvokeCode(Register code, |
| 1307 Register new_target, |
| 1307 const ParameterCount& expected, | 1308 const ParameterCount& expected, |
| 1308 const ParameterCount& actual, | 1309 const ParameterCount& actual, |
| 1309 InvokeFlag flag, | 1310 InvokeFlag flag, |
| 1310 const CallWrapper& call_wrapper) { | 1311 const CallWrapper& call_wrapper) { |
| 1311 // You can't call a function without a valid frame. | 1312 // You can't call a function without a valid frame. |
| 1312 DCHECK(flag == JUMP_FUNCTION || has_frame()); | 1313 DCHECK(flag == JUMP_FUNCTION || has_frame()); |
| 1313 | 1314 |
| 1315 // Ensure new target is passed in the correct register. Otherwise clear the |
| 1316 // appropriate register in case new target is not given. |
| 1317 DCHECK_IMPLIES(new_target.is_valid(), new_target.is(r3)); |
| 1318 if (!new_target.is_valid()) { |
| 1319 LoadRoot(r3, Heap::kUndefinedValueRootIndex); |
| 1320 } |
| 1321 |
| 1314 Label done; | 1322 Label done; |
| 1315 bool definitely_mismatches = false; | 1323 bool definitely_mismatches = false; |
| 1316 InvokePrologue(expected, actual, &done, &definitely_mismatches, flag, | 1324 InvokePrologue(expected, actual, &done, &definitely_mismatches, flag, |
| 1317 call_wrapper); | 1325 call_wrapper); |
| 1318 if (!definitely_mismatches) { | 1326 if (!definitely_mismatches) { |
| 1319 if (flag == CALL_FUNCTION) { | 1327 if (flag == CALL_FUNCTION) { |
| 1320 call_wrapper.BeforeCall(CallSize(code)); | 1328 call_wrapper.BeforeCall(CallSize(code)); |
| 1321 Call(code); | 1329 Call(code); |
| 1322 call_wrapper.AfterCall(); | 1330 call_wrapper.AfterCall(); |
| 1323 } else { | 1331 } else { |
| 1324 DCHECK(flag == JUMP_FUNCTION); | 1332 DCHECK(flag == JUMP_FUNCTION); |
| 1325 Jump(code); | 1333 Jump(code); |
| 1326 } | 1334 } |
| 1327 | 1335 |
| 1328 // Continue here if InvokePrologue does handle the invocation due to | 1336 // Continue here if InvokePrologue does handle the invocation due to |
| 1329 // mismatched parameter counts. | 1337 // mismatched parameter counts. |
| 1330 bind(&done); | 1338 bind(&done); |
| 1331 } | 1339 } |
| 1332 } | 1340 } |
| 1333 | 1341 |
| 1334 | 1342 |
| 1335 void MacroAssembler::InvokeFunction(Register fun, | 1343 void MacroAssembler::InvokeFunction(Register fun, |
| 1344 Register new_target, |
| 1336 const ParameterCount& actual, | 1345 const ParameterCount& actual, |
| 1337 InvokeFlag flag, | 1346 InvokeFlag flag, |
| 1338 const CallWrapper& call_wrapper) { | 1347 const CallWrapper& call_wrapper) { |
| 1339 // You can't call a function without a valid frame. | 1348 // You can't call a function without a valid frame. |
| 1340 DCHECK(flag == JUMP_FUNCTION || has_frame()); | 1349 DCHECK(flag == JUMP_FUNCTION || has_frame()); |
| 1341 | 1350 |
| 1342 // Contract with called JS functions requires that function is passed in r1. | 1351 // Contract with called JS functions requires that function is passed in r1. |
| 1343 DCHECK(fun.is(r1)); | 1352 DCHECK(fun.is(r1)); |
| 1344 | 1353 |
| 1345 Register expected_reg = r2; | 1354 Register expected_reg = r2; |
| 1346 Register code_reg = r3; | 1355 Register code_reg = r4; |
| 1347 | 1356 |
| 1348 ldr(code_reg, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); | 1357 ldr(code_reg, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
| 1349 ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | 1358 ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
| 1350 ldr(expected_reg, | 1359 ldr(expected_reg, |
| 1351 FieldMemOperand(code_reg, | 1360 FieldMemOperand(code_reg, |
| 1352 SharedFunctionInfo::kFormalParameterCountOffset)); | 1361 SharedFunctionInfo::kFormalParameterCountOffset)); |
| 1353 SmiUntag(expected_reg); | 1362 SmiUntag(expected_reg); |
| 1354 ldr(code_reg, | 1363 ldr(code_reg, |
| 1355 FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); | 1364 FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); |
| 1356 | 1365 |
| 1357 ParameterCount expected(expected_reg); | 1366 ParameterCount expected(expected_reg); |
| 1358 InvokeCode(code_reg, expected, actual, flag, call_wrapper); | 1367 InvokeCode(code_reg, new_target, expected, actual, flag, call_wrapper); |
| 1359 } | 1368 } |
| 1360 | 1369 |
| 1361 | 1370 |
| 1362 void MacroAssembler::InvokeFunction(Register function, | 1371 void MacroAssembler::InvokeFunction(Register function, |
| 1363 const ParameterCount& expected, | 1372 const ParameterCount& expected, |
| 1364 const ParameterCount& actual, | 1373 const ParameterCount& actual, |
| 1365 InvokeFlag flag, | 1374 InvokeFlag flag, |
| 1366 const CallWrapper& call_wrapper) { | 1375 const CallWrapper& call_wrapper) { |
| 1367 // You can't call a function without a valid frame. | 1376 // You can't call a function without a valid frame. |
| 1368 DCHECK(flag == JUMP_FUNCTION || has_frame()); | 1377 DCHECK(flag == JUMP_FUNCTION || has_frame()); |
| 1369 | 1378 |
| 1370 // Contract with called JS functions requires that function is passed in r1. | 1379 // Contract with called JS functions requires that function is passed in r1. |
| 1371 DCHECK(function.is(r1)); | 1380 DCHECK(function.is(r1)); |
| 1372 | 1381 |
| 1373 // Get the function and setup the context. | 1382 // Get the function and setup the context. |
| 1374 ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | 1383 ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
| 1375 | 1384 |
| 1376 // We call indirectly through the code field in the function to | 1385 // We call indirectly through the code field in the function to |
| 1377 // allow recompilation to take effect without changing any of the | 1386 // allow recompilation to take effect without changing any of the |
| 1378 // call sites. | 1387 // call sites. |
| 1379 ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); | 1388 ldr(r4, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); |
| 1380 InvokeCode(r3, expected, actual, flag, call_wrapper); | 1389 InvokeCode(r4, no_reg, expected, actual, flag, call_wrapper); |
| 1381 } | 1390 } |
| 1382 | 1391 |
| 1383 | 1392 |
| 1384 void MacroAssembler::InvokeFunction(Handle<JSFunction> function, | 1393 void MacroAssembler::InvokeFunction(Handle<JSFunction> function, |
| 1385 const ParameterCount& expected, | 1394 const ParameterCount& expected, |
| 1386 const ParameterCount& actual, | 1395 const ParameterCount& actual, |
| 1387 InvokeFlag flag, | 1396 InvokeFlag flag, |
| 1388 const CallWrapper& call_wrapper) { | 1397 const CallWrapper& call_wrapper) { |
| 1389 Move(r1, function); | 1398 Move(r1, function); |
| 1390 InvokeFunction(r1, expected, actual, flag, call_wrapper); | 1399 InvokeFunction(r1, expected, actual, flag, call_wrapper); |
| (...skipping 2320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3711 } | 3720 } |
| 3712 } | 3721 } |
| 3713 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); | 3722 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); |
| 3714 add(result, result, Operand(dividend, LSR, 31)); | 3723 add(result, result, Operand(dividend, LSR, 31)); |
| 3715 } | 3724 } |
| 3716 | 3725 |
| 3717 } // namespace internal | 3726 } // namespace internal |
| 3718 } // namespace v8 | 3727 } // namespace v8 |
| 3719 | 3728 |
| 3720 #endif // V8_TARGET_ARCH_ARM | 3729 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |