31
32 #define __ masm->
33
34 #define BUFFER_SIZE 30
35
36 #ifdef _WINDOWS
37 GetBooleanField_t JNI_FastGetField::jni_fast_GetBooleanField_fp;
38 GetByteField_t JNI_FastGetField::jni_fast_GetByteField_fp;
39 GetCharField_t JNI_FastGetField::jni_fast_GetCharField_fp;
40 GetShortField_t JNI_FastGetField::jni_fast_GetShortField_fp;
41 GetIntField_t JNI_FastGetField::jni_fast_GetIntField_fp;
42 GetLongField_t JNI_FastGetField::jni_fast_GetLongField_fp;
43 GetFloatField_t JNI_FastGetField::jni_fast_GetFloatField_fp;
44 GetDoubleField_t JNI_FastGetField::jni_fast_GetDoubleField_fp;
45 #endif
46
47 // Instead of issuing lfence for LoadLoad barrier, we create data dependency
48 // between loads, which is much more efficient than lfence.
49
50 address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
51 const char *name;
52 switch (type) {
53 case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break;
54 case T_BYTE: name = "jni_fast_GetByteField"; break;
55 case T_CHAR: name = "jni_fast_GetCharField"; break;
56 case T_SHORT: name = "jni_fast_GetShortField"; break;
57 case T_INT: name = "jni_fast_GetIntField"; break;
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
105 __ xorptr(rdx, rax);
106 __ xorptr(rdx, rax);
107 __ cmp32(rcx, Address(rdx, 0));
108 // ca1 is the same as ca because
109 // rax, ^ counter_addr ^ rax, = address
110 // ca1 is data dependent on rax,.
111 } else {
112 __ cmp32(rcx, counter);
113 }
114 __ jcc (Assembler::notEqual, slow);
115
116 #ifndef _WINDOWS
117 __ ret (0);
118 #else
119 // __stdcall calling convention
120 __ ret (3*wordSize);
121 #endif
122
123 slowcase_entry_pclist[count++] = __ pc();
124 __ bind (slow);
125 address slow_case_addr;
126 switch (type) {
127 case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break;
128 case T_BYTE: slow_case_addr = jni_GetByteField_addr(); break;
129 case T_CHAR: slow_case_addr = jni_GetCharField_addr(); break;
130 case T_SHORT: slow_case_addr = jni_GetShortField_addr(); break;
131 case T_INT: slow_case_addr = jni_GetIntField_addr();
132 }
133 // tail call
134 __ jump (ExternalAddress(slow_case_addr));
135
136 __ flush ();
137
138 #ifndef _WINDOWS
139 return fast_entry;
140 #else
141 switch (type) {
142 case T_BOOLEAN: jni_fast_GetBooleanField_fp = (GetBooleanField_t) fast_entry; break;
143 case T_BYTE: jni_fast_GetByteField_fp = (GetByteField_t) fast_entry; break;
144 case T_CHAR: jni_fast_GetCharField_fp = (GetCharField_t) fast_entry; break;
145 case T_SHORT: jni_fast_GetShortField_fp = (GetShortField_t) fast_entry; break;
239
240 slowcase_entry_pclist[count-1] = __ pc();
241 slowcase_entry_pclist[count++] = __ pc();
242 __ bind (slow);
243 __ pop (rsi);
244 address slow_case_addr = jni_GetLongField_addr();;
245 // tail call
246 __ jump (ExternalAddress(slow_case_addr));
247
248 __ flush ();
249
250 #ifndef _WINDOWS
251 return fast_entry;
252 #else
253 jni_fast_GetLongField_fp = (GetLongField_t) fast_entry;
254 return os::win32::fast_jni_accessor_wrapper(T_LONG);
255 #endif
256 }
257
258 address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) {
259 const char *name;
260 switch (type) {
261 case T_FLOAT: name = "jni_fast_GetFloatField"; break;
262 case T_DOUBLE: name = "jni_fast_GetDoubleField"; break;
263 default: ShouldNotReachHere();
264 }
265 ResourceMark rm;
266 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize);
267 CodeBuffer cbuf(blob);
268 MacroAssembler* masm = new MacroAssembler(&cbuf);
269 address fast_entry = __ pc();
270
271 Label slow_with_pop, slow;
272
273 // stack layout: offset from rsp (in words):
274 // return pc 0
275 // jni env 1
276 // obj 2
277 // jfieldID 3
278
279 ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr());
320 // ca1 is data dependent on the field
321 // access.
322 } else {
323 __ cmp32(rcx, counter);
324 }
325 __ jcc (Assembler::notEqual, slow_with_pop);
326
327 #ifndef _WINDOWS
328 __ ret (0);
329 #else
330 // __stdcall calling convention
331 __ ret (3*wordSize);
332 #endif
333
334 __ bind (slow_with_pop);
335 // invalid load. pop FPU stack.
336 __ fstp_d (0);
337
338 slowcase_entry_pclist[count++] = __ pc();
339 __ bind (slow);
340 address slow_case_addr;
341 switch (type) {
342 case T_FLOAT: slow_case_addr = jni_GetFloatField_addr(); break;
343 case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); break;
344 default: ShouldNotReachHere();
345 }
346 // tail call
347 __ jump (ExternalAddress(slow_case_addr));
348
349 __ flush ();
350
351 #ifndef _WINDOWS
352 return fast_entry;
353 #else
354 switch (type) {
355 case T_FLOAT: jni_fast_GetFloatField_fp = (GetFloatField_t) fast_entry; break;
356 case T_DOUBLE: jni_fast_GetDoubleField_fp = (GetDoubleField_t) fast_entry; break;
357 }
358 return os::win32::fast_jni_accessor_wrapper(type);
359 #endif
360 }
|
31
32 #define __ masm->
33
34 #define BUFFER_SIZE 30
35
36 #ifdef _WINDOWS
37 GetBooleanField_t JNI_FastGetField::jni_fast_GetBooleanField_fp;
38 GetByteField_t JNI_FastGetField::jni_fast_GetByteField_fp;
39 GetCharField_t JNI_FastGetField::jni_fast_GetCharField_fp;
40 GetShortField_t JNI_FastGetField::jni_fast_GetShortField_fp;
41 GetIntField_t JNI_FastGetField::jni_fast_GetIntField_fp;
42 GetLongField_t JNI_FastGetField::jni_fast_GetLongField_fp;
43 GetFloatField_t JNI_FastGetField::jni_fast_GetFloatField_fp;
44 GetDoubleField_t JNI_FastGetField::jni_fast_GetDoubleField_fp;
45 #endif
46
47 // Instead of issuing lfence for LoadLoad barrier, we create data dependency
48 // between loads, which is much more efficient than lfence.
49
50 address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
51 const char *name = NULL;
52 switch (type) {
53 case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break;
54 case T_BYTE: name = "jni_fast_GetByteField"; break;
55 case T_CHAR: name = "jni_fast_GetCharField"; break;
56 case T_SHORT: name = "jni_fast_GetShortField"; break;
57 case T_INT: name = "jni_fast_GetIntField"; break;
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
105 __ xorptr(rdx, rax);
106 __ xorptr(rdx, rax);
107 __ cmp32(rcx, Address(rdx, 0));
108 // ca1 is the same as ca because
109 // rax, ^ counter_addr ^ rax, = address
110 // ca1 is data dependent on rax,.
111 } else {
112 __ cmp32(rcx, counter);
113 }
114 __ jcc (Assembler::notEqual, slow);
115
116 #ifndef _WINDOWS
117 __ ret (0);
118 #else
119 // __stdcall calling convention
120 __ ret (3*wordSize);
121 #endif
122
123 slowcase_entry_pclist[count++] = __ pc();
124 __ bind (slow);
125 address slow_case_addr = NULL;
126 switch (type) {
127 case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break;
128 case T_BYTE: slow_case_addr = jni_GetByteField_addr(); break;
129 case T_CHAR: slow_case_addr = jni_GetCharField_addr(); break;
130 case T_SHORT: slow_case_addr = jni_GetShortField_addr(); break;
131 case T_INT: slow_case_addr = jni_GetIntField_addr();
132 }
133 // tail call
134 __ jump (ExternalAddress(slow_case_addr));
135
136 __ flush ();
137
138 #ifndef _WINDOWS
139 return fast_entry;
140 #else
141 switch (type) {
142 case T_BOOLEAN: jni_fast_GetBooleanField_fp = (GetBooleanField_t) fast_entry; break;
143 case T_BYTE: jni_fast_GetByteField_fp = (GetByteField_t) fast_entry; break;
144 case T_CHAR: jni_fast_GetCharField_fp = (GetCharField_t) fast_entry; break;
145 case T_SHORT: jni_fast_GetShortField_fp = (GetShortField_t) fast_entry; break;
239
240 slowcase_entry_pclist[count-1] = __ pc();
241 slowcase_entry_pclist[count++] = __ pc();
242 __ bind (slow);
243 __ pop (rsi);
244 address slow_case_addr = jni_GetLongField_addr();;
245 // tail call
246 __ jump (ExternalAddress(slow_case_addr));
247
248 __ flush ();
249
250 #ifndef _WINDOWS
251 return fast_entry;
252 #else
253 jni_fast_GetLongField_fp = (GetLongField_t) fast_entry;
254 return os::win32::fast_jni_accessor_wrapper(T_LONG);
255 #endif
256 }
257
258 address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) {
259 const char *name = NULL;
260 switch (type) {
261 case T_FLOAT: name = "jni_fast_GetFloatField"; break;
262 case T_DOUBLE: name = "jni_fast_GetDoubleField"; break;
263 default: ShouldNotReachHere();
264 }
265 ResourceMark rm;
266 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize);
267 CodeBuffer cbuf(blob);
268 MacroAssembler* masm = new MacroAssembler(&cbuf);
269 address fast_entry = __ pc();
270
271 Label slow_with_pop, slow;
272
273 // stack layout: offset from rsp (in words):
274 // return pc 0
275 // jni env 1
276 // obj 2
277 // jfieldID 3
278
279 ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr());
320 // ca1 is data dependent on the field
321 // access.
322 } else {
323 __ cmp32(rcx, counter);
324 }
325 __ jcc (Assembler::notEqual, slow_with_pop);
326
327 #ifndef _WINDOWS
328 __ ret (0);
329 #else
330 // __stdcall calling convention
331 __ ret (3*wordSize);
332 #endif
333
334 __ bind (slow_with_pop);
335 // invalid load. pop FPU stack.
336 __ fstp_d (0);
337
338 slowcase_entry_pclist[count++] = __ pc();
339 __ bind (slow);
340 address slow_case_addr = NULL;
341 switch (type) {
342 case T_FLOAT: slow_case_addr = jni_GetFloatField_addr(); break;
343 case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); break;
344 default: ShouldNotReachHere();
345 }
346 // tail call
347 __ jump (ExternalAddress(slow_case_addr));
348
349 __ flush ();
350
351 #ifndef _WINDOWS
352 return fast_entry;
353 #else
354 switch (type) {
355 case T_FLOAT: jni_fast_GetFloatField_fp = (GetFloatField_t) fast_entry; break;
356 case T_DOUBLE: jni_fast_GetDoubleField_fp = (GetDoubleField_t) fast_entry; break;
357 }
358 return os::win32::fast_jni_accessor_wrapper(type);
359 #endif
360 }
|