package init as aarch64-shenandoah-jdk8u232-b09
This commit is contained in:
parent
0651764d9c
commit
1baa42186f
187
8031085.patch
Normal file
187
8031085.patch
Normal file
@ -0,0 +1,187 @@
|
||||
From 727421f7f1abdcc90ac203fa03b279090a208cd7 Mon Sep 17 00:00:00 2001
|
||||
From: hedongbo <hedongbo@huawei.com>
|
||||
Date: Fri, 18 Oct 2019 12:06:46 +0000
|
||||
Subject: [PATCH] backport of JDK-8031085
|
||||
|
||||
Summary: <class DateTimeFormatterBuilder.java>: 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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
|
||||
|
||||
331
8033552-Fix-missing-missing-volatile-specifiers-in-C.patch
Normal file
331
8033552-Fix-missing-missing-volatile-specifiers-in-C.patch
Normal file
@ -0,0 +1,331 @@
|
||||
From cad6af30875f8c5731b76cca494f1f1301e04c96 Mon Sep 17 00:00:00 2001
|
||||
From: zhanggaofeng <zhanggaofeng9@huawei.com>
|
||||
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<mtGC> {
|
||||
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<mtGC> {
|
||||
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<mtGC> {
|
||||
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<mtInternal> {
|
||||
// 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<mtGC> {
|
||||
// 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
|
||||
|
||||
269
8047212.patch
Normal file
269
8047212.patch
Normal file
@ -0,0 +1,269 @@
|
||||
From 752e6b3d3747194e9ebc2a57c06403a3ed6fccc0 Mon Sep 17 00:00:00 2001
|
||||
From: guoxuanda <guoxuanda@huawei.com>
|
||||
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<Symbol*, mtClass> 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<Symbol*, mtClass> 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<Symbol*, mtClass> 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<Symbol*, mtClass> 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
|
||||
|
||||
133
8060463.patch
Normal file
133
8060463.patch
Normal file
@ -0,0 +1,133 @@
|
||||
From e01473adc4c392aa947417cbde478161b2d741bb Mon Sep 17 00:00:00 2001
|
||||
From: wangyadong <wangyadong4@huawei.com>
|
||||
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<size_t>(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
|
||||
|
||||
107
8129626.patch
Normal file
107
8129626.patch
Normal file
@ -0,0 +1,107 @@
|
||||
From 570f33e3f57acb9a8b4b7e3c378b836bef774df4 Mon Sep 17 00:00:00 2001
|
||||
From: hexuejin <hexuejin2@huawei.com>
|
||||
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
|
||||
|
||||
46
8131600.patch
Normal file
46
8131600.patch
Normal file
@ -0,0 +1,46 @@
|
||||
From a0788fc8804ec901f1011a7a7a3264098a717223 Mon Sep 17 00:00:00 2001
|
||||
From: songyaofei <songyaofei2@huawei.com>
|
||||
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
|
||||
|
||||
189
8134883.patch
Normal file
189
8134883.patch
Normal file
@ -0,0 +1,189 @@
|
||||
From d58ebe4882c0dfcb2f185e948c5c838f2d867e6b Mon Sep 17 00:00:00 2001
|
||||
From: songyaofei <songyaofei2@huawei.com>
|
||||
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 "<init>":"()V"
|
||||
+ stack 1 locals 1
|
||||
+{
|
||||
+ aload_0;
|
||||
+ invokespecial Method java/lang/Object."<init>":"()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
|
||||
|
||||
33
8135318.patch
Normal file
33
8135318.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From ab0474ea0dae399dcd256aa520089450a3363f33 Mon Sep 17 00:00:00 2001
|
||||
From: zhangli <zhanggaofeng9@huawei.com>
|
||||
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
|
||||
|
||||
27
8138971.patch
Normal file
27
8138971.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From ffb7c326ceb85f9bab196a23d3c2adb4a27613ce Mon Sep 17 00:00:00 2001
|
||||
From: hexuejin <hexuejin2@huawei.com>
|
||||
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
|
||||
|
||||
46
8141356.patch
Normal file
46
8141356.patch
Normal file
@ -0,0 +1,46 @@
|
||||
From 81c4aa5c13e38b701a0ace0765ab153b750a1e7e Mon Sep 17 00:00:00 2001
|
||||
From: mashoubing <mashoubing1@huawei.com>
|
||||
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
|
||||
|
||||
52
8146792.patch
Normal file
52
8146792.patch
Normal file
@ -0,0 +1,52 @@
|
||||
From 81b3011925783d6eb1effec9b858e1d0e162d378 Mon Sep 17 00:00:00 2001
|
||||
From: guoxuanda <guoxuanda@huawei.com>
|
||||
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
|
||||
|
||||
180
8148754-C2-loop-unrolling-fails-due-to-unexpected-gr.patch
Normal file
180
8148754-C2-loop-unrolling-fails-due-to-unexpected-gr.patch
Normal file
@ -0,0 +1,180 @@
|
||||
From be0206e834bab370da41cf9ec9e6b9be710e1987 Mon Sep 17 00:00:00 2001
|
||||
From: guoge <guoge1@huawei.com>
|
||||
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
|
||||
|
||||
94
8151788.patch
Normal file
94
8151788.patch
Normal file
@ -0,0 +1,94 @@
|
||||
From bf24abe7a9499638a43dfd03fecfbfb763430a63 Mon Sep 17 00:00:00 2001
|
||||
From: hexuejin <hexuejin2@huawei.com>
|
||||
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
|
||||
|
||||
68
8154313.patch
Normal file
68
8154313.patch
Normal file
@ -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)
|
||||
70
8157570.patch
Normal file
70
8157570.patch
Normal file
@ -0,0 +1,70 @@
|
||||
From 58fcf0eb2ce3e74334ef124116a6e8f429ee9ae4 Mon Sep 17 00:00:00 2001
|
||||
From: hexuejin <hexuejin2@huawei.com>
|
||||
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<Void> pa = new PrivilegedAction<Void>() {
|
||||
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
|
||||
|
||||
436
8158946-JDK-8165808-JDK-8166583-JDK-.patch
Normal file
436
8158946-JDK-8165808-JDK-8166583-JDK-.patch
Normal file
@ -0,0 +1,436 @@
|
||||
From 213dd3425bd0681a0ad4ed3c5f004898be645d86 Mon Sep 17 00:00:00 2001
|
||||
From: wangshuai <wangshuai94@huawei.com>
|
||||
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<mtInternal> {
|
||||
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<mtInternal> {
|
||||
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<volatile narrowKlass*>(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
|
||||
|
||||
327
8160300.patch
Normal file
327
8160300.patch
Normal file
@ -0,0 +1,327 @@
|
||||
From 51f5988d94ab3488080c4b9350b9d37b2ea19140 Mon Sep 17 00:00:00 2001
|
||||
From: guoge <guoge1@huawei.com>
|
||||
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 <stdio.h>
|
||||
+#include <errno.h>
|
||||
+#include <unistd.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <sys/stat.h>
|
||||
+
|
||||
+/**
|
||||
+ * 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<Void>() {");
|
||||
+ 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 <stdio.h>
|
||||
+#include <errno.h>
|
||||
+#include <unistd.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <sys/stat.h>
|
||||
+#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
|
||||
|
||||
549
8160369.patch
Normal file
549
8160369.patch
Normal file
@ -0,0 +1,549 @@
|
||||
From 822f93a00af8300b0516707c2fded59c7487b3ea Mon Sep 17 00:00:00 2001
|
||||
From: wangshuai <wangshuai94@huawei.com>
|
||||
Date: Mon, 14 Oct 2019 16:34:52 +0000
|
||||
Subject: [PATCH] Backport of JDK-8160369
|
||||
|
||||
Summary:<GC>:[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<volatile jbyte*>(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
|
||||
|
||||
58
8161072.patch
Normal file
58
8161072.patch
Normal file
@ -0,0 +1,58 @@
|
||||
From e42367ab7ce5d66823ef32ea00dbc5e44e3b20d1 Mon Sep 17 00:00:00 2001
|
||||
From: jitao <jitao8@huawei.com>
|
||||
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
|
||||
|
||||
41
8164948.patch
Normal file
41
8164948.patch
Normal file
@ -0,0 +1,41 @@
|
||||
From d0c532d9b3e657fea7ce93602553c9d74aab85a6 Mon Sep 17 00:00:00 2001
|
||||
From: mashoubing <mashoubing1@huawei.com>
|
||||
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
|
||||
|
||||
43
8165857-CMS-_overflow_list-is-missing-volatile-speci.patch
Normal file
43
8165857-CMS-_overflow_list-is-missing-volatile-speci.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From 19da764152e382f53c5c0f7069f52d993c649818 Mon Sep 17 00:00:00 2001
|
||||
From: hedongbo <hedongbo@huawei.com>
|
||||
Date: Mon, 11 Nov 2019 16:59:01 +0000
|
||||
Subject: [PATCH] 8165857: CMS _overflow_list is missing volatile specifiers.
|
||||
|
||||
Summary: <gc>: [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<mtGC> {
|
||||
|
||||
// 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
|
||||
|
||||
87
8165860-WorkGroup-classes-are-missing-volatile-speci.patch
Normal file
87
8165860-WorkGroup-classes-are-missing-volatile-speci.patch
Normal file
@ -0,0 +1,87 @@
|
||||
From 92585164635278b4b127f426bf50014d0a03b572 Mon Sep 17 00:00:00 2001
|
||||
From: songyaofei <songyaofei2@huawei.com>
|
||||
Date: Thu, 14 Nov 2019 15:23:46 +0000
|
||||
Subject: [PATCH] 8165860: WorkGroup classes are missing volatile specifiers
|
||||
for lock-free code
|
||||
|
||||
Summary: <gc>: 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<mtInternal> {
|
||||
- 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<mtInternal> {
|
||||
// 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
|
||||
|
||||
119
8166197.patch
Normal file
119
8166197.patch
Normal file
@ -0,0 +1,119 @@
|
||||
From ece7241c82e94a5ec19e7a83754db10a646ddb11 Mon Sep 17 00:00:00 2001
|
||||
From: wangyadong <wangyadong4@huawei.com>
|
||||
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
|
||||
|
||||
234
8166253.patch
Normal file
234
8166253.patch
Normal file
@ -0,0 +1,234 @@
|
||||
From 0350ff861595f4d3b8d903533def704ac319dd45 Mon Sep 17 00:00:00 2001
|
||||
From: hexuejin <hexuejin2@huawei.com>
|
||||
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<FileLock> locks;
|
||||
+
|
||||
SharedFileLockTable(Channel channel, FileDescriptor fd) throws IOException {
|
||||
this.channel = channel;
|
||||
this.fileKey = FileKey.create(fd);
|
||||
+ this.locks = new HashSet<FileLock>();
|
||||
}
|
||||
|
||||
@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<FileLock> 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
|
||||
|
||||
121
8167409-Invalid-value-passed-to-critical-JNI-function.patch
Normal file
121
8167409-Invalid-value-passed-to-critical-JNI-function.patch
Normal file
@ -0,0 +1,121 @@
|
||||
From de7d96bd84ba81580e36f556587496e497ec1daf Mon Sep 17 00:00:00 2001
|
||||
From: hexuejin <hexuejin2@huawei.com>
|
||||
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
|
||||
|
||||
27
8171537.patch
Normal file
27
8171537.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From 26c54187c40901643d0cf65a985c98ddcee40bf0 Mon Sep 17 00:00:00 2001
|
||||
From: guoge <guoge1@huawei.com>
|
||||
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
|
||||
|
||||
29
8182036.patch
Normal file
29
8182036.patch
Normal file
@ -0,0 +1,29 @@
|
||||
From 27de742e21eda38d2aff89d07364ec8f961f8e34 Mon Sep 17 00:00:00 2001
|
||||
From: hexuejin <hexuejin2@huawei.com>
|
||||
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
|
||||
|
||||
242
8182397-race-in-field-updates.patch
Normal file
242
8182397-race-in-field-updates.patch
Normal file
@ -0,0 +1,242 @@
|
||||
From bd619b88d5e074d960b34ece8f60b4e5147c4a47 Mon Sep 17 00:00:00 2001
|
||||
From: zhuliying <zhuliying1@huawei.com>
|
||||
Date: Fri, 8 Nov 2019 17:42:55 +0000
|
||||
Subject: [PATCH] 8182397: race in field updates
|
||||
|
||||
Summary: <ArrayKlasses>: 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
|
||||
|
||||
412
8186042-OopmapCache-implementation.patch
Normal file
412
8186042-OopmapCache-implementation.patch
Normal file
@ -0,0 +1,412 @@
|
||||
From c673dc6b67a6f44bafb279b02c0f8616704636ea Mon Sep 17 00:00:00 2001
|
||||
From: zhanggaofeng <zhanggaofeng9@huawei.com>
|
||||
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<mtClass> {
|
||||
+ 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<mtClass> {
|
||||
|
||||
// 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
|
||||
|
||||
116
8191129.patch
Normal file
116
8191129.patch
Normal file
@ -0,0 +1,116 @@
|
||||
From aee65626b97f366705d47c2d02df34aca5c64251 Mon Sep 17 00:00:00 2001
|
||||
From: hexuejin <hexuejin2@huawei.com>
|
||||
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<int> 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
|
||||
|
||||
144
8191483.patch
Normal file
144
8191483.patch
Normal file
@ -0,0 +1,144 @@
|
||||
From 8ae431d4207547ccd5a1d74c3a074c6b79097adb Mon Sep 17 00:00:00 2001
|
||||
From: hexuejin <hexuejin2@huawei.com>
|
||||
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.
|
||||
*
|
||||
- * <p>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.
|
||||
*
|
||||
- * <p>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
|
||||
|
||||
37
8191955.patch
Normal file
37
8191955.patch
Normal file
@ -0,0 +1,37 @@
|
||||
From 70641d56fb22355a85ad142700ae721a6a293908 Mon Sep 17 00:00:00 2001
|
||||
From: hexuejin <hexuejin2@huawei.com>
|
||||
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
|
||||
|
||||
158
8194154-System-property-user.dir-should-not-be-chang.patch
Normal file
158
8194154-System-property-user.dir-should-not-be-chang.patch
Normal file
@ -0,0 +1,158 @@
|
||||
From 8ca41b47ee0af3868fcfe745ddedd89cd342a25a Mon Sep 17 00:00:00 2001
|
||||
From: muyongmei <muyongmei@huawei.com>
|
||||
Date: Tue, 12 Nov 2019 15:31:59 +0000
|
||||
Subject: [PATCH] 8194154: System property user.dir should not be changed
|
||||
|
||||
Summary: <io>: 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
|
||||
|
||||
57
8194246.patch
Normal file
57
8194246.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From 86d65f4258c2c47751ae42281e84b6ba36712a08 Mon Sep 17 00:00:00 2001
|
||||
From: hexuejin <hexuejin2@huawei.com>
|
||||
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
|
||||
|
||||
72
8202076.patch
Normal file
72
8202076.patch
Normal file
@ -0,0 +1,72 @@
|
||||
From 480c546fa5d07a92d09fbe669a7a36e718baedca Mon Sep 17 00:00:00 2001
|
||||
From: xuwei <xuwei43@huawei.com>
|
||||
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 <direct.h>
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
+#include <limits.h>
|
||||
+#include <wchar.h>
|
||||
|
||||
#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
|
||||
|
||||
26
8202952-C2-Unexpected-dead-nodes-after-matching.patch
Normal file
26
8202952-C2-Unexpected-dead-nodes-after-matching.patch
Normal file
@ -0,0 +1,26 @@
|
||||
From 11a00ac42593c9338b9ec8779dd8c142d1492907 Mon Sep 17 00:00:00 2001
|
||||
From: wangkun <wangkun49@huawei.com>
|
||||
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
|
||||
|
||||
214
8203699-java-lang-invoke-SpecialInte.patch
Normal file
214
8203699-java-lang-invoke-SpecialInte.patch
Normal file
@ -0,0 +1,214 @@
|
||||
From f9f94ca5422ae79bf4ed90f41b7698febc6bed24 Mon Sep 17 00:00:00 2001
|
||||
From: zhangli <zhangli152@huawei.com>
|
||||
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 <b>SPECIAL</b> MethodHandle for the method "test()V" in the <b>DIRECT</b> super interface DefenderInterface. The method
|
||||
+ * has a default implementation in DefenderInterface and does <b>NOT</b> 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<? extends DefenderInterface> defc = this.getClass();
|
||||
+ Class<DefenderInterface> 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 <b>testDirectSuperInterface</b>, but with the findSpecial arguments <b>target</b> and <b>defc</b> 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<? extends DefenderInterface> defc = this.getClass();
|
||||
+ Class<DefenderInterface> 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 <b>SPECIAL</b> MethodHandle for the method "test()V" in the <b>DIRECT</b> super interface DefenderInterface. The method
|
||||
+ * has a default implementation in DefenderInterface and does <b>ALSO</b> 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<? extends DefenderInterface> defc = DefenderInterface.class;
|
||||
+ Class<DefenderInterface> 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 <b>testDirectSuperInterfaceWithOverride</b>, but with the findSpecial arguments <b>target</b> and <b>defc</b> 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<? extends DefenderInterface> defc = this.getClass();
|
||||
+ Class<DefenderInterface> 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);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * <b>NEGATIVE</b><br />
|
||||
+ * Try to get a <b>SPECIAL</b> MethodHandle for the method "test()V" in the <b>INDIRECT</b> super interface DefenderInterface
|
||||
+ * (through the interface <b>DefenderSubInterface</b>).
|
||||
+ *
|
||||
+ * @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<? extends DefenderInterface> defc = this.getClass();
|
||||
+ Class<DefenderInterface> 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
|
||||
|
||||
71
8214345.patch
Normal file
71
8214345.patch
Normal file
@ -0,0 +1,71 @@
|
||||
From a3a0d29610bef14392cf20a8d5807ab288320056 Mon Sep 17 00:00:00 2001
|
||||
From: hexuejin <hexuejin2@huawei.com>
|
||||
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<Type> 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<Type> 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<E extends InfiniteLoop1<E>> extends E {}
|
||||
+ abstract class InfiniteLoop2<E extends InfiniteLoop2<E>> 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
|
||||
|
||||
36
8221658.patch
Normal file
36
8221658.patch
Normal file
@ -0,0 +1,36 @@
|
||||
From a0559370c5b6ca2a080b673da7198ae366aa34bd Mon Sep 17 00:00:00 2001
|
||||
From: jitao <jitao8@huawei.com>
|
||||
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
|
||||
|
||||
32
8229169.patch
Normal file
32
8229169.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From b5af97426c82ead4df42f3824a32e9ee634585a4 Mon Sep 17 00:00:00 2001
|
||||
From: wuyan <wuyan34@huawei.com>
|
||||
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<E, F, N>::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
|
||||
|
||||
376
8231584-Deadlock-with-ClassLoader.findLibrary-and-Sy.patch
Normal file
376
8231584-Deadlock-with-ClassLoader.findLibrary-and-Sy.patch
Normal file
@ -0,0 +1,376 @@
|
||||
From 219a986b26fe9813730939038b3b1d70255d19a6 Mon Sep 17 00:00:00 2001
|
||||
From: wangshuai <wangshuai94@huawei.com>
|
||||
Date: Mon, 11 Nov 2019 19:42:17 +0000
|
||||
Subject: [PATCH] 8231584:Deadlock with ClassLoader.findLibrary and
|
||||
System.loadLibrary call
|
||||
|
||||
Summary:<java.lang>: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
|
||||
|
||||
32
8231988.patch
Normal file
32
8231988.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From d73c61c26fd00e3cb8daa24fa254b756c48309ca Mon Sep 17 00:00:00 2001
|
||||
From: wanghuang <wanghuang3@huawei.com>
|
||||
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
|
||||
|
||||
37
8233839-aarch64-missing-memory-barrier-in-NewObjectA.patch
Normal file
37
8233839-aarch64-missing-memory-barrier-in-NewObjectA.patch
Normal file
@ -0,0 +1,37 @@
|
||||
From 485dd83220fa3f41b979d5f6bc3fe5866f673ca7 Mon Sep 17 00:00:00 2001
|
||||
From: zhanggaofeng <zhanggaofeng9@huawei.com>
|
||||
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
|
||||
|
||||
38
8234264-Incorrrect-8047434-JDK-8-backport-in-8219677.patch
Normal file
38
8234264-Incorrrect-8047434-JDK-8-backport-in-8219677.patch
Normal file
@ -0,0 +1,38 @@
|
||||
From 8af05a28e8856fb9a05e87e9199b1c9c21ab1c17 Mon Sep 17 00:00:00 2001
|
||||
From: zhanggaofeng <zhanggaofeng9@huawei.com>
|
||||
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
|
||||
|
||||
44
AARCH64-fix-itable-stub-code-size-limit.patch
Normal file
44
AARCH64-fix-itable-stub-code-size-limit.patch
Normal file
@ -0,0 +1,44 @@
|
||||
From 8e390a2cdfff1138f3ba6e694395cd8790aa1603 Mon Sep 17 00:00:00 2001
|
||||
From: guoge <guoge1@huawei.com>
|
||||
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
|
||||
|
||||
278
FromCardCache-default-card-index-can-cause.patch
Normal file
278
FromCardCache-default-card-index-can-cause.patch
Normal file
@ -0,0 +1,278 @@
|
||||
From 3cdfc055dbaae92f295ac0c3ae52d33e1650e8c1 Mon Sep 17 00:00:00 2001
|
||||
From: hexuejin <hexuejin2@huawei.com>
|
||||
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<int, mtGC>::create_unfreeable(n_par_rs,
|
||||
- _max_regions,
|
||||
- &_static_mem_size);
|
||||
-
|
||||
+ _cache = Padded2DArray<uintptr_t, mtGC>::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
|
||||
|
||||
36
README.en.md
36
README.en.md
@ -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/)
|
||||
38
README.md
38
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)
|
||||
|
||||
65
Reduce-the-probability-of-the-crash-related-to-ciObj.patch
Normal file
65
Reduce-the-probability-of-the-crash-related-to-ciObj.patch
Normal file
@ -0,0 +1,65 @@
|
||||
From 29e183488a96a4c169f89eab9410e0a91a903476 Mon Sep 17 00:00:00 2001
|
||||
From: songyaofei <songyaofei2@huawei.com>
|
||||
Date: Tue, 22 Oct 2019 19:18:39 +0000
|
||||
Subject: [PATCH] Reduce the probability of the crash related to
|
||||
ciObjectFactory::create_new_metadata
|
||||
|
||||
Summary: <interpreter>: 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
|
||||
|
||||
72
TestCryptoLevel.java
Normal file
72
TestCryptoLevel.java
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
49
TestECDSA.java
Normal file
49
TestECDSA.java
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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.");
|
||||
}
|
||||
}
|
||||
28
X500Name-implemation-change-to-avoid-OOM.patch
Normal file
28
X500Name-implemation-change-to-avoid-OOM.patch
Normal file
@ -0,0 +1,28 @@
|
||||
From 6b96a97e8e04d62f4ab4b03c05682765516c0872 Mon Sep 17 00:00:00 2001
|
||||
From: zhanggaofeng <zhanggaofeng9@huawei.com>
|
||||
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
|
||||
|
||||
BIN
aarch64-shenandoah-jdk8u232-b09.tar.xz
Normal file
BIN
aarch64-shenandoah-jdk8u232-b09.tar.xz
Normal file
Binary file not shown.
28
add-debuginfo-for-libsaproc-on-aarch64.patch
Normal file
28
add-debuginfo-for-libsaproc-on-aarch64.patch
Normal file
@ -0,0 +1,28 @@
|
||||
From b26a2445044d5ba0a3ed0d45ef66108231fcec0f Mon Sep 17 00:00:00 2001
|
||||
From: songyaofei <songyaofei2@huawei.com>
|
||||
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
|
||||
|
||||
148
add-with-company-name-option.patch
Normal file
148
add-with-company-name-option.patch
Normal file
@ -0,0 +1,148 @@
|
||||
From 2f9cb1a32393b6bb2607133836d16c1da73ec497 Mon Sep 17 00:00:00 2001
|
||||
From: = <fengshijie2@huawei.com>
|
||||
Date: Tue, 3 Sep 2019 09:52:13 +0000
|
||||
Subject: [PATCH] Add with-company-name option
|
||||
|
||||
Summary: <openjdk_dev>: <Add with-company-name option to support customize the output of java -version>
|
||||
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
|
||||
|
||||
608
delete-read-write-barriers-in-ShenandoahGC.patch
Normal file
608
delete-read-write-barriers-in-ShenandoahGC.patch
Normal file
@ -0,0 +1,608 @@
|
||||
From 455904c69b9f3e7590559d7f3367bc4518fea74d Mon Sep 17 00:00:00 2001
|
||||
From: guoge <guoge1@huawei.com>
|
||||
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<narrowOop>(offset)) :
|
||||
- load_decode_heap_oop(p->obj_field_addr<oop>(offset));
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->read_barrier((oop) this);
|
||||
+ return UseCompressedOops ?
|
||||
+ load_decode_heap_oop(p->obj_field_addr<narrowOop>(offset)) :
|
||||
+ load_decode_heap_oop(p->obj_field_addr<oop>(offset));
|
||||
+ } else {
|
||||
+ return UseCompressedOops ?
|
||||
+ load_decode_heap_oop(obj_field_addr<narrowOop>(offset)) :
|
||||
+ load_decode_heap_oop(obj_field_addr<oop>(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<narrowOop>(offset), value) :
|
||||
- oop_store(p->obj_field_addr<oop>(offset), value);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ value = bs()->read_barrier(value);
|
||||
+ UseCompressedOops ? oop_store(p->obj_field_addr<narrowOop>(offset), value) :
|
||||
+ oop_store(p->obj_field_addr<oop>(offset), value);
|
||||
+ } else {
|
||||
+ UseCompressedOops ? oop_store(obj_field_addr<narrowOop>(offset), value) :
|
||||
+ oop_store(obj_field_addr<oop>(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<narrowOop>(offset), value) :
|
||||
- encode_store_heap_oop(p->obj_field_addr<oop>(offset), value);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ value = bs()->read_barrier(value);
|
||||
+ UseCompressedOops ?
|
||||
+ encode_store_heap_oop(p->obj_field_addr<narrowOop>(offset), value) :
|
||||
+ encode_store_heap_oop(p->obj_field_addr<oop>(offset), value);
|
||||
+ } else {
|
||||
+ UseCompressedOops ?
|
||||
+ encode_store_heap_oop(obj_field_addr<narrowOop>(offset), value) :
|
||||
+ encode_store_heap_oop(obj_field_addr<oop>(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<narrowOop>(offset)))
|
||||
- : decode_heap_oop((oop)
|
||||
- OrderAccess::load_ptr_acquire(p->obj_field_addr<oop>(offset)));
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->read_barrier((oop) this);
|
||||
+ return UseCompressedOops ?
|
||||
+ decode_heap_oop((narrowOop)
|
||||
+ OrderAccess::load_acquire(p->obj_field_addr<narrowOop>(offset)))
|
||||
+ : decode_heap_oop((oop)
|
||||
+ OrderAccess::load_ptr_acquire(p->obj_field_addr<oop>(offset)));
|
||||
+ } else {
|
||||
+ return UseCompressedOops ?
|
||||
+ decode_heap_oop((narrowOop)
|
||||
+ OrderAccess::load_acquire(obj_field_addr<narrowOop>(offset)))
|
||||
+ : decode_heap_oop((oop)
|
||||
+ OrderAccess::load_ptr_acquire(obj_field_addr<oop>(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<narrowOop>(offset), value) :
|
||||
- oop_store((volatile oop*) p->obj_field_addr<oop>(offset), value);
|
||||
+ if (UseShenandoahGC) {
|
||||
+ oop p = bs()->write_barrier(this);
|
||||
+ value = bs()->read_barrier(value);
|
||||
+ UseCompressedOops ?
|
||||
+ oop_store((volatile narrowOop*)p->obj_field_addr<narrowOop>(offset), value) :
|
||||
+ oop_store((volatile oop*) p->obj_field_addr<oop>(offset), value);
|
||||
+ } else {
|
||||
+ UseCompressedOops ?
|
||||
+ oop_store((volatile narrowOop*)obj_field_addr<narrowOop>(offset), value) :
|
||||
+ oop_store((volatile oop*) obj_field_addr<oop>(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
|
||||
|
||||
48
disable-UseLSE-on-ARMv8.1-by-default.patch
Normal file
48
disable-UseLSE-on-ARMv8.1-by-default.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From 1161177ce24da0348b5f6c6358667dc4a93f544b Mon Sep 17 00:00:00 2001
|
||||
From: guoge <guoge1@huawei.com>
|
||||
Date: Thu, 17 Oct 2019 14:49:51 +0000
|
||||
Subject: [PATCH] disable UseLSE on ARMv8.1 by default
|
||||
|
||||
Summary: <UseLSE>: 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
|
||||
|
||||
52
fix-vendor-info.patch
Normal file
52
fix-vendor-info.patch
Normal file
@ -0,0 +1,52 @@
|
||||
From f2833457ae8419c099bf167693c602911413257c Mon Sep 17 00:00:00 2001
|
||||
From: sunjianye <sunjianye@huawei.com>
|
||||
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
|
||||
|
||||
1686
java-1.8.0-openjdk.spec
Normal file
1686
java-1.8.0-openjdk.spec
Normal file
File diff suppressed because it is too large
Load Diff
450
replace-vector-to-improve-performance-of-xml.validat.patch
Normal file
450
replace-vector-to-improve-performance-of-xml.validat.patch
Normal file
@ -0,0 +1,450 @@
|
||||
From 6ee202c81902416a9ec5ec5a32c536d3294bd5e6 Mon Sep 17 00:00:00 2001
|
||||
From: guoge <guoge1@huawei.com>
|
||||
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<RegularExpression> fPattern;
|
||||
+ private List<String> 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<String> enumVals = facets.enumeration;
|
||||
+ int size = enumVals.size();
|
||||
+ fEnumeration = new ValidatedInfo[size];
|
||||
+ List<NamespaceContext> 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<Op> 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<Op> 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
|
||||
|
||||
268
set_HongKong_timezone_to_CTT.patch
Normal file
268
set_HongKong_timezone_to_CTT.patch
Normal file
@ -0,0 +1,268 @@
|
||||
From 09d4f8a17aff883e7937c048a2da6bcf3feb7894 Mon Sep 17 00:00:00 2001
|
||||
From: wangshuai <wangshuai94@huawei.com>
|
||||
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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user