77 __ adrp(rcounter_addr, |
77 __ adrp(rcounter_addr, |
78 SafepointSynchronize::safepoint_counter_addr(), offset); |
78 SafepointSynchronize::safepoint_counter_addr(), offset); |
79 Address safepoint_counter_addr(rcounter_addr, offset); |
79 Address safepoint_counter_addr(rcounter_addr, offset); |
80 __ ldrw(rcounter, safepoint_counter_addr); |
80 __ ldrw(rcounter, safepoint_counter_addr); |
81 __ tbnz(rcounter, 0, slow); |
81 __ tbnz(rcounter, 0, slow); |
82 __ eor(robj, c_rarg1, rcounter); |
82 |
83 __ eor(robj, robj, rcounter); // obj, since |
83 if (!UseBarriersForVolatile) { |
84 // robj ^ rcounter ^ rcounter == robj |
84 // Field may be volatile. See other usages of this flag. |
85 // robj is address dependent on rcounter. |
85 __ membar(MacroAssembler::AnyAny); |
86 |
86 __ mov(robj, c_rarg1); |
|
87 } else if (JvmtiExport::can_post_field_access()) { |
|
88 // Using barrier to order wrt. JVMTI check and load of result. |
|
89 __ membar(Assembler::LoadLoad); |
|
90 __ mov(robj, c_rarg1); |
|
91 } else { |
|
92 // Using address dependency to order wrt. load of result. |
|
93 __ eor(robj, c_rarg1, rcounter); |
|
94 __ eor(robj, robj, rcounter); // obj, since |
|
95 // robj ^ rcounter ^ rcounter == robj |
|
96 // robj is address dependent on rcounter. |
|
97 } |
|
98 |
|
99 if (JvmtiExport::can_post_field_access()) { |
|
100 // Check to see if a field access watch has been set before we |
|
101 // take the fast path. |
|
102 unsigned long offset2; |
|
103 __ adrp(result, |
|
104 ExternalAddress((address) JvmtiExport::get_field_access_count_addr()), |
|
105 offset2); |
|
106 __ ldrw(result, Address(result, offset2)); |
|
107 __ cbnzw(result, slow); |
|
108 } |
|
109 |
|
110 // Both robj and rscratch1 are clobbered by try_resolve_jobject_in_native. |
87 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); |
111 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); |
88 bs->try_resolve_jobject_in_native(masm, c_rarg0, robj, rscratch1, slow); |
112 bs->try_resolve_jobject_in_native(masm, c_rarg0, robj, rscratch1, slow); |
89 |
113 |
90 __ lsr(roffset, c_rarg2, 2); // offset |
114 __ lsr(roffset, c_rarg2, 2); // offset |
|
115 __ add(result, robj, roffset); |
91 |
116 |
92 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); |
117 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); |
93 speculative_load_pclist[count] = __ pc(); // Used by the segfault handler |
118 speculative_load_pclist[count] = __ pc(); // Used by the segfault handler |
94 switch (type) { |
119 // Using acquire: Order JVMTI check and load of result wrt. succeeding check |
95 case T_BOOLEAN: __ ldrb (result, Address(robj, roffset)); break; |
120 // (LoadStore for volatile field). |
96 case T_BYTE: __ ldrsb (result, Address(robj, roffset)); break; |
121 switch (type) { |
97 case T_CHAR: __ ldrh (result, Address(robj, roffset)); break; |
122 case T_BOOLEAN: __ ldarb(result, result); break; |
98 case T_SHORT: __ ldrsh (result, Address(robj, roffset)); break; |
123 case T_BYTE: __ ldarb(result, result); __ sxtb(result, result); break; |
99 case T_FLOAT: __ ldrw (result, Address(robj, roffset)); break; |
124 case T_CHAR: __ ldarh(result, result); break; |
100 case T_INT: __ ldrsw (result, Address(robj, roffset)); break; |
125 case T_SHORT: __ ldarh(result, result); __ sxth(result, result); break; |
|
126 case T_FLOAT: __ ldarw(result, result); break; |
|
127 case T_INT: __ ldarw(result, result); __ sxtw(result, result); break; |
101 case T_DOUBLE: |
128 case T_DOUBLE: |
102 case T_LONG: __ ldr (result, Address(robj, roffset)); break; |
129 case T_LONG: __ ldar (result, result); break; |
103 default: ShouldNotReachHere(); |
130 default: ShouldNotReachHere(); |
104 } |
131 } |
105 |
132 |
106 // counter_addr is address dependent on result. |
|
107 __ eor(rcounter_addr, rcounter_addr, result); |
|
108 __ eor(rcounter_addr, rcounter_addr, result); |
|
109 __ ldrw(rscratch1, safepoint_counter_addr); |
133 __ ldrw(rscratch1, safepoint_counter_addr); |
110 __ cmpw(rcounter, rscratch1); |
134 __ cmpw(rcounter, rscratch1); |
111 __ br (Assembler::NE, slow); |
135 __ br (Assembler::NE, slow); |
112 |
136 |
113 switch (type) { |
137 switch (type) { |