# HG changeset patch # User amurillo # Date 1459459535 25200 # Node ID 9ac2550c36c63aa4ebaa4f2351bc8dce844c3154 # Parent 6072af7a98be3922f26bdce71b53bb3646cb2ac9# Parent bb127602cd19c78661a07f8675445fd8ceaddf43 Merge diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/.mx.jvmci/suite.py --- a/hotspot/.mx.jvmci/suite.py Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/.mx.jvmci/suite.py Thu Mar 31 14:25:35 2016 -0700 @@ -32,24 +32,9 @@ "libraries" : { - "HCFDIS" : { - "urls" : ["https://lafo.ssw.uni-linz.ac.at/pub/hcfdis-3.jar"], - "sha1" : "a71247c6ddb90aad4abf7c77e501acc60674ef57", - }, - - "C1VISUALIZER_DIST" : { - "urls" : ["https://java.net/downloads/c1visualizer/c1visualizer_2015-07-22.zip"], - "sha1" : "7ead6b2f7ed4643ef4d3343a5562e3d3f39564ac", - }, - - "JOL_INTERNALS" : { - "urls" : ["https://lafo.ssw.uni-linz.ac.at/pub/truffle/jol/jol-internals.jar"], - "sha1" : "508bcd26a4d7c4c44048990c6ea789a3b11a62dc", - }, - - "BATIK" : { - "sha1" : "122b87ca88e41a415cf8b523fd3d03b4325134a3", - "urls" : ["https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/batik-all-1.7.jar"], + "TESTNG" : { + "urls" : ["http://central.maven.org/maven2/org/testng/testng/6.9.10/testng-6.9.10.jar"], + "sha1" : "6feb3e964aeb7097aff30c372aac3ec0f8d87ede", }, # Stubs for classes introduced in JDK9 that allow compilation with a JDK8 javac and Eclipse. @@ -175,6 +160,18 @@ "workingSets" : "JVMCI", }, + "jdk.vm.ci.hotspot.test" : { + "subDir" : "test/compiler/jvmci", + "sourceDirs" : ["src"], + "dependencies" : [ + "mx:TESTNG", + "jdk.vm.ci.hotspot", + ], + "checkstyle" : "jdk.vm.ci.services", + "javaCompliance" : "1.8", + "workingSets" : "API,JVMCI", + }, + "jdk.vm.ci.hotspotvmconfig" : { "subDir" : "src/jdk.vm.ci/share/classes", "sourceDirs" : ["src"], diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/cpu/aarch64/vm/jvmciCodeInstaller_aarch64.cpp --- a/hotspot/src/cpu/aarch64/vm/jvmciCodeInstaller_aarch64.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/cpu/aarch64/vm/jvmciCodeInstaller_aarch64.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -65,7 +65,7 @@ Unimplemented(); } else { NativeMovConstReg* move = nativeMovConstReg_at(pc); - Metadata* reference = record_metadata_reference(constant, CHECK); + void* reference = record_metadata_reference(constant, CHECK); move->set_data((intptr_t) reference); TRACE_jvmci_3("relocating (metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(reference)); } diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp --- a/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -211,10 +211,6 @@ return (r->reg2stack() + SharedRuntime::out_preserve_stack_slots()) * VMRegImpl::stack_slot_size; } -template static const T& min (const T& a, const T& b) { - return (a > b) ? b : a; -} - // --------------------------------------------------------------------------- // Read the array of BasicTypes from a signature, and compute where the // arguments should go. Values in the VMRegPair regs array refer to 4-byte diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/cpu/sparc/vm/jvmciCodeInstaller_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/jvmciCodeInstaller_sparc.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/cpu/sparc/vm/jvmciCodeInstaller_sparc.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -79,7 +79,7 @@ #endif } else { NativeMovConstReg* move = nativeMovConstReg_at(pc); - Metadata* reference = record_metadata_reference(constant, CHECK); + void* reference = record_metadata_reference(constant, CHECK); move->set_data((intptr_t)reference); TRACE_jvmci_3("relocating (metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(reference)); } diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -4666,8 +4666,109 @@ bind(Ldone); } +void MacroAssembler::has_negatives(Register inp, Register size, Register result, Register t2, Register t3, Register t4, Register t5) { + + // test for negative bytes in input string of a given size + // result 1 if found, 0 otherwise. + + Label Lcore, Ltail, Lreturn, Lcore_rpt; + + assert_different_registers(inp, size, t2, t3, t4, t5, result); + + Register i = result; // result used as integer index i until very end + Register lmask = t2; // t2 is aliased to lmask + + // INITIALIZATION + // =========================================================== + // initialize highbits mask -> lmask = 0x8080808080808080 (8B/64b) + // compute unaligned offset -> i + // compute core end index -> t5 + Assembler::sethi(0x80808000, t2); //! sethi macro fails to emit optimal + add(t2, 0x80, t2); + sllx(t2, 32, t3); + or3(t3, t2, lmask); // 0x8080808080808080 -> lmask + sra(size,0,size); + andcc(inp, 0x7, i); // unaligned offset -> i + br(Assembler::zero, true, Assembler::pn, Lcore); // starts 8B aligned? + delayed()->add(size, -8, t5); // (annuled) core end index -> t5 + + // =========================================================== + + // UNALIGNED HEAD + // =========================================================== + // * unaligned head handling: grab aligned 8B containing unaligned inp(ut) + // * obliterate (ignore) bytes outside string by shifting off reg ends + // * compare with bitmask, short circuit return true if one or more high + // bits set. + cmp(size, 0); + br(Assembler::zero, true, Assembler::pn, Lreturn); // short-circuit? + delayed()->mov(0,result); // annuled so i not clobbered for following + neg(i, t4); + add(i, size, t5); + ldx(inp, t4, t3); // raw aligned 8B containing unaligned head -> t3 + mov(8, t4); + sub(t4, t5, t4); + sra(t4, 31, t5); + andn(t4, t5, t5); + add(i, t5, t4); + sll(t5, 3, t5); + sll(t4, 3, t4); // # bits to shift right, left -> t5,t4 + srlx(t3, t5, t3); + sllx(t3, t4, t3); // bytes outside string in 8B header obliterated -> t3 + andcc(lmask, t3, G0); + brx(Assembler::notZero, true, Assembler::pn, Lreturn); // short circuit? + delayed()->mov(1,result); // annuled so i not clobbered for following + add(size, -8, t5); // core end index -> t5 + mov(8, t4); + sub(t4, i, i); // # bytes examined in unalgn head (<8) -> i + // =========================================================== + + // ALIGNED CORE + // =========================================================== + // * iterate index i over aligned 8B sections of core, comparing with + // bitmask, short circuit return true if one or more high bits set + // t5 contains core end index/loop limit which is the index + // of the MSB of last (unaligned) 8B fully contained in the string. + // inp contains address of first byte in string/array + // lmask contains 8B high bit mask for comparison + // i contains next index to be processed (adr. inp+i is on 8B boundary) + bind(Lcore); + cmp_and_br_short(i, t5, Assembler::greater, Assembler::pn, Ltail); + bind(Lcore_rpt); + ldx(inp, i, t3); + andcc(t3, lmask, G0); + brx(Assembler::notZero, true, Assembler::pn, Lreturn); + delayed()->mov(1, result); // annuled so i not clobbered for following + add(i, 8, i); + cmp_and_br_short(i, t5, Assembler::lessEqual, Assembler::pn, Lcore_rpt); + // =========================================================== + + // ALIGNED TAIL (<8B) + // =========================================================== + // handle aligned tail of 7B or less as complete 8B, obliterating end of + // string bytes by shifting them off end, compare what's left with bitmask + // inp contains address of first byte in string/array + // lmask contains 8B high bit mask for comparison + // i contains next index to be processed (adr. inp+i is on 8B boundary) + bind(Ltail); + subcc(size, i, t4); // # of remaining bytes in string -> t4 + // return 0 if no more remaining bytes + br(Assembler::lessEqual, true, Assembler::pn, Lreturn); + delayed()->mov(0, result); // annuled so i not clobbered for following + ldx(inp, i, t3); // load final 8B (aligned) containing tail -> t3 + mov(8, t5); + sub(t5, t4, t4); + mov(0, result); // ** i clobbered at this point + sll(t4, 3, t4); // bits beyond end of string -> t4 + srlx(t3, t4, t3); // bytes beyond end now obliterated -> t3 + andcc(lmask, t3, G0); + movcc(Assembler::notZero, false, xcc, 1, result); + bind(Lreturn); +} + #endif + // Use BIS for zeroing (count is in bytes). void MacroAssembler::bis_zeroing(Register to, Register count, Register temp, Label& Ldone) { assert(UseBlockZeroing && VM_Version::has_block_zeroing(), "only works with BIS zeroing"); diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp --- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp Thu Mar 31 14:25:35 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1392,6 +1392,11 @@ void array_equals(bool is_array_equ, Register ary1, Register ary2, Register limit, Register tmp, Register result, bool is_byte); + // test for negative bytes in input string of a given size, result 0 if none + void has_negatives(Register inp, Register size, Register result, + Register t2, Register t3, Register t4, + Register t5); + #endif // Use BIS for zeroing diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/cpu/sparc/vm/sparc.ad --- a/hotspot/src/cpu/sparc/vm/sparc.ad Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/cpu/sparc/vm/sparc.ad Thu Mar 31 14:25:35 2016 -0700 @@ -10168,6 +10168,22 @@ ins_pipe(long_memory_op); %} +instruct has_negatives(o0RegP pAryR, g3RegI iSizeR, notemp_iRegI resultR, + iRegL tmp1L, iRegL tmp2L, iRegL tmp3L, iRegL tmp4L, + flagsReg ccr) +%{ + match(Set resultR (HasNegatives pAryR iSizeR)); + effect(TEMP resultR, TEMP tmp1L, TEMP tmp2L, TEMP tmp3L, TEMP tmp4L, USE pAryR, USE iSizeR, KILL ccr); + format %{ "has negatives byte[] $pAryR,$iSizeR -> $resultR // KILL $tmp1L,$tmp2L,$tmp3L,$tmp4L" %} + ins_encode %{ + __ has_negatives($pAryR$$Register, $iSizeR$$Register, + $resultR$$Register, + $tmp1L$$Register, $tmp2L$$Register, + $tmp3L$$Register, $tmp4L$$Register); + %} + ins_pipe(long_memory_op); +%} + // char[] to byte[] compression instruct string_compress(o0RegP src, o1RegP dst, g3RegI len, notemp_iRegI result, iRegL tmp, flagsReg ccr) %{ predicate(UseVIS < 3); diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/cpu/x86/vm/assembler_x86.cpp --- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -394,7 +394,7 @@ int mod_idx = 0; // We will test if the displacement fits the compressed format and if so // apply the compression to the displacment iff the result is8bit. - if (VM_Version::supports_evex() && (_attributes != NULL) && _attributes->is_evex_instruction()) { + if (VM_Version::supports_evex() && _attributes && _attributes->is_evex_instruction()) { int evex_encoding = _attributes->get_evex_encoding(); int tuple_type = _attributes->get_tuple_type(); switch (tuple_type) { @@ -2154,7 +2154,7 @@ void Assembler::movddup(XMMRegister dst, XMMRegister src) { NOT_LP64(assert(VM_Version::supports_sse3(), "")); - int vector_len = VM_Version::supports_evex() ? AVX_512bit : AVX_128bit; + int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_128bit; InstructionAttr attributes(vector_len, /* rex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes); emit_int8(0x12); @@ -2423,7 +2423,8 @@ void Assembler::evmovdqub(XMMRegister dst, XMMRegister src, int vector_len) { assert(VM_Version::supports_evex(), ""); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true); - int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes); + int prefix = (_legacy_mode_bw) ? VEX_SIMD_F2 : VEX_SIMD_F3; + int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes); emit_int8(0x6F); emit_int8((unsigned char)(0xC0 | encode)); } @@ -2432,8 +2433,9 @@ assert(VM_Version::supports_evex(), ""); InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true); + int prefix = (_legacy_mode_bw) ? VEX_SIMD_F2 : VEX_SIMD_F3; attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit); - vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes); + vex_prefix(src, 0, dst->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes); emit_int8(0x6F); emit_operand(dst, src); } @@ -2443,8 +2445,9 @@ assert(src != xnoreg, "sanity"); InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true); + int prefix = (_legacy_mode_bw) ? VEX_SIMD_F2 : VEX_SIMD_F3; attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit); - vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes); + vex_prefix(dst, 0, src->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes); emit_int8(0x7F); emit_operand(src, dst); } @@ -2452,7 +2455,8 @@ void Assembler::evmovdquw(XMMRegister dst, XMMRegister src, int vector_len) { assert(VM_Version::supports_evex(), ""); InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true); - int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes); + int prefix = (_legacy_mode_bw) ? VEX_SIMD_F2 : VEX_SIMD_F3; + int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes); emit_int8(0x6F); emit_int8((unsigned char)(0xC0 | encode)); } @@ -2462,7 +2466,8 @@ InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true); attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit); - vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes); + int prefix = (_legacy_mode_bw) ? VEX_SIMD_F2 : VEX_SIMD_F3; + vex_prefix(src, 0, dst->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes); emit_int8(0x6F); emit_operand(dst, src); } @@ -2473,13 +2478,16 @@ InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true); attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit); - vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F, &attributes); + int prefix = (_legacy_mode_bw) ? VEX_SIMD_F2 : VEX_SIMD_F3; + vex_prefix(dst, 0, src->encoding(), (Assembler::VexSimdPrefix)prefix, VEX_OPCODE_0F, &attributes); emit_int8(0x7F); emit_operand(src, dst); } + void Assembler::evmovdqul(XMMRegister dst, XMMRegister src, int vector_len) { assert(VM_Version::supports_evex(), ""); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_is_evex_instruction(); int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes); emit_int8(0x6F); emit_int8((unsigned char)(0xC0 | encode)); @@ -2490,6 +2498,7 @@ InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false , /* uses_vl */ true); attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit); + attributes.set_is_evex_instruction(); vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes); emit_int8(0x6F); emit_operand(dst, src); @@ -2500,6 +2509,7 @@ assert(src != xnoreg, "sanity"); InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_is_evex_instruction(); attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit); vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes); emit_int8(0x7F); @@ -2509,6 +2519,7 @@ void Assembler::evmovdquq(XMMRegister dst, XMMRegister src, int vector_len) { assert(VM_Version::supports_evex(), ""); InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_is_evex_instruction(); int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes); emit_int8(0x6F); emit_int8((unsigned char)(0xC0 | encode)); @@ -2518,6 +2529,7 @@ assert(VM_Version::supports_evex(), ""); InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_is_evex_instruction(); attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit); vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes); emit_int8(0x6F); @@ -2529,6 +2541,7 @@ assert(src != xnoreg, "sanity"); InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_is_evex_instruction(); attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit); vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F, &attributes); emit_int8(0x7F); @@ -3196,6 +3209,7 @@ void Assembler::evpcmpeqb(KRegister kdst, XMMRegister nds, XMMRegister src, int vector_len) { assert(VM_Version::supports_avx512bw(), ""); InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_is_evex_instruction(); int nds_enc = nds->is_valid() ? nds->encoding() : 0; int encode = vex_prefix_and_encode(kdst->encoding(), nds_enc, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes); emit_int8(0x74); @@ -3206,6 +3220,7 @@ assert(VM_Version::supports_avx512bw(), ""); InstructionMark im(this); InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_is_evex_instruction(); attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit); int nds_enc = nds->is_valid() ? nds->encoding() : 0; int dst_enc = kdst->encoding(); @@ -3237,6 +3252,7 @@ void Assembler::evpcmpeqw(KRegister kdst, XMMRegister nds, XMMRegister src, int vector_len) { assert(VM_Version::supports_avx512bw(), ""); InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_is_evex_instruction(); int nds_enc = nds->is_valid() ? nds->encoding() : 0; int encode = vex_prefix_and_encode(kdst->encoding(), nds_enc, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes); emit_int8(0x75); @@ -3248,6 +3264,7 @@ InstructionMark im(this); InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit); + attributes.set_is_evex_instruction(); int nds_enc = nds->is_valid() ? nds->encoding() : 0; int dst_enc = kdst->encoding(); vex_prefix(src, nds_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F, &attributes); @@ -3278,6 +3295,7 @@ void Assembler::evpcmpeqd(KRegister kdst, XMMRegister nds, XMMRegister src, int vector_len) { assert(VM_Version::supports_evex(), ""); InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_is_evex_instruction(); int nds_enc = nds->is_valid() ? nds->encoding() : 0; int encode = vex_prefix_and_encode(kdst->encoding(), nds_enc, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes); emit_int8(0x76); @@ -3289,6 +3307,7 @@ InstructionMark im(this); InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit); + attributes.set_is_evex_instruction(); int nds_enc = nds->is_valid() ? nds->encoding() : 0; int dst_enc = kdst->encoding(); vex_prefix(src, nds_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F, &attributes); @@ -3319,6 +3338,7 @@ void Assembler::evpcmpeqq(KRegister kdst, XMMRegister nds, XMMRegister src, int vector_len) { assert(VM_Version::supports_evex(), ""); InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_is_evex_instruction(); int nds_enc = nds->is_valid() ? nds->encoding() : 0; int encode = vex_prefix_and_encode(kdst->encoding(), nds_enc, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); emit_int8(0x29); @@ -3330,6 +3350,7 @@ assert(VM_Version::supports_evex(), ""); InstructionMark im(this); InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_is_evex_instruction(); attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit); int nds_enc = nds->is_valid() ? nds->encoding() : 0; int dst_enc = kdst->encoding(); @@ -3634,7 +3655,7 @@ void Assembler::pshufd(XMMRegister dst, XMMRegister src, int mode) { assert(isByte(mode), "invalid value"); NOT_LP64(assert(VM_Version::supports_sse2(), "")); - int vector_len = VM_Version::supports_evex() ? AVX_512bit : AVX_128bit; + int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_128bit; InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes); emit_int8(0x70); @@ -5702,7 +5723,7 @@ void Assembler::vinsertf128(XMMRegister dst, XMMRegister nds, XMMRegister src, uint8_t imm8) { assert(VM_Version::supports_avx(), ""); assert(imm8 <= 0x01, "imm8: %u", imm8); - int vector_len = VM_Version::supports_evex() ? AVX_512bit : AVX_256bit; + int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_256bit; InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false); int nds_enc = nds->is_valid() ? nds->encoding() : 0; int encode = vex_prefix_and_encode(dst->encoding(), nds_enc, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); @@ -5782,7 +5803,7 @@ assert(VM_Version::supports_avx(), ""); assert(dst != xnoreg, "sanity"); assert(imm8 <= 0x01, "imm8: %u", imm8); - int vector_len = VM_Version::supports_evex() ? AVX_512bit : AVX_256bit; + int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_256bit; int nds_enc = nds->is_valid() ? nds->encoding() : 0; InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false); @@ -5799,7 +5820,7 @@ void Assembler::vextractf128(XMMRegister dst, XMMRegister src, uint8_t imm8) { assert(VM_Version::supports_avx(), ""); assert(imm8 <= 0x01, "imm8: %u", imm8); - int vector_len = VM_Version::supports_evex() ? AVX_512bit : AVX_256bit; + int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_256bit; InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false); int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); emit_int8(0x19); @@ -5813,7 +5834,7 @@ assert(VM_Version::supports_avx(), ""); assert(src != xnoreg, "sanity"); assert(imm8 <= 0x01, "imm8: %u", imm8); - int vector_len = VM_Version::supports_evex() ? AVX_512bit : AVX_256bit; + int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_256bit; InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit); @@ -5828,7 +5849,7 @@ void Assembler::vinserti128(XMMRegister dst, XMMRegister nds, XMMRegister src, uint8_t imm8) { assert(VM_Version::supports_avx2(), ""); assert(imm8 <= 0x01, "imm8: %u", imm8); - int vector_len = VM_Version::supports_evex() ? AVX_512bit : AVX_256bit; + int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_256bit; InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false); int nds_enc = nds->is_valid() ? nds->encoding() : 0; int encode = vex_prefix_and_encode(dst->encoding(), nds_enc, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); @@ -5856,7 +5877,7 @@ assert(VM_Version::supports_avx2(), ""); assert(dst != xnoreg, "sanity"); assert(imm8 <= 0x01, "imm8: %u", imm8); - int vector_len = VM_Version::supports_evex() ? AVX_512bit : AVX_256bit; + int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_256bit; int nds_enc = nds->is_valid() ? nds->encoding() : 0; InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false); @@ -5873,7 +5894,7 @@ void Assembler::vextracti128(XMMRegister dst, XMMRegister src, uint8_t imm8) { assert(VM_Version::supports_avx(), ""); assert(imm8 <= 0x01, "imm8: %u", imm8); - int vector_len = VM_Version::supports_evex() ? AVX_512bit : AVX_256bit; + int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_256bit; InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false); int encode = vex_prefix_and_encode(src->encoding(), 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes); emit_int8(0x39); @@ -5887,7 +5908,7 @@ assert(VM_Version::supports_avx2(), ""); assert(src != xnoreg, "sanity"); assert(imm8 <= 0x01, "imm8: %u", imm8); - int vector_len = VM_Version::supports_evex() ? AVX_512bit : AVX_256bit; + int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_256bit; InstructionMark im(this); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ false); attributes.set_address_attributes(/* tuple_type */ EVEX_T4, /* input_size_in_bits */ EVEX_32bit); @@ -6147,7 +6168,11 @@ assert(VM_Version::supports_evex(), ""); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true); int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); - emit_int8(0x7A); + if (attributes.is_evex_instruction()) { + emit_int8(0x7A); + } else { + emit_int8(0x78); + } emit_int8((unsigned char)(0xC0 | encode)); } @@ -6156,7 +6181,11 @@ assert(VM_Version::supports_evex(), ""); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true); int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); - emit_int8(0x7B); + if (attributes.is_evex_instruction()) { + emit_int8(0x7B); + } else { + emit_int8(0x79); + } emit_int8((unsigned char)(0xC0 | encode)); } @@ -6165,7 +6194,11 @@ assert(VM_Version::supports_evex(), ""); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); - emit_int8(0x7C); + if (attributes.is_evex_instruction()) { + emit_int8(0x7C); + } else { + emit_int8(0x58); + } emit_int8((unsigned char)(0xC0 | encode)); } @@ -6174,7 +6207,11 @@ assert(VM_Version::supports_evex(), ""); InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); - emit_int8(0x7C); + if (attributes.is_evex_instruction()) { + emit_int8(0x7C); + } else { + emit_int8(0x59); + } emit_int8((unsigned char)(0xC0 | encode)); } @@ -6793,7 +6830,7 @@ attributes->set_current_assembler(this); // if vector length is turned off, revert to AVX for vectors smaller than 512-bit - if ((UseAVX > 2) && _legacy_mode_vl && attributes->uses_vl()) { + if (UseAVX > 2 && _legacy_mode_vl && attributes->uses_vl()) { switch (attributes->get_vector_len()) { case AVX_128bit: case AVX_256bit: @@ -6802,7 +6839,27 @@ } } - if ((UseAVX > 2) && !attributes->is_legacy_mode()) + // For pure EVEX check and see if this instruction + // is allowed in legacy mode and has resources which will + // fit in it. Pure EVEX instructions will use set_is_evex_instruction in their definition, + // else that field is set when we encode to EVEX + if (UseAVX > 2 && !attributes->is_legacy_mode() && + !_is_managed && !attributes->is_evex_instruction()) { + if (!_legacy_mode_vl && attributes->get_vector_len() != AVX_512bit) { + bool check_register_bank = NOT_IA32(true) IA32_ONLY(false); + if (check_register_bank) { + // check nds_enc and xreg_enc for upper bank usage + if (nds_enc < 16 && xreg_enc < 16) { + attributes->set_is_legacy_mode(); + } + } else { + attributes->set_is_legacy_mode(); + } + } + } + + _is_managed = false; + if (UseAVX > 2 && !attributes->is_legacy_mode()) { bool evex_r = (xreg_enc >= 16); bool evex_v = (nds_enc >= 16); @@ -6819,15 +6876,20 @@ bool vex_x = false; set_attributes(attributes); attributes->set_current_assembler(this); + bool check_register_bank = NOT_IA32(true) IA32_ONLY(false); // if vector length is turned off, revert to AVX for vectors smaller than 512-bit - if ((UseAVX > 2) && _legacy_mode_vl && attributes->uses_vl()) { + if (UseAVX > 2 && _legacy_mode_vl && attributes->uses_vl()) { switch (attributes->get_vector_len()) { case AVX_128bit: case AVX_256bit: - if ((dst_enc >= 16) | (nds_enc >= 16) | (src_enc >= 16)) { - // up propagate arithmetic instructions to meet RA requirements - attributes->set_vector_len(AVX_512bit); + if (check_register_bank) { + if (dst_enc >= 16 || nds_enc >= 16 || src_enc >= 16) { + // up propagate arithmetic instructions to meet RA requirements + attributes->set_vector_len(AVX_512bit); + } else { + attributes->set_is_legacy_mode(); + } } else { attributes->set_is_legacy_mode(); } @@ -6835,7 +6897,26 @@ } } - if ((UseAVX > 2) && !attributes->is_legacy_mode()) + // For pure EVEX check and see if this instruction + // is allowed in legacy mode and has resources which will + // fit in it. Pure EVEX instructions will use set_is_evex_instruction in their definition, + // else that field is set when we encode to EVEX + if (UseAVX > 2 && !attributes->is_legacy_mode() && + !_is_managed && !attributes->is_evex_instruction()) { + if (!_legacy_mode_vl && attributes->get_vector_len() != AVX_512bit) { + if (check_register_bank) { + // check dst_enc, nds_enc and src_enc for upper bank usage + if (dst_enc < 16 && nds_enc < 16 && src_enc < 16) { + attributes->set_is_legacy_mode(); + } + } else { + attributes->set_is_legacy_mode(); + } + } + } + + _is_managed = false; + if (UseAVX > 2 && !attributes->is_legacy_mode()) { bool evex_r = (dst_enc >= 16); bool evex_v = (nds_enc >= 16); diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/cpu/x86/vm/assembler_x86.hpp --- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp Thu Mar 31 14:25:35 2016 -0700 @@ -605,6 +605,7 @@ bool _legacy_mode_dq; bool _legacy_mode_vl; bool _legacy_mode_vlbw; + bool _is_managed; class InstructionAttr *_attributes; @@ -811,12 +812,17 @@ _legacy_mode_dq = (VM_Version::supports_avx512dq() == false); _legacy_mode_vl = (VM_Version::supports_avx512vl() == false); _legacy_mode_vlbw = (VM_Version::supports_avx512vlbw() == false); + _is_managed = false; _attributes = NULL; } void set_attributes(InstructionAttr *attributes) { _attributes = attributes; } void clear_attributes(void) { _attributes = NULL; } + void set_managed(void) { _is_managed = true; } + void clear_managed(void) { _is_managed = false; } + bool is_managed(void) { return _is_managed; } + void lea(Register dst, Address src); void mov(Register dst, Register src); diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp --- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -1646,31 +1646,15 @@ __ jmp(done); __ bind(runtime); - __ push(rcx); -#ifdef _LP64 - __ push(r8); - __ push(r9); - __ push(r10); - __ push(r11); -# ifndef _WIN64 - __ push(rdi); - __ push(rsi); -# endif -#endif + + save_live_registers(sasm, 3); + // load the pre-value f.load_argument(0, rcx); __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), rcx, thread); -#ifdef _LP64 -# ifndef _WIN64 - __ pop(rsi); - __ pop(rdi); -# endif - __ pop(r11); - __ pop(r10); - __ pop(r9); - __ pop(r8); -#endif - __ pop(rcx); + + restore_live_registers(sasm); + __ bind(done); __ pop(rdx); @@ -1744,27 +1728,13 @@ __ jmp(enqueued); __ bind(runtime); -#ifdef _LP64 - __ push(r8); - __ push(r9); - __ push(r10); - __ push(r11); -# ifndef _WIN64 - __ push(rdi); - __ push(rsi); -# endif -#endif + + save_live_registers(sasm, 3); + __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), card_addr, thread); -#ifdef _LP64 -# ifndef _WIN64 - __ pop(rsi); - __ pop(rdi); -# endif - __ pop(r11); - __ pop(r10); - __ pop(r9); - __ pop(r8); -#endif + + restore_live_registers(sasm); + __ bind(enqueued); __ pop(rdx); diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/cpu/x86/vm/jvmciCodeInstaller_x86.cpp --- a/hotspot/src/cpu/x86/vm/jvmciCodeInstaller_x86.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/cpu/x86/vm/jvmciCodeInstaller_x86.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -96,7 +96,7 @@ #endif } else { address operand = Assembler::locate_operand(pc, Assembler::imm_operand); - *((Metadata**) operand) = record_metadata_reference(constant, CHECK); + *((void**) operand) = record_metadata_reference(constant, CHECK); TRACE_jvmci_3("relocating (metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand)); } } diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp --- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -2600,15 +2600,12 @@ // rax - input length // - address generate_cipherBlockChaining_decryptAESCrypt() { + address generate_cipherBlockChaining_decryptAESCrypt_Parallel() { assert(UseAES, "need AES instructions and misaligned SSE support"); __ align(CodeEntryAlignment); StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_decryptAESCrypt"); address start = __ pc(); - Label L_exit, L_key_192_256, L_key_256; - Label L_singleBlock_loopTop_128; - Label L_singleBlock_loopTop_192, L_singleBlock_loopTop_256; const Register from = rsi; // source array address const Register to = rdx; // destination array address const Register key = rcx; // key array address @@ -2617,14 +2614,24 @@ const Register len_reg = rbx; // src len (must be multiple of blocksize 16) const Register pos = rax; - // xmm register assignments for the loops below - const XMMRegister xmm_result = xmm0; - const XMMRegister xmm_temp = xmm1; - // first 6 keys preloaded into xmm2-xmm7 - const int XMM_REG_NUM_KEY_FIRST = 2; - const int XMM_REG_NUM_KEY_LAST = 7; - const int FIRST_NON_REG_KEY_offset = 0x70; - const XMMRegister xmm_key_first = as_XMMRegister(XMM_REG_NUM_KEY_FIRST); + const int PARALLEL_FACTOR = 4; + const int ROUNDS[3] = { 10, 12, 14 }; //aes rounds for key128, key192, key256 + + Label L_exit; + Label L_singleBlock_loopTop[3]; //128, 192, 256 + Label L_multiBlock_loopTop[3]; //128, 192, 256 + + const XMMRegister xmm_prev_block_cipher = xmm0; // holds cipher of previous block + const XMMRegister xmm_key_shuf_mask = xmm1; + + const XMMRegister xmm_key_tmp0 = xmm2; + const XMMRegister xmm_key_tmp1 = xmm3; + + // registers holding the six results in the parallelized loop + const XMMRegister xmm_result0 = xmm4; + const XMMRegister xmm_result1 = xmm5; + const XMMRegister xmm_result2 = xmm6; + const XMMRegister xmm_result3 = xmm7; __ enter(); // required for proper stackwalking of RuntimeStub frame handleSOERegisters(true /*saving*/); @@ -2643,126 +2650,123 @@ const Address key_param (rbp, 8+8); const Address rvec_param (rbp, 8+12); const Address len_param (rbp, 8+16); + __ movptr(from , from_param); __ movptr(to , to_param); __ movptr(key , key_param); __ movptr(rvec , rvec_param); __ movptr(len_reg , len_param); - // the java expanded key ordering is rotated one position from what we want - // so we start from 0x10 here and hit 0x00 last - const XMMRegister xmm_key_shuf_mask = xmm1; // used temporarily to swap key bytes up front __ movdqu(xmm_key_shuf_mask, ExternalAddress(StubRoutines::x86::key_shuffle_mask_addr())); - // load up xmm regs 2 thru 6 with first 5 keys - for (int rnum = XMM_REG_NUM_KEY_FIRST, offset = 0x10; rnum <= XMM_REG_NUM_KEY_LAST; rnum++) { - load_key(as_XMMRegister(rnum), key, offset, xmm_key_shuf_mask); - offset += 0x10; - } - - // inside here, use the rvec register to point to previous block cipher - // with which we xor at the end of each newly decrypted block - const Register prev_block_cipher_ptr = rvec; + __ movdqu(xmm_prev_block_cipher, Address(rvec, 0x00)); // initialize with initial rvec + + __ xorptr(pos, pos); // now split to different paths depending on the keylen (len in ints of AESCrypt.KLE array (52=192, or 60=256)) - __ movl(rax, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT))); - __ cmpl(rax, 44); - __ jcc(Assembler::notEqual, L_key_192_256); - - - // 128-bit code follows here, parallelized - __ movl(pos, 0); - __ align(OptoLoopAlignment); - __ BIND(L_singleBlock_loopTop_128); - __ cmpptr(len_reg, 0); // any blocks left?? - __ jcc(Assembler::equal, L_exit); - __ movdqu(xmm_result, Address(from, pos, Address::times_1, 0)); // get next 16 bytes of cipher input - __ pxor (xmm_result, xmm_key_first); // do the aes dec rounds - for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST; rnum++) { - __ aesdec(xmm_result, as_XMMRegister(rnum)); - } - for (int key_offset = FIRST_NON_REG_KEY_offset; key_offset <= 0xa0; key_offset += 0x10) { // 128-bit runs up to key offset a0 - aes_dec_key(xmm_result, xmm_temp, key, key_offset); - } - load_key(xmm_temp, key, 0x00); // final key is stored in java expanded array at offset 0 - __ aesdeclast(xmm_result, xmm_temp); - __ movdqu(xmm_temp, Address(prev_block_cipher_ptr, 0x00)); - __ pxor (xmm_result, xmm_temp); // xor with the current r vector - __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result); // store into the next 16 bytes of output - // no need to store r to memory until we exit - __ lea(prev_block_cipher_ptr, Address(from, pos, Address::times_1, 0)); // set up new ptr - __ addptr(pos, AESBlockSize); - __ subptr(len_reg, AESBlockSize); - __ jmp(L_singleBlock_loopTop_128); - + // rvec is reused + __ movl(rvec, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT))); + __ cmpl(rvec, 52); + __ jcc(Assembler::equal, L_multiBlock_loopTop[1]); + __ cmpl(rvec, 60); + __ jcc(Assembler::equal, L_multiBlock_loopTop[2]); + +#define DoFour(opc, src_reg) \ + __ opc(xmm_result0, src_reg); \ + __ opc(xmm_result1, src_reg); \ + __ opc(xmm_result2, src_reg); \ + __ opc(xmm_result3, src_reg); \ + + for (int k = 0; k < 3; ++k) { + __ align(OptoLoopAlignment); + __ BIND(L_multiBlock_loopTop[k]); + __ cmpptr(len_reg, PARALLEL_FACTOR * AESBlockSize); // see if at least 4 blocks left + __ jcc(Assembler::less, L_singleBlock_loopTop[k]); + + __ movdqu(xmm_result0, Address(from, pos, Address::times_1, 0 * AESBlockSize)); // get next 4 blocks into xmmresult registers + __ movdqu(xmm_result1, Address(from, pos, Address::times_1, 1 * AESBlockSize)); + __ movdqu(xmm_result2, Address(from, pos, Address::times_1, 2 * AESBlockSize)); + __ movdqu(xmm_result3, Address(from, pos, Address::times_1, 3 * AESBlockSize)); + + // the java expanded key ordering is rotated one position from what we want + // so we start from 0x10 here and hit 0x00 last + load_key(xmm_key_tmp0, key, 0x10, xmm_key_shuf_mask); + DoFour(pxor, xmm_key_tmp0); //xor with first key + // do the aes dec rounds + for (int rnum = 1; rnum <= ROUNDS[k];) { + //load two keys at a time + //k1->0x20, ..., k9->0xa0, k10->0x00 + load_key(xmm_key_tmp1, key, (rnum + 1) * 0x10, xmm_key_shuf_mask); + load_key(xmm_key_tmp0, key, ((rnum + 2) % (ROUNDS[k] + 1)) * 0x10, xmm_key_shuf_mask); // hit 0x00 last! + DoFour(aesdec, xmm_key_tmp1); + rnum++; + if (rnum != ROUNDS[k]) { + DoFour(aesdec, xmm_key_tmp0); + } + else { + DoFour(aesdeclast, xmm_key_tmp0); + } + rnum++; + } + + // for each result, xor with the r vector of previous cipher block + __ pxor(xmm_result0, xmm_prev_block_cipher); + __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 0 * AESBlockSize)); + __ pxor(xmm_result1, xmm_prev_block_cipher); + __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 1 * AESBlockSize)); + __ pxor(xmm_result2, xmm_prev_block_cipher); + __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 2 * AESBlockSize)); + __ pxor(xmm_result3, xmm_prev_block_cipher); + __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 3 * AESBlockSize)); // this will carry over to next set of blocks + + // store 4 results into the next 64 bytes of output + __ movdqu(Address(to, pos, Address::times_1, 0 * AESBlockSize), xmm_result0); + __ movdqu(Address(to, pos, Address::times_1, 1 * AESBlockSize), xmm_result1); + __ movdqu(Address(to, pos, Address::times_1, 2 * AESBlockSize), xmm_result2); + __ movdqu(Address(to, pos, Address::times_1, 3 * AESBlockSize), xmm_result3); + + __ addptr(pos, 4 * AESBlockSize); + __ subptr(len_reg, 4 * AESBlockSize); + __ jmp(L_multiBlock_loopTop[k]); + + //singleBlock starts here + __ align(OptoLoopAlignment); + __ BIND(L_singleBlock_loopTop[k]); + __ cmpptr(len_reg, 0); // any blocks left? + __ jcc(Assembler::equal, L_exit); + __ movdqu(xmm_result0, Address(from, pos, Address::times_1, 0)); // get next 16 bytes of cipher input + __ movdqa(xmm_result1, xmm_result0); + + load_key(xmm_key_tmp0, key, 0x10, xmm_key_shuf_mask); + __ pxor(xmm_result0, xmm_key_tmp0); + // do the aes dec rounds + for (int rnum = 1; rnum < ROUNDS[k]; rnum++) { + // the java expanded key ordering is rotated one position from what we want + load_key(xmm_key_tmp0, key, (rnum + 1) * 0x10, xmm_key_shuf_mask); + __ aesdec(xmm_result0, xmm_key_tmp0); + } + load_key(xmm_key_tmp0, key, 0x00, xmm_key_shuf_mask); + __ aesdeclast(xmm_result0, xmm_key_tmp0); + __ pxor(xmm_result0, xmm_prev_block_cipher); // xor with the current r vector + __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result0); // store into the next 16 bytes of output + // no need to store r to memory until we exit + __ movdqa(xmm_prev_block_cipher, xmm_result1); // set up next r vector with cipher input from this block + + __ addptr(pos, AESBlockSize); + __ subptr(len_reg, AESBlockSize); + __ jmp(L_singleBlock_loopTop[k]); + }//for 128/192/256 __ BIND(L_exit); - __ movdqu(xmm_temp, Address(prev_block_cipher_ptr, 0x00)); - __ movptr(rvec , rvec_param); // restore this since used in loop - __ movdqu(Address(rvec, 0), xmm_temp); // final value of r stored in rvec of CipherBlockChaining object + __ movptr(rvec, rvec_param); // restore this since reused earlier + __ movdqu(Address(rvec, 0), xmm_prev_block_cipher); // final value of r stored in rvec of CipherBlockChaining object handleSOERegisters(false /*restoring*/); - __ movptr(rax, len_param); // return length - __ leave(); // required for proper stackwalking of RuntimeStub frame + __ movptr(rax, len_param); // return length + __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); - - __ BIND(L_key_192_256); - // here rax = len in ints of AESCrypt.KLE array (52=192, or 60=256) - __ cmpl(rax, 52); - __ jcc(Assembler::notEqual, L_key_256); - - // 192-bit code follows here (could be optimized to use parallelism) - __ movl(pos, 0); - __ align(OptoLoopAlignment); - __ BIND(L_singleBlock_loopTop_192); - __ movdqu(xmm_result, Address(from, pos, Address::times_1, 0)); // get next 16 bytes of cipher input - __ pxor (xmm_result, xmm_key_first); // do the aes dec rounds - for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST; rnum++) { - __ aesdec(xmm_result, as_XMMRegister(rnum)); - } - for (int key_offset = FIRST_NON_REG_KEY_offset; key_offset <= 0xc0; key_offset += 0x10) { // 192-bit runs up to key offset c0 - aes_dec_key(xmm_result, xmm_temp, key, key_offset); - } - load_key(xmm_temp, key, 0x00); // final key is stored in java expanded array at offset 0 - __ aesdeclast(xmm_result, xmm_temp); - __ movdqu(xmm_temp, Address(prev_block_cipher_ptr, 0x00)); - __ pxor (xmm_result, xmm_temp); // xor with the current r vector - __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result); // store into the next 16 bytes of output - // no need to store r to memory until we exit - __ lea(prev_block_cipher_ptr, Address(from, pos, Address::times_1, 0)); // set up new ptr - __ addptr(pos, AESBlockSize); - __ subptr(len_reg, AESBlockSize); - __ jcc(Assembler::notEqual,L_singleBlock_loopTop_192); - __ jmp(L_exit); - - __ BIND(L_key_256); - // 256-bit code follows here (could be optimized to use parallelism) - __ movl(pos, 0); - __ align(OptoLoopAlignment); - __ BIND(L_singleBlock_loopTop_256); - __ movdqu(xmm_result, Address(from, pos, Address::times_1, 0)); // get next 16 bytes of cipher input - __ pxor (xmm_result, xmm_key_first); // do the aes dec rounds - for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST; rnum++) { - __ aesdec(xmm_result, as_XMMRegister(rnum)); - } - for (int key_offset = FIRST_NON_REG_KEY_offset; key_offset <= 0xe0; key_offset += 0x10) { // 256-bit runs up to key offset e0 - aes_dec_key(xmm_result, xmm_temp, key, key_offset); - } - load_key(xmm_temp, key, 0x00); // final key is stored in java expanded array at offset 0 - __ aesdeclast(xmm_result, xmm_temp); - __ movdqu(xmm_temp, Address(prev_block_cipher_ptr, 0x00)); - __ pxor (xmm_result, xmm_temp); // xor with the current r vector - __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result); // store into the next 16 bytes of output - // no need to store r to memory until we exit - __ lea(prev_block_cipher_ptr, Address(from, pos, Address::times_1, 0)); // set up new ptr - __ addptr(pos, AESBlockSize); - __ subptr(len_reg, AESBlockSize); - __ jcc(Assembler::notEqual,L_singleBlock_loopTop_256); - __ jmp(L_exit); - return start; } - // CTR AES crypt. // In 32-bit stub, parallelize 4 blocks at a time // Arguments: @@ -3894,7 +3898,7 @@ StubRoutines::_aescrypt_encryptBlock = generate_aescrypt_encryptBlock(); StubRoutines::_aescrypt_decryptBlock = generate_aescrypt_decryptBlock(); StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt(); - StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt(); + StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt_Parallel(); } if (UseAESCTRIntrinsics) { diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp --- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -3469,16 +3469,12 @@ // Output: // rax - input length // - address generate_cipherBlockChaining_decryptAESCrypt_Parallel() { assert(UseAES, "need AES instructions and misaligned SSE support"); __ align(CodeEntryAlignment); StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_decryptAESCrypt"); address start = __ pc(); - Label L_exit, L_key_192_256, L_key_256; - Label L_singleBlock_loopTop_128, L_multiBlock_loopTop_128; - Label L_singleBlock_loopTop_192, L_singleBlock_loopTop_256; const Register from = c_rarg0; // source array address const Register to = c_rarg1; // destination array address const Register key = c_rarg2; // key array address @@ -3492,7 +3488,17 @@ #endif const Register pos = rax; - // keys 0-10 preloaded into xmm2-xmm12 + const int PARALLEL_FACTOR = 4; + const int ROUNDS[3] = { 10, 12, 14 }; // aes rounds for key128, key192, key256 + + Label L_exit; + Label L_singleBlock_loopTopHead[3]; // 128, 192, 256 + Label L_singleBlock_loopTopHead2[3]; // 128, 192, 256 + Label L_singleBlock_loopTop[3]; // 128, 192, 256 + Label L_multiBlock_loopTopHead[3]; // 128, 192, 256 + Label L_multiBlock_loopTop[3]; // 128, 192, 256 + + // keys 0-10 preloaded into xmm5-xmm15 const int XMM_REG_NUM_KEY_FIRST = 5; const int XMM_REG_NUM_KEY_LAST = 15; const XMMRegister xmm_key_first = as_XMMRegister(XMM_REG_NUM_KEY_FIRST); @@ -3519,7 +3525,7 @@ #else __ push(len_reg); // Save #endif - + __ push(rbx); // the java expanded key ordering is rotated one position from what we want // so we start from 0x10 here and hit 0x00 last const XMMRegister xmm_key_shuf_mask = xmm1; // used temporarily to swap key bytes up front @@ -3541,85 +3547,173 @@ __ movdqu(xmm_prev_block_cipher, Address(rvec, 0x00)); // initialize with initial rvec + __ xorptr(pos, pos); + // now split to different paths depending on the keylen (len in ints of AESCrypt.KLE array (52=192, or 60=256)) - __ movl(rax, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT))); - __ cmpl(rax, 44); - __ jcc(Assembler::notEqual, L_key_192_256); - - - // 128-bit code follows here, parallelized - __ movptr(pos, 0); - __ align(OptoLoopAlignment); - __ BIND(L_multiBlock_loopTop_128); - __ cmpptr(len_reg, 4*AESBlockSize); // see if at least 4 blocks left - __ jcc(Assembler::less, L_singleBlock_loopTop_128); - - __ movdqu(xmm_result0, Address(from, pos, Address::times_1, 0*AESBlockSize)); // get next 4 blocks into xmmresult registers - __ movdqu(xmm_result1, Address(from, pos, Address::times_1, 1*AESBlockSize)); - __ movdqu(xmm_result2, Address(from, pos, Address::times_1, 2*AESBlockSize)); - __ movdqu(xmm_result3, Address(from, pos, Address::times_1, 3*AESBlockSize)); - -#define DoFour(opc, src_reg) \ - __ opc(xmm_result0, src_reg); \ - __ opc(xmm_result1, src_reg); \ - __ opc(xmm_result2, src_reg); \ - __ opc(xmm_result3, src_reg); - - DoFour(pxor, xmm_key_first); - for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST - 1; rnum++) { - DoFour(aesdec, as_XMMRegister(rnum)); - } - DoFour(aesdeclast, xmm_key_last); - // for each result, xor with the r vector of previous cipher block - __ pxor(xmm_result0, xmm_prev_block_cipher); - __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 0*AESBlockSize)); - __ pxor(xmm_result1, xmm_prev_block_cipher); - __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 1*AESBlockSize)); - __ pxor(xmm_result2, xmm_prev_block_cipher); - __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 2*AESBlockSize)); - __ pxor(xmm_result3, xmm_prev_block_cipher); - __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 3*AESBlockSize)); // this will carry over to next set of blocks - - __ movdqu(Address(to, pos, Address::times_1, 0*AESBlockSize), xmm_result0); // store 4 results into the next 64 bytes of output - __ movdqu(Address(to, pos, Address::times_1, 1*AESBlockSize), xmm_result1); - __ movdqu(Address(to, pos, Address::times_1, 2*AESBlockSize), xmm_result2); - __ movdqu(Address(to, pos, Address::times_1, 3*AESBlockSize), xmm_result3); - - __ addptr(pos, 4*AESBlockSize); - __ subptr(len_reg, 4*AESBlockSize); - __ jmp(L_multiBlock_loopTop_128); - - // registers used in the non-parallelized loops - // xmm register assignments for the loops below - const XMMRegister xmm_result = xmm0; - const XMMRegister xmm_prev_block_cipher_save = xmm2; - const XMMRegister xmm_key11 = xmm3; - const XMMRegister xmm_key12 = xmm4; - const XMMRegister xmm_temp = xmm4; - - __ align(OptoLoopAlignment); - __ BIND(L_singleBlock_loopTop_128); - __ cmpptr(len_reg, 0); // any blocks left?? - __ jcc(Assembler::equal, L_exit); - __ movdqu(xmm_result, Address(from, pos, Address::times_1, 0)); // get next 16 bytes of cipher input - __ movdqa(xmm_prev_block_cipher_save, xmm_result); // save for next r vector - __ pxor (xmm_result, xmm_key_first); // do the aes dec rounds - for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST - 1; rnum++) { - __ aesdec(xmm_result, as_XMMRegister(rnum)); - } - __ aesdeclast(xmm_result, xmm_key_last); - __ pxor (xmm_result, xmm_prev_block_cipher); // xor with the current r vector - __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result); // store into the next 16 bytes of output - // no need to store r to memory until we exit - __ movdqa(xmm_prev_block_cipher, xmm_prev_block_cipher_save); // set up next r vector with cipher input from this block - - __ addptr(pos, AESBlockSize); - __ subptr(len_reg, AESBlockSize); - __ jmp(L_singleBlock_loopTop_128); - + __ movl(rbx, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT))); + __ cmpl(rbx, 52); + __ jcc(Assembler::equal, L_multiBlock_loopTopHead[1]); + __ cmpl(rbx, 60); + __ jcc(Assembler::equal, L_multiBlock_loopTopHead[2]); + +#define DoFour(opc, src_reg) \ + __ opc(xmm_result0, src_reg); \ + __ opc(xmm_result1, src_reg); \ + __ opc(xmm_result2, src_reg); \ + __ opc(xmm_result3, src_reg); \ + + for (int k = 0; k < 3; ++k) { + __ BIND(L_multiBlock_loopTopHead[k]); + if (k != 0) { + __ cmpptr(len_reg, PARALLEL_FACTOR * AESBlockSize); // see if at least 4 blocks left + __ jcc(Assembler::less, L_singleBlock_loopTopHead2[k]); + } + if (k == 1) { + __ subptr(rsp, 6 * wordSize); + __ movdqu(Address(rsp, 0), xmm15); //save last_key from xmm15 + load_key(xmm15, key, 0xb0); // 0xb0; 192-bit key goes up to 0xc0 + __ movdqu(Address(rsp, 2 * wordSize), xmm15); + load_key(xmm1, key, 0xc0); // 0xc0; + __ movdqu(Address(rsp, 4 * wordSize), xmm1); + } else if (k == 2) { + __ subptr(rsp, 10 * wordSize); + __ movdqu(Address(rsp, 0), xmm15); //save last_key from xmm15 + load_key(xmm15, key, 0xd0); // 0xd0; 256-bit key goes upto 0xe0 + __ movdqu(Address(rsp, 6 * wordSize), xmm15); + load_key(xmm1, key, 0xe0); // 0xe0; + __ movdqu(Address(rsp, 8 * wordSize), xmm1); + load_key(xmm15, key, 0xb0); // 0xb0; + __ movdqu(Address(rsp, 2 * wordSize), xmm15); + load_key(xmm1, key, 0xc0); // 0xc0; + __ movdqu(Address(rsp, 4 * wordSize), xmm1); + } + __ align(OptoLoopAlignment); + __ BIND(L_multiBlock_loopTop[k]); + __ cmpptr(len_reg, PARALLEL_FACTOR * AESBlockSize); // see if at least 4 blocks left + __ jcc(Assembler::less, L_singleBlock_loopTopHead[k]); + + if (k != 0) { + __ movdqu(xmm15, Address(rsp, 2 * wordSize)); + __ movdqu(xmm1, Address(rsp, 4 * wordSize)); + } + + __ movdqu(xmm_result0, Address(from, pos, Address::times_1, 0 * AESBlockSize)); // get next 4 blocks into xmmresult registers + __ movdqu(xmm_result1, Address(from, pos, Address::times_1, 1 * AESBlockSize)); + __ movdqu(xmm_result2, Address(from, pos, Address::times_1, 2 * AESBlockSize)); + __ movdqu(xmm_result3, Address(from, pos, Address::times_1, 3 * AESBlockSize)); + + DoFour(pxor, xmm_key_first); + if (k == 0) { + for (int rnum = 1; rnum < ROUNDS[k]; rnum++) { + DoFour(aesdec, as_XMMRegister(rnum + XMM_REG_NUM_KEY_FIRST)); + } + DoFour(aesdeclast, xmm_key_last); + } else if (k == 1) { + for (int rnum = 1; rnum <= ROUNDS[k]-2; rnum++) { + DoFour(aesdec, as_XMMRegister(rnum + XMM_REG_NUM_KEY_FIRST)); + } + __ movdqu(xmm_key_last, Address(rsp, 0)); // xmm15 needs to be loaded again. + DoFour(aesdec, xmm1); // key : 0xc0 + __ movdqu(xmm_prev_block_cipher, Address(rvec, 0x00)); // xmm1 needs to be loaded again + DoFour(aesdeclast, xmm_key_last); + } else if (k == 2) { + for (int rnum = 1; rnum <= ROUNDS[k] - 4; rnum++) { + DoFour(aesdec, as_XMMRegister(rnum + XMM_REG_NUM_KEY_FIRST)); + } + DoFour(aesdec, xmm1); // key : 0xc0 + __ movdqu(xmm15, Address(rsp, 6 * wordSize)); + __ movdqu(xmm1, Address(rsp, 8 * wordSize)); + DoFour(aesdec, xmm15); // key : 0xd0 + __ movdqu(xmm_key_last, Address(rsp, 0)); // xmm15 needs to be loaded again. + DoFour(aesdec, xmm1); // key : 0xe0 + __ movdqu(xmm_prev_block_cipher, Address(rvec, 0x00)); // xmm1 needs to be loaded again + DoFour(aesdeclast, xmm_key_last); + } + + // for each result, xor with the r vector of previous cipher block + __ pxor(xmm_result0, xmm_prev_block_cipher); + __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 0 * AESBlockSize)); + __ pxor(xmm_result1, xmm_prev_block_cipher); + __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 1 * AESBlockSize)); + __ pxor(xmm_result2, xmm_prev_block_cipher); + __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 2 * AESBlockSize)); + __ pxor(xmm_result3, xmm_prev_block_cipher); + __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 3 * AESBlockSize)); // this will carry over to next set of blocks + if (k != 0) { + __ movdqu(Address(rvec, 0x00), xmm_prev_block_cipher); + } + + __ movdqu(Address(to, pos, Address::times_1, 0 * AESBlockSize), xmm_result0); // store 4 results into the next 64 bytes of output + __ movdqu(Address(to, pos, Address::times_1, 1 * AESBlockSize), xmm_result1); + __ movdqu(Address(to, pos, Address::times_1, 2 * AESBlockSize), xmm_result2); + __ movdqu(Address(to, pos, Address::times_1, 3 * AESBlockSize), xmm_result3); + + __ addptr(pos, PARALLEL_FACTOR * AESBlockSize); + __ subptr(len_reg, PARALLEL_FACTOR * AESBlockSize); + __ jmp(L_multiBlock_loopTop[k]); + + // registers used in the non-parallelized loops + // xmm register assignments for the loops below + const XMMRegister xmm_result = xmm0; + const XMMRegister xmm_prev_block_cipher_save = xmm2; + const XMMRegister xmm_key11 = xmm3; + const XMMRegister xmm_key12 = xmm4; + const XMMRegister key_tmp = xmm4; + + __ BIND(L_singleBlock_loopTopHead[k]); + if (k == 1) { + __ addptr(rsp, 6 * wordSize); + } else if (k == 2) { + __ addptr(rsp, 10 * wordSize); + } + __ cmpptr(len_reg, 0); // any blocks left?? + __ jcc(Assembler::equal, L_exit); + __ BIND(L_singleBlock_loopTopHead2[k]); + if (k == 1) { + load_key(xmm_key11, key, 0xb0); // 0xb0; 192-bit key goes upto 0xc0 + load_key(xmm_key12, key, 0xc0); // 0xc0; 192-bit key goes upto 0xc0 + } + if (k == 2) { + load_key(xmm_key11, key, 0xb0); // 0xb0; 256-bit key goes upto 0xe0 + } + __ align(OptoLoopAlignment); + __ BIND(L_singleBlock_loopTop[k]); + __ movdqu(xmm_result, Address(from, pos, Address::times_1, 0)); // get next 16 bytes of cipher input + __ movdqa(xmm_prev_block_cipher_save, xmm_result); // save for next r vector + __ pxor(xmm_result, xmm_key_first); // do the aes dec rounds + for (int rnum = 1; rnum <= 9 ; rnum++) { + __ aesdec(xmm_result, as_XMMRegister(rnum + XMM_REG_NUM_KEY_FIRST)); + } + if (k == 1) { + __ aesdec(xmm_result, xmm_key11); + __ aesdec(xmm_result, xmm_key12); + } + if (k == 2) { + __ aesdec(xmm_result, xmm_key11); + load_key(key_tmp, key, 0xc0); + __ aesdec(xmm_result, key_tmp); + load_key(key_tmp, key, 0xd0); + __ aesdec(xmm_result, key_tmp); + load_key(key_tmp, key, 0xe0); + __ aesdec(xmm_result, key_tmp); + } + + __ aesdeclast(xmm_result, xmm_key_last); // xmm15 always came from key+0 + __ pxor(xmm_result, xmm_prev_block_cipher); // xor with the current r vector + __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result); // store into the next 16 bytes of output + // no need to store r to memory until we exit + __ movdqa(xmm_prev_block_cipher, xmm_prev_block_cipher_save); // set up next r vector with cipher input from this block + __ addptr(pos, AESBlockSize); + __ subptr(len_reg, AESBlockSize); + __ jcc(Assembler::notEqual, L_singleBlock_loopTop[k]); + if (k != 2) { + __ jmp(L_exit); + } + } //for 128/192/256 __ BIND(L_exit); __ movdqu(Address(rvec, 0), xmm_prev_block_cipher); // final value of r stored in rvec of CipherBlockChaining object + __ pop(rbx); #ifdef _WIN64 // restore regs belonging to calling function for (int i = 6; i <= XMM_REG_NUM_KEY_LAST; i++) { @@ -3631,69 +3725,8 @@ #endif __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); - - - __ BIND(L_key_192_256); - // here rax = len in ints of AESCrypt.KLE array (52=192, or 60=256) - load_key(xmm_key11, key, 0xb0); - __ cmpl(rax, 52); - __ jcc(Assembler::notEqual, L_key_256); - - // 192-bit code follows here (could be optimized to use parallelism) - load_key(xmm_key12, key, 0xc0); // 192-bit key goes up to c0 - __ movptr(pos, 0); - __ align(OptoLoopAlignment); - - __ BIND(L_singleBlock_loopTop_192); - __ movdqu(xmm_result, Address(from, pos, Address::times_1, 0)); // get next 16 bytes of cipher input - __ movdqa(xmm_prev_block_cipher_save, xmm_result); // save for next r vector - __ pxor (xmm_result, xmm_key_first); // do the aes dec rounds - for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST - 1; rnum++) { - __ aesdec(xmm_result, as_XMMRegister(rnum)); - } - __ aesdec(xmm_result, xmm_key11); - __ aesdec(xmm_result, xmm_key12); - __ aesdeclast(xmm_result, xmm_key_last); // xmm15 always came from key+0 - __ pxor (xmm_result, xmm_prev_block_cipher); // xor with the current r vector - __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result); // store into the next 16 bytes of output - // no need to store r to memory until we exit - __ movdqa(xmm_prev_block_cipher, xmm_prev_block_cipher_save); // set up next r vector with cipher input from this block - __ addptr(pos, AESBlockSize); - __ subptr(len_reg, AESBlockSize); - __ jcc(Assembler::notEqual,L_singleBlock_loopTop_192); - __ jmp(L_exit); - - __ BIND(L_key_256); - // 256-bit code follows here (could be optimized to use parallelism) - __ movptr(pos, 0); - __ align(OptoLoopAlignment); - - __ BIND(L_singleBlock_loopTop_256); - __ movdqu(xmm_result, Address(from, pos, Address::times_1, 0)); // get next 16 bytes of cipher input - __ movdqa(xmm_prev_block_cipher_save, xmm_result); // save for next r vector - __ pxor (xmm_result, xmm_key_first); // do the aes dec rounds - for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST - 1; rnum++) { - __ aesdec(xmm_result, as_XMMRegister(rnum)); - } - __ aesdec(xmm_result, xmm_key11); - load_key(xmm_temp, key, 0xc0); - __ aesdec(xmm_result, xmm_temp); - load_key(xmm_temp, key, 0xd0); - __ aesdec(xmm_result, xmm_temp); - load_key(xmm_temp, key, 0xe0); // 256-bit key goes up to e0 - __ aesdec(xmm_result, xmm_temp); - __ aesdeclast(xmm_result, xmm_key_last); // xmm15 came from key+0 - __ pxor (xmm_result, xmm_prev_block_cipher); // xor with the current r vector - __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result); // store into the next 16 bytes of output - // no need to store r to memory until we exit - __ movdqa(xmm_prev_block_cipher, xmm_prev_block_cipher_save); // set up next r vector with cipher input from this block - __ addptr(pos, AESBlockSize); - __ subptr(len_reg, AESBlockSize); - __ jcc(Assembler::notEqual,L_singleBlock_loopTop_256); - __ jmp(L_exit); - return start; - } +} address generate_upper_word_mask() { __ align(64); diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/cpu/x86/vm/x86_32.ad --- a/hotspot/src/cpu/x86/vm/x86_32.ad Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/cpu/x86/vm/x86_32.ad Thu Mar 31 14:25:35 2016 -0700 @@ -795,6 +795,9 @@ } if (cbuf) { MacroAssembler _masm(cbuf); + // EVEX spills remain EVEX: Compressed displacemement is better than AVX on spill mem operations, + // it maps more cases to single byte displacement + _masm.set_managed(); if (reg_lo+1 == reg_hi) { // double move? if (is_load) { __ movdbl(as_XMMRegister(Matcher::_regEncode[reg_lo]), Address(rsp, offset)); @@ -845,6 +848,8 @@ int src_hi, int dst_hi, int size, outputStream* st ) { if (cbuf) { MacroAssembler _masm(cbuf); + // EVEX spills remain EVEX: logic complex between full EVEX, partial and AVX, manage EVEX spill code one way. + _masm.set_managed(); if (src_lo+1 == src_hi && dst_lo+1 == dst_hi) { // double move? __ movdbl(as_XMMRegister(Matcher::_regEncode[dst_lo]), as_XMMRegister(Matcher::_regEncode[src_lo])); @@ -883,6 +888,8 @@ // 32-bit if (cbuf) { MacroAssembler _masm(cbuf); + // EVEX spills remain EVEX: logic complex between full EVEX, partial and AVX, manage EVEX spill code one way. + _masm.set_managed(); __ movdl(as_XMMRegister(Matcher::_regEncode[dst_lo]), as_Register(Matcher::_regEncode[src_lo])); #ifndef PRODUCT @@ -899,6 +906,8 @@ // 32-bit if (cbuf) { MacroAssembler _masm(cbuf); + // EVEX spills remain EVEX: logic complex between full EVEX, partial and AVX, manage EVEX spill code one way. + _masm.set_managed(); __ movdl(as_Register(Matcher::_regEncode[dst_lo]), as_XMMRegister(Matcher::_regEncode[src_lo])); #ifndef PRODUCT diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/cpu/zero/vm/globals_zero.hpp --- a/hotspot/src/cpu/zero/vm/globals_zero.hpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/cpu/zero/vm/globals_zero.hpp Thu Mar 31 14:25:35 2016 -0700 @@ -42,7 +42,8 @@ define_pd_global(intx, CodeEntryAlignment, 32); define_pd_global(intx, OptoLoopAlignment, 16); define_pd_global(intx, InlineFrequencyCount, 100); -define_pd_global(intx, InlineSmallCode, 1000 ); +define_pd_global(intx, InlineSmallCode, 1000); +define_pd_global(intx, InitArrayShortSize, -1); // not used #define DEFAULT_STACK_YELLOW_PAGES (2) #define DEFAULT_STACK_RED_PAGES (1) diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/NMethod.java --- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/NMethod.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/NMethod.java Thu Mar 31 14:25:35 2016 -0700 @@ -249,7 +249,6 @@ // public int age(); // public boolean isMarkedForDeoptimization(); // public boolean isMarkedForUnloading(); - // public boolean isMarkedForReclamation(); // public int level(); // public int version(); diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java Thu Mar 31 14:25:35 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -480,6 +480,11 @@ native String getSymbol(long metaspaceSymbol); /** + * Lookup a VMSymbol from a String. + */ + native long lookupSymbol(String symbol); + + /** * Looks for the next Java stack frame matching an entry in {@code methods}. * * @param frame the starting point of the search, where {@code null} refers to the topmost frame diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProvider.java --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProvider.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProvider.java Thu Mar 31 14:25:35 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,4 +39,6 @@ Constant readNarrowKlassPointerConstant(Constant base, long displacement, CompressEncoding encoding); Constant readMethodPointerConstant(Constant base, long displacement); + + Constant readSymbolConstant(Constant base, long displacement); } diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java Thu Mar 31 14:25:35 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,13 +82,13 @@ Object base = asObject(baseConstant); if (base != null) { switch (bits) { - case 8: + case Byte.SIZE: return UNSAFE.getByte(base, displacement); - case 16: + case Short.SIZE: return UNSAFE.getShort(base, displacement); - case 32: + case Integer.SIZE: return UNSAFE.getInt(base, displacement); - case 64: + case Long.SIZE: return UNSAFE.getLong(base, displacement); default: throw new JVMCIError("%d", bits); @@ -96,13 +96,13 @@ } else { long pointer = asRawPointer(baseConstant); switch (bits) { - case 8: + case Byte.SIZE: return UNSAFE.getByte(pointer + displacement); - case 16: + case Short.SIZE: return UNSAFE.getShort(pointer + displacement); - case 32: + case Integer.SIZE: return UNSAFE.getInt(pointer + displacement); - case 64: + case Long.SIZE: return UNSAFE.getLong(pointer + displacement); default: throw new JVMCIError("%d", bits); @@ -151,7 +151,8 @@ Object o = readRawObject(baseConstant, displacement, runtime.getConfig().useCompressedOops); return HotSpotObjectConstantImpl.forObject(o); } else { - return readPrimitiveConstant(kind, baseConstant, displacement, kind.getByteCount() * 8); + int bits = kind.getByteCount() * Byte.SIZE; + return readPrimitiveConstant(kind, baseConstant, displacement, bits); } } @@ -229,4 +230,16 @@ HotSpotResolvedJavaMethodImpl method = runtime.getCompilerToVM().getResolvedJavaMethod(baseObject, displacement); return HotSpotMetaspaceConstantImpl.forMetaspaceObject(method, false); } + + @Override + public Constant readSymbolConstant(Constant base, long displacement) { + int bits = runtime.getConfig().symbolPointerSize * Byte.SIZE; + long pointer = readRawValue(base, displacement, bits); + if (pointer == 0) { + return JavaConstant.NULL_POINTER; + } else { + String symbol = runtime.getCompilerToVM().getSymbol(pointer); + return new HotSpotSymbol(symbol, pointer).asConstant(); + } + } } diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java Thu Mar 31 14:25:35 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -78,6 +78,15 @@ return new HotSpotSignature(runtime, signature); } + public HotSpotSymbol lookupSymbol(String symbol) { + long pointer = runtime.getCompilerToVM().lookupSymbol(symbol); + if (pointer == 0) { + return null; + } else { + return new HotSpotSymbol(symbol, pointer); + } + } + /** * {@link Field} object of {@link Method#slot}. */ diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstant.java --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstant.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstant.java Thu Mar 31 14:25:35 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,4 +29,6 @@ HotSpotResolvedObjectType asResolvedJavaType(); HotSpotResolvedJavaMethod asResolvedJavaMethod(); + + HotSpotSymbol asSymbol(); } diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java Thu Mar 31 14:25:35 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -108,4 +108,11 @@ } return null; } + + public HotSpotSymbol asSymbol() { + if (metaspaceObject instanceof HotSpotSymbol) { + return (HotSpotSymbol) metaspaceObject; + } + return null; + } } diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSymbol.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSymbol.java Thu Mar 31 14:25:35 2016 -0700 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.meta.Constant; + +/** + * Class to access the C++ {@code vmSymbols} table. + */ +public final class HotSpotSymbol implements MetaspaceWrapperObject { + + private final String symbol; + private final long pointer; + + HotSpotSymbol(String symbol, long pointer) { + this.symbol = symbol; + this.pointer = pointer; + } + + public String getSymbol() { + return symbol; + } + + public Constant asConstant() { + return HotSpotMetaspaceConstantImpl.forMetaspaceObject(this, false); + } + + @Override + public long getMetaspacePointer() { + return pointer; + } + + @Override + public String toString() { + return "Symbol<" + symbol + ">"; + } +} diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java Thu Mar 31 14:25:35 2016 -0700 @@ -1001,6 +1001,7 @@ @HotSpotVMField(name = "Klass::_modifier_flags", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int klassModifierFlagsOffset; @HotSpotVMField(name = "Klass::_access_flags", type = "AccessFlags", get = HotSpotVMField.Type.OFFSET) @Stable public int klassAccessFlagsOffset; @HotSpotVMField(name = "Klass::_layout_helper", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int klassLayoutHelperOffset; + @HotSpotVMField(name = "Klass::_name", type = "Symbol*", get = HotSpotVMField.Type.OFFSET) @Stable public int klassNameOffset; @HotSpotVMConstant(name = "Klass::_lh_neutral_value") @Stable public int klassLayoutHelperNeutralValue; @HotSpotVMConstant(name = "Klass::_lh_instance_slow_path_bit") @Stable public int klassLayoutHelperInstanceSlowPathBit; @@ -1536,8 +1537,9 @@ @HotSpotVMAddress(name = "JVMCIRuntime::exception_handler_for_pc") @Stable public long exceptionHandlerForPcAddress; @HotSpotVMAddress(name = "JVMCIRuntime::monitorenter") @Stable public long monitorenterAddress; @HotSpotVMAddress(name = "JVMCIRuntime::monitorexit") @Stable public long monitorexitAddress; - @HotSpotVMAddress(name = "JVMCIRuntime::create_null_exception") @Stable public long createNullPointerExceptionAddress; - @HotSpotVMAddress(name = "JVMCIRuntime::create_out_of_bounds_exception") @Stable public long createOutOfBoundsExceptionAddress; + @HotSpotVMAddress(name = "JVMCIRuntime::throw_and_post_jvmti_exception") @Stable public long throwAndPostJvmtiExceptionAddress; + @HotSpotVMAddress(name = "JVMCIRuntime::throw_klass_external_name_exception") @Stable public long throwKlassExternalNameExceptionAddress; + @HotSpotVMAddress(name = "JVMCIRuntime::throw_class_cast_exception") @Stable public long throwClassCastExceptionAddress; @HotSpotVMAddress(name = "JVMCIRuntime::log_primitive") @Stable public long logPrimitiveAddress; @HotSpotVMAddress(name = "JVMCIRuntime::log_object") @Stable public long logObjectAddress; @HotSpotVMAddress(name = "JVMCIRuntime::log_printf") @Stable public long logPrintfAddress; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompilerFactory.java --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompilerFactory.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompilerFactory.java Thu Mar 31 14:25:35 2016 -0700 @@ -28,8 +28,7 @@ public interface JVMCICompilerFactory { /** - * Get the name of this compiler. The compiler will be selected when the jvmci.compiler system - * property is equal to this name. + * Get the name of this compiler. */ String getCompilerName(); diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp --- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -277,7 +277,7 @@ return false; } else { *fr = os::fetch_frame_from_ucontext(thread, uc); - *fr = frame(fr->sender_sp(), frame::unpatchable, fr->sender_pc()); + *fr = frame(fr->sender_sp(), fr->sp()); if (!fr->is_java_frame()) { assert(fr->safe_for_sender(thread), "Safety check"); *fr = fr->java_sender(); diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/c1/c1_Compiler.cpp --- a/hotspot/src/share/vm/c1/c1_Compiler.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/c1/c1_Compiler.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -209,9 +209,6 @@ case vmIntrinsics::_putLong_raw: case vmIntrinsics::_putFloat_raw: case vmIntrinsics::_putDouble_raw: - case vmIntrinsics::_putOrderedObject: - case vmIntrinsics::_putOrderedInt: - case vmIntrinsics::_putOrderedLong: case vmIntrinsics::_getShortUnaligned: case vmIntrinsics::_getCharUnaligned: case vmIntrinsics::_getIntUnaligned: diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/c1/c1_GraphBuilder.cpp --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -3450,9 +3450,6 @@ case vmIntrinsics::_putLong_raw : append_unsafe_put_raw(callee, T_LONG ); return; case vmIntrinsics::_putFloat_raw : append_unsafe_put_raw(callee, T_FLOAT ); return; case vmIntrinsics::_putDouble_raw : append_unsafe_put_raw(callee, T_DOUBLE); return; - case vmIntrinsics::_putOrderedObject : append_unsafe_put_obj(callee, T_OBJECT, true); return; - case vmIntrinsics::_putOrderedInt : append_unsafe_put_obj(callee, T_INT, true); return; - case vmIntrinsics::_putOrderedLong : append_unsafe_put_obj(callee, T_LONG, true); return; case vmIntrinsics::_compareAndSwapLong: case vmIntrinsics::_compareAndSwapInt: case vmIntrinsics::_compareAndSwapObject: append_unsafe_CAS(callee); return; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/c1/c1_LIRGenerator.cpp --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -999,8 +999,16 @@ Phi* phi = sux_val->as_Phi(); // cur_val can be null without phi being null in conjunction with inlining if (phi != NULL && cur_val != NULL && cur_val != phi && !phi->is_illegal()) { + Phi* cur_phi = cur_val->as_Phi(); + if (cur_phi != NULL && cur_phi->is_illegal()) { + // Phi and local would need to get invalidated + // (which is unexpected for Linear Scan). + // But this case is very rare so we simply bail out. + bailout("propagation of illegal phi"); + return; + } LIR_Opr operand = cur_val->operand(); - if (cur_val->operand()->is_illegal()) { + if (operand->is_illegal()) { assert(cur_val->as_Constant() != NULL || cur_val->as_Local() != NULL, "these can be produced lazily"); operand = operand_for_instruction(cur_val); diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/c1/c1_ValueStack.hpp --- a/hotspot/src/share/vm/c1/c1_ValueStack.hpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/c1/c1_ValueStack.hpp Thu Mar 31 14:25:35 2016 -0700 @@ -99,14 +99,14 @@ void clear_locals(); // sets all locals to NULL; void invalidate_local(int i) { - assert(_locals.at(i)->type()->is_single_word() || + assert(!_locals.at(i)->type()->is_double_word() || _locals.at(i + 1) == NULL, "hi-word of doubleword value must be NULL"); _locals.at_put(i, NULL); } Value local_at(int i) const { Value x = _locals.at(i); - assert(x == NULL || x->type()->is_single_word() || + assert(x == NULL || !x->type()->is_double_word() || _locals.at(i + 1) == NULL, "hi-word of doubleword value must be NULL"); return x; } @@ -131,7 +131,7 @@ // stack access Value stack_at(int i) const { Value x = _stack.at(i); - assert(x->type()->is_single_word() || + assert(!x->type()->is_double_word() || _stack.at(i + 1) == NULL, "hi-word of doubleword value must be NULL"); return x; } diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/c1/c1_globals.hpp --- a/hotspot/src/share/vm/c1/c1_globals.hpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/c1/c1_globals.hpp Thu Mar 31 14:25:35 2016 -0700 @@ -176,7 +176,7 @@ product(bool, InlineSynchronizedMethods, true, \ "Inline synchronized methods") \ \ - develop(bool, InlineNIOCheckIndex, true, \ + diagnostic(bool, InlineNIOCheckIndex, true, \ "Intrinsify java.nio.Buffer.checkIndex") \ \ develop(bool, CanonicalizeNodes, true, \ diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/ci/ciEnv.cpp --- a/hotspot/src/share/vm/ci/ciEnv.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/ci/ciEnv.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -773,7 +773,7 @@ Symbol* sig_sym = cpool->signature_ref_at(index); if (cpool->has_preresolution() - || (holder == ciEnv::MethodHandle_klass() && + || ((holder == ciEnv::MethodHandle_klass() || holder == ciEnv::VarHandle_klass()) && MethodHandles::is_signature_polymorphic_name(holder->get_Klass(), name_sym))) { // Short-circuit lookups for JSR 292-related call sites. // That is, do not rely only on name-based lookups, because they may fail diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/ci/ciReplay.cpp --- a/hotspot/src/share/vm/ci/ciReplay.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/ci/ciReplay.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -1,4 +1,4 @@ -/* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1057,8 +1057,6 @@ int ciReplay::replay_impl(TRAPS) { HandleMark hm; ResourceMark rm; - // Make sure we don't run with background compilation - BackgroundCompilation = false; if (ReplaySuppressInitializers > 2) { // ReplaySuppressInitializers > 2 means that we want to allow diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/classfile/classLoader.cpp --- a/hotspot/src/share/vm/classfile/classLoader.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/classfile/classLoader.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -1455,8 +1455,7 @@ EXCEPTION_MARK; HandleMark hm(THREAD); ResourceMark rm(THREAD); - // Make sure we don't run with background compilation - BackgroundCompilation = false; + // Find bootstrap loader Handle system_class_loader (THREAD, SystemDictionary::java_system_loader()); // Iterate over all bootstrap class path entries diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/classfile/systemDictionary.cpp --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -2563,7 +2563,8 @@ return empty; } -methodHandle SystemDictionary::find_method_handle_invoker(Symbol* name, +methodHandle SystemDictionary::find_method_handle_invoker(KlassHandle klass, + Symbol* name, Symbol* signature, KlassHandle accessing_klass, Handle *appendix_result, @@ -2574,7 +2575,6 @@ Handle method_type = SystemDictionary::find_method_handle_type(signature, accessing_klass, CHECK_(empty)); - KlassHandle mh_klass = SystemDictionary::MethodHandle_klass(); int ref_kind = JVM_REF_invokeVirtual; Handle name_str = StringTable::intern(name, CHECK_(empty)); objArrayHandle appendix_box = oopFactory::new_objArray(SystemDictionary::Object_klass(), 1, CHECK_(empty)); @@ -2589,7 +2589,7 @@ JavaCallArguments args; args.push_oop(accessing_klass()->java_mirror()); args.push_int(ref_kind); - args.push_oop(mh_klass()->java_mirror()); + args.push_oop(klass()->java_mirror()); args.push_oop(name_str()); args.push_oop(method_type()); args.push_oop(appendix_box()); diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/classfile/systemDictionary.hpp --- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp Thu Mar 31 14:25:35 2016 -0700 @@ -153,6 +153,7 @@ /* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \ do_klass(DirectMethodHandle_klass, java_lang_invoke_DirectMethodHandle, Opt ) \ do_klass(MethodHandle_klass, java_lang_invoke_MethodHandle, Pre ) \ + do_klass(VarHandle_klass, java_lang_invoke_VarHandle, Pre ) \ do_klass(MemberName_klass, java_lang_invoke_MemberName, Pre ) \ do_klass(MethodHandleNatives_klass, java_lang_invoke_MethodHandleNatives, Pre ) \ do_klass(LambdaForm_klass, java_lang_invoke_LambdaForm, Opt ) \ @@ -518,7 +519,8 @@ // JSR 292 // find a java.lang.invoke.MethodHandle.invoke* method for a given signature // (asks Java to compute it if necessary, except in a compiler thread) - static methodHandle find_method_handle_invoker(Symbol* name, + static methodHandle find_method_handle_invoker(KlassHandle klass, + Symbol* name, Symbol* signature, KlassHandle accessing_klass, Handle *appendix_result, diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/classfile/vmSymbols.cpp --- a/hotspot/src/share/vm/classfile/vmSymbols.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/classfile/vmSymbols.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -592,9 +592,6 @@ case vmIntrinsics::_putLong_raw: case vmIntrinsics::_putFloat_raw: case vmIntrinsics::_putDouble_raw: - case vmIntrinsics::_putOrderedObject: - case vmIntrinsics::_putOrderedLong: - case vmIntrinsics::_putOrderedInt: case vmIntrinsics::_getAndAddInt: case vmIntrinsics::_getAndAddLong: case vmIntrinsics::_getAndSetInt: diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/classfile/vmSymbols.hpp --- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Thu Mar 31 14:25:35 2016 -0700 @@ -289,6 +289,7 @@ template(java_lang_invoke_MutableCallSite, "java/lang/invoke/MutableCallSite") \ template(java_lang_invoke_VolatileCallSite, "java/lang/invoke/VolatileCallSite") \ template(java_lang_invoke_MethodHandle, "java/lang/invoke/MethodHandle") \ + template(java_lang_invoke_VarHandle, "java/lang/invoke/VarHandle") \ template(java_lang_invoke_MethodType, "java/lang/invoke/MethodType") \ template(java_lang_invoke_MethodType_signature, "Ljava/lang/invoke/MethodType;") \ template(java_lang_invoke_MemberName_signature, "Ljava/lang/invoke/MemberName;") \ @@ -1329,16 +1330,6 @@ do_intrinsic(_weakCompareAndSwapIntAcquire, jdk_internal_misc_Unsafe, weakCompareAndSwapIntAcquire_name, compareAndSwapInt_signature, F_R) \ do_intrinsic(_weakCompareAndSwapIntRelease, jdk_internal_misc_Unsafe, weakCompareAndSwapIntRelease_name, compareAndSwapInt_signature, F_R) \ \ - do_intrinsic(_putOrderedObject, jdk_internal_misc_Unsafe, putOrderedObject_name, putOrderedObject_signature, F_RN) \ - do_name( putOrderedObject_name, "putOrderedObject") \ - do_alias( putOrderedObject_signature, /*(LObject;JLObject;)V*/ putObject_signature) \ - do_intrinsic(_putOrderedLong, jdk_internal_misc_Unsafe, putOrderedLong_name, putOrderedLong_signature, F_RN) \ - do_name( putOrderedLong_name, "putOrderedLong") \ - do_alias( putOrderedLong_signature, /*(Ljava/lang/Object;JJ)V*/ putLong_signature) \ - do_intrinsic(_putOrderedInt, jdk_internal_misc_Unsafe, putOrderedInt_name, putOrderedInt_signature, F_RN) \ - do_name( putOrderedInt_name, "putOrderedInt") \ - do_alias( putOrderedInt_signature, /*(Ljava/lang/Object;JI)V*/ putInt_signature) \ - \ do_intrinsic(_getAndAddInt, jdk_internal_misc_Unsafe, getAndAddInt_name, getAndAddInt_signature, F_R) \ do_name( getAndAddInt_name, "getAndAddInt") \ do_signature(getAndAddInt_signature, "(Ljava/lang/Object;JI)I" ) \ diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/code/nmethod.cpp --- a/hotspot/src/share/vm/code/nmethod.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/code/nmethod.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -530,7 +530,6 @@ void nmethod::init_defaults() { _state = in_use; _unloading_clock = 0; - _marked_for_reclamation = 0; _has_flushed_dependencies = 0; _has_unsafe_access = 0; _has_method_handle_invokes = 0; @@ -1332,8 +1331,19 @@ } // Unlink the osr method, so we do not look this up again if (is_osr_method()) { - invalidate_osr_method(); + // Invalidate the osr nmethod only once + if (is_in_use()) { + invalidate_osr_method(); + } +#ifdef ASSERT + if (method() != NULL) { + // Make sure osr nmethod is invalidated, i.e. not on the list + bool found = method()->method_holder()->remove_osr_nmethod(this); + assert(!found, "osr nmethod should have been invalidated"); + } +#endif } + // If _method is already NULL the Method* is about to be unloaded, // so we don't have to break the cycle. Note that it is possible to // have the Method* live here, in case we unload the nmethod because @@ -1387,8 +1397,9 @@ void nmethod::invalidate_osr_method() { assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod"); // Remove from list of active nmethods - if (method() != NULL) + if (method() != NULL) { method()->method_holder()->remove_osr_nmethod(this); + } } void nmethod::log_state_change() const { @@ -1436,8 +1447,9 @@ // invalidate osr nmethod before acquiring the patching lock since // they both acquire leaf locks and we don't want a deadlock. // This logic is equivalent to the logic below for patching the - // verified entry point of regular methods. - if (is_osr_method()) { + // verified entry point of regular methods. We check that the + // nmethod is in use to ensure that it is invalidated only once. + if (is_osr_method() && is_in_use()) { // this effectively makes the osr nmethod not entrant invalidate_osr_method(); } @@ -1503,13 +1515,21 @@ } } // leave critical region under Patching_lock +#ifdef ASSERT + if (is_osr_method() && method() != NULL) { + // Make sure osr nmethod is invalidated, i.e. not on the list + bool found = method()->method_holder()->remove_osr_nmethod(this); + assert(!found, "osr nmethod should have been invalidated"); + } +#endif + // When the nmethod becomes zombie it is no longer alive so the // dependencies must be flushed. nmethods in the not_entrant // state will be flushed later when the transition to zombie // happens or they get unloaded. if (state == zombie) { { - // Flushing dependecies must be done before any possible + // Flushing dependencies must be done before any possible // safepoint can sneak in, otherwise the oops used by the // dependency logic could have become stale. MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); @@ -1525,7 +1545,7 @@ // zombie only - if a JVMTI agent has enabled the CompiledMethodUnload // event and it hasn't already been reported for this nmethod then - // report it now. The event may have been reported earilier if the GC + // report it now. The event may have been reported earlier if the GC // marked it for unloading). JvmtiDeferredEventQueue support means // we no longer go to a safepoint here. post_compiled_method_unload(); @@ -1553,18 +1573,18 @@ void nmethod::flush() { // Note that there are no valid oops in the nmethod anymore. - assert(is_zombie() || (is_osr_method() && is_unloaded()), "must be a zombie method"); - assert(is_marked_for_reclamation() || (is_osr_method() && is_unloaded()), "must be marked for reclamation"); - + assert(!is_osr_method() || is_unloaded() || is_zombie(), + "osr nmethod must be unloaded or zombie before flushing"); + assert(is_zombie() || is_osr_method(), "must be a zombie method"); assert (!is_locked_by_vm(), "locked methods shouldn't be flushed"); assert_locked_or_safepoint(CodeCache_lock); // completely deallocate this method Events::log(JavaThread::current(), "flushing nmethod " INTPTR_FORMAT, p2i(this)); if (PrintMethodFlushing) { - tty->print_cr("*flushing nmethod %3d/" INTPTR_FORMAT ". Live blobs:" UINT32_FORMAT + tty->print_cr("*flushing %s nmethod %3d/" INTPTR_FORMAT ". Live blobs:" UINT32_FORMAT "/Free CodeCache:" SIZE_FORMAT "Kb", - _compile_id, p2i(this), CodeCache::blob_count(), + is_osr_method() ? "osr" : "",_compile_id, p2i(this), CodeCache::blob_count(), CodeCache::unallocated_capacity(CodeCache::get_code_blob_type(this))/1024); } @@ -2916,10 +2936,7 @@ tty->print("((nmethod*) " INTPTR_FORMAT ") ", p2i(this)); tty->print(" for method " INTPTR_FORMAT , p2i(method())); tty->print(" { "); - if (is_in_use()) tty->print("in_use "); - if (is_not_entrant()) tty->print("not_entrant "); - if (is_zombie()) tty->print("zombie "); - if (is_unloaded()) tty->print("unloaded "); + tty->print_cr("%s ", state()); if (on_scavenge_root_list()) tty->print("scavenge_root "); tty->print_cr("}:"); } diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/code/nmethod.hpp --- a/hotspot/src/share/vm/code/nmethod.hpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/code/nmethod.hpp Thu Mar 31 14:25:35 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -188,8 +188,6 @@ // protected by CodeCache_lock bool _has_flushed_dependencies; // Used for maintenance of dependencies (CodeCache_lock) - bool _marked_for_reclamation; // Used by NMethodSweeper (set only by sweeper) - enum MarkForDeoptimizationStatus { not_marked, deoptimize, @@ -207,7 +205,7 @@ unsigned int _has_wide_vectors:1; // Preserve wide vectors at safepoints // Protected by Patching_lock - volatile unsigned char _state; // {alive, not_entrant, zombie, unloaded} + volatile unsigned char _state; // {in_use, not_entrant, zombie, unloaded} volatile unsigned char _unloading_clock; // Incremented after GC unloaded/cleaned the nmethod @@ -438,7 +436,20 @@ bool is_alive() const { return _state == in_use || _state == not_entrant; } bool is_not_entrant() const { return _state == not_entrant; } bool is_zombie() const { return _state == zombie; } - bool is_unloaded() const { return _state == unloaded; } + bool is_unloaded() const { return _state == unloaded; } + + // returns a string version of the nmethod state + const char* state() const { + switch(_state) { + case in_use: return "in use"; + case not_entrant: return "not_entrant"; + case zombie: return "zombie"; + case unloaded: return "unloaded"; + default: + fatal("unexpected nmethod state: %d", _state); + return NULL; + } + } #if INCLUDE_RTM_OPT // rtm state accessing and manipulating @@ -490,9 +501,6 @@ _has_flushed_dependencies = 1; } - bool is_marked_for_reclamation() const { return _marked_for_reclamation; } - void mark_for_reclamation() { _marked_for_reclamation = 1; } - bool has_unsafe_access() const { return _has_unsafe_access; } void set_has_unsafe_access(bool z) { _has_unsafe_access = z; } diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/compiler/compileBroker.cpp --- a/hotspot/src/share/vm/compiler/compileBroker.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -773,7 +773,8 @@ #endif // !ZERO && !SHARK // Initialize the compilation queue if (c2_compiler_count > 0) { - _c2_compile_queue = new CompileQueue("C2 compile queue"); + const char* name = JVMCI_ONLY(UseJVMCICompiler ? "JVMCI compile queue" :) "C2 compile queue"; + _c2_compile_queue = new CompileQueue(name); _compilers[1]->set_num_compiler_threads(c2_compiler_count); } if (c1_compiler_count > 0) { @@ -1169,7 +1170,8 @@ CompilationPolicy::policy()->delay_compilation(method()); return NULL; } - compile_method_base(method, osr_bci, comp_level, hot_method, hot_count, comment, !directive->BackgroundCompilationOption, THREAD); + bool is_blocking = !directive->BackgroundCompilationOption || CompileTheWorld || ReplayCompiles; + compile_method_base(method, osr_bci, comp_level, hot_method, hot_count, comment, is_blocking, THREAD); } // return requested nmethod @@ -1649,6 +1651,10 @@ tty->print_cr("Opening compilation log %s", file_name); } CompileLog* log = new(ResourceObj::C_HEAP, mtCompiler) CompileLog(file_name, fp, thread_id); + if (log == NULL) { + fclose(fp); + return; + } thread->init_log(log); if (xtty != NULL) { diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/interpreter/linkResolver.cpp --- a/hotspot/src/share/vm/interpreter/linkResolver.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -90,10 +90,16 @@ void CallInfo::set_handle(const methodHandle& resolved_method, Handle resolved_appendix, Handle resolved_method_type, TRAPS) { + set_handle(SystemDictionary::MethodHandle_klass(), resolved_method, resolved_appendix, resolved_method_type, CHECK); +} + +void CallInfo::set_handle(KlassHandle resolved_klass, + const methodHandle& resolved_method, + Handle resolved_appendix, + Handle resolved_method_type, TRAPS) { if (resolved_method.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "resolved method is null"); } - KlassHandle resolved_klass = SystemDictionary::MethodHandle_klass(); assert(resolved_method->intrinsic_id() == vmIntrinsics::_invokeBasic || resolved_method->is_compiled_lambda_form(), "linkMethod must return one of these"); @@ -433,7 +439,8 @@ vmIntrinsics::name_at(iid), klass->external_name(), name->as_C_string(), full_signature->as_C_string()); } - if (klass() == SystemDictionary::MethodHandle_klass() && + if ((klass() == SystemDictionary::MethodHandle_klass() || + klass() == SystemDictionary::VarHandle_klass()) && iid != vmIntrinsics::_none) { if (MethodHandles::is_signature_polymorphic_intrinsic(iid)) { // Most of these do not need an up-call to Java to resolve, so can be done anywhere. @@ -482,6 +489,7 @@ Handle appendix; Handle method_type; methodHandle result = SystemDictionary::find_method_handle_invoker( + klass, name, full_signature, link_info.current_klass(), @@ -1561,13 +1569,15 @@ const LinkInfo& link_info, TRAPS) { // JSR 292: this must be an implicitly generated method MethodHandle.invokeExact(*...) or similar - assert(link_info.resolved_klass()() == SystemDictionary::MethodHandle_klass(), ""); + KlassHandle resolved_klass = link_info.resolved_klass(); + assert(resolved_klass() == SystemDictionary::MethodHandle_klass() || + resolved_klass() == SystemDictionary::VarHandle_klass(), ""); assert(MethodHandles::is_signature_polymorphic_name(link_info.name()), ""); Handle resolved_appendix; Handle resolved_method_type; methodHandle resolved_method = lookup_polymorphic_method(link_info, &resolved_appendix, &resolved_method_type, CHECK); - result.set_handle(resolved_method, resolved_appendix, resolved_method_type, CHECK); + result.set_handle(resolved_klass, resolved_method, resolved_appendix, resolved_method_type, CHECK); } static void wrap_invokedynamic_exception(TRAPS) { diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/interpreter/linkResolver.hpp --- a/hotspot/src/share/vm/interpreter/linkResolver.hpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/interpreter/linkResolver.hpp Thu Mar 31 14:25:35 2016 -0700 @@ -69,6 +69,9 @@ int vtable_index, TRAPS); void set_handle(const methodHandle& resolved_method, Handle resolved_appendix, Handle resolved_method_type, TRAPS); + void set_handle(KlassHandle resolved_klass, + const methodHandle& resolved_method, + Handle resolved_appendix, Handle resolved_method_type, TRAPS); void set_common(KlassHandle resolved_klass, KlassHandle selected_klass, const methodHandle& resolved_method, const methodHandle& selected_method, diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/interpreter/rewriter.cpp --- a/hotspot/src/share/vm/interpreter/rewriter.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/interpreter/rewriter.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -54,8 +54,10 @@ add_resolved_references_entry(i); break; case JVM_CONSTANT_Utf8: - if (_pool->symbol_at(i) == vmSymbols::java_lang_invoke_MethodHandle()) + if (_pool->symbol_at(i) == vmSymbols::java_lang_invoke_MethodHandle() || + _pool->symbol_at(i) == vmSymbols::java_lang_invoke_VarHandle()) { saw_mh_symbol = true; + } break; } } @@ -200,6 +202,12 @@ // we may need a resolved_refs entry for the appendix add_invokedynamic_resolved_references_entries(cp_index, cache_index); status = +1; + } else if (_pool->klass_ref_at_noresolve(cp_index) == vmSymbols::java_lang_invoke_VarHandle() && + MethodHandles::is_signature_polymorphic_name(SystemDictionary::VarHandle_klass(), + _pool->name_ref_at(cp_index))) { + // we may need a resolved_refs entry for the appendix + add_invokedynamic_resolved_references_entries(cp_index, cache_index); + status = +1; } else { status = -1; } diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/jvmci/jvmciCodeInstaller.cpp --- a/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -177,7 +177,13 @@ return map; } -Metadata* CodeInstaller::record_metadata_reference(Handle constant, TRAPS) { +void* CodeInstaller::record_metadata_reference(Handle constant, TRAPS) { + /* + * This method needs to return a raw (untyped) pointer, since the value of a pointer to the base + * class is in general not equal to the pointer of the subclass. When patching metaspace pointers, + * the compiler expects a direct pointer to the subclass (Klass*, Method* or Symbol*), not a + * pointer to the base class (Metadata* or MetaspaceObj*). + */ oop obj = HotSpotMetaspaceConstantImpl::metaspaceObject(constant); if (obj->is_a(HotSpotResolvedObjectTypeImpl::klass())) { Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(obj)); @@ -191,6 +197,11 @@ int index = _oop_recorder->find_index(method); TRACE_jvmci_3("metadata[%d of %d] = %s", index, _oop_recorder->metadata_count(), method->name()->as_C_string()); return method; + } else if (obj->is_a(HotSpotSymbol::klass())) { + Symbol* symbol = (Symbol*) (address) HotSpotSymbol::pointer(obj); + assert(!HotSpotMetaspaceConstantImpl::compressed(constant), "unexpected compressed symbol pointer %s @ " INTPTR_FORMAT, symbol->as_C_string(), p2i(symbol)); + TRACE_jvmci_3("symbol = %s", symbol->as_C_string()); + return symbol; } else { JVMCI_ERROR_NULL("unexpected metadata reference for constant of type %s", obj->klass()->signature_name()); } @@ -706,7 +717,7 @@ JVMCI_ERROR_OK("unexpected compressed Klass* in 32-bit mode"); #endif } else { - *((Metadata**) dest) = record_metadata_reference(constant, CHECK_OK); + *((void**) dest) = record_metadata_reference(constant, CHECK_OK); } } else if (constant->is_a(HotSpotObjectConstantImpl::klass())) { Handle obj = HotSpotObjectConstantImpl::object(constant); diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/jvmci/jvmciCodeInstaller.hpp --- a/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.hpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.hpp Thu Mar 31 14:25:35 2016 -0700 @@ -189,7 +189,7 @@ ScopeValue* get_scope_value(Handle value, BasicType type, GrowableArray* objects, ScopeValue* &second, TRAPS); MonitorValue* get_monitor_value(Handle value, GrowableArray* objects, TRAPS); - Metadata* record_metadata_reference(Handle constant, TRAPS); + void* record_metadata_reference(Handle constant, TRAPS); #ifdef _LP64 narrowKlass record_narrow_metadata_reference(Handle constant, TRAPS); #endif diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp --- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -448,7 +448,10 @@ C2V_VMENTRY(jboolean, canInlineMethod,(JNIEnv *, jobject, jobject jvmci_method)) methodHandle method = CompilerToVM::asMethod(jvmci_method); - return !method->is_not_compilable() && !CompilerOracle::should_not_inline(method) && !method->dont_inline(); + // In hosted mode ignore the not_compilable flags since they are never set by + // the JVMCI compiler. + bool is_compilable = UseJVMCICompiler ? !method->is_not_compilable(CompLevel_full_optimization) : true; + return is_compilable && !CompilerOracle::should_not_inline(method) && !method->dont_inline(); C2V_END C2V_VMENTRY(jboolean, shouldInlineMethod,(JNIEnv *, jobject, jobject jvmci_method)) @@ -1048,6 +1051,11 @@ return JNIHandles::make_local(THREAD, sym()); C2V_END +C2V_VMENTRY(jlong, lookupSymbol, (JNIEnv*, jobject, jobject string)) + Symbol* symbol = java_lang_String::as_symbol_or_null(JNIHandles::resolve(string)); + return (jlong) symbol; +C2V_END + bool matches(jobjectArray methods, Method* method) { objArrayOop methods_oop = (objArrayOop) JNIHandles::resolve(methods); @@ -1475,6 +1483,7 @@ {CC"isMature", CC"("METASPACE_METHOD_DATA")Z", FN_PTR(isMature)}, {CC"hasCompiledCodeForOSR", CC"("HS_RESOLVED_METHOD"II)Z", FN_PTR(hasCompiledCodeForOSR)}, {CC"getSymbol", CC"(J)"STRING, FN_PTR(getSymbol)}, + {CC"lookupSymbol", CC"("STRING")J", FN_PTR(lookupSymbol)}, {CC"getNextStackFrame", CC"("HS_STACK_FRAME_REF "["RESOLVED_METHOD"I)"HS_STACK_FRAME_REF, FN_PTR(getNextStackFrame)}, {CC"materializeVirtualObjects", CC"("HS_STACK_FRAME_REF"Z)V", FN_PTR(materializeVirtualObjects)}, {CC"shouldDebugNonSafepoints", CC"()Z", FN_PTR(shouldDebugNonSafepoints)}, diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/jvmci/jvmciJavaClasses.hpp --- a/hotspot/src/share/vm/jvmci/jvmciJavaClasses.hpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/jvmci/jvmciJavaClasses.hpp Thu Mar 31 14:25:35 2016 -0700 @@ -64,6 +64,9 @@ start_class(HotSpotResolvedJavaMethodImpl) \ long_field(HotSpotResolvedJavaMethodImpl, metaspaceMethod) \ end_class \ + start_class(HotSpotSymbol) \ + long_field(HotSpotSymbol, pointer) \ + end_class \ start_class(InstalledCode) \ long_field(InstalledCode, address) \ long_field(InstalledCode, entryPoint) \ diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/jvmci/jvmciRuntime.cpp --- a/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -363,20 +363,6 @@ return continuation; } -JRT_ENTRY(void, JVMCIRuntime::create_null_exception(JavaThread* thread)) - SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_NullPointerException()); - thread->set_vm_result(PENDING_EXCEPTION); - CLEAR_PENDING_EXCEPTION; -JRT_END - -JRT_ENTRY(void, JVMCIRuntime::create_out_of_bounds_exception(JavaThread* thread, jint index)) - char message[jintAsStringSize]; - sprintf(message, "%d", index); - SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), message); - thread->set_vm_result(PENDING_EXCEPTION); - CLEAR_PENDING_EXCEPTION; -JRT_END - JRT_ENTRY_NO_ASYNC(void, JVMCIRuntime::monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock)) IF_TRACE_jvmci_3 { char type[O_BUFLEN]; @@ -438,6 +424,21 @@ } JRT_END +JRT_ENTRY(void, JVMCIRuntime::throw_and_post_jvmti_exception(JavaThread* thread, Symbol* name, const char* message)) + SharedRuntime::throw_and_post_jvmti_exception(thread, name, message); +JRT_END + +JRT_ENTRY(void, JVMCIRuntime::throw_klass_external_name_exception(JavaThread* thread, Symbol* exception, Klass* klass)) + ResourceMark rm(thread); + SharedRuntime::throw_and_post_jvmti_exception(thread, exception, klass->external_name()); +JRT_END + +JRT_ENTRY(void, JVMCIRuntime::throw_class_cast_exception(JavaThread* thread, Symbol* exception, Klass* caster_klass, Klass* target_klass)) + ResourceMark rm(thread); + const char* message = SharedRuntime::generate_class_cast_message(caster_klass, target_klass); + SharedRuntime::throw_and_post_jvmti_exception(thread, exception, message); +JRT_END + JRT_LEAF(void, JVMCIRuntime::log_object(JavaThread* thread, oopDesc* obj, bool as_string, bool newline)) ttyLocker ttyl; @@ -800,12 +801,9 @@ bool JVMCIRuntime::treat_as_trivial(Method* method) { if (_HotSpotJVMCIRuntime_initialized) { - oop loader = method->method_holder()->class_loader(); - if (loader == NULL) { - for (int i = 0; i < _trivial_prefixes_count; i++) { - if (method->method_holder()->name()->starts_with(_trivial_prefixes[i])) { - return true; - } + for (int i = 0; i < _trivial_prefixes_count; i++) { + if (method->method_holder()->name()->starts_with(_trivial_prefixes[i])) { + return true; } } } diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/jvmci/jvmciRuntime.hpp --- a/hotspot/src/share/vm/jvmci/jvmciRuntime.hpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/jvmci/jvmciRuntime.hpp Thu Mar 31 14:25:35 2016 -0700 @@ -141,8 +141,6 @@ static address exception_handler_for_pc(JavaThread* thread); static void monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock); static void monitorexit (JavaThread* thread, oopDesc* obj, BasicLock* lock); - static void create_null_exception(JavaThread* thread); - static void create_out_of_bounds_exception(JavaThread* thread, jint index); static void vm_error(JavaThread* thread, jlong where, jlong format, jlong value); static oopDesc* load_and_clear_exception(JavaThread* thread); static void log_printf(JavaThread* thread, oopDesc* format, jlong v1, jlong v2, jlong v3); @@ -157,6 +155,12 @@ static jboolean validate_object(JavaThread* thread, oopDesc* parent, oopDesc* child); static void new_store_pre_barrier(JavaThread* thread); + // used to throw exceptions from compiled JVMCI code + static void throw_and_post_jvmti_exception(JavaThread* thread, Symbol* exception, const char* message); + // helper methods to throw exception with complex messages + static void throw_klass_external_name_exception(JavaThread* thread, Symbol* exception, Klass* klass); + static void throw_class_cast_exception(JavaThread* thread, Symbol* exception, Klass* caster_klass, Klass* target_klass); + // Test only function static int test_deoptimize_call_int(JavaThread* thread, int value); }; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/jvmci/systemDictionary_jvmci.hpp --- a/hotspot/src/share/vm/jvmci/systemDictionary_jvmci.hpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/jvmci/systemDictionary_jvmci.hpp Thu Mar 31 14:25:35 2016 -0700 @@ -49,6 +49,7 @@ do_klass(HotSpotJVMCIMetaAccessContext_klass, jdk_vm_ci_hotspot_HotSpotJVMCIMetaAccessContext, Jvmci) \ do_klass(HotSpotJVMCIRuntime_klass, jdk_vm_ci_hotspot_HotSpotJVMCIRuntime, Jvmci) \ do_klass(HotSpotSpeculationLog_klass, jdk_vm_ci_hotspot_HotSpotSpeculationLog, Jvmci) \ + do_klass(HotSpotSymbol_klass, jdk_vm_ci_hotspot_HotSpotSymbol, Jvmci) \ do_klass(Assumptions_ConcreteMethod_klass, jdk_vm_ci_meta_Assumptions_ConcreteMethod, Jvmci) \ do_klass(Assumptions_NoFinalizableSubclass_klass, jdk_vm_ci_meta_Assumptions_NoFinalizableSubclass, Jvmci) \ do_klass(Assumptions_ConcreteSubtype_klass, jdk_vm_ci_meta_Assumptions_ConcreteSubtype, Jvmci) \ diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp --- a/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -165,6 +165,7 @@ nonstatic_field(Klass, _super_check_offset, juint) \ nonstatic_field(Klass, _subklass, Klass*) \ nonstatic_field(Klass, _layout_helper, jint) \ + nonstatic_field(Klass, _name, Symbol*) \ nonstatic_field(Klass, _prototype_header, markOop) \ nonstatic_field(Klass, _next_sibling, Klass*) \ nonstatic_field(Klass, _java_mirror, oop) \ @@ -551,8 +552,9 @@ declare_function(JVMCIRuntime::exception_handler_for_pc) \ declare_function(JVMCIRuntime::monitorenter) \ declare_function(JVMCIRuntime::monitorexit) \ - declare_function(JVMCIRuntime::create_null_exception) \ - declare_function(JVMCIRuntime::create_out_of_bounds_exception) \ + declare_function(JVMCIRuntime::throw_and_post_jvmti_exception) \ + declare_function(JVMCIRuntime::throw_klass_external_name_exception) \ + declare_function(JVMCIRuntime::throw_class_cast_exception) \ declare_function(JVMCIRuntime::log_primitive) \ declare_function(JVMCIRuntime::log_object) \ declare_function(JVMCIRuntime::log_printf) \ diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/jvmci/vmSymbols_jvmci.hpp --- a/hotspot/src/share/vm/jvmci/vmSymbols_jvmci.hpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/jvmci/vmSymbols_jvmci.hpp Thu Mar 31 14:25:35 2016 -0700 @@ -50,6 +50,7 @@ template(jdk_vm_ci_hotspot_HotSpotJVMCIMetaAccessContext, "jdk/vm/ci/hotspot/HotSpotJVMCIMetaAccessContext") \ template(jdk_vm_ci_hotspot_HotSpotJVMCIRuntime, "jdk/vm/ci/hotspot/HotSpotJVMCIRuntime") \ template(jdk_vm_ci_hotspot_HotSpotSpeculationLog, "jdk/vm/ci/hotspot/HotSpotSpeculationLog") \ + template(jdk_vm_ci_hotspot_HotSpotSymbol, "jdk/vm/ci/hotspot/HotSpotSymbol") \ template(jdk_vm_ci_meta_JavaConstant, "jdk/vm/ci/meta/JavaConstant") \ template(jdk_vm_ci_meta_PrimitiveConstant, "jdk/vm/ci/meta/PrimitiveConstant") \ template(jdk_vm_ci_meta_RawConstant, "jdk/vm/ci/meta/RawConstant") \ diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/memory/metachunk.cpp --- a/hotspot/src/share/vm/memory/metachunk.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/memory/metachunk.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -30,8 +30,6 @@ class VirtualSpaceNode; -const size_t metadata_chunk_initialize = 0xf7f7f7f7; - size_t Metachunk::object_alignment() { // Must align pointers and sizes to 8, // so that 64 bit types get correctly aligned. @@ -58,12 +56,7 @@ _top = initial_top(); #ifdef ASSERT set_is_tagged_free(false); - size_t data_word_size = pointer_delta(end(), - _top, - sizeof(MetaWord)); - Copy::fill_to_words((HeapWord*)_top, - data_word_size, - metadata_chunk_initialize); + mangle(uninitMetaWordVal); #endif } @@ -98,12 +91,12 @@ } #ifndef PRODUCT -void Metachunk::mangle() { - // Mangle the payload of the chunk and not the links that +void Metachunk::mangle(juint word_value) { + // Overwrite the payload of the chunk and not the links that // maintain list of chunks. - HeapWord* start = (HeapWord*)(bottom() + overhead()); + HeapWord* start = (HeapWord*)initial_top(); size_t size = word_size() - overhead(); - Copy::fill_to_words(start, size, metadata_chunk_initialize); + Copy::fill_to_words(start, size, word_value); } #endif // PRODUCT diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/memory/metachunk.hpp --- a/hotspot/src/share/vm/memory/metachunk.hpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/memory/metachunk.hpp Thu Mar 31 14:25:35 2016 -0700 @@ -145,7 +145,9 @@ bool contains(const void* ptr) { return bottom() <= ptr && ptr < _top; } - NOT_PRODUCT(void mangle();) +#ifndef PRODUCT + void mangle(juint word_value); +#endif void print_on(outputStream* st) const; void verify(); diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/memory/metaspace.cpp --- a/hotspot/src/share/vm/memory/metaspace.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/memory/metaspace.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -811,11 +811,6 @@ BlockFreelist::BlockFreelist() : _dictionary(new BlockTreeDictionary()) {} BlockFreelist::~BlockFreelist() { - LogHandle(gc, metaspace, freelist) log; - if (log.is_trace()) { - ResourceMark rm; - dictionary()->print_free_lists(log.trace_stream()); - } delete _dictionary; } @@ -2145,6 +2140,7 @@ // by the call to return_chunk_at_head(); Metachunk* next = cur->next(); DEBUG_ONLY(cur->set_is_tagged_free(true);) + NOT_PRODUCT(cur->mangle(badMetaWordVal);) list->return_chunk_at_head(cur); cur = next; } @@ -2169,11 +2165,9 @@ log.trace("~SpaceManager(): " PTR_FORMAT, p2i(this)); ResourceMark rm; locked_print_chunks_in_use_on(log.trace_stream()); + block_freelists()->print_on(log.trace_stream()); } - // Do not mangle freed Metachunks. The chunk size inside Metachunks - // is during the freeing of a VirtualSpaceNodes. - // Have to update before the chunks_in_use lists are emptied // below. chunk_manager()->inc_free_chunks_total(allocated_chunks_words(), @@ -2206,9 +2200,8 @@ Metachunk* humongous_chunks = chunks_in_use(HumongousIndex); while (humongous_chunks != NULL) { -#ifdef ASSERT - humongous_chunks->set_is_tagged_free(true); -#endif + DEBUG_ONLY(humongous_chunks->set_is_tagged_free(true);) + NOT_PRODUCT(humongous_chunks->mangle(badMetaWordVal);) log.trace(PTR_FORMAT " (" SIZE_FORMAT ") ", p2i(humongous_chunks), humongous_chunks->word_size()); assert(humongous_chunks->word_size() == (size_t) align_size_up(humongous_chunks->word_size(), @@ -2527,7 +2520,7 @@ for (Metachunk* curr = chunks_in_use(index); curr != NULL; curr = curr->next()) { - curr->mangle(); + curr->mangle(uninitMetaWordVal); } } } diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/oops/instanceKlass.cpp --- a/hotspot/src/share/vm/oops/instanceKlass.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -2614,8 +2614,8 @@ } } - -void InstanceKlass::remove_osr_nmethod(nmethod* n) { +// Remove osr nmethod from the list. Return true if found and removed. +bool InstanceKlass::remove_osr_nmethod(nmethod* n) { // This is a short non-blocking critical region, so the no safepoint check is ok. MutexLockerEx ml(OsrList_lock, Mutex::_no_safepoint_check_flag); assert(n->is_osr_method(), "wrong kind of nmethod"); @@ -2624,6 +2624,7 @@ int max_level = CompLevel_none; // Find the max comp level excluding n Method* m = n->method(); // Search for match + bool found = false; while(cur != NULL && cur != n) { if (TieredCompilation && m == cur->method()) { // Find max level before n @@ -2634,6 +2635,7 @@ } nmethod* next = NULL; if (cur == n) { + found = true; next = cur->osr_link(); if (last == NULL) { // Remove first element @@ -2654,6 +2656,7 @@ } m->set_highest_osr_comp_level(max_level); } + return found; } int InstanceKlass::mark_osr_nmethods(const Method* m) { diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/oops/instanceKlass.hpp --- a/hotspot/src/share/vm/oops/instanceKlass.hpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Thu Mar 31 14:25:35 2016 -0700 @@ -878,7 +878,7 @@ nmethod* osr_nmethods_head() const { return _osr_nmethods_head; }; void set_osr_nmethods_head(nmethod* h) { _osr_nmethods_head = h; }; void add_osr_nmethod(nmethod* n); - void remove_osr_nmethod(nmethod* n); + bool remove_osr_nmethod(nmethod* n); int mark_osr_nmethods(const Method* m); nmethod* lookup_osr_nmethod(const Method* m, int bci, int level, bool match_level) const; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/oops/method.cpp --- a/hotspot/src/share/vm/oops/method.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/oops/method.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -1351,11 +1351,16 @@ // ditto for method and signature: vmSymbols::SID name_id = vmSymbols::find_sid(name()); if (klass_id != vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_MethodHandle) - && name_id == vmSymbols::NO_SID) + && klass_id != vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_VarHandle) + && name_id == vmSymbols::NO_SID) { return; + } vmSymbols::SID sig_id = vmSymbols::find_sid(signature()); if (klass_id != vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_MethodHandle) - && sig_id == vmSymbols::NO_SID) return; + && klass_id != vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_VarHandle) + && sig_id == vmSymbols::NO_SID) { + return; + } jshort flags = access_flags().as_short(); vmIntrinsics::ID id = vmIntrinsics::find_id(klass_id, name_id, sig_id, flags); @@ -1383,8 +1388,9 @@ } break; - // Signature-polymorphic methods: MethodHandle.invoke*, InvokeDynamic.*. + // Signature-polymorphic methods: MethodHandle.invoke*, InvokeDynamic.*., VarHandle case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_MethodHandle): + case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_VarHandle): if (!is_native()) break; id = MethodHandles::signature_polymorphic_name_id(method_holder(), name()); if (is_static() != MethodHandles::is_signature_polymorphic_static(id)) diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/opto/c2_globals.hpp --- a/hotspot/src/share/vm/opto/c2_globals.hpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/c2_globals.hpp Thu Mar 31 14:25:35 2016 -0700 @@ -595,26 +595,26 @@ product(bool, BlockLayoutRotateLoops, true, \ "Allow back branches to be fall throughs in the block layour") \ \ - develop(bool, InlineReflectionGetCallerClass, true, \ + diagnostic(bool, InlineReflectionGetCallerClass, true, \ "inline sun.reflect.Reflection.getCallerClass(), known to be " \ "part of base library DLL") \ \ - develop(bool, InlineObjectCopy, true, \ + diagnostic(bool, InlineObjectCopy, true, \ "inline Object.clone and Arrays.copyOf[Range] intrinsics") \ \ - develop(bool, SpecialStringCompareTo, true, \ + diagnostic(bool, SpecialStringCompareTo, true, \ "special version of string compareTo") \ \ - develop(bool, SpecialStringIndexOf, true, \ + diagnostic(bool, SpecialStringIndexOf, true, \ "special version of string indexOf") \ \ - develop(bool, SpecialStringEquals, true, \ + diagnostic(bool, SpecialStringEquals, true, \ "special version of string equals") \ \ - develop(bool, SpecialArraysEquals, true, \ + diagnostic(bool, SpecialArraysEquals, true, \ "special version of Arrays.equals(char[],char[])") \ \ - product(bool, SpecialEncodeISOArray, true, \ + diagnostic(bool, SpecialEncodeISOArray, true, \ "special version of ISO_8859_1$Encoder.encodeISOArray") \ \ develop(bool, BailoutToInterpreterForThrows, false, \ @@ -716,22 +716,22 @@ diagnostic(bool, OptimizeExpensiveOps, true, \ "Find best control for expensive operations") \ \ - product(bool, UseMathExactIntrinsics, true, \ + diagnostic(bool, UseMathExactIntrinsics, true, \ "Enables intrinsification of various java.lang.Math functions") \ \ - product(bool, UseMultiplyToLenIntrinsic, false, \ + diagnostic(bool, UseMultiplyToLenIntrinsic, false, \ "Enables intrinsification of BigInteger.multiplyToLen()") \ \ - product(bool, UseSquareToLenIntrinsic, false, \ + diagnostic(bool, UseSquareToLenIntrinsic, false, \ "Enables intrinsification of BigInteger.squareToLen()") \ \ - product(bool, UseMulAddIntrinsic, false, \ + diagnostic(bool, UseMulAddIntrinsic, false, \ "Enables intrinsification of BigInteger.mulAdd()") \ \ - product(bool, UseMontgomeryMultiplyIntrinsic, false, \ + diagnostic(bool, UseMontgomeryMultiplyIntrinsic, false, \ "Enables intrinsification of BigInteger.montgomeryMultiply()") \ \ - product(bool, UseMontgomerySquareIntrinsic, false, \ + diagnostic(bool, UseMontgomerySquareIntrinsic, false, \ "Enables intrinsification of BigInteger.montgomerySquare()") \ \ product(bool, UseTypeSpeculation, true, \ diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/opto/c2compiler.cpp --- a/hotspot/src/share/vm/opto/c2compiler.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/c2compiler.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -484,9 +484,6 @@ case vmIntrinsics::_putCharUnaligned: case vmIntrinsics::_putIntUnaligned: case vmIntrinsics::_putLongUnaligned: - case vmIntrinsics::_putOrderedObject: - case vmIntrinsics::_putOrderedInt: - case vmIntrinsics::_putOrderedLong: case vmIntrinsics::_loadFence: case vmIntrinsics::_storeFence: case vmIntrinsics::_fullFence: diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/opto/library_call.cpp --- a/hotspot/src/share/vm/opto/library_call.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/library_call.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -621,10 +621,6 @@ case vmIntrinsics::_putIntUnaligned: return inline_unsafe_access(!is_native_ptr, is_store, T_INT, Relaxed, true); case vmIntrinsics::_putLongUnaligned: return inline_unsafe_access(!is_native_ptr, is_store, T_LONG, Relaxed, true); - case vmIntrinsics::_putOrderedObject: return inline_unsafe_access(!is_native_ptr, is_store, T_OBJECT, Release, false); - case vmIntrinsics::_putOrderedInt: return inline_unsafe_access(!is_native_ptr, is_store, T_INT, Release, false); - case vmIntrinsics::_putOrderedLong: return inline_unsafe_access(!is_native_ptr, is_store, T_LONG, Release, false); - case vmIntrinsics::_getObjectAcquire: return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT, Acquire, false); case vmIntrinsics::_getBooleanAcquire: return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN, Acquire, false); case vmIntrinsics::_getByteAcquire: return inline_unsafe_access(!is_native_ptr, !is_store, T_BYTE, Acquire, false); diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/opto/loopTransform.cpp --- a/hotspot/src/share/vm/opto/loopTransform.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/loopTransform.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -1453,20 +1453,14 @@ Node *opaq = NULL; if (adjust_min_trip) { // If not maximally unrolling, need adjustment // Search for zero-trip guard. - assert( loop_head->is_main_loop(), "" ); - assert( ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse, "" ); - Node *iff = ctrl->in(0); - assert( iff->Opcode() == Op_If, "" ); - Node *bol = iff->in(1); - assert( bol->Opcode() == Op_Bool, "" ); - Node *cmp = bol->in(1); - assert( cmp->Opcode() == Op_CmpI, "" ); - opaq = cmp->in(2); - // Occasionally it's possible for a zero-trip guard Opaque1 node to be - // optimized away and then another round of loop opts attempted. - // We can not optimize this particular loop in that case. - if (opaq->Opcode() != Op_Opaque1) - return; // Cannot find zero-trip guard! Bail out! + + // Check the shape of the graph at the loop entry. If an inappropriate + // graph shape is encountered, the compiler bails out loop unrolling; + // compilation of the method will still succeed. + if (!is_canonical_main_loop_entry(loop_head)) { + return; + } + opaq = ctrl->in(0)->in(1)->in(1)->in(2); // Zero-trip test uses an 'opaque' node which is not shared. assert(opaq->outcnt() == 1 && opaq->in(1) == limit, ""); } @@ -2109,7 +2103,6 @@ #endif assert(RangeCheckElimination, ""); CountedLoopNode *cl = loop->_head->as_CountedLoop(); - assert(cl->is_main_loop(), ""); // protect against stride not being a constant if (!cl->stride_is_con()) @@ -2121,20 +2114,17 @@ // to not ever trip end tests Node *main_limit = cl->limit(); + // Check graph shape. Cannot optimize a loop if zero-trip + // Opaque1 node is optimized away and then another round + // of loop opts attempted. + if (!is_canonical_main_loop_entry(cl)) { + return; + } + // Need to find the main-loop zero-trip guard Node *ctrl = cl->in(LoopNode::EntryControl); - assert(ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse, ""); Node *iffm = ctrl->in(0); - assert(iffm->Opcode() == Op_If, ""); - Node *bolzm = iffm->in(1); - assert(bolzm->Opcode() == Op_Bool, ""); - Node *cmpzm = bolzm->in(1); - assert(cmpzm->is_Cmp(), ""); - Node *opqzm = cmpzm->in(2); - // Can not optimize a loop if zero-trip Opaque1 node is optimized - // away and then another round of loop opts attempted. - if (opqzm->Opcode() != Op_Opaque1) - return; + Node *opqzm = iffm->in(1)->in(1)->in(2); assert(opqzm->in(1) == main_limit, "do not understand situation"); // Find the pre-loop limit; we will expand its iterations to diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/opto/loopnode.cpp --- a/hotspot/src/share/vm/opto/loopnode.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/loopnode.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -3275,6 +3275,41 @@ return LCA; } +// Check the shape of the graph at the loop entry. In some cases, +// the shape of the graph does not match the shape outlined below. +// That is caused by the Opaque1 node "protecting" the shape of +// the graph being removed by, for example, the IGVN performed +// in PhaseIdealLoop::build_and_optimize(). +// +// After the Opaque1 node has been removed, optimizations (e.g., split-if, +// loop unswitching, and IGVN, or a combination of them) can freely change +// the graph's shape. As a result, the graph shape outlined below cannot +// be guaranteed anymore. +bool PhaseIdealLoop::is_canonical_main_loop_entry(CountedLoopNode* cl) { + assert(cl->is_main_loop(), "check should be applied to main loops"); + Node* ctrl = cl->in(LoopNode::EntryControl); + if (ctrl == NULL || (!ctrl->is_IfTrue() && !ctrl->is_IfFalse())) { + return false; + } + Node* iffm = ctrl->in(0); + if (iffm == NULL || !iffm->is_If()) { + return false; + } + Node* bolzm = iffm->in(1); + if (bolzm == NULL || !bolzm->is_Bool()) { + return false; + } + Node* cmpzm = bolzm->in(1); + if (cmpzm == NULL || !cmpzm->is_Cmp()) { + return false; + } + Node* opqzm = cmpzm->in(2); + if (opqzm == NULL || opqzm->Opcode() != Op_Opaque1) { + return false; + } + return true; +} + //------------------------------get_late_ctrl---------------------------------- // Compute latest legal control. Node *PhaseIdealLoop::get_late_ctrl( Node *n, Node *early ) { diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/opto/loopnode.hpp --- a/hotspot/src/share/vm/opto/loopnode.hpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/loopnode.hpp Thu Mar 31 14:25:35 2016 -0700 @@ -656,6 +656,9 @@ bool cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop); public: + + static bool is_canonical_main_loop_entry(CountedLoopNode* cl); + bool has_node( Node* n ) const { guarantee(n != NULL, "No Node."); return _nodes[n->_idx] != NULL; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/opto/memnode.cpp --- a/hotspot/src/share/vm/opto/memnode.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/memnode.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -742,7 +742,7 @@ // standard dump does this in Verbose and WizardMode st->print(" #"); _type->dump_on(st); } - if (!_depends_only_on_test) { + if (!depends_only_on_test()) { st->print(" (does not depend only on test)"); } } @@ -914,7 +914,7 @@ } } // load depends on the tests that validate the arraycopy - ld->as_Load()->_depends_only_on_test = Pinned; + ld->as_Load()->_control_dependency = Pinned; return ld; } return NULL; @@ -1118,6 +1118,44 @@ return this; } +// Construct an equivalent unsigned load. +Node* LoadNode::convert_to_unsigned_load(PhaseGVN& gvn) { + BasicType bt = T_ILLEGAL; + const Type* rt = NULL; + switch (Opcode()) { + case Op_LoadUB: return this; + case Op_LoadUS: return this; + case Op_LoadB: bt = T_BOOLEAN; rt = TypeInt::UBYTE; break; + case Op_LoadS: bt = T_CHAR; rt = TypeInt::CHAR; break; + default: + assert(false, "no unsigned variant: %s", Name()); + return NULL; + } + return LoadNode::make(gvn, in(MemNode::Control), in(MemNode::Memory), in(MemNode::Address), + raw_adr_type(), rt, bt, _mo, _control_dependency, + is_unaligned_access(), is_mismatched_access()); +} + +// Construct an equivalent signed load. +Node* LoadNode::convert_to_signed_load(PhaseGVN& gvn) { + BasicType bt = T_ILLEGAL; + const Type* rt = NULL; + switch (Opcode()) { + case Op_LoadUB: bt = T_BYTE; rt = TypeInt::BYTE; break; + case Op_LoadUS: bt = T_SHORT; rt = TypeInt::SHORT; break; + case Op_LoadB: // fall through + case Op_LoadS: // fall through + case Op_LoadI: // fall through + case Op_LoadL: return this; + default: + assert(false, "no signed variant: %s", Name()); + return NULL; + } + return LoadNode::make(gvn, in(MemNode::Control), in(MemNode::Memory), in(MemNode::Address), + raw_adr_type(), rt, bt, _mo, _control_dependency, + is_unaligned_access(), is_mismatched_access()); +} + // We're loading from an object which has autobox behaviour. // If this object is result of a valueOf call we'll have a phi // merging a newly allocated object and a load from the cache. @@ -1582,7 +1620,7 @@ return NULL; } -static bool is_mismatched_access(ciConstant con, BasicType loadbt) { +static ciConstant check_mismatched_access(ciConstant con, BasicType loadbt, bool is_unsigned) { BasicType conbt = con.basic_type(); switch (conbt) { case T_BOOLEAN: conbt = T_BYTE; break; @@ -1594,23 +1632,40 @@ case T_ARRAY: loadbt = T_OBJECT; break; case T_ADDRESS: loadbt = T_OBJECT; break; } - return (conbt != loadbt); + if (conbt == loadbt) { + if (is_unsigned && conbt == T_BYTE) { + // LoadB (T_BYTE) with a small mask (<=8-bit) is converted to LoadUB (T_BYTE). + return ciConstant(T_INT, con.as_int() & 0xFF); + } else { + return con; + } + } + if (conbt == T_SHORT && loadbt == T_CHAR) { + // LoadS (T_SHORT) with a small mask (<=16-bit) is converted to LoadUS (T_CHAR). + return ciConstant(T_INT, con.as_int() & 0xFFFF); + } + return ciConstant(); // T_ILLEGAL } // Try to constant-fold a stable array element. -static const Type* fold_stable_ary_elem(const TypeAryPtr* ary, int off, BasicType loadbt) { +static const Type* fold_stable_ary_elem(const TypeAryPtr* ary, int off, bool is_unsigned_load, BasicType loadbt) { assert(ary->const_oop(), "array should be constant"); assert(ary->is_stable(), "array should be stable"); // Decode the results of GraphKit::array_element_address. ciArray* aobj = ary->const_oop()->as_array(); - ciConstant con = aobj->element_value_by_offset(off); - if (con.basic_type() != T_ILLEGAL && !con.is_null_or_zero()) { - bool is_mismatched = is_mismatched_access(con, loadbt); - assert(!is_mismatched, "conbt=%s; loadbt=%s", type2name(con.basic_type()), type2name(loadbt)); + ciConstant element_value = aobj->element_value_by_offset(off); + if (element_value.basic_type() == T_ILLEGAL) { + return NULL; // wrong offset + } + ciConstant con = check_mismatched_access(element_value, loadbt, is_unsigned_load); + assert(con.basic_type() != T_ILLEGAL, "elembt=%s; loadbt=%s; unsigned=%d", + type2name(element_value.basic_type()), type2name(loadbt), is_unsigned_load); + + if (con.basic_type() != T_ILLEGAL && // not a mismatched access + !con.is_null_or_zero()) { // not a default value const Type* con_type = Type::make_from_constant(con); - // Guard against erroneous constant folding. - if (!is_mismatched && con_type != NULL) { + if (con_type != NULL) { if (con_type->isa_aryptr()) { // Join with the array element type, in case it is also stable. int dim = ary->stable_dimension(); @@ -1662,7 +1717,7 @@ if (FoldStableValues && !is_mismatched_access() && ary->is_stable() && ary->const_oop() != NULL) { // Make sure the reference is not into the header and the offset is constant if (off_beyond_header && adr->is_AddP() && off != Type::OffsetBot) { - const Type* con_type = fold_stable_ary_elem(ary, off, memory_type()); + const Type* con_type = fold_stable_ary_elem(ary, off, is_unsigned(), memory_type()); if (con_type != NULL) { return con_type; } diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/opto/memnode.hpp --- a/hotspot/src/share/vm/opto/memnode.hpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/memnode.hpp Thu Mar 31 14:25:35 2016 -0700 @@ -148,9 +148,8 @@ class LoadNode : public MemNode { public: // Some loads (from unsafe) should be pinned: they don't depend only - // on the dominating test. The boolean field _depends_only_on_test - // below records whether that node depends only on the dominating - // test. + // on the dominating test. The field _control_dependency below records + // whether that node depends only on the dominating test. // Methods used to build LoadNodes pass an argument of type enum // ControlDependency instead of a boolean because those methods // typically have multiple boolean parameters with default values: @@ -162,7 +161,7 @@ DependsOnlyOnTest }; private: - // LoadNode::hash() doesn't take the _depends_only_on_test field + // LoadNode::hash() doesn't take the _control_dependency field // into account: If the graph already has a non-pinned LoadNode and // we add a pinned LoadNode with the same inputs, it's safe for GVN // to replace the pinned LoadNode with the non-pinned LoadNode, @@ -171,7 +170,7 @@ // pinned LoadNode and we add a non pinned LoadNode with the same // inputs, it's safe (but suboptimal) for GVN to replace the // non-pinned LoadNode by the pinned LoadNode. - bool _depends_only_on_test; + ControlDependency _control_dependency; // On platforms with weak memory ordering (e.g., PPC, Ia64) we distinguish // loads that can be reordered, and such requiring acquire semantics to @@ -190,7 +189,7 @@ public: LoadNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *rt, MemOrd mo, ControlDependency control_dependency) - : MemNode(c,mem,adr,at), _type(rt), _mo(mo), _depends_only_on_test(control_dependency == DependsOnlyOnTest) { + : MemNode(c,mem,adr,at), _type(rt), _mo(mo), _control_dependency(control_dependency) { init_class_id(Class_Load); } inline bool is_unordered() const { return !is_acquire(); } @@ -198,6 +197,10 @@ assert(_mo == unordered || _mo == acquire, "unexpected"); return _mo == acquire; } + inline bool is_unsigned() const { + int lop = Opcode(); + return (lop == Op_LoadUB) || (lop == Op_LoadUS); + } // Polymorphic factory method: static Node* make(PhaseGVN& gvn, Node *c, Node *mem, Node *adr, @@ -252,6 +255,9 @@ // Check if the load's memory input is a Phi node with the same control. bool is_instance_field_load_with_local_phi(Node* ctrl); + Node* convert_to_unsigned_load(PhaseGVN& gvn); + Node* convert_to_signed_load(PhaseGVN& gvn); + #ifndef PRODUCT virtual void dump_spec(outputStream *st) const; #endif @@ -274,7 +280,9 @@ // which produce results (new raw memory state) inside of loops preventing all // manner of other optimizations). Basically, it's ugly but so is the alternative. // See comment in macro.cpp, around line 125 expand_allocate_common(). - virtual bool depends_only_on_test() const { return adr_type() != TypeRawPtr::BOTTOM && _depends_only_on_test; } + virtual bool depends_only_on_test() const { + return adr_type() != TypeRawPtr::BOTTOM && _control_dependency == DependsOnlyOnTest; + } }; //------------------------------LoadBNode-------------------------------------- diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/opto/mulnode.cpp --- a/hotspot/src/share/vm/opto/mulnode.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/mulnode.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -483,11 +483,7 @@ if (can_reshape && load->outcnt() == 1 && load->unique_out() == this) { if (lop == Op_LoadS && (mask & 0xFFFF0000) == 0 ) { - Node *ldus = new LoadUSNode(load->in(MemNode::Control), - load->in(MemNode::Memory), - load->in(MemNode::Address), - load->adr_type(), - TypeInt::CHAR, MemNode::unordered); + Node* ldus = load->as_Load()->convert_to_unsigned_load(*phase); ldus = phase->transform(ldus); return new AndINode(ldus, phase->intcon(mask & 0xFFFF)); } @@ -495,11 +491,7 @@ // Masking sign bits off of a Byte? Do an unsigned byte load plus // an and. if (lop == Op_LoadB && (mask & 0xFFFFFF00) == 0) { - Node* ldub = new LoadUBNode(load->in(MemNode::Control), - load->in(MemNode::Memory), - load->in(MemNode::Address), - load->adr_type(), - TypeInt::UBYTE, MemNode::unordered); + Node* ldub = load->as_Load()->convert_to_unsigned_load(*phase); ldub = phase->transform(ldub); return new AndINode(ldub, phase->intcon(mask)); } @@ -934,11 +926,7 @@ ld->Opcode() == Op_LoadUS && ld->outcnt() == 1 && ld->unique_out() == shl) // Replace zero-extension-load with sign-extension-load - return new LoadSNode( ld->in(MemNode::Control), - ld->in(MemNode::Memory), - ld->in(MemNode::Address), - ld->adr_type(), TypeInt::SHORT, - MemNode::unordered); + return ld->as_Load()->convert_to_signed_load(*phase); } // Check for "(byte[i] <<24)>>24" which simply sign-extends diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/opto/reg_split.cpp --- a/hotspot/src/share/vm/opto/reg_split.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/reg_split.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -287,7 +287,7 @@ Node* clone_node(Node* def, Block *b, Compile* C) { if (def->needs_anti_dependence_check()) { #ifdef ASSERT - if (Verbose) { + if (PrintOpto && WizardMode) { tty->print_cr("RA attempts to clone node with anti_dependence:"); def->dump(-1); tty->cr(); tty->print_cr("into block:"); diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/opto/superword.cpp --- a/hotspot/src/share/vm/opto/superword.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/opto/superword.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -3074,21 +3074,13 @@ //----------------------------get_pre_loop_end--------------------------- // Find pre loop end from main loop. Returns null if none. CountedLoopEndNode* SuperWord::get_pre_loop_end(CountedLoopNode* cl) { - Node* ctrl = cl->in(LoopNode::EntryControl); - if (!ctrl->is_IfTrue() && !ctrl->is_IfFalse()) return NULL; - Node* iffm = ctrl->in(0); - if (!iffm->is_If()) return NULL; - Node* bolzm = iffm->in(1); - if (!bolzm->is_Bool()) return NULL; - Node* cmpzm = bolzm->in(1); - if (!cmpzm->is_Cmp()) return NULL; - Node* opqzm = cmpzm->in(2); - // Can not optimize a loop if zero-trip Opaque1 node is optimized - // away and then another round of loop opts attempted. - if (opqzm->Opcode() != Op_Opaque1) { + // The loop cannot be optimized if the graph shape at + // the loop entry is inappropriate. + if (!PhaseIdealLoop::is_canonical_main_loop_entry(cl)) { return NULL; } - Node* p_f = iffm->in(0); + + Node* p_f = cl->in(LoopNode::EntryControl)->in(0)->in(0); if (!p_f->is_IfFalse()) return NULL; if (!p_f->in(0)->is_CountedLoopEnd()) return NULL; CountedLoopEndNode* pre_end = p_f->in(0)->as_CountedLoopEnd(); diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/prims/methodHandles.cpp --- a/hotspot/src/share/vm/prims/methodHandles.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/prims/methodHandles.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -318,9 +318,9 @@ // JVM 2.9 Special Methods: // A method is signature polymorphic if and only if all of the following conditions hold : -// * It is declared in the java.lang.invoke.MethodHandle class. +// * It is declared in the java.lang.invoke.MethodHandle/VarHandle classes. // * It has a single formal parameter of type Object[]. -// * It has a return type of Object. +// * It has a return type of Object for a polymorphic return type, otherwise a fixed return type. // * It has the ACC_VARARGS and ACC_NATIVE flags set. bool MethodHandles::is_method_handle_invoke_name(Klass* klass, Symbol* name) { if (klass == NULL) @@ -328,14 +328,36 @@ // The following test will fail spuriously during bootstrap of MethodHandle itself: // if (klass != SystemDictionary::MethodHandle_klass()) // Test the name instead: - if (klass->name() != vmSymbols::java_lang_invoke_MethodHandle()) + if (klass->name() != vmSymbols::java_lang_invoke_MethodHandle() && + klass->name() != vmSymbols::java_lang_invoke_VarHandle()) { return false; + } + + // Look up signature polymorphic method with polymorphic return type Symbol* poly_sig = vmSymbols::object_array_object_signature(); - Method* m = InstanceKlass::cast(klass)->find_method(name, poly_sig); - if (m == NULL) return false; - int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS; - int flags = m->access_flags().as_int(); - return (flags & required) == required; + InstanceKlass* iklass = InstanceKlass::cast(klass); + Method* m = iklass->find_method(name, poly_sig); + if (m != NULL) { + int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS; + int flags = m->access_flags().as_int(); + if ((flags & required) == required) { + return true; + } + } + + // Look up signature polymorphic method with non-polymorphic (non Object) return type + int me; + int ms = iklass->find_method_by_name(name, &me); + if (ms == -1) return false; + for (; ms < me; ms++) { + Method* m = iklass->methods()->at(ms); + int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS; + int flags = m->access_flags().as_int(); + if ((flags & required) == required && ArgumentCount(m->signature()).size() == 1) { + return true; + } + } + return false; } @@ -395,8 +417,16 @@ // Cover the case of invokeExact and any future variants of invokeFoo. Klass* mh_klass = SystemDictionary::well_known_klass( SystemDictionary::WK_KLASS_ENUM_NAME(MethodHandle_klass) ); - if (mh_klass != NULL && is_method_handle_invoke_name(mh_klass, name)) + if (mh_klass != NULL && is_method_handle_invoke_name(mh_klass, name)) { return vmIntrinsics::_invokeGeneric; + } + + // Cover the case of methods on VarHandle. + Klass* vh_klass = SystemDictionary::well_known_klass( + SystemDictionary::WK_KLASS_ENUM_NAME(VarHandle_klass) ); + if (vh_klass != NULL && is_method_handle_invoke_name(vh_klass, name)) { + return vmIntrinsics::_invokeGeneric; + } // Note: The pseudo-intrinsic _compiledLambdaForm is never linked against. // Instead it is used to mark lambda forms bound to invokehandle or invokedynamic. @@ -405,7 +435,8 @@ vmIntrinsics::ID MethodHandles::signature_polymorphic_name_id(Klass* klass, Symbol* name) { if (klass != NULL && - klass->name() == vmSymbols::java_lang_invoke_MethodHandle()) { + (klass->name() == vmSymbols::java_lang_invoke_MethodHandle() || + klass->name() == vmSymbols::java_lang_invoke_VarHandle())) { vmIntrinsics::ID iid = signature_polymorphic_name_id(name); if (iid != vmIntrinsics::_none) return iid; @@ -1197,10 +1228,10 @@ THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "obsolete MemberName format"); } if ((flags & ALL_KINDS) == IS_FIELD) { - THROW_MSG_NULL(vmSymbols::java_lang_NoSuchMethodError(), "field resolution failed"); + THROW_MSG_NULL(vmSymbols::java_lang_NoSuchFieldError(), "field resolution failed"); } else if ((flags & ALL_KINDS) == IS_METHOD || (flags & ALL_KINDS) == IS_CONSTRUCTOR) { - THROW_MSG_NULL(vmSymbols::java_lang_NoSuchFieldError(), "method resolution failed"); + THROW_MSG_NULL(vmSymbols::java_lang_NoSuchMethodError(), "method resolution failed"); } else { THROW_MSG_NULL(vmSymbols::java_lang_LinkageError(), "resolution failed"); } diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/prims/methodHandles.hpp --- a/hotspot/src/share/vm/prims/methodHandles.hpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/prims/methodHandles.hpp Thu Mar 31 14:25:35 2016 -0700 @@ -120,7 +120,8 @@ iid <= vmIntrinsics::_linkToInterface); } static bool has_member_arg(Symbol* klass, Symbol* name) { - if ((klass == vmSymbols::java_lang_invoke_MethodHandle()) && + if ((klass == vmSymbols::java_lang_invoke_MethodHandle() || + klass == vmSymbols::java_lang_invoke_VarHandle()) && is_signature_polymorphic_name(name)) { vmIntrinsics::ID iid = signature_polymorphic_name_id(name); return has_member_arg(iid); diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/prims/unsafe.cpp --- a/hotspot/src/share/vm/prims/unsafe.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/prims/unsafe.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -378,44 +378,6 @@ #undef DEFINE_GETSETOOP_VOLATILE -// The non-intrinsified versions of setOrdered just use setVolatile - -UNSAFE_ENTRY(void, Unsafe_SetOrderedInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint x)) { - SET_FIELD_VOLATILE(obj, offset, jint, x); -} UNSAFE_END - -UNSAFE_ENTRY(void, Unsafe_SetOrderedObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) { - oop x = JNIHandles::resolve(x_h); - oop p = JNIHandles::resolve(obj); - void* addr = index_oop_from_field_offset_long(p, offset); - OrderAccess::release(); - - if (UseCompressedOops) { - oop_store((narrowOop*)addr, x); - } else { - oop_store((oop*)addr, x); - } - - OrderAccess::fence(); -} UNSAFE_END - -UNSAFE_ENTRY(void, Unsafe_SetOrderedLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong x)) { -#ifdef SUPPORTS_NATIVE_CX8 - SET_FIELD_VOLATILE(obj, offset, jlong, x); -#else - - // Keep old code for platforms which may not have atomic long (8 bytes) instructions - if (VM_Version::supports_cx8()) { - SET_FIELD_VOLATILE(obj, offset, jlong, x); - } else { - Handle p(THREAD, JNIHandles::resolve(obj)); - jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset)); - MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag); - Atomic::store(x, addr); - } -#endif -} UNSAFE_END - UNSAFE_LEAF(void, Unsafe_LoadFence(JNIEnv *env, jobject unsafe)) { OrderAccess::acquire(); } UNSAFE_END @@ -1230,9 +1192,6 @@ {CC "compareAndExchangeIntVolatile", CC "(" OBJ "J""I""I"")I", FN_PTR(Unsafe_CompareAndExchangeInt)}, {CC "compareAndExchangeLongVolatile", CC "(" OBJ "J""J""J"")J", FN_PTR(Unsafe_CompareAndExchangeLong)}, - {CC "putOrderedObject", CC "(" OBJ "J" OBJ ")V", FN_PTR(Unsafe_SetOrderedObject)}, - {CC "putOrderedInt", CC "(" OBJ "JI)V", FN_PTR(Unsafe_SetOrderedInt)}, - {CC "putOrderedLong", CC "(" OBJ "JJ)V", FN_PTR(Unsafe_SetOrderedLong)}, {CC "park", CC "(ZJ)V", FN_PTR(Unsafe_Park)}, {CC "unpark", CC "(" OBJ ")V", FN_PTR(Unsafe_Unpark)}, diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/runtime/arguments.cpp --- a/hotspot/src/share/vm/runtime/arguments.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/runtime/arguments.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -2550,6 +2550,13 @@ warning("Reserved Stack Area not supported on this platform"); } #endif + + if (BackgroundCompilation && (CompileTheWorld || ReplayCompiles)) { + if (!FLAG_IS_DEFAULT(BackgroundCompilation)) { + warning("BackgroundCompilation disabled due to CompileTheWorld or ReplayCompiles options."); + } + FLAG_SET_CMDLINE(bool, BackgroundCompilation, false); + } return status; } diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/runtime/globals.hpp --- a/hotspot/src/share/vm/runtime/globals.hpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/runtime/globals.hpp Thu Mar 31 14:25:35 2016 -0700 @@ -727,7 +727,7 @@ "Control whether SHA instructions can be used " \ "on SPARC, on ARM and on x86") \ \ - product(bool, UseGHASHIntrinsics, false, \ + diagnostic(bool, UseGHASHIntrinsics, false, \ "Use intrinsics for GHASH versions of crypto") \ \ product(size_t, LargePageSizeInBytes, 0, \ @@ -797,27 +797,27 @@ product(bool, UseInlineCaches, true, \ "Use Inline Caches for virtual calls ") \ \ - develop(bool, InlineArrayCopy, true, \ + diagnostic(bool, InlineArrayCopy, true, \ "Inline arraycopy native that is known to be part of " \ "base library DLL") \ \ - develop(bool, InlineObjectHash, true, \ + diagnostic(bool, InlineObjectHash, true, \ "Inline Object::hashCode() native that is known to be part " \ "of base library DLL") \ \ - develop(bool, InlineNatives, true, \ + diagnostic(bool, InlineNatives, true, \ "Inline natives that are known to be part of base library DLL") \ \ - develop(bool, InlineMathNatives, true, \ + diagnostic(bool, InlineMathNatives, true, \ "Inline SinD, CosD, etc.") \ \ - develop(bool, InlineClassNatives, true, \ + diagnostic(bool, InlineClassNatives, true, \ "Inline Class.isInstance, etc") \ \ - develop(bool, InlineThreadNatives, true, \ + diagnostic(bool, InlineThreadNatives, true, \ "Inline Thread.currentThread, etc") \ \ - develop(bool, InlineUnsafeOps, true, \ + diagnostic(bool, InlineUnsafeOps, true, \ "Inline memory ops (native methods) from Unsafe") \ \ product(bool, CriticalJNINatives, true, \ @@ -826,34 +826,34 @@ notproduct(bool, StressCriticalJNINatives, false, \ "Exercise register saving code in critical natives") \ \ - product(bool, UseAESIntrinsics, false, \ + diagnostic(bool, UseAESIntrinsics, false, \ "Use intrinsics for AES versions of crypto") \ \ - product(bool, UseAESCTRIntrinsics, false, \ + diagnostic(bool, UseAESCTRIntrinsics, false, \ "Use intrinsics for the paralleled version of AES/CTR crypto") \ \ - product(bool, UseSHA1Intrinsics, false, \ + diagnostic(bool, UseSHA1Intrinsics, false, \ "Use intrinsics for SHA-1 crypto hash function. " \ "Requires that UseSHA is enabled.") \ \ - product(bool, UseSHA256Intrinsics, false, \ + diagnostic(bool, UseSHA256Intrinsics, false, \ "Use intrinsics for SHA-224 and SHA-256 crypto hash functions. " \ "Requires that UseSHA is enabled.") \ \ - product(bool, UseSHA512Intrinsics, false, \ + diagnostic(bool, UseSHA512Intrinsics, false, \ "Use intrinsics for SHA-384 and SHA-512 crypto hash functions. " \ "Requires that UseSHA is enabled.") \ \ - product(bool, UseCRC32Intrinsics, false, \ + diagnostic(bool, UseCRC32Intrinsics, false, \ "use intrinsics for java.util.zip.CRC32") \ \ - product(bool, UseCRC32CIntrinsics, false, \ + diagnostic(bool, UseCRC32CIntrinsics, false, \ "use intrinsics for java.util.zip.CRC32C") \ \ - product(bool, UseAdler32Intrinsics, false, \ + diagnostic(bool, UseAdler32Intrinsics, false, \ "use intrinsics for java.util.zip.Adler32") \ \ - product(bool, UseVectorizedMismatchIntrinsic, false, \ + diagnostic(bool, UseVectorizedMismatchIntrinsic, false, \ "Enables intrinsification of ArraysSupport.vectorizedMismatch()") \ \ diagnostic(ccstrlist, DisableIntrinsic, "", \ diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/runtime/sweeper.cpp --- a/hotspot/src/share/vm/runtime/sweeper.cpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/runtime/sweeper.cpp Thu Mar 31 14:25:35 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -146,7 +146,6 @@ volatile int NMethodSweeper::_bytes_changed = 0; // Counts the total nmethod size if the nmethod changed from: // 1) alive -> not_entrant // 2) not_entrant -> zombie - // 3) zombie -> marked_for_reclamation int NMethodSweeper::_hotness_counter_reset_val = 0; long NMethodSweeper::_total_nof_methods_reclaimed = 0; // Accumulated nof methods flushed @@ -355,8 +354,8 @@ bool forced = _force_sweep; // Force stack scanning if there is only 10% free space in the code cache. - // We force stack scanning only non-profiled code heap gets full, since critical - // allocation go to the non-profiled heap and we must be make sure that there is + // We force stack scanning only if the non-profiled code heap gets full, since critical + // allocations go to the non-profiled heap and we must be make sure that there is // enough space. double free_percent = 1 / CodeCache::reverse_free_ratio(CodeBlobType::MethodNonProfiled) * 100; if (free_percent <= StartAggressiveSweepingAt) { @@ -397,7 +396,6 @@ int flushed_count = 0; int zombified_count = 0; - int marked_for_reclamation_count = 0; int flushed_c2_count = 0; if (PrintMethodFlushing && Verbose) { @@ -423,22 +421,27 @@ // Now ready to process nmethod and give up CodeCache_lock { MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + // Save information before potentially flushing the nmethod int size = nm->total_size(); bool is_c2_method = nm->is_compiled_by_c2(); + bool is_osr = nm->is_osr_method(); + int compile_id = nm->compile_id(); + intptr_t address = p2i(nm); + const char* state_before = nm->state(); + const char* state_after = ""; MethodStateChange type = process_nmethod(nm); switch (type) { case Flushed: + state_after = "flushed"; freed_memory += size; ++flushed_count; if (is_c2_method) { ++flushed_c2_count; } break; - case MarkedForReclamation: - ++marked_for_reclamation_count; - break; case MadeZombie: + state_after = "made zombie"; ++zombified_count; break; case None: @@ -446,7 +449,11 @@ default: ShouldNotReachHere(); } + if (PrintMethodFlushing && Verbose && type != None) { + tty->print_cr("### %s nmethod %3d/" PTR_FORMAT " (%s) %s", is_osr ? "osr" : "", compile_id, address, state_before, state_after); + } } + _seen++; handle_safepoint_request(); } @@ -473,7 +480,6 @@ event.set_sweepIndex(_traversals); event.set_sweptCount(swept_count); event.set_flushedCount(flushed_count); - event.set_markedCount(marked_for_reclamation_count); event.set_zombifiedCount(zombified_count); event.commit(); } @@ -533,7 +539,7 @@ NMethodMarker(nmethod* nm) { JavaThread* current = JavaThread::current(); assert (current->is_Code_cache_sweeper_thread(), "Must be"); - _thread = (CodeCacheSweeperThread*)JavaThread::current(); + _thread = (CodeCacheSweeperThread*)current; if (!nm->is_zombie() && !nm->is_unloaded()) { // Only expose live nmethods for scanning _thread->set_scanned_nmethod(nm); @@ -545,6 +551,10 @@ }; void NMethodSweeper::release_nmethod(nmethod* nm) { + // Make sure the released nmethod is no longer referenced by the sweeper thread + CodeCacheSweeperThread* thread = (CodeCacheSweeperThread*)JavaThread::current(); + thread->set_scanned_nmethod(NULL); + // Clean up any CompiledICHolders { ResourceMark rm; @@ -575,7 +585,7 @@ if (nm->is_locked_by_vm()) { // But still remember to clean-up inline caches for alive nmethods if (nm->is_alive()) { - // Clean inline caches that point to zombie/non-entrant methods + // Clean inline caches that point to zombie/non-entrant/unloaded nmethods MutexLocker cl(CompiledIC_lock); nm->cleanup_inline_caches(); SWEEP(nm); @@ -584,47 +594,41 @@ } if (nm->is_zombie()) { - // If it is the first time we see nmethod then we mark it. Otherwise, - // we reclaim it. When we have seen a zombie method twice, we know that - // there are no inline caches that refer to it. - if (nm->is_marked_for_reclamation()) { - assert(!nm->is_locked_by_vm(), "must not flush locked nmethods"); - if (PrintMethodFlushing && Verbose) { - tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), p2i(nm)); - } - release_nmethod(nm); - assert(result == None, "sanity"); - result = Flushed; - } else { - if (PrintMethodFlushing && Verbose) { - tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), p2i(nm)); - } - nm->mark_for_reclamation(); - // Keep track of code cache state change - _bytes_changed += nm->total_size(); - SWEEP(nm); - assert(result == None, "sanity"); - result = MarkedForReclamation; - } + // All inline caches that referred to this nmethod were cleaned in the + // previous sweeper cycle. Now flush the nmethod from the code cache. + assert(!nm->is_locked_by_vm(), "must not flush locked nmethods"); + release_nmethod(nm); + assert(result == None, "sanity"); + result = Flushed; } else if (nm->is_not_entrant()) { // If there are no current activations of this method on the // stack we can safely convert it to a zombie method if (nm->can_convert_to_zombie()) { - // Clear ICStubs to prevent back patching stubs of zombie or unloaded + // Clear ICStubs to prevent back patching stubs of zombie or flushed // nmethods during the next safepoint (see ICStub::finalize). { MutexLocker cl(CompiledIC_lock); nm->clear_ic_stubs(); } - if (PrintMethodFlushing && Verbose) { - tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (not entrant) being made zombie", nm->compile_id(), p2i(nm)); - } // Code cache state change is tracked in make_zombie() nm->make_zombie(); SWEEP(nm); - assert(result == None, "sanity"); - result = MadeZombie; - assert(nm->is_zombie(), "nmethod must be zombie"); + // The nmethod may have been locked by JVMTI after being made zombie (see + // JvmtiDeferredEvent::compiled_method_unload_event()). If so, we cannot + // flush the osr nmethod directly but have to wait for a later sweeper cycle. + if (nm->is_osr_method() && !nm->is_locked_by_vm()) { + // No inline caches will ever point to osr methods, so we can just remove it. + // Make sure that we unregistered the nmethod with the heap and flushed all + // dependencies before removing the nmethod (done in make_zombie()). + assert(nm->is_zombie(), "nmethod must be unregistered"); + release_nmethod(nm); + assert(result == None, "sanity"); + result = Flushed; + } else { + assert(result == None, "sanity"); + result = MadeZombie; + assert(nm->is_zombie(), "nmethod must be zombie"); + } } else { // Still alive, clean up its inline caches MutexLocker cl(CompiledIC_lock); @@ -632,9 +636,13 @@ SWEEP(nm); } } else if (nm->is_unloaded()) { - // Unloaded code, just make it a zombie - if (PrintMethodFlushing && Verbose) { - tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), p2i(nm)); + // Code is unloaded, so there are no activations on the stack. + // Convert the nmethod to zombie or flush it directly in the OSR case. + { + // Clean ICs of unloaded nmethods as well because they may reference other + // unloaded nmethods that may be flushed earlier in the sweeper cycle. + MutexLocker cl(CompiledIC_lock); + nm->cleanup_inline_caches(); } if (nm->is_osr_method()) { SWEEP(nm); @@ -643,12 +651,6 @@ assert(result == None, "sanity"); result = Flushed; } else { - { - // Clean ICs of unloaded nmethods as well because they may reference other - // unloaded nmethods that may be flushed earlier in the sweeper cycle. - MutexLocker cl(CompiledIC_lock); - nm->cleanup_inline_caches(); - } // Code cache state change is tracked in make_zombie() nm->make_zombie(); SWEEP(nm); @@ -657,7 +659,7 @@ } } else { possibly_flush(nm); - // Clean-up all inline caches that point to zombie/non-reentrant methods + // Clean inline caches that point to zombie/non-entrant/unloaded nmethods MutexLocker cl(CompiledIC_lock); nm->cleanup_inline_caches(); SWEEP(nm); @@ -668,10 +670,10 @@ void NMethodSweeper::possibly_flush(nmethod* nm) { if (UseCodeCacheFlushing) { - if (!nm->is_locked_by_vm() && !nm->is_osr_method() && !nm->is_native_method()) { + if (!nm->is_locked_by_vm() && !nm->is_native_method()) { bool make_not_entrant = false; - // Do not make native methods and OSR-methods not-entrant + // Do not make native methods not-entrant nm->dec_hotness_counter(); // Get the initial value of the hotness counter. This value depends on the // ReservedCodeCacheSize diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/runtime/sweeper.hpp --- a/hotspot/src/share/vm/runtime/sweeper.hpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/runtime/sweeper.hpp Thu Mar 31 14:25:35 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,12 +45,12 @@ // and sweep_code_cache() cannot execute at the same time. // To reclaim memory, nmethods are first marked as 'not-entrant'. Methods can // be made not-entrant by (i) the sweeper, (ii) deoptimization, (iii) dependency -// invalidation, and (iv) being replaced be a different method version (tiered -// compilation). Not-entrant nmethod cannot be called by Java threads, but they -// can still be active on the stack. To ensure that active nmethod are not reclaimed, +// invalidation, and (iv) being replaced by a different method version (tiered +// compilation). Not-entrant nmethods cannot be called by Java threads, but they +// can still be active on the stack. To ensure that active nmethods are not reclaimed, // we have to wait until the next marking phase has completed. If a not-entrant // nmethod was NOT marked as active, it can be converted to 'zombie' state. To safely -// remove the nmethod, all inline caches (IC) that point to the the nmethod must be +// remove the nmethod, all inline caches (IC) that point to the nmethod must be // cleared. After that, the nmethod can be evicted from the code cache. Each nmethod's // state change happens during separate sweeps. It may take at least 3 sweeps before an // nmethod's space is freed. @@ -60,7 +60,6 @@ enum MethodStateChange { None, MadeZombie, - MarkedForReclamation, Flushed }; static long _traversals; // Stack scan count, also sweep ID. @@ -76,7 +75,6 @@ static volatile int _bytes_changed; // Counts the total nmethod size if the nmethod changed from: // 1) alive -> not_entrant // 2) not_entrant -> zombie - // 3) zombie -> marked_for_reclamation // Stat counters static long _total_nof_methods_reclaimed; // Accumulated nof methods flushed static long _total_nof_c2_methods_reclaimed; // Accumulated nof C2-compiled methods flushed diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/trace/trace.xml --- a/hotspot/src/share/vm/trace/trace.xml Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/trace/trace.xml Thu Mar 31 14:25:35 2016 -0700 @@ -550,7 +550,6 @@ - diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/src/share/vm/utilities/globalDefinitions.hpp --- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp Thu Mar 31 14:25:35 2016 -0700 @@ -1056,6 +1056,7 @@ const int badResourceValue = 0xAB; // value used to zap resource area const int freeBlockPad = 0xBA; // value used to pad freed blocks. const int uninitBlockPad = 0xF1; // value used to zap newly malloc'd blocks. +const juint uninitMetaWordVal= 0xf7f7f7f7; // value used to zap newly allocated metachunk const intptr_t badJNIHandleVal = (intptr_t) UCONST64(0xFEFEFEFEFEFEFEFE); // value used to zap jni handle area const juint badHeapWordVal = 0xBAADBABE; // value used to zap heap after GC const juint badMetaWordVal = 0xBAADFADE; // value used to zap metadata heap after GC diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/TEST.groups --- a/hotspot/test/TEST.groups Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/TEST.groups Thu Mar 31 14:25:35 2016 -0700 @@ -98,7 +98,7 @@ serviceability/attach/AttachWithStalePidFile.java \ serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java \ serviceability/dcmd/vm/DynLibsTest.java \ - serviceability/tmtools + serviceability/tmtools # JRE adds further tests to compact3 @@ -248,7 +248,7 @@ gc/metaspace/G1AddMetaspaceDependency.java \ gc/metaspace/TestMetaspacePerfCounters.java \ gc/startup_warnings/TestG1.java \ - gc/whitebox/TestConcMarkCycleWB.java + gc/whitebox/TestConcMarkCycleWB.java hotspot_native_sanity = \ native_sanity @@ -267,7 +267,7 @@ -compiler/c2/6792161 \ -compiler/c2/7070134 \ -compiler/c2/8004867 - + hotspot_compiler_2 = \ compiler/classUnloading/ \ compiler/codecache/ \ @@ -284,8 +284,9 @@ compiler/interpreter/ \ compiler/jvmci/ \ -compiler/codegen/7184394 \ - -compiler/codecache/stress - + -compiler/codecache/stress \ + -compiler/gcbarriers/PreserveFPRegistersTest.java + hotspot_compiler_3 = \ compiler/intrinsics/ \ compiler/jsr292/ \ @@ -370,4 +371,4 @@ -:needs_nashorn hotspot_tmtools = \ - serviceability/tmtools + serviceability/tmtools diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/commandfile/CompileOnlyTest.java --- a/hotspot/test/compiler/compilercontrol/commandfile/CompileOnlyTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/commandfile/CompileOnlyTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.commandfile.CompileOnlyTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.commandfile.CompileOnlyTest + * @run driver compiler.compilercontrol.commandfile.CompileOnlyTest */ package compiler.compilercontrol.commandfile; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/commandfile/ExcludeTest.java --- a/hotspot/test/compiler/compilercontrol/commandfile/ExcludeTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/commandfile/ExcludeTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.commandfile.ExcludeTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.commandfile.ExcludeTest + * @run driver compiler.compilercontrol.commandfile.ExcludeTest */ package compiler.compilercontrol.commandfile; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/commandfile/LogTest.java --- a/hotspot/test/compiler/compilercontrol/commandfile/LogTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/commandfile/LogTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.commandfile.LogTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.commandfile.LogTest + * @run driver compiler.compilercontrol.commandfile.LogTest */ package compiler.compilercontrol.commandfile; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/commandfile/PrintTest.java --- a/hotspot/test/compiler/compilercontrol/commandfile/PrintTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/commandfile/PrintTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -30,9 +30,9 @@ * @build compiler.compilercontrol.commandfile.PrintTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.commandfile.PrintTest + * @run driver compiler.compilercontrol.commandfile.PrintTest */ package compiler.compilercontrol.commandfile; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/commands/CompileOnlyTest.java --- a/hotspot/test/compiler/compilercontrol/commands/CompileOnlyTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/commands/CompileOnlyTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.commands.CompileOnlyTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.commands.CompileOnlyTest + * @run driver compiler.compilercontrol.commands.CompileOnlyTest */ package compiler.compilercontrol.commands; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/commands/ExcludeTest.java --- a/hotspot/test/compiler/compilercontrol/commands/ExcludeTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/commands/ExcludeTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.commands.ExcludeTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.commands.ExcludeTest + * @run driver compiler.compilercontrol.commands.ExcludeTest */ package compiler.compilercontrol.commands; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/commands/LogTest.java --- a/hotspot/test/compiler/compilercontrol/commands/LogTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/commands/LogTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.commands.LogTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.commands.LogTest + * @run driver compiler.compilercontrol.commands.LogTest */ package compiler.compilercontrol.commands; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/commands/PrintTest.java --- a/hotspot/test/compiler/compilercontrol/commands/PrintTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/commands/PrintTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -30,9 +30,9 @@ * @build compiler.compilercontrol.commands.PrintTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.commands.PrintTest + * @run driver compiler.compilercontrol.commands.PrintTest */ package compiler.compilercontrol.commands; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/directives/CompileOnlyTest.java --- a/hotspot/test/compiler/compilercontrol/directives/CompileOnlyTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/directives/CompileOnlyTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.directives.CompileOnlyTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.directives.CompileOnlyTest + * @run driver compiler.compilercontrol.directives.CompileOnlyTest */ package compiler.compilercontrol.directives; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/directives/ExcludeTest.java --- a/hotspot/test/compiler/compilercontrol/directives/ExcludeTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/directives/ExcludeTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.directives.ExcludeTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.directives.ExcludeTest + * @run driver compiler.compilercontrol.directives.ExcludeTest */ package compiler.compilercontrol.directives; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/directives/LogTest.java --- a/hotspot/test/compiler/compilercontrol/directives/LogTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/directives/LogTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.directives.LogTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.directives.LogTest + * @run driver compiler.compilercontrol.directives.LogTest */ package compiler.compilercontrol.directives; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/directives/PrintTest.java --- a/hotspot/test/compiler/compilercontrol/directives/PrintTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/directives/PrintTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -30,9 +30,9 @@ * @build compiler.compilercontrol.directives.PrintTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.directives.PrintTest + * @run driver compiler.compilercontrol.directives.PrintTest */ package compiler.compilercontrol.directives; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/jcmd/AddAndRemoveTest.java --- a/hotspot/test/compiler/compilercontrol/jcmd/AddAndRemoveTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/jcmd/AddAndRemoveTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.jcmd.AddAndRemoveTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.jcmd.AddAndRemoveTest + * @run driver compiler.compilercontrol.jcmd.AddAndRemoveTest */ package compiler.compilercontrol.jcmd; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/jcmd/AddCompileOnlyTest.java --- a/hotspot/test/compiler/compilercontrol/jcmd/AddCompileOnlyTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/jcmd/AddCompileOnlyTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.jcmd.AddCompileOnlyTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.jcmd.AddCompileOnlyTest + * @run driver compiler.compilercontrol.jcmd.AddCompileOnlyTest */ package compiler.compilercontrol.jcmd; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/jcmd/AddExcludeTest.java --- a/hotspot/test/compiler/compilercontrol/jcmd/AddExcludeTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/jcmd/AddExcludeTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.jcmd.AddExcludeTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.jcmd.AddExcludeTest + * @run driver compiler.compilercontrol.jcmd.AddExcludeTest */ package compiler.compilercontrol.jcmd; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/jcmd/AddLogTest.java --- a/hotspot/test/compiler/compilercontrol/jcmd/AddLogTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/jcmd/AddLogTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.jcmd.AddLogTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.jcmd.AddLogTest + * @run driver compiler.compilercontrol.jcmd.AddLogTest */ package compiler.compilercontrol.jcmd; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/jcmd/AddPrintAssemblyTest.java --- a/hotspot/test/compiler/compilercontrol/jcmd/AddPrintAssemblyTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/jcmd/AddPrintAssemblyTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -30,9 +30,9 @@ * @build compiler.compilercontrol.jcmd.AddPrintAssemblyTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.jcmd.AddPrintAssemblyTest + * @run driver compiler.compilercontrol.jcmd.AddPrintAssemblyTest */ package compiler.compilercontrol.jcmd; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/jcmd/ClearDirectivesFileStackTest.java --- a/hotspot/test/compiler/compilercontrol/jcmd/ClearDirectivesFileStackTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/jcmd/ClearDirectivesFileStackTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -30,9 +30,9 @@ * @build compiler.compilercontrol.jcmd.ClearDirectivesFileStackTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.jcmd.ClearDirectivesFileStackTest + * @run driver compiler.compilercontrol.jcmd.ClearDirectivesFileStackTest */ package compiler.compilercontrol.jcmd; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/jcmd/ClearDirectivesStackTest.java --- a/hotspot/test/compiler/compilercontrol/jcmd/ClearDirectivesStackTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/jcmd/ClearDirectivesStackTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.jcmd.ClearDirectivesStackTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.jcmd.ClearDirectivesStackTest + * @run driver compiler.compilercontrol.jcmd.ClearDirectivesStackTest */ package compiler.compilercontrol.jcmd; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/jcmd/PrintDirectivesTest.java --- a/hotspot/test/compiler/compilercontrol/jcmd/PrintDirectivesTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/jcmd/PrintDirectivesTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -30,9 +30,9 @@ * @build compiler.compilercontrol.jcmd.PrintDirectivesTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm compiler.compilercontrol.jcmd.PrintDirectivesTest + * @run driver compiler.compilercontrol.jcmd.PrintDirectivesTest */ package compiler.compilercontrol.jcmd; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/jcmd/StressAddMultiThreadedTest.java --- a/hotspot/test/compiler/compilercontrol/jcmd/StressAddMultiThreadedTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/jcmd/StressAddMultiThreadedTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -31,7 +31,7 @@ * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils * compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission * @run driver compiler.compilercontrol.jcmd.StressAddMultiThreadedTest */ diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/matcher/MethodMatcherTest.java --- a/hotspot/test/compiler/compilercontrol/matcher/MethodMatcherTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/matcher/MethodMatcherTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -42,7 +42,7 @@ * @summary Tests CompilerCommand's method matcher * @library /testlibrary /test/lib /compiler/whitebox ../share / * @build compiler.compilercontrol.matcher.MethodMatcherTest - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI compiler.compilercontrol.matcher.MethodMatcherTest diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/mixed/RandomCommandsTest.java --- a/hotspot/test/compiler/compilercontrol/mixed/RandomCommandsTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/mixed/RandomCommandsTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -29,9 +29,9 @@ * @build compiler.compilercontrol.mixed.RandomCommandsTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm/timeout=600 compiler.compilercontrol.mixed.RandomCommandsTest + * @run driver/timeout=600 compiler.compilercontrol.mixed.RandomCommandsTest */ package compiler.compilercontrol.mixed; diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/mixed/RandomValidCommandsTest.java --- a/hotspot/test/compiler/compilercontrol/mixed/RandomValidCommandsTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/mixed/RandomValidCommandsTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -30,7 +30,7 @@ * @build compiler.compilercontrol.mixed.RandomValidCommandsTest * pool.sub.* pool.subpack.* sun.hotspot.WhiteBox * compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.* - * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission * @run main/othervm/timeout=600 compiler.compilercontrol.mixed.RandomValidCommandsTest */ diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/share/MultiCommand.java --- a/hotspot/test/compiler/compilercontrol/share/MultiCommand.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/share/MultiCommand.java Thu Mar 31 14:25:35 2016 -0700 @@ -72,6 +72,7 @@ @Override public void test() { Scenario.Builder builder = Scenario.getBuilder(); + builder.addFlag("-Xmixed"); for (CompileCommand cc : testCases) { cc.print(); builder.add(cc); diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/compilercontrol/share/scenario/Scenario.java --- a/hotspot/test/compiler/compilercontrol/share/scenario/Scenario.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/compilercontrol/share/scenario/Scenario.java Thu Mar 31 14:25:35 2016 -0700 @@ -200,6 +200,7 @@ private final List jcmdCommands = new ArrayList<>(); public Builder() { + addFlag("-Xmixed"); builders.put(Type.FILE, new CommandFileBuilder(Type.FILE.fileName)); builders.put(Type.OPTION, new CommandOptionsBuilder()); builders.put(Type.DIRECTIVE, new DirectiveBuilder( @@ -207,6 +208,10 @@ jcmdStateBuilder = new JcmdStateBuilder(Type.JCMD.fileName); } + public void addFlag(String flag) { + vmopts.add(flag); + } + public void add(CompileCommand compileCommand) { String[] vmOptions = compileCommand.command.vmOpts; Collections.addAll(vmopts, vmOptions); diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/gcbarriers/PreserveFPRegistersTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/gcbarriers/PreserveFPRegistersTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/** + * @test + * @bug 8148175 + * @ignore 8153194 + * @run main/othervm/timeout=300 -Xbatch -Xmx128m PreserveFPRegistersTest + */ +public class PreserveFPRegistersTest { + + public static void main(String... args) throws InterruptedException { + new PreserveFPRegistersTest().go(); + } + + public final Object[][] storage; + + /** + * Number of objects per region. + */ + public final int K = 10; + + /** + * Length of object array: sizeOf(Object[N]) ~= regionSize / K . + */ + public final int N; + + /** + * How many regions involved into testing. + */ + public final int regionCount; + + PreserveFPRegistersTest() { + long regionSize = 1_000_000; //WB.g1RegionSize(); + + Runtime rt = Runtime.getRuntime(); + long used = rt.totalMemory() - rt.freeMemory(); + long totalFree = rt.maxMemory() - used; + regionCount = (int) ( (totalFree / regionSize) * 0.9); + int refSize = 4; + + N = (int) ((regionSize / K ) / refSize) - 5; + storage = new Object[regionCount * K][]; + for (int i = 0; i < storage.length; i++) { + storage[i] = new Object[N]; + } + } + + public void go() throws InterruptedException { + final float FINAL = getValue(); + + for (int to = 0; to < regionCount; to++) { + Object celebrity = storage[to * K]; + for (int from = 0; from < regionCount; from++) { + for (int rn = 0; rn != 100; rn++) { + storage[getY(to, from, rn)][getX(to, from, rn)] = celebrity; + } + if (FINAL != getValue()) { + throw new AssertionError("Final value has changed: " + FINAL + " != " + getValue()); + } + } + } + + System.out.println("TEST PASSED"); + } + + public float getValue() { + return 6; + } + + private int getX(int to, int from, int rn) { + return (rn*regionCount + to) % N; + } + + private int getY(int to, int from, int rn) { + return ((rn*regionCount + to) / N + from * K) % (regionCount*K) ; + } +} diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/intrinsics/muladd/TestMulAdd.java --- a/hotspot/test/compiler/intrinsics/muladd/TestMulAdd.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/intrinsics/muladd/TestMulAdd.java Thu Mar 31 14:25:35 2016 -0700 @@ -28,7 +28,7 @@ * @summary Add C2 x86 intrinsic for BigInteger::mulAdd() method * * @run main/othervm/timeout=600 -XX:-TieredCompilation -Xbatch - * -XX:+IgnoreUnrecognizedVMOptions -XX:-UseSquareToLenIntrinsic -XX:-UseMultiplyToLenIntrinsic + * -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:-UseSquareToLenIntrinsic -XX:-UseMultiplyToLenIntrinsic * -XX:CompileCommand=dontinline,TestMulAdd::main * -XX:CompileCommand=option,TestMulAdd::base_multiply,ccstr,DisableIntrinsic,_mulAdd * -XX:CompileCommand=option,java.math.BigInteger::multiply,ccstr,DisableIntrinsic,_mulAdd diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/intrinsics/string/TestHasNegatives.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/intrinsics/string/TestHasNegatives.java Thu Mar 31 14:25:35 2016 -0700 @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8054307 + * @summary Validates StringCoding.hasNegatives intrinsic with a small range of tests. + * @library /compiler/patches + * @build java.base/java.lang.Helper + * @build compiler.intrinsics.string.TestHasNegatives + * @run main compiler.intrinsics.string.TestHasNegatives + */ +package compiler.intrinsics.string; + +import java.lang.Helper; + +/* + * @summary Validates StringCoding.hasNegatives intrinsic with a small + * range of tests. + */ +public class TestHasNegatives { + + private static byte[] tBa = new byte[4096 + 16]; + + /** + * Completely initialize the test array, preparing it for tests of the + * StringCoding.hasNegatives method with a given array segment offset, + * length, and number of negative bytes. + */ + public static void initialize(int off, int len, int neg) { + assert (len + off <= tBa.length); + // insert "canary" (negative) values before offset + for (int i = 0; i < off; ++i) { + tBa[i] = (byte) (((i + 15) & 0x7F) | 0x80); + } + // fill the array segment + for (int i = off; i < len + off; ++i) { + tBa[i] = (byte) (((i - off + 15) & 0x7F)); + } + if (neg != 0) { + // modify a number (neg) disparate array bytes inside + // segment to be negative. + int div = (neg > 1) ? (len - 1) / (neg - 1) : 0; + int idx; + for (int i = 0; i < neg; ++i) { + idx = off + (len - 1) - div * i; + tBa[idx] = (byte) (0x80 | tBa[idx]); + } + } + // insert "canary" negative values after array segment + for (int i = len + off; i < tBa.length; ++i) { + tBa[i] = (byte) (((i + 15) & 0x7F) | 0x80); + } + } + + /** Sizes of array segments to test. */ + private static int sizes[] = { 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 13, 17, 19, 23, 37, 61, 131, + 4099 }; + + /** + * Test different array segment sizes, offsets, and number of negative + * bytes. + */ + public static void test_hasNegatives() throws Exception { + int len, off; + int ng; + boolean r; + + for (ng = 0; ng < 57; ++ng) { // number of negatives in array segment + for (off = 0; off < 8; ++off) { // starting offset of array segment + for (int i = 0; i < sizes.length; ++i) { // array segment size + // choice + len = sizes[i]; + if (len + off > tBa.length) + continue; + initialize(off, len, ng); + r = Helper.StringCodingHasNegatives(tBa, off, len); + if (r ^ ((ng == 0) ? false : true)) { + throw new Exception("Failed test hasNegatives " + "offset: " + off + " " + + "length: " + len + " " + "return: " + r + " " + "negatives: " + + ng); + } + } + } + } + } + + public void run() throws Exception { + // iterate to eventually get intrinsic inlined + for (int j = 0; j < 1000; ++j) { + test_hasNegatives(); + } + } + + public static void main(String[] args) throws Exception { + (new TestHasNegatives()).run(); + System.out.println("hasNegatives validated"); + } +} diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/jvmci/code/DataPatchTest.java --- a/hotspot/test/compiler/jvmci/code/DataPatchTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/jvmci/code/DataPatchTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -40,6 +40,8 @@ import jdk.vm.ci.code.Register; import jdk.vm.ci.code.site.DataSectionReference; import jdk.vm.ci.hotspot.HotSpotConstant; +import jdk.vm.ci.hotspot.HotSpotMetaAccessProvider; +import jdk.vm.ci.hotspot.HotSpotSymbol; import jdk.vm.ci.hotspot.HotSpotVMConfig; import jdk.vm.ci.meta.ResolvedJavaType; @@ -155,4 +157,33 @@ asm.emitPointerRet(ret); }); } + + + public static long getConstSymbol(HotSpotMetaAccessProvider meta) { + HotSpotSymbol symbol = meta.lookupSymbol("java/lang/Object"); + return symbol.getMetaspacePointer(); + } + + private void testSymbol(TestCompiler compiler) { + test(compiler, getMethod("getConstSymbol", HotSpotMetaAccessProvider.class), (HotSpotMetaAccessProvider) metaAccess); + } + + @Test + public void testInlineSymbol() { + testSymbol(asm -> { + HotSpotSymbol symbol = ((HotSpotMetaAccessProvider) metaAccess).lookupSymbol("java/lang/Object"); + Register ret = asm.emitLoadPointer((HotSpotConstant) symbol.asConstant()); + asm.emitPointerRet(ret); + }); + } + + @Test + public void testSymbolInDataSection() { + testSymbol(asm -> { + HotSpotSymbol symbol = ((HotSpotMetaAccessProvider) metaAccess).lookupSymbol("java/lang/Object"); + DataSectionReference ref = asm.emitDataItem((HotSpotConstant) symbol.asConstant()); + Register ret = asm.emitLoadPointer(ref); + asm.emitPointerRet(ret); + }); + } } diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/AsJavaTypeDataProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/AsJavaTypeDataProvider.java Thu Mar 31 14:25:35 2016 -0700 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.CONSTANT_REFLECTION_PROVIDER; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_INSTANCE; + +import jdk.vm.ci.meta.JavaConstant; +import org.testng.annotations.DataProvider; + +public class AsJavaTypeDataProvider { + + @DataProvider(name = "asJavaTypeDataProvider") + public static Object[][] asJavaTypeDataProvider() { + return new Object[][]{ + {CONSTANT_REFLECTION_PROVIDER.forObject(DummyClass.class), + "jdk.vm.ci.hotspot.test.DummyClass"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(boolean.class), "boolean"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(byte.class), "byte"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(short.class), "short"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(char.class), "char"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(int.class), "int"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(long.class), "long"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(float.class), "float"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(double.class), "double"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(Object.class), "java.lang.Object"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(boolean[].class), "boolean[]"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(boolean[][].class), "boolean[][]"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(Object[].class), "java.lang.Object[]"}, + {CONSTANT_REFLECTION_PROVIDER.forObject(Object[][].class), "java.lang.Object[][]"}, + {JavaConstant.forBoolean(DUMMY_CLASS_INSTANCE.booleanField), null}, + {CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectField), null}, + {CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE), null}, + {CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.booleanArrayWithValues), null}, + {CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.booleanArrayArrayWithValues), null}, + {JavaConstant.NULL_POINTER, null}, {null, null}}; + } +} diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/BoxPrimitiveDataProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/BoxPrimitiveDataProvider.java Thu Mar 31 14:25:35 2016 -0700 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.CONSTANT_REFLECTION_PROVIDER; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_INSTANCE; + +import java.util.LinkedList; +import jdk.vm.ci.meta.JavaConstant; +import org.testng.annotations.DataProvider; + +public class BoxPrimitiveDataProvider { + + @DataProvider(name = "boxPrimitiveDataProvider") + public static Object[][] boxPrimitiveDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + // Boolean testing + cfgSet.add( + new Object[]{JavaConstant.forBoolean(true), CONSTANT_REFLECTION_PROVIDER.forObject((Boolean) true)}); + cfgSet.add(new Object[]{JavaConstant.forBoolean(false), + CONSTANT_REFLECTION_PROVIDER.forObject((Boolean) false)}); + // Boxed boolean testing (returns null) + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject((Boolean) true), null}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject((Boolean) false), null}); + for (byte number : new byte[]{-128, 0, 1, 127}) { + // Integer primitives testing + cfgSet.add(new Object[]{JavaConstant.forByte(number), + CONSTANT_REFLECTION_PROVIDER.forObject(Byte.valueOf(number))}); + cfgSet.add(new Object[]{JavaConstant.forShort(number), + CONSTANT_REFLECTION_PROVIDER.forObject(Short.valueOf(number))}); + cfgSet.add(new Object[]{JavaConstant.forInt(number), + CONSTANT_REFLECTION_PROVIDER.forObject(Integer.valueOf(number))}); + cfgSet.add(new Object[]{JavaConstant.forLong(number), + CONSTANT_REFLECTION_PROVIDER.forObject(Long.valueOf(number))}); + if (number >= 0) { + cfgSet.add(new Object[]{JavaConstant.forChar((char) number), + CONSTANT_REFLECTION_PROVIDER.forObject(Character.valueOf((char) number))}); + } + // Float and Double variables are not cached, + // so the tested method returns "null" on them + cfgSet.add(new Object[]{JavaConstant.forFloat((float) number), null}); + cfgSet.add(new Object[]{JavaConstant.forDouble((double) number), null}); + // Boxed primitives testing (return null) + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Byte.valueOf(number)), null}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Short.valueOf(number)), null}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Integer.valueOf(number)), null}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Long.valueOf(number)), null}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Character.valueOf((char) number)), null}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Float.valueOf(number)), null}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Double.valueOf(number)), null}); + } + // Integer primitives testing with big non-cached values (returns null) + cfgSet.add(new Object[]{JavaConstant.forShort(Short.MAX_VALUE), null}); + cfgSet.add(new Object[]{JavaConstant.forInt(Integer.MAX_VALUE), null}); + cfgSet.add(new Object[]{JavaConstant.forLong(Long.MAX_VALUE), null}); + cfgSet.add(new Object[]{JavaConstant.forChar(Character.MAX_VALUE), null}); + // Non-primitives testing + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectField), null}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.booleanArrayWithValues), + null}); + // Null testing + cfgSet.add(new Object[]{JavaConstant.NULL_POINTER, null}); + cfgSet.add(new Object[]{null, null}); + return cfgSet.toArray(new Object[0][0]); + } +} diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ConstantEqualsDataProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ConstantEqualsDataProvider.java Thu Mar 31 14:25:35 2016 -0700 @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.CONSTANT_REFLECTION_PROVIDER; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_INSTANCE; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Objects; +import jdk.vm.ci.meta.Constant; +import jdk.vm.ci.meta.JavaConstant; +import org.testng.annotations.DataProvider; + +public class ConstantEqualsDataProvider { + @DataProvider(name = "constantEqualsDataProvider") + public static Object[][] constantEqualsDataProvider() { + HashMap constMap = new HashMap<>(); + constMap.put(DUMMY_CLASS_INSTANCE.booleanField, JavaConstant.forBoolean(DUMMY_CLASS_INSTANCE.booleanField)); + constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultBooleanField, + JavaConstant.forBoolean(DUMMY_CLASS_INSTANCE.stableDefaultBooleanField)); + constMap.put(DUMMY_CLASS_INSTANCE.byteField, JavaConstant.forByte(DUMMY_CLASS_INSTANCE.byteField)); + constMap.put(DUMMY_CLASS_INSTANCE.finalByteField, JavaConstant.forByte(DUMMY_CLASS_INSTANCE.finalByteField)); + constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultByteField, + JavaConstant.forByte(DUMMY_CLASS_INSTANCE.stableDefaultByteField)); + constMap.put(DUMMY_CLASS_INSTANCE.shortField, JavaConstant.forShort(DUMMY_CLASS_INSTANCE.shortField)); + constMap.put(DUMMY_CLASS_INSTANCE.finalShortField, JavaConstant.forShort(DUMMY_CLASS_INSTANCE.finalShortField)); + constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultShortField, + JavaConstant.forShort(DUMMY_CLASS_INSTANCE.stableDefaultShortField)); + constMap.put(DUMMY_CLASS_INSTANCE.intField, JavaConstant.forInt(DUMMY_CLASS_INSTANCE.intField)); + constMap.put(DUMMY_CLASS_INSTANCE.finalIntField, JavaConstant.forInt(DUMMY_CLASS_INSTANCE.finalIntField)); + constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultIntField, + JavaConstant.forInt(DUMMY_CLASS_INSTANCE.stableDefaultIntField)); + constMap.put(DUMMY_CLASS_INSTANCE.longField, JavaConstant.forLong(DUMMY_CLASS_INSTANCE.longField)); + constMap.put(DUMMY_CLASS_INSTANCE.finalLongField, JavaConstant.forLong(DUMMY_CLASS_INSTANCE.finalLongField)); + constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultLongField, + JavaConstant.forLong(DUMMY_CLASS_INSTANCE.stableDefaultLongField)); + constMap.put(DUMMY_CLASS_INSTANCE.doubleField, JavaConstant.forDouble(DUMMY_CLASS_INSTANCE.doubleField)); + constMap.put(DUMMY_CLASS_INSTANCE.finalDoubleField, + JavaConstant.forDouble(DUMMY_CLASS_INSTANCE.finalDoubleField)); + constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultDoubleField, + JavaConstant.forDouble(DUMMY_CLASS_INSTANCE.stableDefaultDoubleField)); + constMap.put(DUMMY_CLASS_INSTANCE.floatField, JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.floatField)); + constMap.put(DUMMY_CLASS_INSTANCE.finalFloatField, JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.finalFloatField)); + constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultFloatField, + JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.stableDefaultFloatField)); + constMap.put(DUMMY_CLASS_INSTANCE.charField, JavaConstant.forChar(DUMMY_CLASS_INSTANCE.charField)); + constMap.put(DUMMY_CLASS_INSTANCE.finalCharField, JavaConstant.forChar(DUMMY_CLASS_INSTANCE.finalCharField)); + constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultCharField, + JavaConstant.forChar(DUMMY_CLASS_INSTANCE.stableDefaultCharField)); + constMap.put(DUMMY_CLASS_INSTANCE.stringField, + CONSTANT_REFLECTION_PROVIDER.forString(DUMMY_CLASS_INSTANCE.stringField)); + constMap.put(DUMMY_CLASS_INSTANCE.stringField2, + CONSTANT_REFLECTION_PROVIDER.forString(DUMMY_CLASS_INSTANCE.stringField2)); + constMap.put(DUMMY_CLASS_INSTANCE.objectField, + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectField)); + constMap.put(DUMMY_CLASS_INSTANCE.finalObjectField, + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.finalObjectField)); + constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultObjectField, + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.stableDefaultObjectField)); + constMap.put(null, null); + constMap.put(JavaConstant.NULL_POINTER, JavaConstant.NULL_POINTER); + LinkedList cfgSet = new LinkedList<>(); + constMap.entrySet().stream().forEach((obj1) -> { + constMap.entrySet().stream().forEach((obj2) -> { + cfgSet.add(new Object[]{obj1.getValue(), obj2.getValue(), + Objects.equals(obj1.getKey(), obj2.getKey())}); + }); + }); + return cfgSet.toArray(new Object[0][0]); + } +} diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/DummyClass.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/DummyClass.java Thu Mar 31 14:25:35 2016 -0700 @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.vm.ci.hotspot.test; + +import jdk.internal.vm.annotation.Stable; + +public class DummyClass { + + public boolean booleanField = true; + public byte byteField = 2; + public short shortField = 3; + public char charField = 'a'; + public int intField = 4; + public long longField = 5L; + public float floatField = 4.5f; + public double doubleField = 53.2; + public Object objectField = new Object(); + + public final boolean finalBooleanField = true; + public final byte finalByteField = -2; + public final short finalShortField = -3; + public final char finalCharField = 'b'; + public final int finalIntField = 8; + public final long finalLongField = 888L; + public final float finalFloatField = 77.8f; + public final double finalDoubleField = -234.2; + public final Object finalObjectField = new Object(); + + @Stable public boolean stableBooleanField = true; + @Stable public byte stableByteField = -2; + @Stable public short stableShortField = -3; + @Stable public char stableCharField = 'c'; + @Stable public int stableIntField = 8; + @Stable public long stableLongField = 888L; + @Stable public float stableFloatField = 77.8f; + @Stable public double stableDoubleField = -234.2; + @Stable public Object stableObjectField = new Object(); + + @Stable public boolean stableDefaultBooleanField; + @Stable public byte stableDefaultByteField; + @Stable public short stableDefaultShortField; + @Stable public char stableDefaultCharField; + @Stable public int stableDefaultIntField; + @Stable public long stableDefaultLongField; + @Stable public float stableDefaultFloatField; + @Stable public double stableDefaultDoubleField; + @Stable public Object stableDefaultObjectField; + + public final boolean finalDefaultBooleanField = false; + public final byte finalDefaultByteField = 0; + public final short finalDefaultShortField = 0; + public final char finalDefaultCharField = 0; + public final int finalDefaultIntField = 0; + public final long finalDefaultLongField = 0L; + public final float finalDefaultFloatField = 0.0f; + public final double finalDefaultDoubleField = 0.0; + public final Object finalDefaultObjectField = null; + + public static boolean staticBooleanField = true; + public static byte staticByteField = -1; + public static short staticShortField = 11; + public static char staticCharField = 'e'; + public static int staticIntField = 344; + public static long staticLongField = 34231212L; + public static float staticFloatField = -4.5f; + public static double staticDoubleField = 453.2; + public static Object staticObjectField = new Object(); + + public static final boolean staticFinalBooleanField = true; + public static final byte staticFinalByteField = -51; + public static final short staticFinalShortField = 911; + public static final char staticFinalCharField = 'g'; + public static final int staticFinalIntField = 9344; + public static final long staticFinalLongField = 54231212L; + public static final float staticFinalFloatField = -42.5f; + public static final double staticFinalDoubleField = 5453.2; + public static final Object staticFinalObjectField = new Object(); + + @Stable public static boolean staticStableBooleanField = true; + @Stable public static byte staticStableByteField = -61; + @Stable public static short staticStableShortField = 661; + @Stable public static char staticStableCharField = 'y'; + @Stable public static int staticStableIntField = 6574; + @Stable public static long staticStableLongField = -2342L; + @Stable public static float staticStableFloatField = -466.5f; + @Stable public static double staticStableDoubleField = 4563.2; + @Stable public static Object staticStableObjectField = new Object(); + + @Stable public static boolean staticStableDefaultBooleanField; + @Stable public static byte staticStableDefaultByteField; + @Stable public static short staticStableDefaultShortField; + @Stable public static char staticStableDefaultCharField; + @Stable public static int staticStableDefaultIntField; + @Stable public static long staticStableDefaultLongField; + @Stable public static float staticStableDefaultFloatField; + @Stable public static double staticStableDefaultDoubleField; + @Stable public static Object staticStableDefaultObjectField; + + public boolean[] booleanArrayWithValues = new boolean[]{true, false}; + public byte[] byteArrayWithValues = new byte[]{43, 0}; + public short[] shortArrayWithValues = new short[]{9, 0}; + public char[] charArrayWithValues = new char[]{'a', 0}; + public int[] intArrayWithValues = new int[]{99, 0}; + public long[] longArrayWithValues = new long[]{868L, 0L}; + public float[] floatArrayWithValues = new float[]{75.8f, 0f}; + public double[] doubleArrayWithValues = new double[]{-294.66, 0.0}; + public Object[] objectArrayWithValues = new Object[]{new Object(), null}; + + @Stable public boolean[] stableBooleanArrayWithValues = new boolean[]{true, false}; + @Stable public byte[] stableByteArrayWithValues = new byte[]{-2, 0}; + @Stable public short[] stableShortArrayWithValues = new short[]{-3, 0}; + @Stable public char[] stableCharArrayWithValues = new char[]{'c', 0}; + @Stable public int[] stableIntArrayWithValues = new int[]{8, 0}; + @Stable public long[] stableLongArrayWithValues = new long[]{888L, 0L}; + @Stable public float[] stableFloatArrayWithValues = new float[]{77.8f, 0f}; + @Stable public double[] stableDoubleArrayWithValues = new double[]{-234.2, 0.0}; + @Stable public Object[] stableObjectArrayWithValues = new Object[]{new Object(), null}; + + public boolean[][] booleanArrayArrayWithValues = new boolean[][]{{true}, null}; + public byte[][] byteArrayArrayWithValues = new byte[][]{{43, 0}, null}; + public short[][] shortArrayArrayWithValues = new short[][]{{9, 0}, null}; + public char[][] charArrayArrayWithValues = new char[][]{{'a', 0}, null}; + public int[][] intArrayArrayWithValues = new int[][]{{99, 0}, null}; + public long[][] longArrayArrayWithValues = new long[][]{{868L, 0L}, null}; + public float[][] floatArrayArrayWithValues = new float[][]{{75.8f, 0f}, null}; + public double[][] doubleArrayArrayWithValues = new double[][]{{-294.66, 0.0}, null}; + public Object[][] objectArrayArrayWithValues = new Object[][]{{new Object(), null}, null}; + + @Stable public boolean[][] stableBooleanArrayArrayWithValues = new boolean[][]{{true, false}, null}; + @Stable public byte[][] stableByteArrayArrayWithValues = new byte[][]{{-2, 0}, null}; + @Stable public short[][] stableShortArrayArrayWithValues = new short[][]{{-3, 0}, null}; + @Stable public char[][] stableCharArrayArrayWithValues = new char[][]{{'c', 0}, null}; + @Stable public int[][] stableIntArrayArrayWithValues = new int[][]{{8, 0}, null}; + @Stable public long[][] stableLongArrayArrayWithValues = new long[][]{{888L, 0L}, null}; + @Stable public float[][] stableFloatArrayArrayWithValues = new float[][]{{77.8f, 0f}, null}; + @Stable public double[][] stableDoubleArrayArrayWithValues = new double[][]{{-234.2, 0.0}, null}; + @Stable public Object[][] stableObjectArrayArrayWithValues = new Object[][]{{new Object(), null}, null}; + + // Strings for testing "forString" method + public final String stringField = "abc"; + public final String stringField2 = "xyz"; + public final String stringEmptyField = ""; +} diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ForObjectDataProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ForObjectDataProvider.java Thu Mar 31 14:25:35 2016 -0700 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.vm.ci.hotspot.test; + +import org.testng.annotations.DataProvider; + +public class ForObjectDataProvider { + @DataProvider(name = "forObjectDataProvider") + public static Object[][] forObjectDataProvider() { + return new Object[][]{ + {TestHelper.DUMMY_CLASS_INSTANCE.objectField, + "Object[Object@" + TestHelper.DUMMY_CLASS_INSTANCE.objectField.hashCode() + "]"}, + {TestHelper.DUMMY_CLASS_INSTANCE.stringField, + "Object[String:\"" + TestHelper.DUMMY_CLASS_INSTANCE.stringField + "\"]"}, + {TestHelper.DUMMY_CLASS_INSTANCE.booleanField, + "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.booleanField + "]"}, + {TestHelper.DUMMY_CLASS_INSTANCE.byteField, + "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.byteField + "]"}, + {TestHelper.DUMMY_CLASS_INSTANCE.charField, + "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.charField + "]"}, + {TestHelper.DUMMY_CLASS_INSTANCE.shortField, + "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.shortField + "]"}, + {TestHelper.DUMMY_CLASS_INSTANCE.intField, + "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.intField + "]"}, + {TestHelper.DUMMY_CLASS_INSTANCE.longField, + "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.longField + "]"}, + {TestHelper.DUMMY_CLASS_INSTANCE.floatField, + "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.floatField + "]"}, + {TestHelper.DUMMY_CLASS_INSTANCE.doubleField, + "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.doubleField + "]"}, + {new Object[0], "Object[Object[" + 0 + "]{}]"}, {new Object[1], "Object[Object[" + 1 + "]{null}]"}, + {null, "Object[null]"}}; + } +} diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ForStringDataProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ForStringDataProvider.java Thu Mar 31 14:25:35 2016 -0700 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_INSTANCE; + +import org.testng.annotations.DataProvider; + +public class ForStringDataProvider { + @DataProvider(name = "forStringDataProvider") + public static Object[][] forStringDataProvider() { + return new Object[][]{ + {DUMMY_CLASS_INSTANCE.stringField, "Object[String:\"" + DUMMY_CLASS_INSTANCE.stringField + "\"]"}, + {DUMMY_CLASS_INSTANCE.stringEmptyField, "Object[String:\"\"]"}, + {null, "Object[null]"}}; + } +} diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/HotSpotConstantReflectionProviderTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/HotSpotConstantReflectionProviderTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test jdk.vm.ci.hotspot.test.HotSpotConstantReflectionProviderTest + * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9" | os.simpleArch == "aarch64") + * @modules jdk.vm.ci/jdk.vm.ci.runtime + * jdk.vm.ci/jdk.vm.ci.meta + * jdk.vm.ci/jdk.vm.ci.hotspot + * java.base/jdk.internal.vm.annotation + * java.base/jdk.internal.misc + * @library /testlibrary /test/lib /compiler/jvmci/jdk.vm.ci.hotspot.test/src + * @build jdk.vm.ci.hotspot.test.DummyClass + * @run driver ClassFileInstaller jdk.vm.ci.hotspot.test.DummyClass + * @run testng/othervm/timeout=300 -Xbootclasspath/a:. + * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * jdk.vm.ci.hotspot.test.HotSpotConstantReflectionProviderTest + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.CONSTANT_REFLECTION_PROVIDER; + +import java.lang.reflect.Method; +import jdk.vm.ci.hotspot.HotSpotResolvedJavaField; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.Constant; +import jdk.vm.ci.meta.MemoryAccessProvider; +import jdk.vm.ci.meta.MethodHandleAccessProvider; +import jdk.vm.ci.meta.ResolvedJavaField; +import jdk.vm.ci.meta.ResolvedJavaType; +import org.testng.Assert; +import org.testng.annotations.Test; + +public class HotSpotConstantReflectionProviderTest { + + @Test(dataProvider = "forObjectDataProvider", dataProviderClass = ForObjectDataProvider.class) + public void testForObject(Object obj, String expected) { + JavaConstant jConst = TestHelper.CONSTANT_REFLECTION_PROVIDER.forObject(obj); + Assert.assertNotNull(jConst, + "An instance of JavaConstant returned by" + " \"forObject\" method should not be null"); + Assert.assertEquals(jConst.toString(), expected, "Unexpected result:"); + } + + @Test(dataProvider = "forStringDataProvider", dataProviderClass = ForStringDataProvider.class) + public void testForString(String string, String expected) { + JavaConstant jConst = CONSTANT_REFLECTION_PROVIDER.forString(string); + Assert.assertNotNull(jConst, + "An instance of JavaConstant returned by" + " \"forString\" method should not be null"); + Assert.assertEquals(jConst.toString(), expected, "Unexpected result:"); + } + + @Test(dataProvider = "constantEqualsDataProvider", dataProviderClass = ConstantEqualsDataProvider.class) + public void testConstantEquals(Constant const1, Constant const2, Boolean expected) { + Assert.assertEquals(CONSTANT_REFLECTION_PROVIDER.constantEquals(const1, const2), expected, + "Unexpected result:"); + } + + @Test(dataProvider = "readArrayLengthDataProvider", dataProviderClass = ReadArrayLengthDataProvider.class) + public void testReadArrayLength(JavaConstant array, Integer expected) { + Assert.assertEquals(CONSTANT_REFLECTION_PROVIDER.readArrayLength(array), expected, + "Unexpected result:"); + } + + @Test(dataProvider = "readArrayElementDataProvider", dataProviderClass = ReadArrayElementDataProvider.class) + public void testReadArrayElement(JavaConstant array, int index, Object expected) { + Assert.assertEquals(CONSTANT_REFLECTION_PROVIDER.readArrayElement(array, index), expected, + "Unexpected result:"); + } + + @Test(dataProvider = "readFieldValueDataProvider", dataProviderClass = ReadFieldValueDataProvider.class) + public void testReadFieldValue(ResolvedJavaField field, JavaConstant receiver, JavaConstant expected) { + JavaConstant actual = CONSTANT_REFLECTION_PROVIDER.readFieldValue(field, receiver); + Assert.assertEquals(actual == null ? "null" : actual.toString(), + expected == null ? "null" : expected.toString(), "Unexpected result:"); + } + + @Test(dataProvider = "readFieldValueNegativeDataProvider", + dataProviderClass = ReadFieldValueDataProvider.class, + expectedExceptions = {NullPointerException.class}) + public void testNegativeReadFieldValue(ResolvedJavaField field, JavaConstant receiver) { + CONSTANT_REFLECTION_PROVIDER.readFieldValue(field, receiver); + } + + @Test(dataProvider = "readStableFieldValueDataProvider", + dataProviderClass = ReadStableFieldValueDataProvider.class) + public void testReadStableFieldValue(ResolvedJavaField field, JavaConstant receiver, boolean isDefStab, + JavaConstant expected) { + Assert.assertEquals( + CONSTANT_REFLECTION_PROVIDER.readStableFieldValue(field, receiver, isDefStab), + expected, + "Unexpected result:"); + } + + @Test(dataProvider = "readStableFieldValueArrayDataProvider", + dataProviderClass = ReadStableFieldValueDataProvider.class) + public void testReadStableFieldValueForArray(ResolvedJavaField field, JavaConstant receiver, boolean isDefStab, + int arrayDim, JavaConstant expected) { + JavaConstant result = CONSTANT_REFLECTION_PROVIDER.readStableFieldValue(field, receiver, + isDefStab); + boolean resultDefStab = false; + int resultStableDim = -1; + try { + Class hotSpotObjectConstantImplClass = Class.forName( + "jdk.vm.ci.hotspot.HotSpotObjectConstantImpl"); + Method getStableDimensionMethod = hotSpotObjectConstantImplClass.getDeclaredMethod( + "getStableDimension"); + Method isDefaultStableMethod = hotSpotObjectConstantImplClass.getDeclaredMethod( + "isDefaultStable"); + getStableDimensionMethod.setAccessible(true); + isDefaultStableMethod.setAccessible(true); + resultDefStab = (boolean) isDefaultStableMethod.invoke(result); + resultStableDim = (int) getStableDimensionMethod.invoke(result); + } catch (ReflectiveOperationException e) { + throw new Error("Unexpected error: " + e, e); + } + Assert.assertEquals(resultDefStab, isDefStab, + "Wrong default stable value for " + result.toString()); + Assert.assertEquals(resultStableDim, arrayDim, + "Wrong array dimension for " + result.toString()); + Assert.assertEquals(result.toString(), expected.toString(), "Unexpected result:"); + } + + @Test(dataProvider = "readStableFieldValueNegativeDataProvider", + dataProviderClass = ReadStableFieldValueDataProvider.class, + expectedExceptions = {NullPointerException.class}) + public void testNegativeReadStableFieldValue(ResolvedJavaField field, JavaConstant receiver, boolean isDefStab) { + CONSTANT_REFLECTION_PROVIDER.readStableFieldValue(field, receiver, isDefStab); + } + + @Test(dataProvider = "readConstantFieldValueDataProvider", + dataProviderClass = ReadConstantFieldValueDataProvider.class) + public void testReadConstantFieldValue(ResolvedJavaField field, JavaConstant receiver, JavaConstant expected, + String testInfo) { + String msg = String.format("Unexpected result for %s. Field is stable = %s.", testInfo, + ((HotSpotResolvedJavaField) field).isStable()); + Assert.assertEquals(CONSTANT_REFLECTION_PROVIDER.readConstantFieldValue(field, receiver), + expected, msg); + } + + @Test(dataProvider = "readConstantFieldValueNegativeDataProvider", + dataProviderClass = ReadConstantFieldValueDataProvider.class, + expectedExceptions = {NullPointerException.class}) + public void testNegativeReadConstantFieldValue(ResolvedJavaField field, JavaConstant receiver) { + CONSTANT_REFLECTION_PROVIDER.readConstantFieldValue(field, receiver); + } + + @Test(dataProvider = "readConstantArrayElementDataProvider", + dataProviderClass = ReadConstantArrayElementDataProvider.class) + public void testReadConstantArrayElement(JavaConstant array, int index, JavaConstant expected, String testInfo) { + JavaConstant actual = CONSTANT_REFLECTION_PROVIDER.readConstantArrayElement(array, index); + Assert.assertEquals(actual == null ? "null" : actual.toString(), + expected == null ? "null" : expected.toString(), + String.format("Unexpected result while testing %s:", testInfo)); + } + + @Test(dataProvider = "readConstantArrayElementForOffsetDataProvider", + dataProviderClass = ReadConstantArrayElementDataProvider.class) + public void testReadConstantArrayElementForOffset(JavaConstant array, long offset, JavaConstant expected, + String testInfo) { + JavaConstant actual = CONSTANT_REFLECTION_PROVIDER.readConstantArrayElementForOffset(array, + offset); + Assert.assertEquals(actual == null ? "null" : actual.toString(), + expected == null ? "null" : expected.toString(), + String.format("Unexpected result while testing %s:", testInfo)); + } + + @Test(dataProvider = "asJavaTypeDataProvider", dataProviderClass = AsJavaTypeDataProvider.class) + public void testAsJavaType(JavaConstant constant, String expected) { + ResolvedJavaType actual = CONSTANT_REFLECTION_PROVIDER.asJavaType(constant); + Assert.assertEquals(actual == null ? "null" : actual.toJavaName(), + expected == null ? "null" : expected, + "Unexpected result, wrong type returned:"); + } + + @Test(dataProvider = "boxPrimitiveDataProvider", dataProviderClass = BoxPrimitiveDataProvider.class) + public void testBoxPrimitive(JavaConstant constant, JavaConstant expected) { + JavaConstant actual = CONSTANT_REFLECTION_PROVIDER.boxPrimitive(constant); + Assert.assertEquals(actual, expected, "Unexpected result:"); + } + + @Test(dataProvider = "unboxPrimitiveDataProvider", dataProviderClass = UnboxPrimitiveDataProvider.class) + public void testUnboxPrimitive(JavaConstant constant, JavaConstant expected) { + JavaConstant actual = CONSTANT_REFLECTION_PROVIDER.unboxPrimitive(constant); + Assert.assertEquals(actual, expected, "Unexpected result:"); + } + + @Test(dataProvider = "isEmbeddableDataProvider", dataProviderClass = IsEmbeddableDataProvider.class) + public void testIsEmbeddable(JavaConstant constant, boolean expected) { + boolean actual = CONSTANT_REFLECTION_PROVIDER.isEmbeddable(constant); + Assert.assertEquals(actual, expected, "Unexpected result:"); + } + + @Test + public void testGetMemoryAccessProvider() { + MemoryAccessProvider actual = CONSTANT_REFLECTION_PROVIDER.getMemoryAccessProvider(); + Assert.assertNotNull(actual, "Returned MemoryAccessProvider instance should not be null"); + } + + @Test + public void testGetMethodHandleAccess() { + MethodHandleAccessProvider actual = CONSTANT_REFLECTION_PROVIDER.getMethodHandleAccess(); + Assert.assertNotNull(actual, + "Returned MethodHandleAccessProvider instance should not be null"); + } +} diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/IsEmbeddableDataProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/IsEmbeddableDataProvider.java Thu Mar 31 14:25:35 2016 -0700 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.CONSTANT_REFLECTION_PROVIDER; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_INSTANCE; + +import jdk.vm.ci.meta.JavaConstant; +import org.testng.annotations.DataProvider; + +public class IsEmbeddableDataProvider { + @DataProvider(name = "isEmbeddableDataProvider") + public static Object[][] isEmbeddableDataProvider() { + return new Object[][]{{JavaConstant.forBoolean(DUMMY_CLASS_INSTANCE.booleanField), true}, + {JavaConstant.forByte(DUMMY_CLASS_INSTANCE.byteField), true}, + {JavaConstant.forShort(DUMMY_CLASS_INSTANCE.shortField), true}, + {JavaConstant.forInt(DUMMY_CLASS_INSTANCE.intField), true}, + {JavaConstant.forLong(DUMMY_CLASS_INSTANCE.longField), true}, + {JavaConstant.forChar(DUMMY_CLASS_INSTANCE.charField), true}, + {JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.floatField), true}, + {JavaConstant.forDouble(DUMMY_CLASS_INSTANCE.doubleField), true}, + {CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectField), true}, + {JavaConstant.NULL_POINTER, true}, {null, true}}; + } +} diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadArrayElementDataProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadArrayElementDataProvider.java Thu Mar 31 14:25:35 2016 -0700 @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.ARRAY_ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.CONSTANT_REFLECTION_PROVIDER; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_INSTANCE; +import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_FIELDS_MAP; + +import java.util.LinkedList; +import java.util.stream.Stream; + +import jdk.vm.ci.meta.JavaConstant; +import org.testng.annotations.DataProvider; + +public class ReadArrayElementDataProvider { + + @DataProvider(name = "readArrayElementDataProvider") + public static Object[][] readArrayElementDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + for (int i : new int[]{0, 1}) { + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.booleanArrayWithValues), + i, JavaConstant.forBoolean(DUMMY_CLASS_INSTANCE.booleanArrayWithValues[i])}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.byteArrayWithValues), + i, JavaConstant.forByte(DUMMY_CLASS_INSTANCE.byteArrayWithValues[i])}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.shortArrayWithValues), + i, JavaConstant.forShort(DUMMY_CLASS_INSTANCE.shortArrayWithValues[i])}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.charArrayWithValues), + i, JavaConstant.forChar(DUMMY_CLASS_INSTANCE.charArrayWithValues[i])}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.intArrayWithValues), + i, JavaConstant.forInt(DUMMY_CLASS_INSTANCE.intArrayWithValues[i])}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.longArrayWithValues), + i, JavaConstant.forLong(DUMMY_CLASS_INSTANCE.longArrayWithValues[i])}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.floatArrayWithValues), + i, JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.floatArrayWithValues[i])}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.doubleArrayWithValues), + i, JavaConstant.forDouble(DUMMY_CLASS_INSTANCE.doubleArrayWithValues[i])}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectArrayWithValues), + i, CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectArrayWithValues[i])}); + cfgSet.add(new Object[]{ + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.booleanArrayArrayWithValues), i, + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.booleanArrayArrayWithValues[i])}); + cfgSet.add(new Object[]{ + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.byteArrayArrayWithValues), i, + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.byteArrayArrayWithValues[i])}); + cfgSet.add(new Object[]{ + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.shortArrayArrayWithValues), i, + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.shortArrayArrayWithValues[i])}); + cfgSet.add(new Object[]{ + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.charArrayArrayWithValues), i, + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.charArrayArrayWithValues[i])}); + cfgSet.add(new Object[]{ + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.intArrayArrayWithValues), i, + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.intArrayArrayWithValues[i])}); + cfgSet.add(new Object[]{ + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.longArrayArrayWithValues), i, + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.longArrayArrayWithValues[i])}); + cfgSet.add(new Object[]{ + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.floatArrayArrayWithValues), i, + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.floatArrayArrayWithValues[i])}); + cfgSet.add(new Object[]{ + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.doubleArrayArrayWithValues), i, + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.doubleArrayArrayWithValues[i])}); + cfgSet.add(new Object[]{ + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectArrayArrayWithValues), i, + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectArrayArrayWithValues[i])}); + } + Stream.concat(ARRAYS_MAP.values().stream(), ARRAY_ARRAYS_MAP.values().stream()).forEach((array) -> { + for (int i : new int[]{-1, 2}) { + cfgSet.add(new Object[]{array, i, null}); + } + }); + cfgSet.add(new Object[]{null, 0, null}); + cfgSet.add(new Object[]{JavaConstant.NULL_POINTER, 0, null}); + INSTANCE_FIELDS_MAP.values().forEach((constant) -> { + cfgSet.add(new Object[]{constant, 0, null}); + }); + return cfgSet.toArray(new Object[0][0]); + } +} diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadArrayLengthDataProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadArrayLengthDataProvider.java Thu Mar 31 14:25:35 2016 -0700 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.CONSTANT_REFLECTION_PROVIDER; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_INSTANCE; + +import java.util.LinkedList; +import java.util.List; +import jdk.vm.ci.meta.JavaConstant; +import org.testng.annotations.DataProvider; + +public class ReadArrayLengthDataProvider { + + public static List createListOfDummyArrays(int length) { + List arrays = new LinkedList<>(); + arrays.add(new boolean[length]); + arrays.add(new byte[length]); + arrays.add(new short[length]); + arrays.add(new char[length]); + arrays.add(new int[length]); + arrays.add(new long[length]); + arrays.add(new float[length]); + arrays.add(new double[length]); + arrays.add(new Object[length]); + arrays.add(new boolean[length][2]); + arrays.add(new byte[length][2]); + arrays.add(new short[length][2]); + arrays.add(new char[length][2]); + arrays.add(new int[length][2]); + arrays.add(new long[length][2]); + arrays.add(new float[length][2]); + arrays.add(new double[length][2]); + arrays.add(new Object[length][2]); + return arrays; + } + + @DataProvider(name = "readArrayLengthDataProvider") + public static Object[][] readArrayLengthDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + for (int i : new int[]{0, 1, 42}) { + createListOfDummyArrays(i).stream().forEach((array) -> { + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(array), i}); + }); + } + cfgSet.add(new Object[]{null, null}); + cfgSet.add(new Object[]{JavaConstant.NULL_POINTER, null}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.intField), null}); + cfgSet.add(new Object[]{JavaConstant.forInt(DUMMY_CLASS_INSTANCE.intField), null}); + return cfgSet.toArray(new Object[0][0]); + } +} diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadConstantArrayElementDataProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadConstantArrayElementDataProvider.java Thu Mar 31 14:25:35 2016 -0700 @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.ARRAY_ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.CONSTANT_REFLECTION_PROVIDER; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_CONSTANT; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_INSTANCE; +import static jdk.vm.ci.hotspot.test.TestHelper.getResolvedJavaField; +import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_STABLE_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.STABLE_ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.STABLE_ARRAY_ARRAYS_MAP; + +import java.lang.reflect.Field; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +import jdk.vm.ci.meta.JavaConstant; +import org.testng.annotations.DataProvider; +import jdk.internal.misc.Unsafe; +import jdk.vm.ci.meta.ResolvedJavaField; + +public class ReadConstantArrayElementDataProvider { + + // Non-stable array fields names mapped to their base offsets and index scale + private static final List NON_STABLE_ARRAY_NAMES + = new LinkedList<>(); + + static { + NON_STABLE_ARRAY_NAMES.add( + new ArrayFieldParams("booleanArrayWithValues", Unsafe.ARRAY_BOOLEAN_BASE_OFFSET, + Unsafe.ARRAY_BOOLEAN_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("byteArrayWithValues", + Unsafe.ARRAY_BYTE_BASE_OFFSET, + Unsafe.ARRAY_BYTE_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("shortArrayWithValues", + Unsafe.ARRAY_SHORT_BASE_OFFSET, + Unsafe.ARRAY_SHORT_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("charArrayWithValues", + Unsafe.ARRAY_CHAR_BASE_OFFSET, + Unsafe.ARRAY_CHAR_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("intArrayWithValues", + Unsafe.ARRAY_INT_BASE_OFFSET, + Unsafe.ARRAY_INT_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("longArrayWithValues", + Unsafe.ARRAY_LONG_BASE_OFFSET, + Unsafe.ARRAY_LONG_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("floatArrayWithValues", + Unsafe.ARRAY_FLOAT_BASE_OFFSET, + Unsafe.ARRAY_FLOAT_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("doubleArrayWithValues", + Unsafe.ARRAY_DOUBLE_BASE_OFFSET, + Unsafe.ARRAY_DOUBLE_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("objectArrayWithValues", + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET, + Unsafe.ARRAY_BOOLEAN_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("booleanArrayArrayWithValues", + Unsafe.ARRAY_OBJECT_BASE_OFFSET, + Unsafe.ARRAY_OBJECT_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("byteArrayArrayWithValues", + Unsafe.ARRAY_OBJECT_BASE_OFFSET, + Unsafe.ARRAY_OBJECT_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("shortArrayArrayWithValues", + Unsafe.ARRAY_OBJECT_BASE_OFFSET, + Unsafe.ARRAY_OBJECT_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("charArrayArrayWithValues", + Unsafe.ARRAY_OBJECT_BASE_OFFSET, + Unsafe.ARRAY_OBJECT_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("intArrayArrayWithValues", + Unsafe.ARRAY_OBJECT_BASE_OFFSET, + Unsafe.ARRAY_OBJECT_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("longArrayArrayWithValues", + Unsafe.ARRAY_OBJECT_BASE_OFFSET, + Unsafe.ARRAY_OBJECT_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("floatArrayArrayWithValues", + Unsafe.ARRAY_OBJECT_BASE_OFFSET, + Unsafe.ARRAY_OBJECT_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("doubleArrayArrayWithValues", + Unsafe.ARRAY_OBJECT_BASE_OFFSET, + Unsafe.ARRAY_OBJECT_INDEX_SCALE)); + NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("objectArrayArrayWithValues", + Unsafe.ARRAY_OBJECT_BASE_OFFSET, + Unsafe.ARRAY_OBJECT_INDEX_SCALE)); + } + + // Stable array fields names mapped to their base offsets and index scale + private static final List STABLE_ARRAY_NAMES + = new LinkedList<>(); + + static { + NON_STABLE_ARRAY_NAMES.stream().forEach((entry) -> { + String nsFieldName = entry.name; + char firstChar = nsFieldName.charAt(0); + char newFirstChar = Character.toUpperCase(firstChar); + String sFieldName = nsFieldName.replaceFirst("" + firstChar, + "" + newFirstChar); + sFieldName = "stable" + sFieldName; + STABLE_ARRAY_NAMES.add(new ArrayFieldParams(sFieldName, entry.offsetBase, entry.scale)); + }); + } + + @DataProvider(name = "readConstantArrayElementDataProvider") + public static Object[][] readConstantArrayElementDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + for (int i : new int[]{0, 1}) { + NON_STABLE_ARRAY_NAMES.stream().forEach((entry) -> { + String fieldName = entry.name; + cfgSet.add(new Object[]{ + readFieldValue(fieldName), + i, + null, + "array field \"" + fieldName + "\" for index " + i}); + }); + STABLE_ARRAY_NAMES.stream().forEach((entry) -> { + String fieldName = entry.name; + cfgSet.add(new Object[]{ + readFieldValue(fieldName), + i, + i == 0 ? getJavaConstant(fieldName) : null, + "array field \"" + fieldName + "\" for index " + i}); + }); + } + Stream> arraysStream1 + = Stream.concat(ARRAYS_MAP.entrySet().stream(), + ARRAY_ARRAYS_MAP.entrySet().stream()); + Stream> arraysStream2 + = Stream.concat(STABLE_ARRAYS_MAP.entrySet().stream(), + STABLE_ARRAY_ARRAYS_MAP.entrySet().stream()); + Stream.concat(arraysStream1, arraysStream2).forEach((array) -> { + for (int i : new int[]{-1, 2}) { + cfgSet.add(new Object[]{ + array.getValue(), + i, + null, + "array field \"" + array.getKey() + "\" for index " + i}); + } + }); + cfgSet.add(new Object[]{null, 0, null, "null"}); + cfgSet.add(new Object[]{JavaConstant.NULL_POINTER, 0, null, "JavaConstant.NULL_POINTER"}); + INSTANCE_FIELDS_MAP.values().forEach((constant) -> { + cfgSet.add(new Object[]{constant, 0, null, "non-stable non-array field"}); + }); + INSTANCE_STABLE_FIELDS_MAP.values().forEach((constant) -> { + cfgSet.add(new Object[]{constant, 0, null, "stable non-array field"}); + }); + return cfgSet.toArray(new Object[0][0]); + } + + @DataProvider(name = "readConstantArrayElementForOffsetDataProvider") + public static Object[][] readConstantArrayElementForOffsetDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + // Testing non-stable arrays. Result should be null in all cases + for (double i : new double[]{-1, 0, 0.5, 1, 1.5, 2}) { + NON_STABLE_ARRAY_NAMES.stream().forEach(entry -> { + String fieldName = entry.name; + long offset = (long) (entry.offsetBase + i * entry.scale); + cfgSet.add(new Object[]{ + readFieldValue(fieldName), + offset, + null, + "array field \"" + fieldName + "\" for offset " + offset}); + }); + } + // Testing stable arrays. Result should be null in all cases except "offset = base + 0" + for (double i : new double[]{-1, 0.5, 1, 1.5, 2}) { + STABLE_ARRAY_NAMES.stream().forEach(entry -> { + String fieldName = entry.name; + long offset = (long) Math.ceil(entry.offsetBase + i * entry.scale); + cfgSet.add(new Object[]{ + readFieldValue(fieldName), + offset, + null, + "array field \"" + fieldName + "\" for offset " + offset}); + }); + } + // Testing stable arrays "offset = base + 0". Result should be non-null + STABLE_ARRAY_NAMES.stream().forEach(entry -> { + String fieldName = entry.name; + long offset = (long) entry.offsetBase; + cfgSet.add(new Object[]{ + readFieldValue(fieldName), + offset, + getJavaConstant(fieldName), + "array field \"" + fieldName + "\" for offset " + offset}); + }); + // Testing null as array + cfgSet.add(new Object[]{null, 0, null, "null"}); + // Testing JavaConstant.NULL_POINTER as array + cfgSet.add(new Object[]{JavaConstant.NULL_POINTER, 0, null, "JavaConstant.NULL_POINTER"}); + // Testing non-stable non-array fields + INSTANCE_FIELDS_MAP.values().forEach((constant) -> { + cfgSet.add(new Object[]{constant, 0, null, "non-stable non-array field"}); + }); + // Testing stable non-array fields + INSTANCE_STABLE_FIELDS_MAP.values().forEach((constant) -> { + cfgSet.add(new Object[]{constant, 0, null, "stable non-array field"}); + }); + return cfgSet.toArray(new Object[0][0]); + } + + private static JavaConstant readFieldValue(String fieldName) { + return CONSTANT_REFLECTION_PROVIDER.readFieldValue(getResolvedJavaField(DummyClass.class, fieldName), + DUMMY_CLASS_CONSTANT); + } + + private static JavaConstant getJavaConstant(String fieldName) { + Class dummyClass = DummyClass.class; + Field arrayField; + try { + arrayField = dummyClass.getDeclaredField(fieldName); + } catch (NoSuchFieldException ex) { + throw new Error("Test bug: wrong field name " + ex, ex); + } catch (SecurityException ex) { + throw new Error("Unexpected error: " + ex, ex); + } + arrayField.setAccessible(true); + Class componentType = arrayField.getType().getComponentType(); + if (componentType == null) { + throw new Error("Test error: field is not an array"); + } + Object value; + try { + value = arrayField.get(DUMMY_CLASS_INSTANCE); + } catch (IllegalArgumentException | IllegalAccessException ex) { + throw new Error("Unexpected error: " + ex, ex); + } + if (componentType == boolean.class) { + return JavaConstant.forBoolean(((boolean[]) value)[0]); + } + if (componentType == byte.class) { + return JavaConstant.forByte(((byte[]) value)[0]); + } + if (componentType == short.class) { + return JavaConstant.forShort(((short[]) value)[0]); + } + if (componentType == char.class) { + return JavaConstant.forChar(((char[]) value)[0]); + } + if (componentType == int.class) { + return JavaConstant.forInt(((int[]) value)[0]); + } + if (componentType == long.class) { + return JavaConstant.forLong(((long[]) value)[0]); + } + if (componentType == float.class) { + return JavaConstant.forFloat(((float[]) value)[0]); + } + if (componentType == double.class) { + return JavaConstant.forDouble(((double[]) value)[0]); + } + return CONSTANT_REFLECTION_PROVIDER.forObject(((Object[]) value)[0]); + } + + private static class ArrayFieldParams { + public final String name; + public final int offsetBase; + public final int scale; + + ArrayFieldParams(String name, int offsetBase, int scale) { + this.name = name; + this.offsetBase = offsetBase; + this.scale = scale; + } + } +} diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadConstantFieldValueDataProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadConstantFieldValueDataProvider.java Thu Mar 31 14:25:35 2016 -0700 @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_CONSTANT; +import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_STABLE_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_FINAL_DEFAULT_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_FINAL_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_STABLE_DEFAULT_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.STATIC_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.STATIC_FINAL_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.STATIC_STABLE_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.STATIC_STABLE_DEFAULT_FIELDS_MAP; + +import java.util.LinkedList; +import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; +import jdk.vm.ci.meta.JavaConstant; +import org.testng.annotations.DataProvider; + + +public class ReadConstantFieldValueDataProvider { + + @DataProvider(name = "readConstantFieldValueDataProvider") + public static Object[][] readConstantFieldValueDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + // Testing static final fields + STATIC_FINAL_FIELDS_MAP.entrySet().stream().forEach((field) -> { + cfgSet.add(new Object[]{field.getKey(), null, field.getValue(), "static final field"}); + }); + // Testing static stable fields + STATIC_STABLE_FIELDS_MAP.entrySet().stream().forEach((field) -> { + cfgSet.add(new Object[]{field.getKey(), null, field.getValue(), "static stable field"}); + }); + // Testing instance final non-default fields + INSTANCE_FINAL_FIELDS_MAP.entrySet().stream().forEach((field) -> { + cfgSet.add(new Object[]{field.getKey(), + DUMMY_CLASS_CONSTANT, + field.getValue(), + "instance final field"}); + }); + // Testing instance final default fields. + boolean trustDefFinal = HotSpotJVMCIRuntime.Option.TrustFinalDefaultFields.getBoolean(); + INSTANCE_FINAL_DEFAULT_FIELDS_MAP.entrySet().stream().forEach((field) -> { + JavaConstant expected = trustDefFinal ? field.getValue() : null; + cfgSet.add(new Object[]{field.getKey(), + DUMMY_CLASS_CONSTANT, + expected, + "instance final default field"}); + }); + // Testing instance stable non-default fields + INSTANCE_STABLE_FIELDS_MAP.entrySet().stream().forEach((field) -> { + cfgSet.add(new Object[]{field.getKey(), + DUMMY_CLASS_CONSTANT, + field.getValue(), + "instance stable field"}); + }); + // Testing instance stable default fields + INSTANCE_STABLE_DEFAULT_FIELDS_MAP.entrySet().stream().forEach((field) -> { + cfgSet.add(new Object[]{field.getKey(), + DUMMY_CLASS_CONSTANT, + null, + "instance stable default field"}); + }); + // Testing regular instance fields + INSTANCE_FIELDS_MAP.entrySet().stream().forEach((field) -> { + cfgSet.add(new Object[]{field.getKey(), DUMMY_CLASS_CONSTANT, null, "instance field"}); + }); + // Testing regular static fields + STATIC_FIELDS_MAP.entrySet().stream().forEach((field) -> { + cfgSet.add(new Object[]{field.getKey(), null, null, "static field"}); + }); + // Testing static stable fields + STATIC_STABLE_DEFAULT_FIELDS_MAP.entrySet().stream().forEach((field) -> { + cfgSet.add(new Object[]{field.getKey(), null, null, "static stable default field"}); + }); + return cfgSet.toArray(new Object[0][0]); + } + + @DataProvider(name = "readConstantFieldValueNegativeDataProvider") + public static Object[][] readConstantFieldValueNegativeDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + // Testing instance fields with null as receiver + INSTANCE_FIELDS_MAP.entrySet().stream().forEach((field) -> { + cfgSet.add(new Object[]{field.getKey(), null}); + }); + // Testing null as a field argument + cfgSet.add(new Object[]{null, null}); + return cfgSet.toArray(new Object[0][0]); + } +} diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadFieldValueDataProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadFieldValueDataProvider.java Thu Mar 31 14:25:35 2016 -0700 @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.ARRAY_ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.CONSTANT_REFLECTION_PROVIDER; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_CONSTANT; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_INSTANCE; +import static jdk.vm.ci.hotspot.test.TestHelper.STABLE_ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.STABLE_ARRAY_ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_STABLE_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.STATIC_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.STATIC_STABLE_FIELDS_MAP; + +import java.util.LinkedList; +import jdk.vm.ci.meta.JavaConstant; +import org.testng.annotations.DataProvider; + + +public class ReadFieldValueDataProvider { + + @DataProvider(name = "readFieldValueDataProvider") + public static Object[][] readFieldValueDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + // Testing instance non-stable fields + INSTANCE_FIELDS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + DUMMY_CLASS_CONSTANT, + instanceField.getValue()}); + }); + // Testing static non-stable fields with null as receiver + STATIC_FIELDS_MAP.entrySet().stream().forEach((staticField) -> { + cfgSet.add(new Object[]{staticField.getKey(), null, staticField.getValue()}); + }); + // Testing static non-stable fields with JavaConstant.NULL_POINTER as receiver + STATIC_FIELDS_MAP.entrySet().stream().forEach((staticField) -> { + cfgSet.add(new Object[]{staticField.getKey(), + JavaConstant.NULL_POINTER, + staticField.getValue()}); + }); + // Testing instance stable fields + INSTANCE_STABLE_FIELDS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + DUMMY_CLASS_CONSTANT, + instanceField.getValue()}); + }); + // Testing static stable fields with null as receiver + STATIC_STABLE_FIELDS_MAP.entrySet().stream().forEach((staticField) -> { + cfgSet.add(new Object[]{staticField.getKey(), null, staticField.getValue()}); + }); + // Testing static stable fields with JavaConstant.NULL_POINTER as receiver + STATIC_STABLE_FIELDS_MAP.entrySet().stream().forEach((staticField) -> { + cfgSet.add(new Object[]{staticField.getKey(), + JavaConstant.NULL_POINTER, + staticField.getValue()}); + }); + // Testing instance non-stable array fields + ARRAYS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + DUMMY_CLASS_CONSTANT, + instanceField.getValue()}); + }); + // Testing instance stable array fields + STABLE_ARRAYS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + DUMMY_CLASS_CONSTANT, + instanceField.getValue()}); + }); + // Testing instance non-stable array-of-array fields + ARRAY_ARRAYS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + DUMMY_CLASS_CONSTANT, + instanceField.getValue()}); + }); + // Testing instance stable array-of-array fields + STABLE_ARRAY_ARRAYS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + DUMMY_CLASS_CONSTANT, + instanceField.getValue()}); + }); + // Testing instance fields with JavaConstant.NULL_POINTER as receiver + INSTANCE_FIELDS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), JavaConstant.NULL_POINTER, null}); + }); + // Testing instance fields with an object that does not have the field + INSTANCE_FIELDS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectField), + null}); + }); + return cfgSet.toArray(new Object[0][0]); + } + + @DataProvider(name = "readFieldValueNegativeDataProvider") + public static Object[][] readFieldValueNegativeDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + // Testing instance fields with null as receiver + INSTANCE_FIELDS_MAP.keySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField, null}); + }); + // Testing null as a field argument + cfgSet.add(new Object[]{null, null}); + return cfgSet.toArray(new Object[0][0]); + } +} diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadStableFieldValueDataProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadStableFieldValueDataProvider.java Thu Mar 31 14:25:35 2016 -0700 @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.ARRAY_ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.CONSTANT_REFLECTION_PROVIDER; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_CONSTANT; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_INSTANCE; +import static jdk.vm.ci.hotspot.test.TestHelper.STABLE_ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.STABLE_ARRAY_ARRAYS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_STABLE_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.STATIC_FIELDS_MAP; +import static jdk.vm.ci.hotspot.test.TestHelper.STATIC_STABLE_FIELDS_MAP; + +import java.util.LinkedList; +import jdk.vm.ci.meta.JavaConstant; +import org.testng.annotations.DataProvider; + +public class ReadStableFieldValueDataProvider { + + @DataProvider(name = "readStableFieldValueDataProvider") + public static Object[][] readStableFieldValueDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + for (boolean isDefStab : new boolean[]{true, false}) { + // Testing instance non-stable fields + INSTANCE_FIELDS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + DUMMY_CLASS_CONSTANT, + isDefStab, + instanceField.getValue()}); + }); + // Testing static non-stable fields with null as receiver + STATIC_FIELDS_MAP.entrySet().stream().forEach((staticField) -> { + cfgSet.add(new Object[]{staticField.getKey(), + null, + isDefStab, + staticField.getValue()}); + }); + // Testing static non-stable fields with JavaConstant.NULL_POINTER as receiver + STATIC_FIELDS_MAP.entrySet().stream().forEach((staticField) -> { + cfgSet.add(new Object[]{staticField.getKey(), + JavaConstant.NULL_POINTER, + isDefStab, + staticField.getValue()}); + }); + // Testing instance stable fields + INSTANCE_STABLE_FIELDS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + DUMMY_CLASS_CONSTANT, + isDefStab, + instanceField.getValue()}); + }); + // Testing static stable fields with null as receiver + STATIC_STABLE_FIELDS_MAP.entrySet().stream().forEach((staticField) -> { + cfgSet.add(new Object[]{staticField.getKey(), + null, + isDefStab, + staticField.getValue()}); + }); + // Testing static stable fields with JavaConstant.NULL_POINTER as receiver + STATIC_STABLE_FIELDS_MAP.entrySet().stream().forEach((staticField) -> { + cfgSet.add(new Object[]{staticField.getKey(), + JavaConstant.NULL_POINTER, + isDefStab, + staticField.getValue()}); + }); + // Testing instance fields with JavaConstant.NULL_POINTER as receiver + INSTANCE_FIELDS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + JavaConstant.NULL_POINTER, + isDefStab, + null}); + }); + // Testing instance fields with an object that does not have the field + INSTANCE_FIELDS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectField), + isDefStab, + null}); + }); + } + return cfgSet.toArray(new Object[0][0]); + } + + @DataProvider(name = "readStableFieldValueArrayDataProvider") + public static Object[][] readStableFieldValueArrayDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + for (boolean isDefStab : new boolean[]{true, false}) { + // Testing instance non-stable array fields + ARRAYS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + DUMMY_CLASS_CONSTANT, + isDefStab, + TestHelper.ARRAY_DIMENSION, + instanceField.getValue()}); + }); + // Testing instance stable array fields + STABLE_ARRAYS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + DUMMY_CLASS_CONSTANT, + isDefStab, + TestHelper.ARRAY_DIMENSION, + instanceField.getValue()}); + }); + // Testing instance non-stable array-of-array fields + ARRAY_ARRAYS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + DUMMY_CLASS_CONSTANT, + isDefStab, + TestHelper.ARRAY_OF_ARRAYS_DIMENSION, + instanceField.getValue()}); + }); + // Testing instance stable array-of-array fields + STABLE_ARRAY_ARRAYS_MAP.entrySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField.getKey(), + DUMMY_CLASS_CONSTANT, + isDefStab, + TestHelper.ARRAY_OF_ARRAYS_DIMENSION, + instanceField.getValue()}); + }); + } + return cfgSet.toArray(new Object[0][0]); + } + + @DataProvider(name = "readStableFieldValueNegativeDataProvider") + public static Object[][] readStableFieldValueNegativeDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + for (boolean isDefStab : new boolean[]{true, false}) { + // Testing instance fields with null as receiver + INSTANCE_FIELDS_MAP.keySet().stream().forEach((instanceField) -> { + cfgSet.add(new Object[]{instanceField, null, isDefStab}); + }); + // Testing null as a field argument + cfgSet.add(new Object[]{null, null, isDefStab}); + } + return cfgSet.toArray(new Object[0][0]); + } +} diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestHelper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestHelper.java Thu Mar 31 14:25:35 2016 -0700 @@ -0,0 +1,486 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.vm.ci.hotspot.test; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; +import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.MetaAccessProvider; +import jdk.vm.ci.meta.ResolvedJavaField; +import jdk.vm.ci.runtime.JVMCI; + +public class TestHelper { + + public static final DummyClass DUMMY_CLASS_INSTANCE = new DummyClass(); + public static final HotSpotConstantReflectionProvider CONSTANT_REFLECTION_PROVIDER + = (HotSpotConstantReflectionProvider) JVMCI.getRuntime().getHostJVMCIBackend().getConstantReflection(); + public static final JavaConstant DUMMY_CLASS_CONSTANT + = CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE); + + public static final Map INSTANCE_FIELDS_MAP + = new HashMap<>(); + + static { + INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "booleanField"), + JavaConstant.forBoolean(DUMMY_CLASS_INSTANCE.booleanField)); + INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "byteField"), + JavaConstant.forByte(DUMMY_CLASS_INSTANCE.byteField)); + INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "shortField"), + JavaConstant.forShort(DUMMY_CLASS_INSTANCE.shortField)); + INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "charField"), + JavaConstant.forChar(DUMMY_CLASS_INSTANCE.charField)); + INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "intField"), + JavaConstant.forInt(DUMMY_CLASS_INSTANCE.intField)); + INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "longField"), + JavaConstant.forLong(DUMMY_CLASS_INSTANCE.longField)); + INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "floatField"), + JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.floatField)); + INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "doubleField"), + JavaConstant.forDouble(DUMMY_CLASS_INSTANCE.doubleField)); + INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "objectField"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.objectField)); + } + + public static final Map INSTANCE_FINAL_FIELDS_MAP + = new HashMap<>(); + + static { + INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalBooleanField"), + JavaConstant.forBoolean( + DUMMY_CLASS_INSTANCE.finalBooleanField)); + INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalByteField"), + JavaConstant.forByte(DUMMY_CLASS_INSTANCE.finalByteField)); + INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalShortField"), + JavaConstant.forShort(DUMMY_CLASS_INSTANCE.finalShortField)); + INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalCharField"), + JavaConstant.forChar(DUMMY_CLASS_INSTANCE.finalCharField)); + INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalIntField"), + JavaConstant.forInt(DUMMY_CLASS_INSTANCE.finalIntField)); + INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalLongField"), + JavaConstant.forLong(DUMMY_CLASS_INSTANCE.finalLongField)); + INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalFloatField"), + JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.finalFloatField)); + INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalDoubleField"), + JavaConstant.forDouble( + DUMMY_CLASS_INSTANCE.finalDoubleField)); + INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalObjectField"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.finalObjectField)); + } + + public static final Map INSTANCE_FINAL_DEFAULT_FIELDS_MAP + = new HashMap<>(); + + static { + INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "finalDefaultBooleanField"), + JavaConstant.forBoolean( + DUMMY_CLASS_INSTANCE.finalDefaultBooleanField)); + INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "finalDefaultByteField"), + JavaConstant.forByte( + DUMMY_CLASS_INSTANCE.finalDefaultByteField)); + INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "finalDefaultShortField"), + JavaConstant.forShort( + DUMMY_CLASS_INSTANCE.finalDefaultShortField)); + INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "finalDefaultCharField"), + JavaConstant.forChar( + DUMMY_CLASS_INSTANCE.finalDefaultCharField)); + INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "finalDefaultIntField"), + JavaConstant.forInt( + DUMMY_CLASS_INSTANCE.finalDefaultIntField)); + INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "finalDefaultLongField"), + JavaConstant.forLong( + DUMMY_CLASS_INSTANCE.finalDefaultLongField)); + INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "finalDefaultFloatField"), + JavaConstant.forFloat( + DUMMY_CLASS_INSTANCE.finalDefaultFloatField)); + INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "finalDefaultDoubleField"), + JavaConstant.forDouble( + DUMMY_CLASS_INSTANCE.finalDefaultDoubleField)); + INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "finalDefaultObjectField"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.finalDefaultObjectField)); + } + + public static final Map INSTANCE_STABLE_FIELDS_MAP + = new HashMap<>(); + + static { + INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableBooleanField"), + JavaConstant.forBoolean( + DUMMY_CLASS_INSTANCE.stableBooleanField)); + INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableByteField"), + JavaConstant.forByte(DUMMY_CLASS_INSTANCE.stableByteField)); + INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableShortField"), + JavaConstant.forShort( + DUMMY_CLASS_INSTANCE.stableShortField)); + INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableCharField"), + JavaConstant.forChar(DUMMY_CLASS_INSTANCE.stableCharField)); + INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableIntField"), + JavaConstant.forInt(DUMMY_CLASS_INSTANCE.stableIntField)); + INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableLongField"), + JavaConstant.forLong(DUMMY_CLASS_INSTANCE.stableLongField)); + INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableFloatField"), + JavaConstant.forFloat( + DUMMY_CLASS_INSTANCE.stableFloatField)); + INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableDoubleField"), + JavaConstant.forDouble( + DUMMY_CLASS_INSTANCE.stableDoubleField)); + INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableObjectField"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableObjectField)); + } + + public static final Map INSTANCE_STABLE_DEFAULT_FIELDS_MAP + = new HashMap<>(); + + static { + INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "stableDefaultBooleanField"), + JavaConstant.forBoolean( + DUMMY_CLASS_INSTANCE.stableDefaultBooleanField)); + INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "stableDefaultByteField"), + JavaConstant.forByte( + DUMMY_CLASS_INSTANCE.stableDefaultByteField)); + INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "stableDefaultShortField"), + JavaConstant.forShort( + DUMMY_CLASS_INSTANCE.stableDefaultShortField)); + INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "stableDefaultCharField"), + JavaConstant.forChar( + DUMMY_CLASS_INSTANCE.stableDefaultCharField)); + INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "stableDefaultIntField"), + JavaConstant.forInt( + DUMMY_CLASS_INSTANCE.stableDefaultIntField)); + INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "stableDefaultLongField"), + JavaConstant.forLong( + DUMMY_CLASS_INSTANCE.stableDefaultLongField)); + INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "stableDefaultFloatField"), + JavaConstant.forFloat( + DUMMY_CLASS_INSTANCE.stableDefaultFloatField)); + INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "stableDefaultDoubleField"), + JavaConstant.forDouble( + DUMMY_CLASS_INSTANCE.stableDefaultDoubleField)); + INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "stableDefaultObjectField"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableDefaultObjectField)); + } + + public static final Map STATIC_FIELDS_MAP = new HashMap<>(); + + static { + STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticBooleanField"), + JavaConstant.forBoolean(DummyClass.staticBooleanField)); + STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticByteField"), + JavaConstant.forByte(DummyClass.staticByteField)); + STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticShortField"), + JavaConstant.forShort(DummyClass.staticShortField)); + STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticCharField"), + JavaConstant.forChar(DummyClass.staticCharField)); + STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticIntField"), + JavaConstant.forInt(DummyClass.staticIntField)); + STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticLongField"), + JavaConstant.forLong(DummyClass.staticLongField)); + STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticFloatField"), + JavaConstant.forFloat(DummyClass.staticFloatField)); + STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticDoubleField"), + JavaConstant.forDouble(DummyClass.staticDoubleField)); + STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticObjectField"), + CONSTANT_REFLECTION_PROVIDER.forObject(DummyClass.staticObjectField)); + } + + public static final Map STATIC_FINAL_FIELDS_MAP + = new HashMap<>(); + + static { + STATIC_FINAL_FIELDS_MAP.put( + getResolvedJavaField(DummyClass.class, "staticFinalBooleanField"), + JavaConstant.forBoolean(DummyClass.staticFinalBooleanField)); + STATIC_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticFinalByteField"), + JavaConstant.forByte(DummyClass.staticFinalByteField)); + STATIC_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticFinalShortField"), + JavaConstant.forShort(DummyClass.staticFinalShortField)); + STATIC_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticFinalCharField"), + JavaConstant.forChar(DummyClass.staticFinalCharField)); + STATIC_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticFinalIntField"), + JavaConstant.forInt(DummyClass.staticFinalIntField)); + STATIC_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticFinalLongField"), + JavaConstant.forLong(DummyClass.staticFinalLongField)); + STATIC_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticFinalFloatField"), + JavaConstant.forFloat(DummyClass.staticFinalFloatField)); + STATIC_FINAL_FIELDS_MAP.put( + getResolvedJavaField(DummyClass.class, "staticFinalDoubleField"), + JavaConstant.forDouble(DummyClass.staticFinalDoubleField)); + STATIC_FINAL_FIELDS_MAP.put( + getResolvedJavaField(DummyClass.class, "staticFinalObjectField"), + CONSTANT_REFLECTION_PROVIDER.forObject(DummyClass.staticFinalObjectField)); + } + + public static final Map STATIC_STABLE_FIELDS_MAP + = new HashMap<>(); + + static { + STATIC_STABLE_FIELDS_MAP.put( + getResolvedJavaField(DummyClass.class, "staticStableBooleanField"), + JavaConstant.forBoolean(DummyClass.staticStableBooleanField)); + STATIC_STABLE_FIELDS_MAP.put( + getResolvedJavaField(DummyClass.class, "staticStableByteField"), + JavaConstant.forByte(DummyClass.staticStableByteField)); + STATIC_STABLE_FIELDS_MAP.put( + getResolvedJavaField(DummyClass.class, "staticStableShortField"), + JavaConstant.forShort(DummyClass.staticStableShortField)); + STATIC_STABLE_FIELDS_MAP.put( + getResolvedJavaField(DummyClass.class, "staticStableCharField"), + JavaConstant.forChar(DummyClass.staticStableCharField)); + STATIC_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticStableIntField"), + JavaConstant.forInt(DummyClass.staticStableIntField)); + STATIC_STABLE_FIELDS_MAP.put( + getResolvedJavaField(DummyClass.class, "staticStableLongField"), + JavaConstant.forLong(DummyClass.staticStableLongField)); + STATIC_STABLE_FIELDS_MAP.put( + getResolvedJavaField(DummyClass.class, "staticStableFloatField"), + JavaConstant.forFloat(DummyClass.staticStableFloatField)); + STATIC_STABLE_FIELDS_MAP.put( + getResolvedJavaField(DummyClass.class, "staticStableDoubleField"), + JavaConstant.forDouble(DummyClass.staticStableDoubleField)); + STATIC_STABLE_FIELDS_MAP.put( + getResolvedJavaField(DummyClass.class, "staticStableObjectField"), + CONSTANT_REFLECTION_PROVIDER.forObject(DummyClass.staticStableObjectField)); + } + + public static final Map STATIC_STABLE_DEFAULT_FIELDS_MAP + = new HashMap<>(); + + static { + STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "staticStableDefaultBooleanField"), + JavaConstant.forBoolean( + DummyClass.staticStableDefaultBooleanField)); + STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "staticStableDefaultByteField"), + JavaConstant.forByte( + DummyClass.staticStableDefaultByteField)); + STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "staticStableDefaultShortField"), + JavaConstant.forShort( + DummyClass.staticStableDefaultShortField)); + STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "staticStableDefaultCharField"), + JavaConstant.forChar( + DummyClass.staticStableDefaultCharField)); + STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "staticStableDefaultIntField"), + JavaConstant.forInt( + DummyClass.staticStableDefaultIntField)); + STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "staticStableDefaultLongField"), + JavaConstant.forLong( + DummyClass.staticStableDefaultLongField)); + STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "staticStableDefaultFloatField"), + JavaConstant.forFloat( + DummyClass.staticStableDefaultFloatField)); + STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "staticStableDefaultDoubleField"), + JavaConstant.forDouble( + DummyClass.staticStableDefaultDoubleField)); + STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, + "staticStableDefaultObjectField"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DummyClass.staticStableDefaultObjectField)); + } + + public static final int ARRAY_DIMENSION = 1; + public static final int ARRAY_OF_ARRAYS_DIMENSION = 2; + + public static final Map ARRAYS_MAP = new HashMap<>(); + + static { + ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "booleanArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.booleanArrayWithValues)); + ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "byteArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.byteArrayWithValues)); + ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "shortArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.shortArrayWithValues)); + ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "charArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.charArrayWithValues)); + ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "intArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.intArrayWithValues)); + ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "longArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.longArrayWithValues)); + ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "floatArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.floatArrayWithValues)); + ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "doubleArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.doubleArrayWithValues)); + ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "objectArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.objectArrayWithValues)); + } + + public static final Map STABLE_ARRAYS_MAP = new HashMap<>(); + + static { + STABLE_ARRAYS_MAP.put( + getResolvedJavaField(DummyClass.class, "stableBooleanArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableBooleanArrayWithValues)); + STABLE_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "stableByteArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableByteArrayWithValues)); + STABLE_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "stableShortArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableShortArrayWithValues)); + STABLE_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "stableCharArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableCharArrayWithValues)); + STABLE_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "stableIntArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableIntArrayWithValues)); + STABLE_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "stableLongArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableLongArrayWithValues)); + STABLE_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "stableFloatArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableFloatArrayWithValues)); + STABLE_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "stableDoubleArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableDoubleArrayWithValues)); + STABLE_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "stableObjectArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableObjectArrayWithValues)); + } + + public static final Map ARRAY_ARRAYS_MAP = new HashMap<>(); + + static { + ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "booleanArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.booleanArrayArrayWithValues)); + ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "byteArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.byteArrayArrayWithValues)); + ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "shortArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.shortArrayArrayWithValues)); + ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "charArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.charArrayArrayWithValues)); + ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "intArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.intArrayArrayWithValues)); + ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "longArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.longArrayArrayWithValues)); + ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "floatArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.floatArrayArrayWithValues)); + ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "doubleArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.doubleArrayArrayWithValues)); + ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "objectArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.objectArrayArrayWithValues)); + } + + public static final Map STABLE_ARRAY_ARRAYS_MAP = new HashMap<>(); + + static { + STABLE_ARRAY_ARRAYS_MAP.put( + getResolvedJavaField(DummyClass.class, "stableBooleanArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableBooleanArrayArrayWithValues)); + STABLE_ARRAY_ARRAYS_MAP.put( + getResolvedJavaField(DummyClass.class, "stableByteArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableByteArrayArrayWithValues)); + STABLE_ARRAY_ARRAYS_MAP.put( + getResolvedJavaField(DummyClass.class, "stableShortArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableShortArrayArrayWithValues)); + STABLE_ARRAY_ARRAYS_MAP.put( + getResolvedJavaField(DummyClass.class, "stableCharArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableCharArrayArrayWithValues)); + STABLE_ARRAY_ARRAYS_MAP.put( + getResolvedJavaField(DummyClass.class, "stableIntArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableIntArrayArrayWithValues)); + STABLE_ARRAY_ARRAYS_MAP.put( + getResolvedJavaField(DummyClass.class, "stableLongArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableLongArrayArrayWithValues)); + STABLE_ARRAY_ARRAYS_MAP.put( + getResolvedJavaField(DummyClass.class, "stableFloatArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableFloatArrayArrayWithValues)); + STABLE_ARRAY_ARRAYS_MAP.put( + getResolvedJavaField(DummyClass.class, "stableDoubleArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableDoubleArrayArrayWithValues)); + STABLE_ARRAY_ARRAYS_MAP.put( + getResolvedJavaField(DummyClass.class, "stableObjectArrayArrayWithValues"), + CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.stableObjectArrayArrayWithValues)); + } + + public static ResolvedJavaField getResolvedJavaField(Class clazz, String fieldName) { + Field reflectionField = null; + try { + reflectionField = clazz.getDeclaredField(fieldName); + reflectionField.setAccessible(true); + } catch (NoSuchFieldException ex) { + throw new Error("Test bug: Invalid field name: " + ex, ex); + } catch (SecurityException ex) { + throw new Error("Unexpected error: " + ex, ex); + } + MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess(); + return metaAccess.lookupJavaField(reflectionField); + } +} diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/UnboxPrimitiveDataProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/UnboxPrimitiveDataProvider.java Thu Mar 31 14:25:35 2016 -0700 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.vm.ci.hotspot.test; + +import static jdk.vm.ci.hotspot.test.TestHelper.CONSTANT_REFLECTION_PROVIDER; +import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_INSTANCE; + +import java.util.LinkedList; + +import jdk.vm.ci.meta.JavaConstant; +import org.testng.annotations.DataProvider; + +public class UnboxPrimitiveDataProvider { + + @DataProvider(name = "unboxPrimitiveDataProvider") + public static Object[][] unboxPrimitiveDataProvider() { + LinkedList cfgSet = new LinkedList<>(); + // Testing boolean + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject( + (Boolean) true), JavaConstant.forBoolean(true)}); + cfgSet.add(new Object[]{JavaConstant.forBoolean(true), null}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject((Boolean) false), + JavaConstant.forBoolean(false)}); + cfgSet.add(new Object[]{JavaConstant.forBoolean(false), null}); + for (byte number : new byte[]{-128, 0, 1, 127}) { + // Testing boxed primitives + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Byte.valueOf(number)), + JavaConstant.forByte(number)}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Short.valueOf(number)), + JavaConstant.forShort(number)}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Integer.valueOf(number)), + JavaConstant.forInt(number)}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Long.valueOf(number)), + JavaConstant.forLong(number)}); + if (number >= 0) { + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject( + Character.valueOf((char) number)), + JavaConstant.forChar((char) number)}); + } + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject( + Float.valueOf(number * 1.1f)), + JavaConstant.forFloat(number * 1.1f)}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject( + Double.valueOf(number * 1.1)), + JavaConstant.forDouble(number * 1.1)}); + // Testing non-boxed primitives (should result in returning of "null") + cfgSet.add(new Object[]{JavaConstant.forByte(number), null}); + cfgSet.add(new Object[]{JavaConstant.forShort(number), null}); + cfgSet.add(new Object[]{JavaConstant.forInt(number), null}); + cfgSet.add(new Object[]{JavaConstant.forLong(number), null}); + cfgSet.add(new Object[]{JavaConstant.forChar((char) number), null}); + cfgSet.add(new Object[]{JavaConstant.forFloat(number), null}); + cfgSet.add(new Object[]{JavaConstant.forDouble(number), null}); + } + // Testing boxed primitives with max values + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Short.MAX_VALUE), + JavaConstant.forShort(Short.MAX_VALUE)}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Integer.MAX_VALUE), + JavaConstant.forInt(Integer.MAX_VALUE)}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Long.MAX_VALUE), + JavaConstant.forLong(Long.MAX_VALUE)}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Character.MAX_VALUE), + JavaConstant.forChar(Character.MAX_VALUE)}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Float.MAX_VALUE), + JavaConstant.forFloat(Float.MAX_VALUE)}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Double.MAX_VALUE), + JavaConstant.forDouble(Double.MAX_VALUE)}); + // Non-primitives testing + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.objectField), null}); + cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject( + DUMMY_CLASS_INSTANCE.booleanArrayWithValues), + null}); + // Null testing + cfgSet.add(new Object[]{JavaConstant.NULL_POINTER, null}); + cfgSet.add(new Object[]{null, null}); + return cfgSet.toArray(new Object[0][0]); + } +} diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/patches/java.base/java/lang/Helper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/patches/java.base/java/lang/Helper.java Thu Mar 31 14:25:35 2016 -0700 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang; + +/** + * A helper class to get access to package-private members + */ +public class Helper { + @jdk.internal.vm.annotation.ForceInline + public static boolean StringCodingHasNegatives(byte[] ba, int off, int len) { + return StringCoding.hasNegatives(ba, off, len); + } +} diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/runtime/6859338/Test6859338.java --- a/hotspot/test/compiler/runtime/6859338/Test6859338.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/runtime/6859338/Test6859338.java Thu Mar 31 14:25:35 2016 -0700 @@ -27,7 +27,7 @@ * @bug 6859338 * @summary Assertion failure in sharedRuntime.cpp * - * @run main/othervm -Xcomp -XX:+IgnoreUnrecognizedVMOptions -XX:-InlineObjectHash -Xbatch -XX:-ProfileInterpreter Test6859338 + * @run main/othervm -Xcomp -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:-InlineObjectHash -Xbatch -XX:-ProfileInterpreter Test6859338 */ public class Test6859338 { diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/stable/TestStableUByte.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/stable/TestStableUByte.java Thu Mar 31 14:25:35 2016 -0700 @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test TestStableUByte + * @summary tests on stable fields and arrays + * @library /testlibrary /test/lib / + * @modules java.base/jdk.internal.vm.annotation + * @build sun.hotspot.WhiteBox + * @build compiler.stable.TestStableUByte + * + * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp + * -XX:-TieredCompilation + * -XX:+FoldStableValues + * -XX:CompileOnly=::get,::get1 + * compiler.stable.TestStableUByte + * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp + * -XX:-TieredCompilation + * -XX:-FoldStableValues + * -XX:CompileOnly=::get,::get1 + * compiler.stable.TestStableUByte + * + * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp + * -XX:+TieredCompilation -XX:TieredStopAtLevel=1 + * -XX:+FoldStableValues + * -XX:CompileOnly=::get,::get1 + * compiler.stable.TestStableUByte + * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp + * -XX:+TieredCompilation -XX:TieredStopAtLevel=1 + * -XX:-FoldStableValues + * -XX:CompileOnly=::get,::get1 + * compiler.stable.TestStableUByte + * + */ +package compiler.stable; + +import jdk.internal.vm.annotation.Stable; + +import java.lang.reflect.InvocationTargetException; + +public class TestStableUByte { + static final boolean isStableEnabled = StableConfiguration.isStableEnabled; + + public static void main(String[] args) throws Exception { + run(UByteStable.class); + run(UByteArrayDim1.class); + + if (failed) { + throw new Error("TEST FAILED"); + } + } + + /* ==================================================== */ + + static class UByteStable { + public @Stable byte v; + + public static final UByteStable c = new UByteStable(); + + public static int get() { return c.v & 0xFF; } + + public static void test() throws Exception { + byte v1 = -1, v2 = 1; + + c.v = v1; int r1 = get(); + c.v = v2; int r2 = get(); + + assertEquals(r1, v1 & 0xFF); + assertEquals(r2, (isStableEnabled ? v1 : v2) & 0xFF); + } + } + + /* ==================================================== */ + + static class UByteArrayDim1 { + public @Stable byte[] v; + + public static final UByteArrayDim1 c = new UByteArrayDim1(); + + public static byte[] get() { return c.v; } + public static int get1() { return get()[0] & 0xFF; } + + public static void test() throws Exception { + byte v1 = -1, v2 = 1; + + c.v = new byte[1]; + c.v[0] = v1; int r1 = get1(); + c.v[0] = v2; int r2 = get1(); + + assertEquals(r1, v1 & 0xFF); + assertEquals(r2, (isStableEnabled ? v1 : v2) & 0xFF); + } + } + + /* ==================================================== */ + // Auxiliary methods + static void assertEquals(int i, int j) { if (i != j) throw new AssertionError(i + " != " + j); } + static void assertTrue(boolean b) { if (!b) throw new AssertionError(); } + + static boolean failed = false; + + public static void run(Class test) { + Throwable ex = null; + System.out.print(test.getName()+": "); + try { + test.getMethod("test").invoke(null); + } catch (InvocationTargetException e) { + ex = e.getCause(); + } catch (Throwable e) { + ex = e; + } finally { + if (ex == null) { + System.out.println("PASSED"); + } else { + failed = true; + System.out.println("FAILED"); + ex.printStackTrace(System.out); + } + } + } +} diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/stable/TestStableUShort.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/stable/TestStableUShort.java Thu Mar 31 14:25:35 2016 -0700 @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test TestStableUShort + * @summary tests on stable fields and arrays + * @library /testlibrary /test/lib / + * @modules java.base/jdk.internal.vm.annotation + * @build sun.hotspot.WhiteBox + * @build compiler.stable.TestStableUShort + * + * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp + * -XX:-TieredCompilation + * -XX:+FoldStableValues + * -XX:CompileOnly=::get,::get1 + * compiler.stable.TestStableUShort + * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp + * -XX:-TieredCompilation + * -XX:-FoldStableValues + * -XX:CompileOnly=::get,::get1 + * compiler.stable.TestStableUShort + * + * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp + * -XX:+TieredCompilation -XX:TieredStopAtLevel=1 + * -XX:+FoldStableValues + * -XX:CompileOnly=::get,::get1 + * compiler.stable.TestStableUShort + * @run main/bootclasspath -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xcomp + * -XX:+TieredCompilation -XX:TieredStopAtLevel=1 + * -XX:-FoldStableValues + * -XX:CompileOnly=::get,::get1 + * compiler.stable.TestStableUShort + * + */ +package compiler.stable; + +import jdk.internal.vm.annotation.Stable; + +import java.lang.reflect.InvocationTargetException; + +public class TestStableUShort { + static final boolean isStableEnabled = StableConfiguration.isStableEnabled; + + public static void main(String[] args) throws Exception { + run(UShortStable.class); + run(UShortArrayDim1.class); + + if (failed) { + throw new Error("TEST FAILED"); + } + } + + /* ==================================================== */ + + static class UShortStable { + public @Stable short v; + + public static final UShortStable c = new UShortStable(); + + public static int get() { return c.v & 0xFFFF; } + + public static void test() throws Exception { + short v1 = -1, v2 = 1; + + c.v = v1; int r1 = get(); + c.v = v2; int r2 = get(); + + assertEquals(r1, v1 & 0xFFFF); + assertEquals(r2, (isStableEnabled ? v1 : v2) & 0xFFFF); + } + } + + /* ==================================================== */ + + static class UShortArrayDim1 { + public @Stable short[] v; + + public static final UShortArrayDim1 c = new UShortArrayDim1(); + + public static short[] get() { return c.v; } + public static int get1() { return get()[0] & 0xFFFF; } + + public static void test() throws Exception { + short v1 = -1, v2 = 1; + + c.v = new short[1]; + c.v[0] = v1; int r1 = get1(); + c.v[0] = v2; int r2 = get1(); + + assertEquals(r1, v1 & 0xFFFF); + assertEquals(r2, (isStableEnabled ? v1 : v2) & 0xFFFF); + } + } + + /* ==================================================== */ + // Auxiliary methods + static void assertEquals(int i, int j) { if (i != j) throw new AssertionError(i + " != " + j); } + static void assertTrue(boolean b) { if (!b) throw new AssertionError(); } + + static boolean failed = false; + + public static void run(Class test) { + Throwable ex = null; + System.out.print(test.getName()+": "); + try { + test.getMethod("test").invoke(null); + } catch (InvocationTargetException e) { + ex = e.getCause(); + } catch (Throwable e) { + ex = e; + } finally { + if (ex == null) { + System.out.println("PASSED"); + } else { + failed = true; + System.out.println("FAILED"); + ex.printStackTrace(System.out); + } + } + } +} diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestBoolean.java --- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestBoolean.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestBoolean.java Thu Mar 31 14:25:35 2016 -0700 @@ -147,3 +147,4 @@ } } + diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestByte.java --- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestByte.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestByte.java Thu Mar 31 14:25:35 2016 -0700 @@ -184,3 +184,4 @@ } } } + diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestChar.java --- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestChar.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestChar.java Thu Mar 31 14:25:35 2016 -0700 @@ -202,3 +202,4 @@ } } } + diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestDouble.java --- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestDouble.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestDouble.java Thu Mar 31 14:25:35 2016 -0700 @@ -184,3 +184,4 @@ } } } + diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestFloat.java --- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestFloat.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestFloat.java Thu Mar 31 14:25:35 2016 -0700 @@ -184,3 +184,4 @@ } } } + diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestInt.java --- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestInt.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestInt.java Thu Mar 31 14:25:35 2016 -0700 @@ -156,12 +156,6 @@ assertEquals(x, 2, "putVolatile int value"); } - // Lazy - { - UNSAFE.putOrderedInt(base, offset, 1); - int x = UNSAFE.getIntVolatile(base, offset); - assertEquals(x, 1, "putRelease int value"); - } // Lazy { @@ -305,3 +299,4 @@ } } } + diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestLong.java --- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestLong.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestLong.java Thu Mar 31 14:25:35 2016 -0700 @@ -156,12 +156,6 @@ assertEquals(x, 2L, "putVolatile long value"); } - // Lazy - { - UNSAFE.putOrderedLong(base, offset, 1L); - long x = UNSAFE.getLongVolatile(base, offset); - assertEquals(x, 1L, "putRelease long value"); - } // Lazy { @@ -305,3 +299,4 @@ } } } + diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestObject.java --- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestObject.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestObject.java Thu Mar 31 14:25:35 2016 -0700 @@ -127,12 +127,6 @@ assertEquals(x, "bar", "putVolatile Object value"); } - // Lazy - { - UNSAFE.putOrderedObject(base, offset, "foo"); - Object x = UNSAFE.getObjectVolatile(base, offset); - assertEquals(x, "foo", "putRelease Object value"); - } // Lazy { @@ -241,3 +235,4 @@ } } + diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestShort.java --- a/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestShort.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestShort.java Thu Mar 31 14:25:35 2016 -0700 @@ -202,3 +202,4 @@ } } } + diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestBoolean.java --- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestBoolean.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestBoolean.java Thu Mar 31 14:25:35 2016 -0700 @@ -130,6 +130,8 @@ + } } + diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestByte.java --- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestByte.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestByte.java Thu Mar 31 14:25:35 2016 -0700 @@ -159,6 +159,7 @@ + } static void testAccess(long address) { @@ -170,3 +171,4 @@ } } } + diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestChar.java --- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestChar.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestChar.java Thu Mar 31 14:25:35 2016 -0700 @@ -159,6 +159,7 @@ + } static void testAccess(long address) { @@ -170,3 +171,4 @@ } } } + diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestDouble.java --- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestDouble.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestDouble.java Thu Mar 31 14:25:35 2016 -0700 @@ -159,6 +159,7 @@ + } static void testAccess(long address) { @@ -170,3 +171,4 @@ } } } + diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestFloat.java --- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestFloat.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestFloat.java Thu Mar 31 14:25:35 2016 -0700 @@ -159,6 +159,7 @@ + } static void testAccess(long address) { @@ -170,3 +171,4 @@ } } } + diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestInt.java --- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestInt.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestInt.java Thu Mar 31 14:25:35 2016 -0700 @@ -164,6 +164,7 @@ } + UNSAFE.putInt(base, offset, 1); // Compare @@ -181,6 +182,7 @@ assertEquals(x, 2, "failing compareAndSwap int value"); } + // Compare set and get { int o = UNSAFE.getAndSetInt(base, offset, 1); @@ -209,3 +211,4 @@ } } } + diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestLong.java --- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestLong.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestLong.java Thu Mar 31 14:25:35 2016 -0700 @@ -164,6 +164,7 @@ } + UNSAFE.putLong(base, offset, 1L); // Compare @@ -181,6 +182,7 @@ assertEquals(x, 2L, "failing compareAndSwap long value"); } + // Compare set and get { long o = UNSAFE.getAndSetLong(base, offset, 1L); @@ -209,3 +211,4 @@ } } } + diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestObject.java --- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestObject.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestObject.java Thu Mar 31 14:25:35 2016 -0700 @@ -135,6 +135,7 @@ } + UNSAFE.putObject(base, offset, "foo"); // Compare @@ -152,6 +153,7 @@ assertEquals(x, "bar", "failing compareAndSwap Object value"); } + // Compare set and get { Object o = UNSAFE.getAndSetObject(base, offset, "foo"); @@ -163,3 +165,4 @@ } } + diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestShort.java --- a/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestShort.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/unsafe/SunMiscUnsafeAccessTestShort.java Thu Mar 31 14:25:35 2016 -0700 @@ -159,6 +159,7 @@ + } static void testAccess(long address) { @@ -170,3 +171,4 @@ } } } + diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/unsafe/UnsafeGetConstantField.java --- a/hotspot/test/compiler/unsafe/UnsafeGetConstantField.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/unsafe/UnsafeGetConstantField.java Thu Mar 31 14:25:35 2016 -0700 @@ -46,6 +46,7 @@ * -XX:+FoldStableValues * -XX:CompileCommand=dontinline,UnsafeGetConstantField.checkGetAddress() * -XX:CompileCommand=dontinline,*.test* + * -XX:CompileCommand=inline,*Unsafe.get* * -XX:-UseUnalignedAccesses * compiler.unsafe.UnsafeGetConstantField */ diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/unsafe/X-UnsafeAccessTest.java.template --- a/hotspot/test/compiler/unsafe/X-UnsafeAccessTest.java.template Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/unsafe/X-UnsafeAccessTest.java.template Thu Mar 31 14:25:35 2016 -0700 @@ -160,6 +160,7 @@ assertEquals(x, $value2$, "putVolatile $type$ value"); } +#if[!JdkInternalMisc] #if[Ordered] // Lazy { @@ -168,6 +169,7 @@ assertEquals(x, $value1$, "putRelease $type$ value"); } #end[Ordered] +#end[!JdkInternalMisc] #if[JdkInternalMisc] // Lazy diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/whitebox/ForceNMethodSweepTest.java --- a/hotspot/test/compiler/whitebox/ForceNMethodSweepTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/whitebox/ForceNMethodSweepTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -90,7 +90,7 @@ return usage; } private void guaranteedSweep() { - // not entrant -> ++stack_traversal_mark -> zombie -> reclamation -> flushed + // not entrant -> ++stack_traversal_mark -> zombie -> flushed for (int i = 0; i < 5; ++i) { WHITE_BOX.fullGC(); WHITE_BOX.forceNMethodSweep(); diff -r 6072af7a98be -r 9ac2550c36c6 hotspot/test/compiler/whitebox/LockCompilationTest.java --- a/hotspot/test/compiler/whitebox/LockCompilationTest.java Wed Jul 05 21:31:37 2017 +0200 +++ b/hotspot/test/compiler/whitebox/LockCompilationTest.java Thu Mar 31 14:25:35 2016 -0700 @@ -23,12 +23,12 @@ /* * @test LockCompilationTest - * @bug 8059624 + * @bug 8059624 8152169 * @library /testlibrary /test/lib / * @modules java.management * @build LockCompilationTest - * @run main ClassFileInstaller sun.hotspot.WhiteBox - * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run driver ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission * @run main/othervm -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI LockCompilationTest * @summary testing of WB::lock/unlockCompilation() */ @@ -42,10 +42,25 @@ import jdk.test.lib.Asserts; public class LockCompilationTest extends CompilerWhiteBoxTest { + public static void main(String[] args) throws Exception { - // This case waits for 10 seconds and verifies that the method hasn't been + // This case waits for 5 seconds and verifies that the method hasn't been // compiled during that time. Only do that for one of the test cases. - CompilerWhiteBoxTest.main(LockCompilationTest::new, new String[] {"METHOD_TEST"}); + + // Only compile SimpleTestCase$Helper.method and exclude all other to ensure no + // contention on the compile queue causes problems. + String directive = + "[{ match:\"*SimpleTestCase$Helper.method\", Exclude:false}, " + + " { match:\"*.*\", Exclude:true}]"; + if (WHITE_BOX.addCompilerDirective(directive) != 2) { + throw new RuntimeException("Could not add directive"); + } + try { + CompilerWhiteBoxTest.main(LockCompilationTest::new, new String[] {"METHOD_TEST"}); + } finally { + WHITE_BOX.removeCompilerDirective(2); + } + } private LockCompilationTest(TestCase testCase) { @@ -66,7 +81,9 @@ // to check if it works correctly w/ safepoints System.out.println("going to safepoint"); WHITE_BOX.fullGC(); - waitBackgroundCompilation(); + // Sleep a while and then make sure the compile is still waiting + Thread.sleep(5000); + Asserts.assertTrue( WHITE_BOX.isMethodQueuedForCompilation(method), method + " must be in queue");