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

Side by Side Diff: src/arm/macro-assembler-arm.cc

Issue 6170001: Direct call api functions (arm implementation) (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 11 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
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 1379 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 void MacroAssembler::EnterExitFramePrologue(int unwind_space) {
1411 add(ip, sp, Operand(unwind_space * kPointerSize));
1412 // Push in reverse order: caller_fp, sp_on_exit, and caller_pc.
1413 stm(db_w, sp, fp.bit() | ip.bit() | lr.bit());
1414 mov(fp, Operand(sp));
1415
1416 mov(ip, Operand(CodeObject()));
1417 push(ip);
1418 mov(ip, Operand(ExitApiFrameConstants::kMarker));
1419 push(ip);
1420 push(ip); // Exit Frame sp patched before call.
1421
1422 mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address)));
1423 str(fp, MemOperand(ip));
1424 mov(ip, Operand(ExternalReference(Top::k_context_address)));
1425 str(cp, MemOperand(ip));
1426 }
1427
1428 void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space) {
1429 // Create space for the args.
1430 sub(sp, sp, Operand(arg_stack_space * kPointerSize));
1431
1432 int frame_alignment = ActivationFrameAlignment();
1433 int frame_alignment_mask = frame_alignment - 1;
1434 if (frame_alignment > kPointerSize) {
1435 ASSERT(frame_alignment == 2 * kPointerSize);
1436 tst(sp, Operand(frame_alignment_mask));
1437 // Stack alignment place holder need not be initialized as its below
1438 // c_entry_fp_address and does not affect GC.
1439 push(ip, nz);
1440 }
1441 str(sp, MemOperand(fp, ExitApiFrameConstants::kSPOffset));
1442 }
1443
1444 void MacroAssembler::PrepareCallApiFunction(int arg_stack_space,
1445 int unwind_space) {
1446 EnterExitFramePrologue(unwind_space);
1447 EnterExitFrameEpilogue(arg_stack_space);
1448 }
1449
1450 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) {
1451 int64_t offset = (ref0.address() - ref1.address());
1452 // Check that fits into int.
1453 ASSERT(static_cast<int>(offset) == offset);
1454 return static_cast<int>(offset);
1455 }
1456
1457 MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn(
1458 ApiFunction* function) {
1459 ExternalReference next_address =
1460 ExternalReference::handle_scope_next_address();
1461 const int kNextOffset = 0;
1462 const int kLimitOffset = AddressOffset(
1463 ExternalReference::handle_scope_limit_address(),
1464 next_address);
1465 const int kLevelOffset = AddressOffset(
1466 ExternalReference::handle_scope_level_address(),
1467 next_address);
1468
1469 // Allocate HandleScope in callee-save registers.
1470 mov(r7, Operand(next_address));
1471 ldr(r4, MemOperand(r7, kNextOffset));
1472 ldr(r5, MemOperand(r7, kLimitOffset));
1473 ldr(r6, MemOperand(r7, kLevelOffset));
1474 add(r6, r6, Operand(1));
1475 str(r6, MemOperand(r7, kLevelOffset));
1476
1477 // Call the api function.
1478 Call(function->address(), RelocInfo::RUNTIME_ENTRY);
SeRya 2011/01/18 19:01:57 This will be translated into mov(lr, Operand(pc),
1479
1480 Label promote_scheduled_exception;
1481 Label delete_allocated_handles;
1482 Label leave_exit_frame;
1483
1484 // If result is non-zero, dereference to get the result value
1485 // otherwise set it to undefined.
1486 cmp(r0, Operand(0));
1487 LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
1488 ldr(r0, MemOperand(r0), ne);
1489
1490 // No more valid handles (the result handle was the last one). Restore
1491 // previous handle scope.
1492 str(r4, MemOperand(r7, kNextOffset));
1493 if (FLAG_debug_code) {
1494 ldr(r1, MemOperand(r7, kLevelOffset));
1495 cmp(r1, r6);
1496 Check(eq, "Unexpected level after return from api call");
1497 }
1498 sub(r6, r6, Operand(1));
1499 str(r6, MemOperand(r7, kLevelOffset));
1500 ldr(ip, MemOperand(r7, kLimitOffset));
1501 cmp(r5, ip);
1502 b(ne, &delete_allocated_handles);
1503
1504 // Check if the function scheduled an exception.
1505 bind(&leave_exit_frame);
1506 LoadRoot(r4, Heap::kTheHoleValueRootIndex);
1507 mov(ip, Operand(ExternalReference(Top::k_pending_exception_address)));
1508 ldr(r5, MemOperand(ip));
1509 cmp(r4, r5);
1510 b(ne, &promote_scheduled_exception);
1511 LeaveExitFrame(false);
1512
1513 bind(&promote_scheduled_exception);
1514 MaybeObject* result = TryTailCallExternalReference(
1515 ExternalReference(Runtime::kPromoteScheduledException), 0, 1);
1516 if (result->IsFailure()) {
1517 return result;
1518 }
1519
1520 // HandleScope limit has changed. Delete allocated extensions.
1521 bind(&delete_allocated_handles);
1522 str(r5, MemOperand(r7, kLimitOffset));
1523 mov(r4, r0);
1524 PrepareCallCFunction(0, r5);
1525 CallCFunction(ExternalReference::delete_handle_scope_extensions(), 0);
1526 mov(r0, r4);
1527 jmp(&leave_exit_frame);
1528
1529 return result;
1530 }
1531
1532
1400 void MacroAssembler::IllegalOperation(int num_arguments) { 1533 void MacroAssembler::IllegalOperation(int num_arguments) {
1401 if (num_arguments > 0) { 1534 if (num_arguments > 0) {
1402 add(sp, sp, Operand(num_arguments * kPointerSize)); 1535 add(sp, sp, Operand(num_arguments * kPointerSize));
1403 } 1536 }
1404 LoadRoot(r0, Heap::kUndefinedValueRootIndex); 1537 LoadRoot(r0, Heap::kUndefinedValueRootIndex);
1405 } 1538 }
1406 1539
1407 1540
1408 void MacroAssembler::IndexFromHash(Register hash, Register index) { 1541 void MacroAssembler::IndexFromHash(Register hash, Register index) {
1409 // If the hash field contains an array index pick it out. The assert checks 1542 // 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
1642 int num_arguments, 1775 int num_arguments,
1643 int result_size) { 1776 int result_size) {
1644 // TODO(1236192): Most runtime routines don't need the number of 1777 // TODO(1236192): Most runtime routines don't need the number of
1645 // arguments passed in because it is constant. At some point we 1778 // arguments passed in because it is constant. At some point we
1646 // should remove this need and make the runtime routine entry code 1779 // should remove this need and make the runtime routine entry code
1647 // smarter. 1780 // smarter.
1648 mov(r0, Operand(num_arguments)); 1781 mov(r0, Operand(num_arguments));
1649 JumpToExternalReference(ext); 1782 JumpToExternalReference(ext);
1650 } 1783 }
1651 1784
1785 MaybeObject* MacroAssembler::TryTailCallExternalReference(
1786 const ExternalReference& ext, int num_arguments, int result_size) {
1787 // TODO(1236192): Most runtime routines don't need the number of
1788 // arguments passed in because it is constant. At some point we
1789 // should remove this need and make the runtime routine entry code
1790 // smarter.
1791 mov(r0, Operand(num_arguments));
1792 return TryJumpToExternalReference(ext);
1793 }
1652 1794
1653 void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid, 1795 void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid,
1654 int num_arguments, 1796 int num_arguments,
1655 int result_size) { 1797 int result_size) {
1656 TailCallExternalReference(ExternalReference(fid), num_arguments, result_size); 1798 TailCallExternalReference(ExternalReference(fid), num_arguments, result_size);
1657 } 1799 }
1658 1800
1659 1801
1660 void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin) { 1802 void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin) {
1661 #if defined(__thumb__) 1803 #if defined(__thumb__)
1662 // Thumb mode builtin. 1804 // Thumb mode builtin.
1663 ASSERT((reinterpret_cast<intptr_t>(builtin.address()) & 1) == 1); 1805 ASSERT((reinterpret_cast<intptr_t>(builtin.address()) & 1) == 1);
1664 #endif 1806 #endif
1665 mov(r1, Operand(builtin)); 1807 mov(r1, Operand(builtin));
1666 CEntryStub stub(1); 1808 CEntryStub stub(1);
1667 Jump(stub.GetCode(), RelocInfo::CODE_TARGET); 1809 Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
1668 } 1810 }
1669 1811
1812 MaybeObject* MacroAssembler::TryJumpToExternalReference(
1813 const ExternalReference& builtin) {
1814 #if defined(__thumb__)
1815 // Thumb mode builtin.
1816 ASSERT((reinterpret_cast<intptr_t>(builtin.address()) & 1) == 1);
1817 #endif
1818 mov(r1, Operand(builtin));
1819 CEntryStub stub(1);
1820 return TryTailCallStub(&stub);
1821 }
1670 1822
1671 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, 1823 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
1672 InvokeJSFlags flags) { 1824 InvokeJSFlags flags) {
1673 GetBuiltinEntry(r2, id); 1825 GetBuiltinEntry(r2, id);
1674 if (flags == CALL_JS) { 1826 if (flags == CALL_JS) {
1675 Call(r2); 1827 Call(r2);
1676 } else { 1828 } else {
1677 ASSERT(flags == JUMP_JS); 1829 ASSERT(flags == JUMP_JS);
1678 Jump(r2); 1830 Jump(r2);
1679 } 1831 }
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
2145 2297
2146 void CodePatcher::Emit(Address addr) { 2298 void CodePatcher::Emit(Address addr) {
2147 masm()->emit(reinterpret_cast<Instr>(addr)); 2299 masm()->emit(reinterpret_cast<Instr>(addr));
2148 } 2300 }
2149 #endif // ENABLE_DEBUGGER_SUPPORT 2301 #endif // ENABLE_DEBUGGER_SUPPORT
2150 2302
2151 2303
2152 } } // namespace v8::internal 2304 } } // namespace v8::internal
2153 2305
2154 #endif // V8_TARGET_ARCH_ARM 2306 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698