# HG changeset patch # User aghaisas # Date 1551441448 -19800 # Node ID faf96b92a47b5b727a011446d6a7c98b96acc6e7 # Parent 268875216dfceae24bc2a4c8ab59d7ccb7291d79# Parent b342deab639f19f0c998671fac9a6c0618730d51 Merge diff -r 268875216dfc -r faf96b92a47b .hgtags --- a/.hgtags Mon Feb 25 15:15:46 2019 +0530 +++ b/.hgtags Fri Mar 01 17:27:28 2019 +0530 @@ -546,3 +546,4 @@ 4ce47bc1fb92cf94c6e3d1f49d582f02dcb851ab jdk-12+32 c081f3ea6b9300265a4a34e38f970b1e3ddaae9f jdk-13+9 b67884871b5fff79c5ef3eb8ac74dd48d71ea9b1 jdk-12+33 +8e069f7b4fabfe05d9f500783e6d56cb0196d25c jdk-13+10 diff -r 268875216dfc -r faf96b92a47b make/data/cldr/common/main/my.xml --- a/make/data/cldr/common/main/my.xml Mon Feb 25 15:15:46 2019 +0530 +++ b/make/data/cldr/common/main/my.xml Fri Mar 01 17:27:28 2019 +0530 @@ -1446,17 +1446,14 @@ z HH:mm:ss - - HH:mm:ss + B HH:mm:ss - H:mm + B H:mm diff -r 268875216dfc -r faf96b92a47b make/jdk/src/classes/build/tools/cldrconverter/Bundle.java --- a/make/jdk/src/classes/build/tools/cldrconverter/Bundle.java Mon Feb 25 15:15:46 2019 +0530 +++ b/make/jdk/src/classes/build/tools/cldrconverter/Bundle.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, 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 @@ -523,36 +523,46 @@ for (String k : patternKeys) { if (myMap.containsKey(calendarPrefix + k)) { int len = patternKeys.length; - List rawPatterns = new ArrayList<>(len); - List patterns = new ArrayList<>(len); + List dateTimePatterns = new ArrayList<>(len); + List sdfPatterns = new ArrayList<>(len); for (int i = 0; i < len; i++) { String key = calendarPrefix + patternKeys[i]; String pattern = (String) myMap.remove(key); if (pattern == null) { pattern = (String) parentsMap.remove(key); } - rawPatterns.add(i, pattern); if (pattern != null) { - patterns.add(i, translateDateFormatLetters(calendarType, pattern)); + // Perform date-time format pattern conversion which is + // applicable to both SimpleDateFormat and j.t.f.DateTimeFormatter. + // For example, character 'B' is mapped with 'a', as 'B' is not + // supported in either SimpleDateFormat or j.t.f.DateTimeFormatter + String transPattern = translateDateFormatLetters(calendarType, pattern, this::convertDateTimePatternLetter); + dateTimePatterns.add(i, transPattern); + // Additionally, perform SDF specific date-time format pattern conversion + sdfPatterns.add(i, translateDateFormatLetters(calendarType, transPattern, this::convertSDFLetter)); } else { - patterns.add(i, null); + dateTimePatterns.add(i, null); + sdfPatterns.add(i, null); } } - // If patterns is empty or has any nulls, discard patterns. - if (patterns.isEmpty()) { + // If empty, discard patterns + if (sdfPatterns.isEmpty()) { return; } String key = calendarPrefix + name; - if (!rawPatterns.equals(patterns)) { - myMap.put("java.time." + key, rawPatterns.toArray(new String[len])); + + // If additional changes are made in the SDF specific conversion, + // keep the commonly converted patterns as java.time patterns + if (!dateTimePatterns.equals(sdfPatterns)) { + myMap.put("java.time." + key, dateTimePatterns.toArray(String[]::new)); } - myMap.put(key, patterns.toArray(new String[len])); + myMap.put(key, sdfPatterns.toArray(new String[len])); break; } } } - private String translateDateFormatLetters(CalendarType calendarType, String cldrFormat) { + private String translateDateFormatLetters(CalendarType calendarType, String cldrFormat, ConvertDateTimeLetters converter) { String pattern = cldrFormat; int length = pattern.length(); boolean inQuote = false; @@ -571,7 +581,7 @@ if (nextc == '\'') { i++; if (count != 0) { - convert(calendarType, lastLetter, count, jrePattern); + converter.convert(calendarType, lastLetter, count, jrePattern); lastLetter = 0; count = 0; } @@ -581,7 +591,7 @@ } if (!inQuote) { if (count != 0) { - convert(calendarType, lastLetter, count, jrePattern); + converter.convert(calendarType, lastLetter, count, jrePattern); lastLetter = 0; count = 0; } @@ -598,7 +608,7 @@ } if (!(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')) { if (count != 0) { - convert(calendarType, lastLetter, count, jrePattern); + converter.convert(calendarType, lastLetter, count, jrePattern); lastLetter = 0; count = 0; } @@ -611,7 +621,7 @@ count++; continue; } - convert(calendarType, lastLetter, count, jrePattern); + converter.convert(calendarType, lastLetter, count, jrePattern); lastLetter = c; count = 1; } @@ -621,7 +631,7 @@ } if (count != 0) { - convert(calendarType, lastLetter, count, jrePattern); + converter.convert(calendarType, lastLetter, count, jrePattern); } if (cldrFormat.contentEquals(jrePattern)) { return cldrFormat; @@ -676,71 +686,91 @@ } } - private void convert(CalendarType calendarType, char cldrLetter, int count, StringBuilder sb) { + /** + * Perform a generic conversion of CLDR date-time format pattern letter based + * on the support given by the SimpleDateFormat and the j.t.f.DateTimeFormatter + * for date-time formatting. + */ + private void convertDateTimePatternLetter(CalendarType calendarType, char cldrLetter, int count, StringBuilder sb) { switch (cldrLetter) { - case 'G': - if (calendarType != CalendarType.GREGORIAN) { - // Adjust the number of 'G's for JRE SimpleDateFormat - if (count == 5) { - // CLDR narrow -> JRE short - count = 1; - } else if (count == 1) { - // CLDR abbr -> JRE long - count = 4; - } - } - appendN(cldrLetter, count, sb); - break; - - // TODO: support 'c' and 'e' in JRE SimpleDateFormat - // Use 'u' and 'E' for now. - case 'c': - case 'e': - switch (count) { - case 1: - sb.append('u'); + case 'u': + // Change cldr letter 'u' to 'y', as 'u' is interpreted as + // "Extended year (numeric)" in CLDR/LDML, + // which is not supported in SimpleDateFormat and + // j.t.f.DateTimeFormatter, so it is replaced with 'y' + // as the best approximation + appendN('y', count, sb); break; - case 3: - case 4: - appendN('E', count, sb); + case 'B': + // 'B' character (day period) is not supported by + // SimpleDateFormat and j.t.f.DateTimeFormatter, + // this is a workaround in which 'B' character + // appearing in CLDR date-time pattern is replaced + // with 'a' character and hence resolved with am/pm strings. + // This workaround is based on the the fallback mechanism + // specified in LDML spec for 'B' character, when a locale + // does not have data for day period ('B') + appendN('a', count, sb); break; - case 5: - appendN('E', 3, sb); + default: + appendN(cldrLetter, count, sb); break; - } - break; - case 'l': - // 'l' is deprecated as a pattern character. Should be ignored. - break; + } + } - case 'u': - // Use 'y' for now. - appendN('y', count, sb); - break; - - case 'v': - case 'V': - appendN('z', count, sb); - break; + /** + * Perform a conversion of CLDR date-time format pattern letter which is + * specific to the SimpleDateFormat. + */ + private void convertSDFLetter(CalendarType calendarType, char cldrLetter, int count, StringBuilder sb) { + switch (cldrLetter) { + case 'G': + if (calendarType != CalendarType.GREGORIAN) { + // Adjust the number of 'G's for JRE SimpleDateFormat + if (count == 5) { + // CLDR narrow -> JRE short + count = 1; + } else if (count == 1) { + // CLDR abbr -> JRE long + count = 4; + } + } + appendN(cldrLetter, count, sb); + break; - case 'Z': - if (count == 4 || count == 5) { - sb.append("XXX"); - } - break; + // TODO: support 'c' and 'e' in JRE SimpleDateFormat + // Use 'u' and 'E' for now. + case 'c': + case 'e': + switch (count) { + case 1: + sb.append('u'); + break; + case 3: + case 4: + appendN('E', count, sb); + break; + case 5: + appendN('E', 3, sb); + break; + } + break; - case 'U': - case 'q': - case 'Q': - case 'g': - case 'j': - case 'A': - throw new InternalError(String.format("Unsupported letter: '%c', count=%d, id=%s%n", - cldrLetter, count, id)); - default: - appendN(cldrLetter, count, sb); - break; + case 'v': + case 'V': + appendN('z', count, sb); + break; + + case 'Z': + if (count == 4 || count == 5) { + sb.append("XXX"); + } + break; + + default: + appendN(cldrLetter, count, sb); + break; } } @@ -758,4 +788,9 @@ } return false; } + + @FunctionalInterface + private interface ConvertDateTimeLetters { + void convert(CalendarType calendarType, char cldrLetter, int count, StringBuilder sb); + } } diff -r 268875216dfc -r faf96b92a47b make/lib/Awt2dLibraries.gmk --- a/make/lib/Awt2dLibraries.gmk Mon Feb 25 15:15:46 2019 +0530 +++ b/make/lib/Awt2dLibraries.gmk Fri Mar 01 17:27:28 2019 +0530 @@ -613,7 +613,8 @@ type-limits missing-field-initializers implicit-fallthrough \ strict-aliasing undef unused-function, \ DISABLED_WARNINGS_CXX_gcc := reorder delete-non-virtual-dtor strict-overflow \ - maybe-uninitialized, \ + maybe-uninitialized \ + missing-attributes class-memaccess, \ DISABLED_WARNINGS_clang := unused-value incompatible-pointer-types \ tautological-constant-out-of-range-compare int-to-pointer-cast \ sign-compare undef missing-field-initializers, \ diff -r 268875216dfc -r faf96b92a47b src/hotspot/cpu/aarch64/assembler_aarch64.hpp --- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -2209,13 +2209,15 @@ rf(Vn, 5), rf(Vd, 0); \ } - INSN(addv, 0, 0b100001); - INSN(subv, 1, 0b100001); - INSN(mulv, 0, 0b100111); - INSN(mlav, 0, 0b100101); - INSN(mlsv, 1, 0b100101); - INSN(sshl, 0, 0b010001); - INSN(ushl, 1, 0b010001); + INSN(addv, 0, 0b100001); + INSN(subv, 1, 0b100001); + INSN(mulv, 0, 0b100111); + INSN(mlav, 0, 0b100101); + INSN(mlsv, 1, 0b100101); + INSN(sshl, 0, 0b010001); + INSN(ushl, 1, 0b010001); + INSN(umullv, 1, 0b110000); + INSN(umlalv, 1, 0b100000); #undef INSN @@ -2227,13 +2229,14 @@ rf(Vn, 5), rf(Vd, 0); \ } - INSN(absr, 0, 0b100000101110); - INSN(negr, 1, 0b100000101110); - INSN(notr, 1, 0b100000010110); - INSN(addv, 0, 0b110001101110); - INSN(cls, 0, 0b100000010010); - INSN(clz, 1, 0b100000010010); - INSN(cnt, 0, 0b100000010110); + INSN(absr, 0, 0b100000101110); + INSN(negr, 1, 0b100000101110); + INSN(notr, 1, 0b100000010110); + INSN(addv, 0, 0b110001101110); + INSN(cls, 0, 0b100000010010); + INSN(clz, 1, 0b100000010010); + INSN(cnt, 0, 0b100000010110); + INSN(uaddlv, 1, 0b110000001110); #undef INSN diff -r 268875216dfc -r faf96b92a47b src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved. + * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Red Hat Inc. 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 @@ -373,15 +373,9 @@ Register last_java_fp, address last_java_pc, Register scratch) { - if (last_java_pc != NULL) { - adr(scratch, last_java_pc); - } else { - // FIXME: This is almost never correct. We should delete all - // cases of set_last_Java_frame with last_java_pc=NULL and use the - // correct return address instead. - adr(scratch, pc()); - } - + assert(last_java_pc != NULL, "must provide a valid PC"); + + adr(scratch, last_java_pc); str(scratch, Address(rthread, JavaThread::frame_anchor_offset() + JavaFrameAnchor::last_Java_pc_offset())); @@ -398,7 +392,7 @@ } else { InstructionMark im(this); L.add_patch_at(code(), locator()); - set_last_Java_frame(last_java_sp, last_java_fp, (address)NULL, scratch); + set_last_Java_frame(last_java_sp, last_java_fp, pc() /* Patched later */, scratch); } } diff -r 268875216dfc -r faf96b92a47b src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp --- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -1,6 +1,6 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, 2018, Red Hat Inc. All rights reserved. + * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Red Hat Inc. 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 @@ -1782,14 +1782,11 @@ } // Change state to native (we save the return address in the thread, since it might not - // be pushed on the stack when we do a a stack traversal). It is enough that the pc() - // points into the right code segment. It does not have to be the correct return pc. + // be pushed on the stack when we do a stack traversal). // We use the same pc/oopMap repeatedly when we call out - intptr_t the_pc = (intptr_t) __ pc(); - oop_maps->add_gc_map(the_pc - start, map); - - __ set_last_Java_frame(sp, noreg, (address)the_pc, rscratch1); + Label native_return; + __ set_last_Java_frame(sp, noreg, native_return, rscratch1); Label dtrace_method_entry, dtrace_method_entry_done; { @@ -1922,6 +1919,11 @@ return_type); } + __ bind(native_return); + + intptr_t return_pc = (intptr_t) __ pc(); + oop_maps->add_gc_map(return_pc - start, map); + // Unpack native results. switch (ret_type) { case T_BOOLEAN: __ c2bool(r0); break; diff -r 268875216dfc -r faf96b92a47b src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp --- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -1,6 +1,6 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved. + * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Red Hat Inc. 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 @@ -3257,11 +3257,14 @@ Register buff = c_rarg1; Register len = c_rarg2; Register nmax = r4; - Register base = r5; + Register base = r5; Register count = r6; Register temp0 = rscratch1; Register temp1 = rscratch2; - Register temp2 = r7; + FloatRegister vbytes = v0; + FloatRegister vs1acc = v1; + FloatRegister vs2acc = v2; + FloatRegister vtable = v3; // Max number of bytes we can process before having to take the mod // 0x15B0 is 5552 in decimal, the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 @@ -3271,6 +3274,10 @@ __ mov(base, BASE); __ mov(nmax, NMAX); + // Load accumulation coefficients for the upper 16 bits + __ lea(temp0, ExternalAddress((address) StubRoutines::aarch64::_adler_table)); + __ ld1(vtable, __ T16B, Address(temp0)); + // s1 is initialized to the lower 16 bits of adler // s2 is initialized to the upper 16 bits of adler __ ubfx(s2, adler, 16, 16); // s2 = ((adler >> 16) & 0xffff) @@ -3311,53 +3318,8 @@ __ bind(L_nmax_loop); - __ ldp(temp0, temp1, Address(__ post(buff, 16))); - - __ add(s1, s1, temp0, ext::uxtb); - __ ubfx(temp2, temp0, 8, 8); - __ add(s2, s2, s1); - __ add(s1, s1, temp2); - __ ubfx(temp2, temp0, 16, 8); - __ add(s2, s2, s1); - __ add(s1, s1, temp2); - __ ubfx(temp2, temp0, 24, 8); - __ add(s2, s2, s1); - __ add(s1, s1, temp2); - __ ubfx(temp2, temp0, 32, 8); - __ add(s2, s2, s1); - __ add(s1, s1, temp2); - __ ubfx(temp2, temp0, 40, 8); - __ add(s2, s2, s1); - __ add(s1, s1, temp2); - __ ubfx(temp2, temp0, 48, 8); - __ add(s2, s2, s1); - __ add(s1, s1, temp2); - __ add(s2, s2, s1); - __ add(s1, s1, temp0, Assembler::LSR, 56); - __ add(s2, s2, s1); - - __ add(s1, s1, temp1, ext::uxtb); - __ ubfx(temp2, temp1, 8, 8); - __ add(s2, s2, s1); - __ add(s1, s1, temp2); - __ ubfx(temp2, temp1, 16, 8); - __ add(s2, s2, s1); - __ add(s1, s1, temp2); - __ ubfx(temp2, temp1, 24, 8); - __ add(s2, s2, s1); - __ add(s1, s1, temp2); - __ ubfx(temp2, temp1, 32, 8); - __ add(s2, s2, s1); - __ add(s1, s1, temp2); - __ ubfx(temp2, temp1, 40, 8); - __ add(s2, s2, s1); - __ add(s1, s1, temp2); - __ ubfx(temp2, temp1, 48, 8); - __ add(s2, s2, s1); - __ add(s1, s1, temp2); - __ add(s2, s2, s1); - __ add(s1, s1, temp1, Assembler::LSR, 56); - __ add(s2, s2, s1); + generate_updateBytesAdler32_accum(s1, s2, buff, temp0, temp1, + vbytes, vs1acc, vs2acc, vtable); __ subs(count, count, 16); __ br(Assembler::HS, L_nmax_loop); @@ -3400,53 +3362,8 @@ __ bind(L_by16_loop); - __ ldp(temp0, temp1, Address(__ post(buff, 16))); - - __ add(s1, s1, temp0, ext::uxtb); - __ ubfx(temp2, temp0, 8, 8); - __ add(s2, s2, s1); - __ add(s1, s1, temp2); - __ ubfx(temp2, temp0, 16, 8); - __ add(s2, s2, s1); - __ add(s1, s1, temp2); - __ ubfx(temp2, temp0, 24, 8); - __ add(s2, s2, s1); - __ add(s1, s1, temp2); - __ ubfx(temp2, temp0, 32, 8); - __ add(s2, s2, s1); - __ add(s1, s1, temp2); - __ ubfx(temp2, temp0, 40, 8); - __ add(s2, s2, s1); - __ add(s1, s1, temp2); - __ ubfx(temp2, temp0, 48, 8); - __ add(s2, s2, s1); - __ add(s1, s1, temp2); - __ add(s2, s2, s1); - __ add(s1, s1, temp0, Assembler::LSR, 56); - __ add(s2, s2, s1); - - __ add(s1, s1, temp1, ext::uxtb); - __ ubfx(temp2, temp1, 8, 8); - __ add(s2, s2, s1); - __ add(s1, s1, temp2); - __ ubfx(temp2, temp1, 16, 8); - __ add(s2, s2, s1); - __ add(s1, s1, temp2); - __ ubfx(temp2, temp1, 24, 8); - __ add(s2, s2, s1); - __ add(s1, s1, temp2); - __ ubfx(temp2, temp1, 32, 8); - __ add(s2, s2, s1); - __ add(s1, s1, temp2); - __ ubfx(temp2, temp1, 40, 8); - __ add(s2, s2, s1); - __ add(s1, s1, temp2); - __ ubfx(temp2, temp1, 48, 8); - __ add(s2, s2, s1); - __ add(s1, s1, temp2); - __ add(s2, s2, s1); - __ add(s1, s1, temp1, Assembler::LSR, 56); - __ add(s2, s2, s1); + generate_updateBytesAdler32_accum(s1, s2, buff, temp0, temp1, + vbytes, vs1acc, vs2acc, vtable); __ subs(len, len, 16); __ br(Assembler::HS, L_by16_loop); @@ -3500,6 +3417,43 @@ return start; } + void generate_updateBytesAdler32_accum(Register s1, Register s2, Register buff, + Register temp0, Register temp1, FloatRegister vbytes, + FloatRegister vs1acc, FloatRegister vs2acc, FloatRegister vtable) { + // Below is a vectorized implementation of updating s1 and s2 for 16 bytes. + // We use b1, b2, ..., b16 to denote the 16 bytes loaded in each iteration. + // In non-vectorized code, we update s1 and s2 as: + // s1 <- s1 + b1 + // s2 <- s2 + s1 + // s1 <- s1 + b2 + // s2 <- s2 + b1 + // ... + // s1 <- s1 + b16 + // s2 <- s2 + s1 + // Putting above assignments together, we have: + // s1_new = s1 + b1 + b2 + ... + b16 + // s2_new = s2 + (s1 + b1) + (s1 + b1 + b2) + ... + (s1 + b1 + b2 + ... + b16) + // = s2 + s1 * 16 + (b1 * 16 + b2 * 15 + ... + b16 * 1) + // = s2 + s1 * 16 + (b1, b2, ... b16) dot (16, 15, ... 1) + __ ld1(vbytes, __ T16B, Address(__ post(buff, 16))); + + // s2 = s2 + s1 * 16 + __ add(s2, s2, s1, Assembler::LSL, 4); + + // vs1acc = b1 + b2 + b3 + ... + b16 + // vs2acc = (b1 * 16) + (b2 * 15) + (b3 * 14) + ... + (b16 * 1) + __ umullv(vs2acc, __ T8B, vtable, vbytes); + __ umlalv(vs2acc, __ T16B, vtable, vbytes); + __ uaddlv(vs1acc, __ T16B, vbytes); + __ uaddlv(vs2acc, __ T8H, vs2acc); + + // s1 = s1 + vs1acc, s2 = s2 + vs2acc + __ fmovd(temp0, vs1acc); + __ fmovd(temp1, vs2acc); + __ add(s1, s1, temp0); + __ add(s2, s2, temp1); + } + /** * Arguments: * @@ -4846,7 +4800,7 @@ // Set up last_Java_sp and last_Java_fp address the_pc = __ pc(); - __ set_last_Java_frame(sp, rfp, (address)NULL, rscratch1); + __ set_last_Java_frame(sp, rfp, the_pc, rscratch1); // Call runtime if (arg1 != noreg) { diff -r 268875216dfc -r faf96b92a47b src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp --- a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -287,6 +287,11 @@ 0xD502ED78UL, 0xAE7D62EDUL, // byte swap of word swap }; +// Accumulation coefficients for adler32 upper 16 bits +jubyte StubRoutines::aarch64::_adler_table[] __attribute__ ((aligned(64))) = { + 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 +}; + juint StubRoutines::aarch64::_npio2_hw[] __attribute__ ((aligned(64))) = { // first, various coefficient values: 0.5, invpio2, pio2_1, pio2_1t, pio2_2, // pio2_2t, pio2_3, pio2_3t diff -r 268875216dfc -r faf96b92a47b src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp --- a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -186,6 +186,7 @@ private: static juint _crc_table[]; + static jubyte _adler_table[]; // begin trigonometric tables block. See comments in .cpp file static juint _npio2_hw[]; static jdouble _two_over_pi[]; diff -r 268875216dfc -r faf96b92a47b src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp --- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -1,6 +1,6 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, 2018, Red Hat Inc. All rights reserved. + * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Red Hat Inc. 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 @@ -1351,9 +1351,11 @@ // pass JNIEnv __ add(c_rarg0, rthread, in_bytes(JavaThread::jni_environment_offset())); - // It is enough that the pc() points into the right code - // segment. It does not have to be the correct return pc. - __ set_last_Java_frame(esp, rfp, (address)NULL, rscratch1); + // Set the last Java PC in the frame anchor to be the return address from + // the call to the native method: this will allow the debugger to + // generate an accurate stack trace. + Label native_return; + __ set_last_Java_frame(esp, rfp, native_return, rscratch1); // change thread state #ifdef ASSERT @@ -1374,6 +1376,7 @@ // Call the native method. __ blrt(r10, rscratch1); + __ bind(native_return); __ maybe_isb(); __ get_method(rmethod); // result potentially in r0 or v0 diff -r 268875216dfc -r faf96b92a47b src/hotspot/cpu/aarch64/templateTable_aarch64.cpp --- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -2981,7 +2981,7 @@ { Label notVolatile; __ tbz(r3, ConstantPoolCacheEntry::is_volatile_shift, notVolatile); - __ membar(MacroAssembler::StoreStore); + __ membar(MacroAssembler::StoreStore | MacroAssembler::LoadStore); __ bind(notVolatile); } diff -r 268875216dfc -r faf96b92a47b src/hotspot/cpu/aarch64/vm_version_aarch64.cpp --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -258,8 +258,10 @@ if (FLAG_IS_DEFAULT(UseCRC32)) { UseCRC32 = (auxv & HWCAP_CRC32) != 0; } + if (UseCRC32 && (auxv & HWCAP_CRC32) == 0) { warning("UseCRC32 specified, but not supported on this CPU"); + FLAG_SET_DEFAULT(UseCRC32, false); } if (FLAG_IS_DEFAULT(UseAdler32Intrinsics)) { @@ -277,6 +279,7 @@ } else { if (UseLSE) { warning("UseLSE specified, but not supported on this CPU"); + FLAG_SET_DEFAULT(UseLSE, false); } } @@ -291,9 +294,11 @@ } else { if (UseAES) { warning("UseAES specified, but not supported on this CPU"); + FLAG_SET_DEFAULT(UseAES, false); } if (UseAESIntrinsics) { warning("UseAESIntrinsics specified, but not supported on this CPU"); + FLAG_SET_DEFAULT(UseAESIntrinsics, false); } } diff -r 268875216dfc -r faf96b92a47b src/hotspot/cpu/x86/stubRoutines_x86.hpp --- a/src/hotspot/cpu/x86/stubRoutines_x86.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/cpu/x86/stubRoutines_x86.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -33,7 +33,7 @@ enum platform_dependent_constants { code_size1 = 20000 LP64_ONLY(+10000), // simply increase if too small (assembler will crash if too small) - code_size2 = 35300 LP64_ONLY(+10000) // simply increase if too small (assembler will crash if too small) + code_size2 = 35300 LP64_ONLY(+11000) // simply increase if too small (assembler will crash if too small) }; class x86 { diff -r 268875216dfc -r faf96b92a47b src/hotspot/os/aix/os_aix.inline.hpp --- a/src/hotspot/os/aix/os_aix.inline.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/os/aix/os_aix.inline.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -27,6 +27,7 @@ #define OS_AIX_OS_AIX_INLINE_HPP #include "runtime/os.hpp" +#include "os_posix.inline.hpp" // System includes diff -r 268875216dfc -r faf96b92a47b src/hotspot/os/bsd/os_bsd.cpp --- a/src/hotspot/os/bsd/os_bsd.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/os/bsd/os_bsd.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -37,6 +37,7 @@ #include "memory/filemap.hpp" #include "oops/oop.inline.hpp" #include "os_bsd.inline.hpp" +#include "os_posix.inline.hpp" #include "os_share_bsd.hpp" #include "prims/jniFastGetField.hpp" #include "prims/jvm_misc.hpp" diff -r 268875216dfc -r faf96b92a47b src/hotspot/os/bsd/os_bsd.inline.hpp --- a/src/hotspot/os/bsd/os_bsd.inline.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/os/bsd/os_bsd.inline.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -26,6 +26,7 @@ #define OS_BSD_OS_BSD_INLINE_HPP #include "runtime/os.hpp" +#include "os_posix.inline.hpp" // System includes diff -r 268875216dfc -r faf96b92a47b src/hotspot/os/linux/os_linux.cpp --- a/src/hotspot/os/linux/os_linux.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/os/linux/os_linux.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -38,6 +38,7 @@ #include "memory/filemap.hpp" #include "oops/oop.inline.hpp" #include "os_linux.inline.hpp" +#include "os_posix.inline.hpp" #include "os_share_linux.hpp" #include "osContainer_linux.hpp" #include "prims/jniFastGetField.hpp" @@ -1358,11 +1359,9 @@ void os::abort(bool dump_core, void* siginfo, const void* context) { os::shutdown(); if (dump_core) { -#ifndef ZERO if (DumpPrivateMappingsInCore) { ClassLoader::close_jrt_image(); } -#endif #ifndef PRODUCT fdStream out(defaultStream::output_fd()); out.print_raw("Current thread is "); @@ -1857,10 +1856,9 @@ return true; } -#if defined(S390) +#if defined(S390) || defined(PPC64) // keywords_to_match - NULL terminated array of keywords -static bool print_matching_lines_from_sysinfo_file(outputStream* st, const char* keywords_to_match[]) { - const char* filename = "/proc/sysinfo"; +static bool print_matching_lines_from_file(const char* filename, outputStream* st, const char* keywords_to_match[]) { char* line = NULL; size_t length = 0; FILE* fp = fopen(filename, "r"); @@ -2192,9 +2190,29 @@ // - whole "Box" (CPUs ) // - z/VM / KVM (VM); this is not available in an LPAR-only setup const char* kw[] = { "LPAR", "CPUs", "VM", NULL }; - - if (! print_matching_lines_from_sysinfo_file(st, kw)) { - st->print_cr(" "); + const char* info_file = "/proc/sysinfo"; + + if (!print_matching_lines_from_file(info_file, st, kw)) { + st->print_cr(" <%s Not Available>", info_file); + } +#elif defined(PPC64) + const char* info_file = "/proc/ppc64/lparcfg"; + const char* kw[] = { "system_type=", // qemu indicates PowerKVM + "partition_entitled_capacity=", // entitled processor capacity percentage + "partition_max_entitled_capacity=", + "capacity_weight=", // partition CPU weight + "partition_active_processors=", + "partition_potential_processors=", + "entitled_proc_capacity_available=", + "capped=", // 0 - uncapped, 1 - vcpus capped at entitled processor capacity percentage + "shared_processor_mode=", // (non)dedicated partition + "system_potential_processors=", + "pool=", // CPU-pool number + "pool_capacity=", + "NumLpars=", // on non-KVM machines, NumLpars is not found for full partition mode machines + NULL }; + if (!print_matching_lines_from_file(info_file, st, kw)) { + st->print_cr(" <%s Not Available>", info_file); } #endif } diff -r 268875216dfc -r faf96b92a47b src/hotspot/os/linux/os_perf_linux.cpp --- a/src/hotspot/os/linux/os_perf_linux.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/os/linux/os_perf_linux.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -1062,7 +1062,7 @@ snprintf(buf, sizeof(buf), "/sys/class/net/%s/statistics/%s", iface, counter); - int fd = open(buf, O_RDONLY); + int fd = os::open(buf, O_RDONLY, 0); if (fd == -1) { return -1; } diff -r 268875216dfc -r faf96b92a47b src/hotspot/os/linux/perfMemory_linux.cpp --- a/src/hotspot/os/linux/perfMemory_linux.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/os/linux/perfMemory_linux.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2019, 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 @@ -97,8 +97,8 @@ int result; - RESTARTABLE(::open(destfile, O_CREAT|O_WRONLY|O_TRUNC, S_IREAD|S_IWRITE), - result);; + RESTARTABLE(os::open(destfile, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR), + result); if (result == OS_ERR) { if (PrintMiscellaneous && Verbose) { warning("Could not create Perfdata save file: %s: %s\n", @@ -871,7 +871,7 @@ // Cannot use O_TRUNC here; truncation of an existing file has to happen // after the is_file_secure() check below. int result; - RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_NOFOLLOW, S_IREAD|S_IWRITE), result); + RESTARTABLE(os::open(filename, O_RDWR|O_CREAT|O_NOFOLLOW, S_IRUSR|S_IWUSR), result); if (result == OS_ERR) { if (PrintMiscellaneous && Verbose) { if (errno == ELOOP) { @@ -949,7 +949,7 @@ // open the file int result; - RESTARTABLE(::open(filename, oflags), result); + RESTARTABLE(os::open(filename, oflags, 0), result); if (result == OS_ERR) { if (errno == ENOENT) { THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), diff -r 268875216dfc -r faf96b92a47b src/hotspot/os/posix/os_posix.cpp --- a/src/hotspot/os/posix/os_posix.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/os/posix/os_posix.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -191,10 +191,6 @@ os::native_path(fullname); - sigset_t set, oldset; - int ret = sigfillset(&set); - assert_with_errno(ret == 0, "sigfillset returned error"); - // set the file creation mask. mode_t file_mode = S_IRUSR | S_IWUSR; @@ -208,7 +204,7 @@ } // delete the name from the filesystem. When 'fd' is closed, the file (and space) will be deleted. - ret = unlink(fullname); + int ret = unlink(fullname); assert_with_errno(ret == 0, "unlink returned error"); os::free(fullname); @@ -2219,22 +2215,6 @@ assert_status(status == 0, status, "mutex_destroy"); } -void os::PlatformMonitor::lock() { - int status = pthread_mutex_lock(&_mutex); - assert_status(status == 0, status, "mutex_lock"); -} - -void os::PlatformMonitor::unlock() { - int status = pthread_mutex_unlock(&_mutex); - assert_status(status == 0, status, "mutex_unlock"); -} - -bool os::PlatformMonitor::try_lock() { - int status = pthread_mutex_trylock(&_mutex); - assert_status(status == 0 || status == EBUSY, status, "mutex_trylock"); - return status == 0; -} - // Must already be locked int os::PlatformMonitor::wait(jlong millis) { assert(millis >= 0, "negative timeout"); @@ -2263,14 +2243,4 @@ } } -void os::PlatformMonitor::notify() { - int status = pthread_cond_signal(&_cond); - assert_status(status == 0, status, "cond_signal"); -} - -void os::PlatformMonitor::notify_all() { - int status = pthread_cond_broadcast(&_cond); - assert_status(status == 0, status, "cond_broadcast"); -} - #endif // !SOLARIS diff -r 268875216dfc -r faf96b92a47b src/hotspot/os/posix/os_posix.inline.hpp --- a/src/hotspot/os/posix/os_posix.inline.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/os/posix/os_posix.inline.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -42,6 +42,39 @@ inline int os::Posix::clock_getres(clockid_t clock_id, struct timespec *tp) { return _clock_getres != NULL ? _clock_getres(clock_id, tp) : -1; } + #endif // SUPPORTS_CLOCK_MONOTONIC +#ifndef SOLARIS + +// Platform Monitor implementation + +inline void os::PlatformMonitor::lock() { + int status = pthread_mutex_lock(&_mutex); + assert_status(status == 0, status, "mutex_lock"); +} + +inline void os::PlatformMonitor::unlock() { + int status = pthread_mutex_unlock(&_mutex); + assert_status(status == 0, status, "mutex_unlock"); +} + +inline bool os::PlatformMonitor::try_lock() { + int status = pthread_mutex_trylock(&_mutex); + assert_status(status == 0 || status == EBUSY, status, "mutex_trylock"); + return status == 0; +} + +inline void os::PlatformMonitor::notify() { + int status = pthread_cond_signal(&_cond); + assert_status(status == 0, status, "cond_signal"); +} + +inline void os::PlatformMonitor::notify_all() { + int status = pthread_cond_broadcast(&_cond); + assert_status(status == 0, status, "cond_broadcast"); +} + +#endif // !SOLARIS + #endif // OS_POSIX_OS_POSIX_INLINE_HPP diff -r 268875216dfc -r faf96b92a47b src/hotspot/os/solaris/os_perf_solaris.cpp --- a/src/hotspot/os/solaris/os_perf_solaris.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/os/solaris/os_perf_solaris.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -74,7 +74,7 @@ int fd = -1; - if ((fd = open(path, O_RDONLY)) < 0) { + if ((fd = os::open(path, O_RDONLY, 0)) < 0) { return OS_ERR; } if (pread(fd, info, s, o) != s) { diff -r 268875216dfc -r faf96b92a47b src/hotspot/os/windows/os_windows.cpp --- a/src/hotspot/os/windows/os_windows.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/os/windows/os_windows.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -602,7 +602,7 @@ HANDLE interrupt_event = CreateEvent(NULL, true, false, NULL); if (interrupt_event == NULL) { delete osthread; - return NULL; + return false; } osthread->set_interrupt_event(interrupt_event); osthread->set_interrupted(false); @@ -676,7 +676,7 @@ CloseHandle(osthread->interrupt_event()); thread->set_osthread(NULL); delete osthread; - return NULL; + return false; } Atomic::inc(&os::win32::_os_thread_count); @@ -5320,27 +5320,6 @@ // Platform Monitor implementation -os::PlatformMonitor::PlatformMonitor() { - InitializeConditionVariable(&_cond); - InitializeCriticalSection(&_mutex); -} - -os::PlatformMonitor::~PlatformMonitor() { - DeleteCriticalSection(&_mutex); -} - -void os::PlatformMonitor::lock() { - EnterCriticalSection(&_mutex); -} - -void os::PlatformMonitor::unlock() { - LeaveCriticalSection(&_mutex); -} - -bool os::PlatformMonitor::try_lock() { - return TryEnterCriticalSection(&_mutex); -} - // Must already be locked int os::PlatformMonitor::wait(jlong millis) { assert(millis >= 0, "negative timeout"); @@ -5359,14 +5338,6 @@ return ret; } -void os::PlatformMonitor::notify() { - WakeConditionVariable(&_cond); -} - -void os::PlatformMonitor::notify_all() { - WakeAllConditionVariable(&_cond); -} - // Run the specified command in a separate process. Return its exit value, // or -1 on failure (e.g. can't create a new process). int os::fork_and_exec(char* cmd, bool use_vfork_if_available) { diff -r 268875216dfc -r faf96b92a47b src/hotspot/os/windows/os_windows.inline.hpp --- a/src/hotspot/os/windows/os_windows.inline.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/os/windows/os_windows.inline.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -86,4 +86,35 @@ win32::exit_process_or_thread(win32::EPT_PROCESS, num); } +// Platform Monitor implementation + +inline os::PlatformMonitor::PlatformMonitor() { + InitializeConditionVariable(&_cond); + InitializeCriticalSection(&_mutex); +} + +inline os::PlatformMonitor::~PlatformMonitor() { + DeleteCriticalSection(&_mutex); +} + +inline void os::PlatformMonitor::lock() { + EnterCriticalSection(&_mutex); +} + +inline void os::PlatformMonitor::unlock() { + LeaveCriticalSection(&_mutex); +} + +inline bool os::PlatformMonitor::try_lock() { + return TryEnterCriticalSection(&_mutex); +} + +inline void os::PlatformMonitor::notify() { + WakeConditionVariable(&_cond); +} + +inline void os::PlatformMonitor::notify_all() { + WakeAllConditionVariable(&_cond); +} + #endif // OS_WINDOWS_OS_WINDOWS_INLINE_HPP diff -r 268875216dfc -r faf96b92a47b src/hotspot/os_cpu/linux_x86/gc/z/zBackingFile_linux_x86.cpp --- a/src/hotspot/os_cpu/linux_x86/gc/z/zBackingFile_linux_x86.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/os_cpu/linux_x86/gc/z/zBackingFile_linux_x86.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, 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 @@ -191,7 +191,7 @@ // Try to create an anonymous file using the O_TMPFILE flag. Note that this // flag requires kernel >= 3.11. If this fails we fall back to open/unlink. - const int fd_anon = open(path.get(), O_TMPFILE|O_EXCL|O_RDWR|O_CLOEXEC, S_IRUSR|S_IWUSR); + const int fd_anon = os::open(path.get(), O_TMPFILE|O_EXCL|O_RDWR|O_CLOEXEC, S_IRUSR|S_IWUSR); if (fd_anon == -1) { ZErrno err; log_debug(gc, init)("Failed to create anonymous file in %s (%s)", path.get(), @@ -217,7 +217,7 @@ snprintf(filename, sizeof(filename), "%s/%s.%d", path.get(), name, os::current_process_id()); // Create file - const int fd = open(filename, O_CREAT|O_EXCL|O_RDWR|O_CLOEXEC, S_IRUSR|S_IWUSR); + const int fd = os::open(filename, O_CREAT|O_EXCL|O_RDWR|O_CLOEXEC, S_IRUSR|S_IWUSR); if (fd == -1) { ZErrno err; log_error(gc, init)("Failed to create file %s (%s)", filename, err.to_string()); diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/ci/ciEnv.cpp --- a/src/hotspot/share/ci/ciEnv.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/ci/ciEnv.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -1253,7 +1253,7 @@ static char buffer[O_BUFLEN]; int ret = jio_snprintf(buffer, O_BUFLEN, "replay_pid%p_compid%d.log", os::current_process_id(), compile_id); if (ret > 0) { - int fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666); + int fd = os::open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666); if (fd != -1) { FILE* replay_data_file = os::open(fd, "w"); if (replay_data_file != NULL) { @@ -1271,7 +1271,7 @@ static char buffer[O_BUFLEN]; int ret = jio_snprintf(buffer, O_BUFLEN, "inline_pid%p_compid%d.log", os::current_process_id(), compile_id); if (ret > 0) { - int fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666); + int fd = os::open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666); if (fd != -1) { FILE* inline_data_file = os::open(fd, "w"); if (inline_data_file != NULL) { diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/classfile/classFileParser.cpp --- a/src/hotspot/share/classfile/classFileParser.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/classfile/classFileParser.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -60,6 +60,7 @@ #include "runtime/arguments.hpp" #include "runtime/handles.inline.hpp" #include "runtime/javaCalls.hpp" +#include "runtime/os.hpp" #include "runtime/perfData.hpp" #include "runtime/reflection.hpp" #include "runtime/safepointVerifiers.hpp" @@ -5747,8 +5748,8 @@ int class_name_len = _class_name->utf8_length(); int symbol_len = host_pkg_len + 1 + class_name_len; char* new_anon_name = NEW_RESOURCE_ARRAY(char, symbol_len + 1); - int n = snprintf(new_anon_name, symbol_len + 1, "%s/%.*s", - host_pkg_name, class_name_len, _class_name->base()); + int n = os::snprintf(new_anon_name, symbol_len + 1, "%s/%.*s", + host_pkg_name, class_name_len, _class_name->base()); assert(n == symbol_len, "Unexpected number of characters in string"); // Decrement old _class_name to avoid leaking. diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/classfile/classLoader.cpp --- a/src/hotspot/share/classfile/classLoader.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/classfile/classLoader.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -620,13 +620,14 @@ update_module_path_entry_list(path, THREAD); } +#endif // INCLUDE_CDS + void ClassLoader::close_jrt_image() { - assert(ClassLoader::has_jrt_entry(), "Not applicable for exploded builds"); + // Not applicable for exploded builds + if (!ClassLoader::has_jrt_entry()) return; _jrt_entry->close_jimage(); } -#endif // INCLUDE_CDS - // Construct the array of module/path pairs as specified to --patch-module // for the boot loader to search ahead of the jimage, if the class being // loaded is defined to a module that has been specified to --patch-module. diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/classfile/classLoaderExt.cpp --- a/src/hotspot/share/classfile/classLoaderExt.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/classfile/classLoaderExt.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -208,7 +208,7 @@ ResourceMark rm(THREAD); size_t libname_len = dir_len + name_len; char* libname = NEW_RESOURCE_ARRAY(char, libname_len + 1); - int n = snprintf(libname, libname_len + 1, "%.*s%s", dir_len, dir_name, file_start); + int n = os::snprintf(libname, libname_len + 1, "%.*s%s", dir_len, dir_name, file_start); assert((size_t)n == libname_len, "Unexpected number of characters in string"); trace_class_path("library = ", libname); ClassLoader::update_class_path_entry_list(libname, true, false); diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/classfile/compactHashtable.cpp --- a/src/hotspot/share/classfile/compactHashtable.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/classfile/compactHashtable.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2019, 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 @@ -198,7 +198,7 @@ quit("Unable to get hashtable dump file size", filename); } _size = st.st_size; - _fd = open(filename, O_RDONLY | O_BINARY, 0); + _fd = os::open(filename, O_RDONLY | O_BINARY, 0); if (_fd < 0) { quit("Unable to open hashtable dump file", filename); } diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/classfile/dictionary.cpp --- a/src/hotspot/share/classfile/dictionary.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/classfile/dictionary.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -24,7 +24,7 @@ #include "precompiled.hpp" #include "classfile/classLoaderData.inline.hpp" -#include "classfile/dictionary.inline.hpp" +#include "classfile/dictionary.hpp" #include "classfile/protectionDomainCache.hpp" #include "classfile/systemDictionary.hpp" #include "logging/log.hpp" @@ -35,6 +35,7 @@ #include "oops/oop.inline.hpp" #include "runtime/atomic.hpp" #include "runtime/orderAccess.hpp" +#include "runtime/mutexLocker.hpp" #include "runtime/safepointVerifiers.hpp" #include "utilities/hashtable.inline.hpp" @@ -80,6 +81,8 @@ void Dictionary::free_entry(DictionaryEntry* entry) { // avoid recursion when deleting linked list // pd_set is accessed during a safepoint. + // This doesn't require a lock because nothing is reading this + // entry anymore. The ClassLoader is dead. while (entry->pd_set() != NULL) { ProtectionDomainEntry* to_delete = entry->pd_set(); entry->set_pd_set(to_delete->next()); @@ -146,11 +149,14 @@ } bool DictionaryEntry::contains_protection_domain(oop protection_domain) const { + // Lock the pd_set list. This lock cannot safepoint since the caller holds + // a Dictionary entry, which can be moved if the Dictionary is resized. + MutexLockerEx ml(ProtectionDomainSet_lock, Mutex::_no_safepoint_check_flag); #ifdef ASSERT if (oopDesc::equals(protection_domain, instance_klass()->protection_domain())) { // Ensure this doesn't show up in the pd_set (invariant) bool in_pd_set = false; - for (ProtectionDomainEntry* current = pd_set_acquire(); + for (ProtectionDomainEntry* current = pd_set(); current != NULL; current = current->next()) { if (oopDesc::equals(current->object_no_keepalive(), protection_domain)) { @@ -170,7 +176,7 @@ return true; } - for (ProtectionDomainEntry* current = pd_set_acquire(); + for (ProtectionDomainEntry* current = pd_set(); current != NULL; current = current->next()) { if (oopDesc::equals(current->object_no_keepalive(), protection_domain)) return true; @@ -183,13 +189,12 @@ assert_locked_or_safepoint(SystemDictionary_lock); if (!contains_protection_domain(protection_domain())) { ProtectionDomainCacheEntry* entry = SystemDictionary::cache_get(protection_domain); + // The pd_set in the dictionary entry is protected by a low level lock. + // With concurrent PD table cleanup, these links could be broken. + MutexLockerEx ml(ProtectionDomainSet_lock, Mutex::_no_safepoint_check_flag); ProtectionDomainEntry* new_head = new ProtectionDomainEntry(entry, pd_set()); - // Warning: Preserve store ordering. The SystemDictionary is read - // without locks. The new ProtectionDomainEntry must be - // complete before other threads can be allowed to see it - // via a store to _pd_set. - release_set_pd_set(new_head); + set_pd_set(new_head); } LogTarget(Trace, protectiondomain) lt; if (lt.is_enabled()) { @@ -348,6 +353,56 @@ return entry->is_valid_protection_domain(protection_domain); } +// During class loading we may have cached a protection domain that has +// since been unreferenced, so this entry should be cleared. +void Dictionary::clean_cached_protection_domains() { + assert_locked_or_safepoint(SystemDictionary_lock); + + if (loader_data()->is_the_null_class_loader_data()) { + // Classes in the boot loader are not loaded with protection domains + return; + } + + for (int index = 0; index < table_size(); index++) { + for (DictionaryEntry* probe = bucket(index); + probe != NULL; + probe = probe->next()) { + Klass* e = probe->instance_klass(); + + MutexLockerEx ml(ProtectionDomainSet_lock, Mutex::_no_safepoint_check_flag); + ProtectionDomainEntry* current = probe->pd_set(); + ProtectionDomainEntry* prev = NULL; + while (current != NULL) { + if (current->object_no_keepalive() == NULL) { + LogTarget(Debug, protectiondomain) lt; + if (lt.is_enabled()) { + ResourceMark rm; + // Print out trace information + LogStream ls(lt); + ls.print_cr("PD in set is not alive:"); + ls.print("class loader: "); loader_data()->class_loader()->print_value_on(&ls); + ls.print(" loading: "); probe->instance_klass()->print_value_on(&ls); + ls.cr(); + } + if (probe->pd_set() == current) { + probe->set_pd_set(current->next()); + } else { + assert(prev != NULL, "should be set by alive entry"); + prev->set_next(current->next()); + } + ProtectionDomainEntry* to_delete = current; + current = current->next(); + delete to_delete; + } else { + prev = current; + current = current->next(); + } + } + } + } +} + + SymbolPropertyTable::SymbolPropertyTable(int table_size) : Hashtable(table_size, sizeof(SymbolPropertyEntry)) { @@ -404,6 +459,25 @@ } } +void DictionaryEntry::verify_protection_domain_set() { + MutexLockerEx ml(ProtectionDomainSet_lock, Mutex::_no_safepoint_check_flag); + for (ProtectionDomainEntry* current = pd_set(); // accessed at a safepoint + current != NULL; + current = current->_next) { + guarantee(oopDesc::is_oop_or_null(current->_pd_cache->object_no_keepalive()), "Invalid oop"); + } +} + +void DictionaryEntry::print_count(outputStream *st) { + MutexLockerEx ml(ProtectionDomainSet_lock, Mutex::_no_safepoint_check_flag); + int count = 0; + for (ProtectionDomainEntry* current = pd_set(); // accessed inside SD lock + current != NULL; + current = current->_next) { + count++; + } + st->print_cr("pd set count = #%d", count); +} // ---------------------------------------------------------------------------- diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/classfile/dictionary.hpp --- a/src/hotspot/share/classfile/dictionary.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/classfile/dictionary.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -59,8 +59,6 @@ static bool does_any_dictionary_needs_resizing(); bool resize_if_needed(); - DictionaryEntry* new_entry(unsigned int hash, InstanceKlass* klass); - void add_klass(unsigned int hash, Symbol* class_name, InstanceKlass* obj); InstanceKlass* find_class(int index, unsigned int hash, Symbol* name); @@ -70,7 +68,7 @@ void all_entries_do(KlassClosure* closure); void classes_do(MetaspaceClosure* it); - void unlink(); + void clean_cached_protection_domains(); // Protection domains InstanceKlass* find(unsigned int hash, Symbol* name, Handle protection_domain); @@ -83,6 +81,10 @@ void print_on(outputStream* st) const; void verify(); + + private: + DictionaryEntry* new_entry(unsigned int hash, InstanceKlass* klass); + DictionaryEntry* bucket(int i) const { return (DictionaryEntry*)Hashtable::bucket(i); } @@ -151,9 +153,6 @@ ProtectionDomainEntry* pd_set() const { return _pd_set; } void set_pd_set(ProtectionDomainEntry* new_head) { _pd_set = new_head; } - ProtectionDomainEntry* pd_set_acquire() const; - void release_set_pd_set(ProtectionDomainEntry* new_head); - // Tells whether the initiating class' protection domain can access the klass in this entry bool is_valid_protection_domain(Handle protection_domain) { if (!ProtectionDomainVerification) return true; @@ -164,29 +163,14 @@ : contains_protection_domain(protection_domain()); } - void verify_protection_domain_set() { - for (ProtectionDomainEntry* current = pd_set(); // accessed at a safepoint - current != NULL; - current = current->_next) { - guarantee(oopDesc::is_oop_or_null(current->_pd_cache->object_no_keepalive()), "Invalid oop"); - } - } + void verify_protection_domain_set(); bool equals(const Symbol* class_name) const { InstanceKlass* klass = (InstanceKlass*)literal(); return (klass->name() == class_name); } - void print_count(outputStream *st) { - int count = 0; - for (ProtectionDomainEntry* current = pd_set(); // accessed inside SD lock - current != NULL; - current = current->_next) { - count++; - } - st->print_cr("pd set count = #%d", count); - } - + void print_count(outputStream *st); void verify(); }; diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/classfile/dictionary.inline.hpp --- a/src/hotspot/share/classfile/dictionary.inline.hpp Mon Feb 25 15:15:46 2019 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2018, 2019, 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. - * - */ - -#ifndef SHARE_CLASSFILE_DICTIONARY_INLINE_HPP -#define SHARE_CLASSFILE_DICTIONARY_INLINE_HPP - -#include "classfile/dictionary.hpp" -#include "runtime/orderAccess.hpp" - -inline ProtectionDomainEntry* DictionaryEntry::pd_set_acquire() const { - return OrderAccess::load_acquire(&_pd_set); -} - -inline void DictionaryEntry::release_set_pd_set(ProtectionDomainEntry* new_head) { - OrderAccess::release_store(&_pd_set, new_head); -} - -#endif // SHARE_CLASSFILE_DICTIONARY_INLINE_HPP diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/classfile/javaClasses.cpp --- a/src/hotspot/share/classfile/javaClasses.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/classfile/javaClasses.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -3635,7 +3635,7 @@ // distinct loaders) to ensure the metadata is kept alive. // This mirror may be different than the one in clazz field. new_resolved_method->obj_field_put(_vmholder_offset, m->method_holder()->java_mirror()); - resolved_method = ResolvedMethodTable::add_method(Handle(THREAD, new_resolved_method)); + resolved_method = ResolvedMethodTable::add_method(m, Handle(THREAD, new_resolved_method)); } return resolved_method; } diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/classfile/protectionDomainCache.cpp --- a/src/hotspot/share/classfile/protectionDomainCache.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/classfile/protectionDomainCache.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, 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 @@ -23,6 +23,8 @@ */ #include "precompiled.hpp" +#include "classfile/classLoaderDataGraph.hpp" +#include "classfile/dictionary.hpp" #include "classfile/protectionDomainCache.hpp" #include "classfile/systemDictionary.hpp" #include "logging/log.hpp" @@ -54,7 +56,27 @@ Service_lock->notify_all(); } +class CleanProtectionDomainEntries : public CLDClosure { + void do_cld(ClassLoaderData* data) { + Dictionary* dictionary = data->dictionary(); + if (dictionary != NULL) { + dictionary->clean_cached_protection_domains(); + } + } +}; + void ProtectionDomainCacheTable::unlink() { + { + // First clean cached pd lists in loaded CLDs + // It's unlikely, but some loaded classes in a dictionary might + // point to a protection_domain that has been unloaded. + // The dictionary pd_set points at entries in the ProtectionDomainCacheTable. + MutexLocker ml(ClassLoaderDataGraph_lock); + MutexLocker mldict(SystemDictionary_lock); // need both. + CleanProtectionDomainEntries clean; + ClassLoaderDataGraph::loaded_cld_do(&clean); + } + MutexLocker ml(SystemDictionary_lock); int oops_removed = 0; for (int i = 0; i < table_size(); ++i) { diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/classfile/symbolTable.cpp --- a/src/hotspot/share/classfile/symbolTable.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/classfile/symbolTable.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -436,18 +436,16 @@ } } -void SymbolTable::add(ClassLoaderData* loader_data, const constantPoolHandle& cp, - int names_count, const char** names, int* lengths, - int* cp_indices, unsigned int* hashValues, TRAPS) { +void SymbolTable::new_symbols(ClassLoaderData* loader_data, const constantPoolHandle& cp, + int names_count, const char** names, int* lengths, + int* cp_indices, unsigned int* hashValues, TRAPS) { bool c_heap = !loader_data->is_the_null_class_loader_data(); for (int i = 0; i < names_count; i++) { const char *name = names[i]; int len = lengths[i]; unsigned int hash = hashValues[i]; - Symbol* sym = SymbolTable::the_table()->lookup_common(name, len, hash); - if (sym == NULL) { - sym = SymbolTable::the_table()->do_add_if_needed(name, len, hash, c_heap, CHECK); - } + assert(SymbolTable::the_table()->lookup_shared(name, len, hash) == NULL, "must have checked already"); + Symbol* sym = SymbolTable::the_table()->do_add_if_needed(name, len, hash, c_heap, CHECK); assert(sym->refcount() != 0, "lookup should have incremented the count"); cp->symbol_at_put(cp_indices[i], sym); } diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/classfile/symbolTable.hpp --- a/src/hotspot/share/classfile/symbolTable.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/classfile/symbolTable.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -144,18 +144,11 @@ Symbol* do_add_if_needed(const char* name, int len, uintx hash, bool heap, TRAPS); // Adding elements - static void add(ClassLoaderData* loader_data, - const constantPoolHandle& cp, int names_count, - const char** names, int* lengths, int* cp_indices, - unsigned int* hashValues, TRAPS); - static void new_symbols(ClassLoaderData* loader_data, const constantPoolHandle& cp, int names_count, const char** name, int* lengths, int* cp_indices, unsigned int* hashValues, - TRAPS) { - add(loader_data, cp, names_count, name, lengths, cp_indices, hashValues, THREAD); - } + TRAPS); static Symbol* lookup_shared(const char* name, int len, unsigned int hash); Symbol* lookup_dynamic(const char* name, int len, unsigned int hash); diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/classfile/verifier.cpp --- a/src/hotspot/share/classfile/verifier.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/classfile/verifier.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -2982,14 +2982,14 @@ // add one dimension to component length++; arr_sig_str = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, length + 1); - int n = snprintf(arr_sig_str, length + 1, "[%s", component_name); + int n = os::snprintf(arr_sig_str, length + 1, "[%s", component_name); assert(n == length, "Unexpected number of characters in string"); } else { // it's an object or interface const char* component_name = component_type.name()->as_utf8(); // add one dimension to component with 'L' prepended and ';' postpended. length = (int)strlen(component_name) + 3; arr_sig_str = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, length + 1); - int n = snprintf(arr_sig_str, length + 1, "[L%s;", component_name); + int n = os::snprintf(arr_sig_str, length + 1, "[L%s;", component_name); assert(n == length, "Unexpected number of characters in string"); } Symbol* arr_sig = create_temporary_symbol( diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/code/nmethod.cpp --- a/src/hotspot/share/code/nmethod.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/code/nmethod.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -1370,6 +1370,8 @@ assert(_speculation_log == NULL, "should have been nulled out when transitioned to zombie"); #endif + Universe::heap()->flush_nmethod(this); + CodeBlob::flush(); CodeCache::free(this); } diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/gc/g1/g1RemSet.cpp --- a/src/hotspot/share/gc/g1/g1RemSet.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/gc/g1/g1RemSet.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -48,7 +48,6 @@ #include "runtime/os.hpp" #include "utilities/align.hpp" #include "utilities/globalDefinitions.hpp" -#include "utilities/intHisto.hpp" #include "utilities/stack.inline.hpp" #include "utilities/ticks.hpp" diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/gc/shared/collectedHeap.hpp --- a/src/hotspot/share/gc/shared/collectedHeap.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/gc/shared/collectedHeap.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -521,6 +521,7 @@ // Override with specific mechanism for each specialized heap type. virtual void register_nmethod(nmethod* nm) {} virtual void unregister_nmethod(nmethod* nm) {} + virtual void flush_nmethod(nmethod* nm) {} virtual void verify_nmethod(nmethod* nmethod) {} void trace_heap_before_gc(const GCTracer* gc_tracer); diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -482,7 +482,9 @@ class ShenandoahInitGCLABClosure : public ThreadClosure { public: void do_thread(Thread* thread) { - if (thread != NULL && (thread->is_Java_thread() || thread->is_Worker_thread())) { + assert(thread != NULL, "Sanity"); + assert(!thread->is_Java_thread(), "Don't expect JavaThread this early"); + if (thread->is_Worker_thread()) { ShenandoahThreadLocalData::initialize_gclab(thread); } } @@ -494,8 +496,6 @@ ShenandoahInitGCLABClosure init_gclabs; Threads::threads_do(&init_gclabs); - _workers->threads_do(&init_gclabs); - _safepoint_workers->threads_do(&init_gclabs); // gclab can not be initialized early during VM startup, as it can not determinate its max_size. // Now, we will let WorkGang to initialize gclab when new worker is created. diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp --- a/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/gc/shenandoah/shenandoahThreadLocalData.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Red Hat, Inc. All rights reserved. + * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved. * * 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 @@ -122,6 +122,7 @@ static void initialize_gclab(Thread* thread) { assert (thread->is_Java_thread() || thread->is_Worker_thread(), "Only Java and GC worker threads are allowed to get GCLABs"); + assert(data(thread)->_gclab == NULL, "Only initialize once"); data(thread)->_gclab = new PLAB(PLAB::min_size()); data(thread)->_gclab_size = 0; } diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/gc/z/zBarrierSetNMethod.cpp --- a/src/hotspot/share/gc/z/zBarrierSetNMethod.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/gc/z/zBarrierSetNMethod.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -27,12 +27,12 @@ #include "gc/z/zGlobals.hpp" #include "gc/z/zLock.inline.hpp" #include "gc/z/zOopClosures.hpp" -#include "gc/z/zNMethodTable.hpp" +#include "gc/z/zNMethod.hpp" #include "gc/z/zThreadLocalData.hpp" #include "logging/log.hpp" bool ZBarrierSetNMethod::nmethod_entry_barrier(nmethod* nm) { - ZLocker locker(ZNMethodTable::lock_for_nmethod(nm)); + ZLocker locker(ZNMethod::lock_for_nmethod(nm)); log_trace(nmethod, barrier)("Entered critical zone for %p", nm); if (!is_armed(nm)) { diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/gc/z/zCollectedHeap.cpp --- a/src/hotspot/share/gc/z/zCollectedHeap.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/gc/z/zCollectedHeap.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -27,7 +27,7 @@ #include "gc/z/zCollectedHeap.hpp" #include "gc/z/zGlobals.hpp" #include "gc/z/zHeap.inline.hpp" -#include "gc/z/zNMethodTable.hpp" +#include "gc/z/zNMethod.hpp" #include "gc/z/zServiceability.hpp" #include "gc/z/zStat.hpp" #include "gc/z/zUtils.inline.hpp" @@ -255,11 +255,15 @@ } void ZCollectedHeap::register_nmethod(nmethod* nm) { - ZNMethodTable::register_nmethod(nm); + ZNMethod::register_nmethod(nm); } void ZCollectedHeap::unregister_nmethod(nmethod* nm) { - ZNMethodTable::unregister_nmethod(nm); + ZNMethod::unregister_nmethod(nm); +} + +void ZCollectedHeap::flush_nmethod(nmethod* nm) { + ZNMethod::flush_nmethod(nm); } void ZCollectedHeap::verify_nmethod(nmethod* nm) { diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/gc/z/zCollectedHeap.hpp --- a/src/hotspot/share/gc/z/zCollectedHeap.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/gc/z/zCollectedHeap.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -105,6 +105,7 @@ virtual void register_nmethod(nmethod* nm); virtual void unregister_nmethod(nmethod* nm); + virtual void flush_nmethod(nmethod* nm); virtual void verify_nmethod(nmethod* nmethod); virtual WorkGang* get_safepoint_workers(); diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/gc/z/zNMethod.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/gc/z/zNMethod.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -0,0 +1,386 @@ +/* + * Copyright (c) 2017, 2018, 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. + */ + +#include "precompiled.hpp" +#include "code/relocInfo.hpp" +#include "code/nmethod.hpp" +#include "code/icBuffer.hpp" +#include "gc/shared/barrierSet.hpp" +#include "gc/shared/barrierSetNMethod.hpp" +#include "gc/z/zGlobals.hpp" +#include "gc/z/zLock.inline.hpp" +#include "gc/z/zNMethod.hpp" +#include "gc/z/zNMethodData.hpp" +#include "gc/z/zNMethodTable.hpp" +#include "gc/z/zOopClosures.inline.hpp" +#include "gc/z/zTask.hpp" +#include "gc/z/zWorkers.hpp" +#include "logging/log.hpp" +#include "memory/allocation.inline.hpp" +#include "memory/iterator.hpp" +#include "memory/resourceArea.hpp" +#include "runtime/atomic.hpp" +#include "runtime/orderAccess.hpp" +#include "utilities/debug.hpp" + +static ZNMethodData* gc_data(const nmethod* nm) { + return nm->gc_data(); +} + +static void set_gc_data(nmethod* nm, ZNMethodData* data) { + return nm->set_gc_data(data); +} + +void ZNMethod::attach_gc_data(nmethod* nm) { + GrowableArray immediate_oops; + bool non_immediate_oops = false; + + // Find all oops relocations + RelocIterator iter(nm); + while (iter.next()) { + if (iter.type() != relocInfo::oop_type) { + // Not an oop + continue; + } + + oop_Relocation* r = iter.oop_reloc(); + + if (!r->oop_is_immediate()) { + // Non-immediate oop found + non_immediate_oops = true; + continue; + } + + if (r->oop_value() != NULL) { + // Non-NULL immediate oop found. NULL oops can safely be + // ignored since the method will be re-registered if they + // are later patched to be non-NULL. + immediate_oops.push(r->oop_addr()); + } + } + + // Attach GC data to nmethod + ZNMethodData* data = gc_data(nm); + if (data == NULL) { + data = new ZNMethodData(); + set_gc_data(nm, data); + } + + // Attach oops in GC data + ZNMethodDataOops* const new_oops = ZNMethodDataOops::create(immediate_oops, non_immediate_oops); + ZNMethodDataOops* const old_oops = data->swap_oops(new_oops); + ZNMethodDataOops::destroy(old_oops); +} + +ZReentrantLock* ZNMethod::lock_for_nmethod(nmethod* nm) { + return gc_data(nm)->lock(); +} + +void ZNMethod::log_register(const nmethod* nm) { + LogTarget(Trace, gc, nmethod) log; + if (!log.is_enabled()) { + return; + } + + const ZNMethodDataOops* const oops = gc_data(nm)->oops(); + + log.print("Register NMethod: %s.%s (" PTR_FORMAT "), " + "Compiler: %s, Oops: %d, ImmediateOops: " SIZE_FORMAT ", NonImmediateOops: %s", + nm->method()->method_holder()->external_name(), + nm->method()->name()->as_C_string(), + p2i(nm), + nm->compiler_name(), + nm->oops_count() - 1, + oops->immediates_count(), + oops->has_non_immediates() ? "Yes" : "No"); + + LogTarget(Trace, gc, nmethod, oops) log_oops; + if (!log_oops.is_enabled()) { + return; + } + + // Print nmethod oops table + { + oop* const begin = nm->oops_begin(); + oop* const end = nm->oops_end(); + for (oop* p = begin; p < end; p++) { + log_oops.print(" Oop[" SIZE_FORMAT "] " PTR_FORMAT " (%s)", + (p - begin), p2i(*p), (*p)->klass()->external_name()); + } + } + + // Print nmethod immediate oops + { + oop** const begin = oops->immediates_begin(); + oop** const end = oops->immediates_end(); + for (oop** p = begin; p < end; p++) { + log_oops.print(" ImmediateOop[" SIZE_FORMAT "] " PTR_FORMAT " @ " PTR_FORMAT " (%s)", + (p - begin), p2i(**p), p2i(*p), (**p)->klass()->external_name()); + } + } +} + +void ZNMethod::log_unregister(const nmethod* nm) { + LogTarget(Debug, gc, nmethod) log; + if (!log.is_enabled()) { + return; + } + + log.print("Unregister NMethod: %s.%s (" PTR_FORMAT ")", + nm->method()->method_holder()->external_name(), + nm->method()->name()->as_C_string(), + p2i(nm)); +} + +void ZNMethod::register_nmethod(nmethod* nm) { + ResourceMark rm; + + // Create and attach gc data + attach_gc_data(nm); + + log_register(nm); + + ZNMethodTable::register_nmethod(nm); + + // Disarm nmethod entry barrier + disarm_nmethod(nm); +} + +void ZNMethod::unregister_nmethod(nmethod* nm) { + assert(CodeCache_lock->owned_by_self(), "Lock must be held"); + + if (Thread::current()->is_Code_cache_sweeper_thread()) { + // The sweeper must wait for any ongoing iteration to complete + // before it can unregister an nmethod. + ZNMethodTable::wait_until_iteration_done(); + } + + ResourceMark rm; + + log_unregister(nm); + + ZNMethodTable::unregister_nmethod(nm); +} + +void ZNMethod::flush_nmethod(nmethod* nm) { + // Destroy GC data + delete gc_data(nm); +} + +void ZNMethod::disarm_nmethod(nmethod* nm) { + BarrierSetNMethod* const bs = BarrierSet::barrier_set()->barrier_set_nmethod(); + if (bs != NULL) { + bs->disarm(nm); + } +} + +void ZNMethod::nmethod_oops_do(nmethod* nm, OopClosure* cl) { + // Process oops table + { + oop* const begin = nm->oops_begin(); + oop* const end = nm->oops_end(); + for (oop* p = begin; p < end; p++) { + if (*p != Universe::non_oop_word()) { + cl->do_oop(p); + } + } + } + + ZNMethodDataOops* const oops = gc_data(nm)->oops(); + + // Process immediate oops + { + oop** const begin = oops->immediates_begin(); + oop** const end = oops->immediates_end(); + for (oop** p = begin; p < end; p++) { + if (**p != Universe::non_oop_word()) { + cl->do_oop(*p); + } + } + } + + // Process non-immediate oops + if (oops->has_non_immediates()) { + nm->fix_oop_relocations(); + } +} + +class ZNMethodToOopsDoClosure : public NMethodClosure { +private: + OopClosure* _cl; + +public: + ZNMethodToOopsDoClosure(OopClosure* cl) : + _cl(cl) {} + + virtual void do_nmethod(nmethod* nm) { + ZNMethod::nmethod_oops_do(nm, _cl); + } +}; + +void ZNMethod::oops_do_begin() { + ZNMethodTable::nmethods_do_begin(); +} + +void ZNMethod::oops_do_end() { + ZNMethodTable::nmethods_do_end(); +} + +void ZNMethod::oops_do(OopClosure* cl) { + ZNMethodToOopsDoClosure nmethod_cl(cl); + ZNMethodTable::nmethods_do(&nmethod_cl); +} + +class ZNMethodUnlinkClosure : public NMethodClosure { +private: + bool _unloading_occurred; + volatile bool _failed; + + void set_failed() { + Atomic::store(true, &_failed); + } + +public: + ZNMethodUnlinkClosure(bool unloading_occurred) : + _unloading_occurred(unloading_occurred), + _failed(false) {} + + virtual void do_nmethod(nmethod* nm) { + if (failed()) { + return; + } + + if (!nm->is_alive()) { + return; + } + + ZLocker locker(ZNMethod::lock_for_nmethod(nm)); + + if (nm->is_unloading()) { + // Unlinking of the dependencies must happen before the + // handshake separating unlink and purge. + nm->flush_dependencies(false /* delete_immediately */); + + // We don't need to take the lock when unlinking nmethods from + // the Method, because it is only concurrently unlinked by + // the entry barrier, which acquires the per nmethod lock. + nm->unlink_from_method(false /* acquire_lock */); + return; + } + + // Heal oops and disarm + ZNMethodOopClosure cl; + ZNMethod::nmethod_oops_do(nm, &cl); + ZNMethod::disarm_nmethod(nm); + + // Clear compiled ICs and exception caches + if (!nm->unload_nmethod_caches(_unloading_occurred)) { + set_failed(); + } + } + + bool failed() const { + return Atomic::load(&_failed); + } +}; + +class ZNMethodUnlinkTask : public ZTask { +private: + ZNMethodUnlinkClosure _cl; + ICRefillVerifier* _verifier; + +public: + ZNMethodUnlinkTask(bool unloading_occurred, ICRefillVerifier* verifier) : + ZTask("ZNMethodUnlinkTask"), + _cl(unloading_occurred), + _verifier(verifier) { + ZNMethodTable::nmethods_do_begin(); + } + + ~ZNMethodUnlinkTask() { + ZNMethodTable::nmethods_do_end(); + } + + virtual void work() { + ICRefillVerifierMark mark(_verifier); + ZNMethodTable::nmethods_do(&_cl); + } + + bool success() const { + return !_cl.failed(); + } +}; + +void ZNMethod::unlink(ZWorkers* workers, bool unloading_occurred) { + for (;;) { + ICRefillVerifier verifier; + + { + ZNMethodUnlinkTask task(unloading_occurred, &verifier); + workers->run_concurrent(&task); + if (task.success()) { + return; + } + } + + // Cleaning failed because we ran out of transitional IC stubs, + // so we have to refill and try again. Refilling requires taking + // a safepoint, so we temporarily leave the suspendible thread set. + SuspendibleThreadSetLeaver sts; + InlineCacheBuffer::refill_ic_stubs(); + } +} + +class ZNMethodPurgeClosure : public NMethodClosure { +public: + virtual void do_nmethod(nmethod* nm) { + if (nm->is_alive() && nm->is_unloading()) { + nm->make_unloaded(); + } + } +}; + +class ZNMethodPurgeTask : public ZTask { +private: + ZNMethodPurgeClosure _cl; + +public: + ZNMethodPurgeTask() : + ZTask("ZNMethodPurgeTask"), + _cl() { + ZNMethodTable::nmethods_do_begin(); + } + + ~ZNMethodPurgeTask() { + ZNMethodTable::nmethods_do_end(); + } + + virtual void work() { + ZNMethodTable::nmethods_do(&_cl); + } +}; + +void ZNMethod::purge(ZWorkers* workers) { + ZNMethodPurgeTask task; + workers->run_concurrent(&task); +} diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/gc/z/zNMethod.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/gc/z/zNMethod.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2017, 2019, 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. + */ + +#ifndef SHARE_GC_Z_ZNMETHOD_HPP +#define SHARE_GC_Z_ZNMETHOD_HPP + +#include "memory/allocation.hpp" + +class nmethod; +class OopClosure; +class ZReentrantLock; +class ZWorkers; + +class ZNMethod : public AllStatic { +private: + static void attach_gc_data(nmethod* nm); + + static void log_register(const nmethod* nm); + static void log_unregister(const nmethod* nm); + +public: + static void register_nmethod(nmethod* nm); + static void unregister_nmethod(nmethod* nm); + static void flush_nmethod(nmethod* nm); + + static void disarm_nmethod(nmethod* nm); + + static void nmethod_oops_do(nmethod* nm, OopClosure* cl); + + static void oops_do_begin(); + static void oops_do_end(); + static void oops_do(OopClosure* cl); + + static ZReentrantLock* lock_for_nmethod(nmethod* nm); + + static void unlink(ZWorkers* workers, bool unloading_occurred); + static void purge(ZWorkers* workers); +}; + +#endif // SHARE_GC_Z_ZNMETHOD_HPP diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/gc/z/zNMethodAllocator.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/gc/z/zNMethodAllocator.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2019, 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. + */ + +#include "precompiled.hpp" +#include "gc/z/zArray.inline.hpp" +#include "gc/z/zNMethodAllocator.hpp" +#include "memory/allocation.hpp" + +ZArray ZNMethodAllocator::_deferred_frees; +bool ZNMethodAllocator::_defer_frees(false); + +void ZNMethodAllocator::immediate_free(void* data) { + FREE_C_HEAP_ARRAY(uint8_t, data); +} + +void ZNMethodAllocator::deferred_free(void* data) { + _deferred_frees.add(data); +} + +void* ZNMethodAllocator::allocate(size_t size) { + return NEW_C_HEAP_ARRAY(uint8_t, size, mtGC); +} + +void ZNMethodAllocator::free(void* data) { + if (data == NULL) { + return; + } + + if (_defer_frees) { + deferred_free(data); + } else { + immediate_free(data); + } +} + +void ZNMethodAllocator::activate_deferred_frees() { + assert(_deferred_frees.is_empty(), "precondition"); + _defer_frees = true; +} + +void ZNMethodAllocator::deactivate_and_process_deferred_frees() { + _defer_frees = false; + + ZArrayIterator iter(&_deferred_frees); + for (void* data; iter.next(&data);) { + immediate_free(data); + } + _deferred_frees.clear(); +} diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/gc/z/zNMethodAllocator.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/gc/z/zNMethodAllocator.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019, 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. + */ + +#ifndef SHARE_GC_Z_ZNMETHODALLOCATOR_HPP +#define SHARE_GC_Z_ZNMETHODALLOCATOR_HPP + +#include "memory/allocation.hpp" +#include "gc/z/zArray.hpp" + +class ZNMethodAllocator : public AllStatic { +private: + static ZArray _deferred_frees; + static bool _defer_frees; + + static void immediate_free(void* data); + static void deferred_free(void* data); + +public: + static void* allocate(size_t size); + static void free(void* data); + + static void activate_deferred_frees(); + static void deactivate_and_process_deferred_frees(); +}; + +#endif // SHARE_GC_Z_ZNMETHODALLOCATOR_HPP diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/gc/z/zNMethodData.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/gc/z/zNMethodData.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2017, 2019, 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. + */ + +#include "precompiled.hpp" +#include "gc/z/zLock.inline.hpp" +#include "gc/z/zNMethodData.hpp" +#include "memory/allocation.hpp" +#include "runtime/atomic.hpp" +#include "runtime/orderAccess.hpp" +#include "utilities/align.hpp" +#include "utilities/debug.hpp" +#include "utilities/growableArray.hpp" + +size_t ZNMethodDataOops::header_size() { + const size_t size = sizeof(ZNMethodDataOops); + assert(is_aligned(size, sizeof(oop*)), "Header misaligned"); + return size; +} + +ZNMethodDataOops* ZNMethodDataOops::create(const GrowableArray& immediates, bool has_non_immediates) { + // Allocate memory for the ZNMethodDataOops object + // plus the immediate oop* array that follows right after. + const size_t size = ZNMethodDataOops::header_size() + (sizeof(oop*) * immediates.length()); + void* const mem = NEW_C_HEAP_ARRAY(uint8_t, size, mtGC); + return ::new (mem) ZNMethodDataOops(immediates, has_non_immediates); +} + +void ZNMethodDataOops::destroy(ZNMethodDataOops* oops) { + FREE_C_HEAP_ARRAY(uint8_t, oops); +} + +ZNMethodDataOops::ZNMethodDataOops(const GrowableArray& immediates, bool has_non_immediates) : + _nimmediates(immediates.length()), + _has_non_immediates(has_non_immediates) { + // Save all immediate oops + for (size_t i = 0; i < _nimmediates; i++) { + immediates_begin()[i] = immediates.at(i); + } +} + +size_t ZNMethodDataOops::immediates_count() const { + return _nimmediates; +} + +oop** ZNMethodDataOops::immediates_begin() const { + // The immediate oop* array starts immediately after this object + return (oop**)((uintptr_t)this + header_size()); +} + +oop** ZNMethodDataOops::immediates_end() const { + return immediates_begin() + immediates_count(); +} + +bool ZNMethodDataOops::has_non_immediates() const { + return _has_non_immediates; +} + +ZNMethodData::ZNMethodData() : + _lock(), + _oops(NULL) {} + +ZNMethodData::~ZNMethodData() { + ZNMethodDataOops::destroy(_oops); +} + +ZReentrantLock* ZNMethodData::lock() { + return &_lock; +} + +ZNMethodDataOops* ZNMethodData::oops() const { + return OrderAccess::load_acquire(&_oops); +} + +ZNMethodDataOops* ZNMethodData::swap_oops(ZNMethodDataOops* new_oops) { + ZLocker locker(&_lock); + ZNMethodDataOops* const old_oops = _oops; + _oops = new_oops; + return old_oops; +} diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/gc/z/zNMethodData.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/gc/z/zNMethodData.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2017, 2019, 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. + */ + +#include "gc/z/zLock.hpp" +#include "memory/allocation.hpp" +#include "oops/oopsHierarchy.hpp" +#include "utilities/globalDefinitions.hpp" + +#ifndef SHARE_GC_Z_ZNMETHODDATA_HPP +#define SHARE_GC_Z_ZNMETHODDATA_HPP + +class nmethod; +template class GrowableArray; + +class ZNMethodDataOops { +private: + const size_t _nimmediates; + bool _has_non_immediates; + + static size_t header_size(); + + ZNMethodDataOops(const GrowableArray& immediates, bool has_non_immediates); + +public: + static ZNMethodDataOops* create(const GrowableArray& immediates, bool has_non_immediates); + static void destroy(ZNMethodDataOops* oops); + + size_t immediates_count() const; + oop** immediates_begin() const; + oop** immediates_end() const; + + bool has_non_immediates() const; +}; + +class ZNMethodData : public CHeapObj { +private: + ZReentrantLock _lock; + ZNMethodDataOops* volatile _oops; + +public: + ZNMethodData(); + ~ZNMethodData(); + + ZReentrantLock* lock(); + + ZNMethodDataOops* oops() const; + ZNMethodDataOops* swap_oops(ZNMethodDataOops* oops); +}; + +#endif // SHARE_GC_Z_ZNMETHODDATA_HPP diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/gc/z/zNMethodTable.cpp --- a/src/hotspot/share/gc/z/zNMethodTable.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/gc/z/zNMethodTable.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, 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 @@ -27,205 +27,38 @@ #include "code/icBuffer.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetNMethod.hpp" -#include "gc/z/zArray.inline.hpp" #include "gc/z/zGlobals.hpp" #include "gc/z/zHash.inline.hpp" #include "gc/z/zLock.inline.hpp" +#include "gc/z/zNMethodAllocator.hpp" +#include "gc/z/zNMethodData.hpp" #include "gc/z/zNMethodTable.hpp" +#include "gc/z/zNMethodTableEntry.hpp" +#include "gc/z/zNMethodTableIteration.hpp" #include "gc/z/zOopClosures.inline.hpp" #include "gc/z/zTask.hpp" #include "gc/z/zWorkers.hpp" #include "logging/log.hpp" -#include "memory/allocation.inline.hpp" +#include "memory/allocation.hpp" +#include "memory/iterator.hpp" #include "memory/resourceArea.hpp" #include "runtime/atomic.hpp" #include "runtime/orderAccess.hpp" -#include "runtime/os.hpp" #include "utilities/debug.hpp" -class ZNMethodDataImmediateOops { -private: - const size_t _nimmediate_oops; - - static size_t header_size(); - - ZNMethodDataImmediateOops(const GrowableArray& immediate_oops); - -public: - static ZNMethodDataImmediateOops* create(const GrowableArray& immediate_oops); - static void destroy(ZNMethodDataImmediateOops* data_immediate_oops); - - size_t immediate_oops_count() const; - oop** immediate_oops_begin() const; - oop** immediate_oops_end() const; -}; - -size_t ZNMethodDataImmediateOops::header_size() { - const size_t size = sizeof(ZNMethodDataImmediateOops); - assert(is_aligned(size, sizeof(oop*)), "Header misaligned"); - return size; -} - -ZNMethodDataImmediateOops* ZNMethodDataImmediateOops::create(const GrowableArray& immediate_oops) { - // Allocate memory for the ZNMethodDataImmediateOops object - // plus the immediate oop* array that follows right after. - const size_t size = ZNMethodDataImmediateOops::header_size() + (sizeof(oop*) * immediate_oops.length()); - void* const data_immediate_oops = NEW_C_HEAP_ARRAY(uint8_t, size, mtGC); - return ::new (data_immediate_oops) ZNMethodDataImmediateOops(immediate_oops); -} - -void ZNMethodDataImmediateOops::destroy(ZNMethodDataImmediateOops* data_immediate_oops) { - ZNMethodTable::safe_delete(data_immediate_oops); -} - -ZNMethodDataImmediateOops::ZNMethodDataImmediateOops(const GrowableArray& immediate_oops) : - _nimmediate_oops(immediate_oops.length()) { - // Save all immediate oops - for (size_t i = 0; i < _nimmediate_oops; i++) { - immediate_oops_begin()[i] = immediate_oops.at(i); - } -} - -size_t ZNMethodDataImmediateOops::immediate_oops_count() const { - return _nimmediate_oops; -} - -oop** ZNMethodDataImmediateOops::immediate_oops_begin() const { - // The immediate oop* array starts immediately after this object - return (oop**)((uintptr_t)this + header_size()); -} - -oop** ZNMethodDataImmediateOops::immediate_oops_end() const { - return immediate_oops_begin() + immediate_oops_count(); -} - -class ZNMethodData { -private: - ZReentrantLock _lock; - ZNMethodDataImmediateOops* volatile _immediate_oops; - - ZNMethodData(nmethod* nm); - -public: - static ZNMethodData* create(nmethod* nm); - static void destroy(ZNMethodData* data); - - ZReentrantLock* lock(); - - ZNMethodDataImmediateOops* immediate_oops() const; - ZNMethodDataImmediateOops* swap_immediate_oops(const GrowableArray& immediate_oops); -}; - -ZNMethodData* ZNMethodData::create(nmethod* nm) { - void* const method = NEW_C_HEAP_ARRAY(uint8_t, sizeof(ZNMethodData), mtGC); - return ::new (method) ZNMethodData(nm); -} - -void ZNMethodData::destroy(ZNMethodData* data) { - ZNMethodDataImmediateOops::destroy(data->immediate_oops()); - ZNMethodTable::safe_delete(data); -} - -ZNMethodData::ZNMethodData(nmethod* nm) : - _lock(), - _immediate_oops(NULL) {} - -ZReentrantLock* ZNMethodData::lock() { - return &_lock; -} - -ZNMethodDataImmediateOops* ZNMethodData::immediate_oops() const { - return OrderAccess::load_acquire(&_immediate_oops); -} - -ZNMethodDataImmediateOops* ZNMethodData::swap_immediate_oops(const GrowableArray& immediate_oops) { - ZNMethodDataImmediateOops* const data_immediate_oops = - immediate_oops.is_empty() ? NULL : ZNMethodDataImmediateOops::create(immediate_oops); - return Atomic::xchg(data_immediate_oops, &_immediate_oops); -} - -static ZNMethodData* gc_data(const nmethod* nm) { - return nm->gc_data(); -} - -static void set_gc_data(nmethod* nm, ZNMethodData* data) { - return nm->set_gc_data(data); -} - ZNMethodTableEntry* ZNMethodTable::_table = NULL; size_t ZNMethodTable::_size = 0; -ZLock ZNMethodTable::_iter_lock; -ZNMethodTableEntry* ZNMethodTable::_iter_table = NULL; -size_t ZNMethodTable::_iter_table_size = 0; -ZArray ZNMethodTable::_iter_deferred_deletes; size_t ZNMethodTable::_nregistered = 0; size_t ZNMethodTable::_nunregistered = 0; -volatile size_t ZNMethodTable::_claimed = 0; - -void ZNMethodTable::safe_delete(void* data) { - if (data == NULL) { - return; - } +ZNMethodTableIteration ZNMethodTable::_iteration; - ZLocker locker(&_iter_lock); - if (_iter_table != NULL) { - // Iteration in progress, defer delete - _iter_deferred_deletes.add(data); - } else { - // Iteration not in progress, delete now - FREE_C_HEAP_ARRAY(uint8_t, data); - } +ZNMethodTableEntry* ZNMethodTable::create(size_t size) { + void* const mem = ZNMethodAllocator::allocate(size * sizeof(ZNMethodTableEntry)); + return ::new (mem) ZNMethodTableEntry[size]; } -ZNMethodTableEntry ZNMethodTable::create_entry(nmethod* nm) { - GrowableArray immediate_oops; - bool non_immediate_oops = false; - - // Find all oops relocations - RelocIterator iter(nm); - while (iter.next()) { - if (iter.type() != relocInfo::oop_type) { - // Not an oop - continue; - } - - oop_Relocation* r = iter.oop_reloc(); - - if (!r->oop_is_immediate()) { - // Non-immediate oop found - non_immediate_oops = true; - continue; - } - - if (r->oop_value() != NULL) { - // Non-NULL immediate oop found. NULL oops can safely be - // ignored since the method will be re-registered if they - // are later patched to be non-NULL. - immediate_oops.push(r->oop_addr()); - } - } - - // Attach GC data to nmethod - ZNMethodData* data = gc_data(nm); - if (data == NULL) { - data = ZNMethodData::create(nm); - set_gc_data(nm, data); - } - - // Attach immediate oops in GC data - ZNMethodDataImmediateOops* const old_data_immediate_oops = data->swap_immediate_oops(immediate_oops); - ZNMethodDataImmediateOops::destroy(old_data_immediate_oops); - - // Create entry - return ZNMethodTableEntry(nm, non_immediate_oops, !immediate_oops.is_empty()); -} - -ZReentrantLock* ZNMethodTable::lock_for_nmethod(nmethod* nm) { - ZNMethodData* const data = gc_data(nm); - if (data == NULL) { - return NULL; - } - return data->lock(); +void ZNMethodTable::destroy(ZNMethodTableEntry* table) { + ZNMethodAllocator::free(table); } size_t ZNMethodTable::first_index(const nmethod* nm, size_t size) { @@ -241,8 +74,8 @@ return (prev_index + 1) & mask; } -bool ZNMethodTable::register_entry(ZNMethodTableEntry* table, size_t size, ZNMethodTableEntry entry) { - const nmethod* const nm = entry.method(); +bool ZNMethodTable::register_entry(ZNMethodTableEntry* table, size_t size, nmethod* nm) { + const ZNMethodTableEntry entry(nm); size_t index = first_index(nm, size); for (;;) { @@ -265,11 +98,6 @@ } void ZNMethodTable::unregister_entry(ZNMethodTableEntry* table, size_t size, nmethod* nm) { - if (size == 0) { - // Table is empty - return; - } - size_t index = first_index(nm, size); for (;;) { @@ -279,10 +107,6 @@ if (table_entry.registered() && table_entry.method() == nm) { // Remove entry table[index] = ZNMethodTableEntry(true /* unregistered */); - - // Destroy GC data - ZNMethodData::destroy(gc_data(nm)); - set_gc_data(nm, NULL); return; } @@ -291,7 +115,8 @@ } void ZNMethodTable::rebuild(size_t new_size) { - ZLocker locker(&_iter_lock); + assert(CodeCache_lock->owned_by_self(), "Lock must be held"); + assert(is_power_of_2(new_size), "Invalid size"); log_debug(gc, nmethod)("Rebuilding NMethod Table: " @@ -303,20 +128,18 @@ _nunregistered, percent_of(_nunregistered, _size), 0.0); // Allocate new table - ZNMethodTableEntry* const new_table = new ZNMethodTableEntry[new_size]; + ZNMethodTableEntry* const new_table = ZNMethodTable::create(new_size); // Transfer all registered entries for (size_t i = 0; i < _size; i++) { const ZNMethodTableEntry entry = _table[i]; if (entry.registered()) { - register_entry(new_table, new_size, entry); + register_entry(new_table, new_size, entry.method()); } } - if (_iter_table != _table) { - // Delete old table - delete [] _table; - } + // Free old table + ZNMethodTable::destroy(_table); // Install new table _table = new_table; @@ -353,61 +176,6 @@ } } -void ZNMethodTable::log_register(const nmethod* nm, ZNMethodTableEntry entry) { - LogTarget(Trace, gc, nmethod) log; - if (!log.is_enabled()) { - return; - } - - log.print("Register NMethod: %s.%s (" PTR_FORMAT "), " - "Compiler: %s, Oops: %d, ImmediateOops: " SIZE_FORMAT ", NonImmediateOops: %s", - nm->method()->method_holder()->external_name(), - nm->method()->name()->as_C_string(), - p2i(nm), - nm->compiler_name(), - nm->oops_count() - 1, - entry.immediate_oops() ? gc_data(nm)->immediate_oops()->immediate_oops_count() : 0, - entry.non_immediate_oops() ? "Yes" : "No"); - - LogTarget(Trace, gc, nmethod, oops) log_oops; - if (!log_oops.is_enabled()) { - return; - } - - // Print nmethod oops table - oop* const begin = nm->oops_begin(); - oop* const end = nm->oops_end(); - for (oop* p = begin; p < end; p++) { - log_oops.print(" Oop[" SIZE_FORMAT "] " PTR_FORMAT " (%s)", - (p - begin), p2i(*p), (*p)->klass()->external_name()); - } - - if (entry.immediate_oops()) { - // Print nmethod immediate oops - const ZNMethodDataImmediateOops* const nmi = gc_data(nm)->immediate_oops(); - if (nmi != NULL) { - oop** const begin = nmi->immediate_oops_begin(); - oop** const end = nmi->immediate_oops_end(); - for (oop** p = begin; p < end; p++) { - log_oops.print(" ImmediateOop[" SIZE_FORMAT "] " PTR_FORMAT " @ " PTR_FORMAT " (%s)", - (p - begin), p2i(**p), p2i(*p), (**p)->klass()->external_name()); - } - } - } -} - -void ZNMethodTable::log_unregister(const nmethod* nm) { - LogTarget(Debug, gc, nmethod) log; - if (!log.is_enabled()) { - return; - } - - log.print("Unregister NMethod: %s.%s (" PTR_FORMAT ")", - nm->method()->method_holder()->external_name(), - nm->method()->name()->as_C_string(), - p2i(nm)); -} - size_t ZNMethodTable::registered_nmethods() { return _nregistered; } @@ -418,48 +186,29 @@ void ZNMethodTable::register_nmethod(nmethod* nm) { assert(CodeCache_lock->owned_by_self(), "Lock must be held"); - ResourceMark rm; // Grow/Shrink/Prune table if needed rebuild_if_needed(); - // Create entry - const ZNMethodTableEntry entry = create_entry(nm); - - log_register(nm, entry); - // Insert new entry - if (register_entry(_table, _size, entry)) { + if (register_entry(_table, _size, nm)) { // New entry registered. When register_entry() instead returns // false the nmethod was already in the table so we do not want // to increase number of registered entries in that case. _nregistered++; } - - // Disarm nmethod entry barrier - disarm_nmethod(nm); } -void ZNMethodTable::sweeper_wait_for_iteration() { - // The sweeper must wait for any ongoing iteration to complete - // before it can unregister an nmethod. - if (!Thread::current()->is_Code_cache_sweeper_thread()) { - return; - } +void ZNMethodTable::wait_until_iteration_done() { + assert(CodeCache_lock->owned_by_self(), "Lock must be held"); - while (_iter_table != NULL) { - MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - os::naked_short_sleep(1); + while (_iteration.in_progress()) { + CodeCache_lock->wait(Monitor::_no_safepoint_check_flag); } } void ZNMethodTable::unregister_nmethod(nmethod* nm) { assert(CodeCache_lock->owned_by_self(), "Lock must be held"); - ResourceMark rm; - - sweeper_wait_for_iteration(); - - log_unregister(nm); // Remove entry unregister_entry(_table, _size, nm); @@ -467,248 +216,29 @@ _nregistered--; } -void ZNMethodTable::disarm_nmethod(nmethod* nm) { - BarrierSetNMethod* const bs = BarrierSet::barrier_set()->barrier_set_nmethod(); - if (bs != NULL) { - bs->disarm(nm); - } -} +void ZNMethodTable::nmethods_do_begin() { + MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); -void ZNMethodTable::nmethod_entries_do_begin() { - MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - ZLocker locker(&_iter_lock); + // Make sure we don't free data while iterating + ZNMethodAllocator::activate_deferred_frees(); // Prepare iteration - _iter_table = _table; - _iter_table_size = _size; - _claimed = 0; - assert(_iter_deferred_deletes.is_empty(), "Should be emtpy"); -} - -void ZNMethodTable::nmethod_entries_do_end() { - MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - ZLocker locker(&_iter_lock); - - // Finish iteration - if (_iter_table != _table) { - delete [] _iter_table; - } - _iter_table = NULL; - assert(_claimed >= _iter_table_size, "Failed to claim all table entries"); - - // Process deferred deletes - ZArrayIterator iter(&_iter_deferred_deletes); - for (void* data; iter.next(&data);) { - FREE_C_HEAP_ARRAY(uint8_t, data); - } - _iter_deferred_deletes.clear(); -} - -void ZNMethodTable::entry_oops_do(ZNMethodTableEntry entry, OopClosure* cl) { - nmethod* const nm = entry.method(); - - // Process oops table - oop* const begin = nm->oops_begin(); - oop* const end = nm->oops_end(); - for (oop* p = begin; p < end; p++) { - if (*p != Universe::non_oop_word()) { - cl->do_oop(p); - } - } - - // Process immediate oops - if (entry.immediate_oops()) { - const ZNMethodDataImmediateOops* const nmi = gc_data(nm)->immediate_oops(); - if (nmi != NULL) { - oop** const begin = nmi->immediate_oops_begin(); - oop** const end = nmi->immediate_oops_end(); - for (oop** p = begin; p < end; p++) { - if (**p != Universe::non_oop_word()) { - cl->do_oop(*p); - } - } - } - } - - // Process non-immediate oops - if (entry.non_immediate_oops()) { - nmethod* const nm = entry.method(); - nm->fix_oop_relocations(); - } -} - -class ZNMethodTableEntryToOopsDo : public ZNMethodTableEntryClosure { -private: - OopClosure* _cl; - -public: - ZNMethodTableEntryToOopsDo(OopClosure* cl) : - _cl(cl) {} - - void do_nmethod_entry(ZNMethodTableEntry entry) { - ZNMethodTable::entry_oops_do(entry, _cl); - } -}; - -void ZNMethodTable::oops_do(OopClosure* cl) { - ZNMethodTableEntryToOopsDo entry_cl(cl); - nmethod_entries_do(&entry_cl); -} - -void ZNMethodTable::nmethod_entries_do(ZNMethodTableEntryClosure* cl) { - for (;;) { - // Claim table partition. Each partition is currently sized to span - // two cache lines. This number is just a guess, but seems to work well. - const size_t partition_size = (ZCacheLineSize * 2) / sizeof(ZNMethodTableEntry); - const size_t partition_start = MIN2(Atomic::add(partition_size, &_claimed) - partition_size, _iter_table_size); - const size_t partition_end = MIN2(partition_start + partition_size, _iter_table_size); - if (partition_start == partition_end) { - // End of table - break; - } - - // Process table partition - for (size_t i = partition_start; i < partition_end; i++) { - const ZNMethodTableEntry entry = _iter_table[i]; - if (entry.registered()) { - cl->do_nmethod_entry(entry); - } - } - } + _iteration.nmethods_do_begin(_table, _size); } -class ZNMethodTableUnlinkClosure : public ZNMethodTableEntryClosure { -private: - bool _unloading_occurred; - volatile bool _failed; - - void set_failed() { - Atomic::store(true, &_failed); - } - -public: - ZNMethodTableUnlinkClosure(bool unloading_occurred) : - _unloading_occurred(unloading_occurred), - _failed(false) {} - - virtual void do_nmethod_entry(ZNMethodTableEntry entry) { - if (failed()) { - return; - } - - nmethod* const nm = entry.method(); - if (!nm->is_alive()) { - return; - } +void ZNMethodTable::nmethods_do_end() { + MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - ZLocker locker(ZNMethodTable::lock_for_nmethod(nm)); - - if (nm->is_unloading()) { - // Unlinking of the dependencies must happen before the - // handshake separating unlink and purge. - nm->flush_dependencies(false /* delete_immediately */); - - // We don't need to take the lock when unlinking nmethods from - // the Method, because it is only concurrently unlinked by - // the entry barrier, which acquires the per nmethod lock. - nm->unlink_from_method(false /* acquire_lock */); - return; - } - - // Heal oops and disarm - ZNMethodOopClosure cl; - ZNMethodTable::entry_oops_do(entry, &cl); - ZNMethodTable::disarm_nmethod(nm); - - // Clear compiled ICs and exception caches - if (!nm->unload_nmethod_caches(_unloading_occurred)) { - set_failed(); - } - } + // Finish iteration + _iteration.nmethods_do_end(); - bool failed() const { - return Atomic::load(&_failed); - } -}; - -class ZNMethodTableUnlinkTask : public ZTask { -private: - ZNMethodTableUnlinkClosure _cl; - ICRefillVerifier* _verifier; - -public: - ZNMethodTableUnlinkTask(bool unloading_occurred, ICRefillVerifier* verifier) : - ZTask("ZNMethodTableUnlinkTask"), - _cl(unloading_occurred), - _verifier(verifier) { - ZNMethodTable::nmethod_entries_do_begin(); - } - - ~ZNMethodTableUnlinkTask() { - ZNMethodTable::nmethod_entries_do_end(); - } + // Process deferred frees + ZNMethodAllocator::deactivate_and_process_deferred_frees(); - virtual void work() { - ICRefillVerifierMark mark(_verifier); - ZNMethodTable::nmethod_entries_do(&_cl); - } - - bool success() const { - return !_cl.failed(); - } -}; - -void ZNMethodTable::unlink(ZWorkers* workers, bool unloading_occurred) { - for (;;) { - ICRefillVerifier verifier; - - { - ZNMethodTableUnlinkTask task(unloading_occurred, &verifier); - workers->run_concurrent(&task); - if (task.success()) { - return; - } - } - - // Cleaning failed because we ran out of transitional IC stubs, - // so we have to refill and try again. Refilling requires taking - // a safepoint, so we temporarily leave the suspendible thread set. - SuspendibleThreadSetLeaver sts; - InlineCacheBuffer::refill_ic_stubs(); - } + // Notify iteration done + CodeCache_lock->notify_all(); } -class ZNMethodTablePurgeClosure : public ZNMethodTableEntryClosure { -public: - virtual void do_nmethod_entry(ZNMethodTableEntry entry) { - nmethod* const nm = entry.method(); - if (nm->is_alive() && nm->is_unloading()) { - nm->make_unloaded(); - } - } -}; - -class ZNMethodTablePurgeTask : public ZTask { -private: - ZNMethodTablePurgeClosure _cl; - -public: - ZNMethodTablePurgeTask() : - ZTask("ZNMethodTablePurgeTask"), - _cl() { - ZNMethodTable::nmethod_entries_do_begin(); - } - - ~ZNMethodTablePurgeTask() { - ZNMethodTable::nmethod_entries_do_end(); - } - - virtual void work() { - ZNMethodTable::nmethod_entries_do(&_cl); - } -}; - -void ZNMethodTable::purge(ZWorkers* workers) { - ZNMethodTablePurgeTask task; - workers->run_concurrent(&task); +void ZNMethodTable::nmethods_do(NMethodClosure* cl) { + _iteration.nmethods_do(cl); } diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/gc/z/zNMethodTable.hpp --- a/src/hotspot/share/gc/z/zNMethodTable.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/gc/z/zNMethodTable.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, 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 @@ -24,66 +24,46 @@ #ifndef SHARE_GC_Z_ZNMETHODTABLE_HPP #define SHARE_GC_Z_ZNMETHODTABLE_HPP -#include "gc/z/zArray.hpp" -#include "gc/z/zGlobals.hpp" -#include "gc/z/zLock.hpp" -#include "gc/z/zNMethodTableEntry.hpp" +#include "gc/z/zNMethodTableIteration.hpp" #include "memory/allocation.hpp" +class nmethod; +class NMethodClosure; +class ZNMethodTableEntry; class ZWorkers; -class ZNMethodTableEntryClosure { -public: - virtual void do_nmethod_entry(ZNMethodTableEntry entry) = 0; -}; - class ZNMethodTable : public AllStatic { private: - static ZNMethodTableEntry* _table; - static size_t _size; - static ZLock _iter_lock; - static ZNMethodTableEntry* _iter_table; - static size_t _iter_table_size; - static ZArray _iter_deferred_deletes; - static size_t _nregistered; - static size_t _nunregistered; - static volatile size_t _claimed ATTRIBUTE_ALIGNED(ZCacheLineSize); + static ZNMethodTableEntry* _table; + static size_t _size; + static size_t _nregistered; + static size_t _nunregistered; + static ZNMethodTableIteration _iteration; - static ZNMethodTableEntry create_entry(nmethod* nm); + static ZNMethodTableEntry* create(size_t size); + static void destroy(ZNMethodTableEntry* table); static size_t first_index(const nmethod* nm, size_t size); static size_t next_index(size_t prev_index, size_t size); - static void sweeper_wait_for_iteration(); - - static bool register_entry(ZNMethodTableEntry* table, size_t size, ZNMethodTableEntry entry); + static bool register_entry(ZNMethodTableEntry* table, size_t size, nmethod* nm); static void unregister_entry(ZNMethodTableEntry* table, size_t size, nmethod* nm); static void rebuild(size_t new_size); static void rebuild_if_needed(); - static void log_register(const nmethod* nm, ZNMethodTableEntry entry); - static void log_unregister(const nmethod* nm); - public: - static void safe_delete(void* data); - static size_t registered_nmethods(); static size_t unregistered_nmethods(); static void register_nmethod(nmethod* nm); static void unregister_nmethod(nmethod* nm); - static void disarm_nmethod(nmethod* nm); - static ZReentrantLock* lock_for_nmethod(nmethod* nm); - - static void oops_do(OopClosure* cl); + static void wait_until_iteration_done(); - static void entry_oops_do(ZNMethodTableEntry entry, OopClosure* cl); - - static void nmethod_entries_do_begin(); - static void nmethod_entries_do_end(); - static void nmethod_entries_do(ZNMethodTableEntryClosure* cl); + static void nmethods_do_begin(); + static void nmethods_do_end(); + static void nmethods_do(NMethodClosure* cl); static void unlink(ZWorkers* workers, bool unloading_occurred); static void purge(ZWorkers* workers); diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/gc/z/zNMethodTableEntry.hpp --- a/src/hotspot/share/gc/z/zNMethodTableEntry.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/gc/z/zNMethodTableEntry.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -32,16 +32,16 @@ // -------------------------- // // 6 -// 3 3 2 1 0 -// +--------------------------------------------------------------------+-+-+-+ -// |11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111|1|1|1| -// +--------------------------------------------------------------------+-+-+-+ -// | | | | -// | 2-2 Non-immediate Oops Flag (1-bits) * | | -// | | | -// | 1-1 Immediate Oops/Unregistered Flag (1-bits) * | -// | | -// | 0-0 Registered Flag (1-bits) * +// 3 2 1 0 +// +---------------------------------------------------------------------+-+-+ +// |11111111 11111111 11111111 11111111 11111111 11111111 11111111 111111|1|1| +// +---------------------------------------------------------------------+-+-+ +// | | | +// | | | +// | | | +// | 1-1 Unregistered Flag (1-bits) * | +// | | +// | 0-0 Registered Flag (1-bits) * // | // * 63-3 NMethod Address (61-bits) // @@ -52,22 +52,20 @@ private: typedef ZBitField field_registered; typedef ZBitField field_unregistered; - typedef ZBitField field_immediate_oops; - typedef ZBitField field_non_immediate_oops; - typedef ZBitField field_method; + typedef ZBitField field_method; uint64_t _entry; public: explicit ZNMethodTableEntry(bool unregistered = false) : - _entry(field_unregistered::encode(unregistered) | - field_registered::encode(false)) {} + _entry(field_registered::encode(false) | + field_unregistered::encode(unregistered) | + field_method::encode(NULL)) {} - ZNMethodTableEntry(nmethod* method, bool non_immediate_oops, bool immediate_oops) : - _entry(field_method::encode(method) | - field_non_immediate_oops::encode(non_immediate_oops) | - field_immediate_oops::encode(immediate_oops) | - field_registered::encode(true)) {} + explicit ZNMethodTableEntry(nmethod* method) : + _entry(field_registered::encode(true) | + field_unregistered::encode(false) | + field_method::encode(method)) {} bool registered() const { return field_registered::decode(_entry); @@ -77,14 +75,6 @@ return field_unregistered::decode(_entry); } - bool immediate_oops() const { - return field_immediate_oops::decode(_entry); - } - - bool non_immediate_oops() const { - return field_non_immediate_oops::decode(_entry); - } - nmethod* method() const { return field_method::decode(_entry); } diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/gc/z/zNMethodTableIteration.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/gc/z/zNMethodTableIteration.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2017, 2019, 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. + */ + +#include "precompiled.hpp" +#include "gc/z/zNMethodTableEntry.hpp" +#include "gc/z/zNMethodTableIteration.hpp" +#include "memory/iterator.hpp" +#include "runtime/atomic.hpp" +#include "utilities/debug.hpp" +#include "utilities/globalDefinitions.hpp" + +ZNMethodTableIteration::ZNMethodTableIteration() : + _table(NULL), + _size(0), + _claimed(0) {} + +bool ZNMethodTableIteration::in_progress() const { + return _table != NULL; +} + +void ZNMethodTableIteration::nmethods_do_begin(ZNMethodTableEntry* table, size_t size) { + assert(!in_progress(), "precondition"); + + _table = table; + _size = size; + _claimed = 0; +} + +void ZNMethodTableIteration::nmethods_do_end() { + assert(_claimed >= _size, "Failed to claim all table entries"); + + // Finish iteration + _table = NULL; +} + +void ZNMethodTableIteration::nmethods_do(NMethodClosure* cl) { + for (;;) { + // Claim table partition. Each partition is currently sized to span + // two cache lines. This number is just a guess, but seems to work well. + const size_t partition_size = (ZCacheLineSize * 2) / sizeof(ZNMethodTableEntry); + const size_t partition_start = MIN2(Atomic::add(partition_size, &_claimed) - partition_size, _size); + const size_t partition_end = MIN2(partition_start + partition_size, _size); + if (partition_start == partition_end) { + // End of table + break; + } + + // Process table partition + for (size_t i = partition_start; i < partition_end; i++) { + const ZNMethodTableEntry entry = _table[i]; + if (entry.registered()) { + cl->do_nmethod(entry.method()); + } + } + } +} diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/gc/z/zNMethodTableIteration.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/gc/z/zNMethodTableIteration.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2019, 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. + */ + +#ifndef SHARE_GC_Z_ZNMETHODTABLEITERATION_HPP +#define SHARE_GC_Z_ZNMETHODTABLEITERATION_HPP + +#include "gc/z/zGlobals.hpp" + +class NMethodClosure; +class ZNMethodTableEntry; + +class ZNMethodTableIteration { +private: + ZNMethodTableEntry* _table; + size_t _size; + volatile size_t _claimed ATTRIBUTE_ALIGNED(ZCacheLineSize); + +public: + ZNMethodTableIteration(); + + bool in_progress() const; + + void nmethods_do_begin(ZNMethodTableEntry* table, size_t size); + void nmethods_do_end(); + void nmethods_do(NMethodClosure* cl); +}; + +#endif // SHARE_GC_Z_ZNMETHODTABLEITERATION_HPP diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/gc/z/zRootsIterator.cpp --- a/src/hotspot/share/gc/z/zRootsIterator.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/gc/z/zRootsIterator.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -33,7 +33,7 @@ #include "gc/shared/suspendibleThreadSet.hpp" #include "gc/z/zBarrierSetNMethod.hpp" #include "gc/z/zGlobals.hpp" -#include "gc/z/zNMethodTable.hpp" +#include "gc/z/zNMethod.hpp" #include "gc/z/zOopClosures.inline.hpp" #include "gc/z/zRootsIterator.hpp" #include "gc/z/zStat.hpp" @@ -184,7 +184,7 @@ if (ClassUnloading) { nmethod::oops_do_marking_prologue(); } else { - ZNMethodTable::nmethod_entries_do_begin(); + ZNMethod::oops_do_begin(); } } @@ -194,7 +194,7 @@ if (ClassUnloading) { nmethod::oops_do_marking_epilogue(); } else { - ZNMethodTable::nmethod_entries_do_end(); + ZNMethod::oops_do_end(); } JvmtiExport::gc_epilogue(); @@ -242,7 +242,7 @@ void ZRootsIterator::do_code_cache(ZRootsIteratorClosure* cl) { ZStatTimer timer(ZSubPhasePauseRootsCodeCache); - ZNMethodTable::oops_do(cl); + ZNMethod::oops_do(cl); } void ZRootsIterator::oops_do(ZRootsIteratorClosure* cl, bool visit_jvmti_weak_export) { diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/gc/z/zUnload.cpp --- a/src/hotspot/share/gc/z/zUnload.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/gc/z/zUnload.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -30,7 +30,7 @@ #include "gc/shared/gcBehaviours.hpp" #include "gc/shared/suspendibleThreadSet.hpp" #include "gc/z/zLock.inline.hpp" -#include "gc/z/zNMethodTable.hpp" +#include "gc/z/zNMethod.hpp" #include "gc/z/zOopClosures.hpp" #include "gc/z/zStat.hpp" #include "gc/z/zUnload.hpp" @@ -65,43 +65,30 @@ }; class ZIsUnloadingBehaviour : public IsUnloadingBehaviour { -private: - bool is_unloading(nmethod* nm) const { +public: + virtual bool is_unloading(CompiledMethod* method) const { + nmethod* const nm = method->as_nmethod(); + ZReentrantLock* const lock = ZNMethod::lock_for_nmethod(nm); + ZLocker locker(lock); ZIsUnloadingOopClosure cl; nm->oops_do(&cl, true /* allow_zombie */); return cl.is_unloading(); } - -public: - virtual bool is_unloading(CompiledMethod* method) const { - nmethod* const nm = method->as_nmethod(); - ZReentrantLock* const lock = ZNMethodTable::lock_for_nmethod(nm); - if (lock == NULL) { - return is_unloading(nm); - } else { - ZLocker locker(lock); - return is_unloading(nm); - } - } }; class ZCompiledICProtectionBehaviour : public CompiledICProtectionBehaviour { public: virtual bool lock(CompiledMethod* method) { nmethod* const nm = method->as_nmethod(); - ZReentrantLock* const lock = ZNMethodTable::lock_for_nmethod(nm); - if (lock != NULL) { - lock->lock(); - } + ZReentrantLock* const lock = ZNMethod::lock_for_nmethod(nm); + lock->lock(); return true; } virtual void unlock(CompiledMethod* method) { nmethod* const nm = method->as_nmethod(); - ZReentrantLock* const lock = ZNMethodTable::lock_for_nmethod(nm); - if (lock != NULL) { - lock->unlock(); - } + ZReentrantLock* const lock = ZNMethod::lock_for_nmethod(nm); + lock->unlock(); } virtual bool is_safe(CompiledMethod* method) { @@ -110,8 +97,8 @@ } nmethod* const nm = method->as_nmethod(); - ZReentrantLock* const lock = ZNMethodTable::lock_for_nmethod(nm); - return lock == NULL || lock->is_owned(); + ZReentrantLock* const lock = ZNMethod::lock_for_nmethod(nm); + return lock->is_owned(); } }; @@ -149,7 +136,7 @@ Klass::clean_weak_klass_links(unloading_occurred); - ZNMethodTable::unlink(_workers, unloading_occurred); + ZNMethod::unlink(_workers, unloading_occurred); DependencyContext::cleaning_end(); } @@ -157,7 +144,7 @@ void ZUnload::purge() { { SuspendibleThreadSetJoiner sts; - ZNMethodTable::purge(_workers); + ZNMethod::purge(_workers); } ClassLoaderDataGraph::purge(); diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/interpreter/interpreterRuntime.cpp --- a/src/hotspot/share/interpreter/interpreterRuntime.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -920,19 +920,23 @@ info.call_kind() == CallInfo::vtable_call, ""); } #endif - // Get sender or sender's unsafe_anonymous_host, and only set cpCache entry to resolved if - // it is not an interface. The receiver for invokespecial calls within interface - // methods must be checked for every call. - InstanceKlass* sender = pool->pool_holder(); - sender = sender->is_unsafe_anonymous() ? sender->unsafe_anonymous_host() : sender; switch (info.call_kind()) { - case CallInfo::direct_call: + case CallInfo::direct_call: { + // Get sender or sender's unsafe_anonymous_host, and only set cpCache entry to resolved if + // it is not an interface. The receiver for invokespecial calls within interface + // methods must be checked for every call. + InstanceKlass* pool_holder = pool->pool_holder(); + InstanceKlass* sender = pool_holder->is_unsafe_anonymous() ? + pool_holder->unsafe_anonymous_host() : pool_holder; + cp_cache_entry->set_direct_call( bytecode, info.resolved_method(), - sender->is_interface()); + sender->is_interface(), + pool_holder); break; + } case CallInfo::vtable_call: cp_cache_entry->set_vtable_call( bytecode, diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/jfr/jni/jfrJniMethod.cpp --- a/src/hotspot/share/jfr/jni/jfrJniMethod.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/jfr/jni/jfrJniMethod.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -114,7 +114,7 @@ NO_TRANSITION_END NO_TRANSITION(void, jfr_set_file_notification(JNIEnv* env, jobject jvm, jlong threshold)) - JfrChunkRotation::set_threshold((intptr_t)threshold); + JfrChunkRotation::set_threshold(threshold); NO_TRANSITION_END NO_TRANSITION(void, jfr_set_sample_threads(JNIEnv* env, jobject jvm, jboolean sampleThreads)) diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/jfr/metadata/metadata.xml --- a/src/hotspot/share/jfr/metadata/metadata.xml Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/jfr/metadata/metadata.xml Fri Mar 01 17:27:28 2019 +0530 @@ -533,12 +533,6 @@ - - - - - diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointWriter.cpp --- a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointWriter.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointWriter.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -44,13 +44,13 @@ } } -static void write_checkpoint_header(u1* pos, jlong size, jlong time, bool flushpoint, juint type_count) { +static void write_checkpoint_header(u1* pos, int64_t size, jlong time, bool flushpoint, u4 type_count) { assert(pos != NULL, "invariant"); JfrBigEndianWriter be_writer(pos, sizeof(JfrCheckpointEntry)); be_writer.write(size); be_writer.write(time); be_writer.write(JfrTicks::now().value() - time); - be_writer.write(flushpoint ? (juint)1 : (juint)0); + be_writer.write(flushpoint ? (u4)1 : (u4)0); be_writer.write(type_count); assert(be_writer.is_valid(), "invariant"); } @@ -71,7 +71,7 @@ assert(this->is_valid(), "invariant"); assert(count() > 0, "invariant"); assert(this->used_size() > sizeof(JfrCheckpointEntry), "invariant"); - const jlong size = this->current_offset(); + const int64_t size = this->current_offset(); assert(size + this->start_pos() == this->current_pos(), "invariant"); write_checkpoint_header(const_cast(this->start_pos()), size, _time, is_flushpoint(), count()); release(); @@ -85,11 +85,11 @@ return _flushpoint; } -juint JfrCheckpointWriter::count() const { +u4 JfrCheckpointWriter::count() const { return _count; } -void JfrCheckpointWriter::set_count(juint count) { +void JfrCheckpointWriter::set_count(u4 count) { _count = count; } @@ -111,7 +111,7 @@ } void JfrCheckpointWriter::write_key(u8 key) { - write(key); + write(key); } void JfrCheckpointWriter::increment() { @@ -119,10 +119,10 @@ } void JfrCheckpointWriter::write_count(u4 nof_entries) { - write((u4)nof_entries); + write(nof_entries); } -void JfrCheckpointWriter::write_count(u4 nof_entries, jlong offset) { +void JfrCheckpointWriter::write_count(u4 nof_entries, int64_t offset) { write_padded_at_offset(nof_entries, offset); } diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointWriter.hpp --- a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointWriter.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointWriter.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -49,21 +49,21 @@ typedef EventWriterHost JfrCheckpointWriterBase; struct JfrCheckpointContext { - jlong offset; - juint count; + int64_t offset; + u4 count; }; class JfrCheckpointWriter : public JfrCheckpointWriterBase { friend class JfrSerializerRegistration; private: JfrTicks _time; - jlong _offset; - juint _count; + int64_t _offset; + u4 _count; bool _flushpoint; bool _header; - juint count() const; - void set_count(juint count); + u4 count() const; + void set_count(u4 count); void increment(); void set_flushpoint(bool flushpoint); bool is_flushpoint() const; @@ -75,7 +75,7 @@ ~JfrCheckpointWriter(); void write_type(JfrTypeId type_id); void write_count(u4 nof_entries); - void write_count(u4 nof_entries, jlong offset); + void write_count(u4 nof_entries, int64_t offset); void write_key(u8 key); const JfrCheckpointContext context() const; void set_context(const JfrCheckpointContext ctx); diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp --- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -65,7 +65,7 @@ private: JfrCheckpointWriter& _writer; JfrCheckpointContext _ctx; - const intptr_t _count_position; + const int64_t _count_position; Thread* const _curthread; u4 _count; diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetWriter.hpp --- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetWriter.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetWriter.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -35,7 +35,7 @@ WriterImpl _impl; JfrCheckpointWriter* _writer; JfrCheckpointContext _ctx; - jlong _count_offset; + int64_t _count_offset; int _count; bool _skip_header; public: diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.cpp --- a/src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -29,7 +29,7 @@ #include "runtime/handles.inline.hpp" static jobject chunk_monitor = NULL; -static intptr_t threshold = 0; +static int64_t threshold = 0; static bool rotate = false; static jobject install_chunk_monitor(Thread* thread) { @@ -62,7 +62,6 @@ // already in progress return; } - assert(!rotate, "invariant"); if (writer.size_written() > threshold) { rotate = true; notify(); @@ -77,6 +76,6 @@ rotate = false; } -void JfrChunkRotation::set_threshold(intptr_t bytes) { +void JfrChunkRotation::set_threshold(int64_t bytes) { threshold = bytes; } diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.hpp --- a/src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -36,7 +36,7 @@ class JfrChunkRotation : AllStatic { public: static void evaluate(const JfrChunkWriter& writer); - static void set_threshold(intptr_t bytes); + static void set_threshold(int64_t bytes); static bool should_rotate(); static void on_rotation(); }; diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/jfr/recorder/repository/jfrChunkState.cpp --- a/src/hotspot/share/jfr/recorder/repository/jfrChunkState.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/jfr/recorder/repository/jfrChunkState.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -53,19 +53,19 @@ set_previous_checkpoint_offset(0); } -void JfrChunkState::set_previous_checkpoint_offset(jlong offset) { +void JfrChunkState::set_previous_checkpoint_offset(int64_t offset) { _previous_checkpoint_offset = offset; } -jlong JfrChunkState::previous_checkpoint_offset() const { +int64_t JfrChunkState::previous_checkpoint_offset() const { return _previous_checkpoint_offset; } -jlong JfrChunkState::previous_start_ticks() const { +int64_t JfrChunkState::previous_start_ticks() const { return _previous_start_ticks; } -jlong JfrChunkState::previous_start_nanos() const { +int64_t JfrChunkState::previous_start_nanos() const { return _previous_start_nanos; } @@ -92,7 +92,7 @@ save_current_and_update_start_ticks(); } -jlong JfrChunkState::last_chunk_duration() const { +int64_t JfrChunkState::last_chunk_duration() const { return _start_nanos - _previous_start_nanos; } diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/jfr/recorder/repository/jfrChunkState.hpp --- a/src/hotspot/share/jfr/recorder/repository/jfrChunkState.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/jfr/recorder/repository/jfrChunkState.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -25,7 +25,6 @@ #ifndef SHARE_JFR_RECORDER_REPOSITORY_JFRCHUNKSTATE_HPP #define SHARE_JFR_RECORDER_REPOSITORY_JFRCHUNKSTATE_HPP -#include "jni.h" #include "jfr/utilities/jfrAllocation.hpp" #include "jfr/utilities/jfrTypes.hpp" @@ -33,11 +32,11 @@ friend class JfrChunkWriter; private: char* _path; - jlong _start_ticks; - jlong _start_nanos; - jlong _previous_start_ticks; - jlong _previous_start_nanos; - jlong _previous_checkpoint_offset; + int64_t _start_ticks; + int64_t _start_nanos; + int64_t _previous_start_ticks; + int64_t _previous_start_nanos; + int64_t _previous_checkpoint_offset; void update_start_ticks(); void update_start_nanos(); @@ -47,11 +46,11 @@ JfrChunkState(); ~JfrChunkState(); void reset(); - jlong previous_checkpoint_offset() const; - void set_previous_checkpoint_offset(jlong offset); - jlong previous_start_ticks() const; - jlong previous_start_nanos() const; - jlong last_chunk_duration() const; + int64_t previous_checkpoint_offset() const; + void set_previous_checkpoint_offset(int64_t offset); + int64_t previous_start_ticks() const; + int64_t previous_start_nanos() const; + int64_t last_chunk_duration() const; void update_time_to_now(); void set_path(const char* path); const char* path() const; diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/jfr/recorder/repository/jfrChunkWriter.cpp --- a/src/hotspot/share/jfr/recorder/repository/jfrChunkWriter.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/jfr/recorder/repository/jfrChunkWriter.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -32,9 +32,8 @@ #include "runtime/os.hpp" #include "runtime/os.inline.hpp" -const u2 JFR_VERSION_MAJOR = 2; -const u2 JFR_VERSION_MINOR = 0; - +static const u2 JFR_VERSION_MAJOR = 2; +static const u2 JFR_VERSION_MINOR = 0; static const size_t MAGIC_LEN = 4; static const size_t FILEHEADER_SLOT_SIZE = 8; static const size_t CHUNK_SIZE_OFFSET = 8; @@ -79,14 +78,14 @@ return is_open; } -size_t JfrChunkWriter::close(intptr_t metadata_offset) { +size_t JfrChunkWriter::close(int64_t metadata_offset) { write_header(metadata_offset); this->flush(); this->close_fd(); - return size_written(); + return (size_t)size_written(); } -void JfrChunkWriter::write_header(intptr_t metadata_offset) { +void JfrChunkWriter::write_header(int64_t metadata_offset) { assert(this->is_valid(), "invariant"); // Chunk size this->write_be_at_offset(size_written(), CHUNK_SIZE_OFFSET); @@ -106,15 +105,15 @@ _chunkstate->set_path(chunk_path); } -intptr_t JfrChunkWriter::size_written() const { +int64_t JfrChunkWriter::size_written() const { return this->is_valid() ? this->current_offset() : 0; } -intptr_t JfrChunkWriter::previous_checkpoint_offset() const { +int64_t JfrChunkWriter::previous_checkpoint_offset() const { return _chunkstate->previous_checkpoint_offset(); } -void JfrChunkWriter::set_previous_checkpoint_offset(intptr_t offset) { +void JfrChunkWriter::set_previous_checkpoint_offset(int64_t offset) { _chunkstate->set_previous_checkpoint_offset(offset); } diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/jfr/recorder/repository/jfrChunkWriter.hpp --- a/src/hotspot/share/jfr/recorder/repository/jfrChunkWriter.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/jfr/recorder/repository/jfrChunkWriter.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -41,16 +41,16 @@ JfrChunkState* _chunkstate; bool open(); - size_t close(intptr_t metadata_offset); - void write_header(intptr_t metadata_offset); + size_t close(int64_t metadata_offset); + void write_header(int64_t metadata_offset); void set_chunk_path(const char* chunk_path); public: JfrChunkWriter(); bool initialize(); - intptr_t size_written() const; - intptr_t previous_checkpoint_offset() const; - void set_previous_checkpoint_offset(intptr_t offset); + int64_t size_written() const; + int64_t previous_checkpoint_offset() const; + void set_previous_checkpoint_offset(int64_t offset); void time_stamp_chunk_now(); }; diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/jfr/recorder/repository/jfrRepository.cpp --- a/src/hotspot/share/jfr/recorder/repository/jfrRepository.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/jfr/recorder/repository/jfrRepository.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -147,10 +147,10 @@ iso8601_to_date_time(buffer); } -static jlong file_size(fio_fd fd) { +static int64_t file_size(fio_fd fd) { assert(fd != invalid_fd, "invariant"); - const jlong current_offset = os::current_file_offset(fd); - const jlong size = os::lseek(fd, 0, SEEK_END); + const int64_t current_offset = os::current_file_offset(fd); + const int64_t size = os::lseek(fd, 0, SEEK_END); os::seek_to_file_offset(fd, current_offset); return size; } @@ -218,7 +218,7 @@ if (invalid_fd == entry_fd) { return NULL; } - const jlong entry_size = file_size(entry_fd); + const int64_t entry_size = file_size(entry_fd); os::close(entry_fd); if (0 == entry_size) { return NULL; @@ -260,6 +260,7 @@ } } #endif + bool RepositoryIterator::has_next() const { return (_files != NULL && _iterator < _files->length()); } @@ -275,21 +276,27 @@ if (file_copy_block == NULL) { return; } - jlong bytes_written_total = 0; + int64_t bytes_written_total = 0; while (iterator.has_next()) { fio_fd current_fd = invalid_fd; const char* const fqn = iterator.next(); if (fqn != NULL) { current_fd = open_existing(fqn); if (current_fd != invalid_fd) { - const jlong current_filesize = file_size(current_fd); + const int64_t current_filesize = file_size(current_fd); assert(current_filesize > 0, "invariant"); - jlong bytes_read = 0; - jlong bytes_written = 0; + int64_t bytes_read = 0; + int64_t bytes_written = 0; while (bytes_read < current_filesize) { - bytes_read += (jlong)os::read_at(current_fd, file_copy_block, size_of_file_copy_block, bytes_read); - assert(bytes_read - bytes_written <= (jlong)size_of_file_copy_block, "invariant"); - bytes_written += (jlong)os::write(emergency_fd, file_copy_block, bytes_read - bytes_written); + const ssize_t read_result = os::read_at(current_fd, file_copy_block, size_of_file_copy_block, bytes_read); + if (-1 == read_result) { + log_info(jfr) ( // For user, should not be "jfr, system" + "Unable to recover JFR data"); + break; + } + bytes_read += (int64_t)read_result; + assert(bytes_read - bytes_written <= (int64_t)size_of_file_copy_block, "invariant"); + bytes_written += (int64_t)os::write(emergency_fd, file_copy_block, bytes_read - bytes_written); assert(bytes_read == bytes_written, "invariant"); } os::close(current_fd); @@ -468,6 +475,6 @@ return _chunkwriter->open(); } -size_t JfrRepository::close_chunk(jlong metadata_offset) { +size_t JfrRepository::close_chunk(int64_t metadata_offset) { return _chunkwriter->close(metadata_offset); } diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/jfr/recorder/repository/jfrRepository.hpp --- a/src/hotspot/share/jfr/recorder/repository/jfrRepository.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/jfr/recorder/repository/jfrRepository.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -55,7 +55,7 @@ bool set_path(const char* path); void set_chunk_path(const char* path); bool open_chunk(bool vm_error = false); - size_t close_chunk(jlong metadata_offset); + size_t close_chunk(int64_t metadata_offset); void on_vm_error(); static void notify_on_new_chunk_path(); static JfrChunkWriter& chunkwriter(); diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp --- a/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -130,18 +130,18 @@ bool not_acquired() const { return !_acquired; } }; -static intptr_t write_checkpoint_event_prologue(JfrChunkWriter& cw, u8 type_id) { - const intptr_t prev_cp_offset = cw.previous_checkpoint_offset(); - const intptr_t prev_cp_relative_offset = 0 == prev_cp_offset ? 0 : prev_cp_offset - cw.current_offset(); +static int64_t write_checkpoint_event_prologue(JfrChunkWriter& cw, u8 type_id) { + const int64_t prev_cp_offset = cw.previous_checkpoint_offset(); + const int64_t prev_cp_relative_offset = 0 == prev_cp_offset ? 0 : prev_cp_offset - cw.current_offset(); cw.reserve(sizeof(u4)); cw.write(EVENT_CHECKPOINT); cw.write(JfrTicks::now()); - cw.write((jlong)0); + cw.write((int64_t)0); cw.write(prev_cp_relative_offset); // write previous checkpoint offset delta cw.write(false); // flushpoint - cw.write((u4)1); // nof types in this checkpoint - cw.write(type_id); - const intptr_t number_of_elements_offset = cw.current_offset(); + cw.write((u4)1); // nof types in this checkpoint + cw.write(type_id); + const int64_t number_of_elements_offset = cw.current_offset(); cw.reserve(sizeof(u4)); return number_of_elements_offset; } @@ -161,8 +161,8 @@ } bool process() { // current_cp_offset is also offset for the event size header field - const intptr_t current_cp_offset = _cw.current_offset(); - const intptr_t num_elements_offset = write_checkpoint_event_prologue(_cw, _type_id); + const int64_t current_cp_offset = _cw.current_offset(); + const int64_t num_elements_offset = write_checkpoint_event_prologue(_cw, _type_id); // invocation _content_functor.process(); const u4 number_of_elements = (u4)_content_functor.processed(); @@ -468,9 +468,9 @@ JfrMetadataEvent::lock(); } -static jlong write_metadata_event(JfrChunkWriter& chunkwriter) { +static int64_t write_metadata_event(JfrChunkWriter& chunkwriter) { assert(chunkwriter.is_valid(), "invariant"); - const jlong metadata_offset = chunkwriter.current_offset(); + const int64_t metadata_offset = chunkwriter.current_offset(); JfrMetadataEvent::write(chunkwriter, metadata_offset); return metadata_offset; } diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/jfr/writers/jfrEventWriterHost.inline.hpp --- a/src/hotspot/share/jfr/writers/jfrEventWriterHost.inline.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/jfr/writers/jfrEventWriterHost.inline.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -49,7 +49,7 @@ inline intptr_t EventWriterHost::end_write(void) { assert(this->is_acquired(), "state corruption, calling end with writer with non-acquired state!"); - return this->is_valid() ? this->used_offset() : 0; + return this->is_valid() ? (intptr_t)this->used_offset() : 0; } template diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/jfr/writers/jfrPosition.hpp --- a/src/hotspot/share/jfr/writers/jfrPosition.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/jfr/writers/jfrPosition.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -48,8 +48,8 @@ public: size_t available_size() const; - intptr_t used_offset() const; - intptr_t current_offset() const; + int64_t used_offset() const; + int64_t current_offset() const; size_t used_size() const; void reset(); }; diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/jfr/writers/jfrPosition.inline.hpp --- a/src/hotspot/share/jfr/writers/jfrPosition.inline.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/jfr/writers/jfrPosition.inline.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -80,12 +80,12 @@ } template -inline intptr_t Position::used_offset() const { +inline int64_t Position::used_offset() const { return _current_pos - _start_pos; } template -inline intptr_t Position::current_offset() const { +inline int64_t Position::current_offset() const { return this->used_offset(); } diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/jfr/writers/jfrStreamWriterHost.hpp --- a/src/hotspot/share/jfr/writers/jfrStreamWriterHost.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/jfr/writers/jfrStreamWriterHost.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -33,9 +33,9 @@ public: typedef typename Adapter::StorageType StorageType; private: - intptr_t _stream_pos; + int64_t _stream_pos; fio_fd _fd; - intptr_t current_stream_position() const; + int64_t current_stream_position() const; protected: StreamWriterHost(StorageType* storage, Thread* thread); @@ -47,8 +47,8 @@ bool has_valid_fd() const; public: - intptr_t current_offset() const; - void seek(intptr_t offset); + int64_t current_offset() const; + void seek(int64_t offset); void flush(); void write_unbuffered(const void* src, size_t len); bool is_valid() const; diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/jfr/writers/jfrStreamWriterHost.inline.hpp --- a/src/hotspot/share/jfr/writers/jfrStreamWriterHost.inline.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/jfr/writers/jfrStreamWriterHost.inline.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -44,7 +44,7 @@ } template -inline intptr_t StreamWriterHost::current_stream_position() const { +inline int64_t StreamWriterHost::current_stream_position() const { return this->used_offset() + _stream_pos; } @@ -73,7 +73,7 @@ inline void StreamWriterHost::flush(size_t size) { assert(size > 0, "invariant"); assert(this->is_valid(), "invariant"); - _stream_pos += os::write(_fd, this->start_pos(), (int)size); + _stream_pos += os::write(_fd, this->start_pos(), (unsigned int)size); StorageHost::reset(); assert(0 == this->used_offset(), "invariant"); } @@ -84,12 +84,12 @@ } template -inline intptr_t StreamWriterHost::current_offset() const { +inline int64_t StreamWriterHost::current_offset() const { return current_stream_position(); } template -void StreamWriterHost::seek(intptr_t offset) { +void StreamWriterHost::seek(int64_t offset) { this->flush(); assert(0 == this->used_offset(), "can only seek from beginning"); _stream_pos = os::seek_to_file_offset(_fd, offset); @@ -110,7 +110,7 @@ this->flush(); assert(0 == this->used_offset(), "can only seek from beginning"); while (len > 0) { - const int n = MIN2((int)len, INT_MAX); + const unsigned int n = MIN2((unsigned int)len, (unsigned int)INT_MAX); _stream_pos += os::write(_fd, buf, n); len -= n; } diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/jfr/writers/jfrWriterHost.hpp --- a/src/hotspot/share/jfr/writers/jfrWriterHost.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/jfr/writers/jfrWriterHost.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -91,12 +91,12 @@ void bytes(const void* buf, size_t len); void write_utf8_u2_len(const char* value); template - void write_padded_at_offset(T value, intptr_t offset); + void write_padded_at_offset(T value, int64_t offset); template - void write_at_offset(T value, intptr_t offset); + void write_at_offset(T value, int64_t offset); template - void write_be_at_offset(T value, intptr_t offset); - intptr_t reserve(size_t size); + void write_be_at_offset(T value, int64_t offset); + int64_t reserve(size_t size); }; #endif // SHARE_JFR_WRITERS_JFRWRITERHOST_HPP diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/jfr/writers/jfrWriterHost.inline.hpp --- a/src/hotspot/share/jfr/writers/jfrWriterHost.inline.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/jfr/writers/jfrWriterHost.inline.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -196,7 +196,7 @@ template inline void WriterHost::write(double value) { - be_write(*(uintptr_t*)&(value)); + be_write(*(u8*)&(value)); } template @@ -317,9 +317,9 @@ } template -inline intptr_t WriterHost::reserve(size_t size) { +inline int64_t WriterHost::reserve(size_t size) { if (ensure_size(size) != NULL) { - intptr_t reserved_offset = this->current_offset(); + const int64_t reserved_offset = this->current_offset(); this->set_current_pos(size); return reserved_offset; } @@ -329,9 +329,9 @@ template template -inline void WriterHost::write_padded_at_offset(T value, intptr_t offset) { +inline void WriterHost::write_padded_at_offset(T value, int64_t offset) { if (this->is_valid()) { - const intptr_t current = this->current_offset(); + const int64_t current = this->current_offset(); this->seek(offset); write_padded(value); this->seek(current); // restore @@ -340,9 +340,9 @@ template template -inline void WriterHost::write_at_offset(T value, intptr_t offset) { +inline void WriterHost::write_at_offset(T value, int64_t offset) { if (this->is_valid()) { - const intptr_t current = this->current_offset(); + const int64_t current = this->current_offset(); this->seek(offset); write(value); this->seek(current); // restore @@ -351,9 +351,9 @@ template template -inline void WriterHost::write_be_at_offset(T value, intptr_t offset) { +inline void WriterHost::write_be_at_offset(T value, int64_t offset) { if (this->is_valid()) { - const intptr_t current = this->current_offset(); + const int64_t current = this->current_offset(); this->seek(offset); be_write(value); this->seek(current); // restore diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/memory/filemap.cpp --- a/src/hotspot/share/memory/filemap.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/memory/filemap.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -561,7 +561,7 @@ // Read the FileMapInfo information from the file. bool FileMapInfo::open_for_read() { _full_path = Arguments::GetSharedArchivePath(); - int fd = open(_full_path, O_RDONLY | O_BINARY, 0); + int fd = os::open(_full_path, O_RDONLY | O_BINARY, 0); if (fd < 0) { if (errno == ENOENT) { // Not locating the shared archive is ok. @@ -596,7 +596,7 @@ // Use remove() to delete the existing file because, on Unix, this will // allow processes that have it open continued access to the file. remove(_full_path); - int fd = open(_full_path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0444); + int fd = os::open(_full_path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0444); if (fd < 0) { fail_stop("Unable to create shared archive file %s: (%s).", _full_path, os::strerror(errno)); diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/memory/iterator.hpp --- a/src/hotspot/share/memory/iterator.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/memory/iterator.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -263,6 +263,11 @@ virtual void do_code_blob(CodeBlob* cb); }; +class NMethodClosure : public Closure { + public: + virtual void do_nmethod(nmethod* n) = 0; +}; + // MonitorClosure is used for iterating over monitors in the monitors cache class ObjectMonitor; diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/memory/universe.cpp --- a/src/hotspot/share/memory/universe.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/memory/universe.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -107,6 +107,7 @@ LatestMethodCache* Universe::_finalizer_register_cache = NULL; LatestMethodCache* Universe::_loader_addClass_cache = NULL; LatestMethodCache* Universe::_throw_illegal_access_error_cache = NULL; +LatestMethodCache* Universe::_throw_no_such_method_error_cache = NULL; LatestMethodCache* Universe::_do_stack_walk_cache = NULL; oop Universe::_out_of_memory_error_java_heap = NULL; oop Universe::_out_of_memory_error_metaspace = NULL; @@ -230,6 +231,7 @@ _finalizer_register_cache->metaspace_pointers_do(it); _loader_addClass_cache->metaspace_pointers_do(it); _throw_illegal_access_error_cache->metaspace_pointers_do(it); + _throw_no_such_method_error_cache->metaspace_pointers_do(it); _do_stack_walk_cache->metaspace_pointers_do(it); } @@ -271,6 +273,7 @@ _finalizer_register_cache->serialize(f); _loader_addClass_cache->serialize(f); _throw_illegal_access_error_cache->serialize(f); + _throw_no_such_method_error_cache->serialize(f); _do_stack_walk_cache->serialize(f); } @@ -689,6 +692,7 @@ Universe::_finalizer_register_cache = new LatestMethodCache(); Universe::_loader_addClass_cache = new LatestMethodCache(); Universe::_throw_illegal_access_error_cache = new LatestMethodCache(); + Universe::_throw_no_such_method_error_cache = new LatestMethodCache(); Universe::_do_stack_walk_cache = new LatestMethodCache(); #if INCLUDE_CDS @@ -935,6 +939,11 @@ "throwIllegalAccessError", vmSymbols::void_method_signature(), true, CHECK); + initialize_known_method(_throw_no_such_method_error_cache, + SystemDictionary::internal_Unsafe_klass(), + "throwNoSuchMethodError", + vmSymbols::void_method_signature(), true, CHECK); + // Set up method for registering loaded classes in class loader vector initialize_known_method(_loader_addClass_cache, SystemDictionary::ClassLoader_klass(), diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/memory/universe.hpp --- a/src/hotspot/share/memory/universe.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/memory/universe.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -138,6 +138,7 @@ static LatestMethodCache* _finalizer_register_cache; // static method for registering finalizable objects static LatestMethodCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector static LatestMethodCache* _throw_illegal_access_error_cache; // Unsafe.throwIllegalAccessError() method + static LatestMethodCache* _throw_no_such_method_error_cache; // Unsafe.throwNoSuchMethodError() method static LatestMethodCache* _do_stack_walk_cache; // method for stack walker callback // preallocated error objects (no backtrace) @@ -322,6 +323,7 @@ static Method* loader_addClass_method() { return _loader_addClass_cache->get_method(); } static Method* throw_illegal_access_error() { return _throw_illegal_access_error_cache->get_method(); } + static Method* throw_no_such_method_error() { return _throw_no_such_method_error_cache->get_method(); } static Method* do_stack_walk_method() { return _do_stack_walk_cache->get_method(); } diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/oops/cpCache.cpp --- a/src/hotspot/share/oops/cpCache.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/oops/cpCache.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -168,7 +168,8 @@ void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_code, const methodHandle& method, int vtable_index, - bool sender_is_interface) { + bool sender_is_interface, + InstanceKlass* pool_holder) { bool is_vtable_call = (vtable_index >= 0); // FIXME: split this method on this boolean assert(method->interpreter_entry() != NULL, "should have been set at this point"); assert(!method->is_obsolete(), "attempt to write obsolete method to cpCache"); @@ -263,11 +264,17 @@ } // Don't mark invokestatic to method as resolved if the holder class has not yet completed // initialization. An invokestatic must only proceed if the class is initialized, but if - // we resolve it before then that class initialization check is skipped. - if (invoke_code == Bytecodes::_invokestatic && !method->method_holder()->is_initialized()) { + // we resolve it before then that class initialization check is skipped. However if the call + // is from the same class we can resolve as we must be executing with on our call stack. + if (invoke_code == Bytecodes::_invokestatic && + !method->method_holder()->is_initialized() && + method->method_holder() != pool_holder) { do_resolve = false; } if (do_resolve) { + assert(method->method_holder()->is_initialized() || + method->method_holder()->is_reentrant_initialization(Thread::current()), + "invalid class initalization state"); set_bytecode_1(invoke_code); } } else if (byte_no == 2) { @@ -310,17 +317,17 @@ } void ConstantPoolCacheEntry::set_direct_call(Bytecodes::Code invoke_code, const methodHandle& method, - bool sender_is_interface) { + bool sender_is_interface, InstanceKlass* pool_holder) { int index = Method::nonvirtual_vtable_index; // index < 0; FIXME: inline and customize set_direct_or_vtable_call - set_direct_or_vtable_call(invoke_code, method, index, sender_is_interface); + set_direct_or_vtable_call(invoke_code, method, index, sender_is_interface, pool_holder); } void ConstantPoolCacheEntry::set_vtable_call(Bytecodes::Code invoke_code, const methodHandle& method, int index) { // either the method is a miranda or its holder should accept the given index assert(method->method_holder()->is_interface() || method->method_holder()->verify_vtable_index(index), ""); // index >= 0; FIXME: inline and customize set_direct_or_vtable_call - set_direct_or_vtable_call(invoke_code, method, index, false); + set_direct_or_vtable_call(invoke_code, method, index, false, NULL /* not used */); } void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code, @@ -591,7 +598,7 @@ // a constant pool cache entry should never contain old or obsolete methods bool ConstantPoolCacheEntry::check_no_old_or_obsolete_entries() { - Method* m = get_interesting_method_entry(NULL); + Method* m = get_interesting_method_entry(); // return false if m refers to a non-deleted old or obsolete method if (m != NULL) { assert(m->is_valid() && m->is_method(), "m is a valid method"); @@ -601,7 +608,7 @@ } } -Method* ConstantPoolCacheEntry::get_interesting_method_entry(Klass* k) { +Method* ConstantPoolCacheEntry::get_interesting_method_entry() { if (!is_method_entry()) { // not a method entry so not interesting by default return NULL; @@ -622,12 +629,9 @@ } } assert(m != NULL && m->is_method(), "sanity check"); - if (m == NULL || !m->is_method() || (k != NULL && m->method_holder() != k)) { - // robustness for above sanity checks or method is not in - // the interesting class + if (m == NULL || !m->is_method()) { return NULL; } - // the method is in the interesting class so the entry is interesting return m; } #endif // INCLUDE_JVMTI @@ -777,10 +781,10 @@ // RedefineClasses() API support: // If any entry of this ConstantPoolCache points to any of // old_methods, replace it with the corresponding new_method. -void ConstantPoolCache::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) { +void ConstantPoolCache::adjust_method_entries(bool * trace_name_printed) { for (int i = 0; i < length(); i++) { ConstantPoolCacheEntry* entry = entry_at(i); - Method* old_method = entry->get_interesting_method_entry(holder); + Method* old_method = entry->get_interesting_method_entry(); if (old_method == NULL || !old_method->is_old()) { continue; // skip uninteresting entries } @@ -789,11 +793,7 @@ entry->initialize_entry(entry->constant_pool_index()); continue; } - Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum()); - - assert(new_method != NULL, "method_with_idnum() should not be NULL"); - assert(old_method != new_method, "sanity check"); - + Method* new_method = old_method->get_new_method(); entry_at(i)->adjust_method_entry(old_method, new_method, trace_name_printed); } } @@ -801,7 +801,7 @@ // the constant pool cache should never contain old or obsolete methods bool ConstantPoolCache::check_no_old_or_obsolete_entries() { for (int i = 1; i < length(); i++) { - if (entry_at(i)->get_interesting_method_entry(NULL) != NULL && + if (entry_at(i)->get_interesting_method_entry() != NULL && !entry_at(i)->check_no_old_or_obsolete_entries()) { return false; } @@ -811,7 +811,7 @@ void ConstantPoolCache::dump_cache() { for (int i = 1; i < length(); i++) { - if (entry_at(i)->get_interesting_method_entry(NULL) != NULL) { + if (entry_at(i)->get_interesting_method_entry() != NULL) { entry_at(i)->print(tty, i); } } diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/oops/cpCache.hpp --- a/src/hotspot/share/oops/cpCache.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/oops/cpCache.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -230,14 +230,16 @@ Bytecodes::Code invoke_code, // the bytecode used for invoking the method const methodHandle& method, // the method/prototype if any (NULL, otherwise) int vtable_index, // the vtable index if any, else negative - bool sender_is_interface + bool sender_is_interface, // 'logical' sender (may be host of VMAC) + InstanceKlass* pool_holder // class from which the call is made ); public: void set_direct_call( // sets entry to exact concrete method entry Bytecodes::Code invoke_code, // the bytecode used for invoking the method const methodHandle& method, // the method to call - bool sender_is_interface + bool sender_is_interface, // 'logical' sender (may be host of VMAC) + InstanceKlass* pool_holder // class from which the call is made ); void set_vtable_call( // sets entry to vtable index @@ -376,7 +378,7 @@ void adjust_method_entry(Method* old_method, Method* new_method, bool* trace_name_printed); bool check_no_old_or_obsolete_entries(); - Method* get_interesting_method_entry(Klass* k); + Method* get_interesting_method_entry(); #endif // INCLUDE_JVMTI // Debugging & Printing @@ -496,7 +498,7 @@ // trace_name_printed is set to true if the current call has // printed the klass name so that other routines in the adjust_* // group don't print the klass name. - void adjust_method_entries(InstanceKlass* holder, bool* trace_name_printed); + void adjust_method_entries(bool* trace_name_printed); bool check_no_old_or_obsolete_entries(); void dump_cache(); #endif // INCLUDE_JVMTI diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/oops/instanceKlass.cpp --- a/src/hotspot/share/oops/instanceKlass.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/oops/instanceKlass.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -2917,22 +2917,18 @@ // not yet in the vtable due to concurrent subclass define and superinterface // redefinition // Note: those in the vtable, should have been updated via adjust_method_entries -void InstanceKlass::adjust_default_methods(InstanceKlass* holder, bool* trace_name_printed) { +void InstanceKlass::adjust_default_methods(bool* trace_name_printed) { // search the default_methods for uses of either obsolete or EMCP methods if (default_methods() != NULL) { for (int index = 0; index < default_methods()->length(); index ++) { Method* old_method = default_methods()->at(index); - if (old_method == NULL || old_method->method_holder() != holder || !old_method->is_old()) { + if (old_method == NULL || !old_method->is_old()) { continue; // skip uninteresting entries } assert(!old_method->is_deleted(), "default methods may not be deleted"); - - Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum()); - - assert(new_method != NULL, "method_with_idnum() should not be NULL"); - assert(old_method != new_method, "sanity check"); - + Method* new_method = old_method->get_new_method(); default_methods()->at_put(index, new_method); + if (log_is_enabled(Info, redefine, class, update)) { ResourceMark rm; if (!(*trace_name_printed)) { diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/oops/instanceKlass.hpp --- a/src/hotspot/share/oops/instanceKlass.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/oops/instanceKlass.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -1141,7 +1141,7 @@ Method* method_at_itable(Klass* holder, int index, TRAPS); #if INCLUDE_JVMTI - void adjust_default_methods(InstanceKlass* holder, bool* trace_name_printed); + void adjust_default_methods(bool* trace_name_printed); #endif // INCLUDE_JVMTI void clean_weak_instanceklass_links(); diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/oops/klassVtable.cpp --- a/src/hotspot/share/oops/klassVtable.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/oops/klassVtable.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2019, 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 @@ -942,21 +942,18 @@ } // search the vtable for uses of either obsolete or EMCP methods -void klassVtable::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) { +void klassVtable::adjust_method_entries(bool * trace_name_printed) { int prn_enabled = 0; for (int index = 0; index < length(); index++) { Method* old_method = unchecked_method_at(index); - if (old_method == NULL || old_method->method_holder() != holder || !old_method->is_old()) { + if (old_method == NULL || !old_method->is_old()) { continue; // skip uninteresting entries } assert(!old_method->is_deleted(), "vtable methods may not be deleted"); - Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum()); + Method* new_method = old_method->get_new_method(); + put_method_at(new_method, index); - assert(new_method != NULL, "method_with_idnum() should not be NULL"); - assert(old_method != new_method, "sanity check"); - - put_method_at(new_method, index); // For default methods, need to update the _default_methods array // which can only have one method entry for a given signature bool updated_default = false; @@ -1272,21 +1269,16 @@ #if INCLUDE_JVMTI // search the itable for uses of either obsolete or EMCP methods -void klassItable::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) { +void klassItable::adjust_method_entries(bool * trace_name_printed) { itableMethodEntry* ime = method_entry(0); for (int i = 0; i < _size_method_table; i++, ime++) { Method* old_method = ime->method(); - if (old_method == NULL || old_method->method_holder() != holder || !old_method->is_old()) { + if (old_method == NULL || !old_method->is_old()) { continue; // skip uninteresting entries } assert(!old_method->is_deleted(), "itable methods may not be deleted"); - - Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum()); - - assert(new_method != NULL, "method_with_idnum() should not be NULL"); - assert(old_method != new_method, "sanity check"); - + Method* new_method = old_method->get_new_method(); ime->initialize(new_method); if (log_is_enabled(Info, redefine, class, update)) { diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/oops/klassVtable.hpp --- a/src/hotspot/share/oops/klassVtable.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/oops/klassVtable.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -103,7 +103,7 @@ // printed the klass name so that other routines in the adjust_* // group don't print the klass name. bool adjust_default_method(int vtable_index, Method* old_method, Method* new_method); - void adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed); + void adjust_method_entries(bool* trace_name_printed); bool check_no_old_or_obsolete_entries(); void dump_vtable(); #endif // INCLUDE_JVMTI @@ -322,7 +322,7 @@ // trace_name_printed is set to true if the current call has // printed the klass name so that other routines in the adjust_* // group don't print the klass name. - void adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed); + void adjust_method_entries(bool* trace_name_printed); bool check_no_old_or_obsolete_entries(); void dump_itable(); #endif // INCLUDE_JVMTI diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/oops/method.cpp --- a/src/hotspot/share/oops/method.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/oops/method.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -2120,7 +2120,8 @@ // Can't assert the method_holder is the same because the new method has the // scratch method holder. assert(resolve_jmethod_id(jmid)->method_holder()->class_loader() - == new_method->method_holder()->class_loader(), + == new_method->method_holder()->class_loader() || + new_method->method_holder()->class_loader() == NULL, // allow Unsafe substitution "changing to a different class loader"); // Just change the method in place, jmethodID pointer doesn't change. *((Method**)jmid) = new_method; diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/oops/method.hpp --- a/src/hotspot/share/oops/method.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/oops/method.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -974,6 +974,15 @@ // Deallocation function for redefine classes or if an error occurs void deallocate_contents(ClassLoaderData* loader_data); + Method* get_new_method() const { + InstanceKlass* holder = method_holder(); + Method* new_method = holder->method_with_idnum(orig_method_idnum()); + + assert(new_method != NULL, "method_with_idnum() should not be NULL"); + assert(this != new_method, "sanity check"); + return new_method; + } + // Printing #ifndef PRODUCT void print_on(outputStream* st) const; diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/opto/indexSet.cpp --- a/src/hotspot/share/opto/indexSet.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/opto/indexSet.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -50,72 +50,6 @@ int IndexSet::_serial_count = 1; #endif -// What is the first set bit in a 5 bit integer? -const uint8_t IndexSetIterator::_first_bit[32] = { - 0, 0, 1, 0, - 2, 0, 1, 0, - 3, 0, 1, 0, - 2, 0, 1, 0, - 4, 0, 1, 0, - 2, 0, 1, 0, - 3, 0, 1, 0, - 2, 0, 1, 0 -}; - -// What is the second set bit in a 5 bit integer? -const uint8_t IndexSetIterator::_second_bit[32] = { - 5, 5, 5, 1, - 5, 2, 2, 1, - 5, 3, 3, 1, - 3, 2, 2, 1, - 5, 4, 4, 1, - 4, 2, 2, 1, - 4, 3, 3, 1, - 3, 2, 2, 1 -}; - -// I tried implementing the IndexSetIterator with a window_size of 8 and -// didn't seem to get a noticeable speedup. I am leaving in the tables -// in case we want to switch back. - -/*const byte IndexSetIterator::_first_bit[256] = { - 8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 -}; - -const byte IndexSetIterator::_second_bit[256] = { - 8, 8, 8, 1, 8, 2, 2, 1, 8, 3, 3, 1, 3, 2, 2, 1, - 8, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1, - 8, 5, 5, 1, 5, 2, 2, 1, 5, 3, 3, 1, 3, 2, 2, 1, - 5, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1, - 8, 6, 6, 1, 6, 2, 2, 1, 6, 3, 3, 1, 3, 2, 2, 1, - 6, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1, - 6, 5, 5, 1, 5, 2, 2, 1, 5, 3, 3, 1, 3, 2, 2, 1, - 5, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1, - 8, 7, 7, 1, 7, 2, 2, 1, 7, 3, 3, 1, 3, 2, 2, 1, - 7, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1, - 7, 5, 5, 1, 5, 2, 2, 1, 5, 3, 3, 1, 3, 2, 2, 1, - 5, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1, - 7, 6, 6, 1, 6, 2, 2, 1, 6, 3, 3, 1, 3, 2, 2, 1, - 6, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1, - 6, 5, 5, 1, 5, 2, 2, 1, 5, 3, 3, 1, 3, 2, 2, 1, - 5, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1 -};*/ - //---------------------------- IndexSet::populate_free_list() ----------------------------- // Populate the free BitBlock list with a batch of BitBlocks. The BitBlocks // are 32 bit aligned. diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/opto/indexSet.hpp --- a/src/hotspot/share/opto/indexSet.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/opto/indexSet.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -29,6 +29,7 @@ #include "memory/resourceArea.hpp" #include "opto/compile.hpp" #include "opto/regmask.hpp" +#include "utilities/count_trailing_zeros.hpp" // This file defines the IndexSet class, a set of sparse integer indices. // This data structure is used by the compiler in its liveness analysis and @@ -396,19 +397,6 @@ class IndexSetIterator { friend class IndexSet; - public: - - // We walk over the bits in a word in chunks of size window_size. - enum { window_size = 5, - window_mask = right_n_bits(window_size), - table_size = (1 << window_size) }; - - // For an integer of length window_size, what is the first set bit? - static const uint8_t _first_bit[table_size]; - - // For an integer of length window_size, what is the second set bit? - static const uint8_t _second_bit[table_size]; - private: // The current word we are inspecting uint32_t _current; @@ -440,7 +428,6 @@ // element in the set. uint advance_and_next(); - public: // If an iterator is built from a constant set then empty blocks @@ -452,16 +439,11 @@ uint next() { uint current = _current; if (current != 0) { - uint value = _value; - while (mask_bits(current,window_mask) == 0) { - current >>= window_size; - value += window_size; - } - - uint advance = _second_bit[mask_bits(current,window_mask)]; - _current = current >> advance; - _value = value + advance; - return value + _first_bit[mask_bits(current,window_mask)]; + uint advance = count_trailing_zeros(current); + assert(((current >> advance) & 0x1) == 1, "sanity"); + _current = (current >> advance) - 1; + _value += advance; + return _value; } else { return advance_and_next(); } diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/prims/evmCompat.cpp --- a/src/hotspot/share/prims/evmCompat.cpp Mon Feb 25 15:15:46 2019 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright (c) 1999, 2010, 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. - * - */ - -#include "precompiled.hpp" -#include "utilities/debug.hpp" - -// This file contains definitions for functions that exist -// in the ExactVM, but not in HotSpot. They are stubbed out -// here to prevent linker errors when attempting to use HotSpot -// with the ExactVM jdk. - -extern "C" void JVM_Process_DestroyProcess(void); -extern "C" void JVM_Process_ForkAndExec(void); -extern "C" void JVM_Process_WaitForProcessExit(void); -extern "C" void gc(void); - -void JVM_Process_DestroyProcess(void) { - ShouldNotReachHere(); -} - -void JVM_Process_ForkAndExec(void) { - ShouldNotReachHere(); -} - -void JVM_Process_WaitForProcessExit(void) { - ShouldNotReachHere(); -} - -void gc(void) { - ShouldNotReachHere(); -} diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/prims/jni.cpp --- a/src/hotspot/share/prims/jni.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/prims/jni.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -3953,9 +3953,6 @@ } #endif - // Tracks the time application was running before GC - RuntimeService::record_application_start(); - // Notify JVMTI if (JvmtiExport::should_post_thread_life()) { JvmtiExport::post_thread_start(thread); diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/prims/jvmtiRedefineClasses.cpp --- a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -62,10 +62,11 @@ Method** VM_RedefineClasses::_matching_new_methods = NULL; Method** VM_RedefineClasses::_deleted_methods = NULL; Method** VM_RedefineClasses::_added_methods = NULL; -int VM_RedefineClasses::_matching_methods_length = 0; -int VM_RedefineClasses::_deleted_methods_length = 0; -int VM_RedefineClasses::_added_methods_length = 0; -Klass* VM_RedefineClasses::_the_class = NULL; +int VM_RedefineClasses::_matching_methods_length = 0; +int VM_RedefineClasses::_deleted_methods_length = 0; +int VM_RedefineClasses::_added_methods_length = 0; +bool VM_RedefineClasses::_has_redefined_Object = false; +bool VM_RedefineClasses::_has_null_class_loader = false; VM_RedefineClasses::VM_RedefineClasses(jint class_count, @@ -76,6 +77,9 @@ _class_load_kind = class_load_kind; _any_class_has_resolved_methods = false; _res = JVMTI_ERROR_NONE; + _the_class = NULL; + _has_redefined_Object = false; + _has_null_class_loader = false; } static inline InstanceKlass* get_ik(jclass def) { @@ -214,11 +218,12 @@ // Flush all compiled code that depends on the classes redefined. flush_dependent_code(); - // Clean out MethodData pointing to old Method* + // Adjust constantpool caches and vtables for all classes + // that reference methods of the evolved classes. // Have to do this after all classes are redefined and all methods that // are redefined are marked as old. - MethodDataCleaner clean_weak_method_links; - ClassLoaderDataGraph::classes_do(&clean_weak_method_links); + AdjustAndCleanMetadata adjust_and_clean_metadata(thread); + ClassLoaderDataGraph::classes_do(&adjust_and_clean_metadata); // JSR-292 support if (_any_class_has_resolved_methods) { @@ -3415,25 +3420,35 @@ // Unevolving classes may point to methods of the_class directly // from their constant pool caches, itables, and/or vtables. We // use the ClassLoaderDataGraph::classes_do() facility and this helper -// to fix up these pointers. +// to fix up these pointers. MethodData also points to old methods and +// must be cleaned. // Adjust cpools and vtables closure -void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) { +void VM_RedefineClasses::AdjustAndCleanMetadata::do_klass(Klass* k) { // This is a very busy routine. We don't want too much tracing // printed out. bool trace_name_printed = false; - InstanceKlass *the_class = InstanceKlass::cast(_the_class); // If the class being redefined is java.lang.Object, we need to fix all // array class vtables also - if (k->is_array_klass() && _the_class == SystemDictionary::Object_klass()) { - k->vtable().adjust_method_entries(the_class, &trace_name_printed); + if (k->is_array_klass() && _has_redefined_Object) { + k->vtable().adjust_method_entries(&trace_name_printed); } else if (k->is_instance_klass()) { HandleMark hm(_thread); InstanceKlass *ik = InstanceKlass::cast(k); + // Clean MethodData of this class's methods so they don't refer to + // old methods that are no longer running. + Array* methods = ik->methods(); + int num_methods = methods->length(); + for (int index = 0; index < num_methods; ++index) { + if (methods->at(index)->method_data() != NULL) { + methods->at(index)->method_data()->clean_weak_method_links(); + } + } + // HotSpot specific optimization! HotSpot does not currently // support delegation from the bootstrap class loader to a // user-defined class loader. This means that if the bootstrap @@ -3446,57 +3461,29 @@ // If the current class being redefined has a user-defined class // loader as its defining class loader, then we can skip all // classes loaded by the bootstrap class loader. - bool is_user_defined = (_the_class->class_loader() != NULL); - if (is_user_defined && ik->class_loader() == NULL) { + if (!_has_null_class_loader && ik->class_loader() == NULL) { return; } - // Fix the vtable embedded in the_class and subclasses of the_class, - // if one exists. We discard scratch_class and we don't keep an - // InstanceKlass around to hold obsolete methods so we don't have - // any other InstanceKlass embedded vtables to update. The vtable - // holds the Method*s for virtual (but not final) methods. - // Default methods, or concrete methods in interfaces are stored - // in the vtable, so if an interface changes we need to check - // adjust_method_entries() for every InstanceKlass, which will also - // adjust the default method vtable indices. - // We also need to adjust any default method entries that are - // not yet in the vtable, because the vtable setup is in progress. - // This must be done after we adjust the default_methods and - // default_vtable_indices for methods already in the vtable. - // If redefining Unsafe, walk all the vtables looking for entries. - if (ik->vtable_length() > 0 && (_the_class->is_interface() - || _the_class == SystemDictionary::internal_Unsafe_klass() - || ik->is_subtype_of(_the_class))) { - // ik->vtable() creates a wrapper object; rm cleans it up - ResourceMark rm(_thread); - - ik->vtable().adjust_method_entries(the_class, &trace_name_printed); - ik->adjust_default_methods(the_class, &trace_name_printed); + // Adjust all vtables, default methods and itables, to clean out old methods. + ResourceMark rm(_thread); + if (ik->vtable_length() > 0) { + ik->vtable().adjust_method_entries(&trace_name_printed); + ik->adjust_default_methods(&trace_name_printed); } - // If the current class has an itable and we are either redefining an - // interface or if the current class is a subclass of the_class, then - // we potentially have to fix the itable. If we are redefining an - // interface, then we have to call adjust_method_entries() for - // every InstanceKlass that has an itable since there isn't a - // subclass relationship between an interface and an InstanceKlass. - // If redefining Unsafe, walk all the itables looking for entries. - if (ik->itable_length() > 0 && (_the_class->is_interface() - || _the_class == SystemDictionary::internal_Unsafe_klass() - || ik->is_subclass_of(_the_class))) { - ResourceMark rm(_thread); - ik->itable().adjust_method_entries(the_class, &trace_name_printed); + if (ik->itable_length() > 0) { + ik->itable().adjust_method_entries(&trace_name_printed); } // The constant pools in other classes (other_cp) can refer to - // methods in the_class. We have to update method information in + // old methods. We have to update method information in // other_cp's cache. If other_cp has a previous version, then we // have to repeat the process for each previous version. The // constant pool cache holds the Method*s for non-virtual // methods and for virtual, final methods. // - // Special case: if the current class is the_class, then new_cp + // Special case: if the current class being redefined, then new_cp // has already been attached to the_class and old_cp has already // been added as a previous version. The new_cp doesn't have any // cached references to old methods so it doesn't need to be @@ -3505,12 +3492,12 @@ constantPoolHandle other_cp; ConstantPoolCache* cp_cache; - if (ik != _the_class) { + if (!ik->is_being_redefined()) { // this klass' constant pool cache may need adjustment other_cp = constantPoolHandle(ik->constants()); cp_cache = other_cp->cache(); if (cp_cache != NULL) { - cp_cache->adjust_method_entries(the_class, &trace_name_printed); + cp_cache->adjust_method_entries(&trace_name_printed); } } @@ -3520,23 +3507,7 @@ pv_node = pv_node->previous_versions()) { cp_cache = pv_node->constants()->cache(); if (cp_cache != NULL) { - cp_cache->adjust_method_entries(pv_node, &trace_name_printed); - } - } - } -} - -// Clean method data for this class -void VM_RedefineClasses::MethodDataCleaner::do_klass(Klass* k) { - if (k->is_instance_klass()) { - InstanceKlass *ik = InstanceKlass::cast(k); - // Clean MethodData of this class's methods so they don't refer to - // old methods that are no longer running. - Array* methods = ik->methods(); - int num_methods = methods->length(); - for (int index = 0; index < num_methods; ++index) { - if (methods->at(index)->method_data() != NULL) { - methods->at(index)->method_data()->clean_weak_method_links(); + cp_cache->adjust_method_entries(&trace_name_printed); } } } @@ -3554,6 +3525,15 @@ "should be replaced"); } } + // Update deleted jmethodID + for (int j = 0; j < _deleted_methods_length; ++j) { + Method* old_method = _deleted_methods[j]; + jmethodID jmid = old_method->find_jmethod_id_or_null(); + if (jmid != NULL) { + // Change the jmethodID to point to NSME. + Method::change_method_associated_with_jmethod_id(jmid, Universe::throw_no_such_method_error()); + } + } } int VM_RedefineClasses::check_methods_and_mark_as_obsolete() { @@ -3972,6 +3952,10 @@ InstanceKlass* the_class = get_ik(the_jclass); + // Set some flags to control and optimize adjusting method entries + _has_redefined_Object |= the_class == SystemDictionary::Object_klass(); + _has_null_class_loader |= the_class->class_loader() == NULL; + // Remove all breakpoints in methods of this class JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints(); jvmti_breakpoints.clearall_in_class_at_safepoint(the_class); @@ -4193,11 +4177,6 @@ _timer_rsc_phase2.start(); } - // Adjust constantpool caches and vtables for all classes - // that reference methods of the evolved class. - AdjustCpoolCacheAndVtable adjust_cpool_cache_and_vtable(THREAD); - ClassLoaderDataGraph::classes_do(&adjust_cpool_cache_and_vtable); - if (the_class->oop_map_cache() != NULL) { // Flush references to any obsolete methods from the oop map cache // so that obsolete methods are not pinned. diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/prims/jvmtiRedefineClasses.hpp --- a/src/hotspot/share/prims/jvmtiRedefineClasses.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/prims/jvmtiRedefineClasses.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -338,20 +338,22 @@ class VM_RedefineClasses: public VM_Operation { private: // These static fields are needed by ClassLoaderDataGraph::classes_do() - // facility and the AdjustCpoolCacheAndVtable helper: + // facility and the CheckClass and AdjustAndCleanMetadata helpers. static Array* _old_methods; static Array* _new_methods; - static Method** _matching_old_methods; - static Method** _matching_new_methods; - static Method** _deleted_methods; - static Method** _added_methods; + static Method** _matching_old_methods; + static Method** _matching_new_methods; + static Method** _deleted_methods; + static Method** _added_methods; static int _matching_methods_length; static int _deleted_methods_length; static int _added_methods_length; - static Klass* _the_class; + static bool _has_redefined_Object; + static bool _has_null_class_loader; // The instance fields are used to pass information from // doit_prologue() to doit() and doit_epilogue(). + Klass* _the_class; jint _class_count; const jvmtiClassDefinition *_class_defs; // ptr to _class_count defs @@ -513,20 +515,14 @@ // Unevolving classes may point to methods of the_class directly // from their constant pool caches, itables, and/or vtables. We // use the ClassLoaderDataGraph::classes_do() facility and this helper - // to fix up these pointers. - class AdjustCpoolCacheAndVtable : public KlassClosure { + // to fix up these pointers and clean MethodData out. + class AdjustAndCleanMetadata : public KlassClosure { Thread* _thread; public: - AdjustCpoolCacheAndVtable(Thread* t) : _thread(t) {} + AdjustAndCleanMetadata(Thread* t) : _thread(t) {} void do_klass(Klass* k); }; - // Clean MethodData out - class MethodDataCleaner : public KlassClosure { - public: - MethodDataCleaner() {} - void do_klass(Klass* k); - }; public: VM_RedefineClasses(jint class_count, const jvmtiClassDefinition *class_defs, diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/prims/resolvedMethodTable.cpp --- a/src/hotspot/share/prims/resolvedMethodTable.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/prims/resolvedMethodTable.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, 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 @@ -120,18 +120,21 @@ return entry; } -oop ResolvedMethodTable::add_method(Handle resolved_method_name) { +oop ResolvedMethodTable::add_method(const methodHandle& m, Handle resolved_method_name) { MutexLocker ml(ResolvedMethodTable_lock); DEBUG_ONLY(NoSafepointVerifier nsv); + Method* method = m(); // Check if method has been redefined while taking out ResolvedMethodTable_lock, if so - // use new method. - Method* method = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(resolved_method_name()); - assert(method->is_method(), "must be method"); + // use new method. The old method won't be deallocated because it's passed in as a Handle. if (method->is_old()) { // Replace method with redefined version InstanceKlass* holder = method->method_holder(); method = holder->method_with_idnum(method->method_idnum()); + if (method == NULL) { + // Replace deleted method with NSME. + method = Universe::throw_no_such_method_error(); + } java_lang_invoke_ResolvedMethodName::set_vmtarget(resolved_method_name(), method); } // Set flag in class to indicate this InstanceKlass has entries in the table @@ -226,18 +229,9 @@ if (old_method->is_old()) { - if (old_method->is_deleted()) { - // leave deleted method in ResolvedMethod for now (this is a bug that we don't mark - // these on_stack) - continue; - } - - InstanceKlass* holder = old_method->method_holder(); - Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum()); - assert(holder == new_method->method_holder(), "call after swapping redefined guts"); - assert(new_method != NULL, "method_with_idnum() should not be NULL"); - assert(old_method != new_method, "sanity check"); - + Method* new_method = (old_method->is_deleted()) ? + Universe::throw_no_such_method_error() : + old_method->get_new_method(); java_lang_invoke_ResolvedMethodName::set_vmtarget(mem_name, new_method); ResourceMark rm; diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/prims/resolvedMethodTable.hpp --- a/src/hotspot/share/prims/resolvedMethodTable.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/prims/resolvedMethodTable.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -89,7 +89,7 @@ // Called from java_lang_invoke_ResolvedMethodName static oop find_method(Method* method); - static oop add_method(Handle rmethod_name); + static oop add_method(const methodHandle& method, Handle rmethod_name); static bool has_work() { return _dead_entries; } static void trigger_cleanup(); diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/runtime/init.cpp --- a/src/hotspot/share/runtime/init.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/runtime/init.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -174,10 +174,7 @@ ObjectSynchronizer::audit_and_print_stats(true /* on_exit */); } perfMemory_exit(); - if (log_is_enabled(Debug, safepoint, stats)) { - // Print the collected safepoint statistics. - SafepointSynchronize::print_stat_on_exit(); - } + SafepointTracing::statistics_exit_log(); if (PrintStringTableStatistics) { SymbolTable::dump(tty); StringTable::dump(tty); diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/runtime/mutexLocker.cpp --- a/src/hotspot/share/runtime/mutexLocker.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/runtime/mutexLocker.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -39,6 +39,7 @@ Mutex* Patching_lock = NULL; Monitor* SystemDictionary_lock = NULL; +Mutex* ProtectionDomainSet_lock = NULL; Mutex* SharedDictionary_lock = NULL; Mutex* Module_lock = NULL; Mutex* CompiledIC_lock = NULL; @@ -254,6 +255,7 @@ def(JmethodIdCreation_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_always); // used for creating jmethodIDs. def(SystemDictionary_lock , PaddedMonitor, leaf, true, Monitor::_safepoint_check_always); // lookups done by VM thread + def(ProtectionDomainSet_lock , PaddedMutex , leaf-1, true, Monitor::_safepoint_check_never); def(SharedDictionary_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_always); // lookups done by VM thread def(Module_lock , PaddedMutex , leaf+2, true, Monitor::_safepoint_check_always); def(InlineCacheBuffer_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_never); diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/runtime/mutexLocker.hpp --- a/src/hotspot/share/runtime/mutexLocker.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/runtime/mutexLocker.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -33,6 +33,7 @@ extern Mutex* Patching_lock; // a lock used to guard code patching of compiled code extern Monitor* SystemDictionary_lock; // a lock on the system dictionary +extern Mutex* ProtectionDomainSet_lock; // a lock on the pd_set list in the system dictionary extern Mutex* SharedDictionary_lock; // a lock on the CDS shared dictionary extern Mutex* Module_lock; // a lock on module and package related data structures extern Mutex* CompiledIC_lock; // a lock used to guard compiled IC patching and access diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/runtime/safepoint.cpp --- a/src/hotspot/share/runtime/safepoint.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/runtime/safepoint.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -103,16 +103,6 @@ } } -static void post_safepoint_wait_blocked_event(EventSafepointWaitBlocked& event, - uint64_t safepoint_id, - int initial_threads_waiting_to_block) { - if (event.should_commit()) { - event.set_safepointId(safepoint_id); - event.set_runningThreadCount(initial_threads_waiting_to_block); - event.commit(); - } -} - static void post_safepoint_cleanup_task_event(EventSafepointCleanupTask& event, uint64_t safepoint_id, const char* name) { @@ -138,27 +128,21 @@ volatile uint64_t SafepointSynchronize::_safepoint_counter = 0; const uint64_t SafepointSynchronize::InactiveSafepointCounter = 0; int SafepointSynchronize::_current_jni_active_count = 0; -long SafepointSynchronize::_end_of_last_safepoint = 0; WaitBarrier* SafepointSynchronize::_wait_barrier; -// We need a place to save the desc since it is released before we need it. -static char stopped_description[64] = ""; -static bool _vm_is_waiting = false; - static volatile bool PageArmed = false; // safepoint polling page is RO|RW vs PROT_NONE static bool timeout_error_printed = false; // Statistic related -julong SafepointSynchronize::_coalesced_vmop_count = 0; static jlong _safepoint_begin_time = 0; -static float _ts_of_current_safepoint = 0.0f; static volatile int _nof_threads_hit_polling_page = 0; void SafepointSynchronize::init(Thread* vmthread) { // WaitBarrier should never be destroyed since we will have // threads waiting on it while exiting. _wait_barrier = new WaitBarrier(vmthread); + SafepointTracing::init(); } void SafepointSynchronize::increment_jni_active_count() { @@ -244,16 +228,13 @@ DEBUG_ONLY(assert_list_is_valid(tss_head, still_running);) *initial_running = still_running; - if (log_is_enabled(Debug, safepoint, stats)) { - begin_statistics(nof_threads, still_running); - } int iterations = 1; // The first iteration is above. while (still_running > 0) { // Check if this has taken too long: if (SafepointTimeout && safepoint_limit_time < os::javaTimeNanos()) { - print_safepoint_timeout(_spinning_timeout); + print_safepoint_timeout(); } if (int(iterations) == -1) { // overflow - something is wrong. // We can only overflow here when we are using global @@ -291,9 +272,6 @@ assert(tss_head == NULL, "Must be empty"); - if (log_is_enabled(Debug, safepoint, stats)) { - update_statistics_on_spin_end(); - } return iterations; } @@ -303,8 +281,11 @@ // stopped by different mechanisms: // // 1. Running interpreted - // The interpreter dispatch table is changed to force it to - // check for a safepoint condition between bytecodes. + // When executing branching/returning byte codes interpreter + // checks if the poll is armed, if so blocks in SS::block(). + // When using global polling the interpreter dispatch table + // is changed to force it to check for a safepoint condition + // between bytecodes. // 2. Running in native code // When returning from the native code, a Java thread must check // the safepoint _state to see if we must block. If the @@ -322,9 +303,9 @@ // block condition until the safepoint operation is complete. // 5. In VM or Transitioning between states // If a Java thread is currently running in the VM or transitioning - // between states, the safepointing code will wait for the thread to - // block itself when it attempts transitions to a new state. - // + // between states, the safepointing code will poll the thread state + // until the thread blocks itself when it attempts transitions to a + // new state or locking a safepoint checked monitor. // We must never miss a thread with correct safepoint id, so we must make sure we arm // the wait barrier for the next safepoint id/counter. @@ -363,17 +344,10 @@ // Roll all threads forward to a safepoint and suspend them all void SafepointSynchronize::begin() { - EventSafepointBegin begin_event; assert(Thread::current()->is_VM_thread(), "Only VM thread may execute a safepoint"); - strncpy(stopped_description, VMThread::vm_safepoint_description(), sizeof(stopped_description) - 1); - stopped_description[sizeof(stopped_description) - 1] = '\0'; - - if (log_is_enabled(Debug, safepoint, stats)) { - _safepoint_begin_time = os::javaTimeNanos(); - _ts_of_current_safepoint = tty->time_stamp().seconds(); - _nof_threads_hit_polling_page = 0; - } + EventSafepointBegin begin_event; + SafepointTracing::begin(VMThread::vm_op_type()); Universe::heap()->safepoint_synchronize_begin(); @@ -385,9 +359,9 @@ int nof_threads = Threads::number_of_threads(); - log_debug(safepoint)("Safepoint synchronization initiated using %s wait barrier. (%d threads)", _wait_barrier->description(), nof_threads); + _nof_threads_hit_polling_page = 0; - RuntimeService::record_safepoint_begin(); + log_debug(safepoint)("Safepoint synchronization initiated using %s wait barrier. (%d threads)", _wait_barrier->description(), nof_threads); // Reset the count of active JNI critical threads _current_jni_active_count = 0; @@ -399,9 +373,9 @@ if (SafepointTimeout) { // Set the limit time, so that it can be compared to see if this has taken // too long to complete. - safepoint_limit_time = os::javaTimeNanos() + (jlong)SafepointTimeoutDelay * MICROUNITS; + safepoint_limit_time = SafepointTracing::start_of_safepoint() + (jlong)SafepointTimeoutDelay * (NANOUNITS / MILLIUNITS); + timeout_error_printed = false; } - timeout_error_printed = false; EventSafepointStateSynchronization sync_event; int initial_running = 0; @@ -413,20 +387,13 @@ int iterations = synchronize_threads(safepoint_limit_time, nof_threads, &initial_running); assert(_waiting_to_block == 0, "No thread should be running"); - post_safepoint_synchronize_event(sync_event, _safepoint_counter, initial_running, - _waiting_to_block, iterations); - - // Keep event from now. - EventSafepointWaitBlocked wait_blocked_event; - #ifndef PRODUCT - if (SafepointTimeout) { + if (safepoint_limit_time != 0) { jlong current_time = os::javaTimeNanos(); if (safepoint_limit_time < current_time) { log_warning(safepoint)("# SafepointSynchronize: Finished after " INT64_FORMAT_W(6) " ms", - (int64_t)((current_time - safepoint_limit_time) / MICROUNITS + - (jlong)SafepointTimeoutDelay)); + (int64_t)(current_time - SafepointTracing::start_of_safepoint()) / (NANOUNITS / MILLIUNITS)); } } #endif @@ -438,8 +405,6 @@ OrderAccess::fence(); - post_safepoint_wait_blocked_event(wait_blocked_event, _safepoint_counter, 0); - #ifdef ASSERT // Make sure all the threads were visited. for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur = jtiwh.next(); ) { @@ -450,12 +415,12 @@ // Update the count of active JNI critical regions GCLocker::set_jni_lock_count(_current_jni_active_count); - log_info(safepoint)("Entering safepoint region: %s", stopped_description); + post_safepoint_synchronize_event(sync_event, + _safepoint_counter, + initial_running, + _waiting_to_block, iterations); - RuntimeService::record_safepoint_synchronized(); - if (log_is_enabled(Debug, safepoint, stats)) { - update_statistics_on_sync_end(os::javaTimeNanos()); - } + SafepointTracing::synchronized(nof_threads, initial_running, _nof_threads_hit_polling_page); // We do the safepoint cleanup first since a GC related safepoint // needs cleanup to be completed before running the GC op. @@ -463,12 +428,8 @@ do_cleanup_tasks(); post_safepoint_cleanup_event(cleanup_event, _safepoint_counter); - if (log_is_enabled(Debug, safepoint, stats)) { - // Record how much time spend on the above cleanup tasks - update_statistics_on_cleanup_end(os::javaTimeNanos()); - } - post_safepoint_begin_event(begin_event, _safepoint_counter, nof_threads, _current_jni_active_count); + SafepointTracing::cleanup(); } void SafepointSynchronize::disarm_safepoint() { @@ -520,10 +481,6 @@ } } // ~JavaThreadIteratorWithHandle - log_info(safepoint)("Leaving safepoint region"); - - RuntimeService::record_safepoint_end(); - // Release threads lock, so threads can be created/destroyed again. Threads_lock->unlock(); @@ -539,19 +496,11 @@ uint64_t safepoint_id = _safepoint_counter; assert(Thread::current()->is_VM_thread(), "Only VM thread can execute a safepoint"); - if (log_is_enabled(Debug, safepoint, stats)) { - end_statistics(os::javaTimeNanos()); - } - disarm_safepoint(); - RuntimeService::record_safepoint_epilog(stopped_description); - Universe::heap()->safepoint_synchronize_end(); - // record this time so VMThread can keep track how much time has elapsed - // since last safepoint. - _end_of_last_safepoint = os::javaTimeMillis(); + SafepointTracing::end(); post_safepoint_end_event(event, safepoint_id); } @@ -915,7 +864,7 @@ assert(SafepointSynchronize::is_synchronizing(), "polling encountered outside safepoint synchronization"); } - if (log_is_enabled(Debug, safepoint, stats)) { + if (log_is_enabled(Info, safepoint, stats)) { Atomic::inc(&_nof_threads_hit_polling_page); } @@ -925,7 +874,7 @@ } -void SafepointSynchronize::print_safepoint_timeout(SafepointTimeoutReason reason) { +void SafepointSynchronize::print_safepoint_timeout() { if (!timeout_error_printed) { timeout_error_printed = true; // Print out the thread info which didn't reach the safepoint for debugging @@ -937,20 +886,10 @@ ls.cr(); ls.print_cr("# SafepointSynchronize::begin: Timeout detected:"); - if (reason == _spinning_timeout) { - ls.print_cr("# SafepointSynchronize::begin: Timed out while spinning to reach a safepoint."); - } else if (reason == _blocking_timeout) { - ls.print_cr("# SafepointSynchronize::begin: Timed out while waiting for threads to stop."); - } - + ls.print_cr("# SafepointSynchronize::begin: Timed out while spinning to reach a safepoint."); ls.print_cr("# SafepointSynchronize::begin: Threads which did not reach the safepoint:"); - ThreadSafepointState *cur_state; for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur_thread = jtiwh.next(); ) { - cur_state = cur_thread->safepoint_state(); - - if (cur_thread->thread_state() != _thread_blocked && - ((reason == _spinning_timeout && cur_state->is_running()) || - (reason == _blocking_timeout))) { + if (cur_thread->safepoint_state()->is_running()) { ls.print("# "); cur_thread->print_on(&ls); ls.cr(); @@ -964,11 +903,10 @@ // ShowMessageBoxOnError. if (AbortVMOnSafepointTimeout) { fatal("Safepoint sync time longer than " INTX_FORMAT "ms detected when executing %s.", - SafepointTimeoutDelay, VMThread::vm_safepoint_description()); + SafepointTimeoutDelay, VMThread::vm_operation()->name()); } } - // ------------------------------------------------------------------------------------------------------- // Implementation of ThreadSafepointState @@ -1176,108 +1114,25 @@ } -// -// Statistics & Instrumentations -// -struct SafepointStats { - float _time_stamp; // record when the current safepoint occurs in seconds - int _vmop_type; // tyep of VM operation triggers the safepoint - int _nof_total_threads; // total number of Java threads - int _nof_initial_running_threads; // total number of initially seen running threads - int _nof_threads_wait_to_block; // total number of threads waiting for to block - bool _page_armed; // true if polling page is armed, false otherwise - int _nof_threads_hit_page_trap; // total number of threads hitting the page trap - jlong _time_to_spin; // total time in millis spent in spinning - jlong _time_to_wait_to_block; // total time in millis spent in waiting for to block - jlong _time_to_do_cleanups; // total time in millis spent in performing cleanups - jlong _time_to_sync; // total time in millis spent in getting to _synchronized - jlong _time_to_exec_vmop; // total time in millis spent in vm operation itself -}; - -static const int _statistics_header_count = 30; -static int _cur_stat_index = 0; -static SafepointStats safepoint_stats = {0}; // zero initialize -static SafepointStats* spstat = &safepoint_stats; - -static julong _safepoint_reasons[VM_Operation::VMOp_Terminating]; -static jlong _max_sync_time = 0; -static jlong _max_vmop_time = 0; - -static jlong cleanup_end_time = 0; - -void SafepointSynchronize::begin_statistics(int nof_threads, int nof_running) { - - spstat->_time_stamp = _ts_of_current_safepoint; - - VM_Operation *op = VMThread::vm_operation(); - spstat->_vmop_type = op != NULL ? op->type() : VM_Operation::VMOp_None; - _safepoint_reasons[spstat->_vmop_type]++; - - spstat->_nof_total_threads = nof_threads; - spstat->_nof_initial_running_threads = nof_running; - - // Records the start time of spinning. The real time spent on spinning - // will be adjusted when spin is done. Same trick is applied for time - // spent on waiting for threads to block. - if (nof_running != 0) { - spstat->_time_to_spin = os::javaTimeNanos(); - } else { - spstat->_time_to_spin = 0; - } -} +// ------------------------------------------------------------------------------------------------------- +// Implementation of SafepointTracing -void SafepointSynchronize::update_statistics_on_spin_end() { - jlong cur_time = os::javaTimeNanos(); - - spstat->_nof_threads_wait_to_block = _waiting_to_block; - if (spstat->_nof_initial_running_threads != 0) { - spstat->_time_to_spin = cur_time - spstat->_time_to_spin; - } - - // Records the start time of waiting for to block. Updated when block is done. - if (_waiting_to_block != 0) { - spstat->_time_to_wait_to_block = cur_time; - } else { - spstat->_time_to_wait_to_block = 0; - } -} - -void SafepointSynchronize::update_statistics_on_sync_end(jlong end_time) { - - if (spstat->_nof_threads_wait_to_block != 0) { - spstat->_time_to_wait_to_block = end_time - - spstat->_time_to_wait_to_block; - } +jlong SafepointTracing::_last_safepoint_begin_time_ns = 0; +jlong SafepointTracing::_last_safepoint_sync_time_ns = 0; +jlong SafepointTracing::_last_safepoint_cleanup_time_ns = 0; +jlong SafepointTracing::_last_safepoint_end_time_ns = 0; +jlong SafepointTracing::_last_app_time_ns = 0; +int SafepointTracing::_nof_threads = 0; +int SafepointTracing::_nof_running = 0; +int SafepointTracing::_page_trap = 0; +VM_Operation::VMOp_Type SafepointTracing::_current_type; +jlong SafepointTracing::_max_sync_time = 0; +jlong SafepointTracing::_max_vmop_time = 0; +uint64_t SafepointTracing::_op_count[VM_Operation::VMOp_Terminating] = {0}; - // Records the end time of sync which will be used to calculate the total - // vm operation time. Again, the real time spending in syncing will be deducted - // from the start of the sync time later when end_statistics is called. - spstat->_time_to_sync = end_time - _safepoint_begin_time; - if (spstat->_time_to_sync > _max_sync_time) { - _max_sync_time = spstat->_time_to_sync; - } - - spstat->_time_to_do_cleanups = end_time; -} - -void SafepointSynchronize::update_statistics_on_cleanup_end(jlong end_time) { - - // Record how long spent in cleanup tasks. - spstat->_time_to_do_cleanups = end_time - spstat->_time_to_do_cleanups; - cleanup_end_time = end_time; -} - -void SafepointSynchronize::end_statistics(jlong vmop_end_time) { - - // Update the vm operation time. - spstat->_time_to_exec_vmop = vmop_end_time - cleanup_end_time; - if (spstat->_time_to_exec_vmop > _max_vmop_time) { - _max_vmop_time = spstat->_time_to_exec_vmop; - } - - spstat->_nof_threads_hit_page_trap = _nof_threads_hit_polling_page; - - print_statistics(); +void SafepointTracing::init() { + // Application start + _last_safepoint_end_time_ns = os::javaTimeNanos(); } // Helper method to print the header. @@ -1285,66 +1140,121 @@ // The number of spaces is significant here, and should match the format // specifiers in print_statistics(). - st->print(" vmop " - "[ threads: total initially_running wait_to_block ]" - "[ time: spin block sync cleanup vmop ] "); + st->print("VM Operation " + "[ threads: total initial_running ]" + "[ time: sync cleanup vmop total ]"); - st->print_cr("page_trap_count"); + st->print_cr(" page_trap_count"); } // This prints a nice table. To get the statistics to not shift due to the logging uptime -// decorator, use the option as: -Xlog:safepoint+stats=debug:[outputfile]:none -void SafepointSynchronize::print_statistics() { - LogTarget(Debug, safepoint, stats) lt; +// decorator, use the option as: -Xlog:safepoint+stats:[outputfile]:none +void SafepointTracing::statistics_log() { + LogTarget(Info, safepoint, stats) lt; assert (lt.is_enabled(), "should only be called when printing statistics is enabled"); LogStream ls(lt); + static int _cur_stat_index = 0; + // Print header every 30 entries - if ((_cur_stat_index % _statistics_header_count) == 0) { + if ((_cur_stat_index % 30) == 0) { print_header(&ls); _cur_stat_index = 1; // wrap } else { _cur_stat_index++; } - ls.print("%8.3f: ", spstat->_time_stamp); - ls.print("%-28s [ " - INT32_FORMAT_W(8) " " INT32_FORMAT_W(17) " " INT32_FORMAT_W(13) " " + ls.print("%-28s [ " + INT32_FORMAT_W(8) " " INT32_FORMAT_W(8) " " "]", - VM_Operation::name(spstat->_vmop_type), - spstat->_nof_total_threads, - spstat->_nof_initial_running_threads, - spstat->_nof_threads_wait_to_block); - // "/ MICROUNITS " is to convert the unit from nanos to millis. + VM_Operation::name(_current_type), + _nof_threads, + _nof_running); ls.print("[ " - INT64_FORMAT_W(7) " " INT64_FORMAT_W(7) " " - INT64_FORMAT_W(7) " " INT64_FORMAT_W(7) " " - INT64_FORMAT_W(7) " ] ", - (int64_t)(spstat->_time_to_spin / MICROUNITS), - (int64_t)(spstat->_time_to_wait_to_block / MICROUNITS), - (int64_t)(spstat->_time_to_sync / MICROUNITS), - (int64_t)(spstat->_time_to_do_cleanups / MICROUNITS), - (int64_t)(spstat->_time_to_exec_vmop / MICROUNITS)); + INT64_FORMAT_W(10) " " INT64_FORMAT_W(10) " " + INT64_FORMAT_W(10) " " INT64_FORMAT_W(10) " ]", + (int64_t)(_last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns), + (int64_t)(_last_safepoint_cleanup_time_ns - _last_safepoint_sync_time_ns), + (int64_t)(_last_safepoint_end_time_ns - _last_safepoint_cleanup_time_ns), + (int64_t)(_last_safepoint_end_time_ns - _last_safepoint_begin_time_ns)); - ls.print_cr(INT32_FORMAT_W(15) " ", spstat->_nof_threads_hit_page_trap); + ls.print_cr(INT32_FORMAT_W(16), _page_trap); } // This method will be called when VM exits. This tries to summarize the sampling. // Current thread may already be deleted, so don't use ResourceMark. -void SafepointSynchronize::print_stat_on_exit() { - +void SafepointTracing::statistics_exit_log() { + if (!log_is_enabled(Info, safepoint, stats)) { + return; + } for (int index = 0; index < VM_Operation::VMOp_Terminating; index++) { - if (_safepoint_reasons[index] != 0) { - log_debug(safepoint, stats)("%-28s" UINT64_FORMAT_W(10), VM_Operation::name(index), - _safepoint_reasons[index]); + if (_op_count[index] != 0) { + log_info(safepoint, stats)("%-28s" UINT64_FORMAT_W(10), VM_Operation::name(index), + _op_count[index]); } } - log_debug(safepoint, stats)("VM operations coalesced during safepoint " INT64_FORMAT, - _coalesced_vmop_count); - log_debug(safepoint, stats)("Maximum sync time " INT64_FORMAT" ms", - (int64_t)(_max_sync_time / MICROUNITS)); - log_debug(safepoint, stats)("Maximum vm operation time (except for Exit VM operation) " - INT64_FORMAT " ms", - (int64_t)(_max_vmop_time / MICROUNITS)); + log_info(safepoint, stats)("VM operations coalesced during safepoint " INT64_FORMAT, + VMThread::get_coalesced_count()); + log_info(safepoint, stats)("Maximum sync time " INT64_FORMAT" ns", + (int64_t)(_max_sync_time)); + log_info(safepoint, stats)("Maximum vm operation time (except for Exit VM operation) " + INT64_FORMAT " ns", + (int64_t)(_max_vmop_time)); +} + +void SafepointTracing::begin(VM_Operation::VMOp_Type type) { + _op_count[type]++; + _current_type = type; + + // update the time stamp to begin recording safepoint time + _last_safepoint_begin_time_ns = os::javaTimeNanos(); + _last_safepoint_sync_time_ns = 0; + _last_safepoint_cleanup_time_ns = 0; + + _last_app_time_ns = _last_safepoint_begin_time_ns - _last_safepoint_end_time_ns; + _last_safepoint_end_time_ns = 0; + + RuntimeService::record_safepoint_begin(_last_app_time_ns); +} + +void SafepointTracing::synchronized(int nof_threads, int nof_running, int traps) { + _last_safepoint_sync_time_ns = os::javaTimeNanos(); + _nof_threads = nof_threads; + _nof_running = nof_running; + _page_trap = traps; + RuntimeService::record_safepoint_synchronized(_last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns); } + +void SafepointTracing::cleanup() { + _last_safepoint_cleanup_time_ns = os::javaTimeNanos(); +} + +void SafepointTracing::end() { + _last_safepoint_end_time_ns = os::javaTimeNanos(); + + if (_max_sync_time < (_last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns)) { + _max_sync_time = _last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns; + } + if (_max_vmop_time < (_last_safepoint_end_time_ns - _last_safepoint_sync_time_ns)) { + _max_vmop_time = _last_safepoint_end_time_ns - _last_safepoint_sync_time_ns; + } + if (log_is_enabled(Info, safepoint, stats)) { + statistics_log(); + } + + log_info(safepoint)( + "Safepoint \"%s\", " + "Time since last: " JLONG_FORMAT " ns, " + "Reaching safepoint: " JLONG_FORMAT " ns, " + "At safepoint: " JLONG_FORMAT " ns, " + "Total: " JLONG_FORMAT " ns", + VM_Operation::name(_current_type), + _last_app_time_ns, + _last_safepoint_cleanup_time_ns - _last_safepoint_begin_time_ns, + _last_safepoint_end_time_ns - _last_safepoint_cleanup_time_ns, + _last_safepoint_end_time_ns - _last_safepoint_begin_time_ns + ); + + RuntimeService::record_safepoint_end(_last_safepoint_end_time_ns - _last_safepoint_cleanup_time_ns); +} diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/runtime/safepoint.hpp --- a/src/hotspot/share/runtime/safepoint.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/runtime/safepoint.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -28,6 +28,7 @@ #include "memory/allocation.hpp" #include "runtime/os.hpp" #include "runtime/thread.hpp" +#include "runtime/vmOperations.hpp" #include "utilities/ostream.hpp" #include "utilities/waitBarrier.hpp" @@ -77,11 +78,6 @@ friend class ThreadSafepointState; friend class HandshakeState; - enum SafepointTimeoutReason { - _spinning_timeout = 0, - _blocking_timeout = 1 - }; - // Threads might read this flag directly, without acquiring the Threads_lock: static volatile SynchronizeState _state; // Number of threads we are waiting for to block: @@ -110,7 +106,7 @@ static void print_statistics(); // For debug long safepoint - static void print_safepoint_timeout(SafepointTimeoutReason timeout_reason); + static void print_safepoint_timeout(); // Helper methods for safepoint procedure: static void arm_safepoint(); @@ -150,19 +146,9 @@ // Exception handling for page polling static void handle_polling_page_exception(JavaThread *thread); - // VM Thread interface for determining safepoint rate - static long last_non_safepoint_interval() { - return os::javaTimeMillis() - _end_of_last_safepoint; - } - static long end_of_last_safepoint() { - return _end_of_last_safepoint; - } static bool is_cleanup_needed(); static void do_cleanup_tasks(); - static void print_stat_on_exit(); - static void inc_vmop_coalesced_count() { _coalesced_vmop_count++; } - static void set_is_at_safepoint() { _state = _synchronized; } static void set_is_not_at_safepoint() { _state = _not_synchronized; } @@ -247,6 +233,48 @@ static void destroy(JavaThread *thread); }; +class SafepointTracing : public AllStatic { +private: + // Absolute + static jlong _last_safepoint_begin_time_ns; + static jlong _last_safepoint_sync_time_ns; + static jlong _last_safepoint_cleanup_time_ns; + static jlong _last_safepoint_end_time_ns; + // Relative + static jlong _last_app_time_ns; + static int _nof_threads; + static int _nof_running; + static int _page_trap; + + static VM_Operation::VMOp_Type _current_type; + static jlong _max_sync_time; + static jlong _max_vmop_time; + static uint64_t _op_count[VM_Operation::VMOp_Terminating]; + + static void statistics_log(); + +public: + static void init(); + + static void begin(VM_Operation::VMOp_Type type); + static void synchronized(int nof_threads, int nof_running, int traps); + static void cleanup(); + static void end(); + + static void statistics_exit_log(); + + static jlong time_since_last_safepoint_ms() { + return (os::javaTimeNanos() - _last_safepoint_end_time_ns) / (NANOUNITS / MILLIUNITS); + } + + static jlong end_of_last_safepoint_ms() { + return _last_safepoint_end_time_ns / (NANOUNITS / MILLIUNITS); + } + + static jlong start_of_safepoint() { + return _last_safepoint_begin_time_ns; + } +}; #endif // SHARE_RUNTIME_SAFEPOINT_HPP diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/runtime/sharedRuntime.cpp --- a/src/hotspot/share/runtime/sharedRuntime.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/runtime/sharedRuntime.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2019, 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 @@ -1376,13 +1376,17 @@ } #endif - // Do not patch call site for static call when the class is not - // fully initialized. + // Do not patch call site for static call to another class + // when the class is not fully initialized. if (invoke_code == Bytecodes::_invokestatic && - !callee_method->method_holder()->is_initialized()) { + !callee_method->method_holder()->is_initialized() && + callee_method->method_holder() != caller_nm->method()->method_holder()) { assert(callee_method->method_holder()->is_linked(), "must be"); return callee_method; } + assert(callee_method->method_holder()->is_initialized() || + callee_method->method_holder()->is_reentrant_initialization(thread), + "invalid class initalization state"); // JSR 292 key invariant: // If the resolved method is a MethodHandle invoke target, the call diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/runtime/tieredThresholdPolicy.cpp --- a/src/hotspot/share/runtime/tieredThresholdPolicy.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/runtime/tieredThresholdPolicy.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -479,7 +479,7 @@ // We don't update the rate if we've just came out of a safepoint. // delta_s is the time since last safepoint in milliseconds. - jlong delta_s = t - SafepointSynchronize::end_of_last_safepoint(); + jlong delta_s = t - SafepointTracing::end_of_last_safepoint_ms(); jlong delta_t = t - (m->prev_time() != 0 ? m->prev_time() : start_time()); // milliseconds since the last measurement // How many events were there since the last time? int event_count = m->invocation_count() + m->backedge_count(); @@ -504,7 +504,7 @@ // Check if this method has been stale from a given number of milliseconds. // See select_task(). bool TieredThresholdPolicy::is_stale(jlong t, jlong timeout, Method* m) { - jlong delta_s = t - SafepointSynchronize::end_of_last_safepoint(); + jlong delta_s = t - SafepointTracing::end_of_last_safepoint_ms(); jlong delta_t = t - m->prev_time(); if (delta_t > timeout && delta_s > timeout) { int event_count = m->invocation_count() + m->backedge_count(); diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/runtime/vmOperations.hpp --- a/src/hotspot/share/runtime/vmOperations.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/runtime/vmOperations.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -41,6 +41,7 @@ // Note: When new VM_XXX comes up, add 'XXX' to the template table. #define VM_OPS_DO(template) \ template(None) \ + template(Cleanup) \ template(ThreadStop) \ template(ThreadDump) \ template(PrintThreads) \ @@ -213,7 +214,7 @@ // Debugging virtual void print_on_error(outputStream* st) const; - const char* name() const { return _names[type()]; } + virtual const char* name() const { return _names[type()]; } static const char* name(int type) { assert(type >= 0 && type < VMOp_Terminating, "invalid VM operation type"); return _names[type]; @@ -223,6 +224,21 @@ #endif }; +class VM_None: public VM_Operation { + const char* _reason; + public: + VM_None(const char* reason) : _reason(reason) {} + const char* name() const { return _reason; } + VMOp_Type type() const { return VMOp_None; } + void doit() {}; +}; + +class VM_Cleanup: public VM_Operation { + public: + VMOp_Type type() const { return VMOp_Cleanup; } + void doit() {}; +}; + class VM_ThreadStop: public VM_Operation { private: oop _thread; // The Thread that the Throwable is thrown against diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/runtime/vmThread.cpp --- a/src/hotspot/share/runtime/vmThread.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/runtime/vmThread.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -48,19 +48,13 @@ #include "utilities/vmError.hpp" #include "utilities/xmlstream.hpp" -// Dummy VM operation to act as first element in our circular double-linked list -class VM_None: public VM_Operation { - VMOp_Type type() const { return VMOp_None; } - void doit() {}; -}; - VMOperationQueue::VMOperationQueue() { // The queue is a circular doubled-linked list, which always contains // one element (i.e., one element means empty). for(int i = 0; i < nof_priorities; i++) { _queue_length[i] = 0; _queue_counter = 0; - _queue[i] = new VM_None(); + _queue[i] = new VM_None("QueueHead"); _queue[i]->set_next(_queue[i]); _queue[i]->set_prev(_queue[i]); } @@ -229,14 +223,14 @@ //------------------------------------------------------------------------------------------------------------------ // Implementation of VMThread stuff -bool VMThread::_should_terminate = false; +bool VMThread::_should_terminate = false; bool VMThread::_terminated = false; Monitor* VMThread::_terminate_lock = NULL; VMThread* VMThread::_vm_thread = NULL; VM_Operation* VMThread::_cur_vm_operation = NULL; VMOperationQueue* VMThread::_vm_queue = NULL; PerfCounter* VMThread::_perf_accumulated_vm_operation_time = NULL; -const char* VMThread::_no_op_reason = NULL; +uint64_t VMThread::_coalesced_count = 0; VMOperationTimeoutTask* VMThread::_timeout_task = NULL; @@ -283,6 +277,8 @@ _vm_thread = NULL; // VM thread is gone } +static VM_None halt_op("Halt"); + void VMThread::run() { assert(this == vm_thread(), "check"); @@ -320,7 +316,7 @@ } // 4526887 let VM thread exit at Safepoint - _no_op_reason = "Halt"; + _cur_vm_operation = &halt_op; SafepointSynchronize::begin(); if (VerifyBeforeExit) { @@ -435,24 +431,25 @@ } } -bool VMThread::no_op_safepoint_needed(bool check_time) { +static VM_None safepointALot_op("SafepointALot"); +static VM_Cleanup cleanup_op; + +VM_Operation* VMThread::no_op_safepoint(bool check_time) { if (SafepointALot) { - _no_op_reason = "SafepointALot"; - return true; + return &safepointALot_op; } if (!SafepointSynchronize::is_cleanup_needed()) { - return false; + return NULL; } if (check_time) { - long interval = SafepointSynchronize::last_non_safepoint_interval(); + long interval_ms = SafepointTracing::time_since_last_safepoint_ms(); bool max_time_exceeded = GuaranteedSafepointInterval != 0 && - (interval > GuaranteedSafepointInterval); + (interval_ms > GuaranteedSafepointInterval); if (!max_time_exceeded) { - return false; + return NULL; } } - _no_op_reason = "Cleanup"; - return true; + return &cleanup_op; } void VMThread::loop() { @@ -494,7 +491,7 @@ exit(-1); } - if (timedout && VMThread::no_op_safepoint_needed(false)) { + if (timedout && (_cur_vm_operation = VMThread::no_op_safepoint(false)) != NULL) { MutexUnlockerEx mul(VMOperationQueue_lock, Mutex::_no_safepoint_check_flag); // Force a safepoint since we have not had one for at least @@ -506,6 +503,7 @@ if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot(); #endif SafepointSynchronize::end(); + _cur_vm_operation = NULL; } _cur_vm_operation = _vm_queue->remove_next(); @@ -555,9 +553,7 @@ _vm_queue->set_drain_list(next); evaluate_operation(_cur_vm_operation); _cur_vm_operation = next; - if (log_is_enabled(Debug, safepoint, stats)) { - SafepointSynchronize::inc_vmop_coalesced_count(); - } + _coalesced_count++; } while (_cur_vm_operation != NULL); } // There is a chance that a thread enqueued a safepoint op @@ -622,10 +618,11 @@ // // We want to make sure that we get to a safepoint regularly. // - if (VMThread::no_op_safepoint_needed(true)) { + if ((_cur_vm_operation = VMThread::no_op_safepoint(false)) != NULL) { HandleMark hm(VMThread::vm_thread()); SafepointSynchronize::begin(); SafepointSynchronize::end(); + _cur_vm_operation = NULL; } } } diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/runtime/vmThread.hpp --- a/src/hotspot/share/runtime/vmThread.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/runtime/vmThread.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -119,12 +119,11 @@ static bool _terminated; static Monitor * _terminate_lock; static PerfCounter* _perf_accumulated_vm_operation_time; - - static const char* _no_op_reason; + static uint64_t _coalesced_count; static VMOperationTimeoutTask* _timeout_task; - static bool no_op_safepoint_needed(bool check_time); + static VM_Operation* no_op_safepoint(bool check_time); void evaluate_operation(VM_Operation* op); @@ -155,9 +154,8 @@ // Returns the current vm operation if any. static VM_Operation* vm_operation() { return _cur_vm_operation; } - - // Returns the current vm operation name or set reason - static const char* vm_safepoint_description() { return _cur_vm_operation != NULL ? _cur_vm_operation->name() : _no_op_reason; }; + static VM_Operation::VMOp_Type vm_op_type() { return _cur_vm_operation->type(); } + static uint64_t get_coalesced_count() { return _coalesced_count; } // Returns the single instance of VMThread. static VMThread* vm_thread() { return _vm_thread; } diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/services/diagnosticArgument.cpp --- a/src/hotspot/share/services/diagnosticArgument.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/services/diagnosticArgument.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -180,7 +180,7 @@ _value = NULL; } else { _value = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal); - int n = snprintf(_value, len + 1, "%.*s", (int)len, str); + int n = os::snprintf(_value, len + 1, "%.*s", (int)len, str); assert((size_t)n <= len, "Unexpected number of characters in string"); } } diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/services/runtimeService.cpp --- a/src/hotspot/share/services/runtimeService.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/services/runtimeService.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -25,7 +25,7 @@ #include "precompiled.hpp" #include "classfile/classLoader.hpp" #include "logging/log.hpp" -#include "runtime/timer.hpp" +#include "logging/logStream.hpp" #include "runtime/vm_version.hpp" #include "services/attachListener.hpp" #include "services/management.hpp" @@ -35,18 +35,12 @@ #include "utilities/macros.hpp" #if INCLUDE_MANAGEMENT -TimeStamp RuntimeService::_app_timer; -TimeStamp RuntimeService::_safepoint_timer; PerfCounter* RuntimeService::_sync_time_ticks = NULL; PerfCounter* RuntimeService::_total_safepoints = NULL; PerfCounter* RuntimeService::_safepoint_time_ticks = NULL; PerfCounter* RuntimeService::_application_time_ticks = NULL; -jlong RuntimeService::_last_safepoint_sync_time_ns = 0; -jlong RuntimeService::_last_safepoint_end_time_ns = 0; -jlong RuntimeService::_last_app_time_ns = 0; void RuntimeService::init() { - if (UsePerfData) { EXCEPTION_MARK; @@ -87,85 +81,27 @@ } } -void RuntimeService::record_safepoint_begin() { +void RuntimeService::record_safepoint_begin(jlong app_ticks) { HS_PRIVATE_SAFEPOINT_BEGIN(); - - // Print the time interval in which the app was executing - if (_app_timer.is_updated()) { - _last_app_time_ns = _app_timer.ticks_since_update(); - log_info(safepoint)("Application time: %3.7f seconds", TimeHelper::counter_to_seconds(_last_app_time_ns)); - } - - // update the time stamp to begin recording safepoint time - _last_safepoint_sync_time_ns = 0; - _last_safepoint_end_time_ns = 0; - _safepoint_timer.update(); if (UsePerfData) { _total_safepoints->inc(); - if (_app_timer.is_updated()) { - _application_time_ticks->inc(_app_timer.ticks_since_update()); - } - } -} - -void RuntimeService::record_safepoint_synchronized() { - if (UsePerfData) { - _sync_time_ticks->inc(_safepoint_timer.ticks_since_update()); - } - if (log_is_enabled(Info, safepoint) || log_is_enabled(Info, safepoint, stats)) { - _last_safepoint_sync_time_ns = _safepoint_timer.ticks_since_update(); + _application_time_ticks->inc(app_ticks); } } -void RuntimeService::record_safepoint_end() { - HS_PRIVATE_SAFEPOINT_END(); - - // Logging of safepoint+stats=info needs _last_safepoint_end_time_ns to be set. - // Logging of safepoint=info needs _last_safepoint_end_time_ns for following log. - if (log_is_enabled(Info, safepoint) || log_is_enabled(Info, safepoint, stats)) { - _last_safepoint_end_time_ns = _safepoint_timer.ticks_since_update(); - log_info(safepoint)( - "Total time for which application threads were stopped: %3.7f seconds, " - "Stopping threads took: %3.7f seconds", - TimeHelper::counter_to_seconds(_last_safepoint_end_time_ns), - TimeHelper::counter_to_seconds(_last_safepoint_sync_time_ns)); - } - - // update the time stamp to begin recording app time - _app_timer.update(); +void RuntimeService::record_safepoint_synchronized(jlong sync_ticks) { if (UsePerfData) { - _safepoint_time_ticks->inc(_safepoint_timer.ticks_since_update()); + _sync_time_ticks->inc(sync_ticks); } } -void RuntimeService::record_safepoint_epilog(const char* operation_name) { - if (!log_is_enabled(Info, safepoint, stats)) { - return; +void RuntimeService::record_safepoint_end(jlong safepoint_ticks) { + HS_PRIVATE_SAFEPOINT_END(); + if (UsePerfData) { + _safepoint_time_ticks->inc(safepoint_ticks); } - - log_info(safepoint, stats)( - "Safepoint \"%s\", " - "Time since last: " JLONG_FORMAT " ns; " - "Reaching safepoint: " JLONG_FORMAT " ns; " - "At safepoint: " JLONG_FORMAT " ns; " - "Total: " JLONG_FORMAT " ns", - operation_name, - _last_app_time_ns, - _last_safepoint_sync_time_ns, - _last_safepoint_end_time_ns - _last_safepoint_sync_time_ns, - _last_safepoint_end_time_ns - ); } -void RuntimeService::record_application_start() { - // update the time stamp to begin recording app time - _app_timer.update(); -} - -// Don't need to record application end because we currently -// exit at a safepoint and record_safepoint_begin() handles updating -// the application time counter at VM exit. - jlong RuntimeService::safepoint_sync_time_ms() { return UsePerfData ? Management::ticks_to_ms(_sync_time_ticks->get_value()) : -1; diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/services/runtimeService.hpp --- a/src/hotspot/share/services/runtimeService.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/services/runtimeService.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -35,12 +35,6 @@ static PerfCounter* _safepoint_time_ticks; // Accumulated time at safepoints static PerfCounter* _application_time_ticks; // Accumulated time not at safepoints - static TimeStamp _safepoint_timer; - static TimeStamp _app_timer; - static jlong _last_safepoint_sync_time_ns; - static jlong _last_safepoint_end_time_ns; - static jlong _last_app_time_ns; - public: static void init(); @@ -50,12 +44,9 @@ static jlong application_time_ms(); // callbacks - static void record_safepoint_begin() NOT_MANAGEMENT_RETURN; - static void record_safepoint_synchronized() NOT_MANAGEMENT_RETURN; - static void record_safepoint_end() NOT_MANAGEMENT_RETURN; - static void record_safepoint_epilog(const char* operation_name) NOT_MANAGEMENT_RETURN; - static void record_application_start() NOT_MANAGEMENT_RETURN; - + static void record_safepoint_begin(jlong app_ticks) NOT_MANAGEMENT_RETURN; + static void record_safepoint_synchronized(jlong sync_ticks) NOT_MANAGEMENT_RETURN; + static void record_safepoint_end(jlong safepoint_ticks) NOT_MANAGEMENT_RETURN; }; #endif // SHARE_SERVICES_RUNTIMESERVICE_HPP diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/utilities/debug.cpp --- a/src/hotspot/share/utilities/debug.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/utilities/debug.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -643,6 +643,7 @@ tty->print_cr(" pns($sp, $rbp, $pc) on Linux/amd64 and Solaris/amd64 or"); tty->print_cr(" pns($sp, $ebp, $pc) on Linux/x86 or"); tty->print_cr(" pns($sp, 0, $pc) on Linux/ppc64 or"); + tty->print_cr(" pns($sp, $s8, $pc) on Linux/mips or"); tty->print_cr(" pns($sp + 0x7ff, 0, $pc) on Solaris/SPARC"); tty->print_cr(" - in gdb do 'set overload-resolution off' before calling pns()"); tty->print_cr(" - in dbx do 'frame 1' before calling pns()"); diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/utilities/intHisto.cpp --- a/src/hotspot/share/utilities/intHisto.cpp Mon Feb 25 15:15:46 2019 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2001, 2012, 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. - * - */ - -#include "precompiled.hpp" -#include "utilities/intHisto.hpp" - -IntHistogram::IntHistogram(int est, int max) : _max(max), _tot(0) { - assert(0 <= est && est <= max, "Preconditions"); - _elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray(est, true); - guarantee(_elements != NULL, "alloc failure"); -} - -void IntHistogram::add_entry(int outcome) { - if (outcome > _max) outcome = _max; - int new_count = _elements->at_grow(outcome) + 1; - _elements->at_put(outcome, new_count); - _tot++; -} - -int IntHistogram::entries_for_outcome(int outcome) { - return _elements->at_grow(outcome); -} - -void IntHistogram::print_on(outputStream* st) const { - double tot_d = (double)_tot; - st->print_cr("Outcome # of occurrences %% of occurrences"); - st->print_cr("-----------------------------------------------"); - for (int i=0; i < _elements->length()-2; i++) { - int cnt = _elements->at(i); - if (cnt != 0) { - st->print_cr("%7d %10d %8.4f", - i, cnt, (double)cnt/tot_d); - } - } - // Does it have any max entries? - if (_elements->length()-1 == _max) { - int cnt = _elements->at(_max); - st->print_cr(">= %4d %10d %8.4f", - _max, cnt, (double)cnt/tot_d); - } - st->print_cr("-----------------------------------------------"); - st->print_cr(" All %10d %8.4f", _tot, 1.0); -} diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/utilities/intHisto.hpp --- a/src/hotspot/share/utilities/intHisto.hpp Mon Feb 25 15:15:46 2019 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2001, 2019, 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. - * - */ - -#ifndef SHARE_UTILITIES_INTHISTO_HPP -#define SHARE_UTILITIES_INTHISTO_HPP - -#include "memory/allocation.hpp" -#include "utilities/growableArray.hpp" - -// This class implements a simple histogram. - -// A histogram summarizes a series of "measurements", each of which is -// assumed (required in this implementation) to have an outcome that is a -// non-negative integer. The histogram efficiently maps measurement outcomes -// to the number of measurements had that outcome. - -// To print the results, invoke print() on your Histogram*. - -// Note: there is already an existing "Histogram" class, in file -// histogram.{hpp,cpp}, but to my mind that's not a histogram, it's a table -// mapping strings to counts. To be a histogram (IMHO) it needs to map -// numbers (in fact, integers) to number of occurrences of that number. - -// ysr: (i am not sure i agree with the above note.) i suspect we want to have a -// histogram template that will map an arbitrary type (with a defined order -// relation) to a count. - - -class IntHistogram : public CHeapObj { - protected: - int _max; - int _tot; - GrowableArray* _elements; - -public: - // Create a new, empty table. "est" is an estimate of the maximum outcome - // that will be added, and "max" is an outcome such that all outcomes at - // least that large will be bundled with it. - IntHistogram(int est, int max); - // Add a measurement with the given outcome to the sequence. - void add_entry(int outcome); - // Return the number of entries recorded so far with the given outcome. - int entries_for_outcome(int outcome); - // Return the total number of entries recorded so far. - int total_entries() { return _tot; } - // Return the number of entries recorded so far with the given outcome as - // a fraction of the total number recorded so far. - double fraction_for_outcome(int outcome) { - return - (double)entries_for_outcome(outcome)/ - (double)total_entries(); - } - // Print the histogram on the given output stream. - void print_on(outputStream* st) const; -}; - -#endif // SHARE_UTILITIES_INTHISTO_HPP diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/utilities/ostream.cpp --- a/src/hotspot/share/utilities/ostream.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/utilities/ostream.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2019, 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 @@ -559,18 +559,6 @@ fflush(_file); } -fdStream::fdStream(const char* file_name) { - _fd = open(file_name, O_WRONLY | O_CREAT | O_TRUNC, 0666); - _need_close = true; -} - -fdStream::~fdStream() { - if (_fd != -1) { - if (_need_close) close(_fd); - _fd = -1; - } -} - void fdStream::write(const char* s, size_t len) { if (_fd != -1) { // Make an unused local variable to avoid warning from gcc 4.x compiler. diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/utilities/ostream.hpp --- a/src/hotspot/share/utilities/ostream.hpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/utilities/ostream.hpp Fri Mar 01 17:27:28 2019 +0530 @@ -216,7 +216,6 @@ fileStream(FILE* file, bool need_close = false) { _file = file; _need_close = need_close; } ~fileStream(); bool is_open() const { return _file != NULL; } - void set_need_close(bool b) { _need_close = b;} virtual void write(const char* c, size_t len); size_t read(void *data, size_t size, size_t count) { return ::fread(data, size, count, _file); } char* readln(char *data, int count); @@ -235,13 +234,10 @@ class fdStream : public outputStream { protected: int _fd; - bool _need_close; public: - fdStream(const char* file_name); - fdStream(int fd = -1) { _fd = fd; _need_close = false; } - ~fdStream(); + fdStream(int fd = -1) : _fd(fd) { } bool is_open() const { return _fd != -1; } - void set_fd(int fd) { _fd = fd; _need_close = false; } + void set_fd(int fd) { _fd = fd; } int fd() const { return _fd; } virtual void write(const char* c, size_t len); void flush() {}; diff -r 268875216dfc -r faf96b92a47b src/hotspot/share/utilities/xmlstream.cpp --- a/src/hotspot/share/utilities/xmlstream.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/hotspot/share/utilities/xmlstream.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -356,11 +356,11 @@ size_t kind_len; if (kind_end != NULL) { kind_len = kind_end - kind; - int n = snprintf(buffer, sizeof(buffer), "%.*s_done", (int)kind_len, kind); + int n = os::snprintf(buffer, sizeof(buffer), "%.*s_done", (int)kind_len, kind); assert((size_t)n < sizeof(buffer), "Unexpected number of characters in string"); } else { kind_len = format_len; - int n = snprintf(buffer, sizeof(buffer), "%s_done%s", kind, kind + kind_len); + int n = os::snprintf(buffer, sizeof(buffer), "%s_done%s", kind, kind + kind_len); assert((size_t)n < sizeof(buffer), "Unexpected number of characters in string"); } // Output the trailing event with the timestamp. diff -r 268875216dfc -r faf96b92a47b src/java.base/macosx/native/libjli/java_md_macosx.m --- a/src/java.base/macosx/native/libjli/java_md_macosx.m Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.base/macosx/native/libjli/java_md_macosx.m Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, 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 @@ -717,10 +717,17 @@ } /* - * Block current thread and continue execution in a new thread + * Signature adapter for pthread_create(). + */ +static void* ThreadJavaMain(void* args) { + return (void*)(intptr_t)JavaMain(args); +} + +/* + * Block current thread and continue execution in a new thread. */ int -ContinueInNewThread0(int (JNICALL *continuation)(void *), jlong stack_size, void * args) { +CallJavaMainInNewThread(jlong stack_size, void* args) { int rslt; pthread_t tid; pthread_attr_t attr; @@ -728,22 +735,22 @@ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); if (stack_size > 0) { - pthread_attr_setstacksize(&attr, stack_size); + pthread_attr_setstacksize(&attr, stack_size); } pthread_attr_setguardsize(&attr, 0); // no pthread guard page on java threads - if (pthread_create(&tid, &attr, (void *(*)(void*))continuation, (void*)args) == 0) { - void * tmp; - pthread_join(tid, &tmp); - rslt = (int)(intptr_t)tmp; + if (pthread_create(&tid, &attr, ThreadJavaMain, args) == 0) { + void* tmp; + pthread_join(tid, &tmp); + rslt = (int)(intptr_t)tmp; } else { - /* - * Continue execution in current thread if for some reason (e.g. out of - * memory/LWP) a new thread can't be created. This will likely fail - * later in continuation as JNI_CreateJavaVM needs to create quite a - * few new threads, anyway, just give it a try.. - */ - rslt = continuation(args); + /* + * Continue execution in current thread if for some reason (e.g. out of + * memory/LWP) a new thread can't be created. This will likely fail + * later in JavaMain as JNI_CreateJavaVM needs to create quite a + * few new threads, anyway, just give it a try.. + */ + rslt = JavaMain(args); } pthread_attr_destroy(&attr); diff -r 268875216dfc -r faf96b92a47b src/java.base/share/classes/java/lang/Throwable.java --- a/src/java.base/share/classes/java/lang/Throwable.java Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.base/share/classes/java/lang/Throwable.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2019, 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 @@ -616,7 +616,7 @@ * ... 1 more * * Note that the "... n more" notation is used on suppressed exceptions - * just at it is used on causes. Unlike causes, suppressed exceptions are + * just as it is used on causes. Unlike causes, suppressed exceptions are * indented beyond their "containing exceptions." * *

An exception can have both a cause and one or more suppressed diff -r 268875216dfc -r faf96b92a47b src/java.base/share/classes/java/lang/constant/ClassDesc.java --- a/src/java.base/share/classes/java/lang/constant/ClassDesc.java Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.base/share/classes/java/lang/constant/ClassDesc.java Fri Mar 01 17:27:28 2019 +0530 @@ -170,7 +170,7 @@ * * @param rank the rank of the array * @return a {@linkplain ClassDesc} describing the array type - * @throws IllegalArgumentException if the rank is less than zero or if the rank of the resulting array type is + * @throws IllegalArgumentException if the rank is less than or equal to zero or if the rank of the resulting array type is * greater than 255 * @jvms 4.4.1 The CONSTANT_Class_info Structure */ diff -r 268875216dfc -r faf96b92a47b src/java.base/share/classes/java/nio/Bits.java --- a/src/java.base/share/classes/java/nio/Bits.java Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.base/share/classes/java/nio/Bits.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, 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 @@ -172,7 +172,10 @@ } // no luck - throw new OutOfMemoryError("Direct buffer memory"); + throw new OutOfMemoryError + ("Cannot reserve " + + size + " bytes of direct buffer memory (allocated: " + + RESERVED_MEMORY.get() + ", limit: " + MAX_MEMORY +")"); } finally { if (interrupted) { diff -r 268875216dfc -r faf96b92a47b src/java.base/share/classes/java/nio/Buffer.java --- a/src/java.base/share/classes/java/nio/Buffer.java Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.base/share/classes/java/nio/Buffer.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, 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 @@ -134,8 +134,9 @@ * it already contains: It leaves the limit unchanged and sets the position * to zero.

* - *
  • {@link #slice} creates a subsequence of a buffer: It leaves the - * limit and the position unchanged.

  • + *
  • The {@link #slice} and {@link #slice(int,int) slice(index,length)} + * methods create a subsequence of a buffer: They leave the limit and the + * position unchanged.

  • * *
  • {@link #duplicate} creates a shallow copy of a buffer: It leaves * the limit and the position unchanged.

  • @@ -600,6 +601,39 @@ public abstract Buffer slice(); /** + * Creates a new buffer whose content is a shared subsequence of + * this buffer's content. + * + *

    The content of the new buffer will start at position {@code index} + * in this buffer, and will contain {@code length} elements. Changes to + * this buffer's content will be visible in the new buffer, and vice versa; + * the two buffers' position, limit, and mark values will be independent. + * + *

    The new buffer's position will be zero, its capacity and its limit + * will be {@code length}, its mark will be undefined. The new buffer will + * be direct if, and only if, this buffer is direct, and it will be + * read-only if, and only if, this buffer is read-only.

    + * + * @param index + * The position in this buffer at which the content of the new + * buffer will start; must be non-negative and no larger than + * {@link #limit() limit()} + * + * @param length + * The number of elements the new buffer will contain; must be + * non-negative and no larger than {@code limit() - index} + * + * @return The new buffer + * + * @throws IndexOutOfBoundsException + * If {@code index} is negative or greater than {@code limit()}, + * {@code length} is negative, or {@code length > limit() - index} + * + * @since 13 + */ + public abstract Buffer slice(int index, int length); + + /** * Creates a new buffer that shares this buffer's content. * *

    The content of the new buffer will be that of this buffer. Changes diff -r 268875216dfc -r faf96b92a47b src/java.base/share/classes/java/nio/ByteBufferAs-X-Buffer.java.template --- a/src/java.base/share/classes/java/nio/ByteBufferAs-X-Buffer.java.template Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.base/share/classes/java/nio/ByteBufferAs-X-Buffer.java.template Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, 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 @@ -27,9 +27,9 @@ package java.nio; +import java.util.Objects; import jdk.internal.misc.Unsafe; - class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private extends {#if[ro]?ByteBufferAs}$Type$Buffer{#if[ro]?$BO$} { @@ -85,6 +85,18 @@ return new ByteBufferAs$Type$Buffer$RW$$BO$(bb, -1, 0, rem, rem, addr); } + @Override + public $Type$Buffer slice(int index, int length) { + Objects.checkIndex(index, limit() + 1); + Objects.checkIndex(length, limit() - index + 1); + return new ByteBufferAs$Type$Buffer$RW$$BO$(bb, + -1, + 0, + length, + length, + byteOffset(index)); + } + public $Type$Buffer duplicate() { return new ByteBufferAs$Type$Buffer$RW$$BO$(bb, this.markValue(), diff -r 268875216dfc -r faf96b92a47b src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template --- a/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template Fri Mar 01 17:27:28 2019 +0530 @@ -218,14 +218,17 @@ return new Direct$Type$Buffer$RW$$BO$(this, -1, 0, rem, rem, off); } -#if[byte] - public $Type$Buffer slice(int pos, int lim) { - assert (pos >= 0); - assert (pos <= lim); - int rem = lim - pos; - return new Direct$Type$Buffer$RW$$BO$(this, -1, 0, rem, rem, pos); + @Override + public $Type$Buffer slice(int index, int length) { + Objects.checkIndex(index, limit() + 1); + Objects.checkIndex(length, limit() - index + 1); + return new Direct$Type$Buffer$RW$$BO$(this, + -1, + 0, + length, + length, + index); } -#end[byte] public $Type$Buffer duplicate() { return new Direct$Type$Buffer$RW$$BO$(this, diff -r 268875216dfc -r faf96b92a47b src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template --- a/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template Fri Mar 01 17:27:28 2019 +0530 @@ -27,6 +27,8 @@ package java.nio; +import java.util.Objects; + /** #if[rw] * A read/write Heap$Type$Buffer. @@ -38,8 +40,6 @@ #end[rw] */ -import java.util.Objects; - class Heap$Type$Buffer$RW$ extends {#if[ro]?Heap}$Type$Buffer { @@ -112,19 +112,17 @@ this.position() + offset); } -#if[byte] - $Type$Buffer slice(int pos, int lim) { - assert (pos >= 0); - assert (pos <= lim); - int rem = lim - pos; + @Override + public $Type$Buffer slice(int index, int length) { + Objects.checkIndex(index, limit() + 1); + Objects.checkIndex(length, limit() - index + 1); return new Heap$Type$Buffer$RW$(hb, -1, 0, - rem, - rem, - pos + offset); + length, + length, + index + offset); } -#end[byte] public $Type$Buffer duplicate() { return new Heap$Type$Buffer$RW$(hb, @@ -270,6 +268,25 @@ #end[rw] } +#if[char] + + public $Type$Buffer put(String src, int start, int end) { + int length = end - start; + checkBounds(start, length, src.length()); + if (isReadOnly()) + throw new ReadOnlyBufferException(); + int pos = position(); + int lim = limit(); + int rem = (pos <= lim) ? lim - pos : 0; + if (length > rem) + throw new BufferOverflowException(); + src.getChars(start, end, hb, ix(pos)); + position(pos + length); + return this; + } + +#end[char] + public $Type$Buffer compact() { #if[rw] System.arraycopy(hb, ix(position()), hb, ix(0), remaining()); diff -r 268875216dfc -r faf96b92a47b src/java.base/share/classes/java/nio/StringCharBuffer.java --- a/src/java.base/share/classes/java/nio/StringCharBuffer.java Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.base/share/classes/java/nio/StringCharBuffer.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, 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 @@ -25,6 +25,7 @@ package java.nio; +import java.util.Objects; // ## If the sequence is a string, use reflection to share its array @@ -51,6 +52,18 @@ offset + this.position()); } + @Override + public CharBuffer slice(int index, int length) { + Objects.checkIndex(index, limit() + 1); + Objects.checkIndex(length, limit() - index + 1); + return new StringCharBuffer(str, + -1, + 0, + length, + length, + offset + index); + } + private StringCharBuffer(CharSequence s, int mark, int pos, diff -r 268875216dfc -r faf96b92a47b src/java.base/share/classes/java/nio/X-Buffer.java.template --- a/src/java.base/share/classes/java/nio/X-Buffer.java.template Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.base/share/classes/java/nio/X-Buffer.java.template Fri Mar 01 17:27:28 2019 +0530 @@ -547,6 +547,46 @@ public abstract $Type$Buffer slice(); /** + * Creates a new $type$ buffer whose content is a shared subsequence of + * this buffer's content. + * + *

    The content of the new buffer will start at position {@code index} + * in this buffer, and will contain {@code length} elements. Changes to + * this buffer's content will be visible in the new buffer, and vice versa; + * the two buffers' position, limit, and mark values will be independent. + * + *

    The new buffer's position will be zero, its capacity and its limit + * will be {@code length}, its mark will be undefined, and its byte order + * will be +#if[byte] + * {@link ByteOrder#BIG_ENDIAN BIG_ENDIAN}. +#else[byte] + * identical to that of this buffer. +#end[byte] + * The new buffer will be direct if, and only if, this buffer is direct, + * and it will be read-only if, and only if, this buffer is read-only.

    + * + * @param index + * The position in this buffer at which the content of the new + * buffer will start; must be non-negative and no larger than + * {@link #limit() limit()} + * + * @param length + * The number of elements the new buffer will contain; must be + * non-negative and no larger than {@code limit() - index} + * + * @return The new buffer + * + * @throws IndexOutOfBoundsException + * If {@code index} is negative or greater than {@code limit()}, + * {@code length} is negative, or {@code length > limit() - index} + * + * @since 13 + */ + @Override + public abstract $Type$Buffer slice(int index, int length); + + /** * Creates a new $type$ buffer that shares this buffer's content. * *

    The content of the new buffer will be that of this buffer. Changes @@ -1950,11 +1990,9 @@ aligned_pos = aligned_lim = pos; } - return slice(aligned_pos, aligned_lim); + return slice(aligned_pos, aligned_lim - aligned_pos); } - abstract ByteBuffer slice(int pos, int lim); - // #BIN // // Binary-data access methods for short, char, int, long, float, diff -r 268875216dfc -r faf96b92a47b src/java.base/share/classes/java/security/PrivilegedAction.java --- a/src/java.base/share/classes/java/security/PrivilegedAction.java Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.base/share/classes/java/security/PrivilegedAction.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2019, 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,7 +39,7 @@ * @see AccessController#doPrivileged(PrivilegedAction) * @see PrivilegedExceptionAction */ - +@FunctionalInterface public interface PrivilegedAction { /** * Performs the computation. This method will be called by diff -r 268875216dfc -r faf96b92a47b src/java.base/share/classes/java/security/PrivilegedExceptionAction.java --- a/src/java.base/share/classes/java/security/PrivilegedExceptionAction.java Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.base/share/classes/java/security/PrivilegedExceptionAction.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2019, 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 @@ -42,7 +42,7 @@ * AccessControlContext) * @see PrivilegedAction */ - +@FunctionalInterface public interface PrivilegedExceptionAction { /** * Performs the computation. This method will be called by diff -r 268875216dfc -r faf96b92a47b src/java.base/share/classes/java/util/JapaneseImperialCalendar.java --- a/src/java.base/share/classes/java/util/JapaneseImperialCalendar.java Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.base/share/classes/java/util/JapaneseImperialCalendar.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2019, 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 @@ -1022,9 +1022,11 @@ String name = CalendarDataUtility.retrieveFieldValueName(getCalendarType(), field, fieldValue, style, locale); - // If the ERA value is null, then + // If the ERA value is null or empty, then // try to get its name or abbreviation from the Era instance. - if (name == null && field == ERA && fieldValue < eras.length) { + if ((name == null || name.isEmpty()) && + field == ERA && + fieldValue < eras.length) { Era era = eras[fieldValue]; name = (style == SHORT) ? era.getAbbreviation() : era.getName(); } diff -r 268875216dfc -r faf96b92a47b src/java.base/share/classes/java/util/spi/ToolProvider.java --- a/src/java.base/share/classes/java/util/spi/ToolProvider.java Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.base/share/classes/java/util/spi/ToolProvider.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, 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 @@ -126,8 +126,9 @@ default int run(PrintStream out, PrintStream err, String... args) { Objects.requireNonNull(out); Objects.requireNonNull(err); + Objects.requireNonNull(args); for (String arg : args) { - Objects.requireNonNull(args); + Objects.requireNonNull(arg); } PrintWriter outWriter = new PrintWriter(out); diff -r 268875216dfc -r faf96b92a47b src/java.base/share/classes/jdk/internal/misc/Unsafe.java --- a/src/java.base/share/classes/jdk/internal/misc/Unsafe.java Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.base/share/classes/jdk/internal/misc/Unsafe.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, 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 @@ -3114,7 +3114,7 @@ * @param offset field/element offset * @param mask the mask value * @return the previous value - * @since 1.9 + * @since 9 */ @ForceInline public final int getAndBitwiseAndInt(Object o, long offset, int mask) { @@ -3343,6 +3343,14 @@ } /** + * Throws NoSuchMethodError; for use by the VM for redefinition support. + * @since 13 + */ + private static void throwNoSuchMethodError() { + throw new NoSuchMethodError(); + } + + /** * @return Returns true if the native byte ordering of this * platform is big-endian, false if it is little-endian. */ diff -r 268875216dfc -r faf96b92a47b src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java --- a/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2019, 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 @@ -175,7 +175,7 @@ public FieldAccessor newFieldAccessor(Field field, boolean override) { checkInitted(); - Field root = langReflectAccess.getRoot(field); + Field root = langReflectAccess().getRoot(field); if (root != null) { // FieldAccessor will use the root unless the modifiers have // been overrridden @@ -197,7 +197,7 @@ } // use the root Method that will not cache caller class - Method root = langReflectAccess.getRoot(method); + Method root = langReflectAccess().getRoot(method); if (root != null) { method = root; } @@ -233,7 +233,7 @@ } // use the root Constructor that will not cache caller class - Constructor root = langReflectAccess.getRoot(c); + Constructor root = langReflectAccess().getRoot(c); if (root != null) { c = root; } diff -r 268875216dfc -r faf96b92a47b src/java.base/share/classes/sun/security/ssl/Finished.java --- a/src/java.base/share/classes/sun/security/ssl/Finished.java Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.base/share/classes/sun/security/ssl/Finished.java Fri Mar 01 17:27:28 2019 +0530 @@ -102,7 +102,7 @@ } if (m.remaining() != verifyDataLen) { - throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER, + throw context.conContext.fatal(Alert.DECODE_ERROR, "Inappropriate finished message: need " + verifyDataLen + " but remaining " + m.remaining() + " bytes verify_data"); } @@ -120,7 +120,7 @@ "Failed to generate verify_data", ioe); } if (!MessageDigest.isEqual(myVerifyData, verifyData)) { - throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER, + throw context.conContext.fatal(Alert.DECRYPT_ERROR, "The Finished message cannot be verified."); } } diff -r 268875216dfc -r faf96b92a47b src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java --- a/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2019, 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 @@ -916,8 +916,12 @@ /** * Try the best to use up the input records so as to close the * socket gracefully, without impact the performance too much. + * + * Note: please don't synchronize this method as the read() method + * may hold the lock. A race should be fine as this method is + * designed for cleanup only. */ - private synchronized void deplete() { + private void deplete() { if (!conContext.isInboundClosed()) { if (!(conContext.inputRecord instanceof SSLSocketInputRecord)) { return; diff -r 268875216dfc -r faf96b92a47b src/java.base/share/native/libjli/java.c --- a/src/java.base/share/native/libjli/java.c Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.base/share/native/libjli/java.c Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2019, 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 @@ -388,8 +388,8 @@ } while (JNI_FALSE) -int JNICALL -JavaMain(void * _args) +int +JavaMain(void* _args) { JavaMainArgs *args = (JavaMainArgs *)_args; int argc = args->argc; @@ -2348,7 +2348,7 @@ args.what = what; args.ifn = *ifn; - rslt = ContinueInNewThread0(JavaMain, threadStackSize, (void*)&args); + rslt = CallJavaMainInNewThread(threadStackSize, (void*)&args); /* If the caller has deemed there is an error we * simply return that, otherwise we return the value of * the callee diff -r 268875216dfc -r faf96b92a47b src/java.base/share/native/libjli/java.h --- a/src/java.base/share/native/libjli/java.h Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.base/share/native/libjli/java.h Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2019, 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 @@ -156,10 +156,9 @@ void PrintMachineDependentOptions(); /* - * Block current thread and continue execution in new thread + * Block current thread and continue execution in new thread. */ -int ContinueInNewThread0(int (JNICALL *continuation)(void *), - jlong stack_size, void * args); +int CallJavaMainInNewThread(jlong stack_size, void* args); /* sun.java.launcher.* platform properties. */ void SetJavaLauncherPlatformProps(void); @@ -224,7 +223,10 @@ jobjectArray NewPlatformStringArray(JNIEnv *env, char **strv, int strc); jclass GetLauncherHelperClass(JNIEnv *env); -int JNICALL JavaMain(void * args); /* entry point */ +/* + * Entry point. + */ +int JavaMain(void* args); enum LaunchMode { // cf. sun.launcher.LauncherHelper LM_UNKNOWN = 0, diff -r 268875216dfc -r faf96b92a47b src/java.base/unix/native/libjli/java_md_solinux.c --- a/src/java.base/unix/native/libjli/java_md_solinux.c Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.base/unix/native/libjli/java_md_solinux.c Fri Mar 01 17:27:28 2019 +0530 @@ -718,10 +718,17 @@ } /* - * Block current thread and continue execution in a new thread + * Signature adapter for pthread_create() or thr_create(). + */ +static void* ThreadJavaMain(void* args) { + return (void*)(intptr_t)JavaMain(args); +} + +/* + * Block current thread and continue execution in a new thread. */ int -ContinueInNewThread0(int (JNICALL *continuation)(void *), jlong stack_size, void * args) { +CallJavaMainInNewThread(jlong stack_size, void* args) { int rslt; #ifndef __solaris__ pthread_t tid; @@ -730,35 +737,35 @@ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); if (stack_size > 0) { - pthread_attr_setstacksize(&attr, stack_size); + pthread_attr_setstacksize(&attr, stack_size); } pthread_attr_setguardsize(&attr, 0); // no pthread guard page on java threads - if (pthread_create(&tid, &attr, (void *(*)(void*))continuation, (void*)args) == 0) { - void * tmp; - pthread_join(tid, &tmp); - rslt = (int)(intptr_t)tmp; + if (pthread_create(&tid, &attr, ThreadJavaMain, args) == 0) { + void* tmp; + pthread_join(tid, &tmp); + rslt = (int)(intptr_t)tmp; } else { - /* - * Continue execution in current thread if for some reason (e.g. out of - * memory/LWP) a new thread can't be created. This will likely fail - * later in continuation as JNI_CreateJavaVM needs to create quite a - * few new threads, anyway, just give it a try.. - */ - rslt = continuation(args); + /* + * Continue execution in current thread if for some reason (e.g. out of + * memory/LWP) a new thread can't be created. This will likely fail + * later in JavaMain as JNI_CreateJavaVM needs to create quite a + * few new threads, anyway, just give it a try.. + */ + rslt = JavaMain(args); } pthread_attr_destroy(&attr); #else /* __solaris__ */ thread_t tid; long flags = 0; - if (thr_create(NULL, stack_size, (void *(*)(void *))continuation, args, flags, &tid) == 0) { - void * tmp; - thr_join(tid, NULL, &tmp); - rslt = (int)(intptr_t)tmp; + if (thr_create(NULL, stack_size, ThreadJavaMain, args, flags, &tid) == 0) { + void* tmp; + thr_join(tid, NULL, &tmp); + rslt = (int)(intptr_t)tmp; } else { - /* See above. Continue in current thread if thr_create() failed */ - rslt = continuation(args); + /* See above. Continue in current thread if thr_create() failed */ + rslt = JavaMain(args); } #endif /* !__solaris__ */ return rslt; diff -r 268875216dfc -r faf96b92a47b src/java.base/windows/native/libjli/java_md.c --- a/src/java.base/windows/native/libjli/java_md.c Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.base/windows/native/libjli/java_md.c Fri Mar 01 17:27:28 2019 +0530 @@ -704,10 +704,17 @@ } /* - * Block current thread and continue execution in a new thread + * Signature adapter for _beginthreadex(). + */ +static unsigned __stdcall ThreadJavaMain(void* args) { + return (unsigned)JavaMain(args); +} + +/* + * Block current thread and continue execution in a new thread. */ int -ContinueInNewThread0(int (JNICALL *continuation)(void *), jlong stack_size, void * args) { +CallJavaMainInNewThread(jlong stack_size, void* args) { int rslt = 0; unsigned thread_id; @@ -722,20 +729,20 @@ * source (os_win32.cpp) for details. */ HANDLE thread_handle = - (HANDLE)_beginthreadex(NULL, - (unsigned)stack_size, - continuation, - args, - STACK_SIZE_PARAM_IS_A_RESERVATION, - &thread_id); + (HANDLE)_beginthreadex(NULL, + (unsigned)stack_size, + ThreadJavaMain, + args, + STACK_SIZE_PARAM_IS_A_RESERVATION, + &thread_id); if (thread_handle == NULL) { - thread_handle = - (HANDLE)_beginthreadex(NULL, - (unsigned)stack_size, - continuation, - args, - 0, - &thread_id); + thread_handle = + (HANDLE)_beginthreadex(NULL, + (unsigned)stack_size, + ThreadJavaMain, + args, + 0, + &thread_id); } /* AWT preloading (AFTER main thread start) */ @@ -772,11 +779,11 @@ #endif /* ENABLE_AWT_PRELOAD */ if (thread_handle) { - WaitForSingleObject(thread_handle, INFINITE); - GetExitCodeThread(thread_handle, &rslt); - CloseHandle(thread_handle); + WaitForSingleObject(thread_handle, INFINITE); + GetExitCodeThread(thread_handle, &rslt); + CloseHandle(thread_handle); } else { - rslt = continuation(args); + rslt = JavaMain(args); } #ifdef ENABLE_AWT_PRELOAD diff -r 268875216dfc -r faf96b92a47b src/java.compiler/share/classes/javax/lang/model/element/package-info.java --- a/src/java.compiler/share/classes/javax/lang/model/element/package-info.java Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.compiler/share/classes/javax/lang/model/element/package-info.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2019, 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 @@ -107,6 +107,7 @@ * @author Joseph D. Darcy * @author Scott Seligman * @author Peter von der Ahé + * @see javax.lang.model.util.Elements * @since 1.6 */ package javax.lang.model.element; diff -r 268875216dfc -r faf96b92a47b src/java.compiler/share/classes/javax/lang/model/type/package-info.java --- a/src/java.compiler/share/classes/javax/lang/model/type/package-info.java Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.compiler/share/classes/javax/lang/model/type/package-info.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2019, 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 @@ -36,6 +36,7 @@ * @author Joseph D. Darcy * @author Scott Seligman * @author Peter von der Ahé + * @see javax.lang.model.util.Types * @since 1.6 */ package javax.lang.model.type; diff -r 268875216dfc -r faf96b92a47b src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.h --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.h Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.h Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2018, 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 @@ -47,6 +47,7 @@ jint preFullScreenLevel; NSRect standardFrame; BOOL isMinimizing; + BOOL keyNotificationRecd; } // An instance of either AWTWindow_Normal or AWTWindow_Panel @@ -62,6 +63,7 @@ @property (nonatomic) jint preFullScreenLevel; @property (nonatomic) NSRect standardFrame; @property (nonatomic) BOOL isMinimizing; +@property (nonatomic) BOOL keyNotificationRecd; - (id) initWithPlatformWindow:(JNFWeakJObjectWrapper *)javaPlatformWindow ownerWindow:owner diff -r 268875216dfc -r faf96b92a47b src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m Fri Mar 01 17:27:28 2019 +0530 @@ -186,6 +186,7 @@ @synthesize preFullScreenLevel; @synthesize standardFrame; @synthesize isMinimizing; +@synthesize keyNotificationRecd; - (void) updateMinMaxSize:(BOOL)resizable { if (resizable) { @@ -319,6 +320,7 @@ if (self.nsWindow == nil) return nil; // no hope either [self.nsWindow release]; // the property retains the object already + self.keyNotificationRecd = NO; self.isEnabled = YES; self.isMinimizing = NO; self.javaPlatformWindow = platformWindow; @@ -747,9 +749,16 @@ AWT_ASSERT_APPKIT_THREAD; [AWTToolkit eventCountPlusPlus]; #ifdef DEBUG - NSLog(@"became main: %d %@ %@", [self.nsWindow isKeyWindow], [self.nsWindow title], [self menuBarForWindow]); + NSLog(@"became main: %d %@ %@ %d", [self.nsWindow isKeyWindow], [self.nsWindow title], [self menuBarForWindow], self.keyNotificationRecd); #endif + // if for some reason, no KEY notification is received but this main window is also a key window + // then we need to execute the KEY notification functionality. + if(self.keyNotificationRecd != YES && [self.nsWindow isKeyWindow]) { + [self doWindowDidBecomeKey]; + } + self.keyNotificationRecd = NO; + if (![self.nsWindow isKeyWindow]) { [self activateWindowMenuBar]; } @@ -769,6 +778,12 @@ #ifdef DEBUG NSLog(@"became key: %d %@ %@", [self.nsWindow isMainWindow], [self.nsWindow title], [self menuBarForWindow]); #endif + [self doWindowDidBecomeKey]; + self.keyNotificationRecd = YES; +} + +- (void) doWindowDidBecomeKey { +AWT_ASSERT_APPKIT_THREAD; AWTWindow *opposite = [AWTWindow lastKeyWindow]; if (![self.nsWindow isMainWindow]) { diff -r 268875216dfc -r faf96b92a47b src/java.desktop/share/classes/javax/swing/text/html/CSS.java --- a/src/java.desktop/share/classes/javax/swing/text/html/CSS.java Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.desktop/share/classes/javax/swing/text/html/CSS.java Fri Mar 01 17:27:28 2019 +0530 @@ -1362,6 +1362,19 @@ } else { digits = value; } + // Some webpage passes 3 digit color code as in #fff which is + // decoded as #000FFF resulting in blue background. + // As per https://www.w3.org/TR/CSS1/#color-units, + // The three-digit RGB notation (#rgb) is converted into six-digit form + // (#rrggbb) by replicating digits, not by adding zeros. + // This makes sure that white (#ffffff) can be specified with the short notation + // (#fff) and removes any dependencies on the color depth of the display. + if (digits.length() == 3) { + final String r = digits.substring(0, 1); + final String g = digits.substring(1, 2); + final String b = digits.substring(2, 3); + digits = String.format("%s%s%s%s%s%s", r, r, g, g, b, b); + } String hstr = "0x" + digits; Color c; try { diff -r 268875216dfc -r faf96b92a47b src/java.desktop/share/classes/javax/swing/text/rtf/RTFReader.java --- a/src/java.desktop/share/classes/javax/swing/text/rtf/RTFReader.java Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.desktop/share/classes/javax/swing/text/rtf/RTFReader.java Fri Mar 01 17:27:28 2019 +0530 @@ -1185,6 +1185,10 @@ parserState.put(keyword, Integer.valueOf(parameter)); return true; } + if (keyword.equals("cb")) { + parserState.put(keyword, Integer.valueOf(parameter)); + return true; + } { RTFAttribute attr = straightforwardAttributes.get(keyword); diff -r 268875216dfc -r faf96b92a47b src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java --- a/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java Fri Mar 01 17:27:28 2019 +0530 @@ -403,18 +403,36 @@ list. */ class RemotePrinterChangeListener implements Runnable { - private String[] prevRemotePrinters; + private String[] prevRemotePrinters = null; RemotePrinterChangeListener() { prevRemotePrinters = getRemotePrintersNames(); } boolean doCompare(String[] str1, String[] str2) { + if (str1 == null && str2 == null) { + return false; + } else if (str1 == null || str2 == null) { + return true; + } + if (str1.length != str2.length) { return true; } else { for (int i = 0;i < str1.length;i++) { for (int j = 0;j < str2.length;j++) { + // skip if both are nulls + if (str1[i] == null && str2[j] == null) { + continue; + } + + // return true if there is a 'difference' but + // no need to access the individual string + if (str1[i] == null || str2[j] == null) { + return true; + } + + // do comparison only if they are non-nulls if (!str1[i].equals(str2[j])) { return true; } @@ -428,15 +446,19 @@ @Override public void run() { while (true) { - String[] currentRemotePrinters = getRemotePrintersNames(); - if (doCompare(prevRemotePrinters, currentRemotePrinters)) { + if (prevRemotePrinters != null && prevRemotePrinters.length > 0) { + String[] currentRemotePrinters = getRemotePrintersNames(); + if (doCompare(prevRemotePrinters, currentRemotePrinters)) { - // updated the printers data - // printers list now contains both local and network printer data - refreshServices(); + // updated the printers data + // printers list now contains both local and network printer data + refreshServices(); - // store the current data for next comparison - prevRemotePrinters = currentRemotePrinters; + // store the current data for next comparison + prevRemotePrinters = currentRemotePrinters; + } + } else { + prevRemotePrinters = getRemotePrintersNames(); } try { diff -r 268875216dfc -r faf96b92a47b src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp --- a/src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp Fri Mar 01 17:27:28 2019 +0530 @@ -249,7 +249,7 @@ if (clazz == NULL) { return NULL; } - jobjectArray nameArray; + jobjectArray nameArray = NULL; try { ::EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, @@ -270,13 +270,14 @@ } } - // Allocate space only for the network type printers - nameArray = env->NewObjectArray(remotePrintersCount, clazz, NULL); - if (nameArray == NULL) { - throw std::bad_alloc(); + // return remote printers only if the list contains it. + if (remotePrintersCount > 0) { + // Allocate space only for the network type printers + nameArray = env->NewObjectArray(remotePrintersCount, clazz, NULL); + if (nameArray == NULL) { + throw std::bad_alloc(); + } } - } else { - nameArray = NULL; } // Loop thro' network printers list only @@ -298,7 +299,12 @@ delete [] pPrinterEnum; delete [] pNetworkPrinterLoc; - return nameArray; + + if (nameArray != NULL) { + return nameArray; + } else { + return env->NewObjectArray(0, clazz, NULL); + } CATCH_BAD_ALLOC_RET(NULL); } diff -r 268875216dfc -r faf96b92a47b src/java.smartcardio/share/native/libj2pcsc/pcsc.c --- a/src/java.smartcardio/share/native/libj2pcsc/pcsc.c Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.smartcardio/share/native/libj2pcsc/pcsc.c Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2019, 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 @@ -181,7 +181,7 @@ { SCARDCONTEXT context = (SCARDCONTEXT)jContext; LONG rv; - LPTSTR mszReaders = NULL; + LPSTR mszReaders = NULL; DWORD size = 0; jobjectArray result; @@ -220,7 +220,7 @@ { SCARDCONTEXT context = (SCARDCONTEXT)jContext; LONG rv; - LPCTSTR readerName; + LPCSTR readerName; SCARDHANDLE card = 0; DWORD proto = 0; diff -r 268875216dfc -r faf96b92a47b src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/COPYING --- a/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/COPYING Mon Feb 25 15:15:46 2019 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -Copyright (c) 1999-2003 David Corcoran -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -Changes to this license can be made only by the copyright author with -explicit written consent. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff -r 268875216dfc -r faf96b92a47b src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/pcsclite.h --- a/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/pcsclite.h Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/pcsclite.h Fri Mar 01 17:27:28 2019 +0530 @@ -1,374 +1,306 @@ /* - * This keeps a list of defines for pcsc-lite. - * - * MUSCLE SmartCard Development ( http://www.linuxnet.com ) + * MUSCLE SmartCard Development ( https://pcsclite.apdu.fr/ ) * * Copyright (C) 1999-2004 - * David Corcoran + * David Corcoran + * Copyright (C) 2002-2011 * Ludovic Rousseau + * Copyright (C) 2005 + * Martin Paljak * - * $Id: pcsclite.h.in,v 1.47 2004/08/24 21:46:57 rousseau Exp $ +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * @brief This keeps a list of defines for pcsc-lite. + * + * Error codes from http://msdn.microsoft.com/en-us/library/aa924526.aspx */ #ifndef __pcsclite_h__ #define __pcsclite_h__ -#ifndef __sun_jdk #include -#else -#include -#include -#ifdef BYTE -#error BYTE is already defined -#else - typedef unsigned char BYTE; -#endif /* End BYTE */ - - typedef unsigned char UCHAR; - typedef unsigned char *PUCHAR; - typedef unsigned short USHORT; - typedef unsigned long ULONG; - typedef void *LPVOID; - typedef short BOOL; - typedef unsigned long *PULONG; - typedef const void *LPCVOID; - typedef unsigned long DWORD; - typedef unsigned long *PDWORD; - typedef unsigned short WORD; - typedef long LONG; - typedef long RESPONSECODE; - typedef const char *LPCTSTR; - typedef const BYTE *LPCBYTE; - typedef BYTE *LPBYTE; - typedef DWORD *LPDWORD; - typedef char *LPTSTR; - -#endif #ifdef __cplusplus extern "C" { #endif -#ifdef WIN32 -#include -#else -typedef long SCARDCONTEXT; +typedef LONG SCARDCONTEXT; /**< \p hContext returned by SCardEstablishContext() */ typedef SCARDCONTEXT *PSCARDCONTEXT; typedef SCARDCONTEXT *LPSCARDCONTEXT; -typedef long SCARDHANDLE; +typedef LONG SCARDHANDLE; /**< \p hCard returned by SCardConnect() */ typedef SCARDHANDLE *PSCARDHANDLE; typedef SCARDHANDLE *LPSCARDHANDLE; -#define MAX_ATR_SIZE 33 /* Maximum ATR size */ +#define MAX_ATR_SIZE 33 /**< Maximum ATR size */ -#ifndef __APPLE__ +/* Set structure elements aligment on bytes + * http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html */ +#ifdef __APPLE__ +#pragma pack(1) +#endif typedef struct { - const char *szReader; - void *pvUserData; - unsigned long dwCurrentState; - unsigned long dwEventState; - unsigned long cbAtr; - unsigned char rgbAtr[MAX_ATR_SIZE]; + const char *szReader; + void *pvUserData; + DWORD dwCurrentState; + DWORD dwEventState; + DWORD cbAtr; + unsigned char rgbAtr[MAX_ATR_SIZE]; } -SCARD_READERSTATE_A; +SCARD_READERSTATE, *LPSCARD_READERSTATE; -typedef struct _SCARD_IO_REQUEST -{ - unsigned long dwProtocol; /* Protocol identifier */ - unsigned long cbPciLength; /* Protocol Control Inf Length */ -} -SCARD_IO_REQUEST, *PSCARD_IO_REQUEST, *LPSCARD_IO_REQUEST; - -#else // __APPLE__ - -#pragma pack(1) +/** Protocol Control Information (PCI) */ typedef struct { - const char *szReader; - void *pvUserData; - uint32_t dwCurrentState; - uint32_t dwEventState; - uint32_t cbAtr; - unsigned char rgbAtr[MAX_ATR_SIZE]; -} -SCARD_READERSTATE_A; - -typedef struct _SCARD_IO_REQUEST -{ - uint32_t dwProtocol; /* Protocol identifier */ - uint32_t cbPciLength; /* Protocol Control Inf Length */ + unsigned long dwProtocol; /**< Protocol identifier */ + unsigned long cbPciLength; /**< Protocol Control Inf Length */ } SCARD_IO_REQUEST, *PSCARD_IO_REQUEST, *LPSCARD_IO_REQUEST; -#pragma pack() - -#endif // __APPLE__ - -typedef SCARD_READERSTATE_A SCARD_READERSTATE, *PSCARD_READERSTATE_A, - *LPSCARD_READERSTATE_A; typedef const SCARD_IO_REQUEST *LPCSCARD_IO_REQUEST; -extern SCARD_IO_REQUEST g_rgSCardT0Pci, g_rgSCardT1Pci, - g_rgSCardRawPci; - -#define SCARD_PCI_T0 (&g_rgSCardT0Pci) -#define SCARD_PCI_T1 (&g_rgSCardT1Pci) -#define SCARD_PCI_RAW (&g_rgSCardRawPci) - -#define SCARD_S_SUCCESS 0x00000000 -#define SCARD_E_CANCELLED 0x80100002 -#define SCARD_E_CANT_DISPOSE 0x8010000E -#define SCARD_E_INSUFFICIENT_BUFFER 0x80100008 -#define SCARD_E_INVALID_ATR 0x80100015 -#define SCARD_E_INVALID_HANDLE 0x80100003 -#define SCARD_E_INVALID_PARAMETER 0x80100004 -#define SCARD_E_INVALID_TARGET 0x80100005 -#define SCARD_E_INVALID_VALUE 0x80100011 -#define SCARD_E_NO_MEMORY 0x80100006 -#define SCARD_F_COMM_ERROR 0x80100013 -#define SCARD_F_INTERNAL_ERROR 0x80100001 -#define SCARD_F_UNKNOWN_ERROR 0x80100014 -#define SCARD_F_WAITED_TOO_LONG 0x80100007 -#define SCARD_E_UNKNOWN_READER 0x80100009 -#define SCARD_E_TIMEOUT 0x8010000A -#define SCARD_E_SHARING_VIOLATION 0x8010000B -#define SCARD_E_NO_SMARTCARD 0x8010000C -#define SCARD_E_UNKNOWN_CARD 0x8010000D -#define SCARD_E_PROTO_MISMATCH 0x8010000F -#define SCARD_E_NOT_READY 0x80100010 -#define SCARD_E_SYSTEM_CANCELLED 0x80100012 -#define SCARD_E_NOT_TRANSACTED 0x80100016 -#define SCARD_E_READER_UNAVAILABLE 0x80100017 - -#define SCARD_W_UNSUPPORTED_CARD 0x80100065 -#define SCARD_W_UNRESPONSIVE_CARD 0x80100066 -#define SCARD_W_UNPOWERED_CARD 0x80100067 -#define SCARD_W_RESET_CARD 0x80100068 -#define SCARD_W_REMOVED_CARD 0x80100069 - -#define SCARD_E_PCI_TOO_SMALL 0x80100019 -#define SCARD_E_READER_UNSUPPORTED 0x8010001A -#define SCARD_E_DUPLICATE_READER 0x8010001B -#define SCARD_E_CARD_UNSUPPORTED 0x8010001C -#define SCARD_E_NO_SERVICE 0x8010001D -#define SCARD_E_SERVICE_STOPPED 0x8010001E - -#define SCARD_SCOPE_USER 0x0000 /* Scope in user space */ -#define SCARD_SCOPE_TERMINAL 0x0001 /* Scope in terminal */ -#define SCARD_SCOPE_SYSTEM 0x0002 /* Scope in system */ - -#define SCARD_PROTOCOL_UNSET 0x0000 /* protocol not set */ -#define SCARD_PROTOCOL_T0 0x0001 /* T=0 active protocol. */ -#define SCARD_PROTOCOL_T1 0x0002 /* T=1 active protocol. */ -#define SCARD_PROTOCOL_RAW 0x0004 /* Raw active protocol. */ -#define SCARD_PROTOCOL_T15 0x0008 /* T=15 protocol. */ - -#define SCARD_PROTOCOL_ANY (SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1) /* IFD determines prot. */ - -#define SCARD_SHARE_EXCLUSIVE 0x0001 /* Exclusive mode only */ -#define SCARD_SHARE_SHARED 0x0002 /* Shared mode only */ -#define SCARD_SHARE_DIRECT 0x0003 /* Raw mode only */ - -#define SCARD_LEAVE_CARD 0x0000 /* Do nothing on close */ -#define SCARD_RESET_CARD 0x0001 /* Reset on close */ -#define SCARD_UNPOWER_CARD 0x0002 /* Power down on close */ -#define SCARD_EJECT_CARD 0x0003 /* Eject on close */ - -#define SCARD_UNKNOWN 0x0001 /* Unknown state */ -#define SCARD_ABSENT 0x0002 /* Card is absent */ -#define SCARD_PRESENT 0x0004 /* Card is present */ -#define SCARD_SWALLOWED 0x0008 /* Card not powered */ -#define SCARD_POWERED 0x0010 /* Card is powered */ -#define SCARD_NEGOTIABLE 0x0020 /* Ready for PTS */ -#define SCARD_SPECIFIC 0x0040 /* PTS has been set */ +extern const SCARD_IO_REQUEST g_rgSCardT0Pci, g_rgSCardT1Pci, g_rgSCardRawPci; -#define SCARD_STATE_UNAWARE 0x0000 /* App wants status */ -#define SCARD_STATE_IGNORE 0x0001 /* Ignore this reader */ -#define SCARD_STATE_CHANGED 0x0002 /* State has changed */ -#define SCARD_STATE_UNKNOWN 0x0004 /* Reader unknown */ -#define SCARD_STATE_UNAVAILABLE 0x0008 /* Status unavailable */ -#define SCARD_STATE_EMPTY 0x0010 /* Card removed */ -#define SCARD_STATE_PRESENT 0x0020 /* Card inserted */ -#define SCARD_STATE_ATRMATCH 0x0040 /* ATR matches card */ -#define SCARD_STATE_EXCLUSIVE 0x0080 /* Exclusive Mode */ -#define SCARD_STATE_INUSE 0x0100 /* Shared Mode */ -#define SCARD_STATE_MUTE 0x0200 /* Unresponsive card */ -#define SCARD_STATE_UNPOWERED 0x0400 /* Unpowered card */ - -/* - * Tags for requesting card and reader attributes - */ - -#define SCARD_ATTR_VALUE(Class, Tag) ((((ULONG)(Class)) << 16) | ((ULONG)(Tag))) - -#define SCARD_CLASS_VENDOR_INFO 1 /* Vendor information definitions */ -#define SCARD_CLASS_COMMUNICATIONS 2 /* Communication definitions */ -#define SCARD_CLASS_PROTOCOL 3 /* Protocol definitions */ -#define SCARD_CLASS_POWER_MGMT 4 /* Power Management definitions */ -#define SCARD_CLASS_SECURITY 5 /* Security Assurance definitions */ -#define SCARD_CLASS_MECHANICAL 6 /* Mechanical characteristic definitions */ -#define SCARD_CLASS_VENDOR_DEFINED 7 /* Vendor specific definitions */ -#define SCARD_CLASS_IFD_PROTOCOL 8 /* Interface Device Protocol options */ -#define SCARD_CLASS_ICC_STATE 9 /* ICC State specific definitions */ -#define SCARD_CLASS_SYSTEM 0x7fff /* System-specific definitions */ - -#define SCARD_ATTR_VENDOR_NAME SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0100) -#define SCARD_ATTR_VENDOR_IFD_TYPE SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0101) -#define SCARD_ATTR_VENDOR_IFD_VERSION SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0102) -#define SCARD_ATTR_VENDOR_IFD_SERIAL_NO SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0103) -#define SCARD_ATTR_CHANNEL_ID SCARD_ATTR_VALUE(SCARD_CLASS_COMMUNICATIONS, 0x0110) -#define SCARD_ATTR_ASYNC_PROTOCOL_TYPES SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0120) -#define SCARD_ATTR_DEFAULT_CLK SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0121) -#define SCARD_ATTR_MAX_CLK SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0122) -#define SCARD_ATTR_DEFAULT_DATA_RATE SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0123) -#define SCARD_ATTR_MAX_DATA_RATE SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0124) -#define SCARD_ATTR_MAX_IFSD SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0125) -#define SCARD_ATTR_SYNC_PROTOCOL_TYPES SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0126) -#define SCARD_ATTR_POWER_MGMT_SUPPORT SCARD_ATTR_VALUE(SCARD_CLASS_POWER_MGMT, 0x0131) -#define SCARD_ATTR_USER_TO_CARD_AUTH_DEVICE SCARD_ATTR_VALUE(SCARD_CLASS_SECURITY, 0x0140) -#define SCARD_ATTR_USER_AUTH_INPUT_DEVICE SCARD_ATTR_VALUE(SCARD_CLASS_SECURITY, 0x0142) -#define SCARD_ATTR_CHARACTERISTICS SCARD_ATTR_VALUE(SCARD_CLASS_MECHANICAL, 0x0150) - -#define SCARD_ATTR_CURRENT_PROTOCOL_TYPE SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0201) -#define SCARD_ATTR_CURRENT_CLK SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0202) -#define SCARD_ATTR_CURRENT_F SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0203) -#define SCARD_ATTR_CURRENT_D SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0204) -#define SCARD_ATTR_CURRENT_N SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0205) -#define SCARD_ATTR_CURRENT_W SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0206) -#define SCARD_ATTR_CURRENT_IFSC SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0207) -#define SCARD_ATTR_CURRENT_IFSD SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0208) -#define SCARD_ATTR_CURRENT_BWT SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0209) -#define SCARD_ATTR_CURRENT_CWT SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x020a) -#define SCARD_ATTR_CURRENT_EBC_ENCODING SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x020b) -#define SCARD_ATTR_EXTENDED_BWT SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x020c) - -#define SCARD_ATTR_ICC_PRESENCE SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0300) -#define SCARD_ATTR_ICC_INTERFACE_STATUS SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0301) -#define SCARD_ATTR_CURRENT_IO_STATE SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0302) -#define SCARD_ATTR_ATR_STRING SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0303) -#define SCARD_ATTR_ICC_TYPE_PER_ATR SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0304) - -#define SCARD_ATTR_ESC_RESET SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA000) -#define SCARD_ATTR_ESC_CANCEL SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA003) -#define SCARD_ATTR_ESC_AUTHREQUEST SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA005) -#define SCARD_ATTR_MAXINPUT SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA007) - -#define SCARD_ATTR_DEVICE_UNIT SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0001) -#define SCARD_ATTR_DEVICE_IN_USE SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0002) -#define SCARD_ATTR_DEVICE_FRIENDLY_NAME_A SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0003) -#define SCARD_ATTR_DEVICE_SYSTEM_NAME_A SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0004) -#define SCARD_ATTR_DEVICE_FRIENDLY_NAME_W SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0005) -#define SCARD_ATTR_DEVICE_SYSTEM_NAME_W SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0006) -#define SCARD_ATTR_SUPRESS_T1_IFS_REQUEST SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0007) - -#ifdef UNICODE -#define SCARD_ATTR_DEVICE_FRIENDLY_NAME SCARD_ATTR_DEVICE_FRIENDLY_NAME_W -#define SCARD_ATTR_DEVICE_SYSTEM_NAME SCARD_ATTR_DEVICE_SYSTEM_NAME_W -#else -#define SCARD_ATTR_DEVICE_FRIENDLY_NAME SCARD_ATTR_DEVICE_FRIENDLY_NAME_A -#define SCARD_ATTR_DEVICE_SYSTEM_NAME SCARD_ATTR_DEVICE_SYSTEM_NAME_A +/* restore default structure elements alignment */ +#ifdef __APPLE__ +#pragma pack() #endif -#endif - -/* PC/SC Lite specific extensions */ -#define SCARD_W_INSERTED_CARD 0x8010006A -#define SCARD_E_UNSUPPORTED_FEATURE 0x8010001F - -#define SCARD_SCOPE_GLOBAL 0x0003 /* Scope is global */ - -#define SCARD_RESET 0x0001 /* Card was reset */ -#define SCARD_INSERTED 0x0002 /* Card was inserted */ -#define SCARD_REMOVED 0x0004 /* Card was removed */ +#define SCARD_PCI_T0 (&g_rgSCardT0Pci) /**< protocol control information (PCI) for T=0 */ +#define SCARD_PCI_T1 (&g_rgSCardT1Pci) /**< protocol control information (PCI) for T=1 */ +#define SCARD_PCI_RAW (&g_rgSCardRawPci) /**< protocol control information (PCI) for RAW protocol */ -#define BLOCK_STATUS_RESUME 0x00FF /* Normal resume */ -#define BLOCK_STATUS_BLOCKING 0x00FA /* Function is blocking */ - -#define PCSCLITE_CONFIG_DIR "/etc" +/** + * @defgroup ErrorCodes ErrorCodes + * @brief Error code documentation + * + * The error codes descriptions are from + * http://msdn.microsoft.com/en-us/library/aa924526.aspx + */ +/** @ingroup ErrorCodes */ +#define SCARD_S_SUCCESS ((LONG)0x00000000) /**< No error was encountered. */ +/** @ingroup ErrorCodes */ +#define SCARD_F_INTERNAL_ERROR ((LONG)0x80100001) /**< An internal consistency check failed. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_CANCELLED ((LONG)0x80100002) /**< The action was cancelled by an SCardCancel request. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_INVALID_HANDLE ((LONG)0x80100003) /**< The supplied handle was invalid. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_INVALID_PARAMETER ((LONG)0x80100004) /**< One or more of the supplied parameters could not be properly interpreted. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_INVALID_TARGET ((LONG)0x80100005) /**< Registry startup information is missing or invalid. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_NO_MEMORY ((LONG)0x80100006) /**< Not enough memory available to complete this command. */ +/** @ingroup ErrorCodes */ +#define SCARD_F_WAITED_TOO_LONG ((LONG)0x80100007) /**< An internal consistency timer has expired. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_INSUFFICIENT_BUFFER ((LONG)0x80100008) /**< The data buffer to receive returned data is too small for the returned data. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_UNKNOWN_READER ((LONG)0x80100009) /**< The specified reader name is not recognized. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_TIMEOUT ((LONG)0x8010000A) /**< The user-specified timeout value has expired. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_SHARING_VIOLATION ((LONG)0x8010000B) /**< The smart card cannot be accessed because of other connections outstanding. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_NO_SMARTCARD ((LONG)0x8010000C) /**< The operation requires a Smart Card, but no Smart Card is currently in the device. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_UNKNOWN_CARD ((LONG)0x8010000D) /**< The specified smart card name is not recognized. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_CANT_DISPOSE ((LONG)0x8010000E) /**< The system could not dispose of the media in the requested manner. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_PROTO_MISMATCH ((LONG)0x8010000F) /**< The requested protocols are incompatible with the protocol currently in use with the smart card. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_NOT_READY ((LONG)0x80100010) /**< The reader or smart card is not ready to accept commands. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_INVALID_VALUE ((LONG)0x80100011) /**< One or more of the supplied parameters values could not be properly interpreted. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_SYSTEM_CANCELLED ((LONG)0x80100012) /**< The action was cancelled by the system, presumably to log off or shut down. */ +/** @ingroup ErrorCodes */ +#define SCARD_F_COMM_ERROR ((LONG)0x80100013) /**< An internal communications error has been detected. */ +/** @ingroup ErrorCodes */ +#define SCARD_F_UNKNOWN_ERROR ((LONG)0x80100014) /**< An internal error has been detected, but the source is unknown. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_INVALID_ATR ((LONG)0x80100015) /**< An ATR obtained from the registry is not a valid ATR string. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_NOT_TRANSACTED ((LONG)0x80100016) /**< An attempt was made to end a non-existent transaction. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_READER_UNAVAILABLE ((LONG)0x80100017) /**< The specified reader is not currently available for use. */ +/** @ingroup ErrorCodes */ +#define SCARD_P_SHUTDOWN ((LONG)0x80100018) /**< The operation has been aborted to allow the server application to exit. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_PCI_TOO_SMALL ((LONG)0x80100019) /**< The PCI Receive buffer was too small. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_READER_UNSUPPORTED ((LONG)0x8010001A) /**< The reader driver does not meet minimal requirements for support. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_DUPLICATE_READER ((LONG)0x8010001B) /**< The reader driver did not produce a unique reader name. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_CARD_UNSUPPORTED ((LONG)0x8010001C) /**< The smart card does not meet minimal requirements for support. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_NO_SERVICE ((LONG)0x8010001D) /**< The Smart card resource manager is not running. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_SERVICE_STOPPED ((LONG)0x8010001E) /**< The Smart card resource manager has shut down. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_UNEXPECTED ((LONG)0x8010001F) /**< An unexpected card error has occurred. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_UNSUPPORTED_FEATURE ((LONG)0x8010001F) /**< This smart card does not support the requested feature. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_ICC_INSTALLATION ((LONG)0x80100020) /**< No primary provider can be found for the smart card. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_ICC_CREATEORDER ((LONG)0x80100021) /**< The requested order of object creation is not supported. */ +/** @ingroup ErrorCodes */ +/* #define SCARD_E_UNSUPPORTED_FEATURE ((LONG)0x80100022) / **< This smart card does not support the requested feature. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_DIR_NOT_FOUND ((LONG)0x80100023) /**< The identified directory does not exist in the smart card. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_FILE_NOT_FOUND ((LONG)0x80100024) /**< The identified file does not exist in the smart card. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_NO_DIR ((LONG)0x80100025) /**< The supplied path does not represent a smart card directory. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_NO_FILE ((LONG)0x80100026) /**< The supplied path does not represent a smart card file. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_NO_ACCESS ((LONG)0x80100027) /**< Access is denied to this file. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_WRITE_TOO_MANY ((LONG)0x80100028) /**< The smart card does not have enough memory to store the information. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_BAD_SEEK ((LONG)0x80100029) /**< There was an error trying to set the smart card file object pointer. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_INVALID_CHV ((LONG)0x8010002A) /**< The supplied PIN is incorrect. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_UNKNOWN_RES_MNG ((LONG)0x8010002B) /**< An unrecognized error code was returned from a layered component. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_NO_SUCH_CERTIFICATE ((LONG)0x8010002C) /**< The requested certificate does not exist. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_CERTIFICATE_UNAVAILABLE ((LONG)0x8010002D) /**< The requested certificate could not be obtained. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_NO_READERS_AVAILABLE ((LONG)0x8010002E) /**< Cannot find a smart card reader. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_COMM_DATA_LOST ((LONG)0x8010002F) /**< A communications error with the smart card has been detected. Retry the operation. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_NO_KEY_CONTAINER ((LONG)0x80100030) /**< The requested key container does not exist on the smart card. */ +/** @ingroup ErrorCodes */ +#define SCARD_E_SERVER_TOO_BUSY ((LONG)0x80100031) /**< The Smart Card Resource Manager is too busy to complete this operation. */ -#ifndef USE_IPCDIR -#define PCSCLITE_IPC_DIR "/var/run" -#else -#define PCSCLITE_IPC_DIR USE_IPCDIR -#endif +/** @ingroup ErrorCodes */ +#define SCARD_W_UNSUPPORTED_CARD ((LONG)0x80100065) /**< The reader cannot communicate with the card, due to ATR string configuration conflicts. */ +/** @ingroup ErrorCodes */ +#define SCARD_W_UNRESPONSIVE_CARD ((LONG)0x80100066) /**< The smart card is not responding to a reset. */ +/** @ingroup ErrorCodes */ +#define SCARD_W_UNPOWERED_CARD ((LONG)0x80100067) /**< Power has been removed from the smart card, so that further communication is not possible. */ +/** @ingroup ErrorCodes */ +#define SCARD_W_RESET_CARD ((LONG)0x80100068) /**< The smart card has been reset, so any shared state information is invalid. */ +/** @ingroup ErrorCodes */ +#define SCARD_W_REMOVED_CARD ((LONG)0x80100069) /**< The smart card has been removed, so further communication is not possible. */ + +/** @ingroup ErrorCodes */ +#define SCARD_W_SECURITY_VIOLATION ((LONG)0x8010006A) /**< Access was denied because of a security violation. */ +/** @ingroup ErrorCodes */ +#define SCARD_W_WRONG_CHV ((LONG)0x8010006B) /**< The card cannot be accessed because the wrong PIN was presented. */ +/** @ingroup ErrorCodes */ +#define SCARD_W_CHV_BLOCKED ((LONG)0x8010006C) /**< The card cannot be accessed because the maximum number of PIN entry attempts has been reached. */ +/** @ingroup ErrorCodes */ +#define SCARD_W_EOF ((LONG)0x8010006D) /**< The end of the smart card file has been reached. */ +/** @ingroup ErrorCodes */ +#define SCARD_W_CANCELLED_BY_USER ((LONG)0x8010006E) /**< The user pressed "Cancel" on a Smart Card Selection Dialog. */ +/** @ingroup ErrorCodes */ +#define SCARD_W_CARD_NOT_AUTHENTICATED ((LONG)0x8010006F) /**< No PIN was presented to the smart card. */ + +#define SCARD_AUTOALLOCATE (DWORD)(-1) /**< see SCardFreeMemory() */ +#define SCARD_SCOPE_USER 0x0000 /**< Scope in user space */ +#define SCARD_SCOPE_TERMINAL 0x0001 /**< Scope in terminal */ +#define SCARD_SCOPE_SYSTEM 0x0002 /**< Scope in system */ +#define SCARD_SCOPE_GLOBAL 0x0003 /**< Scope is global */ -#define PCSCLITE_READER_CONFIG PCSCLITE_CONFIG_DIR "/reader.conf" -#define PCSCLITE_PUBSHM_FILE PCSCLITE_IPC_DIR "/pcscd.pub" -#define PCSCLITE_CSOCK_NAME PCSCLITE_IPC_DIR "/pcscd.comm" +#define SCARD_PROTOCOL_UNDEFINED 0x0000 /**< protocol not set */ +#define SCARD_PROTOCOL_UNSET SCARD_PROTOCOL_UNDEFINED /* backward compat */ +#define SCARD_PROTOCOL_T0 0x0001 /**< T=0 active protocol. */ +#define SCARD_PROTOCOL_T1 0x0002 /**< T=1 active protocol. */ +#define SCARD_PROTOCOL_RAW 0x0004 /**< Raw active protocol. */ +#define SCARD_PROTOCOL_T15 0x0008 /**< T=15 protocol. */ + +#define SCARD_PROTOCOL_ANY (SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1) /**< IFD determines prot. */ + +#define SCARD_SHARE_EXCLUSIVE 0x0001 /**< Exclusive mode only */ +#define SCARD_SHARE_SHARED 0x0002 /**< Shared mode only */ +#define SCARD_SHARE_DIRECT 0x0003 /**< Raw mode only */ + +#define SCARD_LEAVE_CARD 0x0000 /**< Do nothing on close */ +#define SCARD_RESET_CARD 0x0001 /**< Reset on close */ +#define SCARD_UNPOWER_CARD 0x0002 /**< Power down on close */ +#define SCARD_EJECT_CARD 0x0003 /**< Eject on close */ -#define PCSCLITE_SVC_IDENTITY 0x01030000 /* Service ID */ +#define SCARD_UNKNOWN 0x0001 /**< Unknown state */ +#define SCARD_ABSENT 0x0002 /**< Card is absent */ +#define SCARD_PRESENT 0x0004 /**< Card is present */ +#define SCARD_SWALLOWED 0x0008 /**< Card not powered */ +#define SCARD_POWERED 0x0010 /**< Card is powered */ +#define SCARD_NEGOTIABLE 0x0020 /**< Ready for PTS */ +#define SCARD_SPECIFIC 0x0040 /**< PTS has been set */ + +#define SCARD_STATE_UNAWARE 0x0000 /**< App wants status */ +#define SCARD_STATE_IGNORE 0x0001 /**< Ignore this reader */ +#define SCARD_STATE_CHANGED 0x0002 /**< State has changed */ +#define SCARD_STATE_UNKNOWN 0x0004 /**< Reader unknown */ +#define SCARD_STATE_UNAVAILABLE 0x0008 /**< Status unavailable */ +#define SCARD_STATE_EMPTY 0x0010 /**< Card removed */ +#define SCARD_STATE_PRESENT 0x0020 /**< Card inserted */ +#define SCARD_STATE_ATRMATCH 0x0040 /**< ATR matches card */ +#define SCARD_STATE_EXCLUSIVE 0x0080 /**< Exclusive Mode */ +#define SCARD_STATE_INUSE 0x0100 /**< Shared Mode */ +#define SCARD_STATE_MUTE 0x0200 /**< Unresponsive card */ +#define SCARD_STATE_UNPOWERED 0x0400 /**< Unpowered card */ #ifndef INFINITE -#define INFINITE 0xFFFFFFFF /* Infinite timeout */ +#define INFINITE 0xFFFFFFFF /**< Infinite timeout */ #endif -#define PCSCLITE_INFINITE_TIMEOUT 4320000 /* 50 day infinite t/o */ - -#define PCSCLITE_VERSION_NUMBER "1.2.9-beta7" /* Current version */ -#define PCSCLITE_CLIENT_ATTEMPTS 120 /* Attempts to reach sv */ -#define PCSCLITE_MCLIENT_ATTEMPTS 20 /* Attempts to reach sv */ -#define PCSCLITE_STATUS_POLL_RATE 400000 /* Status polling rate */ -#define PCSCLITE_MSG_KEY_LEN 16 /* App ID key length */ -#define PCSCLITE_RW_ATTEMPTS 100 /* Attempts to rd/wrt */ -/* Maximum applications */ -#define PCSCLITE_MAX_APPLICATIONS 16 -/* Maximum contexts by application */ -#define PCSCLITE_MAX_APPLICATION_CONTEXTS 16 -/* Maximum of applications contexts that pcscd can accept */ -#define PCSCLITE_MAX_APPLICATIONS_CONTEXTS \ - PCSCLITE_MAX_APPLICATIONS * PCSCLITE_MAX_APPLICATION_CONTEXTS -/* Maximum channels on a reader context */ -#define PCSCLITE_MAX_READER_CONTEXT_CHANNELS 16 -/* Maximum channels on an application context */ -#define PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS 16 -/* Maximum readers context (a slot is count as a reader) */ -#define PCSCLITE_MAX_READERS_CONTEXTS 16 +#define PCSCLITE_VERSION_NUMBER "1.8.24" /**< Current version */ +/** Maximum readers context (a slot is count as a reader) */ +#define PCSCLITE_MAX_READERS_CONTEXTS 16 -/* PCSCLITE_MAX_READERS is deprecated - * use PCSCLITE_MAX_READERS_CONTEXTS instead */ -/* extern int PCSCLITE_MAX_READERS __attribute__ ((deprecated)); */ - -#define PCSCLITE_MAX_THREADS 16 /* Stat change threads */ -#define PCSCLITE_STATUS_WAIT 200000 /* Status Change Sleep */ -#define PCSCLITE_TRANSACTION_TIMEOUT 40 /* Transaction timeout */ -#define MAX_READERNAME 52 -#define MAX_LIBNAME 100 -#define MAX_DEVICENAME 255 +#define MAX_READERNAME 128 #ifndef SCARD_ATR_LENGTH -#define SCARD_ATR_LENGTH MAX_ATR_SIZE /* Maximum ATR size */ +#define SCARD_ATR_LENGTH MAX_ATR_SIZE /**< Maximum ATR size */ #endif /* - * Enhanced messaging has been added to accommodate newer devices which have - * more advanced capabilities, such as dedicated secure co-processors which - * can stream and encrypt data over USB. In order to used enhanced messaging - * you must define PCSCLITE_ENHANCED_MESSAGING in the framework(library), - * the daemon, and your application - */ -#undef PCSCLITE_ENHANCED_MESSAGING -#ifndef PCSCLITE_ENHANCED_MESSAGING -#define PCSCLITE_MAX_MESSAGE_SIZE 2048 /* Transport msg len */ -#define MAX_BUFFER_SIZE 264 /* Maximum Tx/Rx Buffer */ -#define PCSCLITE_SERVER_ATTEMPTS 5 /* Attempts to reach cl */ -#else -/* * The message and buffer sizes must be multiples of 16. * The max message size must be at least large enough - * to accommodate the transmit_struct + * to accomodate the transmit_struct */ -#define PCSCLITE_MAX_MESSAGE_SIZE (1<<17) /* enhanced (128K) msg len */ -#define MAX_BUFFER_SIZE (1<<15) /* enhanced (32K) Tx/Rx Buffer */ -#define PCSCLITE_SERVER_ATTEMPTS 200 /* To allow larger data reads/writes */ -#endif +#define MAX_BUFFER_SIZE 264 /**< Maximum Tx/Rx Buffer for short APDU */ +#define MAX_BUFFER_SIZE_EXTENDED (4 + 3 + (1<<16) + 3 + 2) /**< enhanced (64K + APDU + Lc + Le + SW) Tx/Rx Buffer */ /* * Gets a stringified error response */ -char *pcsc_stringify_error(long); +const char *pcsc_stringify_error(const LONG); #ifdef __cplusplus } diff -r 268875216dfc -r faf96b92a47b src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/winscard.h --- a/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/winscard.h Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/winscard.h Fri Mar 01 17:27:28 2019 +0530 @@ -1,13 +1,38 @@ /* - * This handles smartcard reader communications. - * - * MUSCLE SmartCard Development ( http://www.linuxnet.com ) + * MUSCLE SmartCard Development ( https://pcsclite.apdu.fr/ ) * * Copyright (C) 1999-2003 - * David Corcoran + * David Corcoran + * Copyright (C) 2002-2009 * Ludovic Rousseau * - * $Id: winscard.h,v 1.13 2004/08/06 12:12:19 rousseau Exp $ +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * @brief This handles smart card reader communications. */ #ifndef __winscard_h__ @@ -20,71 +45,79 @@ { #endif - LONG SCardEstablishContext(DWORD dwScope, - LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext); - - LONG SCardReleaseContext(SCARDCONTEXT hContext); +#ifndef PCSC_API +#define PCSC_API +#endif - LONG SCardSetTimeout(SCARDCONTEXT hContext, DWORD dwTimeout); + PCSC_API LONG SCardEstablishContext(DWORD dwScope, + /*@null@*/ LPCVOID pvReserved1, /*@null@*/ LPCVOID pvReserved2, + /*@out@*/ LPSCARDCONTEXT phContext); - LONG SCardConnect(SCARDCONTEXT hContext, - LPCTSTR szReader, - DWORD dwShareMode, - DWORD dwPreferredProtocols, - LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol); + PCSC_API LONG SCardReleaseContext(SCARDCONTEXT hContext); + + PCSC_API LONG SCardIsValidContext(SCARDCONTEXT hContext); - LONG SCardReconnect(SCARDHANDLE hCard, - DWORD dwShareMode, - DWORD dwPreferredProtocols, - DWORD dwInitialization, LPDWORD pdwActiveProtocol); + PCSC_API LONG SCardConnect(SCARDCONTEXT hContext, + LPCSTR szReader, + DWORD dwShareMode, + DWORD dwPreferredProtocols, + /*@out@*/ LPSCARDHANDLE phCard, /*@out@*/ LPDWORD pdwActiveProtocol); - LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition); - - LONG SCardBeginTransaction(SCARDHANDLE hCard); + PCSC_API LONG SCardReconnect(SCARDHANDLE hCard, + DWORD dwShareMode, + DWORD dwPreferredProtocols, + DWORD dwInitialization, /*@out@*/ LPDWORD pdwActiveProtocol); - LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition); + PCSC_API LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition); - LONG SCardCancelTransaction(SCARDHANDLE hCard); + PCSC_API LONG SCardBeginTransaction(SCARDHANDLE hCard); + + PCSC_API LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition); - LONG SCardStatus(SCARDHANDLE hCard, - LPTSTR mszReaderNames, LPDWORD pcchReaderLen, - LPDWORD pdwState, - LPDWORD pdwProtocol, - LPBYTE pbAtr, LPDWORD pcbAtrLen); + PCSC_API LONG SCardStatus(SCARDHANDLE hCard, + /*@null@*/ /*@out@*/ LPSTR mszReaderName, + /*@null@*/ /*@out@*/ LPDWORD pcchReaderLen, + /*@null@*/ /*@out@*/ LPDWORD pdwState, + /*@null@*/ /*@out@*/ LPDWORD pdwProtocol, + /*@null@*/ /*@out@*/ LPBYTE pbAtr, + /*@null@*/ /*@out@*/ LPDWORD pcbAtrLen); - LONG SCardGetStatusChange(SCARDCONTEXT hContext, - DWORD dwTimeout, - LPSCARD_READERSTATE_A rgReaderStates, DWORD cReaders); + PCSC_API LONG SCardGetStatusChange(SCARDCONTEXT hContext, + DWORD dwTimeout, + SCARD_READERSTATE *rgReaderStates, DWORD cReaders); - LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, - LPCVOID pbSendBuffer, DWORD cbSendLength, - LPVOID pbRecvBuffer, DWORD cbRecvLength, LPDWORD lpBytesReturned); + PCSC_API LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, + LPCVOID pbSendBuffer, DWORD cbSendLength, + /*@out@*/ LPVOID pbRecvBuffer, DWORD cbRecvLength, + LPDWORD lpBytesReturned); - LONG SCardTransmit(SCARDHANDLE hCard, - LPCSCARD_IO_REQUEST pioSendPci, - LPCBYTE pbSendBuffer, DWORD cbSendLength, - LPSCARD_IO_REQUEST pioRecvPci, - LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength); + PCSC_API LONG SCardTransmit(SCARDHANDLE hCard, + const SCARD_IO_REQUEST *pioSendPci, + LPCBYTE pbSendBuffer, DWORD cbSendLength, + /*@out@*/ SCARD_IO_REQUEST *pioRecvPci, + /*@out@*/ LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength); - LONG SCardListReaderGroups(SCARDCONTEXT hContext, - LPTSTR mszGroups, LPDWORD pcchGroups); + PCSC_API LONG SCardListReaderGroups(SCARDCONTEXT hContext, + /*@out@*/ LPSTR mszGroups, LPDWORD pcchGroups); - LONG SCardListReaders(SCARDCONTEXT hContext, - LPCTSTR mszGroups, - LPTSTR mszReaders, LPDWORD pcchReaders); + PCSC_API LONG SCardListReaders(SCARDCONTEXT hContext, + /*@null@*/ /*@out@*/ LPCSTR mszGroups, + /*@null@*/ /*@out@*/ LPSTR mszReaders, + /*@out@*/ LPDWORD pcchReaders); - LONG SCardCancel(SCARDCONTEXT hContext); + PCSC_API LONG SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem); - LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, - LPDWORD pcbAttrLen); + PCSC_API LONG SCardCancel(SCARDCONTEXT hContext); - LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr, - DWORD cbAttrLen); + PCSC_API LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, + /*@out@*/ LPBYTE pbAttr, LPDWORD pcbAttrLen); - void SCardUnload(void); + PCSC_API LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, + LPCBYTE pbAttr, DWORD cbAttrLen); #ifdef __cplusplus } #endif #endif + diff -r 268875216dfc -r faf96b92a47b src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/wintypes.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/wintypes.h Fri Mar 01 17:27:28 2019 +0530 @@ -0,0 +1,115 @@ +/* + * MUSCLE SmartCard Development ( https://pcsclite.apdu.fr/ ) + * + * Copyright (C) 1999 + * David Corcoran + * Copyright (C) 2002-2011 + * Ludovic Rousseau + * +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * @brief This keeps a list of Windows(R) types. + */ + +#ifndef __wintypes_h__ +#define __wintypes_h__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifdef __APPLE__ + +#include + +#ifndef BYTE + typedef uint8_t BYTE; +#endif + typedef uint8_t UCHAR; + typedef UCHAR *PUCHAR; + typedef uint16_t USHORT; + +#ifndef __COREFOUNDATION_CFPLUGINCOM__ + typedef uint32_t ULONG; + typedef void *LPVOID; + typedef int16_t BOOL; +#endif + + typedef ULONG *PULONG; + typedef const void *LPCVOID; + typedef uint32_t DWORD; + typedef DWORD *PDWORD; + typedef uint16_t WORD; + typedef int32_t LONG; + typedef const char *LPCSTR; + typedef const BYTE *LPCBYTE; + typedef BYTE *LPBYTE; + typedef DWORD *LPDWORD; + typedef char *LPSTR; + +#else + +#ifndef BYTE + typedef unsigned char BYTE; +#endif + typedef unsigned char UCHAR; + typedef UCHAR *PUCHAR; + typedef unsigned short USHORT; + +#ifndef __COREFOUNDATION_CFPLUGINCOM__ + typedef unsigned long ULONG; + typedef void *LPVOID; +#endif + + typedef const void *LPCVOID; + typedef unsigned long DWORD; + typedef DWORD *PDWORD; + typedef long LONG; + typedef const char *LPCSTR; + typedef const BYTE *LPCBYTE; + typedef BYTE *LPBYTE; + typedef DWORD *LPDWORD; + typedef char *LPSTR; + + /* these types were deprecated but still used by old drivers and + * applications. So just declare and use them. */ + typedef LPSTR LPTSTR; + typedef LPCSTR LPCTSTR; + + /* types unused by pcsc-lite */ + typedef short BOOL; + typedef unsigned short WORD; + typedef ULONG *PULONG; + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff -r 268875216dfc -r faf96b92a47b src/java.smartcardio/unix/native/libj2pcsc/pcsc_md.h --- a/src/java.smartcardio/unix/native/libj2pcsc/pcsc_md.h Mon Feb 25 15:15:46 2019 +0530 +++ b/src/java.smartcardio/unix/native/libj2pcsc/pcsc_md.h Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2019, 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 @@ -23,48 +23,49 @@ * questions. */ -typedef LONG (*FPTR_SCardEstablishContext)(ULONG dwScope, - const void *pvReserved1, - const void *pvReserved2, - LONG *phContext); +typedef LONG (*FPTR_SCardEstablishContext)(DWORD dwScope, + LPCVOID pvReserved1, + LPCVOID pvReserved2, + LPSCARDCONTEXT phContext); -typedef LONG (*FPTR_SCardConnect)(LONG hContext, - const char *szReader, - ULONG dwShareMode, - ULONG dwPreferredProtocols, - LONG *phCard, ULONG *pdwActiveProtocol); +typedef LONG (*FPTR_SCardConnect)(SCARDCONTEXT hContext, + LPCSTR szReader, + DWORD dwShareMode, + DWORD dwPreferredProtocols, + LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol); -typedef LONG (*FPTR_SCardDisconnect)(LONG hCard, ULONG dwDisposition); +typedef LONG (*FPTR_SCardDisconnect)(SCARDHANDLE hCard, DWORD dwDisposition); -typedef LONG (*FPTR_SCardStatus)(LONG hCard, - char *mszReaderNames, - ULONG *pcchReaderLen, - ULONG *pdwState, - ULONG *pdwProtocol, - unsigned char *pbAtr, ULONG *pcbAtrLen); +typedef LONG (*FPTR_SCardStatus)(SCARDHANDLE hCard, + LPSTR mszReaderNames, + LPDWORD pcchReaderLen, + LPDWORD pdwState, + LPDWORD pdwProtocol, + LPBYTE pbAtr, LPDWORD pcbAtrLen); -typedef LONG (*FPTR_SCardGetStatusChange)(LONG hContext, - ULONG dwTimeout, - LPSCARD_READERSTATE_A rgReaderStates, ULONG cReaders); +typedef LONG (*FPTR_SCardGetStatusChange)(SCARDCONTEXT hContext, + DWORD dwTimeout, + SCARD_READERSTATE *rgReaderStates, DWORD cReaders); -typedef LONG (*FPTR_SCardTransmit)(LONG hCard, - LPCSCARD_IO_REQUEST pioSendPci, - const unsigned char *pbSendBuffer, - ULONG cbSendLength, - LPSCARD_IO_REQUEST pioRecvPci, - unsigned char *pbRecvBuffer, ULONG *pcbRecvLength); +typedef LONG (*FPTR_SCardTransmit)(SCARDHANDLE hCard, + const SCARD_IO_REQUEST *pioSendPci, + LPCBYTE pbSendBuffer, + DWORD cbSendLength, + SCARD_IO_REQUEST *pioRecvPci, + LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength); -typedef LONG (*FPTR_SCardListReaders)(LONG hContext, - const char *mszGroups, - char *mszReaders, ULONG *pcchReaders); +typedef LONG (*FPTR_SCardListReaders)(SCARDCONTEXT hContext, + LPCSTR mszGroups, + LPSTR mszReaders, LPDWORD pcchReaders); -typedef LONG (*FPTR_SCardBeginTransaction)(LONG hCard); +typedef LONG (*FPTR_SCardBeginTransaction)(SCARDHANDLE hCard); -typedef LONG (*FPTR_SCardEndTransaction)(LONG hCard, ULONG dwDisposition); +typedef LONG (*FPTR_SCardEndTransaction)(SCARDHANDLE hCard, + DWORD dwDisposition); -typedef LONG (*FPTR_SCardControl)(LONG hCard, ULONG dwControlCode, - const void* pbSendBuffer, ULONG cbSendLength, const void* pbRecvBuffer, - ULONG pcbRecvLength, ULONG *lpBytesReturned); +typedef LONG (*FPTR_SCardControl)(SCARDHANDLE hCard, DWORD dwControlCode, + LPCVOID pbSendBuffer, DWORD cbSendLength, LPVOID pbRecvBuffer, + DWORD pcbRecvLength, LPDWORD lpBytesReturned); #define CALL_SCardEstablishContext(dwScope, pvReserved1, pvReserved2, phContext) \ ((scardEstablishContext)(dwScope, pvReserved1, pvReserved2, phContext)) diff -r 268875216dfc -r faf96b92a47b src/jdk.accessibility/windows/native/jaccessinspector/jaccessinspectorWindow.rc --- a/src/jdk.accessibility/windows/native/jaccessinspector/jaccessinspectorWindow.rc Mon Feb 25 15:15:46 2019 +0530 +++ b/src/jdk.accessibility/windows/native/jaccessinspector/jaccessinspectorWindow.rc Fri Mar 01 17:27:28 2019 +0530 @@ -202,7 +202,7 @@ VALUE "CompanyName", XSTR(JDK_COMPANY) "\0" VALUE "FileDescription", XSTR(JDK_COMPONENT) "\0" VALUE "FileVersion", XSTR(JDK_VER) "\0" - VALUE "Full Version", XSTR(JDK_BUILD_ID) "\0" + VALUE "Full Version", XSTR(JDK_VERSION_STRING) "\0" VALUE "InternalName", XSTR(JDK_INTERNAL_NAME) "\0" VALUE "LegalCopyright", XSTR(JDK_COPYRIGHT) "\0" VALUE "OriginalFilename", XSTR(JDK_FNAME) "\0" diff -r 268875216dfc -r faf96b92a47b src/jdk.accessibility/windows/native/jaccesswalker/jaccesswalkerWindow.rc --- a/src/jdk.accessibility/windows/native/jaccesswalker/jaccesswalkerWindow.rc Mon Feb 25 15:15:46 2019 +0530 +++ b/src/jdk.accessibility/windows/native/jaccesswalker/jaccesswalkerWindow.rc Fri Mar 01 17:27:28 2019 +0530 @@ -167,7 +167,7 @@ VALUE "CompanyName", XSTR(JDK_COMPANY) "\0" VALUE "FileDescription", XSTR(JDK_COMPONENT) "\0" VALUE "FileVersion", XSTR(JDK_VER) "\0" - VALUE "Full Version", XSTR(JDK_BUILD_ID) "\0" + VALUE "Full Version", XSTR(JDK_VERSION_STRING) "\0" VALUE "InternalName", XSTR(JDK_INTERNAL_NAME) "\0" VALUE "LegalCopyright", XSTR(JDK_COPYRIGHT) "\0" VALUE "OriginalFilename", XSTR(JDK_FNAME) "\0" diff -r 268875216dfc -r faf96b92a47b src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyGenerator.java --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyGenerator.java Mon Feb 25 15:15:46 2019 +0530 +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyGenerator.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, 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 @@ -119,11 +119,13 @@ // RC4 which is in bits. However, some PKCS#11 impls still use // bytes for all mechs, e.g. NSS. We try to detect this // inconsistency if the minKeySize seems unreasonably small. - int minKeySize = (int)info.ulMinKeySize; - int maxKeySize = (int)info.ulMaxKeySize; + int minKeySize = info.iMinKeySize; + int maxKeySize = info.iMaxKeySize; if (keyGenMech != CKM_RC4_KEY_GEN || minKeySize < 8) { - minKeySize = (int)info.ulMinKeySize << 3; - maxKeySize = (int)info.ulMaxKeySize << 3; + minKeySize = Math.multiplyExact(minKeySize, 8); + if (maxKeySize != Integer.MAX_VALUE) { + maxKeySize = Math.multiplyExact(maxKeySize, 8); + } } // Explicitly disallow keys shorter than 40-bits for security if (minKeySize < 40) minKeySize = 40; diff -r 268875216dfc -r faf96b92a47b src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java Mon Feb 25 15:15:46 2019 +0530 +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, 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 @@ -73,7 +73,7 @@ private BigInteger rsaPublicExponent = RSAKeyGenParameterSpec.F4; // the supported keysize range of the native PKCS11 library - // if the value cannot be retrieved or unspecified, -1 is used. + // if mechanism info is unavailable, 0/Integer.MAX_VALUE is used private final int minKeySize; private final int maxKeySize; @@ -83,13 +83,13 @@ P11KeyPairGenerator(Token token, String algorithm, long mechanism) throws PKCS11Exception { super(); - int minKeyLen = -1; - int maxKeyLen = -1; + int minKeyLen = 0; + int maxKeyLen = Integer.MAX_VALUE; try { CK_MECHANISM_INFO mechInfo = token.getMechanismInfo(mechanism); if (mechInfo != null) { - minKeyLen = (int) mechInfo.ulMinKeySize; - maxKeyLen = (int) mechInfo.ulMaxKeySize; + minKeyLen = mechInfo.iMinKeySize; + maxKeyLen = mechInfo.iMaxKeySize; } } catch (PKCS11Exception p11e) { // Should never happen @@ -101,10 +101,10 @@ // override upper limit to deter DOS attack if (algorithm.equals("EC")) { keySize = DEF_EC_KEY_SIZE; - if ((minKeyLen == -1) || (minKeyLen < 112)) { + if (minKeyLen < 112) { minKeyLen = 112; } - if ((maxKeyLen == -1) || (maxKeyLen > 2048)) { + if (maxKeyLen > 2048) { maxKeyLen = 2048; } } else { @@ -112,24 +112,22 @@ keySize = DEF_DSA_KEY_SIZE; } else if (algorithm.equals("RSA")) { keySize = DEF_RSA_KEY_SIZE; + if (maxKeyLen > 64 * 1024) { + maxKeyLen = 64 * 1024; + } } else { keySize = DEF_DH_KEY_SIZE; } - if ((minKeyLen == -1) || (minKeyLen < 512)) { + if (minKeyLen < 512) { minKeyLen = 512; } - if (algorithm.equals("RSA")) { - if ((maxKeyLen == -1) || (maxKeyLen > 64 * 1024)) { - maxKeyLen = 64 * 1024; - } - } } // auto-adjust default keysize in case it's out-of-range - if ((minKeyLen != -1) && (keySize < minKeyLen)) { + if (keySize < minKeyLen) { keySize = minKeyLen; } - if ((maxKeyLen != -1) && (keySize > maxKeyLen)) { + if (keySize > maxKeyLen) { keySize = maxKeyLen; } this.token = token; @@ -233,13 +231,17 @@ private void checkKeySize(int keySize, AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { + if (keySize <= 0) { + throw new InvalidAlgorithmParameterException + ("key size must be positive, got " + keySize); + } // check native range first - if ((minKeySize != -1) && (keySize < minKeySize)) { + if (keySize < minKeySize) { throw new InvalidAlgorithmParameterException(algorithm + " key must be at least " + minKeySize + " bits. " + "The specific key size " + keySize + " is not supported"); } - if ((maxKeySize != -1) && (keySize > maxKeySize)) { + if (keySize > maxKeySize) { throw new InvalidAlgorithmParameterException(algorithm + " key must be at most " + maxKeySize + " bits. " + "The specific key size " + keySize + " is not supported"); @@ -272,12 +274,8 @@ ((RSAKeyGenParameterSpec)params).getPublicExponent(); } try { - // Reuse the checking in SunRsaSign provider. - // If maxKeySize is -1, then replace it with - // Integer.MAX_VALUE to indicate no limit. RSAKeyFactory.checkKeyLengths(keySize, tmpExponent, - minKeySize, - (maxKeySize==-1? Integer.MAX_VALUE:maxKeySize)); + minKeySize, maxKeySize); } catch (InvalidKeyException e) { throw new InvalidAlgorithmParameterException(e); } diff -r 268875216dfc -r faf96b92a47b src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Signature.java --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Signature.java Mon Feb 25 15:15:46 2019 +0530 +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Signature.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, 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 @@ -394,8 +394,9 @@ // skip the check if no native info available return; } - int minKeySize = (int) mechInfo.ulMinKeySize; - int maxKeySize = (int) mechInfo.ulMaxKeySize; + int minKeySize = mechInfo.iMinKeySize; + int maxKeySize = mechInfo.iMaxKeySize; + // need to override the MAX keysize for SHA1withDSA if (md != null && mechanism == CKM_DSA && maxKeySize > 1024) { maxKeySize = 1024; @@ -419,11 +420,11 @@ " key must be the right type", cce); } } - if ((minKeySize != -1) && (keySize < minKeySize)) { + if (keySize < minKeySize) { throw new InvalidKeyException(keyAlgo + " key must be at least " + minKeySize + " bits"); } - if ((maxKeySize != -1) && (keySize > maxKeySize)) { + if (keySize > maxKeySize) { throw new InvalidKeyException(keyAlgo + " key must be at most " + maxKeySize + " bits"); } diff -r 268875216dfc -r faf96b92a47b src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM_INFO.java --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM_INFO.java Mon Feb 25 15:15:46 2019 +0530 +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM_INFO.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2019, 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. + */ /* * reserved comment block * DO NOT REMOVE OR ALTER! @@ -47,7 +71,7 @@ package sun.security.pkcs11.wrapper; - +import java.security.ProviderException; /** * class CK_MECHANISM_INFO provides information about a particular mechanism. @@ -74,6 +98,10 @@ */ public long ulMinKeySize; + // the integer version of ulMinKeySize for doing the actual range + // check in SunPKCS11 provider, defaults to 0 + public final int iMinKeySize; + /** * PKCS#11: *

    @@ -82,6 +110,10 @@
          */
         public long ulMaxKeySize;
     
    +    // the integer version of ulMaxKeySize for doing the actual range
    +    // check in SunPKCS11 provider, defaults to Integer.MAX_VALUE
    +    public final int iMaxKeySize;
    +
         /**
          * PKCS#11:
          * 
    @@ -94,6 +126,10 @@
                                  long flags) {
             this.ulMinKeySize = minKeySize;
             this.ulMaxKeySize = maxKeySize;
    +        this.iMinKeySize = ((minKeySize < Integer.MAX_VALUE && minKeySize > 0)?
    +                (int)minKeySize : 0);
    +        this.iMaxKeySize = ((maxKeySize < Integer.MAX_VALUE && maxKeySize > 0)?
    +                (int)maxKeySize : Integer.MAX_VALUE);
             this.flags = flags;
         }
     
    diff -r 268875216dfc -r faf96b92a47b src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/aarch64/AARCH64CurrentFrameGuess.java
    --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/aarch64/AARCH64CurrentFrameGuess.java	Mon Feb 25 15:15:46 2019 +0530
    +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/aarch64/AARCH64CurrentFrameGuess.java	Fri Mar 01 17:27:28 2019 +0530
    @@ -1,6 +1,6 @@
     /*
    - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
    - * Copyright (c) 2015, Red Hat Inc.
    + * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2015, 2019, Red Hat Inc.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -223,7 +223,13 @@
             }
           }
     
    -      setValues(sp, fp, null);
    +      // We found a PC in the frame anchor. Check that it's plausible, and
    +      // if it is, use it.
    +      if (vm.isJavaPCDbg(pc)) {
    +        setValues(sp, fp, pc);
    +      } else {
    +        setValues(sp, fp, null);
    +      }
     
           return true;
         }
    diff -r 268875216dfc -r faf96b92a47b src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/aarch64/AARCH64Frame.java
    --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/aarch64/AARCH64Frame.java	Mon Feb 25 15:15:46 2019 +0530
    +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/aarch64/AARCH64Frame.java	Fri Mar 01 17:27:28 2019 +0530
    @@ -1,6 +1,6 @@
     /*
    - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
    - * Copyright (c) 2015, Red Hat Inc.
    + * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2015, 2019, Red Hat Inc.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -136,7 +136,15 @@
         this.raw_sp = raw_sp;
         this.raw_unextendedSP = raw_sp;
         this.raw_fp = raw_fp;
    -    this.pc = raw_sp.getAddressAt(-1 * VM.getVM().getAddressSize());
    +
    +    // We cannot assume SP[-1] always contains a valid return PC (e.g. if
    +    // the callee is a C/C++ compiled frame). If the PC is not known to
    +    // Java then this.pc is null.
    +    Address savedPC = raw_sp.getAddressAt(-1 * VM.getVM().getAddressSize());
    +    if (VM.getVM().isJavaPCDbg(savedPC)) {
    +      this.pc = savedPC;
    +    }
    +
         adjustUnextendedSP();
     
         // Frame must be fully constructed before this call
    diff -r 268875216dfc -r faf96b92a47b src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java
    --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java	Mon Feb 25 15:15:46 2019 +0530
    +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java	Fri Mar 01 17:27:28 2019 +0530
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2004, 2019, 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
    @@ -938,10 +938,16 @@
         }
     
         protected void writeInstance(Instance instance) throws IOException {
    +        Klass klass = instance.getKlass();
    +        if (klass.getClassLoaderData() == null) {
    +            // Ignoring this object since the corresponding Klass is not loaded.
    +            // Might be a dormant archive object.
    +            return;
    +        }
    +
             out.writeByte((byte) HPROF_GC_INSTANCE_DUMP);
             writeObjectID(instance);
             out.writeInt(DUMMY_STACK_TRACE_ID);
    -        Klass klass = instance.getKlass();
             writeObjectID(klass.getJavaMirror());
     
             ClassData cd = (ClassData) classDataCache.get(klass);
    diff -r 268875216dfc -r faf96b92a47b src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java
    --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java	Mon Feb 25 15:15:46 2019 +0530
    +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java	Fri Mar 01 17:27:28 2019 +0530
    @@ -756,6 +756,13 @@
                     }
                     String text = messager.getText("main.doclet_class_not_found", userDocletName);
                     throw new ToolException(CMDERR, text, cnfe);
    +            } catch (NoClassDefFoundError ncfe) {
    +                if (ncfe.getMessage().contains("com/sun/javadoc/Doclet")) {
    +                    String text = messager.getText("main.not_a_doclet", userDocletName);
    +                    throw new ToolException(ERROR, text, ncfe);
    +                } else {
    +                    throw ncfe;
    +                }
                 }
             }
     
    diff -r 268875216dfc -r faf96b92a47b src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Main.java
    --- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Main.java	Mon Feb 25 15:15:46 2019 +0530
    +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Main.java	Fri Mar 01 17:27:28 2019 +0530
    @@ -45,6 +45,8 @@
     import java.util.NoSuchElementException;
     import java.util.Set;
     import java.util.Queue;
    +import java.util.stream.Collectors;
    +import java.util.stream.IntStream;
     import java.util.stream.Stream;
     import java.util.stream.StreamSupport;
     import java.util.jar.JarEntry;
    @@ -106,7 +108,10 @@
         // Keep these updated manually until there's a compiler API
         // that allows querying of supported releases.
         final Set releasesWithoutForRemoval = Set.of("6", "7", "8");
    -    final Set releasesWithForRemoval = Set.of("9", "10", "11", "12", "13");
    +    final Set releasesWithForRemoval = // "9", "10", "11", ...
    +        IntStream.rangeClosed(9, Runtime.version().feature())
    +        .mapToObj(Integer::toString)
    +        .collect(Collectors.toUnmodifiableSet());
     
         final Set validReleases;
         {
    diff -r 268875216dfc -r faf96b92a47b src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/BreakpointSpec.java
    --- a/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/BreakpointSpec.java	Mon Feb 25 15:15:46 2019 +0530
    +++ b/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/BreakpointSpec.java	Fri Mar 01 17:27:28 2019 +0530
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1998, 2019, 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
    @@ -44,20 +44,24 @@
         String methodId;
         List methodArgs;
         int lineNumber;
    +    ThreadReference threadFilter; /* Thread to break in. null if global breakpoint. */
    +    public static final String locationTokenDelimiter = ":( \t\n\r";
     
    -    BreakpointSpec(ReferenceTypeSpec refSpec, int lineNumber) {
    +    BreakpointSpec(ReferenceTypeSpec refSpec, int lineNumber, ThreadReference threadFilter) {
             super(refSpec);
             this.methodId = null;
             this.methodArgs = null;
             this.lineNumber = lineNumber;
    +        this.threadFilter = threadFilter;
         }
     
    -    BreakpointSpec(ReferenceTypeSpec refSpec, String methodId,
    +    BreakpointSpec(ReferenceTypeSpec refSpec, String methodId, ThreadReference threadFilter,
                        List methodArgs) throws MalformedMemberNameException {
             super(refSpec);
             this.methodId = methodId;
             this.methodArgs = methodArgs;
             this.lineNumber = 0;
    +        this.threadFilter = threadFilter;
             if (!isValidMethodName(methodId)) {
                 throw new MalformedMemberNameException(methodId);
             }
    @@ -78,8 +82,11 @@
                 throw new InvalidTypeException();
             }
             EventRequestManager em = refType.virtualMachine().eventRequestManager();
    -        EventRequest bp = em.createBreakpointRequest(location);
    +        BreakpointRequest bp = em.createBreakpointRequest(location);
             bp.setSuspendPolicy(suspendPolicy);
    +        if (threadFilter != null) {
    +            bp.addThreadFilter(threadFilter);
    +        }
             bp.enable();
             return bp;
         }
    @@ -104,7 +111,8 @@
         public int hashCode() {
             return refSpec.hashCode() + lineNumber +
                 ((methodId != null) ? methodId.hashCode() : 0) +
    -            ((methodArgs != null) ? methodArgs.hashCode() : 0);
    +            ((methodArgs != null) ? methodArgs.hashCode() : 0) +
    +            ((threadFilter != null) ? threadFilter.hashCode() : 0);
         }
     
         @Override
    @@ -118,6 +126,9 @@
                        ((methodArgs != null) ?
                             methodArgs.equals(breakpoint.methodArgs)
                           : methodArgs == breakpoint.methodArgs) &&
    +                   ((threadFilter != null) ?
    +                        threadFilter.equals(breakpoint.threadFilter)
    +                      : threadFilter == breakpoint.threadFilter) &&
                        refSpec.equals(breakpoint.refSpec) &&
                        (lineNumber == breakpoint.lineNumber);
             } else {
    diff -r 268875216dfc -r faf96b92a47b src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/Commands.java
    --- a/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/Commands.java	Mon Feb 25 15:15:46 2019 +0530
    +++ b/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/Commands.java	Fri Mar 01 17:27:28 2019 +0530
    @@ -1037,16 +1037,16 @@
         }
     
     
    -    private void printBreakpointCommandUsage(String atForm, String inForm) {
    -        MessageOutput.println("printbreakpointcommandusage",
    -                              new Object [] {atForm, inForm});
    +    private void printBreakpointCommandUsage(String usageMessage) {
    +        MessageOutput.println(usageMessage);
         }
     
    -    protected BreakpointSpec parseBreakpointSpec(StringTokenizer t,
    -                                             String atForm, String inForm) {
    +    protected BreakpointSpec parseBreakpointSpec(StringTokenizer t, String next_token,
    +                                                 ThreadReference threadFilter,
    +                                                 String usageMessage) {
             BreakpointSpec breakpoint = null;
             try {
    -            String token = t.nextToken(":( \t\n\r");
    +            String token = next_token;
     
                 // We can't use hasMoreTokens here because it will cause any leading
                 // paren to be lost.
    @@ -1064,16 +1064,24 @@
     
                     NumberFormat nf = NumberFormat.getNumberInstance();
                     nf.setParseIntegerOnly(true);
    -                Number n = nf.parse(lineToken);
    +                Number n;
    +                try {
    +                    n = nf.parse(lineToken);
    +                } catch (java.text.ParseException pe) {
    +                    MessageOutput.println("Invalid line number specified");
    +                    printBreakpointCommandUsage(usageMessage);
    +                    return null;
    +                }
                     int lineNumber = n.intValue();
     
                     if (t.hasMoreTokens()) {
    -                    printBreakpointCommandUsage(atForm, inForm);
    +                    MessageOutput.println("Extra tokens after breakpoint location");
    +                    printBreakpointCommandUsage(usageMessage);
                         return null;
                     }
                     try {
                         breakpoint = Env.specList.createBreakpoint(classId,
    -                                                               lineNumber);
    +                                                               lineNumber, threadFilter);
                     } catch (ClassNotFoundException exc) {
                         MessageOutput.println("is not a valid class name", classId);
                     }
    @@ -1082,7 +1090,8 @@
                     int idot = token.lastIndexOf('.');
                     if ( (idot <= 0) ||                     /* No dot or dot in first char */
                          (idot >= token.length() - 1) ) { /* dot in last char */
    -                    printBreakpointCommandUsage(atForm, inForm);
    +                    MessageOutput.println("Invalid . specification");
    +                    printBreakpointCommandUsage(usageMessage);
                         return null;
                     }
                     String methodName = token.substring(idot + 1);
    @@ -1090,9 +1099,9 @@
                     List argumentList = null;
                     if (rest != null) {
                         if (!rest.startsWith("(") || !rest.endsWith(")")) {
    -                        MessageOutput.println("Invalid method specification:",
    +                        MessageOutput.println("Invalid  specification:",
                                                   methodName + rest);
    -                        printBreakpointCommandUsage(atForm, inForm);
    +                        printBreakpointCommandUsage(usageMessage);
                             return null;
                         }
                         // Trim the parens
    @@ -1107,6 +1116,7 @@
                     try {
                         breakpoint = Env.specList.createBreakpoint(classId,
                                                                    methodName,
    +                                                               threadFilter,
                                                                    argumentList);
                     } catch (MalformedMemberNameException exc) {
                         MessageOutput.println("is not a valid method name", methodName);
    @@ -1115,7 +1125,7 @@
                     }
                 }
             } catch (Exception e) {
    -            printBreakpointCommandUsage(atForm, inForm);
    +            printBreakpointCommandUsage(usageMessage);
                 return null;
             }
             return breakpoint;
    @@ -1145,33 +1155,74 @@
         }
     
         void commandStop(StringTokenizer t) {
    -        String atIn;
             byte suspendPolicy = EventRequest.SUSPEND_ALL;
    +        ThreadReference threadFilter = null;
     
    -        if (t.hasMoreTokens()) {
    -            atIn = t.nextToken();
    -            if (atIn.equals("go") && t.hasMoreTokens()) {
    -                suspendPolicy = EventRequest.SUSPEND_NONE;
    -                atIn = t.nextToken();
    -            } else if (atIn.equals("thread") && t.hasMoreTokens()) {
    -                suspendPolicy = EventRequest.SUSPEND_EVENT_THREAD;
    -                atIn = t.nextToken();
    -            }
    -        } else {
    +        /*
    +         * Allowed syntax:
    +         *    stop [go|thread] []  
    +         * If no options are given, the current list of breakpoints is printed.
    +         * If "go" is specified, then immediately resume after stopping. No threads are suspended.
    +         * If "thread" is specified, then only suspend the thread we stop in.
    +         * If neither "go" nor "thread" are specified, then suspend all threads.
    +         * If an integer  is specified, then only stop in the specified thread.
    +         *  can either be a line number or a method:
    +         *    - :
    +         *    - .[(argument_type,...)]
    +         */
    +
    +        if (!t.hasMoreTokens()) {
                 listBreakpoints();
                 return;
             }
     
    -        BreakpointSpec spec = parseBreakpointSpec(t, "stop at", "stop in");
    -        if (spec != null) {
    -            // Enforcement of "at" vs. "in". The distinction is really
    -            // unnecessary and we should consider not checking for this
    -            // (and making "at" and "in" optional).
    -            if (atIn.equals("at") && spec.isMethodBreakpoint()) {
    -                MessageOutput.println("Use stop at to set a breakpoint at a line number");
    -                printBreakpointCommandUsage("stop at", "stop in");
    +        String token = t.nextToken();
    +
    +        /* Check for "go" or "thread" modifiers. */
    +        if (token.equals("go") && t.hasMoreTokens()) {
    +            suspendPolicy = EventRequest.SUSPEND_NONE;
    +            token = t.nextToken();
    +        } else if (token.equals("thread") && t.hasMoreTokens()) {
    +            suspendPolicy = EventRequest.SUSPEND_EVENT_THREAD;
    +            token = t.nextToken();
    +        }
    +
    +        /* Handle  modifier. */
    +        if (!token.equals("at") && !token.equals("in")) {
    +            Long threadid;
    +            try {
    +                threadid = Long.decode(token);
    +            } catch (NumberFormatException nfe) {
    +                MessageOutput.println("Expected at, in, or an integer :", token);
    +                printBreakpointCommandUsage("printstopcommandusage");
                     return;
                 }
    +            try {
    +                ThreadInfo threadInfo = ThreadInfo.getThreadInfo(token);
    +                if (threadInfo == null) {
    +                    MessageOutput.println("Invalid :", token);
    +                    return;
    +                }
    +                threadFilter = threadInfo.getThread();
    +                token = t.nextToken(BreakpointSpec.locationTokenDelimiter);
    +            } catch (VMNotConnectedException vmnce) {
    +                MessageOutput.println(" option not valid until the VM is started with the run command");
    +                return;
    +            }
    +
    +        }
    +
    +        /* Make sure "at" or "in" comes next. */
    +        if (!token.equals("at") && !token.equals("in")) {
    +            MessageOutput.println("Missing at or in");
    +            printBreakpointCommandUsage("printstopcommandusage");
    +            return;
    +        }
    +
    +        token = t.nextToken(BreakpointSpec.locationTokenDelimiter);
    +
    +        BreakpointSpec spec = parseBreakpointSpec(t, token, threadFilter, "printstopcommandusage");
    +        if (spec != null) {
                 spec.suspendPolicy = suspendPolicy;
                 resolveNow(spec);
             }
    @@ -1183,7 +1234,8 @@
                 return;
             }
     
    -        BreakpointSpec spec = parseBreakpointSpec(t, "clear", "clear");
    +        String token = t.nextToken(BreakpointSpec.locationTokenDelimiter);
    +        BreakpointSpec spec = parseBreakpointSpec(t, token, null, "printclearcommandusage");
             if (spec != null) {
                 if (Env.specList.delete(spec)) {
                     MessageOutput.println("Removed:", spec.toString());
    diff -r 268875216dfc -r faf96b92a47b src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/EventRequestSpecList.java
    --- a/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/EventRequestSpecList.java	Mon Feb 25 15:15:46 2019 +0530
    +++ b/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/EventRequestSpecList.java	Fri Mar 01 17:27:28 2019 +0530
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1998, 2019, 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
    @@ -36,6 +36,7 @@
     
     import com.sun.jdi.request.EventRequest;
     import com.sun.jdi.event.ClassPrepareEvent;
    +import com.sun.jdi.ThreadReference;
     
     import java.util.ArrayList;
     import java.util.Collections;
    @@ -108,21 +109,21 @@
             }
         }
     
    -    BreakpointSpec createBreakpoint(String classPattern, int line)
    +    BreakpointSpec createBreakpoint(String classPattern, int line, ThreadReference threadFilter)
             throws ClassNotFoundException {
             ReferenceTypeSpec refSpec =
                 new PatternReferenceTypeSpec(classPattern);
    -        return new BreakpointSpec(refSpec, line);
    +        return new BreakpointSpec(refSpec, line, threadFilter);
         }
     
         BreakpointSpec createBreakpoint(String classPattern,
    -                                 String methodId,
    +                                    String methodId, ThreadReference threadFilter,
                                         List methodArgs)
                                     throws MalformedMemberNameException,
                                            ClassNotFoundException {
             ReferenceTypeSpec refSpec =
                 new PatternReferenceTypeSpec(classPattern);
    -        return new BreakpointSpec(refSpec, methodId, methodArgs);
    +        return new BreakpointSpec(refSpec, methodId, threadFilter, methodArgs);
         }
     
         EventRequestSpec createExceptionCatch(String classPattern,
    diff -r 268875216dfc -r faf96b92a47b src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTYResources.java
    --- a/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTYResources.java	Mon Feb 25 15:15:46 2019 +0530
    +++ b/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTYResources.java	Fri Mar 01 17:27:28 2019 +0530
    @@ -120,12 +120,14 @@
             {"Exception occurred caught", "Exception occurred: {0} (to be caught at: {1})"},
             {"Exception occurred uncaught", "Exception occurred: {0} (uncaught)"},
             {"Exceptions caught:", "Break when these exceptions occur:"},
    +        {"Expected at, in, or an integer :", "Expected \"at\", \"in\", or an integer : {0}"},
             {"expr is null", "{0} = null"},
             {"expr is value", "{0} = {1}"},
             {"expr is value ", "  {0} = {1} "},
             {"Expression cannot be void", "Expression cannot be void"},
             {"Expression must evaluate to an object", "Expression must evaluate to an object"},
             {"extends:", "extends: {0}"},
    +        {"Extra tokens after breakpoint location", "Extra tokens after breakpoint location"},
             {"Failed reading output", "Failed reading output of child java interpreter."},
             {"Fatal error", "Fatal error:"},
             {"Field access encountered before after", "Field ({0}) is {1}, will be {2}: "},
    @@ -154,11 +156,14 @@
             {"Invalid connect type", "Invalid connect type"},
             {"Invalid consecutive invocations", "Invalid consecutive invocations"},
             {"Invalid exception object", "Invalid exception object"},
    -        {"Invalid method specification:", "Invalid method specification: {0}"},
    +        {"Invalid line number specified", "Invalid line number specified"},
    +        {"Invalid  specification:", "Invalid  specification: {0}"},
             {"Invalid option on class command", "Invalid option on class command"},
             {"invalid option", "invalid option: {0}"},
             {"Invalid thread status.", "Invalid thread status."},
    +        {"Invalid :", "Invalid : {0}"},
             {"Invalid transport name:", "Invalid transport name: {0}"},
    +        {"Invalid . specification", "Invalid . specification"},
             {"I/O exception occurred:", "I/O Exception occurred: {0}"},
             {"is an ambiguous method name in", "\"{0}\" is an ambiguous method name in \"{1}\""},
             {"is an invalid line number for",  "{0,number,integer} is an invalid line number for {1}"},
    @@ -191,6 +196,7 @@
             {"Method exitedValue:", "Method exited: return value = {0}, "},
             {"Method is overloaded; specify arguments", "Method {0} is overloaded; specify arguments"},
             {"minus version", "This is {0} version {1,number,integer}.{2,number,integer} (Java SE version {3})"},
    +        {"Missing at or in", "Missing \"at\" or \"in\""},
             {"Monitor information for thread", "Monitor information for thread {0}:"},
             {"Monitor information for expr", "Monitor information for {0} ({1}):"},
             {"More than one class named", "More than one class named: ''{0}''"},
    @@ -241,7 +247,18 @@
             {"Owned by:", "  Owned by: {0}, entry count: {1,number,integer}"},
             {"Owned monitor:", "  Owned monitor: {0}"},
             {"Parse exception:", "Parse Exception: {0}"},
    -        {"printbreakpointcommandusage", "Usage: {0} : or\n       {1} .[(argument_type,...)]"},
    +        {"printclearcommandusage", "Usage clear : or\n      clear .[(argument_type,...)]"},
    +        {"printstopcommandusage",
    +         "Usage: stop [go|thread] []  \n" +
    +         "  If \"go\" is specified, immediately resume after stopping\n" +
    +         "  If \"thread\" is specified, only suspend the thread we stop in\n" +
    +         "  If neither \"go\" nor \"thread\" are specified, suspend all threads\n" +
    +         "  If an integer  is specified, only stop in the specified thread\n" +
    +         "  \"at\" and \"in\" have the same meaning\n" +
    +         "   can either be a line number or a method:\n" +
    +         "    :\n" +
    +         "    .[(argument_type,...)]"
    +        },
             {"Removed:", "Removed: {0}"},
             {"Requested stack frame is no longer active:", "Requested stack frame is no longer active: {0,number,integer}"},
             {"run  command is valid only with launched VMs", "'run ' command is valid only with launched VMs"},
    @@ -292,6 +309,8 @@
             {"Thread not suspended", "Thread not suspended"},
             {"thread group number description name", "{0,number,integer}. {1} {2}"},
             {"Threadgroup name not specified.", "Threadgroup name not specified."},
    +        {" option not valid until the VM is started with the run command",
    +         " option not valid until the VM is started with the run command"},
             {"Threads must be suspended", "Threads must be suspended"},
             {"trace method exit in effect for", "trace method exit in effect for {0}"},
             {"trace method exits in effect", "trace method exits in effect"},
    @@ -318,7 +337,6 @@
             {"Usage: unmonitor ", "Usage: unmonitor "},
             {"Usage: up [n frames]", "Usage: up [n frames]"},
             {"Use java minus X to see", "Use 'java -X' to see the available non-standard options"},
    -        {"Use stop at to set a breakpoint at a line number", "Use 'stop at' to set a breakpoint at a line number"},
             {"VM already running. use cont to continue after events.", "VM already running. Use 'cont' to continue after events."},
             {"VM Started:", "VM Started: "},
             {"vmstartexception", "VM start exception: {0}"},
    @@ -357,9 +375,17 @@
                  "threadgroups              -- list threadgroups\n" +
                  "threadgroup         -- set current threadgroup\n" +
                  "\n" +
    -             "stop in .[(argument_type,...)]\n" +
    -             "                          -- set a breakpoint in a method\n" +
    -             "stop at : -- set a breakpoint at a line\n" +
    +             "stop [go|thread] []  \n" +
    +             "                          -- set a breakpoint\n" +
    +             "                          -- if no options are given, the current list of breakpoints is printed\n" +
    +             "                          -- if \"go\" is specified, immediately resume after stopping\n" +
    +             "                          -- if \"thread\" is specified, only suspend the thread we stop in\n" +
    +             "                          -- if neither \"go\" nor \"thread\" are specified, suspend all threads\n" +
    +             "                          -- if an integer  is specified, only stop in the specified thread\n" +
    +             "                          -- \"at\" and \"in\" have the same meaning\n" +
    +             "                          --  can either be a line number or a method:\n" +
    +             "                          --   :\n" +
    +             "                          --   .[(argument_type,...)]\n" +
                  "clear .[(argument_type,...)]\n" +
                  "                          -- clear a breakpoint in a method\n" +
                  "clear :   -- clear a breakpoint at a line\n" +
    @@ -412,7 +438,7 @@
                  "              -- repeat command n times\n" +
                  "#                -- discard (no-op)\n" +
                  "help (or ?)               -- list commands\n" +
    -             "dbgtrace [flag]           -- same as dbgtrace command line option" +
    +             "dbgtrace [flag]           -- same as dbgtrace command line option\n" +
                  "version                   -- print version information\n" +
                  "exit (or quit)            -- exit debugger\n" +
                  "\n" +
    diff -r 268875216dfc -r faf96b92a47b src/jdk.jfr/share/conf/jfr/default.jfc
    --- a/src/jdk.jfr/share/conf/jfr/default.jfc	Mon Feb 25 15:15:46 2019 +0530
    +++ b/src/jdk.jfr/share/conf/jfr/default.jfc	Fri Mar 01 17:27:28 2019 +0530
    @@ -133,11 +133,6 @@
           10 ms
         
     
    -    
    -      false
    -      10 ms
    -    
    -
         
           false
           10 ms
    diff -r 268875216dfc -r faf96b92a47b src/jdk.jfr/share/conf/jfr/profile.jfc
    --- a/src/jdk.jfr/share/conf/jfr/profile.jfc	Mon Feb 25 15:15:46 2019 +0530
    +++ b/src/jdk.jfr/share/conf/jfr/profile.jfc	Fri Mar 01 17:27:28 2019 +0530
    @@ -133,11 +133,6 @@
           0 ms
         
     
    -    
    -      false
    -      0 ms
    -    
    -
         
           false
           0 ms
    diff -r 268875216dfc -r faf96b92a47b src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java
    --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java	Mon Feb 25 15:15:46 2019 +0530
    +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java	Fri Mar 01 17:27:28 2019 +0530
    @@ -49,9 +49,9 @@
     import jdk.tools.jlink.builder.ImageBuilder;
     import jdk.tools.jlink.internal.Jlink.PluginsConfiguration;
     import jdk.tools.jlink.internal.plugins.DefaultCompressPlugin;
    +import jdk.tools.jlink.internal.plugins.DefaultStripDebugPlugin;
     import jdk.tools.jlink.internal.plugins.ExcludeJmodSectionPlugin;
     import jdk.tools.jlink.internal.plugins.PluginsResourceBundle;
    -import jdk.tools.jlink.internal.plugins.StripDebugPlugin;
     import jdk.tools.jlink.plugin.Plugin;
     import jdk.tools.jlink.plugin.Plugin.Category;
     import jdk.tools.jlink.plugin.PluginException;
    @@ -375,7 +375,7 @@
                                     m.put(DefaultCompressPlugin.NAME, DefaultCompressPlugin.LEVEL_2);
                                 }, false, "--compress", "-c");
                         mainOptions.add(plugOption);
    -                } else if (plugin instanceof StripDebugPlugin) {
    +                } else if (plugin instanceof DefaultStripDebugPlugin) {
                         plugOption
                             = new PluginOption(false,
                                 (task, opt, arg) -> {
    diff -r 268875216dfc -r faf96b92a47b src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/DefaultStripDebugPlugin.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/DefaultStripDebugPlugin.java	Fri Mar 01 17:27:28 2019 +0530
    @@ -0,0 +1,58 @@
    +/*
    + * Copyright (c) 2019, Red Hat, Inc.
    + * 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 jdk.tools.jlink.internal.plugins;
    +
    +import jdk.tools.jlink.plugin.Plugin;
    +import jdk.tools.jlink.plugin.ResourcePool;
    +import jdk.tools.jlink.plugin.ResourcePoolBuilder;
    +
    +/**
    + * Combined debug stripping plugin: Java debug attributes and native debug
    + * symbols.
    + *
    + */
    +public final class DefaultStripDebugPlugin implements Plugin {
    +
    +    public static final String NAME = "strip-debug";
    +
    +    private final Plugin javaStripPlugin = new StripJavaDebugAttributesPlugin();
    +
    +    @Override
    +    public String getName() {
    +        return NAME;
    +    }
    +
    +    @Override
    +    public String getDescription() {
    +        return PluginsResourceBundle.getDescription(NAME);
    +    }
    +
    +    @Override
    +    public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
    +        return javaStripPlugin.transform(in, out);
    +    }
    +
    +}
    diff -r 268875216dfc -r faf96b92a47b src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripDebugPlugin.java
    --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripDebugPlugin.java	Mon Feb 25 15:15:46 2019 +0530
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,87 +0,0 @@
    -/*
    - * Copyright (c) 2015, 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 jdk.tools.jlink.internal.plugins;
    -
    -import java.util.function.Predicate;
    -import jdk.internal.org.objectweb.asm.ClassReader;
    -import jdk.internal.org.objectweb.asm.ClassWriter;
    -import jdk.tools.jlink.plugin.ResourcePool;
    -import jdk.tools.jlink.plugin.ResourcePoolBuilder;
    -import jdk.tools.jlink.plugin.ResourcePoolEntry;
    -import jdk.tools.jlink.plugin.Plugin;
    -
    -/**
    - *
    - * Strip debug attributes plugin
    - */
    -public final class StripDebugPlugin implements Plugin {
    -    public static final String NAME = "strip-debug";
    -    private final Predicate predicate;
    -
    -    public StripDebugPlugin() {
    -        this((path) -> false);
    -    }
    -
    -    StripDebugPlugin(Predicate predicate) {
    -        this.predicate = predicate;
    -    }
    -
    -    @Override
    -    public String getName() {
    -        return NAME;
    -    }
    -
    -    @Override
    -    public String getDescription() {
    -        return PluginsResourceBundle.getDescription(NAME);
    -    }
    -
    -    @Override
    -    public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
    -        //remove *.diz files as well as debug attributes.
    -        in.transformAndCopy((resource) -> {
    -            ResourcePoolEntry res = resource;
    -            if (resource.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
    -                String path = resource.path();
    -                if (path.endsWith(".class")) {
    -                    if (path.endsWith("module-info.class")) {
    -                        // XXX. Do we have debug info? Is Asm ready for module-info?
    -                    } else {
    -                        ClassReader reader = new ClassReader(resource.contentBytes());
    -                        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    -                        reader.accept(writer, ClassReader.SKIP_DEBUG);
    -                        byte[] content = writer.toByteArray();
    -                        res = resource.copyWithContent(content);
    -                    }
    -                }
    -            } else if (predicate.test(res.path())) {
    -                res = null;
    -            }
    -            return res;
    -        }, out);
    -
    -        return out.build();
    -    }
    -}
    diff -r 268875216dfc -r faf96b92a47b src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripJavaDebugAttributesPlugin.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripJavaDebugAttributesPlugin.java	Fri Mar 01 17:27:28 2019 +0530
    @@ -0,0 +1,88 @@
    +/*
    + * Copyright (c) 2015, 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 jdk.tools.jlink.internal.plugins;
    +
    +import java.util.function.Predicate;
    +
    +import jdk.internal.org.objectweb.asm.ClassReader;
    +import jdk.internal.org.objectweb.asm.ClassWriter;
    +import jdk.tools.jlink.plugin.Plugin;
    +import jdk.tools.jlink.plugin.ResourcePool;
    +import jdk.tools.jlink.plugin.ResourcePoolBuilder;
    +import jdk.tools.jlink.plugin.ResourcePoolEntry;
    +
    +/**
    + *
    + * Strip java debug attributes plugin
    + */
    +public final class StripJavaDebugAttributesPlugin implements Plugin {
    +    public static final String NAME = "strip-java-debug-attributes";
    +    private final Predicate predicate;
    +
    +    public StripJavaDebugAttributesPlugin() {
    +        this((path) -> false);
    +    }
    +
    +    StripJavaDebugAttributesPlugin(Predicate predicate) {
    +        this.predicate = predicate;
    +    }
    +
    +    @Override
    +    public String getName() {
    +        return NAME;
    +    }
    +
    +    @Override
    +    public String getDescription() {
    +        return PluginsResourceBundle.getDescription(NAME);
    +    }
    +
    +    @Override
    +    public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
    +        //remove *.diz files as well as debug attributes.
    +        in.transformAndCopy((resource) -> {
    +            ResourcePoolEntry res = resource;
    +            if (resource.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
    +                String path = resource.path();
    +                if (path.endsWith(".class")) {
    +                    if (path.endsWith("module-info.class")) {
    +                        // XXX. Do we have debug info? Is Asm ready for module-info?
    +                    } else {
    +                        ClassReader reader = new ClassReader(resource.contentBytes());
    +                        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    +                        reader.accept(writer, ClassReader.SKIP_DEBUG);
    +                        byte[] content = writer.toByteArray();
    +                        res = resource.copyWithContent(content);
    +                    }
    +                }
    +            } else if (predicate.test(res.path())) {
    +                res = null;
    +            }
    +            return res;
    +        }, out);
    +
    +        return out.build();
    +    }
    +}
    diff -r 268875216dfc -r faf96b92a47b src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties
    --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties	Mon Feb 25 15:15:46 2019 +0530
    +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties	Fri Mar 01 17:27:28 2019 +0530
    @@ -99,6 +99,9 @@
     strip-debug.description=\
     Strip debug information from the output image
     
    +strip-java-debug-attributes.description=\
    +Strip Java debug attributes from classes in the output image
    +
     strip-native-commands.description=\
     Exclude native commands (such as java/java.exe) from the image
     
    diff -r 268875216dfc -r faf96b92a47b src/jdk.jlink/share/classes/module-info.java
    --- a/src/jdk.jlink/share/classes/module-info.java	Mon Feb 25 15:15:46 2019 +0530
    +++ b/src/jdk.jlink/share/classes/module-info.java	Fri Mar 01 17:27:28 2019 +0530
    @@ -63,7 +63,8 @@
             jdk.tools.jlink.internal.Main.JlinkToolProvider;
     
         provides jdk.tools.jlink.plugin.Plugin with
    -        jdk.tools.jlink.internal.plugins.StripDebugPlugin,
    +        jdk.tools.jlink.internal.plugins.DefaultStripDebugPlugin,
    +        jdk.tools.jlink.internal.plugins.StripJavaDebugAttributesPlugin,
             jdk.tools.jlink.internal.plugins.ExcludePlugin,
             jdk.tools.jlink.internal.plugins.ExcludeFilesPlugin,
             jdk.tools.jlink.internal.plugins.ExcludeJmodSectionPlugin,
    diff -r 268875216dfc -r faf96b92a47b src/utils/LogCompilation/src/main/java/com/sun/hotspot/tools/compiler/LogParser.java
    --- a/src/utils/LogCompilation/src/main/java/com/sun/hotspot/tools/compiler/LogParser.java	Mon Feb 25 15:15:46 2019 +0530
    +++ b/src/utils/LogCompilation/src/main/java/com/sun/hotspot/tools/compiler/LogParser.java	Fri Mar 01 17:27:28 2019 +0530
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2009, 2019, 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
    @@ -1279,6 +1279,7 @@
                     types.clear();
                     methods.clear();
                     site = null;
    +                lateInlining = false;
                 }
             } catch (Exception e) {
                 reportInternalError("exception while processing end element", e);
    diff -r 268875216dfc -r faf96b92a47b test/hotspot/gtest/memory/test_virtualSpaceNode.cpp
    --- a/test/hotspot/gtest/memory/test_virtualSpaceNode.cpp	Mon Feb 25 15:15:46 2019 +0530
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,277 +0,0 @@
    -/*
    - * Copyright (c) 2018, 2019, 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.
    - */
    -
    -#include "precompiled.hpp"
    -#include "memory/metaspace/virtualSpaceList.hpp"
    -#include "memory/metaspace/chunkManager.hpp"
    -#include "runtime/mutexLocker.hpp"
    -#include "utilities/formatBuffer.hpp"
    -#include "unittest.hpp"
    -
    -// include as last, or otherwise we pull in an incompatible "assert" macro
    -#include 
    -
    -using namespace metaspace;
    -
    -namespace {
    -  static void chunk_up(size_t words_left, size_t& num_medium_chunks,
    -                                          size_t& num_small_chunks,
    -                                          size_t& num_specialized_chunks) {
    -    num_medium_chunks = words_left / MediumChunk;
    -    words_left = words_left % MediumChunk;
    -
    -    num_small_chunks = words_left / SmallChunk;
    -    words_left = words_left % SmallChunk;
    -    // how many specialized chunks can we get?
    -    num_specialized_chunks = words_left / SpecializedChunk;
    -    ASSERT_EQ(0UL, words_left % SpecializedChunk) << "should be nothing left"
    -       << ", words_left = " << words_left
    -       << ", SpecializedChunk = " << SpecializedChunk;
    -  }
    -  static const size_t vsn_test_size_words = MediumChunk * 4;
    -  static const size_t vsn_test_size_bytes = vsn_test_size_words * BytesPerWord;
    -  class MetachunkRemover {
    -    Metachunk* const _m;
    -    ChunkManager* const _c;
    -   public:
    -    MetachunkRemover(Metachunk* m, ChunkManager* c) : _m(m), _c(c) { }
    -    ~MetachunkRemover() { _c->remove_chunk(_m); }
    -  };
    -}
    -
    -class ChunkManagerTest {
    - public:
    -  static size_t sum_free_chunks(ChunkManager* cm) {
    -      return cm->sum_free_chunks();
    -  }
    -  static size_t sum_free_chunks_count(ChunkManager* cm) {
    -      return cm->sum_free_chunks_count();
    -  }
    -  static ChunkList* free_chunks(ChunkManager* cm, ChunkIndex i) {
    -    return cm->free_chunks(i);
    -  }
    -};
    -
    -// removes all the chunks added to the ChunkManager since creation of ChunkManagerRestorer
    -class ChunkManagerRestorer {
    -  metaspace::ChunkManager* const _cm;
    -  std::vector* _free_chunks[metaspace::NumberOfFreeLists];
    -  int _count_pre_existing;
    -public:
    -  ChunkManagerRestorer(metaspace::ChunkManager* cm) : _cm(cm), _count_pre_existing(0) {
    -    _cm->locked_verify();
    -    for (metaspace::ChunkIndex i = metaspace::ZeroIndex; i < metaspace::NumberOfFreeLists; i = next_chunk_index(i)) {
    -      metaspace::ChunkList* l = ChunkManagerTest::free_chunks(_cm, i);
    -      _count_pre_existing += l->count();
    -      std::vector *v = new std::vector(l->count());
    -      metaspace::Metachunk* c = l->head();
    -      while (c) {
    -        v->push_back(c);
    -        c = c->next();
    -      }
    -      _free_chunks[i] = v;
    -    }
    -  }
    -  ~ChunkManagerRestorer() {
    -    _cm->locked_verify();
    -    for (metaspace::ChunkIndex i = metaspace::ZeroIndex; i < metaspace::NumberOfFreeLists; i = next_chunk_index(i)) {
    -      metaspace::ChunkList* l = ChunkManagerTest::free_chunks(_cm, i);
    -      std::vector *v = _free_chunks[i];
    -      ssize_t count = l->count();
    -      for (ssize_t j = 0; j < count; j++) {
    -        metaspace::Metachunk* c = l->head();
    -        while (c) {
    -          bool found = false;
    -          for (size_t k = 0; k < v->size() && !found; k++) {
    -            found = (c == v->at(k));
    -          }
    -          if (found) {
    -            c = c->next();
    -          } else {
    -            _cm->remove_chunk(c);
    -            break;
    -          }
    -        }
    -      }
    -      delete _free_chunks[i];
    -      _free_chunks[i] = NULL;
    -   }
    -    int count_after_cleanup = 0;
    -    for (ChunkIndex i = ZeroIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) {
    -      ChunkList* l = ChunkManagerTest::free_chunks(_cm, i);
    -      count_after_cleanup += l->count();
    -    }
    -    EXPECT_EQ(_count_pre_existing, count_after_cleanup);
    -    _cm->locked_verify();
    -  }
    -};
    -
    -TEST_VM(VirtualSpaceNodeTest, sanity) {
    -  // The chunk sizes must be multiples of eachother, or this will fail
    -  STATIC_ASSERT(MediumChunk % SmallChunk == 0);
    -  STATIC_ASSERT(SmallChunk % SpecializedChunk == 0);
    -
    -  // just in case STATIC_ASSERT doesn't work
    -  EXPECT_EQ(0, MediumChunk % SmallChunk);
    -  EXPECT_EQ(0, SmallChunk % SpecializedChunk);
    -}
    -
    -TEST_VM(VirtualSpaceNodeTest, four_pages_vsn_is_committed_some_is_used_by_chunks) {
    -  const size_t page_chunks = 4 * (size_t)os::vm_page_size() / BytesPerWord;
    -  if (page_chunks >= MediumChunk) {
    -    SUCCEED() << "SKIP: This doesn't work for systems with vm_page_size >= 16K";
    -    return;
    -  }
    -  MutexLockerEx ml(MetaspaceExpand_lock, Mutex::_no_safepoint_check_flag);
    -  ChunkManager cm(false);
    -  VirtualSpaceNode vsn(false, vsn_test_size_bytes);
    -  ChunkManagerRestorer c(Metaspace::get_chunk_manager(false));
    -
    -  vsn.initialize();
    -  EXPECT_TRUE(vsn.expand_by(page_chunks, page_chunks));
    -  vsn.get_chunk_vs(SmallChunk);
    -  vsn.get_chunk_vs(SpecializedChunk);
    -  vsn.retire(&cm);
    -
    -  // committed - used = words left to retire
    -  const size_t words_left = page_chunks - SmallChunk - SpecializedChunk;
    -  size_t num_medium_chunks, num_small_chunks, num_spec_chunks;
    -  chunk_up(words_left, num_medium_chunks, num_small_chunks, num_spec_chunks);
    -
    -  EXPECT_EQ(0UL, num_medium_chunks) << "should not get any medium chunks";
    -  // DISABLED: checks started to fail after 8198423
    -  // EXPECT_EQ((num_small_chunks + num_spec_chunks), ChunkManagerTest::sum_free_chunks_count(&cm)) << "should be space for 3 chunks";
    -  // EXPECT_EQ(words_left, ChunkManagerTest::sum_free_chunks(&cm)) << "sizes should add up";
    -}
    -
    -TEST_VM(VirtualSpaceNodeTest, half_vsn_is_committed_humongous_chunk_is_used) {
    -  MutexLockerEx ml(MetaspaceExpand_lock, Mutex::_no_safepoint_check_flag);
    -  ChunkManager cm(false);
    -  VirtualSpaceNode vsn(false, vsn_test_size_bytes);
    -  ChunkManagerRestorer c(Metaspace::get_chunk_manager(false));
    -
    -  vsn.initialize();
    -  EXPECT_TRUE(vsn.expand_by(MediumChunk * 2, MediumChunk * 2));
    -  // Humongous chunks will be aligned up to MediumChunk + SpecializedChunk
    -  vsn.get_chunk_vs(MediumChunk + SpecializedChunk);
    -  vsn.retire(&cm);
    -
    -  const size_t words_left = MediumChunk * 2 - (MediumChunk + SpecializedChunk);
    -  size_t num_medium_chunks, num_small_chunks, num_spec_chunks;
    -  ASSERT_NO_FATAL_FAILURE(chunk_up(words_left, num_medium_chunks, num_small_chunks, num_spec_chunks));
    -
    -  EXPECT_EQ(0UL, num_medium_chunks) << "should not get any medium chunks";
    -  // DISABLED: checks started to fail after 8198423
    -  // EXPECT_EQ((num_small_chunks + num_spec_chunks), ChunkManagerTest::sum_free_chunks_count(&cm)) << "should be space for 3 chunks";
    -  // EXPECT_EQ(words_left, ChunkManagerTest::sum_free_chunks(&cm)) << "sizes should add up";
    -}
    -
    -TEST_VM(VirtualSpaceNodeTest, all_vsn_is_committed_half_is_used_by_chunks) {
    -  MutexLockerEx ml(MetaspaceExpand_lock, Mutex::_no_safepoint_check_flag);
    -  ChunkManager cm(false);
    -  VirtualSpaceNode vsn(false, vsn_test_size_bytes);
    -  ChunkManagerRestorer c(Metaspace::get_chunk_manager(false));
    -
    -  vsn.initialize();
    -  EXPECT_TRUE(vsn.expand_by(vsn_test_size_words, vsn_test_size_words));
    -  vsn.get_chunk_vs(MediumChunk);
    -  vsn.get_chunk_vs(MediumChunk);
    -  vsn.retire(&cm);
    -
    -  // DISABLED: checks started to fail after 8198423
    -  // EXPECT_EQ(2UL, ChunkManagerTest::sum_free_chunks_count(&cm)) << "should have been memory left for 2 chunks";
    -  // EXPECT_EQ(2UL * MediumChunk, ChunkManagerTest::sum_free_chunks(&cm)) << "sizes should add up";
    -}
    -
    -TEST_VM(VirtualSpaceNodeTest, no_committed_memory) {
    -  MutexLockerEx ml(MetaspaceExpand_lock, Mutex::_no_safepoint_check_flag);
    -  ChunkManager cm(false);
    -  VirtualSpaceNode vsn(false, vsn_test_size_bytes);
    -  ChunkManagerRestorer c(Metaspace::get_chunk_manager(false));
    -
    -  vsn.initialize();
    -  vsn.retire(&cm);
    -
    -  ASSERT_EQ(0UL, ChunkManagerTest::sum_free_chunks_count(&cm)) << "did not commit any memory in the VSN";
    -}
    -
    -TEST_VM(VirtualSpaceNodeTest, is_available_positive) {
    -  // Reserve some memory.
    -  VirtualSpaceNode vsn(false, os::vm_allocation_granularity());
    -  ASSERT_TRUE(vsn.initialize()) << "Failed to setup VirtualSpaceNode";
    -
    -  // Commit some memory.
    -  size_t commit_word_size = os::vm_allocation_granularity() / BytesPerWord;
    -  ASSERT_TRUE(vsn.expand_by(commit_word_size, commit_word_size))
    -      << "Failed to commit, commit_word_size = " << commit_word_size;
    -
    -  SCOPED_TRACE(err_msg("VirtualSpaceNode [" PTR_FORMAT ", " PTR_FORMAT ")",
    -      p2i(vsn.bottom()), p2i(vsn.end())).buffer());
    -
    -  // Check that is_available accepts the committed size.
    -  EXPECT_TRUE(vsn.is_available(commit_word_size)) << " commit_word_size = " << commit_word_size;
    -
    -  // Check that is_available accepts half the committed size.
    -  size_t expand_word_size = commit_word_size / 2;
    -  EXPECT_TRUE(vsn.is_available(expand_word_size)) << " expand_word_size = " << expand_word_size;
    -}
    -
    -TEST_VM(VirtualSpaceNodeTest, is_available_negative) {
    -  // Reserve some memory.
    -  VirtualSpaceNode vsn(false, os::vm_allocation_granularity());
    -  ASSERT_TRUE(vsn.initialize()) << "Failed to setup VirtualSpaceNode";
    -
    -  // Commit some memory.
    -  size_t commit_word_size = os::vm_allocation_granularity() / BytesPerWord;
    -  ASSERT_TRUE(vsn.expand_by(commit_word_size, commit_word_size))
    -      << "Failed to commit, commit_word_size = " << commit_word_size;
    -
    -  SCOPED_TRACE(err_msg("VirtualSpaceNode [" PTR_FORMAT ", " PTR_FORMAT ")",
    -      p2i(vsn.bottom()), p2i(vsn.end())).buffer());
    -
    -  // Check that is_available doesn't accept a too large size.
    -  size_t two_times_commit_word_size = commit_word_size * 2;
    -  EXPECT_FALSE(vsn.is_available(two_times_commit_word_size)) << " two_times_commit_word_size = " << two_times_commit_word_size;
    -}
    -
    -TEST_VM(VirtualSpaceNodeTest, is_available_overflow) {
    -  // Reserve some memory.
    -  VirtualSpaceNode vsn(false, os::vm_allocation_granularity());
    -  ASSERT_TRUE(vsn.initialize()) << "Failed to setup VirtualSpaceNode";
    -
    -  // Commit some memory.
    -  size_t commit_word_size = os::vm_allocation_granularity() / BytesPerWord;
    -  ASSERT_TRUE(vsn.expand_by(commit_word_size, commit_word_size))
    -      << "Failed to commit, commit_word_size = " << commit_word_size;
    -
    -  SCOPED_TRACE(err_msg("VirtualSpaceNode [" PTR_FORMAT ", " PTR_FORMAT ")",
    -      p2i(vsn.bottom()), p2i(vsn.end())).buffer());
    -
    -  // Calculate a size that will overflow the virtual space size.
    -  void* virtual_space_max = (void*)(uintptr_t)-1;
    -  size_t bottom_to_max = pointer_delta(virtual_space_max, vsn.bottom(), 1);
    -  size_t overflow_size = bottom_to_max + BytesPerWord;
    -  size_t overflow_word_size = overflow_size / BytesPerWord;
    -
    -  EXPECT_FALSE(vsn.is_available(overflow_word_size)) << " overflow_word_size = " << overflow_word_size;
    -}
    diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/ProblemList-zgc.txt
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/test/hotspot/jtreg/ProblemList-zgc.txt	Fri Mar 01 17:27:28 2019 +0530
    @@ -0,0 +1,30 @@
    +#
    +# Copyright (c) 2019, 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.
    +#
    +
    +#############################################################################
    +#
    +# List of quarantined tests for testing with ZGC.
    +#
    +#############################################################################
    +
    +serviceability/sa/TestJmapCoreMetaspace.java                  8219443   generic-all
    diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/ProblemList.txt
    --- a/test/hotspot/jtreg/ProblemList.txt	Mon Feb 25 15:15:46 2019 +0530
    +++ b/test/hotspot/jtreg/ProblemList.txt	Fri Mar 01 17:27:28 2019 +0530
    @@ -189,7 +189,6 @@
     vmTestbase/vm/mlvm/meth/stress/gc/callSequencesDuringGC/Test.java 8058176 generic-all
     vmTestbase/vm/mlvm/meth/stress/java/sequences/Test.java 8058176 generic-all
     vmTestbase/vm/mlvm/meth/stress/jdi/breakpointInCompiledCode/Test.java 8058176 generic-all
    -vmTestbase/vm/mlvm/mixed/stress/java/findDeadlock/TestDescription.java 8208278 macosx-all
     vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2none_a/TestDescription.java 8013267 generic-all
     vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_b/TestDescription.java 8013267 generic-all
     vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manySame_b/TestDescription.java 8013267 generic-all
    diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/TEST.ROOT
    --- a/test/hotspot/jtreg/TEST.ROOT	Mon Feb 25 15:15:46 2019 +0530
    +++ b/test/hotspot/jtreg/TEST.ROOT	Fri Mar 01 17:27:28 2019 +0530
    @@ -70,7 +70,7 @@
         test.vm.gc.nvdimm
     
     # Minimum jtreg version
    -requiredVersion=4.2 b13
    +requiredVersion=4.2 b14
     
     # Path to libraries in the topmost test directory. This is needed so @library
     # does not need ../../../ notation to reach them
    @@ -81,3 +81,6 @@
     
     # Use --patch-module instead of -Xmodule:
     useNewPatchModule=true
    +
    +# disabled till JDK-8219140 is fixed
    +allowSmartActionArgs=false
    diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java
    --- a/test/hotspot/jtreg/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java	Mon Feb 25 15:15:46 2019 +0530
    +++ b/test/hotspot/jtreg/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java	Fri Mar 01 17:27:28 2019 +0530
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2015, 2019, 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
    @@ -203,7 +203,13 @@
             allOptionsAsMap = JVMOptionsUtils.getOptionsWithRangeAsMap(origin -> (!(origin.contains("develop") || origin.contains("notproduct"))));
     
             /*
    -         * Remove CICompilerCount from testing because currently it can hang system
    +         * Exclude VMThreadStackSize from max range testing, because it will always exit with code 1,
    +         * which technically passes, but really it fails, and worse yet, it produces hs_err_pid file.
    +         */
    +        excludeTestMaxRange("VMThreadStackSize");
    +
    +        /*
    +         * Exclude CICompilerCount from testing because currently it can hang system
              */
             excludeTestMaxRange("CICompilerCount");
     
    diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/runtime/Dictionary/ProtectionDomainCacheTest.java
    --- a/test/hotspot/jtreg/runtime/Dictionary/ProtectionDomainCacheTest.java	Mon Feb 25 15:15:46 2019 +0530
    +++ b/test/hotspot/jtreg/runtime/Dictionary/ProtectionDomainCacheTest.java	Fri Mar 01 17:27:28 2019 +0530
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2018, 2019, 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
    @@ -23,14 +23,15 @@
     
     /*
      * @test
    - * @bug 8151486
    + * @bug 8151486 8218266
      * @summary Call Class.forName() on the system classloader from a class loaded
      *          from a custom classloader, using the current class's protection domain.
      * @library /test/lib
    + * @modules java.base/jdk.internal.misc
      * @build jdk.test.lib.Utils
      *        jdk.test.lib.util.JarUtils
      * @build ClassForName ProtectionDomainCacheTest
    - * @run main/othervm/policy=test.policy -XX:+UnlockDiagnosticVMOptions -XX:VerifySubSet=dictionary -XX:+VerifyAfterGC -Xlog:gc+verify=debug,protectiondomain=trace,class+unload:gc.log -Djava.security.manager ProtectionDomainCacheTest
    + * @run main/othervm/policy=test.policy -Djava.security.manager ProtectionDomainCacheTest
      */
     
     import java.net.URL;
    @@ -42,48 +43,69 @@
     import java.util.List;
     import jdk.test.lib.Utils;
     import jdk.test.lib.util.JarUtils;
    +import java.io.File;
    +
    +import jdk.test.lib.process.OutputAnalyzer;
    +import jdk.test.lib.process.ProcessTools;
     
     /*
      * Create .jar, load ClassForName from .jar using a URLClassLoader
      */
     public class ProtectionDomainCacheTest {
    -    private static final long TIMEOUT = (long)(5000.0 * Utils.TIMEOUT_FACTOR);
    -    private static final String TESTCLASSES = System.getProperty("test.classes", ".");
    -    private static final String CLASSFILENAME = "ClassForName.class";
    +    static class Test {
    +        private static final long TIMEOUT = (long)(5000.0 * Utils.TIMEOUT_FACTOR);
    +        private static final String TESTCLASSES = System.getProperty("test.classes", ".");
    +        private static final String CLASSFILENAME = "ClassForName.class";
    +
    +        // Use a new classloader to load the ClassForName class.
    +        public static void loadAndRun(Path jarFilePath)
    +                throws Exception {
    +            ClassLoader classLoader = new URLClassLoader(
    +                    new URL[]{jarFilePath.toUri().toURL()}) {
    +                @Override public String toString() { return "LeakedClassLoader"; }
    +            };
    +
    +            Class loadClass = Class.forName("ClassForName", true, classLoader);
    +            loadClass.newInstance();
    +
    +            System.out.println("returning : " + classLoader);
    +        }
     
    -    // Use a new classloader to load the ClassForName class.
    -    public static void loadAndRun(Path jarFilePath)
    -            throws Exception {
    -        ClassLoader classLoader = new URLClassLoader(
    -                new URL[]{jarFilePath.toUri().toURL()}) {
    -            @Override public String toString() { return "LeakedClassLoader"; }
    -        };
    +        public static void main(final String[] args) throws Exception {
    +            // Create a temporary .jar file containing ClassForName.class
    +            Path testClassesDir = Paths.get(TESTCLASSES);
    +            Path jarFilePath = Files.createTempFile("cfn", ".jar");
    +            JarUtils.createJarFile(jarFilePath, testClassesDir, CLASSFILENAME);
    +            jarFilePath.toFile().deleteOnExit();
     
    -        Class loadClass = Class.forName("ClassForName", true, classLoader);
    -        loadClass.newInstance();
    +            // Remove the ClassForName.class file that jtreg built, to make sure
    +            // we're loading from the tmp .jar
    +            Path classFile = FileSystems.getDefault().getPath(TESTCLASSES,
    +                                                              CLASSFILENAME);
    +            Files.delete(classFile);
     
    -        System.out.println("returning : " + classLoader);
    +            loadAndRun(jarFilePath);
    +
    +            // Give the GC a chance to unload protection domains
    +            for (int i = 0; i < 100; i++) {
    +                System.gc();
    +            }
    +            System.out.println("All Classloaders and protection domain cache entries successfully unloaded");
    +        }
         }
     
    -    public static void main(final String[] args) throws Exception {
    -        // Create a temporary .jar file containing ClassForName.class
    -        Path testClassesDir = Paths.get(TESTCLASSES);
    -        Path jarFilePath = Files.createTempFile("cfn", ".jar");
    -        JarUtils.createJarFile(jarFilePath, testClassesDir, CLASSFILENAME);
    -        jarFilePath.toFile().deleteOnExit();
    -
    -        // Remove the ClassForName.class file that jtreg built, to make sure
    -        // we're loading from the tmp .jar
    -        Path classFile = FileSystems.getDefault().getPath(TESTCLASSES,
    -                                                          CLASSFILENAME);
    -        Files.delete(classFile);
    -
    -        loadAndRun(jarFilePath);
    -
    -        // Give the GC a chance to unload protection domains
    -        for (int i = 0; i < 100; i++) {
    -            System.gc();
    -        }
    -        System.out.println("All Classloaders and protection domain cache entries successfully unloaded");
    +    public static void main(String args[]) throws Exception {
    +        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
    +                                      "-Djava.security.policy==" + System.getProperty("test.src") + File.separator + "test.policy",
    +                                      "-Dtest.classes=" + System.getProperty("test.classes", "."),
    +                                      "-XX:+UnlockDiagnosticVMOptions",
    +                                      "-XX:VerifySubSet=dictionary",
    +                                      "-XX:+VerifyAfterGC",
    +                                      "-Xlog:gc+verify,protectiondomain=debug",
    +                                      "-Djava.security.manager",
    +                                      Test.class.getName());
    +        OutputAnalyzer output = new OutputAnalyzer(pb.start());
    +        output.shouldContain("PD in set is not alive");
    +        output.shouldHaveExitValue(0);
         }
     }
    diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/runtime/Dictionary/test.policy
    --- a/test/hotspot/jtreg/runtime/Dictionary/test.policy	Mon Feb 25 15:15:46 2019 +0530
    +++ b/test/hotspot/jtreg/runtime/Dictionary/test.policy	Fri Mar 01 17:27:28 2019 +0530
    @@ -1,5 +1,5 @@
     grant {
    -  permission java.io.FilePermission "<>", "read, write, delete";
    +  permission java.io.FilePermission "<>", "read, write, delete, execute";
       permission java.lang.RuntimePermission "createClassLoader";
       permission java.lang.RuntimePermission "getClassLoader";
       permission java.util.PropertyPermission "*", "read"; /* for Utils */
    diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/runtime/RedefineTests/RedefineDeleteJmethod.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/test/hotspot/jtreg/runtime/RedefineTests/RedefineDeleteJmethod.java	Fri Mar 01 17:27:28 2019 +0530
    @@ -0,0 +1,94 @@
    +/*
    + * Copyright (c) 2019, 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 8181171
    + * @summary Test deleting static method pointing to by a jmethod
    + * @library /test/lib
    + * @modules java.base/jdk.internal.misc
    + * @modules java.compiler
    + *          java.instrument
    + *          jdk.jartool/sun.tools.jar
    + * @run main RedefineClassHelper
    + * @run main/native/othervm -javaagent:redefineagent.jar -Xlog:redefine+class*=trace RedefineDeleteJmethod
    + */
    +
    +class B {
    +    private static int deleteMe() { System.out.println("deleteMe called"); return 5; }
    +    public static int callDeleteMe() { return deleteMe(); }
    +}
    +
    +public class RedefineDeleteJmethod {
    +
    +    public static String newB =
    +        "class B {" +
    +            "public static int callDeleteMe() { return 6; }" +
    +        "}";
    +
    +    public static String newerB =
    +        "class B {" +
    +            "private static int deleteMe() { System.out.println(\"deleteMe (2) called\"); return 7; }" +
    +            "public static int callDeleteMe() { return deleteMe(); }" +
    +        "}";
    +
    +
    +    static {
    +        System.loadLibrary("RedefineDeleteJmethod");
    +    }
    +
    +    static native int jniCallDeleteMe();
    +
    +    static void test(int expected, boolean nsme_expected) throws Exception {
    +        // Call through static method
    +        int res = B.callDeleteMe();
    +        System.out.println("Result = " + res);
    +        if (res != expected) {
    +            throw new Error("returned " + res + " expected " + expected);
    +        }
    +
    +        // Call through jmethodID, saved from first call.
    +        try {
    +            res = jniCallDeleteMe();
    +            if (nsme_expected) {
    +                throw new RuntimeException("Failed, NoSuchMethodError expected");
    +            }
    +            if (res != expected) {
    +                throw new Error("returned " + res + " expected " + expected);
    +            }
    +        } catch (NoSuchMethodError ex) {
    +            if (!nsme_expected) {
    +                throw new RuntimeException("Failed, NoSuchMethodError not expected");
    +            }
    +            System.out.println("Passed, NoSuchMethodError expected");
    +        }
    +    }
    +
    +    public static void main(String[] args) throws Exception {
    +        test(5, false);
    +        RedefineClassHelper.redefineClass(B.class, newB);
    +        test(6, true);
    +        RedefineClassHelper.redefineClass(B.class, newerB);
    +        test(7, true);
    +    }
    +}
    diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/runtime/RedefineTests/libRedefineDeleteJmethod.c
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/test/hotspot/jtreg/runtime/RedefineTests/libRedefineDeleteJmethod.c	Fri Mar 01 17:27:28 2019 +0530
    @@ -0,0 +1,47 @@
    +/*
    + * Copyright (c) 2019, 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.
    + */
    +
    +#include 
    +
    +jmethodID mid;
    +jclass cls;
    +static int count = 0;
    +
    +JNIEXPORT jint JNICALL
    +Java_RedefineDeleteJmethod_jniCallDeleteMe(JNIEnv* env, jobject obj) {
    +
    +    if (count == 0) {
    +      count++;
    +      cls = (*env)->FindClass(env, "B");
    +      if (NULL == cls) {
    +          (*env)->FatalError(env, "could not find class");
    +      }
    +
    +      mid = (*env)->GetStaticMethodID(env, cls, "deleteMe", "()I");
    +      if (NULL == mid) {
    +          (*env)->FatalError(env, "could not find method");
    +      }
    +    }
    +
    +    return (*env)->CallStaticIntMethod(env, cls, mid);
    +}
    diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/runtime/logging/SafepointTest.java
    --- a/test/hotspot/jtreg/runtime/logging/SafepointTest.java	Mon Feb 25 15:15:46 2019 +0530
    +++ b/test/hotspot/jtreg/runtime/logging/SafepointTest.java	Fri Mar 01 17:27:28 2019 +0530
    @@ -41,8 +41,6 @@
                                                                       InnerClass.class.getName());
             OutputAnalyzer output = new OutputAnalyzer(pb.start());
             output.shouldContain("Safepoint synchronization initiated");
    -        output.shouldContain("Entering safepoint region: ");
    -        output.shouldContain("Leaving safepoint region");
             output.shouldHaveExitValue(0);
         }
     
    diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/vmTestbase/gc/g1/unloading/GenClassesBuilder.java
    --- a/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/GenClassesBuilder.java	Mon Feb 25 15:15:46 2019 +0530
    +++ b/test/hotspot/jtreg/vmTestbase/gc/g1/unloading/GenClassesBuilder.java	Fri Mar 01 17:27:28 2019 +0530
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2017, 2019, 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
    @@ -35,12 +35,13 @@
      */
     public class GenClassesBuilder {
         public static void main(String[] args) {
    -        Path template = testRoot().resolve("vmTestbase")
    -                                  .resolve("gc")
    -                                  .resolve("g1")
    -                                  .resolve("unloading")
    -                                  .resolve("ClassNNN.java.template")
    -                                  .toAbsolutePath();
    +        Path template = Paths.get(Utils.TEST_ROOT)
    +                             .resolve("vmTestbase")
    +                             .resolve("gc")
    +                             .resolve("g1")
    +                             .resolve("unloading")
    +                             .resolve("ClassNNN.java.template")
    +                             .toAbsolutePath();
             Path dir = Paths.get(".").toAbsolutePath();
             String count = "1000";
             if (Files.notExists(template)) {
    @@ -52,14 +53,6 @@
                 throw new Error("can't generate classPool.jar", e);
             }
         }
    -
    -    private static Path testRoot() {
    -        Path p = Paths.get(Utils.TEST_SRC);
    -        while (!Files.exists(p.resolve("TEST.ROOT"))) {
    -            p = p.getParent();
    -        }
    -        return p;
    -    }
     }
     
     
    diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassUnloadRequest/addClassExclusionFilter/exclfilter001.java
    --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassUnloadRequest/addClassExclusionFilter/exclfilter001.java	Mon Feb 25 15:15:46 2019 +0530
    +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassUnloadRequest/addClassExclusionFilter/exclfilter001.java	Fri Mar 01 17:27:28 2019 +0530
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2002, 2019, 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
    @@ -23,14 +23,15 @@
     
     package nsk.jdi.ClassUnloadRequest.addClassExclusionFilter;
     
    +import jdk.test.lib.Utils;
     import nsk.share.*;
     import nsk.share.jdi.*;
     
     import com.sun.jdi.*;
     import com.sun.jdi.event.*;
     import com.sun.jdi.request.*;
    +
     import java.io.*;
    -import java.util.*;
     
     /**
      * Debugger requests ClassUnloadEvent and sets class filter by calling
    @@ -64,7 +65,7 @@
         private static int exitStatus;
         private static Log log;
         private static Debugee debugee;
    -    private static int eventWaitTime;
    +    private static long waitTime;
     
         String[] patterns = {
                         prefix + "Sub*",
    @@ -88,7 +89,7 @@
             exclfilter001 tstObj = new exclfilter001();
     
             ArgumentHandler argHandler = new ArgumentHandler(argv);
    -        eventWaitTime = argHandler.getWaitTime() * 60000;
    +        waitTime = argHandler.getWaitTime();
             log = new Log(out, argHandler);
     
             debugee = Debugee.prepareDebugee(argHandler, log, debugeeName);
    @@ -121,7 +122,7 @@
                 debugee.sendSignal(SGNL_UNLOAD);
                 debugee.receiveExpectedSignal(SGNL_READY);
     
    -            receiveEvents(eventWaitTime, patterns[i]);
    +            receiveEvents(patterns[i]);
     
                 display("");
                 debugee.getEventRequestManager().deleteEventRequest(request);
    @@ -146,19 +147,20 @@
             return request;
         }
     
    -    private void receiveEvents(int waitTime, String pattern) {
    +    private void receiveEvents(String pattern) {
             EventSet eventSet = null;
             Event event;
    -        int totalTime = waitTime;
    +        long totalWaitTime = Utils.adjustTimeout(waitTime * 10000);
    +        long waitTimeout = Utils.adjustTimeout(waitTime * 1000);
             long begin, delta;
             int count = 0;
             boolean exit = false;
     
             try {
                 begin = System.currentTimeMillis();
    -            eventSet = debugee.VM().eventQueue().remove(totalTime);
    +            eventSet = debugee.VM().eventQueue().remove(waitTimeout);
                 delta = System.currentTimeMillis() - begin;
    -            totalTime -= delta;
    +            totalWaitTime -= delta;
                 while (eventSet != null) {
                     EventIterator eventIterator = eventSet.eventIterator();
                     while (eventIterator.hasNext()) {
    @@ -174,14 +176,14 @@
                             throw new Failure("Unexpected VMDisconnectEvent received");
                         }
                     }
    -                if (totalTime <= 0 || exit) {
    +                if (totalWaitTime <= 0 || exit) {
                         break;
                     }
                     debugee.resume();
    -                    begin = System.currentTimeMillis();
    -                eventSet = debugee.VM().eventQueue().remove(totalTime);
    +                begin = System.currentTimeMillis();
    +                eventSet = debugee.VM().eventQueue().remove(waitTimeout);
                     delta = System.currentTimeMillis() - begin;
    -                totalTime -= delta;
    +                totalWaitTime -= delta;
                 }
             } catch(InterruptedException e) {
                 throw new Failure(e);
    diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassUnloadRequest/addClassFilter/filter001.java
    --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassUnloadRequest/addClassFilter/filter001.java	Mon Feb 25 15:15:46 2019 +0530
    +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ClassUnloadRequest/addClassFilter/filter001.java	Fri Mar 01 17:27:28 2019 +0530
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2002, 2019, 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
    @@ -23,6 +23,7 @@
     
     package nsk.jdi.ClassUnloadRequest.addClassFilter;
     
    +import jdk.test.lib.Utils;
     import nsk.share.*;
     import nsk.share.jdi.*;
     
    @@ -63,7 +64,7 @@
         private static int exitStatus;
         private static Log log;
         private static Debugee debugee;
    -    private static int eventWaitTime;
    +    private static long waitTime;
     
         String[] patterns = {
                         prefix + "Sub*",
    @@ -87,7 +88,8 @@
             filter001 tstObj = new filter001();
     
             ArgumentHandler argHandler = new ArgumentHandler(argv);
    -        eventWaitTime = argHandler.getWaitTime() * 60000;
    +        waitTime = argHandler.getWaitTime();
    +
             log = new Log(out, argHandler);
     
             debugee = Debugee.prepareDebugee(argHandler, log, debugeeName);
    @@ -120,7 +122,7 @@
                 debugee.sendSignal(SGNL_UNLOAD);
                 debugee.receiveExpectedSignal(SGNL_READY);
     
    -            receiveEvents(eventWaitTime, patterns[i]);
    +            receiveEvents(patterns[i]);
     
                 display("");
                 debugee.getEventRequestManager().deleteEventRequest(request);
    @@ -145,19 +147,20 @@
             return request;
         }
     
    -    private void receiveEvents(int waitTime, String pattern) {
    +    private void receiveEvents(String pattern) {
             EventSet eventSet = null;
             Event event;
    -        int totalTime = waitTime;
    +        long totalWaitTime = Utils.adjustTimeout(waitTime * 10000);
    +        long waitTimeout = Utils.adjustTimeout(waitTime * 1000);
             long begin, delta;
             int count = 0;
             boolean exit = false;
     
             try {
                 begin = System.currentTimeMillis();
    -            eventSet = debugee.VM().eventQueue().remove(totalTime);
    +            eventSet = debugee.VM().eventQueue().remove(waitTimeout);
                 delta = System.currentTimeMillis() - begin;
    -            totalTime -= delta;
    +            totalWaitTime -= delta;
                 while (eventSet != null) {
                     EventIterator eventIterator = eventSet.eventIterator();
                     while (eventIterator.hasNext()) {
    @@ -173,14 +176,14 @@
                             throw new Failure("Unexpected VMDisconnectEvent received");
                         }
                     }
    -                if (totalTime <= 0 || exit) {
    +                if (totalWaitTime <= 0 || exit) {
                         break;
                     }
                     debugee.resume();
    -                    begin = System.currentTimeMillis();
    -                eventSet = debugee.VM().eventQueue().remove(totalTime);
    +                begin = System.currentTimeMillis();
    +                eventSet = debugee.VM().eventQueue().remove(waitTimeout);
                     delta = System.currentTimeMillis() - begin;
    -                totalTime -= delta;
    +                totalWaitTime -= delta;
                 }
             } catch(InterruptedException e) {
                 throw new Failure(e);
    diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/vmTestbase/nsk/jdi/Event/_itself_/event001.java
    --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/Event/_itself_/event001.java	Mon Feb 25 15:15:46 2019 +0530
    +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/Event/_itself_/event001.java	Fri Mar 01 17:27:28 2019 +0530
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2001, 2019, 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
    @@ -36,6 +36,7 @@
     import java.util.List;
     import java.io.*;
     
    +import jdk.test.lib.Utils;
     import nsk.share.*;
     import nsk.share.jpda.*;
     import nsk.share.jdi.*;
    @@ -234,7 +235,7 @@
     
     // wait for a requested event
             try {
    -            gotEvent.wait(argHandler.getWaitTime()*60000);
    +            gotEvent.wait(Utils.adjustTimeout(argHandler.getWaitTime()*1000));
             } catch (InterruptedException e) {
                 log.complain("TEST FAILURE: waiting for a requested AccessWatchpointEvent #"
                     + i + ": caught " + e);
    diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove/remove004.java
    --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove/remove004.java	Mon Feb 25 15:15:46 2019 +0530
    +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove/remove004.java	Fri Mar 01 17:27:28 2019 +0530
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2001, 2019, 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
    @@ -23,6 +23,7 @@
     
     package nsk.jdi.EventQueue.remove;
     
    +import jdk.test.lib.Utils;
     import nsk.share.*;
     import nsk.share.jpda.*;
     import nsk.share.jdi.*;
    @@ -67,7 +68,7 @@
      * 
    * The check includes two steps.
    * In first one, second thread waits for any incoming event from the
    - * debugger which is sleeping for "WAITTIME*90 seconds"; hence,
    + * debugger which is sleeping for some time; hence,
    * no events are expected to be received at the debugger end.
    * In second, second thread is interrupted, and the debugger waits for
    * a breakpoint event after the debuggee finishes sleeping.
    @@ -130,7 +131,7 @@ static Debugee debuggee; static ArgumentHandler argsHandler; - static int waitTime; + static long waitTime; static VirtualMachine vm = null; static EventRequestManager eventRManager = null; @@ -140,6 +141,8 @@ static ReferenceType debuggeeClass = null; + static Value trueValue; + static int testExitCode = PASSED; class JDITestRuntimeException extends RuntimeException { @@ -156,7 +159,7 @@ logHandler = new Log(out, argsHandler); Binder binder = new Binder(argsHandler, logHandler); - waitTime = argsHandler.getWaitTime() * 60000; + waitTime = Utils.adjustTimeout(argsHandler.getWaitTime() * 1000); try { log2("launching a debuggee :"); @@ -285,6 +288,8 @@ if (!debuggeeClass.name().equals(debuggeeName)) throw new JDITestRuntimeException("** Unexpected ClassName for ClassPrepareEvent **"); + trueValue = debuggeeClass.getValue(debuggeeClass.fieldByName("BOOLEAN_TRUE_VALUE")); + log2(" received: ClassPrepareEvent for debuggeeClass"); String bPointMethod = "methodForCommunication"; @@ -356,11 +361,11 @@ thread2.interrupt(); for (int i2 = 0; i2 < waitTime; ) { - waitObj.wait(10000); + waitObj.wait(1000); if (!thread2.isAlive()) { break; } - i2 += 10000; + i2 += 1000; } if (thread2.isAlive()) { log3("ERROR: thread2 is still alive"); @@ -508,9 +513,17 @@ log2("-----t2: eventSet = eventQueue.remove(); expects: InterruptedException"); eventSet = eventQueue.remove(); throw new JDITestRuntimeException("** return from eventQueue.remove(); **"); - } catch ( InterruptedException e1) { + } catch (InterruptedException e1) { log2("-----t2: InterruptedException"); - } catch ( Exception e ) { + // Signal to debuggee to stop sleeping + try { + ((ClassType) debuggeeClass).setValue(debuggeeClass.fieldByName("stopSleeping"), + trueValue); + } catch (InvalidTypeException | ClassNotLoadedException e) { + log3("ERROR: -----t2: Exception : " + e); + testExitCode = FAILED; + } + } catch (Exception e) { log3("ERROR: -----t2: Exception : " + e); testExitCode = FAILED; } diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove/remove004a.java --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove/remove004a.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove/remove004a.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2019, 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 @@ -23,6 +23,7 @@ package nsk.jdi.EventQueue.remove; +import jdk.test.lib.Utils; import nsk.share.*; import nsk.share.jpda.*; import nsk.share.jdi.*; @@ -63,6 +64,12 @@ static int lineForComm = 2; + // Used for communication between debugger and debuggee + static volatile boolean stopSleeping = false; + + // Used by debugger to set stopSleeping flag to true + static final boolean BOOLEAN_TRUE_VALUE = true; + private static void methodForCommunication() { int i1 = instruction; int i2 = i1; @@ -97,10 +104,12 @@ log1("before: methodForCommunication();"); methodForCommunication(); log1("before: Thread.sleep"); - try { - Thread.sleep(argHandler.getWaitTime()*90000); - } catch (InterruptedException e) { - } + Utils.waitForCondition( + () -> { + return stopSleeping; + }, + Utils.adjustTimeout(argHandler.getWaitTime() * 10000), + 100); log1("after: Thread.sleep"); break ; diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove_l/remove_l004.java --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove_l/remove_l004.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove_l/remove_l004.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2019, 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 @@ -23,6 +23,7 @@ package nsk.jdi.EventQueue.remove_l; +import jdk.test.lib.Utils; import nsk.share.*; import nsk.share.jpda.*; import nsk.share.jdi.*; @@ -30,7 +31,6 @@ import com.sun.jdi.*; import com.sun.jdi.event.*; import com.sun.jdi.request.*; - import java.util.*; import java.io.*; @@ -63,8 +63,8 @@ * to be suspended and to inform the debugger with the event.
    * The case for testing consists of of two steps.
    * In the first one the first assertion is checked up on as follows:
    - * the debugger sleeps for "WAITTIME * 90 sec";
    - * hence, no event is expected in the debugger within WAITTINE, and
    + * the debugger sleeps for some time;
    + * hence, no event is expected in the debugger within WAITTIME, and
    * debugger's method breakpointForCommunication() should get null.
    * After WAITTIME, the debugger just expects to get normal breakpoint event.
    */ @@ -126,7 +126,7 @@ static Debugee debuggee; static ArgumentHandler argsHandler; - static int waitTime; + static long waitTime; static VirtualMachine vm = null; static EventRequestManager eventRManager = null; @@ -136,6 +136,8 @@ static ReferenceType debuggeeClass = null; + static Value trueValue; + static int testExitCode = PASSED; class JDITestRuntimeException extends RuntimeException { @@ -152,7 +154,7 @@ logHandler = new Log(out, argsHandler); Binder binder = new Binder(argsHandler, logHandler); - waitTime = argsHandler.getWaitTime() * 60000; + waitTime = Utils.adjustTimeout(argsHandler.getWaitTime() * 1000); try { log2("launching a debuggee :"); @@ -281,6 +283,8 @@ if (!debuggeeClass.name().equals(debuggeeName)) throw new JDITestRuntimeException("** Unexpected ClassName for ClassPrepareEvent **"); + trueValue = debuggeeClass.getValue(debuggeeClass.fieldByName("BOOLEAN_TRUE_VALUE")); + log2(" received: ClassPrepareEvent for debuggeeClass"); String bPointMethod = "methodForCommunication"; @@ -326,6 +330,11 @@ testExitCode = FAILED; throw new JDITestRuntimeException("** unexpected Exception **"); } + + // Signal to debuggee to stop sleeping + ((ClassType) debuggeeClass).setValue(debuggeeClass.fieldByName("stopSleeping"), + trueValue); + } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove_l/remove_l004a.java --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove_l/remove_l004a.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventQueue/remove_l/remove_l004a.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2019, 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 @@ -23,6 +23,7 @@ package nsk.jdi.EventQueue.remove_l; +import jdk.test.lib.Utils; import nsk.share.*; import nsk.share.jpda.*; import nsk.share.jdi.*; @@ -63,6 +64,12 @@ static int lineForComm = 2; + // Used for communication between debugger and debuggee + static volatile boolean stopSleeping = false; + + // Used by debugger to set stopSleeping flag to true + static final boolean BOOLEAN_TRUE_VALUE = true; + private static void methodForCommunication() { int i1 = instruction; int i2 = i1; @@ -97,10 +104,12 @@ log1("before: methodForCommunication();"); methodForCommunication(); log1("before: Thread.sleep"); - try { - Thread.sleep(argHandler.getWaitTime()*90000); - } catch (InterruptedException e) { - } + Utils.waitForCondition( + () -> { + return stopSleeping; + }, + Utils.adjustTimeout(argHandler.getWaitTime() * 10000), + 100); log1("after: Thread.sleep"); break ; diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/suspend/suspend001.java --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/suspend/suspend001.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/suspend/suspend001.java Fri Mar 01 17:27:28 2019 +0530 @@ -23,6 +23,7 @@ package nsk.jdi.ThreadReference.suspend; +import jdk.test.lib.Utils; import nsk.share.*; import nsk.share.jpda.*; import nsk.share.jdi.*; @@ -429,7 +430,8 @@ * It removes events from EventQueue until gets first BreakpointEvent. * To get next EventSet value, it uses the method * EventQueue.remove(int timeout) - * The timeout argument passed to the method, is "waitTime*60000". + * The timeout argument passed to the method, is "waitTime*1000" adjusted to + * test.timeout.factor system property. * Note: the value of waitTime is set up with * the method ArgumentHandler.getWaitTime() at the beginning of the test. * @@ -451,7 +453,7 @@ log2(" new: eventSet = eventQueue.remove();"); try { - eventSet = eventQueue.remove (waitTime*60000); + eventSet = eventQueue.remove(Utils.adjustTimeout(waitTime*1000)); if (eventSet == null) { log2(":::::: timeout when waiting for a BreakpintEvent"); // log3("ERROR: timeout for waiting for a BreakpintEvent"); diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/dispose/dispose002.java --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/dispose/dispose002.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/dispose/dispose002.java Fri Mar 01 17:27:28 2019 +0530 @@ -23,6 +23,7 @@ package nsk.jdi.VirtualMachine.dispose; +import jdk.test.lib.Utils; import nsk.share.*; import nsk.share.jpda.*; import nsk.share.jdi.*; @@ -272,29 +273,29 @@ if (expresult != returnCode0) break label1; - log2(" Thread.sleep(waitTime*60000);"); - try { - Thread.sleep(waitTime*60000); - } catch ( InterruptedException e ) { - log3("ERROR: InterruptedException"); - expresult = returnCode1; - break label1; - } + log2(" Waiting for thread2 is not alive"); - log2("......sending to the debuggee: 'check_alive'"); - log2(" expected reply: 'not_alive'"); - pipe.println("check_alive"); - line = pipe.readln(); - if (line.equals("alive")) { - log3("ERROR: thread2 is alive"); - expresult = returnCode1; - } else if (line.equals("not_alive")) { - log2(" thread2 is not alive"); - } else { - log3("ERROR: unexpected reply: " + line); - expresult = returnCode4; - } + Utils.waitForCondition( + () -> { + log2("......sending to the debuggee: 'check_alive'"); + log2(" expected reply: 'not_alive'"); + pipe.println("check_alive"); + String reply = pipe.readln(); + if (reply.equals("alive")) { + log3("ERROR: thread2 is alive"); + return false; + } else if (reply.equals("not_alive")) { + log2(" thread2 is not alive"); + return true; + } else { + log3("ERROR: unexpected reply: " + reply); + throw new RuntimeException("ERROR: unexpected reply: " + reply); + } + }, + Utils.adjustTimeout(waitTime * 60000), + 1000); + pipe.println("check_done"); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/dispose/dispose002a.java --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/dispose/dispose002a.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/dispose/dispose002a.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2019, 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 @@ -125,18 +125,26 @@ } } log1("mainThread is out of: synchronized (lockingObject)"); - - instruction = pipe.readln(); - if (!instruction.equals("check_alive")) { - logErr("ERROR: unexpected instruction: " + instruction); - exitCode = FAILED; - } else { - log1("checking on: thread2.isAlive"); - if (test_thread.isAlive()) { - pipe.println("alive"); - test_thread.interrupt(); + while (true) { + instruction = pipe.readln(); + if (instruction.equals("check_done")) { + if (test_thread.isAlive()) { + logErr("ERROR: thread thread2 is still alive"); + exitCode = FAILED; + } + break; + } else if (instruction.equals("check_alive")) { + log1("checking on: thread2.isAlive"); + if (test_thread.isAlive()) { + pipe.println("alive"); + test_thread.interrupt(); + } else { + pipe.println("not_alive"); + } } else { - pipe.println("not_alive"); + logErr("ERROR: unexpected instruction: " + instruction); + exitCode = FAILED; + break; } } diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/dispose/dispose003.java --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/dispose/dispose003.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/dispose/dispose003.java Fri Mar 01 17:27:28 2019 +0530 @@ -23,6 +23,7 @@ package nsk.jdi.VirtualMachine.dispose; +import jdk.test.lib.Utils; import nsk.share.*; import nsk.share.jpda.*; import nsk.share.jdi.*; @@ -179,6 +180,7 @@ int expresult = returnCode0; + String threadName = "testedThread"; List allThreads = null; @@ -236,28 +238,28 @@ if (expresult != returnCode0) break label1; - log2(" Thread.sleep(waitTime*60000);"); - try { - Thread.sleep(waitTime*60000); - } catch ( InterruptedException e ) { - log3("ERROR: InterruptedException"); - expresult = returnCode1; - break label1; - } + log2(" Waiting for thread2 is not alive"); - log2("......sending to the debuggee: 'check_alive'"); - log2(" expected reply: 'not_alive'"); - pipe.println("check_alive"); - line = pipe.readln(); - if (line.equals("alive")) { - log3("ERROR: thread2 is alive"); - expresult = returnCode1; - } else if (line.equals("not_alive")) { - log2(" thread2 is not alive"); - } else { - log3("ERROR: unexpected reply: " + line); - expresult = returnCode4; - } + Utils.waitForCondition( + () -> { + log2("......sending to the debuggee: 'check_alive'"); + log2(" expected reply: 'not_alive'"); + pipe.println("check_alive"); + String reply = pipe.readln(); + if (reply.equals("alive")) { + log3("ERROR: thread2 is alive"); + return false; + } else if (reply.equals("not_alive")) { + log2(" thread2 is not alive"); + return true; + } else { + log3("ERROR: unexpected reply: " + reply); + throw new RuntimeException("ERROR: unexpected reply: " + reply); + } + }, + Utils.adjustTimeout(waitTime * 60000), + 1000); + pipe.println("check_done"); } @@ -287,4 +289,6 @@ } return testExitCode; } + + } diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/dispose/dispose003a.java --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/dispose/dispose003a.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/dispose/dispose003a.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2019, 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 @@ -126,17 +126,26 @@ } log1("mainThread is out of: synchronized (lockingObject)"); - instruction = pipe.readln(); - if (!instruction.equals("check_alive")) { - logErr("ERROR: unexpected instruction: " + instruction); - exitCode = FAILED; - } else { - log1("checking on: thread2.isAlive"); - if (test_thread.isAlive()) { - test_thread.resume(); - pipe.println("alive"); + while (true) { + instruction = pipe.readln(); + if (instruction.equals("check_done")) { + if (test_thread.isAlive()) { + logErr("ERROR: thread2 thread is still alive"); + exitCode = FAILED; + } + break; + } else if (instruction.equals("check_alive")) { + log1("checking on: thread2.isAlive"); + if (test_thread.isAlive()) { + test_thread.resume(); + pipe.println("alive"); + } else { + pipe.println("not_alive"); + } } else { - pipe.println("not_alive"); + logErr("ERROR: unexpected instruction: " + instruction); + exitCode = FAILED; + break; } } diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/dispose/dispose004.java --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/dispose/dispose004.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/dispose/dispose004.java Fri Mar 01 17:27:28 2019 +0530 @@ -23,6 +23,7 @@ package nsk.jdi.VirtualMachine.dispose; +import jdk.test.lib.Utils; import nsk.share.*; import nsk.share.jpda.*; import nsk.share.jdi.*; @@ -261,29 +262,30 @@ if (expresult != returnCode0) break label1; - log2(" Thread.sleep(waitTime*60000);"); - try { - Thread.sleep(waitTime*60000); - } catch ( InterruptedException e ) { - log3("ERROR: InterruptedException"); - expresult = returnCode1; - break label1; - } + log2(" Waiting for thread2 is not alive"); - log2("......sending to the debuggee: 'check_alive'"); - log2(" expected reply: 'not_alive'"); - pipe.println("check_alive"); - line = pipe.readln(); - if (line.equals("alive")) { - log3("ERROR: thread2 is alive"); - expresult = returnCode1; - } else if (line.equals("not_alive")) { - log2(" thread2 is not alive"); - } else { - log3("ERROR: unexpected reply: " + line); - expresult = returnCode4; - } + Utils.waitForCondition( + () -> { + log2("......sending to the debuggee: 'check_alive'"); + log2(" expected reply: 'not_alive'"); + pipe.println("check_alive"); + String reply = pipe.readln(); + if (reply.equals("alive")) { + log3("ERROR: thread2 is alive"); + return false; + } else if (reply.equals("not_alive")) { + log2(" thread2 is not alive"); + return true; + } else { + log3("ERROR: unexpected reply: " + reply); + throw new RuntimeException("ERROR: unexpected reply: " + reply); + } + }, + Utils.adjustTimeout(waitTime * 60000), + 1000); + + pipe.println("check_done"); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/dispose/dispose004a.java --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/dispose/dispose004a.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/dispose/dispose004a.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2019, 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 @@ -127,18 +127,26 @@ } } log1("mainThread is out of: synchronized (lockingObject)"); - - instruction = pipe.readln(); - if (!instruction.equals("check_alive")) { - logErr("ERROR: unexpected instruction: " + instruction); - exitCode = FAILED; - } else { - log1("checking on: thread2.isAlive"); - if (test_thread.isAlive()) { - test_thread.resume(); - pipe.println("alive"); + while (true) { + instruction = pipe.readln(); + if (instruction.equals("check_done")) { + if (test_thread.isAlive()) { + logErr("thread thread2 is still alive"); + exitCode = FAILED; + } + break; + } else if (instruction.equals("check_alive")) { + log1("checking on: thread2.isAlive"); + if (test_thread.isAlive()) { + test_thread.resume(); + pipe.println("alive"); + } else { + pipe.println("not_alive"); + } } else { - pipe.println("not_alive"); + logErr("ERROR: unexpected instruction: " + instruction); + exitCode = FAILED; + break; } } diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/suspend/suspend001.java --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/suspend/suspend001.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/VirtualMachine/suspend/suspend001.java Fri Mar 01 17:27:28 2019 +0530 @@ -23,6 +23,7 @@ package nsk.jdi.VirtualMachine.suspend; +import jdk.test.lib.Utils; import nsk.share.*; import nsk.share.jpda.*; import nsk.share.jdi.*; @@ -318,9 +319,10 @@ eventSet1.resume(); eventSet.resume(); - log2(" before: Thread.sleep(waitTime*60000);"); + log2(" before: Thread.sleep(waitTime*1000);"); + try { - Thread.sleep(waitTime*60000); + Thread.sleep(Utils.adjustTimeout(waitTime*1000)); } catch ( InterruptedException e ) { log3("ERROR: InterruptedException"); expresult = returnCode1; diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/GenClassesBuilder.java --- a/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/GenClassesBuilder.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/hotspot/jtreg/vmTestbase/nsk/monitoring/stress/classload/GenClassesBuilder.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, 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 @@ -79,12 +79,13 @@ } catch (IOException e) { throw new Error("can't create dirs for" + dir, e); } - Path pattern = testRoot().resolve("vmTestbase") - .resolve("nsk") - .resolve("monitoring") - .resolve("share") - .resolve("LoadableClass.pattern") - .toAbsolutePath(); + Path pattern = Paths.get(Utils.TEST_ROOT) + .resolve("vmTestbase") + .resolve("nsk") + .resolve("monitoring") + .resolve("share") + .resolve("LoadableClass.pattern") + .toAbsolutePath(); if (Files.notExists(pattern)) { throw new Error("can't find pattern file: " + pattern); } @@ -94,13 +95,5 @@ throw new Error("can't generate classes", e); } } - - private static Path testRoot() { - Path p = Paths.get(Utils.TEST_SRC); - while (!Files.exists(p.resolve("TEST.ROOT"))) { - p = p.getParent(); - } - return p; - } } diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/vmTestbase/vm/mlvm/mixed/stress/java/findDeadlock/INDIFY_Test.java --- a/test/hotspot/jtreg/vmTestbase/vm/mlvm/mixed/stress/java/findDeadlock/INDIFY_Test.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/hotspot/jtreg/vmTestbase/vm/mlvm/mixed/stress/java/findDeadlock/INDIFY_Test.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, 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 @@ -33,6 +33,7 @@ import java.lang.management.ManagementFactory; import java.lang.management.ThreadMXBean; import java.lang.reflect.Method; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.locks.ReentrantLock; @@ -53,6 +54,7 @@ static MutableCallSite[] _cs = new MutableCallSite[THREAD_NUM]; static CyclicBarrier _threadRaceStartBarrier; + static CountDownLatch _threadsRunningLatch; static volatile boolean _testFailed; static volatile boolean _testDone; static volatile int _iteration; @@ -63,22 +65,22 @@ boolean locked = false; place = Thread.currentThread().getName() + ": " + place; if ( ! lockInterruptible ) { - Env.traceVerbose(place + ": Locking " + n); + Env.traceVerbose("Iteration " + _iteration + " " + place + ": Locking " + n); _locks[n].lock(); locked = true; } else { try { - Env.traceVerbose(place + ": Locking interruptibly " + n); + Env.traceVerbose("Iteration " + _iteration + " " + place + ": Locking interruptibly " + n); _locks[n].lockInterruptibly(); locked = true; if ( ! _testDone ) throw new Exception(place + ": LOCKED " + n); else - Env.traceVerbose(place + ": LOCKED " + n); + Env.traceVerbose("Iteration " + _iteration + " " + place + ": LOCKED " + n); } catch ( InterruptedException swallow ) { - Env.traceVerbose(place + ": interrupted while locking " + n); + Env.traceVerbose("Iteration " + _iteration + " " + place + ": interrupted while locking " + n); } } @@ -87,9 +89,9 @@ private static boolean unlock(String place, int n) throws Throwable { place = Thread.currentThread().getName() + ": " + place; - Env.traceVerbose(place + ": Unlocking " + n); + Env.traceVerbose("Iteration " + _iteration + " " + place + ": Unlocking " + n); _locks[n].unlock(); - Env.traceVerbose(place + ": UNLOCKED " + n); + Env.traceVerbose("Iteration " + _iteration + " " + place + ": UNLOCKED " + n); return false; } @@ -98,7 +100,7 @@ if ( l instanceof MethodHandles.Lookup ) { // Method is used as BSM - Env.traceVerbose(thread.getName() + ": Entered BSM. Lock=" + lockNum); + Env.traceVerbose("Iteration " + _iteration + " " + thread.getName() + ": Entered BSM. Lock=" + lockNum); if ( _iteration > 0 ) throw new Exception("BSM called twice!"); @@ -107,6 +109,7 @@ case 0: thread._lockedCurrent = lock("BSM", lockNum, false); _threadRaceStartBarrier.await(); + _threadsRunningLatch.countDown(); thread._lockedNext = lock("BSM", nextLock(lockNum), true); break; @@ -123,7 +126,7 @@ } else { // Method is used as target - Env.traceVerbose(thread.getName() + ": Entered target method. Lock=" + lockNum); + Env.traceVerbose("Iteration " + _iteration + " " + thread.getName() + ": Entered target method. Lock=" + lockNum); try { if ( _iteration > 0 ) { @@ -132,26 +135,29 @@ case 0: thread._lockedCurrent = lock("Target", lockNum, false); _threadRaceStartBarrier.await(); + _threadsRunningLatch.countDown(); thread._lockedNext = lock("Target", nextLock(lockNum), true); break; case 1: thread._lockedCurrent = lock("Target", lockNum, false); _threadRaceStartBarrier.await(); - Env.traceVerbose(thread.getName() + ": Entering synchronize ( " + lockNum + " )"); + _threadsRunningLatch.countDown(); + Env.traceVerbose("Iteration " + _iteration + " " + thread.getName() + ": Entering synchronize ( " + lockNum + " )"); synchronized ( _locks[nextLock(lockNum)] ) { } - Env.traceVerbose(thread.getName() + ": Exited synchronize ( " + lockNum + " )"); + Env.traceVerbose("Iteration " + _iteration + " " + thread.getName() + ": Exited synchronize ( " + lockNum + " )"); break; case 2: - Env.traceVerbose(thread.getName() + ": Entering synchronize ( " + lockNum + " )"); + Env.traceVerbose("Iteration " + _iteration + " " + thread.getName() + ": Entering synchronize ( " + lockNum + " )"); synchronized ( _locks[lockNum] ) { _threadRaceStartBarrier.await(); + _threadsRunningLatch.countDown(); thread._lockedNext = lock("Target", nextLock(lockNum), true); thread._lockedNext = unlock("Target", nextLock(lockNum)); } - Env.traceVerbose(thread.getName() + ": Exited synchronize ( " + lockNum + " )"); + Env.traceVerbose("Iteration " + _iteration + " " + thread.getName() + ": Exited synchronize ( " + lockNum + " )"); break; } @@ -163,12 +169,14 @@ case 1: _threadRaceStartBarrier.await(); + _threadsRunningLatch.countDown(); thread._lockedNext = lock("Target", nextLock(lockNum), true); break; case 2: thread._lockedCurrent = lock("Target", lockNum, false); _threadRaceStartBarrier.await(); + _threadsRunningLatch.countDown(); thread._lockedNext = lock("Target", nextLock(lockNum), true); break; } @@ -18205,8 +18213,9 @@ } boolean test() throws Throwable { - Env.traceNormal("Starting test..."); - + Env.traceNormal("Iteration " + _iteration + " Starting test..."); + + // Sanity check that all the locks are available. for ( int i = 0; i < THREAD_NUM; i++ ) { if ( _locks[i].isLocked() ) { Env.getLog().complain("Lock " + i + " is still locked!"); @@ -18217,60 +18226,87 @@ if ( _testFailed ) throw new Exception("Some locks are still locked"); + // Threads generally wait on this after claiming their first lock, + // and then when released will try to claim the second, which leads + // to deadlock. _threadRaceStartBarrier = new CyclicBarrier(THREAD_NUM + 1); + + // Threads signal this latch after being released from the startbarrier + // so that they are closer to triggering deadlock before the main thread + // starts to check for it. + _threadsRunningLatch = new CountDownLatch(THREAD_NUM); + _testDone = false; _testFailed = false; - for ( int i = 0; i < THREAD_NUM; i++ ) + // Start the new batch of threads. + for ( int i = 0; i < THREAD_NUM; i++ ) { (_threads[i] = new DeadlockedThread(i)).start(); + } try { + // If a thread encounters an error before it reaches the start barrier + // then we will hang here until the test times out. So we do a token + // check for such failure. + if (_testFailed) { + Env.complain("Unexpected thread failure before startBarrier was reached"); + return false; + } + _threadRaceStartBarrier.await(); - Env.traceVerbose("Start race..."); - - // - // Wait for the deadlock and detect it using ThreadMXBean - // - - boolean resultsReady = false; - for ( int i = 0; i < 10 && ! resultsReady && ! _testFailed; i++ ) { - Env.traceNormal("Waiting for threads to lock up..."); - Thread.sleep(100); - - resultsReady = true; - for ( int t = 0; t < THREAD_NUM; t++ ) { - if ( _iteration == 0 && t % 3 != 2 && ! _locks[t].hasQueuedThreads() ) { - Env.traceVerbose("Lock " + t + ": no waiters"); - resultsReady = false; - } else { - Env.traceVerbose("Lock " + t + ": has waiters"); - } - } + Env.traceVerbose("Iteration " + _iteration + " Start race..."); + + // Wait till all threads poised to deadlock. Again we may hang here + // if unexpected errors are encountered, so again a token check. + if (_testFailed) { + Env.complain("Unexpected thread failure after startBarrier was reached"); + return false; } - if ( ! resultsReady ) - Env.traceImportant("Warning: threads are still not deadlocked?"); - - long[] deadlockedThreads = _threadMXBean.findDeadlockedThreads(); - if ( deadlockedThreads == null ) { - Env.complain("Found no deadlocked threads. Expected to find " + THREAD_NUM); + _threadsRunningLatch.await(); + + // There is a race now between checking for a deadlock and the threads + // actually engaging in that deadlock. We can't query all of the "locks" + // involved to see if they are owned and have waiters (no API for built-in + // monitors). Nor can we check the thread states because they could be blocked + // on incidental synchronization (like I/O monitors when logging is enabled). + // So we simply loop checking for a deadlock until we find it, or else the + // overall test times out. + + long[] deadlockedThreads = null; + do { + deadlockedThreads = _threadMXBean.findDeadlockedThreads(); + } while (deadlockedThreads == null && !_testFailed); + + if (_testFailed) { + Env.complain("Unexpected thread failure while checking for deadlock"); return false; - } else if ( deadlockedThreads.length != THREAD_NUM ) { + } + + if (deadlockedThreads.length != THREAD_NUM) { Env.complain("Found " + deadlockedThreads.length + " deadlocked threads. Expected to find " + THREAD_NUM); return false; } else { Env.traceNormal("Found " + deadlockedThreads.length + " deadlocked threads as expected"); - return ! _testFailed; + return true; } } finally { + // Tells the locking threads the interrupt was expected. _testDone = true; + // Break the deadlock by dropping the attempt to lock + // the interruptible locks, which then causes all other + // locks to be released and allow threads acquiring + // non-interruptible locks to proceed. _threads[0].interrupt(); - for ( int i = 0; i < THREAD_NUM; i++ ) { - _threads[i].join(1000); - if ( _threads[i].isAlive() ) - Env.getLog().complain("Thread " + _threads[i].getName() + " is still alive"); + // Wait for all threads to terminate before proceeding to next + // iteration. If we only join() for a limited time and its too short + // then we not only complain here, but will also find locks that are + // still locked. It is far simpler to only proceed when all threads + // are done and rely on the overall test timeout to detect problems. + for (int i = 0; i < THREAD_NUM; i++) { + _threads[i].join(); } MutableCallSite.syncAll(_cs); diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/vmTestbase/vm/mlvm/mixed/stress/java/findDeadlock/INDIFY_Test.jmpp --- a/test/hotspot/jtreg/vmTestbase/vm/mlvm/mixed/stress/java/findDeadlock/INDIFY_Test.jmpp Mon Feb 25 15:15:46 2019 +0530 +++ b/test/hotspot/jtreg/vmTestbase/vm/mlvm/mixed/stress/java/findDeadlock/INDIFY_Test.jmpp Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, 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 @@ -35,6 +35,7 @@ import java.lang.management.ManagementFactory; import java.lang.management.ThreadMXBean; import java.lang.reflect.Method; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.locks.ReentrantLock; @@ -55,6 +56,7 @@ static MutableCallSite[] _cs = new MutableCallSite[THREAD_NUM]; static CyclicBarrier _threadRaceStartBarrier; + static CountDownLatch _threadsRunningLatch; static volatile boolean _testFailed; static volatile boolean _testDone; static volatile int _iteration; @@ -65,22 +67,22 @@ boolean locked = false; place = Thread.currentThread().getName() + ": " + place; if ( ! lockInterruptible ) { - Env.traceVerbose(place + ": Locking " + n); + Env.traceVerbose("Iteration " + _iteration + " " + place + ": Locking " + n); _locks[n].lock(); locked = true; } else { try { - Env.traceVerbose(place + ": Locking interruptibly " + n); + Env.traceVerbose("Iteration " + _iteration + " " + place + ": Locking interruptibly " + n); _locks[n].lockInterruptibly(); locked = true; if ( ! _testDone ) throw new Exception(place + ": LOCKED " + n); else - Env.traceVerbose(place + ": LOCKED " + n); + Env.traceVerbose("Iteration " + _iteration + " " + place + ": LOCKED " + n); } catch ( InterruptedException swallow ) { - Env.traceVerbose(place + ": interrupted while locking " + n); + Env.traceVerbose("Iteration " + _iteration + " " + place + ": interrupted while locking " + n); } } @@ -89,9 +91,9 @@ private static boolean unlock(String place, int n) throws Throwable { place = Thread.currentThread().getName() + ": " + place; - Env.traceVerbose(place + ": Unlocking " + n); + Env.traceVerbose("Iteration " + _iteration + " " + place + ": Unlocking " + n); _locks[n].unlock(); - Env.traceVerbose(place + ": UNLOCKED " + n); + Env.traceVerbose("Iteration " + _iteration + " " + place + ": UNLOCKED " + n); return false; } @@ -100,7 +102,7 @@ if ( l instanceof MethodHandles.Lookup ) { // Method is used as BSM - Env.traceVerbose(thread.getName() + ": Entered BSM. Lock=" + lockNum); + Env.traceVerbose("Iteration " + _iteration + " " + thread.getName() + ": Entered BSM. Lock=" + lockNum); if ( _iteration > 0 ) throw new Exception("BSM called twice!"); @@ -109,6 +111,7 @@ case 0: thread._lockedCurrent = lock("BSM", lockNum, false); _threadRaceStartBarrier.await(); + _threadsRunningLatch.countDown(); thread._lockedNext = lock("BSM", nextLock(lockNum), true); break; @@ -125,7 +128,7 @@ } else { // Method is used as target - Env.traceVerbose(thread.getName() + ": Entered target method. Lock=" + lockNum); + Env.traceVerbose("Iteration " + _iteration + " " + thread.getName() + ": Entered target method. Lock=" + lockNum); try { if ( _iteration > 0 ) { @@ -134,26 +137,29 @@ case 0: thread._lockedCurrent = lock("Target", lockNum, false); _threadRaceStartBarrier.await(); + _threadsRunningLatch.countDown(); thread._lockedNext = lock("Target", nextLock(lockNum), true); break; case 1: thread._lockedCurrent = lock("Target", lockNum, false); _threadRaceStartBarrier.await(); - Env.traceVerbose(thread.getName() + ": Entering synchronize ( " + lockNum + " )"); + _threadsRunningLatch.countDown(); + Env.traceVerbose("Iteration " + _iteration + " " + thread.getName() + ": Entering synchronize ( " + lockNum + " )"); synchronized ( _locks[nextLock(lockNum)] ) { } - Env.traceVerbose(thread.getName() + ": Exited synchronize ( " + lockNum + " )"); + Env.traceVerbose("Iteration " + _iteration + " " + thread.getName() + ": Exited synchronize ( " + lockNum + " )"); break; case 2: - Env.traceVerbose(thread.getName() + ": Entering synchronize ( " + lockNum + " )"); + Env.traceVerbose("Iteration " + _iteration + " " + thread.getName() + ": Entering synchronize ( " + lockNum + " )"); synchronized ( _locks[lockNum] ) { _threadRaceStartBarrier.await(); + _threadsRunningLatch.countDown(); thread._lockedNext = lock("Target", nextLock(lockNum), true); thread._lockedNext = unlock("Target", nextLock(lockNum)); } - Env.traceVerbose(thread.getName() + ": Exited synchronize ( " + lockNum + " )"); + Env.traceVerbose("Iteration " + _iteration + " " + thread.getName() + ": Exited synchronize ( " + lockNum + " )"); break; } @@ -165,12 +171,14 @@ case 1: _threadRaceStartBarrier.await(); + _threadsRunningLatch.countDown(); thread._lockedNext = lock("Target", nextLock(lockNum), true); break; case 2: thread._lockedCurrent = lock("Target", lockNum, false); _threadRaceStartBarrier.await(); + _threadsRunningLatch.countDown(); thread._lockedNext = lock("Target", nextLock(lockNum), true); break; } @@ -255,8 +263,9 @@ } boolean test() throws Throwable { - Env.traceNormal("Starting test..."); + Env.traceNormal("Iteration " + _iteration + " Starting test..."); + // Sanity check that all the locks are available. for ( int i = 0; i < THREAD_NUM; i++ ) { if ( _locks[i].isLocked() ) { Env.getLog().complain("Lock " + i + " is still locked!"); @@ -267,60 +276,87 @@ if ( _testFailed ) throw new Exception("Some locks are still locked"); + // Threads generally wait on this after claiming their first lock, + // and then when released will try to claim the second, which leads + // to deadlock. _threadRaceStartBarrier = new CyclicBarrier(THREAD_NUM + 1); + + // Threads signal this latch after being released from the startbarrier + // so that they are closer to triggering deadlock before the main thread + // starts to check for it. + _threadsRunningLatch = new CountDownLatch(THREAD_NUM); + _testDone = false; _testFailed = false; - for ( int i = 0; i < THREAD_NUM; i++ ) + // Start the new batch of threads. + for ( int i = 0; i < THREAD_NUM; i++ ) { (_threads[i] = new DeadlockedThread(i)).start(); + } try { - _threadRaceStartBarrier.await(); - Env.traceVerbose("Start race..."); - - // - // Wait for the deadlock and detect it using ThreadMXBean - // + // If a thread encounters an error before it reaches the start barrier + // then we will hang here until the test times out. So we do a token + // check for such failure. + if (_testFailed) { + Env.complain("Unexpected thread failure before startBarrier was reached"); + return false; + } - boolean resultsReady = false; - for ( int i = 0; i < 10 && ! resultsReady && ! _testFailed; i++ ) { - Env.traceNormal("Waiting for threads to lock up..."); - Thread.sleep(100); + _threadRaceStartBarrier.await(); + Env.traceVerbose("Iteration " + _iteration + " Start race..."); - resultsReady = true; - for ( int t = 0; t < THREAD_NUM; t++ ) { - if ( _iteration == 0 && t % 3 != 2 && ! _locks[t].hasQueuedThreads() ) { - Env.traceVerbose("Lock " + t + ": no waiters"); - resultsReady = false; - } else { - Env.traceVerbose("Lock " + t + ": has waiters"); - } - } + // Wait till all threads poised to deadlock. Again we may hang here + // if unexpected errors are encountered, so again a token check. + if (_testFailed) { + Env.complain("Unexpected thread failure after startBarrier was reached"); + return false; } - if ( ! resultsReady ) - Env.traceImportant("Warning: threads are still not deadlocked?"); + _threadsRunningLatch.await(); + + // There is a race now between checking for a deadlock and the threads + // actually engaging in that deadlock. We can't query all of the "locks" + // involved to see if they are owned and have waiters (no API for built-in + // monitors). Nor can we check the thread states because they could be blocked + // on incidental synchronization (like I/O monitors when logging is enabled). + // So we simply loop checking for a deadlock until we find it, or else the + // overall test times out. - long[] deadlockedThreads = _threadMXBean.findDeadlockedThreads(); - if ( deadlockedThreads == null ) { - Env.complain("Found no deadlocked threads. Expected to find " + THREAD_NUM); + long[] deadlockedThreads = null; + do { + deadlockedThreads = _threadMXBean.findDeadlockedThreads(); + } while (deadlockedThreads == null && !_testFailed); + + if (_testFailed) { + Env.complain("Unexpected thread failure while checking for deadlock"); return false; - } else if ( deadlockedThreads.length != THREAD_NUM ) { + } + + if (deadlockedThreads.length != THREAD_NUM) { Env.complain("Found " + deadlockedThreads.length + " deadlocked threads. Expected to find " + THREAD_NUM); return false; } else { Env.traceNormal("Found " + deadlockedThreads.length + " deadlocked threads as expected"); - return ! _testFailed; + return true; } } finally { + // Tells the locking threads the interrupt was expected. _testDone = true; + // Break the deadlock by dropping the attempt to lock + // the interruptible locks, which then causes all other + // locks to be released and allow threads acquiring + // non-interruptible locks to proceed. _threads[0].interrupt(); - for ( int i = 0; i < THREAD_NUM; i++ ) { - _threads[i].join(1000); - if ( _threads[i].isAlive() ) - Env.getLog().complain("Thread " + _threads[i].getName() + " is still alive"); + // Wait for all threads to terminate before proceeding to next + // iteration. If we only join() for a limited time and its too short + // then we not only complain here, but will also find locks that are + // still locked. It is far simpler to only proceed when all threads + // are done and rely on the overall test timeout to detect problems. + for (int i = 0; i < THREAD_NUM; i++) { + _threads[i].join(); } MutableCallSite.syncAll(_cs); diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/vmTestbase/vm/mlvm/share/StratumClassesBuilder.java --- a/test/hotspot/jtreg/vmTestbase/vm/mlvm/share/StratumClassesBuilder.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/hotspot/jtreg/vmTestbase/vm/mlvm/share/StratumClassesBuilder.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, 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 @@ -38,7 +38,7 @@ public class StratumClassesBuilder { public static void main(String[] args) { - Path root = testRoot(); + Path root = Paths.get(Utils.TEST_ROOT); Arrays.stream(args) .map(root::resolve) .forEach(StratumClassesBuilder::build); @@ -113,12 +113,4 @@ return file.getParent() .resolve(filename.replaceFirst("\\.class$", ".smap")); } - - private static Path testRoot() { - Path p = Paths.get(Utils.TEST_SRC); - while (!Files.exists(p.resolve("TEST.ROOT"))) { - p = p.getParent(); - } - return p; - } } diff -r 268875216dfc -r faf96b92a47b test/hotspot/jtreg/vmTestbase/vm/runtime/defmeth/shared/BuildJar.java --- a/test/hotspot/jtreg/vmTestbase/vm/runtime/defmeth/shared/BuildJar.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/hotspot/jtreg/vmTestbase/vm/runtime/defmeth/shared/BuildJar.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, 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 @@ -41,13 +41,14 @@ */ public class BuildJar { public static void main(String[] args) { - Path manifest = testRoot().resolve("vmTestbase") - .resolve("vm") - .resolve("runtime") - .resolve("defmeth") - .resolve("shared") - .resolve("retransform.mf") - .toAbsolutePath(); + Path manifest = Paths.get(Utils.TEST_ROOT) + .resolve("vmTestbase") + .resolve("vm") + .resolve("runtime") + .resolve("defmeth") + .resolve("shared") + .resolve("retransform.mf") + .toAbsolutePath(); if (Files.notExists(manifest)) { throw new Error("can't find manifest file: " + manifest); } @@ -90,13 +91,5 @@ } throw new Error("can't find " + file + " in " + Utils.TEST_CLASS_PATH); } - - private static Path testRoot() { - Path p = Paths.get(Utils.TEST_SRC); - while (!Files.exists(p.resolve("TEST.ROOT"))) { - p = p.getParent(); - } - return p; - } } diff -r 268875216dfc -r faf96b92a47b test/jaxp/TEST.ROOT --- a/test/jaxp/TEST.ROOT Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jaxp/TEST.ROOT Fri Mar 01 17:27:28 2019 +0530 @@ -23,7 +23,7 @@ groups=TEST.groups # Minimum jtreg version -requiredVersion=4.2 b13 +requiredVersion=4.2 b14 # Path to libraries in the topmost test directory. This is needed so @library # does not need ../../ notation to reach them diff -r 268875216dfc -r faf96b92a47b test/jdk/ProblemList.txt --- a/test/jdk/ProblemList.txt Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/ProblemList.txt Fri Mar 01 17:27:28 2019 +0530 @@ -556,6 +556,8 @@ java/net/MulticastSocket/Test.java 7145658 macosx-all +java/net/MulticastSocket/SetGetNetworkInterfaceTest.java 8219083 windows-all + java/net/DatagramSocket/SendDatagramToBadAddress.java 7143960 macosx-all java/net/ServerSocket/AcceptInheritHandle.java 8211854 aix-ppc64 @@ -868,3 +870,4 @@ # jdk_jfr jdk/jfr/event/io/TestInstrumentation.java 8202142 generic-all +jdk/jfr/api/recording/event/TestPeriod.java 8215890 generic-all diff -r 268875216dfc -r faf96b92a47b test/jdk/TEST.ROOT --- a/test/jdk/TEST.ROOT Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/TEST.ROOT Fri Mar 01 17:27:28 2019 +0530 @@ -49,7 +49,7 @@ release.implementor # Minimum jtreg version -requiredVersion=4.2 b13 +requiredVersion=4.2 b14 # Path to libraries in the topmost test directory. This is needed so @library # does not need ../../ notation to reach them @@ -60,3 +60,6 @@ # Use --patch-module instead of -Xmodule: useNewPatchModule=true + +# disabled till JDK-8219408 is fixed +allowSmartActionArgs=false diff -r 268875216dfc -r faf96b92a47b test/jdk/com/sun/jdi/JdbStopThreadidTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/com/sun/jdi/JdbStopThreadidTest.java Fri Mar 01 17:27:28 2019 +0530 @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2019, 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 8219143 + * @summary Tests that using the "stop in" threadid option will properly cause the + * breakpoint to only be triggered when hit in the specified thread. + * + * @library /test/lib + * @run compile -g JdbStopThreadidTest.java + * @run main/othervm JdbStopThreadidTest + */ + +import lib.jdb.Jdb; +import lib.jdb.JdbCommand; +import lib.jdb.JdbTest; + +import java.util.regex.*; + +class JdbStopThreadidTestTarg { + static Object lockObj = new Object(); + + public static void main(String[] args) { + test(); + } + + private static void test() { + JdbStopThreadidTestTarg test = new JdbStopThreadidTestTarg(); + MyThread myThread1 = test.new MyThread("MYTHREAD-1"); + MyThread myThread2 = test.new MyThread("MYTHREAD-2"); + MyThread myThread3 = test.new MyThread("MYTHREAD-3"); + + synchronized (lockObj) { + myThread1.start(); + myThread2.start(); + myThread3.start(); + // Wait for all threads to have started. Note they all block on lockObj after starting. + while (!myThread1.started || !myThread2.started || !myThread3.started) { + try { + Thread.sleep(50); + } catch (InterruptedException e) { + } + } + // Stop here so the test can setup the breakpoint in MYTHREAD-2 + brkMethod(); + } + + // Wait for all threads to finish before exiting + try { + myThread1.join(); + myThread2.join(); + myThread3.join(); + } catch (InterruptedException e) { + } + } + + static void brkMethod() { + } + + public static void print(Object obj) { + System.out.println(obj); + } + + class MyThread extends Thread { + volatile boolean started = false; + + public MyThread(String name) { + super(name); + } + + public void run() { + started = true; + synchronized (JdbStopThreadidTestTarg.lockObj) { + } + brkMethod(); + } + + void brkMethod() { + } + } +} + +public class JdbStopThreadidTest extends JdbTest { + public static void main(String argv[]) { + new JdbStopThreadidTest().run(); + } + + private JdbStopThreadidTest() { + super(DEBUGGEE_CLASS); + } + + private static final String DEBUGGEE_CLASS = JdbStopThreadidTestTarg.class.getName(); + private static final String DEBUGGEE_THREAD_CLASS = JdbStopThreadidTestTarg.class.getName() + "$MyThread"; + private static Pattern threadidPattern = Pattern.compile("MyThread\\)(\\S+)\\s+MYTHREAD-2"); + + @Override + protected void runCases() { + jdb.command(JdbCommand.stopIn(DEBUGGEE_CLASS, "brkMethod")); + jdb.command(JdbCommand.run().waitForPrompt("Breakpoint hit: \"thread=main\"", true)); + jdb.command(JdbCommand.threads()); + + // Find the threadid for MYTHREAD-2 in the "threads" command output + String output = jdb.getJdbOutput(); + Matcher m = threadidPattern.matcher(output); + String threadid = null; + if (m.find()) { + threadid = m.group(1); + } else { + throw new RuntimeException("FAILED: Did not match threadid pattern."); + } + + // Setup a breakpoint in MYTHREAD-2. + jdb.command(JdbCommand.stopInThreadid(DEBUGGEE_THREAD_CLASS, "brkMethod", threadid)); + + // Continue until MYTHREAD-2 breakpoint is hit. If we hit any other breakpoint before + // then (we aren't suppose to), then this test will fail. + jdb.command(JdbCommand.cont().waitForPrompt("Breakpoint hit: \"thread=MYTHREAD-2\", \\S+MyThread.brkMethod", true)); + // Continue until the application exits. Once again, hitting a breakpoint will cause + // a failure because we are not suppose to hit one. + jdb.command(JdbCommand.cont().waitForPrompt(Jdb.APPLICATION_EXIT, true)); + } +} diff -r 268875216dfc -r faf96b92a47b test/jdk/com/sun/jdi/OptionTest.java --- a/test/jdk/com/sun/jdi/OptionTest.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/com/sun/jdi/OptionTest.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2019, 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 @@ -33,8 +33,6 @@ * @run driver OptionTest */ -import java.net.ServerSocket; -import java.util.regex.Matcher; import java.util.regex.Pattern; public class OptionTest extends Object { @@ -127,18 +125,12 @@ } public static void main(String[] args) throws Exception { - // find a free port - ServerSocket ss = new ServerSocket(0); - int port = ss.getLocalPort(); - ss.close(); - String address = String.valueOf(port); - String javaExe = System.getProperty("java.home") + java.io.File.separator + "bin" + java.io.File.separator + "java"; String targetClass = "HelloWorld"; String baseOptions = "transport=dt_socket" + - ",address=" + address + + ",address=0" + ",server=y" + ",suspend=n"; diff -r 268875216dfc -r faf96b92a47b test/jdk/com/sun/jdi/RedefineNestmateAttr/TestNestmateAttr.java --- a/test/jdk/com/sun/jdi/RedefineNestmateAttr/TestNestmateAttr.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/com/sun/jdi/RedefineNestmateAttr/TestNestmateAttr.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, 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 @@ -212,6 +212,8 @@ protected void startUp(String targetName) { List argList = new ArrayList<>(Arrays.asList(args)); argList.add(0, targetName); // pre-pend so it becomes the first "app" arg + // We need the class path that contains the path to jdk.test.lib.Asserts. + argList.add(0, " -cp " + System.getProperty("test.class.path")); println("run args: " + argList); connect((String[]) argList.toArray(args)); waitForVMStart(); diff -r 268875216dfc -r faf96b92a47b test/jdk/com/sun/jdi/RunToExit.java --- a/test/jdk/com/sun/jdi/RunToExit.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/com/sun/jdi/RunToExit.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2019, 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 @@ -30,7 +30,6 @@ * @build VMConnection RunToExit Exit0 * @run driver RunToExit */ -import java.net.ServerSocket; import com.sun.jdi.Bootstrap; import com.sun.jdi.VirtualMachine; import com.sun.jdi.event.*; @@ -41,6 +40,8 @@ import java.util.List; import java.util.Iterator; import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; import jdk.test.lib.process.ProcessTools; @@ -50,6 +51,9 @@ static volatile int error_seen = 0; static volatile boolean ready = false; + /* port the debuggee is listening on */ + private static String address; + /* * Find a connector by name */ @@ -66,12 +70,11 @@ } /* - * Launch a server debuggee with the given address + * Launch a server debuggee, detect debuggee listening port */ - private static Process launch(String address, String class_name) throws Exception { + private static Process launch(String class_name) throws Exception { String args[] = new String[]{ - "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=" - + address, + "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=0", class_name }; args = VMConnection.insertDebuggeeVMOptions(args); @@ -92,8 +95,17 @@ return p; } + /* warm-up predicate for debuggee */ + private static Pattern listenRegexp = Pattern.compile("Listening for transport \\b(.+)\\b at address: \\b(.+)\\b"); + private static boolean isTransportListening(String line) { - return line.startsWith("Listening for transport dt_socket"); + Matcher m = listenRegexp.matcher(line); + if (!m.matches()) { + return false; + } + // address is 2nd group + address = m.group(2); + return true; } private static void checkForError(String line) { @@ -103,28 +115,21 @@ } /* - * - pick a TCP port - * - Launch a server debuggee: server=y,suspend=y,address=${port} + * - Launch a server debuggee: server=y,suspend=y,address=0 + * - detect the port debuggee is listening on * - run it to VM death * - verify we saw no error */ public static void main(String args[]) throws Exception { - // find a free port - ServerSocket ss = new ServerSocket(0); - int port = ss.getLocalPort(); - ss.close(); - - String address = String.valueOf(port); - // launch the server debuggee - Process process = launch(address, "Exit0"); + Process process = launch("Exit0"); // attach to server debuggee and resume it so it can exit AttachingConnector conn = (AttachingConnector)findConnector("com.sun.jdi.SocketAttach"); Map conn_args = conn.defaultArguments(); Connector.IntegerArgument port_arg = (Connector.IntegerArgument)conn_args.get("port"); - port_arg.setValue(port); + port_arg.setValue(address); System.out.println("Connection arguments: " + conn_args); diff -r 268875216dfc -r faf96b92a47b test/jdk/com/sun/jdi/lib/jdb/JdbCommand.java --- a/test/jdk/com/sun/jdi/lib/jdb/JdbCommand.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/com/sun/jdi/lib/jdb/JdbCommand.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2019, 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 @@ -162,6 +162,9 @@ public static JdbCommand stopIn(String targetClass, String methodName) { return new JdbCommand("stop in " + targetClass + "." + methodName); } + public static JdbCommand stopInThreadid(String targetClass, String methodName, String threadid) { + return new JdbCommand("stop " + threadid + " in " + targetClass + "." + methodName); + } public static JdbCommand thread(int threadNumber) { return new JdbCommand("thread " + threadNumber); } @@ -226,6 +229,10 @@ return new JdbCommand("methods " + classId); } + public static JdbCommand threads() { + return new JdbCommand("threads"); + } + // trace [go] methods [thread] // -- trace method entries and exits. // -- All threads are suspended unless 'go' is specified diff -r 268875216dfc -r faf96b92a47b test/jdk/java/awt/print/RemotePrinterStatusRefresh/RemotePrinterStatusRefresh.java --- a/test/jdk/java/awt/print/RemotePrinterStatusRefresh/RemotePrinterStatusRefresh.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/java/awt/print/RemotePrinterStatusRefresh/RemotePrinterStatusRefresh.java Fri Mar 01 17:27:28 2019 +0530 @@ -23,7 +23,7 @@ /** * @test - * @bug 8153732 + * @bug 8153732 8212202 * @requires (os.family == "Windows") * @summary Windows remote printer changes do not reflect in lookupPrintServices() * @ignore Requires a new network printer installation\removal diff -r 268875216dfc -r faf96b92a47b test/jdk/java/lang/constant/ClassDescTest.java --- a/test/jdk/java/lang/constant/ClassDescTest.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/java/lang/constant/ClassDescTest.java Fri Mar 01 17:27:28 2019 +0530 @@ -176,6 +176,12 @@ } catch (IllegalArgumentException e) { // good } + try { + cr.arrayType(0); + fail(""); + } catch (IllegalArgumentException e) { + // good + } } public void testArrayClassDesc() throws ReflectiveOperationException { diff -r 268875216dfc -r faf96b92a47b test/jdk/java/lang/instrument/NamedBuffer.java --- a/test/jdk/java/lang/instrument/NamedBuffer.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/java/lang/instrument/NamedBuffer.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, 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 @@ -64,7 +64,7 @@ public static byte[] loadBufferFromStream(InputStream stream) throws IOException - { + { // hack for now, just assume the stream will fit in our reasonable size buffer. // if not, panic int bufferLimit = 200 * 1024; @@ -83,5 +83,60 @@ 0, actualSize); return resultBuffer; + } + + static final String DEST = System.getProperty("test.classes"); + static final boolean VERBOSE = false; + + static boolean checkMatch(byte[] buf, byte[] name, int begIdx) { + if (buf.length < name.length + begIdx) { + return false; } + for (int i = 0; i < name.length; i++) { + if (buf[i + begIdx] != name[i]) { + return false; + } + } + return true; + } + + // This function reads a class file from disk and replaces the first character of + // the name with the one passed as "replace". Then goes through the bytecodes to + // replace all instances of the name of the class with the new name. The + // redefinition tests use this to redefine Host$ classes with precompiled class files + // Xost.java, Yost.java and Zost.java. + static byte[] + bytesForHostClass(char replace, String className) throws Throwable { + String tail = className.substring(1); + String origClassName = "" + replace + tail; + File clsfile = new File(DEST + "/" + origClassName + ".class"); + + if (VERBOSE) { + System.out.println(" Reading bytes from " + clsfile); + } + byte[] buf = null; + try (FileInputStream str = new FileInputStream(clsfile)) { + buf = loadBufferFromStream(str); + } + + boolean found = false; + int dollarSignIdx = className.indexOf('$'); + int ptrnLen = (dollarSignIdx == -1) ? className.length() : dollarSignIdx; + byte[] ptrnBytes = origClassName.substring(0, ptrnLen).getBytes(); + byte firstByte = className.getBytes()[0]; + + for (int i = 0; i < buf.length - ptrnLen; i++) { + if (checkMatch(buf, ptrnBytes, i)) { + if (VERBOSE) { + System.out.println("Appear to have found " + origClassName + " starting at " + i); + } + buf[i] = firstByte; + found = true; + } + } + if (!found) { + throw new Error("Could not locate '" + ptrnBytes + "' name in byte array"); + } + return buf; + } } diff -r 268875216dfc -r faf96b92a47b test/jdk/java/lang/instrument/RedefineAddDeleteMethod/DeleteMethodHandle/MethodHandleDeletedMethod.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineAddDeleteMethod/DeleteMethodHandle/MethodHandleDeletedMethod.java Fri Mar 01 17:27:28 2019 +0530 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2019, 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 8181171 + * @summary Break ResolvedMethodTable with redefined nest class. + * @library /test/lib + * @modules java.base/jdk.internal.misc + * @modules java.compiler + * java.instrument + * jdk.jartool/sun.tools.jar + * @compile ../../NamedBuffer.java + * @compile redef/Xost.java + * @run main RedefineClassHelper + * @run main/othervm -javaagent:redefineagent.jar -Xlog:redefine+class+update*=debug,membername+table=debug MethodHandleDeletedMethod + */ + +import java.io.File; +import java.io.FileInputStream; +import java.lang.invoke.*; + +class Host { + static MethodHandle fooMH; + + static class A { + private static void foo() { System.out.println("OLD foo called"); } + } + static void bar() throws NoSuchMethodError { + A.foo(); + } + static void barMH() throws Throwable { + fooMH.invokeExact(); + } + + public static void reresolve() throws Throwable { + fooMH = MethodHandles.lookup().findStatic(A.class, "foo", MethodType.methodType(void.class)); + } + + static { + try { + fooMH = MethodHandles.lookup().findStatic(A.class, "foo", MethodType.methodType(void.class)); + } catch (ReflectiveOperationException ex) { + } + } +} + +public class MethodHandleDeletedMethod { + + static final String DEST = System.getProperty("test.classes"); + static final boolean VERBOSE = false; + + private static byte[] bytesForHostClass(char replace) throws Throwable { + return NamedBuffer.bytesForHostClass(replace, "Host$A"); + } + + public static void main(java.lang.String[] unused) throws Throwable { + Host h = new Host(); + h.bar(); + h.barMH(); + byte[] buf = bytesForHostClass('X'); + RedefineClassHelper.redefineClass(Host.A.class, buf); + try { + h.bar(); // call deleted Method directly + throw new RuntimeException("Failed, expected NSME"); + } catch (NoSuchMethodError nsme) { + System.out.println("Received expected NSME"); + } + try { + h.barMH(); // call through MethodHandle for deleted Method + throw new RuntimeException("Failed, expected NSME"); + } catch (NoSuchMethodError nsme) { + System.out.println("Received expected NSME"); + } + System.out.println("Passed."); + } +} diff -r 268875216dfc -r faf96b92a47b test/jdk/java/lang/instrument/RedefineAddDeleteMethod/DeleteMethodHandle/redef/Xost.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/instrument/RedefineAddDeleteMethod/DeleteMethodHandle/redef/Xost.java Fri Mar 01 17:27:28 2019 +0530 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2019, 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. + */ + +public class Xost { + // Remove static private methods, in A in redefinition. + static class A { } + // Removed public method to get this to compile, but we don't + // try to redefine Host. +} diff -r 268875216dfc -r faf96b92a47b test/jdk/java/nio/Buffer/Basic-X.java.template --- a/test/jdk/java/nio/Buffer/Basic-X.java.template Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/java/nio/Buffer/Basic-X.java.template Fri Mar 01 17:27:28 2019 +0530 @@ -648,7 +648,7 @@ } } - // Exceptions in absolute bulk operations + // Exceptions in absolute bulk and slice operations catchNullArgument(b, () -> b.get(7, null, 0, 42)); catchNullArgument(b, () -> b.put(7, ($type$[])null, 0, 42)); @@ -668,6 +668,11 @@ catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpa, 0, 1)); catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpa, 0, 42)); + catchIndexOutOfBounds(b, () -> b.slice(-1, 7)); + catchIndexOutOfBounds(b, () -> b.slice(b.limit() + 1, 7)); + catchIndexOutOfBounds(b, () -> b.slice(0, -1)); + catchIndexOutOfBounds(b, () -> b.slice(7, b.limit() - 7 + 1)); + // Values b.clear(); @@ -832,6 +837,20 @@ + sb.arrayOffset() + " != " + sb2.arrayOffset(), sb, sb2); } + int bPos = b.position(); + int bLim = b.limit(); + + b.position(7); + b.limit(42); + $Type$Buffer rsb = b.slice(); + b.position(0); + b.limit(b.capacity()); + $Type$Buffer asb = b.slice(7, 35); + checkSlice(rsb, asb); + + b.position(bPos); + b.limit(bLim); + #if[byte] // Views diff -r 268875216dfc -r faf96b92a47b test/jdk/java/nio/Buffer/Basic.java --- a/test/jdk/java/nio/Buffer/Basic.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/java/nio/Buffer/Basic.java Fri Mar 01 17:27:28 2019 +0530 @@ -25,8 +25,8 @@ * @summary Unit test for buffers * @bug 4413135 4414911 4416536 4416562 4418782 4471053 4472779 4490253 4523725 * 4526177 4463011 4660660 4661219 4663521 4782970 4804304 4938424 5029431 - * 6231529 6221101 6234263 6535542 6591971 6593946 6795561 7190219 7199551 - * 8065556 8149469 + * 5071718 6231529 6221101 6234263 6535542 6591971 6593946 6795561 7190219 + * 7199551 8065556 8149469 * @modules java.base/java.nio:open * java.base/jdk.internal.misc * @author Mark Reinhold diff -r 268875216dfc -r faf96b92a47b test/jdk/java/nio/Buffer/BasicByte.java --- a/test/jdk/java/nio/Buffer/BasicByte.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/java/nio/Buffer/BasicByte.java Fri Mar 01 17:27:28 2019 +0530 @@ -648,7 +648,7 @@ } } - // Exceptions in absolute bulk operations + // Exceptions in absolute bulk and slice operations catchNullArgument(b, () -> b.get(7, null, 0, 42)); catchNullArgument(b, () -> b.put(7, (byte[])null, 0, 42)); @@ -668,6 +668,11 @@ catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpa, 0, 1)); catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpa, 0, 42)); + catchIndexOutOfBounds(b, () -> b.slice(-1, 7)); + catchIndexOutOfBounds(b, () -> b.slice(b.limit() + 1, 7)); + catchIndexOutOfBounds(b, () -> b.slice(0, -1)); + catchIndexOutOfBounds(b, () -> b.slice(7, b.limit() - 7 + 1)); + // Values b.clear(); @@ -832,6 +837,20 @@ + sb.arrayOffset() + " != " + sb2.arrayOffset(), sb, sb2); } + int bPos = b.position(); + int bLim = b.limit(); + + b.position(7); + b.limit(42); + ByteBuffer rsb = b.slice(); + b.position(0); + b.limit(b.capacity()); + ByteBuffer asb = b.slice(7, 35); + checkSlice(rsb, asb); + + b.position(bPos); + b.limit(bLim); + // Views diff -r 268875216dfc -r faf96b92a47b test/jdk/java/nio/Buffer/BasicChar.java --- a/test/jdk/java/nio/Buffer/BasicChar.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/java/nio/Buffer/BasicChar.java Fri Mar 01 17:27:28 2019 +0530 @@ -648,7 +648,7 @@ } } - // Exceptions in absolute bulk operations + // Exceptions in absolute bulk and slice operations catchNullArgument(b, () -> b.get(7, null, 0, 42)); catchNullArgument(b, () -> b.put(7, (char[])null, 0, 42)); @@ -668,6 +668,11 @@ catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpa, 0, 1)); catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpa, 0, 42)); + catchIndexOutOfBounds(b, () -> b.slice(-1, 7)); + catchIndexOutOfBounds(b, () -> b.slice(b.limit() + 1, 7)); + catchIndexOutOfBounds(b, () -> b.slice(0, -1)); + catchIndexOutOfBounds(b, () -> b.slice(7, b.limit() - 7 + 1)); + // Values b.clear(); @@ -832,6 +837,20 @@ + sb.arrayOffset() + " != " + sb2.arrayOffset(), sb, sb2); } + int bPos = b.position(); + int bLim = b.limit(); + + b.position(7); + b.limit(42); + CharBuffer rsb = b.slice(); + b.position(0); + b.limit(b.capacity()); + CharBuffer asb = b.slice(7, 35); + checkSlice(rsb, asb); + + b.position(bPos); + b.limit(bLim); + diff -r 268875216dfc -r faf96b92a47b test/jdk/java/nio/Buffer/BasicDouble.java --- a/test/jdk/java/nio/Buffer/BasicDouble.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/java/nio/Buffer/BasicDouble.java Fri Mar 01 17:27:28 2019 +0530 @@ -648,7 +648,7 @@ } } - // Exceptions in absolute bulk operations + // Exceptions in absolute bulk and slice operations catchNullArgument(b, () -> b.get(7, null, 0, 42)); catchNullArgument(b, () -> b.put(7, (double[])null, 0, 42)); @@ -668,6 +668,11 @@ catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpa, 0, 1)); catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpa, 0, 42)); + catchIndexOutOfBounds(b, () -> b.slice(-1, 7)); + catchIndexOutOfBounds(b, () -> b.slice(b.limit() + 1, 7)); + catchIndexOutOfBounds(b, () -> b.slice(0, -1)); + catchIndexOutOfBounds(b, () -> b.slice(7, b.limit() - 7 + 1)); + // Values b.clear(); @@ -832,6 +837,20 @@ + sb.arrayOffset() + " != " + sb2.arrayOffset(), sb, sb2); } + int bPos = b.position(); + int bLim = b.limit(); + + b.position(7); + b.limit(42); + DoubleBuffer rsb = b.slice(); + b.position(0); + b.limit(b.capacity()); + DoubleBuffer asb = b.slice(7, 35); + checkSlice(rsb, asb); + + b.position(bPos); + b.limit(bLim); + diff -r 268875216dfc -r faf96b92a47b test/jdk/java/nio/Buffer/BasicFloat.java --- a/test/jdk/java/nio/Buffer/BasicFloat.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/java/nio/Buffer/BasicFloat.java Fri Mar 01 17:27:28 2019 +0530 @@ -648,7 +648,7 @@ } } - // Exceptions in absolute bulk operations + // Exceptions in absolute bulk and slice operations catchNullArgument(b, () -> b.get(7, null, 0, 42)); catchNullArgument(b, () -> b.put(7, (float[])null, 0, 42)); @@ -668,6 +668,11 @@ catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpa, 0, 1)); catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpa, 0, 42)); + catchIndexOutOfBounds(b, () -> b.slice(-1, 7)); + catchIndexOutOfBounds(b, () -> b.slice(b.limit() + 1, 7)); + catchIndexOutOfBounds(b, () -> b.slice(0, -1)); + catchIndexOutOfBounds(b, () -> b.slice(7, b.limit() - 7 + 1)); + // Values b.clear(); @@ -832,6 +837,20 @@ + sb.arrayOffset() + " != " + sb2.arrayOffset(), sb, sb2); } + int bPos = b.position(); + int bLim = b.limit(); + + b.position(7); + b.limit(42); + FloatBuffer rsb = b.slice(); + b.position(0); + b.limit(b.capacity()); + FloatBuffer asb = b.slice(7, 35); + checkSlice(rsb, asb); + + b.position(bPos); + b.limit(bLim); + diff -r 268875216dfc -r faf96b92a47b test/jdk/java/nio/Buffer/BasicInt.java --- a/test/jdk/java/nio/Buffer/BasicInt.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/java/nio/Buffer/BasicInt.java Fri Mar 01 17:27:28 2019 +0530 @@ -648,7 +648,7 @@ } } - // Exceptions in absolute bulk operations + // Exceptions in absolute bulk and slice operations catchNullArgument(b, () -> b.get(7, null, 0, 42)); catchNullArgument(b, () -> b.put(7, (int[])null, 0, 42)); @@ -668,6 +668,11 @@ catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpa, 0, 1)); catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpa, 0, 42)); + catchIndexOutOfBounds(b, () -> b.slice(-1, 7)); + catchIndexOutOfBounds(b, () -> b.slice(b.limit() + 1, 7)); + catchIndexOutOfBounds(b, () -> b.slice(0, -1)); + catchIndexOutOfBounds(b, () -> b.slice(7, b.limit() - 7 + 1)); + // Values b.clear(); @@ -832,6 +837,20 @@ + sb.arrayOffset() + " != " + sb2.arrayOffset(), sb, sb2); } + int bPos = b.position(); + int bLim = b.limit(); + + b.position(7); + b.limit(42); + IntBuffer rsb = b.slice(); + b.position(0); + b.limit(b.capacity()); + IntBuffer asb = b.slice(7, 35); + checkSlice(rsb, asb); + + b.position(bPos); + b.limit(bLim); + diff -r 268875216dfc -r faf96b92a47b test/jdk/java/nio/Buffer/BasicLong.java --- a/test/jdk/java/nio/Buffer/BasicLong.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/java/nio/Buffer/BasicLong.java Fri Mar 01 17:27:28 2019 +0530 @@ -648,7 +648,7 @@ } } - // Exceptions in absolute bulk operations + // Exceptions in absolute bulk and slice operations catchNullArgument(b, () -> b.get(7, null, 0, 42)); catchNullArgument(b, () -> b.put(7, (long[])null, 0, 42)); @@ -668,6 +668,11 @@ catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpa, 0, 1)); catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpa, 0, 42)); + catchIndexOutOfBounds(b, () -> b.slice(-1, 7)); + catchIndexOutOfBounds(b, () -> b.slice(b.limit() + 1, 7)); + catchIndexOutOfBounds(b, () -> b.slice(0, -1)); + catchIndexOutOfBounds(b, () -> b.slice(7, b.limit() - 7 + 1)); + // Values b.clear(); @@ -832,6 +837,20 @@ + sb.arrayOffset() + " != " + sb2.arrayOffset(), sb, sb2); } + int bPos = b.position(); + int bLim = b.limit(); + + b.position(7); + b.limit(42); + LongBuffer rsb = b.slice(); + b.position(0); + b.limit(b.capacity()); + LongBuffer asb = b.slice(7, 35); + checkSlice(rsb, asb); + + b.position(bPos); + b.limit(bLim); + diff -r 268875216dfc -r faf96b92a47b test/jdk/java/nio/Buffer/BasicShort.java --- a/test/jdk/java/nio/Buffer/BasicShort.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/java/nio/Buffer/BasicShort.java Fri Mar 01 17:27:28 2019 +0530 @@ -648,7 +648,7 @@ } } - // Exceptions in absolute bulk operations + // Exceptions in absolute bulk and slice operations catchNullArgument(b, () -> b.get(7, null, 0, 42)); catchNullArgument(b, () -> b.put(7, (short[])null, 0, 42)); @@ -668,6 +668,11 @@ catchIndexOutOfBounds(b, () -> b.put(b.limit(), tmpa, 0, 1)); catchIndexOutOfBounds(b, () -> b.put(b.limit() - 41, tmpa, 0, 42)); + catchIndexOutOfBounds(b, () -> b.slice(-1, 7)); + catchIndexOutOfBounds(b, () -> b.slice(b.limit() + 1, 7)); + catchIndexOutOfBounds(b, () -> b.slice(0, -1)); + catchIndexOutOfBounds(b, () -> b.slice(7, b.limit() - 7 + 1)); + // Values b.clear(); @@ -832,6 +837,20 @@ + sb.arrayOffset() + " != " + sb2.arrayOffset(), sb, sb2); } + int bPos = b.position(); + int bLim = b.limit(); + + b.position(7); + b.limit(42); + ShortBuffer rsb = b.slice(); + b.position(0); + b.limit(b.capacity()); + ShortBuffer asb = b.slice(7, 35); + checkSlice(rsb, asb); + + b.position(bPos); + b.limit(bLim); + diff -r 268875216dfc -r faf96b92a47b test/jdk/java/nio/Buffer/ByteBufferViews.java --- a/test/jdk/java/nio/Buffer/ByteBufferViews.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/java/nio/Buffer/ByteBufferViews.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, 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 @@ -64,6 +64,8 @@ size -> ByteBuffer.allocate(size).position(8).slice()), Map.entry("ByteBuffer.allocate(size).position(8).slice().duplicate()", size -> ByteBuffer.allocate(size).position(8).slice().duplicate()), + Map.entry("ByteBuffer.allocate(size).slice(8,size-8)", + size -> ByteBuffer.allocate(size).slice(8,size-8)), // Unaligned Map.entry("ByteBuffer.allocate(size).position(1)", size -> ByteBuffer.allocate(size).position(1)), @@ -71,6 +73,8 @@ size -> ByteBuffer.allocate(size).position(1).slice()), Map.entry("ByteBuffer.allocate(size).position(1).slice().duplicate()", size -> ByteBuffer.allocate(size).position(1).slice().duplicate()), + Map.entry("ByteBuffer.allocate(size).slice(1,size-1)", + size -> ByteBuffer.allocate(size).slice(1,size-1)), // Off-heap Map.entry("ByteBuffer.allocateDirect(size)", @@ -82,13 +86,17 @@ size -> ByteBuffer.allocateDirect(size).position(8).slice()), Map.entry("ByteBuffer.allocateDirect(size).position(8).slice().duplicate()", size -> ByteBuffer.allocateDirect(size).position(8).slice().duplicate()), + Map.entry("ByteBuffer.allocateDirect(size).slice(8,size-8)", + size -> ByteBuffer.allocateDirect(size).slice(8,size-8)), // Unaligned Map.entry("ByteBuffer.allocateDirect(size).position(1)", size -> ByteBuffer.allocateDirect(size).position(1)), Map.entry("ByteBuffer.allocateDirect(size).position(1).slice()", size -> ByteBuffer.allocateDirect(size).position(1).slice()), Map.entry("ByteBuffer.allocateDirect(size).position(1).slice().duplicate()", - size -> ByteBuffer.allocateDirect(size).position(1).slice().duplicate()) + size -> ByteBuffer.allocateDirect(size).position(1).slice().duplicate()), + Map.entry("ByteBuffer.allocateDirect(size).slice(1,size-1)", + size -> ByteBuffer.allocateDirect(size).slice(1,size-1)) ); // List of buffer byte order functions diff -r 268875216dfc -r faf96b92a47b test/jdk/java/nio/Buffer/StringCharBufferSliceTest.java --- a/test/jdk/java/nio/Buffer/StringCharBufferSliceTest.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/java/nio/Buffer/StringCharBufferSliceTest.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2019, 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 @@ -22,11 +22,14 @@ */ /* @test - * @bug 4997655 7000913 + * @bug 4997655 5071718 7000913 * @summary (bf) CharBuffer.slice() on wrapped CharSequence results in wrong position */ -import java.nio.*; +import java.nio.CharBuffer; +import java.nio.InvalidMarkException; +import java.util.function.BiConsumer; +import java.util.function.Consumer; public class StringCharBufferSliceTest { public static void main( String[] args) throws Exception { @@ -40,85 +43,114 @@ CharBuffer buff = CharBuffer.wrap(in); test(buff, buff.slice()); + test(buff, buff.slice(0, buff.remaining())); System.out.println( ">>> StringCharBufferSliceTest-main: testing with new position."); buff.position(2); test(buff, buff.slice()); + test(buff, buff.slice(2, buff.remaining())); System.out.println( ">>> StringCharBufferSliceTest-main: testing with non zero initial position."); buff = CharBuffer.wrap(in, 3, in.length()); test(buff, buff.slice()); + test(buff, buff.slice(0, buff.remaining())); System.out.println( ">>> StringCharBufferSliceTest-main: testing slice result with get()"); buff.position(4); buff.limit(7); - CharBuffer slice = buff.slice(); - for (int i = 0; i < 3; i++) { - if (slice.get() != buff.get()) { - throw new RuntimeException("Wrong characters in slice result."); + BiConsumer bitest = (b, s) -> { + for (int i = 0; i < 3; i++) { + if (s.get() != b.get()) { + throw new RuntimeException + ("Wrong characters in slice result."); + } } - } + }; + bitest.accept(buff, buff.slice()); + buff.position(4); + bitest.accept(buff, buff.slice(4, 3)); System.out.println( ">>> StringCharBufferSliceTest-main: testing slice result with get(int)"); buff.position(4); buff.limit(7); - slice = buff.slice(); - for (int i = 0; i < 3; i++) { - if (slice.get(i) != buff.get(4 + i)) { - throw new RuntimeException("Wrong characters in slice result."); + bitest = (b, s) -> { + for (int i = 0; i < 3; i++) { + if (s.get(i) != b.get(4 + i)) { + throw new RuntimeException + ("Wrong characters in slice result."); + } } - } + }; + bitest.accept(buff, buff.slice()); + buff.position(4); + bitest.accept(buff, buff.slice(4, 3)); System.out.println( ">>> StringCharBufferSliceTest-main: testing slice with result of slice"); buff.position(0); buff.limit(buff.capacity()); - slice = buff.slice(); - for (int i=0; i<4; i++) { - slice.position(i); - CharBuffer nextSlice = slice.slice(); - if (nextSlice.position() != 0) - throw new RuntimeException("New buffer's position should be zero"); - if (!nextSlice.equals(slice)) - throw new RuntimeException("New buffer should be equal"); - slice = nextSlice; - } + Consumer test = (s) -> { + for (int i=0; i<4; i++) { + s.position(i); + CharBuffer nextSlice = s.slice(); + if (nextSlice.position() != 0) + throw new RuntimeException + ("New buffer's position should be zero"); + if (!nextSlice.equals(s)) + throw new RuntimeException("New buffer should be equal"); + s = nextSlice; + } + }; + test.accept(buff.slice()); + test.accept(buff.slice(0, buff.capacity())); System.out.println( ">>> StringCharBufferSliceTest-main: testing toString."); buff.position(4); buff.limit(7); - slice = buff.slice(); - if (!slice.toString().equals("tes")) { - throw new RuntimeException("bad toString() after slice(): " + slice.toString()); - } + test = (s) -> { + if (!s.toString().equals("tes")) { + throw new RuntimeException + ("bad toString() after slice(): " + s.toString()); + } + }; + test.accept(buff.slice()); + test.accept(buff.slice(4, 3)); System.out.println( ">>> StringCharBufferSliceTest-main: testing subSequence."); buff.position(4); buff.limit(8); - slice = buff.slice(); - CharSequence subSeq = slice.subSequence(1, 3); - if (subSeq.charAt(0) != 'e' || subSeq.charAt(1) != 's') { - throw new RuntimeException("bad subSequence() after slice(): '" + subSeq + "'"); - } + test = (s) -> { + CharSequence subSeq = s.subSequence(1, 3); + if (subSeq.charAt(0) != 'e' || subSeq.charAt(1) != 's') { + throw new RuntimeException + ("bad subSequence() after slice(): '" + subSeq + "'"); + } + }; + test.accept(buff.slice()); + test.accept(buff.slice(4, 4)); System.out.println( ">>> StringCharBufferSliceTest-main: testing duplicate."); buff.position(4); buff.limit(8); - slice = buff.slice(); - CharBuffer dupe = slice.duplicate(); - if (dupe.charAt(0) != 't' || dupe.charAt(1) != 'e' - || dupe.charAt(2) != 's' || dupe.charAt(3) != 't') { - throw new RuntimeException("bad duplicate() after slice(): '" + dupe + "'"); - } + test = (s) -> { + CharBuffer dupe = s.duplicate(); + if (dupe.charAt(0) != 't' || dupe.charAt(1) != 'e' + || dupe.charAt(2) != 's' || dupe.charAt(3) != 't') { + throw new RuntimeException + ("bad duplicate() after slice(): '" + dupe + "'"); + } + }; + test.accept(buff.slice()); + test.accept(buff.slice(4, 4)); System.out.println(">>> StringCharBufferSliceTest-main: done!"); } diff -r 268875216dfc -r faf96b92a47b test/jdk/java/text/Format/DateFormat/TestDayPeriodWithSDF.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/text/Format/DateFormat/TestDayPeriodWithSDF.java Fri Mar 01 17:27:28 2019 +0530 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2019, 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 8209175 + * @summary Checks the 'B' character added in the CLDR date-time patterns is + * getting resolved with 'a' character (am/pm strings) for burmese locale. + * This test case assumes that the 'B' character is added in CLDRv33 update + * for burmese locale in the time patterns. Since it is not supported by + * SimpleDateFormat it is replaced with the 'a' while CLDR resource + * conversion. + * @modules jdk.localedata + * @run testng/othervm TestDayPeriodWithSDF + */ + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import static org.testng.Assert.*; + +import java.text.DateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Locale; + +public class TestDayPeriodWithSDF { + + private static final Locale BURMESE = new Locale("my"); + private static final DateFormat FORMAT_SHORT_BURMESE = DateFormat.getTimeInstance(DateFormat.SHORT, BURMESE); + private static final DateFormat FORMAT_MEDIUM_BURMESE = DateFormat.getTimeInstance(DateFormat.MEDIUM, BURMESE); + + private static final Date DATE_AM = new GregorianCalendar(2019, Calendar.FEBRUARY, 14, 10, 10, 10).getTime(); + private static final Date DATE_PM = new GregorianCalendar(2019, Calendar.FEBRUARY, 14, 12, 12, 12).getTime(); + + @DataProvider(name = "timePatternData") + Object[][] timePatternData() { + return new Object[][] { + {FORMAT_SHORT_BURMESE, DATE_AM, "\u1014\u1036\u1014\u1000\u103A \u1041\u1040:\u1041\u1040"}, + {FORMAT_SHORT_BURMESE, DATE_PM, "\u100A\u1014\u1031 \u1041\u1042:\u1041\u1042"}, + {FORMAT_MEDIUM_BURMESE, DATE_AM, "\u1014\u1036\u1014\u1000\u103A \u1041\u1040:\u1041\u1040:\u1041\u1040"}, + {FORMAT_MEDIUM_BURMESE, DATE_PM, "\u100A\u1014\u1031 \u1041\u1042:\u1041\u1042:\u1041\u1042"}, + }; + } + + @Test(dataProvider = "timePatternData") + public void testTimePattern(DateFormat format, Date date, String expected) { + String actual = format.format(date); + assertEquals(actual, expected); + } + +} diff -r 268875216dfc -r faf96b92a47b test/jdk/java/time/test/java/time/format/TestDayPeriodWithDTF.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/time/test/java/time/format/TestDayPeriodWithDTF.java Fri Mar 01 17:27:28 2019 +0530 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2019, 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 8209175 + * @summary Checks the 'B' character added in the CLDR date-time patterns is + * getting resolved with 'a' character (am/pm strings) for burmese locale. + * This test case assumes that the 'B' character is added in CLDRv33 update + * for burmese locale in the time patterns. Since it is not supported by + * DateTimeFormatter it is replaced with the 'a' while CLDR resource + * conversion. + * @modules jdk.localedata + */ +package test.java.time.format; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import static org.testng.Assert.*; + +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.time.format.FormatStyle; +import java.util.Locale; + +@Test +public class TestDayPeriodWithDTF { + + private static final Locale BURMESE = new Locale("my"); + + private static final DateTimeFormatter FORMAT_SHORT_BURMESE = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT).withLocale(BURMESE); + private static final DateTimeFormatter FORMAT_MEDIUM_BURMESE = DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM).withLocale(BURMESE); + + private static final LocalTime LOCAL_TIME_AM = LocalTime.of(10, 10, 10); + private static final LocalTime LOCAL_TIME_PM = LocalTime.of(12, 12, 12); + + @DataProvider(name = "timePatternData") + Object[][] timePatternData() { + return new Object[][] { + {FORMAT_SHORT_BURMESE, LOCAL_TIME_AM, "\u1014\u1036\u1014\u1000\u103A 10:10"}, + {FORMAT_SHORT_BURMESE, LOCAL_TIME_PM, "\u100A\u1014\u1031 12:12"}, + {FORMAT_MEDIUM_BURMESE, LOCAL_TIME_AM, "\u1014\u1036\u1014\u1000\u103A 10:10:10"}, + {FORMAT_MEDIUM_BURMESE, LOCAL_TIME_PM, "\u100A\u1014\u1031 12:12:12"}, + }; + } + + @Test(dataProvider = "timePatternData") + public void testTimePattern(DateTimeFormatter formatter, LocalTime time, String expected) { + String actual = formatter.format(time); + assertEquals(actual, expected); + } + +} diff -r 268875216dfc -r faf96b92a47b test/jdk/java/util/Calendar/JapaneseEraNameTest.java --- a/test/jdk/java/util/Calendar/JapaneseEraNameTest.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/java/util/Calendar/JapaneseEraNameTest.java Fri Mar 01 17:27:28 2019 +0530 @@ -23,7 +23,7 @@ /* * @test - * @bug 8202088 8207152 8217609 + * @bug 8202088 8207152 8217609 8219890 * @summary Test the localized Japanese new era name (May 1st. 2019-) * is retrieved no matter CLDR provider contains the name or not. * @modules jdk.localedata @@ -53,8 +53,10 @@ // type, locale, name { LONG, JAPAN, "\u5143\u53f7" }, // NewEra { LONG, US, "NewEra" }, + { LONG, CHINA, "NewEra" }, { SHORT, JAPAN, "\u5143\u53f7" }, { SHORT, US, "NewEra" }, + { SHORT, CHINA, "N" }, }; } diff -r 268875216dfc -r faf96b92a47b test/jdk/java/util/spi/ToolProviderTest.java --- a/test/jdk/java/util/spi/ToolProviderTest.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/java/util/spi/ToolProviderTest.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, 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 @@ -28,7 +28,6 @@ * @run main/othervm ToolProviderTest */ -import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.nio.file.Files; @@ -46,6 +45,10 @@ void run() throws Exception { initServices(); + System.out.println("Validate an NPE is thrown with null arguments"); + + testNullArgs(); + System.out.println("test without security manager present:"); test(); @@ -63,6 +66,33 @@ } } + private void testNullArgs() { + ToolProvider testProvider = ToolProvider.findFirst("test").get(); + + // out null check + expectNullPointerException(() -> testProvider.run(null, System.err)); + + // err null check + expectNullPointerException(() -> testProvider.run(System.out, null)); + + // args array null check + expectNullPointerException(() -> + testProvider.run(System.out, System.err, (String[]) null)); + + // args array elements null check + expectNullPointerException(() -> + testProvider.run(System.out, System.err, (String) null)); + } + + private static void expectNullPointerException(Runnable test) { + try { + test.run(); + throw new Error("NullPointerException not thrown"); + } catch (NullPointerException e) { + // expected + } + } + private void initServices() throws IOException { Path testClasses = Paths.get(System.getProperty("test.classes")); Path services = testClasses.resolve(Paths.get("META-INF", "services")); diff -r 268875216dfc -r faf96b92a47b test/jdk/javax/net/ssl/compatibility/Cert.java --- a/test/jdk/javax/net/ssl/compatibility/Cert.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/javax/net/ssl/compatibility/Cert.java Fri Mar 01 17:27:28 2019 +0530 @@ -33,134 +33,134 @@ // This certificate is generated by the below command: // openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:2048 \ // -pkeyopt rsa_keygen_pubexp:65537 -out key.pem - // openssl req -x509 -new -key key.pem \ + // openssl req -x509 -new -days 7300 -key key.pem \ // -subj "/CN=RSA-2048-SHA256" -sha256 -out cer.pem RSA_2048_SHA256( KeyAlgorithm.RSA, "-----BEGIN CERTIFICATE-----\n" + - "MIIDFTCCAf2gAwIBAgIUcCwtPduMIU144++G82mUEVNNK9kwDQYJKoZIhvcNAQEL\n" + - "BQAwGjEYMBYGA1UEAwwPUlNBLTIwNDgtU0hBMjU2MB4XDTE5MDExNjA2MDgzNVoX\n" + - "DTE5MDIxNTA2MDgzNVowGjEYMBYGA1UEAwwPUlNBLTIwNDgtU0hBMjU2MIIBIjAN\n" + - "BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAycT4Kd742lTlULVh5BcsZIG/AvVl\n" + - "4IVnCoKoE8EyAf+YB2f+pYTDtyPzxnIUUqJ1/1dRY1EyHKQWRv1/J6H9qrKl48Sx\n" + - "zgctOMN6zrCjPGx85MWRW7jOTi9/FNjCfmmGDzo7jjfhEeSzU56zyOMMka2UvKYa\n" + - "P7YSTfC6nT79uaQNj/fqSK98FDLypDcrMiwzJZ7UX4M4Yo33EtqT0wFJfHl/LHJT\n" + - "lmpQdn7dDCqZGviP59tfuGPO7/la18OiN8hU8cttEkAcW3k19kYNhhtfxqs1MtAZ\n" + - "xGlN3eeW4IfjitMerEUd5wHrACyC4TKuj5NO6Wk1vl8pINsdkUttv5pHbQIDAQAB\n" + - "o1MwUTAdBgNVHQ4EFgQUT6UTyQ2i4qOkx3AAPwWS6wdmgncwHwYDVR0jBBgwFoAU\n" + - "T6UTyQ2i4qOkx3AAPwWS6wdmgncwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B\n" + - "AQsFAAOCAQEAPa4ib8oo7vgOh1c/HBvynkzoZ/ci3hqQCArqHkTKQEFSpHeUz46j\n" + - "u+GBRV/bFvZWc+GR9BPedKZUyRzCy3lmWclsxXEnv1uz/PTGBRMtZpjaaveTHzXm\n" + - "VVIkMH+wTZsZ/EQiz2pHgPuAJdPTHlwIYOYo5jk/eZoTKGupBuce+gsn0ctSZQc/\n" + - "TyayRCvnbQQ9Q6VbcfbrWGAmnCa4VANGuk3uZFj2Hc87udJ+2R8WkyfgXtwypNtb\n" + - "1SrRuCqthfCFa4s+P0LlddVqp18gSvsiB+yA1RVZSlSD4GfJfrgtSsJu/ovqThr7\n" + - "+YTfrHCVl4gliXaVujl6tQHaFk23WbAMwg==\n" + + "MIIDFTCCAf2gAwIBAgIUe8nlNUPJa9Iy57Cy5JM49bCzWdkwDQYJKoZIhvcNAQEL\n" + + "BQAwGjEYMBYGA1UEAwwPUlNBLTIwNDgtU0hBMjU2MB4XDTE5MDIyNzA3NDkwMVoX\n" + + "DTM5MDIyMjA3NDkwMVowGjEYMBYGA1UEAwwPUlNBLTIwNDgtU0hBMjU2MIIBIjAN\n" + + "BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1Clo5Prh1AdHSdM7G85B6K20bjSn\n" + + "bydcWxa7vQDEgFid1Ne8XRbugv5i8I7kGv2sTl99fopHeJcXHJvQGg7KVPgZqH0Z\n" + + "S7ZImlT5f4FYFj8sKnM5wx2P2AxcbO8ktSox0qIgtsHsCd7SusczylqEvSUrcqEe\n" + + "V58LtoWH+trsWoSBDlHRew2eD6ZGyQTM8VFqbt9oF2XXW22JiuP+cSvb+p5qSCy5\n" + + "dGpdPCJpPB/9HpChZl/r+VsqpbHwUPEVu9/FG0SVjpcqvJojYrgglb1PvJxLqceN\n" + + "DPOirwxnnEdiu5j0xC6RhOkbcxTGtS0VgEEC1+HyY+KeauZJOrw2x1ZmxQIDAQAB\n" + + "o1MwUTAdBgNVHQ4EFgQUSSj0EFZWTSFr91nTUE2MrJdrJGowHwYDVR0jBBgwFoAU\n" + + "SSj0EFZWTSFr91nTUE2MrJdrJGowDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B\n" + + "AQsFAAOCAQEAW9uuS2ZpG1ytpNA0g20m29R/DVSnygdfp8r/xeaWgdol4H2syPzg\n" + + "xok3PLkxkSpBv6CgIPXBzy/iXSMlkX0mUKEO3aQnJ8MoZ5Tzu3Bkp2fTugRQuTRi\n" + + "iNWQjsMoupsrTXIZhJ64jkDCnlFADPAdvVqQV01yZcKW98sj3TyaT7TJuYX9mU+V\n" + + "OuICkS1LE5NssuyLodxpfqpjBMtVovSKZ57JvO36G6riftnjr3FBf8ukWFK2/UfP\n" + + "DaHyFQ+NewbjPy7N+taFlLHS7ELwZVQQ42t8JeHRuF5IVvlp1UjTgXC5NuhOBwQY\n" + + "2dXFFroT0vXetn7Fr51zENPP3/TGeaoQnw==\n" + "-----END CERTIFICATE-----", "308204be020100300d06092a864886f70d0101010500048204a8308204a40201" + - "000282010100c9c4f829def8da54e550b561e4172c6481bf02f565e085670a82" + - "a813c13201ff980767fea584c3b723f3c6721452a275ff57516351321ca41646" + - "fd7f27a1fdaab2a5e3c4b1ce072d38c37aceb0a33c6c7ce4c5915bb8ce4e2f7f" + - "14d8c27e69860f3a3b8e37e111e4b3539eb3c8e30c91ad94bca61a3fb6124df0" + - "ba9d3efdb9a40d8ff7ea48af7c1432f2a4372b322c33259ed45f8338628df712" + - "da93d301497c797f2c7253966a50767edd0c2a991af88fe7db5fb863ceeff95a" + - "d7c3a237c854f1cb6d12401c5b7935f6460d861b5fc6ab3532d019c4694ddde7" + - "96e087e38ad31eac451de701eb002c82e132ae8f934ee96935be5f2920db1d91" + - "4b6dbf9a476d0203010001028201006dba71df8b8438707cf9647b2529391a3b" + - "b95e69888b0ee197c4b09575b6b58183f35b2a1067e06c23e03a26e6487e53bf" + - "96840b8827c18db713ca5eb176165713aac5f0bd65b75f6f8457b03a3dbbe9a0" + - "0e662784034027230b7091e54c0c253cf8c554b5acf02739231ba6d87429ecbb" + - "c2acc98472eb988ecc81206d165d33147e03279e60f7fbf73d8f199895f627a3" + - "3cf0c2ef2bcbd096f2e08b2684ea675956da0d95e941afe081e8c79ddb003b50" + - "0f3b340978bce6821438ef25ddbf4fc9dba3f421dbf576f3099dbd4463dbcd2f" + - "da5a987067d00c5af85faa7aea6427f12a1c03c9b5155fc5b5d4da51b4e9f5bf" + - "34087e582728bcaf40b39b0938163d02818100e379b3e110ca339eb1491b95ca" + - "0e73359a167722250f161ff78fef35e22282af28e02da454d0dca6af65b9118b" + - "6e3efe9cabae5d85746b0c336e3d9002c0575afe370ae7a0294c01988d6fa098" + - "9c4a6fc0816addcef3e891f2e56289da5b1b7a1c743664bb8b30ed6028942f72" + - "74f25c075b0646b47fae6c3fc31b4bfd05b02302818100e31210ff848f5a73c6" + - "1a508be415845bb18dcf09688ad543e8b040d9399850801a322e631dc605ec3e" + - "d25695b4f66cb6a728a4e11ff211122c7d0de7de356337b344fca03176c2c370" + - "7fbcdec2433a6c75d7a7d57b761ad6a8c1c8faaf316e0f410643f667958fcfac" + - "c9960d860c73cec45d118517fe72c5939730d8482bdb2f0281807e1a5ab0bb29" + - "0ce2bd6f44de8debe2cc65466cf6bdca963e5474336d10968711e93c15b152df" + - "9262c93b40144cd26a13a5f0bab1d7a8c92b335bbabf19f75cb5f1d5bbb2da23" + - "eaa1bbdb3475b80474736d29917fb3199de542dd0cfa54d54aef2fd4f0ce78f5" + - "59c34e1a50c3d8d4a20288855a7e59d3aa731209ec18fd04693702818100c384" + - "54da8edb9878c384f901db1ca3e1081b20bfeb224fcbaf59c41cc6b8dde7cfa6" + - "91c68a666dc723b89d113ec6488965995b8ef4a0cc0e27fc6db2cee48d4ff2ae" + - "5e0fd94777202d87efaaa6fe9819b7c63f1f54b5371aca2841d3887239602d0f" + - "2609cedb3aff08ba72d7a62aa6b4cce38e2859a6a0507b6add85fd6eb5c50281" + - "8100c07809a53e9ec6769bf2d31ed767766078ff7020199869473c26a211a4b2" + - "9828618b69e6e29ed0f1d8d8cac2c61490c3f20d19c1ff067c5d291080c8e15b" + - "2ce267cd37f8b0c1afe9c070418b310b5641640805d3a75890ccf6d2bf0bea11" + - "d327323db5452cadc1a3bd17c20ab92b6f09d4216a03c7a03c6ffc72e51f51eb" + - "dfa4"), + "000282010100d42968e4fae1d4074749d33b1bce41e8adb46e34a76f275c5b16" + + "bbbd00c480589dd4d7bc5d16ee82fe62f08ee41afdac4e5f7d7e8a477897171c" + + "9bd01a0eca54f819a87d194bb6489a54f97f8158163f2c2a7339c31d8fd80c5c" + + "6cef24b52a31d2a220b6c1ec09ded2bac733ca5a84bd252b72a11e579f0bb685" + + "87fadaec5a84810e51d17b0d9e0fa646c904ccf1516a6edf681765d75b6d898a" + + "e3fe712bdbfa9e6a482cb9746a5d3c22693c1ffd1e90a1665febf95b2aa5b1f0" + + "50f115bbdfc51b44958e972abc9a2362b82095bd4fbc9c4ba9c78d0cf3a2af0c" + + "679c4762bb98f4c42e9184e91b7314c6b52d15804102d7e1f263e29e6ae6493a" + + "bc36c75666c502030100010282010028f1f4f47c16a93cde5d390ee746df2170" + + "a4a9c02fb01c008ef3cc37a5b646aed387083baa1b8adc6d0bdb3138849d006b" + + "ffb1d0820f590e8fbf4db2d3d496e7df19d4929017348ebe7a37cc8bc1dc4944" + + "d4cc781157db32eeefc7763fb756f55699438701d5f3f1b4e9a7182fad5880c8" + + "73a223c61f52ea87c72d7f14511906af61d7fa190b02854471d4bdb77dac34ef" + + "46a3af3f39dff1c8844cad7f74f9936fbcc22bed6b139f47dc215048ddf02f60" + + "a24703b292be106ea4f01ec0839466666d9c3dc8488b353dccdd5f90bd4b5bb9" + + "4493b7da219ec4962fe6a427f6d69e2764065212c5accdbed3aa36a18d540e55" + + "192e63db9f6bdfc90ec52b89714d0102818100f7c35a70ee7d6aabd7feb590f6" + + "30ce9c28299f3431ebcd3c89ec9424cf68c626ee4f6ff0748ffc0ad810a9f6dd" + + "2b203c8fa7f516483545822e6c963b9f6a1687aca663be061aadcca920b09699" + + "bd7d2e8973bafe9ef11e19a27c10befe3e8919c141d04e5aab2990cc061c6798" + + "5d3da742a3c8c62b68a8ccb4af21c1c935bdcd02818100db37101251d805b8d6" + + "12749d8780cce9e4ff8fc58313e4192fbf9018dc2a8875beff70ea2ebaa24058" + + "d3de6eab4be66b0bb81c04f0fa29bad0f787776ed2e6ab7b7d9814ce7721cadd" + + "cc3f500ddfd73ae9def4d92a79e4a1662da16dbfc52d60507308286cf592ed8b" + + "9911089c4ec7dba3fcd64926b55d137d41f6de454694d902818100af6b582077" + + "2ac318d2401bcb7c13886555a64a7b09115be98df9bbd5e827d58c00d4ab7bc2" + + "fba2c706bd9da9146491596f98ca553160ce4ae295ad349fa4dc38c94bb178fc" + + "176d9066faa72ca9c358db572462741e92b6ee0d75ebe15e5f66709ebcfb404e" + + "bfbb1932eaecb7885013f3d5a1e2e83419d0d1c6e7ec6da9096ccd0281810099" + + "81fc922797f3a1d4dec5a4ce8fc66effba6aae7034cca54a8785dbb2c96217ba" + + "315c9bd12f469172e2a2bfb2da8ab769547ae286f157a987cddea2270c2f15e4" + + "7b35b554439e79564a4207c83f7893bbd43277a4c408f370ff012d3e7e506142" + + "d4dae09c3477b83aea6c40305d069d6b3f91bb560ce8e9cdec1478dfe0263902" + + "818002b66c71380142c3e606bfc598b4060f6833ac80e16d08aea40f4837191d" + + "34a3c85b91c3043c6ebb2c651a7fbb89539f5621820f792a5279a947c51f47b7" + + "1b6051c5a81d2d1c30dfa1f93cb57af1d7ee7862e8d90e33bd5c80f14aa9471b" + + "a2ea7aacddbb44d1a5e60f5fac437ca50cd56e237936fd3e9d034efc3e3c6710" + + "4c08"), // This certificate is generated by the below command: // openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:2048 \ // -pkeyopt rsa_keygen_pubexp:65537 -out key.pem - // openssl req -x509 -new -key key.pem \ + // openssl req -x509 -new -days 7300 -key key.pem \ // -subj "/CN=EXAMPLE" -sha256 -out cer.pem EXAMPLE_RSA_2048_SHA256( KeyAlgorithm.RSA, "-----BEGIN CERTIFICATE-----\n" + - "MIIDBTCCAe2gAwIBAgIUfmLJ5eIbVUGXAzlZXtw08GQ6ppMwDQYJKoZIhvcNAQEL\n" + - "BQAwEjEQMA4GA1UEAwwHRVhBTVBMRTAeFw0xOTAxMTYwNjA4MzVaFw0xOTAyMTUw\n" + - "NjA4MzVaMBIxEDAOBgNVBAMMB0VYQU1QTEUwggEiMA0GCSqGSIb3DQEBAQUAA4IB\n" + - "DwAwggEKAoIBAQCp7IDXT8J9iDMVAuLMTZS9oDD83BDkL5INGdXk1esTzyqXFmV2\n" + - "d5zNTr4A8w+YstkR081zL4MyEvHyQF1IlWoniRMXTZNMYYtU8dI8h2Fl5etSIEsc\n" + - "ArsAp3QMcoqEu4F4T68KPU7z1M5kYKevGqPsO4GJwjoydSZMLZMrq09yEyXlnE9l\n" + - "pNhyfFbQIp86mtXkY9nP3hn7JX6KMZSwAHbp7FtFkGfMx+usMnsMan+Z7UyWJE3o\n" + - "2cf29Fr9lBdV24gWAymyJA3BAW60wEI2JPYzIZVNn4zxmlkWk5sr+m5rUCXMzsyp\n" + - "G+rPk7YSpPutmczPe1BEiFwkgk+E5gZsNESbAgMBAAGjUzBRMB0GA1UdDgQWBBRm\n" + - "mZ3V6rNvJyG5DdYt1yo/Eiz+AjAfBgNVHSMEGDAWgBRmmZ3V6rNvJyG5DdYt1yo/\n" + - "Eiz+AjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBNHOWMa7f8\n" + - "iXwhET/6Rpu0JILusRrJVGXl3JOHxDsibUPAeZ4KI7VEEBw6ln0bKAFaYg+Nh9Xh\n" + - "dMuPC6e5wrX2Z912ncexa7BXDQDS4VyuvEGpp7rWFNtKRfc75hKmcRz+blgdhw9m\n" + - "gF1VcW3vBIjAUjMllRuyPlyXThgOPwcBXGEIewvyLXWbkNDFIeqycwsQsw5JJcbA\n" + - "Fh4alzjapSvSM84VS79u/MxaNZAtKpaymMaM05A8vIp8iHDm4N4AhIwHLT1mrtFt\n" + - "8y+3p4W6vtA+SlFGz8fQw5ppoxvPeJyHZmSmGeorcBv9XXWHhJ0rGz8UbE76xE0B\n" + - "EwC7yAE/SiA7\n" + + "MIIDBTCCAe2gAwIBAgIUD+8I14TmOfEfxtD6hgnhhK8ARCAwDQYJKoZIhvcNAQEL\n" + + "BQAwEjEQMA4GA1UEAwwHRVhBTVBMRTAeFw0xOTAyMjcwODAzNDhaFw0zOTAyMjIw\n" + + "ODAzNDhaMBIxEDAOBgNVBAMMB0VYQU1QTEUwggEiMA0GCSqGSIb3DQEBAQUAA4IB\n" + + "DwAwggEKAoIBAQChKYq85df7kUnf35qAfxW/OnqCgn/5FNwlWAwHLlEiHpK+k7jD\n" + + "8S6LVbw55I/4J3lehIHcIapGdmqh9ijUc2aNxTJ33z+/TTu2n+KlWmGj0G7ovTXk\n" + + "TbWptdgk5ro8DCr8I8YcvwdLekwH4AkRL6jSyiqsqlGZYLIxDd4l0CwSt5orbu/y\n" + + "+2UtM4DEOEswrxdP9UAd+W0On4AWaFIEbfuFaLZXHadvKxidnaCmudOJry6NjFWn\n" + + "+3PmIWNhZJitD0gq8FG3pvY502fLqHX95pigWCkDtrDNiqReXgVvZFWPaSMs065y\n" + + "n2ClShbzTs8pqJp8oBde9Iwi3RKwkew8I2iJAgMBAAGjUzBRMB0GA1UdDgQWBBTL\n" + + "3w5XucuEre5nQiaKnqi4s7ldBjAfBgNVHSMEGDAWgBTL3w5XucuEre5nQiaKnqi4\n" + + "s7ldBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBo51E5U5H7\n" + + "kXkI1LaGDs35dOOtrPQQQ7DzhQACUDfyYB8/BBUlYHPegS2ca/l1mkD2P/GNyZbN\n" + + "r4eRoOujfU59gOwH4+MEs/4zUKicajTGUPCbJ56heipHunHzj+2nj3ok5PI0MoI1\n" + + "soQfRV1FshfWAni7E49L1QI/PQrQ2cPR/1dvkB06JCIn0GoTxd8E76VCJz576xnd\n" + + "XgjiadVbjMYDH9XJEy6eQT6vY5WeGOQC2XwSE3mS6G+Z9jlwIswa8RrKGtKqFGK1\n" + + "6yse9zfJv64X8tQwnrkatCx4shJwDUet6wJQzm0/NMPfquoxz7QHF2NsLlNky+fY\n" + + "fZjMnoO3J1nV\n" + "-----END CERTIFICATE-----", - "308204be020100300d06092a864886f70d0101010500048204a8308204a40201" + - "000282010100a9ec80d74fc27d88331502e2cc4d94bda030fcdc10e42f920d19" + - "d5e4d5eb13cf2a97166576779ccd4ebe00f30f98b2d911d3cd732f833212f1f2" + - "405d48956a278913174d934c618b54f1d23c876165e5eb52204b1c02bb00a774" + - "0c728a84bb81784faf0a3d4ef3d4ce6460a7af1aa3ec3b8189c23a3275264c2d" + - "932bab4f721325e59c4f65a4d8727c56d0229f3a9ad5e463d9cfde19fb257e8a" + - "3194b00076e9ec5b459067ccc7ebac327b0c6a7f99ed4c96244de8d9c7f6f45a" + - "fd941755db88160329b2240dc1016eb4c0423624f63321954d9f8cf19a591693" + - "9b2bfa6e6b5025cccecca91beacf93b612a4fbad99cccf7b5044885c24824f84" + - "e6066c34449b0203010001028201005842e1357557678eec4198ab274590e1e2" + - "282fdf3ae2db96b8395831b1af962d8048d438458da1a3bea7d0a46fd077ed6a" + - "66228c16fcc570b3bd8a132a1579fb2927026ea7f8ff9db8b496e81bc5ca80df" + - "775c10c76edfa55a555bf5cedf5ce9c60d55b532dd24a7bfc0c1b7b7ab55c3e9" + - "b0c25661963de573a22494853a11dce95ea31417d3c87c806ef74cb6c8b7190c" + - "cfcdc2d21e8a756061c9e6cf40bca95d5aa43fb990b9492250ec9a752151320c" + - "b30a64beb0e17d83ad9ea702afcd5d8d6b7bfe11031aa27d83652e8db864bdbc" + - "447aee6e973018f77155aa24e05d3b7f9e232096ff93e8e2b1361b6cdbd4edf8" + - "dd88b46b178b38c34fe0ea5fc40f9102818100db14d91a4e8a89cc95a7cc687f" + - "2f2f295bc8a945826b3da840f871161ce2062f980d45b50172e744a308c0972e" + - "6f3f028465e6a59b75c0687bc3db4b69f5a931b73e9dedc6b05d41f4c1dd0575" + - "8e0460efba9bbb98f1c6ae3f018e2fb967a085dc5290ba8487703e1aee05fd90" + - "3c17867130c5676b7b9567a6fd61e9be6d660902818100c68f0053c621d52d65" + - "4ec381775e1b8fbf15ad391a0ad478d5b46374ad3f7c417a2f425f285999b4e6" + - "1672614ec6b4bad54400ecbc9e92f35cdab590a8cff4c029146a9b101d53950f" + - "7dddaa45946bfcf2a4e86bcddfc141a2cc49969519a326c7e5b001912e151d86" + - "b17f5789f39513c3f660c3e41f169a7668b22c17241e8302818100b86d0a7e4c" + - "d3ef40dc530f8e8052b63ef8d729382c9c1ea17f6025c2d9b9a43f789ee3a986" + - "78b61b5fabc485004002291a4fb6247f8456df1e21388079c8a61006149e5a46" + - "42bd9f026e18a3b9dc3def64a010ed91c926da148c38a8104a1e25d1dd679cbc" + - "684fa2d884bb62438372c2689307fb11ce4d6d9e73fb730c2d8811028181008d" + - "fda14c4739d68a9a11d3397835321c7f976ec290df01c64f7caa4abbc1d487b6" + - "6aa95a072edbfe4333f623a403f1265270490102799bb8b0c42e66fe7188230a" + - "bd70e6e685324a3c43d40a79ab83f5e5470c765b49119870650a92c69908d528" + - "ca162d68b6bd9ed9bd80c506ffcbb1d0c715b7c02083377e49ac705f34132502" + - "8180100e20febd1a5af92fdfc36aaf47d1a771cb1484d79e2389d5e6f47dc773" + - "512edef82676f9f9d5a77aac2f01d66fe864d85abcce47e3d22491421f959c1e" + - "5545c16fc5c5f5550ced81485dc237d9df8753cd6031e431bd34425e81b1e193" + - "c51a6d2c8a7cc01028f47b7fb7d79b481facb76c4775ff997f2e63acb3ff429c" + - "47b3"), + "308204bd020100300d06092a864886f70d0101010500048204a7308204a30201" + + "000282010100a1298abce5d7fb9149dfdf9a807f15bf3a7a82827ff914dc2558" + + "0c072e51221e92be93b8c3f12e8b55bc39e48ff827795e8481dc21aa46766aa1" + + "f628d473668dc53277df3fbf4d3bb69fe2a55a61a3d06ee8bd35e44db5a9b5d8" + + "24e6ba3c0c2afc23c61cbf074b7a4c07e009112fa8d2ca2aacaa519960b2310d" + + "de25d02c12b79a2b6eeff2fb652d3380c4384b30af174ff5401df96d0e9f8016" + + "6852046dfb8568b6571da76f2b189d9da0a6b9d389af2e8d8c55a7fb73e62163" + + "616498ad0f482af051b7a6f639d367cba875fde698a0582903b6b0cd8aa45e5e" + + "056f64558f69232cd3ae729f60a54a16f34ecf29a89a7ca0175ef48c22dd12b0" + + "91ec3c236889020301000102820100655c9e60ce62b85b99ce0f71ba2db3fcd1" + + "07ea7baf8776823b8e940a142c7d3c23696fb97eab7b6db11fb07dbbbb0500c5" + + "dcab5c4b642feb1c87ff2d90e97fefdcbe303c9e7870580535ac33f9937d9783" + + "9a281ef41798114448cc74bd5f34fbf8177bebea8de8ffe33ff4bd5f2ccd8ebe" + + "0e7708ac47be54749bd7438b199d2f134b71efc513827f260c0f74f1fc32f45b" + + "e5d510844777fcd2a486bc02c080d120d1c32336000ece743ea755f79f60a44a" + + "5e619ceb1caa873d847715616874d13c2ff1fe9f9f81d8fc83e83fb035bce8d9" + + "ed8f5caa41626d323551311b1d8d8f06785e3700d45e4d771157b22826efe553" + + "7a5892ad3bf3f915ec25342a8c7a3d02818100d19c03d857442bbaedb41b741e" + + "8e93d295940fdfc455898463ad96b0089ee68d90b787848b7aed6bb735c7e4b9" + + "7b22e867000d8e4b4ede4b155c34fd88c10244917912c048d023757bd758a117" + + "764aa80434c5c9636ec125574667ffe01af856f4517d06b6831ad50f16b26bba" + + "67a7125e158988c98b817dbb0928efa00c3ed702818100c4d49f7f3bf36586aa" + + "519bf2841c459c1863e71c08a9111344e51fcf5ff4267420fd9ffc9f72288e44" + + "b56bdae4eaa669e5e350afe4b4402be4af54d5dbc8b5dc5f5b6bb79df4fd17a5" + + "225287947783b5327b5dedf02733fb534514cc05fde1dcfceb8b537ad3c163a8" + + "8f36a60e2fb17fa6d9a0f3fca444f349eed9f07823879f02818100a5e9eb753c" + + "261ec338d23e84dc8718e53036e195cacfb6294fc920a4b83e26da59799c5043" + + "238b789ead784b48b1fa40a0fefebbea4a44548454d730f4256a8921e906f9a2" + + "e8f59851ed741f16f63043ec0865a2720d41df2fc4f01f2ea1ca7ef1a6eae2fc" + + "66ac3f8750fceb9ec1db1203dce25f9ec0c93fdf6371beb31dde430281807852" + + "be59ea4d25504847f13c34948fdd176fe2f4d93a790cbd7e0f8f16ca4ac38cf3" + + "5e5cf11fb93917398c805896353ae164af8b8714c571cfaf7afded086a5c1812" + + "ebeb686d3e56b9051d4c726f091db8897fe7177aefa500c7672a3db370e245de" + + "bbe24160b784f3a2f0b65c4fbd831a7d498e3d70321243acf69fb0e18f630281" + + "8065f0a2f257f8bf1d57e3f1b72c9a664ca92630985ee5ba35438e57a1df67a6" + + "f6b380907f5b7f9bdd2ddc63385615c5ca3c0dcbedfdc3f18433160855824712" + + "eaaeb318774478427dfb58135715cf82730a743dd8448984450905c28a6a97a0" + + "5f4aaad616978c07c5957c4f1945073f333df4337557bd6b754953f71df7a03c" + + "ec"), // This certificate is generated by the below commands: // openssl genpkey -genparam -algorithm dsa -pkeyopt dsa_paramgen_bits:2048 \ @@ -275,106 +275,106 @@ // This certificate is generated by the below commands: // openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:P-256 \ // -pkeyopt ec_param_enc:named_curve -out key.pem - // openssl req -x509 -new -key key.pem \ + // openssl req -x509 -new -days 7300 -key key.pem \ // -subj "/CN=ECDSA-SECP256-SHA256" -sha256 -out cer.pem ECDSA_PRIME256V1_SHA256( KeyAlgorithm.EC, "-----BEGIN CERTIFICATE-----\n" + - "MIIBkzCCATmgAwIBAgIUXebzNfSMvdkNrc5175FM6dE/gxwwCgYIKoZIzj0EAwIw\n" + - "HzEdMBsGA1UEAwwURUNEU0EtU0VDUDI1Ni1TSEEyNTYwHhcNMTkwMTE2MDYwODQx\n" + - "WhcNMTkwMjE1MDYwODQxWjAfMR0wGwYDVQQDDBRFQ0RTQS1TRUNQMjU2LVNIQTI1\n" + - "NjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOp7VcLfpVc5ghO0HlYjwH+YSAf7\n" + - "zTShLeoY35PwqcoUgg9DBR4g7rM3xovOKxGZ5uORD8vo5l9L0+53f2+7YH+jUzBR\n" + - "MB0GA1UdDgQWBBSmW8/6KP8EJKBVlfmFkBSbVWTEWzAfBgNVHSMEGDAWgBSmW8/6\n" + - "KP8EJKBVlfmFkBSbVWTEWzAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0gA\n" + - "MEUCIQCtGdW3Xl5OzX7QiwtiT6pbIrm6eCUwN/vVoMfs3Yn5rgIgCbLidpdMpFrd\n" + - "HWB2/mVxQegLBCOIGMVPXrTat4A76As=\n" + + "MIIBkzCCATmgAwIBAgIUVW+Rj8muf1DO8yUB9NSEDkD8oYowCgYIKoZIzj0EAwIw\n" + + "HzEdMBsGA1UEAwwURUNEU0EtU0VDUDI1Ni1TSEEyNTYwHhcNMTkwMjI3MTEwNzA0\n" + + "WhcNMzkwMjIyMTEwNzA0WjAfMR0wGwYDVQQDDBRFQ0RTQS1TRUNQMjU2LVNIQTI1\n" + + "NjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJPHqflVA59hR/sBM64OOY2/PTTx\n" + + "kZZhKcVV8vEkWRWvDV2u2F+lbRQoEoe8bwfGgQgGJIdc+dz9/TVAaYlitaKjUzBR\n" + + "MB0GA1UdDgQWBBRS9gbMeeA7j7QdipPufKn3jI3hKTAfBgNVHSMEGDAWgBRS9gbM\n" + + "eeA7j7QdipPufKn3jI3hKTAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0gA\n" + + "MEUCIDH0b3EewcoZUeSo0c2pNSWGCeRlZI49dASDbZ3A0jdTAiEAy/dM9LwYvyLl\n" + + "yuWq4yTouCdzfQwR9QXg3ohRMhnASlg=\n" + "-----END CERTIFICATE-----", "308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02" + - "01010420aa9602d20de7ebfc2787a6e5ae20166d1e8d8bd29b4e5f046414bae8" + - "9a8e7eb9a14403420004ea7b55c2dfa557398213b41e5623c07f984807fbcd34" + - "a12dea18df93f0a9ca14820f43051e20eeb337c68bce2b1199e6e3910fcbe8e6" + - "5f4bd3ee777f6fbb607f"), + "01010420ae670b91bae99a9752f2b7e26ab9c0e98636f0b0040d78f2ea4081f8" + + "e57c72e0a1440342000493c7a9f955039f6147fb0133ae0e398dbf3d34f19196" + + "6129c555f2f1245915af0d5daed85fa56d14281287bc6f07c681080624875cf9" + + "dcfdfd3540698962b5a2"), // This certificate is generated by the below commands: // openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:P-256 \ // -pkeyopt ec_param_enc:named_curve -out key.pem - // openssl req -x509 -new -key key.pem \ + // openssl req -x509 -new -days 7300 -key key.pem \ // -subj "/CN=EXAMPLE" -sha256 -out cer.pem EXAMPLE_ECDSA_PRIME256V1_SHA256( KeyAlgorithm.EC, "-----BEGIN CERTIFICATE-----\n" + - "MIIBeTCCAR+gAwIBAgIUWZkzN4WOoj7HUYLoWtgy+ad/zjswCgYIKoZIzj0EAwIw\n" + - "EjEQMA4GA1UEAwwHRVhBTVBMRTAeFw0xOTAxMTYwNjA4NDFaFw0xOTAyMTUwNjA4\n" + - "NDFaMBIxEDAOBgNVBAMMB0VYQU1QTEUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC\n" + - "AAQMzWjRuN9r2/kcVYyHFpKduuYj2VFRXo81qd+EcyjnLZab5m9RqIYy6iDUvZk5\n" + - "w8wHeHGpMybPzNSEQ2mVY5Yvo1MwUTAdBgNVHQ4EFgQUUhVK37nQDP6OEW5w7XEb\n" + - "p8/sCxMwHwYDVR0jBBgwFoAUUhVK37nQDP6OEW5w7XEbp8/sCxMwDwYDVR0TAQH/\n" + - "BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiEA9B2e4TWZKMxS8/uyVjl6D+cyqsPU\n" + - "7/qATL5cTK1AIUACID8BPfcPE46ARCretiGWywVuQzAVKz1fkjwEwLmAo+2x\n" + + "MIIBeTCCAR+gAwIBAgIUH6kQ0NfopvszxUwZ58KhMicqgCwwCgYIKoZIzj0EAwIw\n" + + "EjEQMA4GA1UEAwwHRVhBTVBMRTAeFw0xOTAyMjcxMTA5MTJaFw0zOTAyMjIxMTA5\n" + + "MTJaMBIxEDAOBgNVBAMMB0VYQU1QTEUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC\n" + + "AASbW2bDwNxTHAzN7aW/OD/ywfa0A4bPKF3Qw4U4nLFBHhbbEmDrIkRWqU56UUDt\n" + + "fnTZnBCJtm4sH8o9D1D9UZVFo1MwUTAdBgNVHQ4EFgQUEEpzWKgPritmUQNEcQhz\n" + + "bB+5KuUwHwYDVR0jBBgwFoAUEEpzWKgPritmUQNEcQhzbB+5KuUwDwYDVR0TAQH/\n" + + "BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiBjeGB0oc6t2fWOaviIMfqRqta64nl6\n" + + "Gj8I/JfDH97P1wIhAJ5IC9cxVTiPL/QTxUxRRlTYUboL/+ck1XR9JbZjd/ar\n" + "-----END CERTIFICATE-----", "308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02" + - "01010420ed3600c6b62b351b48b4c61f37c46c45460ff599aa7f9c2d79635d0e" + - "147c23a3a144034200040ccd68d1b8df6bdbf91c558c8716929dbae623d95151" + - "5e8f35a9df847328e72d969be66f51a88632ea20d4bd9939c3cc077871a93326" + - "cfccd48443699563962f"), + "010104205dfd6695d259d4047433c0b4520bedcf95130c5c08ba149caddad70d" + + "b3b66c1ba144034200049b5b66c3c0dc531c0ccdeda5bf383ff2c1f6b40386cf" + + "285dd0c385389cb1411e16db1260eb224456a94e7a5140ed7e74d99c1089b66e" + + "2c1fca3d0f50fd519545"), // This certificate is generated by the below commands: // openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:P-256 \ // -pkeyopt ec_param_enc:named_curve -out key.pem // openssl req -new -key key.pem \ // -subj "/CN=EC-RSA-SECP256-SHA256" -sha256 -out csr.pem - // openssl x509 -req -CAcreateserial -in csr.pem -sha256 \ + // openssl x509 -req -CAcreateserial -days 7300 -in csr.pem -sha256 \ // -CA CA.cer -CAkey CA.key -out cer.pem // Actually the CA is RSA_2048_SHA256 EC_RSA_PRIME256V1_SHA256( KeyAlgorithm.EC, "-----BEGIN CERTIFICATE-----\n" + - "MIIB9TCB3gIUIpSnxoBfFOKeRdx52FvEKuk1uvYwDQYJKoZIhvcNAQELBQAwGjEY\n" + - "MBYGA1UEAwwPUlNBLTIwNDgtU0hBMjU2MB4XDTE5MDExNjA2MDg0NloXDTE5MDIx\n" + - "NTA2MDg0NlowIDEeMBwGA1UEAwwVRUMtUlNBLVNFQ1AyNTYtU0hBMjU2MFkwEwYH\n" + - "KoZIzj0CAQYIKoZIzj0DAQcDQgAETcLM10u7ehsxJQbX3ypbSRMz7ZDkFS/QsmPF\n" + - "04NSwiBncQPjtpaPSshVDJzigEDfACcwIdO0BH4Eh2oHcB6hDzANBgkqhkiG9w0B\n" + - "AQsFAAOCAQEAHg06hhIec3ctUh7pao53ZF3SVJ/Pty4rgQ3Hb5gNhZHrmYWldj6J\n" + - "UagMRtfX0fJwzIdY0kNTol38es+6XDTCdYsaDDw4Ix1yF/xoExu6PqJ49npMVxqB\n" + - "yeXwg8aDB9sbmeczZp0kWa1DiN3HgJGoA8HbPOUZbuetCVl2ME82ZPdKdLaHgjO/\n" + - "Af3/gjYGVR27YB5sVIXkq3wJ5wEF+EvePKQZqnHFLhjz0xIIyp7mU6NFr26TsNh0\n" + - "JYecs5S0ydhf41x9GS4p8KpqRcfAOX4z5DEBe+BjgSuprGZabflFCbZ/PQrtBmdp\n" + - "5+cg/cNcA3zEXnsAzLu2R/+73/h9v75g/Q==\n" + + "MIIB9TCB3gIUWuMp26pvpTFO08C+ev6W8ZRDwqAwDQYJKoZIhvcNAQELBQAwGjEY\n" + + "MBYGA1UEAwwPUlNBLTIwNDgtU0hBMjU2MB4XDTE5MDIyNzA3NTUwMFoXDTM5MDIy\n" + + "MjA3NTUwMFowIDEeMBwGA1UEAwwVRUMtUlNBLVNFQ1AyNTYtU0hBMjU2MFkwEwYH\n" + + "KoZIzj0CAQYIKoZIzj0DAQcDQgAEgCoIan3yAA4KVwAO4qrMFF1alcYFzywPHerI\n" + + "eje3eQVhFaTecnbm0rTJE66JF8HeNuefd61+v1FqWo95aJ1l9zANBgkqhkiG9w0B\n" + + "AQsFAAOCAQEAJIgHTHyPJ5X44JR5ee3N2sYA8C9KGf2YFq/yPQ+pYYIk2gNKqMTH\n" + + "IgHzEqpeb1KC8i+F57xD8qL76QZ7YGVueKoU0o2XYO8Fj4Kug9B48uYvw4J025Bf\n" + + "emxVzuDwgPNAeQwzfoR4NpMKV6TjA7c1VVNUwnse7jHyzqkQLlNors62U+O2MI/t\n" + + "4RM6PDLWuGm9eDZAtifxdjjME9efEXOVi2y/9YAr7hOJKn3r1ie1Txo1N3LXTsLg\n" + + "Y0GlCcOiDGD5So6jSn4hY2CyeeEtTOZkloT/2Slpz9MbLzlav8hqnNQDbuSCFnyn\n" + + "fQh6yysvdeRm6Yx8bNkA/pxz/Y21fXVWMg==\n" + "-----END CERTIFICATE-----", "308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02" + - "010104200ab17f2b70ba744b08564635ebfc535c60d43139e1c722cfb9c7152e" + - "9faad5b3a144034200044dc2ccd74bbb7a1b312506d7df2a5b491333ed90e415" + - "2fd0b263c5d38352c220677103e3b6968f4ac8550c9ce28040df00273021d3b4" + - "047e04876a07701ea10f"), + "0101042079433b715d94d8de6b423f55ef05c911613dc708339391339bef6ca3" + + "c14b419ca14403420004802a086a7df2000e0a57000ee2aacc145d5a95c605cf" + + "2c0f1deac87a37b779056115a4de7276e6d2b4c913ae8917c1de36e79f77ad7e" + + "bf516a5a8f79689d65"), // This certificate is generated by the below commands: // openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:P-256 \ // -pkeyopt ec_param_enc:named_curve -out key.pem // openssl req -new -key key.pem -subj "/CN=EXAMPLE" -sha256 -out csr.pem - // openssl x509 -req -CAcreateserial -in csr.pem -sha256 \ + // openssl x509 -req -CAcreateserial -days 7300 -in csr.pem -sha256 \ // -CA CA.cer -CAkey CA.key -out cer.pem // Actually the CA is EXAMPLE_RSA_2048_SHA256 EXAMPLE_EC_RSA_PRIME256V1_SHA256( KeyAlgorithm.EC, "-----BEGIN CERTIFICATE-----\n" + - "MIIB3zCByAIUbogHun+2LFxbX9B5fImITzFQVfIwDQYJKoZIhvcNAQELBQAwEjEQ\n" + - "MA4GA1UEAwwHRVhBTVBMRTAeFw0xOTAxMTYwNjA4NDZaFw0xOTAyMTUwNjA4NDZa\n" + - "MBIxEDAOBgNVBAMMB0VYQU1QTEUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASA\n" + - "pPapPXO0qJO7mDm9dTuSKdsxWatAaloJZnwenBFIY8krulHd8VPSGbERmxRBY/z2\n" + - "+MH8dwaC1t9DAFb+1qdWMA0GCSqGSIb3DQEBCwUAA4IBAQA3SfXMUFj7xCl7nR8L\n" + - "/6mf0La/q4O1pGKmVpy55aP7dZmY3xzaPtDFevdnMqb7tBTiLl0Y8OehMQW/8usb\n" + - "qtcYPekZJV5g1ezMhyB/AHecotfsrBS7l9r+IWYf/GUoQ8izC1srNXVrqDCt0cbB\n" + - "o7bc0lQFhI+rcMt1AzQtrNkVhX0dcBbLyhNJzgyAXatSB5R0/R3kTddUZfrOtOoC\n" + - "IXUZJRQ7hZKx7qi/U4+q246IuKSSp2SjFTU1QpeO4/Q06eJ3sbtx5Nd1Rfzlo2Jq\n" + - "uYi8szOupFC8xKCB+odMndHvh1QO/8E4e4r0mShkrnK3M/lKiwi67yl3Jk9uY9ls\n" + - "X5Q6\n" + + "MIIB3zCByAIUWm9wgVB1TgdT5lpGNNkWBzuclKQwDQYJKoZIhvcNAQELBQAwEjEQ\n" + + "MA4GA1UEAwwHRVhBTVBMRTAeFw0xOTAyMjcwODA0MTNaFw0zOTAyMjIwODA0MTNa\n" + + "MBIxEDAOBgNVBAMMB0VYQU1QTEUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASp\n" + + "6YAqTEEjuMlG+vKl8XPo2T2wgqY6t+j1R5ySC0YiGesfrwVLTM4V+Ey9PKHoEIVK\n" + + "kWNUF5Sb2JdrYIuzb5WdMA0GCSqGSIb3DQEBCwUAA4IBAQBPrIScxw5Nx4DhT5GL\n" + + "ngyNBOun0yAwqrxQ3LPheMuN7CH4qehFPDx8MHhmFFjEIDKVRbEEgxiCJAgca7qD\n" + + "uLCfESM8KU4bkV4Pjx7/OEQZ3AkQ0UwDvDr/DypPg7TLLyF979OQo+fEaqWKH8Q4\n" + + "8Ot8+VUFuwpYhHQlkoPnwFKIuCfDGwYmmHP2btlZ5qBuDDzdo1JVGF8pJ943cfA8\n" + + "zRBJGKw8MMJXlfk3yiDSKMji0106SFuGwFJfkrdUnZ+hpeJ7rrrqW7jwLIil8PKf\n" + + "Z41UjYM4Ut/6O5SFqueBsC6yxfzrJbd8UZ7ZkfagWMr/AXLK1Sm3ICSPHsQW30mH\n" + + "uX+T\n" + "-----END CERTIFICATE-----", "308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02" + - "01010420618ff6a884185b97322aaeab5f9fdf8a14ab18d0478565317b483db0" + - "0f3b5bf6a1440342000480a4f6a93d73b4a893bb9839bd753b9229db3159ab40" + - "6a5a09667c1e9c114863c92bba51ddf153d219b1119b144163fcf6f8c1fc7706" + - "82d6df430056fed6a756"); + "01010420f1f944e1fc4bd7013b157db5fed23b84a4a1cd3d1a22f40746353185" + + "c0d8684da14403420004a9e9802a4c4123b8c946faf2a5f173e8d93db082a63a" + + "b7e8f5479c920b462219eb1faf054b4cce15f84cbd3ca1e810854a9163541794" + + "9bd8976b608bb36f959d"); public final KeyAlgorithm keyAlgorithm; public final String certMaterials; diff -r 268875216dfc -r faf96b92a47b test/jdk/javax/swing/JEditorPane/TestBrowserBGColor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/javax/swing/JEditorPane/TestBrowserBGColor.java Fri Mar 01 17:27:28 2019 +0530 @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2019, 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 + * @key headful + * @bug 8213781 + * @summary Verify webpage background color renders correctly in JEditorPane + */ + +import java.awt.Toolkit; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.IOException; +import java.net.MalformedURLException; +import javax.swing.JDialog; +import javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; +import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; +import javax.swing.text.html.HTMLFrameHyperlinkEvent; +import javax.swing.text.html.HTMLDocument; +import java.awt.Color; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Robot; + +public class TestBrowserBGColor extends JFrame implements HyperlinkListener { + + private static TestBrowserBGColor b; + private static JEditorPane browser; + + public static void main(final String[] args) throws Exception { + Robot r = new Robot(); + SwingUtilities.invokeAndWait(() -> { + try { + b = new TestBrowserBGColor(); + } catch (Exception e) { + throw new RuntimeException(e); + } + b.setSize(Toolkit.getDefaultToolkit().getScreenSize()); + b.setVisible(true); + b.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); + b.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + b.dispose(); + b = null; + } + }); + }); + + r.waitForIdle(); + r.delay(500); + + SwingUtilities.invokeAndWait(() -> { + Insets insets = browser.getInsets(); + Point loc = browser.getLocationOnScreen(); + Color c = r.getPixelColor( loc.x + insets.left+100, + loc.y + insets.top + 100); + b.dispose(); + if (!c.equals(Color.WHITE)) { + throw new RuntimeException("webpage background color wrong"); + } + }); + } + + + String htmlDoc = " Title "; + + public TestBrowserBGColor() throws IOException, MalformedURLException { + browser = new JEditorPane("text/html", htmlDoc); + browser.setEditable(false); + browser.addHyperlinkListener(this); + JScrollPane scroll = new JScrollPane(browser); + getContentPane().add(scroll); + } + + public void hyperlinkUpdate(final HyperlinkEvent e) { + if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { + JEditorPane pane = (JEditorPane) e.getSource(); + if (e instanceof HTMLFrameHyperlinkEvent) { + HTMLFrameHyperlinkEvent evt = (HTMLFrameHyperlinkEvent) e; + HTMLDocument doc = (HTMLDocument) pane.getDocument(); + doc.processHTMLFrameHyperlinkEvent(evt); + } else { + try { + pane.setPage(e.getURL()); + } catch (Throwable t) { + t.printStackTrace(); + } + } + } + } +} diff -r 268875216dfc -r faf96b92a47b test/jdk/javax/swing/text/rtf/RTFReadBGColorTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/javax/swing/text/rtf/RTFReadBGColorTest.java Fri Mar 01 17:27:28 2019 +0530 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2019, 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 + * @key headful + * @bug 8219156 + * @summary Verify RTFEditorKit does not read background color + */ + +import java.awt.Color; +import java.awt.image.BufferedImage; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Enumeration; + +import javax.swing.JTextPane; +import javax.swing.SwingUtilities; +import javax.swing.JFrame; +import javax.swing.text.MutableAttributeSet; +import javax.swing.text.StyleConstants; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.StyledDocument; +import javax.swing.text.AttributeSet; +import javax.swing.text.rtf.RTFEditorKit; + +public class RTFReadBGColorTest { + static JTextPane text; + static String BGTEXT = "yellow_background\n"; + + public static void main(String[] a) throws Exception { + SwingUtilities.invokeAndWait(() -> { + JFrame f = new JFrame(); + f.setBounds(200, 600, 400, 300); + f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + text = new JTextPane(); + text.setEditorKit(new RTFEditorKit()); + + MutableAttributeSet attrBackground = new SimpleAttributeSet(); + StyleConstants.setBackground(attrBackground, Color.YELLOW); + + try { + text.getDocument().insertString(0, BGTEXT, attrBackground); + } catch (Exception e) { + throw new RuntimeException(e); + } + write(); + read(); + + f.getContentPane().add(text); + f.setVisible(true); + text.setCaretPosition(BGTEXT.length()+6); + StyledDocument style = text.getStyledDocument(); + AttributeSet oldSet = style.getCharacterElement(BGTEXT.length()+6).getAttributes(); + f.dispose(); + if (!style.getBackground(oldSet).equals(Color.YELLOW)) { + throw new RuntimeException("RTFEditorKit does not read background color"); + } + }); + } + + static void write() { + try (OutputStream o = Files.newOutputStream(Paths.get("test.rtf"))) { + text.getEditorKit().write(o, text.getDocument(), 0, 0); + } catch (Exception e2) { + throw new RuntimeException(e2); + } + } + + static void read() { + try (InputStream in = Files.newInputStream(Paths.get("test.rtf"))) { + text.getEditorKit().read(in, text.getDocument(), 0); + } catch (Exception e2) { + throw new RuntimeException(e2); + } + } +} + diff -r 268875216dfc -r faf96b92a47b test/jdk/jdk/jfr/event/runtime/TestSafepointEvents.java --- a/test/jdk/jdk/jfr/event/runtime/TestSafepointEvents.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/jdk/jfr/event/runtime/TestSafepointEvents.java Fri Mar 01 17:27:28 2019 +0530 @@ -55,7 +55,6 @@ static final String[] EVENT_NAMES = new String[] { EventNames.SafepointBegin, EventNames.SafepointStateSynchronization, - EventNames.SafepointWaitBlocked, EventNames.SafepointCleanup, EventNames.SafepointCleanupTask, EventNames.SafepointEnd diff -r 268875216dfc -r faf96b92a47b test/jdk/tools/jlink/IntegrationTest.java --- a/test/jdk/tools/jlink/IntegrationTest.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jdk/tools/jlink/IntegrationTest.java Fri Mar 01 17:27:28 2019 +0530 @@ -49,7 +49,7 @@ import jdk.tools.jlink.internal.Jlink.PluginsConfiguration; import jdk.tools.jlink.internal.PostProcessor; import jdk.tools.jlink.internal.plugins.DefaultCompressPlugin; -import jdk.tools.jlink.internal.plugins.StripDebugPlugin; +import jdk.tools.jlink.internal.plugins.DefaultStripDebugPlugin; import tests.Helper; import tests.JImageGenerator; @@ -168,7 +168,7 @@ //Strip debug { Map config1 = new HashMap<>(); - config1.put(StripDebugPlugin.NAME, ""); + config1.put(DefaultStripDebugPlugin.NAME, ""); Plugin strip = Jlink.newPlugin("strip-debug", config1, null); lst.add(strip); } diff -r 268875216dfc -r faf96b92a47b test/jdk/tools/jlink/plugins/StripDebugPluginTest.java --- a/test/jdk/tools/jlink/plugins/StripDebugPluginTest.java Mon Feb 25 15:15:46 2019 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2015, 2018, 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 - * @summary Test StripDebugPlugin - * @author Jean-Francois Denise - * @library ../../lib - * @build tests.* - * @modules java.base/jdk.internal.jimage - * jdk.jlink/jdk.tools.jlink.internal - * jdk.jlink/jdk.tools.jlink.internal.plugins - * jdk.jlink/jdk.tools.jlink.plugin - * jdk.jlink/jdk.tools.jimage - * jdk.jlink/jdk.tools.jmod - * jdk.jdeps/com.sun.tools.classfile - * jdk.compiler - * @run main StripDebugPluginTest - */ - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.stream.Stream; - -import com.sun.tools.classfile.Attribute; -import com.sun.tools.classfile.ClassFile; -import com.sun.tools.classfile.Code_attribute; -import com.sun.tools.classfile.ConstantPoolException; -import com.sun.tools.classfile.Method; -import java.util.HashMap; -import java.util.Map; -import jdk.tools.jlink.internal.ResourcePoolManager; -import jdk.tools.jlink.internal.plugins.StripDebugPlugin; -import jdk.tools.jlink.plugin.ResourcePoolEntry; -import jdk.tools.jlink.plugin.ResourcePool; -import jdk.tools.jlink.plugin.Plugin; -import tests.Helper; - -public class StripDebugPluginTest { - public static void main(String[] args) throws Exception { - new StripDebugPluginTest().test(); - } - - public void test() throws Exception { - Helper helper = Helper.newHelper(); - if (helper == null) { - // Skip test if the jmods directory is missing (e.g. exploded image) - System.err.println("Test not run, NO jmods directory"); - return; - } - - List classes = Arrays.asList("toto.Main", "toto.com.foo.bar.X"); - Path moduleFile = helper.generateModuleCompiledClasses( - helper.getJmodSrcDir(), helper.getJmodClassesDir(), "leaf1", classes); - Path moduleInfo = moduleFile.resolve("module-info.class"); - - // Classes have been compiled in debug. - List covered = new ArrayList<>(); - byte[] infoContent = Files.readAllBytes(moduleInfo); - try (Stream stream = Files.walk(moduleFile)) { - for (Iterator iterator = stream.iterator(); iterator.hasNext(); ) { - Path p = iterator.next(); - if (Files.isRegularFile(p) && p.toString().endsWith(".class")) { - byte[] content = Files.readAllBytes(p); - String path = "/" + helper.getJmodClassesDir().relativize(p).toString(); - String moduleInfoPath = path + "/module-info.class"; - check(path, content, moduleInfoPath, infoContent); - covered.add(p); - } - } - } - if (covered.isEmpty()) { - throw new AssertionError("No class to compress"); - } else { - System.err.println("removed debug attributes from " - + covered.size() + " classes"); - } - } - - private void check(String path, byte[] content, String infoPath, byte[] moduleInfo) throws Exception { - path = path.replace('\\', '/'); - StripDebugPlugin debug = new StripDebugPlugin(); - debug.configure(new HashMap<>()); - ResourcePoolEntry result1 = stripDebug(debug, ResourcePoolEntry.create(path,content), path, infoPath, moduleInfo); - - if (!path.endsWith("module-info.class")) { - if (result1.contentLength() >= content.length) { - throw new AssertionError("Class size not reduced, debug info not " - + "removed for " + path); - } - checkDebugAttributes(result1.contentBytes()); - } - - ResourcePoolEntry result2 = stripDebug(debug, result1, path, infoPath, moduleInfo); - if (result1.contentLength() != result2.contentLength()) { - throw new AssertionError("removing debug info twice reduces class size of " - + path); - } - checkDebugAttributes(result1.contentBytes()); - } - - private ResourcePoolEntry stripDebug(Plugin debug, ResourcePoolEntry classResource, - String path, String infoPath, byte[] moduleInfo) throws Exception { - ResourcePoolManager resources = new ResourcePoolManager(); - resources.add(classResource); - if (!path.endsWith("module-info.class")) { - ResourcePoolEntry res2 = ResourcePoolEntry.create(infoPath, moduleInfo); - resources.add(res2); - } - ResourcePoolManager results = new ResourcePoolManager(); - ResourcePool resPool = debug.transform(resources.resourcePool(), - results.resourcePoolBuilder()); - System.out.println(classResource.path()); - - return resPool.findEntry(classResource.path()).get(); - } - - private void checkDebugAttributes(byte[] strippedClassFile) throws IOException, ConstantPoolException { - ClassFile classFile = ClassFile.read(new ByteArrayInputStream(strippedClassFile)); - String[] debugAttributes = new String[]{ - Attribute.LineNumberTable, - Attribute.LocalVariableTable, - Attribute.LocalVariableTypeTable - }; - for (Method method : classFile.methods) { - String methodName = method.getName(classFile.constant_pool); - Code_attribute code = (Code_attribute) method.attributes.get(Attribute.Code); - for (String attr : debugAttributes) { - if (code.attributes.get(attr) != null) { - throw new AssertionError("Debug attribute was not removed: " + attr + - " from method " + classFile.getName() + "#" + methodName); - } - } - } - } -} diff -r 268875216dfc -r faf96b92a47b test/jdk/tools/jlink/plugins/StripJavaDebugAttributesPluginTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/tools/jlink/plugins/StripJavaDebugAttributesPluginTest.java Fri Mar 01 17:27:28 2019 +0530 @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2015, 2018, 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 + * @summary Test StripJavaDebugAttributesPlugin + * @author Jean-Francois Denise + * @library ../../lib + * @build tests.* + * @modules java.base/jdk.internal.jimage + * jdk.jlink/jdk.tools.jlink.internal + * jdk.jlink/jdk.tools.jlink.internal.plugins + * jdk.jlink/jdk.tools.jlink.plugin + * jdk.jlink/jdk.tools.jimage + * jdk.jlink/jdk.tools.jmod + * jdk.jdeps/com.sun.tools.classfile + * jdk.compiler + * @run main StripJavaDebugAttributesPluginTest + */ + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Stream; + +import com.sun.tools.classfile.Attribute; +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.Code_attribute; +import com.sun.tools.classfile.ConstantPoolException; +import com.sun.tools.classfile.Method; + +import jdk.tools.jlink.internal.ResourcePoolManager; +import jdk.tools.jlink.internal.plugins.StripJavaDebugAttributesPlugin; +import jdk.tools.jlink.plugin.Plugin; +import jdk.tools.jlink.plugin.ResourcePool; +import jdk.tools.jlink.plugin.ResourcePoolEntry; +import tests.Helper; + +public class StripJavaDebugAttributesPluginTest { + public static void main(String[] args) throws Exception { + new StripJavaDebugAttributesPluginTest().test(); + } + + public void test() throws Exception { + Helper helper = Helper.newHelper(); + if (helper == null) { + // Skip test if the jmods directory is missing (e.g. exploded image) + System.err.println("Test not run, NO jmods directory"); + return; + } + + List classes = Arrays.asList("toto.Main", "toto.com.foo.bar.X"); + Path moduleFile = helper.generateModuleCompiledClasses( + helper.getJmodSrcDir(), helper.getJmodClassesDir(), "leaf1", classes); + Path moduleInfo = moduleFile.resolve("module-info.class"); + + // Classes have been compiled in debug. + List covered = new ArrayList<>(); + byte[] infoContent = Files.readAllBytes(moduleInfo); + try (Stream stream = Files.walk(moduleFile)) { + for (Iterator iterator = stream.iterator(); iterator.hasNext(); ) { + Path p = iterator.next(); + if (Files.isRegularFile(p) && p.toString().endsWith(".class")) { + byte[] content = Files.readAllBytes(p); + String path = "/" + helper.getJmodClassesDir().relativize(p).toString(); + String moduleInfoPath = path + "/module-info.class"; + check(path, content, moduleInfoPath, infoContent); + covered.add(p); + } + } + } + if (covered.isEmpty()) { + throw new AssertionError("No class to compress"); + } else { + System.err.println("removed debug attributes from " + + covered.size() + " classes"); + } + } + + private void check(String path, byte[] content, String infoPath, byte[] moduleInfo) throws Exception { + path = path.replace('\\', '/'); + StripJavaDebugAttributesPlugin debug = new StripJavaDebugAttributesPlugin(); + debug.configure(new HashMap<>()); + ResourcePoolEntry result1 = stripDebug(debug, ResourcePoolEntry.create(path,content), path, infoPath, moduleInfo); + + if (!path.endsWith("module-info.class")) { + if (result1.contentLength() >= content.length) { + throw new AssertionError("Class size not reduced, debug info not " + + "removed for " + path); + } + checkDebugAttributes(result1.contentBytes()); + } + + ResourcePoolEntry result2 = stripDebug(debug, result1, path, infoPath, moduleInfo); + if (result1.contentLength() != result2.contentLength()) { + throw new AssertionError("removing debug info twice reduces class size of " + + path); + } + checkDebugAttributes(result1.contentBytes()); + } + + private ResourcePoolEntry stripDebug(Plugin debug, ResourcePoolEntry classResource, + String path, String infoPath, byte[] moduleInfo) throws Exception { + ResourcePoolManager resources = new ResourcePoolManager(); + resources.add(classResource); + if (!path.endsWith("module-info.class")) { + ResourcePoolEntry res2 = ResourcePoolEntry.create(infoPath, moduleInfo); + resources.add(res2); + } + ResourcePoolManager results = new ResourcePoolManager(); + ResourcePool resPool = debug.transform(resources.resourcePool(), + results.resourcePoolBuilder()); + System.out.println(classResource.path()); + + return resPool.findEntry(classResource.path()).get(); + } + + private void checkDebugAttributes(byte[] strippedClassFile) throws IOException, ConstantPoolException { + ClassFile classFile = ClassFile.read(new ByteArrayInputStream(strippedClassFile)); + String[] debugAttributes = new String[]{ + Attribute.LineNumberTable, + Attribute.LocalVariableTable, + Attribute.LocalVariableTypeTable + }; + for (Method method : classFile.methods) { + String methodName = method.getName(classFile.constant_pool); + Code_attribute code = (Code_attribute) method.attributes.get(Attribute.Code); + for (String attr : debugAttributes) { + if (code.attributes.get(attr) != null) { + throw new AssertionError("Debug attribute was not removed: " + attr + + " from method " + classFile.getName() + "#" + methodName); + } + } + } + } +} diff -r 268875216dfc -r faf96b92a47b test/jtreg-ext/requires/VMProps.java --- a/test/jtreg-ext/requires/VMProps.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/jtreg-ext/requires/VMProps.java Fri Mar 01 17:27:28 2019 +0530 @@ -37,6 +37,7 @@ import java.util.Properties; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -49,13 +50,31 @@ /** * The Class to be invoked by jtreg prior Test Suite execution to * collect information about VM. - * Do not use any API's that may not be available in all target VMs. + * Do not use any APIs that may not be available in all target VMs. * Properties set by this Class will be available in the @requires expressions. */ public class VMProps implements Callable> { + // value known to jtreg as an indicator of error state + private static final String ERROR_STATE = "__ERROR__"; private static final WhiteBox WB = WhiteBox.getWhiteBox(); + private static class SafeMap { + private final Map map = new HashMap<>(); + + public void put(String key, Supplier s) { + String value; + try { + value = s.get(); + } catch (Throwable t) { + System.err.println("failed to get value for " + key); + t.printStackTrace(System.err); + value = ERROR_STATE + t; + } + map.put(key, value); + } + } + /** * Collects information about VM properties. * This method will be invoked by jtreg. @@ -64,58 +83,58 @@ */ @Override public Map call() { - Map map = new HashMap<>(); - map.put("vm.flavor", vmFlavor()); - map.put("vm.compMode", vmCompMode()); - map.put("vm.bits", vmBits()); - map.put("vm.flightRecorder", vmFlightRecorder()); - map.put("vm.simpleArch", vmArch()); - map.put("vm.debug", vmDebug()); - map.put("vm.jvmci", vmJvmci()); - map.put("vm.emulatedClient", vmEmulatedClient()); + SafeMap map = new SafeMap(); + map.put("vm.flavor", this::vmFlavor); + map.put("vm.compMode", this::vmCompMode); + map.put("vm.bits", this::vmBits); + map.put("vm.flightRecorder", this::vmFlightRecorder); + map.put("vm.simpleArch", this::vmArch); + map.put("vm.debug", this::vmDebug); + map.put("vm.jvmci", this::vmJvmci); + map.put("vm.emulatedClient", this::vmEmulatedClient); // vm.hasSA is "true" if the VM contains the serviceability agent // and jhsdb. - map.put("vm.hasSA", vmHasSA()); + map.put("vm.hasSA", this::vmHasSA); // vm.hasSAandCanAttach is "true" if the VM contains the serviceability agent // and jhsdb and it can attach to the VM. - map.put("vm.hasSAandCanAttach", vmHasSAandCanAttach()); + map.put("vm.hasSAandCanAttach", this::vmHasSAandCanAttach); // vm.hasJFR is "true" if JFR is included in the build of the VM and // so tests can be executed. - map.put("vm.hasJFR", vmHasJFR()); - map.put("vm.cpu.features", cpuFeatures()); - map.put("vm.rtm.cpu", vmRTMCPU()); - map.put("vm.rtm.compiler", vmRTMCompiler()); - map.put("vm.aot", vmAOT()); - map.put("vm.aot.enabled", vmAotEnabled()); + map.put("vm.hasJFR", this::vmHasJFR); + map.put("vm.cpu.features", this::cpuFeatures); + map.put("vm.rtm.cpu", this::vmRTMCPU); + map.put("vm.rtm.compiler", this::vmRTMCompiler); + map.put("vm.aot", this::vmAOT); + map.put("vm.aot.enabled", this::vmAotEnabled); // vm.cds is true if the VM is compiled with cds support. - map.put("vm.cds", vmCDS()); - map.put("vm.cds.custom.loaders", vmCDSForCustomLoaders()); - map.put("vm.cds.archived.java.heap", vmCDSForArchivedJavaHeap()); + map.put("vm.cds", this::vmCDS); + map.put("vm.cds.custom.loaders", this::vmCDSForCustomLoaders); + map.put("vm.cds.archived.java.heap", this::vmCDSForArchivedJavaHeap); // vm.graal.enabled is true if Graal is used as JIT - map.put("vm.graal.enabled", isGraalEnabled()); - map.put("vm.compiler1.enabled", isCompiler1Enabled()); - map.put("vm.compiler2.enabled", isCompiler2Enabled()); - map.put("docker.support", dockerSupport()); - map.put("release.implementor", implementor()); - map.put("test.vm.gc.nvdimm", isNvdimmTestEnabled()); + map.put("vm.graal.enabled", this::isGraalEnabled); + map.put("vm.compiler1.enabled", this::isCompiler1Enabled); + map.put("vm.compiler2.enabled", this::isCompiler2Enabled); + map.put("docker.support", this::dockerSupport); + map.put("release.implementor", this::implementor); + map.put("test.vm.gc.nvdimm", this::isNvdimmTestEnabled); vmGC(map); // vm.gc.X = true/false vmOptFinalFlags(map); - VMProps.dump(map); - return map; + dump(map.map); + return map.map; } /** - * Prints a stack trace before returning null. + * Print a stack trace before returning error state; * Used by the various helper functions which parse information from * VM properties in the case where they don't find an expected property - * or a propoerty doesn't conform to an expected format. + * or a property doesn't conform to an expected format. * - * @return null + * @return {@link #ERROR_STATE} */ - private String nullWithException(String message) { + private String errorWithMessage(String message) { new Exception(message).printStackTrace(); - return null; + return ERROR_STATE + message; } /** @@ -125,8 +144,7 @@ String arch = System.getProperty("os.arch"); if (arch.equals("x86_64") || arch.equals("amd64")) { return "x64"; - } - else if (arch.contains("86")) { + } else if (arch.contains("86")) { return "x86"; } else { return arch; @@ -140,7 +158,7 @@ // E.g. "Java HotSpot(TM) 64-Bit Server VM" String vmName = System.getProperty("java.vm.name"); if (vmName == null) { - return nullWithException("Can't get 'java.vm.name' property"); + return errorWithMessage("Can't get 'java.vm.name' property"); } Pattern startP = Pattern.compile(".* (\\S+) VM"); @@ -148,7 +166,7 @@ if (m.matches()) { return m.group(1).toLowerCase(); } - return nullWithException("Can't get VM flavor from 'java.vm.name'"); + return errorWithMessage("Can't get VM flavor from 'java.vm.name'"); } /** @@ -158,16 +176,17 @@ // E.g. "mixed mode" String vmInfo = System.getProperty("java.vm.info"); if (vmInfo == null) { - return nullWithException("Can't get 'java.vm.info' property"); + return errorWithMessage("Can't get 'java.vm.info' property"); } - if (vmInfo.toLowerCase().indexOf("mixed mode") != -1) { + vmInfo = vmInfo.toLowerCase(); + if (vmInfo.contains("mixed mode")) { return "Xmixed"; - } else if (vmInfo.toLowerCase().indexOf("compiled mode") != -1) { + } else if (vmInfo.contains("compiled mode")) { return "Xcomp"; - } else if (vmInfo.toLowerCase().indexOf("interpreted mode") != -1) { + } else if (vmInfo.contains("interpreted mode")) { return "Xint"; } else { - return nullWithException("Can't get compilation mode from 'java.vm.info'"); + return errorWithMessage("Can't get compilation mode from 'java.vm.info'"); } } @@ -179,7 +198,7 @@ if (dataModel != null) { return dataModel; } else { - return nullWithException("Can't get 'sun.arch.data.model' property"); + return errorWithMessage("Can't get 'sun.arch.data.model' property"); } } @@ -206,7 +225,7 @@ if (debug != null) { return "" + debug.contains("debug"); } else { - return nullWithException("Can't get 'jdk.debug' property"); + return errorWithMessage("Can't get 'jdk.debug' property"); } } @@ -224,7 +243,7 @@ protected String vmEmulatedClient() { String vmInfo = System.getProperty("java.vm.info"); if (vmInfo == null) { - return "false"; + return errorWithMessage("Can't get 'java.vm.info' property"); } return "" + vmInfo.contains(" emulated-client"); } @@ -241,30 +260,34 @@ * Example vm.gc.G1=true means: * VM supports G1 * User either set G1 explicitely (-XX:+UseG1GC) or did not set any GC + * * @param map - property-value pairs */ - protected void vmGC(Map map) { + protected void vmGC(SafeMap map) { for (GC gc: GC.values()) { - boolean isAcceptable = gc.isSupported() && (gc.isSelected() || GC.isSelectedErgonomically()); - map.put("vm.gc." + gc.name(), "" + isAcceptable); + map.put("vm.gc." + gc.name(), + () -> "" + (gc.isSupported() + && (gc.isSelected() || GC.isSelectedErgonomically()))); } } /** * Selected final flag. + * * @param map - property-value pairs * @param flagName - flag name */ - private void vmOptFinalFlag(Map map, String flagName) { - String value = String.valueOf(WB.getBooleanVMFlag(flagName)); - map.put("vm.opt.final." + flagName, value); + private void vmOptFinalFlag(SafeMap map, String flagName) { + map.put("vm.opt.final." + flagName, + () -> String.valueOf(WB.getBooleanVMFlag(flagName))); } /** * Selected sets of final flags. + * * @param map - property-value pairs */ - protected void vmOptFinalFlags(Map map) { + protected void vmOptFinalFlags(SafeMap map) { vmOptFinalFlag(map, "ClassUnloading"); vmOptFinalFlag(map, "UseCompressedOops"); vmOptFinalFlag(map, "EnableJVMCI"); @@ -286,10 +309,8 @@ try { return "" + Platform.shouldSAAttach(); } catch (IOException e) { - System.out.println("Checking whether SA can attach to the VM failed."); e.printStackTrace(); - // Run the tests anyways. - return "true"; + return errorWithMessage("Checking whether SA can attach to the VM failed.:" + e); } } @@ -350,11 +371,7 @@ * @return true if CDS is supported by the VM to be tested. */ protected String vmCDS() { - if (WB.isCDSIncludedInVmBuild()) { - return "true"; - } else { - return "false"; - } + return "" + WB.isCDSIncludedInVmBuild(); } /** @@ -363,11 +380,7 @@ * @return true if CDS provides support for customer loader in the VM to be tested. */ protected String vmCDSForCustomLoaders() { - if (vmCDS().equals("true") && Platform.areCustomLoadersSupportedForCDS()) { - return "true"; - } else { - return "false"; - } + return "" + ("true".equals(vmCDS()) && Platform.areCustomLoadersSupportedForCDS()); } /** @@ -376,11 +389,7 @@ * @return true if CDS provides support for archive Java heap regions in the VM to be tested. */ protected String vmCDSForArchivedJavaHeap() { - if (vmCDS().equals("true") && WB.isJavaHeapArchiveSupported()) { - return "true"; - } else { - return "false"; - } + return "" + ("true".equals(vmCDS()) && WB.isJavaHeapArchiveSupported()); } /** @@ -389,7 +398,7 @@ * @return true if Graal is used as JIT compiler. */ protected String isGraalEnabled() { - return Compiler.isGraalEnabled() ? "true" : "false"; + return "" + Compiler.isGraalEnabled(); } /** @@ -398,7 +407,7 @@ * @return true if Compiler1 is used as JIT compiler, either alone or as part of the tiered system. */ protected String isCompiler1Enabled() { - return Compiler.isC1Enabled() ? "true" : "false"; + return "" + Compiler.isC1Enabled(); } /** @@ -407,7 +416,7 @@ * @return true if Compiler2 is used as JIT compiler, either alone or as part of the tiered system. */ protected String isCompiler2Enabled() { - return Compiler.isC2Enabled() ? "true" : "false"; + return "" + Compiler.isC2Enabled(); } /** @@ -425,14 +434,11 @@ if (Platform.isX64()) { isSupported = true; - } - else if (Platform.isAArch64()) { + } else if (Platform.isAArch64()) { isSupported = true; - } - else if (Platform.isS390x()) { + } else if (Platform.isS390x()) { isSupported = true; - } - else if (arch.equals("ppc64le")) { + } else if (arch.equals("ppc64le")) { isSupported = true; } } @@ -445,7 +451,7 @@ } } - return (isSupported) ? "true" : "false"; + return "" + isSupported; } private boolean checkDockerSupport() throws IOException, InterruptedException { @@ -456,30 +462,27 @@ return (p.exitValue() == 0); } - private String implementor() { try (InputStream in = new BufferedInputStream(new FileInputStream( System.getProperty("java.home") + "/release"))) { Properties properties = new Properties(); properties.load(in); String implementorProperty = properties.getProperty("IMPLEMENTOR"); - return (implementorProperty == null) ? "null" : implementorProperty.replace("\"", ""); + if (implementorProperty != null) { + return implementorProperty.replace("\"", ""); + } + return errorWithMessage("Can't get 'IMPLEMENTOR' property from 'release' file"); } catch (IOException e) { e.printStackTrace(); + return errorWithMessage("Failed to read 'release' file " + e); } - return null; } private String isNvdimmTestEnabled() { - String isEnbled = System.getenv("TEST_VM_GC_NVDIMM"); - if (isEnbled != null && isEnbled.toLowerCase().equals("true")) { - return "true"; - } - return "false"; + String isEnabled = System.getenv("TEST_VM_GC_NVDIMM"); + return "" + "true".equalsIgnoreCase(isEnabled); } - - /** * Dumps the map to the file if the file name is given as the property. * This functionality could be helpful to know context in the real @@ -495,7 +498,8 @@ List lines = new ArrayList<>(); map.forEach((k, v) -> lines.add(k + ":" + v)); try { - Files.write(Paths.get(dumpFileName), lines, StandardOpenOption.APPEND); + Files.write(Paths.get(dumpFileName), lines, + StandardOpenOption.APPEND, StandardOpenOption.CREATE); } catch (IOException e) { throw new RuntimeException("Failed to dump properties into '" + dumpFileName + "'", e); @@ -504,6 +508,7 @@ /** * This method is for the testing purpose only. + * * @param args */ public static void main(String args[]) { diff -r 268875216dfc -r faf96b92a47b test/langtools/tools/javac/processing/model/completionfailure/SymbolsDontCumulate.java --- a/test/langtools/tools/javac/processing/model/completionfailure/SymbolsDontCumulate.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/langtools/tools/javac/processing/model/completionfailure/SymbolsDontCumulate.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, 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 @@ -24,25 +24,31 @@ /* * @test * @bug 8209055 - * @summary Verify that speculative symbols are not unnecesarily retained in + * @summary Verify that speculative symbols are not unnecessarily retained in * the DeferredCompletionFailureHandler * @library /tools/javac/lib /tools/lib * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.code:+open + * jdk.compiler/com.sun.tools.javac.main * @run main SymbolsDontCumulate */ import java.lang.reflect.Field; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Objects; import javax.tools.JavaCompiler; import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; -import toolbox.*; import com.sun.tools.javac.api.JavacTaskImpl; import com.sun.tools.javac.code.DeferredCompletionFailureHandler; +import toolbox.ToolBox; + public class SymbolsDontCumulate { ToolBox tb = new ToolBox(); @@ -65,7 +71,7 @@ DeferredCompletionFailureHandler h = DeferredCompletionFailureHandler.instance(((JavacTaskImpl) task).getContext()); Field class2Flip = h.userCodeHandler.getClass().getDeclaredField("class2Flip"); class2Flip.setAccessible(true); - int size = ((Map) class2Flip.get(h.userCodeHandler)).size(); + int size = ((Map) class2Flip.get(h.userCodeHandler)).size(); assertEquals(0, size); } } diff -r 268875216dfc -r faf96b92a47b test/lib/jdk/test/lib/Utils.java --- a/test/lib/jdk/test/lib/Utils.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/lib/jdk/test/lib/Utils.java Fri Mar 01 17:27:28 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, 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 @@ -88,6 +88,11 @@ */ public static final String TEST_SRC = System.getProperty("test.src", "").trim(); + /** + * Returns the value of 'test.root' system property. + */ + public static final String TEST_ROOT = System.getProperty("test.root", "").trim(); + /* * Returns the value of 'test.jdk' system property */ @@ -96,12 +101,13 @@ /* * Returns the value of 'compile.jdk' system property */ - public static final String COMPILE_JDK= System.getProperty("compile.jdk", TEST_JDK); + public static final String COMPILE_JDK = System.getProperty("compile.jdk", TEST_JDK); /** * Returns the value of 'test.classes' system property */ public static final String TEST_CLASSES = System.getProperty("test.classes", "."); + /** * Defines property name for seed value. */ @@ -118,9 +124,9 @@ */ public static final long SEED = Long.getLong(SEED_PROPERTY_NAME, new Random().nextLong()); /** - * Returns the value of 'test.timeout.factor' system property - * converted to {@code double}. - */ + * Returns the value of 'test.timeout.factor' system property + * converted to {@code double}. + */ public static final double TIMEOUT_FACTOR; static { String toFactor = System.getProperty("test.timeout.factor", "1.0"); @@ -128,9 +134,9 @@ } /** - * Returns the value of JTREG default test timeout in milliseconds - * converted to {@code long}. - */ + * Returns the value of JTREG default test timeout in milliseconds + * converted to {@code long}. + */ public static final long DEFAULT_TEST_TIMEOUT = TimeUnit.SECONDS.toMillis(120); private Utils() { diff -r 268875216dfc -r faf96b92a47b test/lib/jdk/test/lib/jfr/EventNames.java --- a/test/lib/jdk/test/lib/jfr/EventNames.java Mon Feb 25 15:15:46 2019 +0530 +++ b/test/lib/jdk/test/lib/jfr/EventNames.java Fri Mar 01 17:27:28 2019 +0530 @@ -66,7 +66,6 @@ public final static String ClassUnload = PREFIX + "ClassUnload"; public final static String SafepointBegin = PREFIX + "SafepointBegin"; public final static String SafepointStateSynchronization = PREFIX + "SafepointStateSynchronization"; - public final static String SafepointWaitBlocked = PREFIX + "SafepointWaitBlocked"; public final static String SafepointCleanup = PREFIX + "SafepointCleanup"; public final static String SafepointCleanupTask = PREFIX + "SafepointCleanupTask"; public final static String SafepointEnd = PREFIX + "SafepointEnd"; diff -r 268875216dfc -r faf96b92a47b test/micro/org/openjdk/bench/java/nio/CharBuffers.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/micro/org/openjdk/bench/java/nio/CharBuffers.java Fri Mar 01 17:27:28 2019 +0530 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2019, 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 org.openjdk.bench.java.nio; + +import java.nio.CharBuffer; +import java.util.Arrays; +import java.util.concurrent.TimeUnit; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@State(Scope.Thread) +public class CharBuffers { + + @Param({"2", "256", "16384"}) + public int numChars; + + public String str; + public CharBuffer buf; + + @Setup(Level.Iteration) + public void createString() { + char[] c = new char[numChars]; + Arrays.fill(c, 'X'); + str = String.valueOf(c); + buf = CharBuffer.allocate(numChars); + } + + @Benchmark + public CharBuffer putString() { + buf.clear(); + return buf.put(str); + } + +} diff -r 268875216dfc -r faf96b92a47b test/nashorn/TEST.ROOT --- a/test/nashorn/TEST.ROOT Mon Feb 25 15:15:46 2019 +0530 +++ b/test/nashorn/TEST.ROOT Fri Mar 01 17:27:28 2019 +0530 @@ -8,7 +8,7 @@ groups=TEST.groups # Minimum jtreg version -requiredVersion=4.2 b13 +requiredVersion=4.2 b14 # Use new module options useNewOptions=true