1 /*
   2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2018, SAP SE. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  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 "gc/shared/barrierSetAssembler.hpp"
  29 #include "interpreter/interp_masm.hpp"
  30 #include "oops/compressedOops.hpp"
  31 
  32 #define __ masm->
  33 
  34 void BarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
  35                                              Register dst, Register count, bool do_return) {
  36   if (do_return) { __ z_br(Z_R14); }
  37 }
  38 
  39 void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
  40                                   const Address& addr, Register dst, Register tmp1, Register tmp2, Label *L_handle_null) {
  41   bool in_heap = (decorators & IN_HEAP) != 0;
  42   bool in_native = (decorators & IN_NATIVE) != 0;
  43   bool not_null = (decorators & IS_NOT_NULL) != 0;
  44   assert(in_heap || in_native, "where?");
  45 
  46   switch (type) {
  47   case T_ARRAY:
  48   case T_OBJECT: {
  49     if (UseCompressedOops && in_heap) {
  50       __ z_llgf(dst, addr);
  51       if (L_handle_null != NULL) { // Label provided.
  52         __ compareU32_and_branch(dst, (intptr_t)0, Assembler::bcondEqual, *L_handle_null);
  53         __ oop_decoder(dst, dst, false);
  54       } else {
  55         __ oop_decoder(dst, dst, !not_null);
  56       }
  57     } else {
  58       __ z_lg(dst, addr);
  59       if (L_handle_null != NULL) {
  60         __ compareU64_and_branch(dst, (intptr_t)0, Assembler::bcondEqual, *L_handle_null);
  61       }
  62     }
  63     break;
  64   }
  65   default: Unimplemented();
  66   }
  67 }
  68 
  69 void BarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
  70                                    const Address& addr, Register val, Register tmp1, Register tmp2, Register tmp3) {
  71   bool in_heap = (decorators & IN_HEAP) != 0;
  72   bool in_native = (decorators & IN_NATIVE) != 0;
  73   bool not_null = (decorators & IS_NOT_NULL) != 0;
  74   assert(in_heap || in_native, "where?");
  75   assert_different_registers(val, tmp1, tmp2);
  76 
  77   switch (type) {
  78   case T_ARRAY:
  79   case T_OBJECT: {
  80     if (UseCompressedOops && in_heap) {
  81       if (val == noreg) {
  82         __ clear_mem(addr, 4);
  83       } else if (CompressedOops::mode() == CompressedOops::UnscaledNarrowOop) {
  84         __ z_st(val, addr);
  85       } else {
  86         Register tmp = (tmp1 != Z_R1) ? tmp1 : tmp2; // Avoid tmp == Z_R1 (see oop_encoder).
  87         __ oop_encoder(tmp, val, !not_null);
  88         __ z_st(tmp, addr);
  89       }
  90     } else {
  91       if (val == noreg) {
  92         __ clear_mem(addr, 8);
  93       } else {
  94         __ z_stg(val, addr);
  95       }
  96     }
  97     break;
  98   }
  99   default: Unimplemented();
 100   }
 101 }
 102 
 103 void BarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Register value, Register tmp1, Register tmp2) {
 104   NearLabel Ldone;
 105   __ z_ltgr(tmp1, value);
 106   __ z_bre(Ldone);          // Use NULL result as-is.
 107 
 108   __ z_nill(value, ~JNIHandles::weak_tag_mask);
 109   __ z_lg(value, 0, value); // Resolve (untagged) jobject.
 110 
 111   __ verify_oop(value);
 112   __ bind(Ldone);
 113 }
 114 
 115 void BarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
 116                                                         Register obj, Register tmp, Label& slowpath) {
 117   __ z_nill(obj, ~JNIHandles::weak_tag_mask);
 118   __ z_lg(obj, 0, obj); // Resolve (untagged) jobject.
 119 }