src/cpu/sparc/vm/jniFastGetField_sparc.cpp

Tue, 07 May 2019 20:38:26 +0000

author
phh
date
Tue, 07 May 2019 20:38:26 +0000
changeset 9669
32bc598624bd
parent 4323
f0c2369fda5a
child 9703
2fdf635bcf28
permissions
-rw-r--r--

8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
Summary: Add tag bit to all JNI weak handles
Reviewed-by: kbarrett, coleenp, tschatzl

     1 /*
     2  * Copyright (c) 2004, 2017, 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  */
    25 #include "precompiled.hpp"
    26 #include "asm/macroAssembler.inline.hpp"
    27 #include "memory/resourceArea.hpp"
    28 #include "prims/jniFastGetField.hpp"
    29 #include "prims/jvm_misc.hpp"
    30 #include "runtime/safepoint.hpp"
    32 // TSO ensures that loads are blocking and ordered with respect to
    33 // to earlier loads, so we don't need LoadLoad membars.
    35 #define __ masm->
    37 #define BUFFER_SIZE 30*sizeof(jint)
    39 // Common register usage:
    40 // O0: env
    41 // O1: obj
    42 // O2: jfieldID
    43 // O4: offset (O2 >> 2)
    44 // G4: old safepoint counter
    46 address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
    47   const char *name;
    48   switch (type) {
    49     case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break;
    50     case T_BYTE:    name = "jni_fast_GetByteField";    break;
    51     case T_CHAR:    name = "jni_fast_GetCharField";    break;
    52     case T_SHORT:   name = "jni_fast_GetShortField";   break;
    53     case T_INT:     name = "jni_fast_GetIntField";     break;
    54     default:        ShouldNotReachHere();
    55   }
    56   ResourceMark rm;
    57   BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize);
    58   CodeBuffer cbuf(blob);
    59   MacroAssembler* masm = new MacroAssembler(&cbuf);
    60   address fast_entry = __ pc();
    62   Label label1, label2;
    64   AddressLiteral cnt_addrlit(SafepointSynchronize::safepoint_counter_addr());
    65   __ sethi (cnt_addrlit, O3);
    66   Address cnt_addr(O3, cnt_addrlit.low10());
    67   __ ld (cnt_addr, G4);
    68   __ andcc (G4, 1, G0);
    69   __ br (Assembler::notZero, false, Assembler::pn, label1);
    70   __ delayed()->srl (O2, 2, O4);
    71   __ andn (O1, JNIHandles::weak_tag_mask, O1);
    72   __ ld_ptr (O1, 0, O5);
    74   assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
    75   speculative_load_pclist[count] = __ pc();
    76   switch (type) {
    77     case T_BOOLEAN: __ ldub (O5, O4, G3);  break;
    78     case T_BYTE:    __ ldsb (O5, O4, G3);  break;
    79     case T_CHAR:    __ lduh (O5, O4, G3);  break;
    80     case T_SHORT:   __ ldsh (O5, O4, G3);  break;
    81     case T_INT:     __ ld (O5, O4, G3);    break;
    82     default:        ShouldNotReachHere();
    83   }
    85   __ ld (cnt_addr, O5);
    86   __ cmp (O5, G4);
    87   __ br (Assembler::notEqual, false, Assembler::pn, label2);
    88   __ delayed()->mov (O7, G1);
    89   __ retl ();
    90   __ delayed()->mov (G3, O0);
    92   slowcase_entry_pclist[count++] = __ pc();
    93   __ bind (label1);
    94   __ mov (O7, G1);
    96   address slow_case_addr;
    97   switch (type) {
    98     case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break;
    99     case T_BYTE:    slow_case_addr = jni_GetByteField_addr();    break;
   100     case T_CHAR:    slow_case_addr = jni_GetCharField_addr();    break;
   101     case T_SHORT:   slow_case_addr = jni_GetShortField_addr();   break;
   102     case T_INT:     slow_case_addr = jni_GetIntField_addr();     break;
   103     default:        ShouldNotReachHere();
   104   }
   105   __ bind (label2);
   106   __ call (slow_case_addr, relocInfo::none);
   107   __ delayed()->mov (G1, O7);
   109   __ flush ();
   111   return fast_entry;
   112 }
   114 address JNI_FastGetField::generate_fast_get_boolean_field() {
   115   return generate_fast_get_int_field0(T_BOOLEAN);
   116 }
   118 address JNI_FastGetField::generate_fast_get_byte_field() {
   119   return generate_fast_get_int_field0(T_BYTE);
   120 }
   122 address JNI_FastGetField::generate_fast_get_char_field() {
   123   return generate_fast_get_int_field0(T_CHAR);
   124 }
   126 address JNI_FastGetField::generate_fast_get_short_field() {
   127   return generate_fast_get_int_field0(T_SHORT);
   128 }
   130 address JNI_FastGetField::generate_fast_get_int_field() {
   131   return generate_fast_get_int_field0(T_INT);
   132 }
   134 address JNI_FastGetField::generate_fast_get_long_field() {
   135   const char *name = "jni_fast_GetLongField";
   136   ResourceMark rm;
   137   BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize);
   138   CodeBuffer cbuf(blob);
   139   MacroAssembler* masm = new MacroAssembler(&cbuf);
   140   address fast_entry = __ pc();
   142   Label label1, label2;
   144   AddressLiteral cnt_addrlit(SafepointSynchronize::safepoint_counter_addr());
   145   __ sethi (cnt_addrlit, G3);
   146   Address cnt_addr(G3, cnt_addrlit.low10());
   147   __ ld (cnt_addr, G4);
   148   __ andcc (G4, 1, G0);
   149   __ br (Assembler::notZero, false, Assembler::pn, label1);
   150   __ delayed()->srl (O2, 2, O4);
   151   __ andn (O1, JNIHandles::weak_tag_mask, O1);
   152   __ ld_ptr (O1, 0, O5);
   153   __ add (O5, O4, O5);
   155 #ifndef _LP64
   156   assert(count < LIST_CAPACITY-1, "LIST_CAPACITY too small");
   157   speculative_load_pclist[count++] = __ pc();
   158   __ ld (O5, 0, G2);
   160   speculative_load_pclist[count] = __ pc();
   161   __ ld (O5, 4, O3);
   162 #else
   163   assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
   164   speculative_load_pclist[count] = __ pc();
   165   __ ldx (O5, 0, O3);
   166 #endif
   168   __ ld (cnt_addr, G1);
   169   __ cmp (G1, G4);
   170   __ br (Assembler::notEqual, false, Assembler::pn, label2);
   171   __ delayed()->mov (O7, G1);
   173 #ifndef _LP64
   174   __ mov (G2, O0);
   175   __ retl ();
   176   __ delayed()->mov (O3, O1);
   177 #else
   178   __ retl ();
   179   __ delayed()->mov (O3, O0);
   180 #endif
   182 #ifndef _LP64
   183   slowcase_entry_pclist[count-1] = __ pc();
   184   slowcase_entry_pclist[count++] = __ pc() ;
   185 #else
   186   slowcase_entry_pclist[count++] = __ pc();
   187 #endif
   189   __ bind (label1);
   190   __ mov (O7, G1);
   192   address slow_case_addr = jni_GetLongField_addr();
   193   __ bind (label2);
   194   __ call (slow_case_addr, relocInfo::none);
   195   __ delayed()->mov (G1, O7);
   197   __ flush ();
   199   return fast_entry;
   200 }
   202 address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) {
   203   const char *name;
   204   switch (type) {
   205     case T_FLOAT:  name = "jni_fast_GetFloatField";  break;
   206     case T_DOUBLE: name = "jni_fast_GetDoubleField"; break;
   207     default:       ShouldNotReachHere();
   208   }
   209   ResourceMark rm;
   210   BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize);
   211   CodeBuffer cbuf(blob);
   212   MacroAssembler* masm = new MacroAssembler(&cbuf);
   213   address fast_entry = __ pc();
   215   Label label1, label2;
   217   AddressLiteral cnt_addrlit(SafepointSynchronize::safepoint_counter_addr());
   218   __ sethi (cnt_addrlit, O3);
   219   Address cnt_addr(O3, cnt_addrlit.low10());
   220   __ ld (cnt_addr, G4);
   221   __ andcc (G4, 1, G0);
   222   __ br (Assembler::notZero, false, Assembler::pn, label1);
   223   __ delayed()->srl (O2, 2, O4);
   224   __ andn (O1, JNIHandles::weak_tag_mask, O1);
   225   __ ld_ptr (O1, 0, O5);
   227   assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
   228   speculative_load_pclist[count] = __ pc();
   229   switch (type) {
   230     case T_FLOAT:  __ ldf (FloatRegisterImpl::S, O5, O4, F0); break;
   231     case T_DOUBLE: __ ldf (FloatRegisterImpl::D, O5, O4, F0); break;
   232     default:       ShouldNotReachHere();
   233   }
   235   __ ld (cnt_addr, O5);
   236   __ cmp (O5, G4);
   237   __ br (Assembler::notEqual, false, Assembler::pn, label2);
   238   __ delayed()->mov (O7, G1);
   240   __ retl ();
   241   __ delayed()-> nop ();
   243   slowcase_entry_pclist[count++] = __ pc();
   244   __ bind (label1);
   245   __ mov (O7, G1);
   247   address slow_case_addr;
   248   switch (type) {
   249     case T_FLOAT:  slow_case_addr = jni_GetFloatField_addr();  break;
   250     case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); break;
   251     default:       ShouldNotReachHere();
   252   }
   253   __ bind (label2);
   254   __ call (slow_case_addr, relocInfo::none);
   255   __ delayed()->mov (G1, O7);
   257   __ flush ();
   259   return fast_entry;
   260 }
   262 address JNI_FastGetField::generate_fast_get_float_field() {
   263   return generate_fast_get_float_field0(T_FLOAT);
   264 }
   266 address JNI_FastGetField::generate_fast_get_double_field() {
   267   return generate_fast_get_float_field0(T_DOUBLE);
   268 }

mercurial