14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26 #include "precompiled.hpp"
27 #include "asm/macroAssembler.inline.hpp"
28 #include "registerSaver_s390.hpp"
29 #include "gc/g1/g1CardTable.hpp"
30 #include "gc/g1/g1BarrierSet.hpp"
31 #include "gc/g1/g1BarrierSetAssembler.hpp"
32 #include "gc/g1/g1ThreadLocalData.hpp"
33 #include "gc/g1/heapRegion.hpp"
34 #include "gc/shared/collectedHeap.hpp"
35 #include "interpreter/interp_masm.hpp"
36
37 #define __ masm->
38
39 #define BLOCK_COMMENT(str) if (PrintAssembly) __ block_comment(str)
40
41 void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
42 Register addr, Register count) {
43 bool dest_uninitialized = (decorators & AS_DEST_NOT_INITIALIZED) != 0;
44
45 // With G1, don't generate the call if we statically know that the target is uninitialized.
46 if (!dest_uninitialized) {
47 // Is marking active?
48 Label filtered;
49 assert_different_registers(addr, Z_R0_scratch); // would be destroyed by push_frame()
50 assert_different_registers(count, Z_R0_scratch); // would be destroyed by push_frame()
51 Register Rtmp1 = Z_R0_scratch;
52 const int active_offset = in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset());
53 if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
54 __ load_and_test_int(Rtmp1, Address(Z_thread, active_offset));
243 }
244 if (Rval != noreg && Rval->is_volatile()) {
245 __ z_lg(Rval, Rval->encoding()*BytesPerWord, Z_SP);
246 }
247 if (pre_val_needed && Rpre_val->is_volatile()) {
248 __ lgr_if_needed(Rpre_val, Rpre_save);
249 }
250
251 __ bind(filtered);
252 BLOCK_COMMENT("} g1_write_barrier_pre");
253 }
254
255 void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm, DecoratorSet decorators, Register Rstore_addr, Register Rnew_val,
256 Register Rtmp1, Register Rtmp2, Register Rtmp3) {
257 bool not_null = (decorators & OOP_NOT_NULL) != 0;
258
259 assert_different_registers(Rstore_addr, Rnew_val, Rtmp1, Rtmp2); // Most probably, Rnew_val == Rtmp3.
260
261 Label callRuntime, filtered;
262
263 CardTableBarrierSet* ct = barrier_set_cast<CardTableBarrierSet>(Universe::heap()->barrier_set());
264 assert(sizeof(*ct->card_table()->byte_map_base()) == sizeof(jbyte), "adjust this code");
265
266 BLOCK_COMMENT("g1_write_barrier_post {");
267
268 // Does store cross heap regions?
269 // It does if the two addresses specify different grain addresses.
270 if (G1RSBarrierRegionFilter) {
271 if (VM_Version::has_DistinctOpnds()) {
272 __ z_xgrk(Rtmp1, Rstore_addr, Rnew_val);
273 } else {
274 __ z_lgr(Rtmp1, Rstore_addr);
275 __ z_xgr(Rtmp1, Rnew_val);
276 }
277 __ z_srag(Rtmp1, Rtmp1, HeapRegion::LogOfHRGrainBytes);
278 __ z_bre(filtered);
279 }
280
281 // Crosses regions, storing NULL?
282 if (not_null) {
283 #ifdef ASSERT
|
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26 #include "precompiled.hpp"
27 #include "asm/macroAssembler.inline.hpp"
28 #include "registerSaver_s390.hpp"
29 #include "gc/g1/g1CardTable.hpp"
30 #include "gc/g1/g1BarrierSet.hpp"
31 #include "gc/g1/g1BarrierSetAssembler.hpp"
32 #include "gc/g1/g1ThreadLocalData.hpp"
33 #include "gc/g1/heapRegion.hpp"
34 #include "interpreter/interp_masm.hpp"
35
36 #define __ masm->
37
38 #define BLOCK_COMMENT(str) if (PrintAssembly) __ block_comment(str)
39
40 void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
41 Register addr, Register count) {
42 bool dest_uninitialized = (decorators & AS_DEST_NOT_INITIALIZED) != 0;
43
44 // With G1, don't generate the call if we statically know that the target is uninitialized.
45 if (!dest_uninitialized) {
46 // Is marking active?
47 Label filtered;
48 assert_different_registers(addr, Z_R0_scratch); // would be destroyed by push_frame()
49 assert_different_registers(count, Z_R0_scratch); // would be destroyed by push_frame()
50 Register Rtmp1 = Z_R0_scratch;
51 const int active_offset = in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset());
52 if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
53 __ load_and_test_int(Rtmp1, Address(Z_thread, active_offset));
242 }
243 if (Rval != noreg && Rval->is_volatile()) {
244 __ z_lg(Rval, Rval->encoding()*BytesPerWord, Z_SP);
245 }
246 if (pre_val_needed && Rpre_val->is_volatile()) {
247 __ lgr_if_needed(Rpre_val, Rpre_save);
248 }
249
250 __ bind(filtered);
251 BLOCK_COMMENT("} g1_write_barrier_pre");
252 }
253
254 void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm, DecoratorSet decorators, Register Rstore_addr, Register Rnew_val,
255 Register Rtmp1, Register Rtmp2, Register Rtmp3) {
256 bool not_null = (decorators & OOP_NOT_NULL) != 0;
257
258 assert_different_registers(Rstore_addr, Rnew_val, Rtmp1, Rtmp2); // Most probably, Rnew_val == Rtmp3.
259
260 Label callRuntime, filtered;
261
262 CardTableBarrierSet* ct = barrier_set_cast<CardTableBarrierSet>(BarrierSet::barrier_set());
263 assert(sizeof(*ct->card_table()->byte_map_base()) == sizeof(jbyte), "adjust this code");
264
265 BLOCK_COMMENT("g1_write_barrier_post {");
266
267 // Does store cross heap regions?
268 // It does if the two addresses specify different grain addresses.
269 if (G1RSBarrierRegionFilter) {
270 if (VM_Version::has_DistinctOpnds()) {
271 __ z_xgrk(Rtmp1, Rstore_addr, Rnew_val);
272 } else {
273 __ z_lgr(Rtmp1, Rstore_addr);
274 __ z_xgr(Rtmp1, Rnew_val);
275 }
276 __ z_srag(Rtmp1, Rtmp1, HeapRegion::LogOfHRGrainBytes);
277 __ z_bre(filtered);
278 }
279
280 // Crosses regions, storing NULL?
281 if (not_null) {
282 #ifdef ASSERT
|