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