| OLD | NEW |
| 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 2751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2762 void MacroAssembler::DebugBreak() { | 2762 void MacroAssembler::DebugBreak() { |
| 2763 ASSERT(allow_stub_calls()); | 2763 ASSERT(allow_stub_calls()); |
| 2764 Set(rax, 0); // No arguments. | 2764 Set(rax, 0); // No arguments. |
| 2765 LoadAddress(rbx, ExternalReference(Runtime::kDebugBreak, isolate())); | 2765 LoadAddress(rbx, ExternalReference(Runtime::kDebugBreak, isolate())); |
| 2766 CEntryStub ces(1); | 2766 CEntryStub ces(1); |
| 2767 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); | 2767 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); |
| 2768 } | 2768 } |
| 2769 #endif // ENABLE_DEBUGGER_SUPPORT | 2769 #endif // ENABLE_DEBUGGER_SUPPORT |
| 2770 | 2770 |
| 2771 | 2771 |
| 2772 void MacroAssembler::SetCallKind(Register dst, CallKind call_kind) { |
| 2773 // This macro takes the dst register to make the code more readable |
| 2774 // at the call sites. However, the dst register has to be rcx to |
| 2775 // follow the calling convention which requires the call type to be |
| 2776 // in rcx. |
| 2777 ASSERT(dst.is(rcx)); |
| 2778 if (call_kind == CALL_AS_FUNCTION) { |
| 2779 LoadSmiConstant(dst, Smi::FromInt(1)); |
| 2780 } else { |
| 2781 LoadSmiConstant(dst, Smi::FromInt(0)); |
| 2782 } |
| 2783 } |
| 2784 |
| 2785 |
| 2772 void MacroAssembler::InvokeCode(Register code, | 2786 void MacroAssembler::InvokeCode(Register code, |
| 2773 const ParameterCount& expected, | 2787 const ParameterCount& expected, |
| 2774 const ParameterCount& actual, | 2788 const ParameterCount& actual, |
| 2775 InvokeFlag flag, | 2789 InvokeFlag flag, |
| 2776 const CallWrapper& call_wrapper) { | 2790 const CallWrapper& call_wrapper, |
| 2791 CallKind call_kind) { |
| 2777 Label done; | 2792 Label done; |
| 2778 InvokePrologue(expected, | 2793 InvokePrologue(expected, |
| 2779 actual, | 2794 actual, |
| 2780 Handle<Code>::null(), | 2795 Handle<Code>::null(), |
| 2781 code, | 2796 code, |
| 2782 &done, | 2797 &done, |
| 2783 flag, | 2798 flag, |
| 2799 Label::kNear, |
| 2784 call_wrapper, | 2800 call_wrapper, |
| 2785 Label::kNear); | 2801 call_kind); |
| 2786 if (flag == CALL_FUNCTION) { | 2802 if (flag == CALL_FUNCTION) { |
| 2787 call_wrapper.BeforeCall(CallSize(code)); | 2803 call_wrapper.BeforeCall(CallSize(code)); |
| 2804 SetCallKind(rcx, call_kind); |
| 2788 call(code); | 2805 call(code); |
| 2789 call_wrapper.AfterCall(); | 2806 call_wrapper.AfterCall(); |
| 2790 } else { | 2807 } else { |
| 2791 ASSERT(flag == JUMP_FUNCTION); | 2808 ASSERT(flag == JUMP_FUNCTION); |
| 2809 SetCallKind(rcx, call_kind); |
| 2792 jmp(code); | 2810 jmp(code); |
| 2793 } | 2811 } |
| 2794 bind(&done); | 2812 bind(&done); |
| 2795 } | 2813 } |
| 2796 | 2814 |
| 2797 | 2815 |
| 2798 void MacroAssembler::InvokeCode(Handle<Code> code, | 2816 void MacroAssembler::InvokeCode(Handle<Code> code, |
| 2799 const ParameterCount& expected, | 2817 const ParameterCount& expected, |
| 2800 const ParameterCount& actual, | 2818 const ParameterCount& actual, |
| 2801 RelocInfo::Mode rmode, | 2819 RelocInfo::Mode rmode, |
| 2802 InvokeFlag flag, | 2820 InvokeFlag flag, |
| 2803 const CallWrapper& call_wrapper) { | 2821 const CallWrapper& call_wrapper, |
| 2822 CallKind call_kind) { |
| 2804 Label done; | 2823 Label done; |
| 2805 Register dummy = rax; | 2824 Register dummy = rax; |
| 2806 InvokePrologue(expected, | 2825 InvokePrologue(expected, |
| 2807 actual, | 2826 actual, |
| 2808 code, | 2827 code, |
| 2809 dummy, | 2828 dummy, |
| 2810 &done, | 2829 &done, |
| 2811 flag, | 2830 flag, |
| 2831 Label::kNear, |
| 2812 call_wrapper, | 2832 call_wrapper, |
| 2813 Label::kNear); | 2833 call_kind); |
| 2814 if (flag == CALL_FUNCTION) { | 2834 if (flag == CALL_FUNCTION) { |
| 2815 call_wrapper.BeforeCall(CallSize(code)); | 2835 call_wrapper.BeforeCall(CallSize(code)); |
| 2836 SetCallKind(rcx, call_kind); |
| 2816 Call(code, rmode); | 2837 Call(code, rmode); |
| 2817 call_wrapper.AfterCall(); | 2838 call_wrapper.AfterCall(); |
| 2818 } else { | 2839 } else { |
| 2819 ASSERT(flag == JUMP_FUNCTION); | 2840 ASSERT(flag == JUMP_FUNCTION); |
| 2841 SetCallKind(rcx, call_kind); |
| 2820 Jump(code, rmode); | 2842 Jump(code, rmode); |
| 2821 } | 2843 } |
| 2822 bind(&done); | 2844 bind(&done); |
| 2823 } | 2845 } |
| 2824 | 2846 |
| 2825 | 2847 |
| 2826 void MacroAssembler::InvokeFunction(Register function, | 2848 void MacroAssembler::InvokeFunction(Register function, |
| 2827 const ParameterCount& actual, | 2849 const ParameterCount& actual, |
| 2828 InvokeFlag flag, | 2850 InvokeFlag flag, |
| 2829 const CallWrapper& call_wrapper) { | 2851 const CallWrapper& call_wrapper, |
| 2852 CallKind call_kind) { |
| 2830 ASSERT(function.is(rdi)); | 2853 ASSERT(function.is(rdi)); |
| 2831 movq(rdx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); | 2854 movq(rdx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); |
| 2832 movq(rsi, FieldOperand(function, JSFunction::kContextOffset)); | 2855 movq(rsi, FieldOperand(function, JSFunction::kContextOffset)); |
| 2833 movsxlq(rbx, | 2856 movsxlq(rbx, |
| 2834 FieldOperand(rdx, SharedFunctionInfo::kFormalParameterCountOffset)); | 2857 FieldOperand(rdx, SharedFunctionInfo::kFormalParameterCountOffset)); |
| 2835 // Advances rdx to the end of the Code object header, to the start of | 2858 // Advances rdx to the end of the Code object header, to the start of |
| 2836 // the executable code. | 2859 // the executable code. |
| 2837 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); | 2860 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |
| 2838 | 2861 |
| 2839 ParameterCount expected(rbx); | 2862 ParameterCount expected(rbx); |
| 2840 InvokeCode(rdx, expected, actual, flag, call_wrapper); | 2863 InvokeCode(rdx, expected, actual, flag, call_wrapper, call_kind); |
| 2841 } | 2864 } |
| 2842 | 2865 |
| 2843 | 2866 |
| 2844 void MacroAssembler::InvokeFunction(JSFunction* function, | 2867 void MacroAssembler::InvokeFunction(JSFunction* function, |
| 2845 const ParameterCount& actual, | 2868 const ParameterCount& actual, |
| 2846 InvokeFlag flag, | 2869 InvokeFlag flag, |
| 2847 const CallWrapper& call_wrapper) { | 2870 const CallWrapper& call_wrapper) { |
| 2848 ASSERT(function->is_compiled()); | 2871 ASSERT(function->is_compiled()); |
| 2849 // Get the function and setup the context. | 2872 // Get the function and setup the context. |
| 2850 Move(rdi, Handle<JSFunction>(function)); | 2873 Move(rdi, Handle<JSFunction>(function)); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2869 } | 2892 } |
| 2870 } | 2893 } |
| 2871 | 2894 |
| 2872 | 2895 |
| 2873 void MacroAssembler::InvokePrologue(const ParameterCount& expected, | 2896 void MacroAssembler::InvokePrologue(const ParameterCount& expected, |
| 2874 const ParameterCount& actual, | 2897 const ParameterCount& actual, |
| 2875 Handle<Code> code_constant, | 2898 Handle<Code> code_constant, |
| 2876 Register code_register, | 2899 Register code_register, |
| 2877 Label* done, | 2900 Label* done, |
| 2878 InvokeFlag flag, | 2901 InvokeFlag flag, |
| 2902 Label::Distance near_jump, |
| 2879 const CallWrapper& call_wrapper, | 2903 const CallWrapper& call_wrapper, |
| 2880 Label::Distance near_jump) { | 2904 CallKind call_kind) { |
| 2881 bool definitely_matches = false; | 2905 bool definitely_matches = false; |
| 2882 Label invoke; | 2906 Label invoke; |
| 2883 if (expected.is_immediate()) { | 2907 if (expected.is_immediate()) { |
| 2884 ASSERT(actual.is_immediate()); | 2908 ASSERT(actual.is_immediate()); |
| 2885 if (expected.immediate() == actual.immediate()) { | 2909 if (expected.immediate() == actual.immediate()) { |
| 2886 definitely_matches = true; | 2910 definitely_matches = true; |
| 2887 } else { | 2911 } else { |
| 2888 Set(rax, actual.immediate()); | 2912 Set(rax, actual.immediate()); |
| 2889 if (expected.immediate() == | 2913 if (expected.immediate() == |
| 2890 SharedFunctionInfo::kDontAdaptArgumentsSentinel) { | 2914 SharedFunctionInfo::kDontAdaptArgumentsSentinel) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2920 Handle<Code> adaptor = isolate()->builtins()->ArgumentsAdaptorTrampoline(); | 2944 Handle<Code> adaptor = isolate()->builtins()->ArgumentsAdaptorTrampoline(); |
| 2921 if (!code_constant.is_null()) { | 2945 if (!code_constant.is_null()) { |
| 2922 movq(rdx, code_constant, RelocInfo::EMBEDDED_OBJECT); | 2946 movq(rdx, code_constant, RelocInfo::EMBEDDED_OBJECT); |
| 2923 addq(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 2947 addq(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
| 2924 } else if (!code_register.is(rdx)) { | 2948 } else if (!code_register.is(rdx)) { |
| 2925 movq(rdx, code_register); | 2949 movq(rdx, code_register); |
| 2926 } | 2950 } |
| 2927 | 2951 |
| 2928 if (flag == CALL_FUNCTION) { | 2952 if (flag == CALL_FUNCTION) { |
| 2929 call_wrapper.BeforeCall(CallSize(adaptor)); | 2953 call_wrapper.BeforeCall(CallSize(adaptor)); |
| 2954 SetCallKind(rcx, call_kind); |
| 2930 Call(adaptor, RelocInfo::CODE_TARGET); | 2955 Call(adaptor, RelocInfo::CODE_TARGET); |
| 2931 call_wrapper.AfterCall(); | 2956 call_wrapper.AfterCall(); |
| 2932 jmp(done, near_jump); | 2957 jmp(done, near_jump); |
| 2933 } else { | 2958 } else { |
| 2959 SetCallKind(rcx, call_kind); |
| 2934 Jump(adaptor, RelocInfo::CODE_TARGET); | 2960 Jump(adaptor, RelocInfo::CODE_TARGET); |
| 2935 } | 2961 } |
| 2936 bind(&invoke); | 2962 bind(&invoke); |
| 2937 } | 2963 } |
| 2938 } | 2964 } |
| 2939 | 2965 |
| 2940 | 2966 |
| 2941 void MacroAssembler::EnterFrame(StackFrame::Type type) { | 2967 void MacroAssembler::EnterFrame(StackFrame::Type type) { |
| 2942 push(rbp); | 2968 push(rbp); |
| 2943 movq(rbp, rsp); | 2969 movq(rbp, rsp); |
| (...skipping 755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3699 CPU::FlushICache(address_, size_); | 3725 CPU::FlushICache(address_, size_); |
| 3700 | 3726 |
| 3701 // Check that the code was patched as expected. | 3727 // Check that the code was patched as expected. |
| 3702 ASSERT(masm_.pc_ == address_ + size_); | 3728 ASSERT(masm_.pc_ == address_ + size_); |
| 3703 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 3729 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
| 3704 } | 3730 } |
| 3705 | 3731 |
| 3706 } } // namespace v8::internal | 3732 } } // namespace v8::internal |
| 3707 | 3733 |
| 3708 #endif // V8_TARGET_ARCH_X64 | 3734 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |