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.hpp"
27 #include "interpreter/interpreter.hpp"
28 #include "interpreter/interpreterRuntime.hpp"
29 #include "interpreter/interp_masm.hpp"
30 #include "interpreter/templateTable.hpp"
31 #include "memory/universe.inline.hpp"
32 #include "oops/methodData.hpp"
33 #include "oops/objArrayKlass.hpp"
34 #include "oops/oop.inline.hpp"
35 #include "prims/methodHandles.hpp"
36 #include "runtime/sharedRuntime.hpp"
37 #include "runtime/stubRoutines.hpp"
38 #include "runtime/synchronizer.hpp"
39 #include "utilities/macros.hpp"
40
41 #define __ _masm->
42
43 // Global Register Names
44 static const Register rbcp = LP64_ONLY(r13) NOT_LP64(rsi);
45 static const Register rlocals = LP64_ONLY(r14) NOT_LP64(rdi);
46
130 switch (cc) {
131 case TemplateTable::equal : return Assembler::notEqual;
132 case TemplateTable::not_equal : return Assembler::equal;
133 case TemplateTable::less : return Assembler::greaterEqual;
134 case TemplateTable::less_equal : return Assembler::greater;
135 case TemplateTable::greater : return Assembler::lessEqual;
136 case TemplateTable::greater_equal: return Assembler::less;
137 }
138 ShouldNotReachHere();
139 return Assembler::zero;
140 }
141
142
143
144 // Miscelaneous helper routines
145 // Store an oop (or NULL) at the address described by obj.
146 // If val == noreg this means store a NULL
147
148
149 static void do_oop_store(InterpreterMacroAssembler* _masm,
150 Address obj,
151 Register val,
152 BarrierSet::Name barrier,
153 bool precise) {
154 assert(val == noreg || val == rax, "parameter is just for looks");
155 switch (barrier) {
156 #if INCLUDE_ALL_GCS
157 case BarrierSet::G1SATBCTLogging:
158 {
159 // flatten object address if needed
160 // We do it regardless of precise because we need the registers
161 if (obj.index() == noreg && obj.disp() == 0) {
162 if (obj.base() != rdx) {
163 __ movptr(rdx, obj.base());
164 }
165 } else {
166 __ lea(rdx, obj);
167 }
168
169 Register rtmp = LP64_ONLY(r8) NOT_LP64(rsi);
170 Register rthread = LP64_ONLY(r15_thread) NOT_LP64(rcx);
171
172 NOT_LP64(__ get_thread(rcx));
173 NOT_LP64(__ save_bcp());
174
175 __ g1_write_barrier_pre(rdx /* obj */,
176 rbx /* pre_val */,
177 rthread /* thread */,
178 rtmp /* tmp */,
179 val != noreg /* tosca_live */,
180 false /* expand_call */);
181 if (val == noreg) {
182 __ store_heap_oop_null(Address(rdx, 0));
183 } else {
184 // G1 barrier needs uncompressed oop for region cross check.
185 Register new_val = val;
186 if (UseCompressedOops) {
187 new_val = rbx;
188 __ movptr(new_val, val);
189 }
190 __ store_heap_oop(Address(rdx, 0), val);
191 __ g1_write_barrier_post(rdx /* store_adr */,
192 new_val /* new_val */,
193 rthread /* thread */,
194 rtmp /* tmp */,
195 rbx /* tmp2 */);
196 }
197 NOT_LP64( __ restore_bcp());
198 }
199 break;
200 #endif // INCLUDE_ALL_GCS
201 case BarrierSet::CardTableForRS:
202 case BarrierSet::CardTableExtension:
203 {
204 if (val == noreg) {
205 __ store_heap_oop_null(obj);
206 } else {
207 __ store_heap_oop(obj, val);
208 // flatten object address if needed
209 if (!precise || (obj.index() == noreg && obj.disp() == 0)) {
210 __ store_check(obj.base());
211 } else {
212 __ lea(rdx, obj);
213 __ store_check(rdx);
214 }
215 }
216 }
217 break;
218 case BarrierSet::ModRef:
219 if (val == noreg) {
220 __ store_heap_oop_null(obj);
221 } else {
222 __ store_heap_oop(obj, val);
223 }
224 break;
225 default :
226 ShouldNotReachHere();
227
228 }
229 }
230
231 Address TemplateTable::at_bcp(int offset) {
232 assert(_desc->uses_bcp(), "inconsistent uses_bcp information");
233 return Address(rbcp, offset);
234 }
235
236
237 void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
238 Register temp_reg, bool load_bc_into_bc_reg/*=true*/,
239 int byte_no) {
240 if (!RewriteBytecodes) return;
241 Label L_patch_done;
242
243 switch (bc) {
244 case Bytecodes::_fast_aputfield:
245 case Bytecodes::_fast_bputfield:
246 case Bytecodes::_fast_zputfield:
247 case Bytecodes::_fast_cputfield:
248 case Bytecodes::_fast_dputfield:
729 __ load_float(Address(rdx, rax,
730 Address::times_4,
731 arrayOopDesc::base_offset_in_bytes(T_FLOAT)));
732 }
733
734 void TemplateTable::daload() {
735 transition(itos, dtos);
736 // rax: index
737 // rdx: array
738 index_check(rdx, rax); // kills rbx
739 __ load_double(Address(rdx, rax,
740 Address::times_8,
741 arrayOopDesc::base_offset_in_bytes(T_DOUBLE)));
742 }
743
744 void TemplateTable::aaload() {
745 transition(itos, atos);
746 // rax: index
747 // rdx: array
748 index_check(rdx, rax); // kills rbx
749 __ load_heap_oop(rax, Address(rdx, rax,
750 UseCompressedOops ? Address::times_4 : Address::times_ptr,
751 arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
752 }
753
754 void TemplateTable::baload() {
755 transition(itos, itos);
756 // rax: index
757 // rdx: array
758 index_check(rdx, rax); // kills rbx
759 __ load_signed_byte(rax, Address(rdx, rax, Address::times_1, arrayOopDesc::base_offset_in_bytes(T_BYTE)));
760 }
761
762 void TemplateTable::caload() {
763 transition(itos, itos);
764 // rax: index
765 // rdx: array
766 index_check(rdx, rax); // kills rbx
767 __ load_unsigned_short(rax, Address(rdx, rax, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
768 }
769
770 // iload followed by caload frequent pair
771 void TemplateTable::fast_icaload() {
1042 __ load_klass(rax, rdx);
1043 __ movptr(rax, Address(rax,
1044 ObjArrayKlass::element_klass_offset()));
1045 // Compress array + index*oopSize + 12 into a single register. Frees rcx.
1046 __ lea(rdx, element_address);
1047
1048 // Generate subtype check. Blows rcx, rdi
1049 // Superklass in rax. Subklass in rbx.
1050 __ gen_subtype_check(rbx, ok_is_subtype);
1051
1052 // Come here on failure
1053 // object is at TOS
1054 __ jump(ExternalAddress(Interpreter::_throw_ArrayStoreException_entry));
1055
1056 // Come here on success
1057 __ bind(ok_is_subtype);
1058
1059 // Get the value we will store
1060 __ movptr(rax, at_tos());
1061 // Now store using the appropriate barrier
1062 do_oop_store(_masm, Address(rdx, 0), rax, _bs->kind(), true);
1063 __ jmp(done);
1064
1065 // Have a NULL in rax, rdx=array, ecx=index. Store NULL at ary[idx]
1066 __ bind(is_null);
1067 __ profile_null_seen(rbx);
1068
1069 // Store a NULL
1070 do_oop_store(_masm, element_address, noreg, _bs->kind(), true);
1071
1072 // Pop stack arguments
1073 __ bind(done);
1074 __ addptr(rsp, 3 * Interpreter::stackElementSize);
1075 }
1076
1077 void TemplateTable::bastore() {
1078 transition(itos, vtos);
1079 __ pop_i(rbx);
1080 // rax: value
1081 // rbx: index
1082 // rdx: array
1083 index_check(rdx, rbx); // prefer index in rbx
1084 // Need to check whether array is boolean or byte
1085 // since both types share the bastore bytecode.
1086 __ load_klass(rcx, rdx);
1087 __ movl(rcx, Address(rcx, Klass::layout_helper_offset()));
1088 int diffbit = Klass::layout_helper_boolean_diffbit();
1089 __ testl(rcx, diffbit);
1090 Label L_skip;
3059 {
3060 __ pop(ztos);
3061 if (!is_static) pop_and_check_object(obj);
3062 __ andl(rax, 0x1);
3063 __ movb(field, rax);
3064 if (!is_static && rc == may_rewrite) {
3065 patch_bytecode(Bytecodes::_fast_zputfield, bc, rbx, true, byte_no);
3066 }
3067 __ jmp(Done);
3068 }
3069
3070 __ bind(notBool);
3071 __ cmpl(flags, atos);
3072 __ jcc(Assembler::notEqual, notObj);
3073
3074 // atos
3075 {
3076 __ pop(atos);
3077 if (!is_static) pop_and_check_object(obj);
3078 // Store into the field
3079 do_oop_store(_masm, field, rax, _bs->kind(), false);
3080 if (!is_static && rc == may_rewrite) {
3081 patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx, true, byte_no);
3082 }
3083 __ jmp(Done);
3084 }
3085
3086 __ bind(notObj);
3087 __ cmpl(flags, itos);
3088 __ jcc(Assembler::notEqual, notInt);
3089
3090 // itos
3091 {
3092 __ pop(itos);
3093 if (!is_static) pop_and_check_object(obj);
3094 __ movl(field, rax);
3095 if (!is_static && rc == may_rewrite) {
3096 patch_bytecode(Bytecodes::_fast_iputfield, bc, rbx, true, byte_no);
3097 }
3098 __ jmp(Done);
3099 }
3311 __ movptr(rbx, Address(rcx, rbx, Address::times_ptr,
3312 in_bytes(base + ConstantPoolCacheEntry::f2_offset())));
3313
3314 // [jk] not needed currently
3315 // volatile_barrier(Assembler::Membar_mask_bits(Assembler::LoadStore |
3316 // Assembler::StoreStore));
3317
3318 Label notVolatile;
3319 __ shrl(rdx, ConstantPoolCacheEntry::is_volatile_shift);
3320 __ andl(rdx, 0x1);
3321
3322 // Get object from stack
3323 pop_and_check_object(rcx);
3324
3325 // field address
3326 const Address field(rcx, rbx, Address::times_1);
3327
3328 // access field
3329 switch (bytecode()) {
3330 case Bytecodes::_fast_aputfield:
3331 do_oop_store(_masm, field, rax, _bs->kind(), false);
3332 break;
3333 case Bytecodes::_fast_lputfield:
3334 #ifdef _LP64
3335 __ movq(field, rax);
3336 #else
3337 __ stop("should not be rewritten");
3338 #endif
3339 break;
3340 case Bytecodes::_fast_iputfield:
3341 __ movl(field, rax);
3342 break;
3343 case Bytecodes::_fast_zputfield:
3344 __ andl(rax, 0x1); // boolean is true if LSB is 1
3345 // fall through to bputfield
3346 case Bytecodes::_fast_bputfield:
3347 __ movb(field, rax);
3348 break;
3349 case Bytecodes::_fast_sputfield:
3350 // fall through
3351 case Bytecodes::_fast_cputfield:
|
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.hpp"
27 #include "gc/shared/barrierSet.hpp"
28 #include "gc/shared/barrierSetCodeGen.hpp"
29 #include "interpreter/interpreter.hpp"
30 #include "interpreter/interpreterRuntime.hpp"
31 #include "interpreter/interp_masm.hpp"
32 #include "interpreter/templateTable.hpp"
33 #include "memory/universe.inline.hpp"
34 #include "oops/methodData.hpp"
35 #include "oops/objArrayKlass.hpp"
36 #include "oops/oop.inline.hpp"
37 #include "prims/methodHandles.hpp"
38 #include "runtime/sharedRuntime.hpp"
39 #include "runtime/stubRoutines.hpp"
40 #include "runtime/synchronizer.hpp"
41 #include "utilities/macros.hpp"
42
43 #define __ _masm->
44
45 // Global Register Names
46 static const Register rbcp = LP64_ONLY(r13) NOT_LP64(rsi);
47 static const Register rlocals = LP64_ONLY(r14) NOT_LP64(rdi);
48
132 switch (cc) {
133 case TemplateTable::equal : return Assembler::notEqual;
134 case TemplateTable::not_equal : return Assembler::equal;
135 case TemplateTable::less : return Assembler::greaterEqual;
136 case TemplateTable::less_equal : return Assembler::greater;
137 case TemplateTable::greater : return Assembler::lessEqual;
138 case TemplateTable::greater_equal: return Assembler::less;
139 }
140 ShouldNotReachHere();
141 return Assembler::zero;
142 }
143
144
145
146 // Miscelaneous helper routines
147 // Store an oop (or NULL) at the address described by obj.
148 // If val == noreg this means store a NULL
149
150
151 static void do_oop_store(InterpreterMacroAssembler* _masm,
152 Address dst,
153 Register val,
154 DecoratorSet decorators) {
155 assert(val == noreg || val == rax, "parameter is just for looks");
156 BarrierSetCodeGen *code_gen = Universe::heap()->barrier_set()->code_gen();
157 code_gen->store_at(_masm, decorators, T_OBJECT, dst, val, /*tmp1*/ rdx, /*tmp2*/ rbx);
158 }
159
160 static void do_oop_load(InterpreterMacroAssembler* _masm,
161 Address src,
162 Register dst,
163 DecoratorSet decorators) {
164 BarrierSetCodeGen *code_gen = Universe::heap()->barrier_set()->code_gen();
165 code_gen->load_at(_masm, decorators, T_OBJECT, dst, src, /*tmp1*/ rdx, /*tmp2*/ rbx);
166 }
167
168 Address TemplateTable::at_bcp(int offset) {
169 assert(_desc->uses_bcp(), "inconsistent uses_bcp information");
170 return Address(rbcp, offset);
171 }
172
173
174 void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
175 Register temp_reg, bool load_bc_into_bc_reg/*=true*/,
176 int byte_no) {
177 if (!RewriteBytecodes) return;
178 Label L_patch_done;
179
180 switch (bc) {
181 case Bytecodes::_fast_aputfield:
182 case Bytecodes::_fast_bputfield:
183 case Bytecodes::_fast_zputfield:
184 case Bytecodes::_fast_cputfield:
185 case Bytecodes::_fast_dputfield:
666 __ load_float(Address(rdx, rax,
667 Address::times_4,
668 arrayOopDesc::base_offset_in_bytes(T_FLOAT)));
669 }
670
671 void TemplateTable::daload() {
672 transition(itos, dtos);
673 // rax: index
674 // rdx: array
675 index_check(rdx, rax); // kills rbx
676 __ load_double(Address(rdx, rax,
677 Address::times_8,
678 arrayOopDesc::base_offset_in_bytes(T_DOUBLE)));
679 }
680
681 void TemplateTable::aaload() {
682 transition(itos, atos);
683 // rax: index
684 // rdx: array
685 index_check(rdx, rax); // kills rbx
686 do_oop_load(_masm,
687 Address(rdx, rax,
688 UseCompressedOops ? Address::times_4 : Address::times_ptr,
689 arrayOopDesc::base_offset_in_bytes(T_OBJECT)),
690 rax,
691 ACCESS_ON_HEAP | ACCESS_ON_ARRAY);
692 }
693
694 void TemplateTable::baload() {
695 transition(itos, itos);
696 // rax: index
697 // rdx: array
698 index_check(rdx, rax); // kills rbx
699 __ load_signed_byte(rax, Address(rdx, rax, Address::times_1, arrayOopDesc::base_offset_in_bytes(T_BYTE)));
700 }
701
702 void TemplateTable::caload() {
703 transition(itos, itos);
704 // rax: index
705 // rdx: array
706 index_check(rdx, rax); // kills rbx
707 __ load_unsigned_short(rax, Address(rdx, rax, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
708 }
709
710 // iload followed by caload frequent pair
711 void TemplateTable::fast_icaload() {
982 __ load_klass(rax, rdx);
983 __ movptr(rax, Address(rax,
984 ObjArrayKlass::element_klass_offset()));
985 // Compress array + index*oopSize + 12 into a single register. Frees rcx.
986 __ lea(rdx, element_address);
987
988 // Generate subtype check. Blows rcx, rdi
989 // Superklass in rax. Subklass in rbx.
990 __ gen_subtype_check(rbx, ok_is_subtype);
991
992 // Come here on failure
993 // object is at TOS
994 __ jump(ExternalAddress(Interpreter::_throw_ArrayStoreException_entry));
995
996 // Come here on success
997 __ bind(ok_is_subtype);
998
999 // Get the value we will store
1000 __ movptr(rax, at_tos());
1001 // Now store using the appropriate barrier
1002 do_oop_store(_masm, Address(rdx, 0), rax, ACCESS_ON_HEAP);
1003 __ jmp(done);
1004
1005 // Have a NULL in rax, rdx=array, ecx=index. Store NULL at ary[idx]
1006 __ bind(is_null);
1007 __ profile_null_seen(rbx);
1008
1009 // Store a NULL
1010 do_oop_store(_masm, element_address, noreg, ACCESS_ON_HEAP);
1011
1012 // Pop stack arguments
1013 __ bind(done);
1014 __ addptr(rsp, 3 * Interpreter::stackElementSize);
1015 }
1016
1017 void TemplateTable::bastore() {
1018 transition(itos, vtos);
1019 __ pop_i(rbx);
1020 // rax: value
1021 // rbx: index
1022 // rdx: array
1023 index_check(rdx, rbx); // prefer index in rbx
1024 // Need to check whether array is boolean or byte
1025 // since both types share the bastore bytecode.
1026 __ load_klass(rcx, rdx);
1027 __ movl(rcx, Address(rcx, Klass::layout_helper_offset()));
1028 int diffbit = Klass::layout_helper_boolean_diffbit();
1029 __ testl(rcx, diffbit);
1030 Label L_skip;
2999 {
3000 __ pop(ztos);
3001 if (!is_static) pop_and_check_object(obj);
3002 __ andl(rax, 0x1);
3003 __ movb(field, rax);
3004 if (!is_static && rc == may_rewrite) {
3005 patch_bytecode(Bytecodes::_fast_zputfield, bc, rbx, true, byte_no);
3006 }
3007 __ jmp(Done);
3008 }
3009
3010 __ bind(notBool);
3011 __ cmpl(flags, atos);
3012 __ jcc(Assembler::notEqual, notObj);
3013
3014 // atos
3015 {
3016 __ pop(atos);
3017 if (!is_static) pop_and_check_object(obj);
3018 // Store into the field
3019 do_oop_store(_masm, field, rax, ACCESS_ON_HEAP | ACCESS_ON_ARRAY);
3020 if (!is_static && rc == may_rewrite) {
3021 patch_bytecode(Bytecodes::_fast_aputfield, bc, rbx, true, byte_no);
3022 }
3023 __ jmp(Done);
3024 }
3025
3026 __ bind(notObj);
3027 __ cmpl(flags, itos);
3028 __ jcc(Assembler::notEqual, notInt);
3029
3030 // itos
3031 {
3032 __ pop(itos);
3033 if (!is_static) pop_and_check_object(obj);
3034 __ movl(field, rax);
3035 if (!is_static && rc == may_rewrite) {
3036 patch_bytecode(Bytecodes::_fast_iputfield, bc, rbx, true, byte_no);
3037 }
3038 __ jmp(Done);
3039 }
3251 __ movptr(rbx, Address(rcx, rbx, Address::times_ptr,
3252 in_bytes(base + ConstantPoolCacheEntry::f2_offset())));
3253
3254 // [jk] not needed currently
3255 // volatile_barrier(Assembler::Membar_mask_bits(Assembler::LoadStore |
3256 // Assembler::StoreStore));
3257
3258 Label notVolatile;
3259 __ shrl(rdx, ConstantPoolCacheEntry::is_volatile_shift);
3260 __ andl(rdx, 0x1);
3261
3262 // Get object from stack
3263 pop_and_check_object(rcx);
3264
3265 // field address
3266 const Address field(rcx, rbx, Address::times_1);
3267
3268 // access field
3269 switch (bytecode()) {
3270 case Bytecodes::_fast_aputfield:
3271 do_oop_store(_masm, field, rax, ACCESS_ON_HEAP | ACCESS_ON_ARRAY);
3272 break;
3273 case Bytecodes::_fast_lputfield:
3274 #ifdef _LP64
3275 __ movq(field, rax);
3276 #else
3277 __ stop("should not be rewritten");
3278 #endif
3279 break;
3280 case Bytecodes::_fast_iputfield:
3281 __ movl(field, rax);
3282 break;
3283 case Bytecodes::_fast_zputfield:
3284 __ andl(rax, 0x1); // boolean is true if LSB is 1
3285 // fall through to bputfield
3286 case Bytecodes::_fast_bputfield:
3287 __ movb(field, rax);
3288 break;
3289 case Bytecodes::_fast_sputfield:
3290 // fall through
3291 case Bytecodes::_fast_cputfield:
|