58 default: ShouldNotReachHere(); 59 } 60 ResourceMark rm; 61 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize); 62 CodeBuffer cbuf(blob); 63 MacroAssembler* masm = new MacroAssembler(&cbuf); 64 address fast_entry = __ pc(); 65 66 Label slow; 67 68 // stack layout: offset from rsp (in words): 69 // return pc 0 70 // jni env 1 71 // obj 2 72 // jfieldID 3 73 74 ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr()); 75 __ mov32 (rcx, counter); 76 __ testb (rcx, 1); 77 __ jcc (Assembler::notZero, slow); 78 if (os::is_MP()) { 79 __ mov(rax, rcx); 80 __ andptr(rax, 1); // rax, must end up 0 81 __ movptr(rdx, Address(rsp, rax, Address::times_1, 2*wordSize)); 82 // obj, notice rax, is 0. 83 // rdx is data dependent on rcx. 84 } else { 85 __ movptr (rdx, Address(rsp, 2*wordSize)); // obj 86 } 87 __ movptr(rax, Address(rsp, 3*wordSize)); // jfieldID 88 89 __ clear_jweak_tag(rdx); 90 91 __ movptr(rdx, Address(rdx, 0)); // *obj 92 __ shrptr (rax, 2); // offset 93 94 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); 95 speculative_load_pclist[count] = __ pc(); 96 switch (type) { 97 case T_BOOLEAN: __ movzbl (rax, Address(rdx, rax, Address::times_1)); break; 98 case T_BYTE: __ movsbl (rax, Address(rdx, rax, Address::times_1)); break; 99 case T_CHAR: __ movzwl (rax, Address(rdx, rax, Address::times_1)); break; 100 case T_SHORT: __ movswl (rax, Address(rdx, rax, Address::times_1)); break; 101 case T_INT: __ movl (rax, Address(rdx, rax, Address::times_1)); break; 102 default: ShouldNotReachHere(); 103 } 104 105 Address ca1; 106 if (os::is_MP()) { 107 __ lea(rdx, counter); 108 __ xorptr(rdx, rax); 109 __ xorptr(rdx, rax); 110 __ cmp32(rcx, Address(rdx, 0)); 111 // ca1 is the same as ca because 112 // rax, ^ counter_addr ^ rax, = address 113 // ca1 is data dependent on rax,. 114 } else { 115 __ cmp32(rcx, counter); 116 } 117 __ jcc (Assembler::notEqual, slow); 118 119 #ifndef _WINDOWS 120 __ ret (0); 121 #else 122 // __stdcall calling convention 123 __ ret (3*wordSize); 124 #endif 125 126 slowcase_entry_pclist[count++] = __ pc(); 127 __ bind (slow); 128 address slow_case_addr = NULL; 129 switch (type) { 130 case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break; 131 case T_BYTE: slow_case_addr = jni_GetByteField_addr(); break; 132 case T_CHAR: slow_case_addr = jni_GetCharField_addr(); break; 133 case T_SHORT: slow_case_addr = jni_GetShortField_addr(); break; 134 case T_INT: slow_case_addr = jni_GetIntField_addr(); 135 } 136 // tail call 178 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize); 179 CodeBuffer cbuf(blob); 180 MacroAssembler* masm = new MacroAssembler(&cbuf); 181 address fast_entry = __ pc(); 182 183 Label slow; 184 185 // stack layout: offset from rsp (in words): 186 // old rsi 0 187 // return pc 1 188 // jni env 2 189 // obj 3 190 // jfieldID 4 191 192 ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr()); 193 194 __ push (rsi); 195 __ mov32 (rcx, counter); 196 __ testb (rcx, 1); 197 __ jcc (Assembler::notZero, slow); 198 if (os::is_MP()) { 199 __ mov(rax, rcx); 200 __ andptr(rax, 1); // rax, must end up 0 201 __ movptr(rdx, Address(rsp, rax, Address::times_1, 3*wordSize)); 202 // obj, notice rax, is 0. 203 // rdx is data dependent on rcx. 204 } else { 205 __ movptr(rdx, Address(rsp, 3*wordSize)); // obj 206 } 207 __ movptr(rsi, Address(rsp, 4*wordSize)); // jfieldID 208 209 __ clear_jweak_tag(rdx); 210 211 __ movptr(rdx, Address(rdx, 0)); // *obj 212 __ shrptr(rsi, 2); // offset 213 214 assert(count < LIST_CAPACITY-1, "LIST_CAPACITY too small"); 215 speculative_load_pclist[count++] = __ pc(); 216 __ movptr(rax, Address(rdx, rsi, Address::times_1)); 217 #ifndef _LP64 218 speculative_load_pclist[count] = __ pc(); 219 __ movl(rdx, Address(rdx, rsi, Address::times_1, 4)); 220 #endif // _LP64 221 222 if (os::is_MP()) { 223 __ lea(rsi, counter); 224 __ xorptr(rsi, rdx); 225 __ xorptr(rsi, rax); 226 __ xorptr(rsi, rdx); 227 __ xorptr(rsi, rax); 228 __ cmp32(rcx, Address(rsi, 0)); 229 // ca1 is the same as ca because 230 // rax, ^ rdx ^ counter_addr ^ rax, ^ rdx = address 231 // ca1 is data dependent on both rax, and rdx. 232 } else { 233 __ cmp32(rcx, counter); 234 } 235 __ jcc (Assembler::notEqual, slow); 236 237 __ pop (rsi); 238 239 #ifndef _WINDOWS 240 __ ret (0); 241 #else 242 // __stdcall calling convention 243 __ ret (3*wordSize); 244 #endif 245 246 slowcase_entry_pclist[count-1] = __ pc(); 247 slowcase_entry_pclist[count++] = __ pc(); 248 __ bind (slow); 249 __ pop (rsi); 250 address slow_case_addr = jni_GetLongField_addr();; 251 // tail call 252 __ jump (ExternalAddress(slow_case_addr)); 253 254 __ flush (); 270 } 271 ResourceMark rm; 272 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize); 273 CodeBuffer cbuf(blob); 274 MacroAssembler* masm = new MacroAssembler(&cbuf); 275 address fast_entry = __ pc(); 276 277 Label slow_with_pop, slow; 278 279 // stack layout: offset from rsp (in words): 280 // return pc 0 281 // jni env 1 282 // obj 2 283 // jfieldID 3 284 285 ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr()); 286 287 __ mov32 (rcx, counter); 288 __ testb (rcx, 1); 289 __ jcc (Assembler::notZero, slow); 290 if (os::is_MP()) { 291 __ mov(rax, rcx); 292 __ andptr(rax, 1); // rax, must end up 0 293 __ movptr(rdx, Address(rsp, rax, Address::times_1, 2*wordSize)); 294 // obj, notice rax, is 0. 295 // rdx is data dependent on rcx. 296 } else { 297 __ movptr(rdx, Address(rsp, 2*wordSize)); // obj 298 } 299 __ movptr(rax, Address(rsp, 3*wordSize)); // jfieldID 300 301 __ clear_jweak_tag(rdx); 302 303 __ movptr(rdx, Address(rdx, 0)); // *obj 304 __ shrptr(rax, 2); // offset 305 306 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); 307 speculative_load_pclist[count] = __ pc(); 308 switch (type) { 309 #ifndef _LP64 310 case T_FLOAT: __ fld_s (Address(rdx, rax, Address::times_1)); break; 311 case T_DOUBLE: __ fld_d (Address(rdx, rax, Address::times_1)); break; 312 #else 313 case T_FLOAT: __ movflt (xmm0, Address(robj, roffset, Address::times_1)); break; 314 case T_DOUBLE: __ movdbl (xmm0, Address(robj, roffset, Address::times_1)); break; 315 #endif // _LP64 316 default: ShouldNotReachHere(); 317 } 318 319 Address ca1; 320 if (os::is_MP()) { 321 __ fst_s (Address(rsp, -4)); 322 __ lea(rdx, counter); 323 __ movl (rax, Address(rsp, -4)); 324 // garbage hi-order bits on 64bit are harmless. 325 __ xorptr(rdx, rax); 326 __ xorptr(rdx, rax); 327 __ cmp32(rcx, Address(rdx, 0)); 328 // rax, ^ counter_addr ^ rax, = address 329 // ca1 is data dependent on the field 330 // access. 331 } else { 332 __ cmp32(rcx, counter); 333 } 334 __ jcc (Assembler::notEqual, slow_with_pop); 335 336 #ifndef _WINDOWS 337 __ ret (0); 338 #else 339 // __stdcall calling convention 340 __ ret (3*wordSize); 341 #endif 342 343 __ bind (slow_with_pop); 344 // invalid load. pop FPU stack. 345 __ fstp_d (0); 346 347 slowcase_entry_pclist[count++] = __ pc(); 348 __ bind (slow); 349 address slow_case_addr = NULL; 350 switch (type) { 351 case T_FLOAT: slow_case_addr = jni_GetFloatField_addr(); break; 352 case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); break; 353 default: ShouldNotReachHere(); | 58 default: ShouldNotReachHere(); 59 } 60 ResourceMark rm; 61 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize); 62 CodeBuffer cbuf(blob); 63 MacroAssembler* masm = new MacroAssembler(&cbuf); 64 address fast_entry = __ pc(); 65 66 Label slow; 67 68 // stack layout: offset from rsp (in words): 69 // return pc 0 70 // jni env 1 71 // obj 2 72 // jfieldID 3 73 74 ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr()); 75 __ mov32 (rcx, counter); 76 __ testb (rcx, 1); 77 __ jcc (Assembler::notZero, slow); 78 __ mov(rax, rcx); 79 __ andptr(rax, 1); // rax, must end up 0 80 __ movptr(rdx, Address(rsp, rax, Address::times_1, 2*wordSize)); 81 // obj, notice rax, is 0. 82 // rdx is data dependent on rcx. 83 __ movptr(rax, Address(rsp, 3*wordSize)); // jfieldID 84 85 __ clear_jweak_tag(rdx); 86 87 __ movptr(rdx, Address(rdx, 0)); // *obj 88 __ shrptr (rax, 2); // offset 89 90 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); 91 speculative_load_pclist[count] = __ pc(); 92 switch (type) { 93 case T_BOOLEAN: __ movzbl (rax, Address(rdx, rax, Address::times_1)); break; 94 case T_BYTE: __ movsbl (rax, Address(rdx, rax, Address::times_1)); break; 95 case T_CHAR: __ movzwl (rax, Address(rdx, rax, Address::times_1)); break; 96 case T_SHORT: __ movswl (rax, Address(rdx, rax, Address::times_1)); break; 97 case T_INT: __ movl (rax, Address(rdx, rax, Address::times_1)); break; 98 default: ShouldNotReachHere(); 99 } 100 101 Address ca1; 102 __ lea(rdx, counter); 103 __ xorptr(rdx, rax); 104 __ xorptr(rdx, rax); 105 __ cmp32(rcx, Address(rdx, 0)); 106 // ca1 is the same as ca because 107 // rax, ^ counter_addr ^ rax, = address 108 // ca1 is data dependent on rax,. 109 __ jcc (Assembler::notEqual, slow); 110 111 #ifndef _WINDOWS 112 __ ret (0); 113 #else 114 // __stdcall calling convention 115 __ ret (3*wordSize); 116 #endif 117 118 slowcase_entry_pclist[count++] = __ pc(); 119 __ bind (slow); 120 address slow_case_addr = NULL; 121 switch (type) { 122 case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break; 123 case T_BYTE: slow_case_addr = jni_GetByteField_addr(); break; 124 case T_CHAR: slow_case_addr = jni_GetCharField_addr(); break; 125 case T_SHORT: slow_case_addr = jni_GetShortField_addr(); break; 126 case T_INT: slow_case_addr = jni_GetIntField_addr(); 127 } 128 // tail call 170 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize); 171 CodeBuffer cbuf(blob); 172 MacroAssembler* masm = new MacroAssembler(&cbuf); 173 address fast_entry = __ pc(); 174 175 Label slow; 176 177 // stack layout: offset from rsp (in words): 178 // old rsi 0 179 // return pc 1 180 // jni env 2 181 // obj 3 182 // jfieldID 4 183 184 ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr()); 185 186 __ push (rsi); 187 __ mov32 (rcx, counter); 188 __ testb (rcx, 1); 189 __ jcc (Assembler::notZero, slow); 190 __ mov(rax, rcx); 191 __ andptr(rax, 1); // rax, must end up 0 192 __ movptr(rdx, Address(rsp, rax, Address::times_1, 3*wordSize)); 193 // obj, notice rax, is 0. 194 // rdx is data dependent on rcx. 195 __ movptr(rsi, Address(rsp, 4*wordSize)); // jfieldID 196 197 __ clear_jweak_tag(rdx); 198 199 __ movptr(rdx, Address(rdx, 0)); // *obj 200 __ shrptr(rsi, 2); // offset 201 202 assert(count < LIST_CAPACITY-1, "LIST_CAPACITY too small"); 203 speculative_load_pclist[count++] = __ pc(); 204 __ movptr(rax, Address(rdx, rsi, Address::times_1)); 205 #ifndef _LP64 206 speculative_load_pclist[count] = __ pc(); 207 __ movl(rdx, Address(rdx, rsi, Address::times_1, 4)); 208 #endif // _LP64 209 210 __ lea(rsi, counter); 211 __ xorptr(rsi, rdx); 212 __ xorptr(rsi, rax); 213 __ xorptr(rsi, rdx); 214 __ xorptr(rsi, rax); 215 __ cmp32(rcx, Address(rsi, 0)); 216 // ca1 is the same as ca because 217 // rax, ^ rdx ^ counter_addr ^ rax, ^ rdx = address 218 // ca1 is data dependent on both rax, and rdx. 219 __ jcc (Assembler::notEqual, slow); 220 221 __ pop (rsi); 222 223 #ifndef _WINDOWS 224 __ ret (0); 225 #else 226 // __stdcall calling convention 227 __ ret (3*wordSize); 228 #endif 229 230 slowcase_entry_pclist[count-1] = __ pc(); 231 slowcase_entry_pclist[count++] = __ pc(); 232 __ bind (slow); 233 __ pop (rsi); 234 address slow_case_addr = jni_GetLongField_addr();; 235 // tail call 236 __ jump (ExternalAddress(slow_case_addr)); 237 238 __ flush (); 254 } 255 ResourceMark rm; 256 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize); 257 CodeBuffer cbuf(blob); 258 MacroAssembler* masm = new MacroAssembler(&cbuf); 259 address fast_entry = __ pc(); 260 261 Label slow_with_pop, slow; 262 263 // stack layout: offset from rsp (in words): 264 // return pc 0 265 // jni env 1 266 // obj 2 267 // jfieldID 3 268 269 ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr()); 270 271 __ mov32 (rcx, counter); 272 __ testb (rcx, 1); 273 __ jcc (Assembler::notZero, slow); 274 __ mov(rax, rcx); 275 __ andptr(rax, 1); // rax, must end up 0 276 __ movptr(rdx, Address(rsp, rax, Address::times_1, 2*wordSize)); 277 // obj, notice rax, is 0. 278 // rdx is data dependent on rcx. 279 __ movptr(rax, Address(rsp, 3*wordSize)); // jfieldID 280 281 __ clear_jweak_tag(rdx); 282 283 __ movptr(rdx, Address(rdx, 0)); // *obj 284 __ shrptr(rax, 2); // offset 285 286 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); 287 speculative_load_pclist[count] = __ pc(); 288 switch (type) { 289 #ifndef _LP64 290 case T_FLOAT: __ fld_s (Address(rdx, rax, Address::times_1)); break; 291 case T_DOUBLE: __ fld_d (Address(rdx, rax, Address::times_1)); break; 292 #else 293 case T_FLOAT: __ movflt (xmm0, Address(robj, roffset, Address::times_1)); break; 294 case T_DOUBLE: __ movdbl (xmm0, Address(robj, roffset, Address::times_1)); break; 295 #endif // _LP64 296 default: ShouldNotReachHere(); 297 } 298 299 Address ca1; 300 __ fst_s (Address(rsp, -4)); 301 __ lea(rdx, counter); 302 __ movl (rax, Address(rsp, -4)); 303 // garbage hi-order bits on 64bit are harmless. 304 __ xorptr(rdx, rax); 305 __ xorptr(rdx, rax); 306 __ cmp32(rcx, Address(rdx, 0)); 307 // rax, ^ counter_addr ^ rax, = address 308 // ca1 is data dependent on the field 309 // access. 310 __ jcc (Assembler::notEqual, slow_with_pop); 311 312 #ifndef _WINDOWS 313 __ ret (0); 314 #else 315 // __stdcall calling convention 316 __ ret (3*wordSize); 317 #endif 318 319 __ bind (slow_with_pop); 320 // invalid load. pop FPU stack. 321 __ fstp_d (0); 322 323 slowcase_entry_pclist[count++] = __ pc(); 324 __ bind (slow); 325 address slow_case_addr = NULL; 326 switch (type) { 327 case T_FLOAT: slow_case_addr = jni_GetFloatField_addr(); break; 328 case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); break; 329 default: ShouldNotReachHere(); |