1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/cpu/sparc/vm/jniFastGetField_sparc.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,265 @@ 1.4 +/* 1.5 + * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#include "asm/macroAssembler.inline.hpp" 1.30 +#include "memory/resourceArea.hpp" 1.31 +#include "prims/jniFastGetField.hpp" 1.32 +#include "prims/jvm_misc.hpp" 1.33 +#include "runtime/safepoint.hpp" 1.34 + 1.35 +// TSO ensures that loads are blocking and ordered with respect to 1.36 +// to earlier loads, so we don't need LoadLoad membars. 1.37 + 1.38 +#define __ masm-> 1.39 + 1.40 +#define BUFFER_SIZE 30*sizeof(jint) 1.41 + 1.42 +// Common register usage: 1.43 +// O0: env 1.44 +// O1: obj 1.45 +// O2: jfieldID 1.46 +// O4: offset (O2 >> 2) 1.47 +// G4: old safepoint counter 1.48 + 1.49 +address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { 1.50 + const char *name; 1.51 + switch (type) { 1.52 + case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break; 1.53 + case T_BYTE: name = "jni_fast_GetByteField"; break; 1.54 + case T_CHAR: name = "jni_fast_GetCharField"; break; 1.55 + case T_SHORT: name = "jni_fast_GetShortField"; break; 1.56 + case T_INT: name = "jni_fast_GetIntField"; break; 1.57 + default: ShouldNotReachHere(); 1.58 + } 1.59 + ResourceMark rm; 1.60 + BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize); 1.61 + CodeBuffer cbuf(blob); 1.62 + MacroAssembler* masm = new MacroAssembler(&cbuf); 1.63 + address fast_entry = __ pc(); 1.64 + 1.65 + Label label1, label2; 1.66 + 1.67 + AddressLiteral cnt_addrlit(SafepointSynchronize::safepoint_counter_addr()); 1.68 + __ sethi (cnt_addrlit, O3); 1.69 + Address cnt_addr(O3, cnt_addrlit.low10()); 1.70 + __ ld (cnt_addr, G4); 1.71 + __ andcc (G4, 1, G0); 1.72 + __ br (Assembler::notZero, false, Assembler::pn, label1); 1.73 + __ delayed()->srl (O2, 2, O4); 1.74 + __ ld_ptr (O1, 0, O5); 1.75 + 1.76 + assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); 1.77 + speculative_load_pclist[count] = __ pc(); 1.78 + switch (type) { 1.79 + case T_BOOLEAN: __ ldub (O5, O4, G3); break; 1.80 + case T_BYTE: __ ldsb (O5, O4, G3); break; 1.81 + case T_CHAR: __ lduh (O5, O4, G3); break; 1.82 + case T_SHORT: __ ldsh (O5, O4, G3); break; 1.83 + case T_INT: __ ld (O5, O4, G3); break; 1.84 + default: ShouldNotReachHere(); 1.85 + } 1.86 + 1.87 + __ ld (cnt_addr, O5); 1.88 + __ cmp (O5, G4); 1.89 + __ br (Assembler::notEqual, false, Assembler::pn, label2); 1.90 + __ delayed()->mov (O7, G1); 1.91 + __ retl (); 1.92 + __ delayed()->mov (G3, O0); 1.93 + 1.94 + slowcase_entry_pclist[count++] = __ pc(); 1.95 + __ bind (label1); 1.96 + __ mov (O7, G1); 1.97 + 1.98 + address slow_case_addr; 1.99 + switch (type) { 1.100 + case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break; 1.101 + case T_BYTE: slow_case_addr = jni_GetByteField_addr(); break; 1.102 + case T_CHAR: slow_case_addr = jni_GetCharField_addr(); break; 1.103 + case T_SHORT: slow_case_addr = jni_GetShortField_addr(); break; 1.104 + case T_INT: slow_case_addr = jni_GetIntField_addr(); break; 1.105 + default: ShouldNotReachHere(); 1.106 + } 1.107 + __ bind (label2); 1.108 + __ call (slow_case_addr, relocInfo::none); 1.109 + __ delayed()->mov (G1, O7); 1.110 + 1.111 + __ flush (); 1.112 + 1.113 + return fast_entry; 1.114 +} 1.115 + 1.116 +address JNI_FastGetField::generate_fast_get_boolean_field() { 1.117 + return generate_fast_get_int_field0(T_BOOLEAN); 1.118 +} 1.119 + 1.120 +address JNI_FastGetField::generate_fast_get_byte_field() { 1.121 + return generate_fast_get_int_field0(T_BYTE); 1.122 +} 1.123 + 1.124 +address JNI_FastGetField::generate_fast_get_char_field() { 1.125 + return generate_fast_get_int_field0(T_CHAR); 1.126 +} 1.127 + 1.128 +address JNI_FastGetField::generate_fast_get_short_field() { 1.129 + return generate_fast_get_int_field0(T_SHORT); 1.130 +} 1.131 + 1.132 +address JNI_FastGetField::generate_fast_get_int_field() { 1.133 + return generate_fast_get_int_field0(T_INT); 1.134 +} 1.135 + 1.136 +address JNI_FastGetField::generate_fast_get_long_field() { 1.137 + const char *name = "jni_fast_GetLongField"; 1.138 + ResourceMark rm; 1.139 + BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize); 1.140 + CodeBuffer cbuf(blob); 1.141 + MacroAssembler* masm = new MacroAssembler(&cbuf); 1.142 + address fast_entry = __ pc(); 1.143 + 1.144 + Label label1, label2; 1.145 + 1.146 + AddressLiteral cnt_addrlit(SafepointSynchronize::safepoint_counter_addr()); 1.147 + __ sethi (cnt_addrlit, G3); 1.148 + Address cnt_addr(G3, cnt_addrlit.low10()); 1.149 + __ ld (cnt_addr, G4); 1.150 + __ andcc (G4, 1, G0); 1.151 + __ br (Assembler::notZero, false, Assembler::pn, label1); 1.152 + __ delayed()->srl (O2, 2, O4); 1.153 + __ ld_ptr (O1, 0, O5); 1.154 + __ add (O5, O4, O5); 1.155 + 1.156 +#ifndef _LP64 1.157 + assert(count < LIST_CAPACITY-1, "LIST_CAPACITY too small"); 1.158 + speculative_load_pclist[count++] = __ pc(); 1.159 + __ ld (O5, 0, G2); 1.160 + 1.161 + speculative_load_pclist[count] = __ pc(); 1.162 + __ ld (O5, 4, O3); 1.163 +#else 1.164 + assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); 1.165 + speculative_load_pclist[count] = __ pc(); 1.166 + __ ldx (O5, 0, O3); 1.167 +#endif 1.168 + 1.169 + __ ld (cnt_addr, G1); 1.170 + __ cmp (G1, G4); 1.171 + __ br (Assembler::notEqual, false, Assembler::pn, label2); 1.172 + __ delayed()->mov (O7, G1); 1.173 + 1.174 +#ifndef _LP64 1.175 + __ mov (G2, O0); 1.176 + __ retl (); 1.177 + __ delayed()->mov (O3, O1); 1.178 +#else 1.179 + __ retl (); 1.180 + __ delayed()->mov (O3, O0); 1.181 +#endif 1.182 + 1.183 +#ifndef _LP64 1.184 + slowcase_entry_pclist[count-1] = __ pc(); 1.185 + slowcase_entry_pclist[count++] = __ pc() ; 1.186 +#else 1.187 + slowcase_entry_pclist[count++] = __ pc(); 1.188 +#endif 1.189 + 1.190 + __ bind (label1); 1.191 + __ mov (O7, G1); 1.192 + 1.193 + address slow_case_addr = jni_GetLongField_addr(); 1.194 + __ bind (label2); 1.195 + __ call (slow_case_addr, relocInfo::none); 1.196 + __ delayed()->mov (G1, O7); 1.197 + 1.198 + __ flush (); 1.199 + 1.200 + return fast_entry; 1.201 +} 1.202 + 1.203 +address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) { 1.204 + const char *name; 1.205 + switch (type) { 1.206 + case T_FLOAT: name = "jni_fast_GetFloatField"; break; 1.207 + case T_DOUBLE: name = "jni_fast_GetDoubleField"; break; 1.208 + default: ShouldNotReachHere(); 1.209 + } 1.210 + ResourceMark rm; 1.211 + BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize); 1.212 + CodeBuffer cbuf(blob); 1.213 + MacroAssembler* masm = new MacroAssembler(&cbuf); 1.214 + address fast_entry = __ pc(); 1.215 + 1.216 + Label label1, label2; 1.217 + 1.218 + AddressLiteral cnt_addrlit(SafepointSynchronize::safepoint_counter_addr()); 1.219 + __ sethi (cnt_addrlit, O3); 1.220 + Address cnt_addr(O3, cnt_addrlit.low10()); 1.221 + __ ld (cnt_addr, G4); 1.222 + __ andcc (G4, 1, G0); 1.223 + __ br (Assembler::notZero, false, Assembler::pn, label1); 1.224 + __ delayed()->srl (O2, 2, O4); 1.225 + __ ld_ptr (O1, 0, O5); 1.226 + 1.227 + assert(count < LIST_CAPACITY, "LIST_CAPACITY too small"); 1.228 + speculative_load_pclist[count] = __ pc(); 1.229 + switch (type) { 1.230 + case T_FLOAT: __ ldf (FloatRegisterImpl::S, O5, O4, F0); break; 1.231 + case T_DOUBLE: __ ldf (FloatRegisterImpl::D, O5, O4, F0); break; 1.232 + default: ShouldNotReachHere(); 1.233 + } 1.234 + 1.235 + __ ld (cnt_addr, O5); 1.236 + __ cmp (O5, G4); 1.237 + __ br (Assembler::notEqual, false, Assembler::pn, label2); 1.238 + __ delayed()->mov (O7, G1); 1.239 + 1.240 + __ retl (); 1.241 + __ delayed()-> nop (); 1.242 + 1.243 + slowcase_entry_pclist[count++] = __ pc(); 1.244 + __ bind (label1); 1.245 + __ mov (O7, G1); 1.246 + 1.247 + address slow_case_addr; 1.248 + switch (type) { 1.249 + case T_FLOAT: slow_case_addr = jni_GetFloatField_addr(); break; 1.250 + case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); break; 1.251 + default: ShouldNotReachHere(); 1.252 + } 1.253 + __ bind (label2); 1.254 + __ call (slow_case_addr, relocInfo::none); 1.255 + __ delayed()->mov (G1, O7); 1.256 + 1.257 + __ flush (); 1.258 + 1.259 + return fast_entry; 1.260 +} 1.261 + 1.262 +address JNI_FastGetField::generate_fast_get_float_field() { 1.263 + return generate_fast_get_float_field0(T_FLOAT); 1.264 +} 1.265 + 1.266 +address JNI_FastGetField::generate_fast_get_double_field() { 1.267 + return generate_fast_get_float_field0(T_DOUBLE); 1.268 +}