diff --git a/8031085.patch b/8031085.patch new file mode 100644 index 0000000000000000000000000000000000000000..fcf313c62768514e84cfac78a4f4afa74952b233 --- /dev/null +++ b/8031085.patch @@ -0,0 +1,187 @@ +From 727421f7f1abdcc90ac203fa03b279090a208cd7 Mon Sep 17 00:00:00 2001 +From: hedongbo +Date: Fri, 18 Oct 2019 12:06:46 +0000 +Subject: [PATCH] backport of JDK-8031085 + +Summary: : DateTimeFormatter won't parse dates with custom format "yyyyMMddHHmmssSSS" +LLT: jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java +Bug url: https://bugs.openjdk.java.net/browse/JDK-8031085 +--- + .../java/time/format/DateTimeFormatterBuilder.java | 79 ++++++++++++++++++---- + .../time/format/TCKDateTimeFormatterBuilder.java | 20 +++++- + 2 files changed, 86 insertions(+), 13 deletions(-) + +diff --git a/jdk/src/share/classes/java/time/format/DateTimeFormatterBuilder.java b/jdk/src/share/classes/java/time/format/DateTimeFormatterBuilder.java +index 7e0698dfce..d57a167302 100644 +--- a/jdk/src/share/classes/java/time/format/DateTimeFormatterBuilder.java ++++ b/jdk/src/share/classes/java/time/format/DateTimeFormatterBuilder.java +@@ -664,8 +664,11 @@ public final class DateTimeFormatterBuilder { + * No rounding occurs due to the maximum width - digits are simply dropped. + *

+ * When parsing in strict mode, the number of parsed digits must be between +- * the minimum and maximum width. When parsing in lenient mode, the minimum +- * width is considered to be zero and the maximum is nine. ++ * the minimum and maximum width. In strict mode, if the minimum and maximum widths ++ * are equal and there is no decimal point then the parser will ++ * participate in adjacent value parsing, see ++ * {@link appendValue(java.time.temporal.TemporalField, int)}. When parsing in lenient mode, ++ * the minimum width is considered to be zero and the maximum is nine. + *

+ * If the value cannot be obtained then an exception will be thrown. + * If the value is negative an exception will be thrown. +@@ -684,7 +687,12 @@ public final class DateTimeFormatterBuilder { + */ + public DateTimeFormatterBuilder appendFraction( + TemporalField field, int minWidth, int maxWidth, boolean decimalPoint) { +- appendInternal(new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint)); ++ if (minWidth == maxWidth && decimalPoint == false) { ++ // adjacent parsing ++ appendValue(new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint)); ++ } else { ++ appendInternal(new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint)); ++ } + return this; + } + +@@ -2907,10 +2915,7 @@ public final class DateTimeFormatterBuilder { + /** + * Prints and parses a numeric date-time field with optional padding. + */ +- static final class FractionPrinterParser implements DateTimePrinterParser { +- private final TemporalField field; +- private final int minWidth; +- private final int maxWidth; ++ static final class FractionPrinterParser extends NumberPrinterParser { + private final boolean decimalPoint; + + /** +@@ -2922,6 +2927,7 @@ public final class DateTimeFormatterBuilder { + * @param decimalPoint whether to output the localized decimal point symbol + */ + FractionPrinterParser(TemporalField field, int minWidth, int maxWidth, boolean decimalPoint) { ++ this(field, minWidth, maxWidth, decimalPoint, 0); + Objects.requireNonNull(field, "field"); + if (field.range().isFixed() == false) { + throw new IllegalArgumentException("Field must have a fixed set of values: " + field); +@@ -2936,12 +2942,61 @@ public final class DateTimeFormatterBuilder { + throw new IllegalArgumentException("Maximum width must exceed or equal the minimum width but " + + maxWidth + " < " + minWidth); + } +- this.field = field; +- this.minWidth = minWidth; +- this.maxWidth = maxWidth; ++ } ++ ++ /** ++ * Constructor. ++ * ++ * @param field the field to output, not null ++ * @param minWidth the minimum width to output, from 0 to 9 ++ * @param maxWidth the maximum width to output, from 0 to 9 ++ * @param decimalPoint whether to output the localized decimal point symbol ++ * @param subsequentWidth the subsequentWidth for this instance ++ */ ++ FractionPrinterParser(TemporalField field, int minWidth, int maxWidth, boolean decimalPoint, int subsequentWidth) { ++ super(field, minWidth, maxWidth, SignStyle.NOT_NEGATIVE, subsequentWidth); + this.decimalPoint = decimalPoint; + } + ++ /** ++ * Returns a new instance with fixed width flag set. ++ * ++ * @return a new updated printer-parser, not null ++ */ ++ @Override ++ FractionPrinterParser withFixedWidth() { ++ if (subsequentWidth == -1) { ++ return this; ++ } ++ return new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint, -1); ++ } ++ ++ /** ++ * Returns a new instance with an updated subsequent width. ++ * ++ * @param subsequentWidth the width of subsequent non-negative numbers, 0 or greater ++ * @return a new updated printer-parser, not null ++ */ ++ @Override ++ FractionPrinterParser withSubsequentWidth(int subsequentWidth) { ++ return new FractionPrinterParser(field, minWidth, maxWidth, decimalPoint, this.subsequentWidth + subsequentWidth); ++ } ++ ++ /** ++ * For FractionPrinterPrinterParser, the width is fixed if context is sttrict, ++ * minWidth equal to maxWidth and decimalpoint is absent. ++ * @param context the context ++ * @return if the field is fixed width ++ * @see DateTimeFormatterBuilder#appendValueFraction(java.time.temporal.TemporalField, int, int, boolean) ++ */ ++ @Override ++ boolean isFixedWidth(DateTimeParseContext context) { ++ if (context.isStrict() && minWidth == maxWidth && decimalPoint == false) { ++ return true; ++ } ++ return false; ++ } ++ + @Override + public boolean format(DateTimePrintContext context, StringBuilder buf) { + Long value = context.getValue(field); +@@ -2974,8 +3029,8 @@ public final class DateTimeFormatterBuilder { + + @Override + public int parse(DateTimeParseContext context, CharSequence text, int position) { +- int effectiveMin = (context.isStrict() ? minWidth : 0); +- int effectiveMax = (context.isStrict() ? maxWidth : 9); ++ int effectiveMin = (context.isStrict() || isFixedWidth(context) ? minWidth : 0); ++ int effectiveMax = (context.isStrict() || isFixedWidth(context) ? maxWidth : 9); + int length = text.length(); + if (position == length) { + // valid if whole field is optional, invalid if minimum width +diff --git a/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java b/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java +index c5a017c911..f689cf6512 100644 +--- a/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java ++++ b/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java +@@ -69,6 +69,7 @@ import static org.testng.Assert.assertEquals; + + import java.text.ParsePosition; + import java.time.LocalDate; ++import java.time.LocalDateTime; + import java.time.YearMonth; + import java.time.ZoneOffset; + import java.time.format.DateTimeFormatter; +@@ -868,7 +869,7 @@ public class TCKDateTimeFormatterBuilder { + + @Test + public void test_adjacent_lenient_fractionFollows_0digit() throws Exception { +- // succeeds because hour/min are fixed width ++ // succeeds because hour, min and fraction of seconds are fixed width + DateTimeFormatter f = builder.parseLenient().appendValue(HOUR_OF_DAY, 2).appendValue(MINUTE_OF_HOUR, 2).appendFraction(NANO_OF_SECOND, 3, 3, false).toFormatter(Locale.UK); + ParsePosition pp = new ParsePosition(0); + TemporalAccessor parsed = f.parseUnresolved("1230", pp); +@@ -878,4 +879,21 @@ public class TCKDateTimeFormatterBuilder { + assertEquals(parsed.getLong(MINUTE_OF_HOUR), 30L); + } + ++ @DataProvider(name="adjacentFractionParseData") ++ Object[][] data_adjacent_fraction_parse() { ++ return new Object[][] { ++ {"20130812214600025", "yyyyMMddHHmmssSSS", LocalDateTime.of(2013, 8, 12, 21, 46, 00, 25000000)}, ++ {"201308122146000256", "yyyyMMddHHmmssSSSS", LocalDateTime.of(2013, 8, 12, 21, 46, 00, 25600000)}, ++ }; ++ } ++ ++ @Test(dataProvider = "adjacentFractionParseData") ++ public void test_adjacent_fraction(String input, String pattern, LocalDateTime expected) { ++ DateTimeFormatter dtf = DateTimeFormatter.ofPattern(pattern); ++ LocalDateTime actual = LocalDateTime.parse(input, dtf); ++ assertEquals(actual, expected); ++ } ++ ++ ++ + } +-- +2.12.3 + diff --git a/8033552-Fix-missing-missing-volatile-specifiers-in-C.patch b/8033552-Fix-missing-missing-volatile-specifiers-in-C.patch new file mode 100644 index 0000000000000000000000000000000000000000..b6264adfef7ac576f8777a0f660a82919adf04d6 --- /dev/null +++ b/8033552-Fix-missing-missing-volatile-specifiers-in-C.patch @@ -0,0 +1,331 @@ +From cad6af30875f8c5731b76cca494f1f1301e04c96 Mon Sep 17 00:00:00 2001 +From: zhanggaofeng +Date: Mon, 11 Nov 2019 17:16:36 +0000 +Subject: [PATCH] 8033552:Fix missing missing volatile specifiers in CAS + operations in GC code + +Summary: GC:Fix missing missing volatile specifiers in CAS operations in GC code +LLT: org.openjdk.jcstress.tests.defaultValues.arrays.small.plain.StringTest +Patch Type: backport +Bug url: https://bugs.openjdk.java.net/browse/JDK-8033552 +--- + .../vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp | 4 ++-- + .../concurrentMarkSweep/concurrentMarkSweepGeneration.cpp | 8 ++++---- + .../concurrentMarkSweep/concurrentMarkSweepGeneration.hpp | 2 +- + hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp | 4 ++-- + hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp | 2 +- + hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp | 2 +- + .../gc_implementation/parallelScavenge/parallelScavengeHeap.hpp | 2 +- + .../share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp | 2 +- + .../gc_implementation/parallelScavenge/vmStructs_parallelgc.hpp | 3 ++- + hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp | 4 ++-- + hotspot/src/share/vm/gc_interface/collectedHeap.hpp | 2 +- + hotspot/src/share/vm/memory/defNewGeneration.cpp | 2 +- + hotspot/src/share/vm/memory/defNewGeneration.hpp | 2 +- + hotspot/src/share/vm/memory/genCollectedHeap.cpp | 2 +- + hotspot/src/share/vm/memory/genCollectedHeap.hpp | 2 +- + hotspot/src/share/vm/memory/generation.hpp | 2 +- + hotspot/src/share/vm/runtime/vmStructs.cpp | 3 +++ + 17 files changed, 26 insertions(+), 22 deletions(-) + +diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp +index 5220ee1f34..2697beda2b 100644 +--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp ++++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp +@@ -295,7 +295,7 @@ class Par_PushOrMarkClosure: public MetadataAwareOopClosure { + OopTaskQueue* _work_queue; + CMSMarkStack* _overflow_stack; + HeapWord* const _finger; +- HeapWord** const _global_finger_addr; ++ HeapWord*volatile* const _global_finger_addr; + Par_MarkFromRootsClosure* const + _parent; + protected: +@@ -307,7 +307,7 @@ class Par_PushOrMarkClosure: public MetadataAwareOopClosure { + OopTaskQueue* work_queue, + CMSMarkStack* mark_stack, + HeapWord* finger, +- HeapWord** global_finger_addr, ++ HeapWord*volatile* global_finger_addr, + Par_MarkFromRootsClosure* parent); + virtual void do_oop(oop* p); + virtual void do_oop(narrowOop* p); +diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +index e3c0048da8..6de20cb571 100644 +--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp ++++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +@@ -3914,7 +3914,7 @@ class CMSConcMarkingTask: public YieldingFlexibleGangTask { + bool _result; + CompactibleFreeListSpace* _cms_space; + char _pad_front[64]; // padding to ... +- HeapWord* _global_finger; // ... avoid sharing cache line ++ HeapWord* volatile _global_finger; // ... avoid sharing cache line + char _pad_back[64]; + HeapWord* _restart_addr; + +@@ -3953,7 +3953,7 @@ class CMSConcMarkingTask: public YieldingFlexibleGangTask { + + OopTaskQueue* work_queue(int i) { return task_queues()->queue(i); } + +- HeapWord** global_finger_addr() { return &_global_finger; } ++ HeapWord*volatile* global_finger_addr() { return &_global_finger; } + + CMSConcMarkingTerminator* terminator() { return &_term; } + +@@ -7655,7 +7655,7 @@ void Par_MarkFromRootsClosure::scan_oops_in_oop(HeapWord* ptr) { + + // Note: the local finger doesn't advance while we drain + // the stack below, but the global finger sure can and will. +- HeapWord** gfa = _task->global_finger_addr(); ++ HeapWord*volatile* gfa = _task->global_finger_addr(); + Par_PushOrMarkClosure pushOrMarkClosure(_collector, + _span, _bit_map, + _work_queue, +@@ -7824,7 +7824,7 @@ Par_PushOrMarkClosure::Par_PushOrMarkClosure(CMSCollector* collector, + OopTaskQueue* work_queue, + CMSMarkStack* overflow_stack, + HeapWord* finger, +- HeapWord** global_finger_addr, ++ HeapWord*volatile* global_finger_addr, + Par_MarkFromRootsClosure* parent) : + MetadataAwareOopClosure(collector->ref_processor()), + _collector(collector), +diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp +index a6d06a5dc5..cf2c085dc0 100644 +--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp ++++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp +@@ -750,7 +750,7 @@ class CMSCollector: public CHeapObj { + private: + // Support for parallelizing young gen rescan in CMS remark phase + Generation* _young_gen; // the younger gen +- HeapWord** _top_addr; // ... Top of Eden ++ HeapWord*volatile* _top_addr; // ... Top of Eden + HeapWord** _end_addr; // ... End of Eden + Mutex* _eden_chunk_lock; + HeapWord** _eden_chunk_array; // ... Eden partitioning array +diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp +index ad8a3562e8..8167d2b09d 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp +@@ -56,7 +56,7 @@ class PerRegionTable: public CHeapObj { + PerRegionTable * _collision_list_next; + + // Global free list of PRTs +- static PerRegionTable* _free_list; ++ static PerRegionTable* volatile _free_list; + + protected: + // We need access in order to union things into the base table. +@@ -250,7 +250,7 @@ public: + static void test_fl_mem_size(); + }; + +-PerRegionTable* PerRegionTable::_free_list = NULL; ++PerRegionTable*volatile PerRegionTable::_free_list = NULL; + + size_t OtherRegionsTable::_max_fine_entries = 0; + size_t OtherRegionsTable::_mod_max_fine_entries_mask = 0; +diff --git a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp +index 1439fe668e..b9020002b8 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp +@@ -376,7 +376,7 @@ size_t RSHashTable::mem_size() const { + + // ---------------------------------------------------------------------- + +-SparsePRT* SparsePRT::_head_expanded_list = NULL; ++SparsePRT* volatile SparsePRT::_head_expanded_list = NULL; + + void SparsePRT::add_to_expanded_list(SparsePRT* sprt) { + // We could expand multiple times in a pause -- only put on list once. +diff --git a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp +index 5cc884621a..17bd4a145a 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp +@@ -236,7 +236,7 @@ class SparsePRT VALUE_OBJ_CLASS_SPEC { + + bool should_be_on_expanded_list(); + +- static SparsePRT* _head_expanded_list; ++ static SparsePRT*volatile _head_expanded_list; + + public: + SparsePRT(HeapRegion* hr); +diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp +index 5173ff94ec..bf3a207cdf 100644 +--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp ++++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp +@@ -177,7 +177,7 @@ class ParallelScavengeHeap : public CollectedHeap { + + bool supports_inline_contig_alloc() const { return !UseNUMA; } + +- HeapWord** top_addr() const { return !UseNUMA ? young_gen()->top_addr() : (HeapWord**)-1; } ++ HeapWord*volatile* top_addr() const { return !UseNUMA ? young_gen()->top_addr() : (HeapWord**)-1; } + HeapWord** end_addr() const { return !UseNUMA ? young_gen()->end_addr() : (HeapWord**)-1; } + + void ensure_parsability(bool retire_tlabs); +diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp +index e3da6bdf2b..9bb7eb8e6e 100644 +--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp ++++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp +@@ -162,7 +162,7 @@ class PSYoungGen : public CHeapObj { + return result; + } + +- HeapWord** top_addr() const { return eden_space()->top_addr(); } ++ HeapWord*volatile* top_addr() const { return eden_space()->top_addr(); } + HeapWord** end_addr() const { return eden_space()->end_addr(); } + + // Iteration. +diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmStructs_parallelgc.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmStructs_parallelgc.hpp +index 3c1a20284e..051bcbd800 100644 +--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmStructs_parallelgc.hpp ++++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmStructs_parallelgc.hpp +@@ -26,6 +26,7 @@ + #define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_VMSTRUCTS_PARALLELGC_HPP + + #define VM_STRUCTS_PARALLELGC(nonstatic_field, \ ++ volatile_nonstatic_field, \ + static_field) \ + \ + /**********************/ \ +@@ -40,7 +41,7 @@ + nonstatic_field(ImmutableSpace, _bottom, HeapWord*) \ + nonstatic_field(ImmutableSpace, _end, HeapWord*) \ + \ +- nonstatic_field(MutableSpace, _top, HeapWord*) \ ++ volatile_nonstatic_field(MutableSpace, _top, HeapWord*) \ + \ + nonstatic_field(PSYoungGen, _reserved, MemRegion) \ + nonstatic_field(PSYoungGen, _virtual_space, PSVirtualSpace*) \ +diff --git a/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp b/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp +index 0f1dd075d4..dbd52f24be 100644 +--- a/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp ++++ b/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp +@@ -51,7 +51,7 @@ class MutableSpace: public ImmutableSpace { + MemRegion _last_setup_region; + size_t _alignment; + protected: +- HeapWord* _top; ++ HeapWord *volatile _top; + + MutableSpaceMangler* mangler() { return _mangler; } + +@@ -69,7 +69,7 @@ class MutableSpace: public ImmutableSpace { + HeapWord* top() const { return _top; } + virtual void set_top(HeapWord* value) { _top = value; } + +- HeapWord** top_addr() { return &_top; } ++ HeapWord*volatile* top_addr() { return &_top; } + HeapWord** end_addr() { return &_end; } + + virtual void set_bottom(HeapWord* value) { _bottom = value; } +diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp +index 48fd7e7c0a..653ef5c2ed 100644 +--- a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp ++++ b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp +@@ -379,7 +379,7 @@ class CollectedHeap : public CHeapObj { + // These functions return the addresses of the fields that define the + // boundaries of the contiguous allocation area. (These fields should be + // physically near to one another.) +- virtual HeapWord** top_addr() const { ++ virtual HeapWord*volatile* top_addr() const { + guarantee(false, "inline contiguous allocation not supported"); + return NULL; + } +diff --git a/hotspot/src/share/vm/memory/defNewGeneration.cpp b/hotspot/src/share/vm/memory/defNewGeneration.cpp +index 273d8a3130..15ff6b7328 100644 +--- a/hotspot/src/share/vm/memory/defNewGeneration.cpp ++++ b/hotspot/src/share/vm/memory/defNewGeneration.cpp +@@ -494,7 +494,7 @@ size_t DefNewGeneration::contiguous_available() const { + } + + +-HeapWord** DefNewGeneration::top_addr() const { return eden()->top_addr(); } ++HeapWord*volatile* DefNewGeneration::top_addr() const { return eden()->top_addr(); } + HeapWord** DefNewGeneration::end_addr() const { return eden()->end_addr(); } + + void DefNewGeneration::object_iterate(ObjectClosure* blk) { +diff --git a/hotspot/src/share/vm/memory/defNewGeneration.hpp b/hotspot/src/share/vm/memory/defNewGeneration.hpp +index a5c0eb3095..11359b7979 100644 +--- a/hotspot/src/share/vm/memory/defNewGeneration.hpp ++++ b/hotspot/src/share/vm/memory/defNewGeneration.hpp +@@ -233,7 +233,7 @@ protected: + size_t max_survivor_size() const { return _max_survivor_size; } + + bool supports_inline_contig_alloc() const { return true; } +- HeapWord** top_addr() const; ++ HeapWord*volatile* top_addr() const; + HeapWord** end_addr() const; + + // Thread-local allocation buffers +diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.cpp b/hotspot/src/share/vm/memory/genCollectedHeap.cpp +index 596960e473..572436a388 100644 +--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp ++++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp +@@ -778,7 +778,7 @@ bool GenCollectedHeap::supports_inline_contig_alloc() const { + return _gens[0]->supports_inline_contig_alloc(); + } + +-HeapWord** GenCollectedHeap::top_addr() const { ++HeapWord*volatile* GenCollectedHeap::top_addr() const { + return _gens[0]->top_addr(); + } + +diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.hpp b/hotspot/src/share/vm/memory/genCollectedHeap.hpp +index 416ae87415..6d0dd591c3 100644 +--- a/hotspot/src/share/vm/memory/genCollectedHeap.hpp ++++ b/hotspot/src/share/vm/memory/genCollectedHeap.hpp +@@ -162,7 +162,7 @@ public: + // We may support a shared contiguous allocation area, if the youngest + // generation does. + bool supports_inline_contig_alloc() const; +- HeapWord** top_addr() const; ++ HeapWord*volatile* top_addr() const; + HeapWord** end_addr() const; + + // Does this heap support heap inspection? (+PrintClassHistogram) +diff --git a/hotspot/src/share/vm/memory/generation.hpp b/hotspot/src/share/vm/memory/generation.hpp +index 63dccb70fb..47c26c83dc 100644 +--- a/hotspot/src/share/vm/memory/generation.hpp ++++ b/hotspot/src/share/vm/memory/generation.hpp +@@ -290,7 +290,7 @@ class Generation: public CHeapObj { + // These functions return the addresses of the fields that define the + // boundaries of the contiguous allocation area. (These fields should be + // physicall near to one another.) +- virtual HeapWord** top_addr() const { return NULL; } ++ virtual HeapWord*volatile* top_addr() const { return NULL; } + virtual HeapWord** end_addr() const { return NULL; } + + // Thread-local allocation buffers +diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp +index 7935f8cb47..a498e01563 100644 +--- a/hotspot/src/share/vm/runtime/vmStructs.cpp ++++ b/hotspot/src/share/vm/runtime/vmStructs.cpp +@@ -2926,6 +2926,7 @@ VMStructEntry VMStructs::localHotSpotVMStructs[] = { + + #if INCLUDE_ALL_GCS + VM_STRUCTS_PARALLELGC(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, ++ GENERATE_NONSTATIC_VM_STRUCT_ENTRY, + GENERATE_STATIC_VM_STRUCT_ENTRY) + + VM_STRUCTS_CMS(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, +@@ -3097,6 +3098,7 @@ VMStructs::init() { + + #if INCLUDE_ALL_GCS + VM_STRUCTS_PARALLELGC(CHECK_NONSTATIC_VM_STRUCT_ENTRY, ++ CHECK_VOLATILE_NONSTATIC_VM_STRUCT_ENTRY, + CHECK_STATIC_VM_STRUCT_ENTRY); + + VM_STRUCTS_CMS(CHECK_NONSTATIC_VM_STRUCT_ENTRY, +@@ -3223,6 +3225,7 @@ VMStructs::init() { + CHECK_NO_OP)); + #if INCLUDE_ALL_GCS + debug_only(VM_STRUCTS_PARALLELGC(ENSURE_FIELD_TYPE_PRESENT, ++ ENSURE_FIELD_TYPE_PRESENT, + ENSURE_FIELD_TYPE_PRESENT)); + debug_only(VM_STRUCTS_CMS(ENSURE_FIELD_TYPE_PRESENT, + ENSURE_FIELD_TYPE_PRESENT, +-- +2.12.3 + diff --git a/8047212.patch b/8047212.patch new file mode 100644 index 0000000000000000000000000000000000000000..8bdbfa71e1430377894e912a78092e0df4e79e57 --- /dev/null +++ b/8047212.patch @@ -0,0 +1,269 @@ +From 752e6b3d3747194e9ebc2a57c06403a3ed6fccc0 Mon Sep 17 00:00:00 2001 +From: guoxuanda +Date: Sat, 24 Aug 2019 17:39:22 +0000 +Subject: [PATCH] Backport of JDK-8047212 + +summary: Fix race between ObjectMonitor alloc and verification code; teach SA about "static pointer volatile" fields +LLT: + +Bug url: https://bugs.openjdk.java.net/browse/JDK-8047212 +--- + hotspot/src/share/vm/runtime/synchronizer.cpp | 94 ++++++++++++++------------- + hotspot/src/share/vm/runtime/synchronizer.hpp | 2 +- + hotspot/src/share/vm/runtime/vmStructs.cpp | 19 +++++- + 3 files changed, 68 insertions(+), 47 deletions(-) + +diff --git a/hotspot/src/share/vm/runtime/synchronizer.cpp b/hotspot/src/share/vm/runtime/synchronizer.cpp +index 53341523c8..6e9c1da6bb 100644 +--- a/hotspot/src/share/vm/runtime/synchronizer.cpp ++++ b/hotspot/src/share/vm/runtime/synchronizer.cpp +@@ -149,7 +149,7 @@ int dtrace_waited_probe(ObjectMonitor* monitor, Handle obj, Thread* thr) { + #define NINFLATIONLOCKS 256 + static volatile intptr_t InflationLocks [NINFLATIONLOCKS] ; + +-ObjectMonitor * ObjectSynchronizer::gBlockList = NULL ; ++ObjectMonitor * volatile ObjectSynchronizer::gBlockList = NULL; + ObjectMonitor * volatile ObjectSynchronizer::gFreeList = NULL ; + ObjectMonitor * volatile ObjectSynchronizer::gOmInUseList = NULL ; + int ObjectSynchronizer::gOmInUseCount = 0; +@@ -830,18 +830,18 @@ JavaThread* ObjectSynchronizer::get_lock_owner(Handle h_obj, bool doLock) { + // Visitors ... + + void ObjectSynchronizer::monitors_iterate(MonitorClosure* closure) { +- ObjectMonitor* block = gBlockList; +- ObjectMonitor* mid; +- while (block) { ++ ObjectMonitor* block = ++ (ObjectMonitor*)OrderAccess::load_ptr_acquire(&gBlockList); ++ while (block != NULL) { + assert(block->object() == CHAINMARKER, "must be a block header"); + for (int i = _BLOCKSIZE - 1; i > 0; i--) { +- mid = block + i; +- oop object = (oop) mid->object(); ++ ObjectMonitor* mid = (ObjectMonitor *)(block + i); ++ oop object = (oop)mid->object(); + if (object != NULL) { + closure->do_monitor(mid); + } + } +- block = (ObjectMonitor*) block->FreeNext; ++ block = (ObjectMonitor*)block->FreeNext; + } + } + +@@ -867,7 +867,9 @@ void ObjectSynchronizer::oops_do(OopClosure* f) { + + void ObjectSynchronizer::oops_do(OopClosure* f) { + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); +- for (ObjectMonitor* block = gBlockList; block != NULL; block = next(block)) { ++ ObjectMonitor* block = ++ (ObjectMonitor*)OrderAccess::load_ptr_acquire(&gBlockList); ++ for (; block != NULL; block = (ObjectMonitor *)next(block)) { + assert(block->object() == CHAINMARKER, "must be a block header"); + for (int i = 1; i < _BLOCKSIZE; i++) { + ObjectMonitor* mid = &block[i]; +@@ -1090,7 +1092,9 @@ ObjectMonitor * ATTR ObjectSynchronizer::omAlloc (Thread * Self) { + // The very first objectMonitor in a block is reserved and dedicated. + // It serves as blocklist "next" linkage. + temp[0].FreeNext = gBlockList; +- gBlockList = temp; ++ // There are lock-free uses of gBlockList so make sure that ++ // the previous stores happen before we update gBlockList. ++ OrderAccess::release_store_ptr(&gBlockList, temp); + + // Add the new string of objectMonitors to the global free list + temp[_BLOCKSIZE - 1].FreeNext = gFreeList ; +@@ -1569,29 +1573,31 @@ void ObjectSynchronizer::deflate_idle_monitors() { + nInuse += gOmInUseCount; + } + +- } else for (ObjectMonitor* block = gBlockList; block != NULL; block = next(block)) { +- // Iterate over all extant monitors - Scavenge all idle monitors. +- assert(block->object() == CHAINMARKER, "must be a block header"); +- nInCirculation += _BLOCKSIZE ; +- for (int i = 1 ; i < _BLOCKSIZE; i++) { +- ObjectMonitor* mid = &block[i]; +- oop obj = (oop) mid->object(); +- +- if (obj == NULL) { +- // The monitor is not associated with an object. +- // The monitor should either be a thread-specific private +- // free list or the global free list. +- // obj == NULL IMPLIES mid->is_busy() == 0 +- guarantee (!mid->is_busy(), "invariant") ; +- continue ; +- } +- deflated = deflate_monitor(mid, obj, &FreeHead, &FreeTail); +- +- if (deflated) { +- mid->FreeNext = NULL ; +- nScavenged ++ ; +- } else { +- nInuse ++; ++ } else { ++ ObjectMonitor* block = ++ (ObjectMonitor*)OrderAccess::load_ptr_acquire(&gBlockList); ++ for (; block != NULL; block = (ObjectMonitor*)next(block)) { ++ // Iterate over all extant monitors - Scavenge all idle monitors. ++ assert(block->object() == CHAINMARKER, "must be a block header"); ++ nInCirculation += _BLOCKSIZE; ++ for (int i = 1; i < _BLOCKSIZE; i++) { ++ ObjectMonitor* mid = (ObjectMonitor*)&block[i]; ++ oop obj = (oop)mid->object(); ++ if (obj == NULL) { ++ // The monitor is not associated with an object. ++ // The monitor should either be a thread-specific private ++ // free list or the global free list. ++ // obj == NULL IMPLIES mid->is_busy() == 0 ++ guarantee(!mid->is_busy(), "invariant"); ++ continue; ++ } ++ deflated = deflate_monitor(mid, obj, &FreeHead, &FreeTail); ++ if (deflated) { ++ mid->FreeNext = NULL; ++ nScavenged++; ++ } else { ++ nInuse++; ++ } + } + } + } +@@ -1726,13 +1732,13 @@ void ObjectSynchronizer::sanity_checks(const bool verbose, + + // Verify all monitors in the monitor cache, the verification is weak. + void ObjectSynchronizer::verify() { +- ObjectMonitor* block = gBlockList; +- ObjectMonitor* mid; +- while (block) { ++ ObjectMonitor* block = ++ (ObjectMonitor *)OrderAccess::load_ptr_acquire(&gBlockList); ++ while (block != NULL) { + assert(block->object() == CHAINMARKER, "must be a block header"); + for (int i = 1; i < _BLOCKSIZE; i++) { +- mid = block + i; +- oop object = (oop) mid->object(); ++ ObjectMonitor* mid = (ObjectMonitor *)(block + i); ++ oop object = (oop)mid->object(); + if (object != NULL) { + mid->verify(); + } +@@ -1746,18 +1752,18 @@ void ObjectSynchronizer::verify() { + // the list of extant blocks without taking a lock. + + int ObjectSynchronizer::verify_objmon_isinpool(ObjectMonitor *monitor) { +- ObjectMonitor* block = gBlockList; +- +- while (block) { ++ ObjectMonitor* block = ++ (ObjectMonitor*)OrderAccess::load_ptr_acquire(&gBlockList); ++ while (block != NULL) { + assert(block->object() == CHAINMARKER, "must be a block header"); + if (monitor > &block[0] && monitor < &block[_BLOCKSIZE]) { +- address mon = (address) monitor; +- address blk = (address) block; ++ address mon = (address)monitor; ++ address blk = (address)block; + size_t diff = mon - blk; +- assert((diff % sizeof(ObjectMonitor)) == 0, "check"); ++ assert((diff % sizeof(ObjectMonitor)) == 0, "must be aligned"); + return 1; + } +- block = (ObjectMonitor*) block->FreeNext; ++ block = (ObjectMonitor*)block->FreeNext; + } + return 0; + } +diff --git a/hotspot/src/share/vm/runtime/synchronizer.hpp b/hotspot/src/share/vm/runtime/synchronizer.hpp +index 3247776b74..4c4a7155af 100644 +--- a/hotspot/src/share/vm/runtime/synchronizer.hpp ++++ b/hotspot/src/share/vm/runtime/synchronizer.hpp +@@ -151,7 +151,7 @@ class ObjectSynchronizer : AllStatic { + + private: + enum { _BLOCKSIZE = 128 }; +- static ObjectMonitor* gBlockList; ++ static ObjectMonitor * volatile gBlockList; + static ObjectMonitor * volatile gFreeList; + static ObjectMonitor * volatile gOmInUseList; // for moribund thread, so monitors they inflated still get scanned + static int gOmInUseCount; +diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp +index 5b5282e38e..7935f8cb47 100644 +--- a/hotspot/src/share/vm/runtime/vmStructs.cpp ++++ b/hotspot/src/share/vm/runtime/vmStructs.cpp +@@ -267,6 +267,7 @@ typedef TwoOopHashtable SymbolTwoOopHashtable; + + #define VM_STRUCTS(nonstatic_field, \ + static_field, \ ++ static_ptr_volatile_field, \ + unchecked_nonstatic_field, \ + volatile_nonstatic_field, \ + nonproduct_nonstatic_field, \ +@@ -1091,7 +1092,7 @@ typedef TwoOopHashtable SymbolTwoOopHashtable; + volatile_nonstatic_field(BasicLock, _displaced_header, markOop) \ + nonstatic_field(BasicObjectLock, _lock, BasicLock) \ + nonstatic_field(BasicObjectLock, _obj, oop) \ +- static_field(ObjectSynchronizer, gBlockList, ObjectMonitor*) \ ++ static_ptr_volatile_field(ObjectSynchronizer,gBlockList, ObjectMonitor*) \ + \ + /*********************/ \ + /* Matcher (C2 only) */ \ +@@ -2682,6 +2683,11 @@ typedef TwoOopHashtable SymbolTwoOopHashtable; + #define GENERATE_STATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \ + { QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 1, 0, &typeName::fieldName }, + ++// This macro generates a VMStructEntry line for a static pointer volatile field, ++// e.g.: "static ObjectMonitor * volatile gBlockList;" ++#define GENERATE_STATIC_PTR_VOLATILE_VM_STRUCT_ENTRY(typeName, fieldName, type) \ ++ { QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 1, 0, (void*)&typeName::fieldName }, ++ + // This macro generates a VMStructEntry line for an unchecked + // nonstatic field, in which the size of the type is also specified. + // The type string is given as NULL, indicating an "opaque" type. +@@ -2707,10 +2713,15 @@ typedef TwoOopHashtable SymbolTwoOopHashtable; + #define CHECK_VOLATILE_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \ + {typedef type dummyvtype; typeName *dummyObj = NULL; volatile dummyvtype* dummy = &dummyObj->fieldName; } + +-// This macro checks the type of a VMStructEntry by comparing pointer types ++// This macro checks the type of a static VMStructEntry by comparing pointer types + #define CHECK_STATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \ + {type* dummy = &typeName::fieldName; } + ++// This macro checks the type of a static pointer volatile VMStructEntry by comparing pointer types, ++// e.g.: "static ObjectMonitor * volatile gBlockList;" ++#define CHECK_STATIC_PTR_VOLATILE_VM_STRUCT_ENTRY(typeName, fieldName, type) \ ++ {type volatile * dummy = &typeName::fieldName; } ++ + // This macro ensures the type of a field and its containing type are + // present in the type table. The assertion string is shorter than + // preferable because (incredibly) of a bug in Solstice NFS client +@@ -2904,6 +2915,7 @@ VMStructEntry VMStructs::localHotSpotVMStructs[] = { + + VM_STRUCTS(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, + GENERATE_STATIC_VM_STRUCT_ENTRY, ++ GENERATE_STATIC_PTR_VOLATILE_VM_STRUCT_ENTRY, + GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY, + GENERATE_NONSTATIC_VM_STRUCT_ENTRY, + GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY, +@@ -3074,6 +3086,7 @@ void + VMStructs::init() { + VM_STRUCTS(CHECK_NONSTATIC_VM_STRUCT_ENTRY, + CHECK_STATIC_VM_STRUCT_ENTRY, ++ CHECK_STATIC_PTR_VOLATILE_VM_STRUCT_ENTRY, + CHECK_NO_OP, + CHECK_VOLATILE_NONSTATIC_VM_STRUCT_ENTRY, + CHECK_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY, +@@ -3196,9 +3209,11 @@ VMStructs::init() { + CHECK_NO_OP, + CHECK_NO_OP, + CHECK_NO_OP, ++ CHECK_NO_OP, + CHECK_NO_OP)); + debug_only(VM_STRUCTS(CHECK_NO_OP, + ENSURE_FIELD_TYPE_PRESENT, ++ ENSURE_FIELD_TYPE_PRESENT, + CHECK_NO_OP, + ENSURE_FIELD_TYPE_PRESENT, + ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT, +-- +2.12.3 + diff --git a/8060463.patch b/8060463.patch new file mode 100644 index 0000000000000000000000000000000000000000..b634e1ebe1714e04a76c33cd3f162833d1a5bdfa --- /dev/null +++ b/8060463.patch @@ -0,0 +1,133 @@ +From e01473adc4c392aa947417cbde478161b2d741bb Mon Sep 17 00:00:00 2001 +From: wangyadong +Date: Fri, 12 Jul 2019 16:10:56 +0800 +Subject: [PATCH] Backport of JDK-8060463 + +Summary: ParNew: +SurvivorAlignmentInBytes greater then YoungPLABSize cause assert(obj != NULL +|| plab->words_remaining() < word_sz) failed: Else should have been able to +allocate. +LLT: hotspot/test/gc/survivorAlignment/TestPromotionLABLargeSurvivorAlignment.java +Bug url: https://bugs.openjdk.java.net/browse/JDK-8060463 + +--- + .../parNew/parNewGeneration.cpp | 15 ++-- + ...estPromotionLABLargeSurvivorAlignment.java | 72 +++++++++++++++++++ + 2 files changed, 83 insertions(+), 4 deletions(-) + create mode 100644 hotspot/test/gc/survivorAlignment/TestPromotionLABLargeSurvivorAlignment.java + +diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp +index 8ef1bd2cda..67b0421ebf 100644 +--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp ++++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp +@@ -233,11 +233,15 @@ HeapWord* ParScanThreadState::alloc_in_to_space_slow(size_t word_sz) { + ParallelGCBufferWastePct * plab->word_sz()) { + // Is small enough; abandon this buffer and start a new one. + plab->retire(false, false); +- size_t buf_size = plab->word_sz(); ++ // The minimum size has to be twice SurvivorAlignmentInBytes to ++ // allow for padding used in the alignment of 1 word. A padding ++ // of 1 is too small for a filler word so the padding size will ++ // be increased by SurvivorAlignmentInBytes. ++ size_t min_usable_size = 2 * static_cast(SurvivorAlignmentInBytes >> LogHeapWordSize); ++ size_t buf_size = MAX2(plab->word_sz(), min_usable_size); + HeapWord* buf_space = sp->par_allocate(buf_size); + if (buf_space == NULL) { +- const size_t min_bytes = +- ParGCAllocBuffer::min_size() << LogHeapWordSize; ++ const size_t min_bytes = MAX2(ThreadLocalAllocBuffer::min_size(), min_usable_size) << LogHeapWordSize; + size_t free_bytes = sp->free(); + while(buf_space == NULL && free_bytes >= min_bytes) { + buf_size = free_bytes >> LogHeapWordSize; +@@ -255,7 +259,10 @@ HeapWord* ParScanThreadState::alloc_in_to_space_slow(size_t word_sz) { + // Note that we cannot compare buf_size < word_sz below + // because of AlignmentReserve (see ParGCAllocBuffer::allocate()). + assert(obj != NULL || plab->words_remaining() < word_sz, +- "Else should have been able to allocate"); ++ err_msg("Else should have been able to allocate requested object size " ++ SIZE_FORMAT ", PLAB size " SIZE_FORMAT ", SurvivorAlignmentInBytes " ++ SIZE_FORMAT ", words_remaining " SIZE_FORMAT, ++ word_sz, buf_size, SurvivorAlignmentInBytes, plab->words_remaining())); + // It's conceivable that we may be able to use the + // buffer we just grabbed for subsequent small requests + // even if not for this one. +diff --git a/hotspot/test/gc/survivorAlignment/TestPromotionLABLargeSurvivorAlignment.java b/hotspot/test/gc/survivorAlignment/TestPromotionLABLargeSurvivorAlignment.java +new file mode 100644 +index 0000000000..397b647489 +--- /dev/null ++++ b/hotspot/test/gc/survivorAlignment/TestPromotionLABLargeSurvivorAlignment.java +@@ -0,0 +1,71 @@ ++/* ++ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++ ++/** ++ * @test ++ * @bug 8060463 ++ * @summary Verify that objects promoted from eden space to survivor space ++ * with large values for SurvivorAlignmentInBytes succeed. ++ * @requires vm.opt.ExplicitGCInvokesConcurrent != true ++ * @run main/othervm -Xmx128m ++ * -XX:+UnlockExperimentalVMOptions ++ * -XX:SurvivorAlignmentInBytes=8 -XX:SurvivorRatio=1 ++ * -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB ++ * TestPromotionLABLargeSurvivorAlignment ++ * @run main/othervm -Xmx128m ++ * -XX:+UnlockExperimentalVMOptions ++ * -XX:SurvivorAlignmentInBytes=16 -XX:SurvivorRatio=1 ++ * -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB ++ * TestPromotionLABLargeSurvivorAlignment ++ * @run main/othervm -Xmx128m ++ * -XX:+UnlockExperimentalVMOptions ++ * -XX:SurvivorAlignmentInBytes=512 -XX:SurvivorRatio=1 ++ * -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB ++ * TestPromotionLABLargeSurvivorAlignment ++ * @run main/othervm -Xmx128m ++ * -XX:+UnlockExperimentalVMOptions ++ * -XX:SurvivorAlignmentInBytes=1k -XX:SurvivorRatio=1 ++ * -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB ++ * TestPromotionLABLargeSurvivorAlignment ++ * @run main/othervm -Xmx128m ++ * -XX:+UnlockExperimentalVMOptions ++ * -XX:SurvivorAlignmentInBytes=4k -XX:SurvivorRatio=1 ++ * -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB ++ * TestPromotionLABLargeSurvivorAlignment ++ * @run main/othervm -Xmx128m ++ * -XX:+UnlockExperimentalVMOptions ++ * -XX:SurvivorAlignmentInBytes=16k -XX:SurvivorRatio=1 ++ * -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB ++ * TestPromotionLABLargeSurvivorAlignment ++ */ ++public class TestPromotionLABLargeSurvivorAlignment { ++ public static void main(String args[]) { ++ Object garbage[] = new Object[1000000]; ++ for (int i = 0; i < garbage.length; i++) { ++ garbage[i] = new byte[0]; ++ } ++ for (int i = 0; i < 2; i++) { ++ System.gc(); ++ } ++ } ++} +-- +2.19.0-rc1 + diff --git a/8129626.patch b/8129626.patch new file mode 100644 index 0000000000000000000000000000000000000000..81db9ffe97100912d1682684e68961023f9d4293 --- /dev/null +++ b/8129626.patch @@ -0,0 +1,107 @@ +From 570f33e3f57acb9a8b4b7e3c378b836bef774df4 Mon Sep 17 00:00:00 2001 +From: hexuejin +Date: Wed, 17 Jul 2019 11:36:31 +0000 +Subject: [PATCH] Backport of JDK-8129626 + +summary: G1: set_in_progress() and clear_started() needs a barrier on non-TSO platforms +LLT: + +Bug url: https://bugs.openjdk.java.net/browse/JDK-8129626 +--- + .../gc_implementation/g1/concurrentMarkThread.cpp | 4 +-- + .../gc_implementation/g1/concurrentMarkThread.hpp | 29 +++++++++++++--------- + .../vm/gc_implementation/g1/g1CollectedHeap.cpp | 2 +- + 3 files changed, 19 insertions(+), 16 deletions(-) + +diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp +index b56e309234..53fe0837b1 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp +@@ -43,8 +43,7 @@ SurrogateLockerThread* + ConcurrentMarkThread::ConcurrentMarkThread(ConcurrentMark* cm) : + ConcurrentGCThread(), + _cm(cm), +- _started(false), +- _in_progress(false), ++ _state(Idle), + _vtime_accum(0.0), + _vtime_mark_accum(0.0) { + create_and_start(); +@@ -341,7 +340,6 @@ void ConcurrentMarkThread::sleepBeforeNextCycle() { + + if (started()) { + set_in_progress(); +- clear_started(); + } + } + +diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp +index caa7f429c6..5f5f70ac4d 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp +@@ -46,8 +46,14 @@ class ConcurrentMarkThread: public ConcurrentGCThread { + + private: + ConcurrentMark* _cm; +- volatile bool _started; +- volatile bool _in_progress; ++ ++ enum State { ++ Idle, ++ Started, ++ InProgress ++ }; ++ ++ volatile State _state; + + void sleepBeforeNextCycle(); + +@@ -71,23 +77,22 @@ class ConcurrentMarkThread: public ConcurrentGCThread { + + ConcurrentMark* cm() { return _cm; } + +- void set_started() { assert(!_in_progress, "cycle in progress"); _started = true; } +- void clear_started() { assert(_in_progress, "must be starting a cycle"); _started = false; } +- bool started() { return _started; } +- +- void set_in_progress() { assert(_started, "must be starting a cycle"); _in_progress = true; } +- void clear_in_progress() { assert(!_started, "must not be starting a new cycle"); _in_progress = false; } +- bool in_progress() { return _in_progress; } ++ void set_idle() { assert(_state != Started, "must not be starting a new cycle"); _state = Idle; } ++ bool idle() { return _state == Idle; } ++ void set_started() { assert(_state == Idle, "cycle in progress"); _state = Started; } ++ bool started() { return _state == Started; } ++ void set_in_progress() { assert(_state == Started, "must be starting a cycle"); _state = InProgress; } ++ bool in_progress() { return _state == InProgress; } + +- // This flag returns true from the moment a marking cycle is ++ // Returns true from the moment a marking cycle is + // initiated (during the initial-mark pause when started() is set) + // to the moment when the cycle completes (just after the next + // marking bitmap has been cleared and in_progress() is +- // cleared). While this flag is true we will not start another cycle ++ // cleared). While during_cycle() is true we will not start another cycle + // so that cycles do not overlap. We cannot use just in_progress() + // as the CM thread might take some time to wake up before noticing + // that started() is set and set in_progress(). +- bool during_cycle() { return started() || in_progress(); } ++ bool during_cycle() { return !idle(); } + + // shutdown + void stop(); +diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +index aa6bbc81a4..a6e91a08ce 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +@@ -2409,7 +2409,7 @@ void G1CollectedHeap::increment_old_marking_cycles_completed(bool concurrent) { + // is set) so that if a waiter requests another System.gc() it doesn't + // incorrectly see that a marking cycle is still in progress. + if (concurrent) { +- _cmThread->clear_in_progress(); ++ _cmThread->set_idle(); + } + + // This notify_all() will ensure that a thread that called +-- +2.12.3 + diff --git a/8131600.patch b/8131600.patch new file mode 100644 index 0000000000000000000000000000000000000000..d580eaf0fd4621b20b09b3a3b79981ae91bf5d46 --- /dev/null +++ b/8131600.patch @@ -0,0 +1,46 @@ +From a0788fc8804ec901f1011a7a7a3264098a717223 Mon Sep 17 00:00:00 2001 +From: songyaofei +Date: Tue, 16 Jul 2019 19:36:33 +0000 +Subject: [PATCH] Backport of JDK-8131600 + +Summary: JVM crashes when doing heapdump and handling a signal at a same time +LLT: none + +Bug url: https://bugs.openjdk.java.net/browse/JDK-8131600 +--- + hotspot/src/share/vm/prims/jvmtiTagMap.cpp | 2 +- + hotspot/src/share/vm/services/heapDumper.cpp | 5 +++++ + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/hotspot/src/share/vm/prims/jvmtiTagMap.cpp b/hotspot/src/share/vm/prims/jvmtiTagMap.cpp +index 90c95f417d..84fc25071b 100644 +--- a/hotspot/src/share/vm/prims/jvmtiTagMap.cpp ++++ b/hotspot/src/share/vm/prims/jvmtiTagMap.cpp +@@ -2834,7 +2834,7 @@ inline bool VM_HeapWalkOperation::iterate_over_class(oop java_class) { + if (klass->oop_is_instance()) { + InstanceKlass* ik = InstanceKlass::cast(klass); + +- // ignore the class if it's has been initialized yet ++ // Ignore the class if it hasn't been initialized yet + if (!ik->is_linked()) { + return true; + } +diff --git a/hotspot/src/share/vm/services/heapDumper.cpp b/hotspot/src/share/vm/services/heapDumper.cpp +index e5de80eaeb..9a1bb13ded 100644 +--- a/hotspot/src/share/vm/services/heapDumper.cpp ++++ b/hotspot/src/share/vm/services/heapDumper.cpp +@@ -950,6 +950,11 @@ void DumperSupport::dump_class_and_array_classes(DumpWriter* writer, Klass* k) { + return; + } + ++ // Ignore the class if it hasn't been initialized yet ++ if (!ik->is_linked()) { ++ return; ++ } ++ + writer->write_u1(HPROF_GC_CLASS_DUMP); + + // class ID +-- +2.12.3 + diff --git a/8134883.patch b/8134883.patch new file mode 100644 index 0000000000000000000000000000000000000000..625eb2893b5d779c2c015a52b67473a29bfd073e --- /dev/null +++ b/8134883.patch @@ -0,0 +1,189 @@ +From d58ebe4882c0dfcb2f185e948c5c838f2d867e6b Mon Sep 17 00:00:00 2001 +From: songyaofei +Date: Wed, 12 Jun 2019 20:43:23 +0000 +Subject: [PATCH] fix-fastdebug-jdk-crash-when-running-a-jtreg-case + +Summary: The problem happens when c1’s loop optimizations encounter a non natural loop for which one entry is an exception handler.Backport the patch from openjdk9 +LLT: +Bug url: https://bugs.openjdk.java.net/browse/JDK-8134883 + +--- + hotspot/src/share/vm/c1/c1_IR.cpp | 7 +- + .../TestRangeCheckExceptionHandlerLoop.jasm | 89 +++++++++++++++++++ + ...estRangeCheckExceptionHandlerLoopMain.java | 41 +++++++++ + 3 files changed, 134 insertions(+), 3 deletions(-) + create mode 100644 hotspot/test/compiler/rangechecks/TestRangeCheckExceptionHandlerLoop.jasm + create mode 100644 hotspot/test/compiler/rangechecks/TestRangeCheckExceptionHandlerLoopMain.java + +diff --git a/hotspot/src/share/vm/c1/c1_IR.cpp b/hotspot/src/share/vm/c1/c1_IR.cpp +index 0984098764..b500d5cf79 100644 +--- a/hotspot/src/share/vm/c1/c1_IR.cpp ++++ b/hotspot/src/share/vm/c1/c1_IR.cpp +@@ -578,11 +578,8 @@ void ComputeLinearScanOrder::count_edges(BlockBegin* cur, BlockBegin* parent) { + assert(is_visited(cur), "block must be visisted when block is active"); + assert(parent != NULL, "must have parent"); + +- cur->set(BlockBegin::linear_scan_loop_header_flag); + cur->set(BlockBegin::backward_branch_target_flag); + +- parent->set(BlockBegin::linear_scan_loop_end_flag); +- + // When a loop header is also the start of an exception handler, then the backward branch is + // an exception edge. Because such edges are usually critical edges which cannot be split, the + // loop must be excluded here from processing. +@@ -591,6 +588,10 @@ void ComputeLinearScanOrder::count_edges(BlockBegin* cur, BlockBegin* parent) { + _iterative_dominators = true; + return; + } ++ ++ cur->set(BlockBegin::linear_scan_loop_header_flag); ++ parent->set(BlockBegin::linear_scan_loop_end_flag); ++ + assert(parent->number_of_sux() == 1 && parent->sux_at(0) == cur, + "loop end blocks must have one successor (critical edges are split)"); + +diff --git a/hotspot/test/compiler/rangechecks/TestRangeCheckExceptionHandlerLoop.jasm b/hotspot/test/compiler/rangechecks/TestRangeCheckExceptionHandlerLoop.jasm +new file mode 100644 +index 0000000000..2befe6db09 +--- /dev/null ++++ b/hotspot/test/compiler/rangechecks/TestRangeCheckExceptionHandlerLoop.jasm +@@ -0,0 +1,89 @@ ++/* ++ * 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. ++ * ++ * 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. ++ * ++ */ ++ ++super public class TestRangeCheckExceptionHandlerLoop ++ version 51:0 ++{ ++ ++ ++public Method "":"()V" ++ stack 1 locals 1 ++{ ++ aload_0; ++ invokespecial Method java/lang/Object."":"()V"; ++ return; ++} ++ ++/* This method has an irreducible loop, with 2 entries, one is the exception handler ++ ++ static void test(boolean flag, int[] array, Exception exception) throws Exception { ++ int i = 0; ++ if (flag) { ++ try { ++ throw exception; ++ } catch(Exception e) { ++ array[i] = 0; ++ i++; ++ } ++ } ++ if (i < 10) { ++ throw exception; // caught by exception handler above as well ++ } ++ } ++*/ ++public static Method test:"(Z[ILjava/lang/Exception;)V" ++ throws java/lang/Exception ++ stack 3 locals 5 ++{ ++ iconst_0; ++ istore_3; ++ iload_0; ++ ifeq L17; ++ try t0; ++ aload_2; ++ athrow; ++ endtry t0; ++ catch t0 java/lang/Exception; ++ catch t1 java/lang/Exception; ++ stack_frame_type full; ++ locals_map int, class "[I", class java/lang/Exception, int; ++ stack_map class java/lang/Exception; ++ astore 4; ++ aload_1; ++ iload_3; ++ iconst_0; ++ iastore; ++ iinc 3, 1; ++ L17: stack_frame_type same; ++ iload_3; ++ bipush 10; ++ if_icmpge L25; ++ try t1; ++ aload_2; ++ athrow; ++ endtry t1; ++ L25: stack_frame_type same; ++ return; ++} ++} // end Class TestRangeCheckExceptionHandlerLoop +diff --git a/hotspot/test/compiler/rangechecks/TestRangeCheckExceptionHandlerLoopMain.java b/hotspot/test/compiler/rangechecks/TestRangeCheckExceptionHandlerLoopMain.java +new file mode 100644 +index 0000000000..32df890bc0 +--- /dev/null ++++ b/hotspot/test/compiler/rangechecks/TestRangeCheckExceptionHandlerLoopMain.java +@@ -0,0 +1,41 @@ ++/* ++ * 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. ++ * ++ * 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 8134883 ++ * @summary C1's range check elimination breaks with a non-natural loop that an exception handler as one entry ++ * @compile TestRangeCheckExceptionHandlerLoop.jasm ++ * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestRangeCheckExceptionHandlerLoopMain ++ */ ++ ++public class TestRangeCheckExceptionHandlerLoopMain { ++ public static void main(String[] args) throws Exception { ++ Exception exception = new Exception(); ++ int[] array = new int[10]; ++ for (int i = 0; i < 20000; i++) { ++ TestRangeCheckExceptionHandlerLoop.test(false, array, exception); ++ } ++ } ++} +-- +2.19.0 + diff --git a/8135318.patch b/8135318.patch new file mode 100644 index 0000000000000000000000000000000000000000..0ddb596435375b08fee80b5c1760ee3c7acd1bca --- /dev/null +++ b/8135318.patch @@ -0,0 +1,33 @@ +From ab0474ea0dae399dcd256aa520089450a3363f33 Mon Sep 17 00:00:00 2001 +From: zhangli +Date: Wed, 19 Jun 2019 19:38:37 +0000 +Subject: [PATCH] JDK-8135318 backport + +Summary: CMS: wrong max_eden_size for check_gc_overhead_limit +LLT: +Bug url: https://bugs.openjdk.java.net/browse/JDK-8135318 +--- + .../concurrentMarkSweep/concurrentMarkSweepGeneration.cpp | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +index 1872e72e36..2d7791138c 100644 +--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp ++++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +@@ -1924,9 +1924,10 @@ NOT_PRODUCT( + + // Has the GC time limit been exceeded? + DefNewGeneration* young_gen = _young_gen->as_DefNewGeneration(); +- size_t max_eden_size = young_gen->max_capacity() - +- young_gen->to()->capacity() - +- young_gen->from()->capacity(); ++ ++ //PR JDK-8135318 back port ++ size_t max_eden_size = young_gen->max_eden_size(); ++ + GenCollectedHeap* gch = GenCollectedHeap::heap(); + GCCause::Cause gc_cause = gch->gc_cause(); + size_policy()->check_gc_overhead_limit(_young_gen->used(), +-- +2.12.3 + diff --git a/8138971.patch b/8138971.patch new file mode 100644 index 0000000000000000000000000000000000000000..5fc7df2f1a1e8b3071f201386370eda08ee4d7e6 --- /dev/null +++ b/8138971.patch @@ -0,0 +1,27 @@ +From ffb7c326ceb85f9bab196a23d3c2adb4a27613ce Mon Sep 17 00:00:00 2001 +From: hexuejin +Date: Wed, 17 Jul 2019 09:26:19 +0000 +Subject: [PATCH] Backport of JDK-8138971 + +summary: G1CollectorPolicy::_rs_lengths_prediction is not initialized before use +LLT: +Bug url: https://bugs.openjdk.java.net/browse/JDK-8138971 +--- + hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp +index c4463f50fc..066aa40b25 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp +@@ -122,6 +122,7 @@ G1CollectorPolicy::G1CollectorPolicy() : + new TruncatedSeq(NumPrevPausesForHeuristics)), + + _recent_avg_pause_time_ratio(0.0), ++ _rs_lengths_prediction(0), + + _initiate_conc_mark_if_possible(false), + _during_initial_mark_pause(false), +-- +2.12.3 + diff --git a/8141356.patch b/8141356.patch new file mode 100644 index 0000000000000000000000000000000000000000..e0dd6178c25725791fb574fd2656b05823bccea4 --- /dev/null +++ b/8141356.patch @@ -0,0 +1,46 @@ +From 81c4aa5c13e38b701a0ace0765ab153b750a1e7e Mon Sep 17 00:00:00 2001 +From: mashoubing +Date: Tue, 25 Jun 2019 10:06:19 +0000 +Subject: [PATCH] backport of JDK-8141356 + +Summary: Explicitly stop CMS threads during VM termination +LLT: +Bug url: https://bugs.openjdk.java.net/browse/JDK-8141356 +--- + hotspot/src/share/vm/memory/genCollectedHeap.cpp | 8 ++++++++ + hotspot/src/share/vm/memory/genCollectedHeap.hpp | 3 +++ + 2 files changed, 11 insertions(+) + +diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.cpp b/hotspot/src/share/vm/memory/genCollectedHeap.cpp +index f7c9591d90..eeb56f02a1 100644 +--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp ++++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp +@@ -1408,3 +1408,11 @@ jlong GenCollectedHeap::millis_since_last_gc() { + } + return retVal; + } ++ ++void GenCollectedHeap::stop() { ++#if INCLUDE_ALL_GCS ++ if (UseConcMarkSweepGC) { ++ ConcurrentMarkSweepThread::stop(); ++ } ++#endif ++} +diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.hpp b/hotspot/src/share/vm/memory/genCollectedHeap.hpp +index 58786eded2..c3eb0db064 100644 +--- a/hotspot/src/share/vm/memory/genCollectedHeap.hpp ++++ b/hotspot/src/share/vm/memory/genCollectedHeap.hpp +@@ -538,6 +538,9 @@ private: + protected: + virtual void gc_prologue(bool full); + virtual void gc_epilogue(bool full); ++ ++public: ++ void stop(); + }; + + #endif // SHARE_VM_MEMORY_GENCOLLECTEDHEAP_HPP +-- +2.19.0-rc1 + diff --git a/8146792.patch b/8146792.patch new file mode 100644 index 0000000000000000000000000000000000000000..a2339b299954ec04ad9059b7fc610f63887f6fe2 --- /dev/null +++ b/8146792.patch @@ -0,0 +1,52 @@ +From 81b3011925783d6eb1effec9b858e1d0e162d378 Mon Sep 17 00:00:00 2001 +From: guoxuanda +Date: Tue, 20 Aug 2019 21:09:30 +0000 +Subject: [PATCH] Backport of JDK-8146792 + +summary: Predicate moved after partial peel may lead to broken +LLT: +Bug url: https://bugs.openjdk.java.net/browse/JDK-8146792 +--- + hotspot/src/share/vm/opto/loopPredicate.cpp | 26 +++++++++++++++++++++++++- + 1 file changed, 25 insertions(+), 1 deletion(-) + +diff --git a/hotspot/src/share/vm/opto/loopPredicate.cpp b/hotspot/src/share/vm/opto/loopPredicate.cpp +index db3447dc6e..f216fd9d1e 100644 +--- a/hotspot/src/share/vm/opto/loopPredicate.cpp ++++ b/hotspot/src/share/vm/opto/loopPredicate.cpp +@@ -505,7 +505,31 @@ class Invariance : public StackObj { + _lpt(lpt), _phase(lpt->_phase), + _visited(area), _invariant(area), _stack(area, 10 /* guess */), + _clone_visited(area), _old_new(area) +- {} ++ { ++ Node* head = _lpt->_head; ++ Node* entry = head->in(LoopNode::EntryControl); ++ if (entry->outcnt() != 1) { ++ // If a node is pinned between the predicates and the loop ++ // entry, we won't be able to move any node in the loop that ++ // depends on it above it in a predicate. Mark all those nodes ++ // as non loop invariatnt. ++ Unique_Node_List wq; ++ wq.push(entry); ++ for (uint next = 0; next < wq.size(); ++next) { ++ Node *n = wq.at(next); ++ for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { ++ Node* u = n->fast_out(i); ++ if (!u->is_CFG()) { ++ Node* c = _phase->get_ctrl(u); ++ if (_lpt->is_member(_phase->get_loop(c)) || _phase->is_dominator(c, head)) { ++ _visited.set(u->_idx); ++ wq.push(u); ++ } ++ } ++ } ++ } ++ } ++ } + + // Map old to n for invariance computation and clone + void map_ctrl(Node* old, Node* n) { +-- +2.12.3 + diff --git a/8148754-C2-loop-unrolling-fails-due-to-unexpected-gr.patch b/8148754-C2-loop-unrolling-fails-due-to-unexpected-gr.patch new file mode 100644 index 0000000000000000000000000000000000000000..a211d54389f9e523e6f6929b06da43d5fad4b08f --- /dev/null +++ b/8148754-C2-loop-unrolling-fails-due-to-unexpected-gr.patch @@ -0,0 +1,180 @@ +From be0206e834bab370da41cf9ec9e6b9be710e1987 Mon Sep 17 00:00:00 2001 +From: guoge +Date: Fri, 19 Apr 2019 17:40:19 +0000 +Subject: [PATCH] 8148754: C2 loop unrolling fails due to unexpected graph shape + +Summary: C2 loop unrolling fails due to unexpected graph shape +Bug url: https://bugs.openjdk.java.net/browse/JDK-8148754 +--- + hotspot/src/share/vm/opto/loopTransform.cpp | 44 ++++++++------------- + hotspot/src/share/vm/opto/loopnode.cpp | 36 +++++++++++++++++ + hotspot/src/share/vm/opto/loopnode.hpp | 3 ++ + hotspot/src/share/vm/opto/superword.cpp | 18 ++++----- + 4 files changed, 64 insertions(+), 37 deletions(-) + +diff --git a/hotspot/src/share/vm/opto/loopTransform.cpp b/hotspot/src/share/vm/opto/loopTransform.cpp +index 2edc6f8e4..3148e5cae 100644 +--- a/hotspot/src/share/vm/opto/loopTransform.cpp ++++ b/hotspot/src/share/vm/opto/loopTransform.cpp +@@ -1226,21 +1226,14 @@ void PhaseIdealLoop::do_unroll( IdealLoopTree *loop, Node_List &old_new, bool ad + + Node *opaq = NULL; + if (adjust_min_trip) { // If not maximally unrolling, need adjustment +- // Search for zero-trip guard. +- assert( loop_head->is_main_loop(), "" ); +- assert( ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse, "" ); +- Node *iff = ctrl->in(0); +- assert( iff->Opcode() == Op_If, "" ); +- Node *bol = iff->in(1); +- assert( bol->Opcode() == Op_Bool, "" ); +- Node *cmp = bol->in(1); +- assert( cmp->Opcode() == Op_CmpI, "" ); +- opaq = cmp->in(2); +- // Occasionally it's possible for a zero-trip guard Opaque1 node to be +- // optimized away and then another round of loop opts attempted. +- // We can not optimize this particular loop in that case. +- if (opaq->Opcode() != Op_Opaque1) +- return; // Cannot find zero-trip guard! Bail out! ++ // Check the shape of the graph at the loop entry. If an inappropriate ++ // graph shape is encountered, the compiler bails out loop unrolling; ++ // compilation of the method will still succeed. ++ if (!is_canonical_main_loop_entry(loop_head)) { ++ return; ++ } ++ // get a not shared opaque' node for Zero-trip test ++ opaq = ctrl->in(0)->in(1)->in(1)->in(2); + // Zero-trip test uses an 'opaque' node which is not shared. + assert(opaq->outcnt() == 1 && opaq->in(1) == limit, ""); + } +@@ -1810,7 +1803,6 @@ void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) { + #endif + assert(RangeCheckElimination, ""); + CountedLoopNode *cl = loop->_head->as_CountedLoop(); +- assert(cl->is_main_loop(), ""); + + // protect against stride not being a constant + if (!cl->stride_is_con()) +@@ -1822,20 +1814,18 @@ void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) { + // to not ever trip end tests + Node *main_limit = cl->limit(); + ++ // Check graph shape. Cannot optimize a loop if zero-trip ++ // Opaque1 node is optimized away and then another round ++ // of loop opts attempted. ++ if (!is_canonical_main_loop_entry(cl)) { ++ return; ++ } ++ + // Need to find the main-loop zero-trip guard + Node *ctrl = cl->in(LoopNode::EntryControl); +- assert(ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse, ""); + Node *iffm = ctrl->in(0); +- assert(iffm->Opcode() == Op_If, ""); +- Node *bolzm = iffm->in(1); +- assert(bolzm->Opcode() == Op_Bool, ""); +- Node *cmpzm = bolzm->in(1); +- assert(cmpzm->is_Cmp(), ""); +- Node *opqzm = cmpzm->in(2); +- // Can not optimize a loop if zero-trip Opaque1 node is optimized +- // away and then another round of loop opts attempted. +- if (opqzm->Opcode() != Op_Opaque1) +- return; ++ // get the zero-trip Opaque1 node for testing the main limits ++ Node *opqzm = iffm->in(1)->in(1)->in(2); + assert(opqzm->in(1) == main_limit, "do not understand situation"); + + // Find the pre-loop limit; we will expand it's iterations to +diff --git a/hotspot/src/share/vm/opto/loopnode.cpp b/hotspot/src/share/vm/opto/loopnode.cpp +index ce0a7393d..ef845ca93 100644 +--- a/hotspot/src/share/vm/opto/loopnode.cpp ++++ b/hotspot/src/share/vm/opto/loopnode.cpp +@@ -3278,6 +3278,42 @@ Node* PhaseIdealLoop::compute_lca_of_uses(Node* n, Node* early, bool verify) { + return LCA; + } + ++// Check the shape of the graph at the loop entry. In some cases, ++// the shape of the graph does not match the shape outlined below. ++// That is caused by the Opaque1 node "protecting" the shape of ++// the graph being removed by, for example, the IGVN performed ++// in PhaseIdealLoop::build_and_optimize(). ++// ++// After the Opaque1 node has been removed, optimizations (e.g., split-if, ++// loop unswitching, and IGVN, or a combination of them) can freely change ++// the graph's shape. As a result, the graph shape outlined below cannot ++// be guaranteed anymore. ++bool PhaseIdealLoop::is_canonical_main_loop_entry(CountedLoopNode* cl) { ++ assert(cl->is_main_loop(), "check should be applied to main loops"); ++ Node* ctrl = cl->in(LoopNode::EntryControl); ++ if (ctrl == NULL || (!ctrl->is_IfTrue() && !ctrl->is_IfFalse())) { ++ return false; ++ } ++ Node* iffm = ctrl->in(0); ++ if (iffm == NULL || !iffm->is_If()) { ++ return false; ++ } ++ Node* bolzm = iffm->in(1); ++ if (bolzm == NULL || !bolzm->is_Bool()) { ++ return false; ++ } ++ Node* cmpzm = bolzm->in(1); ++ if (cmpzm == NULL || !cmpzm->is_Cmp()) { ++ return false; ++ } ++ // get the compare node, if null or not return false ++ Node* opqzm = cmpzm->in(2); ++ if (opqzm == NULL || opqzm->Opcode() != Op_Opaque1) { ++ return false; ++ } ++ return true; ++} ++ + //------------------------------get_late_ctrl---------------------------------- + // Compute latest legal control. + Node *PhaseIdealLoop::get_late_ctrl( Node *n, Node *early ) { +diff --git a/hotspot/src/share/vm/opto/loopnode.hpp b/hotspot/src/share/vm/opto/loopnode.hpp +index aba285205..24926d047 100644 +--- a/hotspot/src/share/vm/opto/loopnode.hpp ++++ b/hotspot/src/share/vm/opto/loopnode.hpp +@@ -620,6 +620,9 @@ private: + bool cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop); + + public: ++ ++ static bool is_canonical_main_loop_entry(CountedLoopNode* cl); ++ + bool has_node( Node* n ) const { + guarantee(n != NULL, "No Node."); + return _nodes[n->_idx] != NULL; +diff --git a/hotspot/src/share/vm/opto/superword.cpp b/hotspot/src/share/vm/opto/superword.cpp +index 543ffc035..53878000f 100644 +--- a/hotspot/src/share/vm/opto/superword.cpp ++++ b/hotspot/src/share/vm/opto/superword.cpp +@@ -2208,15 +2208,18 @@ void SuperWord::align_initial_loop_index(MemNode* align_to_ref) { + //----------------------------get_pre_loop_end--------------------------- + // Find pre loop end from main loop. Returns null if none. + CountedLoopEndNode* SuperWord::get_pre_loop_end(CountedLoopNode *cl) { +- Node *ctrl = cl->in(LoopNode::EntryControl); +- if (!ctrl->is_IfTrue() && !ctrl->is_IfFalse()) return NULL; +- Node *iffm = ctrl->in(0); +- if (!iffm->is_If()) return NULL; +- Node *p_f = iffm->in(0); ++ // The loop cannot be optimized if the graph shape at ++ // the loop entry is inappropriate. ++ if (!PhaseIdealLoop::is_canonical_main_loop_entry(cl)) { ++ return NULL; ++ } ++ ++ Node* p_f = cl->in(LoopNode::EntryControl)->in(0)->in(0); + if (!p_f->is_IfFalse()) return NULL; + if (!p_f->in(0)->is_CountedLoopEnd()) return NULL; +- CountedLoopEndNode *pre_end = p_f->in(0)->as_CountedLoopEnd(); +- if (!pre_end->loopnode()->is_pre_loop()) return NULL; ++ CountedLoopEndNode* pre_end = p_f->in(0)->as_CountedLoopEnd(); ++ CountedLoopNode* loop_node = pre_end->loopnode(); ++ if (loop_node == NULL || !loop_node->is_pre_loop()) return NULL; + return pre_end; + } + +-- +2.19.0 + diff --git a/8151788.patch b/8151788.patch new file mode 100644 index 0000000000000000000000000000000000000000..14480afb1dbf263b3b681bc0b30f535105c03b5a --- /dev/null +++ b/8151788.patch @@ -0,0 +1,94 @@ +From bf24abe7a9499638a43dfd03fecfbfb763430a63 Mon Sep 17 00:00:00 2001 +From: hexuejin +Date: Thu, 27 Jun 2019 11:24:39 +0000 +Subject: [PATCH] Backport of JDK-8151788 + +summary: NullPointerException from ntlm.Client.type3 +LLT: +Bug url: https://bugs.openjdk.java.net/browse/JDK-8151788 +--- + .../classes/com/sun/security/ntlm/NTLM.java | 2 +- + .../www/protocol/http/NULLTargetInfoTest.java | 58 +++++++++++++++++++ + 2 files changed, 59 insertions(+), 1 deletion(-) + create mode 100644 jdk/test/sun/net/www/protocol/http/NULLTargetInfoTest.java + +diff --git a/jdk/src/share/classes/com/sun/security/ntlm/NTLM.java b/jdk/src/share/classes/com/sun/security/ntlm/NTLM.java +index da18e2199a..249cd226c4 100644 +--- a/jdk/src/share/classes/com/sun/security/ntlm/NTLM.java ++++ b/jdk/src/share/classes/com/sun/security/ntlm/NTLM.java +@@ -167,7 +167,7 @@ class NTLM { + + byte[] readSecurityBuffer(int offset) throws NTLMException { + int pos = readInt(offset+4); +- if (pos == 0) return null; ++ if (pos == 0) return new byte[0]; + try { + return Arrays.copyOfRange( + internal, pos, pos + readShort(offset)); +diff --git a/jdk/test/sun/net/www/protocol/http/NULLTargetInfoTest.java b/jdk/test/sun/net/www/protocol/http/NULLTargetInfoTest.java +new file mode 100644 +index 0000000000..d8e88554f8 +--- /dev/null ++++ b/jdk/test/sun/net/www/protocol/http/NULLTargetInfoTest.java +@@ -0,0 +1,58 @@ ++/* ++ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++ ++/* ++ * @test ++ * @bug 8151788 ++ * @summary NullPointerException from ntlm.Client.type3 ++ * @modules java.base/com.sun.security.ntlm ++ * @run main NULLTargetInfoTest ++ */ ++import com.sun.security.ntlm.Client; ++ ++public class NULLTargetInfoTest { ++ ++ public static void main(String[] args) throws Exception { ++ Client c = new Client(null, "host", "user", "domain", "pass".toCharArray()); ++ c.type1(); ++ // this input does have the 0x800000 bit(NTLMSSP_NEGOTIATE_TARGET_INFO) set ++ // but after offset 40 all eight bytes are all zero which means there is no ++ // security buffer for target info. ++ byte[] type2 = hex( ++ "4E 54 4C 4D 53 53 50 00 02 00 00 00 00 00 00 00" ++ + "00 00 00 00 05 82 89 00 0B 87 81 B6 2D 6E 8B C1" ++ + "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"); ++ byte[] nonce = new byte[10]; ++ c.type3(type2, nonce); ++ } ++ ++ private static byte[] hex(String str) { ++ str = str.replaceAll("\\s", ""); ++ byte[] response = new byte[str.length() / 2]; ++ int index = 0; ++ for (int i = 0; i < str.length(); i += 2) { ++ response[index++] = Integer.valueOf(str.substring(i, i + 2), 16).byteValue(); ++ } ++ return response; ++ } ++} +-- +2.19.0-rc1 + diff --git a/8154313.patch b/8154313.patch new file mode 100644 index 0000000000000000000000000000000000000000..78bfa6a241a4fca45c1c16e9059d85c31053691e --- /dev/null +++ b/8154313.patch @@ -0,0 +1,68 @@ +--- a/make/Javadoc.gmk 2016-04-01 16:53:41.069477682 +0200 ++++ b/make/Javadoc.gmk 2016-04-01 16:53:41.014477059 +0200 +@@ -220,6 +220,12 @@ + JRE_API_DOCSDIR = $(DOCSDIR)/jre/api + PLATFORM_DOCSDIR = $(DOCSDIR)/platform + ++ ++JAVADOC_ARCHIVE_NAME := jdk-$(FULL_VERSION)-docs.zip ++JAVADOC_ARCHIVE_ASSEMBLY_DIR := $(DOCSTMPDIR)/zip-docs ++JAVADOC_ARCHIVE_DIR := $(OUTPUT_ROOT)/bundles ++JAVADOC_ARCHIVE := $(JAVADOC_ARCHIVE_DIR)/$(JAVADOC_ARCHIVE_NAME) ++ + # The non-core api javadocs need to be able to access the root of the core + # api directory, so for jdk/api or jre/api to get to the core api/ + # directory we would use this: +@@ -319,6 +325,37 @@ + all: docs + docs: coredocs otherdocs + ++# ++# Optional target which bundles all generated javadocs into a zip ++# archive. The dependency on docs is handled in Main.gmk. Incremental ++# building of docs is currently broken so if you invoke zip-docs after ++# docs, the docs are always rebuilt. ++# ++ ++zip-docs: $(JAVADOC_ARCHIVE) ++ ++# ++# Add the core docs as prerequisite to the archive to trigger a rebuild ++# if the core docs were rebuilt. Ideally any doc rebuild should trigger ++# this, but the way prerequisites are currently setup in this file, that ++# is hard to achieve. ++# ++ ++$(JAVADOC_ARCHIVE): $(COREAPI_INDEX_FILE) ++ @$(ECHO) "Compressing javadoc to single $(JAVADOC_ARCHIVE_NAME)" ; ++ $(MKDIR) -p $(JAVADOC_ARCHIVE_DIR) ; ++ $(RM) -r $(JAVADOC_ARCHIVE_ASSEMBLY_DIR) ; ++ $(MKDIR) -p $(JAVADOC_ARCHIVE_ASSEMBLY_DIR); ++ all_roots=`$(FIND) $(DOCSDIR) | $(GREP) index.html `; \ ++ pushd $(JAVADOC_ARCHIVE_ASSEMBLY_DIR); \ ++ for index_file in $${all_roots} ; do \ ++ target_dir=`dirname $${index_file}`; \ ++ name=`$(ECHO) $${target_dir} | $(SED) "s;/spec;;" | $(SED) "s;.*/;;"`; \ ++ $(LN) -s $${target_dir} $${name}; \ ++ done; \ ++ $(ZIP) -q -r $(JAVADOC_ARCHIVE) * ; \ ++ popd ; ++ + ################################################################# + # Production Targets -- USE THESE TARGETS WHEN: + # a) You're generating docs outside of release engineering's +--- a/make/Main.gmk 2016-04-01 16:53:41.311480424 +0200 ++++ b/make/Main.gmk 2016-04-01 16:53:41.266479914 +0200 +@@ -165,6 +165,12 @@ + @($(CD) $(SRC_ROOT)/make && $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) -f Javadoc.gmk docs) + @$(call TargetExit) + ++zip-docs: docs zip-docs-only ++zip-docs-only: start-make ++ @$(call TargetEnter) ++ @($(CD) $(SRC_ROOT)/make && $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) -f Javadoc.gmk zip-docs) ++ @$(call TargetExit) ++ + sign-jars: jdk sign-jars-only + sign-jars-only: start-make + @$(call TargetEnter) diff --git a/8157570.patch b/8157570.patch new file mode 100644 index 0000000000000000000000000000000000000000..ee121784678f074074432aa745846e6dbd6f2ba0 --- /dev/null +++ b/8157570.patch @@ -0,0 +1,70 @@ +From 58fcf0eb2ce3e74334ef124116a6e8f429ee9ae4 Mon Sep 17 00:00:00 2001 +From: hexuejin +Date: Thu, 27 Jun 2019 11:04:38 +0000 +Subject: [PATCH] Backport of JDK-8157570 + +summary: sun.rmi.transport.GC retains a strong reference to the context class loader +LLT: +Bug url: https://bugs.openjdk.java.net/browse/JDK-8157570 +--- + jdk/src/share/classes/sun/misc/GC.java | 26 +++++++++++--------------- + 1 file changed, 11 insertions(+), 15 deletions(-) + +diff --git a/jdk/src/share/classes/sun/misc/GC.java b/jdk/src/share/classes/sun/misc/GC.java +index c77bf1d055..eb92617c19 100644 +--- a/jdk/src/share/classes/sun/misc/GC.java ++++ b/jdk/src/share/classes/sun/misc/GC.java +@@ -29,6 +29,7 @@ import java.security.AccessController; + import java.security.PrivilegedAction; + import java.util.SortedSet; + import java.util.TreeSet; ++import sun.misc.InnocuousThread; + + + /** +@@ -83,8 +84,9 @@ public class GC { + public static native long maxObjectInspectionAge(); + + +- private static class Daemon extends Thread { ++ private static class Daemon implements Runnable { + ++ @Override + public void run() { + for (;;) { + long l; +@@ -122,23 +124,17 @@ public class GC { + } + } + +- private Daemon(ThreadGroup tg) { +- super(tg, "GC Daemon"); +- } +- +- /* Create a new daemon thread in the root thread group */ ++ /* Create a new daemon thread */ + public static void create() { + PrivilegedAction pa = new PrivilegedAction() { + public Void run() { +- ThreadGroup tg = Thread.currentThread().getThreadGroup(); +- for (ThreadGroup tgn = tg; +- tgn != null; +- tg = tgn, tgn = tg.getParent()); +- Daemon d = new Daemon(tg); +- d.setDaemon(true); +- d.setPriority(Thread.MIN_PRIORITY + 1); +- d.start(); +- GC.daemon = d; ++ Thread t = InnocuousThread.newSystemThread("RMI GC Daemon", ++ new Daemon()); ++ assert t.getContextClassLoader() == null; ++ t.setDaemon(true); ++ t.setPriority(Thread.MIN_PRIORITY + 1); ++ t.start(); ++ GC.daemon = t; + return null; + }}; + AccessController.doPrivileged(pa); +-- +2.19.0 + diff --git a/8158946-JDK-8165808-JDK-8166583-JDK-.patch b/8158946-JDK-8165808-JDK-8166583-JDK-.patch new file mode 100644 index 0000000000000000000000000000000000000000..21f4341460c63ecdf2d76dc1b6da5c675aa2cd64 --- /dev/null +++ b/8158946-JDK-8165808-JDK-8166583-JDK-.patch @@ -0,0 +1,436 @@ +From 213dd3425bd0681a0ad4ed3c5f004898be645d86 Mon Sep 17 00:00:00 2001 +From: wangshuai +Date: Thu, 15 Aug 2019 11:15:18 +0000 +Subject: [PATCH] Backport of JDK-8158946 JDK-8165808 JDK-8166583 JDK-8166862 + +summary: Add release barriers when allocating objects with concurrent collection && CMS needs klass_or_null_acquire +LLT: + +Bug url: https://bugs.openjdk.java.net/browse/JDK-8158946 https://bugs.openjdk.java.net/browse/JDK-8165808 https://bugs.openjdk.java.net/browse/JDK-8166583 https://bugs.openjdk.java.net/browse/JDK-8166862 +--- + hotspot/src/share/vm/classfile/javaClasses.cpp | 6 ++- + .../compactibleFreeListSpace.cpp | 23 ++------- + .../concurrentMarkSweepGeneration.cpp | 16 +++---- + .../src/share/vm/gc_interface/collectedHeap.cpp | 16 +++++++ + .../src/share/vm/gc_interface/collectedHeap.hpp | 6 +-- + .../share/vm/gc_interface/collectedHeap.inline.hpp | 54 ++++++++++++---------- + hotspot/src/share/vm/oops/instanceMirrorKlass.cpp | 7 ++- + hotspot/src/share/vm/oops/oop.hpp | 2 + + hotspot/src/share/vm/oops/oop.inline.hpp | 38 ++++++++++++--- + 9 files changed, 104 insertions(+), 64 deletions(-) + +diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp +index a9b40d235e..cd28c758d0 100644 +--- a/hotspot/src/share/vm/classfile/javaClasses.cpp ++++ b/hotspot/src/share/vm/classfile/javaClasses.cpp +@@ -649,10 +649,14 @@ void java_lang_Class::create_mirror(KlassHandle k, Handle class_loader, + + int java_lang_Class::oop_size(oop java_class) { + assert(_oop_size_offset != 0, "must be set"); +- return java_class->int_field(_oop_size_offset); ++ int size = java_class->int_field(_oop_size_offset); ++ assert(size > 0, "Oop size must be greater than zero"); ++ return size; ++ + } + void java_lang_Class::set_oop_size(oop java_class, int size) { + assert(_oop_size_offset != 0, "must be set"); ++ assert(size > 0, "Oop size must be greater than zero"); + java_class->int_field_put_raw(_oop_size_offset, size); + } + int java_lang_Class::static_oop_field_count(oop java_class) { +diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp +index e5a3a11069..2de68f7aeb 100644 +--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp ++++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp +@@ -984,18 +984,13 @@ size_t CompactibleFreeListSpace::block_size(const HeapWord* p) const { + return res; + } + } else { +- // must read from what 'p' points to in each loop. +- Klass* k = ((volatile oopDesc*)p)->klass_or_null(); ++ // Ensure klass read before size. ++ Klass* k = oop(p)->klass_or_null_acquire(); + if (k != NULL) { + assert(k->is_klass(), "Should really be klass oop."); + oop o = (oop)p; + assert(o->is_oop(true /* ignore mark word */), "Should be an oop."); + +- // Bugfix for systems with weak memory model (PPC64/IA64). +- // The object o may be an array. Acquire to make sure that the array +- // size (third word) is consistent. +- OrderAccess::acquire(); +- + size_t res = o->size_given_klass(k); + res = adjustObjectSize(res); + assert(res != 0, "Block size should not be 0"); +@@ -1039,21 +1034,13 @@ const { + return res; + } + } else { +- // must read from what 'p' points to in each loop. +- Klass* k = ((volatile oopDesc*)p)->klass_or_null(); +- // We trust the size of any object that has a non-NULL +- // klass and (for those in the perm gen) is parsable +- // -- irrespective of its conc_safe-ty. ++ // Ensure klass read before size. ++ Klass* k = oop(p)->klass_or_null_acquire(); + if (k != NULL) { + assert(k->is_klass(), "Should really be klass oop."); + oop o = (oop)p; + assert(o->is_oop(), "Should be an oop"); + +- // Bugfix for systems with weak memory model (PPC64/IA64). +- // The object o may be an array. Acquire to make sure that the array +- // size (third word) is consistent. +- OrderAccess::acquire(); +- + size_t res = o->size_given_klass(k); + res = adjustObjectSize(res); + assert(res != 0, "Block size should not be 0"); +@@ -1101,7 +1088,7 @@ bool CompactibleFreeListSpace::block_is_obj(const HeapWord* p) const { + // assert(CollectedHeap::use_parallel_gc_threads() || _bt.block_start(p) == p, + // "Should be a block boundary"); + if (FreeChunk::indicatesFreeChunk(p)) return false; +- Klass* k = oop(p)->klass_or_null(); ++ Klass* k = oop(p)->klass_or_null_acquire(); + if (k != NULL) { + // Ignore mark word because it may have been used to + // chain together promoted objects (the last one +diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +index 2d7791138c..e3fdb6cf89 100644 +--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp ++++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +@@ -6715,7 +6715,7 @@ size_t CMSCollector::block_size_if_printezis_bits(HeapWord* addr) const { + HeapWord* CMSCollector::next_card_start_after_block(HeapWord* addr) const { + size_t sz = 0; + oop p = (oop)addr; +- if (p->klass_or_null() != NULL) { ++ if (p->klass_or_null_acquire() != NULL) { + sz = CompactibleFreeListSpace::adjustObjectSize(p->size()); + } else { + sz = block_size_using_printezis_bits(addr); +@@ -7173,7 +7173,7 @@ size_t ScanMarkedObjectsAgainCarefullyClosure::do_object_careful_m( + } + if (_bitMap->isMarked(addr)) { + // it's marked; is it potentially uninitialized? +- if (p->klass_or_null() != NULL) { ++ if (p->klass_or_null_acquire() != NULL) { + // an initialized object; ignore mark word in verification below + // since we are running concurrent with mutators + assert(p->is_oop(true), "should be an oop"); +@@ -7214,7 +7214,7 @@ size_t ScanMarkedObjectsAgainCarefullyClosure::do_object_careful_m( + } + } else { + // Either a not yet marked object or an uninitialized object +- if (p->klass_or_null() == NULL) { ++ if (p->klass_or_null_acquire() == NULL) { + // An uninitialized object, skip to the next card, since + // we may not be able to read its P-bits yet. + assert(size == 0, "Initial value"); +@@ -7425,7 +7425,7 @@ bool MarkFromRootsClosure::do_bit(size_t offset) { + assert(_skipBits == 0, "tautology"); + _skipBits = 2; // skip next two marked bits ("Printezis-marks") + oop p = oop(addr); +- if (p->klass_or_null() == NULL) { ++ if (p->klass_or_null_acquire() == NULL) { + DEBUG_ONLY(if (!_verifying) {) + // We re-dirty the cards on which this object lies and increase + // the _threshold so that we'll come back to scan this object +@@ -7445,7 +7445,7 @@ bool MarkFromRootsClosure::do_bit(size_t offset) { + if (_threshold < end_card_addr) { + _threshold = end_card_addr; + } +- if (p->klass_or_null() != NULL) { ++ if (p->klass_or_null_acquire() != NULL) { + // Redirty the range of cards... + _mut->mark_range(redirty_range); + } // ...else the setting of klass will dirty the card anyway. +@@ -7596,7 +7596,7 @@ bool Par_MarkFromRootsClosure::do_bit(size_t offset) { + assert(_skip_bits == 0, "tautology"); + _skip_bits = 2; // skip next two marked bits ("Printezis-marks") + oop p = oop(addr); +- if (p->klass_or_null() == NULL) { ++ if (p->klass_or_null_acquire() == NULL) { + // in the case of Clean-on-Enter optimization, redirty card + // and avoid clearing card by increasing the threshold. + return true; +@@ -8583,7 +8583,7 @@ size_t SweepClosure::do_live_chunk(FreeChunk* fc) { + "alignment problem"); + + #ifdef ASSERT +- if (oop(addr)->klass_or_null() != NULL) { ++ if (oop(addr)->klass_or_null_acquire() != NULL) { + // Ignore mark word because we are running concurrent with mutators + assert(oop(addr)->is_oop(true), "live block should be an oop"); + assert(size == +@@ -8594,7 +8594,7 @@ size_t SweepClosure::do_live_chunk(FreeChunk* fc) { + + } else { + // This should be an initialized object that's alive. +- assert(oop(addr)->klass_or_null() != NULL, ++ assert(oop(addr)->klass_or_null_acquire() != NULL, + "Should be an initialized object"); + // Ignore mark word because we are running concurrent with mutators + assert(oop(addr)->is_oop(true), "live block should be an oop"); +diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp +index 4f5e93bbe2..90207a8a4d 100644 +--- a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp ++++ b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp +@@ -305,6 +305,22 @@ HeapWord* CollectedHeap::allocate_from_tlab_slow(KlassHandle klass, Thread* thre + return Universe::heap()->tlab_post_allocation_setup(obj); + } + ++void CollectedHeap::post_allocation_setup_class(KlassHandle klass, ++ HeapWord* obj_ptr, ++ int size) { ++ // Set oop_size field before setting the _klass field because a ++ // non-NULL _klass field indicates that the object is parsable by ++ // concurrent GC. ++ oop new_cls = (oop)obj_ptr; ++ assert(size > 0, "oop_size must be positive."); ++ java_lang_Class::set_oop_size(new_cls, size); ++ post_allocation_setup_common(klass, obj_ptr); ++ assert(Universe::is_bootstrapping() || ++ !new_cls->is_array(), "must not be an array"); ++ // notify jvmti and dtrace ++ post_allocation_notify(klass, new_cls, size); ++} ++ + void CollectedHeap::flush_deferred_store_barrier(JavaThread* thread) { + MemRegion deferred = thread->deferred_card_mark(); + if (!deferred.is_empty()) { +diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp +index 03956b036b..48fd7e7c0a 100644 +--- a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp ++++ b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp +@@ -157,6 +157,8 @@ class CollectedHeap : public CHeapObj { + inline static void post_allocation_setup_array(KlassHandle klass, + HeapWord* obj, int length); + ++ static void post_allocation_setup_class(KlassHandle klass, HeapWord* obj, int size); ++ + // Clears an allocated object. + inline static void init_obj(HeapWord* obj, size_t size); + +@@ -323,9 +325,7 @@ class CollectedHeap : public CHeapObj { + inline static oop obj_allocate(KlassHandle klass, int size, TRAPS); + inline static oop array_allocate(KlassHandle klass, int size, int length, TRAPS); + inline static oop array_allocate_nozero(KlassHandle klass, int size, int length, TRAPS); +- +- inline static void post_allocation_install_obj_klass(KlassHandle klass, +- oop obj); ++ inline static oop class_allocate(KlassHandle klass, int size, TRAPS); + + virtual uint oop_extra_words(); + +diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp b/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp +index 9f3b885a9e..17e02c8f90 100644 +--- a/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp ++++ b/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp +@@ -39,14 +39,22 @@ + // Inline allocation implementations. + + void CollectedHeap::post_allocation_setup_common(KlassHandle klass, +- HeapWord* obj) { +- post_allocation_setup_no_klass_install(klass, obj); +- post_allocation_install_obj_klass(klass, oop(obj)); ++ HeapWord* obj_ptr) { ++ post_allocation_setup_no_klass_install(klass, obj_ptr); ++ oop obj = (oop)obj_ptr; ++#if ! INCLUDE_ALL_GCS ++ obj->set_klass(klass()); ++#else ++ // Need a release store to ensure array/class length, mark word, and ++ // object zeroing are visible before setting the klass non-NULL, for ++ // concurrent collectors. ++ obj->release_set_klass(klass()); ++#endif + } + + void CollectedHeap::post_allocation_setup_no_klass_install(KlassHandle klass, +- HeapWord* objPtr) { +- oop obj = (oop)objPtr; ++ HeapWord* obj_ptr) { ++ oop obj = (oop)obj_ptr; + + assert(obj != NULL, "NULL object pointer"); + if (UseBiasedLocking && (klass() != NULL)) { +@@ -57,18 +65,6 @@ void CollectedHeap::post_allocation_setup_no_klass_install(KlassHandle klass, + } + } + +-void CollectedHeap::post_allocation_install_obj_klass(KlassHandle klass, +- oop obj) { +- // These asserts are kind of complicated because of klassKlass +- // and the beginning of the world. +- assert(klass() != NULL || !Universe::is_fully_initialized(), "NULL klass"); +- assert(klass() == NULL || klass()->is_klass(), "not a klass"); +- assert(obj != NULL, "NULL object pointer"); +- obj->set_klass(klass()); +- assert(!Universe::is_fully_initialized() || obj->klass() != NULL, +- "missing klass"); +-} +- + // Support for jvmti and dtrace + inline void post_allocation_notify(KlassHandle klass, oop obj, int size) { + // support low memory notifications (no-op if not enabled) +@@ -96,15 +92,15 @@ void CollectedHeap::post_allocation_setup_obj(KlassHandle klass, + } + + void CollectedHeap::post_allocation_setup_array(KlassHandle klass, +- HeapWord* obj, ++ HeapWord* obj_ptr, + int length) { +- // Set array length before setting the _klass field +- // in post_allocation_setup_common() because the klass field +- // indicates that the object is parsable by concurrent GC. ++ // Set array length before setting the _klass field because a ++ // non-NULL klass field indicates that the object is parsable by ++ // concurrent GC. + assert(length >= 0, "length should be non-negative"); +- ((arrayOop)obj)->set_length(length); +- post_allocation_setup_common(klass, obj); +- oop new_obj = (oop)obj; ++ ((arrayOop)obj_ptr)->set_length(length); ++ post_allocation_setup_common(klass, obj_ptr); ++ oop new_obj = (oop)obj_ptr; + assert(new_obj->is_array(), "must be an array"); + // notify jvmti and dtrace (must be after length is set for dtrace) + post_allocation_notify(klass, new_obj, new_obj->size()); +@@ -208,6 +204,16 @@ oop CollectedHeap::obj_allocate(KlassHandle klass, int size, TRAPS) { + return (oop)obj; + } + ++oop CollectedHeap::class_allocate(KlassHandle klass, int size, TRAPS) { ++ debug_only(check_for_valid_allocation_state()); ++ assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed"); ++ assert(size >= 0, "int won't convert to size_t"); ++ HeapWord* obj = common_mem_allocate_init(klass, size, CHECK_NULL); ++ post_allocation_setup_class(klass, obj, size); // set oop_size ++ NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size)); ++ return (oop)obj; ++} ++ + oop CollectedHeap::array_allocate(KlassHandle klass, + int size, + int length, +diff --git a/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp b/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp +index 5b4c7d0fd2..73da78e5a8 100644 +--- a/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp ++++ b/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp +@@ -363,13 +363,12 @@ instanceOop InstanceMirrorKlass::allocate_instance(KlassHandle k, TRAPS) { + // Query before forming handle. + int size = instance_size(k); + KlassHandle h_k(THREAD, this); +- instanceOop i = (instanceOop)CollectedHeap::obj_allocate(h_k, size, CHECK_NULL); ++ ++ assert(size > 0, "total object size must be positive"); + + // Since mirrors can be variable sized because of the static fields, store + // the size in the mirror itself. +- java_lang_Class::set_oop_size(i, size); +- +- return i; ++ return (instanceOop)CollectedHeap::class_allocate(h_k, size, CHECK_NULL); + } + + int InstanceMirrorKlass::oop_size(oop obj) const { +diff --git a/hotspot/src/share/vm/oops/oop.hpp b/hotspot/src/share/vm/oops/oop.hpp +index 1643ba9f55..c8d1f99183 100644 +--- a/hotspot/src/share/vm/oops/oop.hpp ++++ b/hotspot/src/share/vm/oops/oop.hpp +@@ -104,10 +104,12 @@ class oopDesc { + + Klass* klass() const; + Klass* klass_or_null() const volatile; ++ inline Klass* klass_or_null_acquire() const volatile; + Klass** klass_addr(); + narrowKlass* compressed_klass_addr(); + + void set_klass(Klass* k); ++ inline void release_set_klass(Klass* k); + + // For klass field compression + int klass_gap() const; +diff --git a/hotspot/src/share/vm/oops/oop.inline.hpp b/hotspot/src/share/vm/oops/oop.inline.hpp +index 535a7a8953..5d47e3f4dc 100644 +--- a/hotspot/src/share/vm/oops/oop.inline.hpp ++++ b/hotspot/src/share/vm/oops/oop.inline.hpp +@@ -97,7 +97,6 @@ inline Klass* oopDesc::klass() const { + } + + inline Klass* oopDesc::klass_or_null() const volatile { +- // can be NULL in CMS + if (UseCompressedClassPointers) { + return Klass::decode_klass(_metadata._compressed_klass); + } else { +@@ -110,6 +109,17 @@ inline int oopDesc::klass_gap_offset_in_bytes() { + return oopDesc::klass_offset_in_bytes() + sizeof(narrowKlass); + } + ++Klass* oopDesc::klass_or_null_acquire() const volatile { ++ if (UseCompressedClassPointers) { ++ // Workaround for non-const load_acquire parameter. ++ const volatile narrowKlass* addr = &_metadata._compressed_klass; ++ volatile narrowKlass* xaddr = const_cast(addr); ++ return Klass::decode_klass(OrderAccess::load_acquire(xaddr)); ++ } else { ++ return (Klass*)OrderAccess::load_ptr_acquire(&_metadata._klass); ++ } ++} ++ + inline Klass** oopDesc::klass_addr() { + // Only used internally and with CMS and will not work with + // UseCompressedOops +@@ -122,10 +132,14 @@ inline narrowKlass* oopDesc::compressed_klass_addr() { + return &_metadata._compressed_klass; + } + ++#define CHECK_SET_KLASS(k) \ ++ do { \ ++ assert(Universe::is_bootstrapping() || k != NULL, "NULL Klass"); \ ++ assert(Universe::is_bootstrapping() || k->is_klass(), "not a Klass"); \ ++ } while (0) ++ + inline void oopDesc::set_klass(Klass* k) { +- // since klasses are promoted no store check is needed +- assert(Universe::is_bootstrapping() || k != NULL, "must be a real Klass*"); +- assert(Universe::is_bootstrapping() || k->is_klass(), "not a Klass*"); ++ CHECK_SET_KLASS(k); + if (UseCompressedClassPointers) { + *compressed_klass_addr() = Klass::encode_klass_not_null(k); + } else { +@@ -133,6 +147,18 @@ inline void oopDesc::set_klass(Klass* k) { + } + } + ++void oopDesc::release_set_klass(Klass* k) { ++ CHECK_SET_KLASS(k); ++ if (UseCompressedClassPointers) { ++ OrderAccess::release_store(compressed_klass_addr(), ++ Klass::encode_klass_not_null(k)); ++ } else { ++ OrderAccess::release_store_ptr(klass_addr(), k); ++ } ++} ++ ++#undef CHECK_SET_KLASS ++ + inline int oopDesc::klass_gap() const { + return *(int*)(((intptr_t)this) + klass_gap_offset_in_bytes()); + } +@@ -805,8 +831,8 @@ inline int oopDesc::size_given_klass(Klass* klass) { + } + } + +- assert(s % MinObjAlignment == 0, "alignment check"); +- assert(s > 0, "Bad size calculated"); ++ assert(s % MinObjAlignment == 0, "Oop size is not properly aligned"); ++ assert(s > 0, "Oop size must be greater than zero"); + return s; + } + +-- +2.12.3 + diff --git a/8160300.patch b/8160300.patch new file mode 100644 index 0000000000000000000000000000000000000000..f78c9ab832f966439a07da0fb8ffc701dd421ec3 --- /dev/null +++ b/8160300.patch @@ -0,0 +1,327 @@ +From 51f5988d94ab3488080c4b9350b9d37b2ea19140 Mon Sep 17 00:00:00 2001 +From: guoge +Date: Fri, 19 Apr 2019 16:13:29 +0000 +Subject: [PATCH] 8160300: aarch32: JNI layer to initialize native nio constants + +Bug url: https://bugs.openjdk.java.net/browse/JDK-8160300 + +--- + jdk/make/gensrc/GensrcMisc.gmk | 4 + + jdk/make/lib/NioLibraries.gmk | 3 +- + jdk/make/mapfiles/libnio/mapfile-linux | 1 + + .../genconstants/fs/genCrossUnixConstants.c | 139 ++++++++++++++++++ + .../solaris/native/sun/nio/fs/UnixConstants.c | 114 ++++++++++++++ + 5 files changed, 260 insertions(+), 1 deletion(-) + create mode 100644 jdk/make/src/native/genconstants/fs/genCrossUnixConstants.c + create mode 100644 jdk/src/solaris/native/sun/nio/fs/UnixConstants.c + +diff --git a/jdk/make/gensrc/GensrcMisc.gmk b/jdk/make/gensrc/GensrcMisc.gmk +index 84a3c27e7d..02ca9ab7e0 100644 +--- a/jdk/make/gensrc/GensrcMisc.gmk ++++ b/jdk/make/gensrc/GensrcMisc.gmk +@@ -102,7 +102,11 @@ ifneq ($(OPENJDK_TARGET_OS), windows) + GENSRC_MISC += $(JDK_OUTPUTDIR)/gensrc/sun/nio/fs/UnixConstants.java + + GENSRC_UC_SRC := $(JDK_TOPDIR)/make/src/native/genconstants/fs ++ifneq ($(OPENJDK_TARGET_OS), linux) + GENSRC_UC_SRC_FILE := genUnixConstants.c ++else ++ GENSRC_UC_SRC_FILE := genCrossUnixConstants.c ++endif + GENSRC_UC_BIN := $(JDK_OUTPUTDIR)/btnative/genUnixConstants + + UC_COPYRIGHT_YEARS = $(shell $(CAT) $(GENSRC_UC_SRC)/$(GENSRC_UC_SRC_FILE) | \ +diff --git a/jdk/make/lib/NioLibraries.gmk b/jdk/make/lib/NioLibraries.gmk +index 6c9c46a3f3..3d6c9ffa30 100644 +--- a/jdk/make/lib/NioLibraries.gmk ++++ b/jdk/make/lib/NioLibraries.gmk +@@ -74,7 +74,8 @@ ifeq ($(OPENJDK_TARGET_OS), linux) + LinuxNativeDispatcher.c \ + LinuxWatchService.c \ + UnixCopyFile.c \ +- UnixNativeDispatcher.c ++ UnixNativeDispatcher.c \ ++ UnixConstants.c + endif + + ifeq ($(OPENJDK_TARGET_OS), macosx) +diff --git a/jdk/make/mapfiles/libnio/mapfile-linux b/jdk/make/mapfiles/libnio/mapfile-linux +index 30f795f6f5..3373a45a82 100644 +--- a/jdk/make/mapfiles/libnio/mapfile-linux ++++ b/jdk/make/mapfiles/libnio/mapfile-linux +@@ -201,6 +201,7 @@ SUNWprivate_1.1 { + Java_sun_nio_fs_UnixNativeDispatcher_getpwnam0; + Java_sun_nio_fs_UnixNativeDispatcher_getgrnam0; + Java_sun_nio_fs_UnixCopyFile_transfer; ++ Java_sun_nio_fs_UnixConstants_init; + handleSocketError; + + local: +diff --git a/jdk/make/src/native/genconstants/fs/genCrossUnixConstants.c b/jdk/make/src/native/genconstants/fs/genCrossUnixConstants.c +new file mode 100644 +index 0000000000..64e14592b4 +--- /dev/null ++++ b/jdk/make/src/native/genconstants/fs/genCrossUnixConstants.c +@@ -0,0 +1,139 @@ ++/* ++ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. Oracle designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Oracle in the LICENSE file that accompanied this code. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/** ++ * Generates sun.nio.fs.UnixConstants class ++ */ ++static const char* cnames[]={ ++ // open flags ++ "O_RDONLY", ++ "O_WRONLY", ++ "O_RDWR", ++ "O_APPEND", ++ "O_CREAT", ++ "O_EXCL", ++ "O_TRUNC", ++ "O_SYNC", ++ "O_DSYNC", ++ "O_NOFOLLOW", ++ // mode masks ++ "S_IRUSR", ++ "S_IWUSR", ++ "S_IXUSR", ++ "S_IRGRP", ++ "S_IWGRP", ++ "S_IXGRP", ++ "S_IROTH", ++ "S_IWOTH", ++ "S_IXOTH", ++ "S_IFMT", ++ "S_IFREG", ++ "S_IFDIR", ++ "S_IFLNK", ++ "S_IFCHR", ++ "S_IFBLK", ++ "S_IFIFO", ++ "S_IAMB", ++ // access modes ++ "R_OK", ++ "W_OK", ++ "X_OK", ++ "F_OK", ++ ++ // errors ++ "ENOENT", ++ "EACCES", ++ "EEXIST", ++ "ENOTDIR", ++ "EINVAL", ++ "EXDEV", ++ "EISDIR", ++ "ENOTEMPTY", ++ "ENOSPC", ++ "EAGAIN", ++ "ENOSYS", ++ "ELOOP", ++ "EROFS", ++ "ENODATA", ++ "ERANGE", ++ "EMFILE", ++ ++ // flags used with openat/unlinkat/etc. ++ "AT_SYMLINK_NOFOLLOW", ++ "AT_REMOVEDIR" ++}; ++static void out(const char* s) { ++ printf("%s\n", s); ++} ++ ++static void declTemp(const char* name) { ++ printf(" private static int p%s=0;\n",name); ++} ++ ++static void declConst(const char* name) { ++ printf(" static final int %s = p%s;\n", name, name); ++} ++ ++static void init() { ++ out(" private static native void init();"); ++ out(" static {"); ++ out(" AccessController.doPrivileged(new PrivilegedAction() {"); ++ out(" public Void run() {"); ++ out(" System.loadLibrary(\"nio\");"); ++ out(" return null;"); ++ out(" }});"); ++ out(" init();"); ++ out(" }"); ++} ++ ++int main(int argc, const char* argv[]) { ++ int i; ++ out("// AUTOMATICALLY GENERATED FILE - DO NOT EDIT "); ++ out("package sun.nio.fs; "); ++ out("import java.security.AccessController; "); ++ out("import java.security.PrivilegedAction; "); ++ out("class UnixConstants { "); ++ out(" private UnixConstants() { } "); ++ ++ // define private intermediate constants ++ for(i=0; i<(int)sizeof(cnames)/sizeof(cnames[0]);i++) ++ declTemp(cnames[i]); ++ ++ init(); ++ ++ // define real unix constants ++ for(i=0; i<(int)sizeof(cnames)/sizeof(cnames[0]);i++) ++ declConst(cnames[i]); ++ ++ out("} "); ++ ++ return 0; ++} +diff --git a/jdk/src/solaris/native/sun/nio/fs/UnixConstants.c b/jdk/src/solaris/native/sun/nio/fs/UnixConstants.c +new file mode 100644 +index 0000000000..95545405ce +--- /dev/null ++++ b/jdk/src/solaris/native/sun/nio/fs/UnixConstants.c +@@ -0,0 +1,114 @@ ++/* ++ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. Oracle designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Oracle in the LICENSE file that accompanied this code. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "jni.h" ++ ++#include "sun_nio_fs_UnixConstants.h" ++ ++#define INIT_CONST(ENV, CLS, VAL) INIT_CONST_NAME(ENV, CLS, VAL, p ## VAL) ++ ++#define INIT_CONST_NAME(ENV, CLS, VAL, NAME) \ ++{ \ ++ jfieldID fID = (*(ENV))->GetStaticFieldID((ENV), (CLS), #NAME, "I"); \ ++ if (fID != 0) { \ ++ (*(ENV))->SetStaticIntField((ENV), (CLS), fID, (VAL)); \ ++ } \ ++} \ ++ ++/** ++ * Initialization of the UnixConstants fields: ++ * file open flags, modes and error codes ++ */ ++JNIEXPORT void JNICALL ++Java_sun_nio_fs_UnixConstants_init(JNIEnv* env, jclass cls) { ++ // open flags ++ INIT_CONST(env, cls, O_RDONLY); ++ INIT_CONST(env, cls, O_WRONLY); ++ INIT_CONST(env, cls, O_RDWR); ++ INIT_CONST(env, cls, O_APPEND); ++ INIT_CONST(env, cls, O_CREAT); ++ INIT_CONST(env, cls, O_EXCL); ++ INIT_CONST(env, cls, O_TRUNC); ++ INIT_CONST(env, cls, O_SYNC); ++ INIT_CONST(env, cls, O_DSYNC); ++ INIT_CONST(env, cls, O_NOFOLLOW); ++ ++ // mode masks ++ INIT_CONST(env, cls, S_IRUSR); ++ INIT_CONST(env, cls, S_IWUSR); ++ INIT_CONST(env, cls, S_IXUSR); ++ INIT_CONST(env, cls, S_IRGRP); ++ INIT_CONST(env, cls, S_IWGRP); ++ INIT_CONST(env, cls, S_IXGRP); ++ INIT_CONST(env, cls, S_IROTH); ++ INIT_CONST(env, cls, S_IWOTH); ++ INIT_CONST(env, cls, S_IXOTH); ++ INIT_CONST(env, cls, S_IFMT); ++ INIT_CONST(env, cls, S_IFREG); ++ INIT_CONST(env, cls, S_IFDIR); ++ INIT_CONST(env, cls, S_IFLNK); ++ INIT_CONST(env, cls, S_IFCHR); ++ INIT_CONST(env, cls, S_IFBLK); ++ INIT_CONST(env, cls, S_IFIFO); ++ INIT_CONST_NAME(env, cls, (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH), pS_IAMB); ++ ++ // access modes ++ INIT_CONST(env, cls, R_OK); ++ INIT_CONST(env, cls, W_OK); ++ INIT_CONST(env, cls, X_OK); ++ INIT_CONST(env, cls, F_OK); ++ ++ // errors ++ INIT_CONST(env, cls, ENOENT); ++ INIT_CONST(env, cls, EACCES); ++ INIT_CONST(env, cls, EEXIST); ++ INIT_CONST(env, cls, ENOTDIR); ++ INIT_CONST(env, cls, EINVAL); ++ INIT_CONST(env, cls, EXDEV); ++ INIT_CONST(env, cls, EISDIR); ++ INIT_CONST(env, cls, ENOTEMPTY); ++ INIT_CONST(env, cls, ENOSPC); ++ INIT_CONST(env, cls, EAGAIN); ++ INIT_CONST(env, cls, ENOSYS); ++ INIT_CONST(env, cls, ELOOP); ++ INIT_CONST(env, cls, EROFS); ++ INIT_CONST(env, cls, ERANGE); ++ INIT_CONST(env, cls, EMFILE); ++ ++#if defined(ENODATA) ++ INIT_CONST(env, cls, ENODATA); ++#endif ++ ++#if defined(AT_SYMLINK_NOFOLLOW) && defined(AT_REMOVEDIR) ++ INIT_CONST(env, cls, AT_SYMLINK_NOFOLLOW); ++ INIT_CONST(env, cls, AT_REMOVEDIR); ++#endif ++ ++} +-- +2.19.0 + diff --git a/8160369.patch b/8160369.patch new file mode 100644 index 0000000000000000000000000000000000000000..8a055191101b5166e598736cd87c43589e6db65d --- /dev/null +++ b/8160369.patch @@ -0,0 +1,549 @@ +From 822f93a00af8300b0516707c2fded59c7487b3ea Mon Sep 17 00:00:00 2001 +From: wangshuai +Date: Mon, 14 Oct 2019 16:34:52 +0000 +Subject: [PATCH] Backport of JDK-8160369 + +Summary::[Backport of JDK-8160369 and it's subtasks] Memory fences needed around setting and reading object lengths +LLT: +bug url: https://bugs.openjdk.java.net/browse/JDK-8160369 +--- + .../vm/gc_implementation/g1/g1BlockOffsetTable.cpp | 2 +- + .../g1/g1BlockOffsetTable.inline.hpp | 4 +- + .../src/share/vm/gc_implementation/g1/g1RemSet.cpp | 137 ++++++++++------- + .../share/vm/gc_implementation/g1/heapRegion.cpp | 166 ++++++++++----------- + .../share/vm/gc_implementation/g1/heapRegion.hpp | 26 ++-- + .../vm/gc_implementation/g1/heapRegionType.hpp | 3 + + .../gc_implementation/parNew/parNewGeneration.cpp | 21 ++- + 7 files changed, 203 insertions(+), 156 deletions(-) + +diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp +index ead98e24a0..1977fc83da 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp +@@ -264,7 +264,7 @@ G1BlockOffsetArray::forward_to_block_containing_addr_slow(HeapWord* q, + while (n <= next_boundary) { + q = n; + oop obj = oop(q); +- if (obj->klass_or_null() == NULL) return q; ++ if (obj->klass_or_null_acquire() == NULL) return q; + n += block_size(q); + } + assert(q <= next_boundary && n > next_boundary, "Consequence of loop"); +diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp +index bcfd52a4a2..ffc56a0ba0 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp +@@ -166,7 +166,7 @@ forward_to_block_containing_addr_const(HeapWord* q, HeapWord* n, + while (n <= addr) { + q = n; + oop obj = oop(q); +- if (obj->klass_or_null() == NULL) return q; ++ if (obj->klass_or_null_acquire() == NULL) return q; + n += block_size(q); + } + assert(q <= n, "wrong order for q and addr"); +@@ -177,7 +177,7 @@ forward_to_block_containing_addr_const(HeapWord* q, HeapWord* n, + inline HeapWord* + G1BlockOffsetArray::forward_to_block_containing_addr(HeapWord* q, + const void* addr) { +- if (oop(q)->klass_or_null() == NULL) return q; ++ if (oop(q)->klass_or_null_acquire() == NULL) return q; + HeapWord* n = q + block_size(q); + // In the normal case, where the query "addr" is a card boundary, and the + // offset table chunks are the same size as cards, the block starting at +diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp +index da4d632487..da417fb725 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp +@@ -460,18 +460,26 @@ bool G1RemSet::refine_card(jbyte* card_ptr, uint worker_i, + // And find the region containing it. + HeapRegion* r = _g1->heap_region_containing(start); + +- // Why do we have to check here whether a card is on a young region, +- // given that we dirty young regions and, as a result, the +- // post-barrier is supposed to filter them out and never to enqueue +- // them? When we allocate a new region as the "allocation region" we +- // actually dirty its cards after we release the lock, since card +- // dirtying while holding the lock was a performance bottleneck. So, +- // as a result, it is possible for other threads to actually +- // allocate objects in the region (after the acquire the lock) +- // before all the cards on the region are dirtied. This is unlikely, +- // and it doesn't happen often, but it can happen. So, the extra +- // check below filters out those cards. +- if (r->is_young()) { ++ // This check is needed for some uncommon cases where we should ++ // ignore the card. ++ // ++ // The region could be young. Cards for young regions are ++ // distinctly marked (set to g1_young_gen), so the post-barrier will ++ // filter them out. However, that marking is performed ++ // concurrently. A write to a young object could occur before the ++ // card has been marked young, slipping past the filter. ++ // ++ // The card could be stale, because the region has been freed since ++ // the card was recorded. In this case the region type could be ++ // anything. If (still) free or (reallocated) young, just ignore ++ // it. If (reallocated) old or humongous, the later card trimming ++ // and additional checks in iteration may detect staleness. At ++ // worst, we end up processing a stale card unnecessarily. ++ // ++ // In the normal (non-stale) case, the synchronization between the ++ // enqueueing of the card and processing it here will have ensured ++ // we see the up-to-date region type here. ++ if (!r->is_old_or_humongous()) { + return false; + } + +@@ -503,26 +511,69 @@ bool G1RemSet::refine_card(jbyte* card_ptr, uint worker_i, + assert(!check_for_refs_into_cset, "sanity"); + assert(!SafepointSynchronize::is_at_safepoint(), "sanity"); + ++ const jbyte* orig_card_ptr = card_ptr; + card_ptr = hot_card_cache->insert(card_ptr); + if (card_ptr == NULL) { + // There was no eviction. Nothing to do. + return false; +- } +- +- start = _ct_bs->addr_for(card_ptr); +- r = _g1->heap_region_containing(start); ++ } else if (card_ptr != orig_card_ptr) { ++ // Original card was inserted and an old card was evicted. ++ start = _ct_bs->addr_for(card_ptr); ++ r = _g1->heap_region_containing(start); ++ ++ // Check whether the region formerly in the cache should be ++ // ignored, as discussed earlier for the original card. The ++ // region could have been freed while in the cache. The cset is ++ // not relevant here, since we're in concurrent phase. ++ if (!r->is_old_or_humongous()) { ++ return false; ++ } ++ } // Else we still have the original card. ++ } + +- // Checking whether the region we got back from the cache +- // is young here is inappropriate. The region could have been +- // freed, reallocated and tagged as young while in the cache. +- // Hence we could see its young type change at any time. ++ // Trim the region designated by the card to what's been allocated ++ // in the region. The card could be stale, or the card could cover ++ // (part of) an object at the end of the allocated space and extend ++ // beyond the end of allocation. ++ HeapWord* scan_limit; ++ if (_g1->is_gc_active()) { ++ // If we're in a STW GC, then a card might be in a GC alloc region ++ // and extend onto a GC LAB, which may not be parsable. Stop such ++ // at the "scan_top" of the region. ++ scan_limit = r->scan_top(); ++ } else { ++ // Non-humongous objects are only allocated in the old-gen during ++ // GC, so if region is old then top is stable. Humongous object ++ // allocation sets top last; if top has not yet been set, this is ++ // a stale card and we'll end up with an empty intersection. If ++ // this is not a stale card, the synchronization between the ++ // enqueuing of the card and processing it here will have ensured ++ // we see the up-to-date top here. ++ scan_limit = r->top(); ++ } ++ if (scan_limit <= start) { ++ // If the trimmed region is empty, the card must be stale. ++ return false; + } + ++ // Okay to clean and process the card now. There are still some ++ // stale card cases that may be detected by iteration and dealt with ++ // as iteration failure. ++ *const_cast(card_ptr) = CardTableModRefBS::clean_card_val(); ++ ++ // This fence serves two purposes. First, the card must be cleaned ++ // before processing the contents. Second, we can't proceed with ++ // processing until after the read of top, for synchronization with ++ // possibly concurrent humongous object allocation. It's okay that ++ // reading top and reading type were racy wrto each other. We need ++ // both set, in any order, to proceed. ++ OrderAccess::fence(); ++ + // Don't use addr_for(card_ptr + 1) which can ask for +- // a card beyond the heap. This is not safe without a perm +- // gen at the upper end of the heap. +- HeapWord* end = start + CardTableModRefBS::card_size_in_words; +- MemRegion dirtyRegion(start, end); ++ // a card beyond the heap. ++ HeapWord* end = start + CardTableModRefBS::card_size_in_words; ++ MemRegion dirty_region(start, MIN2(scan_limit, end)); ++ assert(!dirty_region.is_empty(), "sanity"); + + #if CARD_REPEAT_HISTO + init_ct_freq_table(_g1->max_capacity()); +@@ -555,33 +606,17 @@ bool G1RemSet::refine_card(jbyte* card_ptr, uint worker_i, + (OopClosure*)&mux : + (OopClosure*)&update_rs_oop_cl)); + +- // The region for the current card may be a young region. The +- // current card may have been a card that was evicted from the +- // card cache. When the card was inserted into the cache, we had +- // determined that its region was non-young. While in the cache, +- // the region may have been freed during a cleanup pause, reallocated +- // and tagged as young. +- // +- // We wish to filter out cards for such a region but the current +- // thread, if we're running concurrently, may "see" the young type +- // change at any time (so an earlier "is_young" check may pass or +- // fail arbitrarily). We tell the iteration code to perform this +- // filtering when it has been determined that there has been an actual +- // allocation in this region and making it safe to check the young type. +- bool filter_young = true; +- +- HeapWord* stop_point = +- r->oops_on_card_seq_iterate_careful(dirtyRegion, +- &filter_then_update_rs_oop_cl, +- filter_young, +- card_ptr); +- +- // If stop_point is non-null, then we encountered an unallocated region +- // (perhaps the unfilled portion of a TLAB.) For now, we'll dirty the +- // card and re-enqueue: if we put off the card until a GC pause, then the +- // unallocated portion will be filled in. Alternatively, we might try +- // the full complexity of the technique used in "regular" precleaning. +- if (stop_point != NULL) { ++ bool card_processed = ++ r->oops_on_card_seq_iterate_careful(dirty_region, ++ &filter_then_update_rs_oop_cl); ++ ++ // If unable to process the card then we encountered an unparsable ++ // part of the heap (e.g. a partially allocated object) while ++ // processing a stale card. Despite the card being stale, redirty ++ // and re-enqueue, because we've already cleaned the card. Without ++ // this we could incorrectly discard a non-stale card. ++ if (!card_processed) { ++ assert(!_g1->is_gc_active(), "Unparsable heap during GC"); + // The card might have gotten re-dirtied and re-enqueued while we + // worked. (In fact, it's pretty likely.) + if (*card_ptr != CardTableModRefBS::dirty_card_val()) { +diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp +index eefa1c9499..5d1578a248 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp +@@ -339,6 +339,50 @@ void HeapRegion::note_self_forwarding_removal_end(bool during_initial_mark, + _prev_marked_bytes = marked_bytes; + } + ++// Humongous objects are allocated directly in the old-gen. Need ++// special handling for concurrent processing encountering an ++// in-progress allocation. ++static bool do_oops_on_card_in_humongous(MemRegion mr, ++ FilterOutOfRegionClosure* cl, ++ HeapRegion* hr, ++ G1CollectedHeap* g1h) { ++ assert(hr->isHumongous(), "precondition"); ++ HeapRegion* sr = hr->humongous_start_region(); ++ oop obj = oop(sr->bottom()); ++ ++ // If concurrent and klass_or_null is NULL, then space has been ++ // allocated but the object has not yet been published by setting ++ // the klass. That can only happen if the card is stale. However, ++ // we've already set the card clean, so we must return failure, ++ // since the allocating thread could have performed a write to the ++ // card that might be missed otherwise. ++ if (!g1h->is_gc_active() && (obj->klass_or_null_acquire() == NULL)) { ++ return false; ++ } ++ ++ // We have a well-formed humongous object at the start of sr. ++ // Only filler objects follow a humongous object in the containing ++ // regions, and we can ignore those. So only process the one ++ // humongous object. ++ if (!g1h->is_obj_dead(obj, sr)) { ++ if (obj->is_objArray() || (sr->bottom() < mr.start())) { ++ // objArrays are always marked precisely, so limit processing ++ // with mr. Non-objArrays might be precisely marked, and since ++ // it's humongous it's worthwhile avoiding full processing. ++ // However, the card could be stale and only cover filler ++ // objects. That should be rare, so not worth checking for; ++ // instead let it fall out from the bounded iteration. ++ obj->oop_iterate(cl, mr); ++ } else { ++ // If obj is not an objArray and mr contains the start of the ++ // obj, then this could be an imprecise mark, and we need to ++ // process the entire object. ++ obj->oop_iterate(cl); ++ } ++ } ++ return true; ++} ++ + HeapWord* + HeapRegion::object_iterate_mem_careful(MemRegion mr, + ObjectClosure* cl) { +@@ -363,106 +407,62 @@ HeapRegion::object_iterate_mem_careful(MemRegion mr, + } else if (!g1h->is_obj_dead(obj)) { + cl->do_object(obj); + } +- if (cl->abort()) return cur; +- // The check above must occur before the operation below, since an +- // abort might invalidate the "size" operation. + cur += block_size(cur); + } + return NULL; + } + +-HeapWord* +-HeapRegion:: +-oops_on_card_seq_iterate_careful(MemRegion mr, +- FilterOutOfRegionClosure* cl, +- bool filter_young, +- jbyte* card_ptr) { +- // Currently, we should only have to clean the card if filter_young +- // is true and vice versa. +- if (filter_young) { +- assert(card_ptr != NULL, "pre-condition"); +- } else { +- assert(card_ptr == NULL, "pre-condition"); +- } ++bool HeapRegion::oops_on_card_seq_iterate_careful(MemRegion mr, ++ FilterOutOfRegionClosure* cl) { ++ assert(MemRegion(bottom(), end()).contains(mr), "Card region not in heap region"); + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + +- // If we're within a stop-world GC, then we might look at a card in a +- // GC alloc region that extends onto a GC LAB, which may not be +- // parseable. Stop such at the "scan_top" of the region. +- if (g1h->is_gc_active()) { +- mr = mr.intersection(MemRegion(bottom(), scan_top())); +- } else { +- mr = mr.intersection(used_region()); +- } +- if (mr.is_empty()) return NULL; +- // Otherwise, find the obj that extends onto mr.start(). +- +- // The intersection of the incoming mr (for the card) and the +- // allocated part of the region is non-empty. This implies that +- // we have actually allocated into this region. The code in +- // G1CollectedHeap.cpp that allocates a new region sets the +- // is_young tag on the region before allocating. Thus we +- // safely know if this region is young. +- if (is_young() && filter_young) { +- return NULL; ++ // Special handling for humongous regions. ++ if (isHumongous()) { ++ return do_oops_on_card_in_humongous(mr, cl, this, g1h); + } ++ assert(is_old(), "precondition"); + +- assert(!is_young(), "check value of filter_young"); +- +- // We can only clean the card here, after we make the decision that +- // the card is not young. And we only clean the card if we have been +- // asked to (i.e., card_ptr != NULL). +- if (card_ptr != NULL) { +- *card_ptr = CardTableModRefBS::clean_card_val(); +- // We must complete this write before we do any of the reads below. +- OrderAccess::storeload(); +- } ++ // Because mr has been trimmed to what's been allocated in this ++ // region, the parts of the heap that are examined here are always ++ // parsable; there's no need to use klass_or_null to detect ++ // in-progress allocation. + + // Cache the boundaries of the memory region in some const locals + HeapWord* const start = mr.start(); + HeapWord* const end = mr.end(); + +- // We used to use "block_start_careful" here. But we're actually happy +- // to update the BOT while we do this... ++ // Find the obj that extends onto mr.start(). ++ // Update BOT as needed while finding start of (possibly dead) ++ // object containing the start of the region. + HeapWord* cur = block_start(start); +- assert(cur <= start, "Postcondition"); +- +- oop obj; +- +- HeapWord* next = cur; +- do { +- cur = next; +- obj = oop(cur); +- if (obj->klass_or_null() == NULL) { +- // Ran into an unparseable point. +- return cur; +- } +- // Otherwise... +- next = cur + block_size(cur); +- } while (next <= start); + +- // If we finish the above loop...We have a parseable object that +- // begins on or before the start of the memory region, and ends +- // inside or spans the entire region. +- assert(cur <= start, "Loop postcondition"); +- assert(obj->klass_or_null() != NULL, "Loop postcondition"); ++#ifdef ASSERT ++ { ++ assert(cur <= start, ++ "cur: " PTR_FORMAT ", start: " PTR_FORMAT); ++ HeapWord* next = cur + block_size(cur); ++ assert(start < next, ++ "start: " PTR_FORMAT ", next: " PTR_FORMAT); ++ } ++#endif + + do { +- obj = oop(cur); +- assert((cur + block_size(cur)) > (HeapWord*)obj, "Loop invariant"); +- if (obj->klass_or_null() == NULL) { +- // Ran into an unparseable point. +- return cur; +- } +- +- // Advance the current pointer. "obj" still points to the object to iterate. +- cur = cur + block_size(cur); +- +- if (!g1h->is_obj_dead(obj)) { +- // Non-objArrays are sometimes marked imprecise at the object start. We +- // always need to iterate over them in full. +- // We only iterate over object arrays in full if they are completely contained +- // in the memory region. ++ oop obj = oop(cur); ++ assert(obj->is_oop(true), "Not an oop at " PTR_FORMAT); ++ assert(obj->klass_or_null() != NULL, ++ "Unparsable heap at " PTR_FORMAT); ++ ++ if (g1h->is_obj_dead(obj, this)) { ++ // Carefully step over dead object. ++ cur += block_size(cur); ++ } else { ++ // Step over live object, and process its references. ++ cur += obj->size(); ++ // Non-objArrays are usually marked imprecise at the object ++ // start, in which case we need to iterate over them in full. ++ // objArrays are precisely marked, but can still be iterated ++ // over in full if completely covered. + if (!obj->is_objArray() || (((HeapWord*)obj) >= start && cur <= end)) { + obj->oop_iterate(cl); + } else { +@@ -471,7 +471,7 @@ oops_on_card_seq_iterate_careful(MemRegion mr, + } + } while (cur < end); + +- return NULL; ++ return true; + } + + // Code roots support +diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp +index 76627e7ba4..a3f5e506a5 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp +@@ -418,6 +418,8 @@ class HeapRegion: public G1OffsetTableContigSpace { + + bool is_old() const { return _type.is_old(); } + ++ bool is_old_or_humongous() const { return _type.is_old_or_humongous(); } ++ + // For a humongous region, region in which it starts. + HeapRegion* humongous_start_region() const { + return _humongous_start_region; +@@ -702,7 +704,7 @@ class HeapRegion: public G1OffsetTableContigSpace { + _next_marked_bytes = 0; + } + } +- ++ + // Requires that "mr" be entirely within the region. + // Apply "cl->do_object" to all objects that intersect with "mr". + // If the iteration encounters an unparseable portion of the region, +@@ -714,16 +716,18 @@ class HeapRegion: public G1OffsetTableContigSpace { + HeapWord* + object_iterate_mem_careful(MemRegion mr, ObjectClosure* cl); + +- // filter_young: if true and the region is a young region then we +- // skip the iteration. +- // card_ptr: if not NULL, and we decide that the card is not young +- // and we iterate over it, we'll clean the card before we start the +- // iteration. +- HeapWord* +- oops_on_card_seq_iterate_careful(MemRegion mr, +- FilterOutOfRegionClosure* cl, +- bool filter_young, +- jbyte* card_ptr); ++ // Iterate over the objects overlapping part of a card, applying cl ++ // to all references in the region. This is a helper for ++ // G1RemSet::refine_card, and is tightly coupled with it. ++ // mr: the memory region covered by the card, trimmed to the ++ // allocated space for this region. Must not be empty. ++ // This region must be old or humongous. ++ // Returns true if the designated objects were successfully ++ // processed, false if an unparsable part of the heap was ++ // encountered; that only happens when invoked concurrently with the ++ // mutator. ++ bool oops_on_card_seq_iterate_careful(MemRegion mr, ++ FilterOutOfRegionClosure* cl); + + size_t recorded_rs_length() const { return _recorded_rs_length; } + double predicted_elapsed_time_ms() const { return _predicted_elapsed_time_ms; } +diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionType.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionType.hpp +index b00590a6b7..3b9904c39b 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionType.hpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionType.hpp +@@ -110,6 +110,9 @@ public: + + bool is_old() const { return get() == OldTag; } + ++ bool is_old_or_humongous() const { return (get() & (OldTag | HumMask)) != 0; } ++ ++ + // Setters + + void set_free() { set(FreeTag); } +diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp +index 67b0421ebf..2b9fb53293 100644 +--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp ++++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp +@@ -1551,22 +1551,25 @@ bool ParNewGeneration::take_from_overflow_list_work(ParScanThreadState* par_scan + return false; + } + assert(prefix != NULL && prefix != BUSY, "Error"); +- size_t i = 1; + oop cur = prefix; +- while (i < objsFromOverflow && cur->klass_or_null() != NULL) { +- i++; cur = cur->list_ptr_from_klass(); ++ for (size_t i = 1; i < objsFromOverflow; ++i) { ++ oop next = cur->list_ptr_from_klass(); ++ if (next == NULL) break; ++ cur = next; + } ++ assert(cur != NULL, "Loop postcondition"); + + // Reattach remaining (suffix) to overflow list +- if (cur->klass_or_null() == NULL) { ++ oop suffix = cur->list_ptr_from_klass(); ++ if (suffix == NULL) { + // Write back the NULL in lieu of the BUSY we wrote + // above and it is still the same value. + if (_overflow_list == BUSY) { + (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY); + } + } else { +- assert(cur->klass_or_null() != (Klass*)(address)BUSY, "Error"); +- oop suffix = cur->list_ptr_from_klass(); // suffix will be put back on global list ++ assert(suffix != BUSY, "Error"); ++ // suffix will be put back on global list + cur->set_klass_to_list_ptr(NULL); // break off suffix + // It's possible that the list is still in the empty(busy) state + // we left it in a short while ago; in that case we may be +@@ -1586,8 +1589,10 @@ bool ParNewGeneration::take_from_overflow_list_work(ParScanThreadState* par_scan + // Too bad, someone else got in in between; we'll need to do a splice. + // Find the last item of suffix list + oop last = suffix; +- while (last->klass_or_null() != NULL) { +- last = last->list_ptr_from_klass(); ++ while (true) { ++ oop next = last->list_ptr_from_klass(); ++ if (next == NULL) break; ++ last = next; + } + // Atomically prepend suffix to current overflow list + observed_overflow_list = _overflow_list; +-- +2.12.3 + diff --git a/8161072.patch b/8161072.patch new file mode 100644 index 0000000000000000000000000000000000000000..c9a660c8d81cfabf5e4db0ad40ac54a57f803809 --- /dev/null +++ b/8161072.patch @@ -0,0 +1,58 @@ +From e42367ab7ce5d66823ef32ea00dbc5e44e3b20d1 Mon Sep 17 00:00:00 2001 +From: jitao +Date: Tue, 28 May 2019 21:38:21 +0000 +Subject: [PATCH] 8161072: AArch64: jtreg compiler/uncommontrap/TestDeoptOOM failure + +Summary: +Bug url: https://bugs.openjdk.java.net/browse/JDK-8161072 + +--- + .../cpu/aarch64/vm/templateInterpreter_aarch64.cpp | 25 +++++++++++----------- + 1 file changed, 12 insertions(+), 13 deletions(-) + +diff --git a/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp +index 8dede4b74..566ddd173 100644 +--- a/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp ++++ b/hotspot/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp +@@ -223,19 +223,6 @@ address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, + __ restore_locals(); + __ restore_constant_pool_cache(); + __ get_method(rmethod); +- +- // handle exceptions +- { +- Label L; +- __ ldr(rscratch1, Address(rthread, Thread::pending_exception_offset())); +- __ cbz(rscratch1, L); +- __ call_VM(noreg, +- CAST_FROM_FN_PTR(address, +- InterpreterRuntime::throw_pending_exception)); +- __ should_not_reach_here(); +- __ bind(L); +- } +- + __ get_dispatch(); + + // Calculate stack limit +@@ -253,6 +240,18 @@ address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, + // NULL last_sp until next java call + __ str(zr, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize)); + ++ // handle exceptions ++ { ++ Label L; ++ __ ldr(rscratch1, Address(rthread, Thread::pending_exception_offset())); ++ __ cbz(rscratch1, L); ++ __ call_VM(noreg, ++ CAST_FROM_FN_PTR(address, ++ InterpreterRuntime::throw_pending_exception)); ++ __ should_not_reach_here(); ++ __ bind(L); ++ } ++ + __ dispatch_next(state, step); + return entry; + } +-- +2.12.3 + diff --git a/8164948.patch b/8164948.patch new file mode 100644 index 0000000000000000000000000000000000000000..36bc252ebb79d2fe97de481f0a21f9d390aee6cb --- /dev/null +++ b/8164948.patch @@ -0,0 +1,41 @@ +From d0c532d9b3e657fea7ce93602553c9d74aab85a6 Mon Sep 17 00:00:00 2001 +From: mashoubing +Date: Fri, 21 Jun 2019 14:21:55 +0000 +Subject: [PATCH] 8164948: Initializing stores of HeapRegions are not ordered with regards to their use in G1ConcurrentMark + +Summary: Initializing stores of HeapRegions are not ordered with regards to their use in G1ConcurrentMark +LLT: +bug link: https://bugs.openjdk.java.net/browse/JDK-8164948 +--- + hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp | 2 ++ + hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp | 1 + + 2 files changed, 3 insertions(+) + +diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp +index ea0e564b73..0c12478f2f 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp +@@ -3006,6 +3006,8 @@ ConcurrentMark::claim_region(uint worker_id) { + // iterations) but it should not introduce and correctness issues. + HeapRegion* curr_region = _g1h->heap_region_containing_raw(finger); + ++ // Make sure that the reads below do not float before loading curr_region. ++ OrderAccess::loadload(); + // Above heap_region_containing_raw may return NULL as we always scan claim + // until the end of the heap. In this case, just jump to the next region. + HeapWord* end = curr_region != NULL ? curr_region->end() : finger + HeapRegion::GrainWords; +diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp +index 14673df747..49c231d89b 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp +@@ -124,6 +124,7 @@ void HeapRegionManager::make_regions_available(uint start, uint num_regions) { + for (uint i = start; i < start + num_regions; i++) { + if (_regions.get_by_index(i) == NULL) { + HeapRegion* new_hr = new_heap_region(i); ++ OrderAccess::storestore(); + _regions.set_by_index(i, new_hr); + _allocated_heapregions_length = MAX2(_allocated_heapregions_length, i + 1); + } +-- +2.12.3 + diff --git a/8165857-CMS-_overflow_list-is-missing-volatile-speci.patch b/8165857-CMS-_overflow_list-is-missing-volatile-speci.patch new file mode 100644 index 0000000000000000000000000000000000000000..962418576bf44cc004950c86dd9f9166e6afc3d4 --- /dev/null +++ b/8165857-CMS-_overflow_list-is-missing-volatile-speci.patch @@ -0,0 +1,43 @@ +From 19da764152e382f53c5c0f7069f52d993c649818 Mon Sep 17 00:00:00 2001 +From: hedongbo +Date: Mon, 11 Nov 2019 16:59:01 +0000 +Subject: [PATCH] 8165857: CMS _overflow_list is missing volatile specifiers. + +Summary: : [backport of JDK-8165857][Change _overflow_list from "oop" to "oopDesc* volatile", both CMS and ParNew.] +LLT: NA +Patch Type: backport +Bug url: http://hg.openjdk.java.net/jdk9/jdk9/hotspot/rev/f1ad14991f86 +--- + .../concurrentMarkSweep/concurrentMarkSweepGeneration.hpp | 2 +- + hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp +index a6d06a5dc5..183a97185b 100644 +--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp ++++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp +@@ -556,7 +556,7 @@ class CMSCollector: public CHeapObj { + + // Overflow list of grey objects, threaded through mark-word + // Manipulated with CAS in the parallel/multi-threaded case. +- oop _overflow_list; ++ oopDesc* volatile _overflow_list; + // The following array-pair keeps track of mark words + // displaced for accomodating overflow list above. + // This code will likely be revisited under RFE#4922830. +diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp +index 7685353ed1..5c6b6181fa 100644 +--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp ++++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp +@@ -326,7 +326,7 @@ class ParNewGeneration: public DefNewGeneration { + // A list of from-space images of to-be-scanned objects, threaded through + // klass-pointers (klass information already copied to the forwarded + // image.) Manipulated with CAS. +- oop _overflow_list; ++ oopDesc* volatile _overflow_list; + NOT_PRODUCT(ssize_t _num_par_pushes;) + + // If true, older generation does not support promotion undo, so avoid. +-- +2.12.3 + diff --git a/8165860-WorkGroup-classes-are-missing-volatile-speci.patch b/8165860-WorkGroup-classes-are-missing-volatile-speci.patch new file mode 100644 index 0000000000000000000000000000000000000000..8a4b0b9e8e000e929ccb2e2e67fd9d30195023ab --- /dev/null +++ b/8165860-WorkGroup-classes-are-missing-volatile-speci.patch @@ -0,0 +1,87 @@ +From 92585164635278b4b127f426bf50014d0a03b572 Mon Sep 17 00:00:00 2001 +From: songyaofei +Date: Thu, 14 Nov 2019 15:23:46 +0000 +Subject: [PATCH] 8165860: WorkGroup classes are missing volatile specifiers + for lock-free code + +Summary: : WorkGroup classes are missing volatile specifiers for lock-free code +LLT: NA +Patch Type: backport +Bug url: https://bugs.openjdk.java.net/browse/JDK-8165860 +--- + hotspot/src/share/vm/utilities/workgroup.cpp | 12 +++++------- + hotspot/src/share/vm/utilities/workgroup.hpp | 8 ++++---- + 2 files changed, 9 insertions(+), 11 deletions(-) + +diff --git a/hotspot/src/share/vm/utilities/workgroup.cpp b/hotspot/src/share/vm/utilities/workgroup.cpp +index 3d1f1eef7a..7123574186 100644 +--- a/hotspot/src/share/vm/utilities/workgroup.cpp ++++ b/hotspot/src/share/vm/utilities/workgroup.cpp +@@ -503,23 +503,21 @@ bool SequentialSubTasksDone::valid() { + } + + bool SequentialSubTasksDone::is_task_claimed(uint& t) { +- uint* n_claimed_ptr = &_n_claimed; +- t = *n_claimed_ptr; ++ t = _n_claimed; + while (t < _n_tasks) { +- jint res = Atomic::cmpxchg(t+1, n_claimed_ptr, t); ++ jint res = Atomic::cmpxchg(t+1, &_n_claimed, t); + if (res == (jint)t) { + return false; + } +- t = *n_claimed_ptr; ++ t = res; + } + return true; + } + + bool SequentialSubTasksDone::all_tasks_completed() { +- uint* n_completed_ptr = &_n_completed; +- uint complete = *n_completed_ptr; ++ uint complete = _n_completed; + while (true) { +- uint res = Atomic::cmpxchg(complete+1, n_completed_ptr, complete); ++ uint res = Atomic::cmpxchg(complete+1, &_n_completed, complete); + if (res == complete) { + break; + } +diff --git a/hotspot/src/share/vm/utilities/workgroup.hpp b/hotspot/src/share/vm/utilities/workgroup.hpp +index 30337f1ef5..ef2dff4932 100644 +--- a/hotspot/src/share/vm/utilities/workgroup.hpp ++++ b/hotspot/src/share/vm/utilities/workgroup.hpp +@@ -400,7 +400,7 @@ public: + // enumeration type. + + class SubTasksDone: public CHeapObj { +- uint* _tasks; ++ volatile uint* _tasks; + uint _n_tasks; + // _n_threads is used to determine when a sub task is done. + // It does not control how many threads will execute the subtask +@@ -408,7 +408,7 @@ class SubTasksDone: public CHeapObj { + // in order to correctly decide when the subtask is done (all the + // threads working on the task have finished). + uint _n_threads; +- uint _threads_completed; ++ volatile uint _threads_completed; + #ifdef ASSERT + volatile uint _claimed; + #endif +@@ -454,11 +454,11 @@ public: + class SequentialSubTasksDone : public StackObj { + protected: + uint _n_tasks; // Total number of tasks available. +- uint _n_claimed; // Number of tasks claimed. ++ volatile uint _n_claimed; // Number of tasks claimed. + // _n_threads is used to determine when a sub task is done. + // See comments on SubTasksDone::_n_threads + uint _n_threads; // Total number of parallel threads. +- uint _n_completed; // Number of completed threads. ++ volatile uint _n_completed; // Number of completed threads. + + void clear(); + +-- +2.12.3 + diff --git a/8166197.patch b/8166197.patch new file mode 100644 index 0000000000000000000000000000000000000000..41f93a3ac2bdc932b572b7cc1c4e483ff9915273 --- /dev/null +++ b/8166197.patch @@ -0,0 +1,119 @@ +From ece7241c82e94a5ec19e7a83754db10a646ddb11 Mon Sep 17 00:00:00 2001 +From: wangyadong +Date: Mon, 12 Aug 2019 20:20:50 +0800 +Subject: [PATCH] Backport of JDK-8166197. + +Summary: assert(RelaxAssert || w != Thread::current()->_MutexEvent) failed: invariant +LLT: hotspot/test/stress/gc/TestStressRSetCoarsening.java +Bug url: https://bugs.openjdk.java.net/browse/JDK-8166197 + +--- + hotspot/src/share/vm/runtime/mutex.cpp | 31 ++++++++++++++++++------------- + 1 file changed, 18 insertions(+), 13 deletions(-) + +diff --git a/hotspot/src/share/vm/runtime/mutex.cpp b/hotspot/src/share/vm/runtime/mutex.cpp +index 5973e4f199..9c0dcefe72 100644 +--- a/hotspot/src/share/vm/runtime/mutex.cpp ++++ b/hotspot/src/share/vm/runtime/mutex.cpp +@@ -465,7 +465,7 @@ void Monitor::ILock (Thread * Self) { + ParkEvent * const ESelf = Self->_MutexEvent ; + assert (_OnDeck != ESelf, "invariant") ; + +- // As an optimization, spinners could conditionally try to set ONDECK to _LBIT ++ // As an optimization, spinners could conditionally try to set _OnDeck to _LBIT + // Synchronizer.cpp uses a similar optimization. + if (TrySpin (Self)) goto Exeunt ; + +@@ -476,7 +476,7 @@ void Monitor::ILock (Thread * Self) { + OrderAccess::fence() ; + + // Optional optimization ... try barging on the inner lock +- if ((NativeMonitorFlags & 32) && CASPTR (&_OnDeck, NULL, UNS(Self)) == 0) { ++ if ((NativeMonitorFlags & 32) && CASPTR (&_OnDeck, NULL, UNS(ESelf)) == 0) { + goto OnDeck_LOOP ; + } + +@@ -484,14 +484,14 @@ void Monitor::ILock (Thread * Self) { + + // At any given time there is at most one ondeck thread. + // ondeck implies not resident on cxq and not resident on EntryList +- // Only the OnDeck thread can try to acquire -- contended for -- the lock. ++ // Only the OnDeck thread can try to acquire -- contend for -- the lock. + // CONSIDER: use Self->OnDeck instead of m->OnDeck. + // Deschedule Self so that others may run. +- while (_OnDeck != ESelf) { ++ while (OrderAccess::load_ptr_acquire(&_OnDeck) != ESelf) { + ParkCommon (ESelf, 0) ; + } + +- // Self is now in the ONDECK position and will remain so until it ++ // Self is now in the OnDeck position and will remain so until it + // manages to acquire the lock. + OnDeck_LOOP: + for (;;) { +@@ -515,8 +515,8 @@ void Monitor::ILock (Thread * Self) { + // A. Shift or defer dropping the inner lock until the subsequent IUnlock() operation. + // This might avoid potential reacquisition of the inner lock in IUlock(). + // B. While still holding the inner lock, attempt to opportunistically select +- // and unlink the next ONDECK thread from the EntryList. +- // If successful, set ONDECK to refer to that thread, otherwise clear ONDECK. ++ // and unlink the next OnDeck thread from the EntryList. ++ // If successful, set OnDeck to refer to that thread, otherwise clear OnDeck. + // It's critical that the select-and-unlink operation run in constant-time as + // it executes when holding the outer lock and may artificially increase the + // effective length of the critical section. +@@ -543,7 +543,7 @@ void Monitor::IUnlock (bool RelaxAssert) { + OrderAccess::release_store(&_LockWord.Bytes[_LSBINDEX], 0); // drop outer lock + + OrderAccess::storeload (); +- ParkEvent * const w = _OnDeck ; ++ ParkEvent * const w = _OnDeck ; // raw load as we will just return if non-NULL + assert (RelaxAssert || w != Thread::current()->_MutexEvent, "invariant") ; + if (w != NULL) { + // Either we have a valid ondeck thread or ondeck is transiently "locked" +@@ -551,7 +551,7 @@ void Monitor::IUnlock (bool RelaxAssert) { + // OnDeck allows us to discriminate two cases. If the latter, the + // responsibility for progress and succession lies with that other thread. + // For good performance, we also depend on the fact that redundant unpark() +- // operations are cheap. That is, repeated Unpark()ing of the ONDECK thread ++ // operations are cheap. That is, repeated Unpark()ing of the OnDeck thread + // is inexpensive. This approach provides implicit futile wakeup throttling. + // Note that the referent "w" might be stale with respect to the lock. + // In that case the following unpark() is harmless and the worst that'll happen +@@ -600,8 +600,13 @@ void Monitor::IUnlock (bool RelaxAssert) { + _EntryList = w->ListNext ; + // as a diagnostic measure consider setting w->_ListNext = BAD + assert (UNS(_OnDeck) == _LBIT, "invariant") ; +- _OnDeck = w ; // pass OnDeck to w. +- // w will clear OnDeck once it acquires the outer lock ++ ++ // Pass OnDeck role to w, ensuring that _EntryList has been set first. ++ // w will clear _OnDeck once it acquires the outer lock. ++ // Note that once we set _OnDeck that thread can acquire the mutex, proceed ++ // with its critical section and then enter this code to unlock the mutex. So ++ // you can have multiple threads active in IUnlock at the same time. ++ OrderAccess::release_store_ptr(&_OnDeck, w); + + // Another optional optimization ... + // For heavily contended locks it's not uncommon that some other +@@ -849,7 +854,7 @@ int Monitor::IWait (Thread * Self, jlong timo) { + // ESelf is now on the cxq, EntryList or at the OnDeck position. + // The following fragment is extracted from Monitor::ILock() + for (;;) { +- if (_OnDeck == ESelf && TrySpin(Self)) break ; ++ if (OrderAccess::load_ptr_acquire(&_OnDeck) == ESelf && TrySpin(Self)) break ; + ParkCommon (ESelf, 0) ; + } + assert (_OnDeck == ESelf, "invariant") ; +@@ -1060,7 +1065,7 @@ void Monitor::jvm_raw_lock() { + // Only the OnDeck thread can try to acquire -- contended for -- the lock. + // CONSIDER: use Self->OnDeck instead of m->OnDeck. + for (;;) { +- if (_OnDeck == ESelf && TrySpin(NULL)) break ; ++ if (OrderAccess::load_ptr_acquire(&_OnDeck) == ESelf && TrySpin(NULL)) break ; + ParkCommon (ESelf, 0) ; + } + +-- +2.12.3 + diff --git a/8166253.patch b/8166253.patch new file mode 100644 index 0000000000000000000000000000000000000000..d1c32127d3125f21ff1470ce9e6c340b8311d778 --- /dev/null +++ b/8166253.patch @@ -0,0 +1,234 @@ +From 0350ff861595f4d3b8d903533def704ac319dd45 Mon Sep 17 00:00:00 2001 +From: hexuejin +Date: Sat, 29 Jun 2019 12:05:00 +0000 +Subject: [PATCH] Backport of JDK-8166253 + +summary: (ch) FileLock object can get GC'd and result in unexpected release of file lock +LLT: jdk/test/java/nio/channels/FileLock/FileLockGC.java + +bug link: https://bugs.openjdk.java.net/browse/JDK-8166253 +--- + .../classes/sun/nio/ch/FileLockTable.java | 13 +- + .../nio/channels/FileLock/FileLockGC.java | 143 ++++++++++++++++++ + 2 files changed, 155 insertions(+), 1 deletion(-) + create mode 100644 jdk/test/java/nio/channels/FileLock/FileLockGC.java + +diff --git a/jdk/src/share/classes/sun/nio/ch/FileLockTable.java b/jdk/src/share/classes/sun/nio/ch/FileLockTable.java +index e77e1c4cec..b0351e5668 100644 +--- a/jdk/src/share/classes/sun/nio/ch/FileLockTable.java ++++ b/jdk/src/share/classes/sun/nio/ch/FileLockTable.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2005, 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 +@@ -115,9 +115,13 @@ class SharedFileLockTable extends FileLockTable { + // File key for the file that this channel is connected to + private final FileKey fileKey; + ++ // Locks obtained for this channel ++ private final Set locks; ++ + SharedFileLockTable(Channel channel, FileDescriptor fd) throws IOException { + this.channel = channel; + this.fileKey = FileKey.create(fd); ++ this.locks = new HashSet(); + } + + @Override +@@ -135,6 +139,7 @@ class SharedFileLockTable extends FileLockTable { + if (prev == null) { + // we successfully created the key so we add the file lock + list.add(new FileLockReference(fl, queue, fileKey)); ++ locks.add(fl); + break; + } + } +@@ -151,6 +156,7 @@ class SharedFileLockTable extends FileLockTable { + if (list == current) { + checkList(list, fl.position(), fl.size()); + list.add(new FileLockReference(fl, queue, fileKey)); ++ locks.add(fl); + break; + } + list = current; +@@ -187,6 +193,7 @@ class SharedFileLockTable extends FileLockTable { + assert (lock != null) && (lock.acquiredBy() == channel); + ref.clear(); + list.remove(index); ++ locks.remove(fl); + break; + } + index++; +@@ -220,6 +227,8 @@ class SharedFileLockTable extends FileLockTable { + + // once the lock list is empty we remove it from the map + removeKeyIfEmpty(fileKey, list); ++ ++ locks.clear(); + } + } + return result; +@@ -238,6 +247,8 @@ class SharedFileLockTable extends FileLockTable { + if (lock == fromLock) { + ref.clear(); + list.set(index, new FileLockReference(toLock, queue, fileKey)); ++ locks.remove(fromLock); ++ locks.add(toLock); + break; + } + } +diff --git a/jdk/test/java/nio/channels/FileLock/FileLockGC.java b/jdk/test/java/nio/channels/FileLock/FileLockGC.java +new file mode 100644 +index 0000000000..fb66186884 +--- /dev/null ++++ b/jdk/test/java/nio/channels/FileLock/FileLockGC.java +@@ -0,0 +1,143 @@ ++/* ++ * Copyright (c) 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. ++ */ ++ ++import java.io.File; ++import java.io.IOException; ++import java.io.RandomAccessFile; ++import java.lang.ref.Reference; ++import java.lang.ref.WeakReference; ++import java.nio.channels.FileLock; ++import java.nio.channels.OverlappingFileLockException; ++import java.nio.file.Files; ++import java.nio.file.Path; ++import jdk.test.lib.util.FileUtils; ++ ++/* ++ * @test ++ * @bug 8166253 ++ * @summary Verify that OverlappingFileLockException is thrown when expected. ++ * @library .. /test/lib ++ * @build jdk.test.lib.util.FileUtils ++ * @run main/othervm FileLockGC ++ */ ++public class FileLockGC { ++ public enum TestType { ++ NO_GC_NO_RELEASE(true), ++ // A hypothetical 'GC_THEN_RELEASE' case is infeasible ++ RELEASE(false), ++ RELEASE_THEN_GC(false), ++ GC(true); ++ ++ private final boolean exceptionExpected; ++ ++ TestType(boolean exceptionExpected) { ++ this.exceptionExpected = exceptionExpected; ++ } ++ ++ boolean exceptionExpected() { ++ return exceptionExpected; ++ } ++ } ++ ++ public static void main(String[] args) throws Exception { ++ final File f = new File(System.getProperty("test.dir", ".") ++ + File.separator + "junk.txt"); ++ final Path p = f.toPath(); ++ int failures = 0; ++ ++ for (TestType t : TestType.values()) { ++ try { ++ if (!testFileLockGC(f, t)) { ++ failures++; ++ } ++ } finally { ++ FileUtils.deleteFileIfExistsWithRetry(p); ++ } ++ } ++ ++ if (failures != 0) { ++ throw new RuntimeException("Test had " + failures + " failure(s)"); ++ } ++ } ++ ++ private static boolean testFileLockGC(File f, TestType type) ++ throws InterruptedException, IOException { ++ System.out.printf("Test %s starting%n", type.toString()); ++ ++ final RandomAccessFile raf1 = new RandomAccessFile(f, "rw"); ++ ++ FileLock lock1 = raf1.getChannel().tryLock(); ++ WeakReference ref1 = new WeakReference(lock1); ++ ++ switch (type) { ++ case GC: ++ lock1 = null; ++ System.gc(); ++ break; ++ case RELEASE: ++ lock1.release(); ++ break; ++ case RELEASE_THEN_GC: ++ lock1.release(); ++ lock1 = null; ++ System.gc(); ++ break; ++ default: // NO_GC_NO_RELEASE ++ // lock1 is neither collected nor released ++ break; ++ } ++ ++ final RandomAccessFile raf2 = new RandomAccessFile(f, "rw"); ++ ++ boolean success = true; ++ FileLock lock2 = null; ++ try { ++ lock2 = raf2.getChannel().tryLock(); ++ if (type.exceptionExpected()) { ++ System.err.printf ++ ("No expected OverlappingFileLockException for test %s%n", ++ type.toString()); ++ success = false; ++ } ++ } catch (OverlappingFileLockException ofe) { ++ if (!type.exceptionExpected()) { ++ System.err.printf ++ ("Unexpected OverlappingFileLockException for test %s%n", ++ type.toString()); ++ success = false; ++ } ++ } finally { ++ if (lock1 != null) { ++ lock1.release(); ++ } ++ if (lock2 != null) { ++ lock2.release(); ++ } ++ raf2.close(); ++ raf1.close(); ++ System.out.printf("Test %s finished%n", type.toString()); ++ } ++ ++ return success; ++ } ++} +-- +2.19.0-rc1 + diff --git a/8167409-Invalid-value-passed-to-critical-JNI-function.patch b/8167409-Invalid-value-passed-to-critical-JNI-function.patch new file mode 100644 index 0000000000000000000000000000000000000000..a1f12c81933d152e868f4bbb025d36f25145d44a --- /dev/null +++ b/8167409-Invalid-value-passed-to-critical-JNI-function.patch @@ -0,0 +1,121 @@ +From de7d96bd84ba81580e36f556587496e497ec1daf Mon Sep 17 00:00:00 2001 +From: hexuejin +Date: Mon, 24 Jun 2019 16:39:29 +0000 +Subject: [PATCH] 8167409: Invalid value passed to critical JNI function + +summary: Invalid value passed to critical JNI function +LLT: hotspot/test/compiler/runtime/CheckLongArgs.java +Bug url: https://bugs.openjdk.java.net/browse/JDK-8167409 + +--- + hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp | 2 +- + .../argumentcorruption/CheckLongArgs.java | 46 +++++++++++++++++++++ + .../argumentcorruption/libCNCheckLongArgs.c | 30 ++++++++++++++ + 3 files changed, 77 insertions(+), 1 deletion(-) + create mode 100644 hotspot/test/runtime/criticalnatives/argumentcorruption/CheckLongArgs.java + create mode 100644 hotspot/test/runtime/criticalnatives/argumentcorruption/libCNCheckLongArgs.c + +diff --git a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp +index 5c62d7180b..22c90a59d8 100644 +--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp ++++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp +@@ -2198,7 +2198,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, + int pinned_slot = oop_handle_offset; + + VMRegPair tmp_vmreg; +- tmp_vmreg.set1(rbx->as_VMReg()); ++ tmp_vmreg.set2(rbx->as_VMReg()); + + if (!is_critical_native) { + for (int i = total_in_args - 1, c_arg = total_c_args - 1; i >= 0; i--, c_arg--) { +diff --git a/hotspot/test/runtime/criticalnatives/argumentcorruption/CheckLongArgs.java b/hotspot/test/runtime/criticalnatives/argumentcorruption/CheckLongArgs.java +new file mode 100644 +index 0000000000..15d7c04977 +--- /dev/null ++++ b/hotspot/test/runtime/criticalnatives/argumentcorruption/CheckLongArgs.java +@@ -0,0 +1,46 @@ ++/* ++ * @test ++ * @author yansendao ++ * @requires os.arch != "aarch64" ++ * @run main/othervm -Xcomp -XX:+CriticalJNINatives compiler.runtime.criticalnatives.argumentcorruption.CheckLongArgs ++ */ ++package compiler.runtime.criticalnatives.argumentcorruption; ++public class CheckLongArgs { ++ static { ++ String path = System.getProperty("test.src"); ++ String arch = System.getProperty("os.arch"); ++ String name = System.getProperty("os.name"); ++ if (path == null) ++ System.loadLibrary("CNCheckLongArgs"); ++ else if (name.indexOf("Linux") != -1 && path != null) ++ System.load(path + "/lib/" + arch + "/libCNCheckLongArgs.so"); ++ else ++ throw new RuntimeException("unsupport arch or os!"); ++ } ++ static native void m1(long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, byte[] result); ++ static native void m2(long a1, int[] a2, long a3, int[] a4, long a5, int[] a6, long a7, int[] a8, long a9, byte[] result); ++ public static void main(String args[]) throws Exception { ++ test(); ++ } ++ private static void test() throws Exception { ++ int[] l1 = { 1111, 2222, 3333 }; ++ int[] l2 = { 4444, 5555, 6666 }; ++ int[] l3 = { 7777, 8888, 9999 }; ++ int[] l4 = { 1010, 2020, 3030 }; ++ byte[] result = { -1 }; ++ m1(1111111122222222L, 3333333344444444L, 5555555566666666L, 7777777788888888L, 9999999900000000L, 1212121234343434L, ++ 5656565678787878L, 9090909012121212L, result); ++ check(result[0]); ++ result[0] = -1; ++ m2(1111111122222222L, l1, 3333333344444444L, l2, 5555555566666666L, l3, 7777777788888888L, l4, 9999999900000000L, result); ++ check(result[0]); ++ } ++ private static void check(byte result) throws Exception { ++ if (result != 2) { ++ if (result == 1) { ++ throw new Exception("critical native arguments mismatch"); ++ } ++ throw new Exception("critical native lookup failed"); ++ } ++ } ++} +diff --git a/hotspot/test/runtime/criticalnatives/argumentcorruption/libCNCheckLongArgs.c b/hotspot/test/runtime/criticalnatives/argumentcorruption/libCNCheckLongArgs.c +new file mode 100644 +index 0000000000..c805d75af3 +--- /dev/null ++++ b/hotspot/test/runtime/criticalnatives/argumentcorruption/libCNCheckLongArgs.c +@@ -0,0 +1,30 @@ ++#include "jni.h" ++JNIEXPORT void JNICALL JavaCritical_compiler_runtime_criticalnatives_argumentcorruption_CheckLongArgs_m1 ++ (jlong a1, jlong a2, jlong a3, jlong a4, jlong a5, jlong a6, jlong a7, jlong a8,jint result_length,jbyte* result) { ++ ++ if (a1 != 1111111122222222LL || a2 != 3333333344444444LL || a3 != 5555555566666666LL || a4 != 7777777788888888LL || ++ a5 != 9999999900000000LL || a6 != 1212121234343434LL || a7 != 5656565678787878LL || a8 != 9090909012121212LL || ++ result_length != 1 || result[0] != -1) { ++ result[0] = 1; ++ } else { ++ result[0] = 2; ++ } ++} ++ ++JNIEXPORT void JNICALL JavaCritical_compiler_runtime_criticalnatives_argumentcorruption_CheckLongArgs_m2 ++ (jlong a1, jint a2_length, jint* a2, jlong a3, jint a4_length, jint* a4, jlong a5, jint a6_length, jint* a6, jlong a7, ++ jint a8_length, jint* a8, jlong a9, jint result_length, jbyte* result) { ++ if (a1 != 1111111122222222LL || a2_length != 3 || a2[0] != 1111 || a3 != 3333333344444444LL || a4_length != 3 || a4[0] != 4444 || ++ a5 != 5555555566666666LL || a6_length != 3 || a6[0] != 7777 || a7 != 7777777788888888LL || a8_length != 3 || a8[0] != 1010 || a9 != 9999999900000000LL || ++ result_length != 1 || result[0] != -1) { ++ result[0] = 1; ++ } else { ++ result[0] = 2; ++ } ++} ++ ++JNIEXPORT void JNICALL Java_compiler_runtime_criticalnatives_argumentcorruption_CheckLongArgs_m1 ++ (JNIEnv * env, jclass jclazz, jlong a3, jlong a4, jlong a5, jlong a6, jlong a7, jlong a8, jlong a9, jlong a10, jbyteArray result) {} ++ ++JNIEXPORT void JNICALL Java_compiler_runtime_criticalnatives_argumentcorruption_CheckLongArgs_m2 ++ (JNIEnv * env, jclass jclazz, jlong a3, jintArray a4, jlong a5, jintArray a6, jlong a7, jintArray a8, jlong a9, jintArray a10, jlong a11, jbyteArray result) {} +-- +2.12.3 + diff --git a/8171537.patch b/8171537.patch new file mode 100644 index 0000000000000000000000000000000000000000..b3325732c529e109fd856095d6a58c6019f4d264 --- /dev/null +++ b/8171537.patch @@ -0,0 +1,27 @@ +From 26c54187c40901643d0cf65a985c98ddcee40bf0 Mon Sep 17 00:00:00 2001 +From: guoge +Date: Fri, 19 Apr 2019 17:42:56 +0000 +Subject: [PATCH] 8171537: aarch64: compiler/c1/Test6849574.java generates guarantee failure in C1 + +Bug url: https://bugs.openjdk.java.net/browse/JDK-8171537 + +--- + hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp +index 6e225870e..e536ce649 100644 +--- a/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp ++++ b/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp +@@ -3199,7 +3199,7 @@ void LIR_Assembler::peephole(LIR_List *lir) { + } + + void LIR_Assembler::atomic_op(LIR_Code code, LIR_Opr src, LIR_Opr data, LIR_Opr dest, LIR_Opr tmp_op) { +- Address addr = as_Address(src->as_address_ptr(), noreg); ++ Address addr = as_Address(src->as_address_ptr(), as_reg(tmp_op)); + BasicType type = src->type(); + bool is_oop = type == T_OBJECT || type == T_ARRAY; + +-- +2.19.0 + diff --git a/8182036.patch b/8182036.patch new file mode 100644 index 0000000000000000000000000000000000000000..a513d2f0d84641d386236928d0eea8c50a9e3204 --- /dev/null +++ b/8182036.patch @@ -0,0 +1,29 @@ +From 27de742e21eda38d2aff89d07364ec8f961f8e34 Mon Sep 17 00:00:00 2001 +From: hexuejin +Date: Tue, 25 Jun 2019 21:09:31 +0000 +Subject: [PATCH] Backport of JDK-8182036 + +summary: Load from initializing arraycopy uses wrong memory state +LLT: +Bug url: https://bugs.openjdk.java.net/browse/JDK-8182036 +--- + hotspot/src/share/vm/opto/library_call.cpp | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp +index 4379f8359c..ea11a13e70 100644 +--- a/hotspot/src/share/vm/opto/library_call.cpp ++++ b/hotspot/src/share/vm/opto/library_call.cpp +@@ -5723,7 +5723,8 @@ LibraryCallKit::generate_block_arraycopy(const TypePtr* adr_type, + ((src_off ^ dest_off) & (BytesPerLong-1)) == 0) { + Node* sptr = basic_plus_adr(src, src_off); + Node* dptr = basic_plus_adr(dest, dest_off); +- Node* sval = make_load(control(), sptr, TypeInt::INT, T_INT, adr_type, MemNode::unordered); ++ const TypePtr* s_adr_type = _gvn.type(sptr)->is_ptr(); ++ Node* sval = make_load(control(), sptr, TypeInt::INT, T_INT, s_adr_type, MemNode::unordered); + store_to_memory(control(), dptr, sval, T_INT, adr_type, MemNode::unordered); + src_off += BytesPerInt; + dest_off += BytesPerInt; +-- +2.12.3 + diff --git a/8182397-race-in-field-updates.patch b/8182397-race-in-field-updates.patch new file mode 100644 index 0000000000000000000000000000000000000000..fa64ccd9b6ac4a513728c5f3b3acb537a07de622 --- /dev/null +++ b/8182397-race-in-field-updates.patch @@ -0,0 +1,242 @@ +From bd619b88d5e074d960b34ece8f60b4e5147c4a47 Mon Sep 17 00:00:00 2001 +From: zhuliying +Date: Fri, 8 Nov 2019 17:42:55 +0000 +Subject: [PATCH] 8182397: race in field updates + +Summary: : race in field updates when creating ArrayKlasses can lead to crash +LLT: hotspot/test/runtime/CreateMirror/ArraysNewInstanceBug.java +Patch Type: backport +Bug url: https://bugs.openjdk.java.net/browse/JDK-8182397 +--- + hotspot/src/share/vm/classfile/javaClasses.cpp | 31 ++++---- + hotspot/src/share/vm/classfile/javaClasses.hpp | 2 +- + hotspot/src/share/vm/oops/oop.hpp | 2 + + hotspot/src/share/vm/oops/oop.inline.hpp | 4 ++ + .../runtime/CreateMirror/ArraysNewInstanceBug.java | 83 ++++++++++++++++++++++ + 5 files changed, 107 insertions(+), 15 deletions(-) + create mode 100644 hotspot/test/runtime/CreateMirror/ArraysNewInstanceBug.java + +diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp +index cd28c758d0..e010c77cd1 100644 +--- a/hotspot/src/share/vm/classfile/javaClasses.cpp ++++ b/hotspot/src/share/vm/classfile/javaClasses.cpp +@@ -573,6 +573,7 @@ void java_lang_Class::initialize_mirror_fields(KlassHandle k, + + void java_lang_Class::create_mirror(KlassHandle k, Handle class_loader, + Handle protection_domain, TRAPS) { ++ assert(k() != NULL, "Use create_basic_type_mirror for primitive types"); + assert(k->java_mirror() == NULL, "should only assign mirror once"); + // Use this moment of initialization to cache modifier_flags also, + // to support Class.getModifiers(). Instance classes recalculate +@@ -585,11 +586,10 @@ void java_lang_Class::create_mirror(KlassHandle k, Handle class_loader, + if (SystemDictionary::Class_klass_loaded()) { + // Allocate mirror (java.lang.Class instance) + Handle mirror = InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK); ++ Handle comp_mirror; + + // Setup indirection from mirror->klass +- if (!k.is_null()) { +- java_lang_Class::set_klass(mirror(), k()); +- } ++ java_lang_Class::set_klass(mirror(), k()); + + InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(mirror->klass()); + assert(oop_size(mirror()) == mk->instance_size(k), "should have been set"); +@@ -598,21 +598,21 @@ void java_lang_Class::create_mirror(KlassHandle k, Handle class_loader, + + // It might also have a component mirror. This mirror must already exist. + if (k->oop_is_array()) { +- Handle comp_mirror; + if (k->oop_is_typeArray()) { + BasicType type = TypeArrayKlass::cast(k())->element_type(); +- comp_mirror = Universe::java_mirror(type); ++ comp_mirror = Handle(THREAD, Universe::java_mirror(type)); + } else { + assert(k->oop_is_objArray(), "Must be"); + Klass* element_klass = ObjArrayKlass::cast(k())->element_klass(); + assert(element_klass != NULL, "Must have an element klass"); +- comp_mirror = element_klass->java_mirror(); ++ comp_mirror = Handle(THREAD, element_klass->java_mirror()); + } +- assert(comp_mirror.not_null(), "must have a mirror"); ++ assert(comp_mirror() != NULL, "must have a mirror"); + + // Two-way link between the array klass and its component mirror: + ArrayKlass::cast(k())->set_component_mirror(comp_mirror()); +- set_array_klass(comp_mirror(), k()); ++ // See below for ordering dependencies between field array_klass in component mirror ++ // and java_mirror in this klass. + } else { + assert(k->oop_is_instance(), "Must be"); + +@@ -631,10 +631,13 @@ void java_lang_Class::create_mirror(KlassHandle k, Handle class_loader, + assert(oopDesc::equals(class_loader(), k->class_loader()), "should be same"); + set_class_loader(mirror(), class_loader()); + +- // Setup indirection from klass->mirror last ++ // Setup indirection from klass->mirror + // after any exceptions can happen during allocations. +- if (!k.is_null()) { +- k->set_java_mirror(mirror()); ++ k->set_java_mirror(mirror()); ++ if (comp_mirror() != NULL) { ++ // Set after k->java_mirror() is published, because compiled code running ++ // concurrently doesn't expect a k to have a null java_mirror. ++ release_set_array_klass(comp_mirror(), k()); + } + } else { + if (fixup_mirror_list() == NULL) { +@@ -715,7 +718,7 @@ oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, Basic + if (type != T_VOID) { + Klass* aklass = Universe::typeArrayKlassObj(type); + assert(aklass != NULL, "correct bootstrap"); +- set_array_klass(java_class, aklass); ++ release_set_array_klass(java_class, aklass); + } + #ifdef ASSERT + InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(SystemDictionary::Class_klass()); +@@ -812,9 +815,9 @@ Klass* java_lang_Class::array_klass(oop java_class) { + } + + +-void java_lang_Class::set_array_klass(oop java_class, Klass* klass) { ++void java_lang_Class::release_set_array_klass(oop java_class, Klass* klass) { + assert(klass->is_klass() && klass->oop_is_array(), "should be array klass"); +- java_class->metadata_field_put(_array_klass_offset, klass); ++ java_class->release_metadata_field_put(_array_klass_offset, klass); + } + + +diff --git a/hotspot/src/share/vm/classfile/javaClasses.hpp b/hotspot/src/share/vm/classfile/javaClasses.hpp +index 51879658c7..d9e65f9014 100644 +--- a/hotspot/src/share/vm/classfile/javaClasses.hpp ++++ b/hotspot/src/share/vm/classfile/javaClasses.hpp +@@ -281,7 +281,7 @@ class java_lang_Class : AllStatic { + static oop primitive_mirror(BasicType t); + // JVM_NewArray support + static Klass* array_klass(oop java_class); +- static void set_array_klass(oop java_class, Klass* klass); ++ static void release_set_array_klass(oop java_class, Klass* klass); + // compiler support for class operations + static int klass_offset_in_bytes() { return _klass_offset; } + static int array_klass_offset_in_bytes() { return _array_klass_offset; } +diff --git a/hotspot/src/share/vm/oops/oop.hpp b/hotspot/src/share/vm/oops/oop.hpp +index c8d1f99183..c9bcf96d1c 100644 +--- a/hotspot/src/share/vm/oops/oop.hpp ++++ b/hotspot/src/share/vm/oops/oop.hpp +@@ -243,6 +243,8 @@ class oopDesc { + Metadata* metadata_field(int offset) const; + void metadata_field_put(int offset, Metadata* value); + ++ inline void release_metadata_field_put(int offset, Metadata* value); ++ + jbyte byte_field(int offset) const; + void byte_field_put(int offset, jbyte contents); + +diff --git a/hotspot/src/share/vm/oops/oop.inline.hpp b/hotspot/src/share/vm/oops/oop.inline.hpp +index 5d47e3f4dc..16d2870d79 100644 +--- a/hotspot/src/share/vm/oops/oop.inline.hpp ++++ b/hotspot/src/share/vm/oops/oop.inline.hpp +@@ -393,6 +393,10 @@ inline void oopDesc::metadata_field_put(int offset, Metadata* value) { + } + } + ++void oopDesc::release_metadata_field_put(int offset, Metadata* value) { ++ OrderAccess::release_store_ptr(metadata_field_addr(offset), value); ++} ++ + inline void oopDesc::obj_field_put_raw(int offset, oop value) { + if (UseShenandoahGC) { + oop p = bs()->write_barrier(this); +diff --git a/hotspot/test/runtime/CreateMirror/ArraysNewInstanceBug.java b/hotspot/test/runtime/CreateMirror/ArraysNewInstanceBug.java +new file mode 100644 +index 0000000000..870e8ea94b +--- /dev/null ++++ b/hotspot/test/runtime/CreateMirror/ArraysNewInstanceBug.java +@@ -0,0 +1,83 @@ ++/* ++ * Copyright (c) 2017, 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 ArraysNewInstanceBug ++ * @bug 8182397 ++ * @summary race in setting array_klass field for component mirror with mirror update for klass ++ * @modules java.base/jdk.internal.misc ++ * @run main/othervm -Xcomp ArraysNewInstanceBug ++ */ ++ ++// This test crashes in compiled code with race, because the compiler generates code that assumes this ordering. ++import java.lang.reflect.Array; ++import java.net.URL; ++import java.net.URLClassLoader; ++ ++public class ArraysNewInstanceBug implements Runnable { ++ static Class[] classes; ++ ++ int start; ++ ++ ArraysNewInstanceBug(int start) { ++ this.start = start; ++ } ++ ++ String[] result; ++ ++ public void run() { ++ result = new String[classes.length]; ++ System.err.print('.'); ++ for (int i = start; i < classes.length; i++) { ++ result[i] = Array.newInstance(classes[i], 0).getClass().getName(); ++ } ++ } ++ ++ public static void main(String[] args) throws Throwable { ++ Class c = ArraysNewInstanceBug.class; ++ ClassLoader apploader = c.getClassLoader(); ++ for (int iter = 0; iter < 10 ; iter++) { // 10 is enough to get it to crash on my machine. ++ System.err.print('['); ++ classes = new Class[1000]; ++ String urlpath = "file://" + System.getProperty("test.classes") + "/"; ++ for (int i = 0; i < classes.length; i++) { ++ ClassLoader loader = new URLClassLoader(new URL[] { new URL(urlpath) }, apploader.getParent()); ++ classes[i] = loader.loadClass(c.getSimpleName()); ++ } ++ System.err.print(']'); ++ System.err.print('('); ++ int threadCount = 64; ++ Thread[] threads = new Thread[threadCount]; ++ for (int i = 0; i < threads.length; i++) { ++ threads[i] = new Thread(new ArraysNewInstanceBug(i)); ++ } ++ for (int i = 0; i < threads.length; i++) { ++ threads[i].start(); ++ } ++ for (int i = 0; i < threads.length; i++) { ++ threads[i].join(); ++ } ++ System.err.print(')'); ++ } ++ } ++} +-- +2.12.3 + diff --git a/8186042-OopmapCache-implementation.patch b/8186042-OopmapCache-implementation.patch new file mode 100644 index 0000000000000000000000000000000000000000..3048279e827c4877e4ec0501c29026fa12d332ad --- /dev/null +++ b/8186042-OopmapCache-implementation.patch @@ -0,0 +1,412 @@ +From c673dc6b67a6f44bafb279b02c0f8616704636ea Mon Sep 17 00:00:00 2001 +From: zhanggaofeng +Date: Sun, 7 Jul 2019 19:16:39 +0000 +Subject: [PATCH] Backport of JDK-8186042 for OopmapCache implementation + +Summary: Backport of JDK-8186042 for OopmapCache implementation +LLT: +Bug url: https://bugs.openjdk.java.net/browse/JDK-8186042 +--- + .../shared/vmGCOperations.cpp | 6 +- + .../src/share/vm/interpreter/oopMapCache.cpp | 154 +++++++++++------- + .../src/share/vm/interpreter/oopMapCache.hpp | 11 +- + hotspot/src/share/vm/oops/method.cpp | 26 +-- + hotspot/src/share/vm/runtime/memprofiler.cpp | 2 +- + hotspot/src/share/vm/runtime/vframe.cpp | 8 +- + 6 files changed, 113 insertions(+), 94 deletions(-) + +diff --git a/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp b/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp +index 972099b9cb..e50d9cf023 100644 +--- a/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp ++++ b/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp +@@ -40,6 +40,7 @@ + #if INCLUDE_ALL_GCS + #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" + #endif // INCLUDE_ALL_GCS ++#include "interpreter/oopMapCache.hpp" + + #ifndef USDT2 + HS_DTRACE_PROBE_DECL1(hotspot, gc__begin, bool); +@@ -134,7 +135,10 @@ bool VM_GC_Operation::doit_prologue() { + + void VM_GC_Operation::doit_epilogue() { + assert(Thread::current()->is_Java_thread(), "just checking"); +- // Release the Heap_lock first. ++ // Clean up old interpreter OopMap entries that were replaced ++ // during the GC thread root traversal. ++ OopMapCache::cleanup_old_entries(); ++ // Release the Heap_lock. + SharedHeap* sh = SharedHeap::heap(); + if (sh != NULL) sh->_thread_holds_heap_lock_for_gc = false; + Heap_lock->unlock(); +diff --git a/hotspot/src/share/vm/interpreter/oopMapCache.cpp b/hotspot/src/share/vm/interpreter/oopMapCache.cpp +index f696bcb259..160522912f 100644 +--- a/hotspot/src/share/vm/interpreter/oopMapCache.cpp ++++ b/hotspot/src/share/vm/interpreter/oopMapCache.cpp +@@ -30,6 +30,7 @@ + #include "prims/jvmtiRedefineClassesTrace.hpp" + #include "runtime/handles.inline.hpp" + #include "runtime/signature.hpp" ++#include "runtime/atomic.inline.hpp" + + PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC + +@@ -39,6 +40,9 @@ class OopMapCacheEntry: private InterpreterOopMap { + friend class OopMapCache; + friend class VerifyClosure; + ++ private: ++ OopMapCacheEntry* _next; ++ + protected: + // Initialization + void fill(methodHandle method, int bci); +@@ -56,8 +60,9 @@ class OopMapCacheEntry: private InterpreterOopMap { + + public: + OopMapCacheEntry() : InterpreterOopMap() { ++ _next = NULL; + #ifdef ASSERT +- _resource_allocate_bit_mask = false; ++ _resource_allocate_bit_mask = false; + #endif + } + }; +@@ -424,16 +429,6 @@ void OopMapCacheEntry::flush() { + + // Implementation of OopMapCache + +-#ifndef PRODUCT +- +-static size_t _total_memory_usage = 0; +- +-size_t OopMapCache::memory_usage() { +- return _total_memory_usage; +-} +- +-#endif +- + void InterpreterOopMap::resource_copy(OopMapCacheEntry* from) { + assert(_resource_allocate_bit_mask, + "Should not resource allocate the _bit_mask"); +@@ -474,15 +469,11 @@ inline unsigned int OopMapCache::hash_value_for(methodHandle method, int bci) co + ^ ((unsigned int) method->size_of_parameters() << 6); + } + ++OopMapCacheEntry* volatile OopMapCache::_old_entries = NULL; + +-OopMapCache::OopMapCache() : +- _mut(Mutex::leaf, "An OopMapCache lock", true) +-{ +- _array = NEW_C_HEAP_ARRAY(OopMapCacheEntry, _size, mtClass); +- // Cannot call flush for initialization, since flush +- // will check if memory should be deallocated +- for(int i = 0; i < _size; i++) _array[i].initialize(); +- NOT_PRODUCT(_total_memory_usage += sizeof(OopMapCache) + (sizeof(OopMapCacheEntry) * _size);) ++OopMapCache::OopMapCache() { ++ _array = NEW_C_HEAP_ARRAY(OopMapCacheEntry*, _size, mtClass); ++ for(int i = 0; i < _size; i++) _array[i] = NULL; + } + + +@@ -491,44 +482,59 @@ OopMapCache::~OopMapCache() { + // Deallocate oop maps that are allocated out-of-line + flush(); + // Deallocate array +- NOT_PRODUCT(_total_memory_usage -= sizeof(OopMapCache) + (sizeof(OopMapCacheEntry) * _size);) +- FREE_C_HEAP_ARRAY(OopMapCacheEntry, _array, mtClass); ++ FREE_C_HEAP_ARRAY(OopMapCacheEntry*, _array, mtClass); + } + + OopMapCacheEntry* OopMapCache::entry_at(int i) const { +- return &_array[i % _size]; ++ return (OopMapCacheEntry*)OrderAccess::load_ptr_acquire(&(_array[i % _size])); + } + ++bool OopMapCache::put_at(int i, OopMapCacheEntry* entry, OopMapCacheEntry* old) { ++ return Atomic::cmpxchg_ptr(entry, &_array[i % _size], old) == old; ++ } + void OopMapCache::flush() { +- for (int i = 0; i < _size; i++) _array[i].flush(); ++ for (int i = 0; i < _size; i++) { ++ OopMapCacheEntry* entry = _array[i]; ++ if (entry != NULL) { ++ _array[i] = NULL; // no barrier, only called in OopMapCache destructor ++ entry->flush(); ++ FREE_C_HEAP_OBJ(entry, mtClass); ++ } ++ } + } + ++ + void OopMapCache::flush_obsolete_entries() { +- for (int i = 0; i < _size; i++) +- if (!_array[i].is_empty() && _array[i].method()->is_old()) { ++ assert(SafepointSynchronize::is_at_safepoint(), "called by RedefineClasses in a safepoint"); ++ for (int i = 0; i < _size; i++) { ++ OopMapCacheEntry* entry = _array[i]; ++ if (entry != NULL && !entry->is_empty() && entry->method()->is_old()) { + // Cache entry is occupied by an old redefined method and we don't want + // to pin it down so flush the entry. ++ + RC_TRACE(0x08000000, ("flush: %s(%s): cached entry @%d", +- _array[i].method()->name()->as_C_string(), +- _array[i].method()->signature()->as_C_string(), i)); +- +- _array[i].flush(); ++ entry->method()->name()->as_C_string(), ++ entry->method()->signature()->as_C_string(), i)); ++ ++ _array[i] = NULL; ++ entry->flush(); ++ FREE_C_HEAP_OBJ(entry, mtClass); + } ++ } + } + + void OopMapCache::lookup(methodHandle method, + int bci, +- InterpreterOopMap* entry_for) const { +- MutexLocker x(&_mut); +- +- OopMapCacheEntry* entry = NULL; ++ InterpreterOopMap* entry_for){ ++ assert(SafepointSynchronize::is_at_safepoint(), "called by GC in a safepoint"); + int probe = hash_value_for(method, bci); ++ int i; ++ OopMapCacheEntry* entry = NULL; + + // Search hashtable for match +- int i; + for(i = 0; i < _probe_depth; i++) { + entry = entry_at(probe + i); +- if (entry->match(method, bci)) { ++ if (entry != NULL && !entry->is_empty() && entry->match(method, bci)) { + entry_for->resource_copy(entry); + assert(!entry_for->is_empty(), "A non-empty oop map should be returned"); + return; +@@ -543,26 +549,31 @@ void OopMapCache::lookup(methodHandle method, + } + + // Entry is not in hashtable. +- // Compute entry and return it ++ // Compute entry ++ ++ OopMapCacheEntry* tmp = NEW_C_HEAP_OBJ(OopMapCacheEntry, mtClass); ++ tmp->initialize(); ++ tmp->fill(method, bci); ++ entry_for->resource_copy(tmp); + + if (method->should_not_be_cached()) { + // It is either not safe or not a good idea to cache this Method* + // at this time. We give the caller of lookup() a copy of the + // interesting info via parameter entry_for, but we don't add it to + // the cache. See the gory details in Method*.cpp. +- compute_one_oop_map(method, bci, entry_for); ++ FREE_C_HEAP_OBJ(tmp, mtClass); + return; + } + + // First search for an empty slot + for(i = 0; i < _probe_depth; i++) { +- entry = entry_at(probe + i); +- if (entry->is_empty()) { +- entry->fill(method, bci); +- entry_for->resource_copy(entry); +- assert(!entry_for->is_empty(), "A non-empty oop map should be returned"); +- return; +- } ++ entry = entry_at(probe + i); ++ if (entry == NULL) { ++ if(put_at(probe + i, tmp, NULL)) { ++ assert(!entry_for->is_empty(), "A non-empty oop map should be returned"); ++ return; ++ } ++ } + } + + if (TraceOopMapGeneration) { +@@ -571,30 +582,51 @@ void OopMapCache::lookup(methodHandle method, + } + + // No empty slot (uncommon case). Use (some approximation of a) LRU algorithm +- //entry_at(probe + _probe_depth - 1)->flush(); +- //for(i = _probe_depth - 1; i > 0; i--) { +- // // Coping entry[i] = entry[i-1]; +- // OopMapCacheEntry *to = entry_at(probe + i); +- // OopMapCacheEntry *from = entry_at(probe + i - 1); +- // to->copy(from); +- // } +- +- assert(method->is_method(), "gaga"); ++ // where the first entry in the collision array is replaced with the new one. ++ OopMapCacheEntry* old = entry_at(probe + 0); ++ if (put_at(probe + 0, tmp, old)) { ++ enqueue_for_cleanup(old); ++ } else { ++ enqueue_for_cleanup(tmp); ++ } ++ ++ assert(!entry_for->is_empty(), "A non-empty oop map should be returned"); + +- entry = entry_at(probe + 0); +- entry->fill(method, bci); ++ return; ++} + +- // Copy the newly cached entry to input parameter +- entry_for->resource_copy(entry); ++void OopMapCache::enqueue_for_cleanup(OopMapCacheEntry* entry) { ++ bool success = false; ++ OopMapCacheEntry* head; ++ do { ++ head = _old_entries; ++ entry->_next = head; ++ success = Atomic::cmpxchg_ptr((intptr_t*)entry, (intptr_t*)&_old_entries, (intptr_t*)head) == (intptr_t*)head; ++ } while (!success); + + if (TraceOopMapGeneration) { + ResourceMark rm; +- tty->print("Done with "); +- method->print_value(); tty->cr(); ++ tty->print_cr("enqueue %s at bci %d for cleanup", ++ entry->method()->name_and_sig_as_C_string(), entry->bci()); + } +- assert(!entry_for->is_empty(), "A non-empty oop map should be returned"); ++} + +- return; ++// This is called after GC threads are done and nothing is accessing the old_entries ++// list, so no synchronization needed. ++void OopMapCache::cleanup_old_entries() { ++ OopMapCacheEntry* entry = _old_entries; ++ _old_entries = NULL; ++ while (entry != NULL) { ++ if (TraceOopMapGeneration) { ++ ResourceMark rm; ++ tty->print_cr("cleanup entry %s at bci %d", ++ entry->method()->name_and_sig_as_C_string(), entry->bci()); ++ } ++ OopMapCacheEntry* next = entry->_next; ++ entry->flush(); ++ FREE_C_HEAP_OBJ(entry, mtClass); ++ entry = next; ++ } + } + + void OopMapCache::compute_one_oop_map(methodHandle method, int bci, InterpreterOopMap* entry) { +diff --git a/hotspot/src/share/vm/interpreter/oopMapCache.hpp b/hotspot/src/share/vm/interpreter/oopMapCache.hpp +index 99fbe81681..ecbe4340aa 100644 +--- a/hotspot/src/share/vm/interpreter/oopMapCache.hpp ++++ b/hotspot/src/share/vm/interpreter/oopMapCache.hpp +@@ -147,17 +147,19 @@ class InterpreterOopMap: ResourceObj { + }; + + class OopMapCache : public CHeapObj { ++ static OopMapCacheEntry* volatile _old_entries; + private: + enum { _size = 32, // Use fixed size for now + _probe_depth = 3 // probe depth in case of collisions + }; + +- OopMapCacheEntry* _array; ++ OopMapCacheEntry* volatile * _array; + + unsigned int hash_value_for(methodHandle method, int bci) const; + OopMapCacheEntry* entry_at(int i) const; + +- mutable Mutex _mut; ++ bool put_at(int i, OopMapCacheEntry* entry, OopMapCacheEntry* old); ++ static void enqueue_for_cleanup(OopMapCacheEntry* entry); + + void flush(); + +@@ -170,13 +172,12 @@ class OopMapCache : public CHeapObj { + + // Returns the oopMap for (method, bci) in parameter "entry". + // Returns false if an oop map was not found. +- void lookup(methodHandle method, int bci, InterpreterOopMap* entry) const; ++ void lookup(methodHandle method, int bci, InterpreterOopMap* entry); + + // Compute an oop map without updating the cache or grabbing any locks (for debugging) + static void compute_one_oop_map(methodHandle method, int bci, InterpreterOopMap* entry); + +- // Returns total no. of bytes allocated as part of OopMapCache's +- static size_t memory_usage() PRODUCT_RETURN0; ++ static void cleanup_old_entries(); + }; + + #endif // SHARE_VM_INTERPRETER_OOPMAPCACHE_HPP +diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp +index ec36a59e07..8cfe06e9af 100644 +--- a/hotspot/src/share/vm/oops/method.cpp ++++ b/hotspot/src/share/vm/oops/method.cpp +@@ -216,26 +216,14 @@ int Method::fast_exception_handler_bci_for(methodHandle mh, KlassHandle ex_klass + } + + void Method::mask_for(int bci, InterpreterOopMap* mask) { +- +- Thread* myThread = Thread::current(); +- methodHandle h_this(myThread, this); +-#ifdef ASSERT +- bool has_capability = myThread->is_VM_thread() || +- myThread->is_ConcurrentGC_thread() || +- myThread->is_GC_task_thread(); +- +- if (!has_capability) { +- if (!VerifyStack && !VerifyLastFrame) { +- // verify stack calls this outside VM thread +- warning("oopmap should only be accessed by the " +- "VM, GC task or CMS threads (or during debugging)"); +- InterpreterOopMap local_mask; +- method_holder()->mask_for(h_this, bci, &local_mask); +- local_mask.print(); +- } ++ methodHandle h_this(Thread::current(), this); ++ // Only GC uses the OopMapCache during thread stack root scanning ++ // any other uses generate an oopmap but do not save it in the cache. ++ if (Universe::heap()->is_gc_active()) { ++ method_holder()->mask_for(h_this, bci, mask); ++ } else { ++ OopMapCache::compute_one_oop_map(h_this, bci, mask); + } +-#endif +- method_holder()->mask_for(h_this, bci, mask); + return; + } + +diff --git a/hotspot/src/share/vm/runtime/memprofiler.cpp b/hotspot/src/share/vm/runtime/memprofiler.cpp +index c1cfb60bd6..ddb22601fa 100644 +--- a/hotspot/src/share/vm/runtime/memprofiler.cpp ++++ b/hotspot/src/share/vm/runtime/memprofiler.cpp +@@ -129,7 +129,7 @@ void MemProfiler::do_trace() { + fprintf(_log_fp, UINTX_FORMAT_W(6) "," UINTX_FORMAT_W(6) "," UINTX_FORMAT_W(6) "\n", + handles_memory_usage / K, + resource_memory_usage / K, +- OopMapCache::memory_usage() / K); ++ 0L); + fflush(_log_fp); + } + +diff --git a/hotspot/src/share/vm/runtime/vframe.cpp b/hotspot/src/share/vm/runtime/vframe.cpp +index d98eb145ca..dfa02c55a5 100644 +--- a/hotspot/src/share/vm/runtime/vframe.cpp ++++ b/hotspot/src/share/vm/runtime/vframe.cpp +@@ -365,13 +365,7 @@ StackValueCollection* interpretedVFrame::expressions() const { + StackValueCollection* interpretedVFrame::stack_data(bool expressions) const { + + InterpreterOopMap oop_mask; +- // oopmap for current bci +- if (TraceDeoptimization && Verbose) { +- methodHandle m_h(Thread::current(), method()); +- OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask); +- } else { +- method()->mask_for(bci(), &oop_mask); +- } ++ method()->mask_for(bci(), &oop_mask); + + const int mask_len = oop_mask.number_of_entries(); + +-- +2.19.0-rc1 + diff --git a/8191129.patch b/8191129.patch new file mode 100644 index 0000000000000000000000000000000000000000..064e668dbb691d42d54c9a2306d9cc30c7140068 --- /dev/null +++ b/8191129.patch @@ -0,0 +1,116 @@ +From aee65626b97f366705d47c2d02df34aca5c64251 Mon Sep 17 00:00:00 2001 +From: hexuejin +Date: Fri, 12 Jul 2019 12:45:54 +0000 +Subject: [PATCH] Backport of JDK-8191129 + +summary: AARCH64: Invalid value passed to critical JNI function +LLT: +Bug url: https://bugs.openjdk.java.net/browse/JDK-8191129 +--- + .../src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp | 2 +- + hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp | 3 +++ + hotspot/src/share/vm/runtime/arguments.cpp | 22 ---------------------- + hotspot/src/share/vm/runtime/arguments.hpp | 22 ++++++++++++++++++++++ + 4 files changed, 26 insertions(+), 23 deletions(-) + +diff --git a/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp +index 3eec8a3273..c48f2235ee 100644 +--- a/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp ++++ b/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp +@@ -1660,7 +1660,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, + // critical natives they are offset down. + GrowableArray arg_order(2 * total_in_args); + VMRegPair tmp_vmreg; +- tmp_vmreg.set1(r19->as_VMReg()); ++ tmp_vmreg.set2(r19->as_VMReg()); + + if (!is_critical_native) { + for (int i = total_in_args - 1, c_arg = total_c_args - 1; i >= 0; i--, c_arg--) { +diff --git a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp +index fe0f49a209..df81bacbd7 100644 +--- a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp ++++ b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp +@@ -31,6 +31,7 @@ + #include "runtime/java.hpp" + #include "runtime/stubCodeGenerator.hpp" + #include "vm_version_aarch64.hpp" ++#include "runtime/arguments.hpp" + #ifdef TARGET_OS_FAMILY_linux + # include "os_linux.inline.hpp" + #endif +@@ -343,4 +344,6 @@ void VM_Version::initialize() { + g.generate_getPsrInfo()); + + get_processor_features(); ++ ++ UNSUPPORTED_OPTION(CriticalJNINatives, "CriticalJNINatives"); + } +diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp +index 6995c30405..83f5d3cfee 100644 +--- a/hotspot/src/share/vm/runtime/arguments.cpp ++++ b/hotspot/src/share/vm/runtime/arguments.cpp +@@ -76,28 +76,6 @@ + #endif + #define DEFAULT_JAVA_LAUNCHER "generic" + +-// Disable options not supported in this release, with a warning if they +-// were explicitly requested on the command-line +-#define UNSUPPORTED_OPTION(opt, description) \ +-do { \ +- if (opt) { \ +- if (FLAG_IS_CMDLINE(opt)) { \ +- warning(description " is disabled in this release."); \ +- } \ +- FLAG_SET_DEFAULT(opt, false); \ +- } \ +-} while(0) +- +-#define UNSUPPORTED_GC_OPTION(gc) \ +-do { \ +- if (gc) { \ +- if (FLAG_IS_CMDLINE(gc)) { \ +- warning(#gc " is not supported in this VM. Using Serial GC."); \ +- } \ +- FLAG_SET_DEFAULT(gc, false); \ +- } \ +-} while(0) +- + char** Arguments::_jvm_flags_array = NULL; + int Arguments::_num_jvm_flags = 0; + char** Arguments::_jvm_args_array = NULL; +diff --git a/hotspot/src/share/vm/runtime/arguments.hpp b/hotspot/src/share/vm/runtime/arguments.hpp +index 86c415e6a2..a5cd59ea60 100644 +--- a/hotspot/src/share/vm/runtime/arguments.hpp ++++ b/hotspot/src/share/vm/runtime/arguments.hpp +@@ -39,6 +39,28 @@ extern "C" { + typedef jint (JNICALL *vfprintf_hook_t)(FILE *fp, const char *format, va_list args) ATTRIBUTE_PRINTF(2, 0); + } + ++// Disable options not supported in this release, with a warning if they ++// were explicitly requested on the command-line ++#define UNSUPPORTED_OPTION(opt, description) \ ++do { \ ++ if (opt) { \ ++ if (FLAG_IS_CMDLINE(opt)) { \ ++ warning(description " is disabled in this release."); \ ++ } \ ++ FLAG_SET_DEFAULT(opt, false); \ ++ } \ ++} while(0) ++ ++#define UNSUPPORTED_GC_OPTION(gc) \ ++do { \ ++ if (gc) { \ ++ if (FLAG_IS_CMDLINE(gc)) { \ ++ warning(#gc " is not supported in this VM. Using Serial GC."); \ ++ } \ ++ FLAG_SET_DEFAULT(gc, false); \ ++ } \ ++} while(0) ++ + // Forward declarations + + class SysClassPath; +-- +2.12.3 + diff --git a/8191483.patch b/8191483.patch new file mode 100644 index 0000000000000000000000000000000000000000..a3567a2eb1b9b34f1158acf11362fb952d290a82 --- /dev/null +++ b/8191483.patch @@ -0,0 +1,144 @@ +From 8ae431d4207547ccd5a1d74c3a074c6b79097adb Mon Sep 17 00:00:00 2001 +From: hexuejin +Date: Fri, 28 Jun 2019 14:34:24 +0000 +Subject: [PATCH] Backport of JDK-8191483 + +summary: AbstractQueuedSynchronizer cancel/cancel race +LLT: +Bug url: https://bugs.openjdk.java.net/browse/JDK-8191483 +--- + .../locks/AbstractQueuedLongSynchronizer.java | 34 +++++++++++-------- + .../locks/AbstractQueuedSynchronizer.java | 34 +++++++++++-------- + 2 files changed, 40 insertions(+), 28 deletions(-) + +diff --git a/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java b/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java +index 47fdbfb944..8699fc9b8f 100644 +--- a/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java ++++ b/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java +@@ -531,7 +531,9 @@ public abstract class AbstractQueuedLongSynchronizer + + // predNext is the apparent node to unsplice. CASes below will + // fail if not, in which case, we lost race vs another cancel +- // or signal, so no further action is necessary. ++ // or signal, so no further action is necessary, although with ++ // a possibility that a cancelled node may transiently remain ++ // reachable. + Node predNext = pred.next; + + // Can use unconditional write instead of CAS here. +@@ -1131,13 +1133,13 @@ public abstract class AbstractQueuedLongSynchronizer + * at any time, a {@code true} return does not guarantee that any + * other thread will ever acquire. + * +- *

In this implementation, this operation returns in +- * constant time. +- * + * @return {@code true} if there may be other threads waiting to acquire + */ + public final boolean hasQueuedThreads() { +- return head != tail; ++ for (Node p = tail, h = head; p != h && p != null; p = p.prev) ++ if (p.waitStatus <= 0) ++ return true; ++ return false; + } + + /** +@@ -1288,17 +1290,21 @@ public abstract class AbstractQueuedLongSynchronizer + * @since 1.7 + */ + public final boolean hasQueuedPredecessors() { +- // The correctness of this depends on head being initialized +- // before tail and on head.next being accurate if the current +- // thread is first in queue. +- Node t = tail; // Read fields in reverse initialization order +- Node h = head; +- Node s; +- return h != t && +- ((s = h.next) == null || s.thread != Thread.currentThread()); ++ Node h, s; ++ if ((h = head) != null) { ++ if ((s = h.next) == null || s.waitStatus > 0) { ++ s = null; // traverse in case of concurrent cancellation ++ for (Node p = tail; p != h && p != null; p = p.prev) { ++ if (p.waitStatus <= 0) ++ s = p; ++ } ++ } ++ if (s != null && s.thread != Thread.currentThread()) ++ return true; ++ } ++ return false; + } + +- + // Instrumentation and monitoring methods + + /** +diff --git a/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java b/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java +index dce35765df..9088e5894b 100644 +--- a/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java ++++ b/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java +@@ -753,7 +753,9 @@ public abstract class AbstractQueuedSynchronizer + + // predNext is the apparent node to unsplice. CASes below will + // fail if not, in which case, we lost race vs another cancel +- // or signal, so no further action is necessary. ++ // or signal, so no further action is necessary, although with ++ // a possibility that a cancelled node may transiently remain ++ // reachable. + Node predNext = pred.next; + + // Can use unconditional write instead of CAS here. +@@ -1353,13 +1355,13 @@ public abstract class AbstractQueuedSynchronizer + * at any time, a {@code true} return does not guarantee that any + * other thread will ever acquire. + * +- *

In this implementation, this operation returns in +- * constant time. +- * + * @return {@code true} if there may be other threads waiting to acquire + */ + public final boolean hasQueuedThreads() { +- return head != tail; ++ for (Node p = tail, h = head; p != h && p != null; p = p.prev) ++ if (p.waitStatus <= 0) ++ return true; ++ return false; + } + + /** +@@ -1510,17 +1512,21 @@ public abstract class AbstractQueuedSynchronizer + * @since 1.7 + */ + public final boolean hasQueuedPredecessors() { +- // The correctness of this depends on head being initialized +- // before tail and on head.next being accurate if the current +- // thread is first in queue. +- Node t = tail; // Read fields in reverse initialization order +- Node h = head; +- Node s; +- return h != t && +- ((s = h.next) == null || s.thread != Thread.currentThread()); ++ Node h, s; ++ if ((h = head) != null) { ++ if ((s = h.next) == null || s.waitStatus > 0) { ++ s = null; // traverse in case of concurrent cancellation ++ for (Node p = tail; p != h && p != null; p = p.prev) { ++ if (p.waitStatus <= 0) ++ s = p; ++ } ++ } ++ if (s != null && s.thread != Thread.currentThread()) ++ return true; ++ } ++ return false; + } + +- + // Instrumentation and monitoring methods + + /** +-- +2.19.0-rc1 + diff --git a/8191955.patch b/8191955.patch new file mode 100644 index 0000000000000000000000000000000000000000..834c04901d6d3de886271e57e13c76521660151b --- /dev/null +++ b/8191955.patch @@ -0,0 +1,37 @@ +From 70641d56fb22355a85ad142700ae721a6a293908 Mon Sep 17 00:00:00 2001 +From: hexuejin +Date: Tue, 25 Jun 2019 10:40:42 +0000 +Subject: [PATCH] Backport of JDK-8191955 + +summary: incorrect prefetch distance causes an internal error +LLT: +Bug url: https://bugs.openjdk.java.net/browse/JDK-8191955 +--- + hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp +index f64e356558..ebdfeadf57 100644 +--- a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp ++++ b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp +@@ -144,6 +144,17 @@ void VM_Version::get_processor_features() { + if (PrefetchCopyIntervalInBytes >= 32768) + PrefetchCopyIntervalInBytes = 32760; + } ++ ++ if (AllocatePrefetchDistance !=-1 && (AllocatePrefetchDistance & 7)) { ++ warning("AllocatePrefetchDistance must be multiple of 8"); ++ AllocatePrefetchDistance &= ~7; ++ } ++ ++ if (AllocatePrefetchStepSize & 7) { ++ warning("AllocatePrefetchStepSize must be multiple of 8"); ++ AllocatePrefetchStepSize &= ~7; ++ } ++ + FLAG_SET_DEFAULT(UseSSE42Intrinsics, true); + + unsigned long auxv = getauxval(AT_HWCAP); +-- +2.19.0-rc1 + diff --git a/8194154-System-property-user.dir-should-not-be-chang.patch b/8194154-System-property-user.dir-should-not-be-chang.patch new file mode 100644 index 0000000000000000000000000000000000000000..2cc470a70d365c02fd0e698122f6d6e3370bff8a --- /dev/null +++ b/8194154-System-property-user.dir-should-not-be-chang.patch @@ -0,0 +1,158 @@ +From 8ca41b47ee0af3868fcfe745ddedd89cd342a25a Mon Sep 17 00:00:00 2001 +From: muyongmei +Date: Tue, 12 Nov 2019 15:31:59 +0000 +Subject: [PATCH] 8194154: System property user.dir should not be changed + +Summary: : System property user.dir should not be changed +LLT: jdk/test/java/io/File/UserDirChangedTest.java +Patch Type: backport +Bug url: https://bugs.openjdk.java.net/browse/JDK-8194154 +--- + .../solaris/classes/java/io/UnixFileSystem.java | 11 ++++- + .../windows/classes/java/io/WinNTFileSystem.java | 11 ++++- + jdk/test/java/io/File/UserDirChangedTest.java | 51 ++++++++++++++++++++++ + 3 files changed, 69 insertions(+), 4 deletions(-) + create mode 100644 jdk/test/java/io/File/UserDirChangedTest.java + +diff --git a/jdk/src/solaris/classes/java/io/UnixFileSystem.java b/jdk/src/solaris/classes/java/io/UnixFileSystem.java +index fb0fef6364..a6ef2d3a62 100644 +--- a/jdk/src/solaris/classes/java/io/UnixFileSystem.java ++++ b/jdk/src/solaris/classes/java/io/UnixFileSystem.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1998, 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 +@@ -34,6 +34,7 @@ class UnixFileSystem extends FileSystem { + private final char slash; + private final char colon; + private final String javaHome; ++ private final String userDir; + + public UnixFileSystem() { + slash = AccessController.doPrivileged( +@@ -42,6 +43,8 @@ class UnixFileSystem extends FileSystem { + new GetPropertyAction("path.separator")).charAt(0); + javaHome = AccessController.doPrivileged( + new GetPropertyAction("java.home")); ++ userDir = AccessController.doPrivileged( ++ new GetPropertyAction("user.dir")); + } + + +@@ -130,7 +133,11 @@ class UnixFileSystem extends FileSystem { + + public String resolve(File f) { + if (isAbsolute(f)) return f.getPath(); +- return resolve(System.getProperty("user.dir"), f.getPath()); ++ SecurityManager sm = System.getSecurityManager(); ++ if (sm != null) { ++ sm.checkPropertyAccess("user.dir"); ++ } ++ return resolve(userDir, f.getPath()); + } + + // Caches for canonicalization results to improve startup performance. +diff --git a/jdk/src/windows/classes/java/io/WinNTFileSystem.java b/jdk/src/windows/classes/java/io/WinNTFileSystem.java +index caa47f80c0..1844a662a2 100644 +--- a/jdk/src/windows/classes/java/io/WinNTFileSystem.java ++++ b/jdk/src/windows/classes/java/io/WinNTFileSystem.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2001, 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 +@@ -40,6 +40,7 @@ class WinNTFileSystem extends FileSystem { + private final char slash; + private final char altSlash; + private final char semicolon; ++ private final String userDir; + + public WinNTFileSystem() { + slash = AccessController.doPrivileged( +@@ -47,6 +48,8 @@ class WinNTFileSystem extends FileSystem { + semicolon = AccessController.doPrivileged( + new GetPropertyAction("path.separator")).charAt(0); + altSlash = (this.slash == '\\') ? '/' : '\\'; ++ userDir = AccessController.doPrivileged( ++ new GetPropertyAction("user.dir")); + } + + private boolean isSlash(char c) { +@@ -343,7 +346,11 @@ class WinNTFileSystem extends FileSystem { + private String getUserPath() { + /* For both compatibility and security, + we must look this up every time */ +- return normalize(System.getProperty("user.dir")); ++ SecurityManager sm = System.getSecurityManager(); ++ if (sm != null) { ++ sm.checkPropertyAccess("user.dir"); ++ } ++ return normalize(userDir); + } + + private String getDrive(String path) { +diff --git a/jdk/test/java/io/File/UserDirChangedTest.java b/jdk/test/java/io/File/UserDirChangedTest.java +new file mode 100644 +index 0000000000..9eccb768e6 +--- /dev/null ++++ b/jdk/test/java/io/File/UserDirChangedTest.java +@@ -0,0 +1,51 @@ ++/* ++ * Copyright (c) 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 ++ @bug 8194154 ++ @summary Test changing property user.dir on impacting getCanonicalPath ++ @run main/othervm UserDirChangedTest ++ */ ++ ++import java.io.File; ++ ++public class UserDirChangedTest { ++ public static void main(String[] args) throws Exception { ++ String keyUserDir = "user.dir"; ++ String userDirNew = "/home/a/b/c/"; ++ String fileName = "./a"; ++ ++ String userDir = System.getProperty(keyUserDir); ++ File file = new File(fileName); ++ String canFilePath = file.getCanonicalPath(); ++ ++ // now reset user.dir, this will cause crash on linux without bug 8194154 fixed. ++ System.setProperty(keyUserDir, userDirNew); ++ String newCanFilePath = file.getCanonicalPath(); ++ System.out.format("%24s %48s%n", "Canonical Path = ", canFilePath); ++ System.out.format("%24s %48s%n", "new Canonical Path = ", newCanFilePath); ++ if (!canFilePath.equals(newCanFilePath)) { ++ throw new RuntimeException("Changing property user.dir should have no effect on getCanonicalPath"); ++ } ++ } ++} +-- +2.12.3 + diff --git a/8194246.patch b/8194246.patch new file mode 100644 index 0000000000000000000000000000000000000000..60e2d0d3d3bc6d73c8c66c9a99f3c5880815da16 --- /dev/null +++ b/8194246.patch @@ -0,0 +1,57 @@ +From 86d65f4258c2c47751ae42281e84b6ba36712a08 Mon Sep 17 00:00:00 2001 +From: hexuejin +Date: Tue, 9 Jul 2019 10:41:26 +0000 +Subject: [PATCH] Backport of JDK-8194246 + +summary: JVM crashes when calling getStackTrace if stack contains a method that is a member of a very large class +LLT: +Bug url: https://bugs.openjdk.java.net/browse/JDK-8194246 +--- + hotspot/src/share/vm/classfile/javaClasses.cpp | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp +index ff65cb97e2..a9b40d235e 100644 +--- a/hotspot/src/share/vm/classfile/javaClasses.cpp ++++ b/hotspot/src/share/vm/classfile/javaClasses.cpp +@@ -1434,9 +1434,9 @@ class BacktraceBuilder: public StackObj { + method = mhandle(); + } + +- _methods->short_at_put(_index, method->orig_method_idnum()); ++ _methods->ushort_at_put(_index, method->orig_method_idnum()); + _bcis->int_at_put(_index, merge_bci_and_version(bci, method->constants()->version())); +- _cprefs->short_at_put(_index, method->name_index()); ++ _cprefs->ushort_at_put(_index, method->name_index()); + + // We need to save the mirrors in the backtrace to keep the class + // from being unloaded while we still have this stack trace. +@@ -1553,10 +1553,10 @@ void java_lang_Throwable::print_stack_trace(oop throwable, outputStream* st) { + Handle mirror(THREAD, mirrors->obj_at(index)); + // NULL mirror means end of stack trace + if (mirror.is_null()) goto handle_cause; +- int method = methods->short_at(index); ++ int method = methods->ushort_at(index); + int version = version_at(bcis->int_at(index)); + int bci = bci_at(bcis->int_at(index)); +- int cpref = cprefs->short_at(index); ++ int cpref = cprefs->ushort_at(index); + print_stack_element(st, mirror, method, version, bci, cpref); + } + result = objArrayHandle(THREAD, objArrayOop(result->obj_at(trace_next_offset))); +@@ -1849,10 +1849,10 @@ oop java_lang_Throwable::get_stack_trace_element(oop throwable, int index, TRAPS + + assert(methods != NULL && bcis != NULL && mirrors != NULL, "sanity check"); + +- int method = methods->short_at(chunk_index); ++ int method = methods->ushort_at(chunk_index); + int version = version_at(bcis->int_at(chunk_index)); + int bci = bci_at(bcis->int_at(chunk_index)); +- int cpref = cprefs->short_at(chunk_index); ++ int cpref = cprefs->ushort_at(chunk_index); + Handle mirror(THREAD, mirrors->obj_at(chunk_index)); + + // Chunk can be partial full +-- +2.19.0-rc1 + diff --git a/8202076.patch b/8202076.patch new file mode 100644 index 0000000000000000000000000000000000000000..e5405e6a01c2a8facce2ab7ab82c660acddf48f9 --- /dev/null +++ b/8202076.patch @@ -0,0 +1,72 @@ +From 480c546fa5d07a92d09fbe669a7a36e718baedca Mon Sep 17 00:00:00 2001 +From: xuwei +Date: Fri, 19 Apr 2019 16:15:04 +0000 +Subject: [PATCH] 8202076: test/jdk/java/io/File/WinSpecialFiles.java on windows with VS2017 + +Bug url: https://bugs.openjdk.java.net/browse/JDK-8202076 + +--- + .../native/java/io/WinNTFileSystem_md.c | 40 +++++++++++++++---- + 1 file changed, 33 insertions(+), 7 deletions(-) + +diff --git a/jdk/src/windows/native/java/io/WinNTFileSystem_md.c b/jdk/src/windows/native/java/io/WinNTFileSystem_md.c +index 4c61fa5817..8c8494743f 100644 +--- a/jdk/src/windows/native/java/io/WinNTFileSystem_md.c ++++ b/jdk/src/windows/native/java/io/WinNTFileSystem_md.c +@@ -35,6 +35,8 @@ + #include + #include + #include ++#include ++#include + + #include "jni.h" + #include "io_util.h" +@@ -525,13 +527,37 @@ Java_java_io_WinNTFileSystem_getLength(JNIEnv *env, jobject this, jobject file) + } + } else { + if (GetLastError() == ERROR_SHARING_VIOLATION) { +- /* The error is "share violation", which means the file/dir +- must exists. Try _wstati64, we know this at least works +- for pagefile.sys and hiberfil.sys. +- */ +- struct _stati64 sb; +- if (_wstati64(pathbuf, &sb) == 0) { +- rv = sb.st_size; ++ // The error is a "share violation", which means the file/dir ++ // must exist. Try FindFirstFile, we know this at least works ++ // for pagefile.sys. ++ WIN32_FIND_DATAW fileData; ++ HANDLE h = FindFirstFileW(pathbuf, &fileData); ++ if (h != INVALID_HANDLE_VALUE) { ++ if ((fileData.dwFileAttributes & ++ FILE_ATTRIBUTE_REPARSE_POINT) == 0) { ++ WCHAR backslash = L'\\'; ++ WCHAR *pslash = wcsrchr(pathbuf, backslash); ++ if (pslash == NULL) { ++ pslash = pathbuf; ++ } else { ++ pslash++; ++ } ++ WCHAR *fslash = wcsrchr(fileData.cFileName, backslash); ++ if (fslash == NULL) { ++ fslash = fileData.cFileName; ++ } else { ++ fslash++; ++ } ++ if (wcscmp(pslash, fslash) == 0) { ++ ULARGE_INTEGER length; ++ length.LowPart = fileData.nFileSizeLow; ++ length.HighPart = fileData.nFileSizeHigh; ++ if (length.QuadPart <= _I64_MAX) { ++ rv = (jlong)length.QuadPart; ++ } ++ } ++ } ++ FindClose(h); + } + } + } +-- +2.19.0 + diff --git a/8202952-C2-Unexpected-dead-nodes-after-matching.patch b/8202952-C2-Unexpected-dead-nodes-after-matching.patch new file mode 100644 index 0000000000000000000000000000000000000000..c6439cc4aa26d677257013f1c6635ab000a99cc0 --- /dev/null +++ b/8202952-C2-Unexpected-dead-nodes-after-matching.patch @@ -0,0 +1,26 @@ +From 11a00ac42593c9338b9ec8779dd8c142d1492907 Mon Sep 17 00:00:00 2001 +From: wangkun +Date: Mon, 27 May 2019 21:41:37 +0000 +Subject: [PATCH] 8202952:C2:Unexpected dead nodes after matching + +Bug url: https://bugs.openjdk.java.net/browse/JDK-8202952 + +--- + hotspot/src/share/vm/opto/matcher.cpp | 1 + + 1 files changed, 1 insertion(+), 1 deletions(-) + +diff --git a/hotspot/src/share/vm/opto/matcher.cpp b/hotspot/src/share/vm/opto/matcher.cpp +index ddd34e7503..6cc9e04e6c 100644 +--- a/hotspot/src/share/vm/opto/matcher.cpp ++++ b/hotspot/src/share/vm/opto/matcher.cpp +@@ -2236,6 +2236,7 @@ void Matcher::find_shared( Node *n ) { + // AtomicAdd is not an addressing expression. + // Cheap to find it by looking for screwy base. + !adr->in(AddPNode::Base)->is_top() && ++ LP64_ONLY( off->get_long() == (int) (off->get_long()) && ) // immL32 + // Are there other uses besides address expressions? + !is_visited(adr) ) { + address_visited.set(adr->_idx); // Flag as address_visited +-- +2.19.0 + diff --git a/8203699-java-lang-invoke-SpecialInte.patch b/8203699-java-lang-invoke-SpecialInte.patch new file mode 100644 index 0000000000000000000000000000000000000000..4d06c6ae729c620846b6ce47bf5d79aa7de26f56 --- /dev/null +++ b/8203699-java-lang-invoke-SpecialInte.patch @@ -0,0 +1,214 @@ +From f9f94ca5422ae79bf4ed90f41b7698febc6bed24 Mon Sep 17 00:00:00 2001 +From: zhangli +Date: Fri, 12 Jul 2019 15:26:27 +0000 +Subject: [PATCH] Backport of JDK-8203699: java/lang/invoke/SpecialInterfaceCall fails with SIGILL on aarch64 + +summary: Get super_klass value into r0 to make check in VerifyMethodHandles success +LLT: jdk/test/java/lang/invoke/lookup/TestDefenderMethodLookup.java +Bug url: https://bugs.openjdk.java.net/browse/JDK-8203699 + +--- + .../src/cpu/aarch64/vm/macroAssembler_aarch64.cpp | 6 +- + .../invoke/lookup/TestDefenderMethodLookup.java | 167 +++++++++++++++++++++ + 2 files changed, 172 insertions(+), 1 deletion(-) + create mode 100644 jdk/test/java/lang/invoke/lookup/TestDefenderMethodLookup.java + +diff --git a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp +index 42b732f37a..4659d628db 100644 +--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp ++++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp +@@ -1208,7 +1208,6 @@ void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass, + assert(sub_klass != r0, "killed reg"); // killed by mov(r0, super) + assert(sub_klass != r2, "killed reg"); // killed by lea(r2, &pst_counter) + +- // Get super_klass value into r0 (even if it was in r5 or r2). + RegSet pushed_registers; + if (!IS_A_TEMP(r2)) pushed_registers += r2; + if (!IS_A_TEMP(r5)) pushed_registers += r5; +@@ -1219,6 +1218,11 @@ void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass, + + push(pushed_registers, sp); + ++ // Get super_klass value into r0 (even if it was in r5 or r2) ++ if (super_klass != r0) { ++ mov(r0, super_klass); ++ } ++ + #ifndef PRODUCT + mov(rscratch2, (address)&SharedRuntime::_partial_subtype_ctr); + Address pst_counter_addr(rscratch2); +diff --git a/jdk/test/java/lang/invoke/lookup/TestDefenderMethodLookup.java b/jdk/test/java/lang/invoke/lookup/TestDefenderMethodLookup.java +new file mode 100644 +index 0000000000..1d0ade9fe4 +--- /dev/null ++++ b/jdk/test/java/lang/invoke/lookup/TestDefenderMethodLookup.java +@@ -0,0 +1,166 @@ ++/* ++ * @test ++ * @author zhangli ++ * @bug 8203699 ++ * @summary see https://code.huawei.com/HuaweiJDK/JVM-team/JVM/issues/1368 ++ * @run testng/othervm test.java.lang.invoke.lookup.TestDefenderMethodLookup ++ */ ++ ++package test.java.lang.invoke.lookup; ++ ++import org.testng.annotations.Test; ++import org.testng.Assert; ++import java.lang.invoke.*; ++import java.lang.invoke.MethodHandle; ++import java.lang.invoke.MethodHandles; ++import java.lang.invoke.MethodHandles.Lookup; ++ ++//@Test(groups = { "level.sanity" }) ++public class TestDefenderMethodLookup { ++ /** ++ * Get a SPECIAL MethodHandle for the method "test()V" in the DIRECT super interface DefenderInterface. The method ++ * has a default implementation in DefenderInterface and does NOT have an implementation in the class. ++ * Invoke the MethodHandle, and assert that the DefenderInterface.test was invoked (should return "default"). ++ * ++ * @throws Throwable No exceptions is expected. Any exception should be treated as an error. ++ */ ++ @Test ++ public void testDirectSuperInterface() throws Throwable { ++ DefenderInterface impl = new DefenderInterface() { ++ public MethodHandle run() throws Throwable { ++ Lookup l = DefenderInterface.lookup(); ++ Class defc = this.getClass(); ++ Class target = DefenderInterface.class; ++ MethodType mt = MethodType.methodType(String.class); ++ return l.findSpecial(defc, "test", mt, target); ++ } ++ }; ++ MethodHandle mh = impl.run(); ++ String result = (String)mh.invoke(impl); ++ Assert.assertEquals("default", result); ++ } ++ ++ /** ++ * Same as testDirectSuperInterface, but with the findSpecial arguments target and defc switched. ++ * ++ * @throws Throwable No exceptions is expected. Any exception should be treated as an error. ++ */ ++ @Test ++ public void testDirectSuperInterfaceSwitchedTargetDefc() throws Throwable { ++ DefenderInterface impl = new DefenderInterface() { ++ public MethodHandle run() throws Throwable { ++ Lookup l = MethodHandles.lookup(); ++ Class defc = this.getClass(); ++ Class target = DefenderInterface.class; ++ MethodType mt = MethodType.methodType(String.class); ++ // Switched target and defc ++ return l.findSpecial(target, "test", mt, defc); ++ } ++ }; ++ MethodHandle mh = impl.run(); ++ String result = (String)mh.invoke(impl); ++ Assert.assertEquals("default", result); ++ } ++ ++ /** ++ * Get a SPECIAL MethodHandle for the method "test()V" in the DIRECT super interface DefenderInterface. The method ++ * has a default implementation in DefenderInterface and does ALSO have an implementation in the class. ++ * Invoke the MethodHandle, and assert that the DefenderInterface.test was invoked (should return "default"). ++ * ++ * @throws Throwable No exceptions is expected. Any exception should be treated as an error. ++ */ ++ @Test ++ public void testDirectSuperInterfaceWithOverride() throws Throwable { ++ DefenderInterface impl = new DefenderInterface() { ++ @Test ++ @Override ++ public String test() { ++ return "impl"; ++ } ++ ++ public MethodHandle run() throws Throwable { ++ Lookup l = DefenderInterface.lookup(); ++ Class defc = DefenderInterface.class; ++ Class target = DefenderInterface.class; ++ MethodType mt = MethodType.methodType(String.class); ++ return l.findSpecial(defc, "test", mt, target); ++ } ++ }; ++ MethodHandle mh = impl.run(); ++ String result = (String)mh.invoke(impl); ++ Assert.assertEquals("default", result); ++ } ++ ++ /** ++ * Same as testDirectSuperInterfaceWithOverride, but with the findSpecial arguments target and defc switched. ++ * ++ * @throws Throwable No exceptions is expected. Any exception should be treated as an error. ++ */ ++ @Test ++ public void testDirectSuperInterfaceWithOverrideSwitchedTargetDefc() throws Throwable { ++ DefenderInterface impl = new DefenderInterface() { ++ @Override ++ public String test() { ++ return "impl"; ++ } ++ ++ public MethodHandle run() throws Throwable { ++ Lookup l = MethodHandles.lookup(); ++ Class defc = this.getClass(); ++ Class target = DefenderInterface.class; ++ MethodType mt = MethodType.methodType(String.class); ++ // Switched target and defc ++ return l.findSpecial(target, "test", mt, defc); ++ } ++ }; ++ MethodHandle mh = impl.run(); ++ String result = (String)mh.invoke(impl); ++ Assert.assertEquals("default", result); ++ } ++ ++ /** ++ * NEGATIVE
++ * Try to get a SPECIAL MethodHandle for the method "test()V" in the INDIRECT super interface DefenderInterface ++ * (through the interface DefenderSubInterface). ++ * ++ * @throws Throwable Expected exceptions are caught. Any other exception should be treated as an error. ++ */ ++ @Test ++ public void testIndirectSuperInterface() throws Throwable { ++ DefenderSubInterface impl = new DefenderSubInterface() { ++ public MethodHandle run() throws Throwable { ++ Lookup l = DefenderSubInterface.lookup(); ++ Class defc = this.getClass(); ++ Class target = DefenderInterface.class; ++ MethodType mt = MethodType.methodType(String.class); ++ return l.findSpecial(defc, "test", mt, target); ++ } ++ }; ++ try { ++ impl.run(); ++ Assert.fail("Successfully created supersend MethodHandle to INDIRECT super interface. Should fail with IllegalAccessException."); ++ } catch (IllegalAccessException e) {} ++ } ++} ++ ++interface DefenderInterface { ++ public default String test() { ++ return "default"; ++ } ++ ++ public static Lookup lookup() { ++ return MethodHandles.lookup(); ++ } ++ ++ public MethodHandle run() throws Throwable; ++} ++ ++interface DefenderSubInterface extends DefenderInterface { ++ public default String test() { ++ return "subDefault"; ++ } ++ ++ public static Lookup lookup() { ++ return MethodHandles.lookup(); ++ } ++} +-- +2.12.3 + diff --git a/8214345.patch b/8214345.patch new file mode 100644 index 0000000000000000000000000000000000000000..1f6dd7ef8f6fad8f6cd984306f2a49a3de6e3682 --- /dev/null +++ b/8214345.patch @@ -0,0 +1,71 @@ +From a3a0d29610bef14392cf20a8d5807ab288320056 Mon Sep 17 00:00:00 2001 +From: hexuejin +Date: Mon, 1 Jul 2019 11:47:36 +0000 +Subject: [PATCH] Backpot of JDK-8214345 + +Summary: infinite recursion while checking super class +LLT: langtools/test/tools/javac/generics/ClassBoundCheckingOverflow.java +Bug url: https://bugs.openjdk.java.net/browse/JDK-8214345 +--- + .../classes/com/sun/tools/javac/comp/Check.java | 7 +++++++ + .../javac/generics/ClassBoundCheckingOverflow.java | 12 ++++++++++++ + .../javac/generics/ClassBoundCheckingOverflow.out | 3 +++ + 3 files changed, 22 insertions(+) + create mode 100644 langtools/test/tools/javac/generics/ClassBoundCheckingOverflow.java + create mode 100644 langtools/test/tools/javac/generics/ClassBoundCheckingOverflow.out + +diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +index d5e9c47a41..68af438218 100644 +--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java ++++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +@@ -2617,6 +2617,10 @@ public class Check { + if (type.isErroneous()) return; + for (List l = types.interfaces(type); l.nonEmpty(); l = l.tail) { + Type it = l.head; ++ if (type.hasTag(CLASS) && !it.hasTag(CLASS)) { ++ continue; ++ } // JLS 8.1.5 ++ + Type oldit = seensofar.put(it.tsym, it); + if (oldit != null) { + List oldparams = oldit.allparams(); +@@ -2629,6 +2633,9 @@ public class Check { + checkClassBounds(pos, seensofar, it); + } + Type st = types.supertype(type); ++ if (type.hasTag(CLASS) && !st.hasTag(CLASS)) { ++ return; ++ } // JLS 8.1.4 + if (st != Type.noType) checkClassBounds(pos, seensofar, st); + } + +diff --git a/langtools/test/tools/javac/generics/ClassBoundCheckingOverflow.java b/langtools/test/tools/javac/generics/ClassBoundCheckingOverflow.java +new file mode 100644 +index 0000000000..1aeb7d71ab +--- /dev/null ++++ b/langtools/test/tools/javac/generics/ClassBoundCheckingOverflow.java +@@ -0,0 +1,12 @@ ++/* ++ * @test /nodynamiccopyright/ ++ * @bug 8214345 ++ * @summary infinite recursion while checking super class ++ * ++ * @compile/fail/ref=ClassBoundCheckingOverflow.out -XDrawDiagnostics ClassBoundCheckingOverflow.java ++ */ ++ ++public class ClassBoundCheckingOverflow { ++ abstract class InfiniteLoop1> extends E {} ++ abstract class InfiniteLoop2> implements E {} ++} +diff --git a/langtools/test/tools/javac/generics/ClassBoundCheckingOverflow.out b/langtools/test/tools/javac/generics/ClassBoundCheckingOverflow.out +new file mode 100644 +index 0000000000..bed6acfd7f +--- /dev/null ++++ b/langtools/test/tools/javac/generics/ClassBoundCheckingOverflow.out +@@ -0,0 +1,3 @@ ++ClassBoundCheckingOverflow.java:10:70: compiler.err.type.found.req: (compiler.misc.type.parameter: E), (compiler.misc.type.req.class) ++ClassBoundCheckingOverflow.java:11:73: compiler.err.type.found.req: (compiler.misc.type.parameter: E), (compiler.misc.type.req.class) ++2 errors +-- +2.19.0-rc1 + diff --git a/8221658.patch b/8221658.patch new file mode 100644 index 0000000000000000000000000000000000000000..43d3c51d4aad4a3d5e1a95ff349f172090a89ae8 --- /dev/null +++ b/8221658.patch @@ -0,0 +1,36 @@ +From a0559370c5b6ca2a080b673da7198ae366aa34bd Mon Sep 17 00:00:00 2001 +From: jitao +Date: Fri, 19 Apr 2019 17:34:30 +0000 +Subject: [PATCH] 8221658: aarch64: add necessary predicate for ubfx patterns + +Bug url: https://bugs.openjdk.java.net/browse/JDK-8221658 + +--- + hotspot/src/cpu/aarch64/vm/aarch64.ad | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hotspot/src/cpu/aarch64/vm/aarch64.ad b/hotspot/src/cpu/aarch64/vm/aarch64.ad +index d779915db..a82629edd 100644 +--- a/hotspot/src/cpu/aarch64/vm/aarch64.ad ++++ b/hotspot/src/cpu/aarch64/vm/aarch64.ad +@@ -10777,7 +10777,7 @@ instruct ubfxwI(iRegINoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask) + long mask = $mask$$constant; + int width = exact_log2(mask+1); + __ ubfxw(as_Register($dst$$reg), +- as_Register($src$$reg), rshift, width); ++ as_Register($src$$reg), $rshift$$constant & 31, width); + %} + ins_pipe(ialu_reg_shift); + %} +@@ -10792,7 +10792,7 @@ instruct ubfxL(iRegLNoSp dst, iRegL src, immI rshift, immL_bitmask mask) + long mask = $mask$$constant; + int width = exact_log2(mask+1); + __ ubfx(as_Register($dst$$reg), +- as_Register($src$$reg), rshift, width); ++ as_Register($src$$reg), $rshift$$constant & 63, width); + %} + ins_pipe(ialu_reg_shift); + %} +-- +2.19.0 + diff --git a/8229169.patch b/8229169.patch new file mode 100644 index 0000000000000000000000000000000000000000..99016d3d390fb78e43d7e7b912c81f4cc3f887c5 --- /dev/null +++ b/8229169.patch @@ -0,0 +1,32 @@ +From b5af97426c82ead4df42f3824a32e9ee634585a4 Mon Sep 17 00:00:00 2001 +From: wuyan +Date: Sat, 21 Sep 2019 15:47:05 +0800 +Subject: [PATCH] Backport of JDK-8229169 + +Summary: [Backport of JDK-8229169] False failure of GenericTaskQueue::pop_local on architectures with weak memory model +LLT: +Bug url: https://bugs.openjdk.java.net/browse/JDK-8229169 + +--- + hotspot/src/share/vm/utilities/taskqueue.hpp | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/hotspot/src/share/vm/utilities/taskqueue.hpp b/hotspot/src/share/vm/utilities/taskqueue.hpp +index 6ebd185b76..798f9aa183 100644 +--- a/hotspot/src/share/vm/utilities/taskqueue.hpp ++++ b/hotspot/src/share/vm/utilities/taskqueue.hpp +@@ -724,6 +724,11 @@ GenericTaskQueue::pop_local(volatile E& t) { + } else { + // Otherwise, the queue contained exactly one element; we take the slow + // path. ++ ++ // The barrier is required to prevent reordering the two reads of _age: ++ // one is the _age.get() below, and the other is _age.top() above the if-stmt. ++ // The algorithm may fail if _age.get() reads an older value than _age.top(). ++ OrderAccess::loadload(); + return pop_local_slow(localBot, _age.get()); + } + } +-- +2.12.3 + diff --git a/8231584-Deadlock-with-ClassLoader.findLibrary-and-Sy.patch b/8231584-Deadlock-with-ClassLoader.findLibrary-and-Sy.patch new file mode 100644 index 0000000000000000000000000000000000000000..30b7fd18b9346d8b82b914e03528ee60f8f34d18 --- /dev/null +++ b/8231584-Deadlock-with-ClassLoader.findLibrary-and-Sy.patch @@ -0,0 +1,376 @@ +From 219a986b26fe9813730939038b3b1d70255d19a6 Mon Sep 17 00:00:00 2001 +From: wangshuai +Date: Mon, 11 Nov 2019 19:42:17 +0000 +Subject: [PATCH] 8231584:Deadlock with ClassLoader.findLibrary and + System.loadLibrary call + +Summary::Deadlock with ClassLoader.findLibrary and System.loadLibrary call +LLT:FileSystemsDeadlockTest.java +Patch Type:backport +bug url: https://bugs.openjdk.java.net/browse/JDK-8231584 +--- + jdk/src/share/classes/java/lang/ClassLoader.java | 32 +++-- + jdk/src/share/classes/java/lang/Runtime.java | 7 +- + jdk/src/share/classes/java/lang/System.java | 2 + + .../lang/Runtime/loadLibrary/LoadLibraryTest.java | 156 +++++++++++++++++++++ + jdk/test/java/lang/Runtime/loadLibrary/Target.java | 34 +++++ + .../java/lang/Runtime/loadLibrary/Target2.java | 29 ++++ + 6 files changed, 247 insertions(+), 13 deletions(-) + create mode 100644 jdk/test/java/lang/Runtime/loadLibrary/LoadLibraryTest.java + create mode 100644 jdk/test/java/lang/Runtime/loadLibrary/Target.java + create mode 100644 jdk/test/java/lang/Runtime/loadLibrary/Target2.java + +diff --git a/jdk/src/share/classes/java/lang/ClassLoader.java b/jdk/src/share/classes/java/lang/ClassLoader.java +index 2e98092f63..925fdacce3 100644 +--- a/jdk/src/share/classes/java/lang/ClassLoader.java ++++ b/jdk/src/share/classes/java/lang/ClassLoader.java +@@ -1,5 +1,6 @@ + /* + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2019, Azul Systems, 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 +@@ -1467,6 +1468,17 @@ public abstract class ClassLoader { + } + } + ++ /* ++ * Initialize default paths for native libraries search. ++ * Must be done early as JDK may load libraries during bootstrap. ++ * ++ * @see java.lang.System#initPhase1 ++ */ ++ static void initLibraryPaths() { ++ usr_paths = initializePath("java.library.path"); ++ sys_paths = initializePath("sun.boot.library.path"); ++ } ++ + // Returns true if the specified class loader can be found in this class + // loader's delegation chain. + boolean isAncestor(ClassLoader cl) { +@@ -1809,10 +1821,9 @@ public abstract class ClassLoader { + boolean isAbsolute) { + ClassLoader loader = + (fromClass == null) ? null : fromClass.getClassLoader(); +- if (sys_paths == null) { +- usr_paths = initializePath("java.library.path"); +- sys_paths = initializePath("sun.boot.library.path"); +- } ++ assert sys_paths != null : "should be initialized at this point"; ++ assert usr_paths != null : "should be initialized at this point"; ++ + if (isAbsolute) { + if (loadLibrary0(fromClass, new File(name))) { + return; +@@ -1902,13 +1913,14 @@ public abstract class ClassLoader { + name + + " already loaded in another classloader"); + } +- /* If the library is being loaded (must be by the same thread, +- * because Runtime.load and Runtime.loadLibrary are +- * synchronous). The reason is can occur is that the JNI_OnLoad +- * function can cause another loadLibrary invocation. ++ /* ++ * When a library is being loaded, JNI_OnLoad function can cause ++ * another loadLibrary invocation that should succeed. + * +- * Thus we can use a static stack to hold the list of libraries +- * we are loading. ++ * We use a static stack to hold the list of libraries we are ++ * loading because this can happen only when called by the ++ * same thread because Runtime.load and Runtime.loadLibrary ++ * are synchronous. + * + * If there is a pending load operation for the library, we + * immediately return success; otherwise, we raise +diff --git a/jdk/src/share/classes/java/lang/Runtime.java b/jdk/src/share/classes/java/lang/Runtime.java +index 9e53dc939e..5039059149 100644 +--- a/jdk/src/share/classes/java/lang/Runtime.java ++++ b/jdk/src/share/classes/java/lang/Runtime.java +@@ -1,5 +1,6 @@ + /* + * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2019, Azul Systems, 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 +@@ -797,7 +798,7 @@ public class Runtime { + load0(Reflection.getCallerClass(), filename); + } + +- synchronized void load0(Class fromClass, String filename) { ++ void load0(Class fromClass, String filename) { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkLink(filename); +@@ -858,14 +859,14 @@ public class Runtime { + loadLibrary0(Reflection.getCallerClass(), libname); + } + +- synchronized void loadLibrary0(Class fromClass, String libname) { ++ void loadLibrary0(Class fromClass, String libname) { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkLink(libname); + } + if (libname.indexOf((int)File.separatorChar) != -1) { + throw new UnsatisfiedLinkError( +- "Directory separator should not appear in library name: " + libname); ++ "Directory separator should not appear in library name: " + libname); + } + ClassLoader.loadLibrary(fromClass, libname, false); + } +diff --git a/jdk/src/share/classes/java/lang/System.java b/jdk/src/share/classes/java/lang/System.java +index b2747fa7a4..7bc235beff 100644 +--- a/jdk/src/share/classes/java/lang/System.java ++++ b/jdk/src/share/classes/java/lang/System.java +@@ -1192,6 +1192,8 @@ public final class System { + setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding"))); + setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding"))); + ++ ClassLoader.initLibraryPaths(); ++ + // Load the zip library now in order to keep java.util.zip.ZipFile + // from trying to use itself to load this library later. + loadLibrary("zip"); +diff --git a/jdk/test/java/lang/Runtime/loadLibrary/LoadLibraryTest.java b/jdk/test/java/lang/Runtime/loadLibrary/LoadLibraryTest.java +new file mode 100644 +index 0000000000..62eac12e18 +--- /dev/null ++++ b/jdk/test/java/lang/Runtime/loadLibrary/LoadLibraryTest.java +@@ -0,0 +1,156 @@ ++/* ++ * Copyright (c) 2018, Amazon and/or its affiliates. All rights reserved. ++ * Copyright (c) 2019, Azul Systems, 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 ++ * 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 8231584 ++ * @library /lib/testlibrary ++ * @run main/othervm LoadLibraryTest ++ */ ++ ++import java.nio.file.FileSystems; ++import java.nio.file.Files; ++import java.nio.file.Paths; ++import java.nio.file.Path; ++import java.net.MalformedURLException; ++import java.net.URLClassLoader; ++import java.net.URL; ++ ++public class LoadLibraryTest { ++ static Thread thread1 = null; ++ static Thread thread2 = null; ++ ++ static volatile boolean thread1Ready = false; ++ ++ private static final String TEST_SRC = System.getProperty("test.src"); ++ private static final Path SRC_DIR = Paths.get(TEST_SRC, "src"); ++ private static final Path CLS_DIR = Paths.get("classes"); ++ ++ static TestClassLoader loader; ++ static void someLibLoad() { ++ try { ++/* ++ FileSystems.getDefault(); ++ ++ // jdk/jdk: loads directly from Bootstrap Classloader (doesn't take lock on Runtime) ++ java.net.NetworkInterface.getNetworkInterfaces(); ++ ++ System.out.println(jdk.net.ExtendedSocketOptions.SO_FLOW_SLA); ++*/ ++ Class c = Class.forName("Target2", true, loader); ++ } catch (Exception e) { ++ throw new RuntimeException(e); ++ } ++ } ++ ++ static class TestClassLoader extends URLClassLoader { ++ boolean passed = false; ++ ++ public boolean passed() { ++ return passed; ++ } ++ ++ TestClassLoader() throws MalformedURLException { ++ super(new URL[] { new URL("file://" + CLS_DIR.toAbsolutePath().toString() + '/') }); ++ } ++ ++ public String findLibrary(String name) { ++ System.out.println("findLibrary " + name); ++ ++ if ("someLibrary".equals(name)) { ++ try { ++ synchronized(thread1) { ++ while(!thread1Ready) { ++ thread1.wait(); ++ } ++ thread1.notifyAll(); ++ } ++ ++ Thread.sleep(10000); ++ ++ System.out.println("Thread2 load"); ++ someLibLoad(); ++ ++ // no deadlock happened ++ passed = true; ++ } catch (Exception e) { ++ throw new RuntimeException(e); ++ } ++ return null; ++ } ++ ++ return super.findLibrary(name); ++ } ++ } ++ ++ ++ public static void main(String[] args) throws Exception { ++ loader = new TestClassLoader(); ++ ++ if (!CompilerUtils.compile(SRC_DIR, CLS_DIR)) { ++ throw new Exception("Can't compile"); ++ } ++ ++ thread1 = new Thread() { ++ public void run() { ++ try { ++ synchronized(this) { ++ thread1Ready = true; ++ thread1.notifyAll(); ++ thread1.wait(); ++ } ++ } catch(InterruptedException e) { ++ throw new RuntimeException(e); ++ } ++ ++ System.out.println("Thread1 load"); ++ someLibLoad(); ++ }; ++ }; ++ ++ thread2 = new Thread() { ++ public void run() { ++ try { ++ Class c = Class.forName("Target", true, loader); ++ System.out.println(c); ++ } catch (Exception e) { ++ throw new RuntimeException(e); ++ } ++ }; ++ }; ++ ++ thread1.setDaemon(true); ++ thread2.setDaemon(true); ++ ++ thread1.start(); ++ thread2.start(); ++ ++ thread1.join(); ++ thread2.join(); ++ ++ if (!loader.passed()) { ++ throw new RuntimeException("FAIL"); ++ } ++ } ++} +diff --git a/jdk/test/java/lang/Runtime/loadLibrary/Target.java b/jdk/test/java/lang/Runtime/loadLibrary/Target.java +new file mode 100644 +index 0000000000..fc51481053 +--- /dev/null ++++ b/jdk/test/java/lang/Runtime/loadLibrary/Target.java +@@ -0,0 +1,34 @@ ++/* ++ * Copyright (c) 2019, Azul Systems, 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 ++ * 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. ++ */ ++ ++class Target { ++ static { ++ try { ++ System.loadLibrary("someLibrary"); ++ throw new RuntimeException("someLibrary was loaded"); ++ } catch (UnsatisfiedLinkError e) { ++ // expected: we do not have a someLibrary ++ } ++ } ++} ++ +diff --git a/jdk/test/java/lang/Runtime/loadLibrary/Target2.java b/jdk/test/java/lang/Runtime/loadLibrary/Target2.java +new file mode 100644 +index 0000000000..bc8dfc5e63 +--- /dev/null ++++ b/jdk/test/java/lang/Runtime/loadLibrary/Target2.java +@@ -0,0 +1,29 @@ ++/* ++ * Copyright (c) 2019, Azul Systems, 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 ++ * 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. ++ */ ++ ++class Target2 { ++ static { ++ System.loadLibrary("awt"); ++ } ++} ++ +-- +2.12.3 + diff --git a/8231988.patch b/8231988.patch new file mode 100644 index 0000000000000000000000000000000000000000..e344caff378806bca1dd311f6c9b4eee3cae205a --- /dev/null +++ b/8231988.patch @@ -0,0 +1,32 @@ +From d73c61c26fd00e3cb8daa24fa254b756c48309ca Mon Sep 17 00:00:00 2001 +From: wanghuang +Date: Sun, 29 Sep 2019 15:57:24 +0000 +Subject: [PATCH] 8231988: Unexpected test result caused by C2 IdealLoopTree::do_remove_empty_loop + +Summary: Unexpected test result caused by C2 IdealLoopTree::do_remove_empty_loop +LLT: +Bug url: https://bugs.openjdk.java.net/browse/JDK-8231988 +--- + hotspot/src/share/vm/opto/loopTransform.cpp | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/hotspot/src/share/vm/opto/loopTransform.cpp b/hotspot/src/share/vm/opto/loopTransform.cpp +index caf7a9b758..c7bb19763c 100644 +--- a/hotspot/src/share/vm/opto/loopTransform.cpp ++++ b/hotspot/src/share/vm/opto/loopTransform.cpp +@@ -2215,6 +2215,12 @@ bool IdealLoopTree::policy_do_remove_empty_loop( PhaseIdealLoop *phase ) { + // We also need to replace the original limit to collapse loop exit. + Node* cmp = cl->loopexit()->cmp_node(); + assert(cl->limit() == cmp->in(2), "sanity"); ++ if (cmp->outcnt() > 1) { //we have more than one BoolNode here ++ cmp = cmp->clone(); ++ cmp = phase->_igvn.register_new_node_with_optimizer(cmp); ++ BoolNode *bl = cl->loopexit()->in(CountedLoopEndNode::TestValue)->as_Bool(); ++ phase->_igvn.replace_input_of(bl, 1, cmp); // put BoolNode on worklist ++ } + phase->_igvn._worklist.push(cmp->in(2)); // put limit on worklist + phase->_igvn.replace_input_of(cmp, 2, exact_limit); // put cmp on worklist + } +-- +2.12.3 + diff --git a/8233839-aarch64-missing-memory-barrier-in-NewObjectA.patch b/8233839-aarch64-missing-memory-barrier-in-NewObjectA.patch new file mode 100644 index 0000000000000000000000000000000000000000..15bdb28a2676da11d98a629b2c8b826e4bbfd954 --- /dev/null +++ b/8233839-aarch64-missing-memory-barrier-in-NewObjectA.patch @@ -0,0 +1,37 @@ +From 485dd83220fa3f41b979d5f6bc3fe5866f673ca7 Mon Sep 17 00:00:00 2001 +From: zhanggaofeng +Date: Mon, 11 Nov 2019 14:18:42 +0000 +Subject: [PATCH] 8233839-aarch64: missing memory barrier in NewObjectArrayStub + and NewTypeArrayStub + +Summary: aarch64: missing memory barrier in NewObjectArrayStub and NewTypeArrayStub +LLT: org.openjdk.jcstress.tests.defaultValues.arrays.small.plain.StringTest +Patch Type: backport +Bug url: https://bugs.openjdk.java.net/browse/JDK-8233839 +--- + hotspot/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/hotspot/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp +index 20a35432d1..c1e48ac97c 100644 +--- a/hotspot/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp ++++ b/hotspot/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp +@@ -877,6 +877,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { + __ sub(arr_size, arr_size, t1); // body length + __ add(t1, t1, obj); // body start + __ initialize_body(t1, arr_size, 0, t2); ++ __ membar(Assembler::StoreStore); + __ verify_oop(obj); + + __ ret(lr); +@@ -905,6 +906,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { + __ sub(arr_size, arr_size, t1); // body length + __ add(t1, t1, obj); // body start + __ initialize_body(t1, arr_size, 0, t2); ++ __ membar(Assembler::StoreStore); + __ verify_oop(obj); + + __ ret(lr); +-- +2.12.3 + diff --git a/8234264-Incorrrect-8047434-JDK-8-backport-in-8219677.patch b/8234264-Incorrrect-8047434-JDK-8-backport-in-8219677.patch new file mode 100644 index 0000000000000000000000000000000000000000..444631c6c8385a8d2afa0fcdd66dbf09cd59a8d5 --- /dev/null +++ b/8234264-Incorrrect-8047434-JDK-8-backport-in-8219677.patch @@ -0,0 +1,38 @@ +From 8af05a28e8856fb9a05e87e9199b1c9c21ab1c17 Mon Sep 17 00:00:00 2001 +From: zhanggaofeng +Date: Thu, 14 Nov 2019 14:26:22 +0000 +Subject: [PATCH] 8234264: Incorrect 8047434 JDK 8 backport in 8219677 + +Summary: Runtime: community backport from JDK12 to JDK8 about this issue is not correctly implemented. +LLT: NA +Patch Type: backport +Bug url: https://bugs.openjdk.java.net/browse/JDK-8234264 +--- + hotspot/src/share/vm/utilities/vmError.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hotspot/src/share/vm/utilities/vmError.cpp b/hotspot/src/share/vm/utilities/vmError.cpp +index ef3bb5cee5..49b978a025 100644 +--- a/hotspot/src/share/vm/utilities/vmError.cpp ++++ b/hotspot/src/share/vm/utilities/vmError.cpp +@@ -1060,7 +1060,7 @@ void VMError::report_and_die() { + out.print_raw (cmd); + out.print_raw_cr("\" ..."); + +- if (os::fork_and_exec(cmd, true) < 0) { ++ if (os::fork_and_exec(cmd) < 0) { + out.print_cr("os::fork_and_exec failed: %s (%d)", strerror(errno), errno); + } + } +@@ -1147,7 +1147,7 @@ void VM_ReportJavaOutOfMemory::doit() { + #endif + tty->print_cr("\"%s\"...", cmd); + +- if (os::fork_and_exec(cmd) < 0) { ++ if (os::fork_and_exec(cmd, true) < 0) { + tty->print_cr("os::fork_and_exec failed: %s (%d)", strerror(errno), errno); + } + } +-- +2.12.3 + diff --git a/AARCH64-fix-itable-stub-code-size-limit.patch b/AARCH64-fix-itable-stub-code-size-limit.patch new file mode 100644 index 0000000000000000000000000000000000000000..5f43968c930a6eb8936df9a4b01aae489728a072 --- /dev/null +++ b/AARCH64-fix-itable-stub-code-size-limit.patch @@ -0,0 +1,44 @@ +From 8e390a2cdfff1138f3ba6e694395cd8790aa1603 Mon Sep 17 00:00:00 2001 +From: guoge +Date: Fri, 19 Apr 2019 17:33:26 +0000 +Subject: [PATCH] AARCH64 fix itable stub code size limit + +--- + hotspot/src/cpu/aarch64/vm/vtableStubs_aarch64.cpp | 12 +++++++++--- + hotspot/src/share/vm/code/codeCache.cpp | 2 ++ + 2 files changed, 11 insertions(+), 3 deletions(-) + +diff --git a/hotspot/src/cpu/aarch64/vm/vtableStubs_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/vtableStubs_aarch64.cpp +index d8d1ec11ba..645b690dae 100644 +--- a/hotspot/src/cpu/aarch64/vm/vtableStubs_aarch64.cpp ++++ b/hotspot/src/cpu/aarch64/vm/vtableStubs_aarch64.cpp +@@ -130,6 +130,10 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) { + // returned by pd_code_size_limit! + const int code_length = VtableStub::pd_code_size_limit(false); + VtableStub* s = new(code_length) VtableStub(false, itable_index); ++ // Can be NULL if there is no free space in the code cache. ++ if (s == NULL) { ++ return NULL; ++ } + ResourceMark rm; + CodeBuffer cb(s->entry_point(), code_length); + MacroAssembler* masm = new MacroAssembler(&cb); +@@ -222,10 +226,12 @@ int VtableStub::pd_code_size_limit(bool is_vtable_stub) { + if (CountCompiledCalls) + size += 6 * 4; + // FIXME: vtable stubs only need 36 bytes +- if (is_vtable_stub) ++ if (is_vtable_stub) { + size += 52; +- else +- size += 176; ++ } else { ++ // itable code size limit, see issue ++ size += 192; ++ } + return size; + + // In order to tune these parameters, run the JVM with VM options +-- +2.19.0 + diff --git a/FromCardCache-default-card-index-can-cause.patch b/FromCardCache-default-card-index-can-cause.patch new file mode 100644 index 0000000000000000000000000000000000000000..f4483e4cec70668f05c03f6f3388b39a345b9ea4 --- /dev/null +++ b/FromCardCache-default-card-index-can-cause.patch @@ -0,0 +1,278 @@ +From 3cdfc055dbaae92f295ac0c3ae52d33e1650e8c1 Mon Sep 17 00:00:00 2001 +From: hexuejin +Date: Wed, 19 Jun 2019 09:30:39 +0000 +Subject: [PATCH] 8196485: FromCardCache default card index can cause crashes + +Summary: FromCardCache default card index can cause crashes +LLT: hotspot/test/gc/g1/TestFromCardCacheIndex.java +Bug url: https://bugs.openjdk.java.net/browse/JDK-8196485 +--- + .../gc_implementation/g1/heapRegionRemSet.cpp | 36 +++--- + .../gc_implementation/g1/heapRegionRemSet.hpp | 17 +-- + .../test/gc/g1/TestFromCardCacheIndex.java | 120 ++++++++++++++++++ + 3 files changed, 146 insertions(+), 27 deletions(-) + create mode 100644 hotspot/test/gc/g1/TestFromCardCacheIndex.java + +diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp +index 437636281b..ad8a3562e8 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp +@@ -102,17 +102,8 @@ protected: + // If the test below fails, then this table was reused concurrently + // with this operation. This is OK, since the old table was coarsened, + // and adding a bit to the new table is never incorrect. +- // If the table used to belong to a continues humongous region and is +- // now reused for the corresponding start humongous region, we need to +- // make sure that we detect this. Thus, we call is_in_reserved_raw() +- // instead of just is_in_reserved() here. + if (loc_hr->is_in_reserved_raw(from)) { +- size_t hw_offset = pointer_delta((HeapWord*)from, loc_hr->bottom()); +- CardIdx_t from_card = (CardIdx_t) +- hw_offset >> (CardTableModRefBS::card_shift - LogHeapWordSize); +- +- assert(0 <= from_card && (size_t)from_card < HeapRegion::CardsPerRegion, +- "Must be in range."); ++ CardIdx_t from_card = OtherRegionsTable::card_within_region(from, loc_hr); + add_card_work(from_card, par); + } + } +@@ -331,6 +322,12 @@ void OtherRegionsTable::link_to_all(PerRegionTable* prt) { + "just checking"); + } + ++CardIdx_t OtherRegionsTable::card_within_region(OopOrNarrowOopStar within_region, HeapRegion* hr) { ++ assert(hr->is_in_reserved(within_region),"should be"); ++ CardIdx_t result = (CardIdx_t)(pointer_delta((HeapWord*)within_region, hr->bottom()) >> (CardTableModRefBS::card_shift - LogHeapWordSize)); ++ return result; ++} ++ + void OtherRegionsTable::unlink_from_all(PerRegionTable* prt) { + if (prt->prev() != NULL) { + assert(_first_all_fine_prts != prt, "just checking"); +@@ -364,18 +361,17 @@ void OtherRegionsTable::unlink_from_all(PerRegionTable* prt) { + "just checking"); + } + +-int** FromCardCache::_cache = NULL; +-uint FromCardCache::_max_regions = 0; +-size_t FromCardCache::_static_mem_size = 0; ++uintptr_t** FromCardCache::_cache = NULL; ++uint FromCardCache::_max_regions = 0; ++size_t FromCardCache::_static_mem_size = 0; + + void FromCardCache::initialize(uint n_par_rs, uint max_num_regions) { + guarantee(_cache == NULL, "Should not call this multiple times"); + + _max_regions = max_num_regions; +- _cache = Padded2DArray::create_unfreeable(n_par_rs, +- _max_regions, +- &_static_mem_size); +- ++ _cache = Padded2DArray::create_unfreeable(n_par_rs, ++ _max_regions, ++ &_static_mem_size); + invalidate(0, _max_regions); + } + +@@ -396,7 +392,8 @@ void FromCardCache::invalidate(uint start_idx, size_t new_num_regions) { + void FromCardCache::print(outputStream* out) { + for (uint i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) { + for (uint j = 0; j < _max_regions; j++) { +- out->print_cr("_from_card_cache[" UINT32_FORMAT "][" UINT32_FORMAT "] = " INT32_FORMAT ".", ++ out->print_cr("_from_card_cache[%u][%u] = " SIZE_FORMAT ".", ++ + i, j, at(i, j)); + } + } +@@ -433,7 +430,8 @@ void OtherRegionsTable::add_reference(OopOrNarrowOopStar from, int tid) { + : (void *)oopDesc::load_decode_heap_oop((oop*)from)); + } + +- int from_card = (int)(uintptr_t(from) >> CardTableModRefBS::card_shift); ++ uintptr_t from_card = uintptr_t(from) >> CardTableModRefBS::card_shift; ++ + + if (G1TraceHeapRegionRememberedSet) { + gclog_or_tty->print_cr("Table for [" PTR_FORMAT "...): card %d (cache = " INT32_FORMAT ")", +diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp +index 1646e8cb98..77751b4a98 100644 +--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp ++++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp +@@ -51,21 +51,19 @@ class FromCardCache : public AllStatic { + private: + // Array of card indices. Indexed by thread X and heap region to minimize + // thread contention. +- static int** _cache; ++ static uintptr_t** _cache; + static uint _max_regions; + static size_t _static_mem_size; + + public: +- enum { +- InvalidCard = -1 // Card value of an invalid card, i.e. a card index not otherwise used. +- }; ++ static const uintptr_t InvalidCard = UINTPTR_MAX; + + static void clear(uint region_idx); + + // Returns true if the given card is in the cache at the given location, or + // replaces the card at that location and returns false. +- static bool contains_or_replace(uint worker_id, uint region_idx, int card) { +- int card_in_cache = at(worker_id, region_idx); ++ static bool contains_or_replace(uint worker_id, uint region_idx, uintptr_t card) { ++ uintptr_t card_in_cache = at(worker_id, region_idx); + if (card_in_cache == card) { + return true; + } else { +@@ -74,11 +72,11 @@ class FromCardCache : public AllStatic { + } + } + +- static int at(uint worker_id, uint region_idx) { ++ static uintptr_t at(uint worker_id, uint region_idx) { + return _cache[worker_id][region_idx]; + } + +- static void set(uint worker_id, uint region_idx, int val) { ++ static void set(uint worker_id, uint region_idx, uintptr_t val) { + _cache[worker_id][region_idx] = val; + } + +@@ -177,6 +175,9 @@ public: + + HeapRegion* hr() const { return _hr; } + ++ // Returns the card index of the given within_region pointer relative to the bottom ————————————————————heapRegionRemSet.hpp:312 OtherRegionsTable ++ // of the given heap region. ++ static CardIdx_t card_within_region(OopOrNarrowOopStar within_region, HeapRegion* hr); + // For now. Could "expand" some tables in the future, so that this made + // sense. + void add_reference(OopOrNarrowOopStar from, int tid); +diff --git a/hotspot/test/gc/g1/TestFromCardCacheIndex.java b/hotspot/test/gc/g1/TestFromCardCacheIndex.java +new file mode 100644 +index 0000000000..f2332306da +--- /dev/null ++++ b/hotspot/test/gc/g1/TestFromCardCacheIndex.java +@@ -0,0 +1,119 @@ ++/* ++ * @test TestFromCardCacheIndex.java ++ * @bug 8196485 ++ * @summary Ensure that G1 does not miss a remembered set entry due to from card cache default value indices. ++ * @key gc ++ * @requires vm.gc.G1 ++ * @requires vm.debug ++ * @requires vm.bits != "32" ++ * @library /test/lib ++ * @modules java.base/jdk.internal.misc ++ * java.management ++ * @build sun.hotspot.WhiteBox ++ * @run driver ClassFileInstaller sun.hotspot.WhiteBox ++ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. -Xms20M -Xmx20M -XX:+UseCompressedOops -XX:G1HeapRegionSize=1M -XX:HeapBaseMinAddress=2199011721216 -XX:+UseG1GC -verbose:gc TestFromCardCacheIndex ++ */ ++ ++import sun.hotspot.WhiteBox; ++ ++/** ++ * Repeatedly tries to generate references from objects that contained a card with the same index ++ * of the from card cache default value. ++ */ ++public class TestFromCardCacheIndex { ++ private static WhiteBox WB; ++ ++ // Shift value to calculate card indices from addresses. ++ private static final int CardSizeShift = 9; ++ ++ /** ++ * Returns the last address on the heap within the object. ++ * ++ * @param The Object array to get the last address from. ++ */ ++ private static long getObjectLastAddress(Object[] o) { ++ return WB.getObjectAddress(o) + WB.getObjectSize(o) - 1; ++ } ++ ++ /** ++ * Returns the (truncated) 32 bit card index for the given address. ++ * ++ * @param The address to get the 32 bit card index from. ++ */ ++ private static int getCardIndex32bit(long address) { ++ return (int)(address >> CardSizeShift); ++ } ++ ++ // The source arrays that are placed on the heap in old gen. ++ private static int numArrays = 7000; ++ private static int arraySize = 508; ++ // Size of a humongous byte array, a bit less than a 1M region. This makes sure ++ // that we always create a cross-region reference when referencing it. ++ private static int byteArraySize = 1024*1023; ++ ++ public static void main(String[] args) { ++ WB = sun.hotspot.WhiteBox.getWhiteBox(); ++ for (int i = 0; i < 5; i++) { ++ runTest(); ++ WB.fullGC(); ++ } ++ } ++ ++ public static void runTest() { ++ System.out.println("Starting test"); ++ ++ // Spray the heap with random object arrays in the hope that we get one ++ // at the proper place. ++ Object[][] arrays = new Object[numArrays][]; ++ for (int i = 0; i < numArrays; i++) { ++ arrays[i] = new Object[arraySize]; ++ } ++ ++ // Make sure that everything is in old gen. ++ WB.fullGC(); ++ ++ // Find if we got an allocation at the right spot. ++ Object[] arrayWithCardMinus1 = findArray(arrays); ++ ++ if (arrayWithCardMinus1 == null) { ++ System.out.println("Array with card -1 not found. Trying again."); ++ return; ++ } else { ++ System.out.println("Array with card -1 found."); ++ } ++ ++ System.out.println("Modifying the last card in the array with a new object in a different region..."); ++ // Create a target object that is guaranteed to be in a different region. ++ byte[] target = new byte[byteArraySize]; ++ ++ // Modify the last entry of the object we found. ++ arrayWithCardMinus1[arraySize - 1] = target; ++ ++ target = null; ++ // Make sure that the dirty cards are flushed by doing a GC. ++ System.out.println("Doing a GC."); ++ WB.youngGC(); ++ ++ System.out.println("The crash didn't reproduce. Trying again."); ++ } ++ ++ /** ++ * Finds an returns an array that contains a (32 bit truncated) card with value -1. ++ */ ++ private static Object[] findArray(Object[][] arrays) { ++ for (int i = 0; i < arrays.length; i++) { ++ Object[] target = arrays[i]; ++ if (target == null) { ++ continue; ++ } ++ final long startAddress = WB.getObjectAddress(target); ++ final long lastAddress = getObjectLastAddress(target); ++ final int card = getCardIndex32bit(lastAddress); ++ if (card == -1) { ++ Object[] foundArray = target; ++ return foundArray; ++ } ++ } ++ return null; ++ } ++} +-- +2.19.0 + diff --git a/README.en.md b/README.en.md deleted file mode 100644 index 578e4cbe785cf5f1f44f6c3382a7db01e733b6b4..0000000000000000000000000000000000000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# openjdk-1.8.0 - -#### Description -openEuler Community builds of OpenJDK - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md index 4ba31fd29d000fd7de432095f5d3b7b0c4183ee2..8dd3c9b789ab2c279cc3ff3a33ab736bf2d23f26 100644 --- a/README.md +++ b/README.md @@ -1,37 +1 @@ -# openjdk-1.8.0 - -#### 介绍 -openEuler Community builds of OpenJDK - -#### 软件架构 -软件架构说明 - - -#### 安装教程 - -1. xxxx -2. xxxx -3. xxxx - -#### 使用说明 - -1. xxxx -2. xxxx -3. xxxx - -#### 参与贡献 - -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request - - -#### 码云特技 - -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目 -5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) +openEuler builds of OpenJDK 8(LTS) diff --git a/Reduce-the-probability-of-the-crash-related-to-ciObj.patch b/Reduce-the-probability-of-the-crash-related-to-ciObj.patch new file mode 100644 index 0000000000000000000000000000000000000000..1cf7d5760c63a7569e1187e637e5ce95b28607af --- /dev/null +++ b/Reduce-the-probability-of-the-crash-related-to-ciObj.patch @@ -0,0 +1,65 @@ +From 29e183488a96a4c169f89eab9410e0a91a903476 Mon Sep 17 00:00:00 2001 +From: songyaofei +Date: Tue, 22 Oct 2019 19:18:39 +0000 +Subject: [PATCH] Reduce the probability of the crash related to + ciObjectFactory::create_new_metadata + +Summary: : add load acquire barriers when profiling klass +LLT: +Patch Type: huawei +Bug url: +--- + hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp | 10 ++++++++++ + hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp | 1 + + hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp | 2 +- + 3 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp +index d8926cd87d..58fc267f99 100644 +--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp ++++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp +@@ -3234,6 +3234,16 @@ void MacroAssembler::load_klass(Register dst, Register src) { + } + } + ++void MacroAssembler::load_klass_acquire(Register dst, Register src) { ++ lea(dst, Address(src, oopDesc::klass_offset_in_bytes())); ++ if (UseCompressedClassPointers) { ++ ldarw(dst, dst); ++ decode_klass_not_null(dst); ++ } else { ++ ldar(dst, dst); ++ } ++} ++ + void MacroAssembler::cmp_klass(Register oop, Register trial_klass, Register tmp) { + if (UseCompressedClassPointers) { + ldrw(tmp, Address(oop, oopDesc::klass_offset_in_bytes())); +diff --git a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp +index 2cf827dcf0..168fe4d3b1 100644 +--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp ++++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp +@@ -790,6 +790,7 @@ public: + + // oop manipulations + void load_klass(Register dst, Register src); ++ void load_klass_acquire(Register dst, Register src); + void store_klass(Register dst, Register src); + void cmp_klass(Register oop, Register trial_klass, Register tmp); + +diff --git a/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp +index 1e590780b7..7ee4e317d4 100644 +--- a/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp ++++ b/hotspot/src/cpu/aarch64/vm/templateTable_aarch64.cpp +@@ -3243,7 +3243,7 @@ void TemplateTable::invokevirtual_helper(Register index, + + // get receiver klass + __ null_check(recv, oopDesc::klass_offset_in_bytes()); +- __ load_klass(r0, recv); ++ __ load_klass_acquire(r0, recv); + + // profile this call + __ profile_virtual_call(r0, rlocals, r3); +-- +2.12.3 + diff --git a/TestCryptoLevel.java b/TestCryptoLevel.java new file mode 100644 index 0000000000000000000000000000000000000000..b32b7aef7da5d2347ec3b7379434b6570d803b26 --- /dev/null +++ b/TestCryptoLevel.java @@ -0,0 +1,72 @@ +/* TestCryptoLevel -- Ensure unlimited crypto policy is in use. + Copyright (C) 2012 Red Hat, Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; + +import java.security.Permission; +import java.security.PermissionCollection; + +public class TestCryptoLevel +{ + public static void main(String[] args) + throws NoSuchFieldException, ClassNotFoundException, + IllegalAccessException, InvocationTargetException + { + Class cls = null; + Method def = null, exempt = null; + + try + { + cls = Class.forName("javax.crypto.JceSecurity"); + } + catch (ClassNotFoundException ex) + { + System.err.println("Running a non-Sun JDK."); + System.exit(0); + } + try + { + def = cls.getDeclaredMethod("getDefaultPolicy"); + exempt = cls.getDeclaredMethod("getExemptPolicy"); + } + catch (NoSuchMethodException ex) + { + System.err.println("Running IcedTea with the original crypto patch."); + System.exit(0); + } + def.setAccessible(true); + exempt.setAccessible(true); + PermissionCollection defPerms = (PermissionCollection) def.invoke(null); + PermissionCollection exemptPerms = (PermissionCollection) exempt.invoke(null); + Class apCls = Class.forName("javax.crypto.CryptoAllPermission"); + Field apField = apCls.getDeclaredField("INSTANCE"); + apField.setAccessible(true); + Permission allPerms = (Permission) apField.get(null); + if (defPerms.implies(allPerms) && (exemptPerms == null || exemptPerms.implies(allPerms))) + { + System.err.println("Running with the unlimited policy."); + System.exit(0); + } + else + { + System.err.println("WARNING: Running with a restricted crypto policy."); + System.exit(-1); + } + } +} diff --git a/TestECDSA.java b/TestECDSA.java new file mode 100644 index 0000000000000000000000000000000000000000..6eb9cb211ff59b7ff60167a2a2171e6a8b0e760d --- /dev/null +++ b/TestECDSA.java @@ -0,0 +1,49 @@ +/* TestECDSA -- Ensure ECDSA signatures are working. + Copyright (C) 2016 Red Hat, Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ + +import java.math.BigInteger; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.Signature; + +/** + * @test + */ +public class TestECDSA { + + public static void main(String[] args) throws Exception { + KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC"); + KeyPair key = keyGen.generateKeyPair(); + + byte[] data = "This is a string to sign".getBytes("UTF-8"); + + Signature dsa = Signature.getInstance("NONEwithECDSA"); + dsa.initSign(key.getPrivate()); + dsa.update(data); + byte[] sig = dsa.sign(); + System.out.println("Signature: " + new BigInteger(1, sig).toString(16)); + + Signature dsaCheck = Signature.getInstance("NONEwithECDSA"); + dsaCheck.initVerify(key.getPublic()); + dsaCheck.update(data); + boolean success = dsaCheck.verify(sig); + if (!success) { + throw new RuntimeException("Test failed. Signature verification error"); + } + System.out.println("Test passed."); + } +} diff --git a/X500Name-implemation-change-to-avoid-OOM.patch b/X500Name-implemation-change-to-avoid-OOM.patch new file mode 100644 index 0000000000000000000000000000000000000000..5150edab7b97cbb1b7dbee9906b1c3f5b7c626d1 --- /dev/null +++ b/X500Name-implemation-change-to-avoid-OOM.patch @@ -0,0 +1,28 @@ +From 6b96a97e8e04d62f4ab4b03c05682765516c0872 Mon Sep 17 00:00:00 2001 +From: zhanggaofeng +Date: Mon, 23 Sep 2019 10:43:46 +0000 +Subject: [PATCH] X500Name implemation change to avoid OOM + +Summary: X500Name implemation change. +LLT: +bug link: +--- + jdk/src/share/classes/sun/security/x509/X500Name.java | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/jdk/src/share/classes/sun/security/x509/X500Name.java b/jdk/src/share/classes/sun/security/x509/X500Name.java +index 447395c503..2062dc9747 100644 +--- a/jdk/src/share/classes/sun/security/x509/X500Name.java ++++ b/jdk/src/share/classes/sun/security/x509/X500Name.java +@@ -1108,7 +1108,7 @@ public class X500Name implements GeneralNameInterface, Principal { + * and speed recognition of common X.500 attributes. + */ + static ObjectIdentifier intern(ObjectIdentifier oid) { +- ObjectIdentifier interned = internedOIDs.putIfAbsent(oid, oid); ++ ObjectIdentifier interned = internedOIDs.getOrDefault(oid, oid); + return (interned == null) ? oid : interned; + } + +-- +2.12.3 + diff --git a/aarch64-shenandoah-jdk8u232-b09.tar.xz b/aarch64-shenandoah-jdk8u232-b09.tar.xz new file mode 100644 index 0000000000000000000000000000000000000000..e8c58269ac974480f7c5e7f0afe0bd498ac2db50 Binary files /dev/null and b/aarch64-shenandoah-jdk8u232-b09.tar.xz differ diff --git a/add-debuginfo-for-libsaproc-on-aarch64.patch b/add-debuginfo-for-libsaproc-on-aarch64.patch new file mode 100644 index 0000000000000000000000000000000000000000..5718963359b5d02e3a8a4048bb14775883f8af9f --- /dev/null +++ b/add-debuginfo-for-libsaproc-on-aarch64.patch @@ -0,0 +1,28 @@ +From b26a2445044d5ba0a3ed0d45ef66108231fcec0f Mon Sep 17 00:00:00 2001 +From: songyaofei +Date: Fri, 19 Apr 2019 17:41:12 +0000 +Subject: [PATCH] add debuginfo for libsaproc on aarch64 + +--- + hotspot/make/linux/makefiles/defs.make | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/hotspot/make/linux/makefiles/defs.make b/hotspot/make/linux/makefiles/defs.make +index 9aebd998d2..bb382bbd76 100644 +--- a/hotspot/make/linux/makefiles/defs.make ++++ b/hotspot/make/linux/makefiles/defs.make +@@ -316,9 +316,11 @@ ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) + ifeq ($(ZIP_DEBUGINFO_FILES),1) + ADD_SA_BINARIES/x86 += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.diz + ADD_SA_BINARIES/sparc += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.diz ++ ADD_SA_BINARIES/aarch64 += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.diz + else + ADD_SA_BINARIES/x86 += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.debuginfo + ADD_SA_BINARIES/sparc += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.debuginfo ++ ADD_SA_BINARIES/aarch64 += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.debuginfo + endif + endif + endif +-- +2.19.0 + diff --git a/add-with-company-name-option.patch b/add-with-company-name-option.patch new file mode 100644 index 0000000000000000000000000000000000000000..8f216ff804d534ded211279bffd10bb5811412e6 --- /dev/null +++ b/add-with-company-name-option.patch @@ -0,0 +1,148 @@ +From 2f9cb1a32393b6bb2607133836d16c1da73ec497 Mon Sep 17 00:00:00 2001 +From: = +Date: Tue, 3 Sep 2019 09:52:13 +0000 +Subject: [PATCH] Add with-company-name option + +Summary: : +LLT: +Bug url: AdoptOpenJDK +--- + common/autoconf/generated-configure.sh | 22 ++++++++++++++-------- + common/autoconf/jdk-options.m4 | 12 ++++++++++++ + jdk/make/gensrc/GensrcMisc.gmk | 6 ++++++ + .../share/classes/sun/misc/Version.java.template | 9 ++++++--- + 4 files changed, 38 insertions(+), 11 deletions(-) + +diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh +index 19efd8be38..32dc7779d5 100644 +--- a/common/autoconf/generated-configure.sh ++++ b/common/autoconf/generated-configure.sh +@@ -1062,6 +1062,7 @@ with_milestone + with_update_version + with_user_release_suffix + with_build_number ++with_company_name + with_vendor_name + with_vendor_url + with_vendor_bug_url +@@ -1910,6 +1911,7 @@ Optional Packages: + Add a custom string to the version string if build + number isn't set.[username_builddateb00] + --with-build-number Set build number value for build [b00] ++ --with-company-name Set company name. + --with-vendor-name Set vendor name. Among others, used to set the + 'java.vendor' and 'java.vm.vendor' system + properties. [not specified] +@@ -19886,16 +19888,20 @@ fi + # Now set the JDK version, milestone, build number etc. + + ++ # The company name, if any + ++# Check whether --with-company-name was given. ++if test "${with_company_name+set}" = set; then : ++ withval=$with_company_name; ++fi + +- +- +- +- +- +- +- +- ++ if test "x$with_company_name" = xyes; then ++ as_fn_error $? "--with-company-name must have a value" "$LINENO" 5 ++ elif ! [[ $with_company_name =~ ^[[:print:]]*$ ]] ; then ++ as_fn_error $? "--with-company-name contains non-printing characters: $with_company_name" "$LINENO" 5 ++ elif test "x$with_company_name" != x; then ++ COMPANY_NAME="$with_company_name" ++ fi + + + # The vendor name, if any +diff --git a/common/autoconf/jdk-options.m4 b/common/autoconf/jdk-options.m4 +index 9d75dc7bd4..e7657a14fe 100644 +--- a/common/autoconf/jdk-options.m4 ++++ b/common/autoconf/jdk-options.m4 +@@ -509,6 +509,18 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_JDK_VERSION_NUMBERS], + AC_SUBST(MACOSX_BUNDLE_NAME_BASE) + AC_SUBST(MACOSX_BUNDLE_ID_BASE) + ++ # The company name, if any ++ AC_ARG_WITH(company-name, [AS_HELP_STRING([--with-company-name], ++ [Set company name.])]) ++ if test "x$with_company_name" = xyes; then ++ AC_MSG_ERROR([--with-company-name must have a value]) ++ elif [ ! [[ $with_company_name =~ ^[[:print:]]*$ ]] ]; then ++ AC_MSG_ERROR([--with-company-name contains non-printing characters: $with_company_name]) ++ elif test "x$with_company_name" != x; then ++ COMPANY_NAME="$with_company_name" ++ fi ++ AC_SUBST(COMPANY_NAME) ++ + # The vendor name, if any + AC_ARG_WITH(vendor-name, [AS_HELP_STRING([--with-vendor-name], + [Set vendor name. Among others, used to set the 'java.vendor' +diff --git a/jdk/make/gensrc/GensrcMisc.gmk b/jdk/make/gensrc/GensrcMisc.gmk +index df886e88f4..c0c7b7bdb3 100644 +--- a/jdk/make/gensrc/GensrcMisc.gmk ++++ b/jdk/make/gensrc/GensrcMisc.gmk +@@ -30,6 +30,11 @@ include ProfileNames.gmk + # string and the runtime name into the Version.java file. + # To be printed by java -version + ++company_name = ++ifneq ($(COMPANY_NAME),N/A) ++ company_name=($(COMPANY_NAME)) ++endif ++ + $(JDK_OUTPUTDIR)/gensrc/sun/misc/Version.java \ + $(PROFILE_VERSION_JAVA_TARGETS): \ + $(JDK_TOPDIR)/src/share/classes/sun/misc/Version.java.template +@@ -41,6 +46,7 @@ $(PROFILE_VERSION_JAVA_TARGETS): \ + -e 's/@@java_runtime_version@@/$(FULL_VERSION)/g' \ + -e 's/@@java_runtime_name@@/$(RUNTIME_NAME)/g' \ + -e 's/@@java_profile_name@@/$(call profile_version_name, $@)/g' \ ++ -e 's/@@company_name@@/$(company_name)/g' \ + $< > $@.tmp + $(MV) $@.tmp $@ + +diff --git a/jdk/src/share/classes/sun/misc/Version.java.template b/jdk/src/share/classes/sun/misc/Version.java.template +index 32e2586e79..022c142810 100644 +--- a/jdk/src/share/classes/sun/misc/Version.java.template ++++ b/jdk/src/share/classes/sun/misc/Version.java.template +@@ -44,6 +44,9 @@ public class Version { + private static final String java_runtime_version = + "@@java_runtime_version@@"; + ++ private static final String company_name = ++ "@@company_name@@"; ++ + static { + init(); + } +@@ -103,7 +106,7 @@ public class Version { + + /* Second line: runtime version (ie, libraries). */ + +- ps.print(java_runtime_name + " (build " + java_runtime_version); ++ ps.print(java_runtime_name + " " + company_name + "(build " + java_runtime_version); + + if (java_profile_name.length() > 0) { + // profile name +@@ -120,8 +123,8 @@ public class Version { + String java_vm_name = System.getProperty("java.vm.name"); + String java_vm_version = System.getProperty("java.vm.version"); + String java_vm_info = System.getProperty("java.vm.info"); +- ps.println(java_vm_name + " (build " + java_vm_version + ", " + +- java_vm_info + ")"); ++ ps.println(java_vm_name + " " + company_name + "(build " + java_vm_version + ", " + ++ java_vm_info + ")"); + } + + +-- +2.12.3 + diff --git a/delete-read-write-barriers-in-ShenandoahGC.patch b/delete-read-write-barriers-in-ShenandoahGC.patch new file mode 100644 index 0000000000000000000000000000000000000000..f239574e12e8f16a1dd500a9d5fec900003e42ca --- /dev/null +++ b/delete-read-write-barriers-in-ShenandoahGC.patch @@ -0,0 +1,608 @@ +From 455904c69b9f3e7590559d7f3367bc4518fea74d Mon Sep 17 00:00:00 2001 +From: guoge +Date: Fri, 19 Apr 2019 22:40:50 +0000 +Subject: [PATCH] delete read/write barriers in ShenandoahGC + +--- + hotspot/src/share/vm/oops/oop.hpp | 16 +- + hotspot/src/share/vm/oops/oop.inline.hpp | 399 +++++++++++++++++------ + hotspot/src/share/vm/runtime/globals.hpp | 7 +- + 3 files changed, 311 insertions(+), 111 deletions(-) + +diff --git a/hotspot/src/share/vm/oops/oop.hpp b/hotspot/src/share/vm/oops/oop.hpp +index 7e31327a2b..a9461b45ba 100644 +--- a/hotspot/src/share/vm/oops/oop.hpp ++++ b/hotspot/src/share/vm/oops/oop.hpp +@@ -70,14 +70,22 @@ class oopDesc { + + public: + markOop mark() const { +- oop p = bs()->read_barrier((oop) this); +- return p->_mark; ++ if (UseShenandoahGC) { ++ oop p = bs()->read_barrier((oop) this); ++ return p->_mark; ++ } else { ++ return _mark; ++ } + } + markOop* mark_addr() const { return (markOop*) &_mark; } + + void set_mark(volatile markOop m) { +- oop p = bs()->write_barrier(this); +- p->_mark = m; ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ p->_mark = m; ++ } else { ++ _mark = m; ++ } + } + + void set_mark_raw(volatile markOop m) { +diff --git a/hotspot/src/share/vm/oops/oop.inline.hpp b/hotspot/src/share/vm/oops/oop.inline.hpp +index 93a803e830..e0ebd1edcf 100644 +--- a/hotspot/src/share/vm/oops/oop.inline.hpp ++++ b/hotspot/src/share/vm/oops/oop.inline.hpp +@@ -65,13 +65,21 @@ + // We need a separate file to avoid circular references + + inline void oopDesc::release_set_mark(markOop m) { +- oop p = bs()->write_barrier(this); +- OrderAccess::release_store_ptr(&p->_mark, m); ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ OrderAccess::release_store_ptr(&p->_mark, m); ++ } else { ++ OrderAccess::release_store_ptr(&_mark, m); ++ } + } + + inline markOop oopDesc::cas_set_mark(markOop new_mark, markOop old_mark) { +- oop p = bs()->write_barrier(this); +- return (markOop) Atomic::cmpxchg_ptr(new_mark, &p->_mark, old_mark); ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ return (markOop) Atomic::cmpxchg_ptr(new_mark, &p->_mark, old_mark); ++ } else { ++ return (markOop) Atomic::cmpxchg_ptr(new_mark, &_mark, old_mark); ++ } + } + + inline Klass* oopDesc::klass() const { +@@ -307,10 +315,16 @@ inline oop oopDesc::atomic_exchange_oop(oop exchange_value, volatile HeapWord *d + // In order to put or get a field out of an instance, must first check + // if the field has been compressed and uncompress it. + inline oop oopDesc::obj_field(int offset) const { +- oop p = bs()->read_barrier((oop) this); +- return UseCompressedOops ? +- load_decode_heap_oop(p->obj_field_addr(offset)) : +- load_decode_heap_oop(p->obj_field_addr(offset)); ++ if (UseShenandoahGC) { ++ oop p = bs()->read_barrier((oop) this); ++ return UseCompressedOops ? ++ load_decode_heap_oop(p->obj_field_addr(offset)) : ++ load_decode_heap_oop(p->obj_field_addr(offset)); ++ } else { ++ return UseCompressedOops ? ++ load_decode_heap_oop(obj_field_addr(offset)) : ++ load_decode_heap_oop(obj_field_addr(offset)); ++ } + } + inline volatile oop oopDesc::obj_field_volatile(int offset) const { + volatile oop value = obj_field(offset); +@@ -318,28 +332,47 @@ inline volatile oop oopDesc::obj_field_volatile(int offset) const { + return value; + } + inline void oopDesc::obj_field_put(int offset, oop value) { +- oop p = bs()->write_barrier(this); +- value = bs()->read_barrier(value); +- UseCompressedOops ? oop_store(p->obj_field_addr(offset), value) : +- oop_store(p->obj_field_addr(offset), value); ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ value = bs()->read_barrier(value); ++ UseCompressedOops ? oop_store(p->obj_field_addr(offset), value) : ++ oop_store(p->obj_field_addr(offset), value); ++ } else { ++ UseCompressedOops ? oop_store(obj_field_addr(offset), value) : ++ oop_store(obj_field_addr(offset), value); ++ } + } + + inline Metadata* oopDesc::metadata_field(int offset) const { +- oop p = bs()->read_barrier((oop) this); +- return *p->metadata_field_addr(offset); ++ if (UseShenandoahGC) { ++ oop p = bs()->read_barrier((oop) this); ++ return *p->metadata_field_addr(offset); ++ } else { ++ return *metadata_field_addr(offset); ++ } + } + + inline void oopDesc::metadata_field_put(int offset, Metadata* value) { +- oop p = bs()->write_barrier(this); +- *p->metadata_field_addr(offset) = value; ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ *p->metadata_field_addr(offset) = value; ++ } else { ++ *metadata_field_addr(offset) = value; ++ } + } + + inline void oopDesc::obj_field_put_raw(int offset, oop value) { +- oop p = bs()->write_barrier(this); +- value = bs()->read_barrier(value); +- UseCompressedOops ? +- encode_store_heap_oop(p->obj_field_addr(offset), value) : +- encode_store_heap_oop(p->obj_field_addr(offset), value); ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ value = bs()->read_barrier(value); ++ UseCompressedOops ? ++ encode_store_heap_oop(p->obj_field_addr(offset), value) : ++ encode_store_heap_oop(p->obj_field_addr(offset), value); ++ } else { ++ UseCompressedOops ? ++ encode_store_heap_oop(obj_field_addr(offset), value) : ++ encode_store_heap_oop(obj_field_addr(offset), value); ++ } + } + inline void oopDesc::obj_field_put_volatile(int offset, oop value) { + OrderAccess::release(); +@@ -348,184 +381,342 @@ inline void oopDesc::obj_field_put_volatile(int offset, oop value) { + } + + inline jbyte oopDesc::byte_field(int offset) const { +- oop p = bs()->read_barrier((oop) this); +- return (jbyte) *p->byte_field_addr(offset); ++ if (UseShenandoahGC) { ++ oop p = bs()->read_barrier((oop) this); ++ return (jbyte) *p->byte_field_addr(offset); ++ } else { ++ return (jbyte) *byte_field_addr(offset); ++ } + } + inline void oopDesc::byte_field_put(int offset, jbyte contents) { +- oop p = bs()->write_barrier(this); +- *p->byte_field_addr(offset) = (jint) contents; ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ *p->byte_field_addr(offset) = (jint) contents; ++ } else { ++ *byte_field_addr(offset) = (jint) contents; ++ } + } + + inline jboolean oopDesc::bool_field(int offset) const { +- oop p = bs()->read_barrier((oop) this); +- return (jboolean) *p->bool_field_addr(offset); ++ if (UseShenandoahGC) { ++ oop p = bs()->read_barrier((oop) this); ++ return (jboolean) *p->bool_field_addr(offset); ++ } else { ++ return (jboolean) *bool_field_addr(offset); ++ } + } + inline void oopDesc::bool_field_put(int offset, jboolean contents) { +- oop p = bs()->write_barrier(this); +- *p->bool_field_addr(offset) = (( (jint) contents) & 1); ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ *p->bool_field_addr(offset) = (((jint) contents) & 1); ++ } else { ++ *bool_field_addr(offset) = (((jint) contents) & 1); ++ } + } + + inline jchar oopDesc::char_field(int offset) const { +- oop p = bs()->read_barrier((oop) this); +- return (jchar) *p->char_field_addr(offset); ++ if (UseShenandoahGC) { ++ oop p = bs()->read_barrier((oop) this); ++ return (jchar) *p->char_field_addr(offset); ++ } else { ++ return (jchar) *char_field_addr(offset); ++ } + } + inline void oopDesc::char_field_put(int offset, jchar contents) { +- oop p = bs()->write_barrier(this); +- *p->char_field_addr(offset) = (jint) contents; ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ *p->char_field_addr(offset) = (jint) contents; ++ } else { ++ *char_field_addr(offset) = (jint) contents; ++ } + } + + inline jint oopDesc::int_field(int offset) const { +- oop p = bs()->read_barrier((oop) this); +- return *p->int_field_addr(offset); ++ if (UseShenandoahGC) { ++ oop p = bs()->read_barrier((oop) this); ++ return *p->int_field_addr(offset); ++ } else { ++ return *int_field_addr(offset); ++ } + } + inline void oopDesc::int_field_put(int offset, jint contents) { +- oop p = bs()->write_barrier(this); +- *p->int_field_addr(offset) = contents; ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ *p->int_field_addr(offset) = contents; ++ } else { ++ *int_field_addr(offset) = contents; ++ } + } + inline void oopDesc::int_field_put_raw(int offset, jint contents) { + *int_field_addr(offset) = contents; + } + + inline jshort oopDesc::short_field(int offset) const { +- oop p = bs()->read_barrier((oop) this); +- return (jshort) *p->short_field_addr(offset); ++ if (UseShenandoahGC) { ++ oop p = bs()->read_barrier((oop) this); ++ return (jshort) *p->short_field_addr(offset); ++ } else { ++ return (jshort) *short_field_addr(offset); ++ } + } + inline void oopDesc::short_field_put(int offset, jshort contents) { +- oop p = bs()->write_barrier(this); +- *p->short_field_addr(offset) = (jint) contents; ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ *p->short_field_addr(offset) = (jint) contents; ++ } else { ++ *short_field_addr(offset) = (jint) contents; ++ } + } + + inline jlong oopDesc::long_field(int offset) const { +- oop p = bs()->read_barrier((oop) this); +- return *p->long_field_addr(offset); ++ if (UseShenandoahGC) { ++ oop p = bs()->read_barrier((oop) this); ++ return *p->long_field_addr(offset); ++ } else { ++ return *long_field_addr(offset); ++ } + } + inline void oopDesc::long_field_put(int offset, jlong contents) { +- oop p = bs()->write_barrier(this); +- *p->long_field_addr(offset) = contents; ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ *p->long_field_addr(offset) = contents; ++ } else { ++ *long_field_addr(offset) = contents; ++ } + } + + inline jfloat oopDesc::float_field(int offset) const { +- oop p = bs()->read_barrier((oop) this); +- return *p->float_field_addr(offset); ++ if (UseShenandoahGC) { ++ oop p = bs()->read_barrier((oop) this); ++ return *p->float_field_addr(offset); ++ } else { ++ return *float_field_addr(offset); ++ } + } + inline void oopDesc::float_field_put(int offset, jfloat contents) { +- oop p = bs()->write_barrier(this); +- *p->float_field_addr(offset) = contents; ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ *p->float_field_addr(offset) = contents; ++ } else { ++ *float_field_addr(offset) = contents; ++ } + } + + inline jdouble oopDesc::double_field(int offset) const { +- oop p = bs()->read_barrier((oop) this); +- return *p->double_field_addr(offset); ++ if (UseShenandoahGC) { ++ oop p = bs()->read_barrier((oop) this); ++ return *p->double_field_addr(offset); ++ } else { ++ return *double_field_addr(offset); ++ } + } + inline void oopDesc::double_field_put(int offset, jdouble contents) { +- oop p = bs()->write_barrier(this); +- *p->double_field_addr(offset) = contents; ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ *p->double_field_addr(offset) = contents; ++ } else { ++ *double_field_addr(offset) = contents; ++ } + } + + inline address oopDesc::address_field(int offset) const { +- oop p = bs()->read_barrier((oop) this); +- return *p->address_field_addr(offset); ++ if (UseShenandoahGC) { ++ oop p = bs()->read_barrier((oop) this); ++ return *p->address_field_addr(offset); ++ } else { ++ return *address_field_addr(offset); ++ } + } + inline void oopDesc::address_field_put(int offset, address contents) { +- oop p = bs()->write_barrier(this); +- *p->address_field_addr(offset) = contents; ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ *p->address_field_addr(offset) = contents; ++ } else { ++ *address_field_addr(offset) = contents; ++ } + } + + inline oop oopDesc::obj_field_acquire(int offset) const { +- oop p = bs()->read_barrier((oop) this); +- return UseCompressedOops ? +- decode_heap_oop((narrowOop) +- OrderAccess::load_acquire(p->obj_field_addr(offset))) +- : decode_heap_oop((oop) +- OrderAccess::load_ptr_acquire(p->obj_field_addr(offset))); ++ if (UseShenandoahGC) { ++ oop p = bs()->read_barrier((oop) this); ++ return UseCompressedOops ? ++ decode_heap_oop((narrowOop) ++ OrderAccess::load_acquire(p->obj_field_addr(offset))) ++ : decode_heap_oop((oop) ++ OrderAccess::load_ptr_acquire(p->obj_field_addr(offset))); ++ } else { ++ return UseCompressedOops ? ++ decode_heap_oop((narrowOop) ++ OrderAccess::load_acquire(obj_field_addr(offset))) ++ : decode_heap_oop((oop) ++ OrderAccess::load_ptr_acquire(obj_field_addr(offset))); ++ } + } + inline void oopDesc::release_obj_field_put(int offset, oop value) { +- oop p = bs()->write_barrier(this); +- value = bs()->read_barrier(value); +- UseCompressedOops ? +- oop_store((volatile narrowOop*)p->obj_field_addr(offset), value) : +- oop_store((volatile oop*) p->obj_field_addr(offset), value); ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ value = bs()->read_barrier(value); ++ UseCompressedOops ? ++ oop_store((volatile narrowOop*)p->obj_field_addr(offset), value) : ++ oop_store((volatile oop*) p->obj_field_addr(offset), value); ++ } else { ++ UseCompressedOops ? ++ oop_store((volatile narrowOop*)obj_field_addr(offset), value) : ++ oop_store((volatile oop*) obj_field_addr(offset), value); ++ } + } + + inline jbyte oopDesc::byte_field_acquire(int offset) const { +- oop p = bs()->read_barrier((oop) this); +- return OrderAccess::load_acquire(p->byte_field_addr(offset)); ++ if (UseShenandoahGC) { ++ oop p = bs()->read_barrier((oop) this); ++ return OrderAccess::load_acquire(p->byte_field_addr(offset)); ++ } else { ++ return OrderAccess::load_acquire(byte_field_addr(offset)); ++ } + } + inline void oopDesc::release_byte_field_put(int offset, jbyte contents) { +- oop p = bs()->write_barrier(this); +- OrderAccess::release_store(p->byte_field_addr(offset), contents); ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ OrderAccess::release_store(p->byte_field_addr(offset), contents); ++ } else { ++ OrderAccess::release_store(byte_field_addr(offset), contents); ++ } + } + + inline jboolean oopDesc::bool_field_acquire(int offset) const { +- oop p = bs()->read_barrier((oop) this); +- return OrderAccess::load_acquire(p->bool_field_addr(offset)); ++ if (UseShenandoahGC) { ++ oop p = bs()->read_barrier((oop) this); ++ return OrderAccess::load_acquire(p->bool_field_addr(offset)); ++ } else { ++ return OrderAccess::load_acquire(bool_field_addr(offset)); ++ } + } + inline void oopDesc::release_bool_field_put(int offset, jboolean contents) { +- oop p = bs()->write_barrier(this); +- OrderAccess::release_store(p->bool_field_addr(offset), (contents & 1)); ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ OrderAccess::release_store(p->bool_field_addr(offset), (contents & 1)); ++ } else { ++ OrderAccess::release_store(bool_field_addr(offset), (contents & 1)); ++ } + } + + inline jchar oopDesc::char_field_acquire(int offset) const { +- oop p = bs()->read_barrier((oop) this); +- return OrderAccess::load_acquire(p->char_field_addr(offset)); ++ if (UseShenandoahGC) { ++ oop p = bs()->read_barrier((oop) this); ++ return OrderAccess::load_acquire(p->char_field_addr(offset)); ++ } else { ++ return OrderAccess::load_acquire(char_field_addr(offset)); ++ } + } + inline void oopDesc::release_char_field_put(int offset, jchar contents) { +- oop p = bs()->write_barrier(this); +- OrderAccess::release_store(p->char_field_addr(offset), contents); ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ OrderAccess::release_store(p->char_field_addr(offset), contents); ++ } else { ++ OrderAccess::release_store(char_field_addr(offset), contents); ++ } + } + + inline jint oopDesc::int_field_acquire(int offset) const { +- oop p = bs()->read_barrier((oop) this); +- return OrderAccess::load_acquire(p->int_field_addr(offset)); ++ if (UseShenandoahGC) { ++ oop p = bs()->read_barrier((oop) this); ++ return OrderAccess::load_acquire(p->int_field_addr(offset)); ++ } else { ++ return OrderAccess::load_acquire(int_field_addr(offset)); ++ } + } + inline void oopDesc::release_int_field_put(int offset, jint contents) { +- oop p = bs()->write_barrier(this); +- OrderAccess::release_store(p->int_field_addr(offset), contents); ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ OrderAccess::release_store(p->int_field_addr(offset), contents); ++ } else { ++ OrderAccess::release_store(int_field_addr(offset), contents); ++ } + } + + inline jshort oopDesc::short_field_acquire(int offset) const { +- oop p = bs()->read_barrier((oop) this); +- return (jshort)OrderAccess::load_acquire(p->short_field_addr(offset)); ++ if (UseShenandoahGC) { ++ oop p = bs()->read_barrier((oop) this); ++ return (jshort)OrderAccess::load_acquire(p->short_field_addr(offset)); ++ } else { ++ return (jshort)OrderAccess::load_acquire(short_field_addr(offset)); ++ } + } + inline void oopDesc::release_short_field_put(int offset, jshort contents) { +- oop p = bs()->write_barrier(this); +- OrderAccess::release_store(p->short_field_addr(offset), contents); ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ OrderAccess::release_store(p->short_field_addr(offset), contents); ++ } else { ++ OrderAccess::release_store(short_field_addr(offset), contents); ++ } + } + + inline jlong oopDesc::long_field_acquire(int offset) const { +- oop p = bs()->read_barrier((oop) this); +- return OrderAccess::load_acquire(p->long_field_addr(offset)); ++ if (UseShenandoahGC) { ++ oop p = bs()->read_barrier((oop) this); ++ return OrderAccess::load_acquire(p->long_field_addr(offset)); ++ } else { ++ return OrderAccess::load_acquire(long_field_addr(offset)); ++ } + } + inline void oopDesc::release_long_field_put(int offset, jlong contents) { +- oop p = bs()->write_barrier(this); +- OrderAccess::release_store(p->long_field_addr(offset), contents); ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ OrderAccess::release_store(p->long_field_addr(offset), contents); ++ } else { ++ OrderAccess::release_store(long_field_addr(offset), contents); ++ } + } + + inline jfloat oopDesc::float_field_acquire(int offset) const { +- oop p = bs()->read_barrier((oop) this); +- return OrderAccess::load_acquire(p->float_field_addr(offset)); ++ if (UseShenandoahGC) { ++ oop p = bs()->read_barrier((oop) this); ++ return OrderAccess::load_acquire(p->float_field_addr(offset)); ++ } else { ++ return OrderAccess::load_acquire(float_field_addr(offset)); ++ } + } + inline void oopDesc::release_float_field_put(int offset, jfloat contents) { +- oop p = bs()->write_barrier(this); +- OrderAccess::release_store(p->float_field_addr(offset), contents); ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ OrderAccess::release_store(p->float_field_addr(offset), contents); ++ } else { ++ OrderAccess::release_store(float_field_addr(offset), contents); ++ } + } + + inline jdouble oopDesc::double_field_acquire(int offset) const { +- oop p = bs()->read_barrier((oop) this); +- return OrderAccess::load_acquire(p->double_field_addr(offset)); ++ if (UseShenandoahGC) { ++ oop p = bs()->read_barrier((oop) this); ++ return OrderAccess::load_acquire(p->double_field_addr(offset)); ++ } else { ++ return OrderAccess::load_acquire(double_field_addr(offset)); ++ } + } + inline void oopDesc::release_double_field_put(int offset, jdouble contents) { +- oop p = bs()->write_barrier(this); +- OrderAccess::release_store(p->double_field_addr(offset), contents); ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ OrderAccess::release_store(p->double_field_addr(offset), contents); ++ } else { ++ OrderAccess::release_store(double_field_addr(offset), contents); ++ } + } + + inline address oopDesc::address_field_acquire(int offset) const { +- oop p = bs()->read_barrier((oop) this); +- return (address) OrderAccess::load_ptr_acquire(p->address_field_addr(offset)); ++ if (UseShenandoahGC) { ++ oop p = bs()->read_barrier((oop) this); ++ return (address) OrderAccess::load_ptr_acquire(p->address_field_addr(offset)); ++ } else { ++ return (address) OrderAccess::load_ptr_acquire(address_field_addr(offset)); ++ } + } + inline void oopDesc::release_address_field_put(int offset, address contents) { +- oop p = bs()->write_barrier(this); +- OrderAccess::release_store_ptr(p->address_field_addr(offset), contents); ++ if (UseShenandoahGC) { ++ oop p = bs()->write_barrier(this); ++ OrderAccess::release_store_ptr(p->address_field_addr(offset), contents); ++ } else { ++ OrderAccess::release_store_ptr(address_field_addr(offset), contents); ++ } + } + + inline int oopDesc::size_given_klass(Klass* klass) { +diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp +index a45c522449..e7c1721c03 100644 +--- a/hotspot/src/share/vm/runtime/globals.hpp ++++ b/hotspot/src/share/vm/runtime/globals.hpp +@@ -216,6 +216,10 @@ define_pd_global(uint64_t,MaxRAM, 1ULL*G); + + #endif // no compilers + ++// Since Shenandoah GC will add read/write barrier, that wii affect the ++// performance of critical, it will disabled forcibly. ++#define UseShenandoahGC false ++ + // string type aliases used only in this file + typedef const char* ccstr; + typedef const char* ccstrlist; // represents string arguments which accumulate +@@ -1427,9 +1431,6 @@ class CommandLineFlags { + product(bool, UseParallelOldGC, false, \ + "Use the Parallel Old garbage collector") \ + \ +- product(bool, UseShenandoahGC, false, \ +- "Use the Shenandoah garbage collector") \ +- \ + product(uintx, HeapMaximumCompactionInterval, 20, \ + "How often should we maximally compact the heap (not allowing " \ + "any dead space)") \ +-- +2.19.0 + diff --git a/disable-UseLSE-on-ARMv8.1-by-default.patch b/disable-UseLSE-on-ARMv8.1-by-default.patch new file mode 100644 index 0000000000000000000000000000000000000000..42134f2063cd9998eb416f0bfc044beb52d813e6 --- /dev/null +++ b/disable-UseLSE-on-ARMv8.1-by-default.patch @@ -0,0 +1,48 @@ +From 1161177ce24da0348b5f6c6358667dc4a93f544b Mon Sep 17 00:00:00 2001 +From: guoge +Date: Thu, 17 Oct 2019 14:49:51 +0000 +Subject: [PATCH] disable UseLSE on ARMv8.1 by default + +Summary: : disable UseLSE by default and set UseLSE to +experimental +LLT: java -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal +Patch Type: huawei +Bug url: NA +--- + .../hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp | 2 +- + .../hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp | 3 ++- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp b/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp +index 8cdd5c498..e0749ff80 100644 +--- a/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp ++++ b/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp +@@ -87,7 +87,7 @@ define_pd_global(intx, InlineSmallCode, 1000); + "Use Neon for CRC32 computation") \ + product(bool, UseCRC32, false, \ + "Use CRC32 instructions for CRC32 computation") \ +- product(bool, UseLSE, false, \ ++ experimental(bool, UseLSE, false, \ + "Use LSE instructions") \ + product(bool, UseSIMDForMemoryOps, false, \ + "Use SIMD instructions in generated memory move code") \ +diff --git a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp +index 65bdaa83a..35d1062c8 100644 +--- a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp ++++ b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp +@@ -203,10 +203,11 @@ void VM_Version::get_processor_features() { + + if (auxv & HWCAP_ATOMICS) { + if (FLAG_IS_DEFAULT(UseLSE)) +- FLAG_SET_DEFAULT(UseLSE, true); ++ FLAG_SET_DEFAULT(UseLSE, false); + } else { + if (UseLSE) { + warning("UseLSE specified, but not supported on this CPU"); ++ FLAG_SET_DEFAULT(UseLSE, false); + } + } + +-- +2.19.0 + diff --git a/fix-vendor-info.patch b/fix-vendor-info.patch new file mode 100644 index 0000000000000000000000000000000000000000..bf93e7d63cec162af7278ca51c45d02b2ebf0fd0 --- /dev/null +++ b/fix-vendor-info.patch @@ -0,0 +1,52 @@ +From f2833457ae8419c099bf167693c602911413257c Mon Sep 17 00:00:00 2001 +From: sunjianye +Date: Sat, 25 May 2019 10:36:33 +0000 +Subject: [PATCH] modify vendor to Huawei Technologies Co., LTD + +--- + hotspot/src/share/vm/runtime/vm_version.cpp | 7 +------ + jdk/src/share/native/java/lang/System.c | 6 +++--- + 2 files changed, 4 insertions(+), 9 deletions(-) + +diff --git a/hotspot/src/share/vm/runtime/vm_version.cpp b/hotspot/src/share/vm/runtime/vm_version.cpp +index c7d34aac64..fa721facea 100644 +--- a/hotspot/src/share/vm/runtime/vm_version.cpp ++++ b/hotspot/src/share/vm/runtime/vm_version.cpp +@@ -142,12 +142,7 @@ const char* Abstract_VM_Version::vm_name() { + + + const char* Abstract_VM_Version::vm_vendor() { +-#ifdef VENDOR +- return VENDOR; +-#else +- return JDK_Version::is_gte_jdk17x_version() ? +- "Oracle Corporation" : "Sun Microsystems Inc."; +-#endif ++ return "openEuler"; + } + + +diff --git a/jdk/src/share/native/java/lang/System.c b/jdk/src/share/native/java/lang/System.c +index ff80b0abdd..758cfabb39 100644 +--- a/jdk/src/share/native/java/lang/System.c ++++ b/jdk/src/share/native/java/lang/System.c +@@ -110,13 +110,13 @@ Java_java_lang_System_identityHashCode(JNIEnv *env, jobject this, jobject x) + + /* Third party may overwrite these values. */ + #ifndef VENDOR +-#define VENDOR "Oracle Corporation" ++#define VENDOR "openEuler" + #endif + #ifndef VENDOR_URL +-#define VENDOR_URL "http://java.oracle.com/" ++#define VENDOR_URL "https://openeuler.org/" + #endif + #ifndef VENDOR_URL_BUG +-#define VENDOR_URL_BUG "http://bugreport.sun.com/bugreport/" ++#define VENDOR_URL_BUG "https://gitee.com/openeuler/" + #endif + + #define JAVA_MAX_SUPPORTED_VERSION 52 +-- +2.19.0 + diff --git a/java-1.8.0-openjdk.spec b/java-1.8.0-openjdk.spec new file mode 100644 index 0000000000000000000000000000000000000000..5449687f4a69be71b1b380dd7c4d5641be05076a --- /dev/null +++ b/java-1.8.0-openjdk.spec @@ -0,0 +1,1686 @@ +# RPM conditionals so as to be able to dynamically produce +# slowdebug/release builds. See: +# http://rpm.org/user_doc/conditional_builds.html +# +# Examples: +# +# Produce release *and* slowdebug builds on x86_64 (default): +# $ rpmbuild -ba java-1.8.0-openjdk.spec +# +# Produce only release builds (no slowdebug builds) on x86_64: +# $ rpmbuild -ba java-1.8.0-openjdk.spec --without slowdebug +# +# Only produce a release build on x86_64: +# $ fedpkg mockbuild --without slowdebug +# +# Only produce a debug build on x86_64: +# $ fedpkg local --without release +# +# Enable slowdebug builds by default on relevant arches. +%bcond_without slowdebug +# Enable release builds by default on relevant arches. +%bcond_without release + +# Do not check unpackaged files +%define _unpackaged_files_terminate_build 0 + +%define _find_debuginfo_opts -g +# note: parametrized macros are order-sensitive (unlike not-parametrized) even with normal macros +# also necessary when passing it as parameter to other macros. If not macro, then it is considered a switch +# see the difference between global and define: +# See https://github.com/rpm-software-management/rpm/issues/127 to comments at "pmatilai commented on Aug 18, 2017" +# (initiated in https://bugzilla.redhat.com/show_bug.cgi?id=1482192) +%global debug_suffix_unquoted -slowdebug +# quoted one for shell operations +%global debug_suffix "%{debug_suffix_unquoted}" +%global normal_suffix "" + +# if you want only debug build but providing java build only normal build but set normalbuild_parameter +%global debug_warning This package has full debug on. Install only in need and remove asap. +%global debug_on with full debug on +%global for_debug for packages with debug on + +%if %{with release} +%global include_normal_build 1 +%else +%global include_normal_build 0 +%endif + +%if %{include_normal_build} +%global build_loop1 %{normal_suffix} +%else +%global build_loop1 %{nil} +%endif + +%global aarch64 aarch64 arm64 armv8 +# we need to distinguish between big and little endian PPC64 +%global ppc64le ppc64le +%global ppc64be ppc64 ppc64p7 +%global multilib_arches %{power64} sparc64 x86_64 +%global jit_arches x86_64 sparcv9 sparc64 %{aarch64} %{power64} + +# By default, we build a debug build during main build on JIT architectures +%if %{with slowdebug} +%ifarch %{jit_arches} +%ifnarch %{arm} +%global include_debug_build 0 +%else +%global include_debug_build 0 +%endif +%else +%global include_debug_build 0 +%endif +%else +%global include_debug_build 0 +%endif + +# On x86_64 and AArch64, we use the Shenandoah HotSpot +%ifarch x86_64 %{aarch64} +%global use_shenandoah_hotspot 1 +%else +%global use_shenandoah_hotspot 0 +%endif + +%if %{include_debug_build} +%global build_loop2 %{debug_suffix} +%else +%global build_loop2 %{nil} +%endif + +# if you disable both builds, then the build fails +%global build_loop %{build_loop1} %{build_loop2} +# note: that order: normal_suffix debug_suffix, in case of both enabled +# is expected in one single case at the end of the build +%global rev_build_loop %{build_loop2} %{build_loop1} + +%ifarch %{jit_arches} +%global bootstrap_build 1 +%else +%global bootstrap_build 1 +%endif + +%if %{bootstrap_build} +%global targets bootcycle-images docs +%else +%global targets all +%endif + + +# Filter out flags from the optflags macro that cause problems with the OpenJDK build +# We filter out -Wall which will otherwise cause HotSpot to produce hundreds of thousands of warnings (100+mb logs) +# We filter out -O flags so that the optimization of HotSpot is not lowered from O3 to O2 +# We replace it with -Wformat (required by -Werror=format-security) and -Wno-cpp to avoid FORTIFY_SOURCE warnings +# We filter out -fexceptions as the HotSpot build explicitly does -fno-exceptions and it's otherwise the default for C++ +%global ourflags %(echo %optflags | sed -e 's|-Wall|-Wformat -Wno-cpp|' | sed -r -e 's|-O[0-9]*||') +%global ourcppflags %(echo %ourflags | sed -e 's|-fexceptions||') +%global ourldflags %{__global_ldflags} + +# With disabled nss is NSS deactivated, so NSS_LIBDIR can contain the wrong path +# the initialization must be here. Later the pkg-config have buggy behavior +# looks like openjdk RPM specific bug +# Always set this so the nss.cfg file is not broken +%global NSS_LIBDIR %(pkg-config --variable=libdir nss) +%global NSS_LIBS %(pkg-config --libs nss) +%global NSS_CFLAGS %(pkg-config --cflags nss-softokn) +# see https://bugzilla.redhat.com/show_bug.cgi?id=1332456 +%global NSSSOFTOKN_BUILDTIME_NUMBER %(pkg-config --modversion nss-softokn || : ) +%global NSS_BUILDTIME_NUMBER %(pkg-config --modversion nss || : ) +# this is workaround for processing of requires during srpm creation +%global NSSSOFTOKN_BUILDTIME_VERSION %(if [ "x%{NSSSOFTOKN_BUILDTIME_NUMBER}" == "x" ] ; then echo "" ;else echo ">= %{NSSSOFTOKN_BUILDTIME_NUMBER}" ;fi) +%global NSS_BUILDTIME_VERSION %(if [ "x%{NSS_BUILDTIME_NUMBER}" == "x" ] ; then echo "" ;else echo ">= %{NSS_BUILDTIME_NUMBER}" ;fi) + + +# Fix for https://bugzilla.redhat.com/show_bug.cgi?id=1111349. +# See also https://bugzilla.redhat.com/show_bug.cgi?id=1590796 +# as to why some libraries *cannot* be excluded. In particular, +# these are: +# libjsig.so, libjava.so, libjawt.so, libjvm.so and libverify.so +%global _privatelibs libatk-wrapper[.]so.*|libattach[.]so.*|libawt_headless[.]so.*|libawt[.]so.*|libawt_xawt[.]so.*|libdt_socket[.]so.*|libfontmanager[.]so.*|libhprof[.]so.*|libinstrument[.]so.*|libj2gss[.]so.*|libj2pcsc[.]so.*|libj2pkcs11[.]so.*|libjaas_unix[.]so.*|libjava_crw_demo[.]so.*|libjavajpeg[.]so.*|libjdwp[.]so.*|libjli[.]so.*|libjsdt[.]so.*|libjsoundalsa[.]so.*|libjsound[.]so.*|liblcms[.]so.*|libmanagement[.]so.*|libmlib_image[.]so.*|libnet[.]so.*|libnio[.]so.*|libnpt[.]so.*|libsaproc[.]so.*|libsctp[.]so.*|libsplashscreen[.]so.*|libsunec[.]so.*|libunpack[.]so.*|libzip[.]so.*|lib[.]so\\(SUNWprivate_.* + +%global __provides_exclude ^(%{_privatelibs})$ +%global __requires_exclude ^(%{_privatelibs})$ + +# In some cases, the arch used by the JDK does +# not match _arch. +# Also, in some cases, the machine name used by SystemTap +# does not match that given by _build_cpu +%ifarch x86_64 +%global archinstall amd64 +%endif +%ifarch %{arm} +%global archinstall arm +%endif +%ifarch %{aarch64} +%global archinstall aarch64 +%endif +%ifnarch %{jit_arches} +%global archinstall %{_arch} +%endif + +# New Version-String scheme-style defines +%global majorver 8 + +# Standard JPackage naming and versioning defines. +%global origin openjdk +%global origin_nice OpenJDK +%global top_level_dir_name %{shenandoah_revision} +# note, following three variables are sedded from update_sources if used correctly. Hardcode them rather there. +%global shenandoah_project aarch64-port +%global shenandoah_repo jdk8u-shenandoah +%global shenandoah_revision aarch64-shenandoah-jdk8u232-b09 +# Define old aarch64/jdk8u tree variables for compatibility +%global project %{shenandoah_project} +%global repo %{shenandoah_repo} +%global revision %{shenandoah_revision} + +# eg # jdk8u60-b27 -> jdk8u60 or # aarch64-jdk8u60-b27 -> aarch64-jdk8u60 (dont forget spec escape % by %%) +%global whole_update %(VERSION=%{revision}; echo ${VERSION%%-*}) +# eg jdk8u60 -> 60 or aarch64-jdk8u60 -> 60 +%global updatever %(VERSION=%{whole_update}; echo ${VERSION##*u}) +# eg jdk8u60-b27 -> b27 +%global buildver %(VERSION=%{revision}; echo ${VERSION##*-}) +# priority must be 7 digits in total. The expression is workarounding tip +%global priority %(TIP=1800%{updatever}; echo ${TIP/tip/999}) + +%global javaver 1.%{majorver}.0 + +# parametrized macros are order-sensitive +%global compatiblename %{name} +%global fullversion %{compatiblename}-%{version}-%{release} +# images stub +%global jdkimage j2sdk-image +# output dir stub +%define buildoutputdir() %{expand:aarch64-shenandoah-jdk8u232-b09/build/jdk8.build%{?1}} +# we can copy the javadoc to not arched dir, or make it not noarch +%define uniquejavadocdir() %{expand:%{fullversion}%{?1}} +# main id and dir of this jdk +%define uniquesuffix() %{expand:%{fullversion}.%{_arch}%{?1}} + +# Standard JPackage directories and symbolic links. +%define sdkdir() %{expand:%{uniquesuffix -- %{?1}}} +%define jrelnk() %{expand:jre-%{javaver}-%{origin}-%{version}-%{release}.%{_arch}%{?1}} + +%define jredir() %{expand:%{sdkdir -- %{?1}}/jre} +%define sdkbindir() %{expand:%{_jvmdir}/%{sdkdir -- %{?1}}/bin} +%define jrebindir() %{expand:%{_jvmdir}/%{jredir -- %{?1}}/bin} + +%global rpm_state_dir %{_localstatedir}/lib/rpm-state/ + + + +%define post_script() %{expand: +/bin/touch --no-create %{_datadir}/icons/hicolor &>/dev/null || : +exit 0 +} + +%define post_headless() %{expand: +PRIORITY=%{priority} +if [ "%{?1}" == %{debug_suffix} ]; then + let PRIORITY=PRIORITY-1 +fi + +ext=.gz +alternatives \\ + --install %{_bindir}/java java %{jrebindir -- %{?1}}/java $PRIORITY --family %{name}.%{_arch} \\ + --slave %{_jvmdir}/jre jre %{_jvmdir}/%{jredir -- %{?1}} \\ + --slave %{_bindir}/jjs jjs %{jrebindir -- %{?1}}/jjs \\ + --slave %{_bindir}/keytool keytool %{jrebindir -- %{?1}}/keytool \\ + --slave %{_bindir}/orbd orbd %{jrebindir -- %{?1}}/orbd \\ + --slave %{_bindir}/pack200 pack200 %{jrebindir -- %{?1}}/pack200 \\ + --slave %{_bindir}/rmid rmid %{jrebindir -- %{?1}}/rmid \\ + --slave %{_bindir}/rmiregistry rmiregistry %{jrebindir -- %{?1}}/rmiregistry \\ + --slave %{_bindir}/servertool servertool %{jrebindir -- %{?1}}/servertool \\ + --slave %{_bindir}/tnameserv tnameserv %{jrebindir -- %{?1}}/tnameserv \\ + --slave %{_bindir}/policytool policytool %{jrebindir -- %{?1}}/policytool \\ + --slave %{_bindir}/unpack200 unpack200 %{jrebindir -- %{?1}}/unpack200 \\ + --slave %{_mandir}/man1/java.1$ext java.1$ext \\ + %{_mandir}/man1/java-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/jjs.1$ext jjs.1$ext \\ + %{_mandir}/man1/jjs-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/keytool.1$ext keytool.1$ext \\ + %{_mandir}/man1/keytool-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/orbd.1$ext orbd.1$ext \\ + %{_mandir}/man1/orbd-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/pack200.1$ext pack200.1$ext \\ + %{_mandir}/man1/pack200-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/rmid.1$ext rmid.1$ext \\ + %{_mandir}/man1/rmid-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/rmiregistry.1$ext rmiregistry.1$ext \\ + %{_mandir}/man1/rmiregistry-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/servertool.1$ext servertool.1$ext \\ + %{_mandir}/man1/servertool-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/tnameserv.1$ext tnameserv.1$ext \\ + %{_mandir}/man1/tnameserv-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/policytool.1$ext policytool.1$ext \\ + %{_mandir}/man1/policytool-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/unpack200.1$ext unpack200.1$ext \\ + %{_mandir}/man1/unpack200-%{uniquesuffix -- %{?1}}.1$ext + +for X in %{origin} %{javaver} ; do + alternatives --install %{_jvmdir}/jre-"$X" jre_"$X" %{_jvmdir}/%{jredir -- %{?1}} $PRIORITY --family %{name}.%{_arch} +done + +update-alternatives --install %{_jvmdir}/jre-%{javaver}-%{origin} jre_%{javaver}_%{origin} %{_jvmdir}/%{jrelnk -- %{?1}} $PRIORITY --family %{name}.%{_arch} + +/bin/touch --no-create %{_datadir}/icons/hicolor &>/dev/null || : + +# see pretrans where this file is declared +# also see that pretrans is only for non-debug +if [ ! "%{?1}" == %{debug_suffix} ]; then + if [ -f %{_libexecdir}/copy_jdk_configs_fixFiles.sh ] ; then + sh %{_libexecdir}/copy_jdk_configs_fixFiles.sh %{rpm_state_dir}/%{name}.%{_arch} %{_jvmdir}/%{sdkdir -- %{?1}} + fi +fi + +exit 0 +} + +%define postun_script() %{expand: +exit 0 +} + +%define postun_headless() %{expand: + alternatives --remove java %{jrebindir -- %{?1}}/java + alternatives --remove jre_%{origin} %{_jvmdir}/%{jredir -- %{?1}} + alternatives --remove jre_%{javaver} %{_jvmdir}/%{jredir -- %{?1}} + alternatives --remove jre_%{javaver}_%{origin} %{_jvmdir}/%{jrelnk -- %{?1}} +} + +%define posttrans_script() %{expand: +} + +%define post_devel() %{expand: + +PRIORITY=%{priority} +if [ "%{?1}" == %{debug_suffix} ]; then + let PRIORITY=PRIORITY-1 +fi + +ext=.gz +alternatives \\ + --install %{_bindir}/javac javac %{sdkbindir -- %{?1}}/javac $PRIORITY --family %{name}.%{_arch} \\ + --slave %{_jvmdir}/java java_sdk %{_jvmdir}/%{sdkdir -- %{?1}} \\ + --slave %{_bindir}/appletviewer appletviewer %{sdkbindir -- %{?1}}/appletviewer \\ + --slave %{_bindir}/extcheck extcheck %{sdkbindir -- %{?1}}/extcheck \\ + --slave %{_bindir}/idlj idlj %{sdkbindir -- %{?1}}/idlj \\ + --slave %{_bindir}/jar jar %{sdkbindir -- %{?1}}/jar \\ + --slave %{_bindir}/jarsigner jarsigner %{sdkbindir -- %{?1}}/jarsigner \\ + --slave %{_bindir}/javadoc javadoc %{sdkbindir -- %{?1}}/javadoc \\ + --slave %{_bindir}/javah javah %{sdkbindir -- %{?1}}/javah \\ + --slave %{_bindir}/javap javap %{sdkbindir -- %{?1}}/javap \\ + --slave %{_bindir}/jcmd jcmd %{sdkbindir -- %{?1}}/jcmd \\ + --slave %{_bindir}/jconsole jconsole %{sdkbindir -- %{?1}}/jconsole \\ + --slave %{_bindir}/jdb jdb %{sdkbindir -- %{?1}}/jdb \\ + --slave %{_bindir}/jdeps jdeps %{sdkbindir -- %{?1}}/jdeps \\ + --slave %{_bindir}/jhat jhat %{sdkbindir -- %{?1}}/jhat \\ + --slave %{_bindir}/jinfo jinfo %{sdkbindir -- %{?1}}/jinfo \\ + --slave %{_bindir}/jmap jmap %{sdkbindir -- %{?1}}/jmap \\ + --slave %{_bindir}/jps jps %{sdkbindir -- %{?1}}/jps \\ + --slave %{_bindir}/jrunscript jrunscript %{sdkbindir -- %{?1}}/jrunscript \\ + --slave %{_bindir}/jsadebugd jsadebugd %{sdkbindir -- %{?1}}/jsadebugd \\ + --slave %{_bindir}/jstack jstack %{sdkbindir -- %{?1}}/jstack \\ + --slave %{_bindir}/jstat jstat %{sdkbindir -- %{?1}}/jstat \\ + --slave %{_bindir}/jstatd jstatd %{sdkbindir -- %{?1}}/jstatd \\ + --slave %{_bindir}/native2ascii native2ascii %{sdkbindir -- %{?1}}/native2ascii \\ + --slave %{_bindir}/rmic rmic %{sdkbindir -- %{?1}}/rmic \\ + --slave %{_bindir}/schemagen schemagen %{sdkbindir -- %{?1}}/schemagen \\ + --slave %{_bindir}/serialver serialver %{sdkbindir -- %{?1}}/serialver \\ + --slave %{_bindir}/wsgen wsgen %{sdkbindir -- %{?1}}/wsgen \\ + --slave %{_bindir}/wsimport wsimport %{sdkbindir -- %{?1}}/wsimport \\ + --slave %{_bindir}/xjc xjc %{sdkbindir -- %{?1}}/xjc \\ + --slave %{_mandir}/man1/appletviewer.1$ext appletviewer.1$ext \\ + %{_mandir}/man1/appletviewer-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/extcheck.1$ext extcheck.1$ext \\ + %{_mandir}/man1/extcheck-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/idlj.1$ext idlj.1$ext \\ + %{_mandir}/man1/idlj-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/jar.1$ext jar.1$ext \\ + %{_mandir}/man1/jar-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/jarsigner.1$ext jarsigner.1$ext \\ + %{_mandir}/man1/jarsigner-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/javac.1$ext javac.1$ext \\ + %{_mandir}/man1/javac-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/javadoc.1$ext javadoc.1$ext \\ + %{_mandir}/man1/javadoc-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/javah.1$ext javah.1$ext \\ + %{_mandir}/man1/javah-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/javap.1$ext javap.1$ext \\ + %{_mandir}/man1/javap-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/jcmd.1$ext jcmd.1$ext \\ + %{_mandir}/man1/jcmd-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/jconsole.1$ext jconsole.1$ext \\ + %{_mandir}/man1/jconsole-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/jdb.1$ext jdb.1$ext \\ + %{_mandir}/man1/jdb-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/jdeps.1$ext jdeps.1$ext \\ + %{_mandir}/man1/jdeps-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/jhat.1$ext jhat.1$ext \\ + %{_mandir}/man1/jhat-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/jinfo.1$ext jinfo.1$ext \\ + %{_mandir}/man1/jinfo-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/jmap.1$ext jmap.1$ext \\ + %{_mandir}/man1/jmap-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/jps.1$ext jps.1$ext \\ + %{_mandir}/man1/jps-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/jrunscript.1$ext jrunscript.1$ext \\ + %{_mandir}/man1/jrunscript-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/jsadebugd.1$ext jsadebugd.1$ext \\ + %{_mandir}/man1/jsadebugd-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/jstack.1$ext jstack.1$ext \\ + %{_mandir}/man1/jstack-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/jstat.1$ext jstat.1$ext \\ + %{_mandir}/man1/jstat-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/jstatd.1$ext jstatd.1$ext \\ + %{_mandir}/man1/jstatd-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/native2ascii.1$ext native2ascii.1$ext \\ + %{_mandir}/man1/native2ascii-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/rmic.1$ext rmic.1$ext \\ + %{_mandir}/man1/rmic-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/schemagen.1$ext schemagen.1$ext \\ + %{_mandir}/man1/schemagen-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/serialver.1$ext serialver.1$ext \\ + %{_mandir}/man1/serialver-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/wsgen.1$ext wsgen.1$ext \\ + %{_mandir}/man1/wsgen-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/wsimport.1$ext wsimport.1$ext \\ + %{_mandir}/man1/wsimport-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/xjc.1$ext xjc.1$ext \\ + %{_mandir}/man1/xjc-%{uniquesuffix -- %{?1}}.1$ext + +for X in %{origin} %{javaver} ; do + alternatives \\ + --install %{_jvmdir}/java-"$X" java_sdk_"$X" %{_jvmdir}/%{sdkdir -- %{?1}} $PRIORITY --family %{name}.%{_arch} +done + +update-alternatives --install %{_jvmdir}/java-%{javaver}-%{origin} java_sdk_%{javaver}_%{origin} %{_jvmdir}/%{sdkdir -- %{?1}} $PRIORITY --family %{name}.%{_arch} + +exit 0 +} + +%define postun_devel() %{expand: + alternatives --remove javac %{sdkbindir -- %{?1}}/javac + alternatives --remove java_sdk_%{origin} %{_jvmdir}/%{sdkdir -- %{?1}} + alternatives --remove java_sdk_%{javaver} %{_jvmdir}/%{sdkdir -- %{?1}} + alternatives --remove java_sdk_%{javaver}_%{origin} %{_jvmdir}/%{sdkdir -- %{?1}} + +exit 0 +} + +%define posttrans_devel() %{expand: +} + +%define post_javadoc() %{expand: + +PRIORITY=%{priority} +if [ "%{?1}" == %{debug_suffix} ]; then + let PRIORITY=PRIORITY-1 +fi + +alternatives \\ + --install %{_javadocdir}/java javadocdir %{_javadocdir}/%{uniquejavadocdir -- %{?1}}/api \\ + $PRIORITY --family %{name} +exit 0 +} + +%define postun_javadoc() %{expand: + alternatives --remove javadocdir %{_javadocdir}/%{uniquejavadocdir -- %{?1}}/api +exit 0 +} + +%define post_javadoc_zip() %{expand: + +PRIORITY=%{priority} +if [ "%{?1}" == %{debug_suffix} ]; then + let PRIORITY=PRIORITY-1 +fi + +alternatives \\ + --install %{_javadocdir}/java-zip javadoczip %{_javadocdir}/%{uniquejavadocdir -- %{?1}}.zip \\ + $PRIORITY --family %{name} +exit 0 +} + +%define postun_javadoc_zip() %{expand: + alternatives --remove javadoczip %{_javadocdir}/%{uniquejavadocdir -- %{?1}}.zip +exit 0 +} + +%define files_jre() %{expand: +%{_jvmdir}/%{sdkdir -- %{?1}}/jre/lib/%{archinstall}/libjsoundalsa.so +%{_jvmdir}/%{sdkdir -- %{?1}}/jre/lib/%{archinstall}/libsplashscreen.so +%{_jvmdir}/%{sdkdir -- %{?1}}/jre/lib/%{archinstall}/libawt_xawt.so +%{_jvmdir}/%{sdkdir -- %{?1}}/jre/lib/%{archinstall}/libjawt.so +%{_jvmdir}/%{sdkdir -- %{?1}}/jre/bin/policytool +} + + +%define files_jre_headless() %{expand: +%defattr(-,root,root,-) +%license %{buildoutputdir -- %{?1}}/images/%{jdkimage}/jre/ASSEMBLY_EXCEPTION +%license %{buildoutputdir -- %{?1}}/images/%{jdkimage}/jre/LICENSE +%license %{buildoutputdir -- %{?1}}/images/%{jdkimage}/jre/THIRD_PARTY_README +%dir %{_jvmdir}/%{sdkdir -- %{?1}} +%{_jvmdir}/%{jrelnk -- %{?1}} +%dir %{_jvmdir}/%{jredir -- %{?1}}/lib/security +%{_jvmdir}/%{jredir -- %{?1}}/lib/security/cacerts +%dir %{_jvmdir}/%{jredir -- %{?1}} +%dir %{_jvmdir}/%{jredir -- %{?1}}/bin +%dir %{_jvmdir}/%{jredir -- %{?1}}/lib +%{_jvmdir}/%{jredir -- %{?1}}/bin/java +%{_jvmdir}/%{jredir -- %{?1}}/bin/jjs +%{_jvmdir}/%{jredir -- %{?1}}/bin/keytool +%{_jvmdir}/%{jredir -- %{?1}}/bin/orbd +%{_jvmdir}/%{jredir -- %{?1}}/bin/pack200 +%{_jvmdir}/%{jredir -- %{?1}}/bin/rmid +%{_jvmdir}/%{jredir -- %{?1}}/bin/rmiregistry +%{_jvmdir}/%{jredir -- %{?1}}/bin/servertool +%{_jvmdir}/%{jredir -- %{?1}}/bin/tnameserv +%{_jvmdir}/%{jredir -- %{?1}}/bin/unpack200 +%dir %{_jvmdir}/%{jredir -- %{?1}}/lib/security/policy/unlimited/ +%dir %{_jvmdir}/%{jredir -- %{?1}}/lib/security/policy/limited/ +%dir %{_jvmdir}/%{jredir -- %{?1}}/lib/security/policy/ +%config(noreplace) %{_jvmdir}/%{jredir -- %{?1}}/lib/security/policy/unlimited/US_export_policy.jar +%config(noreplace) %{_jvmdir}/%{jredir -- %{?1}}/lib/security/policy/unlimited/local_policy.jar +%config(noreplace) %{_jvmdir}/%{jredir -- %{?1}}/lib/security/policy/limited/US_export_policy.jar +%config(noreplace) %{_jvmdir}/%{jredir -- %{?1}}/lib/security/policy/limited/local_policy.jar +%config(noreplace) %{_jvmdir}/%{jredir -- %{?1}}/lib/security/java.policy +%config(noreplace) %{_jvmdir}/%{jredir -- %{?1}}/lib/security/java.security +%config(noreplace) %{_jvmdir}/%{jredir -- %{?1}}/lib/security/blacklisted.certs +%config(noreplace) %{_jvmdir}/%{jredir -- %{?1}}/lib/logging.properties +%config(noreplace) %{_jvmdir}/%{jredir -- %{?1}}/lib/calendars.properties +%{_mandir}/man1/java-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/jjs-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/keytool-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/orbd-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/pack200-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/rmid-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/rmiregistry-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/servertool-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/tnameserv-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/unpack200-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/policytool-%{uniquesuffix -- %{?1}}.1* +%ifarch %{jit_arches} +%ifnarch %{power64} +%attr(444, root, root) %ghost %{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/server/classes.jsa +%attr(444, root, root) %ghost %{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/client/classes.jsa +%endif +%endif +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/server/ +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/client/ +%dir %{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall} +%dir %{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/jli +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/jli/libjli.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/jvm.cfg +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libattach.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libawt.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libawt_headless.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libdt_socket.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libfontmanager.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libhprof.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libinstrument.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libj2gss.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libj2pcsc.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libj2pkcs11.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libjaas_unix.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libjava.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libjava_crw_demo.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libjdwp.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libjsdt.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libjsig.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libjsound.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/liblcms.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libmanagement.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libmlib_image.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libnet.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libnio.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libnpt.so +%ifarch x86_64 %{aarch64} +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libsaproc.so +%endif +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libsctp.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libsunec.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libunpack.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libverify.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libzip.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/charsets.jar +%{_jvmdir}/%{jredir -- %{?1}}/lib/classlist +%{_jvmdir}/%{jredir -- %{?1}}/lib/content-types.properties +%{_jvmdir}/%{jredir -- %{?1}}/lib/currency.data +%{_jvmdir}/%{jredir -- %{?1}}/lib/flavormap.properties +%{_jvmdir}/%{jredir -- %{?1}}/lib/hijrah-config-umalqura.properties +%{_jvmdir}/%{jredir -- %{?1}}/lib/images/cursors/* +%{_jvmdir}/%{jredir -- %{?1}}/lib/jce.jar +%{_jvmdir}/%{jredir -- %{?1}}/lib/jexec +%{_jvmdir}/%{jredir -- %{?1}}/lib/jsse.jar +%{_jvmdir}/%{jredir -- %{?1}}/lib/jvm.hprof.txt +%{_jvmdir}/%{jredir -- %{?1}}/lib/meta-index +%{_jvmdir}/%{jredir -- %{?1}}/lib/net.properties +%{_jvmdir}/%{jredir -- %{?1}}/lib/psfont.properties.ja +%{_jvmdir}/%{jredir -- %{?1}}/lib/psfontj2d.properties +%{_jvmdir}/%{jredir -- %{?1}}/lib/resources.jar +%{_jvmdir}/%{jredir -- %{?1}}/lib/rt.jar +%{_jvmdir}/%{jredir -- %{?1}}/lib/sound.properties +%{_jvmdir}/%{jredir -- %{?1}}/lib/tzdb.dat +%{_jvmdir}/%{jredir -- %{?1}}/lib/management-agent.jar +%{_jvmdir}/%{jredir -- %{?1}}/lib/management/* +%{_jvmdir}/%{jredir -- %{?1}}/lib/cmm/* +%{_jvmdir}/%{jredir -- %{?1}}/lib/ext/cldrdata.jar +%{_jvmdir}/%{jredir -- %{?1}}/lib/ext/dnsns.jar +%{_jvmdir}/%{jredir -- %{?1}}/lib/ext/jaccess.jar +%{_jvmdir}/%{jredir -- %{?1}}/lib/ext/localedata.jar +%{_jvmdir}/%{jredir -- %{?1}}/lib/ext/meta-index +%{_jvmdir}/%{jredir -- %{?1}}/lib/ext/nashorn.jar +%{_jvmdir}/%{jredir -- %{?1}}/lib/ext/sunec.jar +%{_jvmdir}/%{jredir -- %{?1}}/lib/ext/sunjce_provider.jar +%{_jvmdir}/%{jredir -- %{?1}}/lib/ext/sunpkcs11.jar +%{_jvmdir}/%{jredir -- %{?1}}/lib/ext/zipfs.jar + +%dir %{_jvmdir}/%{jredir -- %{?1}}/lib/images +%dir %{_jvmdir}/%{jredir -- %{?1}}/lib/images/cursors +%dir %{_jvmdir}/%{jredir -- %{?1}}/lib/management +%dir %{_jvmdir}/%{jredir -- %{?1}}/lib/cmm +%dir %{_jvmdir}/%{jredir -- %{?1}}/lib/ext +} + +%define files_devel() %{expand: +%defattr(-,root,root,-) +%license %{buildoutputdir -- %{?1}}/images/%{jdkimage}/ASSEMBLY_EXCEPTION +%license %{buildoutputdir -- %{?1}}/images/%{jdkimage}/LICENSE +%license %{buildoutputdir -- %{?1}}/images/%{jdkimage}/THIRD_PARTY_README +%dir %{_jvmdir}/%{sdkdir -- %{?1}}/bin +%dir %{_jvmdir}/%{sdkdir -- %{?1}}/include +%dir %{_jvmdir}/%{sdkdir -- %{?1}}/lib +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/appletviewer +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/extcheck +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/idlj +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jar +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jarsigner +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/java +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/javac +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/javadoc +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/javah +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/javap +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/java-rmi.cgi +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jcmd +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jconsole +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jdb +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jdeps +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jhat +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jinfo +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jjs +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jmap +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jps +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jrunscript +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jsadebugd +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jstack +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jstat +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jstatd +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/keytool +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/native2ascii +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/orbd +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/pack200 +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/policytool +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/rmic +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/rmid +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/rmiregistry +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/schemagen +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/serialver +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/servertool +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/tnameserv +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/unpack200 +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/wsgen +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/wsimport +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/xjc +%{_jvmdir}/%{sdkdir -- %{?1}}/include/* +%{_jvmdir}/%{sdkdir -- %{?1}}/lib/%{archinstall} +%{_jvmdir}/%{sdkdir -- %{?1}}/lib/ct.sym +%{_jvmdir}/%{sdkdir -- %{?1}}/lib/ir.idl +%{_jvmdir}/%{sdkdir -- %{?1}}/lib/jconsole.jar +%{_jvmdir}/%{sdkdir -- %{?1}}/lib/orb.idl +%ifarch x86_64 +%{_jvmdir}/%{sdkdir -- %{?1}}/lib/sa-jdi.jar +%endif +%{_jvmdir}/%{sdkdir -- %{?1}}/lib/dt.jar +%{_jvmdir}/%{sdkdir -- %{?1}}/lib/jexec +%{_jvmdir}/%{sdkdir -- %{?1}}/lib/tools.jar +%{_mandir}/man1/appletviewer-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/extcheck-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/idlj-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/jar-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/jarsigner-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/javac-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/javadoc-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/javah-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/javap-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/jconsole-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/jcmd-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/jdb-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/jdeps-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/jhat-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/jinfo-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/jmap-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/jps-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/jrunscript-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/jsadebugd-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/jstack-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/jstat-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/jstatd-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/native2ascii-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/rmic-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/schemagen-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/serialver-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/wsgen-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/wsimport-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/xjc-%{uniquesuffix -- %{?1}}.1* +} + +%define files_demo() %{expand: +%defattr(-,root,root,-) +%license %{buildoutputdir -- %{?1}}/images/%{jdkimage}/jre/LICENSE +} + +%define files_src() %{expand: +%defattr(-,root,root,-) +%{_jvmdir}/%{sdkdir -- %{?1}}/src.zip +} + +%define files_javadoc() %{expand: +%defattr(-,root,root,-) +%doc %{_javadocdir}/%{uniquejavadocdir -- %{?1}} +%license %{buildoutputdir -- %{?1}}/images/%{jdkimage}/jre/LICENSE +} + +%define files_javadoc_zip() %{expand: +%defattr(-,root,root,-) +%doc %{_javadocdir}/%{uniquejavadocdir -- %{?1}}.zip +%license %{buildoutputdir -- %{?1}}/images/%{jdkimage}/jre/LICENSE +} + +%define files_accessibility() %{expand: +%{_jvmdir}/%{jredir -- %{?1}}/lib/%{archinstall}/libatk-wrapper.so +%{_jvmdir}/%{jredir -- %{?1}}/lib/ext/java-atk-wrapper.jar +%{_jvmdir}/%{jredir -- %{?1}}/lib/accessibility.properties +} + +# not-duplicated requires/provides/obsoletes for normal/debug packages +%define java_rpo() %{expand: +Requires: fontconfig%{?_isa} +Requires: xorg-x11-fonts-Type1 +# Require libXcomposite explicitly since it's only dynamically loaded +# at runtime. Fixes screenshot issues. See JDK-8150954. +Requires: libXcomposite%{?_isa} +# Requires rest of java +Requires: %{name}-headless%{?1}%{?_isa} = %{epoch}:%{version}-%{release} +OrderWithRequires: %{name}-headless%{?1}%{?_isa} = %{epoch}:%{version}-%{release} + +Provides: java-%{javaver}-%{origin} = %{epoch}:%{version}-%{release} + +# Standard JPackage base provides +Provides: jre = %{javaver}%{?1} +Provides: jre-%{origin}%{?1} = %{epoch}:%{version}-%{release} +Provides: jre-%{javaver}%{?1} = %{epoch}:%{version}-%{release} +Provides: jre-%{javaver}-%{origin}%{?1} = %{epoch}:%{version}-%{release} +Provides: java-%{javaver}%{?1} = %{epoch}:%{version}-%{release} +Provides: java-%{origin}%{?1} = %{epoch}:%{version}-%{release} +Provides: java%{?1} = %{epoch}:%{javaver} +} + +%define java_headless_rpo() %{expand: +# Require javapackages-filesystem for ownership of /usr/lib/jvm/ +Requires: javapackages-filesystem +# libsctp.so.1 is being `dlopen`ed on demand +Requires: lksctp-tools%{?_isa} +# there is a need to depend on the exact version of NSS +Requires: nss%{?_isa} %{NSS_BUILDTIME_VERSION} +Requires: nss-softokn%{?_isa} %{NSSSOFTOKN_BUILDTIME_VERSION} +# tool to copy jdk's configs - should be Recommends only, but then only dnf/yum enforce it, +# not rpm transaction and so no configs are persisted when pure rpm -u is run. It may be +# considered as regression +Requires: copy-jdk-configs >= 3.3 +OrderWithRequires: copy-jdk-configs +# Post requires alternatives to install tool alternatives +Requires(post): %{_sbindir}/alternatives +# in version 1.7 and higher for --family switch +Requires(post): chkconfig >= 1.7 +# Postun requires alternatives to uninstall tool alternatives +Requires(postun): %{_sbindir}/alternatives +# in version 1.7 and higher for --family switch +Requires(postun): chkconfig >= 1.7 +# for optional support of kernel stream control, card reader and printing bindings +Suggests: lksctp-tools%{?_isa}, pcsc-lite-devel%{?_isa}, cups + +# Standard JPackage base provides +Provides: jre-headless%{?1} = %{epoch}:%{javaver} +Provides: jre-%{javaver}-%{origin}-headless%{?1} = %{epoch}:%{version}-%{release} +Provides: jre-%{origin}-headless%{?1} = %{epoch}:%{version}-%{release} +Provides: jre-%{javaver}-headless%{?1} = %{epoch}:%{version}-%{release} +Provides: java-%{javaver}-%{origin}-headless%{?1} = %{epoch}:%{version}-%{release} +Provides: java-%{javaver}-headless%{?1} = %{epoch}:%{version}-%{release} +Provides: java-%{origin}-headless%{?1} = %{epoch}:%{version}-%{release} +Provides: java-headless%{?1} = %{epoch}:%{javaver} + +# https://bugzilla.redhat.com/show_bug.cgi?id=1312019 +Provides: /usr/bin/jjs + +} + +%define java_devel_rpo() %{expand: +# Requires base package +Requires: %{name}%{?1}%{?_isa} = %{epoch}:%{version}-%{release} +OrderWithRequires: %{name}-headless%{?1}%{?_isa} = %{epoch}:%{version}-%{release} +# Post requires alternatives to install tool alternatives +Requires(post): %{_sbindir}/alternatives +# in version 1.7 and higher for --family switch +Requires(post): chkconfig >= 1.7 +# Postun requires alternatives to uninstall tool alternatives +Requires(postun): %{_sbindir}/alternatives +# in version 1.7 and higher for --family switch +Requires(postun): chkconfig >= 1.7 + +# Standard JPackage devel provides +Provides: java-sdk-%{javaver}-%{origin}%{?1} = %{epoch}:%{version} +Provides: java-sdk-%{javaver}%{?1} = %{epoch}:%{version} +Provides: java-sdk-%{origin}%{?1} = %{epoch}:%{version} +Provides: java-sdk%{?1} = %{epoch}:%{javaver} +Provides: java-%{javaver}-devel%{?1} = %{epoch}:%{version} +Provides: java-%{javaver}-%{origin}-devel%{?1} = %{epoch}:%{version} +Provides: java-devel-%{origin}%{?1} = %{epoch}:%{version} +Provides: java-devel%{?1} = %{epoch}:%{javaver} +} + +%define java_demo_rpo() %{expand: +Requires: %{name}%{?1}%{?_isa} = %{epoch}:%{version}-%{release} +OrderWithRequires: %{name}-headless%{?1}%{?_isa} = %{epoch}:%{version}-%{release} + +Provides: java-demo%{?1} = %{epoch}:%{version}-%{release} +Provides: java-%{javaver}-demo%{?1} = %{epoch}:%{version}-%{release} +Provides: java-%{javaver}-%{origin}-demo%{?1} = %{epoch}:%{version}-%{release} +} + +%define java_javadoc_rpo() %{expand: +OrderWithRequires: %{name}-headless%{?1}%{?_isa} = %{epoch}:%{version}-%{release} +# Post requires alternatives to install javadoc alternative +Requires(post): %{_sbindir}/alternatives +# in version 1.7 and higher for --family switch +Requires(post): chkconfig >= 1.7 +# Postun requires alternatives to uninstall javadoc alternative +Requires(postun): %{_sbindir}/alternatives +# in version 1.7 and higher for --family switch +Requires(postun): chkconfig >= 1.7 + +# Standard JPackage javadoc provides +Provides: java-javadoc%{?1} = %{epoch}:%{version}-%{release} +Provides: java-%{javaver}-javadoc%{?1} = %{epoch}:%{version}-%{release} +Provides: java-%{javaver}-%{origin}-javadoc%{?1} = %{epoch}:%{version}-%{release} +} + +%define java_src_rpo() %{expand: +Requires: %{name}-headless%{?1}%{?_isa} = %{epoch}:%{version}-%{release} + +# Standard JPackage sources provides +Provides: java-src%{?1} = %{epoch}:%{version}-%{release} +Provides: java-%{javaver}-src%{?1} = %{epoch}:%{version}-%{release} +Provides: java-%{javaver}-%{origin}-src%{?1} = %{epoch}:%{version}-%{release} +} + +%define java_accessibility_rpo() %{expand: +Requires: java-atk-wrapper%{?_isa} +Requires: %{name}%{?1}%{?_isa} = %{epoch}:%{version}-%{release} +OrderWithRequires: %{name}-headless%{?1}%{?_isa} = %{epoch}:%{version}-%{release} + +Provides: java-accessibility = %{epoch}:%{version}-%{release} +Provides: java-%{javaver}-accessibility = %{epoch}:%{version}-%{release} +Provides: java-%{javaver}-%{origin}-accessibility = %{epoch}:%{version}-%{release} + +} + +# Prevent brp-java-repack-jars from being run +%global __jar_repack 0 + +Name: java-%{javaver}-%{origin} +Version: %{javaver}.%{updatever}.%{buildver} +Release: 1.h1 +Epoch: 1 +Summary: %{origin_nice} Runtime Environment %{majorver} +Group: Development/Languages + +# HotSpot code is licensed under GPLv2 +# JDK library code is licensed under GPLv2 with the Classpath exception +# The Apache license is used in code taken from Apache projects (primarily JAXP & JAXWS) +# DOM levels 2 & 3 and the XML digital signature schemas are licensed under the W3C Software License +# The JSR166 concurrency code is in the public domain +# The BSD and MIT licenses are used for a number of third-party libraries (see THIRD_PARTY_README) +# The OpenJDK source tree includes the JPEG library (IJG), zlib & libpng (zlib), giflib and LCMS (MIT) +# The test code includes copies of NSS under the Mozilla Public License v2.0 +# The PCSClite headers are under a BSD with advertising license +# The elliptic curve cryptography (ECC) source code is licensed under the LGPLv2.1 or any later version +License: ASL 1.1 and ASL 2.0 and BSD and BSD with advertising and GPL+ and GPLv2 and GPLv2 with exceptions and IJG and LGPLv2+ and MIT and MPLv2.0 and Public Domain and W3C and zlib +URL: http://openjdk.java.net + +# Shenandoah HotSpot +# aarch64-port/jdk8u-shenandoah contains an integration forest of +# OpenJDK 8u, the aarch64 port and Shenandoah +# To regenerate, use: +# VERSION=%%{shenandoah_revision} +# FILE_NAME_ROOT=%%{shenandoah_project}-%%{shenandoah_repo}-${VERSION} +# REPO_ROOT= generate_source_tarball.sh +# where the source is obtained from http://hg.openjdk.java.net/%%{project}/%%{repo} +Source0: %{shenandoah_revision}.tar.xz + +# Custom README for -src subpackage +Source2: README.md + +# Ensure we aren't using the limited crypto policy +Source13: TestCryptoLevel.java + +# Ensure ECDSA is working +Source14: TestECDSA.java + +Patch1: 8160300.patch +Patch2: 8202076.patch +Patch7: delete-read-write-barriers-in-ShenandoahGC.patch +Patch8: replace-vector-to-improve-performance-of-xml.validat.patch +Patch9: AARCH64-fix-itable-stub-code-size-limit.patch +Patch10: 8221658.patch +Patch11: 8148754-C2-loop-unrolling-fails-due-to-unexpected-gr.patch +Patch12: add-debuginfo-for-libsaproc-on-aarch64.patch +Patch13: 8171537.patch +Patch18: fix-vendor-info.patch +Patch21: 8202952-C2-Unexpected-dead-nodes-after-matching.patch +Patch22: 8161072.patch +Patch23: 8135318.patch +Patch24: 8134883.patch +Patch25: FromCardCache-default-card-index-can-cause.patch +Patch26: disable-UseLSE-on-ARMv8.1-by-default.patch +Patch27: 8157570.patch +Patch28: 8194246.patch +Patch29: 8214345.patch +Patch30: 8191483.patch +Patch31: 8141356.patch +Patch32: 8151788.patch +Patch33: 8166253.patch +Patch34: 8191955.patch +Patch35: 8186042-OopmapCache-implementation.patch +Patch36: 8060463.patch +Patch37: 8131600.patch +Patch38: 8138971.patch +Patch39: 8167409-Invalid-value-passed-to-critical-JNI-function.patch +Patch40: 8129626.patch +Patch41: 8203699-java-lang-invoke-SpecialInte.patch +Patch45: 8191129.patch +Patch46: 8182036.patch +Patch47: 8166197.patch +Patch48: 8158946-JDK-8165808-JDK-8166583-JDK-.patch +Patch49: 8146792.patch +Patch50: 8047212.patch +Patch51: add-with-company-name-option.patch +Patch52: set_HongKong_timezone_to_CTT.patch +Patch53: 8229169.patch +Patch54: X500Name-implemation-change-to-avoid-OOM.patch +Patch55: 8231988.patch +Patch56: 8160369.patch +Patch57: 8031085.patch +Patch58: Reduce-the-probability-of-the-crash-related-to-ciObj.patch +Patch60: 8233839-aarch64-missing-memory-barrier-in-NewObjectA.patch +Patch61: 8231584-Deadlock-with-ClassLoader.findLibrary-and-Sy.patch +Patch62: 8165857-CMS-_overflow_list-is-missing-volatile-speci.patch +Patch63: 8033552-Fix-missing-missing-volatile-specifiers-in-C.patch +Patch64: 8182397-race-in-field-updates.patch +Patch65: 8234264-Incorrrect-8047434-JDK-8-backport-in-8219677.patch +Patch67: 8165860-WorkGroup-classes-are-missing-volatile-speci.patch +Patch68: 8194154-System-property-user.dir-should-not-be-chang.patch +Patch70: 8164948.patch +Patch71: 8154313.patch + +BuildRequires: autoconf +BuildRequires: automake +BuildRequires: alsa-lib-devel +BuildRequires: binutils +BuildRequires: cups-devel +# elfutils only are OK for build without AOT +BuildRequires: elfutils-devel +BuildRequires: fontconfig +BuildRequires: freetype-devel +BuildRequires: giflib-devel +BuildRequires: gcc-c++ +BuildRequires: gdb +BuildRequires: gtk2-devel +BuildRequires: lcms2-devel +BuildRequires: libjpeg-devel +BuildRequires: libpng-devel +BuildRequires: libxslt +BuildRequires: libX11-devel +BuildRequires: libXi-devel +BuildRequires: libXinerama-devel +BuildRequires: libXt-devel +BuildRequires: libXtst-devel +# Requirements for setting up the nss.cfg +BuildRequires: nss-devel +BuildRequires: pkgconfig +BuildRequires: xorg-x11-proto-devel +BuildRequires: zip +BuildRequires: unzip + +BuildRequires: java-1.8.0-openjdk-devel + +# Earlier versions have a bug in tree vectorization on PPC +BuildRequires: gcc >= 4.8.3-8 +# Build requirements for SunEC system NSS support +BuildRequires: nss-softokn-freebl-devel >= 3.16.1 + +# this is always built, also during debug-only build +# when it is built in debug-only this package is just placeholder +%{java_rpo %{nil}} + +%description +The %{origin_nice} runtime environment. + +%if %{include_debug_build} +%package slowdebug +Summary: %{origin_nice} Runtime Environment %{majorver} %{debug_on} +Group: Development/Languages + +%{java_rpo -- %{debug_suffix_unquoted}} +%description slowdebug +The %{origin_nice} runtime environment. +%{debug_warning} +%endif + +%if %{include_normal_build} +%package headless +Summary: %{origin_nice} Headless Runtime Environment %{majorver} +Group: Development/Languages + +%{java_headless_rpo %{nil}} + +%description headless +The %{origin_nice} runtime environment %{majorver} without audio and video support. +%endif + +%if %{include_debug_build} +%package headless-slowdebug +Summary: %{origin_nice} Runtime Environment %{debug_on} +Group: Development/Languages + +%{java_headless_rpo -- %{debug_suffix_unquoted}} + +%description headless-slowdebug +The %{origin_nice} runtime environment %{majorver} without audio and video support. +%{debug_warning} +%endif + +%if %{include_normal_build} +%package devel +Summary: %{origin_nice} Development Environment %{majorver} +Group: Development/Tools + +%{java_devel_rpo %{nil}} + +%description devel +The %{origin_nice} development tools %{majorver}. +%endif + +%if %{include_debug_build} +%package devel-slowdebug +Summary: %{origin_nice} Development Environment %{majorver} %{debug_on} +Group: Development/Tools + +%{java_devel_rpo -- %{debug_suffix_unquoted}} + +%description devel-slowdebug +The %{origin_nice} development tools %{majorver}. +%{debug_warning} +%endif + +%if %{include_normal_build} +%package demo +Summary: %{origin_nice} Demos %{majorver} +Group: Development/Languages + +%{java_demo_rpo %{nil}} + +%description demo +The %{origin_nice} demos %{majorver}. +%endif + +%if %{include_debug_build} +%package demo-slowdebug +Summary: %{origin_nice} Demos %{majorver} %{debug_on} +Group: Development/Languages + +%{java_demo_rpo -- %{debug_suffix_unquoted}} + +%description demo-slowdebug +The %{origin_nice} demos %{majorver}. +%{debug_warning} +%endif + +%if %{include_normal_build} +%package src +Summary: %{origin_nice} Source Bundle %{majorver} +Group: Development/Languages + +%{java_src_rpo %{nil}} + +%description src +The java-%{origin}-src sub-package contains the complete %{origin_nice} %{majorver} +class library source code for use by IDE indexers and debuggers. +%endif + +%if %{include_debug_build} +%package src-slowdebug +Summary: %{origin_nice} Source Bundle %{majorver} %{for_debug} +Group: Development/Languages + +%{java_src_rpo -- %{debug_suffix_unquoted}} + +%description src-slowdebug +The java-%{origin}-src-slowdebug sub-package contains the complete %{origin_nice} %{majorver} + class library source code for use by IDE indexers and debuggers. Debugging %{for_debug}. +%endif + +%if %{include_normal_build} +%package javadoc +Summary: %{origin_nice} %{majorver} API documentation +Group: Documentation +Requires: javapackages-filesystem +BuildArch: noarch + +%{java_javadoc_rpo %{nil}} + +%description javadoc +The %{origin_nice} %{majorver} API documentation. +%endif + +%if %{include_normal_build} +%package javadoc-zip +Summary: %{origin_nice} %{majorver} API documentation compressed in single archive +Group: Documentation +Requires: javapackages-filesystem +BuildArch: noarch + +%{java_javadoc_rpo %{nil}} + +%description javadoc-zip +The %{origin_nice} %{majorver} API documentation compressed in single archive. +%endif + +%if %{include_debug_build} +%package javadoc-slowdebug +Summary: %{origin_nice} %{majorver} API documentation %{for_debug} +Group: Documentation +Requires: javapackages-filesystem +BuildArch: noarch + +%{java_javadoc_rpo -- %{debug_suffix_unquoted}} + +%description javadoc-slowdebug +The %{origin_nice} %{majorver} API documentation %{for_debug}. +%endif + +%if %{include_debug_build} +%package javadoc-zip-slowdebug +Summary: %{origin_nice} %{majorver} API documentation compressed in single archive %{for_debug} +Group: Documentation +Requires: javapackages-filesystem +BuildArch: noarch + +%{java_javadoc_rpo -- %{debug_suffix_unquoted}} + +%description javadoc-zip-slowdebug +The %{origin_nice} %{majorver} API documentation compressed in single archive %{for_debug}. +%endif + + +%if %{include_normal_build} +%package accessibility +Summary: %{origin_nice} %{majorver} accessibility connector + +%{java_accessibility_rpo %{nil}} + +%description accessibility +Enables accessibility support in %{origin_nice} %{majorver} by using java-atk-wrapper. This allows +compatible at-spi2 based accessibility programs to work for AWT and Swing-based +programs. + +Please note, the java-atk-wrapper is still in beta, and %{origin_nice} %{majorver} itself is still +being tuned to be working with accessibility features. There are known issues +with accessibility on, so please do not install this package unless you really +need to. +%endif + +%if %{include_debug_build} +%package accessibility-slowdebug +Summary: %{origin_nice} %{majorver} accessibility connector %{for_debug} + +%{java_accessibility_rpo -- %{debug_suffix_unquoted}} + +%description accessibility-slowdebug +See normal java-%{version}-openjdk-accessibility description. +%endif + +%prep +if [ %{include_normal_build} -eq 0 -o %{include_normal_build} -eq 1 ] ; then + echo "include_normal_build is %{include_normal_build}" +else + echo "include_normal_build is %{include_normal_build}, thats invalid. Use 1 for yes or 0 for no" + exit 11 +fi +if [ %{include_debug_build} -eq 0 -o %{include_debug_build} -eq 1 ] ; then + echo "include_debug_build is %{include_debug_build}" +else + echo "include_debug_build is %{include_debug_build}, thats invalid. Use 1 for yes or 0 for no" + exit 12 +fi +if [ %{include_debug_build} -eq 0 -a %{include_normal_build} -eq 0 ] ; then + echo "You have disabled both include_debug_build and include_normal_build. That is a no go." + exit 13 +fi +%setup -q -c -n %{uniquesuffix ""} -T -a 0 +# https://bugzilla.redhat.com/show_bug.cgi?id=1189084 +prioritylength=`expr length %{priority}` +if [ $prioritylength -ne 7 ] ; then + echo "priority must be 7 digits in total, violated" + exit 14 +fi + +pushd %{top_level_dir_name} +# OpenJDK patches + +%patch1 -p1 +%patch2 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch18 -p1 +%patch21 -p1 +%patch22 -p1 +%patch23 -p1 +%patch24 -p1 +%patch25 -p1 +%patch26 -p1 +%patch27 -p1 +%patch28 -p1 +%patch29 -p1 +%patch30 -p1 +%patch31 -p1 +%patch32 -p1 +%patch33 -p1 +%patch34 -p1 +%patch35 -p1 +%patch36 -p1 +%patch37 -p1 +%patch38 -p1 +%patch39 -p1 +%patch40 -p1 +%patch41 -p1 +%patch45 -p1 +%patch46 -p1 +%patch47 -p1 +%patch48 -p1 +%patch49 -p1 +%patch50 -p1 +%patch51 -p1 +%patch52 -p1 +%patch53 -p1 +%patch54 -p1 +%patch55 -p1 +%patch56 -p1 +%patch57 -p1 +%patch58 -p1 +%patch60 -p1 +%patch61 -p1 +%patch62 -p1 +%patch63 -p1 +%patch64 -p1 +%patch65 -p1 +%patch67 -p1 +%patch68 -p1 +%patch70 -p1 +%patch71 -p1 + +popd + +%build +# How many CPU's do we have? +export NUM_PROC=%(/usr/bin/getconf _NPROCESSORS_ONLN 2> /dev/null || :) +export NUM_PROC=${NUM_PROC:-1} +%if 0%{?_smp_ncpus_max} +# Honor %%_smp_ncpus_max +[ ${NUM_PROC} -gt %{?_smp_ncpus_max} ] && export NUM_PROC=%{?_smp_ncpus_max} +%endif + +%ifarch s390x sparc64 alpha %{power64} %{aarch64} +export ARCH_DATA_MODEL=64 +%endif +%ifarch alpha +export CFLAGS="$CFLAGS -mieee" +%endif + +# We use ourcppflags because the OpenJDK build seems to +# pass EXTRA_CFLAGS to the HotSpot C++ compiler... +# Explicitly set the C++ standard as the default has changed on GCC >= 6 +EXTRA_CFLAGS="-std=gnu++98 -Wno-error -fno-delete-null-pointer-checks -fno-lifetime-dse -fstack-protector-strong" +EXTRA_CPP_FLAGS="-std=gnu++98 -fno-delete-null-pointer-checks -fno-lifetime-dse -fstack-protector-strong" +EXTRA_LDFLAGS="-Wl,-z,now,-z,relro" + +export EXTRA_CFLAGS + +for suffix in %{build_loop} ; do +if [ "x$suffix" = "x" ] ; then + debugbuild=release +else + # change --something to something + debugbuild=`echo $suffix | sed "s/-//g"` +fi + +# Variable used in hs_err hook on build failures +top_dir_abs_path=$(pwd)/%{top_level_dir_name} + +mkdir -p %{buildoutputdir -- $suffix} +pushd %{buildoutputdir -- $suffix} + +NSS_LIBS="%{NSS_LIBS} -lfreebl" \ +NSS_CFLAGS="%{NSS_CFLAGS}" \ +bash ../../configure \ + --with-native-debug-symbols=internal \ + --with-milestone="fcs" \ + --with-update-version=%{updatever} \ + --with-build-number=%{buildver} \ + --with-debug-level=$debugbuild \ + --enable-unlimited-crypto \ + --with-extra-cxxflags="$EXTRA_CPP_FLAGS" \ + --with-extra-cflags="$EXTRA_CFLAGS" \ + --with-extra-ldflags="%{ourldflags}" \ + --with-num-cores="$NUM_PROC" \ + --with-boot-jdk-jvmargs=-XX:-UsePerfData + +cat spec.gmk +cat hotspot-spec.gmk + +make \ + JAVAC_FLAGS=-g \ + LOG=trace \ + SCTP_WERROR= \ + %{targets} || ( pwd; find $top_dir_abs_path -name "hs_err_pid*.log" | xargs cat && false ) + +make zip-docs + +# the build (erroneously) removes read permissions from some jars +# this is a regression in OpenJDK 7 (our compiler): +# http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=1437 +find images/%{jdkimage} -iname '*.jar' -exec chmod ugo+r {} \; +chmod ugo+r images/%{jdkimage}/lib/ct.sym + +# remove redundant *diz and *debuginfo files +find images/%{jdkimage} -iname '*.diz' -exec rm {} \; +find images/%{jdkimage} -iname '*.debuginfo' -exec rm {} \; + +# Build screws up permissions on binaries +# https://bugs.openjdk.java.net/browse/JDK-8173610 +find images/%{jdkimage} -iname '*.so' -exec chmod +x {} \; +find images/%{jdkimage}/bin/ -exec chmod +x {} \; + +popd >& /dev/null + +# Install nss.cfg right away as we will be using the JRE above +export JAVA_HOME=$(pwd)/%{buildoutputdir -- $suffix}/images/%{jdkimage} + +# build cycles +done + +%check + +# We test debug first as it will give better diagnostics on a crash +for suffix in %{rev_build_loop} ; do + +export JAVA_HOME=$(pwd)/%{buildoutputdir -- $suffix}/images/%{jdkimage} + +# Check unlimited policy has been used +$JAVA_HOME/bin/javac -d . %{SOURCE13} +$JAVA_HOME/bin/java TestCryptoLevel + +# Check ECC is working +$JAVA_HOME/bin/javac -d . %{SOURCE14} +$JAVA_HOME/bin/java $(echo $(basename %{SOURCE14})|sed "s|\.java||") + +# Check debug symbols are present and can identify code +find "$JAVA_HOME" -iname '*.so' -print0 | while read -d $'\0' lib +do + if [ -f "$lib" ] ; then + echo "Testing $lib for debug symbols" + # All these tests rely on RPM failing the build if the exit code of any set + # of piped commands is non-zero. + + # Test for .debug_* sections in the shared object. This is the main test + # Stripped objects will not contain these + eu-readelf -S "$lib" | grep "] .debug_" + test $(eu-readelf -S "$lib" | grep -E "\]\ .debug_(info|abbrev)" | wc --lines) == 2 + + # Test FILE symbols. These will most likely be removed by anything that + # manipulates symbol tables because it's generally useless. So a nice test + # that nothing has messed with symbols + old_IFS="$IFS" + IFS=$'\n' + for line in $(eu-readelf -s "$lib" | grep "00000000 0 FILE LOCAL DEFAULT") + do + # We expect to see .cpp files, except for architectures like aarch64 and + # s390 where we expect .o and .oS files + echo "$line" | grep -E "ABS ((.*/)?[-_a-zA-Z0-9]+\.(c|cc|cpp|cxx|o|oS))?$" + done + IFS="$old_IFS" + + # If this is the JVM, look for javaCalls.(cpp|o) in FILEs, for extra sanity checking + if [ "`basename $lib`" = "libjvm.so" ]; then + eu-readelf -s "$lib" | \ + grep -E "00000000 0 FILE LOCAL DEFAULT ABS javaCalls.(cpp|o)$" + fi + + # Test that there are no .gnu_debuglink sections pointing to another + # debuginfo file. There shouldn't be any debuginfo files, so the link makes + # no sense either + eu-readelf -S "$lib" | grep 'gnu' + if eu-readelf -S "$lib" | grep '] .gnu_debuglink' | grep PROGBITS; then + echo "bad .gnu_debuglink section." + eu-readelf -x .gnu_debuglink "$lib" + false + fi + fi +done + +# Make sure gdb can do a backtrace based on line numbers on libjvm.so +# javaCalls.cpp:58 should map to: +# http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/ff3b27e6bcc2/src/share/vm/runtime/javaCalls.cpp#l58 +# Using line number 1 might cause build problems. See: +# https://bugzilla.redhat.com/show_bug.cgi?id=1539664 +# https://bugzilla.redhat.com/show_bug.cgi?id=1538767 +gdb -q "$JAVA_HOME/bin/java" <> %{name}-demo.files"$suffix" +# Find documentation demo files. +find $RPM_BUILD_ROOT%{_jvmdir}/%{sdkdir -- $suffix}/demo \ + $RPM_BUILD_ROOT%{_jvmdir}/%{sdkdir -- $suffix}/sample \ + -type f -o -type l | sort \ + | grep README \ + | sed 's|'$RPM_BUILD_ROOT'||' \ + | sed 's|^|%doc |' \ + >> %{name}-demo.files"$suffix" + +# Create links which leads to separately installed java-atk-bridge and allow configuration +# links points to java-atk-wrapper - an dependence + pushd $RPM_BUILD_ROOT/%{_jvmdir}/%{jredir -- $suffix}/lib/%{archinstall} + ln -s %{_libdir}/java-atk-wrapper/libatk-wrapper.so.0 libatk-wrapper.so + popd + pushd $RPM_BUILD_ROOT/%{_jvmdir}/%{jredir -- $suffix}/lib/ext + ln -s %{_libdir}/java-atk-wrapper/java-atk-wrapper.jar java-atk-wrapper.jar + popd + pushd $RPM_BUILD_ROOT/%{_jvmdir}/%{jredir -- $suffix}/lib/ + echo "#Config file to enable java-atk-wrapper" > accessibility.properties + echo "" >> accessibility.properties + echo "assistive_technologies=org.GNOME.Accessibility.AtkWrapper" >> accessibility.properties + echo "" >> accessibility.properties + popd + +# stabilize permissions +find $RPM_BUILD_ROOT/%{_jvmdir}/%{sdkdir -- $suffix}/ -name "*.so" -exec chmod 755 {} \; ; +find $RPM_BUILD_ROOT/%{_jvmdir}/%{sdkdir -- $suffix}/ -type d -exec chmod 755 {} \; ; +find $RPM_BUILD_ROOT/%{_jvmdir}/%{sdkdir -- $suffix}/ -name "ASSEMBLY_EXCEPTION" -exec chmod 644 {} \; ; +find $RPM_BUILD_ROOT/%{_jvmdir}/%{sdkdir -- $suffix}/ -name "LICENSE" -exec chmod 644 {} \; ; +find $RPM_BUILD_ROOT/%{_jvmdir}/%{sdkdir -- $suffix}/ -name "THIRD_PARTY_README" -exec chmod 644 {} \; ; + +# end, dual install +done + +%if %{include_normal_build} +# intentionally only for non-debug +%pretrans headless -p +-- see https://bugzilla.redhat.com/show_bug.cgi?id=1038092 for whole issue +-- see https://bugzilla.redhat.com/show_bug.cgi?id=1290388 for pretrans over pre +-- if copy-jdk-configs is in transaction, it installs in pretrans to temp +-- if copy_jdk_configs is in temp, then it means that copy-jdk-configs is in transaction and so is +-- preferred over one in %%{_libexecdir}. If it is not in transaction, then depends +-- whether copy-jdk-configs is installed or not. If so, then configs are copied +-- (copy_jdk_configs from %%{_libexecdir} used) or not copied at all +local posix = require "posix" +local debug = false + +SOURCE1 = "%{rpm_state_dir}/copy_jdk_configs.lua" +SOURCE2 = "%{_libexecdir}/copy_jdk_configs.lua" + +local stat1 = posix.stat(SOURCE1, "type"); +local stat2 = posix.stat(SOURCE2, "type"); + + if (stat1 ~= nil) then + if (debug) then + print(SOURCE1 .." exists - copy-jdk-configs in transaction, using this one.") + end; + package.path = package.path .. ";" .. SOURCE1 +else + if (stat2 ~= nil) then + if (debug) then + print(SOURCE2 .." exists - copy-jdk-configs already installed and NOT in transaction. Using.") + end; + package.path = package.path .. ";" .. SOURCE2 + else + if (debug) then + print(SOURCE1 .." does NOT exists") + print(SOURCE2 .." does NOT exists") + print("No config files will be copied") + end + return + end +end +-- run content of included file with fake args +arg = {"--currentjvm", "%{uniquesuffix %{nil}}", "--jvmdir", "%{_jvmdir %{nil}}", "--origname", "%{name}", "--origjavaver", "%{javaver}", "--arch", "%{_arch}", "--temp", "%{rpm_state_dir}/%{name}.%{_arch}"} +require "copy_jdk_configs.lua" + +%post +%{post_script %{nil}} + +%post headless +%{post_headless %{nil}} + +%postun +%{postun_script %{nil}} + +%postun headless +%{postun_headless %{nil}} + +%posttrans +%{posttrans_script %{nil}} + +%post devel +%{post_devel %{nil}} + +%postun devel +%{postun_devel %{nil}} + +%posttrans devel +%{posttrans_devel %{nil}} + +%post javadoc +%{post_javadoc %{nil}} + +%postun javadoc +%{postun_javadoc %{nil}} + +%post javadoc-zip +%{post_javadoc_zip %{nil}} + +%postun javadoc-zip +%{postun_javadoc_zip %{nil}} +%endif + +%if %{include_debug_build} +%post slowdebug +%{post_script -- %{debug_suffix_unquoted}} + +%post headless-slowdebug +%{post_headless -- %{debug_suffix_unquoted}} + +%postun slowdebug +%{postun_script -- %{debug_suffix_unquoted}} + +%postun headless-slowdebug +%{postun_headless -- %{debug_suffix_unquoted}} + +%posttrans slowdebug +%{posttrans_script -- %{debug_suffix_unquoted}} + +%post devel-slowdebug +%{post_devel -- %{debug_suffix_unquoted}} + +%postun devel-slowdebug +%{postun_devel -- %{debug_suffix_unquoted}} + +%posttrans devel-slowdebug +%{posttrans_devel -- %{debug_suffix_unquoted}} + +%post javadoc-slowdebug +%{post_javadoc -- %{debug_suffix_unquoted}} + +%postun javadoc-slowdebug +%{postun_javadoc -- %{debug_suffix_unquoted}} + +%post javadoc-zip-slowdebug +%{post_javadoc_zip -- %{debug_suffix_unquoted}} + +%postun javadoc-zip-slowdebug +%{postun_javadoc_zip -- %{debug_suffix_unquoted}} +%endif + +%if %{include_normal_build} +%files +# main package builds always +%{files_jre %{nil}} +%else +%files +# placeholder +%endif + + +%if %{include_normal_build} +%files headless +# important note, see https://bugzilla.redhat.com/show_bug.cgi?id=1038092 for whole issue +# all config/noreplace files (and more) have to be declared in pretrans. See pretrans +%{files_jre_headless %{nil}} + +%files devel +%{files_devel %{nil}} + +%files demo -f %{name}-demo.files +%{files_demo %{nil}} + +%files src +%{files_src %{nil}} + +%files javadoc +%{files_javadoc %{nil}} + +# this puts huge file to /usr/share +# unluckily ti is really a documentation file +# and unluckily it really is architecture-dependent, as eg. aot and grail are now x86_64 only +# same for debug variant +%files javadoc-zip +%{files_javadoc_zip %{nil}} + +%files accessibility +%{files_accessibility %{nil}} +%endif + +%changelog +* Sat Dec 14 2019 guoge - 1:1.8.0.232-b09.1 +- Initial build from OpenJDK aarch64-shenandoah-8u232-b09 diff --git a/replace-vector-to-improve-performance-of-xml.validat.patch b/replace-vector-to-improve-performance-of-xml.validat.patch new file mode 100644 index 0000000000000000000000000000000000000000..8748053ca962bd53d29f5478a37984e59eaede51 --- /dev/null +++ b/replace-vector-to-improve-performance-of-xml.validat.patch @@ -0,0 +1,450 @@ +From 6ee202c81902416a9ec5ec5a32c536d3294bd5e6 Mon Sep 17 00:00:00 2001 +From: guoge +Date: Fri, 19 Apr 2019 17:23:48 +0000 +Subject: [PATCH] replace vector to improve performance of xml.validation + +--- + .../internal/impl/dv/ValidatedInfo.java | 5 + + .../internal/impl/dv/xs/XSSimpleTypeDecl.java | 148 ++++++++++-------- + .../xerces/internal/impl/xpath/regex/Op.java | 10 +- + .../impl/xpath/regex/RegularExpression.java | 6 +- + 4 files changed, 97 insertions(+), 72 deletions(-) + +diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/ValidatedInfo.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/ValidatedInfo.java +index e6b8f267a5..8d5d86772f 100644 +--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/ValidatedInfo.java ++++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/ValidatedInfo.java +@@ -95,4 +95,9 @@ public class ValidatedInfo { + else + return actualValue.toString(); + } ++ ++ public Object getActualValue() { ++ return actualValue; ++ } ++ + } +diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/XSSimpleTypeDecl.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/XSSimpleTypeDecl.java +index c9c913464e..98546f2d50 100644 +--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/XSSimpleTypeDecl.java ++++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/dv/xs/XSSimpleTypeDecl.java +@@ -20,11 +20,6 @@ + + package com.sun.org.apache.xerces.internal.impl.dv.xs; + +-import java.util.AbstractList; +-import java.util.Locale; +-import java.util.StringTokenizer; +-import java.util.Vector; +- + import com.sun.org.apache.xerces.internal.impl.Constants; + import com.sun.org.apache.xerces.internal.impl.dv.DatatypeException; + import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeFacetException; +@@ -52,6 +47,12 @@ import com.sun.org.apache.xerces.internal.xs.XSObjectList; + import com.sun.org.apache.xerces.internal.xs.XSSimpleTypeDefinition; + import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; + import com.sun.org.apache.xerces.internal.xs.datatypes.ObjectList; ++import java.math.BigInteger; ++import java.util.AbstractList; ++import java.util.ArrayList; ++import java.util.List; ++import java.util.Locale; ++import java.util.StringTokenizer; + import org.w3c.dom.TypeInfo; + + /** +@@ -266,11 +267,10 @@ public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo { + private int fMaxLength = -1; + private int fTotalDigits = -1; + private int fFractionDigits = -1; +- private Vector fPattern; +- private Vector fPatternStr; +- private Vector fEnumeration; +- private short[] fEnumerationType; +- private ShortList[] fEnumerationItemType; // used in case fenumerationType value is LIST or LISTOFUNION ++ private List fPattern; ++ private List fPatternStr; ++ private ValidatedInfo[] fEnumeration; ++ private int fEnumerationSize; + private ShortList fEnumerationTypeList; + private ObjectList fEnumerationItemTypeList; + private StringList fLexicalPattern; +@@ -388,8 +388,7 @@ public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo { + fPattern = fBase.fPattern; + fPatternStr = fBase.fPatternStr; + fEnumeration = fBase.fEnumeration; +- fEnumerationType = fBase.fEnumerationType; +- fEnumerationItemType = fBase.fEnumerationItemType; ++ fEnumerationSize = fBase.fEnumerationSize; + fWhiteSpace = fBase.fWhiteSpace; + fMaxExclusive = fBase.fMaxExclusive; + fMaxInclusive = fBase.fMaxInclusive; +@@ -509,8 +508,7 @@ public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo { + fPattern = fBase.fPattern; + fPatternStr = fBase.fPatternStr; + fEnumeration = fBase.fEnumeration; +- fEnumerationType = fBase.fEnumerationType; +- fEnumerationItemType = fBase.fEnumerationItemType; ++ fEnumerationSize = fBase.fEnumerationSize; + fWhiteSpace = fBase.fWhiteSpace; + fMaxExclusive = fBase.fMaxExclusive; + fMaxInclusive = fBase.fMaxInclusive; +@@ -846,10 +844,10 @@ public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo { + reportError("InvalidRegex", new Object[]{facets.pattern, e.getLocalizedMessage()}); + } + if (regex != null) { +- fPattern = new Vector(); +- fPattern.addElement(regex); +- fPatternStr = new Vector(); +- fPatternStr.addElement(facets.pattern); ++ fPattern = new ArrayList<>(); ++ fPattern.add(regex); ++ fPatternStr = new ArrayList<>(); ++ fPatternStr.add(facets.pattern); + fFacetsDefined |= FACET_PATTERN; + if ((fixedFacet & FACET_PATTERN) != 0) + fFixedFacet |= FACET_PATTERN; +@@ -874,24 +872,22 @@ public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo { + if ((allowedFacet & FACET_ENUMERATION) == 0) { + reportError("cos-applicable-facets", new Object[]{"enumeration", fTypeName}); + } else { +- fEnumeration = new Vector(); +- Vector enumVals = facets.enumeration; +- fEnumerationType = new short[enumVals.size()]; +- fEnumerationItemType = new ShortList[enumVals.size()]; +- Vector enumNSDecls = facets.enumNSDecls; ++ List enumVals = facets.enumeration; ++ int size = enumVals.size(); ++ fEnumeration = new ValidatedInfo[size]; ++ List enumNSDecls = facets.enumNSDecls; + ValidationContextImpl ctx = new ValidationContextImpl(context); + enumerationAnnotations = facets.enumAnnotations; +- for (int i = 0; i < enumVals.size(); i++) { ++ fEnumerationSize = 0; ++ for (int i = 0; i < size; i++) { + if (enumNSDecls != null) +- ctx.setNSContext((NamespaceContext)enumNSDecls.elementAt(i)); ++ ctx.setNSContext(enumNSDecls.get(i)); + try { +- ValidatedInfo info = getActualEnumValue((String)enumVals.elementAt(i), ctx, tempInfo); ++ ValidatedInfo info = getActualEnumValue(enumVals.get(i), ctx, null); + // check 4.3.5.c0 must: enumeration values from the value space of base +- fEnumeration.addElement(info.actualValue); +- fEnumerationType[i] = info.actualValueType; +- fEnumerationItemType[i] = info.itemValueTypes; ++ fEnumeration[fEnumerationSize++] = info; + } catch (InvalidDatatypeValueException ide) { +- reportError("enumeration-valid-restriction", new Object[]{enumVals.elementAt(i), this.getBaseType().getName()}); ++ reportError("enumeration-valid-restriction", new Object[]{enumVals.get(i), this.getBaseType().getName()}); + } + } + fFacetsDefined |= FACET_ENUMERATION; +@@ -1454,8 +1450,8 @@ public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo { + } + else { + for (int i = fBase.fPattern.size()-1; i >= 0; --i) { +- fPattern.addElement(fBase.fPattern.elementAt(i)); +- fPatternStr.addElement(fBase.fPatternStr.elementAt(i)); ++ fPattern.add(fBase.fPattern.get(i)); ++ fPatternStr.add(fBase.fPatternStr.get(i)); + } + if (fBase.patternAnnotations != null) { + if (patternAnnotations != null) { +@@ -1479,6 +1475,7 @@ public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo { + if ((fFacetsDefined & FACET_ENUMERATION) == 0 && (fBase.fFacetsDefined & FACET_ENUMERATION) != 0) { + fFacetsDefined |= FACET_ENUMERATION; + fEnumeration = fBase.fEnumeration; ++ fEnumerationSize = fBase.fEnumerationSize; + enumerationAnnotations = fBase.enumerationAnnotations; + } + // inherit maxExclusive +@@ -1674,16 +1671,16 @@ public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo { + //enumeration + if ( ((fFacetsDefined & FACET_ENUMERATION) != 0 ) ) { + boolean present = false; +- final int enumSize = fEnumeration.size(); ++ final int enumSize = fEnumerationSize; + final short primitiveType1 = convertToPrimitiveKind(type); + for (int i = 0; i < enumSize; i++) { +- final short primitiveType2 = convertToPrimitiveKind(fEnumerationType[i]); ++ final short primitiveType2 = convertToPrimitiveKind(fEnumeration[i].actualValueType); + if ((primitiveType1 == primitiveType2 || + primitiveType1 == XSConstants.ANYSIMPLETYPE_DT && primitiveType2 == XSConstants.STRING_DT || + primitiveType1 == XSConstants.STRING_DT && primitiveType2 == XSConstants.ANYSIMPLETYPE_DT) +- && fEnumeration.elementAt(i).equals(ob)) { ++ && fEnumeration[i].actualValue.equals(ob)) { + if (primitiveType1 == XSConstants.LIST_DT || primitiveType1 == XSConstants.LISTOFUNION_DT) { +- ShortList enumItemType = fEnumerationItemType[i]; ++ ShortList enumItemType = fEnumeration[i].itemValueTypes; + final int typeList1Length = itemType != null ? itemType.getLength() : 0; + final int typeList2Length = enumItemType != null ? enumItemType.getLength() : 0; + if (typeList1Length == typeList2Length) { +@@ -1712,8 +1709,10 @@ public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo { + } + } + if(!present){ ++ StringBuffer sb = new StringBuffer(); ++ appendEnumString(sb); + throw new InvalidDatatypeValueException("cvc-enumeration-valid", +- new Object [] {content, fEnumeration.toString()}); ++ new Object [] {content, sb.toString()}); + } + } + +@@ -1836,11 +1835,12 @@ public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo { + } + RegularExpression regex; + for (int idx = fPattern.size()-1; idx >= 0; idx--) { +- regex = (RegularExpression)fPattern.elementAt(idx); ++ regex = fPattern.get(idx); + if (!regex.matches(nvalue)){ + throw new InvalidDatatypeValueException("cvc-pattern-valid", + new Object[]{content, +- fPatternStr.elementAt(idx), ++ fPatternStr.get(idx), ++ + fTypeName}); + } + } +@@ -1911,6 +1911,7 @@ public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo { + validatedInfo.memberTypes = memberTypes; + validatedInfo.itemValueTypes = new ShortListImpl(itemTypes, itemTypes.length); + validatedInfo.normalizedValue = nvalue; ++ // Need to set it here or it will become the item type + + return v; + +@@ -1930,6 +1931,7 @@ public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo { + fMemberTypes[i].checkFacets(validatedInfo); + } + validatedInfo.memberType = fMemberTypes[i]; ++ // Need to set it here or it will become the member type + return aValue; + } catch(InvalidDatatypeValueException invalidValue) { + } +@@ -1947,14 +1949,8 @@ public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo { + } + typesBuffer.append(decl.fTypeName); + if(decl.fEnumeration != null) { +- Vector v = decl.fEnumeration; +- typesBuffer.append(" : ["); +- for(int j = 0;j < v.size(); j++) { +- if(j != 0) +- typesBuffer.append(','); +- typesBuffer.append(v.elementAt(j)); +- } +- typesBuffer.append(']'); ++ typesBuffer.append(" : "); ++ decl.appendEnumString(typesBuffer); + } + } + throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", +@@ -2246,10 +2242,10 @@ public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo { + if (fLexicalEnumeration == null){ + if (fEnumeration == null) + return StringListImpl.EMPTY_LIST; +- int size = fEnumeration.size(); ++ int size = fEnumerationSize; + String[] strs = new String[size]; + for (int i = 0; i < size; i++) +- strs[i] = fEnumeration.elementAt(i).toString(); ++ strs[i] = fEnumeration[i].actualValue.toString(); + fLexicalEnumeration = new StringListImpl(strs, size); + } + return fLexicalEnumeration; +@@ -2263,16 +2259,24 @@ public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo { + if (fActualEnumeration == null) { + fActualEnumeration = new AbstractObjectList() { + public int getLength() { +- return (fEnumeration != null) ? fEnumeration.size() : 0; ++ return (fEnumeration != null) ? fEnumerationSize : 0; + } + public boolean contains(Object item) { +- return (fEnumeration != null && fEnumeration.contains(item)); ++ if (fEnumeration == null) { ++ return false; ++ } ++ for (int i = 0; i < fEnumerationSize; i++) { ++ if (fEnumeration[i].getActualValue().equals(item)) { ++ return true; ++ } ++ } ++ return false; + } + public Object item(int index) { + if (index < 0 || index >= getLength()) { + return null; + } +- return fEnumeration.elementAt(index); ++ return fEnumeration[index].getActualValue(); + } + }; + } +@@ -2285,17 +2289,18 @@ public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo { + */ + public ObjectList getEnumerationItemTypeList() { + if (fEnumerationItemTypeList == null) { +- if(fEnumerationItemType == null) ++ if (fEnumeration == null) { + return null; ++ } + fEnumerationItemTypeList = new AbstractObjectList() { + public int getLength() { +- return (fEnumerationItemType != null) ? fEnumerationItemType.length : 0; ++ return (fEnumeration != null) ? fEnumerationSize : 0; + } + public boolean contains(Object item) { +- if(fEnumerationItemType == null || !(item instanceof ShortList)) ++ if (fEnumeration == null || !(item instanceof ShortList)) + return false; +- for(int i = 0;i < fEnumerationItemType.length; i++) +- if(fEnumerationItemType[i] == item) ++ for (int i = 0;i < fEnumerationSize; i++) ++ if (fEnumeration[i].itemValueTypes == item) + return true; + return false; + } +@@ -2303,7 +2308,7 @@ public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo { + if (index < 0 || index >= getLength()) { + return null; + } +- return fEnumerationItemType[index]; ++ return fEnumeration[index].itemValueTypes; + } + }; + } +@@ -2312,10 +2317,14 @@ public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo { + + public ShortList getEnumerationTypeList() { + if (fEnumerationTypeList == null) { +- if (fEnumerationType == null) { ++ if (fEnumeration == null) { + return ShortListImpl.EMPTY_LIST; + } +- fEnumerationTypeList = new ShortListImpl (fEnumerationType, fEnumerationType.length); ++ short[] list = new short[fEnumerationSize]; ++ for (int i = 0; i < fEnumerationSize; i++) { ++ list[i] = fEnumeration[i].actualValueType; ++ } ++ fEnumerationTypeList = new ShortListImpl(list, fEnumerationSize); + } + return fEnumerationTypeList; + } +@@ -2351,7 +2360,7 @@ public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo { + strs = new String[size]; + } + for (int i = 0; i < size; i++) +- strs[i] = (String)fPatternStr.elementAt(i); ++ strs[i] = fPatternStr.get(i); + fLexicalPattern = new StringListImpl(strs, strs.length); + } + return fLexicalPattern; +@@ -2596,7 +2605,7 @@ public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo { + ((ancestorNS == null && type.getNamespace() == null) || + (ancestorNS != null && ancestorNS.equals(type.getNamespace())))) && // compare with ancestor + type != fAnySimpleType) { // reached anySimpleType +- type = (XSTypeDefinition)type.getBaseType(); ++ type = type.getBaseType(); + } + + return type != fAnySimpleType; +@@ -2979,10 +2988,11 @@ public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo { + fPattern = null; + fPatternStr = null; + fEnumeration = null; +- fEnumerationType = null; +- fEnumerationItemType = null; + fLexicalPattern = null; + fLexicalEnumeration = null; ++ fActualEnumeration = null; ++ fEnumerationTypeList = null; ++ fEnumerationItemTypeList = null; + fMaxInclusive = null; + fMaxExclusive = null; + fMinExclusive = null; +@@ -3395,4 +3405,14 @@ public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo { + return valueType; + } + ++ private void appendEnumString(StringBuffer sb) { ++ sb.append('['); ++ for (int i = 0; i < fEnumerationSize; i++) { ++ if (i != 0) { ++ sb.append(", "); ++ } ++ sb.append(fEnumeration[i].actualValue); ++ } ++ sb.append(']'); ++ } + } // class XSSimpleTypeDecl +diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xpath/regex/Op.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xpath/regex/Op.java +index 372242ff6e..ab6cdb8455 100644 +--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xpath/regex/Op.java ++++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xpath/regex/Op.java +@@ -20,7 +20,7 @@ + + package com.sun.org.apache.xerces.internal.impl.xpath.regex; + +-import java.util.Vector; ++import java.util.ArrayList; + + /** + * @xerces.internal +@@ -170,19 +170,19 @@ class Op { + + // ================================================================ + static class UnionOp extends Op { +- Vector branches; ++ final ArrayList branches; + UnionOp(int type, int size) { + super(type); +- this.branches = new Vector(size); ++ this.branches = new ArrayList<>(size); + } + void addElement(Op op) { +- this.branches.addElement(op); ++ this.branches.add(op); + } + int size() { + return this.branches.size(); + } + Op elementAt(int index) { +- return (Op)this.branches.elementAt(index); ++ return this.branches.get(index); + } + } + +diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xpath/regex/RegularExpression.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xpath/regex/RegularExpression.java +index fa488d64ad..913740fe0d 100644 +--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xpath/regex/RegularExpression.java ++++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xpath/regex/RegularExpression.java +@@ -22,7 +22,7 @@ package com.sun.org.apache.xerces.internal.impl.xpath.regex; + + import java.text.CharacterIterator; + import java.util.Locale; +-import java.util.Stack; ++import java.util.LinkedList; + + import com.sun.org.apache.xerces.internal.util.IntStack; + +@@ -1044,7 +1044,7 @@ public class RegularExpression implements java.io.Serializable { + */ + private int match(Context con, Op op, int offset, int dx, int opts) { + final ExpressionTarget target = con.target; +- final Stack opStack = new Stack(); ++ final LinkedList opStack = new LinkedList<>(); + final IntStack dataStack = new IntStack(); + final boolean isSetIgnoreCase = isSet(opts, IGNORE_CASE); + int retValue = -1; +@@ -1323,7 +1323,7 @@ public class RegularExpression implements java.io.Serializable { + return retValue; + } + +- op = (Op) opStack.pop(); ++ op = opStack.pop(); + offset = dataStack.pop(); + + switch (op.type) { +-- +2.19.0 + diff --git a/set_HongKong_timezone_to_CTT.patch b/set_HongKong_timezone_to_CTT.patch new file mode 100644 index 0000000000000000000000000000000000000000..5c576e0c340be8a5ca53611b79a58adba4a160ea --- /dev/null +++ b/set_HongKong_timezone_to_CTT.patch @@ -0,0 +1,268 @@ +From 09d4f8a17aff883e7937c048a2da6bcf3feb7894 Mon Sep 17 00:00:00 2001 +From: wangshuai +Date: Thu, 5 Sep 2019 21:45:57 +0000 +Subject: [PATCH] + +Summary: The timezone of HongKong is different from that of other cities in China. +LLT: Local passed the jcstress and JTREG +Bug url: + +--- + jdk/src/share/classes/sun/util/resources/TimeZoneNames.java | 4 ++-- + jdk/src/share/classes/sun/util/resources/de/TimeZoneNames_de.java | 4 ++-- + jdk/src/share/classes/sun/util/resources/es/TimeZoneNames_es.java | 4 ++-- + jdk/src/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java | 4 ++-- + jdk/src/share/classes/sun/util/resources/it/TimeZoneNames_it.java | 4 ++-- + jdk/src/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java | 4 ++-- + jdk/src/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java | 4 ++-- + jdk/src/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java | 4 ++-- + jdk/src/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java | 4 ++-- + jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java | 4 ++-- + jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java | 4 ++-- + 11 files changed, 22 insertions(+), 22 deletions(-) + +diff --git a/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java b/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java +index 2c4b56da7e..27526e3928 100644 +--- a/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java ++++ b/jdk/src/share/classes/sun/util/resources/TimeZoneNames.java +@@ -634,7 +634,7 @@ public final class TimeZoneNames extends TimeZoneNamesBundle { + {"Asia/Harbin", CTT}, + {"Asia/Hebron", EET}, + {"Asia/Ho_Chi_Minh", ICT}, +- {"Asia/Hong_Kong", HKT}, ++ {"Asia/Hong_Kong", CTT}, + {"Asia/Hovd", new String[] {"Hovd Time", "HOVT", + "Hovd Summer Time", "HOVST", + "Hovd Time", "HOVT"}}, +@@ -864,7 +864,7 @@ public final class TimeZoneNames extends TimeZoneNamesBundle { + {"GB", GMTBST}, + {"GB-Eire", GMTBST}, + {"Greenwich", GMT}, +- {"Hongkong", HKT}, ++ {"Hongkong", CTT}, + {"Iceland", GMT}, + {"Iran", IRT}, + {"IST", IST}, +diff --git a/jdk/src/share/classes/sun/util/resources/de/TimeZoneNames_de.java b/jdk/src/share/classes/sun/util/resources/de/TimeZoneNames_de.java +index e258618c9d..b8e3dde8ea 100644 +--- a/jdk/src/share/classes/sun/util/resources/de/TimeZoneNames_de.java ++++ b/jdk/src/share/classes/sun/util/resources/de/TimeZoneNames_de.java +@@ -635,7 +635,7 @@ public final class TimeZoneNames_de extends TimeZoneNamesBundle { + {"Asia/Harbin", CTT}, + {"Asia/Hebron", EET}, + {"Asia/Ho_Chi_Minh", ICT}, +- {"Asia/Hong_Kong", HKT}, ++ {"Asia/Hong_Kong", CTT}, + {"Asia/Hovd", new String[] {"Hovd Zeit", "HOVT", + "Hovd Sommerzeit", "HOVST", + "Hovd Zeit", "HOVT"}}, +@@ -862,7 +862,7 @@ public final class TimeZoneNames_de extends TimeZoneNamesBundle { + {"GB", GMTBST}, + {"GB-Eire", GMTBST}, + {"Greenwich", GMT}, +- {"Hongkong", HKT}, ++ {"Hongkong", CTT}, + {"Iceland", GMT}, + {"Iran", IRT}, + {"IST", IST}, +diff --git a/jdk/src/share/classes/sun/util/resources/es/TimeZoneNames_es.java b/jdk/src/share/classes/sun/util/resources/es/TimeZoneNames_es.java +index ea8887e139..93b24d893e 100644 +--- a/jdk/src/share/classes/sun/util/resources/es/TimeZoneNames_es.java ++++ b/jdk/src/share/classes/sun/util/resources/es/TimeZoneNames_es.java +@@ -635,7 +635,7 @@ public final class TimeZoneNames_es extends TimeZoneNamesBundle { + {"Asia/Harbin", CTT}, + {"Asia/Hebron", EET}, + {"Asia/Ho_Chi_Minh", ICT}, +- {"Asia/Hong_Kong", HKT}, ++ {"Asia/Hong_Kong", CTT}, + {"Asia/Hovd", new String[] {"Hora de Hovd", "HOVT", + "Hora de verano de Hovd", "HOVST", + "Hora de Hovd", "HOVT"}}, +@@ -862,7 +862,7 @@ public final class TimeZoneNames_es extends TimeZoneNamesBundle { + {"GB", GMTBST}, + {"GB-Eire", GMTBST}, + {"Greenwich", GMT}, +- {"Hongkong", HKT}, ++ {"Hongkong", CTT}, + {"Iceland", GMT}, + {"Iran", IRT}, + {"IST", IST}, +diff --git a/jdk/src/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java b/jdk/src/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java +index 58891022d3..f443a028d1 100644 +--- a/jdk/src/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java ++++ b/jdk/src/share/classes/sun/util/resources/fr/TimeZoneNames_fr.java +@@ -635,7 +635,7 @@ public final class TimeZoneNames_fr extends TimeZoneNamesBundle { + {"Asia/Harbin", CTT}, + {"Asia/Hebron", EET}, + {"Asia/Ho_Chi_Minh", ICT}, +- {"Asia/Hong_Kong", HKT}, ++ {"Asia/Hong_Kong", CTT}, + {"Asia/Hovd", new String[] {"Heure de Hovd", "HOVT", + "Heure d'\u00e9t\u00e9 de Hovd", "HOVST", + "Heure de Hovd", "HOVT"}}, +@@ -862,7 +862,7 @@ public final class TimeZoneNames_fr extends TimeZoneNamesBundle { + {"GB", GMTBST}, + {"GB-Eire", GMTBST}, + {"Greenwich", GMT}, +- {"Hongkong", HKT}, ++ {"Hongkong", CTT}, + {"Iceland", GMT}, + {"Iran", IRT}, + {"IST", IST}, +diff --git a/jdk/src/share/classes/sun/util/resources/it/TimeZoneNames_it.java b/jdk/src/share/classes/sun/util/resources/it/TimeZoneNames_it.java +index 53ab4a6d73..fecfc9474e 100644 +--- a/jdk/src/share/classes/sun/util/resources/it/TimeZoneNames_it.java ++++ b/jdk/src/share/classes/sun/util/resources/it/TimeZoneNames_it.java +@@ -635,7 +635,7 @@ public final class TimeZoneNames_it extends TimeZoneNamesBundle { + {"Asia/Harbin", CTT}, + {"Asia/Hebron", EET}, + {"Asia/Ho_Chi_Minh", ICT}, +- {"Asia/Hong_Kong", HKT}, ++ {"Asia/Hong_Kong", CTT}, + {"Asia/Hovd", new String[] {"Ora di Hovd", "HOVT", + "Ora estiva di Hovd", "HOVST", + "Ora di Hovd", "HOVT"}}, +@@ -862,7 +862,7 @@ public final class TimeZoneNames_it extends TimeZoneNamesBundle { + {"GB", GMTBST}, + {"GB-Eire", GMTBST}, + {"Greenwich", GMT}, +- {"Hongkong", HKT}, ++ {"Hongkong", CTT}, + {"Iceland", GMT}, + {"Iran", IRT}, + {"IST", IST}, +diff --git a/jdk/src/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java b/jdk/src/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java +index 8bec0d7db0..7af8ffc042 100644 +--- a/jdk/src/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java ++++ b/jdk/src/share/classes/sun/util/resources/ja/TimeZoneNames_ja.java +@@ -635,7 +635,7 @@ public final class TimeZoneNames_ja extends TimeZoneNamesBundle { + {"Asia/Harbin", CTT}, + {"Asia/Hebron", EET}, + {"Asia/Ho_Chi_Minh", ICT}, +- {"Asia/Hong_Kong", HKT}, ++ {"Asia/Hong_Kong", CTT}, + {"Asia/Hovd", new String[] {"\u30db\u30d6\u30c9\u6642\u9593", "HOVT", + "\u30db\u30d6\u30c9\u590f\u6642\u9593", "HOVST", + "\u30DB\u30D6\u30C9\u6642\u9593", "HOVT"}}, +@@ -862,7 +862,7 @@ public final class TimeZoneNames_ja extends TimeZoneNamesBundle { + {"GB", GMTBST}, + {"GB-Eire", GMTBST}, + {"Greenwich", GMT}, +- {"Hongkong", HKT}, ++ {"Hongkong", CTT}, + {"Iceland", GMT}, + {"Iran", IRT}, + {"IST", IST}, +diff --git a/jdk/src/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java b/jdk/src/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java +index 7c72073b73..d8b90b4d3e 100644 +--- a/jdk/src/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java ++++ b/jdk/src/share/classes/sun/util/resources/ko/TimeZoneNames_ko.java +@@ -635,7 +635,7 @@ public final class TimeZoneNames_ko extends TimeZoneNamesBundle { + {"Asia/Harbin", CTT}, + {"Asia/Hebron", EET}, + {"Asia/Ho_Chi_Minh", ICT}, +- {"Asia/Hong_Kong", HKT}, ++ {"Asia/Hong_Kong", CTT}, + {"Asia/Hovd", new String[] {"Hovd \uc2dc\uac04", "HOVT", + "Hovd \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "HOVST", + "\uD638\uBE0C\uB4DC \uD45C\uC900\uC2DC", "HOVT"}}, +@@ -862,7 +862,7 @@ public final class TimeZoneNames_ko extends TimeZoneNamesBundle { + {"GB", GMTBST}, + {"GB-Eire", GMTBST}, + {"Greenwich", GMT}, +- {"Hongkong", HKT}, ++ {"Hongkong", CTT}, + {"Iceland", GMT}, + {"Iran", IRT}, + {"IST", IST}, +diff --git a/jdk/src/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java b/jdk/src/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java +index c65dfa5da7..a202fec6b9 100644 +--- a/jdk/src/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java ++++ b/jdk/src/share/classes/sun/util/resources/pt/TimeZoneNames_pt_BR.java +@@ -635,7 +635,7 @@ public final class TimeZoneNames_pt_BR extends TimeZoneNamesBundle { + {"Asia/Harbin", CTT}, + {"Asia/Hebron", EET}, + {"Asia/Ho_Chi_Minh", ICT}, +- {"Asia/Hong_Kong", HKT}, ++ {"Asia/Hong_Kong", CTT}, + {"Asia/Hovd", new String[] {"Fuso hor\u00e1rio de Hovd", "HOVT", + "Fuso hor\u00e1rio de ver\u00e3o de Hovd", "HOVST", + "Hor\u00E1rio de Hovd", "HOVT"}}, +@@ -862,7 +862,7 @@ public final class TimeZoneNames_pt_BR extends TimeZoneNamesBundle { + {"GB", GMTBST}, + {"GB-Eire", GMTBST}, + {"Greenwich", GMT}, +- {"Hongkong", HKT}, ++ {"Hongkong", CTT}, + {"Iceland", GMT}, + {"Iran", IRT}, + {"IST", IST}, +diff --git a/jdk/src/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java b/jdk/src/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java +index 6ce81e8011..dcaaf6ddeb 100644 +--- a/jdk/src/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java ++++ b/jdk/src/share/classes/sun/util/resources/sv/TimeZoneNames_sv.java +@@ -635,7 +635,7 @@ public final class TimeZoneNames_sv extends TimeZoneNamesBundle { + {"Asia/Harbin", CTT}, + {"Asia/Hebron", EET}, + {"Asia/Ho_Chi_Minh", ICT}, +- {"Asia/Hong_Kong", HKT}, ++ {"Asia/Hong_Kong", CTT}, + {"Asia/Hovd", new String[] {"Hovd, normaltid", "HOVT", + "Hovd, sommartid", "HOVST", + "Hovd-tid", "HOVT"}}, +@@ -862,7 +862,7 @@ public final class TimeZoneNames_sv extends TimeZoneNamesBundle { + {"GB", GMTBST}, + {"GB-Eire", GMTBST}, + {"Greenwich", GMT}, +- {"Hongkong", HKT}, ++ {"Hongkong", CTT}, + {"Iceland", GMT}, + {"Iran", IRT}, + {"IST", IST}, +diff --git a/jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java b/jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java +index 3e81b6b42c..9360808ca5 100644 +--- a/jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java ++++ b/jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_CN.java +@@ -635,7 +635,7 @@ public final class TimeZoneNames_zh_CN extends TimeZoneNamesBundle { + {"Asia/Harbin", CTT}, + {"Asia/Hebron", EET}, + {"Asia/Ho_Chi_Minh", ICT}, +- {"Asia/Hong_Kong", HKT}, ++ {"Asia/Hong_Kong", CTT}, + {"Asia/Hovd", new String[] {"\u79d1\u5e03\u591a\u65f6\u95f4", "HOVT", + "\u79d1\u5e03\u591a\u590f\u4ee4\u65f6", "HOVST", + "\u79D1\u5E03\u591A\u65F6\u95F4", "HOVT"}}, +@@ -862,7 +862,7 @@ public final class TimeZoneNames_zh_CN extends TimeZoneNamesBundle { + {"GB", GMTBST}, + {"GB-Eire", GMTBST}, + {"Greenwich", GMT}, +- {"Hongkong", HKT}, ++ {"Hongkong", CTT}, + {"Iceland", GMT}, + {"Iran", IRT}, + {"IST", IST}, +diff --git a/jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java b/jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java +index 0233a53f4f..1bfcee78d5 100644 +--- a/jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java ++++ b/jdk/src/share/classes/sun/util/resources/zh/TimeZoneNames_zh_TW.java +@@ -635,7 +635,7 @@ public final class TimeZoneNames_zh_TW extends TimeZoneNamesBundle { + {"Asia/Harbin", CTT}, + {"Asia/Hebron", EET}, + {"Asia/Ho_Chi_Minh", ICT}, +- {"Asia/Hong_Kong", HKT}, ++ {"Asia/Hong_Kong", CTT}, + {"Asia/Hovd", new String[] {"\u4faf\u5fb7 (Hovd) \u6642\u9593", "HOVT", + "\u4faf\u5fb7 (Hovd) \u590f\u4ee4\u6642\u9593", "HOVST", + "\u4FAF\u5FB7 (Hovd) \u6642\u9593", "HOVT"}}, +@@ -864,7 +864,7 @@ public final class TimeZoneNames_zh_TW extends TimeZoneNamesBundle { + {"GB", GMTBST}, + {"GB-Eire", GMTBST}, + {"Greenwich", GMT}, +- {"Hongkong", HKT}, ++ {"Hongkong", CTT}, + {"Iceland", GMT}, + {"Iran", IRT}, + {"IST", IST}, +-- +2.12.3 +