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

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

Issue 6538019: Porting of revisions 6639, 6794 and 6805 to the 3.0 branch. (Closed) Base URL: https://v8.googlecode.com/svn/branches/3.0
Patch Set: Created 9 years, 10 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/arm/macro-assembler-arm.h ('k') | src/arm/regexp-macro-assembler-arm.h » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 596 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 // r1: preserved 607 // r1: preserved
608 // r2: preserved 608 // r2: preserved
609 609
610 // Drop the execution stack down to the frame pointer and restore 610 // Drop the execution stack down to the frame pointer and restore
611 // the caller frame pointer and return address. 611 // the caller frame pointer and return address.
612 mov(sp, fp); 612 mov(sp, fp);
613 ldm(ia_w, sp, fp.bit() | lr.bit()); 613 ldm(ia_w, sp, fp.bit() | lr.bit());
614 } 614 }
615 615
616 616
617 void MacroAssembler::EnterExitFrame(bool save_doubles) { 617 void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) {
618 // Compute the argv pointer in a callee-saved register.
619 add(r6, sp, Operand(r0, LSL, kPointerSizeLog2));
620 sub(r6, r6, Operand(kPointerSize));
621
622 // Setup the frame structure on the stack. 618 // Setup the frame structure on the stack.
623 ASSERT_EQ(2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement); 619 ASSERT_EQ(2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement);
624 ASSERT_EQ(1 * kPointerSize, ExitFrameConstants::kCallerPCOffset); 620 ASSERT_EQ(1 * kPointerSize, ExitFrameConstants::kCallerPCOffset);
625 ASSERT_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); 621 ASSERT_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset);
626 Push(lr, fp); 622 Push(lr, fp);
627 mov(fp, Operand(sp)); // Setup new frame pointer. 623 mov(fp, Operand(sp)); // Setup new frame pointer.
628 // Reserve room for saved entry sp and code object. 624 // Reserve room for saved entry sp and code object.
629 sub(sp, sp, Operand(2 * kPointerSize)); 625 sub(sp, sp, Operand(2 * kPointerSize));
630 if (FLAG_debug_code) { 626 if (FLAG_debug_code) {
631 mov(ip, Operand(0)); 627 mov(ip, Operand(0));
632 str(ip, MemOperand(fp, ExitFrameConstants::kSPOffset)); 628 str(ip, MemOperand(fp, ExitFrameConstants::kSPOffset));
633 } 629 }
634 mov(ip, Operand(CodeObject())); 630 mov(ip, Operand(CodeObject()));
635 str(ip, MemOperand(fp, ExitFrameConstants::kCodeOffset)); 631 str(ip, MemOperand(fp, ExitFrameConstants::kCodeOffset));
636 632
637 // Save the frame pointer and the context in top. 633 // Save the frame pointer and the context in top.
638 mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address))); 634 mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address)));
639 str(fp, MemOperand(ip)); 635 str(fp, MemOperand(ip));
640 mov(ip, Operand(ExternalReference(Top::k_context_address))); 636 mov(ip, Operand(ExternalReference(Top::k_context_address)));
641 str(cp, MemOperand(ip)); 637 str(cp, MemOperand(ip));
642 638
643 // Setup argc and the builtin function in callee-saved registers.
644 mov(r4, Operand(r0));
645 mov(r5, Operand(r1));
646
647 // Optionally save all double registers. 639 // Optionally save all double registers.
648 if (save_doubles) { 640 if (save_doubles) {
649 sub(sp, sp, Operand(DwVfpRegister::kNumRegisters * kDoubleSize)); 641 sub(sp, sp, Operand(DwVfpRegister::kNumRegisters * kDoubleSize));
650 const int offset = -2 * kPointerSize; 642 const int offset = -2 * kPointerSize;
651 for (int i = 0; i < DwVfpRegister::kNumRegisters; i++) { 643 for (int i = 0; i < DwVfpRegister::kNumRegisters; i++) {
652 DwVfpRegister reg = DwVfpRegister::from_code(i); 644 DwVfpRegister reg = DwVfpRegister::from_code(i);
653 vstr(reg, fp, offset - ((i + 1) * kDoubleSize)); 645 vstr(reg, fp, offset - ((i + 1) * kDoubleSize));
654 } 646 }
655 // Note that d0 will be accessible at 647 // Note that d0 will be accessible at
656 // fp - 2 * kPointerSize - DwVfpRegister::kNumRegisters * kDoubleSize, 648 // fp - 2 * kPointerSize - DwVfpRegister::kNumRegisters * kDoubleSize,
657 // since the sp slot and code slot were pushed after the fp. 649 // since the sp slot and code slot were pushed after the fp.
658 } 650 }
659 651
660 // Reserve place for the return address and align the frame preparing for 652 // Reserve place for the return address and stack space and align the frame
661 // calling the runtime function. 653 // preparing for calling the runtime function.
662 const int frame_alignment = MacroAssembler::ActivationFrameAlignment(); 654 const int frame_alignment = MacroAssembler::ActivationFrameAlignment();
663 sub(sp, sp, Operand(kPointerSize)); 655 sub(sp, sp, Operand((stack_space + 1) * kPointerSize));
664 if (frame_alignment > 0) { 656 if (frame_alignment > 0) {
665 ASSERT(IsPowerOf2(frame_alignment)); 657 ASSERT(IsPowerOf2(frame_alignment));
666 and_(sp, sp, Operand(-frame_alignment)); 658 and_(sp, sp, Operand(-frame_alignment));
667 } 659 }
668 660
669 // Set the exit frame sp value to point just before the return address 661 // Set the exit frame sp value to point just before the return address
670 // location. 662 // location.
671 add(ip, sp, Operand(kPointerSize)); 663 add(ip, sp, Operand(kPointerSize));
672 str(ip, MemOperand(fp, ExitFrameConstants::kSPOffset)); 664 str(ip, MemOperand(fp, ExitFrameConstants::kSPOffset));
673 } 665 }
(...skipping 23 matching lines...) Expand all
697 #else // defined(V8_HOST_ARCH_ARM) 689 #else // defined(V8_HOST_ARCH_ARM)
698 // If we are using the simulator then we should always align to the expected 690 // If we are using the simulator then we should always align to the expected
699 // alignment. As the simulator is used to generate snapshots we do not know 691 // alignment. As the simulator is used to generate snapshots we do not know
700 // if the target platform will need alignment, so this is controlled from a 692 // if the target platform will need alignment, so this is controlled from a
701 // flag. 693 // flag.
702 return FLAG_sim_stack_alignment; 694 return FLAG_sim_stack_alignment;
703 #endif // defined(V8_HOST_ARCH_ARM) 695 #endif // defined(V8_HOST_ARCH_ARM)
704 } 696 }
705 697
706 698
707 void MacroAssembler::LeaveExitFrame(bool save_doubles) { 699 void MacroAssembler::LeaveExitFrame(bool save_doubles,
700 Register argument_count) {
708 // Optionally restore all double registers. 701 // Optionally restore all double registers.
709 if (save_doubles) { 702 if (save_doubles) {
710 for (int i = 0; i < DwVfpRegister::kNumRegisters; i++) { 703 for (int i = 0; i < DwVfpRegister::kNumRegisters; i++) {
711 DwVfpRegister reg = DwVfpRegister::from_code(i); 704 DwVfpRegister reg = DwVfpRegister::from_code(i);
712 const int offset = -2 * kPointerSize; 705 const int offset = -2 * kPointerSize;
713 vldr(reg, fp, offset - ((i + 1) * kDoubleSize)); 706 vldr(reg, fp, offset - ((i + 1) * kDoubleSize));
714 } 707 }
715 } 708 }
716 709
717 // Clear top frame. 710 // Clear top frame.
718 mov(r3, Operand(0, RelocInfo::NONE)); 711 mov(r3, Operand(0, RelocInfo::NONE));
719 mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address))); 712 mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address)));
720 str(r3, MemOperand(ip)); 713 str(r3, MemOperand(ip));
721 714
722 // Restore current context from top and clear it in debug mode. 715 // Restore current context from top and clear it in debug mode.
723 mov(ip, Operand(ExternalReference(Top::k_context_address))); 716 mov(ip, Operand(ExternalReference(Top::k_context_address)));
724 ldr(cp, MemOperand(ip)); 717 ldr(cp, MemOperand(ip));
725 #ifdef DEBUG 718 #ifdef DEBUG
726 str(r3, MemOperand(ip)); 719 str(r3, MemOperand(ip));
727 #endif 720 #endif
728 721
729 // Tear down the exit frame, pop the arguments, and return. Callee-saved 722 // Tear down the exit frame, pop the arguments, and return.
730 // register r4 still holds argc.
731 mov(sp, Operand(fp)); 723 mov(sp, Operand(fp));
732 ldm(ia_w, sp, fp.bit() | lr.bit()); 724 ldm(ia_w, sp, fp.bit() | lr.bit());
733 add(sp, sp, Operand(r4, LSL, kPointerSizeLog2)); 725 if (argument_count.is_valid()) {
734 mov(pc, lr); 726 add(sp, sp, Operand(argument_count, LSL, kPointerSizeLog2));
727 }
735 } 728 }
736 729
737 730
738 void MacroAssembler::InvokePrologue(const ParameterCount& expected, 731 void MacroAssembler::InvokePrologue(const ParameterCount& expected,
739 const ParameterCount& actual, 732 const ParameterCount& actual,
740 Handle<Code> code_constant, 733 Handle<Code> code_constant,
741 Register code_reg, 734 Register code_reg,
742 Label* done, 735 Label* done,
743 InvokeFlag flag, 736 InvokeFlag flag,
744 PostCallGenerator* post_call_generator) { 737 PostCallGenerator* post_call_generator) {
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
988 981
989 void MacroAssembler::PopTryHandler() { 982 void MacroAssembler::PopTryHandler() {
990 ASSERT_EQ(0, StackHandlerConstants::kNextOffset); 983 ASSERT_EQ(0, StackHandlerConstants::kNextOffset);
991 pop(r1); 984 pop(r1);
992 mov(ip, Operand(ExternalReference(Top::k_handler_address))); 985 mov(ip, Operand(ExternalReference(Top::k_handler_address)));
993 add(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize)); 986 add(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize));
994 str(r1, MemOperand(ip)); 987 str(r1, MemOperand(ip));
995 } 988 }
996 989
997 990
991 void MacroAssembler::Throw(Register value) {
992 // r0 is expected to hold the exception.
993 if (!value.is(r0)) {
994 mov(r0, value);
995 }
996
997 // Adjust this code if not the case.
998 STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize);
999
1000 // Drop the sp to the top of the handler.
1001 mov(r3, Operand(ExternalReference(Top::k_handler_address)));
1002 ldr(sp, MemOperand(r3));
1003
1004 // Restore the next handler and frame pointer, discard handler state.
1005 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
1006 pop(r2);
1007 str(r2, MemOperand(r3));
1008 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize);
1009 ldm(ia_w, sp, r3.bit() | fp.bit()); // r3: discarded state.
1010
1011 // Before returning we restore the context from the frame pointer if
1012 // not NULL. The frame pointer is NULL in the exception handler of a
1013 // JS entry frame.
1014 cmp(fp, Operand(0, RelocInfo::NONE));
1015 // Set cp to NULL if fp is NULL.
1016 mov(cp, Operand(0, RelocInfo::NONE), LeaveCC, eq);
1017 // Restore cp otherwise.
1018 ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne);
1019 #ifdef DEBUG
1020 if (FLAG_debug_code) {
1021 mov(lr, Operand(pc));
1022 }
1023 #endif
1024 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize);
1025 pop(pc);
1026 }
1027
1028
1029 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
1030 Register value) {
1031 // Adjust this code if not the case.
1032 STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize);
1033
1034 // r0 is expected to hold the exception.
1035 if (!value.is(r0)) {
1036 mov(r0, value);
1037 }
1038
1039 // Drop sp to the top stack handler.
1040 mov(r3, Operand(ExternalReference(Top::k_handler_address)));
1041 ldr(sp, MemOperand(r3));
1042
1043 // Unwind the handlers until the ENTRY handler is found.
1044 Label loop, done;
1045 bind(&loop);
1046 // Load the type of the current stack handler.
1047 const int kStateOffset = StackHandlerConstants::kStateOffset;
1048 ldr(r2, MemOperand(sp, kStateOffset));
1049 cmp(r2, Operand(StackHandler::ENTRY));
1050 b(eq, &done);
1051 // Fetch the next handler in the list.
1052 const int kNextOffset = StackHandlerConstants::kNextOffset;
1053 ldr(sp, MemOperand(sp, kNextOffset));
1054 jmp(&loop);
1055 bind(&done);
1056
1057 // Set the top handler address to next handler past the current ENTRY handler.
1058 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
1059 pop(r2);
1060 str(r2, MemOperand(r3));
1061
1062 if (type == OUT_OF_MEMORY) {
1063 // Set external caught exception to false.
1064 ExternalReference external_caught(Top::k_external_caught_exception_address);
1065 mov(r0, Operand(false, RelocInfo::NONE));
1066 mov(r2, Operand(external_caught));
1067 str(r0, MemOperand(r2));
1068
1069 // Set pending exception and r0 to out of memory exception.
1070 Failure* out_of_memory = Failure::OutOfMemoryException();
1071 mov(r0, Operand(reinterpret_cast<int32_t>(out_of_memory)));
1072 mov(r2, Operand(ExternalReference(Top::k_pending_exception_address)));
1073 str(r0, MemOperand(r2));
1074 }
1075
1076 // Stack layout at this point. See also StackHandlerConstants.
1077 // sp -> state (ENTRY)
1078 // fp
1079 // lr
1080
1081 // Discard handler state (r2 is not used) and restore frame pointer.
1082 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize);
1083 ldm(ia_w, sp, r2.bit() | fp.bit()); // r2: discarded state.
1084 // Before returning we restore the context from the frame pointer if
1085 // not NULL. The frame pointer is NULL in the exception handler of a
1086 // JS entry frame.
1087 cmp(fp, Operand(0, RelocInfo::NONE));
1088 // Set cp to NULL if fp is NULL.
1089 mov(cp, Operand(0, RelocInfo::NONE), LeaveCC, eq);
1090 // Restore cp otherwise.
1091 ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne);
1092 #ifdef DEBUG
1093 if (FLAG_debug_code) {
1094 mov(lr, Operand(pc));
1095 }
1096 #endif
1097 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize);
1098 pop(pc);
1099 }
1100
1101
998 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, 1102 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
999 Register scratch, 1103 Register scratch,
1000 Label* miss) { 1104 Label* miss) {
1001 Label same_contexts; 1105 Label same_contexts;
1002 1106
1003 ASSERT(!holder_reg.is(scratch)); 1107 ASSERT(!holder_reg.is(scratch));
1004 ASSERT(!holder_reg.is(ip)); 1108 ASSERT(!holder_reg.is(ip));
1005 ASSERT(!scratch.is(ip)); 1109 ASSERT(!scratch.is(ip));
1006 1110
1007 // Load current lexical context from the stack frame. 1111 // Load current lexical context from the stack frame.
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
1452 // in initial map. 1556 // in initial map.
1453 bind(&non_instance); 1557 bind(&non_instance);
1454 ldr(result, FieldMemOperand(result, Map::kConstructorOffset)); 1558 ldr(result, FieldMemOperand(result, Map::kConstructorOffset));
1455 1559
1456 // All done. 1560 // All done.
1457 bind(&done); 1561 bind(&done);
1458 } 1562 }
1459 1563
1460 1564
1461 void MacroAssembler::CallStub(CodeStub* stub, Condition cond) { 1565 void MacroAssembler::CallStub(CodeStub* stub, Condition cond) {
1462 ASSERT(allow_stub_calls()); // stub calls are not allowed in some stubs 1566 ASSERT(allow_stub_calls()); // Stub calls are not allowed in some stubs.
1463 Call(stub->GetCode(), RelocInfo::CODE_TARGET, cond); 1567 Call(stub->GetCode(), RelocInfo::CODE_TARGET, cond);
1464 } 1568 }
1465 1569
1466 1570
1467 void MacroAssembler::TailCallStub(CodeStub* stub, Condition cond) { 1571 void MacroAssembler::TailCallStub(CodeStub* stub, Condition cond) {
1468 ASSERT(allow_stub_calls()); // stub calls are not allowed in some stubs 1572 ASSERT(allow_stub_calls()); // Stub calls are not allowed in some stubs.
1469 Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond); 1573 Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond);
1470 } 1574 }
1471 1575
1472 1576
1577 MaybeObject* MacroAssembler::TryTailCallStub(CodeStub* stub, Condition cond) {
1578 ASSERT(allow_stub_calls()); // Stub calls are not allowed in some stubs.
1579 Object* result;
1580 { MaybeObject* maybe_result = stub->TryGetCode();
1581 if (!maybe_result->ToObject(&result)) return maybe_result;
1582 }
1583 Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond);
1584 return result;
1585 }
1586
1587
1588 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) {
1589 return ref0.address() - ref1.address();
1590 }
1591
1592
1593 MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn(
1594 ApiFunction* function, int stack_space) {
1595 ExternalReference next_address =
1596 ExternalReference::handle_scope_next_address();
1597 const int kNextOffset = 0;
1598 const int kLimitOffset = AddressOffset(
1599 ExternalReference::handle_scope_limit_address(),
1600 next_address);
1601 const int kLevelOffset = AddressOffset(
1602 ExternalReference::handle_scope_level_address(),
1603 next_address);
1604
1605 // Allocate HandleScope in callee-save registers.
1606 mov(r7, Operand(next_address));
1607 ldr(r4, MemOperand(r7, kNextOffset));
1608 ldr(r5, MemOperand(r7, kLimitOffset));
1609 ldr(r6, MemOperand(r7, kLevelOffset));
1610 add(r6, r6, Operand(1));
1611 str(r6, MemOperand(r7, kLevelOffset));
1612
1613 // Native call returns to the DirectCEntry stub which redirects to the
1614 // return address pushed on stack (could have moved after GC).
1615 // DirectCEntry stub itself is generated early and never moves.
1616 DirectCEntryStub stub;
1617 stub.GenerateCall(this, function);
1618
1619 Label promote_scheduled_exception;
1620 Label delete_allocated_handles;
1621 Label leave_exit_frame;
1622
1623 // If result is non-zero, dereference to get the result value
1624 // otherwise set it to undefined.
1625 cmp(r0, Operand(0));
1626 LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
1627 ldr(r0, MemOperand(r0), ne);
1628
1629 // No more valid handles (the result handle was the last one). Restore
1630 // previous handle scope.
1631 str(r4, MemOperand(r7, kNextOffset));
1632 if (FLAG_debug_code) {
1633 ldr(r1, MemOperand(r7, kLevelOffset));
1634 cmp(r1, r6);
1635 Check(eq, "Unexpected level after return from api call");
1636 }
1637 sub(r6, r6, Operand(1));
1638 str(r6, MemOperand(r7, kLevelOffset));
1639 ldr(ip, MemOperand(r7, kLimitOffset));
1640 cmp(r5, ip);
1641 b(ne, &delete_allocated_handles);
1642
1643 // Check if the function scheduled an exception.
1644 bind(&leave_exit_frame);
1645 LoadRoot(r4, Heap::kTheHoleValueRootIndex);
1646 mov(ip, Operand(ExternalReference::scheduled_exception_address()));
1647 ldr(r5, MemOperand(ip));
1648 cmp(r4, r5);
1649 b(ne, &promote_scheduled_exception);
1650
1651 // LeaveExitFrame expects unwind space to be in a register.
1652 mov(r4, Operand(stack_space));
1653 LeaveExitFrame(false, r4);
1654 mov(pc, lr);
1655
1656 bind(&promote_scheduled_exception);
1657 MaybeObject* result = TryTailCallExternalReference(
1658 ExternalReference(Runtime::kPromoteScheduledException), 0, 1);
1659 if (result->IsFailure()) {
1660 return result;
1661 }
1662
1663 // HandleScope limit has changed. Delete allocated extensions.
1664 bind(&delete_allocated_handles);
1665 str(r5, MemOperand(r7, kLimitOffset));
1666 mov(r4, r0);
1667 PrepareCallCFunction(0, r5);
1668 CallCFunction(ExternalReference::delete_handle_scope_extensions(), 0);
1669 mov(r0, r4);
1670 jmp(&leave_exit_frame);
1671
1672 return result;
1673 }
1674
1675
1473 void MacroAssembler::IllegalOperation(int num_arguments) { 1676 void MacroAssembler::IllegalOperation(int num_arguments) {
1474 if (num_arguments > 0) { 1677 if (num_arguments > 0) {
1475 add(sp, sp, Operand(num_arguments * kPointerSize)); 1678 add(sp, sp, Operand(num_arguments * kPointerSize));
1476 } 1679 }
1477 LoadRoot(r0, Heap::kUndefinedValueRootIndex); 1680 LoadRoot(r0, Heap::kUndefinedValueRootIndex);
1478 } 1681 }
1479 1682
1480 1683
1481 void MacroAssembler::IndexFromHash(Register hash, Register index) { 1684 void MacroAssembler::IndexFromHash(Register hash, Register index) {
1482 // If the hash field contains an array index pick it out. The assert checks 1685 // If the hash field contains an array index pick it out. The assert checks
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
1716 int result_size) { 1919 int result_size) {
1717 // TODO(1236192): Most runtime routines don't need the number of 1920 // TODO(1236192): Most runtime routines don't need the number of
1718 // arguments passed in because it is constant. At some point we 1921 // arguments passed in because it is constant. At some point we
1719 // should remove this need and make the runtime routine entry code 1922 // should remove this need and make the runtime routine entry code
1720 // smarter. 1923 // smarter.
1721 mov(r0, Operand(num_arguments)); 1924 mov(r0, Operand(num_arguments));
1722 JumpToExternalReference(ext); 1925 JumpToExternalReference(ext);
1723 } 1926 }
1724 1927
1725 1928
1929 MaybeObject* MacroAssembler::TryTailCallExternalReference(
1930 const ExternalReference& ext, int num_arguments, int result_size) {
1931 // TODO(1236192): Most runtime routines don't need the number of
1932 // arguments passed in because it is constant. At some point we
1933 // should remove this need and make the runtime routine entry code
1934 // smarter.
1935 mov(r0, Operand(num_arguments));
1936 return TryJumpToExternalReference(ext);
1937 }
1938
1939
1726 void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid, 1940 void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid,
1727 int num_arguments, 1941 int num_arguments,
1728 int result_size) { 1942 int result_size) {
1729 TailCallExternalReference(ExternalReference(fid), num_arguments, result_size); 1943 TailCallExternalReference(ExternalReference(fid), num_arguments, result_size);
1730 } 1944 }
1731 1945
1732 1946
1733 void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin) { 1947 void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin) {
1734 #if defined(__thumb__) 1948 #if defined(__thumb__)
1735 // Thumb mode builtin. 1949 // Thumb mode builtin.
1736 ASSERT((reinterpret_cast<intptr_t>(builtin.address()) & 1) == 1); 1950 ASSERT((reinterpret_cast<intptr_t>(builtin.address()) & 1) == 1);
1737 #endif 1951 #endif
1738 mov(r1, Operand(builtin)); 1952 mov(r1, Operand(builtin));
1739 CEntryStub stub(1); 1953 CEntryStub stub(1);
1740 Jump(stub.GetCode(), RelocInfo::CODE_TARGET); 1954 Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
1741 } 1955 }
1742 1956
1743 1957
1958 MaybeObject* MacroAssembler::TryJumpToExternalReference(
1959 const ExternalReference& builtin) {
1960 #if defined(__thumb__)
1961 // Thumb mode builtin.
1962 ASSERT((reinterpret_cast<intptr_t>(builtin.address()) & 1) == 1);
1963 #endif
1964 mov(r1, Operand(builtin));
1965 CEntryStub stub(1);
1966 return TryTailCallStub(&stub);
1967 }
1968
1969
1744 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, 1970 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
1745 InvokeJSFlags flags, 1971 InvokeJSFlags flags,
1746 PostCallGenerator* post_call_generator) { 1972 PostCallGenerator* post_call_generator) {
1747 GetBuiltinEntry(r2, id); 1973 GetBuiltinEntry(r2, id);
1748 if (flags == CALL_JS) { 1974 if (flags == CALL_JS) {
1749 Call(r2); 1975 Call(r2);
1750 if (post_call_generator != NULL) post_call_generator->Generate(); 1976 if (post_call_generator != NULL) post_call_generator->Generate();
1751 } else { 1977 } else {
1752 ASSERT(flags == JUMP_JS); 1978 ASSERT(flags == JUMP_JS);
1753 Jump(r2); 1979 Jump(r2);
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after
2258 2484
2259 void CodePatcher::Emit(Address addr) { 2485 void CodePatcher::Emit(Address addr) {
2260 masm()->emit(reinterpret_cast<Instr>(addr)); 2486 masm()->emit(reinterpret_cast<Instr>(addr));
2261 } 2487 }
2262 #endif // ENABLE_DEBUGGER_SUPPORT 2488 #endif // ENABLE_DEBUGGER_SUPPORT
2263 2489
2264 2490
2265 } } // namespace v8::internal 2491 } } // namespace v8::internal
2266 2492
2267 #endif // V8_TARGET_ARCH_ARM 2493 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/macro-assembler-arm.h ('k') | src/arm/regexp-macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698