Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 1379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1390 Call(stub->GetCode(), RelocInfo::CODE_TARGET, cond); | 1390 Call(stub->GetCode(), RelocInfo::CODE_TARGET, cond); |
| 1391 } | 1391 } |
| 1392 | 1392 |
| 1393 | 1393 |
| 1394 void MacroAssembler::TailCallStub(CodeStub* stub, Condition cond) { | 1394 void MacroAssembler::TailCallStub(CodeStub* stub, Condition cond) { |
| 1395 ASSERT(allow_stub_calls()); // stub calls are not allowed in some stubs | 1395 ASSERT(allow_stub_calls()); // stub calls are not allowed in some stubs |
| 1396 Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond); | 1396 Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond); |
| 1397 } | 1397 } |
| 1398 | 1398 |
| 1399 | 1399 |
| 1400 MaybeObject* MacroAssembler::TryTailCallStub(CodeStub* stub, Condition cond) { | |
| 1401 ASSERT(allow_stub_calls()); // stub calls are not allowed in some stubs | |
| 1402 Object* result; | |
| 1403 { MaybeObject* maybe_result = stub->TryGetCode(); | |
| 1404 if (!maybe_result->ToObject(&result)) return maybe_result; | |
| 1405 } | |
| 1406 Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond); | |
| 1407 return result; | |
| 1408 } | |
| 1409 | |
| 1410 | |
| 1411 void MacroAssembler::PrepareCallApiFunction(int arg_stack_space, | |
| 1412 int unwind_space, | |
| 1413 Register scratch) { | |
| 1414 mov(scratch, Operand(unwind_space)); | |
|
antonm
2011/01/11 14:11:33
it looks like a lot of code below is shared with M
Zaheer
2011/01/11 15:44:35
The behavior is different from EnterExitFrame
- v8
antonm
2011/01/11 19:27:40
Zaheer,
I am not sure it's something which cannot
Zaheer
2011/01/12 13:20:03
split the code as EnterApiExitFramePrologue/Epilog
| |
| 1415 add(ip, sp, Operand(scratch, LSL, kPointerSizeLog2)); | |
|
SeRya
2011/01/11 16:34:50
add(ip, sp, Operand(unwind_space * kPointerSize));
Zaheer
2011/01/12 13:20:03
Done
| |
| 1416 | |
| 1417 stm(db_w, sp, fp.bit() | ip.bit() | lr.bit()); | |
| 1418 mov(fp, Operand(sp)); | |
| 1419 | |
| 1420 mov(ip, Operand(CodeObject())); | |
| 1421 push(ip); | |
| 1422 push(ip); // Exit Frame pc patched before call | |
| 1423 | |
| 1424 // create space for the args | |
| 1425 sub(sp, sp, Operand(arg_stack_space * kPointerSize)); | |
| 1426 | |
| 1427 int frame_alignment = ActivationFrameAlignment(); | |
| 1428 int frame_alignment_mask = frame_alignment - 1; | |
| 1429 if (frame_alignment > kPointerSize) { | |
| 1430 mov(scratch, Operand(0)); | |
| 1431 tst(sp, Operand(frame_alignment_mask)); | |
| 1432 push(scratch, nz); | |
|
SeRya
2011/01/11 16:34:50
ASSERT(frame_alignment == 2 * kPointerSize);
Zaheer
2011/01/12 13:20:03
Done
| |
| 1433 } | |
| 1434 | |
| 1435 mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address))); | |
|
SeRya
2011/01/11 16:34:50
ia32 code allocates C arguments below c_entry_fp_a
Zaheer
2011/01/12 13:20:03
i do allocate the args on top of the exit frame si
| |
| 1436 str(fp, MemOperand(ip)); | |
| 1437 mov(ip, Operand(ExternalReference(Top::k_context_address))); | |
| 1438 str(cp, MemOperand(ip)); | |
| 1439 } | |
| 1440 | |
| 1441 | |
| 1442 MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn( | |
| 1443 ApiFunction* function) { | |
| 1444 ExternalReference next_address = | |
| 1445 ExternalReference::handle_scope_next_address(); | |
| 1446 ExternalReference limit_address = | |
| 1447 ExternalReference::handle_scope_limit_address(); | |
| 1448 ExternalReference level_address = | |
| 1449 ExternalReference::handle_scope_level_address(); | |
| 1450 | |
| 1451 // Allocate HandleScope in callee-save registers. | |
| 1452 mov(ip, Operand(next_address)); | |
|
SeRya
2011/01/11 16:34:50
x64 implementation use offsets to eliminate 2 of 3
Zaheer
2011/01/12 13:20:03
Done! but i could remove only the mov not ldr inst
| |
| 1453 ldr(r4, MemOperand(ip)); | |
| 1454 mov(ip, Operand(limit_address)); | |
| 1455 ldr(r5, MemOperand(ip)); | |
| 1456 mov(ip, Operand(level_address)); | |
| 1457 ldr(r6, MemOperand(ip)); | |
| 1458 add(r6, r6, Operand(1)); | |
| 1459 str(r6, MemOperand(ip)); | |
| 1460 | |
| 1461 // patch the exit frame pc and Call the api function! | |
|
antonm
2011/01/11 14:11:33
nit: [P]atch and [c]all.
antonm
2011/01/11 14:11:33
once again, can we factor out frame handling?
Zaheer
2011/01/11 15:44:35
Done
Zaheer
2011/01/11 15:44:35
same issues as mentioned before for refactoring
| |
| 1462 add(ip, pc, Operand(8)); | |
| 1463 str(ip, MemOperand(fp, -2 * kPointerSize)); | |
|
antonm
2011/01/11 14:11:33
do not we have a named constant for -2?
Zaheer
2011/01/11 15:44:35
check ExitFrame::FillState(..) it seems to be hard
| |
| 1464 Call(function->address(), RelocInfo::RUNTIME_ENTRY); | |
| 1465 | |
| 1466 Label empty_handle; | |
| 1467 Label prologue; | |
| 1468 Label promote_scheduled_exception; | |
| 1469 Label delete_allocated_handles; | |
| 1470 Label leave_exit_frame; | |
| 1471 | |
| 1472 // Check if the result handle holds 0. | |
| 1473 cmp(r0, Operand(0)); | |
| 1474 b(eq, &empty_handle); | |
| 1475 // It was non-zero. Dereference to get the result value. | |
| 1476 ldr(r0, MemOperand(r0)); | |
|
SeRya
2011/01/11 16:34:50
LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
Zaheer
2011/01/12 13:20:03
Done! Thanks for the pointer, it simplifies the co
| |
| 1477 bind(&prologue); | |
| 1478 // No more valid handles (the result handle was the last one). Restore | |
| 1479 // previous handle scope. | |
| 1480 mov(ip, Operand(next_address)); | |
| 1481 str(r4, MemOperand(ip)); | |
| 1482 mov(ip, Operand(level_address)); | |
| 1483 ldr(r6, MemOperand(ip)); | |
| 1484 sub(r6, r6, Operand(1)); | |
| 1485 str(r6, MemOperand(ip)); | |
| 1486 mov(ip, Operand(limit_address)); | |
| 1487 ldr(ip, MemOperand(ip)); | |
| 1488 cmp(r5, ip); | |
| 1489 b(ne, &delete_allocated_handles); | |
| 1490 | |
| 1491 // Check if the function scheduled an exception. | |
| 1492 bind(&leave_exit_frame); | |
| 1493 mov(ip, Operand(ExternalReference::the_hole_value_location())); | |
| 1494 ldr(r4, MemOperand(ip)); | |
|
antonm
2011/01/11 14:11:33
Shouldn't it be LoadRoot(r4, Heap::kTheHoleValueRo
Zaheer
2011/01/11 15:44:35
Done
| |
| 1495 mov(ip, Operand(ExternalReference(Top::k_pending_exception_address))); | |
| 1496 ldr(r5, MemOperand(ip)); | |
| 1497 cmp(r4, r5); | |
| 1498 b(ne, &promote_scheduled_exception); | |
| 1499 LeaveExitFrame(0); | |
|
antonm
2011/01/11 14:11:33
LeaveExitFrame apparently takes bool, not int
Zaheer
2011/01/11 15:44:35
done
| |
| 1500 | |
| 1501 bind(&promote_scheduled_exception); | |
| 1502 MaybeObject* result = TryTailCallExternalReference( | |
| 1503 ExternalReference(Runtime::kPromoteScheduledException), 0, 1); | |
| 1504 if (result->IsFailure()) { | |
| 1505 return result; | |
| 1506 } | |
| 1507 | |
| 1508 bind(&empty_handle); | |
| 1509 // It was zero; the result is undefined. | |
| 1510 LoadRoot(r0, Heap::kUndefinedValueRootIndex); | |
| 1511 b(&prologue); | |
| 1512 | |
| 1513 // HandleScope limit has changed. Delete allocated extensions. | |
| 1514 bind(&delete_allocated_handles); | |
| 1515 mov(ip, Operand(limit_address)); | |
| 1516 str(r5, MemOperand(ip)); | |
| 1517 mov(r4, r0); | |
| 1518 PrepareCallCFunction(0, r5); | |
| 1519 CallCFunction(ExternalReference::delete_handle_scope_extensions(), 0); | |
| 1520 mov(r0, r4); | |
| 1521 jmp(&leave_exit_frame); | |
| 1522 | |
| 1523 return result; | |
| 1524 } | |
| 1525 | |
| 1526 | |
| 1400 void MacroAssembler::IllegalOperation(int num_arguments) { | 1527 void MacroAssembler::IllegalOperation(int num_arguments) { |
| 1401 if (num_arguments > 0) { | 1528 if (num_arguments > 0) { |
| 1402 add(sp, sp, Operand(num_arguments * kPointerSize)); | 1529 add(sp, sp, Operand(num_arguments * kPointerSize)); |
| 1403 } | 1530 } |
| 1404 LoadRoot(r0, Heap::kUndefinedValueRootIndex); | 1531 LoadRoot(r0, Heap::kUndefinedValueRootIndex); |
| 1405 } | 1532 } |
| 1406 | 1533 |
| 1407 | 1534 |
| 1408 void MacroAssembler::IndexFromHash(Register hash, Register index) { | 1535 void MacroAssembler::IndexFromHash(Register hash, Register index) { |
| 1409 // If the hash field contains an array index pick it out. The assert checks | 1536 // If the hash field contains an array index pick it out. The assert checks |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1642 int num_arguments, | 1769 int num_arguments, |
| 1643 int result_size) { | 1770 int result_size) { |
| 1644 // TODO(1236192): Most runtime routines don't need the number of | 1771 // TODO(1236192): Most runtime routines don't need the number of |
| 1645 // arguments passed in because it is constant. At some point we | 1772 // arguments passed in because it is constant. At some point we |
| 1646 // should remove this need and make the runtime routine entry code | 1773 // should remove this need and make the runtime routine entry code |
| 1647 // smarter. | 1774 // smarter. |
| 1648 mov(r0, Operand(num_arguments)); | 1775 mov(r0, Operand(num_arguments)); |
| 1649 JumpToExternalReference(ext); | 1776 JumpToExternalReference(ext); |
| 1650 } | 1777 } |
| 1651 | 1778 |
| 1779 MaybeObject* MacroAssembler::TryTailCallExternalReference( | |
| 1780 const ExternalReference& ext, int num_arguments, int result_size) { | |
| 1781 // TODO(1236192): Most runtime routines don't need the number of | |
| 1782 // arguments passed in because it is constant. At some point we | |
| 1783 // should remove this need and make the runtime routine entry code | |
| 1784 // smarter. | |
| 1785 mov(r0, Operand(num_arguments)); | |
| 1786 return TryJumpToExternalReference(ext); | |
| 1787 } | |
| 1652 | 1788 |
| 1653 void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid, | 1789 void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid, |
| 1654 int num_arguments, | 1790 int num_arguments, |
| 1655 int result_size) { | 1791 int result_size) { |
| 1656 TailCallExternalReference(ExternalReference(fid), num_arguments, result_size); | 1792 TailCallExternalReference(ExternalReference(fid), num_arguments, result_size); |
| 1657 } | 1793 } |
| 1658 | 1794 |
| 1659 | 1795 |
| 1660 void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin) { | 1796 void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin) { |
| 1661 #if defined(__thumb__) | 1797 #if defined(__thumb__) |
| 1662 // Thumb mode builtin. | 1798 // Thumb mode builtin. |
| 1663 ASSERT((reinterpret_cast<intptr_t>(builtin.address()) & 1) == 1); | 1799 ASSERT((reinterpret_cast<intptr_t>(builtin.address()) & 1) == 1); |
| 1664 #endif | 1800 #endif |
| 1665 mov(r1, Operand(builtin)); | 1801 mov(r1, Operand(builtin)); |
| 1666 CEntryStub stub(1); | 1802 CEntryStub stub(1); |
| 1667 Jump(stub.GetCode(), RelocInfo::CODE_TARGET); | 1803 Jump(stub.GetCode(), RelocInfo::CODE_TARGET); |
| 1668 } | 1804 } |
| 1669 | 1805 |
| 1806 MaybeObject* MacroAssembler::TryJumpToExternalReference( | |
| 1807 const ExternalReference& builtin) { | |
| 1808 #if defined(__thumb__) | |
| 1809 // Thumb mode builtin. | |
| 1810 ASSERT((reinterpret_cast<intptr_t>(builtin.address()) & 1) == 1); | |
| 1811 #endif | |
| 1812 mov(r1, Operand(builtin)); | |
| 1813 CEntryStub stub(1); | |
| 1814 return TryTailCallStub(&stub); | |
| 1815 } | |
| 1670 | 1816 |
| 1671 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, | 1817 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, |
| 1672 InvokeJSFlags flags) { | 1818 InvokeJSFlags flags) { |
| 1673 GetBuiltinEntry(r2, id); | 1819 GetBuiltinEntry(r2, id); |
| 1674 if (flags == CALL_JS) { | 1820 if (flags == CALL_JS) { |
| 1675 Call(r2); | 1821 Call(r2); |
| 1676 } else { | 1822 } else { |
| 1677 ASSERT(flags == JUMP_JS); | 1823 ASSERT(flags == JUMP_JS); |
| 1678 Jump(r2); | 1824 Jump(r2); |
| 1679 } | 1825 } |
| (...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2145 | 2291 |
| 2146 void CodePatcher::Emit(Address addr) { | 2292 void CodePatcher::Emit(Address addr) { |
| 2147 masm()->emit(reinterpret_cast<Instr>(addr)); | 2293 masm()->emit(reinterpret_cast<Instr>(addr)); |
| 2148 } | 2294 } |
| 2149 #endif // ENABLE_DEBUGGER_SUPPORT | 2295 #endif // ENABLE_DEBUGGER_SUPPORT |
| 2150 | 2296 |
| 2151 | 2297 |
| 2152 } } // namespace v8::internal | 2298 } } // namespace v8::internal |
| 2153 | 2299 |
| 2154 #endif // V8_TARGET_ARCH_ARM | 2300 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |