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 "asm/macroAssembler.inline.hpp"
28 #include "interpreter/interpreter.hpp"
29 #include "nativeInst_x86.hpp"
30 #include "oops/instanceOop.hpp"
31 #include "oops/method.hpp"
32 #include "oops/objArrayKlass.hpp"
33 #include "oops/oop.inline.hpp"
34 #include "prims/methodHandles.hpp"
35 #include "runtime/frame.inline.hpp"
36 #include "runtime/handles.inline.hpp"
37 #include "runtime/sharedRuntime.hpp"
38 #include "runtime/stubCodeGenerator.hpp"
39 #include "runtime/stubRoutines.hpp"
40 #include "runtime/thread.inline.hpp"
41 #include "utilities/top.hpp"
42 #ifdef COMPILER2
43 #include "opto/runtime.hpp"
44 #endif
45
46 // Declaration and definition of StubGenerator (no .hpp file).
47 // For a more detailed description of the stub routine structure
787 __ stmxcsr(mxcsr_save);
788 __ movl(rax, mxcsr_save);
789 __ andl(rax, MXCSR_MASK); // Only check control and mask bits
790 __ cmp32(rax, mxcsr_std);
791 __ jcc(Assembler::equal, ok_ret);
792
793 __ warn("MXCSR changed by native JNI code, use -XX:+RestoreMXCSROnJNICall");
794
795 __ ldmxcsr(mxcsr_std);
796
797 __ bind(ok_ret);
798 __ addptr(rsp, wordSize);
799 __ pop(rax);
800 }
801
802 __ ret(0);
803
804 return start;
805 }
806
807 address generate_f2i_fixup() {
808 StubCodeMark mark(this, "StubRoutines", "f2i_fixup");
809 Address inout(rsp, 5 * wordSize); // return address + 4 saves
810
811 address start = __ pc();
812
813 Label L;
814
815 __ push(rax);
816 __ push(c_rarg3);
817 __ push(c_rarg2);
818 __ push(c_rarg1);
819
820 __ movl(rax, 0x7f800000);
821 __ xorl(c_rarg3, c_rarg3);
822 __ movl(c_rarg2, inout);
823 __ movl(c_rarg1, c_rarg2);
824 __ andl(c_rarg1, 0x7fffffff);
825 __ cmpl(rax, c_rarg1); // NaN? -> 0
826 __ jcc(Assembler::negative, L);
1217 const Register saved_rdi = r9;
1218 const Register saved_rsi = r10;
1219 #ifdef _WIN64
1220 __ movptr(rdi, saved_rdi);
1221 __ movptr(rsi, saved_rsi);
1222 #endif
1223 }
1224
1225 // Generate code for an array write pre barrier
1226 //
1227 // addr - starting address
1228 // count - element count
1229 // tmp - scratch register
1230 //
1231 // Destroy no registers!
1232 //
1233 void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
1234 BarrierSet* bs = Universe::heap()->barrier_set();
1235 switch (bs->kind()) {
1236 case BarrierSet::G1SATBCTLogging:
1237 // With G1, don't generate the call if we statically know that the target in uninitialized
1238 if (!dest_uninitialized) {
1239 __ pusha(); // push registers
1240 if (count == c_rarg0) {
1241 if (addr == c_rarg1) {
1242 // exactly backwards!!
1243 __ xchgptr(c_rarg1, c_rarg0);
1244 } else {
1245 __ movptr(c_rarg1, count);
1246 __ movptr(c_rarg0, addr);
1247 }
1248 } else {
1249 __ movptr(c_rarg0, addr);
1250 __ movptr(c_rarg1, count);
1251 }
1252 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 2);
1253 __ popa();
1254 }
1255 break;
1256 case BarrierSet::CardTableForRS:
1261 ShouldNotReachHere();
1262
1263 }
1264 }
1265
1266 //
1267 // Generate code for an array write post barrier
1268 //
1269 // Input:
1270 // start - register containing starting address of destination array
1271 // count - elements count
1272 // scratch - scratch register
1273 //
1274 // The input registers are overwritten.
1275 //
1276 void gen_write_ref_array_post_barrier(Register start, Register count, Register scratch) {
1277 assert_different_registers(start, count, scratch);
1278 BarrierSet* bs = Universe::heap()->barrier_set();
1279 switch (bs->kind()) {
1280 case BarrierSet::G1SATBCTLogging:
1281 {
1282 __ pusha(); // push registers (overkill)
1283 if (c_rarg0 == count) { // On win64 c_rarg0 == rcx
1284 assert_different_registers(c_rarg1, start);
1285 __ mov(c_rarg1, count);
1286 __ mov(c_rarg0, start);
1287 } else {
1288 assert_different_registers(c_rarg0, count);
1289 __ mov(c_rarg0, start);
1290 __ mov(c_rarg1, count);
1291 }
1292 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), 2);
1293 __ popa();
1294 }
1295 break;
1296 case BarrierSet::CardTableForRS:
1297 case BarrierSet::CardTableExtension:
1298 {
1299 CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(bs);
1300 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
4258 // fabricate a RuntimeStub internally.
4259 StubRoutines::_throw_AbstractMethodError_entry =
4260 generate_throw_exception("AbstractMethodError throw_exception",
4261 CAST_FROM_FN_PTR(address,
4262 SharedRuntime::
4263 throw_AbstractMethodError));
4264
4265 StubRoutines::_throw_IncompatibleClassChangeError_entry =
4266 generate_throw_exception("IncompatibleClassChangeError throw_exception",
4267 CAST_FROM_FN_PTR(address,
4268 SharedRuntime::
4269 throw_IncompatibleClassChangeError));
4270
4271 StubRoutines::_throw_NullPointerException_at_call_entry =
4272 generate_throw_exception("NullPointerException at call throw_exception",
4273 CAST_FROM_FN_PTR(address,
4274 SharedRuntime::
4275 throw_NullPointerException_at_call));
4276
4277 // entry points that are platform specific
4278 StubRoutines::x86::_f2i_fixup = generate_f2i_fixup();
4279 StubRoutines::x86::_f2l_fixup = generate_f2l_fixup();
4280 StubRoutines::x86::_d2i_fixup = generate_d2i_fixup();
4281 StubRoutines::x86::_d2l_fixup = generate_d2l_fixup();
4282
4283 StubRoutines::x86::_float_sign_mask = generate_fp_mask("float_sign_mask", 0x7FFFFFFF7FFFFFFF);
4284 StubRoutines::x86::_float_sign_flip = generate_fp_mask("float_sign_flip", 0x8000000080000000);
4285 StubRoutines::x86::_double_sign_mask = generate_fp_mask("double_sign_mask", 0x7FFFFFFFFFFFFFFF);
4286 StubRoutines::x86::_double_sign_flip = generate_fp_mask("double_sign_flip", 0x8000000000000000);
4287
4288 // support for verify_oop (must happen after universe_init)
4289 StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop();
4290
4291 // arraycopy stubs used by compilers
4292 generate_arraycopy_stubs();
4293
4294 generate_math_stubs();
4295
4296 // don't bother generating these AES intrinsic stubs unless global flag is set
4297 if (UseAESIntrinsics) {
|
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 "asm/macroAssembler.inline.hpp"
28 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
29 #include "gc/shenandoah/shenandoahHeap.hpp"
30 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
31 #include "interpreter/interpreter.hpp"
32 #include "nativeInst_x86.hpp"
33 #include "oops/instanceOop.hpp"
34 #include "oops/method.hpp"
35 #include "oops/objArrayKlass.hpp"
36 #include "oops/oop.inline.hpp"
37 #include "prims/methodHandles.hpp"
38 #include "runtime/frame.inline.hpp"
39 #include "runtime/handles.inline.hpp"
40 #include "runtime/sharedRuntime.hpp"
41 #include "runtime/stubCodeGenerator.hpp"
42 #include "runtime/stubRoutines.hpp"
43 #include "runtime/thread.inline.hpp"
44 #include "utilities/top.hpp"
45 #ifdef COMPILER2
46 #include "opto/runtime.hpp"
47 #endif
48
49 // Declaration and definition of StubGenerator (no .hpp file).
50 // For a more detailed description of the stub routine structure
790 __ stmxcsr(mxcsr_save);
791 __ movl(rax, mxcsr_save);
792 __ andl(rax, MXCSR_MASK); // Only check control and mask bits
793 __ cmp32(rax, mxcsr_std);
794 __ jcc(Assembler::equal, ok_ret);
795
796 __ warn("MXCSR changed by native JNI code, use -XX:+RestoreMXCSROnJNICall");
797
798 __ ldmxcsr(mxcsr_std);
799
800 __ bind(ok_ret);
801 __ addptr(rsp, wordSize);
802 __ pop(rax);
803 }
804
805 __ ret(0);
806
807 return start;
808 }
809
810 address generate_shenandoah_wb() {
811 StubCodeMark mark(this, "StubRoutines", "shenandoah_wb");
812 address start = __ pc();
813
814 Label done;
815
816 __ push(rbx);
817 // Check for object beeing in the collection set.
818 // TODO: Can we use only 1 register here?
819 __ movptr(rdi, rax);
820 __ shrptr(rdi, ShenandoahHeapRegion::RegionSizeShift);
821 __ movptr(rbx, (intptr_t) ShenandoahHeap::in_cset_fast_test_addr());
822 __ movbool(rbx, Address(rbx, rdi, Address::times_1));
823 __ testbool(rbx);
824 __ jcc(Assembler::zero, done);
825
826 __ push(rcx);
827 __ push(rdx);
828 __ push(rdi);
829 __ push(rsi);
830 __ push(r8);
831 __ push(r9);
832 __ push(r10);
833 __ push(r11);
834 __ push(r12);
835 __ push(r13);
836 __ push(r14);
837 __ push(r15);
838 __ subptr(rsp, 128);
839 __ movdbl(Address(rsp, 0), xmm0);
840 __ movdbl(Address(rsp, 8), xmm1);
841 __ movdbl(Address(rsp, 16), xmm2);
842 __ movdbl(Address(rsp, 24), xmm3);
843 __ movdbl(Address(rsp, 32), xmm4);
844 __ movdbl(Address(rsp, 40), xmm5);
845 __ movdbl(Address(rsp, 48), xmm6);
846 __ movdbl(Address(rsp, 56), xmm7);
847 __ movdbl(Address(rsp, 64), xmm8);
848 __ movdbl(Address(rsp, 72), xmm9);
849 __ movdbl(Address(rsp, 80), xmm10);
850 __ movdbl(Address(rsp, 88), xmm11);
851 __ movdbl(Address(rsp, 96), xmm12);
852 __ movdbl(Address(rsp, 104), xmm13);
853 __ movdbl(Address(rsp, 112), xmm14);
854 __ movdbl(Address(rsp, 120), xmm15);
855 __ movptr(rdi, rax);
856 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahBarrierSet::write_barrier_c2), rdi);
857 __ movdbl(xmm0, Address(rsp, 0));
858 __ movdbl(xmm1, Address(rsp, 8));
859 __ movdbl(xmm2, Address(rsp, 16));
860 __ movdbl(xmm3, Address(rsp, 24));
861 __ movdbl(xmm4, Address(rsp, 32));
862 __ movdbl(xmm5, Address(rsp, 40));
863 __ movdbl(xmm6, Address(rsp, 48));
864 __ movdbl(xmm7, Address(rsp, 56));
865 __ movdbl(xmm8, Address(rsp, 64));
866 __ movdbl(xmm9, Address(rsp, 72));
867 __ movdbl(xmm10, Address(rsp, 80));
868 __ movdbl(xmm11, Address(rsp, 88));
869 __ movdbl(xmm12, Address(rsp, 96));
870 __ movdbl(xmm13, Address(rsp, 104));
871 __ movdbl(xmm14, Address(rsp, 112));
872 __ movdbl(xmm15, Address(rsp, 120));
873 __ addptr(rsp, 128);
874 __ pop(r15);
875 __ pop(r14);
876 __ pop(r13);
877 __ pop(r12);
878 __ pop(r11);
879 __ pop(r10);
880 __ pop(r9);
881 __ pop(r8);
882 __ pop(rsi);
883 __ pop(rdi);
884 __ pop(rdx);
885 __ pop(rcx);
886
887 __ bind(done);
888
889 __ pop(rbx);
890
891 __ ret(0);
892
893 return start;
894 }
895
896 address generate_f2i_fixup() {
897 StubCodeMark mark(this, "StubRoutines", "f2i_fixup");
898 Address inout(rsp, 5 * wordSize); // return address + 4 saves
899
900 address start = __ pc();
901
902 Label L;
903
904 __ push(rax);
905 __ push(c_rarg3);
906 __ push(c_rarg2);
907 __ push(c_rarg1);
908
909 __ movl(rax, 0x7f800000);
910 __ xorl(c_rarg3, c_rarg3);
911 __ movl(c_rarg2, inout);
912 __ movl(c_rarg1, c_rarg2);
913 __ andl(c_rarg1, 0x7fffffff);
914 __ cmpl(rax, c_rarg1); // NaN? -> 0
915 __ jcc(Assembler::negative, L);
1306 const Register saved_rdi = r9;
1307 const Register saved_rsi = r10;
1308 #ifdef _WIN64
1309 __ movptr(rdi, saved_rdi);
1310 __ movptr(rsi, saved_rsi);
1311 #endif
1312 }
1313
1314 // Generate code for an array write pre barrier
1315 //
1316 // addr - starting address
1317 // count - element count
1318 // tmp - scratch register
1319 //
1320 // Destroy no registers!
1321 //
1322 void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
1323 BarrierSet* bs = Universe::heap()->barrier_set();
1324 switch (bs->kind()) {
1325 case BarrierSet::G1SATBCTLogging:
1326 case BarrierSet::ShenandoahBarrierSet:
1327 // With G1, don't generate the call if we statically know that the target in uninitialized
1328 if (!dest_uninitialized) {
1329 __ pusha(); // push registers
1330 if (count == c_rarg0) {
1331 if (addr == c_rarg1) {
1332 // exactly backwards!!
1333 __ xchgptr(c_rarg1, c_rarg0);
1334 } else {
1335 __ movptr(c_rarg1, count);
1336 __ movptr(c_rarg0, addr);
1337 }
1338 } else {
1339 __ movptr(c_rarg0, addr);
1340 __ movptr(c_rarg1, count);
1341 }
1342 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 2);
1343 __ popa();
1344 }
1345 break;
1346 case BarrierSet::CardTableForRS:
1351 ShouldNotReachHere();
1352
1353 }
1354 }
1355
1356 //
1357 // Generate code for an array write post barrier
1358 //
1359 // Input:
1360 // start - register containing starting address of destination array
1361 // count - elements count
1362 // scratch - scratch register
1363 //
1364 // The input registers are overwritten.
1365 //
1366 void gen_write_ref_array_post_barrier(Register start, Register count, Register scratch) {
1367 assert_different_registers(start, count, scratch);
1368 BarrierSet* bs = Universe::heap()->barrier_set();
1369 switch (bs->kind()) {
1370 case BarrierSet::G1SATBCTLogging:
1371 case BarrierSet::ShenandoahBarrierSet:
1372 {
1373 __ pusha(); // push registers (overkill)
1374 if (c_rarg0 == count) { // On win64 c_rarg0 == rcx
1375 assert_different_registers(c_rarg1, start);
1376 __ mov(c_rarg1, count);
1377 __ mov(c_rarg0, start);
1378 } else {
1379 assert_different_registers(c_rarg0, count);
1380 __ mov(c_rarg0, start);
1381 __ mov(c_rarg1, count);
1382 }
1383 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), 2);
1384 __ popa();
1385 }
1386 break;
1387 case BarrierSet::CardTableForRS:
1388 case BarrierSet::CardTableExtension:
1389 {
1390 CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(bs);
1391 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
4349 // fabricate a RuntimeStub internally.
4350 StubRoutines::_throw_AbstractMethodError_entry =
4351 generate_throw_exception("AbstractMethodError throw_exception",
4352 CAST_FROM_FN_PTR(address,
4353 SharedRuntime::
4354 throw_AbstractMethodError));
4355
4356 StubRoutines::_throw_IncompatibleClassChangeError_entry =
4357 generate_throw_exception("IncompatibleClassChangeError throw_exception",
4358 CAST_FROM_FN_PTR(address,
4359 SharedRuntime::
4360 throw_IncompatibleClassChangeError));
4361
4362 StubRoutines::_throw_NullPointerException_at_call_entry =
4363 generate_throw_exception("NullPointerException at call throw_exception",
4364 CAST_FROM_FN_PTR(address,
4365 SharedRuntime::
4366 throw_NullPointerException_at_call));
4367
4368 // entry points that are platform specific
4369 if (UseShenandoahGC) {
4370 StubRoutines::x86::_shenandoah_wb = generate_shenandoah_wb();
4371 }
4372 StubRoutines::x86::_f2i_fixup = generate_f2i_fixup();
4373 StubRoutines::x86::_f2l_fixup = generate_f2l_fixup();
4374 StubRoutines::x86::_d2i_fixup = generate_d2i_fixup();
4375 StubRoutines::x86::_d2l_fixup = generate_d2l_fixup();
4376
4377 StubRoutines::x86::_float_sign_mask = generate_fp_mask("float_sign_mask", 0x7FFFFFFF7FFFFFFF);
4378 StubRoutines::x86::_float_sign_flip = generate_fp_mask("float_sign_flip", 0x8000000080000000);
4379 StubRoutines::x86::_double_sign_mask = generate_fp_mask("double_sign_mask", 0x7FFFFFFFFFFFFFFF);
4380 StubRoutines::x86::_double_sign_flip = generate_fp_mask("double_sign_flip", 0x8000000000000000);
4381
4382 // support for verify_oop (must happen after universe_init)
4383 StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop();
4384
4385 // arraycopy stubs used by compilers
4386 generate_arraycopy_stubs();
4387
4388 generate_math_stubs();
4389
4390 // don't bother generating these AES intrinsic stubs unless global flag is set
4391 if (UseAESIntrinsics) {
|