< prev index next >

src/hotspot/cpu/sparc/sharedRuntime_sparc.cpp

Print this page




2354   default:
2355     ShouldNotReachHere();
2356   }
2357 
2358   Label after_transition;
2359   // must we block?
2360 
2361   // Block, if necessary, before resuming in _thread_in_Java state.
2362   // In order for GC to work, don't clear the last_Java_sp until after blocking.
2363   { Label no_block;
2364 
2365     // Switch thread to "native transition" state before reading the synchronization state.
2366     // This additional state is necessary because reading and testing the synchronization
2367     // state is not atomic w.r.t. GC, as this scenario demonstrates:
2368     //     Java thread A, in _thread_in_native state, loads _not_synchronized and is preempted.
2369     //     VM thread changes sync state to synchronizing and suspends threads for GC.
2370     //     Thread A is resumed to finish this native method, but doesn't block here since it
2371     //     didn't see any synchronization is progress, and escapes.
2372     __ set(_thread_in_native_trans, G3_scratch);
2373     __ st(G3_scratch, G2_thread, JavaThread::thread_state_offset());
2374     if(os::is_MP()) {
2375       if (UseMembar) {
2376         // Force this write out before the read below
2377         __ membar(Assembler::StoreLoad);
2378       } else {
2379         // Write serialization page so VM thread can do a pseudo remote membar.
2380         // We use the current thread pointer to calculate a thread specific
2381         // offset to write to within the page. This minimizes bus traffic
2382         // due to cache line collision.
2383         __ serialize_memory(G2_thread, G1_scratch, G3_scratch);
2384       }
2385     }
2386 
2387     Label L;
2388     Address suspend_state(G2_thread, JavaThread::suspend_flags_offset());
2389     __ safepoint_poll(L, false, G2_thread, G3_scratch);
2390     __ delayed()->ld(suspend_state, G3_scratch);
2391     __ cmp_and_br_short(G3_scratch, 0, Assembler::equal, Assembler::pt, no_block);
2392     __ bind(L);
2393 
2394     // Block.  Save any potential method result value before the operation and
2395     // use a leaf call to leave the last_Java_frame setup undisturbed. Doing this
2396     // lets us share the oopMap we used when we went native rather the create
2397     // a distinct one for this pc
2398     //
2399     save_native_result(masm, ret_type, stack_slots);
2400     if (!is_critical_native) {
2401       __ call_VM_leaf(L7_thread_cache,
2402                       CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans),
2403                       G2_thread);
2404     } else {




2354   default:
2355     ShouldNotReachHere();
2356   }
2357 
2358   Label after_transition;
2359   // must we block?
2360 
2361   // Block, if necessary, before resuming in _thread_in_Java state.
2362   // In order for GC to work, don't clear the last_Java_sp until after blocking.
2363   { Label no_block;
2364 
2365     // Switch thread to "native transition" state before reading the synchronization state.
2366     // This additional state is necessary because reading and testing the synchronization
2367     // state is not atomic w.r.t. GC, as this scenario demonstrates:
2368     //     Java thread A, in _thread_in_native state, loads _not_synchronized and is preempted.
2369     //     VM thread changes sync state to synchronizing and suspends threads for GC.
2370     //     Thread A is resumed to finish this native method, but doesn't block here since it
2371     //     didn't see any synchronization is progress, and escapes.
2372     __ set(_thread_in_native_trans, G3_scratch);
2373     __ st(G3_scratch, G2_thread, JavaThread::thread_state_offset());
2374 
2375     if (UseMembar) {
2376       // Force this write out before the read below
2377       __ membar(Assembler::StoreLoad);
2378     } else {
2379       // Write serialization page so VM thread can do a pseudo remote membar.
2380       // We use the current thread pointer to calculate a thread specific
2381       // offset to write to within the page. This minimizes bus traffic
2382       // due to cache line collision.
2383       __ serialize_memory(G2_thread, G1_scratch, G3_scratch);

2384     }
2385 
2386     Label L;
2387     Address suspend_state(G2_thread, JavaThread::suspend_flags_offset());
2388     __ safepoint_poll(L, false, G2_thread, G3_scratch);
2389     __ delayed()->ld(suspend_state, G3_scratch);
2390     __ cmp_and_br_short(G3_scratch, 0, Assembler::equal, Assembler::pt, no_block);
2391     __ bind(L);
2392 
2393     // Block.  Save any potential method result value before the operation and
2394     // use a leaf call to leave the last_Java_frame setup undisturbed. Doing this
2395     // lets us share the oopMap we used when we went native rather the create
2396     // a distinct one for this pc
2397     //
2398     save_native_result(masm, ret_type, stack_slots);
2399     if (!is_critical_native) {
2400       __ call_VM_leaf(L7_thread_cache,
2401                       CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans),
2402                       G2_thread);
2403     } else {


< prev index next >