src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp

Print this page
rev 7516 : 8069593: AARCH64: Changes to JavaThread::_thread_state must use acquire and release
Summary: Use release stores for all changes to thread state.
Reviewed-by: kvn


1080   __ add(c_rarg0, rthread, in_bytes(JavaThread::jni_environment_offset()));
1081 
1082   // It is enough that the pc() points into the right code
1083   // segment. It does not have to be the correct return pc.
1084   __ set_last_Java_frame(esp, rfp, (address)NULL, rscratch1);
1085 
1086   // change thread state
1087 #ifdef ASSERT
1088   {
1089     Label L;
1090     __ ldrw(t, Address(rthread, JavaThread::thread_state_offset()));
1091     __ cmp(t, _thread_in_Java);
1092     __ br(Assembler::EQ, L);
1093     __ stop("Wrong thread state in native stub");
1094     __ bind(L);
1095   }
1096 #endif
1097 
1098   // Change state to native
1099   __ mov(rscratch1, _thread_in_native);
1100   __ strw(rscratch1, Address(rthread, JavaThread::thread_state_offset()));

1101 
1102   // Call the native method.
1103   __ blrt(r10, rscratch1);
1104   __ maybe_isb();
1105   __ get_method(rmethod);
1106   // result potentially in r0 or v0
1107 
1108   // make room for the pushes we're about to do
1109   __ sub(rscratch1, esp, 4 * wordSize);
1110   __ andr(sp, rscratch1, -16);
1111 
1112   // NOTE: The order of these pushes is known to frame::interpreter_frame_result
1113   // in order to extract the result of a method call. If the order of these
1114   // pushes change or anything else is added to the stack then the code in
1115   // interpreter_frame_result must also change.
1116   __ push(dtos);
1117   __ push(ltos);
1118 
1119   // change thread state
1120   __ mov(rscratch1, _thread_in_native_trans);
1121   __ strw(rscratch1, Address(rthread, JavaThread::thread_state_offset()));

1122 
1123   if (os::is_MP()) {
1124     if (UseMembar) {
1125       // Force this write out before the read below
1126       __ dsb(Assembler::SY);
1127     } else {
1128       // Write serialization page so VM thread can do a pseudo remote membar.
1129       // We use the current thread pointer to calculate a thread specific
1130       // offset to write to within the page. This minimizes bus traffic
1131       // due to cache line collision.
1132       __ serialize_memory(rthread, rscratch2);
1133     }
1134   }
1135 
1136   // check for safepoint operation in progress and/or pending suspend requests
1137   {
1138     Label Continue;
1139     {
1140       unsigned long offset;
1141       __ adrp(rscratch2, SafepointSynchronize::address_of_state(), offset);


1148     __ ldrw(rscratch2, Address(rthread, JavaThread::suspend_flags_offset()));
1149     __ cbz(rscratch2, Continue);
1150     __ bind(L);
1151 
1152     // Don't use call_VM as it will see a possible pending exception
1153     // and forward it and never return here preventing us from
1154     // clearing _last_native_pc down below. So we do a runtime call by
1155     // hand.
1156     //
1157     __ mov(c_rarg0, rthread);
1158     __ mov(rscratch2, CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans));
1159     __ blrt(rscratch2, 1, 0, 0);
1160     __ maybe_isb();
1161     __ get_method(rmethod);
1162     __ reinit_heapbase();
1163     __ bind(Continue);
1164   }
1165 
1166   // change thread state
1167   __ mov(rscratch1, _thread_in_Java);
1168   __ strw(rscratch1, Address(rthread, JavaThread::thread_state_offset()));

