1 /*
   2  * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
   4  * Copyright (c) 2015, Linaro Ltd. All rights reserved.
   5  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   6  *
   7  * This code is free software; you can redistribute it and/or modify it
   8  * under the terms of the GNU General Public License version 2 only, as
   9  * published by the Free Software Foundation.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  *
  25  */
  26 
  27 #include "precompiled.hpp"
  28 #include "asm/macroAssembler.hpp"
  29 #include "gc/shared/barrierSet.hpp"
  30 #include "gc/shared/barrierSetAssembler.hpp"
  31 #include "memory/resourceArea.hpp"
  32 #include "prims/jniFastGetField.hpp"
  33 #include "prims/jvm_misc.hpp"
  34 #include "runtime/safepoint.hpp"
  35 
  36 #define __ masm->
  37 
  38 #define BUFFER_SIZE_ARMV7 31*wordSize
  39 #define BUFFER_SIZE_ARMV6 51*wordSize
  40 
  41 // Instead of issuing a LoadLoad barrier we create an address
  42 // dependency between loads; this might be more efficient.
  43 
  44 // Common register usage:
  45 // r0/v0:      result
  46 // c_rarg0:    jni env
  47 // c_rarg1:    obj
  48 // c_rarg2:    jfield id
  49 
  50 address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
  51   Register result   = c_rarg0;
  52   Register robj     = c_rarg1;
  53   Register rcounter = c_rarg3;
  54   int      args     = RegSet::of(c_rarg0, c_rarg1, c_rarg2).bits();
  55   int      nargs    = 3;
  56 
  57   const char *name;
  58   switch (type) {
  59     case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break;
  60     case T_BYTE:    name = "jni_fast_GetByteField";    break;
  61     case T_CHAR:    name = "jni_fast_GetCharField";    break;
  62     case T_SHORT:   name = "jni_fast_GetShortField";   break;
  63     case T_INT:     name = "jni_fast_GetIntField";     break;
  64     case T_LONG:    name = "jni_fast_GetLongField";    break;
  65     case T_FLOAT:   name = "jni_fast_GetFloatField";   break;
  66     case T_DOUBLE:  name = "jni_fast_GetDoubleField";  break;
  67     default:        ShouldNotReachHere(); name = ""; // unreachable
  68   }
  69   ResourceMark rm;
  70   BufferBlob* blob = BufferBlob::create(name,
  71                                         VM_Version::features() & FT_ARMV7 ?
  72                                          BUFFER_SIZE_ARMV7 :
  73                                          BUFFER_SIZE_ARMV6 );
  74   CodeBuffer cbuf(blob);
  75   MacroAssembler* masm = new MacroAssembler(&cbuf);
  76   address fast_entry = __ pc();
  77 
  78   Label slow;
  79 
  80   __ lea(rcounter, SafepointSynchronize::safepoint_counter_addr());
  81   __ ldr(rcounter, rcounter);
  82   __ tst(rcounter, 1);
  83   __ b(slow, Assembler::NE);
  84   __ stmdb(sp, args);
  85   // doesn't change c_rarg1 but does force a dependency on rcounter before
  86   // performing __ ldr(robj, ...
  87   __ eor(robj, c_rarg1, rcounter);
  88   __ eor(robj, robj, rcounter);
  89 
  90   BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
  91   bs->try_resolve_jobject_in_native(masm, c_rarg0, robj, noreg, slow);
  92 
  93   assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
  94   speculative_load_pclist[count] = __ pc();   // Used by the segfault handler
  95   // c_rarg2 * 2 is offset
  96   // Only ldr & ldrb support shifted loads
  97   switch (type) {
  98     case T_FLOAT:
  99     case T_INT:     __ ldr (result, Address(robj, c_rarg2, lsr(2))); break;
 100     case T_BOOLEAN: __ ldrb(result, Address(robj, c_rarg2, lsr(2))); break;
 101     default: {
 102       __ lsr(c_rarg2, c_rarg2, 2);
 103       switch(type) {
 104         case T_BYTE:    __ ldrsb   (result, Address(robj, c_rarg2)); break;
 105         case T_CHAR:    __ ldrh    (result, Address(robj, c_rarg2)); break;
 106         case T_SHORT:   __ ldrsh   (result, Address(robj, c_rarg2)); break;
 107         case T_DOUBLE:
 108         case T_LONG:    __ ldrd    (result, Address(robj, c_rarg2)); break;
 109         default:        ShouldNotReachHere();
 110       }
 111     }
 112   }
 113   __ lea(rscratch2, SafepointSynchronize::safepoint_counter_addr());
 114   // rscratch2 is address dependent on result.
 115   // TODO Do we need to force dependency on r1 too?
 116   __ eor(rscratch2, rscratch2, result);
 117   __ eor(rscratch2, rscratch2, result);
 118   __ ldr(rscratch2, rscratch2);
 119   __ cmp(rcounter, rscratch2);
 120 
 121 #ifdef HARD_FLOAT_CC
 122   switch (type) {
 123     case T_FLOAT:   __ vmov_f32(d0, result, Assembler::EQ); break;
 124     case T_DOUBLE:  __ vmov_f64(d0, r0, r1, Assembler::EQ); break; // Change me if result changes
 125     default:                                                break;
 126   }
 127 #endif//HARD_FLOAT_CC
 128 
 129   __ add(sp, sp, nargs * wordSize, Assembler::EQ); // Pop args if we don't need them.
 130   __ b(lr, Assembler::EQ);
 131 
 132   // Restore args for slowcase call into the vm
 133   __ ldmia(sp, args);
 134 
 135   // Slowcase
 136   slowcase_entry_pclist[count++] = __ pc();
 137   __ bind(slow);
 138 
 139   address slow_case_addr = NULL;
 140   switch (type) {
 141     case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break;
 142     case T_BYTE:    slow_case_addr = jni_GetByteField_addr();    break;
 143     case T_CHAR:    slow_case_addr = jni_GetCharField_addr();    break;
 144     case T_SHORT:   slow_case_addr = jni_GetShortField_addr();   break;
 145     case T_INT:     slow_case_addr = jni_GetIntField_addr();     break;
 146     case T_LONG:    slow_case_addr = jni_GetLongField_addr();    break;
 147     case T_FLOAT:   slow_case_addr = jni_GetFloatField_addr();   break;
 148     case T_DOUBLE:  slow_case_addr = jni_GetDoubleField_addr();  break;
 149     default:        ShouldNotReachHere();
 150   }
 151 
 152   {
 153     __ enter();
 154     __ lea(rscratch2, ExternalAddress(slow_case_addr));
 155     __ bl(rscratch2);
 156     __ maybe_isb();
 157     __ leave();
 158     __ b(lr);
 159   }
 160   __ flush ();
 161 
 162   return fast_entry;
 163 }
 164 
 165 address JNI_FastGetField::generate_fast_get_boolean_field() {
 166   return generate_fast_get_int_field0(T_BOOLEAN);
 167 }
 168 
 169 address JNI_FastGetField::generate_fast_get_byte_field() {
 170   return generate_fast_get_int_field0(T_BYTE);
 171 }
 172 
 173 address JNI_FastGetField::generate_fast_get_char_field() {
 174   return generate_fast_get_int_field0(T_CHAR);
 175 }
 176 
 177 address JNI_FastGetField::generate_fast_get_short_field() {
 178   return generate_fast_get_int_field0(T_SHORT);
 179 }
 180 
 181 address JNI_FastGetField::generate_fast_get_int_field() {
 182   return generate_fast_get_int_field0(T_INT);
 183 }
 184 
 185 address JNI_FastGetField::generate_fast_get_long_field() {
 186   return generate_fast_get_int_field0(T_LONG);
 187 }
 188 
 189 address JNI_FastGetField::generate_fast_get_float_field() {
 190   return generate_fast_get_int_field0(T_FLOAT);
 191 }
 192 
 193 address JNI_FastGetField::generate_fast_get_double_field() {
 194   return generate_fast_get_int_field0(T_DOUBLE);
 195 }