1 /*
   2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "asm/macroAssembler.inline.hpp"
  27 #include "gc/shared/barrierSetAssembler.hpp"
  28 #include "interpreter/interp_masm.hpp"
  29 #include "runtime/jniHandles.hpp"
  30 
  31 #define __ masm->
  32 
  33 void BarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
  34                                    Register val, Address dst, Register tmp) {
  35   bool in_heap = (decorators & IN_HEAP) != 0;
  36   bool in_native = (decorators & IN_NATIVE) != 0;
  37   bool oop_not_null = (decorators & OOP_NOT_NULL) != 0;
  38 
  39   switch (type) {
  40   case T_ARRAY:
  41   case T_OBJECT: {
  42     if (in_heap) {
  43       if (dst.has_disp() && !Assembler::is_simm13(dst.disp())) {
  44         assert(!dst.has_index(), "not supported yet");
  45         __ set(dst.disp(), tmp);
  46         dst = Address(dst.base(), tmp);
  47       }
  48       if (UseCompressedOops) {
  49         assert(dst.base() != val, "not enough registers");
  50         if (oop_not_null) {
  51           __ encode_heap_oop_not_null(val);
  52         } else {
  53           __ encode_heap_oop(val);
  54         }
  55         __ st(val, dst);
  56       } else {
  57         __ st_ptr(val, dst);
  58       }
  59     } else {
  60       assert(in_native, "why else?");
  61       __ st_ptr(val, dst);
  62     }
  63     break;
  64   }
  65   default: Unimplemented();
  66   }
  67 }
  68 
  69 void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
  70                                   Address src, Register dst, Register tmp) {
  71   bool in_heap = (decorators & IN_HEAP) != 0;
  72   bool in_native = (decorators & IN_NATIVE) != 0;
  73   bool oop_not_null = (decorators & OOP_NOT_NULL) != 0;
  74 
  75   switch (type) {
  76   case T_ARRAY:
  77   case T_OBJECT: {
  78     if (in_heap) {
  79       if (src.has_disp() && !Assembler::is_simm13(src.disp())) {
  80         assert(!src.has_index(), "not supported yet");
  81         __ set(src.disp(), tmp);
  82         src = Address(src.base(), tmp);
  83       }
  84       if (UseCompressedOops) {
  85         __ lduw(src, dst);
  86         if (oop_not_null) {
  87           __ decode_heap_oop_not_null(dst);
  88         } else {
  89           __ decode_heap_oop(dst);
  90         }
  91       } else {
  92         __ ld_ptr(src, dst);
  93       }
  94     } else {
  95       assert(in_native, "why else?");
  96       __ ld_ptr(src, dst);
  97     }
  98     break;
  99   }
 100   default: Unimplemented();
 101   }
 102 }
 103 
 104 void BarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
 105                                                         Register obj, Register tmp, Label& slowpath) {
 106   __ andn(obj, JNIHandles::weak_tag_mask, obj);
 107   __ ld_ptr(obj, 0, obj);
 108 }