src/cpu/mips/vm/jniFastGetField_mips_64.cpp

Fri, 27 Sep 2019 11:31:13 +0800

author
huangjia
date
Fri, 27 Sep 2019 11:31:13 +0800
changeset 9705
0b27fc8adf1b
parent 8863
5376ce0dc552
child 9932
86ea9a02a717
permissions
-rw-r--r--

#10071 MIPS Port of 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
Summary: runtime/jni/CallWithJNIWeak/test.sh runtime/jni/ReturnJNIWeak/test.sh crash
Reviewed-by: aoqi

aoqi@1 1 /*
aoqi@1 2 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
huangjia@9705 3 * Copyright (c) 2015, 2019, Loongson Technology. All rights reserved.
aoqi@1 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@1 5 *
aoqi@1 6 * This code is free software; you can redistribute it and/or modify it
aoqi@1 7 * under the terms of the GNU General Public License version 2 only, as
aoqi@1 8 * published by the Free Software Foundation.
aoqi@1 9 *
aoqi@1 10 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@1 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@1 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@1 13 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@1 14 * accompanied this code).
aoqi@1 15 *
aoqi@1 16 * You should have received a copy of the GNU General Public License version
aoqi@1 17 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@1 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@1 19 *
aoqi@1 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@1 21 * or visit www.oracle.com if you need additional information or have any
aoqi@1 22 * questions.
aoqi@1 23 *
aoqi@1 24 */
aoqi@1 25
aoqi@1 26 #include "precompiled.hpp"
aoqi@1 27 #include "asm/macroAssembler.hpp"
aoqi@1 28 #include "memory/resourceArea.hpp"
aoqi@1 29 #include "prims/jniFastGetField.hpp"
aoqi@1 30 #include "prims/jvm_misc.hpp"
aoqi@1 31 #include "runtime/safepoint.hpp"
aoqi@1 32
aoqi@1 33 #define __ masm->
aoqi@1 34
aoqi@1 35 #define BUFFER_SIZE 30*wordSize
aoqi@1 36
aoqi@1 37 // Instead of issuing lfence for LoadLoad barrier, we create data dependency
aoqi@1 38 // between loads, which is more efficient than lfence.
aoqi@1 39
aoqi@1 40 address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
fujie@8859 41 const char *name = NULL;
aoqi@1 42 switch (type) {
aoqi@1 43 case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break;
aoqi@1 44 case T_BYTE: name = "jni_fast_GetByteField"; break;
aoqi@1 45 case T_CHAR: name = "jni_fast_GetCharField"; break;
aoqi@1 46 case T_SHORT: name = "jni_fast_GetShortField"; break;
aoqi@1 47 case T_INT: name = "jni_fast_GetIntField"; break;
aoqi@1 48 case T_LONG: name = "jni_fast_GetLongField"; break;
aoqi@1 49 default: ShouldNotReachHere();
aoqi@1 50 }
aoqi@1 51 ResourceMark rm;
aoqi@1 52 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);
aoqi@6880 53 CodeBuffer cbuf(blob);
aoqi@1 54 MacroAssembler* masm = new MacroAssembler(&cbuf);
aoqi@1 55 address fast_entry = __ pc();
aoqi@1 56
aoqi@1 57 Label slow;
aoqi@1 58
aoqi@1 59 // return pc RA
aoqi@1 60 // jni env A0
aoqi@1 61 // obj A1
aoqi@1 62 // jfieldID A2
aoqi@1 63
aoqi@1 64 address counter_addr = SafepointSynchronize::safepoint_counter_addr();
fujie@368 65 __ set64(AT, (long)counter_addr);
aoqi@1 66 __ lw(T1, AT, 0);
aoqi@1 67
huangjia@9705 68 // Parameters(A0~A3) should not be modified, since they will be used in slow path
aoqi@1 69 __ andi(AT, T1, 1);
aoqi@1 70 __ bne(AT, R0, slow);
aoqi@1 71 __ delayed()->nop();
aoqi@1 72
huangjia@9705 73 __ move(T0, A1);
huangjia@9705 74 __ clear_jweak_tag(T0);
huangjia@9705 75
huangjia@9705 76 __ ld(T0, T0, 0); // unbox, *obj
aoqi@1 77 __ move(T2, A2);
aoqi@1 78 __ shr(T2, 2); // offset
aoqi@1 79 __ dadd(T0, T0, T2);
aoqi@1 80
aoqi@1 81 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
aoqi@1 82 speculative_load_pclist[count] = __ pc();
aoqi@1 83 switch (type) {
aoqi@1 84 case T_BOOLEAN: __ lbu (V0, T0, 0); break;
aoqi@1 85 case T_BYTE: __ lb (V0, T0, 0); break;
aoqi@1 86 case T_CHAR: __ lhu (V0, T0, 0); break;
aoqi@1 87 case T_SHORT: __ lh (V0, T0, 0); break;
aoqi@1 88 case T_INT: __ lw (V0, T0, 0); break;
aoqi@1 89 case T_LONG: __ ld (V0, T0, 0); break;
aoqi@1 90 default: ShouldNotReachHere();
aoqi@1 91 }
aoqi@1 92
fujie@368 93 __ set64(AT, (long)counter_addr);
aoqi@1 94 __ lw(AT, AT, 0);
aoqi@1 95 __ bne(T1, AT, slow);
aoqi@1 96 __ delayed()->nop();
aoqi@1 97
aoqi@1 98 __ jr(RA);
aoqi@1 99 __ delayed()->nop();
aoqi@1 100
aoqi@1 101 slowcase_entry_pclist[count++] = __ pc();
aoqi@1 102 __ bind (slow);
fujie@8859 103 address slow_case_addr = NULL;
aoqi@1 104 switch (type) {
aoqi@1 105 case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break;
aoqi@1 106 case T_BYTE: slow_case_addr = jni_GetByteField_addr(); break;
aoqi@1 107 case T_CHAR: slow_case_addr = jni_GetCharField_addr(); break;
aoqi@1 108 case T_SHORT: slow_case_addr = jni_GetShortField_addr(); break;
aoqi@1 109 case T_INT: slow_case_addr = jni_GetIntField_addr(); break;
aoqi@1 110 case T_LONG: slow_case_addr = jni_GetLongField_addr();
aoqi@1 111 }
aoqi@1 112 __ jmp(slow_case_addr);
aoqi@1 113 __ delayed()->nop();
aoqi@1 114
aoqi@1 115 __ flush ();
aoqi@1 116
aoqi@1 117 return fast_entry;
aoqi@1 118 }
aoqi@1 119
aoqi@1 120 address JNI_FastGetField::generate_fast_get_boolean_field() {
aoqi@1 121 return generate_fast_get_int_field0(T_BOOLEAN);
aoqi@1 122 }
aoqi@1 123
aoqi@1 124 address JNI_FastGetField::generate_fast_get_byte_field() {
aoqi@1 125 return generate_fast_get_int_field0(T_BYTE);
aoqi@1 126 }
aoqi@1 127
aoqi@1 128 address JNI_FastGetField::generate_fast_get_char_field() {
aoqi@1 129 return generate_fast_get_int_field0(T_CHAR);
aoqi@1 130 }
aoqi@1 131
aoqi@1 132 address JNI_FastGetField::generate_fast_get_short_field() {
aoqi@1 133 return generate_fast_get_int_field0(T_SHORT);
aoqi@1 134 }
aoqi@1 135
aoqi@1 136 address JNI_FastGetField::generate_fast_get_int_field() {
aoqi@1 137 return generate_fast_get_int_field0(T_INT);
aoqi@1 138 }
aoqi@1 139
aoqi@1 140 address JNI_FastGetField::generate_fast_get_long_field() {
aoqi@1 141 return generate_fast_get_int_field0(T_LONG);
aoqi@1 142 }
aoqi@1 143
aoqi@1 144 address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) {
fujie@8859 145 const char *name =NULL;
aoqi@1 146 switch (type) {
aoqi@1 147 case T_FLOAT: name = "jni_fast_GetFloatField"; break;
aoqi@1 148 case T_DOUBLE: name = "jni_fast_GetDoubleField"; break;
aoqi@1 149 default: ShouldNotReachHere();
aoqi@1 150 }
aoqi@1 151 ResourceMark rm;
aoqi@1 152 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);
aoqi@6880 153 CodeBuffer cbuf(blob);
aoqi@1 154 MacroAssembler* masm = new MacroAssembler(&cbuf);
aoqi@6880 155 address fast_entry = __ pc();
aoqi@1 156
aoqi@1 157 Label slow;
aoqi@1 158
aoqi@6880 159 // return pc RA
aoqi@6880 160 // jni env A0
aoqi@6880 161 // obj A1
aoqi@6880 162 // jfieldID A2
aoqi@1 163
aoqi@6880 164 address counter_addr = SafepointSynchronize::safepoint_counter_addr();
aoqi@1 165 #ifdef _LP64
aoqi@6880 166 __ set64(AT, (intptr_t)counter_addr);
aoqi@6880 167 __ lw(T1, AT, 0);
aoqi@1 168 #else
aoqi@6880 169 __ lui(AT, Assembler::split_high((intptr_t)counter_addr));
aoqi@6880 170 __ lw(T1, AT, Assembler::split_low((intptr_t)counter_addr));
aoqi@1 171 #endif
aoqi@6880 172 __ andi(AT, T1, 1);
aoqi@6880 173 __ bne(AT, R0, slow);
aoqi@6880 174 __ delayed()->nop();
aoqi@1 175
huangjia@9705 176 __ clear_jweak_tag(A1);
huangjia@9705 177
aoqi@1 178 #ifdef _LP64
aoqi@6880 179 __ ld(A1, A1, 0); // unbox, *obj
aoqi@1 180 #else
aoqi@6880 181 __ lw(A1, A1, 0); // unbox, *obj
aoqi@1 182 #endif
huangjia@9705 183
aoqi@6880 184 __ shr(A2, 2); // offset
aoqi@6880 185 __ add(A1, A1, A2);
aoqi@1 186
aoqi@6880 187 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
aoqi@6880 188 speculative_load_pclist[count] = __ pc();
aoqi@6880 189 switch (type) {
aoqi@6880 190 case T_FLOAT:
aoqi@6880 191 __ lwc1(F0, A1, 0);
aoqi@6880 192 break;
aoqi@6880 193 case T_DOUBLE:
aoqi@1 194 #ifdef _LP64
aoqi@6880 195 __ ldc1(F0, A1, 0);
aoqi@1 196 #else
aoqi@6880 197 __ lwc1(F0, A1, 0);
aoqi@6880 198 __ lwc1(F1, A1, 4);
aoqi@1 199 #endif
aoqi@6880 200 break;
aoqi@6880 201 default: ShouldNotReachHere();
aoqi@6880 202 }
aoqi@1 203
aoqi@1 204 #ifdef _LP64
aoqi@6880 205 __ set64(AT, (intptr_t)counter_addr);
aoqi@6880 206 __ lw(AT, AT, 0);
aoqi@1 207 #else
aoqi@6880 208 __ lui(AT, Assembler::split_high((intptr_t)counter_addr));
aoqi@6880 209 __ lw(AT, AT, Assembler::split_low((intptr_t)counter_addr));
aoqi@1 210 #endif
aoqi@6880 211 __ bne(T1, AT, slow);
aoqi@6880 212 __ delayed()->nop();
aoqi@1 213
aoqi@6880 214 __ jr(RA);
aoqi@6880 215 __ delayed()->nop();
aoqi@1 216
aoqi@1 217
aoqi@6880 218 slowcase_entry_pclist[count++] = __ pc();
aoqi@6880 219 __ bind (slow);
fujie@8859 220 address slow_case_addr = NULL;
aoqi@6880 221 switch (type) {
aoqi@6880 222 case T_FLOAT: slow_case_addr = jni_GetFloatField_addr(); break;
aoqi@6880 223 case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); break;
aoqi@6880 224 default: ShouldNotReachHere();
aoqi@6880 225 }
aoqi@6880 226 __ jmp(slow_case_addr);
aoqi@6880 227 __ delayed()->nop();
aoqi@1 228
aoqi@6880 229 __ flush ();
aoqi@6880 230
aoqi@6880 231 return fast_entry;
aoqi@1 232 }
aoqi@1 233
aoqi@1 234 address JNI_FastGetField::generate_fast_get_float_field() {
aoqi@1 235 return generate_fast_get_float_field0(T_FLOAT);
aoqi@1 236 }
aoqi@1 237
aoqi@1 238 address JNI_FastGetField::generate_fast_get_double_field() {
aoqi@1 239 return generate_fast_get_float_field0(T_DOUBLE);
aoqi@1 240 }

mercurial