1169 
1170   // reset_last_Java_frame
1171   __ reset_last_Java_frame(true, true);
1172 
1173   // reset handle block
1174   __ ldr(t, Address(rthread, JavaThread::active_handles_offset()));
1175   __ str(zr, Address(t, JNIHandleBlock::top_offset_in_bytes()));
1176 
1177   // If result is an oop unbox and store it in frame where gc will see it
1178   // and result handler will pick it up
1179 
1180   {
1181     Label no_oop, store_result;
1182     __ adr(t, ExternalAddress(AbstractInterpreter::result_handler(T_OBJECT)));
1183     __ cmp(t, result_handler);
1184     __ br(Assembler::NE, no_oop);
1185     // retrieve result
1186     __ pop(ltos);
1187     __ cbz(r0, store_result);
1188     __ ldr(r0, Address(r0, 0));




1080   __ add(c_rarg0, rthread, in_bytes(JavaThread::jni_environment_offset()));
1081 
1082   // It is enough that the pc() points into the right code
1083   // segment. It does not have to be the correct return pc.
1084   __ set_last_Java_frame(esp, rfp, (address)NULL, rscratch1);
1085 
1086   // change thread state
1087 #ifdef ASSERT
1088   {
1089     Label L;
1090     __ ldrw(t, Address(rthread, JavaThread::thread_state_offset()));
1091     __ cmp(t, _thread_in_Java);
1092     __ br(Assembler::EQ, L);
1093     __ stop("Wrong thread state in native stub");
1094     __ bind(L);
1095   }
1096 #endif
1097 
1098   // Change state to native
1099   __ mov(rscratch1, _thread_in_native);
1100   __ lea(rscratch2, Address(rthread, JavaThread::thread_state_offset()));
1101   __ stlrw(rscratch1, rscratch2);
1102 
1103   // Call the native method.
1104   __ blrt(r10, rscratch1);
1105   __ maybe_isb();
1106   __ get_method(rmethod);
1107   // result potentially in r0 or v0
1108 
1109   // make room for the pushes we're about to do
1110   __ sub(rscratch1, esp, 4 * wordSize);
1111   __ andr(sp, rscratch1, -16);
1112 
1113   // NOTE: The order of these pushes is known to frame::interpreter_frame_result
1114   // in order to extract the result of a method call. If the order of these
1115   // pushes change or anything else is added to the stack then the code in
1116   // interpreter_frame_result must also change.
1117   __ push(dtos);
1118   __ push(ltos);
1119 
1120   // change thread state
1121   __ mov(rscratch1, _thread_in_native_trans);
1122   __ lea(rscratch2, Address(rthread, JavaThread::thread_state_offset()));
1123   __ stlrw(rscratch1, rscratch2);
1124 
1125   if (os::is_MP()) {
1126     if (UseMembar) {
1127       // Force this write out before the read below
1128       __ dsb(Assembler::SY);
1129     } else {
1130       // Write serialization page so VM thread can do a pseudo remote membar.
1131       // We use the current thread pointer to calculate a thread specific
1132       // offset to write to within the page. This minimizes bus traffic
1133       // due to cache line collision.
1134       __ serialize_memory(rthread, rscratch2);
1135     }
1136   }
1137 
1138   // check for safepoint operation in progress and/or pending suspend requests
1139   {
1140     Label Continue;
1141     {
1142       unsigned long offset;
1143       __ adrp(rscratch2, SafepointSynchronize::address_of_state(), offset);


1150     __ ldrw(rscratch2, Address(rthread, JavaThread::suspend_flags_offset()));
1151     __ cbz(rscratch2, Continue);
1152     __ bind(L);
1153 
1154     // Don't use call_VM as it will see a possible pending exception
1155     // and forward it and never return here preventing us from
1156     // clearing _last_native_pc down below. So we do a runtime call by
1157     // hand.
1158     //
1159     __ mov(c_rarg0, rthread);
1160     __ mov(rscratch2, CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans));
1161     __ blrt(rscratch2, 1, 0, 0);
1162     __ maybe_isb();
1163     __ get_method(rmethod);
1164     __ reinit_heapbase();
1165     __ bind(Continue);
1166   }
1167 
1168   // change thread state
1169   __ mov(rscratch1, _thread_in_Java);
1170   __ lea(rscratch2, Address(rthread, JavaThread::thread_state_offset()));
1171   __ stlrw(rscratch1, rscratch2);
1172 
1173   // reset_last_Java_frame
1174   __ reset_last_Java_frame(true, true);
1175 
1176   // reset handle block
1177   __ ldr(t, Address(rthread, JavaThread::active_handles_offset()));
1178   __ str(zr, Address(t, JNIHandleBlock::top_offset_in_bytes()));
1179 
1180   // If result is an oop unbox and store it in frame where gc will see it
1181   // and result handler will pick it up
1182 
1183   {
1184     Label no_oop, store_result;
1185     __ adr(t, ExternalAddress(AbstractInterpreter::result_handler(T_OBJECT)));
1186     __ cmp(t, result_handler);
1187     __ br(Assembler::NE, no_oop);
1188     // retrieve result
1189     __ pop(ltos);
1190     __ cbz(r0, store_result);
1191     __ ldr(r0, Address(r0, 0));