2926 Address buf_arg(rbp, 8 + 4); 2927 Address len_arg(rbp, 8 + 8); 2928 2929 // Load up: 2930 __ movl(crc, crc_arg); 2931 __ movptr(buf, buf_arg); 2932 __ movl(len, len_arg); 2933 2934 __ kernel_crc32(crc, buf, len, table, tmp); 2935 2936 __ movl(rax, crc); 2937 __ pop(rbx); 2938 __ pop(rdi); 2939 __ pop(rsi); 2940 __ leave(); // required for proper stackwalking of RuntimeStub frame 2941 __ ret(0); 2942 2943 return start; 2944 } 2945 2946 // Safefetch stubs. 2947 void generate_safefetch(const char* name, int size, address* entry, 2948 address* fault_pc, address* continuation_pc) { 2949 // safefetch signatures: 2950 // int SafeFetch32(int* adr, int errValue); 2951 // intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue); 2952 2953 StubCodeMark mark(this, "StubRoutines", name); 2954 2955 // Entry point, pc or function descriptor. 2956 *entry = __ pc(); 2957 2958 __ movl(rax, Address(rsp, 0x8)); 2959 __ movl(rcx, Address(rsp, 0x4)); 2960 // Load *adr into eax, may fault. 2961 *fault_pc = __ pc(); 2962 switch (size) { 2963 case 4: 2964 // int32_t 2965 __ movl(rax, Address(rcx, 0)); 3138 StubRoutines::_handler_for_unsafe_access_entry = 3139 generate_handler_for_unsafe_access(); 3140 3141 // platform dependent 3142 create_control_words(); 3143 3144 StubRoutines::x86::_verify_mxcsr_entry = generate_verify_mxcsr(); 3145 StubRoutines::x86::_verify_fpu_cntrl_wrd_entry = generate_verify_fpu_cntrl_wrd(); 3146 StubRoutines::_d2i_wrapper = generate_d2i_wrapper(T_INT, 3147 CAST_FROM_FN_PTR(address, SharedRuntime::d2i)); 3148 StubRoutines::_d2l_wrapper = generate_d2i_wrapper(T_LONG, 3149 CAST_FROM_FN_PTR(address, SharedRuntime::d2l)); 3150 3151 // Build this early so it's available for the interpreter 3152 StubRoutines::_throw_StackOverflowError_entry = generate_throw_exception("StackOverflowError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError)); 3153 3154 if (UseCRC32Intrinsics) { 3155 // set table address before stub generation which use it 3156 StubRoutines::_crc_table_adr = (address)StubRoutines::x86::_crc_table; 3157 StubRoutines::_updateBytesCRC32 = generate_updateBytesCRC32(); 3158 } 3159 } 3160 3161 3162 void generate_all() { 3163 // Generates all stubs and initializes the entry points 3164 3165 // These entry points require SharedInfo::stack0 to be set up in non-core builds 3166 // and need to be relocatable, so they each fabricate a RuntimeStub internally. 3167 StubRoutines::_throw_AbstractMethodError_entry = generate_throw_exception("AbstractMethodError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_AbstractMethodError)); 3168 StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError)); 3169 StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call)); 3170 3171 //------------------------------------------------------------------------------------------------------------------------ 3172 // entry points that are platform specific 3173 3174 // support for verify_oop (must happen after universe_init) 3175 StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop(); 3176 3177 // arraycopy stubs used by compilers | 2926 Address buf_arg(rbp, 8 + 4); 2927 Address len_arg(rbp, 8 + 8); 2928 2929 // Load up: 2930 __ movl(crc, crc_arg); 2931 __ movptr(buf, buf_arg); 2932 __ movl(len, len_arg); 2933 2934 __ kernel_crc32(crc, buf, len, table, tmp); 2935 2936 __ movl(rax, crc); 2937 __ pop(rbx); 2938 __ pop(rdi); 2939 __ pop(rsi); 2940 __ leave(); // required for proper stackwalking of RuntimeStub frame 2941 __ ret(0); 2942 2943 return start; 2944 } 2945 2946 /** 2947 * Arguments: 2948 * 2949 * Inputs: 2950 * rsp(4) - int crc 2951 * rsp(8) - byte* buf 2952 * rsp(12) - int length 2953 * rsp(16) - table_start - optional (present only when doing a library_calll, 2954 * not used by x86 algorithm) 2955 * 2956 * Ouput: 2957 * rax - int crc result 2958 */ 2959 address generate_updateBytesCRC32C(bool is_pclmulqdq_supported) { 2960 assert(UseCRC32CIntrinsics, "need SSE4_2"); 2961 __ align(CodeEntryAlignment); 2962 StubCodeMark mark(this, "StubRoutines", "updateBytesCRC32C"); 2963 address start = __ pc(); 2964 const Register crc = rax; // crc 2965 const Register buf = rcx; // source java byte array address 2966 const Register len = rdx; // length 2967 const Register d = rbx; 2968 const Register g = rsi; 2969 const Register h = rdi; 2970 const Register empty = 0; // will never be used, in order not 2971 // to change a signature for crc32c_IPL_Alg2_Alt2 2972 // between 64/32 I'm just keeping it here 2973 assert_different_registers(crc, buf, len, d, g, h); 2974 2975 BLOCK_COMMENT("Entry:"); 2976 __ enter(); // required for proper stackwalking of RuntimeStub frame 2977 Address crc_arg(rsp, 4 + 4 + 0); // ESP+4 + 2978 // we need to add additional 4 because __ enter 2979 // have just pushed ebp on a stack 2980 Address buf_arg(rsp, 4 + 4 + 4); 2981 Address len_arg(rsp, 4 + 4 + 8); 2982 // Load up: 2983 __ movl(crc, crc_arg); 2984 __ movl(buf, buf_arg); 2985 __ movl(len, len_arg); 2986 __ push(d); 2987 __ push(g); 2988 __ push(h); 2989 __ crc32c_ipl_alg2_alt2(crc, buf, len, 2990 d, g, h, 2991 empty, empty, empty, 2992 xmm0, xmm1, xmm2, 2993 is_pclmulqdq_supported); 2994 __ pop(h); 2995 __ pop(g); 2996 __ pop(d); 2997 __ leave(); // required for proper stackwalking of RuntimeStub frame 2998 __ ret(0); 2999 3000 return start; 3001 } 3002 3003 // Safefetch stubs. 3004 void generate_safefetch(const char* name, int size, address* entry, 3005 address* fault_pc, address* continuation_pc) { 3006 // safefetch signatures: 3007 // int SafeFetch32(int* adr, int errValue); 3008 // intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue); 3009 3010 StubCodeMark mark(this, "StubRoutines", name); 3011 3012 // Entry point, pc or function descriptor. 3013 *entry = __ pc(); 3014 3015 __ movl(rax, Address(rsp, 0x8)); 3016 __ movl(rcx, Address(rsp, 0x4)); 3017 // Load *adr into eax, may fault. 3018 *fault_pc = __ pc(); 3019 switch (size) { 3020 case 4: 3021 // int32_t 3022 __ movl(rax, Address(rcx, 0)); 3195 StubRoutines::_handler_for_unsafe_access_entry = 3196 generate_handler_for_unsafe_access(); 3197 3198 // platform dependent 3199 create_control_words(); 3200 3201 StubRoutines::x86::_verify_mxcsr_entry = generate_verify_mxcsr(); 3202 StubRoutines::x86::_verify_fpu_cntrl_wrd_entry = generate_verify_fpu_cntrl_wrd(); 3203 StubRoutines::_d2i_wrapper = generate_d2i_wrapper(T_INT, 3204 CAST_FROM_FN_PTR(address, SharedRuntime::d2i)); 3205 StubRoutines::_d2l_wrapper = generate_d2i_wrapper(T_LONG, 3206 CAST_FROM_FN_PTR(address, SharedRuntime::d2l)); 3207 3208 // Build this early so it's available for the interpreter 3209 StubRoutines::_throw_StackOverflowError_entry = generate_throw_exception("StackOverflowError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError)); 3210 3211 if (UseCRC32Intrinsics) { 3212 // set table address before stub generation which use it 3213 StubRoutines::_crc_table_adr = (address)StubRoutines::x86::_crc_table; 3214 StubRoutines::_updateBytesCRC32 = generate_updateBytesCRC32(); 3215 } 3216 3217 if (UseCRC32CIntrinsics) { 3218 bool supports_clmul = VM_Version::supports_clmul(); 3219 StubRoutines::x86::generate_CRC32C_table(supports_clmul); 3220 StubRoutines::_crc32c_table_addr = (address)StubRoutines::x86::_crc32c_table; 3221 StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(supports_clmul); 3222 } 3223 } 3224 3225 3226 void generate_all() { 3227 // Generates all stubs and initializes the entry points 3228 3229 // These entry points require SharedInfo::stack0 to be set up in non-core builds 3230 // and need to be relocatable, so they each fabricate a RuntimeStub internally. 3231 StubRoutines::_throw_AbstractMethodError_entry = generate_throw_exception("AbstractMethodError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_AbstractMethodError)); 3232 StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError)); 3233 StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call)); 3234 3235 //------------------------------------------------------------------------------------------------------------------------ 3236 // entry points that are platform specific 3237 3238 // support for verify_oop (must happen after universe_init) 3239 StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop(); 3240 3241 // arraycopy stubs used by compilers |