From 70f22c649b8320c72788b01359033b49de933320 Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Fri, 31 May 2013 14:32:44 +0200 Subject: [PATCH 001/102] 8022880: False sharing between PSPromotionManager instances Pad the PSPromotionManager instances in the manager array. Reviewed-by: brutisso, jmasa --- .../concurrentMarkSweepGeneration.cpp | 1 + .../parNew/parNewGeneration.hpp | 3 +- .../parNew/parOopClosures.hpp | 3 +- .../parallelScavenge/psPromotionManager.cpp | 25 +++-- .../parallelScavenge/psPromotionManager.hpp | 12 ++- .../psPromotionManager.inline.hpp | 2 +- hotspot/src/share/vm/memory/padded.hpp | 93 +++++++++++++++++++ hotspot/src/share/vm/memory/padded.inline.hpp | 49 ++++++++++ hotspot/src/share/vm/utilities/debug.hpp | 16 ++++ .../share/vm/utilities/globalDefinitions.hpp | 32 ++----- 10 files changed, 189 insertions(+), 47 deletions(-) create mode 100644 hotspot/src/share/vm/memory/padded.hpp create mode 100644 hotspot/src/share/vm/memory/padded.inline.hpp diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp index c04a5261338..54ade2db111 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -50,6 +50,7 @@ #include "memory/genMarkSweep.hpp" #include "memory/genOopClosures.inline.hpp" #include "memory/iterator.hpp" +#include "memory/padded.hpp" #include "memory/referencePolicy.hpp" #include "memory/resourceArea.hpp" #include "memory/tenuredGeneration.hpp" diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp index 987767b1640..6d3b25d9545 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ #include "gc_implementation/shared/parGCAllocBuffer.hpp" #include "gc_implementation/shared/copyFailedInfo.hpp" #include "memory/defNewGeneration.hpp" +#include "memory/padded.hpp" #include "utilities/taskqueue.hpp" class ChunkArray; diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.hpp b/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.hpp index 0d9d7761c74..00b865f2a35 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.hpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2013, 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 @@ -26,6 +26,7 @@ #define SHARE_VM_GC_IMPLEMENTATION_PARNEW_PAROOPCLOSURES_HPP #include "memory/genOopClosures.hpp" +#include "memory/padded.hpp" // Closures for ParNewGeneration diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp index 32929e7a55c..dd3933b0009 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp @@ -29,14 +29,16 @@ #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" #include "gc_implementation/shared/gcTrace.hpp" #include "gc_implementation/shared/mutableSpace.hpp" +#include "memory/allocation.inline.hpp" #include "memory/memRegion.hpp" +#include "memory/padded.inline.hpp" #include "oops/oop.inline.hpp" #include "oops/oop.psgc.inline.hpp" -PSPromotionManager** PSPromotionManager::_manager_array = NULL; -OopStarTaskQueueSet* PSPromotionManager::_stack_array_depth = NULL; -PSOldGen* PSPromotionManager::_old_gen = NULL; -MutableSpace* PSPromotionManager::_young_space = NULL; +PaddedEnd* PSPromotionManager::_manager_array = NULL; +OopStarTaskQueueSet* PSPromotionManager::_stack_array_depth = NULL; +PSOldGen* PSPromotionManager::_old_gen = NULL; +MutableSpace* PSPromotionManager::_young_space = NULL; void PSPromotionManager::initialize() { ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); @@ -45,8 +47,10 @@ void PSPromotionManager::initialize() { _old_gen = heap->old_gen(); _young_space = heap->young_gen()->to_space(); + // To prevent false sharing, we pad the PSPromotionManagers + // and make sure that the first instance starts at a cache line. assert(_manager_array == NULL, "Attempt to initialize twice"); - _manager_array = NEW_C_HEAP_ARRAY(PSPromotionManager*, ParallelGCThreads+1, mtGC); + _manager_array = PaddedArray::create_unfreeable(ParallelGCThreads + 1); guarantee(_manager_array != NULL, "Could not initialize promotion manager"); _stack_array_depth = new OopStarTaskQueueSet(ParallelGCThreads); @@ -54,26 +58,21 @@ void PSPromotionManager::initialize() { // Create and register the PSPromotionManager(s) for the worker threads. for(uint i=0; iregister_queue(i, _manager_array[i]->claimed_stack_depth()); + stack_array_depth()->register_queue(i, _manager_array[i].claimed_stack_depth()); } - // The VMThread gets its own PSPromotionManager, which is not available // for work stealing. - _manager_array[ParallelGCThreads] = new PSPromotionManager(); - guarantee(_manager_array[ParallelGCThreads] != NULL, "Could not create PSPromotionManager"); } PSPromotionManager* PSPromotionManager::gc_thread_promotion_manager(int index) { assert(index >= 0 && index < (int)ParallelGCThreads, "index out of range"); assert(_manager_array != NULL, "Sanity"); - return _manager_array[index]; + return &_manager_array[index]; } PSPromotionManager* PSPromotionManager::vm_thread_promotion_manager() { assert(_manager_array != NULL, "Sanity"); - return _manager_array[ParallelGCThreads]; + return &_manager_array[ParallelGCThreads]; } void PSPromotionManager::pre_scavenge() { diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp index 8f4731428ac..6707ade2d17 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp @@ -29,6 +29,8 @@ #include "gc_implementation/shared/gcTrace.hpp" #include "gc_implementation/shared/copyFailedInfo.hpp" #include "memory/allocation.hpp" +#include "memory/padded.hpp" +#include "utilities/globalDefinitions.hpp" #include "utilities/taskqueue.hpp" // @@ -51,14 +53,14 @@ class MutableSpace; class PSOldGen; class ParCompactionManager; -class PSPromotionManager : public CHeapObj { +class PSPromotionManager VALUE_OBJ_CLASS_SPEC { friend class PSScavenge; friend class PSRefProcTaskExecutor; private: - static PSPromotionManager** _manager_array; - static OopStarTaskQueueSet* _stack_array_depth; - static PSOldGen* _old_gen; - static MutableSpace* _young_space; + static PaddedEnd* _manager_array; + static OopStarTaskQueueSet* _stack_array_depth; + static PSOldGen* _old_gen; + static MutableSpace* _young_space; #if TASKQUEUE_STATS size_t _masked_pushes; diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp index 841ef64f20b..34c935408d8 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp @@ -32,7 +32,7 @@ inline PSPromotionManager* PSPromotionManager::manager_array(int index) { assert(_manager_array != NULL, "access of NULL manager_array"); assert(index >= 0 && index <= (int)ParallelGCThreads, "out of range manager_array access"); - return _manager_array[index]; + return &_manager_array[index]; } template diff --git a/hotspot/src/share/vm/memory/padded.hpp b/hotspot/src/share/vm/memory/padded.hpp new file mode 100644 index 00000000000..4c50b39963e --- /dev/null +++ b/hotspot/src/share/vm/memory/padded.hpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_MEMORY_PADDED_HPP +#define SHARE_VM_MEMORY_PADDED_HPP + +#include "memory/allocation.hpp" +#include "utilities/globalDefinitions.hpp" + +// Bytes needed to pad type to avoid cache-line sharing; alignment should be the +// expected cache line size (a power of two). The first addend avoids sharing +// when the start address is not a multiple of alignment; the second maintains +// alignment of starting addresses that happen to be a multiple. +#define PADDING_SIZE(type, alignment) \ + ((alignment) + align_size_up_(sizeof(type), alignment)) + +// Templates to create a subclass padded to avoid cache line sharing. These are +// effective only when applied to derived-most (leaf) classes. + +// When no args are passed to the base ctor. +template +class Padded : public T { + private: + char _pad_buf_[PADDING_SIZE(T, alignment)]; +}; + +// When either 0 or 1 args may be passed to the base ctor. +template +class Padded01 : public T { + public: + Padded01(): T() { } + Padded01(Arg1T arg1): T(arg1) { } + private: + char _pad_buf_[PADDING_SIZE(T, alignment)]; +}; + +// Super class of PaddedEnd when pad_size != 0. +template +class PaddedEndImpl : public T { + private: + char _pad_buf[pad_size]; +}; + +// Super class of PaddedEnd when pad_size == 0. +template +class PaddedEndImpl : public T { + // No padding. +}; + +#define PADDED_END_SIZE(type, alignment) (align_size_up_(sizeof(type), alignment) - sizeof(type)) + +// More memory conservative implementation of Padded. The subclass adds the +// minimal amount of padding needed to make the size of the objects be aligned. +// This will help reducing false sharing, +// if the start address is a multiple of alignment. +template +class PaddedEnd : public PaddedEndImpl { + // C++ don't allow zero-length arrays. The padding is put in a + // super class that is specialized for the pad_size == 0 case. +}; + +// Helper class to create an array of PaddedEnd objects. All elements will +// start at a multiple of alignment and the size will be aligned to alignment. +template +class PaddedArray { + public: + // Creates an aligned padded array. + // The memory can't be deleted since the raw memory chunk is not returned. + static PaddedEnd* create_unfreeable(uint length); +}; + +#endif // SHARE_VM_MEMORY_PADDED_HPP diff --git a/hotspot/src/share/vm/memory/padded.inline.hpp b/hotspot/src/share/vm/memory/padded.inline.hpp new file mode 100644 index 00000000000..1e9994ab647 --- /dev/null +++ b/hotspot/src/share/vm/memory/padded.inline.hpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "memory/allocation.inline.hpp" +#include "memory/padded.hpp" +#include "utilities/debug.hpp" +#include "utilities/globalDefinitions.hpp" + +// Creates an aligned padded array. +// The memory can't be deleted since the raw memory chunk is not returned. +template +PaddedEnd* PaddedArray::create_unfreeable(uint length) { + // Check that the PaddedEnd class works as intended. + STATIC_ASSERT(is_size_aligned_(sizeof(PaddedEnd), alignment)); + + // Allocate a chunk of memory large enough to allow for some alignment. + void* chunk = AllocateHeap(length * sizeof(PaddedEnd) + alignment, flags); + + // Make the initial alignment. + PaddedEnd* aligned_padded_array = (PaddedEnd*)align_pointer_up(chunk, alignment); + + // Call the default constructor for each element. + for (uint i = 0; i < length; i++) { + ::new (&aligned_padded_array[i]) T(); + } + + return aligned_padded_array; +} diff --git a/hotspot/src/share/vm/utilities/debug.hpp b/hotspot/src/share/vm/utilities/debug.hpp index 2450c8fe113..85b26f35fda 100644 --- a/hotspot/src/share/vm/utilities/debug.hpp +++ b/hotspot/src/share/vm/utilities/debug.hpp @@ -225,6 +225,22 @@ void report_untested(const char* file, int line, const char* message); void warning(const char* format, ...); +#ifdef ASSERT +// Compile-time asserts. +template struct StaticAssert; +template <> struct StaticAssert {}; + +// Only StaticAssert is defined, so if cond evaluates to false we get +// a compile time exception when trying to use StaticAssert. +#define STATIC_ASSERT(cond) \ + do { \ + StaticAssert<(cond)> DUMMY_STATIC_ASSERT; \ + (void)DUMMY_STATIC_ASSERT; /* ignore */ \ + } while (false) +#else +#define STATIC_ASSERT(cond) +#endif + // out of shared space reporting enum SharedSpaceType { SharedPermGen, diff --git a/hotspot/src/share/vm/utilities/globalDefinitions.hpp b/hotspot/src/share/vm/utilities/globalDefinitions.hpp index 181e80a0823..f15bb5da9fe 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp +++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp @@ -410,6 +410,8 @@ inline intptr_t align_size_down(intptr_t size, intptr_t alignment) { return align_size_down_(size, alignment); } +#define is_size_aligned_(size, alignment) ((size) == (align_size_up_(size, alignment))) + // Align objects by rounding up their size, in HeapWord units. #define align_object_size_(size) align_size_up_(size, MinObjAlignment) @@ -428,6 +430,10 @@ inline intptr_t align_object_offset(intptr_t offset) { return align_size_up(offset, HeapWordsPerLong); } +inline void* align_pointer_up(const void* addr, size_t size) { + return (void*) align_size_up_((uintptr_t)addr, size); +} + // Clamp an address to be within a specific page // 1. If addr is on the page it is returned as is // 2. If addr is above the page_address the start of the *next* page will be returned @@ -449,32 +455,6 @@ inline address clamp_address_in_page(address addr, address page_address, intptr_ // The expected size in bytes of a cache line, used to pad data structures. #define DEFAULT_CACHE_LINE_SIZE 64 -// Bytes needed to pad type to avoid cache-line sharing; alignment should be the -// expected cache line size (a power of two). The first addend avoids sharing -// when the start address is not a multiple of alignment; the second maintains -// alignment of starting addresses that happen to be a multiple. -#define PADDING_SIZE(type, alignment) \ - ((alignment) + align_size_up_(sizeof(type), alignment)) - -// Templates to create a subclass padded to avoid cache line sharing. These are -// effective only when applied to derived-most (leaf) classes. - -// When no args are passed to the base ctor. -template -class Padded: public T { -private: - char _pad_buf_[PADDING_SIZE(T, alignment)]; -}; - -// When either 0 or 1 args may be passed to the base ctor. -template -class Padded01: public T { -public: - Padded01(): T() { } - Padded01(Arg1T arg1): T(arg1) { } -private: - char _pad_buf_[PADDING_SIZE(T, alignment)]; -}; //---------------------------------------------------------------------------------------------------- // Utility macros for compilers From a7ac24961a51ebbf37355499953bb0c4b751770c Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Fri, 16 Aug 2013 11:28:15 -0400 Subject: [PATCH 002/102] 8022770: java/time/tck/java/time/chrono/TCKChronology.java start failing 8022766: java/time/test/java/time/chrono/TestUmmAlQuraChronology.java failed TCKChronology: corrected display name to match update from JDK-8015986 Reviewed-by: alanb --- jdk/test/java/time/tck/java/time/chrono/TCKChronology.java | 2 +- .../time/test/java/time/chrono/TestUmmAlQuraChronology.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java b/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java index c705f9794ce..363f2b94044 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java @@ -148,7 +148,7 @@ public class TCKChronology { @DataProvider(name = "calendarDisplayName") Object[][] data_of_calendarDisplayNames() { return new Object[][] { - {"Hijrah", "Hijrah-umalqura"}, + {"Hijrah", "Islamic Umm al-Qura Calendar"}, {"ISO", "ISO"}, {"Japanese", "Japanese Calendar"}, {"Minguo", "Minguo Calendar"}, diff --git a/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java b/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java index 63e433f7ac4..3e7cce46d1f 100644 --- a/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java +++ b/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java @@ -438,13 +438,13 @@ public class TestUmmAlQuraChronology { // Test to verify the formatted dates @Test(dataProvider="patternMonthNames") public void test_ofPattern(int year, int month, int day, String expected) { - DateTimeFormatter test = DateTimeFormatter.ofPattern("dd G E MMMM yyyy"); + DateTimeFormatter test = DateTimeFormatter.ofPattern("dd G E MMMM yyyy", Locale.US); assertEquals(test.format(HijrahDate.of(year, month, day)), expected); } // Data provider for localized dates @DataProvider(name="chronoDateTimes") - Object[][] data_chronodatetimes() { + Object[][] data_chronodatetimes() { return new Object[][] { {1432, 12, 29, "Safar 1, 1434 AH"}, {1433, 1, 30, "Safar 30, 1434 AH"}, @@ -463,7 +463,7 @@ public class TestUmmAlQuraChronology { hdt = hdt.plus(1, ChronoUnit.HOURS); hdt = hdt.plus(1, ChronoUnit.MINUTES); hdt = hdt.plus(1, ChronoUnit.SECONDS); - DateTimeFormatter df = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG).withChronology(Chronology.of("Hijrah-umalqura")).withLocale(Locale.forLanguageTag("en-US")); + DateTimeFormatter df = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG).withChronology(Chronology.of("Hijrah-umalqura")).withLocale(Locale.US); assertEquals(df.format(hdt), expected); } From b23fa14820882076195ca65163604e10fc5b2ce2 Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Fri, 16 Aug 2013 11:11:00 -0400 Subject: [PATCH 003/102] 8022193: java/time/test/java/util/TestFormatter.java failed in th locale Tests corrected to use fixed locale and not dependent on the environment Reviewed-by: sherman --- .../share/classes/java/util/Formatter.java | 2 +- .../time/test/java/util/TestFormatter.java | 95 ++++++++++++++----- 2 files changed, 72 insertions(+), 25 deletions(-) diff --git a/jdk/src/share/classes/java/util/Formatter.java b/jdk/src/share/classes/java/util/Formatter.java index 275e1854e0a..3f30c5ebaae 100644 --- a/jdk/src/share/classes/java/util/Formatter.java +++ b/jdk/src/share/classes/java/util/Formatter.java @@ -4196,7 +4196,7 @@ public final class Formatter implements Closeable, Flushable { case DateTime.CENTURY: // 'C' (00 - 99) case DateTime.YEAR_2: // 'y' (00 - 99) case DateTime.YEAR_4: { // 'Y' (0000 - 9999) - int i = t.get(ChronoField.YEAR); + int i = t.get(ChronoField.YEAR_OF_ERA); int size = 2; switch (c) { case DateTime.CENTURY: diff --git a/jdk/test/java/time/test/java/util/TestFormatter.java b/jdk/test/java/time/test/java/util/TestFormatter.java index 8f3b899b97e..4c3ac4b6039 100644 --- a/jdk/test/java/time/test/java/util/TestFormatter.java +++ b/jdk/test/java/time/test/java/util/TestFormatter.java @@ -22,16 +22,27 @@ */ package test.java.util; +import static org.testng.Assert.assertEquals; + import java.time.Instant; +import java.time.LocalTime; import java.time.OffsetDateTime; import java.time.ZonedDateTime; import java.time.ZoneId; + +import java.time.chrono.ChronoLocalDate; +import java.time.chrono.ChronoLocalDateTime; +import java.time.chrono.ChronoZonedDateTime; +import java.time.chrono.Chronology; + import java.time.temporal.ChronoField; +import java.time.temporal.TemporalQuery; +import java.time.temporal.TemporalAccessor; import java.util.*; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import static org.testng.Assert.assertEquals; /* @test * @summary Unit test for j.u.Formatter threeten date/time support @@ -57,18 +68,32 @@ public class TestFormatter { private int total = 0; private int failure = 0; - private boolean verbose = true; + private boolean verbose = false; - @Test - public void test () { + @DataProvider(name = "calendarsByLocale") + Object[][] data_calendars() { + return new Object[][] { + {"en_US"}, + {"th_TH"}, + {"ja-JP-u-ca-japanese"}, + }; + } + @Test(dataProvider="calendarsByLocale") + public void test (String calendarLocale) { + failure = 0; int N = 12; //locales = Locale.getAvailableLocales(); Locale[] locales = new Locale[] { Locale.ENGLISH, Locale.FRENCH, Locale.JAPANESE, Locale.CHINESE}; Random r = new Random(); - ZonedDateTime zdt0 = ZonedDateTime.now(); - ZonedDateTime[] zdts = new ZonedDateTime[] { + + Locale calLocale = Locale.forLanguageTag(calendarLocale); + Chronology chrono = Chronology.ofLocale(calLocale); + ChronoLocalDate now = chrono.dateNow(); + ChronoLocalDateTime ldt0 = now.atTime(LocalTime.now()); + ChronoZonedDateTime zdt0 = ldt0.atZone(ZoneId.systemDefault()); + ChronoZonedDateTime[] zdts = new ChronoZonedDateTime[] { zdt0, zdt0.withZoneSameLocal(ZoneId.of("UTC")), zdt0.withZoneSameLocal(ZoneId.of("GMT")), @@ -76,11 +101,11 @@ public class TestFormatter { }; while (N-- > 0) { - for (ZonedDateTime zdt : zdts) { - zdt = zdt.withDayOfYear(r.nextInt(365) + 1) + for (ChronoZonedDateTime zdt : zdts) { + zdt = zdt.with(ChronoField.DAY_OF_YEAR, (r.nextInt(365) + 1)) .with(ChronoField.SECOND_OF_DAY, r.nextInt(86400)); Instant instant = zdt.toInstant(); - Calendar cal = Calendar.getInstance(); + Calendar cal = Calendar.getInstance(calLocale); cal.setTimeInMillis(instant.toEpochMilli()); cal.setTimeZone(TimeZone.getTimeZone(zdt.getZone())); for (Locale locale : locales) { @@ -106,8 +131,19 @@ public class TestFormatter { } private String getClassName(Object o) { - Class c = o.getClass(); - return c.getName().substring(c.getPackage().getName().length() + 1); + Class c = o.getClass(); + String clname = c.getName().substring(c.getPackage().getName().length() + 1); + if (o instanceof TemporalAccessor) { + Chronology chrono = ((TemporalAccessor)o).query(TemporalQuery.chronology()); + if (chrono != null) { + clname = clname + "(" + chrono.getId() + ")"; + } + } + if (o instanceof Calendar) { + String type = ((Calendar)o).getCalendarType(); + clname = clname + "(" + type + ")"; + } + return clname; } private String test(String fmtStr, Locale locale, @@ -115,12 +151,12 @@ public class TestFormatter { String out = new Formatter( new StringBuilder(), locale).format(fmtStr, dt).out().toString(); if (verbose) { - System.out.printf("%-18s : %s%n", getClassName(dt), out); + System.out.printf("%-24s : %s%n", getClassName(dt), out); } if (expected != null && !out.equals(expected)) { - System.out.printf("=====>%-18s : %s [ FAILED expected: %s ]%n", + System.out.printf("%-24s actual: %s%n FAILED; expected: %s%n", getClassName(dt), out, expected); - new RuntimeException().printStackTrace(); + new RuntimeException().printStackTrace(System.out); failure++; } total++; @@ -135,24 +171,29 @@ public class TestFormatter { } private void testDate(String fmtStr, Locale locale, - ZonedDateTime zdt, Calendar cal) { + ChronoZonedDateTime zdt, Calendar cal) { printFmtStr(locale, fmtStr); String expected = test(fmtStr, locale, null, cal); test(fmtStr, locale, expected, zdt); - test(fmtStr, locale, expected, zdt.toOffsetDateTime()); test(fmtStr, locale, expected, zdt.toLocalDateTime()); test(fmtStr, locale, expected, zdt.toLocalDate()); + if (zdt instanceof ZonedDateTime) { + test(fmtStr, locale, expected, ((ZonedDateTime)zdt).toOffsetDateTime()); + } } private void testTime(String fmtStr, Locale locale, - ZonedDateTime zdt, Calendar cal) { + ChronoZonedDateTime zdt, Calendar cal) { printFmtStr(locale, fmtStr); String expected = test(fmtStr, locale, null, cal); test(fmtStr, locale, expected, zdt); - test(fmtStr, locale, expected, zdt.toOffsetDateTime()); test(fmtStr, locale, expected, zdt.toLocalDateTime()); - test(fmtStr, locale, expected, zdt.toOffsetDateTime().toOffsetTime()); test(fmtStr, locale, expected, zdt.toLocalTime()); + if (zdt instanceof ZonedDateTime) { + OffsetDateTime odt = ((ZonedDateTime)zdt).toOffsetDateTime(); + test(fmtStr, locale, expected, odt); + test(fmtStr, locale, expected, odt.toOffsetTime()); + } } private String toZoneIdStr(String expected) { @@ -164,7 +205,7 @@ public class TestFormatter { .replaceAll("GMT|UTC|UT", "Z"); } - private void testZoneId(Locale locale, ZonedDateTime zdt, Calendar cal) { + private void testZoneId(Locale locale, ChronoZonedDateTime zdt, Calendar cal) { String fmtStr = "z:[%tz] z:[%1$Tz] Z:[%1$tZ] Z:[%1$TZ]"; printFmtStr(locale, fmtStr); String expected = toZoneIdStr(test(fmtStr, locale, null, cal)); @@ -174,8 +215,11 @@ public class TestFormatter { cal0.setTimeInMillis(zdt.toInstant().toEpochMilli()); cal0.setTimeZone(TimeZone.getTimeZone("GMT" + zdt.getOffset().getId())); expected = toZoneOffsetStr(test(fmtStr, locale, null, cal0)); - test(fmtStr, locale, expected, zdt.toOffsetDateTime()); - test(fmtStr, locale, expected, zdt.toOffsetDateTime().toOffsetTime()); + if (zdt instanceof ZonedDateTime) { + OffsetDateTime odt = ((ZonedDateTime)zdt).toOffsetDateTime(); + test(fmtStr, locale, expected, odt); + test(fmtStr, locale, expected, odt.toOffsetTime()); + } // datetime + zid fmtStr = "c:[%tc] c:[%1$Tc]"; @@ -185,12 +229,15 @@ public class TestFormatter { } private void testInstant(Locale locale, Instant instant, - ZonedDateTime zdt, Calendar cal) { + ChronoZonedDateTime zdt, Calendar cal) { String fmtStr = "s:[%ts] s:[%1$Ts] Q:[%1$tQ] Q:[%1$TQ]"; printFmtStr(locale, fmtStr); String expected = test(fmtStr, locale, null, cal); test(fmtStr, locale, expected, instant); test(fmtStr, locale, expected, zdt); - test(fmtStr, locale, expected, zdt.toOffsetDateTime()); + if (zdt instanceof ZonedDateTime) { + OffsetDateTime odt = ((ZonedDateTime)zdt).toOffsetDateTime(); + test(fmtStr, locale, expected, odt); + } } } From 63de7b9fd0abfe5deabc7224d47c4007384e4a18 Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Fri, 16 Aug 2013 13:58:43 -0400 Subject: [PATCH 004/102] 8019185: Inconsistency between JapaneseEra start dates and java.util.JapaneseImperialDate Align Meiji start date with lib/calendar.properties to avoid any confusion Reviewed-by: sherman --- jdk/src/share/classes/java/time/chrono/JapaneseEra.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/time/chrono/JapaneseEra.java b/jdk/src/share/classes/java/time/chrono/JapaneseEra.java index ba9fb434bf9..29dda6bbbcf 100644 --- a/jdk/src/share/classes/java/time/chrono/JapaneseEra.java +++ b/jdk/src/share/classes/java/time/chrono/JapaneseEra.java @@ -107,7 +107,7 @@ public final class JapaneseEra * The singleton instance for the 'Meiji' era (1868-09-08 - 1912-07-29) * which has the value -1. */ - public static final JapaneseEra MEIJI = new JapaneseEra(-1, LocalDate.of(1868, 9, 8)); + public static final JapaneseEra MEIJI = new JapaneseEra(-1, LocalDate.of(1868, 1, 1)); /** * The singleton instance for the 'Taisho' era (1912-07-30 - 1926-12-24) * which has the value 0. From b42c6fb241c476fc045eee68a9c2b3fa98c26811 Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Tue, 6 Aug 2013 14:26:34 +0100 Subject: [PATCH 005/102] 8022318: Document Spliterator characteristics and binding policy of java util concurrent collection impls Co-authored-by: Martin Buchholz Reviewed-by: chegar --- .../util/concurrent/ArrayBlockingQueue.java | 25 +++++-- .../util/concurrent/ConcurrentHashMap.java | 57 +++++++------- .../concurrent/ConcurrentLinkedDeque.java | 46 +++++++----- .../concurrent/ConcurrentLinkedQueue.java | 31 ++++++-- .../concurrent/ConcurrentNavigableMap.java | 21 ++---- .../concurrent/ConcurrentSkipListMap.java | 74 +++++++++++-------- .../concurrent/ConcurrentSkipListSet.java | 30 ++++++-- .../util/concurrent/CopyOnWriteArrayList.java | 35 +++++++-- .../util/concurrent/CopyOnWriteArraySet.java | 15 ++++ .../java/util/concurrent/DelayQueue.java | 8 +- .../util/concurrent/LinkedBlockingDeque.java | 38 +++++++--- .../util/concurrent/LinkedBlockingQueue.java | 30 ++++++-- .../util/concurrent/LinkedTransferQueue.java | 31 ++++++-- .../concurrent/PriorityBlockingQueue.java | 32 ++++++-- .../util/concurrent/SynchronousQueue.java | 30 ++++---- .../java/util/concurrent/package-info.java | 20 +++-- 16 files changed, 348 insertions(+), 175 deletions(-) diff --git a/jdk/src/share/classes/java/util/concurrent/ArrayBlockingQueue.java b/jdk/src/share/classes/java/util/concurrent/ArrayBlockingQueue.java index fe91686627d..9a0346f6a52 100644 --- a/jdk/src/share/classes/java/util/concurrent/ArrayBlockingQueue.java +++ b/jdk/src/share/classes/java/util/concurrent/ArrayBlockingQueue.java @@ -757,12 +757,8 @@ public class ArrayBlockingQueue extends AbstractQueue * Returns an iterator over the elements in this queue in proper sequence. * The elements will be returned in order from first (head) to last (tail). * - *

The returned iterator is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse - * elements as they existed upon construction of the iterator, and - * may (but is not guaranteed to) reflect any modifications - * subsequent to construction. + *

The returned iterator is + * weakly consistent. * * @return an iterator over the elements in this queue in proper sequence */ @@ -1396,9 +1392,26 @@ public class ArrayBlockingQueue extends AbstractQueue // } } + /** + * Returns a {@link Spliterator} over the elements in this queue. + * + *

The returned spliterator is + * weakly consistent. + * + *

The {@code Spliterator} reports {@link Spliterator#CONCURRENT}, + * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}. + * + * @implNote + * The {@code Spliterator} implements {@code trySplit} to permit limited + * parallelism. + * + * @return a {@code Spliterator} over the elements in this queue + * @since 1.8 + */ public Spliterator spliterator() { return Spliterators.spliterator (this, Spliterator.ORDERED | Spliterator.NONNULL | Spliterator.CONCURRENT); } + } diff --git a/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java b/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java index f29ec1d4efb..1936e244946 100644 --- a/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -43,7 +43,6 @@ import java.util.AbstractMap; import java.util.Arrays; import java.util.Collection; import java.util.Comparator; -import java.util.ConcurrentModificationException; import java.util.Enumeration; import java.util.HashMap; import java.util.Hashtable; @@ -94,14 +93,14 @@ import java.util.stream.Stream; * that key reporting the updated value.) For aggregate operations * such as {@code putAll} and {@code clear}, concurrent retrievals may * reflect insertion or removal of only some entries. Similarly, - * Iterators and Enumerations return elements reflecting the state of - * the hash table at some point at or since the creation of the + * Iterators, Spliterators and Enumerations return elements reflecting the + * state of the hash table at some point at or since the creation of the * iterator/enumeration. They do not throw {@link - * ConcurrentModificationException}. However, iterators are designed - * to be used by only one thread at a time. Bear in mind that the - * results of aggregate status methods including {@code size}, {@code - * isEmpty}, and {@code containsValue} are typically useful only when - * a map is not undergoing concurrent updates in other threads. + * java.util.ConcurrentModificationException ConcurrentModificationException}. + * However, iterators are designed to be used by only one thread at a time. + * Bear in mind that the results of aggregate status methods including + * {@code size}, {@code isEmpty}, and {@code containsValue} are typically + * useful only when a map is not undergoing concurrent updates in other threads. * Otherwise the results of these methods reflect transient states * that may be adequate for monitoring or estimation purposes, but not * for program control. @@ -1200,11 +1199,11 @@ public class ConcurrentHashMap extends AbstractMap * operations. It does not support the {@code add} or * {@code addAll} operations. * - *

The view's {@code iterator} is a "weakly consistent" iterator - * that will never throw {@link ConcurrentModificationException}, - * and guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not guaranteed to) - * reflect any modifications subsequent to construction. + *

The view's iterators and spliterators are + * weakly consistent. + * + *

The view's {@code spliterator} reports {@link Spliterator#CONCURRENT}, + * {@link Spliterator#DISTINCT}, and {@link Spliterator#NONNULL}. * * @return the set view */ @@ -1223,11 +1222,11 @@ public class ConcurrentHashMap extends AbstractMap * {@code retainAll}, and {@code clear} operations. It does not * support the {@code add} or {@code addAll} operations. * - *

The view's {@code iterator} is a "weakly consistent" iterator - * that will never throw {@link ConcurrentModificationException}, - * and guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not guaranteed to) - * reflect any modifications subsequent to construction. + *

The view's iterators and spliterators are + * weakly consistent. + * + *

The view's {@code spliterator} reports {@link Spliterator#CONCURRENT} + * and {@link Spliterator#NONNULL}. * * @return the collection view */ @@ -1245,11 +1244,11 @@ public class ConcurrentHashMap extends AbstractMap * {@code removeAll}, {@code retainAll}, and {@code clear} * operations. * - *

The view's {@code iterator} is a "weakly consistent" iterator - * that will never throw {@link ConcurrentModificationException}, - * and guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not guaranteed to) - * reflect any modifications subsequent to construction. + *

The view's iterators and spliterators are + * weakly consistent. + * + *

The view's {@code spliterator} reports {@link Spliterator#CONCURRENT}, + * {@link Spliterator#DISTINCT}, and {@link Spliterator#NONNULL}. * * @return the set view */ @@ -4308,12 +4307,12 @@ public class ConcurrentHashMap extends AbstractMap // implementations below rely on concrete classes supplying these // abstract methods /** - * Returns a "weakly consistent" iterator that will never - * throw {@link ConcurrentModificationException}, and - * guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not - * guaranteed to) reflect any modifications subsequent to - * construction. + * Returns an iterator over the elements in this collection. + * + *

The returned iterator is + * weakly consistent. + * + * @return an iterator over the elements in this collection */ public abstract Iterator iterator(); public abstract boolean contains(Object o); diff --git a/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java index 6bb62f0f98c..5697c419470 100644 --- a/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java +++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java @@ -55,12 +55,8 @@ import java.util.function.Consumer; * Like most other concurrent collection implementations, this class * does not permit the use of {@code null} elements. * - *

Iterators are weakly consistent, returning elements - * reflecting the state of the deque at some point at or since the - * creation of the iterator. They do not throw {@link - * java.util.ConcurrentModificationException - * ConcurrentModificationException}, and may proceed concurrently with - * other operations. + *

Iterators and spliterators are + * weakly consistent. * *

Beware that, unlike in most collections, the {@code size} method * is NOT a constant-time operation. Because of the @@ -1290,12 +1286,8 @@ public class ConcurrentLinkedDeque * Returns an iterator over the elements in this deque in proper sequence. * The elements will be returned in order from first (head) to last (tail). * - *

The returned iterator is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse - * elements as they existed upon construction of the iterator, and - * may (but is not guaranteed to) reflect any modifications - * subsequent to construction. + *

The returned iterator is + * weakly consistent. * * @return an iterator over the elements in this deque in proper sequence */ @@ -1308,12 +1300,8 @@ public class ConcurrentLinkedDeque * sequential order. The elements will be returned in order from * last (tail) to first (head). * - *

The returned iterator is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse - * elements as they existed upon construction of the iterator, and - * may (but is not guaranteed to) reflect any modifications - * subsequent to construction. + *

The returned iterator is + * weakly consistent. * * @return an iterator over the elements in this deque in reverse order */ @@ -1493,6 +1481,22 @@ public class ConcurrentLinkedDeque } } + /** + * Returns a {@link Spliterator} over the elements in this deque. + * + *

The returned spliterator is + * weakly consistent. + * + *

The {@code Spliterator} reports {@link Spliterator#CONCURRENT}, + * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}. + * + * @implNote + * The {@code Spliterator} implements {@code trySplit} to permit limited + * parallelism. + * + * @return a {@code Spliterator} over the elements in this deque + * @since 1.8 + */ public Spliterator spliterator() { return new CLDSpliterator(this); } @@ -1500,6 +1504,8 @@ public class ConcurrentLinkedDeque /** * Saves this deque to a stream (that is, serializes it). * + * @param s the stream + * @throws java.io.IOException if an I/O error occurs * @serialData All of the elements (each an {@code E}) in * the proper order, followed by a null */ @@ -1522,6 +1528,10 @@ public class ConcurrentLinkedDeque /** * Reconstitutes this deque from a stream (that is, deserializes it). + * @param s the stream + * @throws ClassNotFoundException if the class of a serialized object + * could not be found + * @throws java.io.IOException if an I/O error occurs */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { diff --git a/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java index 0b562bc217d..62512ac41dc 100644 --- a/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java +++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java @@ -654,12 +654,8 @@ public class ConcurrentLinkedQueue extends AbstractQueue * Returns an iterator over the elements in this queue in proper sequence. * The elements will be returned in order from first (head) to last (tail). * - *

The returned iterator is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse - * elements as they existed upon construction of the iterator, and - * may (but is not guaranteed to) reflect any modifications - * subsequent to construction. + *

The returned iterator is + * weakly consistent. * * @return an iterator over the elements in this queue in proper sequence */ @@ -749,6 +745,8 @@ public class ConcurrentLinkedQueue extends AbstractQueue /** * Saves this queue to a stream (that is, serializes it). * + * @param s the stream + * @throws java.io.IOException if an I/O error occurs * @serialData All of the elements (each an {@code E}) in * the proper order, followed by a null */ @@ -771,6 +769,10 @@ public class ConcurrentLinkedQueue extends AbstractQueue /** * Reconstitutes this queue from a stream (that is, deserializes it). + * @param s the stream + * @throws ClassNotFoundException if the class of a serialized object + * could not be found + * @throws java.io.IOException if an I/O error occurs */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { @@ -881,6 +883,23 @@ public class ConcurrentLinkedQueue extends AbstractQueue } } + /** + * Returns a {@link Spliterator} over the elements in this queue. + * + *

The returned spliterator is + * weakly consistent. + * + *

The {@code Spliterator} reports {@link Spliterator#CONCURRENT}, + * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}. + * + * @implNote + * The {@code Spliterator} implements {@code trySplit} to permit limited + * parallelism. + * + * @return a {@code Spliterator} over the elements in this queue + * @since 1.8 + */ + @Override public Spliterator spliterator() { return new CLQSpliterator(this); } diff --git a/jdk/src/share/classes/java/util/concurrent/ConcurrentNavigableMap.java b/jdk/src/share/classes/java/util/concurrent/ConcurrentNavigableMap.java index 7f54eab7b4e..9d624f44e5a 100644 --- a/jdk/src/share/classes/java/util/concurrent/ConcurrentNavigableMap.java +++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentNavigableMap.java @@ -120,11 +120,8 @@ public interface ConcurrentNavigableMap * operations. It does not support the {@code add} or {@code addAll} * operations. * - *

The view's {@code iterator} is a "weakly consistent" iterator - * that will never throw {@link ConcurrentModificationException}, - * and guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not guaranteed to) - * reflect any modifications subsequent to construction. + *

The view's iterators and spliterators are + * weakly consistent. * * @return a navigable set view of the keys in this map */ @@ -141,11 +138,8 @@ public interface ConcurrentNavigableMap * operations. It does not support the {@code add} or {@code addAll} * operations. * - *

The view's {@code iterator} is a "weakly consistent" iterator - * that will never throw {@link ConcurrentModificationException}, - * and guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not guaranteed to) - * reflect any modifications subsequent to construction. + *

The view's iterators and spliterators are + * weakly consistent. * *

This method is equivalent to method {@code navigableKeySet}. * @@ -164,11 +158,8 @@ public interface ConcurrentNavigableMap * operations. It does not support the {@code add} or {@code addAll} * operations. * - *

The view's {@code iterator} is a "weakly consistent" iterator - * that will never throw {@link ConcurrentModificationException}, - * and guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not guaranteed to) - * reflect any modifications subsequent to construction. + *

The view's iterators and spliterators are + * weakly consistent. * * @return a reverse order navigable set view of the keys in this map */ diff --git a/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index ff75003e4c2..62364d9f0ec 100644 --- a/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -71,12 +71,13 @@ import java.util.function.Function; * {@code containsKey}, {@code get}, {@code put} and * {@code remove} operations and their variants. Insertion, removal, * update, and access operations safely execute concurrently by - * multiple threads. Iterators are weakly consistent, returning - * elements reflecting the state of the map at some point at or since - * the creation of the iterator. They do not throw {@link - * java.util.ConcurrentModificationException ConcurrentModificationException}, - * and may proceed concurrently with other operations. Ascending key ordered - * views and their iterators are faster than descending ones. + * multiple threads. + * + *

Iterators and spliterators are + * weakly consistent. + * + *

Ascending key ordered views and their iterators are faster than + * descending ones. * *

All {@code Map.Entry} pairs returned by methods in this class * and its views represent snapshots of mappings at the time they were @@ -1804,8 +1805,18 @@ public class ConcurrentSkipListMap extends AbstractMap /** * Returns a {@link NavigableSet} view of the keys contained in this map. - * The set's iterator returns the keys in ascending order. - * The set is backed by the map, so changes to the map are + * + *

The set's iterator returns the keys in ascending order. + * The set's spliterator additionally reports {@link Spliterator#CONCURRENT}, + * {@link Spliterator#NONNULL}, {@link Spliterator#SORTED} and + * {@link Spliterator#ORDERED}, with an encounter order that is ascending + * key order. The spliterator's comparator (see + * {@link java.util.Spliterator#getComparator()}) is {@code null} if + * the map's comparator (see {@link #comparator()}) is {@code null}. + * Otherwise, the spliterator's comparator is the same as or imposes the + * same total ordering as the map's comparator. + * + *

The set is backed by the map, so changes to the map are * reflected in the set, and vice-versa. The set supports element * removal, which removes the corresponding mapping from the map, * via the {@code Iterator.remove}, {@code Set.remove}, @@ -1813,11 +1824,8 @@ public class ConcurrentSkipListMap extends AbstractMap * operations. It does not support the {@code add} or {@code addAll} * operations. * - *

The view's {@code iterator} is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse elements - * as they existed upon construction of the iterator, and may (but is not - * guaranteed to) reflect any modifications subsequent to construction. + *

The view's iterators and spliterators are + * weakly consistent. * *

This method is equivalent to method {@code navigableKeySet}. * @@ -1835,9 +1843,13 @@ public class ConcurrentSkipListMap extends AbstractMap /** * Returns a {@link Collection} view of the values contained in this map. - * The collection's iterator returns the values in ascending order - * of the corresponding keys. - * The collection is backed by the map, so changes to the map are + *

The collection's iterator returns the values in ascending order + * of the corresponding keys. The collections's spliterator additionally + * reports {@link Spliterator#CONCURRENT}, {@link Spliterator#NONNULL} and + * {@link Spliterator#ORDERED}, with an encounter order that is ascending + * order of the corresponding keys. + * + *

The collection is backed by the map, so changes to the map are * reflected in the collection, and vice-versa. The collection * supports element removal, which removes the corresponding * mapping from the map, via the {@code Iterator.remove}, @@ -1845,11 +1857,8 @@ public class ConcurrentSkipListMap extends AbstractMap * {@code retainAll} and {@code clear} operations. It does not * support the {@code add} or {@code addAll} operations. * - *

The view's {@code iterator} is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse elements - * as they existed upon construction of the iterator, and may (but is not - * guaranteed to) reflect any modifications subsequent to construction. + *

The view's iterators and spliterators are + * weakly consistent. */ public Collection values() { Values vs = values; @@ -1858,8 +1867,14 @@ public class ConcurrentSkipListMap extends AbstractMap /** * Returns a {@link Set} view of the mappings contained in this map. - * The set's iterator returns the entries in ascending key order. - * The set is backed by the map, so changes to the map are + * + *

The set's iterator returns the entries in ascending key order. The + * set's spliterator additionally reports {@link Spliterator#CONCURRENT}, + * {@link Spliterator#NONNULL}, {@link Spliterator#SORTED} and + * {@link Spliterator#ORDERED}, with an encounter order that is ascending + * key order. + * + *

The set is backed by the map, so changes to the map are * reflected in the set, and vice-versa. The set supports element * removal, which removes the corresponding mapping from the map, * via the {@code Iterator.remove}, {@code Set.remove}, @@ -1867,15 +1882,12 @@ public class ConcurrentSkipListMap extends AbstractMap * operations. It does not support the {@code add} or * {@code addAll} operations. * - *

The view's {@code iterator} is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse elements - * as they existed upon construction of the iterator, and may (but is not - * guaranteed to) reflect any modifications subsequent to construction. + *

The view's iterators and spliterators are + * weakly consistent. * - *

The {@code Map.Entry} elements returned by - * {@code iterator.next()} do not support the - * {@code setValue} operation. + *

The {@code Map.Entry} elements traversed by the {@code iterator} + * or {@code spliterator} do not support the {@code setValue} + * operation. * * @return a set view of the mappings contained in this map, * sorted in ascending key order diff --git a/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index 4c41e388c8b..17989f8d3cc 100644 --- a/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -57,12 +57,12 @@ import java.util.Spliterator; * cost for the {@code contains}, {@code add}, and {@code remove} * operations and their variants. Insertion, removal, and access * operations safely execute concurrently by multiple threads. - * Iterators are weakly consistent, returning elements - * reflecting the state of the set at some point at or since the - * creation of the iterator. They do not throw {@link - * java.util.ConcurrentModificationException}, and may proceed - * concurrently with other operations. Ascending ordered views and - * their iterators are faster than descending ones. + * + *

Iterators and spliterators are + * weakly consistent. + * + *

Ascending ordered views and their iterators are faster than + * descending ones. * *

Beware that, unlike in most collections, the {@code size} * method is not a constant-time operation. Because of the @@ -480,6 +480,24 @@ public class ConcurrentSkipListSet return new ConcurrentSkipListSet(m.descendingMap()); } + /** + * Returns a {@link Spliterator} over the elements in this set. + * + *

The {@code Spliterator} reports {@link Spliterator#CONCURRENT}, + * {@link Spliterator#NONNULL}, {@link Spliterator#DISTINCT}, + * {@link Spliterator#SORTED} and {@link Spliterator#ORDERED}, with an + * encounter order that is ascending order. Overriding implementations + * should document the reporting of additional characteristic values. + * + *

The spliterator's comparator (see + * {@link java.util.Spliterator#getComparator()}) is {@code null} if + * the set's comparator (see {@link #comparator()}) is {@code null}. + * Otherwise, the spliterator's comparator is the same as or imposes the + * same total ordering as the set's comparator. + * + * @return a {@code Spliterator} over the elements in this set + * @since 1.8 + */ @SuppressWarnings("unchecked") public Spliterator spliterator() { if (m instanceof ConcurrentSkipListMap) diff --git a/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java b/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java index 2ea321100c3..fae67b2b2d0 100644 --- a/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java +++ b/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java @@ -952,6 +952,8 @@ public class CopyOnWriteArrayList /** * Saves this list to a stream (that is, serializes it). * + * @param s the stream + * @throws java.io.IOException if an I/O error occurs * @serialData The length of the array backing the list is emitted * (int), followed by all of its elements (each an Object) * in the proper order. @@ -972,6 +974,10 @@ public class CopyOnWriteArrayList /** * Reconstitutes this list from a stream (that is, deserializes it). + * @param s the stream + * @throws ClassNotFoundException if the class of a serialized object + * could not be found + * @throws java.io.IOException if an I/O error occurs */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { @@ -1092,15 +1098,29 @@ public class CopyOnWriteArrayList * * @throws IndexOutOfBoundsException {@inheritDoc} */ - public ListIterator listIterator(final int index) { + public ListIterator listIterator(int index) { Object[] elements = getArray(); int len = elements.length; - if (index<0 || index>len) + if (index < 0 || index > len) throw new IndexOutOfBoundsException("Index: "+index); return new COWIterator(elements, index); } + /** + * Returns a {@link Spliterator} over the elements in this list. + * + *

The {@code Spliterator} reports {@link Spliterator#IMMUTABLE}, + * {@link Spliterator#ORDERED}, {@link Spliterator#SIZED}, and + * {@link Spliterator#SUBSIZED}. + * + *

The spliterator provides a snapshot of the state of the list + * when the spliterator was constructed. No synchronization is needed while + * operating on the spliterator. + * + * @return a {@code Spliterator} over the elements in this list + * @since 1.8 + */ public Spliterator spliterator() { return Spliterators.spliterator (getArray(), Spliterator.IMMUTABLE | Spliterator.ORDERED); @@ -1257,7 +1277,7 @@ public class CopyOnWriteArrayList // only call this holding l's lock private void rangeCheck(int index) { - if (index<0 || index>=size) + if (index < 0 || index >= size) throw new IndexOutOfBoundsException("Index: "+index+ ",Size: "+size); } @@ -1304,7 +1324,7 @@ public class CopyOnWriteArrayList lock.lock(); try { checkForComodification(); - if (index<0 || index>size) + if (index < 0 || index > size) throw new IndexOutOfBoundsException(); l.add(index+offset, element); expectedArray = l.getArray(); @@ -1361,12 +1381,12 @@ public class CopyOnWriteArrayList } } - public ListIterator listIterator(final int index) { + public ListIterator listIterator(int index) { final ReentrantLock lock = l.lock; lock.lock(); try { checkForComodification(); - if (index<0 || index>size) + if (index < 0 || index > size) throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+size); return new COWSubListIterator(l, index, offset, size); @@ -1380,7 +1400,7 @@ public class CopyOnWriteArrayList lock.lock(); try { checkForComodification(); - if (fromIndex<0 || toIndex>size) + if (fromIndex < 0 || toIndex > size) throw new IndexOutOfBoundsException(); return new COWSubList(l, fromIndex + offset, toIndex + offset); @@ -1580,6 +1600,7 @@ public class CopyOnWriteArrayList return Spliterators.spliterator (a, lo, hi, Spliterator.IMMUTABLE | Spliterator.ORDERED); } + } private static class COWSubListIterator implements ListIterator { diff --git a/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArraySet.java b/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArraySet.java index ffb9668647c..059cceb103a 100644 --- a/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArraySet.java +++ b/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArraySet.java @@ -404,6 +404,21 @@ public class CopyOnWriteArraySet extends AbstractSet al.forEach(action); } + /** + * Returns a {@link Spliterator} over the elements in this set in the order + * in which these elements were added. + * + *

The {@code Spliterator} reports {@link Spliterator#IMMUTABLE}, + * {@link Spliterator#DISTINCT}, {@link Spliterator#SIZED}, and + * {@link Spliterator#SUBSIZED}. + * + *

The spliterator provides a snapshot of the state of the set + * when the spliterator was constructed. No synchronization is needed while + * operating on the spliterator. + * + * @return a {@code Spliterator} over the elements in this set + * @since 1.8 + */ public Spliterator spliterator() { return Spliterators.spliterator (al.getArray(), Spliterator.IMMUTABLE | Spliterator.DISTINCT); diff --git a/jdk/src/share/classes/java/util/concurrent/DelayQueue.java b/jdk/src/share/classes/java/util/concurrent/DelayQueue.java index 610fb717ac8..b729265a016 100644 --- a/jdk/src/share/classes/java/util/concurrent/DelayQueue.java +++ b/jdk/src/share/classes/java/util/concurrent/DelayQueue.java @@ -512,12 +512,8 @@ public class DelayQueue extends AbstractQueue * unexpired) in this queue. The iterator does not return the * elements in any particular order. * - *

The returned iterator is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse - * elements as they existed upon construction of the iterator, and - * may (but is not guaranteed to) reflect any modifications - * subsequent to construction. + *

The returned iterator is + * weakly consistent. * * @return an iterator over the elements in this queue */ diff --git a/jdk/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java b/jdk/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java index df688a57b06..73d3da049ec 100644 --- a/jdk/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java +++ b/jdk/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java @@ -1008,12 +1008,8 @@ public class LinkedBlockingDeque * Returns an iterator over the elements in this deque in proper sequence. * The elements will be returned in order from first (head) to last (tail). * - *

The returned iterator is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse - * elements as they existed upon construction of the iterator, and - * may (but is not guaranteed to) reflect any modifications - * subsequent to construction. + *

The returned iterator is + * weakly consistent. * * @return an iterator over the elements in this deque in proper sequence */ @@ -1026,12 +1022,8 @@ public class LinkedBlockingDeque * sequential order. The elements will be returned in order from * last (tail) to first (head). * - *

The returned iterator is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse - * elements as they existed upon construction of the iterator, and - * may (but is not guaranteed to) reflect any modifications - * subsequent to construction. + *

The returned iterator is + * weakly consistent. * * @return an iterator over the elements in this deque in reverse order */ @@ -1270,6 +1262,22 @@ public class LinkedBlockingDeque } } + /** + * Returns a {@link Spliterator} over the elements in this deque. + * + *

The returned spliterator is + * weakly consistent. + * + *

The {@code Spliterator} reports {@link Spliterator#CONCURRENT}, + * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}. + * + * @implNote + * The {@code Spliterator} implements {@code trySplit} to permit limited + * parallelism. + * + * @return a {@code Spliterator} over the elements in this deque + * @since 1.8 + */ public Spliterator spliterator() { return new LBDSpliterator(this); } @@ -1277,6 +1285,8 @@ public class LinkedBlockingDeque /** * Saves this deque to a stream (that is, serializes it). * + * @param s the stream + * @throws java.io.IOException if an I/O error occurs * @serialData The capacity (int), followed by elements (each an * {@code Object}) in the proper order, followed by a null */ @@ -1299,6 +1309,10 @@ public class LinkedBlockingDeque /** * Reconstitutes this deque from a stream (that is, deserializes it). + * @param s the stream + * @throws ClassNotFoundException if the class of a serialized object + * could not be found + * @throws java.io.IOException if an I/O error occurs */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { diff --git a/jdk/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java b/jdk/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java index 05bf7cc22de..d7a1587146a 100644 --- a/jdk/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java +++ b/jdk/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java @@ -766,12 +766,8 @@ public class LinkedBlockingQueue extends AbstractQueue * Returns an iterator over the elements in this queue in proper sequence. * The elements will be returned in order from first (head) to last (tail). * - *

The returned iterator is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse - * elements as they existed upon construction of the iterator, and - * may (but is not guaranteed to) reflect any modifications - * subsequent to construction. + *

The returned iterator is + * weakly consistent. * * @return an iterator over the elements in this queue in proper sequence */ @@ -973,6 +969,22 @@ public class LinkedBlockingQueue extends AbstractQueue } } + /** + * Returns a {@link Spliterator} over the elements in this queue. + * + *

The returned spliterator is + * weakly consistent. + * + *

The {@code Spliterator} reports {@link Spliterator#CONCURRENT}, + * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}. + * + * @implNote + * The {@code Spliterator} implements {@code trySplit} to permit limited + * parallelism. + * + * @return a {@code Spliterator} over the elements in this queue + * @since 1.8 + */ public Spliterator spliterator() { return new LBQSpliterator(this); } @@ -980,6 +992,8 @@ public class LinkedBlockingQueue extends AbstractQueue /** * Saves this queue to a stream (that is, serializes it). * + * @param s the stream + * @throws java.io.IOException if an I/O error occurs * @serialData The capacity is emitted (int), followed by all of * its elements (each an {@code Object}) in the proper order, * followed by a null @@ -1005,6 +1019,10 @@ public class LinkedBlockingQueue extends AbstractQueue /** * Reconstitutes this queue from a stream (that is, deserializes it). + * @param s the stream + * @throws ClassNotFoundException if the class of a serialized object + * could not be found + * @throws java.io.IOException if an I/O error occurs */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { diff --git a/jdk/src/share/classes/java/util/concurrent/LinkedTransferQueue.java b/jdk/src/share/classes/java/util/concurrent/LinkedTransferQueue.java index 7dbb368cc52..5ebd04923d4 100644 --- a/jdk/src/share/classes/java/util/concurrent/LinkedTransferQueue.java +++ b/jdk/src/share/classes/java/util/concurrent/LinkedTransferQueue.java @@ -40,6 +40,7 @@ import java.util.Collection; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Queue; +import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.LockSupport; import java.util.Spliterator; import java.util.Spliterators; @@ -1018,6 +1019,22 @@ public class LinkedTransferQueue extends AbstractQueue } } + /** + * Returns a {@link Spliterator} over the elements in this queue. + * + *

The returned spliterator is + * weakly consistent. + * + *

The {@code Spliterator} reports {@link Spliterator#CONCURRENT}, + * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}. + * + * @implNote + * The {@code Spliterator} implements {@code trySplit} to permit limited + * parallelism. + * + * @return a {@code Spliterator} over the elements in this queue + * @since 1.8 + */ public Spliterator spliterator() { return new LTQSpliterator(this); } @@ -1301,12 +1318,8 @@ public class LinkedTransferQueue extends AbstractQueue * Returns an iterator over the elements in this queue in proper sequence. * The elements will be returned in order from first (head) to last (tail). * - *

The returned iterator is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse - * elements as they existed upon construction of the iterator, and - * may (but is not guaranteed to) reflect any modifications - * subsequent to construction. + *

The returned iterator is + * weakly consistent. * * @return an iterator over the elements in this queue in proper sequence */ @@ -1407,6 +1420,8 @@ public class LinkedTransferQueue extends AbstractQueue /** * Saves this queue to a stream (that is, serializes it). * + * @param s the stream + * @throws java.io.IOException if an I/O error occurs * @serialData All of the elements (each an {@code E}) in * the proper order, followed by a null */ @@ -1421,6 +1436,10 @@ public class LinkedTransferQueue extends AbstractQueue /** * Reconstitutes this queue from a stream (that is, deserializes it). + * @param s the stream + * @throws ClassNotFoundException if the class of a serialized object + * could not be found + * @throws java.io.IOException if an I/O error occurs */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { diff --git a/jdk/src/share/classes/java/util/concurrent/PriorityBlockingQueue.java b/jdk/src/share/classes/java/util/concurrent/PriorityBlockingQueue.java index fdf9c71af93..db888250c10 100644 --- a/jdk/src/share/classes/java/util/concurrent/PriorityBlockingQueue.java +++ b/jdk/src/share/classes/java/util/concurrent/PriorityBlockingQueue.java @@ -229,7 +229,7 @@ public class PriorityBlockingQueue extends AbstractQueue /** * Creates a {@code PriorityBlockingQueue} containing the elements * in the specified collection. If the specified collection is a - * {@link SortedSet} or a {@link PriorityQueue}, this + * {@link SortedSet} or a {@link PriorityQueue}, this * priority queue will be ordered according to the same ordering. * Otherwise, this priority queue will be ordered according to the * {@linkplain Comparable natural ordering} of its elements. @@ -864,12 +864,8 @@ public class PriorityBlockingQueue extends AbstractQueue * Returns an iterator over the elements in this queue. The * iterator does not return the elements in any particular order. * - *

The returned iterator is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse - * elements as they existed upon construction of the iterator, and - * may (but is not guaranteed to) reflect any modifications - * subsequent to construction. + *

The returned iterator is + * weakly consistent. * * @return an iterator over the elements in this queue */ @@ -915,6 +911,9 @@ public class PriorityBlockingQueue extends AbstractQueue * For compatibility with previous version of this class, elements * are first copied to a java.util.PriorityQueue, which is then * serialized. + * + * @param s the stream + * @throws java.io.IOException if an I/O error occurs */ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { @@ -932,6 +931,10 @@ public class PriorityBlockingQueue extends AbstractQueue /** * Reconstitutes this queue from a stream (that is, deserializes it). + * @param s the stream + * @throws ClassNotFoundException if the class of a serialized object + * could not be found + * @throws java.io.IOException if an I/O error occurs */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { @@ -1005,6 +1008,21 @@ public class PriorityBlockingQueue extends AbstractQueue } } + /** + * Returns a {@link Spliterator} over the elements in this queue. + * + *

The returned spliterator is + * weakly consistent. + * + *

The {@code Spliterator} reports {@link Spliterator#SIZED} and + * {@link Spliterator#NONNULL}. + * + * @implNote + * The {@code Spliterator} additionally reports {@link Spliterator#SUBSIZED}. + * + * @return a {@code Spliterator} over the elements in this queue + * @since 1.8 + */ public Spliterator spliterator() { return new PBQSpliterator(this, null, 0, -1); } diff --git a/jdk/src/share/classes/java/util/concurrent/SynchronousQueue.java b/jdk/src/share/classes/java/util/concurrent/SynchronousQueue.java index 97b53049716..fdc42f926ee 100644 --- a/jdk/src/share/classes/java/util/concurrent/SynchronousQueue.java +++ b/jdk/src/share/classes/java/util/concurrent/SynchronousQueue.java @@ -38,6 +38,8 @@ package java.util.concurrent; import java.util.concurrent.locks.LockSupport; import java.util.concurrent.locks.ReentrantLock; import java.util.*; +import java.util.Spliterator; +import java.util.Spliterators; /** * A {@linkplain BlockingQueue blocking queue} in which each insert @@ -1062,21 +1064,17 @@ public class SynchronousQueue extends AbstractQueue * * @return an empty iterator */ - @SuppressWarnings("unchecked") public Iterator iterator() { - return (Iterator) EmptyIterator.EMPTY_ITERATOR; - } - - // Replicated from a previous version of Collections - private static class EmptyIterator implements Iterator { - static final EmptyIterator EMPTY_ITERATOR - = new EmptyIterator(); - - public boolean hasNext() { return false; } - public E next() { throw new NoSuchElementException(); } - public void remove() { throw new IllegalStateException(); } + return Collections.emptyIterator(); } + /** + * Returns an empty spliterator in which calls to + * {@link java.util.Spliterator#trySplit()} always return {@code null}. + * + * @return an empty spliterator + * @since 1.8 + */ public Spliterator spliterator() { return Spliterators.emptySpliterator(); } @@ -1163,6 +1161,8 @@ public class SynchronousQueue extends AbstractQueue /** * Saves this queue to a stream (that is, serializes it). + * @param s the stream + * @throws java.io.IOException if an I/O error occurs */ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { @@ -1182,8 +1182,12 @@ public class SynchronousQueue extends AbstractQueue /** * Reconstitutes this queue from a stream (that is, deserializes it). + * @param s the stream + * @throws ClassNotFoundException if the class of a serialized object + * could not be found + * @throws java.io.IOException if an I/O error occurs */ - private void readObject(final java.io.ObjectInputStream s) + private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { s.defaultReadObject(); if (waitingProducers instanceof FifoWaitQueue) diff --git a/jdk/src/share/classes/java/util/concurrent/package-info.java b/jdk/src/share/classes/java/util/concurrent/package-info.java index b236c290b10..585c769fc7d 100644 --- a/jdk/src/share/classes/java/util/concurrent/package-info.java +++ b/jdk/src/share/classes/java/util/concurrent/package-info.java @@ -210,13 +210,19 @@ * collections are unshared, or are accessible only when * holding other locks. * - *

Most concurrent Collection implementations (including most - * Queues) also differ from the usual java.util conventions in that - * their Iterators provide weakly consistent rather than - * fast-fail traversal. A weakly consistent iterator is thread-safe, - * but does not necessarily freeze the collection while iterating, so - * it may (or may not) reflect any updates since the iterator was - * created. + *

Most concurrent Collection implementations + * (including most Queues) also differ from the usual {@code java.util} + * conventions in that their {@linkplain java.util.Iterator Iterators} + * and {@linkplain java.util.Spliterator Spliterators} provide + * weakly consistent rather than fast-fail traversal: + *

    + *
  • they may proceed concurrently with other operations + *
  • they will never throw {@link java.util.ConcurrentModificationException + * ConcurrentModificationException} + *
  • they are guaranteed to traverse elements as they existed upon + * construction exactly once, and may (but are not guaranteed to) + * reflect any modifications subsequent to construction. + *
* *

Memory Consistency Properties

* From 06e0c4e161c887e96ea0beb9bda6401713725d53 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Fri, 16 Aug 2013 17:02:12 +0200 Subject: [PATCH 006/102] 6417702: Graph in Memory tab is not redrawn immediately if changed via 'Chart' combo box Reviewed-by: alanb, jbachorik, sjiang --- jdk/src/share/classes/sun/tools/jconsole/MemoryTab.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/classes/sun/tools/jconsole/MemoryTab.java b/jdk/src/share/classes/sun/tools/jconsole/MemoryTab.java index 29bed08c5cb..c4a5970b366 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/MemoryTab.java +++ b/jdk/src/share/classes/sun/tools/jconsole/MemoryTab.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2013, 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 @@ -228,6 +228,7 @@ class MemoryTab extends Tab implements ActionListener, ItemListener { if (ev.getStateChange() == ItemEvent.SELECTED) { Plotter plotter = (Plotter)plotterChoice.getSelectedItem(); plotterPanel.setPlotter(plotter); + plotterPanel.repaint(); } } From 2fb1ac860cad488f0de835abb1ded66c2fcb9ae8 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Fri, 16 Aug 2013 17:11:25 +0200 Subject: [PATCH 007/102] 6721425: jconsole Makefile clean rule is missing rm of generated Version.java Reviewed-by: alanb, jbachorik --- jdk/make/sun/jconsole/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/make/sun/jconsole/Makefile b/jdk/make/sun/jconsole/Makefile index 38a53c63962..b859848aad1 100644 --- a/jdk/make/sun/jconsole/Makefile +++ b/jdk/make/sun/jconsole/Makefile @@ -94,4 +94,5 @@ $(JARFILE): $(LIBDIR) $(FILES_class) $(FILES_png) $(FILES_gif) $(FILES_prop) $(T clean clobber:: $(RM) $(TEMPDIR)/manifest $(JARFILE) + $(RM) $(GENSRCDIR)/sun/tools/jconsole/Version.java From 6b503b6a096dbccca53d01b674beb44d77d3100c Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Fri, 16 Aug 2013 16:53:46 +0200 Subject: [PATCH 008/102] 7015157: String "Tabular Navigation" should be rephrased for avoiding mistranslation Reviewed-by: alanb, jbachorik, sjiang --- .../sun/tools/jconsole/resources/messages.properties | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties b/jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties index 03d705f9888..3a222e2800d 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties +++ b/jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties @@ -137,14 +137,14 @@ MBEAN_OPERATION_INFO=MBeanOperationInfo MBEANS=MBeans MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON=&Clear MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON_TOOLTIP=Clear notifications -MBEANS_TAB_COMPOSITE_NAVIGATION_MULTIPLE=Composite Navigation {0}/{1} -MBEANS_TAB_COMPOSITE_NAVIGATION_SINGLE=Composite Navigation +MBEANS_TAB_COMPOSITE_NAVIGATION_MULTIPLE=Composite Data Navigation {0}/{1} +MBEANS_TAB_COMPOSITE_NAVIGATION_SINGLE=Composite Data Navigation MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON=&Refresh MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON_TOOLTIP=Refresh attributes MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON=&Subscribe MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP=Start listening for notifications -MBEANS_TAB_TABULAR_NAVIGATION_MULTIPLE=Tabular Navigation {0}/{1} -MBEANS_TAB_TABULAR_NAVIGATION_SINGLE=Tabular Navigation +MBEANS_TAB_TABULAR_NAVIGATION_MULTIPLE=Tabular Data Navigation {0}/{1} +MBEANS_TAB_TABULAR_NAVIGATION_SINGLE=Tabular Data Navigation MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON=&Unsubscribe MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP=Stop listening for notifications MANAGE_HOTSPOT_MBEANS_IN_COLON_=Manage Hotspot MBeans in: From 90a9913da7ebadabee59601a1197f1c4b8610fc9 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Fri, 16 Aug 2013 18:58:36 +0200 Subject: [PATCH 009/102] 6696970: Jconsole becomes unusable if a plugin throws an exception Reviewed-by: mchung, jbachorik --- .../tools/jconsole/ExceptionSafePlugin.java | 126 ++++++++++++++++++ .../classes/sun/tools/jconsole/Messages.java | 5 + .../classes/sun/tools/jconsole/VMPanel.java | 12 +- .../jconsole/resources/messages.properties | 5 + 4 files changed, 142 insertions(+), 6 deletions(-) create mode 100644 jdk/src/share/classes/sun/tools/jconsole/ExceptionSafePlugin.java diff --git a/jdk/src/share/classes/sun/tools/jconsole/ExceptionSafePlugin.java b/jdk/src/share/classes/sun/tools/jconsole/ExceptionSafePlugin.java new file mode 100644 index 00000000000..bd1c83ee7ee --- /dev/null +++ b/jdk/src/share/classes/sun/tools/jconsole/ExceptionSafePlugin.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package sun.tools.jconsole; + +import java.util.HashMap; +import java.util.Map; + +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.SwingWorker; + +import com.sun.tools.jconsole.JConsolePlugin; + +/** + * Proxy that shields GUI from plug-in exceptions. + * + */ +final class ExceptionSafePlugin extends JConsolePlugin { + + private static boolean ignoreExceptions; + private final JConsolePlugin plugin; + + public ExceptionSafePlugin(JConsolePlugin plugin) { + this.plugin = plugin; + } + + @Override + public Map getTabs() { + try { + return plugin.getTabs(); + } catch (RuntimeException e) { + handleException(e); + } + return new HashMap<>(); + } + + @Override + public SwingWorker newSwingWorker() { + try { + return plugin.newSwingWorker(); + } catch (RuntimeException e) { + handleException(e); + } + return null; + } + + @Override + public void dispose() { + try { + plugin.dispose(); + } catch (RuntimeException e) { + handleException(e); + } + } + + public void executeSwingWorker(SwingWorker sw) { + try { + sw.execute(); + } catch (RuntimeException e) { + handleException(e); + } + } + + private void handleException(Exception e) { + if (JConsole.isDebug()) { + System.err.println("Plug-in exception:"); + e.printStackTrace(); + } else { + if (!ignoreExceptions) { + showExceptionDialog(e); + } + } + } + + private void showExceptionDialog(Exception e) { + Object[] buttonTexts = { + Messages.PLUGIN_EXCEPTION_DIALOG_BUTTON_OK, + Messages.PLUGIN_EXCEPTION_DIALOG_BUTTON_EXIT, + Messages.PLUGIN_EXCEPTION_DIALOG_BUTTON_IGNORE + }; + + String message = String.format( + Messages.PLUGIN_EXCEPTION_DIALOG_MESSAGE, + plugin.getClass().getSimpleName(), + String.valueOf(e.getMessage()) + ); + + int buttonIndex = JOptionPane.showOptionDialog( + null, + message, + Messages.PLUGIN_EXCEPTION_DIALOG_TITLE, + JOptionPane.YES_NO_CANCEL_OPTION, + JOptionPane.ERROR_MESSAGE, + null, + buttonTexts, + buttonTexts[0] + ); + + if (buttonIndex == 1) { + System.exit(0); + } + ignoreExceptions = buttonIndex == 2; + } +} diff --git a/jdk/src/share/classes/sun/tools/jconsole/Messages.java b/jdk/src/share/classes/sun/tools/jconsole/Messages.java index c566a444749..0e5fd76bd20 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/Messages.java +++ b/jdk/src/share/classes/sun/tools/jconsole/Messages.java @@ -240,6 +240,11 @@ final public class Messages { public static String PLOTTER_ACCESSIBLE_NAME_NO_DATA; public static String PLOTTER_SAVE_AS_MENU_ITEM; public static String PLOTTER_TIME_RANGE_MENU; + public static String PLUGIN_EXCEPTION_DIALOG_BUTTON_EXIT; + public static String PLUGIN_EXCEPTION_DIALOG_BUTTON_IGNORE; + public static String PLUGIN_EXCEPTION_DIALOG_BUTTON_OK; + public static String PLUGIN_EXCEPTION_DIALOG_MESSAGE; + public static String PLUGIN_EXCEPTION_DIALOG_TITLE; public static String PROBLEM_ADDING_LISTENER; public static String PROBLEM_DISPLAYING_MBEAN; public static String PROBLEM_INVOKING; diff --git a/jdk/src/share/classes/sun/tools/jconsole/VMPanel.java b/jdk/src/share/classes/sun/tools/jconsole/VMPanel.java index f72f1e20315..b7a0f5b410b 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/VMPanel.java +++ b/jdk/src/share/classes/sun/tools/jconsole/VMPanel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2013, 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 @@ -71,7 +71,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { // Each VMPanel has its own instance of the JConsolePlugin // A map of JConsolePlugin to the previous SwingWorker - private Map> plugins = null; + private Map> plugins = null; private boolean pluginTabsAdded = false; // Update these only on the EDT @@ -107,10 +107,10 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { } } - plugins = new LinkedHashMap>(); + plugins = new LinkedHashMap>(); for (JConsolePlugin p : JConsole.getPlugins()) { p.setContext(proxyClient); - plugins.put(p, null); + plugins.put(new ExceptionSafePlugin(p), null); } Utilities.updateTransparency(this); @@ -566,7 +566,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { } // plugin GUI update - for (JConsolePlugin p : plugins.keySet()) { + for (ExceptionSafePlugin p : plugins.keySet()) { SwingWorker sw = p.newSwingWorker(); SwingWorker prevSW = plugins.get(p); // schedule SwingWorker to run only if the previous @@ -575,7 +575,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { if (sw == null || sw.getState() == SwingWorker.StateValue.PENDING) { plugins.put(p, sw); if (sw != null) { - sw.execute(); + p.executeSwingWorker(sw); } } } diff --git a/jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties b/jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties index 3a222e2800d..ef0b4f136e4 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties +++ b/jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties @@ -198,6 +198,11 @@ PLOTTER_ACCESSIBLE_NAME_KEY_AND_VALUE={0}={1}\n PLOTTER_ACCESSIBLE_NAME_NO_DATA=No data plotted. PLOTTER_SAVE_AS_MENU_ITEM=Save data &as... PLOTTER_TIME_RANGE_MENU=&Time Range +PLUGIN_EXCEPTION_DIALOG_BUTTON_EXIT=Exit +PLUGIN_EXCEPTION_DIALOG_BUTTON_IGNORE=Ignore +PLUGIN_EXCEPTION_DIALOG_BUTTON_OK=OK +PLUGIN_EXCEPTION_DIALOG_MESSAGE=An unexpected exception has occurred in %s:\n\n%s\n\nStart with -debug for details. Ignore will suppress further exceptions. +PLUGIN_EXCEPTION_DIALOG_TITLE=Plug-in exception PROBLEM_ADDING_LISTENER=Problem adding listener PROBLEM_DISPLAYING_MBEAN=Problem displaying MBean PROBLEM_INVOKING=Problem invoking From 3eae3a200c26c6d0084940d7062e169c8ee0a032 Mon Sep 17 00:00:00 2001 From: Aleksei Efimov Date: Fri, 16 Aug 2013 18:41:35 +0400 Subject: [PATCH 010/102] 8021820: Number of opened files used in select() is limited to 1024 [macosx] Reviewed-by: alanb, chegar, tbell, smarks --- .../java/net/ServerSocket/SelectFdsLimit.java | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 jdk/test/java/net/ServerSocket/SelectFdsLimit.java diff --git a/jdk/test/java/net/ServerSocket/SelectFdsLimit.java b/jdk/test/java/net/ServerSocket/SelectFdsLimit.java new file mode 100644 index 00000000000..2ecb1a28e1e --- /dev/null +++ b/jdk/test/java/net/ServerSocket/SelectFdsLimit.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013, 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 8021820 + * @summary The total number of file descriptors is limited to + * 1024(FDSET_SIZE) on MacOSX (the size of fd array passed to select() + * call in java.net classes is limited to this value). + * @run main/othervm SelectFdsLimit + * @author aleksej.efimov@oracle.com + */ + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.ServerSocket; +import java.net.SocketTimeoutException; + + +/* + * Test must be run in othervm mode to ensure that all files + * opened by openFiles() are closed propertly. +*/ +public class SelectFdsLimit { + static final int FDTOOPEN = 1023; + static final String TESTFILE = "testfile"; + static FileInputStream [] testFIS; + + static void prepareTestEnv() throws IOException { + File fileToCreate = new File(TESTFILE); + if (!fileToCreate.exists()) + if (!fileToCreate.createNewFile()) + throw new RuntimeException("Can't create test file"); + } + + //If there will be some problem (i.e. ulimits on number of opened files will fail) + //then this method will fail with exception and test will be considered as + //failed. But allocated fds will be released because the test is executed by + //dedicated VM (@run main/othervm). + static void openFiles(int fn, File f) throws FileNotFoundException, IOException { + testFIS = new FileInputStream[FDTOOPEN]; + for (;;) { + if (0 == fn) + break; + FileInputStream fis = new FileInputStream(f); + testFIS[--fn] = fis; + } + } + + public static void main(String [] args) throws IOException, FileNotFoundException { + + //The bug 8021820 is a Mac specific and because of that test will pass on all + //other platforms + if (!System.getProperty("os.name").contains("OS X")) { + return; + } + + //Create test directory with test files + prepareTestEnv(); + + //Consume FD ids for this java process to overflow the 1024 + openFiles(FDTOOPEN,new File(TESTFILE)); + + //Wait for incoming connection and make the select() used in java.net + //classes fail the limitation on FDSET_SIZE + ServerSocket socket = new ServerSocket(0); + + //Set the minimal timeout, no one is + //going to connect to this server socket + socket.setSoTimeout(1); + + // The accept() call will throw SocketException if the + // select() has failed due to limitation on fds size, + // indicating test failure. A SocketTimeoutException + // is expected, so it is caught and ignored, and the test + // passes. + try { + socket.accept(); + } catch (SocketTimeoutException e) { } + } +} From 5d38b44a3e3cbf2c59634abfe257d8a7cc0fcad6 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Mon, 19 Aug 2013 11:04:21 +0100 Subject: [PATCH 011/102] 8023215: test/java/util/Comparator/TypeTest.java not running (failing but reported as passing) Reviewed-by: psandoz --- jdk/test/java/util/Comparator/TypeTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/test/java/util/Comparator/TypeTest.java b/jdk/test/java/util/Comparator/TypeTest.java index b1c8a41cf3a..69ae983197f 100644 --- a/jdk/test/java/util/Comparator/TypeTest.java +++ b/jdk/test/java/util/Comparator/TypeTest.java @@ -75,7 +75,7 @@ public class TypeTest { } } - public static void main(String[] args) { + public void testOrder() { Manager m1 = new Manager("Manager", 2, 2000); Manager m2 = new Manager("Manager", 4, 1300); From 7647c6e6a1bb514916ad17878db3f4cc3de30aa5 Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Tue, 6 Aug 2013 14:26:34 +0100 Subject: [PATCH 012/102] 8014824: Document Spliterator characteristics and binding policy of java util collection impls Reviewed-by: chegar --- .../share/classes/java/util/ArrayDeque.java | 13 +++++++ .../share/classes/java/util/ArrayList.java | 14 +++++++ jdk/src/share/classes/java/util/HashSet.java | 12 ++++++ .../classes/java/util/LinkedHashMap.java | 10 +++++ .../classes/java/util/LinkedHashSet.java | 20 +++++++--- .../share/classes/java/util/LinkedList.java | 17 +++++++++ jdk/src/share/classes/java/util/List.java | 2 +- .../classes/java/util/PriorityQueue.java | 13 +++++++ jdk/src/share/classes/java/util/Set.java | 2 +- .../share/classes/java/util/SortedSet.java | 2 +- .../share/classes/java/util/Spliterator.java | 6 ++- jdk/src/share/classes/java/util/TreeMap.java | 38 +++++++++++++++---- jdk/src/share/classes/java/util/TreeSet.java | 19 ++++++++++ jdk/src/share/classes/java/util/Vector.java | 13 +++++++ 14 files changed, 165 insertions(+), 16 deletions(-) diff --git a/jdk/src/share/classes/java/util/ArrayDeque.java b/jdk/src/share/classes/java/util/ArrayDeque.java index 0e20ffc52ef..9e77f6dba5f 100644 --- a/jdk/src/share/classes/java/util/ArrayDeque.java +++ b/jdk/src/share/classes/java/util/ArrayDeque.java @@ -888,6 +888,19 @@ public class ArrayDeque extends AbstractCollection elements[i] = s.readObject(); } + /** + * Creates a late-binding + * and fail-fast {@link Spliterator} over the elements in this + * deque. + * + *

The {@code Spliterator} reports {@link Spliterator#SIZED}, + * {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and + * {@link Spliterator#NONNULL}. Overriding implementations should document + * the reporting of additional characteristic values. + * + * @return a {@code Spliterator} over the elements in this deque + * @since 1.8 + */ public Spliterator spliterator() { return new DeqSpliterator(this, -1, -1); } diff --git a/jdk/src/share/classes/java/util/ArrayList.java b/jdk/src/share/classes/java/util/ArrayList.java index b7d5349cc00..dae280dcde2 100644 --- a/jdk/src/share/classes/java/util/ArrayList.java +++ b/jdk/src/share/classes/java/util/ArrayList.java @@ -1238,6 +1238,20 @@ public class ArrayList extends AbstractList } } + /** + * Creates a late-binding + * and fail-fast {@link Spliterator} over the elements in this + * list. + * + *

The {@code Spliterator} reports {@link Spliterator#SIZED}, + * {@link Spliterator#SUBSIZED}, and {@link Spliterator#ORDERED}. + * Overriding implementations should document the reporting of additional + * characteristic values. + * + * @return a {@code Spliterator} over the elements in this list + * @since 1.8 + */ + @Override public Spliterator spliterator() { return new ArrayListSpliterator<>(this, 0, -1, 0); } diff --git a/jdk/src/share/classes/java/util/HashSet.java b/jdk/src/share/classes/java/util/HashSet.java index 002b80cbe68..6ab58d0edf8 100644 --- a/jdk/src/share/classes/java/util/HashSet.java +++ b/jdk/src/share/classes/java/util/HashSet.java @@ -312,6 +312,18 @@ public class HashSet } } + /** + * Creates a late-binding + * and fail-fast {@link Spliterator} over the elements in this + * set. + * + *

The {@code Spliterator} reports {@link Spliterator#SIZED} and + * {@link Spliterator#DISTINCT}. Overriding implementations should document + * the reporting of additional characteristic values. + * + * @return a {@code Spliterator} over the elements in this set + * @since 1.8 + */ public Spliterator spliterator() { return new HashMap.KeySpliterator(map, 0, -1, 0, 0); } diff --git a/jdk/src/share/classes/java/util/LinkedHashMap.java b/jdk/src/share/classes/java/util/LinkedHashMap.java index ee9c221ef10..feb1005b2aa 100644 --- a/jdk/src/share/classes/java/util/LinkedHashMap.java +++ b/jdk/src/share/classes/java/util/LinkedHashMap.java @@ -129,10 +129,20 @@ import java.util.function.BiFunction; * exception for its correctness: the fail-fast behavior of iterators * should be used only to detect bugs. * + *

The spliterators returned by the spliterator method of the collections + * returned by all of this class's collection view methods are + * late-binding, + * fail-fast, and additionally report {@link Spliterator#ORDERED}. + * *

This class is a member of the * * Java Collections Framework. * + * @implNote + * The spliterators returned by the spliterator method of the collections + * returned by all of this class's collection view methods are created from + * the iterators of the corresponding collections. + * * @param the type of keys maintained by this map * @param the type of mapped values * diff --git a/jdk/src/share/classes/java/util/LinkedHashSet.java b/jdk/src/share/classes/java/util/LinkedHashSet.java index c66015aac6f..08606cfe4cf 100644 --- a/jdk/src/share/classes/java/util/LinkedHashSet.java +++ b/jdk/src/share/classes/java/util/LinkedHashSet.java @@ -170,13 +170,23 @@ public class LinkedHashSet } /** - * Creates a {@code Spliterator}, over the elements in this set, that - * reports {@code SIZED}, {@code DISTINCT} and {@code ORDERED}. - * Overriding implementations are expected to document if the - * {@code Spliterator} reports any additional and relevant characteristic - * values. + * Creates a late-binding + * and fail-fast {@code Spliterator} over the elements in this set. + * + *

The {@code Spliterator} reports {@link Spliterator#SIZED}, + * {@link Spliterator#DISTINCT}, and {@code ORDERED}. Implementations + * should document the reporting of additional characteristic values. + * + * @implNote + * The implementation creates a + * late-binding spliterator + * from the set's {@code Iterator}. The spliterator inherits the + * fail-fast properties of the set's iterator. + * The created {@code Spliterator} additionally reports + * {@link Spliterator#SUBSIZED}. * * @return a {@code Spliterator} over the elements in this set + * @since 1.8 */ @Override public Spliterator spliterator() { diff --git a/jdk/src/share/classes/java/util/LinkedList.java b/jdk/src/share/classes/java/util/LinkedList.java index 4d0f6dbca92..6c0626b433f 100644 --- a/jdk/src/share/classes/java/util/LinkedList.java +++ b/jdk/src/share/classes/java/util/LinkedList.java @@ -1149,6 +1149,23 @@ public class LinkedList linkLast((E)s.readObject()); } + /** + * Creates a late-binding + * and fail-fast {@link Spliterator} over the elements in this + * list. + * + *

The {@code Spliterator} reports {@link Spliterator#SIZED} and + * {@link Spliterator#ORDERED}. Overriding implementations should document + * the reporting of additional characteristic values. + * + * @implNote + * The {@code Spliterator} additionally reports {@link Spliterator#SUBSIZED} + * and implements {@code trySplit} to permit limited parallelism.. + * + * @return a {@code Spliterator} over the elements in this list + * @since 1.8 + */ + @Override public Spliterator spliterator() { return new LLSpliterator(this, -1, 0); } diff --git a/jdk/src/share/classes/java/util/List.java b/jdk/src/share/classes/java/util/List.java index 11104ab760e..65ad1404c38 100644 --- a/jdk/src/share/classes/java/util/List.java +++ b/jdk/src/share/classes/java/util/List.java @@ -671,7 +671,7 @@ public interface List extends Collection { * The default implementation creates a * late-binding spliterator * from the list's {@code Iterator}. The spliterator inherits the - * fail-fast properties of the collection's iterator. + * fail-fast properties of the list's iterator. * * @implNote * The created {@code Spliterator} additionally reports diff --git a/jdk/src/share/classes/java/util/PriorityQueue.java b/jdk/src/share/classes/java/util/PriorityQueue.java index 6a31f3ee292..645497530a7 100644 --- a/jdk/src/share/classes/java/util/PriorityQueue.java +++ b/jdk/src/share/classes/java/util/PriorityQueue.java @@ -795,6 +795,19 @@ public class PriorityQueue extends AbstractQueue heapify(); } + /** + * Creates a late-binding + * and fail-fast {@link Spliterator} over the elements in this + * queue. + * + *

The {@code Spliterator} reports {@link Spliterator#SIZED}, + * {@link Spliterator#SUBSIZED}, and {@link Spliterator#NONNULL}. + * Overriding implementations should document the reporting of additional + * characteristic values. + * + * @return a {@code Spliterator} over the elements in this queue + * @since 1.8 + */ public final Spliterator spliterator() { return new PriorityQueueSpliterator(this, 0, -1, 0); } diff --git a/jdk/src/share/classes/java/util/Set.java b/jdk/src/share/classes/java/util/Set.java index 78da633f1da..d47a06a4a8a 100644 --- a/jdk/src/share/classes/java/util/Set.java +++ b/jdk/src/share/classes/java/util/Set.java @@ -394,7 +394,7 @@ public interface Set extends Collection { * The default implementation creates a * late-binding spliterator * from the set's {@code Iterator}. The spliterator inherits the - * fail-fast properties of the collection's iterator. + * fail-fast properties of the set's iterator. * * @implNote * The created {@code Spliterator} additionally reports diff --git a/jdk/src/share/classes/java/util/SortedSet.java b/jdk/src/share/classes/java/util/SortedSet.java index 367d775083f..3e64804e7b5 100644 --- a/jdk/src/share/classes/java/util/SortedSet.java +++ b/jdk/src/share/classes/java/util/SortedSet.java @@ -238,7 +238,7 @@ public interface SortedSet extends Set { * The default implementation creates a * late-binding spliterator * from the sorted set's {@code Iterator}. The spliterator inherits the - * fail-fast properties of the collection's iterator. The + * fail-fast properties of the set's iterator. The * spliterator's comparator is the same as the sorted set's comparator. * * @implNote diff --git a/jdk/src/share/classes/java/util/Spliterator.java b/jdk/src/share/classes/java/util/Spliterator.java index e3477cf7b7b..542aec76cde 100644 --- a/jdk/src/share/classes/java/util/Spliterator.java +++ b/jdk/src/share/classes/java/util/Spliterator.java @@ -74,7 +74,11 @@ import java.util.function.LongConsumer; * source prior to binding are reflected when the Spliterator is traversed. * After binding a Spliterator should, on a best-effort basis, throw * {@link ConcurrentModificationException} if structural interference is - * detected. Spliterators that do this are called fail-fast. + * detected. Spliterators that do this are called fail-fast. The + * bulk traversal method ({@link #forEachRemaining forEachRemaining()}) of a + * Spliterator may optimize traversal and check for structural interference + * after all elements have been traversed, rather than checking per-element and + * failing immediately. * *

Spliterators can provide an estimate of the number of remaining elements * via the {@link #estimateSize} method. Ideally, as reflected in characteristic diff --git a/jdk/src/share/classes/java/util/TreeMap.java b/jdk/src/share/classes/java/util/TreeMap.java index 5c61d4f71ee..52d9df25a0b 100644 --- a/jdk/src/share/classes/java/util/TreeMap.java +++ b/jdk/src/share/classes/java/util/TreeMap.java @@ -790,8 +790,19 @@ public class TreeMap /** * Returns a {@link Set} view of the keys contained in this map. - * The set's iterator returns the keys in ascending order. - * The set is backed by the map, so changes to the map are + * + *

The set's iterator returns the keys in ascending order. + * The set's spliterator is + * late-binding, + * fail-fast, and additionally reports {@link Spliterator#SORTED} + * and {@link Spliterator#ORDERED} with an encounter order that is ascending + * key order. The spliterator's comparator (see + * {@link java.util.Spliterator#getComparator()}) is {@code null} if + * the tree map's comparator (see {@link #comparator()}) is {@code null}. + * Otherwise, the spliterator's comparator is the same as or imposes the + * same total ordering as the tree map's comparator. + * + *

The set is backed by the map, so changes to the map are * reflected in the set, and vice-versa. If the map is modified * while an iteration over the set is in progress (except through * the iterator's own {@code remove} operation), the results of @@ -823,9 +834,15 @@ public class TreeMap /** * Returns a {@link Collection} view of the values contained in this map. - * The collection's iterator returns the values in ascending order - * of the corresponding keys. - * The collection is backed by the map, so changes to the map are + * + *

The collection's iterator returns the values in ascending order + * of the corresponding keys. The collection's spliterator is + * late-binding, + * fail-fast, and additionally reports {@link Spliterator#ORDERED} + * with an encounter order that is ascending order of the corresponding + * keys. + * + *

The collection is backed by the map, so changes to the map are * reflected in the collection, and vice-versa. If the map is * modified while an iteration over the collection is in progress * (except through the iterator's own {@code remove} operation), @@ -843,8 +860,15 @@ public class TreeMap /** * Returns a {@link Set} view of the mappings contained in this map. - * The set's iterator returns the entries in ascending key order. - * The set is backed by the map, so changes to the map are + * + *

The set's iterator returns the entries in ascending key order. The + * sets's spliterator is + * late-binding, + * fail-fast, and additionally reports {@link Spliterator#SORTED} and + * {@link Spliterator#ORDERED} with an encounter order that is ascending key + * order. + * + *

The set is backed by the map, so changes to the map are * reflected in the set, and vice-versa. If the map is modified * while an iteration over the set is in progress (except through * the iterator's own {@code remove} operation, or through the diff --git a/jdk/src/share/classes/java/util/TreeSet.java b/jdk/src/share/classes/java/util/TreeSet.java index 9484d5b87c7..131de860f57 100644 --- a/jdk/src/share/classes/java/util/TreeSet.java +++ b/jdk/src/share/classes/java/util/TreeSet.java @@ -533,6 +533,25 @@ public class TreeSet extends AbstractSet tm.readTreeSet(size, s, PRESENT); } + /** + * Creates a late-binding + * and fail-fast {@link Spliterator} over the elements in this + * set. + * + *

The {@code Spliterator} reports {@link Spliterator#SIZED}, + * {@link Spliterator#DISTINCT}, {@link Spliterator#SORTED}, and + * {@link Spliterator#ORDERED}. Overriding implementations should document + * the reporting of additional characteristic values. + * + *

The spliterator's comparator (see + * {@link java.util.Spliterator#getComparator()}) is {@code null} if + * the tree set's comparator (see {@link #comparator()}) is {@code null}. + * Otherwise, the spliterator's comparator is the same as or imposes the + * same total ordering as the tree set's comparator. + * + * @return a {@code Spliterator} over the elements in this set + * @since 1.8 + */ public Spliterator spliterator() { return TreeMap.keySpliteratorFor(m); } diff --git a/jdk/src/share/classes/java/util/Vector.java b/jdk/src/share/classes/java/util/Vector.java index 6146957dfd6..ef6540e59b0 100644 --- a/jdk/src/share/classes/java/util/Vector.java +++ b/jdk/src/share/classes/java/util/Vector.java @@ -1323,6 +1323,19 @@ public class Vector modCount++; } + /** + * Creates a late-binding + * and fail-fast {@link Spliterator} over the elements in this + * list. + * + *

The {@code Spliterator} reports {@link Spliterator#SIZED}, + * {@link Spliterator#SUBSIZED}, and {@link Spliterator#ORDERED}. + * Overriding implementations should document the reporting of additional + * characteristic values. + * + * @return a {@code Spliterator} over the elements in this list + * @since 1.8 + */ @Override public Spliterator spliterator() { return new VectorSpliterator<>(this, null, 0, -1, 0); From 6e609cbc6483a377d65b7402fece40e0ea531077 Mon Sep 17 00:00:00 2001 From: Omair Majid Date: Tue, 6 Aug 2013 12:28:46 -0400 Subject: [PATCH 013/102] 8022188: Make zero compile after 8016131 and 8016697 Reviewed-by: dholmes, twisti --- hotspot/src/cpu/zero/vm/entryFrame_zero.hpp | 4 ++-- hotspot/src/cpu/zero/vm/frame_zero.inline.hpp | 2 +- .../src/cpu/zero/vm/stubGenerator_zero.cpp | 22 +++++++++++++++++++ .../os_cpu/linux_zero/vm/os_linux_zero.cpp | 10 --------- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/hotspot/src/cpu/zero/vm/entryFrame_zero.hpp b/hotspot/src/cpu/zero/vm/entryFrame_zero.hpp index 434b11adf1f..97b185c3aab 100644 --- a/hotspot/src/cpu/zero/vm/entryFrame_zero.hpp +++ b/hotspot/src/cpu/zero/vm/entryFrame_zero.hpp @@ -58,8 +58,8 @@ class EntryFrame : public ZeroFrame { JavaCallWrapper* call_wrapper, TRAPS); public: - JavaCallWrapper *call_wrapper() const { - return (JavaCallWrapper *) value_of_word(call_wrapper_off); + JavaCallWrapper **call_wrapper() const { + return (JavaCallWrapper **) addr_of_word(call_wrapper_off); } public: diff --git a/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp b/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp index f6bd6d3c6be..971560cd0d8 100644 --- a/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp +++ b/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp @@ -141,7 +141,7 @@ inline intptr_t* frame::id() const { return fp(); } -inline JavaCallWrapper* frame::entry_frame_call_wrapper() const { +inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const { return zero_entryframe()->call_wrapper(); } diff --git a/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp b/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp index f1a280bb4b4..1203c315879 100644 --- a/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp +++ b/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp @@ -176,6 +176,19 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_oop_arraycopy; } + static int SafeFetch32(int *adr, int errValue) { + int value = errValue; + value = *adr; + return value; + } + + static intptr_t SafeFetchN(intptr_t *adr, intptr_t errValue) { + intptr_t value = errValue; + value = *adr; + return value; + } + + void generate_initial() { // Generates all stubs and initializes the entry points @@ -225,6 +238,15 @@ class StubGenerator: public StubCodeGenerator { // arraycopy stubs used by compilers generate_arraycopy_stubs(); + + // Safefetch stubs. + StubRoutines::_safefetch32_entry = CAST_FROM_FN_PTR(address, StubGenerator::SafeFetch32); + StubRoutines::_safefetch32_fault_pc = NULL; + StubRoutines::_safefetch32_continuation_pc = NULL; + + StubRoutines::_safefetchN_entry = CAST_FROM_FN_PTR(address, StubGenerator::SafeFetchN); + StubRoutines::_safefetchN_fault_pc = NULL; + StubRoutines::_safefetchN_continuation_pc = NULL; } public: diff --git a/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp b/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp index de0ba9a6ad5..2618519e2a4 100644 --- a/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp +++ b/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp @@ -410,16 +410,6 @@ extern "C" { int SpinPause() { } - int SafeFetch32(int *adr, int errValue) { - int value = errValue; - value = *adr; - return value; - } - intptr_t SafeFetchN(intptr_t *adr, intptr_t errValue) { - intptr_t value = errValue; - value = *adr; - return value; - } void _Copy_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) { if (from > to) { From 4974d1aef2e7beac482a9ec4dafbea4ad7761a9d Mon Sep 17 00:00:00 2001 From: Serguei Spitsyn Date: Tue, 6 Aug 2013 16:33:59 -0700 Subject: [PATCH 014/102] 7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments Restore the appendix argument after PopFrame() call Reviewed-by: twisti, coleenp --- .../sparc/vm/templateInterpreter_sparc.cpp | 21 +++++++++++++++ .../cpu/x86/vm/templateInterpreter_x86_32.cpp | 23 ++++++++++++++++ .../cpu/x86/vm/templateInterpreter_x86_64.cpp | 23 ++++++++++++++++ .../src/share/vm/classfile/javaClasses.cpp | 21 +++++++++++++++ .../src/share/vm/classfile/javaClasses.hpp | 26 +++++++++++++++++++ .../share/vm/classfile/systemDictionary.hpp | 1 + hotspot/src/share/vm/classfile/vmSymbols.hpp | 2 ++ .../vm/interpreter/interpreterRuntime.cpp | 23 ++++++++++++++++ .../vm/interpreter/interpreterRuntime.hpp | 3 +++ 9 files changed, 143 insertions(+) diff --git a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp index 7b9a494dff0..b6f8a5a5d1a 100644 --- a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp @@ -1887,6 +1887,27 @@ void TemplateInterpreterGenerator::generate_throw_exception() { if (ProfileInterpreter) { __ set_method_data_pointer_for_bcp(); } + +#if INCLUDE_JVMTI + if (EnableInvokeDynamic) { + Label L_done; + + __ ldub(Address(Lbcp, 0), G1_scratch); // Load current bytecode + __ cmp_and_br_short(G1_scratch, Bytecodes::_invokestatic, Assembler::notEqual, Assembler::pn, L_done); + + // The member name argument must be restored if _invokestatic is re-executed after a PopFrame call. + // Detect such a case in the InterpreterRuntime function and return the member name argument, or NULL. + + __ call_VM(G1_scratch, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), I0, Lmethod, Lbcp); + + __ br_null(G1_scratch, false, Assembler::pn, L_done); + __ delayed()->nop(); + + __ st_ptr(G1_scratch, Lesp, wordSize); + __ bind(L_done); + } +#endif // INCLUDE_JVMTI + // Resume bytecode interpretation at the current bcp __ dispatch_next(vtos); // end of JVMTI PopFrame support diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp index 2efa59f8b33..52e459900c7 100644 --- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp @@ -1920,6 +1920,29 @@ void TemplateInterpreterGenerator::generate_throw_exception() { __ get_thread(thread); __ movl(Address(thread, JavaThread::popframe_condition_offset()), JavaThread::popframe_inactive); +#if INCLUDE_JVMTI + if (EnableInvokeDynamic) { + Label L_done; + const Register local0 = rdi; + + __ cmpb(Address(rsi, 0), Bytecodes::_invokestatic); + __ jcc(Assembler::notEqual, L_done); + + // The member name argument must be restored if _invokestatic is re-executed after a PopFrame call. + // Detect such a case in the InterpreterRuntime function and return the member name argument, or NULL. + + __ get_method(rdx); + __ movptr(rax, Address(local0, 0)); + __ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), rax, rdx, rsi); + + __ testptr(rax, rax); + __ jcc(Assembler::zero, L_done); + + __ movptr(Address(rbx, 0), rax); + __ bind(L_done); + } +#endif // INCLUDE_JVMTI + __ dispatch_next(vtos); // end of PopFrame support diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp index f0a2258a70e..4ac85c49578 100644 --- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp @@ -1929,6 +1929,29 @@ void TemplateInterpreterGenerator::generate_throw_exception() { __ movl(Address(r15_thread, JavaThread::popframe_condition_offset()), JavaThread::popframe_inactive); +#if INCLUDE_JVMTI + if (EnableInvokeDynamic) { + Label L_done; + const Register local0 = r14; + + __ cmpb(Address(r13, 0), Bytecodes::_invokestatic); + __ jcc(Assembler::notEqual, L_done); + + // The member name argument must be restored if _invokestatic is re-executed after a PopFrame call. + // Detect such a case in the InterpreterRuntime function and return the member name argument, or NULL. + + __ get_method(rdx); + __ movptr(rax, Address(local0, 0)); + __ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), rax, rdx, r13); + + __ testptr(rax, rax); + __ jcc(Assembler::zero, L_done); + + __ movptr(Address(rbx, 0), rax); + __ bind(L_done); + } +#endif // INCLUDE_JVMTI + __ dispatch_next(vtos); // end of PopFrame support diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp index 678cb2dcd13..8e94d834ad9 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.cpp +++ b/hotspot/src/share/vm/classfile/javaClasses.cpp @@ -2557,6 +2557,26 @@ void java_lang_ref_SoftReference::set_clock(jlong value) { *offset = value; } +// Support for java_lang_invoke_DirectMethodHandle + +int java_lang_invoke_DirectMethodHandle::_member_offset; + +oop java_lang_invoke_DirectMethodHandle::member(oop dmh) { + oop member_name = NULL; + bool is_dmh = dmh->is_oop() && java_lang_invoke_DirectMethodHandle::is_instance(dmh); + assert(is_dmh, "a DirectMethodHandle oop is expected"); + if (is_dmh) { + member_name = dmh->obj_field(member_offset_in_bytes()); + } + return member_name; +} + +void java_lang_invoke_DirectMethodHandle::compute_offsets() { + Klass* klass_oop = SystemDictionary::DirectMethodHandle_klass(); + if (klass_oop != NULL && EnableInvokeDynamic) { + compute_offset(_member_offset, klass_oop, vmSymbols::member_name(), vmSymbols::java_lang_invoke_MemberName_signature()); + } +} // Support for java_lang_invoke_MethodHandle @@ -3205,6 +3225,7 @@ void JavaClasses::compute_offsets() { java_lang_ThreadGroup::compute_offsets(); if (EnableInvokeDynamic) { java_lang_invoke_MethodHandle::compute_offsets(); + java_lang_invoke_DirectMethodHandle::compute_offsets(); java_lang_invoke_MemberName::compute_offsets(); java_lang_invoke_LambdaForm::compute_offsets(); java_lang_invoke_MethodType::compute_offsets(); diff --git a/hotspot/src/share/vm/classfile/javaClasses.hpp b/hotspot/src/share/vm/classfile/javaClasses.hpp index 899d3ba48a3..8a8e801f387 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.hpp +++ b/hotspot/src/share/vm/classfile/javaClasses.hpp @@ -976,6 +976,32 @@ class java_lang_invoke_MethodHandle: AllStatic { static int form_offset_in_bytes() { return _form_offset; } }; +// Interface to java.lang.invoke.DirectMethodHandle objects + +class java_lang_invoke_DirectMethodHandle: AllStatic { + friend class JavaClasses; + + private: + static int _member_offset; // the MemberName of this DMH + + static void compute_offsets(); + + public: + // Accessors + static oop member(oop mh); + + // Testers + static bool is_subclass(Klass* klass) { + return klass->is_subclass_of(SystemDictionary::DirectMethodHandle_klass()); + } + static bool is_instance(oop obj) { + return obj != NULL && is_subclass(obj->klass()); + } + + // Accessors for code generation: + static int member_offset_in_bytes() { return _member_offset; } +}; + // Interface to java.lang.invoke.LambdaForm objects // (These are a private interface for managing adapter code generation.) diff --git a/hotspot/src/share/vm/classfile/systemDictionary.hpp b/hotspot/src/share/vm/classfile/systemDictionary.hpp index a2a1a857517..85735a732fa 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.hpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp @@ -151,6 +151,7 @@ class SymbolPropertyTable; do_klass(reflect_CallerSensitive_klass, sun_reflect_CallerSensitive, Opt ) \ \ /* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \ + do_klass(DirectMethodHandle_klass, java_lang_invoke_DirectMethodHandle, Opt ) \ do_klass(MethodHandle_klass, java_lang_invoke_MethodHandle, Pre_JSR292 ) \ do_klass(MemberName_klass, java_lang_invoke_MemberName, Pre_JSR292 ) \ do_klass(MethodHandleNatives_klass, java_lang_invoke_MethodHandleNatives, Pre_JSR292 ) \ diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp index df370237167..067cf503305 100644 --- a/hotspot/src/share/vm/classfile/vmSymbols.hpp +++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp @@ -255,6 +255,7 @@ /* Support for JSR 292 & invokedynamic (JDK 1.7 and above) */ \ template(java_lang_invoke_CallSite, "java/lang/invoke/CallSite") \ template(java_lang_invoke_ConstantCallSite, "java/lang/invoke/ConstantCallSite") \ + template(java_lang_invoke_DirectMethodHandle, "java/lang/invoke/DirectMethodHandle") \ template(java_lang_invoke_MutableCallSite, "java/lang/invoke/MutableCallSite") \ template(java_lang_invoke_VolatileCallSite, "java/lang/invoke/VolatileCallSite") \ template(java_lang_invoke_MethodHandle, "java/lang/invoke/MethodHandle") \ @@ -352,6 +353,7 @@ template(thread_id_name, "tid") \ template(newInstance0_name, "newInstance0") \ template(limit_name, "limit") \ + template(member_name, "member") \ template(forName_name, "forName") \ template(forName0_name, "forName0") \ template(isJavaIdentifierStart_name, "isJavaIdentifierStart") \ diff --git a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp index f5f9d39bcec..4a3019f867f 100644 --- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp +++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp @@ -1209,3 +1209,26 @@ IRT_LEAF(void, InterpreterRuntime::popframe_move_outgoing_args(JavaThread* threa size_of_arguments * Interpreter::stackElementSize); IRT_END #endif + +#if INCLUDE_JVMTI +// This is a support of the JVMTI PopFrame interface. +// Make sure it is an invokestatic of a polymorphic intrinsic that has a member_name argument +// and return it as a vm_result so that it can be reloaded in the list of invokestatic parameters. +// The dmh argument is a reference to a DirectMethoHandle that has a member name field. +IRT_ENTRY(void, InterpreterRuntime::member_name_arg_or_null(JavaThread* thread, address dmh, + Method* method, address bcp)) + Bytecodes::Code code = Bytecodes::code_at(method, bcp); + if (code != Bytecodes::_invokestatic) { + return; + } + ConstantPool* cpool = method->constants(); + int cp_index = Bytes::get_native_u2(bcp + 1) + ConstantPool::CPCACHE_INDEX_TAG; + Symbol* cname = cpool->klass_name_at(cpool->klass_ref_index_at(cp_index)); + Symbol* mname = cpool->name_ref_at(cp_index); + + if (MethodHandles::has_member_arg(cname, mname)) { + oop member_name = java_lang_invoke_DirectMethodHandle::member((oop)dmh); + thread->set_vm_result(member_name); + } +IRT_END +#endif // INCLUDE_JVMTI diff --git a/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp b/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp index d46c43e94e0..ad44210ef4d 100644 --- a/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp +++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp @@ -95,6 +95,9 @@ class InterpreterRuntime: AllStatic { static void create_exception(JavaThread* thread, char* name, char* message); static void create_klass_exception(JavaThread* thread, char* name, oopDesc* obj); static address exception_handler_for_exception(JavaThread* thread, oopDesc* exception); +#if INCLUDE_JVMTI + static void member_name_arg_or_null(JavaThread* thread, address dmh, Method* m, address bcp); +#endif static void throw_pending_exception(JavaThread* thread); // Statics & fields From 27f8eea2ea77967cc031b89ed947518118a5747f Mon Sep 17 00:00:00 2001 From: Krystal Mok Date: Wed, 7 Aug 2013 19:02:06 +0400 Subject: [PATCH 015/102] 8021771: warning stat64 is deprecated - when building on OSX 10.7.5 Stat64 have to be replaced with stat Reviewed-by: dholmes, kmo --- hotspot/src/os/bsd/vm/attachListener_bsd.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hotspot/src/os/bsd/vm/attachListener_bsd.cpp b/hotspot/src/os/bsd/vm/attachListener_bsd.cpp index 6f128f2543b..4a580b486fc 100644 --- a/hotspot/src/os/bsd/vm/attachListener_bsd.cpp +++ b/hotspot/src/os/bsd/vm/attachListener_bsd.cpp @@ -445,14 +445,14 @@ AttachOperation* AttachListener::dequeue() { void AttachListener::vm_start() { char fn[UNIX_PATH_MAX]; - struct stat64 st; + struct stat st; int ret; int n = snprintf(fn, UNIX_PATH_MAX, "%s/.java_pid%d", os::get_temp_directory(), os::current_process_id()); assert(n < (int)UNIX_PATH_MAX, "java_pid file name buffer overflow"); - RESTARTABLE(::stat64(fn, &st), ret); + RESTARTABLE(::stat(fn, &st), ret); if (ret == 0) { ret = ::unlink(fn); if (ret == -1) { From bfe8385fa92603a9989b505e523cf1525e86b279 Mon Sep 17 00:00:00 2001 From: Niclas Adlertz Date: Wed, 7 Aug 2013 17:56:19 +0200 Subject: [PATCH 016/102] 8022284: Hide internal data structure in PhaseCFG Hide private node to block mapping using public interface Reviewed-by: kvn, roland --- .../sun/jvm/hotspot/opto/PhaseCFG.java | 2 +- hotspot/src/share/vm/opto/block.cpp | 113 ++++++++------- hotspot/src/share/vm/opto/block.hpp | 59 +++++--- hotspot/src/share/vm/opto/buildOopMap.cpp | 19 ++- hotspot/src/share/vm/opto/chaitin.cpp | 32 ++-- hotspot/src/share/vm/opto/coalesce.cpp | 36 +++-- hotspot/src/share/vm/opto/compile.cpp | 4 +- hotspot/src/share/vm/opto/domgraph.cpp | 4 +- hotspot/src/share/vm/opto/gcm.cpp | 137 +++++++++--------- .../src/share/vm/opto/idealGraphPrinter.cpp | 6 +- hotspot/src/share/vm/opto/ifg.cpp | 4 +- hotspot/src/share/vm/opto/lcm.cpp | 97 +++++++------ hotspot/src/share/vm/opto/live.cpp | 10 +- hotspot/src/share/vm/opto/node.hpp | 1 - hotspot/src/share/vm/opto/output.cpp | 37 +++-- hotspot/src/share/vm/opto/output.hpp | 3 - hotspot/src/share/vm/opto/postaloc.cpp | 19 ++- hotspot/src/share/vm/opto/reg_split.cpp | 22 +-- hotspot/src/share/vm/runtime/vmStructs.cpp | 2 +- 19 files changed, 327 insertions(+), 280 deletions(-) diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/PhaseCFG.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/PhaseCFG.java index 2530f1af7a7..66344b553f6 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/PhaseCFG.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/opto/PhaseCFG.java @@ -44,7 +44,7 @@ public class PhaseCFG extends Phase { Type type = db.lookupType("PhaseCFG"); numBlocksField = new CIntField(type.getCIntegerField("_num_blocks"), 0); blocksField = type.getAddressField("_blocks"); - bbsField = type.getAddressField("_bbs"); + bbsField = type.getAddressField("_node_to_block_mapping"); brootField = type.getAddressField("_broot"); } diff --git a/hotspot/src/share/vm/opto/block.cpp b/hotspot/src/share/vm/opto/block.cpp index 0aa41de0120..9153d070886 100644 --- a/hotspot/src/share/vm/opto/block.cpp +++ b/hotspot/src/share/vm/opto/block.cpp @@ -221,7 +221,7 @@ bool Block::has_uncommon_code() const { //------------------------------is_uncommon------------------------------------ // True if block is low enough frequency or guarded by a test which // mostly does not go here. -bool Block::is_uncommon( Block_Array &bbs ) const { +bool Block::is_uncommon(PhaseCFG* cfg) const { // Initial blocks must never be moved, so are never uncommon. if (head()->is_Root() || head()->is_Start()) return false; @@ -238,7 +238,7 @@ bool Block::is_uncommon( Block_Array &bbs ) const { uint uncommon_for_freq_preds = 0; for( uint i=1; i_idx]; + Block* guard = cfg->get_block_for_node(pred(i)); // Check to see if this block follows its guard 1 time out of 10000 // or less. // @@ -285,11 +285,11 @@ void Block::dump_bidx(const Block* orig, outputStream* st) const { } } -void Block::dump_pred(const Block_Array *bbs, Block* orig, outputStream* st) const { +void Block::dump_pred(const PhaseCFG* cfg, Block* orig, outputStream* st) const { if (is_connector()) { for (uint i=1; i_idx]); - p->dump_pred(bbs, orig, st); + Block *p = cfg->get_block_for_node(pred(i)); + p->dump_pred(cfg, orig, st); } } else { dump_bidx(orig, st); @@ -297,7 +297,7 @@ void Block::dump_pred(const Block_Array *bbs, Block* orig, outputStream* st) con } } -void Block::dump_head( const Block_Array *bbs, outputStream* st ) const { +void Block::dump_head(const PhaseCFG* cfg, outputStream* st) const { // Print the basic block dump_bidx(this, st); st->print(": #\t"); @@ -311,26 +311,28 @@ void Block::dump_head( const Block_Array *bbs, outputStream* st ) const { if( head()->is_block_start() ) { for (uint i=1; i_idx]; - p->dump_pred(bbs, p, st); + if (cfg != NULL) { + Block *p = cfg->get_block_for_node(s); + p->dump_pred(cfg, p, st); } else { while (!s->is_block_start()) s = s->in(0); st->print("N%d ", s->_idx ); } } - } else + } else { st->print("BLOCK HEAD IS JUNK "); + } // Print loop, if any const Block *bhead = this; // Head of self-loop Node *bh = bhead->head(); - if( bbs && bh->is_Loop() && !head()->is_Root() ) { + + if ((cfg != NULL) && bh->is_Loop() && !head()->is_Root()) { LoopNode *loop = bh->as_Loop(); - const Block *bx = (*bbs)[loop->in(LoopNode::LoopBackControl)->_idx]; + const Block *bx = cfg->get_block_for_node(loop->in(LoopNode::LoopBackControl)); while (bx->is_connector()) { - bx = (*bbs)[bx->pred(1)->_idx]; + bx = cfg->get_block_for_node(bx->pred(1)); } st->print("\tLoop: B%d-B%d ", bhead->_pre_order, bx->_pre_order); // Dump any loop-specific bits, especially for CountedLoops. @@ -349,29 +351,32 @@ void Block::dump_head( const Block_Array *bbs, outputStream* st ) const { st->print_cr(""); } -void Block::dump() const { dump(NULL); } +void Block::dump() const { + dump(NULL); +} -void Block::dump( const Block_Array *bbs ) const { - dump_head(bbs); - uint cnt = _nodes.size(); - for( uint i=0; idump(); + } tty->print("\n"); } #endif //============================================================================= //------------------------------PhaseCFG--------------------------------------- -PhaseCFG::PhaseCFG( Arena *a, RootNode *r, Matcher &m ) : - Phase(CFG), - _bbs(a), - _root(r), - _node_latency(NULL) +PhaseCFG::PhaseCFG(Arena* arena, RootNode* root, Matcher& matcher) +: Phase(CFG) +, _block_arena(arena) +, _node_to_block_mapping(arena) +, _root(root) +, _node_latency(NULL) #ifndef PRODUCT - , _trace_opto_pipelining(TraceOptoPipelining || C->method_has_option("TraceOptoPipelining")) +, _trace_opto_pipelining(TraceOptoPipelining || C->method_has_option("TraceOptoPipelining")) #endif #ifdef ASSERT - , _raw_oops(a) +, _raw_oops(arena) #endif { ResourceMark rm; @@ -380,13 +385,13 @@ PhaseCFG::PhaseCFG( Arena *a, RootNode *r, Matcher &m ) : // Node on demand. Node *x = new (C) GotoNode(NULL); x->init_req(0, x); - _goto = m.match_tree(x); + _goto = matcher.match_tree(x); assert(_goto != NULL, ""); _goto->set_req(0,_goto); // Build the CFG in Reverse Post Order _num_blocks = build_cfg(); - _broot = _bbs[_root->_idx]; + _broot = get_block_for_node(_root); } //------------------------------build_cfg-------------------------------------- @@ -440,9 +445,9 @@ uint PhaseCFG::build_cfg() { // 'p' now points to the start of this basic block // Put self in array of basic blocks - Block *bb = new (_bbs._arena) Block(_bbs._arena,p); - _bbs.map(p->_idx,bb); - _bbs.map(x->_idx,bb); + Block *bb = new (_block_arena) Block(_block_arena, p); + map_node_to_block(p, bb); + map_node_to_block(x, bb); if( x != p ) { // Only for root is x == p bb->_nodes.push((Node*)x); } @@ -473,16 +478,16 @@ uint PhaseCFG::build_cfg() { // Check if it the fist node pushed on stack at the beginning. if (idx == 0) break; // end of the build // Find predecessor basic block - Block *pb = _bbs[x->_idx]; + Block *pb = get_block_for_node(x); // Insert into nodes array, if not already there - if( !_bbs.lookup(proj->_idx) ) { + if (!has_block(proj)) { assert( x != proj, "" ); // Map basic block of projection - _bbs.map(proj->_idx,pb); + map_node_to_block(proj, pb); pb->_nodes.push(proj); } // Insert self as a child of my predecessor block - pb->_succs.map(pb->_num_succs++, _bbs[np->_idx]); + pb->_succs.map(pb->_num_succs++, get_block_for_node(np)); assert( pb->_nodes[ pb->_nodes.size() - pb->_num_succs ]->is_block_proj(), "too many control users, not a CFG?" ); } @@ -511,15 +516,15 @@ void PhaseCFG::insert_goto_at(uint block_no, uint succ_no) { RegionNode* region = new (C) RegionNode(2); region->init_req(1, proj); // setup corresponding basic block - Block* block = new (_bbs._arena) Block(_bbs._arena, region); - _bbs.map(region->_idx, block); + Block* block = new (_block_arena) Block(_block_arena, region); + map_node_to_block(region, block); C->regalloc()->set_bad(region->_idx); // add a goto node Node* gto = _goto->clone(); // get a new goto node gto->set_req(0, region); // add it to the basic block block->_nodes.push(gto); - _bbs.map(gto->_idx, block); + map_node_to_block(gto, block); C->regalloc()->set_bad(gto->_idx); // hook up successor block block->_succs.map(block->_num_succs++, out); @@ -570,7 +575,7 @@ void PhaseCFG::convert_NeverBranch_to_Goto(Block *b) { gto->set_req(0, b->head()); Node *bp = b->_nodes[end_idx]; b->_nodes.map(end_idx,gto); // Slam over NeverBranch - _bbs.map(gto->_idx, b); + map_node_to_block(gto, b); C->regalloc()->set_bad(gto->_idx); b->_nodes.pop(); // Yank projections b->_nodes.pop(); // Yank projections @@ -613,7 +618,7 @@ bool PhaseCFG::move_to_next(Block* bx, uint b_index) { // If the previous block conditionally falls into bx, return false, // because moving bx will create an extra jump. for(uint k = 1; k < bx->num_preds(); k++ ) { - Block* pred = _bbs[bx->pred(k)->_idx]; + Block* pred = get_block_for_node(bx->pred(k)); if (pred == _blocks[bx_index-1]) { if (pred->_num_succs != 1) { return false; @@ -682,7 +687,7 @@ void PhaseCFG::remove_empty() { // Look for uncommon blocks and move to end. if (!C->do_freq_based_layout()) { - if( b->is_uncommon(_bbs) ) { + if (b->is_uncommon(this)) { move_to_end(b, i); last--; // No longer check for being uncommon! if( no_flip_branch(b) ) { // Fall-thru case must follow? @@ -870,28 +875,31 @@ void PhaseCFG::_dump_cfg( const Node *end, VectorSet &visited ) const { } while( !p->is_block_start() ); // Recursively visit - for( uint i=1; ireq(); i++ ) - _dump_cfg(p->in(i),visited); + for (uint i = 1; i < p->req(); i++) { + _dump_cfg(p->in(i), visited); + } // Dump the block - _bbs[p->_idx]->dump(&_bbs); + get_block_for_node(p)->dump(this); } void PhaseCFG::dump( ) const { tty->print("\n--- CFG --- %d BBs\n",_num_blocks); - if( _blocks.size() ) { // Did we do basic-block layout? - for( uint i=0; i<_num_blocks; i++ ) - _blocks[i]->dump(&_bbs); + if (_blocks.size()) { // Did we do basic-block layout? + for (uint i = 0; i < _num_blocks; i++) { + _blocks[i]->dump(this); + } } else { // Else do it with a DFS - VectorSet visited(_bbs._arena); + VectorSet visited(_block_arena); _dump_cfg(_root,visited); } } void PhaseCFG::dump_headers() { for( uint i = 0; i < _num_blocks; i++ ) { - if( _blocks[i] == NULL ) continue; - _blocks[i]->dump_head(&_bbs); + if (_blocks[i]) { + _blocks[i]->dump_head(this); + } } } @@ -904,7 +912,7 @@ void PhaseCFG::verify( ) const { uint j; for (j = 0; j < cnt; j++) { Node *n = b->_nodes[j]; - assert( _bbs[n->_idx] == b, "" ); + assert(get_block_for_node(n) == b, ""); if (j >= 1 && n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_CreateEx) { assert(j == 1 || b->_nodes[j-1]->is_Phi(), @@ -913,13 +921,12 @@ void PhaseCFG::verify( ) const { for (uint k = 0; k < n->req(); k++) { Node *def = n->in(k); if (def && def != n) { - assert(_bbs[def->_idx] || def->is_Con(), - "must have block; constants for debug info ok"); + assert(get_block_for_node(def) || def->is_Con(), "must have block; constants for debug info ok"); // Verify that instructions in the block is in correct order. // Uses must follow their definition if they are at the same block. // Mostly done to check that MachSpillCopy nodes are placed correctly // when CreateEx node is moved in build_ifg_physical(). - if (_bbs[def->_idx] == b && + if (get_block_for_node(def) == b && !(b->head()->is_Loop() && n->is_Phi()) && // See (+++) comment in reg_split.cpp !(n->jvms() != NULL && n->jvms()->is_monitor_use(k))) { diff --git a/hotspot/src/share/vm/opto/block.hpp b/hotspot/src/share/vm/opto/block.hpp index a2e4615b8d0..cb9384de2ee 100644 --- a/hotspot/src/share/vm/opto/block.hpp +++ b/hotspot/src/share/vm/opto/block.hpp @@ -48,13 +48,12 @@ class Block_Array : public ResourceObj { friend class VMStructs; uint _size; // allocated size, as opposed to formal limit debug_only(uint _limit;) // limit to formal domain + Arena *_arena; // Arena to allocate in protected: Block **_blocks; void grow( uint i ); // Grow array node to fit public: - Arena *_arena; // Arena to allocate in - Block_Array(Arena *a) : _arena(a), _size(OptoBlockListSize) { debug_only(_limit=0); _blocks = NEW_ARENA_ARRAY( a, Block *, OptoBlockListSize ); @@ -77,7 +76,7 @@ class Block_List : public Block_Array { public: uint _cnt; Block_List() : Block_Array(Thread::current()->resource_area()), _cnt(0) {} - void push( Block *b ) { map(_cnt++,b); } + void push( Block *b ) { map(_cnt++,b); } Block *pop() { return _blocks[--_cnt]; } Block *rpop() { Block *b = _blocks[0]; _blocks[0]=_blocks[--_cnt]; return b;} void remove( uint i ); @@ -284,15 +283,15 @@ class Block : public CFGElement { // helper function that adds caller save registers to MachProjNode void add_call_kills(MachProjNode *proj, RegMask& regs, const char* save_policy, bool exclude_soe); // Schedule a call next in the block - uint sched_call(Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_List &worklist, GrowableArray &ready_cnt, MachCallNode *mcall, VectorSet &next_call); + uint sched_call(Matcher &matcher, PhaseCFG* cfg, uint node_cnt, Node_List &worklist, GrowableArray &ready_cnt, MachCallNode *mcall, VectorSet &next_call); // Perform basic-block local scheduling Node *select(PhaseCFG *cfg, Node_List &worklist, GrowableArray &ready_cnt, VectorSet &next_call, uint sched_slot); - void set_next_call( Node *n, VectorSet &next_call, Block_Array &bbs ); - void needed_for_next_call(Node *this_call, VectorSet &next_call, Block_Array &bbs); + void set_next_call( Node *n, VectorSet &next_call, PhaseCFG* cfg); + void needed_for_next_call(Node *this_call, VectorSet &next_call, PhaseCFG* cfg); bool schedule_local(PhaseCFG *cfg, Matcher &m, GrowableArray &ready_cnt, VectorSet &next_call); // Cleanup if any code lands between a Call and his Catch - void call_catch_cleanup(Block_Array &bbs, Compile *C); + void call_catch_cleanup(PhaseCFG* cfg, Compile *C); // Detect implicit-null-check opportunities. Basically, find NULL checks // with suitable memory ops nearby. Use the memory op to do the NULL check. // I can generate a memory op if there is not one nearby. @@ -331,15 +330,15 @@ class Block : public CFGElement { // Use frequency calculations and code shape to predict if the block // is uncommon. - bool is_uncommon( Block_Array &bbs ) const; + bool is_uncommon(PhaseCFG* cfg) const; #ifndef PRODUCT // Debugging print of basic block void dump_bidx(const Block* orig, outputStream* st = tty) const; - void dump_pred(const Block_Array *bbs, Block* orig, outputStream* st = tty) const; - void dump_head( const Block_Array *bbs, outputStream* st = tty ) const; + void dump_pred(const PhaseCFG* cfg, Block* orig, outputStream* st = tty) const; + void dump_head(const PhaseCFG* cfg, outputStream* st = tty) const; void dump() const; - void dump( const Block_Array *bbs ) const; + void dump(const PhaseCFG* cfg) const; #endif }; @@ -349,6 +348,12 @@ class Block : public CFGElement { class PhaseCFG : public Phase { friend class VMStructs; private: + // Arena for the blocks to be stored in + Arena* _block_arena; + + // Map nodes to owning basic block + Block_Array _node_to_block_mapping; + // Build a proper looking cfg. Return count of basic blocks uint build_cfg(); @@ -371,22 +376,42 @@ class PhaseCFG : public Phase { Block* insert_anti_dependences(Block* LCA, Node* load, bool verify = false); void verify_anti_dependences(Block* LCA, Node* load) { - assert(LCA == _bbs[load->_idx], "should already be scheduled"); + assert(LCA == get_block_for_node(load), "should already be scheduled"); insert_anti_dependences(LCA, load, true); } public: - PhaseCFG( Arena *a, RootNode *r, Matcher &m ); + PhaseCFG(Arena* arena, RootNode* root, Matcher& matcher); uint _num_blocks; // Count of basic blocks Block_List _blocks; // List of basic blocks RootNode *_root; // Root of whole program - Block_Array _bbs; // Map Nodes to owning Basic Block Block *_broot; // Basic block of root uint _rpo_ctr; CFGLoop* _root_loop; float _outer_loop_freq; // Outmost loop frequency + + // set which block this node should reside in + void map_node_to_block(const Node* node, Block* block) { + _node_to_block_mapping.map(node->_idx, block); + } + + // removes the mapping from a node to a block + void unmap_node_from_block(const Node* node) { + _node_to_block_mapping.map(node->_idx, NULL); + } + + // get the block in which this node resides + Block* get_block_for_node(const Node* node) const { + return _node_to_block_mapping[node->_idx]; + } + + // does this node reside in a block; return true + bool has_block(const Node* node) const { + return (_node_to_block_mapping.lookup(node->_idx) != NULL); + } + // Per node latency estimation, valid only during GCM GrowableArray *_node_latency; @@ -405,7 +430,7 @@ class PhaseCFG : public Phase { void Estimate_Block_Frequency(); // Global Code Motion. See Click's PLDI95 paper. Place Nodes in specific - // basic blocks; i.e. _bbs now maps _idx for all Nodes to some Block. + // basic blocks; i.e. _node_to_block_mapping now maps _idx for all Nodes to some Block. void GlobalCodeMotion( Matcher &m, uint unique, Node_List &proj_list ); // Compute the (backwards) latency of a node from the uses @@ -454,7 +479,7 @@ class PhaseCFG : public Phase { // Insert a node into a block, and update the _bbs void insert( Block *b, uint idx, Node *n ) { b->_nodes.insert( idx, n ); - _bbs.map( n->_idx, b ); + map_node_to_block(n, b); } #ifndef PRODUCT @@ -543,7 +568,7 @@ class CFGLoop : public CFGElement { _child(NULL), _exit_prob(1.0f) {} CFGLoop* parent() { return _parent; } - void push_pred(Block* blk, int i, Block_List& worklist, Block_Array& node_to_blk); + void push_pred(Block* blk, int i, Block_List& worklist, PhaseCFG* cfg); void add_member(CFGElement *s) { _members.push(s); } void add_nested_loop(CFGLoop* cl); Block* head() { diff --git a/hotspot/src/share/vm/opto/buildOopMap.cpp b/hotspot/src/share/vm/opto/buildOopMap.cpp index fc731604eaa..884142d57df 100644 --- a/hotspot/src/share/vm/opto/buildOopMap.cpp +++ b/hotspot/src/share/vm/opto/buildOopMap.cpp @@ -426,14 +426,16 @@ static void do_liveness( PhaseRegAlloc *regalloc, PhaseCFG *cfg, Block_List *wor } memset( live, 0, cfg->_num_blocks * (max_reg_ints<req(); i++ ) - worklist->push(cfg->_bbs[root->in(i)->_idx]); + for (uint i = 1; i < root->req(); i++) { + Block* block = cfg->get_block_for_node(root->in(i)); + worklist->push(block); + } // ZKM.jar includes tiny infinite loops which are unreached from below. // If we missed any blocks, we'll retry here after pushing all missed // blocks on the worklist. Normally this outer loop never trips more // than once. - while( 1 ) { + while (1) { while( worklist->size() ) { // Standard worklist algorithm Block *b = worklist->rpop(); @@ -537,8 +539,10 @@ static void do_liveness( PhaseRegAlloc *regalloc, PhaseCFG *cfg, Block_List *wor for( l=0; lnum_preds(); l++ ) - worklist->push(cfg->_bbs[b->pred(l)->_idx]); + for (l = 1; l < (int)b->num_preds(); l++) { + Block* block = cfg->get_block_for_node(b->pred(l)); + worklist->push(block); + } } } @@ -629,10 +633,9 @@ void Compile::BuildOopMaps() { // pred to this block. Otherwise we have to grab a new OopFlow. OopFlow *flow = NULL; // Flag for finding optimized flow Block *pred = (Block*)0xdeadbeef; - uint j; // Scan this block's preds to find a done predecessor - for( j=1; jnum_preds(); j++ ) { - Block *p = _cfg->_bbs[b->pred(j)->_idx]; + for (uint j = 1; j < b->num_preds(); j++) { + Block* p = _cfg->get_block_for_node(b->pred(j)); OopFlow *p_flow = flows[p->_pre_order]; if( p_flow ) { // Predecessor is done assert( p_flow->_b == p, "cross check" ); diff --git a/hotspot/src/share/vm/opto/chaitin.cpp b/hotspot/src/share/vm/opto/chaitin.cpp index 53ffc573284..4fc254f40ca 100644 --- a/hotspot/src/share/vm/opto/chaitin.cpp +++ b/hotspot/src/share/vm/opto/chaitin.cpp @@ -295,7 +295,7 @@ void PhaseChaitin::new_lrg(const Node *x, uint lrg) { bool PhaseChaitin::clone_projs_shared(Block *b, uint idx, Node *con, Node *copy, uint max_lrg_id) { - Block *bcon = _cfg._bbs[con->_idx]; + Block* bcon = _cfg.get_block_for_node(con); uint cindex = bcon->find_node(con); Node *con_next = bcon->_nodes[cindex+1]; if (con_next->in(0) != con || !con_next->is_MachProj()) { @@ -306,7 +306,7 @@ bool PhaseChaitin::clone_projs_shared(Block *b, uint idx, Node *con, Node *copy, Node *kills = con_next->clone(); kills->set_req(0, copy); b->_nodes.insert(idx, kills); - _cfg._bbs.map(kills->_idx, b); + _cfg.map_node_to_block(kills, b); new_lrg(kills, max_lrg_id); return true; } @@ -962,8 +962,7 @@ void PhaseChaitin::gather_lrg_masks( bool after_aggressive ) { // AggressiveCoalesce. This effectively pre-virtual-splits // around uncommon uses of common defs. const RegMask &rm = n->in_RegMask(k); - if( !after_aggressive && - _cfg._bbs[n->in(k)->_idx]->_freq > 1000*b->_freq ) { + if (!after_aggressive && _cfg.get_block_for_node(n->in(k))->_freq > 1000 * b->_freq) { // Since we are BEFORE aggressive coalesce, leave the register // mask untrimmed by the call. This encourages more coalescing. // Later, AFTER aggressive, this live range will have to spill @@ -1709,16 +1708,15 @@ Node *PhaseChaitin::find_base_for_derived( Node **derived_base_map, Node *derive // set control to _root and place it into Start block // (where top() node is placed). base->init_req(0, _cfg._root); - Block *startb = _cfg._bbs[C->top()->_idx]; + Block *startb = _cfg.get_block_for_node(C->top()); startb->_nodes.insert(startb->find_node(C->top()), base ); - _cfg._bbs.map( base->_idx, startb ); + _cfg.map_node_to_block(base, startb); assert(_lrg_map.live_range_id(base) == 0, "should not have LRG yet"); } if (_lrg_map.live_range_id(base) == 0) { new_lrg(base, maxlrg++); } - assert(base->in(0) == _cfg._root && - _cfg._bbs[base->_idx] == _cfg._bbs[C->top()->_idx], "base NULL should be shared"); + assert(base->in(0) == _cfg._root && _cfg.get_block_for_node(base) == _cfg.get_block_for_node(C->top()), "base NULL should be shared"); derived_base_map[derived->_idx] = base; return base; } @@ -1754,12 +1752,12 @@ Node *PhaseChaitin::find_base_for_derived( Node **derived_base_map, Node *derive base->as_Phi()->set_type(t); // Search the current block for an existing base-Phi - Block *b = _cfg._bbs[derived->_idx]; + Block *b = _cfg.get_block_for_node(derived); for( i = 1; i <= b->end_idx(); i++ ) {// Search for matching Phi Node *phi = b->_nodes[i]; if( !phi->is_Phi() ) { // Found end of Phis with no match? b->_nodes.insert( i, base ); // Must insert created Phi here as base - _cfg._bbs.map( base->_idx, b ); + _cfg.map_node_to_block(base, b); new_lrg(base,maxlrg++); break; } @@ -1815,8 +1813,8 @@ bool PhaseChaitin::stretch_base_pointer_live_ranges(ResourceArea *a) { if( n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_CmpI ) { Node *phi = n->in(1); if( phi->is_Phi() && phi->as_Phi()->region()->is_Loop() ) { - Block *phi_block = _cfg._bbs[phi->_idx]; - if( _cfg._bbs[phi_block->pred(2)->_idx] == b ) { + Block *phi_block = _cfg.get_block_for_node(phi); + if (_cfg.get_block_for_node(phi_block->pred(2)) == b) { const RegMask *mask = C->matcher()->idealreg2spillmask[Op_RegI]; Node *spill = new (C) MachSpillCopyNode( phi, *mask, *mask ); insert_proj( phi_block, 1, spill, maxlrg++ ); @@ -1870,7 +1868,7 @@ bool PhaseChaitin::stretch_base_pointer_live_ranges(ResourceArea *a) { if ((_lrg_map.live_range_id(base) >= _lrg_map.max_lrg_id() || // (Brand new base (hence not live) or !liveout.member(_lrg_map.live_range_id(base))) && // not live) AND (_lrg_map.live_range_id(base) > 0) && // not a constant - _cfg._bbs[base->_idx] != b) { // base not def'd in blk) + _cfg.get_block_for_node(base) != b) { // base not def'd in blk) // Base pointer is not currently live. Since I stretched // the base pointer to here and it crosses basic-block // boundaries, the global live info is now incorrect. @@ -1993,8 +1991,8 @@ void PhaseChaitin::dump(const Node *n) const { tty->print("\n"); } -void PhaseChaitin::dump( const Block * b ) const { - b->dump_head( &_cfg._bbs ); +void PhaseChaitin::dump(const Block *b) const { + b->dump_head(&_cfg); // For all instructions for( uint j = 0; j < b->_nodes.size(); j++ ) @@ -2299,7 +2297,7 @@ void PhaseChaitin::dump_lrg( uint lidx, bool defs_only ) const { if (_lrg_map.find_const(n) == lidx) { if (!dump_once++) { tty->cr(); - b->dump_head( &_cfg._bbs ); + b->dump_head(&_cfg); } dump(n); continue; @@ -2314,7 +2312,7 @@ void PhaseChaitin::dump_lrg( uint lidx, bool defs_only ) const { if (_lrg_map.find_const(m) == lidx) { if (!dump_once++) { tty->cr(); - b->dump_head(&_cfg._bbs); + b->dump_head(&_cfg); } dump(n); } diff --git a/hotspot/src/share/vm/opto/coalesce.cpp b/hotspot/src/share/vm/opto/coalesce.cpp index 60c88dc12ba..d1f880a6493 100644 --- a/hotspot/src/share/vm/opto/coalesce.cpp +++ b/hotspot/src/share/vm/opto/coalesce.cpp @@ -52,7 +52,7 @@ void PhaseCoalesce::dump() const { // Print a nice block header tty->print("B%d: ",b->_pre_order); for( j=1; jnum_preds(); j++ ) - tty->print("B%d ", _phc._cfg._bbs[b->pred(j)->_idx]->_pre_order); + tty->print("B%d ", _phc._cfg.get_block_for_node(b->pred(j))->_pre_order); tty->print("-> "); for( j=0; j_num_succs; j++ ) tty->print("B%d ",b->_succs[j]->_pre_order); @@ -208,7 +208,7 @@ void PhaseAggressiveCoalesce::insert_copy_with_overlap( Block *b, Node *copy, ui copy->set_req(idx,tmp); // Save source in temp early, before source is killed b->_nodes.insert(kill_src_idx,tmp); - _phc._cfg._bbs.map( tmp->_idx, b ); + _phc._cfg.map_node_to_block(tmp, b); last_use_idx++; } @@ -286,7 +286,7 @@ void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) { Node *m = n->in(j); uint src_name = _phc._lrg_map.find(m); if (src_name != phi_name) { - Block *pred = _phc._cfg._bbs[b->pred(j)->_idx]; + Block *pred = _phc._cfg.get_block_for_node(b->pred(j)); Node *copy; assert(!m->is_Con() || m->is_Mach(), "all Con must be Mach"); // Rematerialize constants instead of copying them @@ -305,7 +305,7 @@ void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) { } // Insert the copy in the use-def chain n->set_req(j, copy); - _phc._cfg._bbs.map( copy->_idx, pred ); + _phc._cfg.map_node_to_block(copy, pred); // Extend ("register allocate") the names array for the copy. _phc._lrg_map.extend(copy->_idx, phi_name); } // End of if Phi names do not match @@ -343,13 +343,13 @@ void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) { n->set_req(idx, copy); // Extend ("register allocate") the names array for the copy. _phc._lrg_map.extend(copy->_idx, name); - _phc._cfg._bbs.map( copy->_idx, b ); + _phc._cfg.map_node_to_block(copy, b); } } // End of is two-adr // Insert a copy at a debug use for a lrg which has high frequency - if (b->_freq < OPTO_DEBUG_SPLIT_FREQ || b->is_uncommon(_phc._cfg._bbs)) { + if (b->_freq < OPTO_DEBUG_SPLIT_FREQ || b->is_uncommon(&_phc._cfg)) { // Walk the debug inputs to the node and check for lrg freq JVMState* jvms = n->jvms(); uint debug_start = jvms ? jvms->debug_start() : 999999; @@ -391,7 +391,7 @@ void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) { uint max_lrg_id = _phc._lrg_map.max_lrg_id(); _phc.new_lrg(copy, max_lrg_id); _phc._lrg_map.set_max_lrg_id(max_lrg_id + 1); - _phc._cfg._bbs.map(copy->_idx, b); + _phc._cfg.map_node_to_block(copy, b); //tty->print_cr("Split a debug use in Aggressive Coalesce"); } // End of if high frequency use/def } // End of for all debug inputs @@ -437,7 +437,10 @@ void PhaseAggressiveCoalesce::coalesce( Block *b ) { Block *bs = b->_succs[i]; // Find index of 'b' in 'bs' predecessors uint j=1; - while( _phc._cfg._bbs[bs->pred(j)->_idx] != b ) j++; + while (_phc._cfg.get_block_for_node(bs->pred(j)) != b) { + j++; + } + // Visit all the Phis in successor block for( uint k = 1; k_nodes.size(); k++ ) { Node *n = bs->_nodes[k]; @@ -510,9 +513,9 @@ void PhaseConservativeCoalesce::union_helper( Node *lr1_node, Node *lr2_node, ui if( bindex < b->_fhrp_index ) b->_fhrp_index--; // Stretched lr1; add it to liveness of intermediate blocks - Block *b2 = _phc._cfg._bbs[src_copy->_idx]; + Block *b2 = _phc._cfg.get_block_for_node(src_copy); while( b != b2 ) { - b = _phc._cfg._bbs[b->pred(1)->_idx]; + b = _phc._cfg.get_block_for_node(b->pred(1)); _phc._live->live(b)->insert(lr1); } } @@ -532,7 +535,7 @@ uint PhaseConservativeCoalesce::compute_separating_interferences(Node *dst_copy, bindex2--; // Chain backwards 1 instruction while( bindex2 == 0 ) { // At block start, find prior block assert( b2->num_preds() == 2, "cannot double coalesce across c-flow" ); - b2 = _phc._cfg._bbs[b2->pred(1)->_idx]; + b2 = _phc._cfg.get_block_for_node(b2->pred(1)); bindex2 = b2->end_idx()-1; } // Get prior instruction @@ -676,8 +679,8 @@ bool PhaseConservativeCoalesce::copy_copy(Node *dst_copy, Node *src_copy, Block if (UseFPUForSpilling && rm.is_AllStack() ) { // Don't coalesce when frequency difference is large - Block *dst_b = _phc._cfg._bbs[dst_copy->_idx]; - Block *src_def_b = _phc._cfg._bbs[src_def->_idx]; + Block *dst_b = _phc._cfg.get_block_for_node(dst_copy); + Block *src_def_b = _phc._cfg.get_block_for_node(src_def); if (src_def_b->_freq > 10*dst_b->_freq ) return false; } @@ -690,7 +693,7 @@ bool PhaseConservativeCoalesce::copy_copy(Node *dst_copy, Node *src_copy, Block // Another early bail-out test is when we are double-coalescing and the // 2 copies are separated by some control flow. if( dst_copy != src_copy ) { - Block *src_b = _phc._cfg._bbs[src_copy->_idx]; + Block *src_b = _phc._cfg.get_block_for_node(src_copy); Block *b2 = b; while( b2 != src_b ) { if( b2->num_preds() > 2 ){// Found merge-point @@ -701,7 +704,7 @@ bool PhaseConservativeCoalesce::copy_copy(Node *dst_copy, Node *src_copy, Block //record_bias( _phc._lrgs, lr1, lr2 ); return false; // To hard to find all interferences } - b2 = _phc._cfg._bbs[b2->pred(1)->_idx]; + b2 = _phc._cfg.get_block_for_node(b2->pred(1)); } } @@ -786,8 +789,9 @@ bool PhaseConservativeCoalesce::copy_copy(Node *dst_copy, Node *src_copy, Block // Conservative (but pessimistic) copy coalescing of a single block void PhaseConservativeCoalesce::coalesce( Block *b ) { // Bail out on infrequent blocks - if( b->is_uncommon(_phc._cfg._bbs) ) + if (b->is_uncommon(&_phc._cfg)) { return; + } // Check this block for copies. for( uint i = 1; iend_idx(); i++ ) { // Check for actual copies on inputs. Coalesce a copy into its diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp index cd650b00156..f7cadda849b 100644 --- a/hotspot/src/share/vm/opto/compile.cpp +++ b/hotspot/src/share/vm/opto/compile.cpp @@ -2262,7 +2262,7 @@ void Compile::dump_asm(int *pcs, uint pc_limit) { tty->print("%3.3x ", pcs[n->_idx]); else tty->print(" "); - b->dump_head( &_cfg->_bbs ); + b->dump_head(_cfg); if (b->is_connector()) { tty->print_cr(" # Empty connector block"); } else if (b->num_preds() == 2 && b->pred(1)->is_CatchProj() && b->pred(1)->as_CatchProj()->_con == CatchProjNode::fall_through_index) { @@ -3525,7 +3525,7 @@ void Compile::ConstantTable::add(Constant& con) { } Compile::Constant Compile::ConstantTable::add(MachConstantNode* n, BasicType type, jvalue value) { - Block* b = Compile::current()->cfg()->_bbs[n->_idx]; + Block* b = Compile::current()->cfg()->get_block_for_node(n); Constant con(type, value, b->_freq); add(con); return con; diff --git a/hotspot/src/share/vm/opto/domgraph.cpp b/hotspot/src/share/vm/opto/domgraph.cpp index 9973cb562f8..b64e291e7ca 100644 --- a/hotspot/src/share/vm/opto/domgraph.cpp +++ b/hotspot/src/share/vm/opto/domgraph.cpp @@ -105,8 +105,8 @@ void PhaseCFG::Dominators( ) { // Step 2: Node *whead = w->_block->head(); - for( uint j=1; j < whead->req(); j++ ) { - Block *b = _bbs[whead->in(j)->_idx]; + for (uint j = 1; j < whead->req(); j++) { + Block* b = get_block_for_node(whead->in(j)); Tarjan *vx = &tarjan[b->_pre_order]; Tarjan *u = vx->EVAL(); if( u->_semi < w->_semi ) diff --git a/hotspot/src/share/vm/opto/gcm.cpp b/hotspot/src/share/vm/opto/gcm.cpp index 811dc5c6c87..9ded635f65f 100644 --- a/hotspot/src/share/vm/opto/gcm.cpp +++ b/hotspot/src/share/vm/opto/gcm.cpp @@ -66,7 +66,7 @@ // are in b also. void PhaseCFG::schedule_node_into_block( Node *n, Block *b ) { // Set basic block of n, Add n to b, - _bbs.map(n->_idx, b); + map_node_to_block(n, b); b->add_inst(n); // After Matching, nearly any old Node may have projections trailing it. @@ -75,11 +75,12 @@ void PhaseCFG::schedule_node_into_block( Node *n, Block *b ) { for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { Node* use = n->fast_out(i); if (use->is_Proj()) { - Block* buse = _bbs[use->_idx]; + Block* buse = get_block_for_node(use); if (buse != b) { // In wrong block? - if (buse != NULL) + if (buse != NULL) { buse->find_remove(use); // Remove from wrong block - _bbs.map(use->_idx, b); // Re-insert in this block + } + map_node_to_block(use, b); b->add_inst(use); } } @@ -97,7 +98,7 @@ void PhaseCFG::replace_block_proj_ctrl( Node *n ) { if (p != NULL && p != n) { // Control from a block projection? assert(!n->pinned() || n->is_MachConstantBase(), "only pinned MachConstantBase node is expected here"); // Find trailing Region - Block *pb = _bbs[in0->_idx]; // Block-projection already has basic block + Block *pb = get_block_for_node(in0); // Block-projection already has basic block uint j = 0; if (pb->_num_succs != 1) { // More then 1 successor? // Search for successor @@ -127,14 +128,15 @@ void PhaseCFG::schedule_pinned_nodes( VectorSet &visited ) { while ( spstack.is_nonempty() ) { Node *n = spstack.pop(); if( !visited.test_set(n->_idx) ) { // Test node and flag it as visited - if( n->pinned() && !_bbs.lookup(n->_idx) ) { // Pinned? Nail it down! + if( n->pinned() && !has_block(n)) { // Pinned? Nail it down! assert( n->in(0), "pinned Node must have Control" ); // Before setting block replace block_proj control edge replace_block_proj_ctrl(n); Node *input = n->in(0); - while( !input->is_block_start() ) + while (!input->is_block_start()) { input = input->in(0); - Block *b = _bbs[input->_idx]; // Basic block of controlling input + } + Block *b = get_block_for_node(input); // Basic block of controlling input schedule_node_into_block(n, b); } for( int i = n->req() - 1; i >= 0; --i ) { // For all inputs @@ -149,7 +151,7 @@ void PhaseCFG::schedule_pinned_nodes( VectorSet &visited ) { // Assert that new input b2 is dominated by all previous inputs. // Check this by by seeing that it is dominated by b1, the deepest // input observed until b2. -static void assert_dom(Block* b1, Block* b2, Node* n, Block_Array &bbs) { +static void assert_dom(Block* b1, Block* b2, Node* n, const PhaseCFG* cfg) { if (b1 == NULL) return; assert(b1->_dom_depth < b2->_dom_depth, "sanity"); Block* tmp = b2; @@ -162,7 +164,7 @@ static void assert_dom(Block* b1, Block* b2, Node* n, Block_Array &bbs) { for (uint j=0; jlen(); j++) { // For all inputs Node* inn = n->in(j); // Get input if (inn == NULL) continue; // Ignore NULL, missing inputs - Block* inb = bbs[inn->_idx]; + Block* inb = cfg->get_block_for_node(inn); tty->print("B%d idom=B%d depth=%2d ",inb->_pre_order, inb->_idom ? inb->_idom->_pre_order : 0, inb->_dom_depth); inn->dump(); @@ -174,20 +176,20 @@ static void assert_dom(Block* b1, Block* b2, Node* n, Block_Array &bbs) { } #endif -static Block* find_deepest_input(Node* n, Block_Array &bbs) { +static Block* find_deepest_input(Node* n, const PhaseCFG* cfg) { // Find the last input dominated by all other inputs. Block* deepb = NULL; // Deepest block so far int deepb_dom_depth = 0; for (uint k = 0; k < n->len(); k++) { // For all inputs Node* inn = n->in(k); // Get input if (inn == NULL) continue; // Ignore NULL, missing inputs - Block* inb = bbs[inn->_idx]; + Block* inb = cfg->get_block_for_node(inn); assert(inb != NULL, "must already have scheduled this input"); if (deepb_dom_depth < (int) inb->_dom_depth) { // The new inb must be dominated by the previous deepb. // The various inputs must be linearly ordered in the dom // tree, or else there will not be a unique deepest block. - DEBUG_ONLY(assert_dom(deepb, inb, n, bbs)); + DEBUG_ONLY(assert_dom(deepb, inb, n, cfg)); deepb = inb; // Save deepest block deepb_dom_depth = deepb->_dom_depth; } @@ -243,7 +245,7 @@ bool PhaseCFG::schedule_early(VectorSet &visited, Node_List &roots) { ++i; if (in == NULL) continue; // Ignore NULL, missing inputs int is_visited = visited.test_set(in->_idx); - if (!_bbs.lookup(in->_idx)) { // Missing block selection? + if (!has_block(in)) { // Missing block selection? if (is_visited) { // assert( !visited.test(in->_idx), "did not schedule early" ); return false; @@ -265,9 +267,9 @@ bool PhaseCFG::schedule_early(VectorSet &visited, Node_List &roots) { // any projections which depend on them. if (!n->pinned()) { // Set earliest legal block. - _bbs.map(n->_idx, find_deepest_input(n, _bbs)); + map_node_to_block(n, find_deepest_input(n, this)); } else { - assert(_bbs[n->_idx] == _bbs[n->in(0)->_idx], "Pinned Node should be at the same block as its control edge"); + assert(get_block_for_node(n) == get_block_for_node(n->in(0)), "Pinned Node should be at the same block as its control edge"); } if (nstack.is_empty()) { @@ -313,8 +315,8 @@ Block* Block::dom_lca(Block* LCA) { // The definition must dominate the use, so move the LCA upward in the // dominator tree to dominate the use. If the use is a phi, adjust // the LCA only with the phi input paths which actually use this def. -static Block* raise_LCA_above_use(Block* LCA, Node* use, Node* def, Block_Array &bbs) { - Block* buse = bbs[use->_idx]; +static Block* raise_LCA_above_use(Block* LCA, Node* use, Node* def, const PhaseCFG* cfg) { + Block* buse = cfg->get_block_for_node(use); if (buse == NULL) return LCA; // Unused killing Projs have no use block if (!use->is_Phi()) return buse->dom_lca(LCA); uint pmax = use->req(); // Number of Phi inputs @@ -329,7 +331,7 @@ static Block* raise_LCA_above_use(Block* LCA, Node* use, Node* def, Block_Array // more than once. for (uint j=1; jin(j) == def) { // Found matching input? - Block* pred = bbs[buse->pred(j)->_idx]; + Block* pred = cfg->get_block_for_node(buse->pred(j)); LCA = pred->dom_lca(LCA); } } @@ -342,8 +344,7 @@ static Block* raise_LCA_above_use(Block* LCA, Node* use, Node* def, Block_Array // which are marked with the given index. Return the LCA (in the dom tree) // of all marked blocks. If there are none marked, return the original // LCA. -static Block* raise_LCA_above_marks(Block* LCA, node_idx_t mark, - Block* early, Block_Array &bbs) { +static Block* raise_LCA_above_marks(Block* LCA, node_idx_t mark, Block* early, const PhaseCFG* cfg) { Block_List worklist; worklist.push(LCA); while (worklist.size() > 0) { @@ -366,7 +367,7 @@ static Block* raise_LCA_above_marks(Block* LCA, node_idx_t mark, } else { // Keep searching through this block's predecessors. for (uint j = 1, jmax = mid->num_preds(); j < jmax; j++) { - Block* mid_parent = bbs[ mid->pred(j)->_idx ]; + Block* mid_parent = cfg->get_block_for_node(mid->pred(j)); worklist.push(mid_parent); } } @@ -384,7 +385,7 @@ static Block* raise_LCA_above_marks(Block* LCA, node_idx_t mark, // be earlier (at a shallower dom_depth) than the true schedule_early // point of the node. We compute this earlier block as a more permissive // site for anti-dependency insertion, but only if subsume_loads is enabled. -static Block* memory_early_block(Node* load, Block* early, Block_Array &bbs) { +static Block* memory_early_block(Node* load, Block* early, const PhaseCFG* cfg) { Node* base; Node* index; Node* store = load->in(MemNode::Memory); @@ -412,12 +413,12 @@ static Block* memory_early_block(Node* load, Block* early, Block_Array &bbs) { Block* deepb = NULL; // Deepest block so far int deepb_dom_depth = 0; for (int i = 0; i < mem_inputs_length; i++) { - Block* inb = bbs[mem_inputs[i]->_idx]; + Block* inb = cfg->get_block_for_node(mem_inputs[i]); if (deepb_dom_depth < (int) inb->_dom_depth) { // The new inb must be dominated by the previous deepb. // The various inputs must be linearly ordered in the dom // tree, or else there will not be a unique deepest block. - DEBUG_ONLY(assert_dom(deepb, inb, load, bbs)); + DEBUG_ONLY(assert_dom(deepb, inb, load, cfg)); deepb = inb; // Save deepest block deepb_dom_depth = deepb->_dom_depth; } @@ -488,14 +489,14 @@ Block* PhaseCFG::insert_anti_dependences(Block* LCA, Node* load, bool verify) { // and other inputs are first available. (Computed by schedule_early.) // For normal loads, 'early' is the shallowest place (dom graph wise) // to look for anti-deps between this load and any store. - Block* early = _bbs[load_index]; + Block* early = get_block_for_node(load); // If we are subsuming loads, compute an "early" block that only considers // memory or address inputs. This block may be different than the // schedule_early block in that it could be at an even shallower depth in the // dominator tree, and allow for a broader discovery of anti-dependences. if (C->subsume_loads()) { - early = memory_early_block(load, early, _bbs); + early = memory_early_block(load, early, this); } ResourceArea *area = Thread::current()->resource_area(); @@ -619,7 +620,7 @@ Block* PhaseCFG::insert_anti_dependences(Block* LCA, Node* load, bool verify) { // or else observe that 'store' is all the way up in the // earliest legal block for 'load'. In the latter case, // immediately insert an anti-dependence edge. - Block* store_block = _bbs[store->_idx]; + Block* store_block = get_block_for_node(store); assert(store_block != NULL, "unused killing projections skipped above"); if (store->is_Phi()) { @@ -637,7 +638,7 @@ Block* PhaseCFG::insert_anti_dependences(Block* LCA, Node* load, bool verify) { for (uint j = PhiNode::Input, jmax = store->req(); j < jmax; j++) { if (store->in(j) == mem) { // Found matching input? DEBUG_ONLY(found_match = true); - Block* pred_block = _bbs[store_block->pred(j)->_idx]; + Block* pred_block = get_block_for_node(store_block->pred(j)); if (pred_block != early) { // If any predecessor of the Phi matches the load's "early block", // we do not need a precedence edge between the Phi and 'load' @@ -711,7 +712,7 @@ Block* PhaseCFG::insert_anti_dependences(Block* LCA, Node* load, bool verify) { // preventing the load from sinking past any block containing // a store that may invalidate the memory state required by 'load'. if (must_raise_LCA) - LCA = raise_LCA_above_marks(LCA, load->_idx, early, _bbs); + LCA = raise_LCA_above_marks(LCA, load->_idx, early, this); if (LCA == early) return LCA; // Insert anti-dependence edges from 'load' to each store @@ -720,7 +721,7 @@ Block* PhaseCFG::insert_anti_dependences(Block* LCA, Node* load, bool verify) { if (LCA->raise_LCA_mark() == load_index) { while (non_early_stores.size() > 0) { Node* store = non_early_stores.pop(); - Block* store_block = _bbs[store->_idx]; + Block* store_block = get_block_for_node(store); if (store_block == LCA) { // add anti_dependence from store to load in its own block assert(store != load->in(0), "dependence cycle found"); @@ -754,7 +755,7 @@ private: public: // Constructor for the iterator - Node_Backward_Iterator(Node *root, VectorSet &visited, Node_List &stack, Block_Array &bbs); + Node_Backward_Iterator(Node *root, VectorSet &visited, Node_List &stack, PhaseCFG &cfg); // Postincrement operator to iterate over the nodes Node *next(); @@ -762,12 +763,12 @@ public: private: VectorSet &_visited; Node_List &_stack; - Block_Array &_bbs; + PhaseCFG &_cfg; }; // Constructor for the Node_Backward_Iterator -Node_Backward_Iterator::Node_Backward_Iterator( Node *root, VectorSet &visited, Node_List &stack, Block_Array &bbs ) - : _visited(visited), _stack(stack), _bbs(bbs) { +Node_Backward_Iterator::Node_Backward_Iterator( Node *root, VectorSet &visited, Node_List &stack, PhaseCFG &cfg) + : _visited(visited), _stack(stack), _cfg(cfg) { // The stack should contain exactly the root stack.clear(); stack.push(root); @@ -797,8 +798,8 @@ Node *Node_Backward_Iterator::next() { _visited.set(self->_idx); // Now schedule all uses as late as possible. - uint src = self->is_Proj() ? self->in(0)->_idx : self->_idx; - uint src_rpo = _bbs[src]->_rpo; + const Node* src = self->is_Proj() ? self->in(0) : self; + uint src_rpo = _cfg.get_block_for_node(src)->_rpo; // Schedule all nodes in a post-order visit Node *unvisited = NULL; // Unvisited anti-dependent Node, if any @@ -814,7 +815,7 @@ Node *Node_Backward_Iterator::next() { // do not traverse backward control edges Node *use = n->is_Proj() ? n->in(0) : n; - uint use_rpo = _bbs[use->_idx]->_rpo; + uint use_rpo = _cfg.get_block_for_node(use)->_rpo; if ( use_rpo < src_rpo ) continue; @@ -852,7 +853,7 @@ void PhaseCFG::ComputeLatenciesBackwards(VectorSet &visited, Node_List &stack) { tty->print("\n#---- ComputeLatenciesBackwards ----\n"); #endif - Node_Backward_Iterator iter((Node *)_root, visited, stack, _bbs); + Node_Backward_Iterator iter((Node *)_root, visited, stack, *this); Node *n; // Walk over all the nodes from last to first @@ -883,7 +884,7 @@ void PhaseCFG::partial_latency_of_defs(Node *n) { uint nlen = n->len(); uint use_latency = _node_latency->at_grow(n->_idx); - uint use_pre_order = _bbs[n->_idx]->_pre_order; + uint use_pre_order = get_block_for_node(n)->_pre_order; for ( uint j=0; jin(j); @@ -903,7 +904,7 @@ void PhaseCFG::partial_latency_of_defs(Node *n) { #endif // If the defining block is not known, assume it is ok - Block *def_block = _bbs[def->_idx]; + Block *def_block = get_block_for_node(def); uint def_pre_order = def_block ? def_block->_pre_order : 0; if ( (use_pre_order < def_pre_order) || @@ -931,10 +932,11 @@ void PhaseCFG::partial_latency_of_defs(Node *n) { // Compute the latency of a specific use int PhaseCFG::latency_from_use(Node *n, const Node *def, Node *use) { // If self-reference, return no latency - if (use == n || use->is_Root()) + if (use == n || use->is_Root()) { return 0; + } - uint def_pre_order = _bbs[def->_idx]->_pre_order; + uint def_pre_order = get_block_for_node(def)->_pre_order; uint latency = 0; // If the use is not a projection, then it is simple... @@ -946,7 +948,7 @@ int PhaseCFG::latency_from_use(Node *n, const Node *def, Node *use) { } #endif - uint use_pre_order = _bbs[use->_idx]->_pre_order; + uint use_pre_order = get_block_for_node(use)->_pre_order; if (use_pre_order < def_pre_order) return 0; @@ -1018,7 +1020,7 @@ Block* PhaseCFG::hoist_to_cheaper_block(Block* LCA, Block* early, Node* self) { uint start_latency = _node_latency->at_grow(LCA->_nodes[0]->_idx); uint end_latency = _node_latency->at_grow(LCA->_nodes[LCA->end_idx()]->_idx); bool in_latency = (target <= start_latency); - const Block* root_block = _bbs[_root->_idx]; + const Block* root_block = get_block_for_node(_root); // Turn off latency scheduling if scheduling is just plain off if (!C->do_scheduling()) @@ -1126,12 +1128,12 @@ void PhaseCFG::schedule_late(VectorSet &visited, Node_List &stack) { tty->print("\n#---- schedule_late ----\n"); #endif - Node_Backward_Iterator iter((Node *)_root, visited, stack, _bbs); + Node_Backward_Iterator iter((Node *)_root, visited, stack, *this); Node *self; // Walk over all the nodes from last to first while (self = iter.next()) { - Block* early = _bbs[self->_idx]; // Earliest legal placement + Block* early = get_block_for_node(self); // Earliest legal placement if (self->is_top()) { // Top node goes in bb #2 with other constants. @@ -1179,7 +1181,7 @@ void PhaseCFG::schedule_late(VectorSet &visited, Node_List &stack) { for (DUIterator_Fast imax, i = self->fast_outs(imax); i < imax; i++) { // For all uses, find LCA Node* use = self->fast_out(i); - LCA = raise_LCA_above_use(LCA, use, self, _bbs); + LCA = raise_LCA_above_use(LCA, use, self, this); } } // (Hide defs of imax, i from rest of block.) @@ -1187,7 +1189,7 @@ void PhaseCFG::schedule_late(VectorSet &visited, Node_List &stack) { // requirement for correctness but it reduces useless // interference between temps and other nodes. if (mach != NULL && mach->is_MachTemp()) { - _bbs.map(self->_idx, LCA); + map_node_to_block(self, LCA); LCA->add_inst(self); continue; } @@ -1262,10 +1264,10 @@ void PhaseCFG::GlobalCodeMotion( Matcher &matcher, uint unique, Node_List &proj_ } #endif - // Initialize the bbs.map for things on the proj_list - uint i; - for( i=0; i < proj_list.size(); i++ ) - _bbs.map(proj_list[i]->_idx, NULL); + // Initialize the node to block mapping for things on the proj_list + for (uint i = 0; i < proj_list.size(); i++) { + unmap_node_from_block(proj_list[i]); + } // Set the basic block for Nodes pinned into blocks Arena *a = Thread::current()->resource_area(); @@ -1333,7 +1335,7 @@ void PhaseCFG::GlobalCodeMotion( Matcher &matcher, uint unique, Node_List &proj_ for( int i= matcher._null_check_tests.size()-2; i>=0; i-=2 ) { Node *proj = matcher._null_check_tests[i ]; Node *val = matcher._null_check_tests[i+1]; - _bbs[proj->_idx]->implicit_null_check(this, proj, val, allowed_reasons); + get_block_for_node(proj)->implicit_null_check(this, proj, val, allowed_reasons); // The implicit_null_check will only perform the transformation // if the null branch is truly uncommon, *and* it leads to an // uncommon trap. Combined with the too_many_traps guards @@ -1353,7 +1355,7 @@ void PhaseCFG::GlobalCodeMotion( Matcher &matcher, uint unique, Node_List &proj_ uint max_idx = C->unique(); GrowableArray ready_cnt(max_idx, max_idx, -1); visited.Clear(); - for (i = 0; i < _num_blocks; i++) { + for (uint i = 0; i < _num_blocks; i++) { if (!_blocks[i]->schedule_local(this, matcher, ready_cnt, visited)) { if (!C->failure_reason_is(C2Compiler::retry_no_subsuming_loads())) { C->record_method_not_compilable("local schedule failed"); @@ -1364,8 +1366,9 @@ void PhaseCFG::GlobalCodeMotion( Matcher &matcher, uint unique, Node_List &proj_ // If we inserted any instructions between a Call and his CatchNode, // clone the instructions on all paths below the Catch. - for( i=0; i < _num_blocks; i++ ) - _blocks[i]->call_catch_cleanup(_bbs, C); + for (uint i = 0; i < _num_blocks; i++) { + _blocks[i]->call_catch_cleanup(this, C); + } #ifndef PRODUCT if (trace_opto_pipelining()) { @@ -1392,7 +1395,7 @@ void PhaseCFG::Estimate_Block_Frequency() { Block_List worklist; Block* root_blk = _blocks[0]; for (uint i = 1; i < root_blk->num_preds(); i++) { - Block *pb = _bbs[root_blk->pred(i)->_idx]; + Block *pb = get_block_for_node(root_blk->pred(i)); if (pb->has_uncommon_code()) { worklist.push(pb); } @@ -1401,7 +1404,7 @@ void PhaseCFG::Estimate_Block_Frequency() { Block* uct = worklist.pop(); if (uct == _broot) continue; for (uint i = 1; i < uct->num_preds(); i++) { - Block *pb = _bbs[uct->pred(i)->_idx]; + Block *pb = get_block_for_node(uct->pred(i)); if (pb->_num_succs == 1) { worklist.push(pb); } else if (pb->num_fall_throughs() == 2) { @@ -1430,7 +1433,7 @@ void PhaseCFG::Estimate_Block_Frequency() { Block_List worklist; Block* root_blk = _blocks[0]; for (uint i = 1; i < root_blk->num_preds(); i++) { - Block *pb = _bbs[root_blk->pred(i)->_idx]; + Block *pb = get_block_for_node(root_blk->pred(i)); if (pb->has_uncommon_code()) { worklist.push(pb); } @@ -1439,7 +1442,7 @@ void PhaseCFG::Estimate_Block_Frequency() { Block* uct = worklist.pop(); uct->_freq = PROB_MIN; for (uint i = 1; i < uct->num_preds(); i++) { - Block *pb = _bbs[uct->pred(i)->_idx]; + Block *pb = get_block_for_node(uct->pred(i)); if (pb->_num_succs == 1 && pb->_freq > PROB_MIN) { worklist.push(pb); } @@ -1499,7 +1502,7 @@ CFGLoop* PhaseCFG::create_loop_tree() { Block* loop_head = b; assert(loop_head->num_preds() - 1 == 2, "loop must have 2 predecessors"); Node* tail_n = loop_head->pred(LoopNode::LoopBackControl); - Block* tail = _bbs[tail_n->_idx]; + Block* tail = get_block_for_node(tail_n); // Defensively filter out Loop nodes for non-single-entry loops. // For all reasonable loops, the head occurs before the tail in RPO. @@ -1514,13 +1517,13 @@ CFGLoop* PhaseCFG::create_loop_tree() { loop_head->_loop = nloop; // Add to nloop so push_pred() will skip over inner loops nloop->add_member(loop_head); - nloop->push_pred(loop_head, LoopNode::LoopBackControl, worklist, _bbs); + nloop->push_pred(loop_head, LoopNode::LoopBackControl, worklist, this); while (worklist.size() > 0) { Block* member = worklist.pop(); if (member != loop_head) { for (uint j = 1; j < member->num_preds(); j++) { - nloop->push_pred(member, j, worklist, _bbs); + nloop->push_pred(member, j, worklist, this); } } } @@ -1557,9 +1560,9 @@ CFGLoop* PhaseCFG::create_loop_tree() { } //------------------------------push_pred-------------------------------------- -void CFGLoop::push_pred(Block* blk, int i, Block_List& worklist, Block_Array& node_to_blk) { +void CFGLoop::push_pred(Block* blk, int i, Block_List& worklist, PhaseCFG* cfg) { Node* pred_n = blk->pred(i); - Block* pred = node_to_blk[pred_n->_idx]; + Block* pred = cfg->get_block_for_node(pred_n); CFGLoop *pred_loop = pred->_loop; if (pred_loop == NULL) { // Filter out blocks for non-single-entry loops. @@ -1580,7 +1583,7 @@ void CFGLoop::push_pred(Block* blk, int i, Block_List& worklist, Block_Array& no Block* pred_head = pred_loop->head(); assert(pred_head->num_preds() - 1 == 2, "loop must have 2 predecessors"); assert(pred_head != head(), "loop head in only one loop"); - push_pred(pred_head, LoopNode::EntryControl, worklist, node_to_blk); + push_pred(pred_head, LoopNode::EntryControl, worklist, cfg); } else { assert(pred_loop->_parent == this && _parent == NULL, "just checking"); } diff --git a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp index e6909054324..4330643b8b5 100644 --- a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp +++ b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp @@ -413,9 +413,9 @@ void IdealGraphPrinter::visit_node(Node *n, bool edges, VectorSet* temp_set) { print_prop("debug_idx", node->_debug_idx); #endif - if(C->cfg() != NULL) { - Block *block = C->cfg()->_bbs[node->_idx]; - if(block == NULL) { + if (C->cfg() != NULL) { + Block* block = C->cfg()->get_block_for_node(node); + if (block == NULL) { print_prop("block", C->cfg()->_blocks[0]->_pre_order); } else { print_prop("block", block->_pre_order); diff --git a/hotspot/src/share/vm/opto/ifg.cpp b/hotspot/src/share/vm/opto/ifg.cpp index 96c0957cffb..82a8ea893e4 100644 --- a/hotspot/src/share/vm/opto/ifg.cpp +++ b/hotspot/src/share/vm/opto/ifg.cpp @@ -565,7 +565,7 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) { lrgs(r)._def = 0; } n->disconnect_inputs(NULL, C); - _cfg._bbs.map(n->_idx,NULL); + _cfg.unmap_node_from_block(n); n->replace_by(C->top()); // Since yanking a Node from block, high pressure moves up one hrp_index[0]--; @@ -607,7 +607,7 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) { if( n->is_SpillCopy() && lrgs(r).is_singledef() // MultiDef live range can still split && n->outcnt() == 1 // and use must be in this block - && _cfg._bbs[n->unique_out()->_idx] == b ) { + && _cfg.get_block_for_node(n->unique_out()) == b ) { // All single-use MachSpillCopy(s) that immediately precede their // use must color early. If a longer live range steals their // color, the spill copy will split and may push another spill copy diff --git a/hotspot/src/share/vm/opto/lcm.cpp b/hotspot/src/share/vm/opto/lcm.cpp index 2b3eca478d9..fc05a79b416 100644 --- a/hotspot/src/share/vm/opto/lcm.cpp +++ b/hotspot/src/share/vm/opto/lcm.cpp @@ -237,7 +237,7 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe } // Check ctrl input to see if the null-check dominates the memory op - Block *cb = cfg->_bbs[mach->_idx]; + Block *cb = cfg->get_block_for_node(mach); cb = cb->_idom; // Always hoist at least 1 block if( !was_store ) { // Stores can be hoisted only one block while( cb->_dom_depth > (_dom_depth + 1)) @@ -262,7 +262,7 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe if( is_decoden ) continue; } // Block of memory-op input - Block *inb = cfg->_bbs[mach->in(j)->_idx]; + Block *inb = cfg->get_block_for_node(mach->in(j)); Block *b = this; // Start from nul check while( b != inb && b->_dom_depth > inb->_dom_depth ) b = b->_idom; // search upwards for input @@ -272,7 +272,7 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe } if( j > 0 ) continue; - Block *mb = cfg->_bbs[mach->_idx]; + Block *mb = cfg->get_block_for_node(mach); // Hoisting stores requires more checks for the anti-dependence case. // Give up hoisting if we have to move the store past any load. if( was_store ) { @@ -291,7 +291,7 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe break; // Found anti-dependent load // Make sure control does not do a merge (would have to check allpaths) if( b->num_preds() != 2 ) break; - b = cfg->_bbs[b->pred(1)->_idx]; // Move up to predecessor block + b = cfg->get_block_for_node(b->pred(1)); // Move up to predecessor block } if( b != this ) continue; } @@ -303,15 +303,15 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe // Found a candidate! Pick one with least dom depth - the highest // in the dom tree should be closest to the null check. - if( !best || - cfg->_bbs[mach->_idx]->_dom_depth < cfg->_bbs[best->_idx]->_dom_depth ) { + if (best == NULL || cfg->get_block_for_node(mach)->_dom_depth < cfg->get_block_for_node(best)->_dom_depth) { best = mach; bidx = vidx; - } } // No candidate! - if( !best ) return; + if (best == NULL) { + return; + } // ---- Found an implicit null check extern int implicit_null_checks; @@ -319,29 +319,29 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe if( is_decoden ) { // Check if we need to hoist decodeHeapOop_not_null first. - Block *valb = cfg->_bbs[val->_idx]; + Block *valb = cfg->get_block_for_node(val); if( this != valb && this->_dom_depth < valb->_dom_depth ) { // Hoist it up to the end of the test block. valb->find_remove(val); this->add_inst(val); - cfg->_bbs.map(val->_idx,this); + cfg->map_node_to_block(val, this); // DecodeN on x86 may kill flags. Check for flag-killing projections // that also need to be hoisted. for (DUIterator_Fast jmax, j = val->fast_outs(jmax); j < jmax; j++) { Node* n = val->fast_out(j); if( n->is_MachProj() ) { - cfg->_bbs[n->_idx]->find_remove(n); + cfg->get_block_for_node(n)->find_remove(n); this->add_inst(n); - cfg->_bbs.map(n->_idx,this); + cfg->map_node_to_block(n, this); } } } } // Hoist the memory candidate up to the end of the test block. - Block *old_block = cfg->_bbs[best->_idx]; + Block *old_block = cfg->get_block_for_node(best); old_block->find_remove(best); add_inst(best); - cfg->_bbs.map(best->_idx,this); + cfg->map_node_to_block(best, this); // Move the control dependence if (best->in(0) && best->in(0) == old_block->_nodes[0]) @@ -352,9 +352,9 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe for (DUIterator_Fast jmax, j = best->fast_outs(jmax); j < jmax; j++) { Node* n = best->fast_out(j); if( n->is_MachProj() ) { - cfg->_bbs[n->_idx]->find_remove(n); + cfg->get_block_for_node(n)->find_remove(n); add_inst(n); - cfg->_bbs.map(n->_idx,this); + cfg->map_node_to_block(n, this); } } @@ -385,7 +385,7 @@ void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowe Node *old_tst = proj->in(0); MachNode *nul_chk = new (C) MachNullCheckNode(old_tst->in(0),best,bidx); _nodes.map(end_idx(),nul_chk); - cfg->_bbs.map(nul_chk->_idx,this); + cfg->map_node_to_block(nul_chk, this); // Redirect users of old_test to nul_chk for (DUIterator_Last i2min, i2 = old_tst->last_outs(i2min); i2 >= i2min; --i2) old_tst->last_out(i2)->set_req(0, nul_chk); @@ -468,7 +468,7 @@ Node *Block::select(PhaseCFG *cfg, Node_List &worklist, GrowableArray &read Node* use = n->fast_out(j); // The use is a conditional branch, make them adjacent - if (use->is_MachIf() && cfg->_bbs[use->_idx]==this ) { + if (use->is_MachIf() && cfg->get_block_for_node(use) == this) { found_machif = true; break; } @@ -529,13 +529,14 @@ Node *Block::select(PhaseCFG *cfg, Node_List &worklist, GrowableArray &read //------------------------------set_next_call---------------------------------- -void Block::set_next_call( Node *n, VectorSet &next_call, Block_Array &bbs ) { +void Block::set_next_call( Node *n, VectorSet &next_call, PhaseCFG* cfg) { if( next_call.test_set(n->_idx) ) return; for( uint i=0; ilen(); i++ ) { Node *m = n->in(i); if( !m ) continue; // must see all nodes in block that precede call - if( bbs[m->_idx] == this ) - set_next_call( m, next_call, bbs ); + if (cfg->get_block_for_node(m) == this) { + set_next_call(m, next_call, cfg); + } } } @@ -545,12 +546,12 @@ void Block::set_next_call( Node *n, VectorSet &next_call, Block_Array &bbs ) { // next subroutine call get priority - basically it moves things NOT needed // for the next call till after the call. This prevents me from trying to // carry lots of stuff live across a call. -void Block::needed_for_next_call(Node *this_call, VectorSet &next_call, Block_Array &bbs) { +void Block::needed_for_next_call(Node *this_call, VectorSet &next_call, PhaseCFG* cfg) { // Find the next control-defining Node in this block Node* call = NULL; for (DUIterator_Fast imax, i = this_call->fast_outs(imax); i < imax; i++) { Node* m = this_call->fast_out(i); - if( bbs[m->_idx] == this && // Local-block user + if(cfg->get_block_for_node(m) == this && // Local-block user m != this_call && // Not self-start node m->is_MachCall() ) call = m; @@ -558,7 +559,7 @@ void Block::needed_for_next_call(Node *this_call, VectorSet &next_call, Block_Ar } if (call == NULL) return; // No next call (e.g., block end is near) // Set next-call for all inputs to this call - set_next_call(call, next_call, bbs); + set_next_call(call, next_call, cfg); } //------------------------------add_call_kills------------------------------------- @@ -578,7 +579,7 @@ void Block::add_call_kills(MachProjNode *proj, RegMask& regs, const char* save_p //------------------------------sched_call------------------------------------- -uint Block::sched_call( Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_List &worklist, GrowableArray &ready_cnt, MachCallNode *mcall, VectorSet &next_call ) { +uint Block::sched_call( Matcher &matcher, PhaseCFG* cfg, uint node_cnt, Node_List &worklist, GrowableArray &ready_cnt, MachCallNode *mcall, VectorSet &next_call ) { RegMask regs; // Schedule all the users of the call right now. All the users are @@ -597,12 +598,14 @@ uint Block::sched_call( Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_ // Check for scheduling the next control-definer if( n->bottom_type() == Type::CONTROL ) // Warm up next pile of heuristic bits - needed_for_next_call(n, next_call, bbs); + needed_for_next_call(n, next_call, cfg); // Children of projections are now all ready for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) { Node* m = n->fast_out(j); // Get user - if( bbs[m->_idx] != this ) continue; + if(cfg->get_block_for_node(m) != this) { + continue; + } if( m->is_Phi() ) continue; int m_cnt = ready_cnt.at(m->_idx)-1; ready_cnt.at_put(m->_idx, m_cnt); @@ -620,7 +623,7 @@ uint Block::sched_call( Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_ uint r_cnt = mcall->tf()->range()->cnt(); int op = mcall->ideal_Opcode(); MachProjNode *proj = new (matcher.C) MachProjNode( mcall, r_cnt+1, RegMask::Empty, MachProjNode::fat_proj ); - bbs.map(proj->_idx,this); + cfg->map_node_to_block(proj, this); _nodes.insert(node_cnt++, proj); // Select the right register save policy. @@ -708,7 +711,7 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray & uint local = 0; for( uint j=0; jin(j); - if( m && cfg->_bbs[m->_idx] == this && !m->is_top() ) + if( m && cfg->get_block_for_node(m) == this && !m->is_top() ) local++; // One more block-local input } ready_cnt.at_put(n->_idx, local); // Count em up @@ -720,7 +723,7 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray & for (uint prec = n->req(); prec < n->len(); prec++) { Node* oop_store = n->in(prec); if (oop_store != NULL) { - assert(cfg->_bbs[oop_store->_idx]->_dom_depth <= this->_dom_depth, "oop_store must dominate card-mark"); + assert(cfg->get_block_for_node(oop_store)->_dom_depth <= this->_dom_depth, "oop_store must dominate card-mark"); } } } @@ -753,7 +756,7 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray & Node *n = _nodes[i3]; // Get pre-scheduled for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) { Node* m = n->fast_out(j); - if( cfg->_bbs[m->_idx] ==this ) { // Local-block user + if (cfg->get_block_for_node(m) == this) { // Local-block user int m_cnt = ready_cnt.at(m->_idx)-1; ready_cnt.at_put(m->_idx, m_cnt); // Fix ready count } @@ -786,7 +789,7 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray & } // Warm up the 'next_call' heuristic bits - needed_for_next_call(_nodes[0], next_call, cfg->_bbs); + needed_for_next_call(_nodes[0], next_call, cfg); #ifndef PRODUCT if (cfg->trace_opto_pipelining()) { @@ -837,7 +840,7 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray & #endif if( n->is_MachCall() ) { MachCallNode *mcall = n->as_MachCall(); - phi_cnt = sched_call(matcher, cfg->_bbs, phi_cnt, worklist, ready_cnt, mcall, next_call); + phi_cnt = sched_call(matcher, cfg, phi_cnt, worklist, ready_cnt, mcall, next_call); continue; } @@ -847,7 +850,7 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray & regs.OR(n->out_RegMask()); MachProjNode *proj = new (matcher.C) MachProjNode( n, 1, RegMask::Empty, MachProjNode::fat_proj ); - cfg->_bbs.map(proj->_idx,this); + cfg->map_node_to_block(proj, this); _nodes.insert(phi_cnt++, proj); add_call_kills(proj, regs, matcher._c_reg_save_policy, false); @@ -856,7 +859,9 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray & // Children are now all ready for (DUIterator_Fast i5max, i5 = n->fast_outs(i5max); i5 < i5max; i5++) { Node* m = n->fast_out(i5); // Get user - if( cfg->_bbs[m->_idx] != this ) continue; + if (cfg->get_block_for_node(m) != this) { + continue; + } if( m->is_Phi() ) continue; if (m->_idx >= max_idx) { // new node, skip it assert(m->is_MachProj() && n->is_Mach() && n->as_Mach()->has_call(), "unexpected node types"); @@ -914,7 +919,7 @@ static void catch_cleanup_fix_all_inputs(Node *use, Node *old_def, Node *new_def } //------------------------------catch_cleanup_find_cloned_def------------------ -static Node *catch_cleanup_find_cloned_def(Block *use_blk, Node *def, Block *def_blk, Block_Array &bbs, int n_clone_idx) { +static Node *catch_cleanup_find_cloned_def(Block *use_blk, Node *def, Block *def_blk, PhaseCFG* cfg, int n_clone_idx) { assert( use_blk != def_blk, "Inter-block cleanup only"); // The use is some block below the Catch. Find and return the clone of the def @@ -940,7 +945,8 @@ static Node *catch_cleanup_find_cloned_def(Block *use_blk, Node *def, Block *def // PhiNode, the PhiNode uses from the def and IT's uses need fixup. Node_Array inputs = new Node_List(Thread::current()->resource_area()); for(uint k = 1; k < use_blk->num_preds(); k++) { - inputs.map(k, catch_cleanup_find_cloned_def(bbs[use_blk->pred(k)->_idx], def, def_blk, bbs, n_clone_idx)); + Block* block = cfg->get_block_for_node(use_blk->pred(k)); + inputs.map(k, catch_cleanup_find_cloned_def(block, def, def_blk, cfg, n_clone_idx)); } // Check to see if the use_blk already has an identical phi inserted. @@ -962,7 +968,7 @@ static Node *catch_cleanup_find_cloned_def(Block *use_blk, Node *def, Block *def if (fixup == NULL) { Node *new_phi = PhiNode::make(use_blk->head(), def); use_blk->_nodes.insert(1, new_phi); - bbs.map(new_phi->_idx, use_blk); + cfg->map_node_to_block(new_phi, use_blk); for (uint k = 1; k < use_blk->num_preds(); k++) { new_phi->set_req(k, inputs[k]); } @@ -1002,17 +1008,17 @@ static void catch_cleanup_intra_block(Node *use, Node *def, Block *blk, int beg, //------------------------------catch_cleanup_inter_block--------------------- // Fix all input edges in use that reference "def". The use is in a different // block than the def. -static void catch_cleanup_inter_block(Node *use, Block *use_blk, Node *def, Block *def_blk, Block_Array &bbs, int n_clone_idx) { +static void catch_cleanup_inter_block(Node *use, Block *use_blk, Node *def, Block *def_blk, PhaseCFG* cfg, int n_clone_idx) { if( !use_blk ) return; // Can happen if the use is a precedence edge - Node *new_def = catch_cleanup_find_cloned_def(use_blk, def, def_blk, bbs, n_clone_idx); + Node *new_def = catch_cleanup_find_cloned_def(use_blk, def, def_blk, cfg, n_clone_idx); catch_cleanup_fix_all_inputs(use, def, new_def); } //------------------------------call_catch_cleanup----------------------------- // If we inserted any instructions between a Call and his CatchNode, // clone the instructions on all paths below the Catch. -void Block::call_catch_cleanup(Block_Array &bbs, Compile* C) { +void Block::call_catch_cleanup(PhaseCFG* cfg, Compile* C) { // End of region to clone uint end = end_idx(); @@ -1037,7 +1043,7 @@ void Block::call_catch_cleanup(Block_Array &bbs, Compile* C) { // since clones dominate on each path. Node *clone = _nodes[j-1]->clone(); sb->_nodes.insert( 1, clone ); - bbs.map(clone->_idx,sb); + cfg->map_node_to_block(clone, sb); } } @@ -1054,18 +1060,19 @@ void Block::call_catch_cleanup(Block_Array &bbs, Compile* C) { uint max = out->size(); for (uint j = 0; j < max; j++) {// For all users Node *use = out->pop(); - Block *buse = bbs[use->_idx]; + Block *buse = cfg->get_block_for_node(use); if( use->is_Phi() ) { for( uint k = 1; k < use->req(); k++ ) if( use->in(k) == n ) { - Node *fixup = catch_cleanup_find_cloned_def(bbs[buse->pred(k)->_idx], n, this, bbs, n_clone_idx); + Block* block = cfg->get_block_for_node(buse->pred(k)); + Node *fixup = catch_cleanup_find_cloned_def(block, n, this, cfg, n_clone_idx); use->set_req(k, fixup); } } else { if (this == buse) { catch_cleanup_intra_block(use, n, this, beg, n_clone_idx); } else { - catch_cleanup_inter_block(use, buse, n, this, bbs, n_clone_idx); + catch_cleanup_inter_block(use, buse, n, this, cfg, n_clone_idx); } } } // End for all users diff --git a/hotspot/src/share/vm/opto/live.cpp b/hotspot/src/share/vm/opto/live.cpp index 773dd1ea2e6..846609e8a49 100644 --- a/hotspot/src/share/vm/opto/live.cpp +++ b/hotspot/src/share/vm/opto/live.cpp @@ -101,7 +101,7 @@ void PhaseLive::compute(uint maxlrg) { for( uint k=1; kin(k); uint nkidx = nk->_idx; - if( _cfg._bbs[nkidx] != b ) { + if (_cfg.get_block_for_node(nk) != b) { uint u = _names[nkidx]; use->insert( u ); DEBUG_ONLY(def_outside->insert( u );) @@ -121,7 +121,7 @@ void PhaseLive::compute(uint maxlrg) { // Push these live-in things to predecessors for( uint l=1; lnum_preds(); l++ ) { - Block *p = _cfg._bbs[b->pred(l)->_idx]; + Block *p = _cfg.get_block_for_node(b->pred(l)); add_liveout( p, use, first_pass ); // PhiNode uses go in the live-out set of prior blocks. @@ -142,8 +142,10 @@ void PhaseLive::compute(uint maxlrg) { assert( delta->count(), "missing delta set" ); // Add new-live-in to predecessors live-out sets - for( uint l=1; lnum_preds(); l++ ) - add_liveout( _cfg._bbs[b->pred(l)->_idx], delta, first_pass ); + for (uint l = 1; l < b->num_preds(); l++) { + Block* block = _cfg.get_block_for_node(b->pred(l)); + add_liveout(block, delta, first_pass); + } freeset(b); } // End of while-worklist-not-empty diff --git a/hotspot/src/share/vm/opto/node.hpp b/hotspot/src/share/vm/opto/node.hpp index bb5e8f200d0..0690d21b122 100644 --- a/hotspot/src/share/vm/opto/node.hpp +++ b/hotspot/src/share/vm/opto/node.hpp @@ -42,7 +42,6 @@ class AliasInfo; class AllocateArrayNode; class AllocateNode; class Block; -class Block_Array; class BoolNode; class BoxLockNode; class CMoveNode; diff --git a/hotspot/src/share/vm/opto/output.cpp b/hotspot/src/share/vm/opto/output.cpp index f04ab721b97..24a4497c680 100644 --- a/hotspot/src/share/vm/opto/output.cpp +++ b/hotspot/src/share/vm/opto/output.cpp @@ -68,7 +68,6 @@ void Compile::Output() { return; } // Make sure I can find the Start Node - Block_Array& bbs = _cfg->_bbs; Block *entry = _cfg->_blocks[1]; Block *broot = _cfg->_broot; @@ -77,8 +76,8 @@ void Compile::Output() { // Replace StartNode with prolog MachPrologNode *prolog = new (this) MachPrologNode(); entry->_nodes.map( 0, prolog ); - bbs.map( prolog->_idx, entry ); - bbs.map( start->_idx, NULL ); // start is no longer in any block + _cfg->map_node_to_block(prolog, entry); + _cfg->unmap_node_from_block(start); // start is no longer in any block // Virtual methods need an unverified entry point @@ -117,8 +116,7 @@ void Compile::Output() { if( m->is_Mach() && m->as_Mach()->ideal_Opcode() != Op_Halt ) { MachEpilogNode *epilog = new (this) MachEpilogNode(m->as_Mach()->ideal_Opcode() == Op_Return); b->add_inst( epilog ); - bbs.map(epilog->_idx, b); - //_regalloc->set_bad(epilog->_idx); // Already initialized this way. + _cfg->map_node_to_block(epilog, b); } } } @@ -252,7 +250,7 @@ void Compile::Insert_zap_nodes() { if (insert) { Node *zap = call_zap_node(n->as_MachSafePoint(), i); b->_nodes.insert( j, zap ); - _cfg->_bbs.map( zap->_idx, b ); + _cfg->map_node_to_block(zap, b); ++j; } } @@ -1234,7 +1232,7 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) { #ifdef ASSERT if (!b->is_connector()) { stringStream st; - b->dump_head(&_cfg->_bbs, &st); + b->dump_head(_cfg, &st); MacroAssembler(cb).block_comment(st.as_string()); } jmp_target[i] = 0; @@ -1310,7 +1308,7 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) { MachNode *nop = new (this) MachNopNode(nops_cnt); b->_nodes.insert(j++, nop); last_inst++; - _cfg->_bbs.map( nop->_idx, b ); + _cfg->map_node_to_block(nop, b); nop->emit(*cb, _regalloc); cb->flush_bundle(true); current_offset = cb->insts_size(); @@ -1395,7 +1393,7 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) { if (needs_padding && replacement->avoid_back_to_back()) { MachNode *nop = new (this) MachNopNode(); b->_nodes.insert(j++, nop); - _cfg->_bbs.map(nop->_idx, b); + _cfg->map_node_to_block(nop, b); last_inst++; nop->emit(*cb, _regalloc); cb->flush_bundle(true); @@ -1549,7 +1547,7 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) { if( padding > 0 ) { MachNode *nop = new (this) MachNopNode(padding / nop_size); b->_nodes.insert( b->_nodes.size(), nop ); - _cfg->_bbs.map( nop->_idx, b ); + _cfg->map_node_to_block(nop, b); nop->emit(*cb, _regalloc); current_offset = cb->insts_size(); } @@ -1737,7 +1735,6 @@ uint Scheduling::_total_instructions_per_bundle[Pipeline::_max_instrs_per_cycle+ Scheduling::Scheduling(Arena *arena, Compile &compile) : _arena(arena), _cfg(compile.cfg()), - _bbs(compile.cfg()->_bbs), _regalloc(compile.regalloc()), _reg_node(arena), _bundle_instr_count(0), @@ -2085,8 +2082,9 @@ void Scheduling::DecrementUseCounts(Node *n, const Block *bb) { if( def->is_Proj() ) // If this is a machine projection, then def = def->in(0); // propagate usage thru to the base instruction - if( _bbs[def->_idx] != bb ) // Ignore if not block-local + if(_cfg->get_block_for_node(def) != bb) { // Ignore if not block-local continue; + } // Compute the latency uint l = _bundle_cycle_number + n->latency(i); @@ -2358,9 +2356,10 @@ void Scheduling::ComputeUseCount(const Block *bb) { Node *inp = n->in(k); if (!inp) continue; assert(inp != n, "no cycles allowed" ); - if( _bbs[inp->_idx] == bb ) { // Block-local use? - if( inp->is_Proj() ) // Skip through Proj's + if (_cfg->get_block_for_node(inp) == bb) { // Block-local use? + if (inp->is_Proj()) { // Skip through Proj's inp = inp->in(0); + } ++_uses[inp->_idx]; // Count 1 block-local use } } @@ -2643,7 +2642,7 @@ void Scheduling::anti_do_def( Block *b, Node *def, OptoReg::Name def_reg, int is return; Node *pinch = _reg_node[def_reg]; // Get pinch point - if( !pinch || _bbs[pinch->_idx] != b || // No pinch-point yet? + if ((pinch == NULL) || _cfg->get_block_for_node(pinch) != b || // No pinch-point yet? is_def ) { // Check for a true def (not a kill) _reg_node.map(def_reg,def); // Record def/kill as the optimistic pinch-point return; @@ -2669,7 +2668,7 @@ void Scheduling::anti_do_def( Block *b, Node *def, OptoReg::Name def_reg, int is _cfg->C->record_method_not_compilable("too many D-U pinch points"); return; } - _bbs.map(pinch->_idx,b); // Pretend it's valid in this block (lazy init) + _cfg->map_node_to_block(pinch, b); // Pretend it's valid in this block (lazy init) _reg_node.map(def_reg,pinch); // Record pinch-point //_regalloc->set_bad(pinch->_idx); // Already initialized this way. if( later_def->outcnt() == 0 || later_def->ideal_reg() == MachProjNode::fat_proj ) { // Distinguish def from kill @@ -2713,9 +2712,9 @@ void Scheduling::anti_do_use( Block *b, Node *use, OptoReg::Name use_reg ) { return; Node *pinch = _reg_node[use_reg]; // Get pinch point // Check for no later def_reg/kill in block - if( pinch && _bbs[pinch->_idx] == b && + if ((pinch != NULL) && _cfg->get_block_for_node(pinch) == b && // Use has to be block-local as well - _bbs[use->_idx] == b ) { + _cfg->get_block_for_node(use) == b) { if( pinch->Opcode() == Op_Node && // Real pinch-point (not optimistic?) pinch->req() == 1 ) { // pinch not yet in block? pinch->del_req(0); // yank pointer to later-def, also set flag @@ -2895,7 +2894,7 @@ void Scheduling::garbage_collect_pinch_nodes() { int trace_cnt = 0; for (uint k = 0; k < _reg_node.Size(); k++) { Node* pinch = _reg_node[k]; - if (pinch != NULL && pinch->Opcode() == Op_Node && + if ((pinch != NULL) && pinch->Opcode() == Op_Node && // no predecence input edges (pinch->req() == pinch->len() || pinch->in(pinch->req()) == NULL) ) { cleanup_pinch(pinch); diff --git a/hotspot/src/share/vm/opto/output.hpp b/hotspot/src/share/vm/opto/output.hpp index 50b6e76035e..5fb68c6828a 100644 --- a/hotspot/src/share/vm/opto/output.hpp +++ b/hotspot/src/share/vm/opto/output.hpp @@ -96,9 +96,6 @@ private: // List of nodes currently available for choosing for scheduling Node_List _available; - // Mapping from node (index) to basic block - Block_Array& _bbs; - // For each instruction beginning a bundle, the number of following // nodes to be bundled with it. Bundle *_node_bundling_base; diff --git a/hotspot/src/share/vm/opto/postaloc.cpp b/hotspot/src/share/vm/opto/postaloc.cpp index c1b3fdbd231..76c3def2d40 100644 --- a/hotspot/src/share/vm/opto/postaloc.cpp +++ b/hotspot/src/share/vm/opto/postaloc.cpp @@ -78,11 +78,13 @@ bool PhaseChaitin::may_be_copy_of_callee( Node *def ) const { // Helper function for yank_if_dead int PhaseChaitin::yank( Node *old, Block *current_block, Node_List *value, Node_List *regnd ) { int blk_adjust=0; - Block *oldb = _cfg._bbs[old->_idx]; + Block *oldb = _cfg.get_block_for_node(old); oldb->find_remove(old); // Count 1 if deleting an instruction from the current block - if( oldb == current_block ) blk_adjust++; - _cfg._bbs.map(old->_idx,NULL); + if (oldb == current_block) { + blk_adjust++; + } + _cfg.unmap_node_from_block(old); OptoReg::Name old_reg = lrgs(_lrg_map.live_range_id(old)).reg(); if( regnd && (*regnd)[old_reg]==old ) { // Instruction is currently available? value->map(old_reg,NULL); // Yank from value/regnd maps @@ -433,7 +435,7 @@ void PhaseChaitin::post_allocate_copy_removal() { bool missing_some_inputs = false; Block *freed = NULL; for( j = 1; j < b->num_preds(); j++ ) { - Block *pb = _cfg._bbs[b->pred(j)->_idx]; + Block *pb = _cfg.get_block_for_node(b->pred(j)); // Remove copies along phi edges for( uint k=1; k_nodes[k], j, b, *blk2value[pb->_pre_order], *blk2regnd[pb->_pre_order], false ); @@ -478,7 +480,7 @@ void PhaseChaitin::post_allocate_copy_removal() { } else { if( !freed ) { // Didn't get a freebie prior block // Must clone some data - freed = _cfg._bbs[b->pred(1)->_idx]; + freed = _cfg.get_block_for_node(b->pred(1)); Node_List &f_value = *blk2value[freed->_pre_order]; Node_List &f_regnd = *blk2regnd[freed->_pre_order]; for( uint k = 0; k < (uint)_max_reg; k++ ) { @@ -488,7 +490,7 @@ void PhaseChaitin::post_allocate_copy_removal() { } // Merge all inputs together, setting to NULL any conflicts. for( j = 1; j < b->num_preds(); j++ ) { - Block *pb = _cfg._bbs[b->pred(j)->_idx]; + Block *pb = _cfg.get_block_for_node(b->pred(j)); if( pb == freed ) continue; // Did self already via freelist Node_List &p_regnd = *blk2regnd[pb->_pre_order]; for( uint k = 0; k < (uint)_max_reg; k++ ) { @@ -515,8 +517,9 @@ void PhaseChaitin::post_allocate_copy_removal() { u = u ? NodeSentinel : x; // Capture unique input, or NodeSentinel for 2nd input } if( u != NodeSentinel ) { // Junk Phi. Remove - b->_nodes.remove(j--); phi_dex--; - _cfg._bbs.map(phi->_idx,NULL); + b->_nodes.remove(j--); + phi_dex--; + _cfg.unmap_node_from_block(phi); phi->replace_by(u); phi->disconnect_inputs(NULL, C); continue; diff --git a/hotspot/src/share/vm/opto/reg_split.cpp b/hotspot/src/share/vm/opto/reg_split.cpp index 30ac26ba989..6e4323b406e 100644 --- a/hotspot/src/share/vm/opto/reg_split.cpp +++ b/hotspot/src/share/vm/opto/reg_split.cpp @@ -132,7 +132,7 @@ void PhaseChaitin::insert_proj( Block *b, uint i, Node *spill, uint maxlrg ) { } b->_nodes.insert(i,spill); // Insert node in block - _cfg._bbs.map(spill->_idx,b); // Update node->block mapping to reflect + _cfg.map_node_to_block(spill, b); // Update node->block mapping to reflect // Adjust the point where we go hi-pressure if( i <= b->_ihrp_index ) b->_ihrp_index++; if( i <= b->_fhrp_index ) b->_fhrp_index++; @@ -219,7 +219,7 @@ uint PhaseChaitin::split_USE( Node *def, Block *b, Node *use, uint useidx, uint use->set_req(useidx, def); } else { // Block and index where the use occurs. - Block *b = _cfg._bbs[use->_idx]; + Block *b = _cfg.get_block_for_node(use); // Put the clone just prior to use int bindex = b->find_node(use); // DEF is UP, so must copy it DOWN and hook in USE @@ -270,7 +270,7 @@ uint PhaseChaitin::split_USE( Node *def, Block *b, Node *use, uint useidx, uint int bindex; // Phi input spill-copys belong at the end of the prior block if( use->is_Phi() ) { - b = _cfg._bbs[b->pred(useidx)->_idx]; + b = _cfg.get_block_for_node(b->pred(useidx)); bindex = b->end_idx(); } else { // Put the clone just prior to use @@ -335,7 +335,7 @@ Node *PhaseChaitin::split_Rematerialize( Node *def, Block *b, uint insidx, uint continue; } - Block *b_def = _cfg._bbs[def->_idx]; + Block *b_def = _cfg.get_block_for_node(def); int idx_def = b_def->find_node(def); Node *in_spill = get_spillcopy_wide( in, def, i ); if( !in_spill ) return 0; // Bailed out @@ -589,7 +589,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { UPblock[slidx] = true; // Record following instruction in case 'n' rematerializes and // kills flags - Block *pred1 = _cfg._bbs[b->pred(1)->_idx]; + Block *pred1 = _cfg.get_block_for_node(b->pred(1)); continue; } @@ -601,7 +601,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { // Grab predecessor block header n1 = b->pred(1); // Grab the appropriate reaching def info for inpidx - pred = _cfg._bbs[n1->_idx]; + pred = _cfg.get_block_for_node(n1); pidx = pred->_pre_order; Node **Ltmp = Reaches[pidx]; bool *Utmp = UP[pidx]; @@ -616,7 +616,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { // Grab predecessor block headers n2 = b->pred(inpidx); // Grab the appropriate reaching def info for inpidx - pred = _cfg._bbs[n2->_idx]; + pred = _cfg.get_block_for_node(n2); pidx = pred->_pre_order; Ltmp = Reaches[pidx]; Utmp = UP[pidx]; @@ -701,7 +701,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { // Grab predecessor block header n1 = b->pred(1); // Grab the appropriate reaching def info for k - pred = _cfg._bbs[n1->_idx]; + pred = _cfg.get_block_for_node(n1); pidx = pred->_pre_order; Node **Ltmp = Reaches[pidx]; bool *Utmp = UP[pidx]; @@ -919,7 +919,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { return 0; } _lrg_map.extend(def->_idx, 0); - _cfg._bbs.map(def->_idx,b); + _cfg.map_node_to_block(def, b); n->set_req(inpidx, def); continue; } @@ -1291,7 +1291,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { for( insidx = 0; insidx < phis->size(); insidx++ ) { Node *phi = phis->at(insidx); assert(phi->is_Phi(),"This list must only contain Phi Nodes"); - Block *b = _cfg._bbs[phi->_idx]; + Block *b = _cfg.get_block_for_node(phi); // Grab the live range number uint lidx = _lrg_map.find_id(phi); uint slidx = lrg2reach[lidx]; @@ -1315,7 +1315,7 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) { // DEF has the wrong UP/DOWN value. for( uint i = 1; i < b->num_preds(); i++ ) { // Get predecessor block pre-order number - Block *pred = _cfg._bbs[b->pred(i)->_idx]; + Block *pred = _cfg.get_block_for_node(b->pred(i)); pidx = pred->_pre_order; // Grab reaching def Node *def = Reaches[pidx][slidx]; diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index e7de9601c96..163433b524f 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -1098,7 +1098,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; \ c2_nonstatic_field(PhaseCFG, _num_blocks, uint) \ c2_nonstatic_field(PhaseCFG, _blocks, Block_List) \ - c2_nonstatic_field(PhaseCFG, _bbs, Block_Array) \ + c2_nonstatic_field(PhaseCFG, _node_to_block_mapping, Block_Array) \ c2_nonstatic_field(PhaseCFG, _broot, Block*) \ \ c2_nonstatic_field(PhaseRegAlloc, _node_regs, OptoRegPair*) \ From fc44cdf0ecd816b025deea2d56201bd4dcb81300 Mon Sep 17 00:00:00 2001 From: Niclas Adlertz Date: Wed, 7 Aug 2013 18:04:42 +0200 Subject: [PATCH 017/102] 8022475: Remove unneeded ad-files Remove .ad files that are not used Reviewed-by: kvn --- hotspot/make/bsd/makefiles/adlc.make | 6 +- hotspot/make/linux/makefiles/adlc.make | 6 +- hotspot/make/solaris/makefiles/adlc.make | 6 +- hotspot/make/windows/makefiles/adlc.make | 6 +- hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_32.ad | 26 -------- hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_64.ad | 65 ------------------- .../src/os_cpu/linux_x86/vm/linux_x86_32.ad | 26 -------- .../src/os_cpu/linux_x86/vm/linux_x86_64.ad | 65 ------------------- .../os_cpu/solaris_sparc/vm/solaris_sparc.ad | 27 -------- .../os_cpu/solaris_x86/vm/solaris_x86_32.ad | 26 -------- .../os_cpu/solaris_x86/vm/solaris_x86_64.ad | 63 ------------------ .../os_cpu/windows_x86/vm/windows_x86_32.ad | 26 -------- .../os_cpu/windows_x86/vm/windows_x86_64.ad | 63 ------------------ 13 files changed, 8 insertions(+), 403 deletions(-) delete mode 100644 hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_32.ad delete mode 100644 hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_64.ad delete mode 100644 hotspot/src/os_cpu/linux_x86/vm/linux_x86_32.ad delete mode 100644 hotspot/src/os_cpu/linux_x86/vm/linux_x86_64.ad delete mode 100644 hotspot/src/os_cpu/solaris_sparc/vm/solaris_sparc.ad delete mode 100644 hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.ad delete mode 100644 hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.ad delete mode 100644 hotspot/src/os_cpu/windows_x86/vm/windows_x86_32.ad delete mode 100644 hotspot/src/os_cpu/windows_x86/vm/windows_x86_64.ad diff --git a/hotspot/make/bsd/makefiles/adlc.make b/hotspot/make/bsd/makefiles/adlc.make index 826d256b9eb..cf5c05e2ac7 100644 --- a/hotspot/make/bsd/makefiles/adlc.make +++ b/hotspot/make/bsd/makefiles/adlc.make @@ -41,13 +41,11 @@ SOURCE.AD = $(OUTDIR)/$(OS)_$(Platform_arch_model).ad ifeq ("${Platform_arch_model}", "${Platform_arch}") SOURCES.AD = \ - $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \ - $(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad) + $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) else SOURCES.AD = \ $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \ - $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch).ad) \ - $(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad) + $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch).ad) endif EXEC = $(OUTDIR)/adlc diff --git a/hotspot/make/linux/makefiles/adlc.make b/hotspot/make/linux/makefiles/adlc.make index 25ace2f5f76..7b808d9b2ae 100644 --- a/hotspot/make/linux/makefiles/adlc.make +++ b/hotspot/make/linux/makefiles/adlc.make @@ -41,13 +41,11 @@ SOURCE.AD = $(OUTDIR)/$(OS)_$(Platform_arch_model).ad ifeq ("${Platform_arch_model}", "${Platform_arch}") SOURCES.AD = \ - $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \ - $(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad) + $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) else SOURCES.AD = \ $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \ - $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch).ad) \ - $(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad) + $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch).ad) endif EXEC = $(OUTDIR)/adlc diff --git a/hotspot/make/solaris/makefiles/adlc.make b/hotspot/make/solaris/makefiles/adlc.make index 750bd8319bf..642a7ca6136 100644 --- a/hotspot/make/solaris/makefiles/adlc.make +++ b/hotspot/make/solaris/makefiles/adlc.make @@ -42,13 +42,11 @@ SOURCE.AD = $(OUTDIR)/$(OS)_$(Platform_arch_model).ad ifeq ("${Platform_arch_model}", "${Platform_arch}") SOURCES.AD = \ - $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \ - $(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad) + $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) else SOURCES.AD = \ $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \ - $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch).ad) \ - $(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad) + $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch).ad) endif EXEC = $(OUTDIR)/adlc diff --git a/hotspot/make/windows/makefiles/adlc.make b/hotspot/make/windows/makefiles/adlc.make index f320d4e932d..7bcaef718fd 100644 --- a/hotspot/make/windows/makefiles/adlc.make +++ b/hotspot/make/windows/makefiles/adlc.make @@ -55,13 +55,11 @@ CXX_INCLUDE_DIRS=\ !if "$(Platform_arch_model)" == "$(Platform_arch)" SOURCES_AD=\ - $(WorkSpace)/src/cpu/$(Platform_arch)/vm/$(Platform_arch_model).ad \ - $(WorkSpace)/src/os_cpu/windows_$(Platform_arch)/vm/windows_$(Platform_arch_model).ad + $(WorkSpace)/src/cpu/$(Platform_arch)/vm/$(Platform_arch_model).ad !else SOURCES_AD=\ $(WorkSpace)/src/cpu/$(Platform_arch)/vm/$(Platform_arch_model).ad \ - $(WorkSpace)/src/cpu/$(Platform_arch)/vm/$(Platform_arch).ad \ - $(WorkSpace)/src/os_cpu/windows_$(Platform_arch)/vm/windows_$(Platform_arch_model).ad + $(WorkSpace)/src/cpu/$(Platform_arch)/vm/$(Platform_arch).ad !endif # NOTE! If you add any files here, you must also update GENERATED_NAMES_IN_DIR diff --git a/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_32.ad b/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_32.ad deleted file mode 100644 index f58244ea48f..00000000000 --- a/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_32.ad +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. -// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -// -// This code is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License version 2 only, as -// published by the Free Software Foundation. -// -// This code is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// version 2 for more details (a copy is included in the LICENSE file that -// accompanied this code). -// -// You should have received a copy of the GNU General Public License version -// 2 along with this work; if not, write to the Free Software Foundation, -// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -// -// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -// or visit www.oracle.com if you need additional information or have any -// questions. -// -// - -// X86 Bsd Architecture Description File - diff --git a/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_64.ad b/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_64.ad deleted file mode 100644 index 254328e0971..00000000000 --- a/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_64.ad +++ /dev/null @@ -1,65 +0,0 @@ -// -// Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. -// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -// -// This code is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License version 2 only, as -// published by the Free Software Foundation. -// -// This code is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// version 2 for more details (a copy is included in the LICENSE file that -// accompanied this code). -// -// You should have received a copy of the GNU General Public License version -// 2 along with this work; if not, write to the Free Software Foundation, -// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -// -// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -// or visit www.oracle.com if you need additional information or have any -// questions. -// -// - -// AMD64 Bsd Architecture Description File - -//----------OS-DEPENDENT ENCODING BLOCK---------------------------------------- -// This block specifies the encoding classes used by the compiler to -// output byte streams. Encoding classes generate functions which are -// called by Machine Instruction Nodes in order to generate the bit -// encoding of the instruction. Operands specify their base encoding -// interface with the interface keyword. There are currently -// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & -// COND_INTER. REG_INTER causes an operand to generate a function -// which returns its register number when queried. CONST_INTER causes -// an operand to generate a function which returns the value of the -// constant when queried. MEMORY_INTER causes an operand to generate -// four functions which return the Base Register, the Index Register, -// the Scale Value, and the Offset Value of the operand when queried. -// COND_INTER causes an operand to generate six functions which return -// the encoding code (ie - encoding bits for the instruction) -// associated with each basic boolean condition for a conditional -// instruction. Instructions specify two basic values for encoding. -// They use the ins_encode keyword to specify their encoding class -// (which must be one of the class names specified in the encoding -// block), and they use the opcode keyword to specify, in order, their -// primary, secondary, and tertiary opcode. Only the opcode sections -// which a particular instruction needs for encoding need to be -// specified. -encode %{ - // Build emit functions for each basic byte or larger field in the intel - // encoding scheme (opcode, rm, sib, immediate), and call them from C++ - // code in the enc_class source block. Emit functions will live in the - // main source block for now. In future, we can generalize this by - // adding a syntax that specifies the sizes of fields in an order, - // so that the adlc can build the emit functions automagically - -%} - - -// Platform dependent source - -source %{ - -%} diff --git a/hotspot/src/os_cpu/linux_x86/vm/linux_x86_32.ad b/hotspot/src/os_cpu/linux_x86/vm/linux_x86_32.ad deleted file mode 100644 index 5e234deaa4f..00000000000 --- a/hotspot/src/os_cpu/linux_x86/vm/linux_x86_32.ad +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. -// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -// -// This code is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License version 2 only, as -// published by the Free Software Foundation. -// -// This code is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// version 2 for more details (a copy is included in the LICENSE file that -// accompanied this code). -// -// You should have received a copy of the GNU General Public License version -// 2 along with this work; if not, write to the Free Software Foundation, -// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -// -// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -// or visit www.oracle.com if you need additional information or have any -// questions. -// -// - -// X86 Linux Architecture Description File - diff --git a/hotspot/src/os_cpu/linux_x86/vm/linux_x86_64.ad b/hotspot/src/os_cpu/linux_x86/vm/linux_x86_64.ad deleted file mode 100644 index 3b3ac007cd1..00000000000 --- a/hotspot/src/os_cpu/linux_x86/vm/linux_x86_64.ad +++ /dev/null @@ -1,65 +0,0 @@ -// -// Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. -// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -// -// This code is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License version 2 only, as -// published by the Free Software Foundation. -// -// This code is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// version 2 for more details (a copy is included in the LICENSE file that -// accompanied this code). -// -// You should have received a copy of the GNU General Public License version -// 2 along with this work; if not, write to the Free Software Foundation, -// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -// -// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -// or visit www.oracle.com if you need additional information or have any -// questions. -// -// - -// AMD64 Linux Architecture Description File - -//----------OS-DEPENDENT ENCODING BLOCK---------------------------------------- -// This block specifies the encoding classes used by the compiler to -// output byte streams. Encoding classes generate functions which are -// called by Machine Instruction Nodes in order to generate the bit -// encoding of the instruction. Operands specify their base encoding -// interface with the interface keyword. There are currently -// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & -// COND_INTER. REG_INTER causes an operand to generate a function -// which returns its register number when queried. CONST_INTER causes -// an operand to generate a function which returns the value of the -// constant when queried. MEMORY_INTER causes an operand to generate -// four functions which return the Base Register, the Index Register, -// the Scale Value, and the Offset Value of the operand when queried. -// COND_INTER causes an operand to generate six functions which return -// the encoding code (ie - encoding bits for the instruction) -// associated with each basic boolean condition for a conditional -// instruction. Instructions specify two basic values for encoding. -// They use the ins_encode keyword to specify their encoding class -// (which must be one of the class names specified in the encoding -// block), and they use the opcode keyword to specify, in order, their -// primary, secondary, and tertiary opcode. Only the opcode sections -// which a particular instruction needs for encoding need to be -// specified. -encode %{ - // Build emit functions for each basic byte or larger field in the intel - // encoding scheme (opcode, rm, sib, immediate), and call them from C++ - // code in the enc_class source block. Emit functions will live in the - // main source block for now. In future, we can generalize this by - // adding a syntax that specifies the sizes of fields in an order, - // so that the adlc can build the emit functions automagically - -%} - - -// Platform dependent source - -source %{ - -%} diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/solaris_sparc.ad b/hotspot/src/os_cpu/solaris_sparc/vm/solaris_sparc.ad deleted file mode 100644 index 7f27d4591b3..00000000000 --- a/hotspot/src/os_cpu/solaris_sparc/vm/solaris_sparc.ad +++ /dev/null @@ -1,27 +0,0 @@ -// -// Copyright (c) 1999, 2007, 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. -// - -// -// - -// SPARC Solaris Architecture Description File diff --git a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.ad b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.ad deleted file mode 100644 index 9b95823b844..00000000000 --- a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.ad +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. -// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -// -// This code is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License version 2 only, as -// published by the Free Software Foundation. -// -// This code is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// version 2 for more details (a copy is included in the LICENSE file that -// accompanied this code). -// -// You should have received a copy of the GNU General Public License version -// 2 along with this work; if not, write to the Free Software Foundation, -// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -// -// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -// or visit www.oracle.com if you need additional information or have any -// questions. -// -// - -// X86 Solaris Architecture Description File - diff --git a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.ad b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.ad deleted file mode 100644 index f3334952f62..00000000000 --- a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.ad +++ /dev/null @@ -1,63 +0,0 @@ -// -// Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. -// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -// -// This code is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License version 2 only, as -// published by the Free Software Foundation. -// -// This code is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// version 2 for more details (a copy is included in the LICENSE file that -// accompanied this code). -// -// You should have received a copy of the GNU General Public License version -// 2 along with this work; if not, write to the Free Software Foundation, -// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -// -// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -// or visit www.oracle.com if you need additional information or have any -// questions. -// -// - -// AMD64 Solaris Architecture Description File - -//----------OS-DEPENDENT ENCODING BLOCK---------------------------------------- -// This block specifies the encoding classes used by the compiler to -// output byte streams. Encoding classes generate functions which are -// called by Machine Instruction Nodes in order to generate the bit -// encoding of the instruction. Operands specify their base encoding -// interface with the interface keyword. There are currently -// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & -// COND_INTER. REG_INTER causes an operand to generate a function -// which returns its register number when queried. CONST_INTER causes -// an operand to generate a function which returns the value of the -// constant when queried. MEMORY_INTER causes an operand to generate -// four functions which return the Base Register, the Index Register, -// the Scale Value, and the Offset Value of the operand when queried. -// COND_INTER causes an operand to generate six functions which return -// the encoding code (ie - encoding bits for the instruction) -// associated with each basic boolean condition for a conditional -// instruction. Instructions specify two basic values for encoding. -// They use the ins_encode keyword to specify their encoding class -// (which must be one of the class names specified in the encoding -// block), and they use the opcode keyword to specify, in order, their -// primary, secondary, and tertiary opcode. Only the opcode sections -// which a particular instruction needs for encoding need to be -// specified. -encode %{ - // Build emit functions for each basic byte or larger field in the intel - // encoding scheme (opcode, rm, sib, immediate), and call them from C++ - // code in the enc_class source block. Emit functions will live in the - // main source block for now. In future, we can generalize this by - // adding a syntax that specifies the sizes of fields in an order, - // so that the adlc can build the emit functions automagically -%} - - -// Platform dependent source - -source %{ -%} diff --git a/hotspot/src/os_cpu/windows_x86/vm/windows_x86_32.ad b/hotspot/src/os_cpu/windows_x86/vm/windows_x86_32.ad deleted file mode 100644 index 27fedf269c5..00000000000 --- a/hotspot/src/os_cpu/windows_x86/vm/windows_x86_32.ad +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. -// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -// -// This code is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License version 2 only, as -// published by the Free Software Foundation. -// -// This code is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// version 2 for more details (a copy is included in the LICENSE file that -// accompanied this code). -// -// You should have received a copy of the GNU General Public License version -// 2 along with this work; if not, write to the Free Software Foundation, -// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -// -// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -// or visit www.oracle.com if you need additional information or have any -// questions. -// -// - -// X86 Win32 Architecture Description File - diff --git a/hotspot/src/os_cpu/windows_x86/vm/windows_x86_64.ad b/hotspot/src/os_cpu/windows_x86/vm/windows_x86_64.ad deleted file mode 100644 index 54e183a0bc5..00000000000 --- a/hotspot/src/os_cpu/windows_x86/vm/windows_x86_64.ad +++ /dev/null @@ -1,63 +0,0 @@ -// -// Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. -// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -// -// This code is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License version 2 only, as -// published by the Free Software Foundation. -// -// This code is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// version 2 for more details (a copy is included in the LICENSE file that -// accompanied this code). -// -// You should have received a copy of the GNU General Public License version -// 2 along with this work; if not, write to the Free Software Foundation, -// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -// -// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -// or visit www.oracle.com if you need additional information or have any -// questions. -// -// - -// AMD64 Win32 Architecture Description File - -//----------OS-DEPENDENT ENCODING BLOCK----------------------------------------------------- -// This block specifies the encoding classes used by the compiler to output -// byte streams. Encoding classes generate functions which are called by -// Machine Instruction Nodes in order to generate the bit encoding of the -// instruction. Operands specify their base encoding interface with the -// interface keyword. There are currently supported four interfaces, -// REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an -// operand to generate a function which returns its register number when -// queried. CONST_INTER causes an operand to generate a function which -// returns the value of the constant when queried. MEMORY_INTER causes an -// operand to generate four functions which return the Base Register, the -// Index Register, the Scale Value, and the Offset Value of the operand when -// queried. COND_INTER causes an operand to generate six functions which -// return the encoding code (ie - encoding bits for the instruction) -// associated with each basic boolean condition for a conditional instruction. -// Instructions specify two basic values for encoding. They use the -// ins_encode keyword to specify their encoding class (which must be one of -// the class names specified in the encoding block), and they use the -// opcode keyword to specify, in order, their primary, secondary, and -// tertiary opcode. Only the opcode sections which a particular instruction -// needs for encoding need to be specified. -encode %{ - // Build emit functions for each basic byte or larger field in the intel - // encoding scheme (opcode, rm, sib, immediate), and call them from C++ - // code in the enc_class source block. Emit functions will live in the - // main source block for now. In future, we can generalize this by - // adding a syntax that specifies the sizes of fields in an order, - // so that the adlc can build the emit functions automagically - -%} - - -// Platform dependent source - -source %{ - -%} From ae5b50414a41dd1410baabf7f776ada732365e0b Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Thu, 8 Aug 2013 09:21:30 -0700 Subject: [PATCH 018/102] 8016601: Unable to build hsx24 on Windows using project creator and Visual Studio ProjectCreator tool is modified to support two new options: '-relativeAltSrcInclude' and '-altRelativeInclude' which prevents IDE linker errors. Also fixed some cmd line build linker warnings. Misc cleanups. Reviewed-by: rdurbin, coleenp --- hotspot/make/windows/create.bat | 6 +- hotspot/make/windows/create_obj_files.sh | 32 +++--- .../windows/makefiles/projectcreator.make | 20 +--- hotspot/make/windows/makefiles/trace.make | 10 +- hotspot/make/windows/makefiles/vm.make | 4 - .../tools/ProjectCreator/BuildConfig.java | 105 +++++++++++++----- .../ProjectCreator/FileTreeCreatorVC10.java | 58 +++++++++- .../tools/ProjectCreator/ProjectCreator.java | 7 +- .../ProjectCreator/WinGammaPlatform.java | 25 ++++- .../ProjectCreator/WinGammaPlatformVC10.java | 28 ++++- 10 files changed, 212 insertions(+), 83 deletions(-) diff --git a/hotspot/make/windows/create.bat b/hotspot/make/windows/create.bat index 16602c8ea90..6e72fa9c9e9 100644 --- a/hotspot/make/windows/create.bat +++ b/hotspot/make/windows/create.bat @@ -1,6 +1,6 @@ @echo off REM -REM Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. +REM Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. REM REM This code is free software; you can redistribute it and/or modify it @@ -148,7 +148,7 @@ echo HotSpotJDKDist=%HotSpotJDKDist% REM This is now safe to do. :copyfiles -for /D %%i in (compiler1, compiler2, tiered, core) do ( +for /D %%i in (compiler1, compiler2, tiered ) do ( if NOT EXIST %HotSpotBuildSpace%\%%i\generated mkdir %HotSpotBuildSpace%\%%i\generated copy %HotSpotWorkSpace%\make\windows\projectfiles\%%i\* %HotSpotBuildSpace%\%%i\generated > NUL ) @@ -156,7 +156,7 @@ copy %HotSpotWorkSpace%\make\windows\projectfiles\%%i\* %HotSpotBuildSpace%\%%i\ REM force regneration of ProjectFile if exist %ProjectFile% del %ProjectFile% -for /D %%i in (compiler1, compiler2, tiered, core) do ( +for /D %%i in (compiler1, compiler2, tiered ) do ( echo -- %%i -- echo # Generated file! > %HotSpotBuildSpace%\%%i\local.make echo # Changing a variable below and then deleting %ProjectFile% will cause >> %HotSpotBuildSpace%\%%i\local.make diff --git a/hotspot/make/windows/create_obj_files.sh b/hotspot/make/windows/create_obj_files.sh index b162bd07b60..c17b0690e17 100644 --- a/hotspot/make/windows/create_obj_files.sh +++ b/hotspot/make/windows/create_obj_files.sh @@ -73,19 +73,17 @@ done BASE_PATHS="${BASE_PATHS} ${GENERATED}/jvmtifiles ${GENERATED}/tracefiles" -if [ -d "${ALTSRC}/share/vm/jfr" ]; then - BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr" +if [ -d "${ALTSRC}/share/vm/jfr/buffers" ]; then BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr/buffers" fi BASE_PATHS="${BASE_PATHS} ${COMMONSRC}/share/vm/prims/wbtestmethods" -CORE_PATHS="${BASE_PATHS}" # shared is already in BASE_PATHS. Should add vm/memory but that one is also in BASE_PATHS. if [ -d "${ALTSRC}/share/vm/gc_implementation" ]; then - CORE_PATHS="${CORE_PATHS} `$FIND ${ALTSRC}/share/vm/gc_implementation ! -name gc_implementation -prune -type d \! -name shared`" + BASE_PATHS="${BASE_PATHS} `$FIND ${ALTSRC}/share/vm/gc_implementation ! -name gc_implementation -prune -type d \! -name shared`" fi -CORE_PATHS="${CORE_PATHS} `$FIND ${COMMONSRC}/share/vm/gc_implementation ! -name gc_implementation -prune -type d \! -name shared`" +BASE_PATHS="${BASE_PATHS} `$FIND ${COMMONSRC}/share/vm/gc_implementation ! -name gc_implementation -prune -type d \! -name shared`" if [ -d "${ALTSRC}/share/vm/c1" ]; then COMPILER1_PATHS="${ALTSRC}/share/vm/c1" @@ -104,12 +102,11 @@ COMPILER2_PATHS="${COMPILER2_PATHS} ${GENERATED}/adfiles" # Include dirs per type. case "${TYPE}" in - "core") Src_Dirs="${CORE_PATHS}" ;; - "compiler1") Src_Dirs="${CORE_PATHS} ${COMPILER1_PATHS}" ;; - "compiler2") Src_Dirs="${CORE_PATHS} ${COMPILER2_PATHS}" ;; - "tiered") Src_Dirs="${CORE_PATHS} ${COMPILER1_PATHS} ${COMPILER2_PATHS}" ;; - "zero") Src_Dirs="${CORE_PATHS}" ;; - "shark") Src_Dirs="${CORE_PATHS}" ;; + "compiler1") Src_Dirs="${BASE_PATHS} ${COMPILER1_PATHS}" ;; + "compiler2") Src_Dirs="${BASE_PATHS} ${COMPILER2_PATHS}" ;; + "tiered") Src_Dirs="${BASE_PATHS} ${COMPILER1_PATHS} ${COMPILER2_PATHS}" ;; + "zero") Src_Dirs="${BASE_PATHS}" ;; + "shark") Src_Dirs="${BASE_PATHS}" ;; esac COMPILER2_SPECIFIC_FILES="opto libadt bcEscapeAnalyzer.cpp c2_* runtime_*" @@ -122,7 +119,6 @@ Src_Files_EXCLUDE="jsig.c jvmtiEnvRecommended.cpp jvmtiEnvStub.cpp" # Exclude per type. case "${TYPE}" in - "core") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER1_SPECIFIC_FILES} ${COMPILER2_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES} ciTypeFlow.cpp" ;; "compiler1") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER2_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES} ciTypeFlow.cpp" ;; "compiler2") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER1_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES}" ;; "tiered") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES}" ;; @@ -149,9 +145,17 @@ for e in ${Src_Dirs}; do Src_Files="${Src_Files}`findsrc ${e}` " done -Obj_Files= +Obj_Files=" " for e in ${Src_Files}; do - Obj_Files="${Obj_Files}${e%\.[!.]*}.obj " + o="${e%\.[!.]*}.obj" + set +e + chk=`expr "${Obj_Files}" : ".* $o"` + set -e + if [ "$chk" != 0 ]; then + echo "# INFO: skipping duplicate $o" + continue + fi + Obj_Files="${Obj_Files}$o " done echo Obj_Files=${Obj_Files} diff --git a/hotspot/make/windows/makefiles/projectcreator.make b/hotspot/make/windows/makefiles/projectcreator.make index 7aa3ef65cad..a5336c6bf51 100644 --- a/hotspot/make/windows/makefiles/projectcreator.make +++ b/hotspot/make/windows/makefiles/projectcreator.make @@ -44,10 +44,11 @@ ProjectCreatorSources=\ # This is only used internally ProjectCreatorIncludesPRIVATE=\ - -relativeInclude src\closed\share\vm \ - -relativeInclude src\closed\os\windows\vm \ - -relativeInclude src\closed\os_cpu\windows_$(Platform_arch)\vm \ - -relativeInclude src\closed\cpu\$(Platform_arch)\vm \ + -relativeAltSrcInclude src\closed \ + -altRelativeInclude share\vm \ + -altRelativeInclude os\windows\vm \ + -altRelativeInclude os_cpu\windows_$(Platform_arch)\vm \ + -altRelativeInclude cpu\$(Platform_arch)\vm \ -relativeInclude src\share\vm \ -relativeInclude src\share\vm\precompiled \ -relativeInclude src\share\vm\prims\wbtestmethods \ @@ -91,7 +92,7 @@ ProjectCreatorIDEOptions = \ -disablePch getThread_windows_$(Platform_arch).cpp \ -disablePch_compiler2 opcodes.cpp -# Common options for the IDE builds for core, c1, and c2 +# Common options for the IDE builds for c1, and c2 ProjectCreatorIDEOptions=\ $(ProjectCreatorIDEOptions) \ -sourceBase $(HOTSPOTWORKSPACE) \ @@ -157,19 +158,11 @@ ProjectCreatorIDEOptionsIgnoreCompiler2=\ -ignoreFile_TARGET ciTypeFlow.hpp \ -ignoreFile_TARGET $(Platform_arch_model).ad -################################################## -# Without compiler(core) specific options -################################################## -ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \ -$(ProjectCreatorIDEOptionsIgnoreCompiler1:TARGET=core) \ -$(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=core) - ################################################## # Client(C1) compiler specific options ################################################## ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \ -define_compiler1 COMPILER1 \ - -ignorePath_compiler1 core \ $(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=compiler1) ################################################## @@ -178,7 +171,6 @@ $(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=compiler1) #NOTE! This list must be kept in sync with GENERATED_NAMES in adlc.make. ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \ -define_compiler2 COMPILER2 \ - -ignorePath_compiler2 core \ -additionalFile_compiler2 $(Platform_arch_model).ad \ -additionalFile_compiler2 ad_$(Platform_arch_model).cpp \ -additionalFile_compiler2 ad_$(Platform_arch_model).hpp \ diff --git a/hotspot/make/windows/makefiles/trace.make b/hotspot/make/windows/makefiles/trace.make index 82422b173cf..02948c0a8d0 100644 --- a/hotspot/make/windows/makefiles/trace.make +++ b/hotspot/make/windows/makefiles/trace.make @@ -90,25 +90,25 @@ $(TraceOutDir)/traceTypes.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceType !if "$(OPENJDK)" == "true" $(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS) - @echo Generating $@ + @echo Generating OpenJDK $@ @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceSrcDir)/traceEventClasses.xsl -OUT $(TraceOutDir)/traceEventClasses.hpp !else $(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS) - @echo Generating $@ + @echo Generating AltSrc $@ @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceEventClasses.xsl -OUT $(TraceOutDir)/traceEventClasses.hpp $(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS) - @echo Generating $@ + @echo Generating AltSrc $@ @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceProducer.xsl -OUT $(TraceOutDir)/traceProducer.cpp $(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS) - @echo Generating $@ + @echo Generating AltSrc $@ @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceRequestables.xsl -OUT $(TraceOutDir)/traceRequestables.hpp $(TraceOutDir)/traceEventControl.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS) - @echo Generating $@ + @echo Generating AltSrc $@ @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceEventControl.xsl -OUT $(TraceOutDir)/traceEventControl.hpp !endif diff --git a/hotspot/make/windows/makefiles/vm.make b/hotspot/make/windows/makefiles/vm.make index b76443774de..8b5e23d4a28 100644 --- a/hotspot/make/windows/makefiles/vm.make +++ b/hotspot/make/windows/makefiles/vm.make @@ -36,10 +36,6 @@ CXX_FLAGS=$(CXX_FLAGS) /D "PRODUCT" CXX_FLAGS=$(CXX_FLAGS) /D "ASSERT" !endif -!if "$(Variant)" == "core" -# No need to define anything, CORE is defined as !COMPILER1 && !COMPILER2 -!endif - !if "$(Variant)" == "compiler1" CXX_FLAGS=$(CXX_FLAGS) /D "COMPILER1" !endif diff --git a/hotspot/src/share/tools/ProjectCreator/BuildConfig.java b/hotspot/src/share/tools/ProjectCreator/BuildConfig.java index a9b07e03e62..7c95db62f0c 100644 --- a/hotspot/src/share/tools/ProjectCreator/BuildConfig.java +++ b/hotspot/src/share/tools/ProjectCreator/BuildConfig.java @@ -142,6 +142,69 @@ class BuildConfig { return rv; } + // Returns true if the specified path refers to a relative alternate + // source file. RelativeAltSrcInclude is usually "src\closed". + public static boolean matchesRelativeAltSrcInclude(String path) { + String relativeAltSrcInclude = + getFieldString(null, "RelativeAltSrcInclude"); + Vector v = getFieldVector(null, "AltRelativeInclude"); + for (String pathPart : v) { + if (path.contains(relativeAltSrcInclude + Util.sep + pathPart)) { + return true; + } + } + return false; + } + + // Returns the relative alternate source file for the specified path. + // Null is returned if the specified path does not have a matching + // alternate source file. + public static String getMatchingRelativeAltSrcFile(String path) { + Vector v = getFieldVector(null, "RelativeAltSrcFileList"); + if (v == null) { + return null; + } + for (String pathPart : v) { + if (path.endsWith(pathPart)) { + String relativeAltSrcInclude = + getFieldString(null, "RelativeAltSrcInclude"); + return relativeAltSrcInclude + Util.sep + pathPart; + } + } + return null; + } + + // Returns true if the specified path has a matching alternate + // source file. + public static boolean matchesRelativeAltSrcFile(String path) { + return getMatchingRelativeAltSrcFile(path) != null; + } + + // Track the specified alternate source file. The source file is + // tracked without the leading .* + // part to make matching regular source files easier. + public static void trackRelativeAltSrcFile(String path) { + String pattern = getFieldString(null, "RelativeAltSrcInclude") + + Util.sep; + int altSrcInd = path.indexOf(pattern); + if (altSrcInd == -1) { + // not an AltSrc path + return; + } + + altSrcInd += pattern.length(); + if (altSrcInd >= path.length()) { + // not a valid AltSrc path + return; + } + + String altSrcFile = path.substring(altSrcInd); + Vector v = getFieldVector(null, "RelativeAltSrcFileList"); + if (v == null || !v.contains(altSrcFile)) { + addFieldVector(null, "RelativeAltSrcFileList", altSrcFile); + } + } + void addTo(Hashtable ht, String key, String value) { ht.put(expandFormat(key), expandFormat(value)); } @@ -272,8 +335,19 @@ class BuildConfig { private Vector getSourceIncludes() { Vector rv = new Vector(); - Vector ri = new Vector(); String sourceBase = getFieldString(null, "SourceBase"); + + // add relative alternate source include values: + String relativeAltSrcInclude = + getFieldString(null, "RelativeAltSrcInclude"); + Vector asri = new Vector(); + collectRelevantVectors(asri, "AltRelativeInclude"); + for (String f : asri) { + rv.add(sourceBase + Util.sep + relativeAltSrcInclude + + Util.sep + f); + } + + Vector ri = new Vector(); collectRelevantVectors(ri, "RelativeInclude"); for (String f : ri) { rv.add(sourceBase + Util.sep + f); @@ -541,35 +615,6 @@ class TieredProductConfig extends ProductConfig { } } -class CoreDebugConfig extends GenericDebugNonKernelConfig { - String getOptFlag() { - return getCI().getNoOptFlag(); - } - - CoreDebugConfig() { - initNames("core", "debug", "jvm.dll"); - init(getIncludes(), getDefines()); - } -} - -class CoreFastDebugConfig extends GenericDebugNonKernelConfig { - String getOptFlag() { - return getCI().getOptFlag(); - } - - CoreFastDebugConfig() { - initNames("core", "fastdebug", "jvm.dll"); - init(getIncludes(), getDefines()); - } -} - -class CoreProductConfig extends ProductConfig { - CoreProductConfig() { - initNames("core", "product", "jvm.dll"); - init(getIncludes(), getDefines()); - } -} - abstract class CompilerInterface { abstract Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir); diff --git a/hotspot/src/share/tools/ProjectCreator/FileTreeCreatorVC10.java b/hotspot/src/share/tools/ProjectCreator/FileTreeCreatorVC10.java index 837eef1a566..8041d833e34 100644 --- a/hotspot/src/share/tools/ProjectCreator/FileTreeCreatorVC10.java +++ b/hotspot/src/share/tools/ProjectCreator/FileTreeCreatorVC10.java @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2012, 2013, 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 static java.nio.file.FileVisitResult.CONTINUE; import java.io.IOException; @@ -21,6 +45,8 @@ public class FileTreeCreatorVC10 extends FileTreeCreator { boolean usePch = false; boolean disablePch = false; boolean useIgnore = false; + boolean isAltSrc = false; // only needed as a debugging crumb + boolean isReplacedByAltSrc = false; String fileName = file.getFileName().toString(); // TODO hideFile @@ -30,6 +56,26 @@ public class FileTreeCreatorVC10 extends FileTreeCreator { usePch = true; } + String fileLoc = vcProjLocation.relativize(file).toString(); + + // isAltSrc and isReplacedByAltSrc applies to all configs for a file + if (BuildConfig.matchesRelativeAltSrcInclude( + file.toAbsolutePath().toString())) { + // current file is an alternate source file so track it + isAltSrc = true; + BuildConfig.trackRelativeAltSrcFile( + file.toAbsolutePath().toString()); + } else if (BuildConfig.matchesRelativeAltSrcFile( + file.toAbsolutePath().toString())) { + // current file is a regular file that matches an alternate + // source file so yack about replacing the regular file + isReplacedByAltSrc = true; + System.out.println("INFO: alternate source file '" + + BuildConfig.getMatchingRelativeAltSrcFile( + file.toAbsolutePath().toString()) + + "' replaces '" + fileLoc + "'"); + } + for (BuildConfig cfg : allConfigs) { if (cfg.lookupHashFieldInContext("IgnoreFile", fileName) != null) { useIgnore = true; @@ -58,9 +104,8 @@ public class FileTreeCreatorVC10 extends FileTreeCreator { } String tagName = wg.getFileTagFromSuffix(fileName); - String fileLoc = vcProjLocation.relativize(file).toString(); - if (!useIgnore && !disablePch && !usePch) { + if (!useIgnore && !disablePch && !usePch && !isReplacedByAltSrc) { wg.tag(tagName, new String[] { "Include", fileLoc}); } else { wg.startTag( @@ -78,6 +123,11 @@ public class FileTreeCreatorVC10 extends FileTreeCreator { if (disablePch) { wg.tag("PrecompiledHeader", "Condition", "'$(Configuration)|$(Platform)'=='" + cfg.get("Name") + "'"); } + if (isReplacedByAltSrc) { + wg.tagData("ExcludedFromBuild", "true", "Condition", + "'$(Configuration)|$(Platform)'=='" + + cfg.get("Name") + "'"); + } } wg.endTag(); } @@ -137,6 +187,4 @@ public class FileTreeCreatorVC10 extends FileTreeCreator { public void writeFileTree() throws IOException { Files.walkFileTree(this.startDir, this); } - - - } \ No newline at end of file +} diff --git a/hotspot/src/share/tools/ProjectCreator/ProjectCreator.java b/hotspot/src/share/tools/ProjectCreator/ProjectCreator.java index a3065e51273..f1e16ea8a45 100644 --- a/hotspot/src/share/tools/ProjectCreator/ProjectCreator.java +++ b/hotspot/src/share/tools/ProjectCreator/ProjectCreator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,10 +39,15 @@ public class ProjectCreator { + "jvm.dll; no trailing slash>"); System.err.println(" If any of the above are specified, " + "they must all be."); + System.err.println(" Note: if '-altRelativeInclude' option below is " + + "used, then the '-relativeAltSrcInclude' option must be used " + + "to specify the alternate source dir, e.g., 'src\\closed'"); System.err.println(" Additional, optional arguments, which can be " + "specified multiple times:"); System.err.println(" -absoluteInclude "); + System.err.println(" -altRelativeInclude "); System.err.println(" -relativeInclude "); System.err.println(" -define "); System.err.println(" If any of the above are specified, "+ "they must all be."); + System.err.println(" Note: if '-altRelativeInclude' option below " + + "is used, then the '-relativeAltSrcInclude' " + + "option must be used to specify the alternate " + + "source dir, e.g., 'src\\closed'"); System.err.println(" Additional, optional arguments, which can be " + "specified multiple times:"); System.err.println(" -absoluteInclude "); + System.err.println(" -altRelativeInclude "); System.err.println(" -relativeInclude "); System.err.println(" -define allConfigs) throws IOException { System.out.println(); - System.out.print(" Writing .vcxproj file: " + projectFileName); + System.out.println(" Writing .vcxproj file: " + projectFileName); String projDir = Util.normalize(new File(projectFileName).getParent()); @@ -114,7 +138,7 @@ public class WinGammaPlatformVC10 extends WinGammaPlatformVC7 { endTag(); printWriter.close(); - System.out.println(" Done."); + System.out.println(" Done writing .vcxproj file."); writeFilterFile(projectFileName, projectName, allConfigs, projDir); writeUserFile(projectFileName, allConfigs); From 617a84061cf076e36c1e604f0cfecf7726e22f92 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Thu, 8 Aug 2013 14:45:56 -0700 Subject: [PATCH 019/102] 8022093: syntax error near "umpiconninfo_t" -- when building on Solaris 10 Added extra help message in make/solaris/makefiles/dtrace.make Reviewed-by: dholmes, sspitsyn --- hotspot/make/solaris/makefiles/dtrace.make | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/hotspot/make/solaris/makefiles/dtrace.make b/hotspot/make/solaris/makefiles/dtrace.make index b57365b93dc..48f9b295b73 100644 --- a/hotspot/make/solaris/makefiles/dtrace.make +++ b/hotspot/make/solaris/makefiles/dtrace.make @@ -283,9 +283,9 @@ $(DTRACE.o): $(DTRACE).d $(JVMOFFS).h $(JVMOFFS)Index.h $(DTraced_Files) $(QUIETLY) $(DTRACE_PROG) $(DTRACE_OPTS) -C -I. -G -xlazyload -o $@ -s $(DTRACE).d \ $(DTraced_Files) ||\ STATUS=$$?;\ - if [ x"$$STATUS" = x"1" -a \ - x`uname -r` = x"5.10" -a \ - x`uname -p` = x"sparc" ]; then\ + if [ x"$$STATUS" = x"1" ]; then \ + if [ x`uname -r` = x"5.10" -a \ + x`uname -p` = x"sparc" ]; then\ echo "*****************************************************************";\ echo "* If you are building server compiler, and the error message is ";\ echo "* \"incorrect ELF machine type...\", you have run into solaris bug ";\ @@ -294,6 +294,20 @@ $(DTRACE.o): $(DTRACE).d $(JVMOFFS).h $(JVMOFFS)Index.h $(DTraced_Files) echo "* environment variable HOTSPOT_DISABLE_DTRACE_PROBES to disable ";\ echo "* dtrace probes for this build.";\ echo "*****************************************************************";\ + elif [ x`uname -r` = x"5.10" ]; then\ + echo "*****************************************************************";\ + echo "* If you are seeing 'syntax error near \"umpiconninfo_t\"' on Solaris";\ + echo "* 10, try doing 'cd /usr/lib/dtrace && gzip mpi.d' as root, ";\ + echo "* or set the environment variable HOTSPOT_DISABLE_DTRACE_PROBES";\ + echo "* to disable dtrace probes for this build.";\ + echo "*****************************************************************";\ + else \ + echo "*****************************************************************";\ + echo "* If you cannot fix dtrace build issues, try to ";\ + echo "* set the environment variable HOTSPOT_DISABLE_DTRACE_PROBES";\ + echo "* to disable dtrace probes for this build.";\ + echo "*****************************************************************";\ + fi; \ fi;\ exit $$STATUS # Since some DTraced_Files are in LIBJVM.o and they are touched by this From 418cc392cc6933634a2d87a41b9c494e19c3ea41 Mon Sep 17 00:00:00 2001 From: Yumin Qi Date: Thu, 8 Aug 2013 15:19:12 -0700 Subject: [PATCH 020/102] 8019583: [TESTBUG] runtime/7107135 always passes If java test return none zero, the value will be override by 'if' statement, the exit value will always '0' and pass. Fix by recording the result in a variable. Reviewed-by: coleenp, dholmes, iklam --- hotspot/test/runtime/7107135/Test7107135.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/hotspot/test/runtime/7107135/Test7107135.sh b/hotspot/test/runtime/7107135/Test7107135.sh index d8ccbad19ad..742c71c1ce2 100644 --- a/hotspot/test/runtime/7107135/Test7107135.sh +++ b/hotspot/test/runtime/7107135/Test7107135.sh @@ -53,9 +53,6 @@ case "$OS" in fi ;; *) - NULL=NUL - PS=";" - FS="\\" echo "Test passed; only valid for Linux" exit 0; ;; @@ -87,14 +84,16 @@ ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rw echo echo Test changing of stack protection: -echo ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rw +echo ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rwx ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rwx +JAVA_RETVAL=$? -if [ "$?" == "0" ] +if [ "$JAVA_RETVAL" == "0" ] then echo echo ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} TestMT test-rwx ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} TestMT test-rwx + JAVA_RETVAL=$? fi -exit $? +exit $JAVA_RETVAL From 66bb3b1c47be81a612fea118c7f1488b218673af Mon Sep 17 00:00:00 2001 From: Anton Tarasov Date: Fri, 9 Aug 2013 05:20:27 +0400 Subject: [PATCH 021/102] 8013611: Modal dialog fails to obtain keyboard focus Reviewed-by: leonidr --- .../java/awt/KeyboardFocusManager.java | 3 +- .../java/awt/Focus/8013611/JDK8013611.java | 111 ++++++++++++++++++ 2 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 jdk/test/java/awt/Focus/8013611/JDK8013611.java diff --git a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java index 21a8bd84805..51507696cff 100644 --- a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java +++ b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java @@ -2426,7 +2426,8 @@ public abstract class KeyboardFocusManager focusLog.finest("Request {0}", String.valueOf(hwFocusRequest)); } if (hwFocusRequest == null && - heavyweight == nativeFocusOwner) + heavyweight == nativeFocusOwner && + heavyweight.getContainingWindow() == nativeFocusedWindow) { if (descendant == currentFocusOwner) { // Redundant request. diff --git a/jdk/test/java/awt/Focus/8013611/JDK8013611.java b/jdk/test/java/awt/Focus/8013611/JDK8013611.java new file mode 100644 index 00000000000..346f235071e --- /dev/null +++ b/jdk/test/java/awt/Focus/8013611/JDK8013611.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013, 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 8013611 + @summary Tests showing a modal dialog with requesting focus in frame. + @author Anton.Tarasov: area=awt.focus + @library ../../regtesthelpers + @build Util + @run main JDK8013611 +*/ + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import test.java.awt.regtesthelpers.Util; + +import java.awt.*; + +public class JDK8013611 extends JFrame { + static JTextField textField = new JTextField("text"); + static JButton button1 = new JButton("button1"); + static JButton button2 = new JButton("button2"); + static Robot robot; + + static JDialog dialog; + static JButton button3 = new JButton("button3"); + + public static void main(String[] args) { + robot = Util.createRobot(); + + JDK8013611 frame = new JDK8013611(); + frame.setLayout(new FlowLayout()); + frame.add(textField); + frame.add(button1); + frame.add(button2); + frame.pack(); + + dialog = new JDialog(frame, true); + dialog.add(button3); + dialog.pack(); + + textField.addFocusListener(new FocusAdapter() { + @Override + public void focusLost(FocusEvent e) { + dialog.setVisible(true); + } + }); + + button1.addFocusListener(new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + button2.requestFocusInWindow(); + } + }); + + frame.setVisible(true); + + frame.test(); + } + + public void test() { + if (!testFocused(textField)) { + Util.clickOnComp(textField, robot); + if (!testFocused(textField)) { + throw new RuntimeException("Error: couldn't focus " + textField); + } + } + + robot.keyPress(KeyEvent.VK_TAB); + robot.delay(50); + robot.keyRelease(KeyEvent.VK_TAB); + + if (!testFocused(button3)) { + throw new RuntimeException("Test failed: dialog didn't get focus!"); + } + + System.out.println("Test passed."); + } + + boolean testFocused(Component c) { + for (int i=0; i<10; i++) { + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() == c) { + return true; + } + Util.waitForIdle(robot); + } + return false; + } +} From 7cea3820af82902cae33120ca58019cbd67e3bc0 Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Fri, 9 Aug 2013 01:39:11 -0700 Subject: [PATCH 022/102] 8022688: new hotspot build - hs25-b46 Reviewed-by: jcoomes --- hotspot/make/hotspot_version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version index 614c5b082cc..2ec3b0aaf52 100644 --- a/hotspot/make/hotspot_version +++ b/hotspot/make/hotspot_version @@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013 HS_MAJOR_VER=25 HS_MINOR_VER=0 -HS_BUILD_NUMBER=45 +HS_BUILD_NUMBER=46 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 From ad02c635e3a2bafd0570ef9551859c9b5d584ff5 Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy Date: Fri, 9 Aug 2013 14:16:24 +0400 Subject: [PATCH 023/102] 7121409: Two conformance tests for AccessibleText.getCharacterBounds(int i) fail Reviewed-by: serb --- jdk/src/share/classes/javax/swing/JLabel.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/JLabel.java b/jdk/src/share/classes/javax/swing/JLabel.java index 106245ac295..82235093f97 100644 --- a/jdk/src/share/classes/javax/swing/JLabel.java +++ b/jdk/src/share/classes/javax/swing/JLabel.java @@ -1185,14 +1185,13 @@ public class JLabel extends JComponent implements SwingConstants, Accessible } /** - * Determine the bounding box of the character at the given - * index into the string. The bounds are returned in local - * coordinates. If the index is invalid an empty rectangle is - * returned. + * Returns the bounding box of the character at the given + * index in the string. The bounds are returned in local + * coordinates. If the index is invalid, null is returned. * * @param i the index into the String - * @return the screen coordinates of the character's the bounding box, - * if index is invalid returns an empty rectangle. + * @return the screen coordinates of the character's bounding box. + * If the index is invalid, null is returned. * @since 1.3 */ public Rectangle getCharacterBounds(int i) { From 7d471dd141cca96be282d0dbe3019011068cc5ab Mon Sep 17 00:00:00 2001 From: Henry Jen Date: Fri, 9 Aug 2013 09:05:20 -0700 Subject: [PATCH 024/102] 8023681: Fix raw type warning caused by Sink Reviewed-by: mduigou, briangoetz --- .../classes/java/util/stream/Collectors.java | 40 +++++++++---------- .../classes/java/util/stream/DistinctOps.java | 4 +- .../java/util/stream/DoublePipeline.java | 15 ++++--- .../classes/java/util/stream/IntPipeline.java | 21 +++++----- .../java/util/stream/LongPipeline.java | 19 ++++----- .../java/util/stream/ReferencePipeline.java | 26 ++++++------ .../share/classes/java/util/stream/Sink.java | 28 ++++++------- .../classes/java/util/stream/SliceOps.java | 25 +++++++----- .../classes/java/util/stream/SortedOps.java | 34 ++++++++-------- 9 files changed, 101 insertions(+), 111 deletions(-) diff --git a/jdk/src/share/classes/java/util/stream/Collectors.java b/jdk/src/share/classes/java/util/stream/Collectors.java index 27c7c83ead4..bdbd8ad0774 100644 --- a/jdk/src/share/classes/java/util/stream/Collectors.java +++ b/jdk/src/share/classes/java/util/stream/Collectors.java @@ -137,6 +137,11 @@ public final class Collectors { return (u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); }; } + @SuppressWarnings("unchecked") + private static Function castingIdentity() { + return i -> (R) i; + } + /** * Simple implementation class for {@code Collector}. * @@ -166,7 +171,7 @@ public final class Collectors { BiConsumer accumulator, BinaryOperator combiner, Set characteristics) { - this(supplier, accumulator, combiner, i -> (R) i, characteristics); + this(supplier, accumulator, combiner, castingIdentity(), characteristics); } @Override @@ -209,7 +214,7 @@ public final class Collectors { */ public static > Collector toCollection(Supplier collectionFactory) { - return new CollectorImpl<>(collectionFactory, Collection::add, + return new CollectorImpl<>(collectionFactory, Collection::add, (r1, r2) -> { r1.addAll(r2); return r1; }, CH_ID); } @@ -1046,30 +1051,23 @@ public final class Collectors { public static Collector> partitioningBy(Predicate predicate, Collector downstream) { - @SuppressWarnings("unchecked") - BiConsumer downstreamAccumulator = (BiConsumer) downstream.accumulator(); - BiConsumer, T> accumulator = (result, t) -> { - Partition asPartition = ((Partition) result); - downstreamAccumulator.accept(predicate.test(t) ? asPartition.forTrue : asPartition.forFalse, t); - }; + BiConsumer downstreamAccumulator = downstream.accumulator(); + BiConsumer, T> accumulator = (result, t) -> + downstreamAccumulator.accept(predicate.test(t) ? result.forTrue : result.forFalse, t); BinaryOperator op = downstream.combiner(); - BinaryOperator> merger = (m1, m2) -> { - Partition left = (Partition) m1; - Partition right = (Partition) m2; - return new Partition<>(op.apply(left.forTrue, right.forTrue), - op.apply(left.forFalse, right.forFalse)); - }; - Supplier> supplier = () -> new Partition<>(downstream.supplier().get(), - downstream.supplier().get()); + BinaryOperator> merger = (left, right) -> + new Partition<>(op.apply(left.forTrue, right.forTrue), + op.apply(left.forFalse, right.forFalse)); + Supplier> supplier = () -> + new Partition<>(downstream.supplier().get(), + downstream.supplier().get()); if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) { return new CollectorImpl<>(supplier, accumulator, merger, CH_ID); } else { - Function, Map> finisher = (Map par) -> { - Partition asAPartition = (Partition) par; - return new Partition<>(downstream.finisher().apply(asAPartition.forTrue), - downstream.finisher().apply(asAPartition.forFalse)); - }; + Function, Map> finisher = par -> + new Partition<>(downstream.finisher().apply(par.forTrue), + downstream.finisher().apply(par.forFalse)); return new CollectorImpl<>(supplier, accumulator, merger, finisher, CH_NOID); } } diff --git a/jdk/src/share/classes/java/util/stream/DistinctOps.java b/jdk/src/share/classes/java/util/stream/DistinctOps.java index 69d231f88f5..1c4dfee5d67 100644 --- a/jdk/src/share/classes/java/util/stream/DistinctOps.java +++ b/jdk/src/share/classes/java/util/stream/DistinctOps.java @@ -101,7 +101,7 @@ final class DistinctOps { if (StreamOpFlag.DISTINCT.isKnown(flags)) { return sink; } else if (StreamOpFlag.SORTED.isKnown(flags)) { - return new Sink.ChainedReference(sink) { + return new Sink.ChainedReference(sink) { boolean seenNull; T lastSeen; @@ -132,7 +132,7 @@ final class DistinctOps { } }; } else { - return new Sink.ChainedReference(sink) { + return new Sink.ChainedReference(sink) { Set seen; @Override diff --git a/jdk/src/share/classes/java/util/stream/DoublePipeline.java b/jdk/src/share/classes/java/util/stream/DoublePipeline.java index 44c8ff0f5e7..f894fa0abb9 100644 --- a/jdk/src/share/classes/java/util/stream/DoublePipeline.java +++ b/jdk/src/share/classes/java/util/stream/DoublePipeline.java @@ -191,7 +191,7 @@ abstract class DoublePipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedDouble(sink) { + return new Sink.ChainedDouble(sink) { @Override public void accept(double t) { downstream.accept(mapper.applyAsDouble(t)); @@ -208,9 +208,8 @@ abstract class DoublePipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedDouble(sink) { + return new Sink.ChainedDouble(sink) { @Override - @SuppressWarnings("unchecked") public void accept(double t) { downstream.accept(mapper.apply(t)); } @@ -226,7 +225,7 @@ abstract class DoublePipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedDouble(sink) { + return new Sink.ChainedDouble(sink) { @Override public void accept(double t) { downstream.accept(mapper.applyAsInt(t)); @@ -243,7 +242,7 @@ abstract class DoublePipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedDouble(sink) { + return new Sink.ChainedDouble(sink) { @Override public void accept(double t) { downstream.accept(mapper.applyAsLong(t)); @@ -259,7 +258,7 @@ abstract class DoublePipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedDouble(sink) { + return new Sink.ChainedDouble(sink) { @Override public void begin(long size) { downstream.begin(-1); @@ -296,7 +295,7 @@ abstract class DoublePipeline StreamOpFlag.NOT_SIZED) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedDouble(sink) { + return new Sink.ChainedDouble(sink) { @Override public void begin(long size) { downstream.begin(-1); @@ -319,7 +318,7 @@ abstract class DoublePipeline 0) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedDouble(sink) { + return new Sink.ChainedDouble(sink) { @Override public void accept(double t) { consumer.accept(t); diff --git a/jdk/src/share/classes/java/util/stream/IntPipeline.java b/jdk/src/share/classes/java/util/stream/IntPipeline.java index d380e4a3bf5..f7dc79317d3 100644 --- a/jdk/src/share/classes/java/util/stream/IntPipeline.java +++ b/jdk/src/share/classes/java/util/stream/IntPipeline.java @@ -189,9 +189,8 @@ abstract class IntPipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedInt(sink) { + return new Sink.ChainedInt(sink) { @Override - @SuppressWarnings("unchecked") public void accept(int t) { downstream.accept((long) t); } @@ -206,9 +205,8 @@ abstract class IntPipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedInt(sink) { + return new Sink.ChainedInt(sink) { @Override - @SuppressWarnings("unchecked") public void accept(int t) { downstream.accept((double) t); } @@ -229,7 +227,7 @@ abstract class IntPipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedInt(sink) { + return new Sink.ChainedInt(sink) { @Override public void accept(int t) { downstream.accept(mapper.applyAsInt(t)); @@ -246,9 +244,8 @@ abstract class IntPipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedInt(sink) { + return new Sink.ChainedInt(sink) { @Override - @SuppressWarnings("unchecked") public void accept(int t) { downstream.accept(mapper.apply(t)); } @@ -264,7 +261,7 @@ abstract class IntPipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedInt(sink) { + return new Sink.ChainedInt(sink) { @Override public void accept(int t) { downstream.accept(mapper.applyAsLong(t)); @@ -281,7 +278,7 @@ abstract class IntPipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedInt(sink) { + return new Sink.ChainedInt(sink) { @Override public void accept(int t) { downstream.accept(mapper.applyAsDouble(t)); @@ -297,7 +294,7 @@ abstract class IntPipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedInt(sink) { + return new Sink.ChainedInt(sink) { @Override public void begin(long size) { downstream.begin(-1); @@ -334,7 +331,7 @@ abstract class IntPipeline StreamOpFlag.NOT_SIZED) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedInt(sink) { + return new Sink.ChainedInt(sink) { @Override public void begin(long size) { downstream.begin(-1); @@ -357,7 +354,7 @@ abstract class IntPipeline 0) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedInt(sink) { + return new Sink.ChainedInt(sink) { @Override public void accept(int t) { consumer.accept(t); diff --git a/jdk/src/share/classes/java/util/stream/LongPipeline.java b/jdk/src/share/classes/java/util/stream/LongPipeline.java index 083f7bb8b2b..3c199feab59 100644 --- a/jdk/src/share/classes/java/util/stream/LongPipeline.java +++ b/jdk/src/share/classes/java/util/stream/LongPipeline.java @@ -186,7 +186,7 @@ abstract class LongPipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedLong(sink) { + return new Sink.ChainedLong(sink) { @Override public void accept(long t) { downstream.accept((double) t); @@ -208,9 +208,8 @@ abstract class LongPipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedLong(sink) { + return new Sink.ChainedLong(sink) { @Override - @SuppressWarnings("unchecked") public void accept(long t) { downstream.accept(mapper.applyAsLong(t)); } @@ -226,9 +225,8 @@ abstract class LongPipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedLong(sink) { + return new Sink.ChainedLong(sink) { @Override - @SuppressWarnings("unchecked") public void accept(long t) { downstream.accept(mapper.apply(t)); } @@ -244,9 +242,8 @@ abstract class LongPipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedLong(sink) { + return new Sink.ChainedLong(sink) { @Override - @SuppressWarnings("unchecked") public void accept(long t) { downstream.accept(mapper.applyAsInt(t)); } @@ -262,7 +259,7 @@ abstract class LongPipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedLong(sink) { + return new Sink.ChainedLong(sink) { @Override public void accept(long t) { downstream.accept(mapper.applyAsDouble(t)); @@ -278,7 +275,7 @@ abstract class LongPipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedLong(sink) { + return new Sink.ChainedLong(sink) { @Override public void begin(long size) { downstream.begin(-1); @@ -315,7 +312,7 @@ abstract class LongPipeline StreamOpFlag.NOT_SIZED) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedLong(sink) { + return new Sink.ChainedLong(sink) { @Override public void begin(long size) { downstream.begin(-1); @@ -338,7 +335,7 @@ abstract class LongPipeline 0) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedLong(sink) { + return new Sink.ChainedLong(sink) { @Override public void accept(long t) { consumer.accept(t); diff --git a/jdk/src/share/classes/java/util/stream/ReferencePipeline.java b/jdk/src/share/classes/java/util/stream/ReferencePipeline.java index c201950d88c..1fffff48b18 100644 --- a/jdk/src/share/classes/java/util/stream/ReferencePipeline.java +++ b/jdk/src/share/classes/java/util/stream/ReferencePipeline.java @@ -163,17 +163,16 @@ abstract class ReferencePipeline StreamOpFlag.NOT_SIZED) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedReference(sink) { + return new Sink.ChainedReference(sink) { @Override public void begin(long size) { downstream.begin(-1); } @Override - @SuppressWarnings("unchecked") public void accept(P_OUT u) { if (predicate.test(u)) - downstream.accept((Object) u); + downstream.accept(u); } }; } @@ -188,7 +187,7 @@ abstract class ReferencePipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedReference(sink) { + return new Sink.ChainedReference(sink) { @Override public void accept(P_OUT u) { downstream.accept(mapper.apply(u)); @@ -205,7 +204,7 @@ abstract class ReferencePipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedReference(sink) { + return new Sink.ChainedReference(sink) { @Override public void accept(P_OUT u) { downstream.accept(mapper.applyAsInt(u)); @@ -222,7 +221,7 @@ abstract class ReferencePipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedReference(sink) { + return new Sink.ChainedReference(sink) { @Override public void accept(P_OUT u) { downstream.accept(mapper.applyAsLong(u)); @@ -239,7 +238,7 @@ abstract class ReferencePipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedReference(sink) { + return new Sink.ChainedReference(sink) { @Override public void accept(P_OUT u) { downstream.accept(mapper.applyAsDouble(u)); @@ -257,14 +256,13 @@ abstract class ReferencePipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedReference(sink) { + return new Sink.ChainedReference(sink) { @Override public void begin(long size) { downstream.begin(-1); } @Override - @SuppressWarnings("unchecked") public void accept(P_OUT u) { // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it Stream result = mapper.apply(u); @@ -284,7 +282,7 @@ abstract class ReferencePipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedReference(sink) { + return new Sink.ChainedReference(sink) { IntConsumer downstreamAsInt = downstream::accept; @Override public void begin(long size) { @@ -311,7 +309,7 @@ abstract class ReferencePipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedReference(sink) { + return new Sink.ChainedReference(sink) { DoubleConsumer downstreamAsDouble = downstream::accept; @Override public void begin(long size) { @@ -338,7 +336,7 @@ abstract class ReferencePipeline StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedReference(sink) { + return new Sink.ChainedReference(sink) { LongConsumer downstreamAsLong = downstream::accept; @Override public void begin(long size) { @@ -364,9 +362,8 @@ abstract class ReferencePipeline 0) { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedReference(sink) { + return new Sink.ChainedReference(sink) { @Override - @SuppressWarnings("unchecked") public void accept(P_OUT u) { tee.accept(u); downstream.accept(u); @@ -495,6 +492,7 @@ abstract class ReferencePipeline } @Override + @SuppressWarnings("unchecked") public final R collect(Collector collector) { A container; if (isParallel() diff --git a/jdk/src/share/classes/java/util/stream/Sink.java b/jdk/src/share/classes/java/util/stream/Sink.java index 987d0e9efa7..d2a366df16e 100644 --- a/jdk/src/share/classes/java/util/stream/Sink.java +++ b/jdk/src/share/classes/java/util/stream/Sink.java @@ -241,11 +241,10 @@ interface Sink extends Consumer { * implementation of the {@code accept()} method must call the correct * {@code accept()} method on the downstream {@code Sink}. */ - static abstract class ChainedReference implements Sink { - @SuppressWarnings("rawtypes") - protected final Sink downstream; + static abstract class ChainedReference implements Sink { + protected final Sink downstream; - public ChainedReference(Sink downstream) { + public ChainedReference(Sink downstream) { this.downstream = Objects.requireNonNull(downstream); } @@ -274,11 +273,10 @@ interface Sink extends Consumer { * The implementation of the {@code accept()} method must call the correct * {@code accept()} method on the downstream {@code Sink}. */ - static abstract class ChainedInt implements Sink.OfInt { - @SuppressWarnings("rawtypes") - protected final Sink downstream; + static abstract class ChainedInt implements Sink.OfInt { + protected final Sink downstream; - public ChainedInt(Sink downstream) { + public ChainedInt(Sink downstream) { this.downstream = Objects.requireNonNull(downstream); } @@ -307,11 +305,10 @@ interface Sink extends Consumer { * The implementation of the {@code accept()} method must call the correct * {@code accept()} method on the downstream {@code Sink}. */ - static abstract class ChainedLong implements Sink.OfLong { - @SuppressWarnings("rawtypes") - protected final Sink downstream; + static abstract class ChainedLong implements Sink.OfLong { + protected final Sink downstream; - public ChainedLong(Sink downstream) { + public ChainedLong(Sink downstream) { this.downstream = Objects.requireNonNull(downstream); } @@ -340,11 +337,10 @@ interface Sink extends Consumer { * The implementation of the {@code accept()} method must call the correct * {@code accept()} method on the downstream {@code Sink}. */ - static abstract class ChainedDouble implements Sink.OfDouble { - @SuppressWarnings("rawtypes") - protected final Sink downstream; + static abstract class ChainedDouble implements Sink.OfDouble { + protected final Sink downstream; - public ChainedDouble(Sink downstream) { + public ChainedDouble(Sink downstream) { this.downstream = Objects.requireNonNull(downstream); } diff --git a/jdk/src/share/classes/java/util/stream/SliceOps.java b/jdk/src/share/classes/java/util/stream/SliceOps.java index 09e14f637f4..34d55309d2d 100644 --- a/jdk/src/share/classes/java/util/stream/SliceOps.java +++ b/jdk/src/share/classes/java/util/stream/SliceOps.java @@ -96,6 +96,11 @@ final class SliceOps { } } + @SuppressWarnings("unchecked") + private static IntFunction castingArray() { + return size -> (T[]) new Object[size]; + } + /** * Appends a "slice" operation to the provided stream. The slice operation * may be may be skip-only, limit-only, or skip-and-limit. @@ -107,12 +112,12 @@ final class SliceOps { * is to be imposed */ public static Stream makeRef(AbstractPipeline upstream, - long skip, long limit) { + long skip, long limit) { if (skip < 0) throw new IllegalArgumentException("Skip must be non-negative: " + skip); - return new ReferencePipeline.StatefulOp(upstream, StreamShape.REFERENCE, - flags(limit)) { + return new ReferencePipeline.StatefulOp(upstream, StreamShape.REFERENCE, + flags(limit)) { Spliterator unorderedSkipLimitSpliterator(Spliterator s, long skip, long limit, long sizeIfKnown) { if (skip <= sizeIfKnown) { @@ -146,7 +151,7 @@ final class SliceOps { // cancellation will be more aggressive cancelling later tasks // if the target slice size has been reached from a given task, // cancellation should also clear local results if any - return new SliceTask<>(this, helper, spliterator, i -> (T[]) new Object[i], skip, limit). + return new SliceTask<>(this, helper, spliterator, castingArray(), skip, limit). invoke().spliterator(); } } @@ -182,7 +187,7 @@ final class SliceOps { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedReference(sink) { + return new Sink.ChainedReference(sink) { long n = skip; long m = limit >= 0 ? limit : Long.MAX_VALUE; @@ -291,7 +296,7 @@ final class SliceOps { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedInt(sink) { + return new Sink.ChainedInt(sink) { long n = skip; long m = limit >= 0 ? limit : Long.MAX_VALUE; @@ -400,7 +405,7 @@ final class SliceOps { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedLong(sink) { + return new Sink.ChainedLong(sink) { long n = skip; long m = limit >= 0 ? limit : Long.MAX_VALUE; @@ -509,7 +514,7 @@ final class SliceOps { @Override Sink opWrapSink(int flags, Sink sink) { - return new Sink.ChainedDouble(sink) { + return new Sink.ChainedDouble(sink) { long n = skip; long m = limit >= 0 ? limit : Long.MAX_VALUE; @@ -560,13 +565,13 @@ final class SliceOps { private volatile boolean completed; - SliceTask(AbstractPipeline op, + SliceTask(AbstractPipeline op, PipelineHelper helper, Spliterator spliterator, IntFunction generator, long offset, long size) { super(helper, spliterator); - this.op = (AbstractPipeline) op; + this.op = op; this.generator = generator; this.targetOffset = offset; this.targetSize = size; diff --git a/jdk/src/share/classes/java/util/stream/SortedOps.java b/jdk/src/share/classes/java/util/stream/SortedOps.java index 047479a645d..9df65e352e2 100644 --- a/jdk/src/share/classes/java/util/stream/SortedOps.java +++ b/jdk/src/share/classes/java/util/stream/SortedOps.java @@ -129,7 +129,7 @@ final class SortedOps { } @Override - public Sink opWrapSink(int flags, Sink sink) { + public Sink opWrapSink(int flags, Sink sink) { Objects.requireNonNull(sink); // If the input is already naturally sorted and this operation @@ -280,12 +280,12 @@ final class SortedOps { /** * {@link ForkJoinTask} for implementing sort on SIZED reference streams. */ - private static final class SizedRefSortingSink extends Sink.ChainedReference { + private static final class SizedRefSortingSink extends Sink.ChainedReference { private final Comparator comparator; private T[] array; private int offset; - SizedRefSortingSink(Sink sink, Comparator comparator) { + SizedRefSortingSink(Sink sink, Comparator comparator) { super(sink); this.comparator = comparator; } @@ -320,11 +320,11 @@ final class SortedOps { /** * {@link Sink} for implementing sort on reference streams. */ - private static final class RefSortingSink extends Sink.ChainedReference { + private static final class RefSortingSink extends Sink.ChainedReference { private final Comparator comparator; private ArrayList list; - RefSortingSink(Sink sink, Comparator comparator) { + RefSortingSink(Sink sink, Comparator comparator) { super(sink); this.comparator = comparator; } @@ -352,11 +352,11 @@ final class SortedOps { /** * {@link Sink} for implementing sort on SIZED int streams. */ - private static final class SizedIntSortingSink extends Sink.ChainedInt { + private static final class SizedIntSortingSink extends Sink.ChainedInt { private int[] array; private int offset; - SizedIntSortingSink(Sink downstream) { + SizedIntSortingSink(Sink downstream) { super(downstream); } @@ -386,10 +386,10 @@ final class SortedOps { /** * {@link Sink} for implementing sort on int streams. */ - private static final class IntSortingSink extends Sink.ChainedInt { + private static final class IntSortingSink extends Sink.ChainedInt { private SpinedBuffer.OfInt b; - IntSortingSink(Sink sink) { + IntSortingSink(Sink sink) { super(sink); } @@ -417,11 +417,11 @@ final class SortedOps { /** * {@link Sink} for implementing sort on SIZED long streams. */ - private static final class SizedLongSortingSink extends Sink.ChainedLong { + private static final class SizedLongSortingSink extends Sink.ChainedLong { private long[] array; private int offset; - SizedLongSortingSink(Sink downstream) { + SizedLongSortingSink(Sink downstream) { super(downstream); } @@ -451,10 +451,10 @@ final class SortedOps { /** * {@link Sink} for implementing sort on long streams. */ - private static final class LongSortingSink extends Sink.ChainedLong { + private static final class LongSortingSink extends Sink.ChainedLong { private SpinedBuffer.OfLong b; - LongSortingSink(Sink sink) { + LongSortingSink(Sink sink) { super(sink); } @@ -482,11 +482,11 @@ final class SortedOps { /** * {@link Sink} for implementing sort on SIZED double streams. */ - private static final class SizedDoubleSortingSink extends Sink.ChainedDouble { + private static final class SizedDoubleSortingSink extends Sink.ChainedDouble { private double[] array; private int offset; - SizedDoubleSortingSink(Sink downstream) { + SizedDoubleSortingSink(Sink downstream) { super(downstream); } @@ -516,10 +516,10 @@ final class SortedOps { /** * {@link Sink} for implementing sort on double streams. */ - private static final class DoubleSortingSink extends Sink.ChainedDouble { + private static final class DoubleSortingSink extends Sink.ChainedDouble { private SpinedBuffer.OfDouble b; - DoubleSortingSink(Sink sink) { + DoubleSortingSink(Sink sink) { super(sink); } From 5fab892391d80a0838950126c944488b37a69791 Mon Sep 17 00:00:00 2001 From: Mikael Vidstedt Date: Fri, 9 Aug 2013 09:51:21 -0700 Subject: [PATCH 025/102] 8022452: Hotspot needs to know about Windows 8.1 and Windows Server 2012 R2 Add support for recognizing Windows 8.1 and Server 2012 R2 and minor cleanup Reviewed-by: coleenp, dsamersoff --- hotspot/src/os/windows/vm/os_windows.cpp | 106 +++++++++++++---------- 1 file changed, 58 insertions(+), 48 deletions(-) diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index 3b44d9a220f..0674e6f3c83 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -1642,6 +1642,8 @@ void os::print_os_info(outputStream* st) { void os::win32::print_windows_version(outputStream* st) { OSVERSIONINFOEX osvi; + SYSTEM_INFO si; + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); @@ -1651,6 +1653,18 @@ void os::win32::print_windows_version(outputStream* st) { } int os_vers = osvi.dwMajorVersion * 1000 + osvi.dwMinorVersion; + + ZeroMemory(&si, sizeof(SYSTEM_INFO)); + if (os_vers >= 5002) { + // Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could + // find out whether we are running on 64 bit processor or not. + if (os::Kernel32Dll::GetNativeSystemInfoAvailable()) { + os::Kernel32Dll::GetNativeSystemInfo(&si); + } else { + GetSystemInfo(&si); + } + } + if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) { switch (os_vers) { case 3051: st->print(" Windows NT 3.51"); break; @@ -1658,57 +1672,48 @@ void os::win32::print_windows_version(outputStream* st) { case 5000: st->print(" Windows 2000"); break; case 5001: st->print(" Windows XP"); break; case 5002: - case 6000: - case 6001: - case 6002: { - // Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could - // find out whether we are running on 64 bit processor or not. - SYSTEM_INFO si; - ZeroMemory(&si, sizeof(SYSTEM_INFO)); - if (!os::Kernel32Dll::GetNativeSystemInfoAvailable()){ - GetSystemInfo(&si); + if (osvi.wProductType == VER_NT_WORKSTATION && + si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) { + st->print(" Windows XP x64 Edition"); } else { - os::Kernel32Dll::GetNativeSystemInfo(&si); - } - if (os_vers == 5002) { - if (osvi.wProductType == VER_NT_WORKSTATION && - si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) - st->print(" Windows XP x64 Edition"); - else - st->print(" Windows Server 2003 family"); - } else if (os_vers == 6000) { - if (osvi.wProductType == VER_NT_WORKSTATION) - st->print(" Windows Vista"); - else - st->print(" Windows Server 2008"); - if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) - st->print(" , 64 bit"); - } else if (os_vers == 6001) { - if (osvi.wProductType == VER_NT_WORKSTATION) { - st->print(" Windows 7"); - } else { - // Unrecognized windows, print out its major and minor versions - st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion); - } - if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) - st->print(" , 64 bit"); - } else if (os_vers == 6002) { - if (osvi.wProductType == VER_NT_WORKSTATION) { - st->print(" Windows 8"); - } else { - st->print(" Windows Server 2012"); - } - if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) - st->print(" , 64 bit"); - } else { // future os - // Unrecognized windows, print out its major and minor versions - st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion); - if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) - st->print(" , 64 bit"); + st->print(" Windows Server 2003 family"); } break; - } - default: // future windows, print out its major and minor versions + + case 6000: + if (osvi.wProductType == VER_NT_WORKSTATION) { + st->print(" Windows Vista"); + } else { + st->print(" Windows Server 2008"); + } + break; + + case 6001: + if (osvi.wProductType == VER_NT_WORKSTATION) { + st->print(" Windows 7"); + } else { + st->print(" Windows Server 2008 R2"); + } + break; + + case 6002: + if (osvi.wProductType == VER_NT_WORKSTATION) { + st->print(" Windows 8"); + } else { + st->print(" Windows Server 2012"); + } + break; + + case 6003: + if (osvi.wProductType == VER_NT_WORKSTATION) { + st->print(" Windows 8.1"); + } else { + st->print(" Windows Server 2012 R2"); + } + break; + + default: // future os + // Unrecognized windows, print out its major and minor versions st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion); } } else { @@ -1720,6 +1725,11 @@ void os::win32::print_windows_version(outputStream* st) { st->print(" Windows %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion); } } + + if (os_vers >= 6000 && si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) { + st->print(" , 64 bit"); + } + st->print(" Build %d", osvi.dwBuildNumber); st->print(" %s", osvi.szCSDVersion); // service pack st->cr(); From ed4b026105602e1272753344b9ff8127aaa50751 Mon Sep 17 00:00:00 2001 From: Igor Ignatyev Date: Sat, 10 Aug 2013 10:01:12 +0400 Subject: [PATCH 026/102] 8019915: whitebox testClearMethodStateTest fails with tiered on sparc 'compileonly' directive has beens added to each 'compiler/whitebox' test Reviewed-by: kvn --- hotspot/test/compiler/whitebox/ClearMethodStateTest.java | 2 +- hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java | 7 ++++++- hotspot/test/compiler/whitebox/DeoptimizeAllTest.java | 2 +- hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java | 2 +- .../compiler/whitebox/EnqueueMethodForCompilationTest.java | 2 +- hotspot/test/compiler/whitebox/IsMethodCompilableTest.java | 2 +- .../compiler/whitebox/MakeMethodNotCompilableTest.java | 2 +- .../test/compiler/whitebox/SetDontInlineMethodTest.java | 2 +- .../test/compiler/whitebox/SetForceInlineMethodTest.java | 2 +- 9 files changed, 14 insertions(+), 9 deletions(-) diff --git a/hotspot/test/compiler/whitebox/ClearMethodStateTest.java b/hotspot/test/compiler/whitebox/ClearMethodStateTest.java index 491650d3752..6b718ec8851 100644 --- a/hotspot/test/compiler/whitebox/ClearMethodStateTest.java +++ b/hotspot/test/compiler/whitebox/ClearMethodStateTest.java @@ -26,7 +26,7 @@ * @library /testlibrary /testlibrary/whitebox * @build ClearMethodStateTest * @run main ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ClearMethodStateTest + * @run main/othervm -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* ClearMethodStateTest * @summary testing of WB::clearMethodState() * @author igor.ignatyev@oracle.com */ diff --git a/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java b/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java index 74b467ea670..f09922cec8b 100644 --- a/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java +++ b/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java @@ -61,6 +61,9 @@ public abstract class CompilerWhiteBoxTest { /** Value of {@code -XX:TieredStopAtLevel} */ protected static final int TIERED_STOP_AT_LEVEL = Integer.parseInt(getVMOption("TieredStopAtLevel", "0")); + /** Flag for verbose output, true if {@code -Dverbose} specified */ + protected static final boolean IS_VERBOSE + = System.getProperty("verbose") != null; /** * Returns value of VM option. @@ -268,7 +271,9 @@ public abstract class CompilerWhiteBoxTest { } result += tmp == null ? 0 : tmp; } - System.out.println("method was invoked " + count + " times"); + if (IS_VERBOSE) { + System.out.println("method was invoked " + count + " times"); + } return result; } } diff --git a/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java b/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java index c831a23e58c..c659ac164e7 100644 --- a/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java +++ b/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java @@ -26,7 +26,7 @@ * @library /testlibrary /testlibrary/whitebox * @build DeoptimizeAllTest * @run main ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI DeoptimizeAllTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* DeoptimizeAllTest * @summary testing of WB::deoptimizeAll() * @author igor.ignatyev@oracle.com */ diff --git a/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java b/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java index b6c84aeb313..0fedc3402af 100644 --- a/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java +++ b/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java @@ -26,7 +26,7 @@ * @library /testlibrary /testlibrary/whitebox * @build DeoptimizeMethodTest * @run main ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI DeoptimizeMethodTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* DeoptimizeMethodTest * @summary testing of WB::deoptimizeMethod() * @author igor.ignatyev@oracle.com */ diff --git a/hotspot/test/compiler/whitebox/EnqueueMethodForCompilationTest.java b/hotspot/test/compiler/whitebox/EnqueueMethodForCompilationTest.java index f87b3235697..b14bd96709f 100644 --- a/hotspot/test/compiler/whitebox/EnqueueMethodForCompilationTest.java +++ b/hotspot/test/compiler/whitebox/EnqueueMethodForCompilationTest.java @@ -26,7 +26,7 @@ * @library /testlibrary /testlibrary/whitebox * @build EnqueueMethodForCompilationTest * @run main ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI EnqueueMethodForCompilationTest + * @run main/othervm -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* EnqueueMethodForCompilationTest * @summary testing of WB::enqueueMethodForCompilation() * @author igor.ignatyev@oracle.com */ diff --git a/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java b/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java index e1cfaf4887b..bb7da4ab007 100644 --- a/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java +++ b/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java @@ -27,7 +27,7 @@ * @library /testlibrary /testlibrary/whitebox * @build IsMethodCompilableTest * @run main ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI IsMethodCompilableTest + * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* IsMethodCompilableTest * @summary testing of WB::isMethodCompilable() * @author igor.ignatyev@oracle.com */ diff --git a/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java b/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java index 8347049a3d6..8290dcecc3a 100644 --- a/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java +++ b/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java @@ -27,7 +27,7 @@ * @library /testlibrary /testlibrary/whitebox * @build MakeMethodNotCompilableTest * @run main ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI MakeMethodNotCompilableTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* MakeMethodNotCompilableTest * @summary testing of WB::makeMethodNotCompilable() * @author igor.ignatyev@oracle.com */ diff --git a/hotspot/test/compiler/whitebox/SetDontInlineMethodTest.java b/hotspot/test/compiler/whitebox/SetDontInlineMethodTest.java index 6a8b61c373f..22912a1058d 100644 --- a/hotspot/test/compiler/whitebox/SetDontInlineMethodTest.java +++ b/hotspot/test/compiler/whitebox/SetDontInlineMethodTest.java @@ -26,7 +26,7 @@ * @library /testlibrary /testlibrary/whitebox * @build SetDontInlineMethodTest * @run main ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SetDontInlineMethodTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* SetDontInlineMethodTest * @summary testing of WB::testSetDontInlineMethod() * @author igor.ignatyev@oracle.com */ diff --git a/hotspot/test/compiler/whitebox/SetForceInlineMethodTest.java b/hotspot/test/compiler/whitebox/SetForceInlineMethodTest.java index ca3e54389bb..609be614a2c 100644 --- a/hotspot/test/compiler/whitebox/SetForceInlineMethodTest.java +++ b/hotspot/test/compiler/whitebox/SetForceInlineMethodTest.java @@ -26,7 +26,7 @@ * @library /testlibrary /testlibrary/whitebox * @build SetForceInlineMethodTest * @run main ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SetForceInlineMethodTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* SetForceInlineMethodTest * @summary testing of WB::testSetForceInlineMethod() * @author igor.ignatyev@oracle.com */ From 5189d350c9d3b3cd60af69000994062f3f84054c Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Sat, 10 Aug 2013 10:56:27 -0700 Subject: [PATCH 027/102] 8022740: Visual 2008 IDE build is broken Fixed project generation code, and added warning to upgrade to VS 2008 SP1. Reviewed-by: dcubed, ccheung --- .../make/windows/projectfiles/common/Makefile | 1 + .../tools/ProjectCreator/FileTreeCreator.java | 8 +++-- .../ProjectCreator/FileTreeCreatorVC10.java | 6 ++-- .../ProjectCreator/FileTreeCreatorVC7.java | 2 +- .../ProjectCreator/WinGammaPlatformVC7.java | 29 ++++++++++--------- 5 files changed, 27 insertions(+), 19 deletions(-) diff --git a/hotspot/make/windows/projectfiles/common/Makefile b/hotspot/make/windows/projectfiles/common/Makefile index 8ae363be7d5..0bc4fb182ec 100644 --- a/hotspot/make/windows/projectfiles/common/Makefile +++ b/hotspot/make/windows/projectfiles/common/Makefile @@ -112,6 +112,7 @@ ReleaseOptions = -define HOTSPOT_RELEASE_VERSION=$(HOTSPOT_RELEASE_VERSION) -def ProjectCreatorIDEOptions = $(ProjectCreatorIDEOptions) $(ReleaseOptions) $(HOTSPOTBUILDSPACE)/$(ProjectFile): $(HOTSPOTBUILDSPACE)/classes/ProjectCreator.class + @if "$(MSC_VER)"=="1500" echo Make sure you have VS2008 SP1 or later, or you may see 'expanded command line too long' @$(RUN_JAVA) -Djava.class.path="$(HOTSPOTBUILDSPACE)/classes" ProjectCreator WinGammaPlatform$(VcVersion) $(ProjectCreatorIDEOptions) clean: diff --git a/hotspot/src/share/tools/ProjectCreator/FileTreeCreator.java b/hotspot/src/share/tools/ProjectCreator/FileTreeCreator.java index 3643c572e99..a81132c7029 100644 --- a/hotspot/src/share/tools/ProjectCreator/FileTreeCreator.java +++ b/hotspot/src/share/tools/ProjectCreator/FileTreeCreator.java @@ -12,11 +12,15 @@ public class FileTreeCreator extends SimpleFileVisitor final int startDirLength; Stack attributes = new Stack(); Vector allConfigs; - WinGammaPlatformVC10 wg; + WinGammaPlatform wg; + WinGammaPlatformVC10 wg10; - public FileTreeCreator(Path startDir, Vector allConfigs, WinGammaPlatformVC10 wg) { + public FileTreeCreator(Path startDir, Vector allConfigs, WinGammaPlatform wg) { super(); this.wg = wg; + if (wg instanceof WinGammaPlatformVC10) { + wg10 = (WinGammaPlatformVC10)wg; + } this.allConfigs = allConfigs; this.startDir = startDir; startDirLength = startDir.toAbsolutePath().toString().length(); diff --git a/hotspot/src/share/tools/ProjectCreator/FileTreeCreatorVC10.java b/hotspot/src/share/tools/ProjectCreator/FileTreeCreatorVC10.java index 8041d833e34..cb0fe33577e 100644 --- a/hotspot/src/share/tools/ProjectCreator/FileTreeCreatorVC10.java +++ b/hotspot/src/share/tools/ProjectCreator/FileTreeCreatorVC10.java @@ -103,7 +103,7 @@ public class FileTreeCreatorVC10 extends FileTreeCreator { } } - String tagName = wg.getFileTagFromSuffix(fileName); + String tagName = wg10.getFileTagFromSuffix(fileName); if (!useIgnore && !disablePch && !usePch && !isReplacedByAltSrc) { wg.tag(tagName, new String[] { "Include", fileLoc}); @@ -133,7 +133,7 @@ public class FileTreeCreatorVC10 extends FileTreeCreator { } String filter = startDir.relativize(file.getParent().toAbsolutePath()).toString(); - wg.addFilterDependency(fileLoc, filter); + wg10.addFilterDependency(fileLoc, filter); return CONTINUE; } @@ -162,7 +162,7 @@ public class FileTreeCreatorVC10 extends FileTreeCreator { if (!hide) { String name = startDir.relativize(path.toAbsolutePath()).toString(); if (!"".equals(name)) { - wg.addFilter(name); + wg10.addFilter(name); } attributes.push(newAttr); diff --git a/hotspot/src/share/tools/ProjectCreator/FileTreeCreatorVC7.java b/hotspot/src/share/tools/ProjectCreator/FileTreeCreatorVC7.java index b36e0121f8a..9a431845719 100644 --- a/hotspot/src/share/tools/ProjectCreator/FileTreeCreatorVC7.java +++ b/hotspot/src/share/tools/ProjectCreator/FileTreeCreatorVC7.java @@ -12,7 +12,7 @@ import java.util.Vector; public class FileTreeCreatorVC7 extends FileTreeCreator { public FileTreeCreatorVC7(Path startDir, Vector allConfigs, WinGammaPlatform wg) { - super(startDir, allConfigs, null); + super(startDir, allConfigs, wg); } @Override diff --git a/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC7.java b/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC7.java index 09e961cbfa0..b7a99a652db 100644 --- a/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC7.java +++ b/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC7.java @@ -139,19 +139,22 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform { tagV("Tool", cfg.getV("LinkerFlags")); - tag("Tool", - new String[] { - "Name", - "VCPostBuildEventTool", - "Description", - BuildConfig - .getFieldString(null, "PostbuildDescription"), - // Caution: String.replace(String,String) is available - // from JDK5 onwards only - "CommandLine", - cfg.expandFormat(BuildConfig.getFieldString(null, - "PostbuildCommand").replace("\t", - " ")) }); + String postBuildCmd = BuildConfig.getFieldString(null, + "PostbuildCommand"); + if (postBuildCmd != null) { + tag("Tool", + new String[] { + "Name", + "VCPostBuildEventTool", + "Description", + BuildConfig + .getFieldString(null, "PostbuildDescription"), + // Caution: String.replace(String,String) is available + // from JDK5 onwards only + "CommandLine", + cfg.expandFormat(postBuildCmd.replace("\t", + " ")) }); + } tag("Tool", new String[] { "Name", "VCPreBuildEventTool" }); From a25f924de64713995abf675fa462c17902782c8c Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Mon, 12 Aug 2013 17:24:54 -0400 Subject: [PATCH 028/102] 8009728: nsk/jvmti/AttachOnDemand/attach030 crashes on Win32 ActiveMethodOopsCache was used to keep track of old versions of some methods that are cached in Universe but is buggy with permgen removal and not needed anymore Reviewed-by: sspitsyn, dcubed, mseledtsov --- hotspot/src/share/vm/memory/universe.cpp | 128 ++---------------- hotspot/src/share/vm/memory/universe.hpp | 70 +++------- hotspot/src/share/vm/oops/method.cpp | 1 - .../share/vm/prims/jvmtiRedefineClasses.cpp | 9 -- .../test/runtime/RedefineObject/Agent.java | 40 ++++-- .../RedefineObject/TestRedefineObject.java | 7 +- .../RedefineObject/WalkThroughInvoke.java | 38 ++++++ 7 files changed, 109 insertions(+), 184 deletions(-) create mode 100644 hotspot/test/runtime/RedefineObject/WalkThroughInvoke.java diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp index 511610bd3bf..33a857f2a7e 100644 --- a/hotspot/src/share/vm/memory/universe.cpp +++ b/hotspot/src/share/vm/memory/universe.cpp @@ -105,10 +105,9 @@ objArrayOop Universe::_the_empty_class_klass_array = NULL; Array* Universe::_the_array_interfaces_array = NULL; oop Universe::_the_null_string = NULL; oop Universe::_the_min_jint_string = NULL; -LatestMethodOopCache* Universe::_finalizer_register_cache = NULL; -LatestMethodOopCache* Universe::_loader_addClass_cache = NULL; -LatestMethodOopCache* Universe::_pd_implies_cache = NULL; -ActiveMethodOopsCache* Universe::_reflect_invoke_cache = NULL; +LatestMethodCache* Universe::_finalizer_register_cache = NULL; +LatestMethodCache* Universe::_loader_addClass_cache = NULL; +LatestMethodCache* Universe::_pd_implies_cache = NULL; oop Universe::_out_of_memory_error_java_heap = NULL; oop Universe::_out_of_memory_error_metaspace = NULL; oop Universe::_out_of_memory_error_class_metaspace = NULL; @@ -225,7 +224,6 @@ void Universe::serialize(SerializeClosure* f, bool do_all) { f->do_ptr((void**)&_the_empty_klass_array); _finalizer_register_cache->serialize(f); _loader_addClass_cache->serialize(f); - _reflect_invoke_cache->serialize(f); _pd_implies_cache->serialize(f); } @@ -649,10 +647,9 @@ jint universe_init() { // We have a heap so create the Method* caches before // Metaspace::initialize_shared_spaces() tries to populate them. - Universe::_finalizer_register_cache = new LatestMethodOopCache(); - Universe::_loader_addClass_cache = new LatestMethodOopCache(); - Universe::_pd_implies_cache = new LatestMethodOopCache(); - Universe::_reflect_invoke_cache = new ActiveMethodOopsCache(); + Universe::_finalizer_register_cache = new LatestMethodCache(); + Universe::_loader_addClass_cache = new LatestMethodCache(); + Universe::_pd_implies_cache = new LatestMethodCache(); if (UseSharedSpaces) { // Read the data structures supporting the shared spaces (shared @@ -1088,35 +1085,21 @@ bool universe_post_init() { vmSymbols::register_method_name(), vmSymbols::register_method_signature()); if (m == NULL || !m->is_static()) { - THROW_MSG_(vmSymbols::java_lang_NoSuchMethodException(), - "java.lang.ref.Finalizer.register", false); + tty->print_cr("Unable to link/verify Finalizer.register method"); + return false; // initialization failed (cannot throw exception yet) } Universe::_finalizer_register_cache->init( - SystemDictionary::Finalizer_klass(), m, CHECK_false); - - // Resolve on first use and initialize class. - // Note: No race-condition here, since a resolve will always return the same result - - // Setup method for security checks - k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_reflect_Method(), true, CHECK_false); - k_h = instanceKlassHandle(THREAD, k); - k_h->link_class(CHECK_false); - m = k_h->find_method(vmSymbols::invoke_name(), vmSymbols::object_object_array_object_signature()); - if (m == NULL || m->is_static()) { - THROW_MSG_(vmSymbols::java_lang_NoSuchMethodException(), - "java.lang.reflect.Method.invoke", false); - } - Universe::_reflect_invoke_cache->init(k_h(), m, CHECK_false); + SystemDictionary::Finalizer_klass(), m); // Setup method for registering loaded classes in class loader vector InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->link_class(CHECK_false); m = InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->find_method(vmSymbols::addClass_name(), vmSymbols::class_void_signature()); if (m == NULL || m->is_static()) { - THROW_MSG_(vmSymbols::java_lang_NoSuchMethodException(), - "java.lang.ClassLoader.addClass", false); + tty->print_cr("Unable to link/verify ClassLoader.addClass method"); + return false; // initialization failed (cannot throw exception yet) } Universe::_loader_addClass_cache->init( - SystemDictionary::ClassLoader_klass(), m, CHECK_false); + SystemDictionary::ClassLoader_klass(), m); // Setup method for checking protection domain InstanceKlass::cast(SystemDictionary::ProtectionDomain_klass())->link_class(CHECK_false); @@ -1132,7 +1115,7 @@ bool universe_post_init() { return false; // initialization failed } Universe::_pd_implies_cache->init( - SystemDictionary::ProtectionDomain_klass(), m, CHECK_false);; + SystemDictionary::ProtectionDomain_klass(), m);; } // The folowing is initializing converter functions for serialization in @@ -1455,7 +1438,7 @@ void Universe::compute_verify_oop_data() { } -void CommonMethodOopCache::init(Klass* k, Method* m, TRAPS) { +void LatestMethodCache::init(Klass* k, Method* m) { if (!UseSharedSpaces) { _klass = k; } @@ -1471,88 +1454,7 @@ void CommonMethodOopCache::init(Klass* k, Method* m, TRAPS) { } -ActiveMethodOopsCache::~ActiveMethodOopsCache() { - if (_prev_methods != NULL) { - delete _prev_methods; - _prev_methods = NULL; - } -} - - -void ActiveMethodOopsCache::add_previous_version(Method* method) { - assert(Thread::current()->is_VM_thread(), - "only VMThread can add previous versions"); - - // Only append the previous method if it is executing on the stack. - if (method->on_stack()) { - - if (_prev_methods == NULL) { - // This is the first previous version so make some space. - // Start with 2 elements under the assumption that the class - // won't be redefined much. - _prev_methods = new (ResourceObj::C_HEAP, mtClass) GrowableArray(2, true); - } - - // RC_TRACE macro has an embedded ResourceMark - RC_TRACE(0x00000100, - ("add: %s(%s): adding prev version ref for cached method @%d", - method->name()->as_C_string(), method->signature()->as_C_string(), - _prev_methods->length())); - - _prev_methods->append(method); - } - - - // Since the caller is the VMThread and we are at a safepoint, this is a good - // time to clear out unused method references. - - if (_prev_methods == NULL) return; - - for (int i = _prev_methods->length() - 1; i >= 0; i--) { - Method* method = _prev_methods->at(i); - assert(method != NULL, "weak method ref was unexpectedly cleared"); - - if (!method->on_stack()) { - // This method isn't running anymore so remove it - _prev_methods->remove_at(i); - MetadataFactory::free_metadata(method->method_holder()->class_loader_data(), method); - } else { - // RC_TRACE macro has an embedded ResourceMark - RC_TRACE(0x00000400, - ("add: %s(%s): previous cached method @%d is alive", - method->name()->as_C_string(), method->signature()->as_C_string(), i)); - } - } -} // end add_previous_version() - - -bool ActiveMethodOopsCache::is_same_method(const Method* method) const { - InstanceKlass* ik = InstanceKlass::cast(klass()); - const Method* check_method = ik->method_with_idnum(method_idnum()); - assert(check_method != NULL, "sanity check"); - if (check_method == method) { - // done with the easy case - return true; - } - - if (_prev_methods != NULL) { - // The cached method has been redefined at least once so search - // the previous versions for a match. - for (int i = 0; i < _prev_methods->length(); i++) { - check_method = _prev_methods->at(i); - if (check_method == method) { - // a previous version matches - return true; - } - } - } - - // either no previous versions or no previous version matched - return false; -} - - -Method* LatestMethodOopCache::get_Method() { +Method* LatestMethodCache::get_method() { if (klass() == NULL) return NULL; InstanceKlass* ik = InstanceKlass::cast(klass()); Method* m = ik->method_with_idnum(method_idnum()); diff --git a/hotspot/src/share/vm/memory/universe.hpp b/hotspot/src/share/vm/memory/universe.hpp index 24a95e84594..69998434380 100644 --- a/hotspot/src/share/vm/memory/universe.hpp +++ b/hotspot/src/share/vm/memory/universe.hpp @@ -41,10 +41,11 @@ class CollectedHeap; class DeferredObjAllocEvent; -// Common parts of a Method* cache. This cache safely interacts with -// the RedefineClasses API. -// -class CommonMethodOopCache : public CHeapObj { +// A helper class for caching a Method* when the user of the cache +// only cares about the latest version of the Method*. This cache safely +// interacts with the RedefineClasses API. + +class LatestMethodCache : public CHeapObj { // We save the Klass* and the idnum of Method* in order to get // the current cached Method*. private: @@ -52,12 +53,14 @@ class CommonMethodOopCache : public CHeapObj { int _method_idnum; public: - CommonMethodOopCache() { _klass = NULL; _method_idnum = -1; } - ~CommonMethodOopCache() { _klass = NULL; _method_idnum = -1; } + LatestMethodCache() { _klass = NULL; _method_idnum = -1; } + ~LatestMethodCache() { _klass = NULL; _method_idnum = -1; } - void init(Klass* k, Method* m, TRAPS); - Klass* klass() const { return _klass; } - int method_idnum() const { return _method_idnum; } + void init(Klass* k, Method* m); + Klass* klass() const { return _klass; } + int method_idnum() const { return _method_idnum; } + + Method* get_method(); // Enhanced Class Redefinition support void classes_do(void f(Klass*)) { @@ -72,39 +75,6 @@ class CommonMethodOopCache : public CHeapObj { }; -// A helper class for caching a Method* when the user of the cache -// cares about all versions of the Method*. -// -class ActiveMethodOopsCache : public CommonMethodOopCache { - // This subclass adds weak references to older versions of the - // Method* and a query method for a Method*. - - private: - // If the cached Method* has not been redefined, then - // _prev_methods will be NULL. If all of the previous - // versions of the method have been collected, then - // _prev_methods can have a length of zero. - GrowableArray* _prev_methods; - - public: - ActiveMethodOopsCache() { _prev_methods = NULL; } - ~ActiveMethodOopsCache(); - - void add_previous_version(Method* method); - bool is_same_method(const Method* method) const; -}; - - -// A helper class for caching a Method* when the user of the cache -// only cares about the latest version of the Method*. -// -class LatestMethodOopCache : public CommonMethodOopCache { - // This subclass adds a getter method for the latest Method*. - - public: - Method* get_Method(); -}; - // For UseCompressedOops and UseCompressedKlassPointers. struct NarrowPtrStruct { // Base address for oop/klass-within-java-object materialization. @@ -174,10 +144,10 @@ class Universe: AllStatic { static objArrayOop _the_empty_class_klass_array; // Canonicalized obj array of type java.lang.Class static oop _the_null_string; // A cache of "null" as a Java string static oop _the_min_jint_string; // A cache of "-2147483648" as a Java string - static LatestMethodOopCache* _finalizer_register_cache; // static method for registering finalizable objects - static LatestMethodOopCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector - static LatestMethodOopCache* _pd_implies_cache; // method for checking protection domain attributes - static ActiveMethodOopsCache* _reflect_invoke_cache; // method for security checks + static LatestMethodCache* _finalizer_register_cache; // static method for registering finalizable objects + static LatestMethodCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector + static LatestMethodCache* _pd_implies_cache; // method for checking protection domain attributes + // preallocated error objects (no backtrace) static oop _out_of_memory_error_java_heap; static oop _out_of_memory_error_metaspace; @@ -334,11 +304,11 @@ class Universe: AllStatic { static Array* the_array_interfaces_array() { return _the_array_interfaces_array; } static oop the_null_string() { return _the_null_string; } static oop the_min_jint_string() { return _the_min_jint_string; } - static Method* finalizer_register_method() { return _finalizer_register_cache->get_Method(); } - static Method* loader_addClass_method() { return _loader_addClass_cache->get_Method(); } - static Method* protection_domain_implies_method() { return _pd_implies_cache->get_Method(); } - static ActiveMethodOopsCache* reflect_invoke_cache() { return _reflect_invoke_cache; } + static Method* finalizer_register_method() { return _finalizer_register_cache->get_method(); } + static Method* loader_addClass_method() { return _loader_addClass_cache->get_method(); } + + static Method* protection_domain_implies_method() { return _pd_implies_cache->get_method(); } static oop null_ptr_exception_instance() { return _null_ptr_exception_instance; } static oop arithmetic_exception_instance() { return _arithmetic_exception_instance; } diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp index ac210e14834..07cc1aa09cc 100644 --- a/hotspot/src/share/vm/oops/method.cpp +++ b/hotspot/src/share/vm/oops/method.cpp @@ -981,7 +981,6 @@ bool Method::should_not_be_cached() const { bool Method::is_ignored_by_security_stack_walk() const { const bool use_new_reflection = JDK_Version::is_gte_jdk14x_version() && UseNewReflection; - assert(intrinsic_id() != vmIntrinsics::_invoke || Universe::reflect_invoke_cache()->is_same_method((Method*)this), "sanity"); if (intrinsic_id() == vmIntrinsics::_invoke) { // This is Method.invoke() -- ignore it return true; diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp index 877ed0e02fb..c6ec25f1406 100644 --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp @@ -3217,15 +3217,6 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass, JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints(); jvmti_breakpoints.clearall_in_class_at_safepoint(the_class_oop); - if (the_class_oop == Universe::reflect_invoke_cache()->klass()) { - // We are redefining java.lang.reflect.Method. Method.invoke() is - // cached and users of the cache care about each active version of - // the method so we have to track this previous version. - // Do this before methods get switched - Universe::reflect_invoke_cache()->add_previous_version( - the_class->method_with_idnum(Universe::reflect_invoke_cache()->method_idnum())); - } - // Deoptimize all compiled code that depends on this class flush_dependent_code(the_class, THREAD); diff --git a/hotspot/test/runtime/RedefineObject/Agent.java b/hotspot/test/runtime/RedefineObject/Agent.java index 7927094d8aa..b5435c22ca7 100644 --- a/hotspot/test/runtime/RedefineObject/Agent.java +++ b/hotspot/test/runtime/RedefineObject/Agent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,6 +22,7 @@ */ import java.security.*; import java.lang.instrument.*; +import java.lang.reflect.*; public class Agent implements ClassFileTransformer { public synchronized byte[] transform(final ClassLoader classLoader, @@ -29,23 +30,35 @@ public class Agent implements ClassFileTransformer { Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) { - //System.out.println("Transforming class " + className); + System.out.println("Transforming class " + className); return classfileBuffer; } - public static void premain(String agentArgs, Instrumentation instrumentation) { + public static void redefine(String agentArgs, Instrumentation instrumentation, Class to_redefine) { - Agent transformer = new Agent(); - - instrumentation.addTransformer(transformer, true); - - Class c = Object.class; try { - instrumentation.retransformClasses(c); + instrumentation.retransformClasses(to_redefine); } catch (Exception e) { e.printStackTrace(); } + } + + public static void premain(String agentArgs, Instrumentation instrumentation) { + Agent transformer = new Agent(); + instrumentation.addTransformer(transformer, true); + + // Redefine java/lang/Object and java/lang/reflect/Method.invoke and + // java/lang/ClassLoader + Class object_class = Object.class; + redefine(agentArgs, instrumentation, object_class); + + Class method_class = Method.class; + redefine(agentArgs, instrumentation, method_class); + + Class loader_class = ClassLoader.class; + redefine(agentArgs, instrumentation, loader_class); + instrumentation.removeTransformer(transformer); } @@ -57,5 +70,14 @@ public class Agent implements ClassFileTransformer { System.gc(); ba.clone(); } + try { + // Use java/lang/reflect/Method.invoke to call + WalkThroughInvoke a = new WalkThroughInvoke(); + Class aclass = WalkThroughInvoke.class; + Method m = aclass.getMethod("stackWalk"); + m.invoke(a); + } catch (Exception x) { + x.printStackTrace(); + } } } diff --git a/hotspot/test/runtime/RedefineObject/TestRedefineObject.java b/hotspot/test/runtime/RedefineObject/TestRedefineObject.java index bd5003a588a..437cec25b33 100644 --- a/hotspot/test/runtime/RedefineObject/TestRedefineObject.java +++ b/hotspot/test/runtime/RedefineObject/TestRedefineObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2013, 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 @@ -26,14 +26,17 @@ import com.oracle.java.testlibrary.*; /* * Test to redefine java/lang/Object and verify that it doesn't crash on vtable * call on basic array type. + * Test to redefine java/lang/ClassLoader and java/lang/reflect/Method to make + * sure cached versions used afterward are the current version. * * @test * @bug 8005056 + * @bug 8009728 * @library /testlibrary * @build Agent * @run main ClassFileInstaller Agent * @run main TestRedefineObject - * @run main/othervm -javaagent:agent.jar Agent + * @run main/othervm -javaagent:agent.jar -XX:TraceRedefineClasses=5 Agent */ public class TestRedefineObject { public static void main(String[] args) throws Exception { diff --git a/hotspot/test/runtime/RedefineObject/WalkThroughInvoke.java b/hotspot/test/runtime/RedefineObject/WalkThroughInvoke.java new file mode 100644 index 00000000000..51f0e635bca --- /dev/null +++ b/hotspot/test/runtime/RedefineObject/WalkThroughInvoke.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2013, 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.lang.reflect.*; + +public class WalkThroughInvoke { + public void stackWalk() { + try { + Class b = Object.class; + SecurityManager sm = new SecurityManager(); + // Walks the stack with Method.invoke in the stack (which is the + // purpose of the test) before it gets an AccessControlException. + sm.checkMemberAccess(b, Member.DECLARED); + } catch (java.security.AccessControlException e) { + // Ignoring an 'AccessControlException' exception since + // it is expected as part of this test. + } + } +}; From 36197b96c29a36e9f58bff42a37aa01438cc2a54 Mon Sep 17 00:00:00 2001 From: Konstantin Perikov Date: Tue, 13 Aug 2013 15:41:55 +0400 Subject: [PATCH 029/102] 7027045: (doc) java/awt/Window.java has several typos in javadoc Reviewed-by: art, serb --- jdk/src/share/classes/java/awt/Window.java | 378 ++++++++++----------- 1 file changed, 189 insertions(+), 189 deletions(-) diff --git a/jdk/src/share/classes/java/awt/Window.java b/jdk/src/share/classes/java/awt/Window.java index 0e02d8b0a6f..4076939c7f0 100644 --- a/jdk/src/share/classes/java/awt/Window.java +++ b/jdk/src/share/classes/java/awt/Window.java @@ -62,18 +62,18 @@ import sun.security.util.SecurityConstants; import sun.util.logging.PlatformLogger; /** - * A Window object is a top-level window with no borders and no + * A {@code Window} object is a top-level window with no borders and no * menubar. - * The default layout for a window is BorderLayout. + * The default layout for a window is {@code BorderLayout}. *

* A window must have either a frame, dialog, or another window defined as its * owner when it's constructed. *

- * In a multi-screen environment, you can create a Window - * on a different screen device by constructing the Window + * In a multi-screen environment, you can create a {@code Window} + * on a different screen device by constructing the {@code Window} * with {@link #Window(Window, GraphicsConfiguration)}. The - * GraphicsConfiguration object is one of the - * GraphicsConfiguration objects of the target screen device. + * {@code GraphicsConfiguration} object is one of the + * {@code GraphicsConfiguration} objects of the target screen device. *

* In a virtual device multi-screen environment in which the desktop * area could span multiple physical screen devices, the bounds of all @@ -87,21 +87,21 @@ import sun.util.logging.PlatformLogger; * alt="Diagram shows virtual device containing 4 physical screens. Primary physical screen shows coords (0,0), other screen shows (-80,-100)." * ALIGN=center HSPACE=10 VSPACE=7> *

- * In such an environment, when calling setLocation, + * In such an environment, when calling {@code setLocation}, * you must pass a virtual coordinate to this method. Similarly, - * calling getLocationOnScreen on a Window returns - * virtual device coordinates. Call the getBounds method - * of a GraphicsConfiguration to find its origin in the virtual + * calling {@code getLocationOnScreen} on a {@code Window} returns + * virtual device coordinates. Call the {@code getBounds} method + * of a {@code GraphicsConfiguration} to find its origin in the virtual * coordinate system. *

- * The following code sets the location of a Window + * The following code sets the location of a {@code Window} * at (10, 10) relative to the origin of the physical screen - * of the corresponding GraphicsConfiguration. If the - * bounds of the GraphicsConfiguration is not taken - * into account, the Window location would be set + * of the corresponding {@code GraphicsConfiguration}. If the + * bounds of the {@code GraphicsConfiguration} is not taken + * into account, the {@code Window} location would be set * at (10, 10) relative to the virtual-coordinate system and would appear * on the primary physical screen, which might be different from the - * physical screen of the specified GraphicsConfiguration. + * physical screen of the specified {@code GraphicsConfiguration}. * *

  *      Window w = new Window(Window owner, GraphicsConfiguration gc);
@@ -111,19 +111,19 @@ import sun.util.logging.PlatformLogger;
  *
  * 

* Note: the location and size of top-level windows (including - * Windows, Frames, and Dialogs) + * {@code Window}s, {@code Frame}s, and {@code Dialog}s) * are under the control of the desktop's window management system. - * Calls to setLocation, setSize, and - * setBounds are requests (not directives) which are + * Calls to {@code setLocation}, {@code setSize}, and + * {@code setBounds} are requests (not directives) which are * forwarded to the window management system. Every effort will be * made to honor such requests. However, in some cases the window * management system may ignore such requests, or modify the requested - * geometry in order to place and size the Window in a way + * geometry in order to place and size the {@code Window} in a way * that more closely matches the desktop settings. *

* Due to the asynchronous nature of native event handling, the results - * returned by getBounds, getLocation, - * getLocationOnScreen, and getSize might not + * returned by {@code getBounds}, {@code getLocation}, + * {@code getLocationOnScreen}, and {@code getSize} might not * reflect the actual geometry of the Window on screen until the last * request has been processed. During the processing of subsequent * requests these values might change accordingly while the window @@ -340,7 +340,7 @@ public class Window extends Container implements Accessible { */ transient boolean isInShow = false; - /* + /** * The opacity level of the window * * @serial @@ -350,7 +350,7 @@ public class Window extends Container implements Accessible { */ private float opacity = 1.0f; - /* + /** * The shape assigned to this window. This field is set to {@code null} if * no shape is set (rectangular window). * @@ -415,21 +415,21 @@ public class Window extends Container implements Accessible { /** * Constructs a new, initially invisible window in default size with the - * specified GraphicsConfiguration. + * specified {@code GraphicsConfiguration}. *

* If there is a security manager, this method first calls - * the security manager's checkTopLevelWindow - * method with this + * the security manager's {@code checkTopLevelWindow} + * method with {@code this} * as its argument to determine whether or not the window * must be displayed with a warning banner. * - * @param gc the GraphicsConfiguration of the target screen - * device. If gc is null, the system default - * GraphicsConfiguration is assumed - * @exception IllegalArgumentException if gc + * @param gc the {@code GraphicsConfiguration} of the target screen + * device. If {@code gc} is {@code null}, the system default + * {@code GraphicsConfiguration} is assumed + * @exception IllegalArgumentException if {@code gc} * is not from a screen device * @exception HeadlessException when - * GraphicsEnvironment.isHeadless() returns true + * {@code GraphicsEnvironment.isHeadless()} returns {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless * @see java.lang.SecurityManager#checkTopLevelWindow @@ -513,20 +513,20 @@ public class Window extends Container implements Accessible { * Constructs a new, initially invisible window in the default size. * *

First, if there is a security manager, its - * checkTopLevelWindow - * method is called with this + * {@code checkTopLevelWindow} + * method is called with {@code this} * as its argument * to see if it's ok to display the window without a warning banner. - * If the default implementation of checkTopLevelWindow + * If the default implementation of {@code checkTopLevelWindow} * is used (that is, that method is not overriden), then this results in - * a call to the security manager's checkPermission method - * with an AWTPermission("showWindowWithoutWarningBanner") + * a call to the security manager's {@code checkPermission} method + * with an {@code AWTPermission("showWindowWithoutWarningBanner")} * permission. It that method raises a SecurityException, - * checkTopLevelWindow returns false, otherwise it + * {@code checkTopLevelWindow} returns false, otherwise it * returns true. If it returns false, a warning banner is created. * * @exception HeadlessException when - * GraphicsEnvironment.isHeadless() returns true + * {@code GraphicsEnvironment.isHeadless()} returns {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless * @see java.lang.SecurityManager#checkTopLevelWindow @@ -538,21 +538,21 @@ public class Window extends Container implements Accessible { /** * Constructs a new, initially invisible window with the specified - * Frame as its owner. The window will not be focusable + * {@code Frame} as its owner. The window will not be focusable * unless its owner is showing on the screen. *

* If there is a security manager, this method first calls - * the security manager's checkTopLevelWindow - * method with this + * the security manager's {@code checkTopLevelWindow} + * method with {@code this} * as its argument to determine whether or not the window * must be displayed with a warning banner. * - * @param owner the Frame to act as owner or null + * @param owner the {@code Frame} to act as owner or {@code null} * if this window has no owner - * @exception IllegalArgumentException if the owner's - * GraphicsConfiguration is not from a screen device + * @exception IllegalArgumentException if the {@code owner}'s + * {@code GraphicsConfiguration} is not from a screen device * @exception HeadlessException when - * GraphicsEnvironment.isHeadless returns true + * {@code GraphicsEnvironment.isHeadless} returns {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless * @see java.lang.SecurityManager#checkTopLevelWindow @@ -566,23 +566,23 @@ public class Window extends Container implements Accessible { /** * Constructs a new, initially invisible window with the specified - * Window as its owner. This window will not be focusable - * unless its nearest owning Frame or Dialog + * {@code Window} as its owner. This window will not be focusable + * unless its nearest owning {@code Frame} or {@code Dialog} * is showing on the screen. *

* If there is a security manager, this method first calls - * the security manager's checkTopLevelWindow - * method with this + * the security manager's {@code checkTopLevelWindow} + * method with {@code this} * as its argument to determine whether or not the window * must be displayed with a warning banner. * - * @param owner the Window to act as owner or - * null if this window has no owner - * @exception IllegalArgumentException if the owner's - * GraphicsConfiguration is not from a screen device + * @param owner the {@code Window} to act as owner or + * {@code null} if this window has no owner + * @exception IllegalArgumentException if the {@code owner}'s + * {@code GraphicsConfiguration} is not from a screen device * @exception HeadlessException when - * GraphicsEnvironment.isHeadless() returns - * true + * {@code GraphicsEnvironment.isHeadless()} returns + * {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless * @see java.lang.SecurityManager#checkTopLevelWindow @@ -598,27 +598,27 @@ public class Window extends Container implements Accessible { /** * Constructs a new, initially invisible window with the specified owner - * Window and a GraphicsConfiguration + * {@code Window} and a {@code GraphicsConfiguration} * of a screen device. The Window will not be focusable unless - * its nearest owning Frame or Dialog + * its nearest owning {@code Frame} or {@code Dialog} * is showing on the screen. *

* If there is a security manager, this method first calls - * the security manager's checkTopLevelWindow - * method with this + * the security manager's {@code checkTopLevelWindow} + * method with {@code this} * as its argument to determine whether or not the window * must be displayed with a warning banner. * - * @param owner the window to act as owner or null + * @param owner the window to act as owner or {@code null} * if this window has no owner - * @param gc the GraphicsConfiguration of the target - * screen device; if gc is null, - * the system default GraphicsConfiguration is assumed - * @exception IllegalArgumentException if gc + * @param gc the {@code GraphicsConfiguration} of the target + * screen device; if {@code gc} is {@code null}, + * the system default {@code GraphicsConfiguration} is assumed + * @exception IllegalArgumentException if {@code gc} * is not from a screen device * @exception HeadlessException when - * GraphicsEnvironment.isHeadless() returns - * true + * {@code GraphicsEnvironment.isHeadless()} returns + * {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless * @see java.lang.SecurityManager#checkTopLevelWindow @@ -936,7 +936,7 @@ public class Window extends Container implements Accessible { /** * @deprecated As of JDK version 1.1, - * replaced by setBounds(int, int, int, int). + * replaced by {@code setBounds(int, int, int, int)}. */ @Deprecated public void reshape(int x, int y, int width, int height) { @@ -1122,16 +1122,16 @@ public class Window extends Container implements Accessible { /** * Releases all of the native screen resources used by this - * Window, its subcomponents, and all of its owned - * children. That is, the resources for these Components + * {@code Window}, its subcomponents, and all of its owned + * children. That is, the resources for these {@code Component}s * will be destroyed, any memory they consume will be returned to the * OS, and they will be marked as undisplayable. *

- * The Window and its subcomponents can be made displayable + * The {@code Window} and its subcomponents can be made displayable * again by rebuilding the native resources with a subsequent call to - * pack or show. The states of the recreated - * Window and its subcomponents will be identical to the - * states of these objects at the point where the Window + * {@code pack} or {@code show}. The states of the recreated + * {@code Window} and its subcomponents will be identical to the + * states of these objects at the point where the {@code Window} * was disposed (not accounting for additional modifications between * those actions). *

@@ -1363,14 +1363,14 @@ public class Window extends Container implements Accessible { * If this window is insecure, the warning string is displayed * somewhere in the visible area of the window. A window is * insecure if there is a security manager, and the security - * manager's checkTopLevelWindow method returns - * false when this window is passed to it as an + * manager's {@code checkTopLevelWindow} method returns + * {@code false} when this window is passed to it as an * argument. *

- * If the window is secure, then getWarningString - * returns null. If the window is insecure, this + * If the window is secure, then {@code getWarningString} + * returns {@code null}. If the window is insecure, this * method checks for the system property - * awt.appletWarning + * {@code awt.appletWarning} * and returns the string value of that property. * @return the warning string for this window. * @see java.lang.SecurityManager#checkTopLevelWindow(java.lang.Object) @@ -1395,7 +1395,7 @@ public class Window extends Container implements Accessible { } /** - * Gets the Locale object that is associated + * Gets the {@code Locale} object that is associated * with this window, if the locale has been set. * If no locale has been set, then the default locale * is returned. @@ -1432,7 +1432,7 @@ public class Window extends Container implements Accessible { * implementation and/or the native system do not support * changing the mouse cursor shape. * @param cursor One of the constants defined - * by the Cursor class. If this parameter is null + * by the {@code Cursor} class. If this parameter is null * then the cursor for this window will be set to the type * Cursor.DEFAULT_CURSOR. * @see Component#getCursor @@ -1579,7 +1579,7 @@ public class Window extends Container implements Accessible { * Warning: this method may return system created windows, such * as a print dialog. Applications should not assume the existence of * these dialogs, nor should an application assume anything about these - * dialogs such as component positions, LayoutManagers + * dialogs such as component positions, {@code LayoutManager}s * or serialization. * * @see Frame#getFrames @@ -1601,7 +1601,7 @@ public class Window extends Container implements Accessible { * Warning: this method may return system created windows, such * as a print dialog. Applications should not assume the existence of * these dialogs, nor should an application assume anything about these - * dialogs such as component positions, LayoutManagers + * dialogs such as component positions, {@code LayoutManager}s * or serialization. * * @see Frame#getFrames @@ -1646,17 +1646,17 @@ public class Window extends Container implements Accessible { * java.awt.Dialog.ModalExclusionType Dialog.ModalExclusionType} for * possible modal exclusion types. *

- * If the given type is not supported, NO_EXCLUDE is used. + * If the given type is not supported, {@code NO_EXCLUDE} is used. *

* Note: changing the modal exclusion type for a visible window may have no * effect until it is hidden and then shown again. * - * @param exclusionType the modal exclusion type for this window; a null + * @param exclusionType the modal exclusion type for this window; a {@code null} * value is equivivalent to {@link Dialog.ModalExclusionType#NO_EXCLUDE * NO_EXCLUDE} * @throws SecurityException if the calling thread does not have permission * to set the modal exclusion property to the window with the given - * exclusionType + * {@code exclusionType} * @see java.awt.Dialog.ModalExclusionType * @see java.awt.Window#getModalExclusionType * @see java.awt.Toolkit#isModalExclusionTypeSupported @@ -1762,7 +1762,7 @@ public class Window extends Container implements Accessible { /** * Adds the specified window state listener to receive window - * events from this window. If l is null, + * events from this window. If {@code l} is {@code null}, * no exception is thrown and no action is performed. *

Refer to AWT Threading Issues for details on AWT's threading model. @@ -1821,7 +1821,7 @@ public class Window extends Container implements Accessible { /** * Removes the specified window state listener so that it no * longer receives window events from this window. If - * l is null, no exception is thrown and + * {@code l} is {@code null}, no exception is thrown and * no action is performed. *

Refer to AWT Threading Issues for details on AWT's threading model. @@ -1861,7 +1861,7 @@ public class Window extends Container implements Accessible { * Returns an array of all the window listeners * registered on this window. * - * @return all of this window's WindowListeners + * @return all of this window's {@code WindowListener}s * or an empty array if no window * listeners are currently registered * @@ -1877,7 +1877,7 @@ public class Window extends Container implements Accessible { * Returns an array of all the window focus listeners * registered on this window. * - * @return all of this window's WindowFocusListeners + * @return all of this window's {@code WindowFocusListener}s * or an empty array if no window focus * listeners are currently registered * @@ -1893,7 +1893,7 @@ public class Window extends Container implements Accessible { * Returns an array of all the window state listeners * registered on this window. * - * @return all of this window's WindowStateListeners + * @return all of this window's {@code WindowStateListener}s * or an empty array if no window state * listeners are currently registered * @@ -1909,17 +1909,17 @@ public class Window extends Container implements Accessible { /** * Returns an array of all the objects currently registered * as FooListeners - * upon this Window. + * upon this {@code Window}. * FooListeners are registered using the * addFooListener method. * *

* - * You can specify the listenerType argument + * You can specify the {@code listenerType} argument * with a class literal, such as * FooListener.class. * For example, you can query a - * Window w + * {@code Window} {@code w} * for its window listeners with the following code: * *

WindowListener[] wls = (WindowListener[])(w.getListeners(WindowListener.class));
@@ -1928,14 +1928,14 @@ public class Window extends Container implements Accessible { * * @param listenerType the type of listeners requested; this parameter * should specify an interface that descends from - * java.util.EventListener + * {@code java.util.EventListener} * @return an array of all objects registered as * FooListeners on this window, * or an empty array if no such * listeners have been added - * @exception ClassCastException if listenerType + * @exception ClassCastException if {@code listenerType} * doesn't specify a class or interface that implements - * java.util.EventListener + * {@code java.util.EventListener} * @exception NullPointerException if {@code listenerType} is {@code null} * * @see #getWindowListeners @@ -1991,10 +1991,10 @@ public class Window extends Container implements Accessible { /** * Processes events on this window. If the event is an - * WindowEvent, it invokes the - * processWindowEvent method, else it invokes its - * superclass's processEvent. - *

Note that if the event parameter is null + * {@code WindowEvent}, it invokes the + * {@code processWindowEvent} method, else it invokes its + * superclass's {@code processEvent}. + *

Note that if the event parameter is {@code null} * the behavior is unspecified and may result in an * exception. * @@ -2033,10 +2033,10 @@ public class Window extends Container implements Accessible { * following occurs: *

    *
  • A WindowListener object is registered via - * addWindowListener - *
  • Window events are enabled via enableEvents + * {@code addWindowListener} + *
  • Window events are enabled via {@code enableEvents} *
- *

Note that if the event parameter is null + *

Note that if the event parameter is {@code null} * the behavior is unspecified and may result in an * exception. * @@ -2082,10 +2082,10 @@ public class Window extends Container implements Accessible { * following occurs: *

    *
  • a WindowFocusListener is registered via - * addWindowFocusListener - *
  • Window focus events are enabled via enableEvents + * {@code addWindowFocusListener} + *
  • Window focus events are enabled via {@code enableEvents} *
- *

Note that if the event parameter is null + *

Note that if the event parameter is {@code null} * the behavior is unspecified and may result in an * exception. * @@ -2111,17 +2111,17 @@ public class Window extends Container implements Accessible { /** * Processes window state event occuring on this window by - * dispatching them to any registered WindowStateListener + * dispatching them to any registered {@code WindowStateListener} * objects. * NOTE: this method will not be called unless window state events * are enabled for this window. This happens when one of the * following occurs: *

    - *
  • a WindowStateListener is registered via - * addWindowStateListener - *
  • window state events are enabled via enableEvents + *
  • a {@code WindowStateListener} is registered via + * {@code addWindowStateListener} + *
  • window state events are enabled via {@code enableEvents} *
- *

Note that if the event parameter is null + *

Note that if the event parameter is {@code null} * the behavior is unspecified and may result in an * exception. * @@ -2145,7 +2145,7 @@ public class Window extends Container implements Accessible { /** * Implements a debugging hook -- checks to see if * the user has typed control-shift-F1. If so, - * the list of child windows is dumped to System.out. + * the list of child windows is dumped to {@code System.out}. * @param e the keyboard event */ void preProcessKeyEvent(KeyEvent e) { @@ -2176,21 +2176,21 @@ public class Window extends Container implements Accessible { * automatically become always-on-top. If a window ceases to be * always-on-top, the windows that it owns will no longer be * always-on-top. When an always-on-top window is sent {@link #toBack - * toBack}, its always-on-top state is set to false. + * toBack}, its always-on-top state is set to {@code false}. * *

When this method is called on a window with a value of - * true, and the window is visible and the platform + * {@code true}, and the window is visible and the platform * supports always-on-top for this window, the window is immediately * brought forward, "sticking" it in the top-most position. If the * window isn`t currently visible, this method sets the always-on-top - * state to true but does not bring the window forward. + * state to {@code true} but does not bring the window forward. * When the window is later shown, it will be always-on-top. * *

When this method is called on a window with a value of - * false the always-on-top state is set to normal. The + * {@code false} the always-on-top state is set to normal. The * window remains in the top-most position but it`s z-order can be * changed as for any other window. Calling this method with a value - * of false on a window that has a normal state has no + * of {@code false} on a window that has a normal state has no * effect. Setting the always-on-top state to false has no effect on * the relative z-order of the windows if there are no other * always-on-top windows. @@ -2250,9 +2250,9 @@ public class Window extends Container implements Accessible { * window. Some platforms may not support always-on-top windows, some * may support only some kinds of top-level windows; for example, * a platform may not support always-on-top modal dialogs. - * @return true, if the always-on-top mode is + * @return {@code true}, if the always-on-top mode is * supported by the toolkit and for this window, - * false, if always-on-top mode is not supported + * {@code false}, if always-on-top mode is not supported * for this window or toolkit doesn't support always-on-top windows. * @see #setAlwaysOnTop(boolean) * @see Toolkit#isAlwaysOnTopSupported @@ -2265,8 +2265,8 @@ public class Window extends Container implements Accessible { /** * Returns whether this window is an always-on-top window. - * @return true, if the window is in always-on-top state, - * false otherwise + * @return {@code true}, if the window is in always-on-top state, + * {@code false} otherwise * @see #setAlwaysOnTop * @since 1.5 */ @@ -2294,7 +2294,7 @@ public class Window extends Container implements Accessible { /** * Returns the child Component of this Window that will receive the focus * when this Window is focused. If this Window is currently focused, this - * method returns the same Component as getFocusOwner(). If + * method returns the same Component as {@code getFocusOwner()}. If * this Window is not focused, then the child Component that most recently * requested focus will be returned. If no child Component has ever * requested focus, and this is a focusable Window, then this Window's @@ -2359,8 +2359,8 @@ public class Window extends Container implements Accessible { } /** - * Gets a focus traversal key for this Window. (See - * setFocusTraversalKeys for a full description of each key.) + * Gets a focus traversal key for this Window. (See {@code + * setFocusTraversalKeys} for a full description of each key.) *

* If the traversal key has not been explicitly set for this Window, * then this Window's parent's traversal key is returned. If the @@ -2419,10 +2419,10 @@ public class Window extends Container implements Accessible { } /** - * Always returns true because all Windows must be roots of a + * Always returns {@code true} because all Windows must be roots of a * focus traversal cycle. * - * @return true + * @return {@code true} * @see #setFocusCycleRoot * @see Container#setFocusTraversalPolicy * @see Container#getFocusTraversalPolicy @@ -2433,10 +2433,10 @@ public class Window extends Container implements Accessible { } /** - * Always returns null because Windows have no ancestors; they + * Always returns {@code null} because Windows have no ancestors; they * represent the top of the Component hierarchy. * - * @return null + * @return {@code null} * @see Container#isFocusCycleRoot() * @since 1.4 */ @@ -2448,16 +2448,16 @@ public class Window extends Container implements Accessible { * Returns whether this Window can become the focused Window, that is, * whether this Window or any of its subcomponents can become the focus * owner. For a Frame or Dialog to be focusable, its focusable Window state - * must be set to true. For a Window which is not a Frame or + * must be set to {@code true}. For a Window which is not a Frame or * Dialog to be focusable, its focusable Window state must be set to - * true, its nearest owning Frame or Dialog must be + * {@code true}, its nearest owning Frame or Dialog must be * showing on the screen, and it must contain at least one Component in * its focus traversal cycle. If any of these conditions is not met, then * neither this Window nor any of its subcomponents can become the focus * owner. * - * @return true if this Window can be the focused Window; - * false otherwise + * @return {@code true} if this Window can be the focused Window; + * {@code false} otherwise * @see #getFocusableWindowState * @see #setFocusableWindowState * @see #isShowing @@ -2497,16 +2497,16 @@ public class Window extends Container implements Accessible { /** * Returns whether this Window can become the focused Window if it meets - * the other requirements outlined in isFocusableWindow. If - * this method returns false, then - * isFocusableWindow will return false as well. - * If this method returns true, then - * isFocusableWindow may return true or - * false depending upon the other requirements which must be + * the other requirements outlined in {@code isFocusableWindow}. If + * this method returns {@code false}, then + * {@code isFocusableWindow} will return {@code false} as well. + * If this method returns {@code true}, then + * {@code isFocusableWindow} may return {@code true} or + * {@code false} depending upon the other requirements which must be * met in order for a Window to be focusable. *

* By default, all Windows have a focusable Window state of - * true. + * {@code true}. * * @return whether this Window can be the focused Window * @see #isFocusableWindow @@ -2521,25 +2521,25 @@ public class Window extends Container implements Accessible { /** * Sets whether this Window can become the focused Window if it meets - * the other requirements outlined in isFocusableWindow. If - * this Window's focusable Window state is set to false, then - * isFocusableWindow will return false. If this - * Window's focusable Window state is set to true, then - * isFocusableWindow may return true or - * false depending upon the other requirements which must be + * the other requirements outlined in {@code isFocusableWindow}. If + * this Window's focusable Window state is set to {@code false}, then + * {@code isFocusableWindow} will return {@code false}. If this + * Window's focusable Window state is set to {@code true}, then + * {@code isFocusableWindow} may return {@code true} or + * {@code false} depending upon the other requirements which must be * met in order for a Window to be focusable. *

- * Setting a Window's focusability state to false is the + * Setting a Window's focusability state to {@code false} is the * standard mechanism for an application to identify to the AWT a Window * which will be used as a floating palette or toolbar, and thus should be * a non-focusable Window. * - * Setting the focusability state on a visible Window + * Setting the focusability state on a visible {@code Window} * can have a delayed effect on some platforms — the actual - * change may happen only when the Window becomes + * change may happen only when the {@code Window} becomes * hidden and then visible again. To ensure consistent behavior - * across platforms, set the Window's focusable state - * when the Window is invisible and then show it. + * across platforms, set the {@code Window}'s focusable state + * when the {@code Window} is invisible and then show it. * * @param focusableWindowState whether this Window can be the focused * Window @@ -2726,7 +2726,7 @@ public class Window extends Container implements Accessible { /** * @deprecated As of JDK version 1.1 - * replaced by dispatchEvent(AWTEvent). + * replaced by {@code dispatchEvent(AWTEvent)}. */ @Deprecated public boolean postEvent(Event e) { @@ -2876,22 +2876,22 @@ public class Window extends Container implements Accessible { /** * Writes default serializable fields to stream. Writes - * a list of serializable WindowListeners and - * WindowFocusListeners as optional data. + * a list of serializable {@code WindowListener}s and + * {@code WindowFocusListener}s as optional data. * Writes a list of child windows as optional data. * Writes a list of icon images as optional data * - * @param s the ObjectOutputStream to write - * @serialData null terminated sequence of - * 0 or more pairs; the pair consists of a String - * and and Object; the String + * @param s the {@code ObjectOutputStream} to write + * @serialData {@code null} terminated sequence of + * 0 or more pairs; the pair consists of a {@code String} + * and {@code Object}; the {@code String} * indicates the type of object and is one of the following: - * windowListenerK indicating a - * WindowListener object; - * windowFocusWindowK indicating a - * WindowFocusListener object; - * ownedWindowK indicating a child - * Window object + * {@code windowListenerK} indicating a + * {@code WindowListener} object; + * {@code windowFocusWindowK} indicating a + * {@code WindowFocusListener} object; + * {@code ownedWindowK} indicating a child + * {@code Window} object * * @see AWTEventMulticaster#save(java.io.ObjectOutputStream, java.lang.String, java.util.EventListener) * @see Component#windowListenerK @@ -3029,16 +3029,16 @@ public class Window extends Container implements Accessible { } /** - * Reads the ObjectInputStream and an optional + * Reads the {@code ObjectInputStream} and an optional * list of listeners to receive various events fired by * the component; also reads a list of - * (possibly null) child windows. + * (possibly {@code null}) child windows. * Unrecognized keys or values will be ignored. * - * @param s the ObjectInputStream to read + * @param s the {@code ObjectInputStream} to read * @exception HeadlessException if - * GraphicsEnvironment.isHeadless returns - * true + * {@code GraphicsEnvironment.isHeadless} returns + * {@code true} * @see java.awt.GraphicsEnvironment#isHeadless * @see #writeObject */ @@ -3100,7 +3100,7 @@ public class Window extends Container implements Accessible { /** * This class implements accessibility support for the - * Window class. It provides an implementation of the + * {@code Window} class. It provides an implementation of the * Java Accessibility API appropriate to window user-interface elements. * @since 1.3 */ @@ -3186,7 +3186,7 @@ public class Window extends Container implements Accessible { * not changed. *

* Note: If the lower edge of the window is out of the screen, - * then the window is placed to the side of the Component + * then the window is placed to the side of the {@code Component} * that is closest to the center of the screen. So if the * component is on the right part of the screen, the window * is placed to its left, and vice versa. @@ -3289,7 +3289,7 @@ public class Window extends Container implements Accessible { * Creates a new strategy for multi-buffering on this component. * Multi-buffering is useful for rendering performance. This method * attempts to create the best strategy available with the number of - * buffers supplied. It will always create a BufferStrategy + * buffers supplied. It will always create a {@code BufferStrategy} * with that number of buffers. * A page-flipping strategy is attempted first, then a blitting strategy * using accelerated buffers. Finally, an unaccelerated blitting @@ -3318,13 +3318,13 @@ public class Window extends Container implements Accessible { * is called, the existing buffer strategy for this component is discarded. * @param numBuffers number of buffers to create, including the front buffer * @param caps the required capabilities for creating the buffer strategy; - * cannot be null + * cannot be {@code null} * @exception AWTException if the capabilities supplied could not be * supported or met; this may happen, for example, if there is not enough * accelerated memory currently available, or if page flipping is specified * but not possible. * @exception IllegalArgumentException if numBuffers is less than 1, or if - * caps is null + * caps is {@code null} * @see #getBufferStrategy * @since 1.4 */ @@ -3334,8 +3334,8 @@ public class Window extends Container implements Accessible { } /** - * Returns the BufferStrategy used by this component. This - * method will return null if a BufferStrategy has not yet + * Returns the {@code BufferStrategy} used by this component. This + * method will return null if a {@code BufferStrategy} has not yet * been created or has been disposed. * * @return the buffer strategy used by this component @@ -3376,7 +3376,7 @@ public class Window extends Container implements Accessible { /** * Sets whether this Window should appear at the default location for the * native windowing system or at the current location (returned by - * getLocation) the next time the Window is made visible. + * {@code getLocation}) the next time the Window is made visible. * This behavior resembles a native window shown without programmatically * setting its location. Most windowing systems cascade windows if their * locations are not explicitly set. The actual location is determined once the @@ -3386,8 +3386,8 @@ public class Window extends Container implements Accessible { * "java.awt.Window.locationByPlatform" to "true", though calls to this method * take precedence. *

- * Calls to setVisible, setLocation and - * setBounds after calling setLocationByPlatform clear + * Calls to {@code setVisible}, {@code setLocation} and + * {@code setBounds} after calling {@code setLocationByPlatform} clear * this property of the Window. *

* For example, after the following code is executed: @@ -3397,7 +3397,7 @@ public class Window extends Container implements Accessible { * boolean flag = isLocationByPlatform(); *

* The window will be shown at platform's default location and - * flag will be false. + * {@code flag} will be {@code false}. *

* In the following sample: *

@@ -3406,13 +3406,13 @@ public class Window extends Container implements Accessible { * boolean flag = isLocationByPlatform(); * setVisible(true); *
- * The window will be shown at (10, 10) and flag will be - * false. + * The window will be shown at (10, 10) and {@code flag} will be + * {@code false}. * - * @param locationByPlatform true if this Window should appear - * at the default location, false if at the current location - * @throws IllegalComponentStateException if the window - * is showing on screen and locationByPlatform is true. + * @param locationByPlatform {@code true} if this Window should appear + * at the default location, {@code false} if at the current location + * @throws {@code IllegalComponentStateException} if the window + * is showing on screen and locationByPlatform is {@code true}. * @see #setLocation * @see #isShowing * @see #setVisible @@ -3430,9 +3430,9 @@ public class Window extends Container implements Accessible { } /** - * Returns true if this Window will appear at the default location + * Returns {@code true} if this Window will appear at the default location * for the native windowing system the next time this Window is made visible. - * This method always returns false if the Window is showing on the + * This method always returns {@code false} if the Window is showing on the * screen. * * @return whether this Window will appear at the default location @@ -3509,8 +3509,8 @@ public class Window extends Container implements Accessible { /** * Determines whether this component will be displayed on the screen. - * @return true if the component and all of its ancestors - * until a toplevel window are visible, false otherwise + * @return {@code true} if the component and all of its ancestors + * until a toplevel window are visible, {@code false} otherwise */ boolean isRecursivelyVisible() { // 5079694 fix: for a toplevel to be displayed, its parent doesn't have to be visible. From b42a7171ab3619d7ced4c80caeccf14eca13ea3e Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Tue, 13 Aug 2013 18:16:19 +0200 Subject: [PATCH 030/102] 8020598: ObjectCountEventSender::send needs INCLUDE_TRACE guards when building OpenJDK with INCLUDE_TRACE=0 Reviewed-by: stefank, brutisso, sjohanss --- .../vm/gc_implementation/shared/objectCountEventSender.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hotspot/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp b/hotspot/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp index cf95bdd505e..289c458d2dc 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp @@ -32,6 +32,7 @@ #if INCLUDE_SERVICES void ObjectCountEventSender::send(const KlassInfoEntry* entry, GCId gc_id, jlong timestamp) { +#if INCLUDE_TRACE assert(Tracing::is_event_enabled(EventObjectCountAfterGC::eventId), "Only call this method if the event is enabled"); @@ -42,6 +43,7 @@ void ObjectCountEventSender::send(const KlassInfoEntry* entry, GCId gc_id, jlong event.set_totalSize(entry->words() * BytesPerWord); event.set_endtime(timestamp); event.commit(); +#endif // INCLUDE_TRACE } bool ObjectCountEventSender::should_send_event() { From 19ba4665752d33294444f7622410e3006866f308 Mon Sep 17 00:00:00 2001 From: Bengt Rutisson Date: Wed, 14 Aug 2013 09:02:32 +0200 Subject: [PATCH 031/102] 8022800: Use specific generations rather than generation iteration Reviewed-by: jmasa, ehelin --- .../parNew/parNewGeneration.cpp | 4 +-- hotspot/src/share/vm/memory/cardTableRS.cpp | 34 +++++++------------ hotspot/src/share/vm/memory/cardTableRS.hpp | 2 +- .../src/share/vm/memory/defNewGeneration.cpp | 4 --- .../src/share/vm/memory/genCollectedHeap.cpp | 31 +++++------------ .../src/share/vm/memory/genCollectedHeap.hpp | 24 ++++++------- hotspot/src/share/vm/memory/genMarkSweep.cpp | 15 +++----- hotspot/src/share/vm/memory/genRemSet.hpp | 7 ++-- 8 files changed, 41 insertions(+), 80 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp index c104533a47b..a1eb3130bc6 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp @@ -927,11 +927,9 @@ void ParNewGeneration::collect(bool full, workers->active_workers(), Threads::number_of_non_daemon_threads()); workers->set_active_workers(active_workers); - _next_gen = gch->next_gen(this); - assert(_next_gen != NULL, - "This must be the youngest gen, and not the only gen"); assert(gch->n_gens() == 2, "Par collection currently only works with single older gen."); + _next_gen = gch->next_gen(this); // Do we have to avoid promotion_undo? if (gch->collector_policy()->is_concurrent_mark_sweep_policy()) { set_avoid_promotion_undo(true); diff --git a/hotspot/src/share/vm/memory/cardTableRS.cpp b/hotspot/src/share/vm/memory/cardTableRS.cpp index 7c21869945b..502310cebeb 100644 --- a/hotspot/src/share/vm/memory/cardTableRS.cpp +++ b/hotspot/src/share/vm/memory/cardTableRS.cpp @@ -321,35 +321,25 @@ void CardTableRS::clear_into_younger(Generation* gen) { // below to avoid missing cards at the fringes. If clear() or // invalidate() are changed in the future, this code should // be revisited. 20040107.ysr - Generation* g = gen; - for(Generation* prev_gen = gch->prev_gen(g); - prev_gen != NULL; - g = prev_gen, prev_gen = gch->prev_gen(g)) { - MemRegion to_be_cleared_mr = g->prev_used_region(); - clear(to_be_cleared_mr); - } + Generation* old_gen = gen; + clear(old_gen->prev_used_region()); + Generation* young_gen = gch->prev_gen(old_gen); + clear(young_gen->prev_used_region()); } -void CardTableRS::invalidate_or_clear(Generation* gen, bool younger) { - GenCollectedHeap* gch = GenCollectedHeap::heap(); - // For each generation gen (and younger) - // invalidate the cards for the currently occupied part - // of that generation and clear the cards for the +void CardTableRS::invalidate_or_clear(Generation* gen) { + // For generation gen invalidate the cards for the currently + // occupied part of that generation and clear the cards for the // unoccupied part of the generation (if any, making use // of that generation's prev_used_region to determine that // region). No need to do anything for the youngest // generation. Also see note#20040107.ysr above. - Generation* g = gen; - for(Generation* prev_gen = gch->prev_gen(g); prev_gen != NULL; - g = prev_gen, prev_gen = gch->prev_gen(g)) { - MemRegion used_mr = g->used_region(); - MemRegion to_be_cleared_mr = g->prev_used_region().minus(used_mr); - if (!to_be_cleared_mr.is_empty()) { - clear(to_be_cleared_mr); - } - invalidate(used_mr); - if (!younger) break; + MemRegion used_mr = gen->used_region(); + MemRegion to_be_cleared_mr = gen->prev_used_region().minus(used_mr); + if (!to_be_cleared_mr.is_empty()) { + clear(to_be_cleared_mr); } + invalidate(used_mr); } diff --git a/hotspot/src/share/vm/memory/cardTableRS.hpp b/hotspot/src/share/vm/memory/cardTableRS.hpp index 234b3972db5..41e92871c0e 100644 --- a/hotspot/src/share/vm/memory/cardTableRS.hpp +++ b/hotspot/src/share/vm/memory/cardTableRS.hpp @@ -147,7 +147,7 @@ public: void invalidate(MemRegion mr, bool whole_heap = false) { _ct_bs->invalidate(mr, whole_heap); } - void invalidate_or_clear(Generation* gen, bool younger); + void invalidate_or_clear(Generation* gen); static uintx ct_max_alignment_constraint() { return CardTableModRefBS::ct_max_alignment_constraint(); diff --git a/hotspot/src/share/vm/memory/defNewGeneration.cpp b/hotspot/src/share/vm/memory/defNewGeneration.cpp index c61fa0127bc..0b4af29a3e3 100644 --- a/hotspot/src/share/vm/memory/defNewGeneration.cpp +++ b/hotspot/src/share/vm/memory/defNewGeneration.cpp @@ -567,8 +567,6 @@ void DefNewGeneration::collect(bool full, gc_tracer.report_gc_start(gch->gc_cause(), _gc_timer->gc_start()); _next_gen = gch->next_gen(this); - assert(_next_gen != NULL, - "This must be the youngest gen, and not the only gen"); // If the next generation is too full to accommodate promotion // from this generation, pass on collection; let the next generation @@ -901,8 +899,6 @@ bool DefNewGeneration::collection_attempt_is_safe() { if (_next_gen == NULL) { GenCollectedHeap* gch = GenCollectedHeap::heap(); _next_gen = gch->next_gen(this); - assert(_next_gen != NULL, - "This must be the youngest gen, and not the only gen"); } return _next_gen->promotion_attempt_is_safe(used()); } diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.cpp b/hotspot/src/share/vm/memory/genCollectedHeap.cpp index ebdb77f6734..2faed4cc818 100644 --- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp +++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp @@ -1070,13 +1070,13 @@ GenCollectedHeap* GenCollectedHeap::heap() { void GenCollectedHeap::prepare_for_compaction() { - Generation* scanning_gen = _gens[_n_gens-1]; + guarantee(_n_gens = 2, "Wrong number of generations"); + Generation* old_gen = _gens[1]; // Start by compacting into same gen. - CompactPoint cp(scanning_gen, NULL, NULL); - while (scanning_gen != NULL) { - scanning_gen->prepare_for_compaction(&cp); - scanning_gen = prev_gen(scanning_gen); - } + CompactPoint cp(old_gen, NULL, NULL); + old_gen->prepare_for_compaction(&cp); + Generation* young_gen = _gens[0]; + young_gen->prepare_for_compaction(&cp); } GCStats* GenCollectedHeap::gc_stats(int level) const { @@ -1245,27 +1245,14 @@ void GenCollectedHeap::ensure_parsability(bool retire_tlabs) { generation_iterate(&ep_cl, false); } -oop GenCollectedHeap::handle_failed_promotion(Generation* gen, +oop GenCollectedHeap::handle_failed_promotion(Generation* old_gen, oop obj, size_t obj_size) { + guarantee(old_gen->level() == 1, "We only get here with an old generation"); assert(obj_size == (size_t)obj->size(), "bad obj_size passed in"); HeapWord* result = NULL; - // First give each higher generation a chance to allocate the promoted object. - Generation* allocator = next_gen(gen); - if (allocator != NULL) { - do { - result = allocator->allocate(obj_size, false); - } while (result == NULL && (allocator = next_gen(allocator)) != NULL); - } - - if (result == NULL) { - // Then give gen and higher generations a chance to expand and allocate the - // object. - do { - result = gen->expand_and_allocate(obj_size, false); - } while (result == NULL && (gen = next_gen(gen)) != NULL); - } + result = old_gen->expand_and_allocate(obj_size, false); if (result != NULL) { Copy::aligned_disjoint_words((HeapWord*)obj, result, obj_size); diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.hpp b/hotspot/src/share/vm/memory/genCollectedHeap.hpp index 43338c4da46..9ab9d1991df 100644 --- a/hotspot/src/share/vm/memory/genCollectedHeap.hpp +++ b/hotspot/src/share/vm/memory/genCollectedHeap.hpp @@ -368,25 +368,23 @@ public: // collection. virtual bool is_maximal_no_gc() const; - // Return the generation before "gen", or else NULL. + // Return the generation before "gen". Generation* prev_gen(Generation* gen) const { int l = gen->level(); - if (l == 0) return NULL; - else return _gens[l-1]; + guarantee(l > 0, "Out of bounds"); + return _gens[l-1]; } - // Return the generation after "gen", or else NULL. + // Return the generation after "gen". Generation* next_gen(Generation* gen) const { int l = gen->level() + 1; - if (l == _n_gens) return NULL; - else return _gens[l]; + guarantee(l < _n_gens, "Out of bounds"); + return _gens[l]; } Generation* get_gen(int i) const { - if (i >= 0 && i < _n_gens) - return _gens[i]; - else - return NULL; + guarantee(i >= 0 && i < _n_gens, "Out of bounds"); + return _gens[i]; } int n_gens() const { @@ -485,9 +483,9 @@ public: // Promotion of obj into gen failed. Try to promote obj to higher // gens in ascending order; return the new location of obj if successful. - // Otherwise, try expand-and-allocate for obj in each generation starting at - // gen; return the new location of obj if successful. Otherwise, return NULL. - oop handle_failed_promotion(Generation* gen, + // Otherwise, try expand-and-allocate for obj in both the young and old + // generation; return the new location of obj if successful. Otherwise, return NULL. + oop handle_failed_promotion(Generation* old_gen, oop obj, size_t obj_size); diff --git a/hotspot/src/share/vm/memory/genMarkSweep.cpp b/hotspot/src/share/vm/memory/genMarkSweep.cpp index e53e742be70..88afa607971 100644 --- a/hotspot/src/share/vm/memory/genMarkSweep.cpp +++ b/hotspot/src/share/vm/memory/genMarkSweep.cpp @@ -52,8 +52,8 @@ #include "utilities/copy.hpp" #include "utilities/events.hpp" -void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp, - bool clear_all_softrefs) { +void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp, bool clear_all_softrefs) { + guarantee(level == 1, "We always collect both old and young."); assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint"); GenCollectedHeap* gch = GenCollectedHeap::heap(); @@ -84,11 +84,6 @@ void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp, // Capture heap size before collection for printing. size_t gch_prev_used = gch->used(); - // Some of the card table updates below assume that the perm gen is - // also being collected. - assert(level == gch->n_gens() - 1, - "All generations are being collected, ergo perm gen too."); - // Capture used regions for each generation that will be // subject to collection, so that card table adjustments can // be made intelligently (see clear / invalidate further below). @@ -134,9 +129,9 @@ void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp, } else { // Invalidate the cards corresponding to the currently used // region and clear those corresponding to the evacuated region - // of all generations just collected (i.e. level and younger). - rs->invalidate_or_clear(gch->get_gen(level), - true /* younger */); + // of all generations just collected. + rs->invalidate_or_clear(gch->get_gen(1)); + rs->invalidate_or_clear(gch->get_gen(0)); } Threads::gc_epilogue(); diff --git a/hotspot/src/share/vm/memory/genRemSet.hpp b/hotspot/src/share/vm/memory/genRemSet.hpp index e6b8302ad89..f5f73553595 100644 --- a/hotspot/src/share/vm/memory/genRemSet.hpp +++ b/hotspot/src/share/vm/memory/genRemSet.hpp @@ -146,11 +146,8 @@ public: // Informs the RS that refs in this generation // may have changed arbitrarily, and therefore may contain - // old-to-young pointers in arbitrary locations. The parameter - // younger indicates if the same should be done for younger generations - // as well. The parameter perm indicates if the same should be done for - // perm gen as well. - virtual void invalidate_or_clear(Generation* gen, bool younger) = 0; + // old-to-young pointers in arbitrary locations. + virtual void invalidate_or_clear(Generation* gen) = 0; }; #endif // SHARE_VM_MEMORY_GENREMSET_HPP From dab6bdc071bfd47a7cb71809107427509fdcb746 Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Wed, 14 Aug 2013 13:49:36 +0200 Subject: [PATCH 032/102] 8022899: SunStudio compiler can not handle EXCEPTION_MARK and inlining Reviewed-by: coleenp, mgerdin --- hotspot/src/share/vm/utilities/exceptions.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/utilities/exceptions.hpp b/hotspot/src/share/vm/utilities/exceptions.hpp index 32c6f35d8a5..beaabf8dcf7 100644 --- a/hotspot/src/share/vm/utilities/exceptions.hpp +++ b/hotspot/src/share/vm/utilities/exceptions.hpp @@ -306,6 +306,6 @@ class ExceptionMark { // which preserves pre-existing exceptions and does not allow new // exceptions. -#define EXCEPTION_MARK Thread* THREAD; ExceptionMark __em(THREAD); +#define EXCEPTION_MARK Thread* THREAD = NULL; ExceptionMark __em(THREAD); #endif // SHARE_VM_UTILITIES_EXCEPTIONS_HPP From 6a28f9e6fbad58ca8c07e19a30881001f21e98f3 Mon Sep 17 00:00:00 2001 From: Petr Pchelko Date: Wed, 14 Aug 2013 16:17:28 +0400 Subject: [PATCH 033/102] 8013454: [parfait] Memory leak in jdk/src/windows/native/sun/windows/awt_Cursor.cpp 8012079: [parfait] possible null pointer dereference in jdk/src/windows/native/sun/windows/awt_Font.cpp Reviewed-by: art, serb --- jdk/src/windows/native/sun/windows/awt_Cursor.cpp | 13 ++++++++++--- jdk/src/windows/native/sun/windows/awt_Font.cpp | 5 +++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/jdk/src/windows/native/sun/windows/awt_Cursor.cpp b/jdk/src/windows/native/sun/windows/awt_Cursor.cpp index 477fe80ee93..7901601167f 100644 --- a/jdk/src/windows/native/sun/windows/awt_Cursor.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Cursor.cpp @@ -391,9 +391,16 @@ Java_sun_awt_windows_WCustomCursor_createCursorIndirect( DASSERT(hCursor); - AwtCursor::setPData(self, ptr_to_jlong(new AwtCursor(env, hCursor, self, xHotSpot, - yHotSpot, nW, nH, nSS, cols, - (BYTE *)andMaskPtr))); + try { + AwtCursor::setPData(self, ptr_to_jlong(new AwtCursor(env, hCursor, self, xHotSpot, + yHotSpot, nW, nH, nSS, cols, + (BYTE *)andMaskPtr))); + } catch (...) { + if (cols) { + delete[] cols; + } + throw; + } CATCH_BAD_ALLOC; } diff --git a/jdk/src/windows/native/sun/windows/awt_Font.cpp b/jdk/src/windows/native/sun/windows/awt_Font.cpp index 185514c1972..d0d31ff0d07 100644 --- a/jdk/src/windows/native/sun/windows/awt_Font.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Font.cpp @@ -510,6 +510,11 @@ void AwtFont::LoadMetrics(JNIEnv *env, jobject fontMetrics) jobject font = env->GetObjectField(fontMetrics, AwtFont::fontID); AwtFont* awtFont = AwtFont::GetFont(env, font); + if (!awtFont) { + /* failed to get font */ + return; + } + HDC hDC = ::GetDC(0); DASSERT(hDC != NULL); From f996af21159f3dfdd4037ce74db56a91343c7277 Mon Sep 17 00:00:00 2001 From: Petr Pchelko Date: Wed, 14 Aug 2013 17:20:09 +0400 Subject: [PATCH 034/102] 7173464: Clipboard.getAvailableDataFlavors: Comparison method violates contract Reviewed-by: anthony, art, serb --- .../datatransfer/ClipboardTransferable.java | 3 +- .../sun/awt/datatransfer/DataTransferer.java | 52 ++----------------- .../DataFlavorComparatorTest.java | 47 +++++++++++++++++ 3 files changed, 52 insertions(+), 50 deletions(-) create mode 100644 jdk/test/sun/awt/datatransfer/DataFlavorComparatorTest.java diff --git a/jdk/src/share/classes/sun/awt/datatransfer/ClipboardTransferable.java b/jdk/src/share/classes/sun/awt/datatransfer/ClipboardTransferable.java index d766e989a8a..9439ec569b4 100644 --- a/jdk/src/share/classes/sun/awt/datatransfer/ClipboardTransferable.java +++ b/jdk/src/share/classes/sun/awt/datatransfer/ClipboardTransferable.java @@ -98,8 +98,7 @@ public class ClipboardTransferable implements Transferable { } flavors = DataTransferer.getInstance(). - setToSortedDataFlavorArray(flavorsToData.keySet(), - flavorsForFormats); + setToSortedDataFlavorArray(flavorsToData.keySet()); } } finally { clipboard.closeClipboard(); diff --git a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java index 0011e120e10..83a73dbd51c 100644 --- a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java +++ b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java @@ -2405,15 +2405,6 @@ search: return retval; } - /** - * Helper function to reduce a Map with DataFlavor keys to a DataFlavor - * array. The array will be sorted according to - * DataFlavorComparator. - */ - public static DataFlavor[] keysToDataFlavorArray(Map map) { - return setToSortedDataFlavorArray(map.keySet(), map); - } - /** * Helper function to convert a Set of DataFlavors to a sorted array. * The array will be sorted according to DataFlavorComparator. @@ -2427,24 +2418,6 @@ search: return flavors; } - /** - * Helper function to convert a Set of DataFlavors to a sorted array. - * The array will be sorted according to a - * DataFlavorComparator created with the specified - * flavor-to-native map as an argument. - */ - public static DataFlavor[] setToSortedDataFlavorArray - (Set flavorsSet, Map flavorToNativeMap) - { - DataFlavor[] flavors = new DataFlavor[flavorsSet.size()]; - flavorsSet.toArray(flavors); - Comparator comparator = - new DataFlavorComparator(flavorToNativeMap, - IndexedComparator.SELECT_WORST); - Arrays.sort(flavors, comparator); - return flavors; - } - /** * Helper function to convert an InputStream to a byte[] array. */ @@ -2724,11 +2697,9 @@ search: * application/x-java-* MIME types. Unknown application types are preferred * because if the user provides his own data flavor, it will likely be the * most descriptive one. For flavors which are otherwise equal, the - * flavors' native formats are compared, with greater long values - * taking precedence. + * flavors' string representation are compared in the alphabetical order. */ public static class DataFlavorComparator extends IndexedComparator { - protected final Map flavorToFormatMap; private final CharsetComparator charsetComparator; @@ -2864,20 +2835,6 @@ search: super(order); charsetComparator = new CharsetComparator(order); - flavorToFormatMap = Collections.EMPTY_MAP; - } - - public DataFlavorComparator(Map map) { - this(map, SELECT_BEST); - } - - public DataFlavorComparator(Map map, boolean order) { - super(order); - - charsetComparator = new CharsetComparator(order); - HashMap hashMap = new HashMap(map.size()); - hashMap.putAll(map); - flavorToFormatMap = Collections.unmodifiableMap(hashMap); } public int compare(Object obj1, Object obj2) { @@ -2973,10 +2930,9 @@ search: } } - // As a last resort, take the DataFlavor with the greater integer - // format. - return compareLongs(flavorToFormatMap, flavor1, flavor2, - UNKNOWN_OBJECT_LOSES_L); + // The flavours are not equal but still not distinguishable. + // Compare String representations in alphabetical order + return flavor1.getMimeType().compareTo(flavor2.getMimeType()); } } diff --git a/jdk/test/sun/awt/datatransfer/DataFlavorComparatorTest.java b/jdk/test/sun/awt/datatransfer/DataFlavorComparatorTest.java new file mode 100644 index 00000000000..9ef6eab2306 --- /dev/null +++ b/jdk/test/sun/awt/datatransfer/DataFlavorComparatorTest.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013, 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 7173464 + @summary Clipboard.getAvailableDataFlavors: Comparison method violates contract + @author Petr Pchelko + @run main DataFlavorComparatorTest +*/ + +import sun.awt.datatransfer.DataTransferer; + +import java.awt.datatransfer.DataFlavor; + +public class DataFlavorComparatorTest { + + public static void main(String[] args) { + DataTransferer.DataFlavorComparator comparator = new DataTransferer.DataFlavorComparator(); + DataFlavor flavor1 = DataFlavor.imageFlavor; + DataFlavor flavor2 = DataFlavor.selectionHtmlFlavor; + if (comparator.compare(flavor1, flavor2) == 0) { + throw new RuntimeException(flavor1.getMimeType() + " and " + flavor2.getMimeType() + + " should not be equal"); + } + } +} + From 20f7d1a82a1d2ac640043d9a673c43d9bebba4cd Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Wed, 14 Aug 2013 10:21:26 -0700 Subject: [PATCH 035/102] 8022993: Convert MAX_UNROLL constant to LoopMaxUnroll C2 flag Replace MAX_UNROLL constant with new C2 LoopMaxUnroll flag. Reviewed-by: roland --- hotspot/src/share/vm/opto/c2_globals.hpp | 3 +++ hotspot/src/share/vm/opto/loopTransform.cpp | 4 +--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp index 2e212995f3e..15d8befbbac 100644 --- a/hotspot/src/share/vm/opto/c2_globals.hpp +++ b/hotspot/src/share/vm/opto/c2_globals.hpp @@ -179,6 +179,9 @@ product_pd(intx, LoopUnrollLimit, \ "Unroll loop bodies with node count less than this") \ \ + product(intx, LoopMaxUnroll, 16, \ + "Maximum number of unrolls for main loop") \ + \ product(intx, LoopUnrollMin, 4, \ "Minimum number of unroll loop bodies before checking progress" \ "of rounds of unroll,optimize,..") \ diff --git a/hotspot/src/share/vm/opto/loopTransform.cpp b/hotspot/src/share/vm/opto/loopTransform.cpp index c438cf9b880..a30fc80df39 100644 --- a/hotspot/src/share/vm/opto/loopTransform.cpp +++ b/hotspot/src/share/vm/opto/loopTransform.cpp @@ -624,8 +624,6 @@ bool IdealLoopTree::policy_maximally_unroll( PhaseIdealLoop *phase ) const { } -#define MAX_UNROLL 16 // maximum number of unrolls for main loop - //------------------------------policy_unroll---------------------------------- // Return TRUE or FALSE if the loop should be unrolled or not. Unroll if // the loop is a CountedLoop and the body is small enough. @@ -642,7 +640,7 @@ bool IdealLoopTree::policy_unroll( PhaseIdealLoop *phase ) const { if (cl->trip_count() <= (uint)(cl->is_normal_loop() ? 2 : 1)) return false; int future_unroll_ct = cl->unrolled_count() * 2; - if (future_unroll_ct > MAX_UNROLL) return false; + if (future_unroll_ct > LoopMaxUnroll) return false; // Check for initial stride being a small enough constant if (abs(cl->stride_con()) > (1<<2)*future_unroll_ct) return false; From 6b3b53caa1fb01b3b25dc1bbf4431e5cb001763b Mon Sep 17 00:00:00 2001 From: Anthony Scarpino Date: Wed, 14 Aug 2013 10:50:52 -0700 Subject: [PATCH 036/102] 8022669: OAEPParameterSpec does not work if MGF1ParameterSpec is set to SHA2 algorithms Reviewed-by: mullan --- .../classes/sun/security/rsa/RSAPadding.java | 4 +- .../provider/Cipher/RSA/TestOAEPPadding.java | 69 +++++++++++++++++-- 2 files changed, 67 insertions(+), 6 deletions(-) diff --git a/jdk/src/share/classes/sun/security/rsa/RSAPadding.java b/jdk/src/share/classes/sun/security/rsa/RSAPadding.java index 0ea04b1052b..76f0d81c20b 100644 --- a/jdk/src/share/classes/sun/security/rsa/RSAPadding.java +++ b/jdk/src/share/classes/sun/security/rsa/RSAPadding.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013 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 @@ -458,7 +458,7 @@ public final class RSAPadding { private void mgf1(byte[] seed, int seedOfs, int seedLen, byte[] out, int outOfs, int maskLen) throws BadPaddingException { byte[] C = new byte[4]; // 32 bit counter - byte[] digest = new byte[20]; // 20 bytes is length of SHA-1 digest + byte[] digest = new byte[mgfMd.getDigestLength()]; while (maskLen > 0) { mgfMd.update(seed, seedOfs, seedLen); mgfMd.update(C); diff --git a/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPPadding.java b/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPPadding.java index 0f3ec981edc..3804253f870 100644 --- a/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPPadding.java +++ b/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPPadding.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8020081 + * @bug 8020081 8022669 * @summary encryption/decryption test for using OAEPPadding with * OAEPParameterSpec specified and not specified during a Cipher.init(). * @author Anthony Scarpino @@ -62,20 +62,74 @@ public class TestOAEPPadding { publicKey = (RSAPublicKey)kp.getPublic(); // Test using a spec with each digest algorithm case + // MD5 test(new OAEPParameterSpec("MD5", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("MD5", "MGF1", + MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("MD5", "MGF1", + MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("MD5", "MGF1", + MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("MD5", "MGF1", + MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT)); + // SHA1 test(new OAEPParameterSpec("SHA1", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA1", "MGF1", + MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA1", "MGF1", + MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA1", "MGF1", + MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA1", "MGF1", + MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT)); // For default OAEPParameterSpec case (SHA1) test(null); + // SHA-224 test(new OAEPParameterSpec("SHA-224", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-224", "MGF1", + MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-224", "MGF1", + MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-224", "MGF1", + MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-224", "MGF1", + MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT)); + // SHA-256 test(new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-256", "MGF1", + MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-256", "MGF1", + MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-256", "MGF1", + MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-256", "MGF1", + MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT)); + // SHA-384 test(new OAEPParameterSpec("SHA-384", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-384", "MGF1", + MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-384", "MGF1", + MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-384", "MGF1", + MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-384", "MGF1", + MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT)); + // SHA-512 test(new OAEPParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-512", "MGF1", + MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-512", "MGF1", + MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-512", "MGF1", + MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-512", "MGF1", + MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT)); if (failed) { throw new Exception("Test failed"); } @@ -149,9 +203,16 @@ public class TestOAEPPadding { private static void testEncryptDecrypt(OAEPParameterSpec spec, int dataLength) throws Exception { - System.out.println("Testing OAEP with hash " + - ((spec != null) ? spec.getDigestAlgorithm() : "Default") + - ", " + dataLength + " bytes"); + + System.out.print("Testing OAEP with hash "); + if (spec != null) { + System.out.print(spec.getDigestAlgorithm() + " and MGF " + + ((MGF1ParameterSpec)spec.getMGFParameters()). + getDigestAlgorithm()); + } else { + System.out.print("Default"); + } + System.out.println(", " + dataLength + " bytes"); Cipher c = Cipher.getInstance("RSA/ECB/OAEPPadding", cp); if (spec != null) { From 1aa32ce1d04bad35e493b6306aa190655caae76c Mon Sep 17 00:00:00 2001 From: Leonid Romanov Date: Thu, 15 Aug 2013 01:17:30 +0400 Subject: [PATCH 037/102] 8022997: [macosx] Remaining duplicated key events Reviewed-by: anthony, serb --- jdk/src/macosx/native/sun/awt/CMenuItem.m | 2 +- .../ActionListenerCalledTwiceTest.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/jdk/src/macosx/native/sun/awt/CMenuItem.m b/jdk/src/macosx/native/sun/awt/CMenuItem.m index 978710eefc7..219cc5bb971 100644 --- a/jdk/src/macosx/native/sun/awt/CMenuItem.m +++ b/jdk/src/macosx/native/sun/awt/CMenuItem.m @@ -296,7 +296,7 @@ static unichar AWTKeyToMacShortcut(jint awtKey, BOOL doShift) { case java_awt_event_KeyEvent_VK_HELP : macKey = NSHelpFunctionKey; break; case java_awt_event_KeyEvent_VK_TAB : macKey = NSTabCharacter; break; - case java_awt_event_KeyEvent_VK_ENTER : macKey = NSCarriageReturnCharacter; break; + case java_awt_event_KeyEvent_VK_ENTER : macKey = NSNewlineCharacter; break; case java_awt_event_KeyEvent_VK_BACK_SPACE : macKey = NSBackspaceCharacter; break; case java_awt_event_KeyEvent_VK_DELETE : macKey = NSDeleteCharacter; break; case java_awt_event_KeyEvent_VK_CLEAR : macKey = NSClearDisplayFunctionKey; break; diff --git a/jdk/test/javax/swing/JMenuItem/ActionListenerCalledTwice/ActionListenerCalledTwiceTest.java b/jdk/test/javax/swing/JMenuItem/ActionListenerCalledTwice/ActionListenerCalledTwiceTest.java index d9cedf423e6..4b78bb98a0e 100644 --- a/jdk/test/javax/swing/JMenuItem/ActionListenerCalledTwice/ActionListenerCalledTwiceTest.java +++ b/jdk/test/javax/swing/JMenuItem/ActionListenerCalledTwice/ActionListenerCalledTwiceTest.java @@ -35,11 +35,12 @@ import java.awt.event.*; import javax.swing.*; public class ActionListenerCalledTwiceTest { - static String menuItems[] = { "Item1", "Item2", "Item3" }; + static String menuItems[] = { "Item1", "Item2", "Item3", "Item4" }; static KeyStroke keyStrokes[] = { KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.META_MASK), KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.SHIFT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.META_MASK) }; static volatile int listenerCallCounter = 0; From c144b8c30f2830843c08b9e5a69cdc911b927cb1 Mon Sep 17 00:00:00 2001 From: Bengt Rutisson Date: Thu, 15 Aug 2013 10:05:50 +0200 Subject: [PATCH 038/102] 8023021: Unnecessary clearing of the card table introduced by the fix for JDK-8023013 Reviewed-by: stefank, ehelin --- hotspot/src/share/vm/memory/cardTableRS.cpp | 23 ++++++++------------ hotspot/src/share/vm/memory/cardTableRS.hpp | 4 ++-- hotspot/src/share/vm/memory/genMarkSweep.cpp | 10 ++++----- hotspot/src/share/vm/memory/genRemSet.hpp | 4 ++-- 4 files changed, 17 insertions(+), 24 deletions(-) diff --git a/hotspot/src/share/vm/memory/cardTableRS.cpp b/hotspot/src/share/vm/memory/cardTableRS.cpp index 502310cebeb..ddd65d42083 100644 --- a/hotspot/src/share/vm/memory/cardTableRS.cpp +++ b/hotspot/src/share/vm/memory/cardTableRS.cpp @@ -310,32 +310,27 @@ void CardTableRS::younger_refs_in_space_iterate(Space* sp, _ct_bs->non_clean_card_iterate_possibly_parallel(sp, urasm, cl, this); } -void CardTableRS::clear_into_younger(Generation* gen) { - GenCollectedHeap* gch = GenCollectedHeap::heap(); - // Generations younger than gen have been evacuated. We can clear - // card table entries for gen (we know that it has no pointers - // to younger gens) and for those below. The card tables for - // the youngest gen need never be cleared. +void CardTableRS::clear_into_younger(Generation* old_gen) { + assert(old_gen->level() == 1, "Should only be called for the old generation"); + // The card tables for the youngest gen need never be cleared. // There's a bit of subtlety in the clear() and invalidate() // methods that we exploit here and in invalidate_or_clear() // below to avoid missing cards at the fringes. If clear() or // invalidate() are changed in the future, this code should // be revisited. 20040107.ysr - Generation* old_gen = gen; clear(old_gen->prev_used_region()); - Generation* young_gen = gch->prev_gen(old_gen); - clear(young_gen->prev_used_region()); } -void CardTableRS::invalidate_or_clear(Generation* gen) { - // For generation gen invalidate the cards for the currently - // occupied part of that generation and clear the cards for the +void CardTableRS::invalidate_or_clear(Generation* old_gen) { + assert(old_gen->level() == 1, "Should only be called for the old generation"); + // Invalidate the cards for the currently occupied part of + // the old generation and clear the cards for the // unoccupied part of the generation (if any, making use // of that generation's prev_used_region to determine that // region). No need to do anything for the youngest // generation. Also see note#20040107.ysr above. - MemRegion used_mr = gen->used_region(); - MemRegion to_be_cleared_mr = gen->prev_used_region().minus(used_mr); + MemRegion used_mr = old_gen->used_region(); + MemRegion to_be_cleared_mr = old_gen->prev_used_region().minus(used_mr); if (!to_be_cleared_mr.is_empty()) { clear(to_be_cleared_mr); } diff --git a/hotspot/src/share/vm/memory/cardTableRS.hpp b/hotspot/src/share/vm/memory/cardTableRS.hpp index 41e92871c0e..25884feac8b 100644 --- a/hotspot/src/share/vm/memory/cardTableRS.hpp +++ b/hotspot/src/share/vm/memory/cardTableRS.hpp @@ -142,12 +142,12 @@ public: void verify_aligned_region_empty(MemRegion mr); void clear(MemRegion mr) { _ct_bs->clear(mr); } - void clear_into_younger(Generation* gen); + void clear_into_younger(Generation* old_gen); void invalidate(MemRegion mr, bool whole_heap = false) { _ct_bs->invalidate(mr, whole_heap); } - void invalidate_or_clear(Generation* gen); + void invalidate_or_clear(Generation* old_gen); static uintx ct_max_alignment_constraint() { return CardTableModRefBS::ct_max_alignment_constraint(); diff --git a/hotspot/src/share/vm/memory/genMarkSweep.cpp b/hotspot/src/share/vm/memory/genMarkSweep.cpp index 88afa607971..fdeba2adaf9 100644 --- a/hotspot/src/share/vm/memory/genMarkSweep.cpp +++ b/hotspot/src/share/vm/memory/genMarkSweep.cpp @@ -121,17 +121,15 @@ void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp, bool c all_empty = all_empty && gch->get_gen(i)->used() == 0; } GenRemSet* rs = gch->rem_set(); + Generation* old_gen = gch->get_gen(level); // Clear/invalidate below make use of the "prev_used_regions" saved earlier. if (all_empty) { // We've evacuated all generations below us. - Generation* g = gch->get_gen(level); - rs->clear_into_younger(g); + rs->clear_into_younger(old_gen); } else { // Invalidate the cards corresponding to the currently used - // region and clear those corresponding to the evacuated region - // of all generations just collected. - rs->invalidate_or_clear(gch->get_gen(1)); - rs->invalidate_or_clear(gch->get_gen(0)); + // region and clear those corresponding to the evacuated region. + rs->invalidate_or_clear(old_gen); } Threads::gc_epilogue(); diff --git a/hotspot/src/share/vm/memory/genRemSet.hpp b/hotspot/src/share/vm/memory/genRemSet.hpp index f5f73553595..44a43540769 100644 --- a/hotspot/src/share/vm/memory/genRemSet.hpp +++ b/hotspot/src/share/vm/memory/genRemSet.hpp @@ -135,7 +135,7 @@ public: // younger than gen from generations gen and older. // The parameter clear_perm indicates if the perm_gen's // remembered set should also be processed/cleared. - virtual void clear_into_younger(Generation* gen) = 0; + virtual void clear_into_younger(Generation* old_gen) = 0; // Informs the RS that refs in the given "mr" may have changed // arbitrarily, and therefore may contain old-to-young pointers. @@ -147,7 +147,7 @@ public: // Informs the RS that refs in this generation // may have changed arbitrarily, and therefore may contain // old-to-young pointers in arbitrary locations. - virtual void invalidate_or_clear(Generation* gen) = 0; + virtual void invalidate_or_clear(Generation* old_gen) = 0; }; #endif // SHARE_VM_MEMORY_GENREMSET_HPP From 78ee0b6ff23866527d08fcba2b00f3ae19de2fd1 Mon Sep 17 00:00:00 2001 From: Anton Litvinov Date: Thu, 15 Aug 2013 14:20:09 +0400 Subject: [PATCH 039/102] 7191018: Manual test closed/java/awt/JAWT causes JVM to crash starting from JDK 5 Reviewed-by: anthony, serb --- jdk/src/solaris/native/sun/awt/awt_DrawingSurface.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/jdk/src/solaris/native/sun/awt/awt_DrawingSurface.c b/jdk/src/solaris/native/sun/awt/awt_DrawingSurface.c index fe19f990aaa..0609c9d4f06 100644 --- a/jdk/src/solaris/native/sun/awt/awt_DrawingSurface.c +++ b/jdk/src/solaris/native/sun/awt/awt_DrawingSurface.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -346,13 +346,19 @@ JNIEXPORT jobject JNICALL awt_GetComponent(JNIEnv* env, void* platformInfo) { Window window = (Window)platformInfo; - Widget widget = NULL; jobject peer = NULL; jobject target = NULL; AWT_LOCK(); - target = (*env)->GetObjectField(env, peer, targetID); + if (window != None) { + peer = JNU_CallStaticMethodByName(env, NULL, "sun/awt/X11/XToolkit", + "windowToXWindow", "(J)Lsun/awt/X11/XBaseWindow;", (jlong)window).l; + } + if ((peer != NULL) && + (JNU_IsInstanceOfByName(env, peer, "sun/awt/X11/XWindow") == 1)) { + target = (*env)->GetObjectField(env, peer, targetID); + } if (target == NULL) { JNU_ThrowNullPointerException(env, "NullPointerException"); @@ -360,7 +366,6 @@ JNIEXPORT jobject JNICALL return (jobject)NULL; } - AWT_UNLOCK(); return target; From c1b34fdc2c21f3a7829c5c20b5791a8e0d72d195 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Thu, 15 Aug 2013 17:14:53 +0200 Subject: [PATCH 040/102] 8020411: lin32 - JDK 8 build for Linux-i586 on Oracle Linux 6.4 64-bit machines does not generate the bundles directory in the build directory Reviewed-by: tbell --- common/autoconf/generated-configure.sh | 524 ++++++++++++------------- common/autoconf/platform.m4 | 17 +- common/autoconf/spec.gmk.in | 1 + 3 files changed, 259 insertions(+), 283 deletions(-) diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index 1f084da68c9..0e4c4d9194c 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for OpenJDK jdk8. +# Generated by GNU Autoconf 2.67 for OpenJDK jdk8. # # Report bugs to . # @@ -91,7 +91,6 @@ fi IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. -as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -217,18 +216,11 @@ IFS=$as_save_IFS # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. - # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL - case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; - esac - exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : @@ -689,6 +681,7 @@ STATIC_LIBRARY SHARED_LIBRARY OBJ_SUFFIX COMPILER_NAME +TARGET_BITS_FLAG JT_HOME JTREGEXE LIPO @@ -1469,7 +1462,7 @@ Try \`$0 --help' for more information" $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac @@ -1905,7 +1898,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF OpenJDK configure jdk8 -generated by GNU Autoconf 2.68 +generated by GNU Autoconf 2.67 Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation @@ -1951,7 +1944,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_compile @@ -1989,7 +1982,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile @@ -2027,7 +2020,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_objc_try_compile @@ -2064,7 +2057,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_cpp @@ -2101,7 +2094,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp @@ -2114,10 +2107,10 @@ fi ac_fn_cxx_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval \${$3+:} false; then : + if eval "test \"\${$3+set}\"" = set; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 @@ -2184,7 +2177,7 @@ $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" @@ -2193,7 +2186,7 @@ eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_cxx_check_header_mongrel @@ -2234,7 +2227,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_try_run @@ -2248,7 +2241,7 @@ ac_fn_cxx_check_header_compile () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2266,7 +2259,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_cxx_check_header_compile @@ -2443,7 +2436,7 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ rm -f conftest.val fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_compute_int @@ -2489,7 +2482,7 @@ fi # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_try_link @@ -2502,7 +2495,7 @@ ac_fn_cxx_check_func () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2557,7 +2550,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_cxx_check_func @@ -2570,7 +2563,7 @@ ac_fn_c_check_header_compile () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2588,7 +2581,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_header_compile cat >config.log <<_ACEOF @@ -2596,7 +2589,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by OpenJDK $as_me jdk8, which was -generated by GNU Autoconf 2.68. Invocation command line was +generated by GNU Autoconf 2.67. Invocation command line was $ $0 $@ @@ -2854,7 +2847,7 @@ $as_echo "$as_me: loading site script $ac_site_file" >&6;} || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } fi done @@ -3794,7 +3787,7 @@ fi #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1373384053 +DATE_WHEN_GENERATED=1376579640 ############################################################################### # @@ -3832,7 +3825,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_BASENAME+:} false; then : +if test "${ac_cv_path_BASENAME+set}" = set; then : $as_echo_n "(cached) " >&6 else case $BASENAME in @@ -3891,7 +3884,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_BASH+:} false; then : +if test "${ac_cv_path_BASH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $BASH in @@ -3950,7 +3943,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CAT+:} false; then : +if test "${ac_cv_path_CAT+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CAT in @@ -4009,7 +4002,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CHMOD+:} false; then : +if test "${ac_cv_path_CHMOD+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CHMOD in @@ -4068,7 +4061,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CMP+:} false; then : +if test "${ac_cv_path_CMP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CMP in @@ -4127,7 +4120,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_COMM+:} false; then : +if test "${ac_cv_path_COMM+set}" = set; then : $as_echo_n "(cached) " >&6 else case $COMM in @@ -4186,7 +4179,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CP+:} false; then : +if test "${ac_cv_path_CP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CP in @@ -4245,7 +4238,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CPIO+:} false; then : +if test "${ac_cv_path_CPIO+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CPIO in @@ -4304,7 +4297,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CUT+:} false; then : +if test "${ac_cv_path_CUT+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CUT in @@ -4363,7 +4356,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_DATE+:} false; then : +if test "${ac_cv_path_DATE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $DATE in @@ -4422,7 +4415,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_DIFF+:} false; then : +if test "${ac_cv_path_DIFF+set}" = set; then : $as_echo_n "(cached) " >&6 else case $DIFF in @@ -4481,7 +4474,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_DIRNAME+:} false; then : +if test "${ac_cv_path_DIRNAME+set}" = set; then : $as_echo_n "(cached) " >&6 else case $DIRNAME in @@ -4540,7 +4533,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ECHO+:} false; then : +if test "${ac_cv_path_ECHO+set}" = set; then : $as_echo_n "(cached) " >&6 else case $ECHO in @@ -4599,7 +4592,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_EXPR+:} false; then : +if test "${ac_cv_path_EXPR+set}" = set; then : $as_echo_n "(cached) " >&6 else case $EXPR in @@ -4658,7 +4651,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_FILE+:} false; then : +if test "${ac_cv_path_FILE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $FILE in @@ -4717,7 +4710,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_FIND+:} false; then : +if test "${ac_cv_path_FIND+set}" = set; then : $as_echo_n "(cached) " >&6 else case $FIND in @@ -4776,7 +4769,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_HEAD+:} false; then : +if test "${ac_cv_path_HEAD+set}" = set; then : $as_echo_n "(cached) " >&6 else case $HEAD in @@ -4835,7 +4828,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_LN+:} false; then : +if test "${ac_cv_path_LN+set}" = set; then : $as_echo_n "(cached) " >&6 else case $LN in @@ -4894,7 +4887,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_LS+:} false; then : +if test "${ac_cv_path_LS+set}" = set; then : $as_echo_n "(cached) " >&6 else case $LS in @@ -4953,7 +4946,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_MKDIR+:} false; then : +if test "${ac_cv_path_MKDIR+set}" = set; then : $as_echo_n "(cached) " >&6 else case $MKDIR in @@ -5012,7 +5005,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_MKTEMP+:} false; then : +if test "${ac_cv_path_MKTEMP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $MKTEMP in @@ -5071,7 +5064,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_MV+:} false; then : +if test "${ac_cv_path_MV+set}" = set; then : $as_echo_n "(cached) " >&6 else case $MV in @@ -5130,7 +5123,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_PRINTF+:} false; then : +if test "${ac_cv_path_PRINTF+set}" = set; then : $as_echo_n "(cached) " >&6 else case $PRINTF in @@ -5189,7 +5182,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_RM+:} false; then : +if test "${ac_cv_path_RM+set}" = set; then : $as_echo_n "(cached) " >&6 else case $RM in @@ -5248,7 +5241,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_SH+:} false; then : +if test "${ac_cv_path_SH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $SH in @@ -5307,7 +5300,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_SORT+:} false; then : +if test "${ac_cv_path_SORT+set}" = set; then : $as_echo_n "(cached) " >&6 else case $SORT in @@ -5366,7 +5359,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_TAIL+:} false; then : +if test "${ac_cv_path_TAIL+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TAIL in @@ -5425,7 +5418,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_TAR+:} false; then : +if test "${ac_cv_path_TAR+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TAR in @@ -5484,7 +5477,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_TEE+:} false; then : +if test "${ac_cv_path_TEE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TEE in @@ -5543,7 +5536,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_TOUCH+:} false; then : +if test "${ac_cv_path_TOUCH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TOUCH in @@ -5602,7 +5595,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_TR+:} false; then : +if test "${ac_cv_path_TR+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TR in @@ -5661,7 +5654,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_UNAME+:} false; then : +if test "${ac_cv_path_UNAME+set}" = set; then : $as_echo_n "(cached) " >&6 else case $UNAME in @@ -5720,7 +5713,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_UNIQ+:} false; then : +if test "${ac_cv_path_UNIQ+set}" = set; then : $as_echo_n "(cached) " >&6 else case $UNIQ in @@ -5779,7 +5772,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_WC+:} false; then : +if test "${ac_cv_path_WC+set}" = set; then : $as_echo_n "(cached) " >&6 else case $WC in @@ -5838,7 +5831,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_WHICH+:} false; then : +if test "${ac_cv_path_WHICH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $WHICH in @@ -5897,7 +5890,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_XARGS+:} false; then : +if test "${ac_cv_path_XARGS+set}" = set; then : $as_echo_n "(cached) " >&6 else case $XARGS in @@ -5957,7 +5950,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AWK+:} false; then : +if test "${ac_cv_prog_AWK+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then @@ -6007,7 +6000,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if ${ac_cv_path_GREP+:} false; then : +if test "${ac_cv_path_GREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then @@ -6082,7 +6075,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } -if ${ac_cv_path_EGREP+:} false; then : +if test "${ac_cv_path_EGREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 @@ -6161,7 +6154,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } -if ${ac_cv_path_FGREP+:} false; then : +if test "${ac_cv_path_FGREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 @@ -6240,7 +6233,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } -if ${ac_cv_path_SED+:} false; then : +if test "${ac_cv_path_SED+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ @@ -6326,7 +6319,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_NAWK+:} false; then : +if test "${ac_cv_path_NAWK+set}" = set; then : $as_echo_n "(cached) " >&6 else case $NAWK in @@ -6390,7 +6383,7 @@ THEPWDCMD=pwd set dummy cygpath; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CYGPATH+:} false; then : +if test "${ac_cv_path_CYGPATH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CYGPATH in @@ -6430,7 +6423,7 @@ fi set dummy readlink; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_READLINK+:} false; then : +if test "${ac_cv_path_READLINK+set}" = set; then : $as_echo_n "(cached) " >&6 else case $READLINK in @@ -6470,7 +6463,7 @@ fi set dummy df; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_DF+:} false; then : +if test "${ac_cv_path_DF+set}" = set; then : $as_echo_n "(cached) " >&6 else case $DF in @@ -6510,7 +6503,7 @@ fi set dummy SetFile; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_SETFILE+:} false; then : +if test "${ac_cv_path_SETFILE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $SETFILE in @@ -6556,7 +6549,7 @@ $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } -if ${ac_cv_build+:} false; then : +if test "${ac_cv_build+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias @@ -6572,7 +6565,7 @@ fi $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; -*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5 ;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' @@ -6590,7 +6583,7 @@ case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } -if ${ac_cv_host+:} false; then : +if test "${ac_cv_host+set}" = set; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then @@ -6605,7 +6598,7 @@ fi $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; -*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5 ;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' @@ -6623,7 +6616,7 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 $as_echo_n "checking target system type... " >&6; } -if ${ac_cv_target+:} false; then : +if test "${ac_cv_target+set}" = set; then : $as_echo_n "(cached) " >&6 else if test "x$target_alias" = x; then @@ -6638,7 +6631,7 @@ fi $as_echo "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; -*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; +*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5 ;; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' @@ -8164,7 +8157,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_PKGHANDLER+:} false; then : +if test "${ac_cv_prog_PKGHANDLER+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$PKGHANDLER"; then @@ -8529,7 +8522,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CHECK_GMAKE+:} false; then : +if test "${ac_cv_path_CHECK_GMAKE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CHECK_GMAKE in @@ -8883,7 +8876,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CHECK_MAKE+:} false; then : +if test "${ac_cv_path_CHECK_MAKE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CHECK_MAKE in @@ -9242,7 +9235,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CHECK_TOOLSDIR_GMAKE+:} false; then : +if test "${ac_cv_path_CHECK_TOOLSDIR_GMAKE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CHECK_TOOLSDIR_GMAKE in @@ -9595,7 +9588,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CHECK_TOOLSDIR_MAKE+:} false; then : +if test "${ac_cv_path_CHECK_TOOLSDIR_MAKE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CHECK_TOOLSDIR_MAKE in @@ -9991,7 +9984,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_UNZIP+:} false; then : +if test "${ac_cv_path_UNZIP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $UNZIP in @@ -10050,7 +10043,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ZIP+:} false; then : +if test "${ac_cv_path_ZIP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $ZIP in @@ -10109,7 +10102,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} set dummy ldd; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_LDD+:} false; then : +if test "${ac_cv_path_LDD+set}" = set; then : $as_echo_n "(cached) " >&6 else case $LDD in @@ -10155,7 +10148,7 @@ fi set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_OTOOL+:} false; then : +if test "${ac_cv_path_OTOOL+set}" = set; then : $as_echo_n "(cached) " >&6 else case $OTOOL in @@ -10200,7 +10193,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_READELF+:} false; then : +if test "${ac_cv_path_READELF+set}" = set; then : $as_echo_n "(cached) " >&6 else case $READELF in @@ -10243,7 +10236,7 @@ done set dummy hg; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_HG+:} false; then : +if test "${ac_cv_path_HG+set}" = set; then : $as_echo_n "(cached) " >&6 else case $HG in @@ -10283,7 +10276,7 @@ fi set dummy stat; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_STAT+:} false; then : +if test "${ac_cv_path_STAT+set}" = set; then : $as_echo_n "(cached) " >&6 else case $STAT in @@ -10323,7 +10316,7 @@ fi set dummy time; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_TIME+:} false; then : +if test "${ac_cv_path_TIME+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TIME in @@ -10376,7 +10369,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_COMM+:} false; then : +if test "${ac_cv_path_COMM+set}" = set; then : $as_echo_n "(cached) " >&6 else case $COMM in @@ -10438,7 +10431,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_XATTR+:} false; then : +if test "${ac_cv_path_XATTR+set}" = set; then : $as_echo_n "(cached) " >&6 else case $XATTR in @@ -10494,7 +10487,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} set dummy codesign; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CODESIGN+:} false; then : +if test "${ac_cv_path_CODESIGN+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CODESIGN in @@ -10558,7 +10551,7 @@ if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_PKG_CONFIG+:} false; then : +if test "${ac_cv_path_PKG_CONFIG+set}" = set; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in @@ -10601,7 +10594,7 @@ if test -z "$ac_cv_path_PKG_CONFIG"; then set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : +if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in @@ -10774,7 +10767,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_BDEPS_UNZIP+:} false; then : +if test "${ac_cv_prog_BDEPS_UNZIP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$BDEPS_UNZIP"; then @@ -10820,7 +10813,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_BDEPS_FTP+:} false; then : +if test "${ac_cv_prog_BDEPS_FTP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$BDEPS_FTP"; then @@ -12116,7 +12109,7 @@ $as_echo "$BOOT_JDK_VERSION" >&6; } set dummy javac; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_JAVAC_CHECK+:} false; then : +if test "${ac_cv_path_JAVAC_CHECK+set}" = set; then : $as_echo_n "(cached) " >&6 else case $JAVAC_CHECK in @@ -12156,7 +12149,7 @@ fi set dummy java; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_JAVA_CHECK+:} false; then : +if test "${ac_cv_path_JAVA_CHECK+set}" = set; then : $as_echo_n "(cached) " >&6 else case $JAVA_CHECK in @@ -16485,7 +16478,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_JTREGEXE+:} false; then : +if test "${ac_cv_path_JTREGEXE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $JTREGEXE in @@ -16553,7 +16546,7 @@ if test "x$OPENJDK_TARGET_OS" = "xwindows"; then set dummy link; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CYGWIN_LINK+:} false; then : +if test "${ac_cv_path_CYGWIN_LINK+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CYGWIN_LINK in @@ -17996,7 +17989,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_BUILD_CC+:} false; then : +if test "${ac_cv_path_BUILD_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else case $BUILD_CC in @@ -18307,7 +18300,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_BUILD_CXX+:} false; then : +if test "${ac_cv_path_BUILD_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else case $BUILD_CXX in @@ -18616,7 +18609,7 @@ $as_echo "$as_me: Rewriting BUILD_CXX to \"$new_complete\"" >&6;} set dummy ld; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_BUILD_LD+:} false; then : +if test "${ac_cv_path_BUILD_LD+set}" = set; then : $as_echo_n "(cached) " >&6 else case $BUILD_LD in @@ -19123,7 +19116,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_TOOLS_DIR_CC+:} false; then : +if test "${ac_cv_path_TOOLS_DIR_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TOOLS_DIR_CC in @@ -19175,7 +19168,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_POTENTIAL_CC+:} false; then : +if test "${ac_cv_path_POTENTIAL_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else case $POTENTIAL_CC in @@ -19588,7 +19581,7 @@ $as_echo "yes, trying to find proper $COMPILER_NAME compiler" >&6; } set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_PROPER_COMPILER_CC+:} false; then : +if test "${ac_cv_prog_PROPER_COMPILER_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$PROPER_COMPILER_CC"; then @@ -19632,7 +19625,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_PROPER_COMPILER_CC+:} false; then : +if test "${ac_cv_prog_ac_ct_PROPER_COMPILER_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_PROPER_COMPILER_CC"; then @@ -20082,7 +20075,7 @@ if test -n "$ac_tool_prefix"; then set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : +if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then @@ -20126,7 +20119,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then @@ -20179,7 +20172,7 @@ fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 @@ -20294,7 +20287,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } @@ -20337,7 +20330,7 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 @@ -20396,7 +20389,7 @@ $as_echo "$ac_try_echo"; } >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } fi fi fi @@ -20407,7 +20400,7 @@ rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } -if ${ac_cv_objext+:} false; then : +if test "${ac_cv_objext+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -20448,7 +20441,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi @@ -20458,7 +20451,7 @@ OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : +if test "${ac_cv_c_compiler_gnu+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -20495,7 +20488,7 @@ ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : +if test "${ac_cv_prog_cc_g+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag @@ -20573,7 +20566,7 @@ else fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : +if test "${ac_cv_prog_cc_c89+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no @@ -20696,7 +20689,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_TOOLS_DIR_CXX+:} false; then : +if test "${ac_cv_path_TOOLS_DIR_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TOOLS_DIR_CXX in @@ -20748,7 +20741,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_POTENTIAL_CXX+:} false; then : +if test "${ac_cv_path_POTENTIAL_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else case $POTENTIAL_CXX in @@ -21161,7 +21154,7 @@ $as_echo "yes, trying to find proper $COMPILER_NAME compiler" >&6; } set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_PROPER_COMPILER_CXX+:} false; then : +if test "${ac_cv_prog_PROPER_COMPILER_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$PROPER_COMPILER_CXX"; then @@ -21205,7 +21198,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_PROPER_COMPILER_CXX+:} false; then : +if test "${ac_cv_prog_ac_ct_PROPER_COMPILER_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_PROPER_COMPILER_CXX"; then @@ -21659,7 +21652,7 @@ if test -z "$CXX"; then set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CXX+:} false; then : +if test "${ac_cv_prog_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then @@ -21703,7 +21696,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CXX+:} false; then : +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then @@ -21781,7 +21774,7 @@ done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } -if ${ac_cv_cxx_compiler_gnu+:} false; then : +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -21818,7 +21811,7 @@ ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } -if ${ac_cv_prog_cxx_g+:} false; then : +if test "${ac_cv_prog_cxx_g+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag @@ -21916,7 +21909,7 @@ if test -n "$ac_tool_prefix"; then set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OBJC+:} false; then : +if test "${ac_cv_prog_OBJC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJC"; then @@ -21960,7 +21953,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OBJC+:} false; then : +if test "${ac_cv_prog_ac_ct_OBJC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJC"; then @@ -22036,7 +22029,7 @@ done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU Objective C compiler" >&5 $as_echo_n "checking whether we are using the GNU Objective C compiler... " >&6; } -if ${ac_cv_objc_compiler_gnu+:} false; then : +if test "${ac_cv_objc_compiler_gnu+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -22073,7 +22066,7 @@ ac_test_OBJCFLAGS=${OBJCFLAGS+set} ac_save_OBJCFLAGS=$OBJCFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $OBJC accepts -g" >&5 $as_echo_n "checking whether $OBJC accepts -g... " >&6; } -if ${ac_cv_prog_objc_g+:} false; then : +if test "${ac_cv_prog_objc_g+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_save_objc_werror_flag=$ac_objc_werror_flag @@ -22449,7 +22442,7 @@ if test "x$OPENJDK_TARGET_OS" != xwindows; then set dummy ${ac_tool_prefix}ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AR+:} false; then : +if test "${ac_cv_prog_AR+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then @@ -22489,7 +22482,7 @@ if test -z "$ac_cv_prog_AR"; then set dummy ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_AR+:} false; then : +if test "${ac_cv_prog_ac_ct_AR+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then @@ -22831,7 +22824,7 @@ if test "x$OPENJDK_TARGET_OS" = xwindows; then : set dummy link; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_WINLD+:} false; then : +if test "${ac_cv_prog_WINLD+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$WINLD"; then @@ -23170,7 +23163,7 @@ $as_echo "yes" >&6; } set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_MT+:} false; then : +if test "${ac_cv_prog_MT+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$MT"; then @@ -23491,7 +23484,7 @@ $as_echo "$as_me: Rewriting MT to \"$new_complete\"" >&6;} set dummy rc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_RC+:} false; then : +if test "${ac_cv_prog_RC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$RC"; then @@ -23883,7 +23876,7 @@ fi set dummy lib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_WINAR+:} false; then : +if test "${ac_cv_prog_WINAR+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$WINAR"; then @@ -24189,7 +24182,7 @@ $as_echo "$as_me: Rewriting WINAR to \"$new_complete\"" >&6;} set dummy dumpbin; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DUMPBIN+:} false; then : +if test "${ac_cv_prog_DUMPBIN+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then @@ -24508,7 +24501,7 @@ if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : + if test "${ac_cv_prog_CPP+set}" = set; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded @@ -24624,7 +24617,7 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } fi ac_ext=cpp @@ -24908,7 +24901,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then - if ${ac_cv_prog_CXXCPP+:} false; then : + if test "${ac_cv_prog_CXXCPP+set}" = set; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded @@ -25024,7 +25017,7 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } fi ac_ext=cpp @@ -25326,7 +25319,7 @@ if test "x$OPENJDK_TARGET_OS" = xsolaris; then set dummy as; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_AS+:} false; then : +if test "${ac_cv_path_AS+set}" = set; then : $as_echo_n "(cached) " >&6 else case $AS in @@ -25638,7 +25631,7 @@ if test "x$OPENJDK_TARGET_OS" = xsolaris; then set dummy nm; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_NM+:} false; then : +if test "${ac_cv_path_NM+set}" = set; then : $as_echo_n "(cached) " >&6 else case $NM in @@ -25944,7 +25937,7 @@ $as_echo "$as_me: Rewriting NM to \"$new_complete\"" >&6;} set dummy gnm; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_GNM+:} false; then : +if test "${ac_cv_path_GNM+set}" = set; then : $as_echo_n "(cached) " >&6 else case $GNM in @@ -26250,7 +26243,7 @@ $as_echo "$as_me: Rewriting GNM to \"$new_complete\"" >&6;} set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_STRIP+:} false; then : +if test "${ac_cv_path_STRIP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $STRIP in @@ -26556,7 +26549,7 @@ $as_echo "$as_me: Rewriting STRIP to \"$new_complete\"" >&6;} set dummy mcs; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_MCS+:} false; then : +if test "${ac_cv_path_MCS+set}" = set; then : $as_echo_n "(cached) " >&6 else case $MCS in @@ -26864,7 +26857,7 @@ elif test "x$OPENJDK_TARGET_OS" != xwindows; then set dummy ${ac_tool_prefix}nm; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_NM+:} false; then : +if test "${ac_cv_prog_NM+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then @@ -26904,7 +26897,7 @@ if test -z "$ac_cv_prog_NM"; then set dummy nm; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_NM+:} false; then : +if test "${ac_cv_prog_ac_ct_NM+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NM"; then @@ -27224,7 +27217,7 @@ $as_echo "$as_me: Rewriting NM to \"$new_complete\"" >&6;} set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_STRIP+:} false; then : +if test "${ac_cv_prog_STRIP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then @@ -27264,7 +27257,7 @@ if test -z "$ac_cv_prog_STRIP"; then set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_STRIP+:} false; then : +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then @@ -27589,7 +27582,7 @@ if test "x$OPENJDK_TARGET_OS" = xsolaris || test "x$OPENJDK_TARGET_OS" = xlinux; set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OBJCOPY+:} false; then : +if test "${ac_cv_prog_OBJCOPY+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJCOPY"; then @@ -27633,7 +27626,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OBJCOPY+:} false; then : +if test "${ac_cv_prog_ac_ct_OBJCOPY+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJCOPY"; then @@ -27960,7 +27953,7 @@ if test -n "$ac_tool_prefix"; then set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OBJDUMP+:} false; then : +if test "${ac_cv_prog_OBJDUMP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then @@ -28004,7 +27997,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : +if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then @@ -28328,7 +28321,7 @@ if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_LIPO+:} false; then : +if test "${ac_cv_path_LIPO+set}" = set; then : $as_echo_n "(cached) " >&6 else case $LIPO in @@ -28645,7 +28638,7 @@ PATH="$OLD_PATH" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : +if test "${ac_cv_header_stdc+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -28785,17 +28778,16 @@ if test "x$OPENJDK_TARGET_OS" = xsolaris; then # keep track of c/cxx flags that we added outselves... # to prevent emitting warning... - ADDED_CFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" - ADDED_CXXFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" - ADDED_LDFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" + TARGET_BITS_FLAG="-m${OPENJDK_TARGET_CPU_BITS}" - CFLAGS="${CFLAGS}${ADDED_CFLAGS}" - CXXFLAGS="${CXXFLAGS}${ADDED_CXXFLAGS}" - LDFLAGS="${LDFLAGS}${ADDED_LDFLAGS}" - CFLAGS_JDK="${CFLAGS_JDK}${ADDED_CFLAGS}" - CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}" - LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}" + CFLAGS="${CFLAGS} ${TARGET_BITS_FLAG}" + CXXFLAGS="${CXXFLAGS} ${TARGET_BITS_FLAG}" + LDFLAGS="${LDFLAGS} ${TARGET_BITS_FLAG}" + + CFLAGS_JDK="${CFLAGS_JDK} ${TARGET_BITS_FLAG}" + CXXFLAGS_JDK="${CXXFLAGS_JDK} ${TARGET_BITS_FLAG}" + LDFLAGS_JDK="${LDFLAGS_JDK} ${TARGET_BITS_FLAG}" elif test "x$COMPILE_TYPE" = xreduced; then if test "x$OPENJDK_TARGET_OS" != xwindows; then @@ -28803,17 +28795,16 @@ elif test "x$COMPILE_TYPE" = xreduced; then # keep track of c/cxx flags that we added outselves... # to prevent emitting warning... - ADDED_CFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" - ADDED_CXXFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" - ADDED_LDFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" + TARGET_BITS_FLAG="-m${OPENJDK_TARGET_CPU_BITS}" - CFLAGS="${CFLAGS}${ADDED_CFLAGS}" - CXXFLAGS="${CXXFLAGS}${ADDED_CXXFLAGS}" - LDFLAGS="${LDFLAGS}${ADDED_LDFLAGS}" - CFLAGS_JDK="${CFLAGS_JDK}${ADDED_CFLAGS}" - CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}" - LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}" + CFLAGS="${CFLAGS} ${TARGET_BITS_FLAG}" + CXXFLAGS="${CXXFLAGS} ${TARGET_BITS_FLAG}" + LDFLAGS="${LDFLAGS} ${TARGET_BITS_FLAG}" + + CFLAGS_JDK="${CFLAGS_JDK} ${TARGET_BITS_FLAG}" + CXXFLAGS_JDK="${CXXFLAGS_JDK} ${TARGET_BITS_FLAG}" + LDFLAGS_JDK="${LDFLAGS_JDK} ${TARGET_BITS_FLAG}" fi fi @@ -28822,7 +28813,7 @@ fi for ac_header in stdio.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "stdio.h" "ac_cv_header_stdio_h" "$ac_includes_default" -if test "x$ac_cv_header_stdio_h" = xyes; then : +if test "x$ac_cv_header_stdio_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDIO_H 1 _ACEOF @@ -28851,7 +28842,7 @@ done # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int *" >&5 $as_echo_n "checking size of int *... " >&6; } -if ${ac_cv_sizeof_int_p+:} false; then : +if test "${ac_cv_sizeof_int_p+set}" = set; then : $as_echo_n "(cached) " >&6 else if ac_fn_cxx_compute_int "$LINENO" "(long int) (sizeof (int *))" "ac_cv_sizeof_int_p" "$ac_includes_default"; then : @@ -28861,7 +28852,7 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (int *) -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } else ac_cv_sizeof_int_p=0 fi @@ -28908,7 +28899,7 @@ $as_echo "$OPENJDK_TARGET_CPU_BITS bits" >&6; } # { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 $as_echo_n "checking whether byte ordering is bigendian... " >&6; } -if ${ac_cv_c_bigendian+:} false; then : +if test "${ac_cv_c_bigendian+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_cv_c_bigendian=unknown @@ -30084,8 +30075,8 @@ if test "x$with_x" = xno; then have_x=disabled else case $x_includes,$x_libraries in #( - *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #( - *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then : + *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5 ;; #( + *,NONE | NONE,*) if test "${ac_cv_have_x+set}" = set; then : $as_echo_n "(cached) " >&6 else # One or both of the vars are not set, and there is no cached value. @@ -30362,7 +30353,7 @@ if ac_fn_cxx_try_link "$LINENO"; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet" >&5 $as_echo_n "checking for dnet_ntoa in -ldnet... " >&6; } -if ${ac_cv_lib_dnet_dnet_ntoa+:} false; then : +if test "${ac_cv_lib_dnet_dnet_ntoa+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30396,14 +30387,14 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_dnet_ntoa" >&5 $as_echo "$ac_cv_lib_dnet_dnet_ntoa" >&6; } -if test "x$ac_cv_lib_dnet_dnet_ntoa" = xyes; then : +if test "x$ac_cv_lib_dnet_dnet_ntoa" = x""yes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" fi if test $ac_cv_lib_dnet_dnet_ntoa = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet_stub" >&5 $as_echo_n "checking for dnet_ntoa in -ldnet_stub... " >&6; } -if ${ac_cv_lib_dnet_stub_dnet_ntoa+:} false; then : +if test "${ac_cv_lib_dnet_stub_dnet_ntoa+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30437,7 +30428,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5 $as_echo "$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; } -if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = xyes; then : +if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = x""yes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" fi @@ -30456,14 +30447,14 @@ rm -f core conftest.err conftest.$ac_objext \ # The functions gethostbyname, getservbyname, and inet_addr are # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking. ac_fn_cxx_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" -if test "x$ac_cv_func_gethostbyname" = xyes; then : +if test "x$ac_cv_func_gethostbyname" = x""yes; then : fi if test $ac_cv_func_gethostbyname = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 $as_echo_n "checking for gethostbyname in -lnsl... " >&6; } -if ${ac_cv_lib_nsl_gethostbyname+:} false; then : +if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30497,14 +30488,14 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 $as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } -if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : +if test "x$ac_cv_lib_nsl_gethostbyname" = x""yes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" fi if test $ac_cv_lib_nsl_gethostbyname = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lbsd" >&5 $as_echo_n "checking for gethostbyname in -lbsd... " >&6; } -if ${ac_cv_lib_bsd_gethostbyname+:} false; then : +if test "${ac_cv_lib_bsd_gethostbyname+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30538,7 +30529,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_gethostbyname" >&5 $as_echo "$ac_cv_lib_bsd_gethostbyname" >&6; } -if test "x$ac_cv_lib_bsd_gethostbyname" = xyes; then : +if test "x$ac_cv_lib_bsd_gethostbyname" = x""yes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd" fi @@ -30553,14 +30544,14 @@ fi # must be given before -lnsl if both are needed. We assume that # if connect needs -lnsl, so does gethostbyname. ac_fn_cxx_check_func "$LINENO" "connect" "ac_cv_func_connect" -if test "x$ac_cv_func_connect" = xyes; then : +if test "x$ac_cv_func_connect" = x""yes; then : fi if test $ac_cv_func_connect = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 $as_echo_n "checking for connect in -lsocket... " >&6; } -if ${ac_cv_lib_socket_connect+:} false; then : +if test "${ac_cv_lib_socket_connect+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30594,7 +30585,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5 $as_echo "$ac_cv_lib_socket_connect" >&6; } -if test "x$ac_cv_lib_socket_connect" = xyes; then : +if test "x$ac_cv_lib_socket_connect" = x""yes; then : X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" fi @@ -30602,14 +30593,14 @@ fi # Guillermo Gomez says -lposix is necessary on A/UX. ac_fn_cxx_check_func "$LINENO" "remove" "ac_cv_func_remove" -if test "x$ac_cv_func_remove" = xyes; then : +if test "x$ac_cv_func_remove" = x""yes; then : fi if test $ac_cv_func_remove = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for remove in -lposix" >&5 $as_echo_n "checking for remove in -lposix... " >&6; } -if ${ac_cv_lib_posix_remove+:} false; then : +if test "${ac_cv_lib_posix_remove+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30643,7 +30634,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix_remove" >&5 $as_echo "$ac_cv_lib_posix_remove" >&6; } -if test "x$ac_cv_lib_posix_remove" = xyes; then : +if test "x$ac_cv_lib_posix_remove" = x""yes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" fi @@ -30651,14 +30642,14 @@ fi # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. ac_fn_cxx_check_func "$LINENO" "shmat" "ac_cv_func_shmat" -if test "x$ac_cv_func_shmat" = xyes; then : +if test "x$ac_cv_func_shmat" = x""yes; then : fi if test $ac_cv_func_shmat = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shmat in -lipc" >&5 $as_echo_n "checking for shmat in -lipc... " >&6; } -if ${ac_cv_lib_ipc_shmat+:} false; then : +if test "${ac_cv_lib_ipc_shmat+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30692,7 +30683,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_shmat" >&5 $as_echo "$ac_cv_lib_ipc_shmat" >&6; } -if test "x$ac_cv_lib_ipc_shmat" = xyes; then : +if test "x$ac_cv_lib_ipc_shmat" = x""yes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" fi @@ -30710,7 +30701,7 @@ fi # John Interrante, Karl Berry { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IceConnectionNumber in -lICE" >&5 $as_echo_n "checking for IceConnectionNumber in -lICE... " >&6; } -if ${ac_cv_lib_ICE_IceConnectionNumber+:} false; then : +if test "${ac_cv_lib_ICE_IceConnectionNumber+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30744,7 +30735,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5 $as_echo "$ac_cv_lib_ICE_IceConnectionNumber" >&6; } -if test "x$ac_cv_lib_ICE_IceConnectionNumber" = xyes; then : +if test "x$ac_cv_lib_ICE_IceConnectionNumber" = x""yes; then : X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" fi @@ -31762,7 +31753,7 @@ $as_echo "$FREETYPE2_FOUND" >&6; } LDFLAGS="$FREETYPE2_LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FT_Init_FreeType in -lfreetype" >&5 $as_echo_n "checking for FT_Init_FreeType in -lfreetype... " >&6; } -if ${ac_cv_lib_freetype_FT_Init_FreeType+:} false; then : +if test "${ac_cv_lib_freetype_FT_Init_FreeType+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -31796,7 +31787,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_freetype_FT_Init_FreeType" >&5 $as_echo "$ac_cv_lib_freetype_FT_Init_FreeType" >&6; } -if test "x$ac_cv_lib_freetype_FT_Init_FreeType" = xyes; then : +if test "x$ac_cv_lib_freetype_FT_Init_FreeType" = x""yes; then : FREETYPE2_FOUND=true else as_fn_error $? "Could not find freetype2! $HELP_MSG " "$LINENO" 5 @@ -32084,7 +32075,7 @@ fi for ac_header in alsa/asoundlib.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "alsa/asoundlib.h" "ac_cv_header_alsa_asoundlib_h" "$ac_includes_default" -if test "x$ac_cv_header_alsa_asoundlib_h" = xyes; then : +if test "x$ac_cv_header_alsa_asoundlib_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ALSA_ASOUNDLIB_H 1 _ACEOF @@ -32143,7 +32134,7 @@ fi USE_EXTERNAL_LIBJPEG=true { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -ljpeg" >&5 $as_echo_n "checking for main in -ljpeg... " >&6; } -if ${ac_cv_lib_jpeg_main+:} false; then : +if test "${ac_cv_lib_jpeg_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -32171,7 +32162,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jpeg_main" >&5 $as_echo "$ac_cv_lib_jpeg_main" >&6; } -if test "x$ac_cv_lib_jpeg_main" = xyes; then : +if test "x$ac_cv_lib_jpeg_main" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBJPEG 1 _ACEOF @@ -32220,7 +32211,7 @@ if test "x${with_giflib}" = "xbundled"; then USE_EXTERNAL_LIBGIF=false elif test "x${with_giflib}" = "xsystem"; then ac_fn_cxx_check_header_mongrel "$LINENO" "gif_lib.h" "ac_cv_header_gif_lib_h" "$ac_includes_default" -if test "x$ac_cv_header_gif_lib_h" = xyes; then : +if test "x$ac_cv_header_gif_lib_h" = x""yes; then : else as_fn_error $? "--with-giflib=system specified, but gif_lib.h not found!" "$LINENO" 5 @@ -32229,7 +32220,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DGifGetCode in -lgif" >&5 $as_echo_n "checking for DGifGetCode in -lgif... " >&6; } -if ${ac_cv_lib_gif_DGifGetCode+:} false; then : +if test "${ac_cv_lib_gif_DGifGetCode+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -32263,7 +32254,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gif_DGifGetCode" >&5 $as_echo "$ac_cv_lib_gif_DGifGetCode" >&6; } -if test "x$ac_cv_lib_gif_DGifGetCode" = xyes; then : +if test "x$ac_cv_lib_gif_DGifGetCode" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBGIF 1 _ACEOF @@ -32295,7 +32286,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for compress in -lz" >&5 $as_echo_n "checking for compress in -lz... " >&6; } -if ${ac_cv_lib_z_compress+:} false; then : +if test "${ac_cv_lib_z_compress+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -32329,7 +32320,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_compress" >&5 $as_echo "$ac_cv_lib_z_compress" >&6; } -if test "x$ac_cv_lib_z_compress" = xyes; then : +if test "x$ac_cv_lib_z_compress" = x""yes; then : ZLIB_FOUND=yes else ZLIB_FOUND=no @@ -32422,7 +32413,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5 $as_echo_n "checking for cos in -lm... " >&6; } -if ${ac_cv_lib_m_cos+:} false; then : +if test "${ac_cv_lib_m_cos+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -32456,7 +32447,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5 $as_echo "$ac_cv_lib_m_cos" >&6; } -if test "x$ac_cv_lib_m_cos" = xyes; then : +if test "x$ac_cv_lib_m_cos" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF @@ -32480,7 +32471,7 @@ save_LIBS="$LIBS" LIBS="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : +if test "${ac_cv_lib_dl_dlopen+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -32514,7 +32505,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : +if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDL 1 _ACEOF @@ -32744,7 +32735,7 @@ and LIBFFI_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } else LIBFFI_CFLAGS=$pkg_cv_LIBFFI_CFLAGS LIBFFI_LIBS=$pkg_cv_LIBFFI_LIBS @@ -32760,7 +32751,7 @@ if test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then set dummy llvm-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_LLVM_CONFIG+:} false; then : +if test "${ac_cv_prog_LLVM_CONFIG+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$LLVM_CONFIG"; then @@ -33376,7 +33367,7 @@ fi set dummy ccache; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CCACHE+:} false; then : +if test "${ac_cv_path_CCACHE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CCACHE in @@ -33638,21 +33629,10 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then - if test "x$cache_file" != "x/dev/null"; then + test "x$cache_file" != "x/dev/null" && { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} - if test ! -f "$cache_file" || test -h "$cache_file"; then - cat confcache >"$cache_file" - else - case $cache_file in #( - */* | ?:*) - mv -f confcache "$cache_file"$$ && - mv -f "$cache_file"$$ "$cache_file" ;; #( - *) - mv -f confcache "$cache_file" ;; - esac - fi - fi + cat confcache >$cache_file else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} @@ -33684,7 +33664,7 @@ LTLIBOBJS=$ac_ltlibobjs -: "${CONFIG_STATUS=./config.status}" +: ${CONFIG_STATUS=./config.status} ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" @@ -33785,7 +33765,6 @@ fi IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. -as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -34093,7 +34072,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # values after options handling. ac_log=" This file was extended by OpenJDK $as_me jdk8, which was -generated by GNU Autoconf 2.68. Invocation command line was +generated by GNU Autoconf 2.67. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -34156,7 +34135,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ OpenJDK config.status jdk8 -configured by $0, generated by GNU Autoconf 2.68, +configured by $0, generated by GNU Autoconf 2.67, with options \\"\$ac_cs_config\\" Copyright (C) 2010 Free Software Foundation, Inc. @@ -34285,7 +34264,7 @@ do "$OUTPUT_ROOT/spec.sh") CONFIG_FILES="$CONFIG_FILES $OUTPUT_ROOT/spec.sh:$AUTOCONF_DIR/spec.sh.in" ;; "$OUTPUT_ROOT/Makefile") CONFIG_FILES="$CONFIG_FILES $OUTPUT_ROOT/Makefile:$AUTOCONF_DIR/Makefile.in" ;; - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;; esac done @@ -34307,10 +34286,9 @@ fi # after its creation but before its name has been assigned to `$tmp'. $debug || { - tmp= ac_tmp= + tmp= trap 'exit_status=$? - : "${ac_tmp:=$tmp}" - { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } @@ -34318,13 +34296,12 @@ $debug || { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -d "$tmp" + test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 -ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. @@ -34346,7 +34323,7 @@ else ac_cs_awk_cr=$ac_cr fi -echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +echo 'BEGIN {' >"$tmp/subs1.awk" && _ACEOF @@ -34374,7 +34351,7 @@ done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +cat >>"\$tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h @@ -34422,7 +34399,7 @@ t delim rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK -cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && +cat >>"\$tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" @@ -34454,7 +34431,7 @@ if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat -fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ +fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF @@ -34488,7 +34465,7 @@ fi # test -n "$CONFIG_FILES" # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then -cat >"$ac_tmp/defines.awk" <<\_ACAWK || +cat >"$tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF @@ -34500,8 +34477,8 @@ _ACEOF # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do - ac_tt=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_tt"; then + ac_t=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_t"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 @@ -34602,7 +34579,7 @@ do esac case $ac_mode$ac_tag in :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac @@ -34621,7 +34598,7 @@ do for ac_f do case $ac_f in - -) ac_f="$ac_tmp/stdin";; + -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. @@ -34630,7 +34607,7 @@ do [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" @@ -34656,8 +34633,8 @@ $as_echo "$as_me: creating $ac_file" >&6;} esac case $ac_tag in - *:-:* | *:-) cat >"$ac_tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + *:-:* | *:-) cat >"$tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac @@ -34782,22 +34759,21 @@ s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t $ac_datarootdir_hack " -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ - >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ - "$ac_tmp/out"`; test -z "$ac_out"; } && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} - rm -f "$ac_tmp/stdin" + rm -f "$tmp/stdin" case $ac_file in - -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; - *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + -) cat "$tmp/out" && rm -f "$tmp/out";; + *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; @@ -34808,20 +34784,20 @@ which seems to be undefined. Please make sure it is defined" >&2;} if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" - } >"$ac_tmp/config.h" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" + } >"$tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" - mv "$ac_tmp/config.h" "$ac_file" \ + mv "$tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; diff --git a/common/autoconf/platform.m4 b/common/autoconf/platform.m4 index 889b99ed727..ed2581c1005 100644 --- a/common/autoconf/platform.m4 +++ b/common/autoconf/platform.m4 @@ -412,17 +412,16 @@ AC_DEFUN([PLATFORM_SET_COMPILER_TARGET_BITS_FLAGS], [ # keep track of c/cxx flags that we added outselves... # to prevent emitting warning... - ADDED_CFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" - ADDED_CXXFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" - ADDED_LDFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" + TARGET_BITS_FLAG="-m${OPENJDK_TARGET_CPU_BITS}" + AC_SUBST(TARGET_BITS_FLAG) - CFLAGS="${CFLAGS}${ADDED_CFLAGS}" - CXXFLAGS="${CXXFLAGS}${ADDED_CXXFLAGS}" - LDFLAGS="${LDFLAGS}${ADDED_LDFLAGS}" + CFLAGS="${CFLAGS} ${TARGET_BITS_FLAG}" + CXXFLAGS="${CXXFLAGS} ${TARGET_BITS_FLAG}" + LDFLAGS="${LDFLAGS} ${TARGET_BITS_FLAG}" - CFLAGS_JDK="${CFLAGS_JDK}${ADDED_CFLAGS}" - CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}" - LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}" + CFLAGS_JDK="${CFLAGS_JDK} ${TARGET_BITS_FLAG}" + CXXFLAGS_JDK="${CXXFLAGS_JDK} ${TARGET_BITS_FLAG}" + LDFLAGS_JDK="${LDFLAGS_JDK} ${TARGET_BITS_FLAG}" ]) AC_DEFUN_ONCE([PLATFORM_SETUP_OPENJDK_TARGET_BITS], diff --git a/common/autoconf/spec.gmk.in b/common/autoconf/spec.gmk.in index c30fd35dc18..d2ffb614bcc 100644 --- a/common/autoconf/spec.gmk.in +++ b/common/autoconf/spec.gmk.in @@ -304,6 +304,7 @@ MACOSX_VERSION_MIN=@MACOSX_VERSION_MIN@ COMPILER_TYPE:=@COMPILER_TYPE@ COMPILER_NAME:=@COMPILER_NAME@ +TARGET_BITS_FLAG=@TARGET_BITS_FLAG@ COMPILER_SUPPORTS_TARGET_BITS_FLAG=@COMPILER_SUPPORTS_TARGET_BITS_FLAG@ CC_OUT_OPTION:=@CC_OUT_OPTION@ From 034d08cfbd52cb7a77d2b1fa83b7745d6bb6d5e4 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 15 Aug 2013 09:25:23 -0700 Subject: [PATCH 041/102] Added tag jdk8-b103 for changeset 5e42d75f3223 --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index b53d6e5d657..456aa0fa60e 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -224,3 +224,4 @@ a1c1e8bf71f354f3aec0214cf13d6668811e021d jdk8-b97 d2dcb110e9dbaf9903c05b211df800e78e4b394e jdk8-b100 9f74a220677dc265a724515d8e2617548cef62f1 jdk8-b101 5eb3c1dc348f72a7f84f7d9d07834e8bbe09a799 jdk8-b102 +b7e64be81c8a7690703df5711f4fc2375da8a9cb jdk8-b103 From d48217e6124de01b48d006bd422d6c31c68cfa15 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 15 Aug 2013 09:25:27 -0700 Subject: [PATCH 042/102] Added tag jdk8-b103 for changeset 28e832b479d2 --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index 83e58a77cfe..6aa967721af 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -224,3 +224,4 @@ c8286839d0df04aba819ec4bef12b86babccf30e jdk8-b90 8d492f1dfd1b131a4c7886ee6b59528609f7e4fe jdk8-b100 a013024b07475782f1fa8e196e950b34b4077663 jdk8-b101 528c7e76eaeee022817ee085668459bc97cf5665 jdk8-b102 +49c4a777fdfd648d4c3fffc940fdb97a23108ca8 jdk8-b103 From e50bff5642f615658228cbc54ee096f51ec3f6bf Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 15 Aug 2013 09:25:33 -0700 Subject: [PATCH 043/102] Added tag jdk8-b103 for changeset 31869efc272a --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index cdd98f7b367..5acf466da51 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -367,3 +367,4 @@ f6921c876db192bba389cec062855a66372da01c jdk8-b101 530fe88b3b2c710f42810b3580d86a0d83ad6c1c hs25-b44 c4697c1c448416108743b59118b4a2498b339d0c jdk8-b102 7f55137d6aa81efc6eb0035813709f2cb6a26b8b hs25-b45 +6f9be7f87b9653e94fd8fb3070891a0cc91b15bf jdk8-b103 From 34c5c0e63804e6b2bb2e92306df174879d348887 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 15 Aug 2013 09:25:42 -0700 Subject: [PATCH 044/102] Added tag jdk8-b103 for changeset 1317035e27c5 --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index e0c06d60dc2..03148a2fdb0 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -224,3 +224,4 @@ adf49c3ef83c160d53ece623049b2cdccaf78fc7 jdk8-b99 5d1974c1d7b9a86431bc253dc5a6a52d4586622e jdk8-b100 0a7432f898e579ea35e8c51e3edab37f949168e4 jdk8-b101 7cffafa606e9fb865e7b5e6a56e0a681ce5cf617 jdk8-b102 +b1ceab582fc6d795b20aaa8a3fde2eba34af9399 jdk8-b103 From 9e1b038ef228958a8571b07507e02d22874ce18b Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 15 Aug 2013 09:25:44 -0700 Subject: [PATCH 045/102] Added tag jdk8-b103 for changeset bf2d11458125 --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 12637ee84ca..bc095c0cca8 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -224,3 +224,4 @@ b1fb4612a2caea52b5661b87509e560fa044b194 jdk8-b98 4fd722afae5c02f00bbd44c3a34425ee474afb1c jdk8-b100 60b623a361642a0f5aef5f06dad9e5f279b9d9a9 jdk8-b101 988a5f2ac559dcab05698b8a8633aa453e012260 jdk8-b102 +6cdc6ed987801c175a1217d0d3e53c3bd69ba52e jdk8-b103 From b6b9364384492b5c9a7eb041ed32cfeaa71a3565 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 15 Aug 2013 09:25:49 -0700 Subject: [PATCH 046/102] Added tag jdk8-b103 for changeset 49d8688ac040 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index f680ba06806..b185182241f 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -224,3 +224,4 @@ c4908732fef5235f1b98cafe0ce507771ef7892c jdk8-b98 5be9c5bfcfe9b2a40412b4fb364377d49de014eb jdk8-b100 6901612328239fbd471d20823113c1cf3fdaebee jdk8-b101 8ed8e2b4b90e0ac9aa5b3efef51cd576a9db96a9 jdk8-b102 +e0f6039c0290b7381042a6fec3100a69a5a67e37 jdk8-b103 From 4d93dffa7b79864446bcf2daccc8da4a5ea49c21 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 15 Aug 2013 09:26:00 -0700 Subject: [PATCH 047/102] Added tag jdk8-b103 for changeset 30c8df7a1168 --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index e78fa28b744..42ea6c743db 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -224,3 +224,4 @@ ce5a90df517bdceb2739d7dd3e6764b070def802 jdk8-b98 82f68da70e471ee5640016e3f38c014347a5c785 jdk8-b100 0324dbf07b0f1cc51ad9fa18976489d02d23b60d jdk8-b101 453a305e116507847cc6577b80b4d9794bcb08bf jdk8-b102 +76cfe7c61f2575ea5400845b8e80dab6f4b1d7d0 jdk8-b103 From db0ec61ffd5af35a87fadb7f990c5448c2302574 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 15 Aug 2013 09:26:02 -0700 Subject: [PATCH 048/102] Added tag jdk8-b103 for changeset 1f4e22f16147 --- nashorn/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/nashorn/.hgtags b/nashorn/.hgtags index e918394eb1a..0c5b8ca45af 100644 --- a/nashorn/.hgtags +++ b/nashorn/.hgtags @@ -212,3 +212,4 @@ d6bd440ac5b97bb1205b6c3274569c1cfe626723 jdk8-b96 598321c438b52d9408a2671fb3fc2b2947d0f654 jdk8-b100 a302b05d0ee460679501dc01004f70eb395fadf5 jdk8-b101 e966ff0a3ffef8a687eaf5a14167bb595b623d02 jdk8-b102 +414203de4374e1964a9918c38a95fb245010a9f1 jdk8-b103 From bce847b2be908d3183c0c8c22d14fb22b3b94323 Mon Sep 17 00:00:00 2001 From: Jennifer Godinez Date: Thu, 15 Aug 2013 11:56:33 -0700 Subject: [PATCH 049/102] 8023045: [MacOSX] PrinterIOException when printing a JComponent Reviewed-by: bae, jchen --- .../share/classes/sun/print/PSPrinterJob.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/jdk/src/share/classes/sun/print/PSPrinterJob.java b/jdk/src/share/classes/sun/print/PSPrinterJob.java index c4bcc23aa02..30777b3cefe 100644 --- a/jdk/src/share/classes/sun/print/PSPrinterJob.java +++ b/jdk/src/share/classes/sun/print/PSPrinterJob.java @@ -339,6 +339,8 @@ public class PSPrinterJob extends RasterPrinterJob { */ private static Properties mFontProps = null; + private static boolean isMac; + /* Class static initialiser block */ static { //enable priviledges so initProps can access system properties, @@ -347,6 +349,8 @@ public class PSPrinterJob extends RasterPrinterJob { new java.security.PrivilegedAction() { public Object run() { mFontProps = initProps(); + String osName = System.getProperty("os.name"); + isMac = osName.startsWith("Mac"); return null; } }); @@ -473,6 +477,12 @@ public class PSPrinterJob extends RasterPrinterJob { PrintService pServ = getPrintService(); if (pServ != null) { mDestination = pServ.getName(); + if (isMac) { + PrintServiceAttributeSet psaSet = pServ.getAttributes() ; + if (psaSet != null) { + mDestination = psaSet.get(PrinterName.class).toString(); + } + } } } } @@ -771,6 +781,12 @@ public class PSPrinterJob extends RasterPrinterJob { PrintService pServ = getPrintService(); if (pServ != null) { mDestination = pServ.getName(); + if (isMac) { + PrintServiceAttributeSet psaSet = pServ.getAttributes(); + if (psaSet != null) { + mDestination = psaSet.get(PrinterName.class).toString() ; + } + } } PrinterSpooler spooler = new PrinterSpooler(); java.security.AccessController.doPrivileged(spooler); From c70766c84b27376e845a93d62871bb9a27a5698b Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Fri, 16 Aug 2013 04:14:13 -0700 Subject: [PATCH 050/102] Added tag hs25-b46 for changeset 33c42f8baa1d --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 5acf466da51..b58c3218710 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -368,3 +368,4 @@ f6921c876db192bba389cec062855a66372da01c jdk8-b101 c4697c1c448416108743b59118b4a2498b339d0c jdk8-b102 7f55137d6aa81efc6eb0035813709f2cb6a26b8b hs25-b45 6f9be7f87b9653e94fd8fb3070891a0cc91b15bf jdk8-b103 +580430d131ccd475e2f2ad4006531b8c4813d102 hs25-b46 From f09520a064614fa8fd83ad9735d9a5c8ff6c5a12 Mon Sep 17 00:00:00 2001 From: Vadim Pakhnushev Date: Fri, 16 Aug 2013 15:57:28 +0400 Subject: [PATCH 051/102] 8013446: [parfait] Memory leak in jdk/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c Reviewed-by: bae, prr --- .../windows/native/sun/java2d/opengl/WGLSurfaceData.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/jdk/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c b/jdk/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c index ee553224b25..ffcb95b0af5 100644 --- a/jdk/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c +++ b/jdk/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c @@ -67,14 +67,15 @@ Java_sun_java2d_opengl_WGLSurfaceData_initOps(JNIEnv *env, jobject wglsd, J2dTraceLn(J2D_TRACE_INFO, "WGLSurfaceData_initOps"); - if (oglsdo == NULL) { - JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed."); - return; - } if (wglsdo == NULL) { JNU_ThrowOutOfMemoryError(env, "creating native wgl ops"); return; } + if (oglsdo == NULL) { + free(wglsdo); + JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed."); + return; + } oglsdo->privOps = wglsdo; From 90882f83e0aab8474bb753dc8bb6a5ef78a91f4c Mon Sep 17 00:00:00 2001 From: Ivan Gerasimov Date: Fri, 16 Aug 2013 14:43:38 +0200 Subject: [PATCH 052/102] 8023156: make dist-clean should remove javacservers directory Reviewed-by: erikj --- common/makefiles/Main.gmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/makefiles/Main.gmk b/common/makefiles/Main.gmk index 1214ce56427..dd99df2d526 100644 --- a/common/makefiles/Main.gmk +++ b/common/makefiles/Main.gmk @@ -204,7 +204,7 @@ clean: clean-langtools clean-corba clean-jaxp clean-jaxws clean-hotspot clean-jd # If the output directory was created by configure and now becomes empty, remove it as well. # FIXME: tmp should not be here, fix ResetTimers instead. And remove spec.sh! dist-clean: clean - @($(CD) $(OUTPUT_ROOT) && $(RM) -r *spec.gmk config.* configure-arguments Makefile compare.sh spec.sh tmp) + @($(CD) $(OUTPUT_ROOT) && $(RM) -r *spec.gmk config.* configure-arguments Makefile compare.sh spec.sh tmp javacservers) @$(if $(filter $(CONF_NAME),$(notdir $(OUTPUT_ROOT))), \ if test "x`$(LS) $(OUTPUT_ROOT)`" != x; then \ $(ECHO) "Warning: Not removing non-empty configuration directory for '$(CONF_NAME)'" ;\ From 79a458c3d41222c2ba310dafbe4ac47625637b27 Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Fri, 16 Aug 2013 16:52:53 +0400 Subject: [PATCH 053/102] 8020051: [TEST_BUG] Testcase for 8004859 has a typo Reviewed-by: anthony --- jdk/test/java/awt/Graphics2D/Test8004859/Test8004859.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/test/java/awt/Graphics2D/Test8004859/Test8004859.java b/jdk/test/java/awt/Graphics2D/Test8004859/Test8004859.java index 73e0acaeace..8cdb83feaa3 100644 --- a/jdk/test/java/awt/Graphics2D/Test8004859/Test8004859.java +++ b/jdk/test/java/awt/Graphics2D/Test8004859/Test8004859.java @@ -37,7 +37,7 @@ import sun.java2d.SunGraphics2D; */ public final class Test8004859 { - private static Shape[] clips = {new Rectangle(0, 0, 1, 1), new Rectangle( + private static Shape[] clips = {new Rectangle(0, 0, -1, -1), new Rectangle( 100, 100, -100, -100)}; private static boolean status = true; From 0b736d6f91e7547847aa33af3092eb912c5c771a Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Fri, 16 Aug 2013 20:56:46 +0400 Subject: [PATCH 054/102] 8006085: [findbugs] a warning on javax.sound.sampled.DataLine$Info constructor Reviewed-by: art, prr --- .../classes/javax/sound/sampled/DataLine.java | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/jdk/src/share/classes/javax/sound/sampled/DataLine.java b/jdk/src/share/classes/javax/sound/sampled/DataLine.java index f74953b19db..8b3b1809ae0 100644 --- a/jdk/src/share/classes/javax/sound/sampled/DataLine.java +++ b/jdk/src/share/classes/javax/sound/sampled/DataLine.java @@ -25,6 +25,8 @@ package javax.sound.sampled; +import java.util.Arrays; + /** * DataLine adds media-related functionality to its * superinterface, {@link Line}. This functionality includes @@ -282,9 +284,9 @@ public interface DataLine extends Line { */ public static class Info extends Line.Info { - private AudioFormat[] formats; - private int minBufferSize; - private int maxBufferSize; + private final AudioFormat[] formats; + private final int minBufferSize; + private final int maxBufferSize; /** * Constructs a data line's info object from the specified information, @@ -304,7 +306,7 @@ public interface DataLine extends Line { if (formats == null) { this.formats = new AudioFormat[0]; } else { - this.formats = formats; + this.formats = Arrays.copyOf(formats, formats.length); } this.minBufferSize = minBufferSize; @@ -329,8 +331,7 @@ public interface DataLine extends Line { if (format == null) { this.formats = new AudioFormat[0]; } else { - AudioFormat[] formats = { format }; - this.formats = formats; + this.formats = new AudioFormat[]{format}; } this.minBufferSize = bufferSize; @@ -373,10 +374,7 @@ public interface DataLine extends Line { * @see #isFormatSupported(AudioFormat) */ public AudioFormat[] getFormats() { - - AudioFormat[] returnedArray = new AudioFormat[formats.length]; - System.arraycopy(formats, 0, returnedArray, 0, formats.length); - return returnedArray; + return Arrays.copyOf(formats, formats.length); } /** From 88cb86076a42d8fc5ccafd03a3021d4b586ce669 Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Fri, 16 Aug 2013 21:18:21 +0400 Subject: [PATCH 055/102] 8005980: [findbugs] More com.sun.media.sound.* warnings Reviewed-by: art, prr --- .../com/sun/media/sound/DataPusher.java | 26 ++++++++++++------- .../media/sound/ModelStandardDirector.java | 19 +++++++------- .../sound/ModelStandardIndexedDirector.java | 25 +++++++++--------- .../com/sun/media/sound/SoftMixingClip.java | 6 +++-- .../share/classes/sun/audio/AudioData.java | 20 +++++++------- 5 files changed, 55 insertions(+), 41 deletions(-) diff --git a/jdk/src/share/classes/com/sun/media/sound/DataPusher.java b/jdk/src/share/classes/com/sun/media/sound/DataPusher.java index 814a0150ba7..95c0ff9f050 100644 --- a/jdk/src/share/classes/com/sun/media/sound/DataPusher.java +++ b/jdk/src/share/classes/com/sun/media/sound/DataPusher.java @@ -25,6 +25,8 @@ package com.sun.media.sound; +import java.util.Arrays; + import javax.sound.sampled.*; /** @@ -46,11 +48,11 @@ public final class DataPusher implements Runnable { private final AudioFormat format; // stream as source data - private AudioInputStream ais = null; + private final AudioInputStream ais; // byte array as source data - private byte[] audioData = null; - private int audioDataByteLength = 0; + private final byte[] audioData; + private final int audioDataByteLength; private int pos; private int newPos = -1; private boolean looping; @@ -67,16 +69,22 @@ public final class DataPusher implements Runnable { private final int BUFFER_SIZE = 16384; public DataPusher(SourceDataLine sourceLine, AudioFormat format, byte[] audioData, int byteLength) { - this.audioData = audioData; - this.audioDataByteLength = byteLength; - this.format = format; - this.source = sourceLine; + this(sourceLine, format, null, audioData, byteLength); } public DataPusher(SourceDataLine sourceLine, AudioInputStream ais) { + this(sourceLine, ais.getFormat(), ais, null, 0); + } + + private DataPusher(final SourceDataLine source, final AudioFormat format, + final AudioInputStream ais, final byte[] audioData, + final int audioDataByteLength) { + this.source = source; + this.format = format; this.ais = ais; - this.format = ais.getFormat(); - this.source = sourceLine; + this.audioDataByteLength = audioDataByteLength; + this.audioData = audioData == null ? null : Arrays.copyOf(audioData, + audioData.length); } public synchronized void start() { diff --git a/jdk/src/share/classes/com/sun/media/sound/ModelStandardDirector.java b/jdk/src/share/classes/com/sun/media/sound/ModelStandardDirector.java index e64d94cd472..115f28a6fad 100644 --- a/jdk/src/share/classes/com/sun/media/sound/ModelStandardDirector.java +++ b/jdk/src/share/classes/com/sun/media/sound/ModelStandardDirector.java @@ -24,6 +24,8 @@ */ package com.sun.media.sound; +import java.util.Arrays; + /** * A standard director who chooses performers * by there keyfrom,keyto,velfrom,velto properties. @@ -32,17 +34,16 @@ package com.sun.media.sound; */ public final class ModelStandardDirector implements ModelDirector { - ModelPerformer[] performers; - ModelDirectedPlayer player; - boolean noteOnUsed = false; - boolean noteOffUsed = false; + private final ModelPerformer[] performers; + private final ModelDirectedPlayer player; + private boolean noteOnUsed = false; + private boolean noteOffUsed = false; - public ModelStandardDirector(ModelPerformer[] performers, - ModelDirectedPlayer player) { - this.performers = performers; + public ModelStandardDirector(final ModelPerformer[] performers, + final ModelDirectedPlayer player) { + this.performers = Arrays.copyOf(performers, performers.length); this.player = player; - for (int i = 0; i < performers.length; i++) { - ModelPerformer p = performers[i]; + for (final ModelPerformer p : this.performers) { if (p.isReleaseTriggered()) { noteOffUsed = true; } else { diff --git a/jdk/src/share/classes/com/sun/media/sound/ModelStandardIndexedDirector.java b/jdk/src/share/classes/com/sun/media/sound/ModelStandardIndexedDirector.java index a5171eb1fce..a0c2aff39dd 100644 --- a/jdk/src/share/classes/com/sun/media/sound/ModelStandardIndexedDirector.java +++ b/jdk/src/share/classes/com/sun/media/sound/ModelStandardIndexedDirector.java @@ -24,6 +24,8 @@ */ package com.sun.media.sound; +import java.util.Arrays; + /** * A standard indexed director who chooses performers * by there keyfrom,keyto,velfrom,velto properties. @@ -32,22 +34,21 @@ package com.sun.media.sound; */ public final class ModelStandardIndexedDirector implements ModelDirector { - ModelPerformer[] performers; - ModelDirectedPlayer player; - boolean noteOnUsed = false; - boolean noteOffUsed = false; + private final ModelPerformer[] performers; + private final ModelDirectedPlayer player; + private boolean noteOnUsed = false; + private boolean noteOffUsed = false; // Variables needed for index - byte[][] trantables; - int[] counters; - int[][] mat; + private byte[][] trantables; + private int[] counters; + private int[][] mat; - public ModelStandardIndexedDirector(ModelPerformer[] performers, - ModelDirectedPlayer player) { - this.performers = performers; + public ModelStandardIndexedDirector(final ModelPerformer[] performers, + final ModelDirectedPlayer player) { + this.performers = Arrays.copyOf(performers, performers.length); this.player = player; - for (int i = 0; i < performers.length; i++) { - ModelPerformer p = performers[i]; + for (final ModelPerformer p : this.performers) { if (p.isReleaseTriggered()) { noteOffUsed = true; } else { diff --git a/jdk/src/share/classes/com/sun/media/sound/SoftMixingClip.java b/jdk/src/share/classes/com/sun/media/sound/SoftMixingClip.java index bcf67f3b554..748b0eb3e1a 100644 --- a/jdk/src/share/classes/com/sun/media/sound/SoftMixingClip.java +++ b/jdk/src/share/classes/com/sun/media/sound/SoftMixingClip.java @@ -38,7 +38,7 @@ import javax.sound.sampled.LineEvent; import javax.sound.sampled.LineUnavailableException; /** - * Clip implemention for the SoftMixingMixer. + * Clip implementation for the SoftMixingMixer. * * @author Karl Helgason */ @@ -357,7 +357,9 @@ public final class SoftMixingClip extends SoftMixingDataLine implements Clip { throw new IllegalArgumentException( "Buffer size does not represent an integral number of sample frames!"); - this.data = data; + if (data != null) { + this.data = Arrays.copyOf(data, data.length); + } this.offset = offset; this.bufferSize = bufferSize; this.format = format; diff --git a/jdk/src/share/classes/sun/audio/AudioData.java b/jdk/src/share/classes/sun/audio/AudioData.java index 023fd3a93f4..67038769462 100644 --- a/jdk/src/share/classes/sun/audio/AudioData.java +++ b/jdk/src/share/classes/sun/audio/AudioData.java @@ -26,6 +26,8 @@ package sun.audio; import java.io.*; +import java.util.Arrays; + import javax.sound.sampled.*; @@ -65,12 +67,11 @@ public final class AudioData { /** * Constructor */ - public AudioData(byte buffer[]) { - - this.buffer = buffer; - // if we cannot extract valid format information, we resort to assuming the data will be 8k mono u-law - // in order to provide maximal backwards compatibility.... - this.format = DEFAULT_FORMAT; + public AudioData(final byte[] buffer) { + // if we cannot extract valid format information, we resort to assuming + // the data will be 8k mono u-law in order to provide maximal backwards + // compatibility.... + this(DEFAULT_FORMAT, buffer); // okay, we need to extract the format and the byte buffer of data try { @@ -90,9 +91,10 @@ public final class AudioData { * Non-public constructor; this is the one we use in ADS and CADS * constructors. */ - AudioData(AudioFormat format, byte[] buffer) { - + AudioData(final AudioFormat format, final byte[] buffer) { this.format = format; - this.buffer = buffer; + if (buffer != null) { + this.buffer = Arrays.copyOf(buffer, buffer.length); + } } } From a29db3a5b80f7f1b1d1abe939c1d278832205fc3 Mon Sep 17 00:00:00 2001 From: Anthony Scarpino Date: Fri, 16 Aug 2013 12:31:57 -0700 Subject: [PATCH 056/102] 8022896: test/com/sun/crypto/provider/Cipher/RSA/TestOAEPPadding.java fails Reviewed-by: mullan --- jdk/test/ProblemList.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index c69d0eec963..00a354a7b0d 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -289,9 +289,6 @@ sun/security/krb5/auto/BadKdc2.java solaris-sparcv9 sun/security/krb5/auto/BadKdc3.java solaris-sparcv9 sun/security/krb5/auto/BadKdc4.java solaris-sparcv9 -# 8022896 -com/sun/crypto/provider/Cipher/RSA/TestOAEPPadding.java generic-all - ############################################################################ # jdk_sound From 30a0d25953250ac2b3d14bca34769263d99b68d0 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Mon, 19 Aug 2013 10:31:42 +0200 Subject: [PATCH 057/102] 8021430: 64 bit JDK build fails on windows 7 due to missing corba source files Reviewed-by: tbell, katleman --- common/makefiles/IdlCompilation.gmk | 3 --- 1 file changed, 3 deletions(-) diff --git a/common/makefiles/IdlCompilation.gmk b/common/makefiles/IdlCompilation.gmk index b03ea43a9e5..94cc15476ad 100644 --- a/common/makefiles/IdlCompilation.gmk +++ b/common/makefiles/IdlCompilation.gmk @@ -83,9 +83,6 @@ $(foreach i,2 3 4 5 6 7 8 9 10 11 12 13 14 15, $(if $($i),$1_$(strip $($i)))$(NE $(call LogSetupMacroEntry,SetupIdlCompilation($1),$2,$3,$4,$5,$6,$7,$8,$9,$(10),$(11),$(12),$(13),$(14),$(15)) $(if $(16),$(error Internal makefile error: Too many arguments to SetupIdlCompilation, please update IdlCompilation.gmk)) -# Remove any relative addressing in the paths. -$1_SRC := $$(abspath $$($1_SRC)) -$1_BIN := $$(abspath $$($1_BIN)) # Find all existing java files and existing class files. $$(eval $$(call MakeDir,$$($1_BIN))) $1_SRCS := $$(shell find $$($1_SRC) -name "*.idl") From 0e8b1016432bdd072bc7c6e24e50e5de88ff32e0 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Wed, 21 Aug 2013 09:59:12 +0100 Subject: [PATCH 058/102] 8023351: Add TEST.groups in preparation to simplify rules in jdk/test/Makefile Reviewed-by: lancea, mduigou --- jdk/test/TEST.ROOT | 3 + jdk/test/TEST.groups | 214 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 217 insertions(+) create mode 100644 jdk/test/TEST.groups diff --git a/jdk/test/TEST.ROOT b/jdk/test/TEST.ROOT index 6bf72964f66..0aba9d3bc72 100644 --- a/jdk/test/TEST.ROOT +++ b/jdk/test/TEST.ROOT @@ -9,3 +9,6 @@ othervm.dirs=java/awt java/beans java/rmi javax/accessibility javax/imageio java # Tests that cannot run concurrently exclusiveAccess.dirs=java/rmi/Naming java/util/Currency java/util/prefs sun/management/jmxremote sun/tools/jstatd sun/security/mscapi + +# Group definitions +groups=TEST.groups [closed/TEST.groups] diff --git a/jdk/test/TEST.groups b/jdk/test/TEST.groups new file mode 100644 index 00000000000..0674bdc1d91 --- /dev/null +++ b/jdk/test/TEST.groups @@ -0,0 +1,214 @@ +# Copyright (c) 2013, 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. +# + +jdk_lang = \ + java/lang \ + -java/lang/management \ + -java/lang/instrument \ + sun/invoke \ + sun/misc \ + sun/reflect \ + vm + +jdk_util = \ + java/util \ + sun/util + +jdk_math = \ + java/math + +jdk_io = \ + java/io + +jdk_nio = \ + java/nio \ + sun/nio + +jdk_net = \ + java/net \ + com/sun/net \ + com/oracle/net \ + sun/net + +jdk_time = \ + java/time + +jdk_rmi = \ + java/rmi \ + javax/rmi/ssl \ + sun/rmi + +jdk_security1 = \ + java/security + +jdk_security2 = \ + javax/crypto \ + javax/xml/crypto \ + com/sun/crypto + +jdk_security3 = \ + javax/security \ + com/sun/security \ + com/sun/org/apache/xml/internal/security \ + com/oracle/security \ + sun/security \ + lib/security + +jdk_security = \ + :jdk_security1 \ + :jdk_security2 \ + :jdk_security3 + +jdk_text = \ + java/text \ + sun/text + +jdk_management = \ + java/lang/management \ + com/sun/management \ + sun/management + +jdk_instrument = \ + java/lang/instrument + +jdk_jmx = \ + javax/management \ + com/sun/jmx + +jdk_jdi = \ + com/sun/jdi + +# +# Tool (and tool API) tests are split into core and svc groups +# +core_tools = \ + tools \ + com/sun/tools/extcheck \ + sun/tools/java \ + sun/tools/native2ascii \ + sun/tools/jrunscript + +svc_tools = \ + com/sun/tools/attach \ + com/sun/tracing \ + sun/tools \ + -sun/tools/java \ + -sun/tools/native2ascii \ + -sun/tools/jrunscript \ + sun/jvmstat \ + demo/jvmti + +jdk_tools = \ + :core_tools \ + :svc_tools + +# +# Catch-all for other areas with a small number of tests +# +jdk_other = \ + java/sql \ + javax/sql \ + javax/naming \ + javax/script \ + javax/smartcardio \ + javax/xml \ + -javax/xml/crypto \ + jdk/asm \ + jdk/lambda \ + com/sun/jndi \ + com/sun/corba \ + lib/testlibrary \ + demo/zipfs \ + sample + +# +# SCTP is its own group as it is highly sensitive to kernel/network config +# +jdk_sctp = \ + com/sun/nio/sctp + + +# +# core group to run all core area tests +# +jdk_core = \ + :jdk_lang \ + :jdk_util \ + :jdk_math \ + :jdk_io \ + :jdk_nio \ + :jdk_net \ + :jdk_rmi \ + :jdk_time \ + :jdk_security \ + :jdk_text \ + :core_tools \ + :jdk_other + +# +# svc group to run all serviceability area tests +# +jdk_svc = \ + :jdk_management \ + :jdk_instrument \ + :jdk_jmx \ + :jdk_jdi \ + :svc_tools + +############################# + +# +# Client area groups +# + +jdk_awt = \ + java/awt \ + com/sun/awt \ + com/apple/eawt \ + sun/awt + +jdk_2d = \ + javax/print \ + sun/pisces \ + sun/java2d + +jdk_beans = \ + java/beans + +jdk_swing = \ + javax/accessibility \ + javax/swing \ + com/sun/java/swing + +jdk_sound = \ + javax/sound + +jdk_imageio = \ + javax/imageio + +jdk_desktop = \ + :jdk_awt \ + :jdk_2d \ + :jdk_beans \ + :jdk_swing \ + :jdk_sound \ + :jdk_imageio From bf1e11707b5305407f23099bd5bf07beed50a742 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Mon, 19 Aug 2013 12:57:17 +0200 Subject: [PATCH 059/102] 6358357: Division by zero in Threads tab when shrinking jconsole window Reviewed-by: mchung, leifs, jbachorik --- jdk/src/share/classes/sun/tools/jconsole/Plotter.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/classes/sun/tools/jconsole/Plotter.java b/jdk/src/share/classes/sun/tools/jconsole/Plotter.java index 793b0ea263d..acfd005dd0b 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/Plotter.java +++ b/jdk/src/share/classes/sun/tools/jconsole/Plotter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2013, 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 @@ -337,6 +337,13 @@ public class Plotter extends JComponent public void paintComponent(Graphics g) { super.paintComponent(g); + int width = getWidth()-rightMargin-leftMargin-10; + int height = getHeight()-topMargin-bottomMargin; + if (width <= 0 || height <= 0) { + // not enough room to paint anything + return; + } + Color oldColor = g.getColor(); Font oldFont = g.getFont(); Color fg = getForeground(); From 1dd31aff635cafece8b4c7686b4eeb5abb1f1b57 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Mon, 19 Aug 2013 03:58:47 -0700 Subject: [PATCH 060/102] 8017580: Crash in font loading code on Linux (due to use of reflection) Reviewed-by: bae, vadim --- jdk/src/share/native/sun/font/sunFont.c | 25 +++++++++++++++++----- jdk/src/share/native/sun/font/sunfontids.h | 2 +- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/jdk/src/share/native/sun/font/sunFont.c b/jdk/src/share/native/sun/font/sunFont.c index 95927b003d7..70bfee8a102 100644 --- a/jdk/src/share/native/sun/font/sunFont.c +++ b/jdk/src/share/native/sun/font/sunFont.c @@ -71,13 +71,17 @@ JNIEXPORT jlong JNICALL Java_sun_font_NullFontScaler_getGlyphImage void initLCDGammaTables(); /* placeholder for extern variable */ +static int initialisedFontIDs = 0; FontManagerNativeIDs sunFontIDs; -JNIEXPORT void JNICALL -Java_sun_font_SunFontManager_initIDs - (JNIEnv *env, jclass cls) { +static void initFontIDs(JNIEnv *env) { - jclass tmpClass = (*env)->FindClass(env, "sun/font/TrueTypeFont"); + jclass tmpClass; + + if (initialisedFontIDs) { + return; + } + tmpClass = (*env)->FindClass(env, "sun/font/TrueTypeFont"); sunFontIDs.ttReadBlockMID = (*env)->GetMethodID(env, tmpClass, "readBlock", "(Ljava/nio/ByteBuffer;II)I"); @@ -173,9 +177,20 @@ Java_sun_font_SunFontManager_initIDs (*env)->GetFieldID(env, tmpClass, "lcdSubPixPos", "Z"); initLCDGammaTables(); + + initialisedFontIDs = 1; } -JNIEXPORT FontManagerNativeIDs getSunFontIDs() { +JNIEXPORT void JNICALL +Java_sun_font_SunFontManager_initIDs + (JNIEnv *env, jclass cls) { + + initFontIDs(env); +} + +JNIEXPORT FontManagerNativeIDs getSunFontIDs(JNIEnv *env) { + + initFontIDs(env); return sunFontIDs; } diff --git a/jdk/src/share/native/sun/font/sunfontids.h b/jdk/src/share/native/sun/font/sunfontids.h index 211ab7a4c72..a7e4290ad40 100644 --- a/jdk/src/share/native/sun/font/sunfontids.h +++ b/jdk/src/share/native/sun/font/sunfontids.h @@ -84,7 +84,7 @@ typedef struct FontManagerNativeIDs { /* Note: we share variable in the context of fontmanager lib but we need access method to use it from separate rasterizer lib */ extern FontManagerNativeIDs sunFontIDs; -JNIEXPORT FontManagerNativeIDs getSunFontIDs(); +JNIEXPORT FontManagerNativeIDs getSunFontIDs(JNIEnv* env); #ifdef __cplusplus } From 99f960f2ef451260691e4a0ccbf57f28bdc28395 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Mon, 19 Aug 2013 16:21:49 +0200 Subject: [PATCH 061/102] 6417721: Thread list should not allow multiple selection Reviewed-by: alanb, jbachorik, sjiang --- jdk/src/share/classes/sun/tools/jconsole/ThreadTab.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/src/share/classes/sun/tools/jconsole/ThreadTab.java b/jdk/src/share/classes/sun/tools/jconsole/ThreadTab.java index 354f351f750..3932ffa145e 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/ThreadTab.java +++ b/jdk/src/share/classes/sun/tools/jconsole/ThreadTab.java @@ -595,6 +595,7 @@ class ThreadTab extends Tab implements ActionListener, DocumentListener, ListSel setBorder(thinEmptyBorder); + setSelectionMode(ListSelectionModel.SINGLE_SELECTION); addListSelectionListener(ThreadTab.this); setCellRenderer(new DefaultListCellRenderer() { public Component getListCellRendererComponent(JList list, Object value, int index, From 1d3c8aa7088a6c323b34f78644e48d56843e625f Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Mon, 19 Aug 2013 16:41:21 +0200 Subject: [PATCH 062/102] 6800801: NPE in JConsole when using Nimbus L&F Reviewed-by: alanb, sjiang --- .../share/classes/sun/tools/jconsole/ConnectDialog.java | 9 +++++++-- jdk/src/share/classes/sun/tools/jconsole/VMPanel.java | 8 +++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/jdk/src/share/classes/sun/tools/jconsole/ConnectDialog.java b/jdk/src/share/classes/sun/tools/jconsole/ConnectDialog.java index ea3f8366766..3198fd6cd6a 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/ConnectDialog.java +++ b/jdk/src/share/classes/sun/tools/jconsole/ConnectDialog.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2013, 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 @@ -268,8 +268,13 @@ public class ConnectDialog extends InternalDialog public void revalidate() { // Adjust some colors + Color disabledForeground = UIManager.getColor("Label.disabledForeground"); + if (disabledForeground == null) { + // fall back for Nimbus that doesn't support 'Label.disabledForeground' + disabledForeground = UIManager.getColor("Label.disabledText"); + } hintTextColor = - ensureContrast(UIManager.getColor("Label.disabledForeground"), + ensureContrast(disabledForeground, UIManager.getColor("Panel.background")); disabledTableCellColor = ensureContrast(new Color(0x808080), diff --git a/jdk/src/share/classes/sun/tools/jconsole/VMPanel.java b/jdk/src/share/classes/sun/tools/jconsole/VMPanel.java index b7a0f5b410b..1561b9cc5bb 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/VMPanel.java +++ b/jdk/src/share/classes/sun/tools/jconsole/VMPanel.java @@ -153,9 +153,11 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { // in order to reserve space for the connect toggle. public void setUI(TabbedPaneUI ui) { Insets insets = (Insets) UIManager.getLookAndFeelDefaults().get("TabbedPane.tabAreaInsets"); - insets = (Insets) insets.clone(); - insets.right += connectedIcon24.getIconWidth() + 8; - UIManager.put("TabbedPane.tabAreaInsets", insets); + if (insets != null) { + insets = (Insets) insets.clone(); + insets.right += connectedIcon24.getIconWidth() + 8; + UIManager.put("TabbedPane.tabAreaInsets", insets); + } super.setUI(ui); } From 910c4e1d3467206e2bf8696124018fd20adc64a7 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Mon, 19 Aug 2013 13:11:03 +0200 Subject: [PATCH 063/102] 7042707: Un-needed mnemonic in JConsole resource file Reviewed-by: mfang, jbachorik --- jdk/src/share/classes/sun/tools/jconsole/Messages.java | 3 +-- .../classes/sun/tools/jconsole/resources/messages.properties | 1 - .../sun/tools/jconsole/resources/messages_ja.properties | 1 - .../sun/tools/jconsole/resources/messages_zh_CN.properties | 1 - 4 files changed, 1 insertion(+), 5 deletions(-) diff --git a/jdk/src/share/classes/sun/tools/jconsole/Messages.java b/jdk/src/share/classes/sun/tools/jconsole/Messages.java index 0e5fd76bd20..eee57adcc25 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/Messages.java +++ b/jdk/src/share/classes/sun/tools/jconsole/Messages.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -146,7 +146,6 @@ final public class Messages { public static String HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME; public static String HELP_ABOUT_DIALOG_MASTHEAD_TITLE; public static String HELP_ABOUT_DIALOG_TITLE; - public static String HELP_ABOUT_DIALOG_USER_GUIDE_LINK; public static String HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL; public static String HELP_MENU_ABOUT_TITLE; public static String HELP_MENU_USER_GUIDE_TITLE; diff --git a/jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties b/jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties index ef0b4f136e4..70ff2f16c6e 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties +++ b/jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties @@ -104,7 +104,6 @@ HELP_ABOUT_DIALOG_JAVA_VERSION=Java VM version:
{0} HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME=Masthead Graphic HELP_ABOUT_DIALOG_MASTHEAD_TITLE=About JConsole HELP_ABOUT_DIALOG_TITLE=JConsole: About -HELP_ABOUT_DIALOG_USER_GUIDE_LINK=JConsole &User Guide:
{0} HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL=http://docs.oracle.com/javase/{0}/docs/technotes/guides/management/jconsole.html HELP_MENU_ABOUT_TITLE=&About JConsole HELP_MENU_USER_GUIDE_TITLE=Online &User Guide diff --git a/jdk/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties b/jdk/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties index 9cc5df8fad8..c66ace77035 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties +++ b/jdk/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties @@ -104,7 +104,6 @@ HELP_ABOUT_DIALOG_JAVA_VERSION=Java VM\u30D0\u30FC\u30B8\u30E7\u30F3:
{0} HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME=\u30DE\u30B9\u30C8\u30D8\u30C3\u30C9\u56F3\u5F62 HELP_ABOUT_DIALOG_MASTHEAD_TITLE=JConsole\u306B\u3064\u3044\u3066 HELP_ABOUT_DIALOG_TITLE=JConsole: \u8A73\u7D30 -HELP_ABOUT_DIALOG_USER_GUIDE_LINK=JConsole\u30E6\u30FC\u30B6\u30FC\u30FB\u30AC\u30A4\u30C9(&U):
{0} HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL=http://docs.oracle.com/javase/{0}/docs/technotes/guides/management/jconsole.html HELP_MENU_ABOUT_TITLE=JConsole\u306B\u3064\u3044\u3066(&A) HELP_MENU_USER_GUIDE_TITLE=\u30AA\u30F3\u30E9\u30A4\u30F3\u30FB\u30E6\u30FC\u30B6\u30FC\u30FB\u30AC\u30A4\u30C9(&U) diff --git a/jdk/src/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties b/jdk/src/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties index d654392edf2..3f782adc620 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties +++ b/jdk/src/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties @@ -104,7 +104,6 @@ HELP_ABOUT_DIALOG_JAVA_VERSION=Java VM \u7248\u672C:
{0} HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME=\u62A5\u5934\u56FE HELP_ABOUT_DIALOG_MASTHEAD_TITLE=\u5173\u4E8E JConsole HELP_ABOUT_DIALOG_TITLE=JConsole: \u5173\u4E8E -HELP_ABOUT_DIALOG_USER_GUIDE_LINK=JConsole \u7528\u6237\u6307\u5357(&U):
{0} HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL=http://docs.oracle.com/javase/{0}/docs/technotes/guides/management/jconsole.html HELP_MENU_ABOUT_TITLE=\u5173\u4E8E JConsole(&A) HELP_MENU_USER_GUIDE_TITLE=\u8054\u673A\u7528\u6237\u6307\u5357(&U) From c2aba135c237eea1e05859802322aa6cb9e565a9 Mon Sep 17 00:00:00 2001 From: Jennifer Godinez Date: Mon, 19 Aug 2013 11:21:19 -0700 Subject: [PATCH 064/102] 8022241: [macosx] [PIT] lookupPrintServices() returns one too long array Reviewed-by: prr, jchen --- .../sun/print/UnixPrintServiceLookup.java | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java b/jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java index 2c2a6406293..54dc8b666fc 100644 --- a/jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java +++ b/jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java @@ -245,7 +245,7 @@ public class UnixPrintServiceLookup extends PrintServiceLookup continue; } if ((defaultPrintService != null) - && printers[p].equals(defaultPrintService.getName())) { + && printers[p].equals(getPrinterDestName(defaultPrintService))) { printerList.add(defaultPrintService); defaultIndex = printerList.size() - 1; } else { @@ -270,11 +270,12 @@ public class UnixPrintServiceLookup extends PrintServiceLookup } else { int j; for (j=0; j Date: Mon, 19 Aug 2013 12:38:56 -0700 Subject: [PATCH 065/102] 8023203: Wrap RandomAccessFile.seek native method into a Java helper method Reviewed-by: alanb, chegar --- jdk/make/java/java/mapfile-vers | 2 +- jdk/makefiles/mapfiles/libjava/mapfile-vers | 2 +- jdk/src/share/classes/java/io/RandomAccessFile.java | 10 +++++++++- jdk/src/share/native/java/io/RandomAccessFile.c | 4 ++-- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/jdk/make/java/java/mapfile-vers b/jdk/make/java/java/mapfile-vers index ca33582de6b..bb06a3d6036 100644 --- a/jdk/make/java/java/mapfile-vers +++ b/jdk/make/java/java/mapfile-vers @@ -100,7 +100,7 @@ SUNWprivate_1.1 { Java_java_io_RandomAccessFile_open; Java_java_io_RandomAccessFile_read; Java_java_io_RandomAccessFile_readBytes; - Java_java_io_RandomAccessFile_seek; + Java_java_io_RandomAccessFile_seek0; Java_java_io_RandomAccessFile_setLength; Java_java_io_RandomAccessFile_write; Java_java_io_RandomAccessFile_writeBytes; diff --git a/jdk/makefiles/mapfiles/libjava/mapfile-vers b/jdk/makefiles/mapfiles/libjava/mapfile-vers index ca33582de6b..bb06a3d6036 100644 --- a/jdk/makefiles/mapfiles/libjava/mapfile-vers +++ b/jdk/makefiles/mapfiles/libjava/mapfile-vers @@ -100,7 +100,7 @@ SUNWprivate_1.1 { Java_java_io_RandomAccessFile_open; Java_java_io_RandomAccessFile_read; Java_java_io_RandomAccessFile_readBytes; - Java_java_io_RandomAccessFile_seek; + Java_java_io_RandomAccessFile_seek0; Java_java_io_RandomAccessFile_setLength; Java_java_io_RandomAccessFile_write; Java_java_io_RandomAccessFile_writeBytes; diff --git a/jdk/src/share/classes/java/io/RandomAccessFile.java b/jdk/src/share/classes/java/io/RandomAccessFile.java index 440cd225c80..fd1c712d1e3 100644 --- a/jdk/src/share/classes/java/io/RandomAccessFile.java +++ b/jdk/src/share/classes/java/io/RandomAccessFile.java @@ -518,7 +518,15 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable { * @exception IOException if {@code pos} is less than * {@code 0} or if an I/O error occurs. */ - public native void seek(long pos) throws IOException; + public void seek(long pos) throws IOException { + if (pos < 0) { + throw new IOException("Negative seek offset"); + } else { + seek0(pos); + } + } + + private native void seek0(long pos) throws IOException; /** * Returns the length of this file. diff --git a/jdk/src/share/native/java/io/RandomAccessFile.c b/jdk/src/share/native/java/io/RandomAccessFile.c index 42733fb0b3c..3251db87fb9 100644 --- a/jdk/src/share/native/java/io/RandomAccessFile.c +++ b/jdk/src/share/native/java/io/RandomAccessFile.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -123,7 +123,7 @@ Java_java_io_RandomAccessFile_length(JNIEnv *env, jobject this) { } JNIEXPORT void JNICALL -Java_java_io_RandomAccessFile_seek(JNIEnv *env, +Java_java_io_RandomAccessFile_seek0(JNIEnv *env, jobject this, jlong pos) { FD fd; From d2f2e6fd4199926ab04bd43f5a7c289943f1597e Mon Sep 17 00:00:00 2001 From: Sean Mullan Date: Mon, 19 Aug 2013 17:17:17 -0400 Subject: [PATCH 066/102] 8016850: JCK javax.security.auth.Policy tests fail when run in Profiles mode Move default javax.security.auth.Policy implementation to compact1 profile Reviewed-by: vinnie --- .../com/sun/security/auth/PolicyFile.java | 1173 +--------------- .../com/sun/security/auth/PolicyParser.java | 964 ------------- .../classes/javax/security/auth/Policy.java | 23 +- .../sun/security/provider/AuthPolicyFile.java | 1195 +++++++++++++++++ .../security/provider}/SubjectCodeSource.java | 31 +- 5 files changed, 1231 insertions(+), 2155 deletions(-) delete mode 100644 jdk/src/share/classes/com/sun/security/auth/PolicyParser.java create mode 100644 jdk/src/share/classes/sun/security/provider/AuthPolicyFile.java rename jdk/src/share/classes/{com/sun/security/auth => sun/security/provider}/SubjectCodeSource.java (93%) diff --git a/jdk/src/share/classes/com/sun/security/auth/PolicyFile.java b/jdk/src/share/classes/com/sun/security/auth/PolicyFile.java index 2ea13fb3169..1df34428514 100644 --- a/jdk/src/share/classes/com/sun/security/auth/PolicyFile.java +++ b/jdk/src/share/classes/com/sun/security/auth/PolicyFile.java @@ -25,31 +25,9 @@ package com.sun.security.auth; -import java.io.*; -import java.lang.reflect.*; -import java.net.URL; -import java.util.*; - import java.security.CodeSource; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.Permission; -import java.security.Permissions; import java.security.PermissionCollection; -import java.security.Principal; -import java.security.UnresolvedPermission; -import java.security.Security; -import java.security.cert.Certificate; -import java.security.cert.X509Certificate; - import javax.security.auth.Subject; -import javax.security.auth.PrivateCredentialPermission; - -import sun.security.util.PropertyExpander; - -import sun.security.provider.PolicyParser.PrincipalEntry; -import sun.security.provider.PolicyParser.GrantEntry; -import sun.security.provider.PolicyParser.PermissionEntry; /** * This class represents a default implementation for @@ -240,61 +218,14 @@ import sun.security.provider.PolicyParser.PermissionEntry; @Deprecated public class PolicyFile extends javax.security.auth.Policy { - static final java.util.ResourceBundle rb = - java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction() { - public java.util.ResourceBundle run() { - return (java.util.ResourceBundle.getBundle - ("sun.security.util.AuthResources")); - } - }); - // needs to be package private - - private static final sun.security.util.Debug debug = - sun.security.util.Debug.getInstance("policy", "\t[Auth Policy]"); - - private static final String AUTH_POLICY = "java.security.auth.policy"; - private static final String SECURITY_MANAGER = "java.security.manager"; - private static final String AUTH_POLICY_URL = "auth.policy.url."; - - private Vector policyEntries; - private Hashtable aliasMapping; - - private boolean initialized = false; - - private boolean expandProperties = true; - private boolean ignoreIdentityScope = true; - - // for use with the reflection API - - private static final Class[] PARAMS = { String.class, String.class}; + private final sun.security.provider.AuthPolicyFile apf; /** * Initializes the Policy object and reads the default policy * configuration file(s) into the Policy object. */ public PolicyFile() { - // initialize Policy if either the AUTH_POLICY or - // SECURITY_MANAGER properties are set - String prop = System.getProperty(AUTH_POLICY); - - if (prop == null) { - prop = System.getProperty(SECURITY_MANAGER); - } - if (prop != null) - init(); - } - - private synchronized void init() { - - if (initialized) - return; - - policyEntries = new Vector(); - aliasMapping = new Hashtable(11); - - initPolicyFile(); - initialized = true; + apf = new sun.security.provider.AuthPolicyFile(); } /** @@ -305,460 +236,9 @@ public class PolicyFile extends javax.security.auth.Policy { * @exception SecurityException if the caller doesn't have permission * to refresh the Policy. */ - public synchronized void refresh() - { - - java.lang.SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new javax.security.auth.AuthPermission - ("refreshPolicy")); - } - - // XXX - // - // 1) if code instantiates PolicyFile directly, then it will need - // all the permissions required for the PolicyFile initialization - // 2) if code calls Policy.getPolicy, then it simply needs - // AuthPermission(getPolicy), and the javax.security.auth.Policy - // implementation instantiates PolicyFile in a doPrivileged block - // 3) if after instantiating a Policy (either via #1 or #2), - // code calls refresh, it simply needs - // AuthPermission(refreshPolicy). then PolicyFile wraps - // the refresh in a doPrivileged block. - initialized = false; - java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction() { - public Void run() { - init(); - return null; - } - }); - } - - private KeyStore initKeyStore(URL policyUrl, String keyStoreName, - String keyStoreType) { - if (keyStoreName != null) { - try { - /* - * location of keystore is specified as absolute URL in policy - * file, or is relative to URL of policy file - */ - URL keyStoreUrl = null; - try { - keyStoreUrl = new URL(keyStoreName); - // absolute URL - } catch (java.net.MalformedURLException e) { - // relative URL - keyStoreUrl = new URL(policyUrl, keyStoreName); - } - - if (debug != null) { - debug.println("reading keystore"+keyStoreUrl); - } - - InputStream inStream = - new BufferedInputStream(getInputStream(keyStoreUrl)); - - KeyStore ks; - if (keyStoreType != null) - ks = KeyStore.getInstance(keyStoreType); - else - ks = KeyStore.getInstance(KeyStore.getDefaultType()); - ks.load(inStream, null); - inStream.close(); - return ks; - } catch (Exception e) { - // ignore, treat it like we have no keystore - if (debug != null) { - e.printStackTrace(); - } - return null; - } - } - return null; - } - - private void initPolicyFile() { - - String prop = Security.getProperty("policy.expandProperties"); - - if (prop != null) expandProperties = prop.equalsIgnoreCase("true"); - - String iscp = Security.getProperty("policy.ignoreIdentityScope"); - - if (iscp != null) ignoreIdentityScope = iscp.equalsIgnoreCase("true"); - - String allowSys = Security.getProperty("policy.allowSystemProperty"); - - if ((allowSys!=null) && allowSys.equalsIgnoreCase("true")) { - - String extra_policy = System.getProperty(AUTH_POLICY); - if (extra_policy != null) { - boolean overrideAll = false; - if (extra_policy.startsWith("=")) { - overrideAll = true; - extra_policy = extra_policy.substring(1); - } - try { - extra_policy = PropertyExpander.expand(extra_policy); - URL policyURL; - File policyFile = new File(extra_policy); - if (policyFile.exists()) { - policyURL = - new URL("file:" + policyFile.getCanonicalPath()); - } else { - policyURL = new URL(extra_policy); - } - if (debug != null) - debug.println("reading "+policyURL); - init(policyURL); - } catch (Exception e) { - // ignore. - if (debug != null) { - debug.println("caught exception: "+e); - } - - } - if (overrideAll) { - if (debug != null) { - debug.println("overriding other policies!"); - } - return; - } - } - } - - int n = 1; - boolean loaded_one = false; - String policy_url; - - while ((policy_url = Security.getProperty(AUTH_POLICY_URL+n)) != null) { - try { - policy_url = PropertyExpander.expand(policy_url).replace - (File.separatorChar, '/'); - if (debug != null) - debug.println("reading "+policy_url); - init(new URL(policy_url)); - loaded_one = true; - } catch (Exception e) { - if (debug != null) { - debug.println("error reading policy "+e); - e.printStackTrace(); - } - // ignore that policy - } - n++; - } - - if (loaded_one == false) { - // do not load a static policy - } - } - - /** - * Checks public key. If it is marked as trusted in - * the identity database, add it to the policy - * with the AllPermission. - */ - private boolean checkForTrustedIdentity(final Certificate cert) { - // XXX JAAS has no way to access the SUN package. - // we'll add this back in when JAAS goes into core. - return false; - } - - /** - * Reads a policy configuration into the Policy object using a - * Reader object. - * - * @param policyFile the policy Reader object. - */ - private void init(URL policy) { - sun.security.provider.PolicyParser pp = - new sun.security.provider.PolicyParser(expandProperties); - try { - InputStreamReader isr - = new InputStreamReader(getInputStream(policy)); - pp.read(isr); - isr.close(); - KeyStore keyStore = initKeyStore(policy, pp.getKeyStoreUrl(), - pp.getKeyStoreType()); - Enumeration enum_ = pp.grantElements(); - while (enum_.hasMoreElements()) { - GrantEntry ge = enum_.nextElement(); - addGrantEntry(ge, keyStore); - } - } catch (sun.security.provider.PolicyParser.ParsingException pe) { - System.err.println(AUTH_POLICY + - rb.getString(".error.parsing.") + policy); - System.err.println(AUTH_POLICY + - rb.getString("COLON") + - pe.getMessage()); - if (debug != null) - pe.printStackTrace(); - - } catch (Exception e) { - if (debug != null) { - debug.println("error parsing "+policy); - debug.println(e.toString()); - e.printStackTrace(); - } - } - } - - /* - * Fast path reading from file urls in order to avoid calling - * FileURLConnection.connect() which can be quite slow the first time - * it is called. We really should clean up FileURLConnection so that - * this is not a problem but in the meantime this fix helps reduce - * start up time noticeably for the new launcher. -- DAC - */ - private InputStream getInputStream(URL url) throws IOException { - if ("file".equals(url.getProtocol())) { - String path = url.getFile().replace('/', File.separatorChar); - return new FileInputStream(path); - } else { - return url.openStream(); - } - } - - /** - * Given a PermissionEntry, create a codeSource. - * - * @return null if signedBy alias is not recognized - */ - CodeSource getCodeSource(GrantEntry ge, KeyStore keyStore) - throws java.net.MalformedURLException - { - Certificate[] certs = null; - if (ge.signedBy != null) { - certs = getCertificates(keyStore, ge.signedBy); - if (certs == null) { - // we don't have a key for this alias, - // just return - if (debug != null) { - debug.println(" no certs for alias " + - ge.signedBy + ", ignoring."); - } - return null; - } - } - - URL location; - - if (ge.codeBase != null) - location = new URL(ge.codeBase); - else - location = null; - - if (ge.principals == null || ge.principals.size() == 0) { - return (canonicalizeCodebase - (new CodeSource(location, certs), - false)); - } else { - return (canonicalizeCodebase - (new SubjectCodeSource(null, ge.principals, location, certs), - false)); - } - } - - /** - * Add one policy entry to the vector. - */ - private void addGrantEntry(GrantEntry ge, KeyStore keyStore) { - - if (debug != null) { - debug.println("Adding policy entry: "); - debug.println(" signedBy " + ge.signedBy); - debug.println(" codeBase " + ge.codeBase); - if (ge.principals != null && ge.principals.size() > 0) { - ListIterator li = ge.principals.listIterator(); - while (li.hasNext()) { - PrincipalEntry pppe = li.next(); - debug.println(" " + pppe.getPrincipalClass() + - " " + pppe.getPrincipalName()); - } - } - debug.println(); - } - - try { - CodeSource codesource = getCodeSource(ge, keyStore); - // skip if signedBy alias was unknown... - if (codesource == null) return; - - PolicyEntry entry = new PolicyEntry(codesource); - Enumeration enum_ = ge.permissionElements(); - while (enum_.hasMoreElements()) { - PermissionEntry pe = enum_.nextElement(); - try { - // XXX special case PrivateCredentialPermission-SELF - Permission perm; - if (pe.permission.equals - ("javax.security.auth.PrivateCredentialPermission") && - pe.name.endsWith(" self")) { - perm = getInstance(pe.permission, - pe.name + " \"self\"", - pe.action); - } else { - perm = getInstance(pe.permission, - pe.name, - pe.action); - } - entry.add(perm); - if (debug != null) { - debug.println(" "+perm); - } - } catch (ClassNotFoundException cnfe) { - Certificate certs[]; - if (pe.signedBy != null) - certs = getCertificates(keyStore, pe.signedBy); - else - certs = null; - - // only add if we had no signer or we had a - // a signer and found the keys for it. - if (certs != null || pe.signedBy == null) { - Permission perm = new UnresolvedPermission( - pe.permission, - pe.name, - pe.action, - certs); - entry.add(perm); - if (debug != null) { - debug.println(" "+perm); - } - } - } catch (java.lang.reflect.InvocationTargetException ite) { - System.err.println - (AUTH_POLICY + - rb.getString(".error.adding.Permission.") + - pe.permission + - rb.getString("SPACE") + - ite.getTargetException()); - } catch (Exception e) { - System.err.println - (AUTH_POLICY + - rb.getString(".error.adding.Permission.") + - pe.permission + - rb.getString("SPACE") + - e); - } - } - policyEntries.addElement(entry); - } catch (Exception e) { - System.err.println - (AUTH_POLICY + - rb.getString(".error.adding.Entry.") + - ge + - rb.getString("SPACE") + - e); - } - - if (debug != null) - debug.println(); - } - - /** - * Returns a new Permission object of the given Type. The Permission is - * created by getting the - * Class object using the Class.forName method, and using - * the reflection API to invoke the (String name, String actions) - * constructor on the - * object. - * - * @param type the type of Permission being created. - * @param name the name of the Permission being created. - * @param actions the actions of the Permission being created. - * - * @exception ClassNotFoundException if the particular Permission - * class could not be found. - * - * @exception IllegalAccessException if the class or initializer is - * not accessible. - * - * @exception InstantiationException if getInstance tries to - * instantiate an abstract class or an interface, or if the - * instantiation fails for some other reason. - * - * @exception NoSuchMethodException if the (String, String) constructor - * is not found. - * - * @exception InvocationTargetException if the underlying Permission - * constructor throws an exception. - * - */ - - private static final Permission getInstance(String type, - String name, - String actions) - throws ClassNotFoundException, - InstantiationException, - IllegalAccessException, - NoSuchMethodException, - InvocationTargetException - { - //XXX we might want to keep a hash of created factories... - Class pc = Class.forName(type); - Constructor c = pc.getConstructor(PARAMS); - return (Permission) c.newInstance(new Object[] { name, actions }); - } - - /** - * Fetch all certs associated with this alias. - */ - Certificate[] getCertificates( - KeyStore keyStore, String aliases) { - - Vector vcerts = null; - - StringTokenizer st = new StringTokenizer(aliases, ","); - int n = 0; - - while (st.hasMoreTokens()) { - String alias = st.nextToken().trim(); - n++; - Certificate cert = null; - //See if this alias's cert has already been cached - cert = (Certificate) aliasMapping.get(alias); - if (cert == null && keyStore != null) { - - try { - cert = keyStore.getCertificate(alias); - } catch (KeyStoreException kse) { - // never happens, because keystore has already been loaded - // when we call this - } - if (cert != null) { - aliasMapping.put(alias, cert); - aliasMapping.put(cert, alias); - } - } - - if (cert != null) { - if (vcerts == null) - vcerts = new Vector(); - vcerts.addElement(cert); - } - } - - // make sure n == vcerts.size, since we are doing a logical *and* - if (vcerts != null && n == vcerts.size()) { - Certificate[] certs = new Certificate[vcerts.size()]; - vcerts.copyInto(certs); - return certs; - } else { - return null; - } - } - - /** - * Enumerate all the entries in the global policy object. - * This method is used by policy admin tools. The tools - * should use the Enumeration methods on the returned object - * to fetch the elements sequentially. - */ - private final synchronized Enumeration elements(){ - return policyEntries.elements(); + @Override + public void refresh() { + apf.refresh(); } /** @@ -816,646 +296,9 @@ public class PolicyFile extends javax.security.auth.Policy { * @return the Permissions granted to the provided Subject * CodeSource. */ + @Override public PermissionCollection getPermissions(final Subject subject, - final CodeSource codesource) { - - // XXX when JAAS goes into the JDK core, - // we can remove this method and simply - // rely on the getPermissions variant that takes a codesource, - // which no one can use at this point in time. - // at that time, we can also make SubjectCodeSource a public - // class. - - // XXX - // - // 1) if code instantiates PolicyFile directly, then it will need - // all the permissions required for the PolicyFile initialization - // 2) if code calls Policy.getPolicy, then it simply needs - // AuthPermission(getPolicy), and the javax.security.auth.Policy - // implementation instantiates PolicyFile in a doPrivileged block - // 3) if after instantiating a Policy (either via #1 or #2), - // code calls getPermissions, PolicyFile wraps the call - // in a doPrivileged block. - return java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction() { - public PermissionCollection run() { - SubjectCodeSource scs = new SubjectCodeSource - (subject, - null, - codesource == null ? null : codesource.getLocation(), - codesource == null ? null : codesource.getCertificates()); - if (initialized) - return getPermissions(new Permissions(), scs); - else - return new PolicyPermissions(PolicyFile.this, scs); - } - }); - } - - /** - * Examines the global policy for the specified CodeSource, and - * creates a PermissionCollection object with - * the set of permissions for that principal's protection domain. - * - * @param CodeSource the codesource associated with the caller. - * This encapsulates the original location of the code (where the code - * came from) and the public key(s) of its signer. - * - * @return the set of permissions according to the policy. - */ - PermissionCollection getPermissions(CodeSource codesource) { - - if (initialized) - return getPermissions(new Permissions(), codesource); - else - return new PolicyPermissions(this, codesource); - } - - /** - * Examines the global policy for the specified CodeSource, and - * creates a PermissionCollection object with - * the set of permissions for that principal's protection domain. - * - * @param permissions the permissions to populate - * @param codesource the codesource associated with the caller. - * This encapsulates the original location of the code (where the code - * came from) and the public key(s) of its signer. - * - * @return the set of permissions according to the policy. - */ - Permissions getPermissions(final Permissions perms, - final CodeSource cs) - { - if (!initialized) { - init(); - } - - final CodeSource codesource[] = {null}; - - codesource[0] = canonicalizeCodebase(cs, true); - - if (debug != null) { - debug.println("evaluate("+codesource[0]+")\n"); - } - - // needs to be in a begin/endPrivileged block because - // codesource.implies calls URL.equals which does an - // InetAddress lookup - - for (int i = 0; i < policyEntries.size(); i++) { - - PolicyEntry entry = policyEntries.elementAt(i); - - if (debug != null) { - debug.println("PolicyFile CodeSource implies: " + - entry.codesource.toString() + "\n\n" + - "\t" + codesource[0].toString() + "\n\n"); - } - - if (entry.codesource.implies(codesource[0])) { - for (int j = 0; j < entry.permissions.size(); j++) { - Permission p = entry.permissions.elementAt(j); - if (debug != null) { - debug.println(" granting " + p); - } - if (!addSelfPermissions(p, entry.codesource, - codesource[0], perms)) { - // we could check for duplicates - // before adding new permissions, - // but the SubjectDomainCombiner - // already checks for duplicates later - perms.add(p); - } - } - } - } - - // now see if any of the keys are trusted ids. - - if (!ignoreIdentityScope) { - Certificate certs[] = codesource[0].getCertificates(); - if (certs != null) { - for (int k=0; k < certs.length; k++) { - if ((aliasMapping.get(certs[k]) == null) && - checkForTrustedIdentity(certs[k])) { - // checkForTrustedIdentity added it - // to the policy for us. next time - // around we'll find it. This time - // around we need to add it. - perms.add(new java.security.AllPermission()); - } - } - } - } - return perms; - } - - /** - * Returns true if 'Self' permissions were added to the provided - * 'perms', and false otherwise. - * - *

- * - * @param p check to see if this Permission is a "SELF" - * PrivateCredentialPermission.

- * - * @param entryCs the codesource for the Policy entry. - * - * @param accCs the codesource for from the current AccessControlContext. - * - * @param perms the PermissionCollection where the individual - * PrivateCredentialPermissions will be added. - */ - private boolean addSelfPermissions(final Permission p, - CodeSource entryCs, - CodeSource accCs, - Permissions perms) { - - if (!(p instanceof PrivateCredentialPermission)) - return false; - - if (!(entryCs instanceof SubjectCodeSource)) - return false; - - - PrivateCredentialPermission pcp = (PrivateCredentialPermission)p; - SubjectCodeSource scs = (SubjectCodeSource)entryCs; - - // see if it is a SELF permission - String[][] pPrincipals = pcp.getPrincipals(); - if (pPrincipals.length <= 0 || - !pPrincipals[0][0].equalsIgnoreCase("self") || - !pPrincipals[0][1].equalsIgnoreCase("self")) { - - // regular PrivateCredentialPermission - return false; - } else { - - // granted a SELF permission - create a - // PrivateCredentialPermission for each - // of the Policy entry's CodeSource Principals - - if (scs.getPrincipals() == null) { - // XXX SubjectCodeSource has no Subject??? - return true; - } - - ListIterator pli = - scs.getPrincipals().listIterator(); - while (pli.hasNext()) { - - PrincipalEntry principal = pli.next(); - - // XXX - // if the Policy entry's Principal does not contain a - // WILDCARD for the Principal name, then a - // new PrivateCredentialPermission is created - // for the Principal listed in the Policy entry. - // if the Policy entry's Principal contains a WILDCARD - // for the Principal name, then a new - // PrivateCredentialPermission is created - // for each Principal associated with the Subject - // in the current ACC. - - String[][] principalInfo = getPrincipalInfo - (principal, accCs); - - for (int i = 0; i < principalInfo.length; i++) { - - // here's the new PrivateCredentialPermission - - PrivateCredentialPermission newPcp = - new PrivateCredentialPermission - (pcp.getCredentialClass() + - " " + - principalInfo[i][0] + - " " + - "\"" + principalInfo[i][1] + "\"", - "read"); - - if (debug != null) { - debug.println("adding SELF permission: " + - newPcp.toString()); - } - - perms.add(newPcp); - } - } - } - return true; - } - - /** - * return the principal class/name pair in the 2D array. - * array[x][y]: x corresponds to the array length. - * if (y == 0), it's the principal class. - * if (y == 1), it's the principal name. - */ - private String[][] getPrincipalInfo - (PrincipalEntry principal, final CodeSource accCs) { - - // there are 3 possibilities: - // 1) the entry's Principal class and name are not wildcarded - // 2) the entry's Principal name is wildcarded only - // 3) the entry's Principal class and name are wildcarded - - if (!principal.getPrincipalClass().equals - (PrincipalEntry.WILDCARD_CLASS) && - !principal.getPrincipalName().equals - (PrincipalEntry.WILDCARD_NAME)) { - - // build a PrivateCredentialPermission for the principal - // from the Policy entry - String[][] info = new String[1][2]; - info[0][0] = principal.getPrincipalClass(); - info[0][1] = principal.getPrincipalName(); - return info; - - } else if (!principal.getPrincipalClass().equals - (PrincipalEntry.WILDCARD_CLASS) && - principal.getPrincipalName().equals - (PrincipalEntry.WILDCARD_NAME)) { - - // build a PrivateCredentialPermission for all - // the Subject's principals that are instances of principalClass - - // the accCs is guaranteed to be a SubjectCodeSource - // because the earlier CodeSource.implies succeeded - SubjectCodeSource scs = (SubjectCodeSource)accCs; - - Set principalSet = null; - try { - // principal.principalClass should extend Principal - // If it doesn't, we should stop here with a ClassCastException. - @SuppressWarnings("unchecked") - Class pClass = (Class) - Class.forName(principal.getPrincipalClass(), false, - ClassLoader.getSystemClassLoader()); - principalSet = scs.getSubject().getPrincipals(pClass); - } catch (Exception e) { - if (debug != null) { - debug.println("problem finding Principal Class " + - "when expanding SELF permission: " + - e.toString()); - } - } - - if (principalSet == null) { - // error - return new String[0][0]; - } - - String[][] info = new String[principalSet.size()][2]; - - int i = 0; - for (Principal p : principalSet) { - info[i][0] = p.getClass().getName(); - info[i][1] = p.getName(); - i++; - } - return info; - - } else { - - // build a PrivateCredentialPermission for every - // one of the current Subject's principals - - // the accCs is guaranteed to be a SubjectCodeSource - // because the earlier CodeSource.implies succeeded - SubjectCodeSource scs = (SubjectCodeSource)accCs; - Set principalSet = scs.getSubject().getPrincipals(); - - String[][] info = new String[principalSet.size()][2]; - java.util.Iterator pIterator = principalSet.iterator(); - - int i = 0; - while (pIterator.hasNext()) { - Principal p = pIterator.next(); - info[i][0] = p.getClass().getName(); - info[i][1] = p.getName(); - i++; - } - return info; - } - } - - /* - * Returns the signer certificates from the list of certificates associated - * with the given code source. - * - * The signer certificates are those certificates that were used to verify - * signed code originating from the codesource location. - * - * This method assumes that in the given code source, each signer - * certificate is followed by its supporting certificate chain - * (which may be empty), and that the signer certificate and its - * supporting certificate chain are ordered bottom-to-top (i.e., with the - * signer certificate first and the (root) certificate authority last). - */ - Certificate[] getSignerCertificates(CodeSource cs) { - Certificate[] certs = null; - if ((certs = cs.getCertificates()) == null) - return null; - for (int i=0; i userCertList = new ArrayList<>(); - i = 0; - while (i < certs.length) { - userCertList.add(certs[i]); - while (((i+1) < certs.length) - && ((X509Certificate)certs[i]).getIssuerDN().equals( - ((X509Certificate)certs[i+1]).getSubjectDN())) { - i++; - } - i++; - } - Certificate[] userCerts = new Certificate[userCertList.size()]; - userCertList.toArray(userCerts); - return userCerts; - } - - private CodeSource canonicalizeCodebase(CodeSource cs, - boolean extractSignerCerts) { - CodeSource canonCs = cs; - if (cs.getLocation() != null && - cs.getLocation().getProtocol().equalsIgnoreCase("file")) { - try { - String path = cs.getLocation().getFile().replace - ('/', - File.separatorChar); - URL csUrl = null; - if (path.endsWith("*")) { - // remove trailing '*' because it causes canonicalization - // to fail on win32 - path = path.substring(0, path.length()-1); - boolean appendFileSep = false; - if (path.endsWith(File.separator)) - appendFileSep = true; - if (path.equals("")) { - path = System.getProperty("user.dir"); - } - File f = new File(path); - path = f.getCanonicalPath(); - StringBuffer sb = new StringBuffer(path); - // reappend '*' to canonicalized filename (note that - // canonicalization may have removed trailing file - // separator, so we have to check for that, too) - if (!path.endsWith(File.separator) && - (appendFileSep || f.isDirectory())) - sb.append(File.separatorChar); - sb.append('*'); - path = sb.toString(); - } else { - path = new File(path).getCanonicalPath(); - } - csUrl = new File(path).toURL(); - - if (cs instanceof SubjectCodeSource) { - SubjectCodeSource scs = (SubjectCodeSource)cs; - if (extractSignerCerts) { - canonCs = new SubjectCodeSource - (scs.getSubject(), - scs.getPrincipals(), - csUrl, - getSignerCertificates(scs)); - } else { - canonCs = new SubjectCodeSource - (scs.getSubject(), - scs.getPrincipals(), - csUrl, - scs.getCertificates()); - } - } else { - if (extractSignerCerts) { - canonCs = new CodeSource(csUrl, - getSignerCertificates(cs)); - } else { - canonCs = new CodeSource(csUrl, - cs.getCertificates()); - } - } - } catch (IOException ioe) { - // leave codesource as it is, unless we have to extract its - // signer certificates - if (extractSignerCerts) { - if (!(cs instanceof SubjectCodeSource)) { - canonCs = new CodeSource(cs.getLocation(), - getSignerCertificates(cs)); - } else { - SubjectCodeSource scs = (SubjectCodeSource)cs; - canonCs = new SubjectCodeSource(scs.getSubject(), - scs.getPrincipals(), - scs.getLocation(), - getSignerCertificates(scs)); - } - } - } - } else { - if (extractSignerCerts) { - if (!(cs instanceof SubjectCodeSource)) { - canonCs = new CodeSource(cs.getLocation(), - getSignerCertificates(cs)); - } else { - SubjectCodeSource scs = (SubjectCodeSource)cs; - canonCs = new SubjectCodeSource(scs.getSubject(), - scs.getPrincipals(), - scs.getLocation(), - getSignerCertificates(scs)); - } - } - } - return canonCs; - } - - /** - * Each entry in the policy configuration file is represented by a - * PolicyEntry object.

- * - * A PolicyEntry is a (CodeSource,Permission) pair. The - * CodeSource contains the (URL, PublicKey) that together identify - * where the Java bytecodes come from and who (if anyone) signed - * them. The URL could refer to localhost. The URL could also be - * null, meaning that this policy entry is given to all comers, as - * long as they match the signer field. The signer could be null, - * meaning the code is not signed.

- * - * The Permission contains the (Type, Name, Action) triplet.

- * - * For now, the Policy object retrieves the public key from the - * X.509 certificate on disk that corresponds to the signedBy - * alias specified in the Policy config file. For reasons of - * efficiency, the Policy object keeps a hashtable of certs already - * read in. This could be replaced by a secure internal key - * store. - * - *

- * For example, the entry - *

-     *          permission java.io.File "/tmp", "read,write",
-     *          signedBy "Duke";
-     * 
- * is represented internally - *
-     *
-     * FilePermission f = new FilePermission("/tmp", "read,write");
-     * PublicKey p = publickeys.get("Duke");
-     * URL u = InetAddress.getLocalHost();
-     * CodeBase c = new CodeBase( p, u );
-     * pe = new PolicyEntry(f, c);
-     * 
- * - * @author Marianne Mueller - * @author Roland Schemers - * @see java.security.CodeSource - * @see java.security.Policy - * @see java.security.Permissions - * @see java.security.ProtectionDomain - */ - - private static class PolicyEntry { - - CodeSource codesource; - Vector permissions; - - /** - * Given a Permission and a CodeSource, create a policy entry. - * - * XXX Decide if/how to add validity fields and "purpose" fields to - * XXX policy entries - * - * @param cs the CodeSource, which encapsulates the URL and the public - * key - * attributes from the policy config file. Validity checks are - * performed on the public key before PolicyEntry is called. - * - */ - PolicyEntry(CodeSource cs) - { - this.codesource = cs; - this.permissions = new Vector(); - } - - /** - * add a Permission object to this entry. - */ - void add(Permission p) { - permissions.addElement(p); - } - - /** - * Return the CodeSource for this policy entry - */ - CodeSource getCodeSource() { - return this.codesource; - } - - public String toString(){ - StringBuffer sb = new StringBuffer(); - sb.append(rb.getString("LPARAM")); - sb.append(getCodeSource()); - sb.append("\n"); - for (int j = 0; j < permissions.size(); j++) { - Permission p = permissions.elementAt(j); - sb.append(rb.getString("SPACE")); - sb.append(rb.getString("SPACE")); - sb.append(p); - sb.append(rb.getString("NEWLINE")); - } - sb.append(rb.getString("RPARAM")); - sb.append(rb.getString("NEWLINE")); - return sb.toString(); - } - - } -} - -@SuppressWarnings("deprecation") -class PolicyPermissions extends PermissionCollection { - - private static final long serialVersionUID = -1954188373270545523L; - - private CodeSource codesource; - private Permissions perms; - private PolicyFile policy; - private boolean notInit; // have we pulled in the policy permissions yet? - private Vector additionalPerms; - - PolicyPermissions(PolicyFile policy, - CodeSource codesource) - { - this.codesource = codesource; - this.policy = policy; - this.perms = null; - this.notInit = true; - this.additionalPerms = null; - } - - public void add(Permission permission) { - if (isReadOnly()) - throw new SecurityException - (PolicyFile.rb.getString - ("attempt.to.add.a.Permission.to.a.readonly.PermissionCollection")); - - if (perms == null) { - if (additionalPerms == null) - additionalPerms = new Vector(); - additionalPerms.add(permission); - } else { - perms.add(permission); - } - } - - private synchronized void init() { - if (notInit) { - if (perms == null) - perms = new Permissions(); - - if (additionalPerms != null) { - Enumeration e = additionalPerms.elements(); - while (e.hasMoreElements()) { - perms.add(e.nextElement()); - } - additionalPerms = null; - } - policy.getPermissions(perms,codesource); - notInit=false; - } - } - - public boolean implies(Permission permission) { - if (notInit) - init(); - return perms.implies(permission); - } - - public Enumeration elements() { - if (notInit) - init(); - return perms.elements(); - } - - public String toString() { - if (notInit) - init(); - return perms.toString(); + final CodeSource codesource) { + return apf.getPermissions(subject, codesource); } } diff --git a/jdk/src/share/classes/com/sun/security/auth/PolicyParser.java b/jdk/src/share/classes/com/sun/security/auth/PolicyParser.java deleted file mode 100644 index aaf061b514f..00000000000 --- a/jdk/src/share/classes/com/sun/security/auth/PolicyParser.java +++ /dev/null @@ -1,964 +0,0 @@ -/* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.security.auth; - -import java.io.*; -import java.lang.RuntimePermission; -import java.net.MalformedURLException; -import java.net.SocketPermission; -import java.net.URL; -import java.security.GeneralSecurityException; -import java.text.MessageFormat; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.LinkedList; -import java.util.ListIterator; -import java.util.Vector; -import java.util.StringTokenizer; -import sun.security.util.PropertyExpander; - -/** - * The policy for a Java runtime (specifying - * which permissions are available for code from various principals) - * is represented as a separate - * persistent configuration. The configuration may be stored as a - * flat ASCII file, as a serialized binary file of - * the Policy class, or as a database.

- * - *

The Java runtime creates one global Policy object, which is used to - * represent the static policy configuration file. It is consulted by - * a ProtectionDomain when the protection domain initializes its set of - * permissions.

- * - *

The Policy init method parses the policy - * configuration file, and then - * populates the Policy object. The Policy object is agnostic in that - * it is not involved in making policy decisions. It is merely the - * Java runtime representation of the persistent policy configuration - * file.

- * - *

When a protection domain needs to initialize its set of - * permissions, it executes code such as the following - * to ask the global Policy object to populate a - * Permissions object with the appropriate permissions: - *

- *  policy = Policy.getPolicy();
- *  Permissions perms = policy.getPermissions(MyCodeSource)
- * 
- * - *

The protection domain passes in a CodeSource - * object, which encapsulates its codebase (URL) and public key attributes. - * The Policy object evaluates the global policy in light of who the - * principal is and returns an appropriate Permissions object. - * - * @deprecated As of JDK 1.4, replaced by - * {@link sun.security.provider.PolicyParser}. - * This class is entirely deprecated. - * - * @author Roland Schemers - * - * @since 1.2 - */ -@Deprecated -class PolicyParser { - - private static final java.util.ResourceBundle rb = - java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction() { - public java.util.ResourceBundle run() { - return (java.util.ResourceBundle.getBundle - ("sun.security.util.AuthResources")); - } - }); - - private Vector grantEntries; - - // Convenience variables for parsing - private static final sun.security.util.Debug debug = - sun.security.util.Debug.getInstance("parser", "\t[Auth Policy Parser]"); - private StreamTokenizer st; - private int lookahead; - private int linenum; - private boolean expandProp = false; - private String keyStoreUrlString = null; // unexpanded - private String keyStoreType = null; - - private String expand(String value) - throws PropertyExpander.ExpandException - { - if (expandProp) - return PropertyExpander.expand(value); - else - return value; - } - /** - * Creates a PolicyParser object. - */ - - public PolicyParser() { - grantEntries = new Vector(); - } - - - public PolicyParser(boolean expandProp) { - this(); - this.expandProp = expandProp; - } - - /** - * Reads a policy configuration into the Policy object using a - * Reader object.

- * - * @param policy the policy Reader object. - * - * @exception ParsingException if the policy configuration contains - * a syntax error. - * - * @exception IOException if an error occurs while reading the policy - * configuration. - */ - - public void read(Reader policy) - throws ParsingException, IOException - { - if (!(policy instanceof BufferedReader)) { - policy = new BufferedReader(policy); - } - - /** - * Configure the stream tokenizer: - * Recognize strings between "..." - * Don't convert words to lowercase - * Recognize both C-style and C++-style comments - * Treat end-of-line as white space, not as a token - */ - st = new StreamTokenizer(policy); - - st.resetSyntax(); - st.wordChars('a', 'z'); - st.wordChars('A', 'Z'); - st.wordChars('.', '.'); - st.wordChars('0', '9'); - st.wordChars('_', '_'); - st.wordChars('$', '$'); - st.wordChars(128 + 32, 255); - st.whitespaceChars(0, ' '); - st.commentChar('/'); - st.quoteChar('\''); - st.quoteChar('"'); - st.lowerCaseMode(false); - st.ordinaryChar('/'); - st.slashSlashComments(true); - st.slashStarComments(true); - - /** - * The main parsing loop. The loop is executed once - * for each entry in the config file. The entries - * are delimited by semicolons. Once we've read in - * the information for an entry, go ahead and try to - * add it to the policy vector. - * - */ - - lookahead = st.nextToken(); - while (lookahead != StreamTokenizer.TT_EOF) { - if (peek("grant")) { - GrantEntry ge = parseGrantEntry(); - // could be null if we couldn't expand a property - if (ge != null) - add(ge); - } else if (peek("keystore") && keyStoreUrlString==null) { - // only one keystore entry per policy file, others will be - // ignored - parseKeyStoreEntry(); - } else { - // error? - } - match(";"); - } - } - - public void add(GrantEntry ge) - { - grantEntries.addElement(ge); - } - - public void replace(GrantEntry origGe, GrantEntry newGe) - { - grantEntries.setElementAt(newGe, grantEntries.indexOf(origGe)); - } - - public boolean remove(GrantEntry ge) - { - return grantEntries.removeElement(ge); - } - - /** - * Returns the (possibly expanded) keystore location, or null if the - * expansion fails. - */ - public String getKeyStoreUrl() { - try { - if (keyStoreUrlString!=null && keyStoreUrlString.length()!=0) { - return expand(keyStoreUrlString).replace(File.separatorChar, - '/'); - } - } catch (PropertyExpander.ExpandException peee) { - return null; - } - return null; - } - - public void setKeyStoreUrl(String url) { - keyStoreUrlString = url; - } - - public String getKeyStoreType() { - return keyStoreType; - } - - public void setKeyStoreType(String type) { - keyStoreType = type; - } - - /** - * Enumerate all the entries in the global policy object. - * This method is used by policy admin tools. The tools - * should use the Enumeration methods on the returned object - * to fetch the elements sequentially. - */ - public Enumeration grantElements(){ - return grantEntries.elements(); - } - - /** - * write out the policy - */ - - public void write(Writer policy) - { - PrintWriter out = new PrintWriter(new BufferedWriter(policy)); - - Enumeration enum_ = grantElements(); - - out.println("/* AUTOMATICALLY GENERATED ON "+ - (new java.util.Date()) + "*/"); - out.println("/* DO NOT EDIT */"); - out.println(); - - // write the (unexpanded) keystore entry as the first entry of the - // policy file - if (keyStoreUrlString != null) { - writeKeyStoreEntry(out); - } - - // write "grant" entries - while (enum_.hasMoreElements()) { - GrantEntry ge = enum_.nextElement(); - ge.write(out); - out.println(); - } - out.flush(); - } - - /** - * parses a keystore entry - */ - private void parseKeyStoreEntry() throws ParsingException, IOException { - match("keystore"); - keyStoreUrlString = match("quoted string"); - - // parse keystore type - if (!peek(",")) { - return; // default type - } - match(","); - - if (peek("\"")) { - keyStoreType = match("quoted string"); - } else { - throw new ParsingException(st.lineno(), - rb.getString("expected.keystore.type")); - } - } - - /** - * writes the (unexpanded) keystore entry - */ - private void writeKeyStoreEntry(PrintWriter out) { - out.print("keystore \""); - out.print(keyStoreUrlString); - out.print('"'); - if (keyStoreType != null && keyStoreType.length() > 0) - out.print(", \"" + keyStoreType + "\""); - out.println(";"); - out.println(); - } - - /** - * parse a Grant entry - */ - private GrantEntry parseGrantEntry() - throws ParsingException, IOException - { - GrantEntry e = new GrantEntry(); - LinkedList principals = null; - boolean ignoreEntry = false; - - match("grant"); - - while(!peek("{")) { - - if (peekAndMatch("Codebase")) { - e.codeBase = match("quoted string"); - peekAndMatch(","); - } else if (peekAndMatch("SignedBy")) { - e.signedBy = match("quoted string"); - peekAndMatch(","); - } else if (peekAndMatch("Principal")) { - if (principals == null) { - principals = new LinkedList(); - } - - // check for principalClass wildcard - String principalClass; - if (peek("*")) { - match("*"); - principalClass = PrincipalEntry.WILDCARD_CLASS; - } else { - principalClass = match("principal type"); - } - - // check for principalName wildcard - String principalName; - if (peek("*")) { - match("*"); - principalName = PrincipalEntry.WILDCARD_NAME; - } else { - principalName = match("quoted string"); - } - - // disallow WILDCARD_CLASS && actual name - if (principalClass.equals(PrincipalEntry.WILDCARD_CLASS) && - !principalName.equals(PrincipalEntry.WILDCARD_NAME)) { - if (debug != null) - debug.println("disallowing principal that has " + - "WILDCARD class but no WILDCARD name"); - throw new ParsingException - (st.lineno(), - rb.getString("can.not.specify.Principal.with.a." + - "wildcard.class.without.a.wildcard.name")); - } - - try { - principalName = expand(principalName); - principals.add - (new PrincipalEntry(principalClass, principalName)); - } catch (PropertyExpander.ExpandException peee) { - // ignore the entire policy entry - // but continue parsing all the info - // so we can get to the next entry - if (debug != null) - debug.println("principal name expansion failed: " + - principalName); - ignoreEntry = true; - } - peekAndMatch(","); - } else { - throw new - ParsingException(st.lineno(), - rb.getString("expected.codeBase.or.SignedBy")); - } - } - - // disallow non principal-based grant entries - if (principals == null) { - throw new ParsingException - (st.lineno(), - rb.getString("only.Principal.based.grant.entries.permitted")); - } - - e.principals = principals; - match("{"); - - while(!peek("}")) { - if (peek("Permission")) { - try { - PermissionEntry pe = parsePermissionEntry(); - e.add(pe); - } catch (PropertyExpander.ExpandException peee) { - // ignore. The add never happened - skipEntry(); // BugId 4219343 - } - match(";"); - } else { - throw new - ParsingException(st.lineno(), - rb.getString("expected.permission.entry")); - } - } - match("}"); - - try { - if (e.codeBase != null) - e.codeBase = expand(e.codeBase).replace(File.separatorChar, '/'); - e.signedBy = expand(e.signedBy); - } catch (PropertyExpander.ExpandException peee) { - return null; - } - - return (ignoreEntry == true) ? null : e; - } - - /** - * parse a Permission entry - */ - private PermissionEntry parsePermissionEntry() - throws ParsingException, IOException, PropertyExpander.ExpandException - { - PermissionEntry e = new PermissionEntry(); - - // Permission - match("Permission"); - e.permission = match("permission type"); - - if (peek("\"")) { - // Permission name - e.name = expand(match("quoted string")); - } - - if (!peek(",")) { - return e; - } - match(","); - - if (peek("\"")) { - e.action = expand(match("quoted string")); - if (!peek(",")) { - return e; - } - match(","); - } - - if (peekAndMatch("SignedBy")) { - e.signedBy = expand(match("quoted string")); - } - return e; - } - - private boolean peekAndMatch(String expect) - throws ParsingException, IOException - { - if (peek(expect)) { - match(expect); - return true; - } else { - return false; - } - } - - private boolean peek(String expect) { - boolean found = false; - - switch (lookahead) { - - case StreamTokenizer.TT_WORD: - if (expect.equalsIgnoreCase(st.sval)) - found = true; - break; - case ',': - if (expect.equalsIgnoreCase(",")) - found = true; - break; - case '{': - if (expect.equalsIgnoreCase("{")) - found = true; - break; - case '}': - if (expect.equalsIgnoreCase("}")) - found = true; - break; - case '"': - if (expect.equalsIgnoreCase("\"")) - found = true; - break; - case '*': - if (expect.equalsIgnoreCase("*")) - found = true; - break; - default: - - } - return found; - } - - private String match(String expect) - throws ParsingException, IOException - { - String value = null; - - switch (lookahead) { - case StreamTokenizer.TT_NUMBER: - throw new ParsingException(st.lineno(), expect, - rb.getString("number.") + - String.valueOf(st.nval)); - case StreamTokenizer.TT_EOF: - MessageFormat form = new MessageFormat( - rb.getString("expected.expect.read.end.of.file.")); - Object[] source = {expect}; - throw new ParsingException(form.format(source)); - case StreamTokenizer.TT_WORD: - if (expect.equalsIgnoreCase(st.sval)) { - lookahead = st.nextToken(); - } else if (expect.equalsIgnoreCase("permission type")) { - value = st.sval; - lookahead = st.nextToken(); - } else if (expect.equalsIgnoreCase("principal type")) { - value = st.sval; - lookahead = st.nextToken(); - } else { - throw new ParsingException(st.lineno(), expect, st.sval); - } - break; - case '"': - if (expect.equalsIgnoreCase("quoted string")) { - value = st.sval; - lookahead = st.nextToken(); - } else if (expect.equalsIgnoreCase("permission type")) { - value = st.sval; - lookahead = st.nextToken(); - } else if (expect.equalsIgnoreCase("principal type")) { - value = st.sval; - lookahead = st.nextToken(); - } else { - throw new ParsingException(st.lineno(), expect, st.sval); - } - break; - case ',': - if (expect.equalsIgnoreCase(",")) - lookahead = st.nextToken(); - else - throw new ParsingException(st.lineno(), expect, ","); - break; - case '{': - if (expect.equalsIgnoreCase("{")) - lookahead = st.nextToken(); - else - throw new ParsingException(st.lineno(), expect, "{"); - break; - case '}': - if (expect.equalsIgnoreCase("}")) - lookahead = st.nextToken(); - else - throw new ParsingException(st.lineno(), expect, "}"); - break; - case ';': - if (expect.equalsIgnoreCase(";")) - lookahead = st.nextToken(); - else - throw new ParsingException(st.lineno(), expect, ";"); - break; - case '*': - if (expect.equalsIgnoreCase("*")) - lookahead = st.nextToken(); - else - throw new ParsingException(st.lineno(), expect, "*"); - break; - default: - throw new ParsingException(st.lineno(), expect, - new String(new char[] {(char)lookahead})); - } - return value; - } - - /** - * skip all tokens for this entry leaving the delimiter ";" - * in the stream. - */ - private void skipEntry() - throws ParsingException, IOException - { - while(lookahead != ';') { - switch (lookahead) { - case StreamTokenizer.TT_NUMBER: - throw new ParsingException(st.lineno(), ";", - rb.getString("number.") + - String.valueOf(st.nval)); - case StreamTokenizer.TT_EOF: - throw new ParsingException - (rb.getString("expected.read.end.of.file")); - default: - lookahead = st.nextToken(); - } - } - } - - /** - * Each grant entry in the policy configuration file is - * represented by a - * GrantEntry object.

- * - *

- * For example, the entry - *

-     *      grant signedBy "Duke" {
-     *          permission java.io.FilePermission "/tmp", "read,write";
-     *      };
-     *
-     * 
- * is represented internally - *
-     *
-     * pe = new PermissionEntry("java.io.FilePermission",
-     *                           "/tmp", "read,write");
-     *
-     * ge = new GrantEntry("Duke", null);
-     *
-     * ge.add(pe);
-     *
-     * 
- * - * @author Roland Schemers - * - * version 1.19, 05/21/98 - */ - - static class GrantEntry { - - public String signedBy; - public String codeBase; - public LinkedList principals; - public Vector permissionEntries; - - public GrantEntry() { - permissionEntries = new Vector(); - } - - public GrantEntry(String signedBy, String codeBase) { - this.codeBase = codeBase; - this.signedBy = signedBy; - permissionEntries = new Vector(); - } - - public void add(PermissionEntry pe) - { - permissionEntries.addElement(pe); - } - - public boolean remove(PermissionEntry pe) - { - return permissionEntries.removeElement(pe); - } - - public boolean contains(PermissionEntry pe) - { - return permissionEntries.contains(pe); - } - - /** - * Enumerate all the permission entries in this GrantEntry. - */ - public Enumeration permissionElements(){ - return permissionEntries.elements(); - } - - - public void write(PrintWriter out) { - out.print("grant"); - if (signedBy != null) { - out.print(" signedBy \""); - out.print(signedBy); - out.print('"'); - if (codeBase != null) - out.print(", "); - } - if (codeBase != null) { - out.print(" codeBase \""); - out.print(codeBase); - out.print('"'); - if (principals != null && principals.size() > 0) - out.print(",\n"); - } - if (principals != null && principals.size() > 0) { - ListIterator pli = principals.listIterator(); - while (pli.hasNext()) { - out.print("\tPrincipal "); - PrincipalEntry pe = pli.next(); - out.print(pe.principalClass + - " \"" + pe.principalName + "\""); - if (pli.hasNext()) - out.print(",\n"); - } - } - out.println(" {"); - Enumeration enum_ = permissionEntries.elements(); - while (enum_.hasMoreElements()) { - PermissionEntry pe = enum_.nextElement(); - out.write(" "); - pe.write(out); - } - out.println("};"); - } - - } - - /** - * Principal info (class and name) in a grant entry - */ - static class PrincipalEntry { - - static final String WILDCARD_CLASS = "WILDCARD_PRINCIPAL_CLASS"; - static final String WILDCARD_NAME = "WILDCARD_PRINCIPAL_NAME"; - - String principalClass; - String principalName; - - /** - * A PrincipalEntry consists of the Principal - * class and Principal name. - * - *

- * - * @param principalClass the Principal class.

- * - * @param principalName the Principal name.

- */ - public PrincipalEntry(String principalClass, String principalName) { - if (principalClass == null || principalName == null) - throw new NullPointerException - ("null principalClass or principalName"); - this.principalClass = principalClass; - this.principalName = principalName; - } - - /** - * Test for equality between the specified object and this object. - * Two PrincipalEntries are equal if their PrincipalClass and - * PrincipalName values are equal. - * - *

- * - * @param obj the object to test for equality with this object. - * - * @return true if the objects are equal, false otherwise. - */ - public boolean equals(Object obj) { - if (this == obj) - return true; - - if (!(obj instanceof PrincipalEntry)) - return false; - - PrincipalEntry that = (PrincipalEntry)obj; - if (this.principalClass.equals(that.principalClass) && - this.principalName.equals(that.principalName)) { - return true; - } - - return false; - } - - /** - * Return a hashcode for this PrincipalEntry. - * - *

- * - * @return a hashcode for this PrincipalEntry. - */ - public int hashCode() { - return principalClass.hashCode(); - } - } - - /** - * Each permission entry in the policy configuration file is - * represented by a - * PermissionEntry object.

- * - *

- * For example, the entry - *

-     *          permission java.io.FilePermission "/tmp", "read,write";
-     * 
- * is represented internally - *
-     *
-     * pe = new PermissionEntry("java.io.FilePermission",
-     *                           "/tmp", "read,write");
-     * 
- * - * @author Roland Schemers - * - * version 1.19, 05/21/98 - */ - - static class PermissionEntry { - - public String permission; - public String name; - public String action; - public String signedBy; - - public PermissionEntry() { - } - - public PermissionEntry(String permission, - String name, - String action) { - this.permission = permission; - this.name = name; - this.action = action; - } - - /** - * Calculates a hash code value for the object. Objects - * which are equal will also have the same hashcode. - */ - public int hashCode() { - int retval = permission.hashCode(); - if (name != null) retval ^= name.hashCode(); - if (action != null) retval ^= action.hashCode(); - return retval; - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - - if (! (obj instanceof PermissionEntry)) - return false; - - PermissionEntry that = (PermissionEntry) obj; - - if (this.permission == null) { - if (that.permission != null) return false; - } else { - if (!this.permission.equals(that.permission)) return false; - } - - if (this.name == null) { - if (that.name != null) return false; - } else { - if (!this.name.equals(that.name)) return false; - } - - if (this.action == null) { - if (that.action != null) return false; - } else { - if (!this.action.equals(that.action)) return false; - } - - if (this.signedBy == null) { - if (that.signedBy != null) return false; - } else { - if (!this.signedBy.equals(that.signedBy)) return false; - } - - // everything matched -- the 2 objects are equal - return true; - } - - public void write(PrintWriter out) { - out.print("permission "); - out.print(permission); - if (name != null) { - out.print(" \""); - - // have to add escape chars for quotes - if (name.indexOf("\"") != -1) { - int numQuotes = 0; - char[] chars = name.toCharArray(); - - // count the number of quote chars - for (int i = 0; i < chars.length; i++) { - if (chars[i] == '"') - numQuotes++; - } - - // now, add an escape char before each quote - char[] newChars = new char[chars.length + numQuotes]; - for (int i = 0, j = 0; i < chars.length; i++) { - if (chars[i] != '"') { - newChars[j++] = chars[i]; - } else { - newChars[j++] = '\\'; - newChars[j++] = chars[i]; - } - } - name = new String(newChars); - } - out.print(name); - out.print('"'); - } - if (action != null) { - out.print(", \""); - out.print(action); - out.print('"'); - } - if (signedBy != null) { - out.print(", signedBy \""); - out.print(signedBy); - out.print('"'); - } - out.println(";"); - } - } - - static class ParsingException extends GeneralSecurityException { - - private static final long serialVersionUID = 8240970523155877400L; - - /** - * Constructs a ParsingException with the specified - * detail message. A detail message is a String that describes - * this particular exception, which may, for example, specify which - * algorithm is not available. - * - * @param msg the detail message. - */ - public ParsingException(String msg) { - super(msg); - } - - public ParsingException(int line, String msg) { - super(rb.getString("line.") + line + rb.getString("COLON") + msg); - } - - public ParsingException(int line, String expect, String actual) { - super(rb.getString("line.") + line + rb.getString(".expected.") + - expect + rb.getString(".found.") + actual + - rb.getString("QUOTE")); - } - } - - public static void main(String arg[]) throws Exception { - PolicyParser pp = new PolicyParser(true); - pp.read(new FileReader(arg[0])); - FileWriter fr = new FileWriter(arg[1]); - pp.write(fr); - fr.close(); - } -} diff --git a/jdk/src/share/classes/javax/security/auth/Policy.java b/jdk/src/share/classes/javax/security/auth/Policy.java index a32339ca78c..607bf40aca8 100644 --- a/jdk/src/share/classes/javax/security/auth/Policy.java +++ b/jdk/src/share/classes/javax/security/auth/Policy.java @@ -156,9 +156,10 @@ public abstract class Policy { private static Policy policy; private static ClassLoader contextClassLoader; + private final static String AUTH_POLICY = + "sun.security.provider.AuthPolicyFile"; - // true if a custom (not com.sun.security.auth.PolicyFile) system-wide - // policy object is set + // true if a custom (not AUTH_POLICY) system-wide policy object is set private static boolean isCustomPolicy; static { @@ -220,7 +221,7 @@ public abstract class Policy { } }); if (policy_class == null) { - policy_class = "com.sun.security.auth.PolicyFile"; + policy_class = AUTH_POLICY; } try { @@ -236,8 +237,7 @@ public abstract class Policy { contextClassLoader).newInstance(); } }); - isCustomPolicy = - !finalClass.equals("com.sun.security.auth.PolicyFile"); + isCustomPolicy = !finalClass.equals(AUTH_POLICY); } catch (Exception e) { throw new SecurityException (sun.security.util.ResourcesMgr.getString @@ -274,14 +274,14 @@ public abstract class Policy { } /** - * Returns true if a custom (not com.sun.security.auth.PolicyFile) - * system-wide policy object has been set or installed. This method is - * called by SubjectDomainCombiner to provide backwards compatibility for + * Returns true if a custom (not AUTH_POLICY) system-wide policy object + * has been set or installed. This method is called by + * SubjectDomainCombiner to provide backwards compatibility for * developers that provide their own javax.security.auth.Policy * implementations. * - * @return true if a custom (not com.sun.security.auth.PolicyFile) - * system-wide policy object has been set; false otherwise + * @return true if a custom (not AUTH_POLICY) system-wide policy object + * has been set; false otherwise */ static boolean isCustomPolicySet(Debug debug) { if (policy != null) { @@ -299,8 +299,7 @@ public abstract class Policy { return Security.getProperty("auth.policy.provider"); } }); - if (policyClass != null - && !policyClass.equals("com.sun.security.auth.PolicyFile")) { + if (policyClass != null && !policyClass.equals(AUTH_POLICY)) { if (debug != null) { debug.println("Providing backwards compatibility for " + "javax.security.auth.policy implementation: " + diff --git a/jdk/src/share/classes/sun/security/provider/AuthPolicyFile.java b/jdk/src/share/classes/sun/security/provider/AuthPolicyFile.java new file mode 100644 index 00000000000..ed9dce614ac --- /dev/null +++ b/jdk/src/share/classes/sun/security/provider/AuthPolicyFile.java @@ -0,0 +1,1195 @@ +/* + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.security.provider; + +import java.io.*; +import java.lang.reflect.*; +import java.net.URL; +import java.util.*; + +import java.security.AccessController; +import java.security.CodeSource; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.Permission; +import java.security.Permissions; +import java.security.PermissionCollection; +import java.security.Principal; +import java.security.PrivilegedAction; +import java.security.UnresolvedPermission; +import java.security.Security; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; + +import javax.security.auth.Subject; +import javax.security.auth.PrivateCredentialPermission; + +import sun.security.provider.PolicyParser.GrantEntry; +import sun.security.provider.PolicyParser.PermissionEntry; +import sun.security.provider.PolicyParser.PrincipalEntry; +import sun.security.util.Debug; +import sun.security.util.PolicyUtil; +import sun.security.util.PropertyExpander; + +/** + * See {@code com.sun.security.auth.PolicyFile} for the class description. + * This class is necessary in order to support a default + * {@code javax.security.auth.Policy} implementation on the compact1 and + * compact2 profiles. + * + * @deprecated As of JDK 1.4, replaced by + * {@code sun.security.provider.PolicyFile}. + * This class is entirely deprecated. + */ +@Deprecated +public class AuthPolicyFile extends javax.security.auth.Policy { + + static final ResourceBundle rb = + AccessController.doPrivileged(new PrivilegedAction() { + @Override public ResourceBundle run() { + return (ResourceBundle.getBundle + ("sun.security.util.AuthResources")); + } + }); + + private static final Debug debug = Debug.getInstance("policy", + "\t[Auth Policy]"); + + private static final String AUTH_POLICY = "java.security.auth.policy"; + private static final String SECURITY_MANAGER = "java.security.manager"; + private static final String AUTH_POLICY_URL = "auth.policy.url."; + + private Vector policyEntries; + private Hashtable aliasMapping; + + private boolean initialized = false; + + private boolean expandProperties = true; + private boolean ignoreIdentityScope = true; + + // for use with the reflection API + private static final Class[] PARAMS = { String.class, String.class}; + + /** + * Initializes the Policy object and reads the default policy + * configuration file(s) into the Policy object. + */ + public AuthPolicyFile() { + // initialize Policy if either the AUTH_POLICY or + // SECURITY_MANAGER properties are set + String prop = System.getProperty(AUTH_POLICY); + + if (prop == null) { + prop = System.getProperty(SECURITY_MANAGER); + } + if (prop != null) { + init(); + } + } + + private synchronized void init() { + if (initialized) { + return; + } + + policyEntries = new Vector(); + aliasMapping = new Hashtable(11); + + initPolicyFile(); + initialized = true; + } + + @Override + public synchronized void refresh() { + + java.lang.SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(new javax.security.auth.AuthPermission + ("refreshPolicy")); + } + + // XXX + // + // 1) if code instantiates PolicyFile directly, then it will need + // all the permissions required for the PolicyFile initialization + // 2) if code calls Policy.getPolicy, then it simply needs + // AuthPermission(getPolicy), and the javax.security.auth.Policy + // implementation instantiates PolicyFile in a doPrivileged block + // 3) if after instantiating a Policy (either via #1 or #2), + // code calls refresh, it simply needs + // AuthPermission(refreshPolicy). then PolicyFile wraps + // the refresh in a doPrivileged block. + initialized = false; + AccessController.doPrivileged(new PrivilegedAction() { + @Override public Void run() { + init(); + return null; + } + }); + } + + private KeyStore initKeyStore(URL policyUrl, String keyStoreName, + String keyStoreType) { + if (keyStoreName != null) { + try { + /* + * location of keystore is specified as absolute URL in policy + * file, or is relative to URL of policy file + */ + URL keyStoreUrl = null; + try { + keyStoreUrl = new URL(keyStoreName); + // absolute URL + } catch (java.net.MalformedURLException e) { + // relative URL + keyStoreUrl = new URL(policyUrl, keyStoreName); + } + + if (debug != null) { + debug.println("reading keystore"+keyStoreUrl); + } + + InputStream inStream = new BufferedInputStream( + PolicyUtil.getInputStream(keyStoreUrl)); + + KeyStore ks; + if (keyStoreType != null) + ks = KeyStore.getInstance(keyStoreType); + else + ks = KeyStore.getInstance(KeyStore.getDefaultType()); + ks.load(inStream, null); + inStream.close(); + return ks; + } catch (Exception e) { + // ignore, treat it like we have no keystore + if (debug != null) { + e.printStackTrace(); + } + return null; + } + } + return null; + } + + private void initPolicyFile() { + + String prop = Security.getProperty("policy.expandProperties"); + if (prop != null) { + expandProperties = prop.equalsIgnoreCase("true"); + } + + String iscp = Security.getProperty("policy.ignoreIdentityScope"); + if (iscp != null) { + ignoreIdentityScope = iscp.equalsIgnoreCase("true"); + } + + String allowSys = Security.getProperty("policy.allowSystemProperty"); + if (allowSys != null && allowSys.equalsIgnoreCase("true")) { + String extra_policy = System.getProperty(AUTH_POLICY); + if (extra_policy != null) { + boolean overrideAll = false; + if (extra_policy.startsWith("=")) { + overrideAll = true; + extra_policy = extra_policy.substring(1); + } + try { + extra_policy = PropertyExpander.expand(extra_policy); + URL policyURL; + File policyFile = new File(extra_policy); + if (policyFile.exists()) { + policyURL = + new URL("file:" + policyFile.getCanonicalPath()); + } else { + policyURL = new URL(extra_policy); + } + if (debug != null) { + debug.println("reading " + policyURL); + } + init(policyURL); + } catch (Exception e) { + // ignore. + if (debug != null) { + debug.println("caught exception: " + e); + } + + } + if (overrideAll) { + if (debug != null) { + debug.println("overriding other policies!"); + } + return; + } + } + } + + int n = 1; + boolean loaded_one = false; + String policy_url; + + while ((policy_url = Security.getProperty(AUTH_POLICY_URL+n)) != null) { + try { + policy_url = PropertyExpander.expand(policy_url).replace + (File.separatorChar, '/'); + if (debug != null) { + debug.println("reading " + policy_url); + } + init(new URL(policy_url)); + loaded_one = true; + } catch (Exception e) { + if (debug != null) { + debug.println("error reading policy " + e); + e.printStackTrace(); + } + // ignore that policy + } + n++; + } + + if (loaded_one == false) { + // do not load a static policy + } + } + + /** + * Checks public key. If it is marked as trusted in + * the identity database, add it to the policy + * with the AllPermission. + */ + private boolean checkForTrustedIdentity(final Certificate cert) { + return false; + } + + /** + * Reads a policy configuration into the Policy object using a + * Reader object. + * + * @param policyFile the policy Reader object. + */ + private void init(URL policy) { + PolicyParser pp = new PolicyParser(expandProperties); + try (InputStreamReader isr + = new InputStreamReader(PolicyUtil.getInputStream(policy))) { + pp.read(isr); + KeyStore keyStore = initKeyStore(policy, pp.getKeyStoreUrl(), + pp.getKeyStoreType()); + Enumeration enum_ = pp.grantElements(); + while (enum_.hasMoreElements()) { + GrantEntry ge = enum_.nextElement(); + addGrantEntry(ge, keyStore); + } + } catch (PolicyParser.ParsingException pe) { + System.err.println(AUTH_POLICY + + rb.getString(".error.parsing.") + policy); + System.err.println(AUTH_POLICY + rb.getString("COLON") + + pe.getMessage()); + if (debug != null) { + pe.printStackTrace(); + } + } catch (Exception e) { + if (debug != null) { + debug.println("error parsing " + policy); + debug.println(e.toString()); + e.printStackTrace(); + } + } + } + + /** + * Given a PermissionEntry, create a codeSource. + * + * @return null if signedBy alias is not recognized + */ + CodeSource getCodeSource(GrantEntry ge, KeyStore keyStore) + throws java.net.MalformedURLException + { + Certificate[] certs = null; + if (ge.signedBy != null) { + certs = getCertificates(keyStore, ge.signedBy); + if (certs == null) { + // we don't have a key for this alias, + // just return + if (debug != null) { + debug.println(" no certs for alias " + + ge.signedBy + ", ignoring."); + } + return null; + } + } + + URL location; + if (ge.codeBase != null) { + location = new URL(ge.codeBase); + } else { + location = null; + } + + if (ge.principals == null || ge.principals.size() == 0) { + return (canonicalizeCodebase + (new CodeSource(location, certs), + false)); + } else { + return (canonicalizeCodebase + (new SubjectCodeSource(null, ge.principals, location, certs), + false)); + } + } + + /** + * Add one policy entry to the vector. + */ + private void addGrantEntry(GrantEntry ge, KeyStore keyStore) { + + if (debug != null) { + debug.println("Adding policy entry: "); + debug.println(" signedBy " + ge.signedBy); + debug.println(" codeBase " + ge.codeBase); + if (ge.principals != null) { + for (PrincipalEntry pppe : ge.principals) { + debug.println(" " + pppe.getPrincipalClass() + + " " + pppe.getPrincipalName()); + } + } + debug.println(); + } + + try { + CodeSource codesource = getCodeSource(ge, keyStore); + // skip if signedBy alias was unknown... + if (codesource == null) return; + + PolicyEntry entry = new PolicyEntry(codesource); + Enumeration enum_ = ge.permissionElements(); + while (enum_.hasMoreElements()) { + PermissionEntry pe = enum_.nextElement(); + try { + // XXX special case PrivateCredentialPermission-SELF + Permission perm; + if (pe.permission.equals + ("javax.security.auth.PrivateCredentialPermission") && + pe.name.endsWith(" self")) { + perm = getInstance(pe.permission, + pe.name + " \"self\"", + pe.action); + } else { + perm = getInstance(pe.permission, + pe.name, + pe.action); + } + entry.add(perm); + if (debug != null) { + debug.println(" "+perm); + } + } catch (ClassNotFoundException cnfe) { + Certificate certs[]; + if (pe.signedBy != null) { + certs = getCertificates(keyStore, pe.signedBy); + } else { + certs = null; + } + + // only add if we had no signer or we had a + // a signer and found the keys for it. + if (certs != null || pe.signedBy == null) { + Permission perm = new UnresolvedPermission( + pe.permission, + pe.name, + pe.action, + certs); + entry.add(perm); + if (debug != null) { + debug.println(" "+perm); + } + } + } catch (java.lang.reflect.InvocationTargetException ite) { + System.err.println + (AUTH_POLICY + + rb.getString(".error.adding.Permission.") + + pe.permission + + rb.getString("SPACE") + + ite.getTargetException()); + } catch (Exception e) { + System.err.println + (AUTH_POLICY + + rb.getString(".error.adding.Permission.") + + pe.permission + + rb.getString("SPACE") + + e); + } + } + policyEntries.addElement(entry); + } catch (Exception e) { + System.err.println + (AUTH_POLICY + + rb.getString(".error.adding.Entry.") + + ge + + rb.getString("SPACE") + + e); + } + + if (debug != null) { + debug.println(); + } + } + + /** + * Returns a new Permission object of the given Type. The Permission is + * created by getting the + * Class object using the Class.forName method, and using + * the reflection API to invoke the (String name, String actions) + * constructor on the + * object. + * + * @param type the type of Permission being created. + * @param name the name of the Permission being created. + * @param actions the actions of the Permission being created. + * + * @exception ClassNotFoundException if the particular Permission + * class could not be found. + * + * @exception IllegalAccessException if the class or initializer is + * not accessible. + * + * @exception InstantiationException if getInstance tries to + * instantiate an abstract class or an interface, or if the + * instantiation fails for some other reason. + * + * @exception NoSuchMethodException if the (String, String) constructor + * is not found. + * + * @exception InvocationTargetException if the underlying Permission + * constructor throws an exception. + * + */ + private static final Permission getInstance(String type, + String name, + String actions) + throws ClassNotFoundException, + InstantiationException, + IllegalAccessException, + NoSuchMethodException, + InvocationTargetException + { + //XXX we might want to keep a hash of created factories... + Class pc = Class.forName(type); + Constructor c = pc.getConstructor(PARAMS); + return (Permission) c.newInstance(new Object[] { name, actions }); + } + + /** + * Fetch all certs associated with this alias. + */ + Certificate[] getCertificates(KeyStore keyStore, String aliases) { + + Vector vcerts = null; + + StringTokenizer st = new StringTokenizer(aliases, ","); + int n = 0; + + while (st.hasMoreTokens()) { + String alias = st.nextToken().trim(); + n++; + Certificate cert = null; + // See if this alias's cert has already been cached + cert = (Certificate) aliasMapping.get(alias); + if (cert == null && keyStore != null) { + + try { + cert = keyStore.getCertificate(alias); + } catch (KeyStoreException kse) { + // never happens, because keystore has already been loaded + // when we call this + } + if (cert != null) { + aliasMapping.put(alias, cert); + aliasMapping.put(cert, alias); + } + } + + if (cert != null) { + if (vcerts == null) { + vcerts = new Vector(); + } + vcerts.addElement(cert); + } + } + + // make sure n == vcerts.size, since we are doing a logical *and* + if (vcerts != null && n == vcerts.size()) { + Certificate[] certs = new Certificate[vcerts.size()]; + vcerts.copyInto(certs); + return certs; + } else { + return null; + } + } + + /** + * Enumerate all the entries in the global policy object. + * This method is used by policy admin tools. The tools + * should use the Enumeration methods on the returned object + * to fetch the elements sequentially. + */ + private final synchronized Enumeration elements() { + return policyEntries.elements(); + } + + @Override + public PermissionCollection getPermissions(final Subject subject, + final CodeSource codesource) { + + // 1) if code instantiates PolicyFile directly, then it will need + // all the permissions required for the PolicyFile initialization + // 2) if code calls Policy.getPolicy, then it simply needs + // AuthPermission(getPolicy), and the javax.security.auth.Policy + // implementation instantiates PolicyFile in a doPrivileged block + // 3) if after instantiating a Policy (either via #1 or #2), + // code calls getPermissions, PolicyFile wraps the call + // in a doPrivileged block. + return AccessController.doPrivileged + (new PrivilegedAction() { + @Override public PermissionCollection run() { + SubjectCodeSource scs = new SubjectCodeSource( + subject, null, + codesource == null ? null : codesource.getLocation(), + codesource == null ? null : codesource.getCertificates()); + if (initialized) { + return getPermissions(new Permissions(), scs); + } else { + return new PolicyPermissions(AuthPolicyFile.this, scs); + } + } + }); + } + + /** + * Examines the global policy for the specified CodeSource, and + * creates a PermissionCollection object with + * the set of permissions for that principal's protection domain. + * + * @param CodeSource the codesource associated with the caller. + * This encapsulates the original location of the code (where the code + * came from) and the public key(s) of its signer. + * + * @return the set of permissions according to the policy. + */ + PermissionCollection getPermissions(CodeSource codesource) { + + if (initialized) { + return getPermissions(new Permissions(), codesource); + } else { + return new PolicyPermissions(this, codesource); + } + } + + /** + * Examines the global policy for the specified CodeSource, and + * creates a PermissionCollection object with + * the set of permissions for that principal's protection domain. + * + * @param permissions the permissions to populate + * @param codesource the codesource associated with the caller. + * This encapsulates the original location of the code (where the code + * came from) and the public key(s) of its signer. + * + * @return the set of permissions according to the policy. + */ + Permissions getPermissions(final Permissions perms, + final CodeSource cs) + { + if (!initialized) { + init(); + } + + final CodeSource codesource[] = {null}; + + codesource[0] = canonicalizeCodebase(cs, true); + + if (debug != null) { + debug.println("evaluate(" + codesource[0] + ")\n"); + } + + // needs to be in a begin/endPrivileged block because + // codesource.implies calls URL.equals which does an + // InetAddress lookup + + for (int i = 0; i < policyEntries.size(); i++) { + + PolicyEntry entry = policyEntries.elementAt(i); + + if (debug != null) { + debug.println("PolicyFile CodeSource implies: " + + entry.codesource.toString() + "\n\n" + + "\t" + codesource[0].toString() + "\n\n"); + } + + if (entry.codesource.implies(codesource[0])) { + for (int j = 0; j < entry.permissions.size(); j++) { + Permission p = entry.permissions.elementAt(j); + if (debug != null) { + debug.println(" granting " + p); + } + if (!addSelfPermissions(p, entry.codesource, + codesource[0], perms)) { + // we could check for duplicates + // before adding new permissions, + // but the SubjectDomainCombiner + // already checks for duplicates later + perms.add(p); + } + } + } + } + + // now see if any of the keys are trusted ids. + + if (!ignoreIdentityScope) { + Certificate certs[] = codesource[0].getCertificates(); + if (certs != null) { + for (int k=0; k < certs.length; k++) { + if (aliasMapping.get(certs[k]) == null && + checkForTrustedIdentity(certs[k])) { + // checkForTrustedIdentity added it + // to the policy for us. next time + // around we'll find it. This time + // around we need to add it. + perms.add(new java.security.AllPermission()); + } + } + } + } + return perms; + } + + /** + * Returns true if 'Self' permissions were added to the provided + * 'perms', and false otherwise. + * + *

+ * + * @param p check to see if this Permission is a "SELF" + * PrivateCredentialPermission.

+ * + * @param entryCs the codesource for the Policy entry. + * + * @param accCs the codesource for from the current AccessControlContext. + * + * @param perms the PermissionCollection where the individual + * PrivateCredentialPermissions will be added. + */ + private boolean addSelfPermissions(final Permission p, + CodeSource entryCs, + CodeSource accCs, + Permissions perms) { + + if (!(p instanceof PrivateCredentialPermission)) { + return false; + } + + if (!(entryCs instanceof SubjectCodeSource)) { + return false; + } + + PrivateCredentialPermission pcp = (PrivateCredentialPermission)p; + SubjectCodeSource scs = (SubjectCodeSource)entryCs; + + // see if it is a SELF permission + String[][] pPrincipals = pcp.getPrincipals(); + if (pPrincipals.length <= 0 || + !pPrincipals[0][0].equalsIgnoreCase("self") || + !pPrincipals[0][1].equalsIgnoreCase("self")) { + + // regular PrivateCredentialPermission + return false; + } else { + + // granted a SELF permission - create a + // PrivateCredentialPermission for each + // of the Policy entry's CodeSource Principals + + if (scs.getPrincipals() == null) { + // XXX SubjectCodeSource has no Subject??? + return true; + } + + for (PrincipalEntry principal : scs.getPrincipals()) { + + // if the Policy entry's Principal does not contain a + // WILDCARD for the Principal name, then a + // new PrivateCredentialPermission is created + // for the Principal listed in the Policy entry. + // if the Policy entry's Principal contains a WILDCARD + // for the Principal name, then a new + // PrivateCredentialPermission is created + // for each Principal associated with the Subject + // in the current ACC. + + String[][] principalInfo = getPrincipalInfo(principal, accCs); + + for (int i = 0; i < principalInfo.length; i++) { + + // here's the new PrivateCredentialPermission + + PrivateCredentialPermission newPcp = + new PrivateCredentialPermission + (pcp.getCredentialClass() + + " " + + principalInfo[i][0] + + " " + + "\"" + principalInfo[i][1] + "\"", + "read"); + + if (debug != null) { + debug.println("adding SELF permission: " + + newPcp.toString()); + } + + perms.add(newPcp); + } + } + } + return true; + } + + /** + * return the principal class/name pair in the 2D array. + * array[x][y]: x corresponds to the array length. + * if (y == 0), it's the principal class. + * if (y == 1), it's the principal name. + */ + private String[][] getPrincipalInfo(PrincipalEntry principal, + final CodeSource accCs) { + + // there are 3 possibilities: + // 1) the entry's Principal class and name are not wildcarded + // 2) the entry's Principal name is wildcarded only + // 3) the entry's Principal class and name are wildcarded + + if (!principal.getPrincipalClass().equals + (PrincipalEntry.WILDCARD_CLASS) && + !principal.getPrincipalName().equals + (PrincipalEntry.WILDCARD_NAME)) { + + // build a PrivateCredentialPermission for the principal + // from the Policy entry + String[][] info = new String[1][2]; + info[0][0] = principal.getPrincipalClass(); + info[0][1] = principal.getPrincipalName(); + return info; + + } else if (!principal.getPrincipalClass().equals + (PrincipalEntry.WILDCARD_CLASS) && + principal.getPrincipalName().equals + (PrincipalEntry.WILDCARD_NAME)) { + + // build a PrivateCredentialPermission for all + // the Subject's principals that are instances of principalClass + + // the accCs is guaranteed to be a SubjectCodeSource + // because the earlier CodeSource.implies succeeded + SubjectCodeSource scs = (SubjectCodeSource)accCs; + + Set principalSet = null; + try { + // principal.principalClass should extend Principal + // If it doesn't, we should stop here with a ClassCastException. + @SuppressWarnings("unchecked") + Class pClass = (Class) + Class.forName(principal.getPrincipalClass(), false, + ClassLoader.getSystemClassLoader()); + principalSet = scs.getSubject().getPrincipals(pClass); + } catch (Exception e) { + if (debug != null) { + debug.println("problem finding Principal Class " + + "when expanding SELF permission: " + + e.toString()); + } + } + + if (principalSet == null) { + // error + return new String[0][0]; + } + + String[][] info = new String[principalSet.size()][2]; + + int i = 0; + for (Principal p : principalSet) { + info[i][0] = p.getClass().getName(); + info[i][1] = p.getName(); + i++; + } + return info; + + } else { + + // build a PrivateCredentialPermission for every + // one of the current Subject's principals + + // the accCs is guaranteed to be a SubjectCodeSource + // because the earlier CodeSource.implies succeeded + SubjectCodeSource scs = (SubjectCodeSource)accCs; + Set principalSet = scs.getSubject().getPrincipals(); + + String[][] info = new String[principalSet.size()][2]; + + int i = 0; + for (Principal p : principalSet) { + info[i][0] = p.getClass().getName(); + info[i][1] = p.getName(); + i++; + } + return info; + } + } + + /* + * Returns the signer certificates from the list of certificates associated + * with the given code source. + * + * The signer certificates are those certificates that were used to verify + * signed code originating from the codesource location. + * + * This method assumes that in the given code source, each signer + * certificate is followed by its supporting certificate chain + * (which may be empty), and that the signer certificate and its + * supporting certificate chain are ordered bottom-to-top (i.e., with the + * signer certificate first and the (root) certificate authority last). + */ + Certificate[] getSignerCertificates(CodeSource cs) { + Certificate[] certs = null; + if ((certs = cs.getCertificates()) == null) { + return null; + } + for (int i = 0; i < certs.length; i++) { + if (!(certs[i] instanceof X509Certificate)) + return cs.getCertificates(); + } + + // Do we have to do anything? + int i = 0; + int count = 0; + while (i < certs.length) { + count++; + while (((i+1) < certs.length) + && ((X509Certificate)certs[i]).getIssuerDN().equals( + ((X509Certificate)certs[i+1]).getSubjectDN())) { + i++; + } + i++; + } + if (count == certs.length) { + // Done + return certs; + } + + ArrayList userCertList = new ArrayList<>(); + i = 0; + while (i < certs.length) { + userCertList.add(certs[i]); + while (((i+1) < certs.length) + && ((X509Certificate)certs[i]).getIssuerDN().equals( + ((X509Certificate)certs[i+1]).getSubjectDN())) { + i++; + } + i++; + } + Certificate[] userCerts = new Certificate[userCertList.size()]; + userCertList.toArray(userCerts); + return userCerts; + } + + private CodeSource canonicalizeCodebase(CodeSource cs, + boolean extractSignerCerts) { + CodeSource canonCs = cs; + if (cs.getLocation() != null && + cs.getLocation().getProtocol().equalsIgnoreCase("file")) { + try { + String path = cs.getLocation().getFile().replace + ('/', + File.separatorChar); + URL csUrl = null; + if (path.endsWith("*")) { + // remove trailing '*' because it causes canonicalization + // to fail on win32 + path = path.substring(0, path.length()-1); + boolean appendFileSep = false; + if (path.endsWith(File.separator)) { + appendFileSep = true; + } + if (path.equals("")) { + path = System.getProperty("user.dir"); + } + File f = new File(path); + path = f.getCanonicalPath(); + StringBuffer sb = new StringBuffer(path); + // reappend '*' to canonicalized filename (note that + // canonicalization may have removed trailing file + // separator, so we have to check for that, too) + if (!path.endsWith(File.separator) && + (appendFileSep || f.isDirectory())) { + sb.append(File.separatorChar); + } + sb.append('*'); + path = sb.toString(); + } else { + path = new File(path).getCanonicalPath(); + } + csUrl = new File(path).toURL(); + + if (cs instanceof SubjectCodeSource) { + SubjectCodeSource scs = (SubjectCodeSource)cs; + if (extractSignerCerts) { + canonCs = new SubjectCodeSource(scs.getSubject(), + scs.getPrincipals(), + csUrl, + getSignerCertificates(scs)); + } else { + canonCs = new SubjectCodeSource(scs.getSubject(), + scs.getPrincipals(), + csUrl, + scs.getCertificates()); + } + } else { + if (extractSignerCerts) { + canonCs = new CodeSource(csUrl, + getSignerCertificates(cs)); + } else { + canonCs = new CodeSource(csUrl, + cs.getCertificates()); + } + } + } catch (IOException ioe) { + // leave codesource as it is, unless we have to extract its + // signer certificates + if (extractSignerCerts) { + if (!(cs instanceof SubjectCodeSource)) { + canonCs = new CodeSource(cs.getLocation(), + getSignerCertificates(cs)); + } else { + SubjectCodeSource scs = (SubjectCodeSource)cs; + canonCs = new SubjectCodeSource(scs.getSubject(), + scs.getPrincipals(), + scs.getLocation(), + getSignerCertificates(scs)); + } + } + } + } else { + if (extractSignerCerts) { + if (!(cs instanceof SubjectCodeSource)) { + canonCs = new CodeSource(cs.getLocation(), + getSignerCertificates(cs)); + } else { + SubjectCodeSource scs = (SubjectCodeSource)cs; + canonCs = new SubjectCodeSource(scs.getSubject(), + scs.getPrincipals(), + scs.getLocation(), + getSignerCertificates(scs)); + } + } + } + return canonCs; + } + + /** + * Each entry in the policy configuration file is represented by a + * PolicyEntry object.

+ * + * A PolicyEntry is a (CodeSource,Permission) pair. The + * CodeSource contains the (URL, PublicKey) that together identify + * where the Java bytecodes come from and who (if anyone) signed + * them. The URL could refer to localhost. The URL could also be + * null, meaning that this policy entry is given to all comers, as + * long as they match the signer field. The signer could be null, + * meaning the code is not signed.

+ * + * The Permission contains the (Type, Name, Action) triplet.

+ * + * For now, the Policy object retrieves the public key from the + * X.509 certificate on disk that corresponds to the signedBy + * alias specified in the Policy config file. For reasons of + * efficiency, the Policy object keeps a hashtable of certs already + * read in. This could be replaced by a secure internal key + * store. + * + *

+ * For example, the entry + *

+     *          permission java.io.File "/tmp", "read,write",
+     *          signedBy "Duke";
+     * 
+ * is represented internally + *
+     *
+     * FilePermission f = new FilePermission("/tmp", "read,write");
+     * PublicKey p = publickeys.get("Duke");
+     * URL u = InetAddress.getLocalHost();
+     * CodeBase c = new CodeBase( p, u );
+     * pe = new PolicyEntry(f, c);
+     * 
+ * + * @author Marianne Mueller + * @author Roland Schemers + * @see java.security.CodeSource + * @see java.security.Policy + * @see java.security.Permissions + * @see java.security.ProtectionDomain + */ + private static class PolicyEntry { + + CodeSource codesource; + Vector permissions; + + /** + * Given a Permission and a CodeSource, create a policy entry. + * + * XXX Decide if/how to add validity fields and "purpose" fields to + * XXX policy entries + * + * @param cs the CodeSource, which encapsulates the URL and the public + * key attributes from the policy config file. Validity checks + * are performed on the public key before PolicyEntry is called. + * + */ + PolicyEntry(CodeSource cs) { + this.codesource = cs; + this.permissions = new Vector(); + } + + /** + * add a Permission object to this entry. + */ + void add(Permission p) { + permissions.addElement(p); + } + + /** + * Return the CodeSource for this policy entry + */ + CodeSource getCodeSource() { + return this.codesource; + } + + @Override + public String toString(){ + StringBuffer sb = new StringBuffer(); + sb.append(rb.getString("LPARAM")); + sb.append(getCodeSource()); + sb.append("\n"); + for (int j = 0; j < permissions.size(); j++) { + Permission p = permissions.elementAt(j); + sb.append(rb.getString("SPACE")); + sb.append(rb.getString("SPACE")); + sb.append(p); + sb.append(rb.getString("NEWLINE")); + } + sb.append(rb.getString("RPARAM")); + sb.append(rb.getString("NEWLINE")); + return sb.toString(); + } + + } +} + +@SuppressWarnings("deprecation") +class PolicyPermissions extends PermissionCollection { + + private static final long serialVersionUID = -1954188373270545523L; + + private CodeSource codesource; + private Permissions perms; + private AuthPolicyFile policy; + private boolean notInit; // have we pulled in the policy permissions yet? + private Vector additionalPerms; + + PolicyPermissions(AuthPolicyFile policy, + CodeSource codesource) + { + this.codesource = codesource; + this.policy = policy; + this.perms = null; + this.notInit = true; + this.additionalPerms = null; + } + + @Override + public void add(Permission permission) { + if (isReadOnly()) + throw new SecurityException + (AuthPolicyFile.rb.getString + ("attempt.to.add.a.Permission.to.a.readonly.PermissionCollection")); + + if (perms == null) { + if (additionalPerms == null) { + additionalPerms = new Vector(); + } + additionalPerms.add(permission); + } else { + perms.add(permission); + } + } + + private synchronized void init() { + if (notInit) { + if (perms == null) { + perms = new Permissions(); + } + if (additionalPerms != null) { + Enumeration e = additionalPerms.elements(); + while (e.hasMoreElements()) { + perms.add(e.nextElement()); + } + additionalPerms = null; + } + policy.getPermissions(perms, codesource); + notInit = false; + } + } + + @Override + public boolean implies(Permission permission) { + if (notInit) { + init(); + } + return perms.implies(permission); + } + + @Override + public Enumeration elements() { + if (notInit) { + init(); + } + return perms.elements(); + } + + @Override + public String toString() { + if (notInit) { + init(); + } + return perms.toString(); + } +} diff --git a/jdk/src/share/classes/com/sun/security/auth/SubjectCodeSource.java b/jdk/src/share/classes/sun/security/provider/SubjectCodeSource.java similarity index 93% rename from jdk/src/share/classes/com/sun/security/auth/SubjectCodeSource.java rename to jdk/src/share/classes/sun/security/provider/SubjectCodeSource.java index 7e38a087420..89a98129f19 100644 --- a/jdk/src/share/classes/com/sun/security/auth/SubjectCodeSource.java +++ b/jdk/src/share/classes/sun/security/provider/SubjectCodeSource.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.security.auth; +package sun.security.provider; import java.net.URL; import java.util.*; @@ -39,8 +39,7 @@ import sun.security.provider.PolicyParser.PrincipalEntry; *

This SubjectCodeSource class contains * a URL, signer certificates, and either a Subject * (that represents the Subject in the current - * AccessControlContext), - * or a linked list of Principals/PrincipalComparators + * AccessControlContext), or a linked list of Principals * (that represent a "subject" in a Policy). * */ @@ -148,10 +147,10 @@ class SubjectCodeSource extends CodeSource implements java.io.Serializable { *

  • for each principal in this codesource's principal list: *
      *
    1. if the principal is an instanceof - * PrincipalComparator, then the principal must + * Principal, then the principal must * imply the provided codesource's Subject. *
    2. if the principal is not an instanceof - * PrincipalComparator, then the provided + * Principal, then the provided * codesource's Subject must have an * associated Principal, P, where * P.getClass().getName equals principal.principalClass, @@ -203,16 +202,20 @@ class SubjectCodeSource extends CodeSource implements java.io.Serializable { PrincipalEntry pppe = li.next(); try { - // handle PrincipalComparators + // use new Principal.implies method - Class principalComparator = Class.forName( - pppe.getPrincipalClass(), true, sysClassLoader); - Constructor c = principalComparator.getConstructor(PARAMS); - PrincipalComparator pc = - (PrincipalComparator)c.newInstance - (new Object[] { pppe.getPrincipalName() }); + Class pClass = Class.forName(pppe.principalClass, + true, sysClassLoader); + if (!Principal.class.isAssignableFrom(pClass)) { + // not the right subtype + throw new ClassCastException(pppe.principalClass + + " is not a Principal"); + } + Constructor c = pClass.getConstructor(PARAMS); + Principal p = (Principal)c.newInstance(new Object[] { + pppe.principalName }); - if (!pc.implies(that.getSubject())) { + if (!p.implies(that.getSubject())) { if (debug != null) debug.println("\tSubjectCodeSource.implies: FAILURE 3"); return false; @@ -223,7 +226,7 @@ class SubjectCodeSource extends CodeSource implements java.io.Serializable { } } catch (Exception e) { - // no PrincipalComparator, simply compare Principals + // simply compare Principals if (subjectList == null) { From 2e2313ef8732e406bc0ad08cfd5812915d6b082d Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Mon, 19 Aug 2013 17:42:39 -0700 Subject: [PATCH 067/102] 8020842: IDN do not throw IAE when hostname ends with a trailing dot Reviewed-by: weijun, michaelm --- jdk/src/share/classes/java/net/IDN.java | 43 +++++++++-- jdk/test/java/net/IDN/IllegalArg.java | 72 +++++++++++++++++++ .../net/ssl/ServerName/IllegalSNIName.java | 54 ++++++++++++++ 3 files changed, 164 insertions(+), 5 deletions(-) create mode 100644 jdk/test/java/net/IDN/IllegalArg.java create mode 100644 jdk/test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java diff --git a/jdk/src/share/classes/java/net/IDN.java b/jdk/src/share/classes/java/net/IDN.java index 0e481558956..ed2f3a38159 100644 --- a/jdk/src/share/classes/java/net/IDN.java +++ b/jdk/src/share/classes/java/net/IDN.java @@ -113,11 +113,18 @@ public final class IDN { int p = 0, q = 0; StringBuffer out = new StringBuffer(); + if (isRootLabel(input)) { + return "."; + } + while (p < input.length()) { q = searchDots(input, p); out.append(toASCIIInternal(input.substring(p, q), flag)); + if (q != (input.length())) { + // has more labels, or keep the trailing dot as at present + out.append('.'); + } p = q + 1; - if (p < input.length()) out.append('.'); } return out.toString(); @@ -167,11 +174,18 @@ public final class IDN { int p = 0, q = 0; StringBuffer out = new StringBuffer(); + if (isRootLabel(input)) { + return "."; + } + while (p < input.length()) { q = searchDots(input, p); out.append(toUnicodeInternal(input.substring(p, q), flag)); + if (q != (input.length())) { + // has more labels, or keep the trailing dot as at present + out.append('.'); + } p = q + 1; - if (p < input.length()) out.append('.'); } return out.toString(); @@ -263,6 +277,13 @@ public final class IDN { dest = new StringBuffer(label); } + // step 8, move forward to check the smallest number of the code points + // the length must be inside 1..63 + if (dest.length() == 0) { + throw new IllegalArgumentException( + "Empty label is not a legal name"); + } + // step 3 // Verify the absence of non-LDH ASCII code points // 0..0x2c, 0x2e..0x2f, 0x3a..0x40, 0x5b..0x60, 0x7b..0x7f @@ -311,7 +332,7 @@ public final class IDN { // step 8 // the length must be inside 1..63 - if(dest.length() > MAX_LABEL_LENGTH){ + if (dest.length() > MAX_LABEL_LENGTH) { throw new IllegalArgumentException("The label in the input is too long"); } @@ -409,8 +430,7 @@ public final class IDN { private static int searchDots(String s, int start) { int i; for (i = start; i < s.length(); i++) { - char c = s.charAt(i); - if (c == '.' || c == '\u3002' || c == '\uFF0E' || c == '\uFF61') { + if (isLabelSeparator(s.charAt(i))) { break; } } @@ -418,6 +438,19 @@ public final class IDN { return i; } + // + // to check if a string is a root label, ".". + // + private static boolean isRootLabel(String s) { + return (s.length() == 1 && isLabelSeparator(s.charAt(0))); + } + + // + // to check if a character is a label separator, i.e. a dot character. + // + private static boolean isLabelSeparator(char c) { + return (c == '.' || c == '\u3002' || c == '\uFF0E' || c == '\uFF61'); + } // // to check if a string only contains US-ASCII code point diff --git a/jdk/test/java/net/IDN/IllegalArg.java b/jdk/test/java/net/IDN/IllegalArg.java new file mode 100644 index 00000000000..39fee7c55be --- /dev/null +++ b/jdk/test/java/net/IDN/IllegalArg.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013, 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 8020842 + * @summary IDN do not throw IAE when hostname ends with a trailing dot + */ + +import java.net.*; + +public class IllegalArg { + + public static void main(String[] args) throws Exception { + String[] illegalNames = { + "com..net", + "com..", + ".com", + ".com." + }; + + String[] legalNames = { + "example.com", + "com\u3002", + "com.", + "." + }; + + for (String name : illegalNames) { + try { + IDN.toASCII(name, IDN.USE_STD3_ASCII_RULES); + throw new Exception( + "Expected to get IllegalArgumentException for " + name); + } catch (IllegalArgumentException iae) { + // That's the right behavior. + } + + try { + IDN.toASCII(name); + throw new Exception( + "Expected to get IllegalArgumentException for " + name); + } catch (IllegalArgumentException iae) { + // That's the right behavior. + } + } + + for (String name : legalNames) { + System.out.println("Convering " + name); + System.out.println(IDN.toASCII(name, IDN.USE_STD3_ASCII_RULES)); + } + } +} diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java b/jdk/test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java new file mode 100644 index 00000000000..4d5460739cd --- /dev/null +++ b/jdk/test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013, 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 8020842 + * @summary SNIHostName does not throw IAE when hostname ends + * with a trailing dot + */ + +import javax.net.ssl.SNIHostName; + +public class IllegalSNIName { + + public static void main(String[] args) throws Exception { + String[] illegalNames = { + "example\u3003\u3002com", + "example..com", + "com\u3002", + "com.", + "." + }; + + for (String name : illegalNames) { + try { + SNIHostName hostname = new SNIHostName(name); + throw new Exception( + "Expected to get IllegalArgumentException for " + name); + } catch (IllegalArgumentException iae) { + // That's the right behavior. + } + } + } +} From 92f9b54cd34f7ac25af3935587e5fe9e1f6382d9 Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Mon, 19 Aug 2013 18:49:36 -0700 Subject: [PATCH 068/102] 8023230: The impl of KerberosClientKeyExchange maybe not exist Reviewed-by: weijun --- .../ssl/KerberosClientKeyExchange.java | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/jdk/src/share/classes/sun/security/ssl/KerberosClientKeyExchange.java b/jdk/src/share/classes/sun/security/ssl/KerberosClientKeyExchange.java index cd5822b00ea..7b4decf1be7 100644 --- a/jdk/src/share/classes/sun/security/ssl/KerberosClientKeyExchange.java +++ b/jdk/src/share/classes/sun/security/ssl/KerberosClientKeyExchange.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -57,7 +57,8 @@ public class KerberosClientKeyExchange extends HandshakeMessage { private final KerberosClientKeyExchange impl = createImpl(); private KerberosClientKeyExchange createImpl() { - if (getClass() == KerberosClientKeyExchange.class) { + if (implClass != null && + getClass() == KerberosClientKeyExchange.class) { try { return (KerberosClientKeyExchange)implClass.newInstance(); } catch (InstantiationException e) { @@ -69,8 +70,11 @@ public class KerberosClientKeyExchange extends HandshakeMessage { return null; } - public KerberosClientKeyExchange() { - // empty + // This constructor will be called when constructing an instance of its + // subclass -- KerberosClientKeyExchangeImpl. Please won't check the + // value of impl variable in this constructor. + protected KerberosClientKeyExchange() { + // please won't check the value of impl variable } public KerberosClientKeyExchange(String serverName, boolean isLoopback, @@ -85,8 +89,9 @@ public class KerberosClientKeyExchange extends HandshakeMessage { } public KerberosClientKeyExchange(ProtocolVersion protocolVersion, - ProtocolVersion clientVersion, SecureRandom rand, - HandshakeInStream input, AccessControlContext acc, Object serverKeys) throws IOException { + ProtocolVersion clientVersion, SecureRandom rand, + HandshakeInStream input, AccessControlContext acc, + Object serverKeys) throws IOException { if (impl != null) { init(protocolVersion, clientVersion, rand, input, acc, serverKeys); @@ -101,7 +106,7 @@ public class KerberosClientKeyExchange extends HandshakeMessage { } @Override - public int messageLength() { + public int messageLength() { return impl.messageLength(); } @@ -125,11 +130,13 @@ public class KerberosClientKeyExchange extends HandshakeMessage { } public void init(ProtocolVersion protocolVersion, - ProtocolVersion clientVersion, SecureRandom rand, - HandshakeInStream input, AccessControlContext acc, Object ServiceCreds) throws IOException { + ProtocolVersion clientVersion, SecureRandom rand, + HandshakeInStream input, AccessControlContext acc, + Object ServiceCreds) throws IOException { if (impl != null) { - impl.init(protocolVersion, clientVersion, rand, input, acc, ServiceCreds); + impl.init(protocolVersion, clientVersion, + rand, input, acc, ServiceCreds); } } From 073cd1d63218621c18e0cb38a4187b8d1d76c68b Mon Sep 17 00:00:00 2001 From: Staffan Larsen Date: Tue, 20 Aug 2013 08:59:15 +0200 Subject: [PATCH 069/102] 8022071: Some vm/jvmti tests fail because cannot attach to the Java virtual machine Reviewed-by: erikj, sspitsyn --- jdk/makefiles/CompileNativeLibraries.gmk | 24 ++++++++++--------- .../mapfiles/libattach/reorder-windows-x86 | 2 ++ .../mapfiles/libattach/reorder-windows-x86_64 | 2 ++ .../sun/tools/attach/WindowsVirtualMachine.c | 12 +++++----- 4 files changed, 23 insertions(+), 17 deletions(-) create mode 100644 jdk/makefiles/mapfiles/libattach/reorder-windows-x86 create mode 100644 jdk/makefiles/mapfiles/libattach/reorder-windows-x86_64 diff --git a/jdk/makefiles/CompileNativeLibraries.gmk b/jdk/makefiles/CompileNativeLibraries.gmk index f5582fc6a90..656ee3c4841 100644 --- a/jdk/makefiles/CompileNativeLibraries.gmk +++ b/jdk/makefiles/CompileNativeLibraries.gmk @@ -199,7 +199,7 @@ LIBJAVA_CFLAGS:=$(foreach dir,$(LIBJAVA_SRC_DIRS),-I$(dir)) \ LIBJAVA_CFLAGS += -DJDK_MAJOR_VERSION='"$(JDK_MAJOR_VERSION)"' \ -DJDK_MINOR_VERSION='"$(JDK_MINOR_VERSION)"' \ -DJDK_MICRO_VERSION='"$(JDK_MICRO_VERSION)"' \ - -DJDK_BUILD_NUMBER='"$(JDK_BUILD_NUMBER)"' + -DJDK_BUILD_NUMBER='"$(JDK_BUILD_NUMBER)"' ifneq (,$(JDK_UPDATE_VERSION)) LIBJAVA_CFLAGS += -DJDK_UPDATE_VERSION='"$(JDK_UPDATE_VERSION)"' @@ -279,7 +279,7 @@ $(BUILD_LIBJAVA) : $(BUILD_LIBFDLIBM) BUILD_LIBMLIB_SRC:=$(JDK_TOPDIR)/src/share/native/sun/awt/medialib BUILD_LIBMLIB_CFLAGS:=-D__USE_J2D_NAMES -D__MEDIALIB_OLD_NAMES \ -I$(BUILD_LIBMLIB_SRC) \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/awt/medialib + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/awt/medialib BUILD_LIBMLIB_LDLIBS:= BUILD_LIBMLIB_IMAGE_MAPFILE:=$(JDK_TOPDIR)/makefiles/mapfiles/libmlib_image/mapfile-vers @@ -1042,6 +1042,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBATTACH,\ LANG:=C,\ OPTIMIZATION:=LOW, \ CFLAGS:=$(CFLAGS_JDKLIB),\ + CFLAGS_windows:=/Gy,\ MAPFILE:=$(JDK_TOPDIR)/makefiles/mapfiles/libattach/mapfile-$(OPENJDK_TARGET_OS), \ VERSIONINFO_RESOURCE:=$(JDK_TOPDIR)/src/windows/resource/version.rc,\ RC_FLAGS:=$(RC_FLAGS) \ @@ -1051,6 +1052,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBATTACH,\ LDFLAGS:=$(LDFLAGS_JDKLIB) \ $(call SET_SHARED_LIBRARY_ORIGIN),\ LDFLAGS_solaris:=-ldoor,\ + LDFLAGS_windows:=/ORDER:@$(JDK_TOPDIR)/makefiles/mapfiles/libattach/reorder-windows-$(OPENJDK_TARGET_CPU),\ LDFLAGS_SUFFIX:=$(LDFLAGS_JDKLIB_SUFFIX),\ LDFLAGS_SUFFIX_windows:=$(WIN_JAVA_LIB) advapi32.lib psapi.lib,\ OBJECT_DIR:=$(JDK_OUTPUTDIR)/objs/libattach,\ @@ -1413,10 +1415,10 @@ ifndef OPENJDK # ifeq ($(OPENJDK_TARGET_OS), linux) # ifeq ("$(CC_VER_MAJOR)", "3") # OTHER_LDLIBS += -Wl,-Bstatic -lgcc_eh -Wl,-Bdynamic -# endif +# endif # endif # -# The resulting size of the t2k lib file is (at least on linux) dependant on the order of +# The resulting size of the t2k lib file is (at least on linux) dependant on the order of # the input .o files. Because of this the new build will differ in size to the old build. BUILD_LIBT2K_CFLAGS_COMMON:=-I$(JDK_TOPDIR)/src/share/native/sun/font \ -I$(JDK_TOPDIR)/src/closed/share/native/sun/font/t2k \ @@ -1590,8 +1592,8 @@ LIBINSTRUMENT_LDFLAGS_SUFFIX:= ifeq ($(OPENJDK_TARGET_OS), windows) LIBINSTRUMENT_LDFLAGS += $(JDK_OUTPUTDIR)/objs/jli_static.lib $(WIN_JAVA_LIB) \ -export:Agent_OnAttach advapi32.lib - # Statically link the C runtime so that there are not dependencies on modules - # not on the search patch when invoked from the Windows system directory + # Statically link the C runtime so that there are not dependencies on modules + # not on the search patch when invoked from the Windows system directory # (or elsewhere). LIBINSTRUMENT_CFLAGS := $(filter-out -MD,$(LIBINSTRUMENT_CFLAGS)) # equivalent of strcasecmp is stricmp on Windows @@ -2065,13 +2067,13 @@ endif ifeq ($(OPENJDK_TARGET_OS), windows) BUILD_LIBJLI_FILES += java_md.c \ - cmdtoargs.c + cmdtoargs.c # Staticically link with c runtime on windows. LIBJLI_CFLAGS:=$(filter-out -MD,$(LIBJLI_CFLAGS)) else ifneq ($(OPENJDK_TARGET_OS), macosx) BUILD_LIBJLI_FILES += java_md_common.c - BUILD_LIBJLI_FILES += java_md_solinux.c ergo.c + BUILD_LIBJLI_FILES += java_md_solinux.c ergo.c ERGO_ARCH_FILE = ergo_$(ERGO_FAMILY).c @@ -2518,7 +2520,7 @@ $(eval $(call SetupNativeCompilation,LIBSPLASHSCREEN,\ BUILD_LIBRARIES += $(LIBSPLASHSCREEN) ifeq ($(OPENJDK_TARGET_OS),macosx) -$(LIBSPLASHSCREEN) : $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)osxapp$(SHARED_LIBRARY_SUFFIX) +$(LIBSPLASHSCREEN) : $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)osxapp$(SHARED_LIBRARY_SUFFIX) endif endif @@ -3246,7 +3248,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBAWT_LWAWT,\ BUILD_LIBRARIES += $(BUILD_LIBAWT_LWAWT) -$(BUILD_LIBAWT_LWAWT) : $(BUILD_LIBAWT) +$(BUILD_LIBAWT_LWAWT) : $(BUILD_LIBAWT) $(BUILD_LIBAWT_LWAWT) : $(BUILD_LIBMLIB_IMAGE) @@ -3287,7 +3289,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBOSXUI,\ BUILD_LIBRARIES += $(BUILD_LIBOSXUI) -$(BUILD_LIBOSXUI) : $(BUILD_LIBAWT) +$(BUILD_LIBOSXUI) : $(BUILD_LIBAWT) $(BUILD_LIBOSXUI) : $(BUILD_LIBOSXAPP) diff --git a/jdk/makefiles/mapfiles/libattach/reorder-windows-x86 b/jdk/makefiles/mapfiles/libattach/reorder-windows-x86 new file mode 100644 index 00000000000..d5e250febf2 --- /dev/null +++ b/jdk/makefiles/mapfiles/libattach/reorder-windows-x86 @@ -0,0 +1,2 @@ +jvm_attach_thread_func@4 +jvm_attach_thread_func_end diff --git a/jdk/makefiles/mapfiles/libattach/reorder-windows-x86_64 b/jdk/makefiles/mapfiles/libattach/reorder-windows-x86_64 new file mode 100644 index 00000000000..c7beea8eae5 --- /dev/null +++ b/jdk/makefiles/mapfiles/libattach/reorder-windows-x86_64 @@ -0,0 +1,2 @@ +jvm_attach_thread_func +jvm_attach_thread_func_end diff --git a/jdk/src/windows/native/sun/tools/attach/WindowsVirtualMachine.c b/jdk/src/windows/native/sun/tools/attach/WindowsVirtualMachine.c index 28424dd1523..4938b0a824d 100644 --- a/jdk/src/windows/native/sun/tools/attach/WindowsVirtualMachine.c +++ b/jdk/src/windows/native/sun/tools/attach/WindowsVirtualMachine.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -91,7 +91,7 @@ typedef struct { * Code copied to target process */ #pragma check_stack (off) -static DWORD WINAPI thread_func(DataBlock *pData) +DWORD WINAPI jvm_attach_thread_func(DataBlock *pData) { HINSTANCE h; EnqueueOperationFunc addr; @@ -117,8 +117,8 @@ static DWORD WINAPI thread_func(DataBlock *pData) } } -/* This function marks the end of thread_func. */ -static void thread_end (void) { +/* This function marks the end of jvm_attach_thread_func. */ +void jvm_attach_thread_func_end (void) { } #pragma check_stack @@ -152,10 +152,10 @@ JNIEXPORT jbyteArray JNICALL Java_sun_tools_attach_WindowsVirtualMachine_generat DWORD len; jbyteArray array; - len = (DWORD)((LPBYTE) thread_end - (LPBYTE) thread_func); + len = (DWORD)((LPBYTE) jvm_attach_thread_func_end - (LPBYTE) jvm_attach_thread_func); array= (*env)->NewByteArray(env, (jsize)len); if (array != NULL) { - (*env)->SetByteArrayRegion(env, array, 0, (jint)len, (jbyte*)&thread_func); + (*env)->SetByteArrayRegion(env, array, 0, (jint)len, (jbyte*)&jvm_attach_thread_func); } return array; } From 0c815d136020e45ff275d2a91202fef2b45da596 Mon Sep 17 00:00:00 2001 From: David Holmes Date: Tue, 20 Aug 2013 03:18:56 -0400 Subject: [PATCH 070/102] 8023311: Clean up profile-includes.txt Reviewed-by: alanb --- jdk/makefiles/profile-includes.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jdk/makefiles/profile-includes.txt b/jdk/makefiles/profile-includes.txt index f4876284b73..fe2f13e2be8 100644 --- a/jdk/makefiles/profile-includes.txt +++ b/jdk/makefiles/profile-includes.txt @@ -102,6 +102,7 @@ PROFILE_1_JRE_JAR_FILES := \ security/US_export_policy.jar \ security/local_policy.jar + PROFILE_2_JRE_BIN_FILES := \ rmid$(EXE_SUFFIX) \ rmiregistry$(EXE_SUFFIX) @@ -140,7 +141,6 @@ PROFILE_3_JRE_LIB_FILES := \ PROFILE_3_JRE_OTHER_FILES := PROFILE_3_JRE_JAR_FILES := \ - jfr.jar \ management-agent.jar @@ -253,6 +253,6 @@ FULL_JRE_JAR_FILES := \ ext/cldrdata.jar \ ext/dnsns.jar \ ext/nashorn.jar \ - ext/zipfs.jar - + ext/zipfs.jar \ + jfr.jar From e838e317684bd1fd3111528afe5007c87ea0c1a4 Mon Sep 17 00:00:00 2001 From: Staffan Larsen Date: Tue, 20 Aug 2013 16:53:27 +0200 Subject: [PATCH 071/102] 8016727: test/com/sun/jdi/sde/TemperatureTableTest.java failing intermittently Reviewed-by: alanb --- jdk/test/com/sun/jdi/sde/TemperatureTableTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/test/com/sun/jdi/sde/TemperatureTableTest.java b/jdk/test/com/sun/jdi/sde/TemperatureTableTest.java index 39db17e6b31..fbaae62ca62 100644 --- a/jdk/test/com/sun/jdi/sde/TemperatureTableTest.java +++ b/jdk/test/com/sun/jdi/sde/TemperatureTableTest.java @@ -7,7 +7,7 @@ * @author Robert Field * * @library .. - * @run build TestScaffold VMConnection TargetListener TargetAdapter InstallSDE + * @run build TestScaffold VMConnection TargetListener TargetAdapter InstallSDE HelloWorld * @run compile TemperatureTableTest.java * @run compile -g TemperatureTableServlet.java * @run main TemperatureTableTest From 906bb894db7f187276502bf8bd62098464186ab6 Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Tue, 20 Aug 2013 17:36:15 +0200 Subject: [PATCH 072/102] 8023367: Collections.emptyList().sort((Comparator)null) throws NPE Reviewed-by: alanb, mduigou --- jdk/src/share/classes/java/util/Collections.java | 1 - jdk/test/java/util/Collection/ListDefaults.java | 7 +++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/util/Collections.java b/jdk/src/share/classes/java/util/Collections.java index 97555f567fa..16263277f70 100644 --- a/jdk/src/share/classes/java/util/Collections.java +++ b/jdk/src/share/classes/java/util/Collections.java @@ -4508,7 +4508,6 @@ public class Collections { } @Override public void sort(Comparator c) { - Objects.requireNonNull(c); } // Override default methods in Collection diff --git a/jdk/test/java/util/Collection/ListDefaults.java b/jdk/test/java/util/Collection/ListDefaults.java index e0f8e6f6992..0d7a29152f6 100644 --- a/jdk/test/java/util/Collection/ListDefaults.java +++ b/jdk/test/java/util/Collection/ListDefaults.java @@ -49,6 +49,7 @@ import java.util.function.Predicate; /** * @test + * @bug 8023367 * @library testlibrary * @build CollectionAsserts CollectionSupplier * @run testng ListDefaults @@ -100,6 +101,7 @@ public class ListDefaults { @DataProvider(name="listProvider", parallel=true) public static Object[][] listCases() { final List cases = new LinkedList<>(); + cases.add(new Object[] { Collections.emptyList() }); cases.add(new Object[] { new ArrayList<>() }); cases.add(new Object[] { new LinkedList<>() }); cases.add(new Object[] { new Vector<>() }); @@ -128,6 +130,11 @@ public class ListDefaults { list.removeIf(null); fail("expected NPE not thrown"); } catch (NullPointerException npe) {} + try { + list.sort(null); + } catch (Throwable t) { + fail("Exception not expected: " + t); + } } @Test From ab53c307532abb084d125a6303a5472a71c0bd85 Mon Sep 17 00:00:00 2001 From: Attila Szegedi Date: Tue, 20 Aug 2013 11:15:08 +0200 Subject: [PATCH 073/102] 8023250: Update JavaScript code in JDK for changes in iteration over Java arrays Reviewed-by: sundar, sla --- jdk/src/share/classes/com/sun/tools/hat/resources/hat.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/classes/com/sun/tools/hat/resources/hat.js b/jdk/src/share/classes/com/sun/tools/hat/resources/hat.js index f2c92ab4b0d..ec15e15acd6 100644 --- a/jdk/src/share/classes/com/sun/tools/hat/resources/hat.js +++ b/jdk/src/share/classes/com/sun/tools/hat/resources/hat.js @@ -1144,7 +1144,7 @@ function contains(array, code) { } else { for (var index in array) { var it = array[index]; - if (func(it, index, array)) { + if (func(it, String(index), array)) { return true; } } @@ -1244,7 +1244,7 @@ function filter(array, code) { var result = new Array(); for (var index in array) { var it = array[index]; - if (func(it, index, array, result)) { + if (func(it, String(index), array, result)) { result[result.length] = it; } } @@ -1317,7 +1317,7 @@ function map(array, code) { var result = new Array(); for (var index in array) { var it = array[index]; - result[result.length] = func(it, index, array, result); + result[result.length] = func(it, String(index), array, result); } return result; } From 7568ce74817aebe1d62d0bb86e9b560d0674a68c Mon Sep 17 00:00:00 2001 From: David Holmes Date: Wed, 21 Aug 2013 05:56:46 -0400 Subject: [PATCH 074/102] 8023460: OPENJDK build fails due to missing jfr.jar Reviewed-by: alanb --- jdk/makefiles/Profiles.gmk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jdk/makefiles/Profiles.gmk b/jdk/makefiles/Profiles.gmk index 47fadcc9df9..9e79b2b27ac 100644 --- a/jdk/makefiles/Profiles.gmk +++ b/jdk/makefiles/Profiles.gmk @@ -65,10 +65,6 @@ PROFILE_2_JARS := \ $(if $(PROFILE_2_JRE_JAR_FILES), $(addprefix $(IMAGES_OUTPUTDIR)/lib/, $(PROFILE_2_JRE_JAR_FILES))) \ $(PROFILE_1_JARS) -ifneq ($(ENABLE_JFR), true) - PROFILE_3_JRE_JAR_FILES := $(filter-out jfr.jar, $(PROFILE_3_JRE_JAR_FILES)) -endif - PROFILE_3_JARS := \ $(addprefix $(IMAGES_OUTPUTDIR)/lib/, $(PROFILE_3_JRE_JAR_FILES)) \ $(PROFILE_2_JARS) @@ -77,6 +73,10 @@ ifdef OPENJDK FULL_JRE_JAR_FILES := $(filter-out alt-rt.jar, $(FULL_JRE_JAR_FILES)) endif +ifneq ($(ENABLE_JFR), true) + FULL_JRE_JAR_FILES := $(filter-out jfr.jar, $(FULL_JRE_JAR_FILES)) +endif + FULL_JRE_JARS := \ $(addprefix $(IMAGES_OUTPUTDIR)/lib/, $(FULL_JRE_JAR_FILES)) \ $(PROFILE_3_JARS) From 01ba926ba1c9bb8bf32f017a74d1c2549b866bce Mon Sep 17 00:00:00 2001 From: Staffan Larsen Date: Wed, 21 Aug 2013 17:19:46 +0200 Subject: [PATCH 075/102] 8023485: Remove com/sun/jdi/DoubleAgentTest.java and com/sun/jdi/FieldWatchpoints.java from ProblemList.txt Reviewed-by: chegar, mgronlun --- jdk/test/ProblemList.txt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 00a354a7b0d..ab2eac5ecbd 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -336,12 +336,6 @@ com/sun/jdi/SuspendThreadTest.java generic-all # Filed 6653793 com/sun/jdi/RedefineCrossEvent.java generic-all -# Filed 6987312 -com/sun/jdi/DoubleAgentTest.java generic-all - -# Filed 7020857 -com/sun/jdi/FieldWatchpoints.java generic-all - # Filed 6402201 com/sun/jdi/ProcessAttachTest.sh generic-all From 8a3c65febe4da5102c544676429e26868e6110ee Mon Sep 17 00:00:00 2001 From: Mike Duigou Date: Wed, 21 Aug 2013 12:03:19 -0700 Subject: [PATCH 076/102] 8023306: Add replace() implementations to TreeMap Reviewed-by: psandoz, alanb, chegar, bpb --- jdk/src/share/classes/java/util/TreeMap.java | 21 ++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/jdk/src/share/classes/java/util/TreeMap.java b/jdk/src/share/classes/java/util/TreeMap.java index 52d9df25a0b..9a4681d771a 100644 --- a/jdk/src/share/classes/java/util/TreeMap.java +++ b/jdk/src/share/classes/java/util/TreeMap.java @@ -972,6 +972,27 @@ public class TreeMap return tailMap(fromKey, true); } + @Override + public boolean replace(K key, V oldValue, V newValue) { + Entry p = getEntry(key); + if (p!=null && Objects.equals(oldValue, p.value)) { + p.value = newValue; + return true; + } + return false; + } + + @Override + public V replace(K key, V value) { + Entry p = getEntry(key); + if (p!=null) { + V oldValue = p.value; + p.value = value; + return oldValue; + } + return null; + } + @Override public void forEach(BiConsumer action) { Objects.requireNonNull(action); From 629de57fe861fa4cfc986f48570c17790381e0b5 Mon Sep 17 00:00:00 2001 From: Mike Duigou Date: Wed, 21 Aug 2013 12:03:28 -0700 Subject: [PATCH 077/102] 8023395: Remove sun.misc.Sort and sun.misc.Compare Reviewed-by: alanb, smarks, darcy, mr --- jdk/src/share/classes/sun/misc/Compare.java | 46 ------------- jdk/src/share/classes/sun/misc/Sort.java | 74 --------------------- 2 files changed, 120 deletions(-) delete mode 100644 jdk/src/share/classes/sun/misc/Compare.java delete mode 100644 jdk/src/share/classes/sun/misc/Sort.java diff --git a/jdk/src/share/classes/sun/misc/Compare.java b/jdk/src/share/classes/sun/misc/Compare.java deleted file mode 100644 index 400fc1713ca..00000000000 --- a/jdk/src/share/classes/sun/misc/Compare.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 1996, 1997, 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. - */ - -/** - * Compare: an interface to enable users to define the result of - * a comparison of two objects. - * - * @author Sunita Mani - */ - -package sun.misc; - -public interface Compare { - - /** - * doCompare - * - * @param obj1 first object to compare. - * @param obj2 second object to compare. - * @return -1 if obj1 < obj2, 0 if obj1 == obj2, 1 if obj1 > obj2. - */ - public int doCompare(Object obj1, Object obj2); - -} diff --git a/jdk/src/share/classes/sun/misc/Sort.java b/jdk/src/share/classes/sun/misc/Sort.java deleted file mode 100644 index adf8e78ff2c..00000000000 --- a/jdk/src/share/classes/sun/misc/Sort.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 1996, 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. - */ - -/** - * Sort: a class that uses the quicksort algorithm to sort an - * array of objects. - * - * @author Sunita Mani - */ - -package sun.misc; - -public class Sort { - - private static void swap(Object arr[], int i, int j) { - Object tmp; - - tmp = arr[i]; - arr[i] = arr[j]; - arr[j] = tmp; - } - - /** - * quicksort the array of objects. - * - * @param arr[] - an array of objects - * @param left - the start index - from where to begin sorting - * @param right - the last index. - * @param comp - an object that implemnts the Compare interface to resolve thecomparison. - */ - public static void quicksort(Object arr[], int left, int right, Compare comp) { - int i, last; - - if (left >= right) { /* do nothing if array contains fewer than two */ - return; /* two elements */ - } - swap(arr, left, (left+right) / 2); - last = left; - for (i = left+1; i <= right; i++) { - if (comp.doCompare(arr[i], arr[left]) < 0) { - swap(arr, ++last, i); - } - } - swap(arr, left, last); - quicksort(arr, left, last-1, comp); - quicksort(arr, last+1, right, comp); - } - - public static void quicksort(Object arr[], Compare comp) { - quicksort(arr, 0, arr.length-1, comp); - } -} From c9443a8346bb73891c3cdbc7e174daebf4fa1b79 Mon Sep 17 00:00:00 2001 From: Ben Evans Date: Tue, 20 Aug 2013 14:23:32 -0700 Subject: [PATCH 078/102] 8016846: Pattern.splitAsStream tests required Reviewed-by: alanb, psandoz --- jdk/test/java/util/regex/PatternTest.java | 147 ++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 jdk/test/java/util/regex/PatternTest.java diff --git a/jdk/test/java/util/regex/PatternTest.java b/jdk/test/java/util/regex/PatternTest.java new file mode 100644 index 00000000000..aab17319ae4 --- /dev/null +++ b/jdk/test/java/util/regex/PatternTest.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary Unit tests for wrapping classes should delegate to default methods + * @library ../stream/bootlib + * @build java.util.stream.OpTestCase + * @run testng/othervm PatternTest + */ + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; +import java.util.regex.Pattern; +import java.util.stream.LambdaTestHelpers; +import java.util.stream.OpTestCase; +import java.util.stream.Stream; +import java.util.stream.TestData; + +@Test +public class PatternTest extends OpTestCase { + + @DataProvider(name = "Stream") + public static Object[][] makeStreamTestData() { + List data = new ArrayList<>(); + + String description = ""; + String input = "awgqwefg1fefw4vssv1vvv1"; + Pattern pattern = Pattern.compile("4"); + List expected = new ArrayList<>(); + expected.add("awgqwefg1fefw"); + expected.add("vssv1vvv1"); + + // Must match the type signature of the consumer of this data, testStrings + // String, String, Pattern, List + data.add(new Object[]{description, input, pattern, expected}); + + input = "afbfq\u00a3abgwgb\u00a3awngnwggw\u00a3a\u00a3ahjrnhneerh"; + pattern = Pattern.compile("\u00a3a"); + expected = new ArrayList<>(); + expected.add("afbfq"); + expected.add("bgwgb"); + expected.add("wngnwggw"); + expected.add(""); + expected.add("hjrnhneerh"); + + data.add(new Object[]{description, input, pattern, expected}); + + + input = "awgqwefg1fefw4vssv1vvv1"; + pattern = Pattern.compile("1"); + expected = new ArrayList<>(); + expected.add("awgqwefg"); + expected.add("fefw4vssv"); + expected.add("vvv"); + + data.add(new Object[]{description, input, pattern, expected}); + + + input = "a\u4ebafg1fefw\u4eba4\u9f9cvssv\u9f9c1v\u672c\u672cvv"; + pattern = Pattern.compile("1"); + expected = new ArrayList<>(); + expected.add("a\u4ebafg"); + expected.add("fefw\u4eba4\u9f9cvssv\u9f9c"); + expected.add("v\u672c\u672cvv"); + + data.add(new Object[]{description, input, pattern, expected}); + + + input = "1\u56da23\u56da456\u56da7890"; + pattern = Pattern.compile("\u56da"); + expected = new ArrayList<>(); + expected.add("1"); + expected.add("23"); + expected.add("456"); + expected.add("7890"); + + data.add(new Object[]{description, input, pattern, expected}); + + + input = "1\u56da23\u9f9c\u672c\u672c\u56da456\u56da\u9f9c\u672c7890"; + pattern = Pattern.compile("\u56da"); + expected = new ArrayList<>(); + expected.add("1"); + expected.add("23\u9f9c\u672c\u672c"); + expected.add("456"); + expected.add("\u9f9c\u672c7890"); + + data.add(new Object[]{description, input, pattern, expected}); + + + input = ""; + pattern = Pattern.compile("\u56da"); + expected = new ArrayList<>(); + + data.add(new Object[]{description, input, pattern, expected}); + + + description = "Multiple separators"; + input = "This is,testing: with\tdifferent separators."; + pattern = Pattern.compile("[ \t,:.]"); + expected = new ArrayList<>(); + expected.add("This"); + expected.add("is"); + expected.add("testing"); + expected.add(""); + expected.add("with"); + expected.add("different"); + expected.add("separators"); + + data.add(new Object[] {description, input, pattern, expected}); + return data.toArray(new Object[0][]); + } + + @Test(dataProvider = "Stream") + public void testStrings(String description, String input, Pattern pattern, List expected) { + Supplier> ss = () -> pattern.splitAsStream(input); + withData(TestData.Factory.ofSupplier(description, ss)) + .stream(LambdaTestHelpers.identity()) + .expectedResult(expected) + .exercise(); + } +} From cac8b88f4892dd356e2612a51c8045810ed1fc06 Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Wed, 21 Aug 2013 19:44:35 -0700 Subject: [PATCH 079/102] 8022228: Intermittent test failures in sun/security/ssl/javax/net/ssl/NewAPIs Reviewed-by: weijun --- .../ssl/NewAPIs/SessionCacheSizeTests.java | 124 +++++++++++++----- .../net/ssl/NewAPIs/SessionTimeOutTests.java | 119 ++++++++++++----- .../ssl/templates/SSLSocketTemplate.java | 2 +- 3 files changed, 176 insertions(+), 69 deletions(-) diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionCacheSizeTests.java b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionCacheSizeTests.java index d5fdadd9b1e..d4e00855dc6 100644 --- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionCacheSizeTests.java +++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionCacheSizeTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -21,14 +21,16 @@ * questions. */ +// +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. +// + /* * @test * @bug 4366807 * @summary Need new APIs to get/set session timeout and session cache size. * @run main/othervm SessionCacheSizeTests - * - * SunJSSE does not support dynamic system properties, no way to re-use - * system properties in samevm/agentvm mode. */ import java.io.*; @@ -113,7 +115,9 @@ public class SessionCacheSizeTests { /* * Signal Client, we're ready for his connect. */ - serverReady = true; + if (createdPorts == serverPorts.length) { + serverReady = true; + } int read = 0; int nConnections = 0; /* @@ -310,7 +314,6 @@ public class SessionCacheSizeTests { * Fork off the other side, then do your work. */ SessionCacheSizeTests() throws Exception { - /* * create the SSLServerSocket and SSLSocket factories */ @@ -323,46 +326,87 @@ public class SessionCacheSizeTests { int serverConns = MAX_ACTIVE_CONNECTIONS / (serverPorts.length); int remainingConns = MAX_ACTIVE_CONNECTIONS % (serverPorts.length); - if (separateServerThread) { - for (int i = 0; i < serverPorts.length; i++) { - - // distribute remaining connections among the available ports - if (i < remainingConns) - startServer(serverPorts[i], (serverConns + 1), true); - else - startServer(serverPorts[i], serverConns, true); - } - startClient(false); - } else { - startClient(true); - for (int i = 0; i < serverPorts.length; i++) { - if (i < remainingConns) - startServer(serverPorts[i], (serverConns + 1), false); - else - startServer(serverPorts[i], serverConns, false); + Exception startException = null; + try { + if (separateServerThread) { + for (int i = 0; i < serverPorts.length; i++) { + // distribute remaining connections among the + // available ports + if (i < remainingConns) + startServer(serverPorts[i], (serverConns + 1), true); + else + startServer(serverPorts[i], serverConns, true); + } + startClient(false); + } else { + startClient(true); + for (int i = 0; i < serverPorts.length; i++) { + if (i < remainingConns) + startServer(serverPorts[i], (serverConns + 1), false); + else + startServer(serverPorts[i], serverConns, false); + } } + } catch (Exception e) { + startException = e; } /* * Wait for other side to close down. */ if (separateServerThread) { - serverThread.join(); + if (serverThread != null) { + serverThread.join(); + } } else { - clientThread.join(); + if (clientThread != null) { + clientThread.join(); + } } /* * When we get here, the test is pretty much over. - * - * If the main thread excepted, that propagates back - * immediately. If the other thread threw an exception, we - * should report back. */ - if (serverException != null) - throw serverException; - if (clientException != null) - throw clientException; + Exception local; + Exception remote; + + if (separateServerThread) { + remote = serverException; + local = clientException; + } else { + remote = clientException; + local = serverException; + } + + Exception exception = null; + + /* + * Check various exception conditions. + */ + if ((local != null) && (remote != null)) { + // If both failed, return the curthread's exception. + local.initCause(remote); + exception = local; + } else if (local != null) { + exception = local; + } else if (remote != null) { + exception = remote; + } else if (startException != null) { + exception = startException; + } + + /* + * If there was an exception *AND* a startException, + * output it. + */ + if (exception != null) { + if (exception != startException && startException != null) { + exception.addSuppressed(startException); + } + throw exception; + } + + // Fall-through: no exception to throw! } void startServer(final int port, final int nConns, @@ -387,7 +431,13 @@ public class SessionCacheSizeTests { }; serverThread.start(); } else { - doServerSide(port, nConns); + try { + doServerSide(port, nConns); + } catch (Exception e) { + serverException = e; + } finally { + serverReady = true; + } } } @@ -409,7 +459,11 @@ public class SessionCacheSizeTests { }; clientThread.start(); } else { - doClientSide(); + try { + doClientSide(); + } catch (Exception e) { + clientException = e; + } } } } diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionTimeOutTests.java b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionTimeOutTests.java index 3d0946724f5..9264cb08723 100644 --- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionTimeOutTests.java +++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionTimeOutTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -21,14 +21,14 @@ * questions. */ +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. + /* * @test * @bug 4366807 * @summary Need new APIs to get/set session timeout and session cache size. * @run main/othervm SessionTimeOutTests - * - * SunJSSE does not support dynamic system properties, no way to re-use - * system properties in samevm/agentvm mode. */ import java.io.*; @@ -263,7 +263,7 @@ public class SessionTimeOutTests { for (int i = 0; i < nConnections; i++) { sslSockets[i].close(); } - System.out.println("----------------------------------------" + System.out.println("----------------------------------------" + "-----------------------"); System.out.println("Session timeout test passed"); } @@ -348,45 +348,88 @@ public class SessionTimeOutTests { int serverConns = MAX_ACTIVE_CONNECTIONS / (serverPorts.length); int remainingConns = MAX_ACTIVE_CONNECTIONS % (serverPorts.length); - if (separateServerThread) { - for (int i = 0; i < serverPorts.length; i++) { - // distribute remaining connections among the available ports - if (i < remainingConns) - startServer(serverPorts[i], (serverConns + 1), true); - else - startServer(serverPorts[i], serverConns, true); - } - startClient(false); - } else { - startClient(true); - for (int i = 0; i < serverPorts.length; i++) { - if (i < remainingConns) - startServer(serverPorts[i], (serverConns + 1), false); - else - startServer(serverPorts[i], serverConns, false); + Exception startException = null; + try { + if (separateServerThread) { + for (int i = 0; i < serverPorts.length; i++) { + // distribute remaining connections among the + // vailable ports + if (i < remainingConns) + startServer(serverPorts[i], (serverConns + 1), true); + else + startServer(serverPorts[i], serverConns, true); + } + startClient(false); + } else { + startClient(true); + for (int i = 0; i < serverPorts.length; i++) { + if (i < remainingConns) + startServer(serverPorts[i], (serverConns + 1), false); + else + startServer(serverPorts[i], serverConns, false); + } } + } catch (Exception e) { + startException = e; } /* * Wait for other side to close down. */ if (separateServerThread) { - serverThread.join(); + if (serverThread != null) { + serverThread.join(); + } } else { - clientThread.join(); + if (clientThread != null) { + clientThread.join(); + } } /* * When we get here, the test is pretty much over. - * - * If the main thread excepted, that propagates back - * immediately. If the other thread threw an exception, we - * should report back. + * Which side threw the error? */ - if (serverException != null) - throw serverException; - if (clientException != null) - throw clientException; + Exception local; + Exception remote; + + if (separateServerThread) { + remote = serverException; + local = clientException; + } else { + remote = clientException; + local = serverException; + } + + Exception exception = null; + + /* + * Check various exception conditions. + */ + if ((local != null) && (remote != null)) { + // If both failed, return the curthread's exception. + local.initCause(remote); + exception = local; + } else if (local != null) { + exception = local; + } else if (remote != null) { + exception = remote; + } else if (startException != null) { + exception = startException; + } + + /* + * If there was an exception *AND* a startException, + * output it. + */ + if (exception != null) { + if (exception != startException && startException != null) { + exception.addSuppressed(startException); + } + throw exception; + } + + // Fall-through: no exception to throw! } void startServer(final int port, final int nConns, @@ -411,7 +454,13 @@ public class SessionTimeOutTests { }; serverThread.start(); } else { - doServerSide(port, nConns); + try { + doServerSide(port, nConns); + } catch (Exception e) { + serverException = e; + } finally { + serverReady = 0; + } } } @@ -433,7 +482,11 @@ public class SessionTimeOutTests { }; clientThread.start(); } else { - doClientSide(); + try { + doClientSide(); + } catch (Exception e) { + clientException = e; + } } } } diff --git a/jdk/test/sun/security/ssl/templates/SSLSocketTemplate.java b/jdk/test/sun/security/ssl/templates/SSLSocketTemplate.java index e8bfe91db06..af9f40f77c5 100644 --- a/jdk/test/sun/security/ssl/templates/SSLSocketTemplate.java +++ b/jdk/test/sun/security/ssl/templates/SSLSocketTemplate.java @@ -243,7 +243,7 @@ public class SSLSocketTemplate { * output it. */ if (exception != null) { - if (exception != startException) { + if (exception != startException && startException != null) { exception.addSuppressed(startException); } throw exception; From 138561d596308e0126916afcd65427d218fcfe3f Mon Sep 17 00:00:00 2001 From: Staffan Larsen Date: Thu, 22 Aug 2013 08:28:53 +0200 Subject: [PATCH 080/102] 8023101: java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java fails Reviewed-by: ysr --- .../management/MemoryMXBean/ResetPeakMemoryUsage.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java b/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java index 9e37d6670f4..1cc530e6541 100644 --- a/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java +++ b/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java @@ -33,10 +33,10 @@ * @author Mandy Chung * * @build ResetPeakMemoryUsage MemoryUtil - * @run main/othervm -XX:+UseSerialGC -XX:MarkSweepAlwaysCompactCount=1 -Xmn8m ResetPeakMemoryUsage - * @run main/othervm -XX:+UseConcMarkSweepGC -Xmn8m ResetPeakMemoryUsage - * @run main/othervm -XX:+UseParallelGC -Xmn8m ResetPeakMemoryUsage - * @run main/othervm -XX:+UseG1GC -Xmn8m -XX:G1HeapRegionSize=1m ResetPeakMemoryUsage + * @run main/othervm -XX:+PrintGCDetails -XX:+UseSerialGC -Xms256m -XX:MarkSweepAlwaysCompactCount=1 -Xmn8m ResetPeakMemoryUsage + * @run main/othervm -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC -Xms256m -Xmn8m ResetPeakMemoryUsage + * @run main/othervm -XX:+PrintGCDetails -XX:+UseParallelGC -Xms256m -Xmn8m ResetPeakMemoryUsage + * @run main/othervm -XX:+PrintGCDetails -XX:+UseG1GC -Xms256m -Xmn8m -XX:G1HeapRegionSize=1m ResetPeakMemoryUsage */ import java.lang.management.*; From b3961cb6be42c942bc00dd1332a99c15ef43a4c5 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Thu, 22 Aug 2013 09:40:36 -0700 Subject: [PATCH 081/102] 8023587: Fix lone remaining doclint issue in java.util.regex Reviewed-by: jjg --- jdk/src/share/classes/java/util/regex/Pattern.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/util/regex/Pattern.java b/jdk/src/share/classes/java/util/regex/Pattern.java index d7b800e3258..4eedd34c72a 100644 --- a/jdk/src/share/classes/java/util/regex/Pattern.java +++ b/jdk/src/share/classes/java/util/regex/Pattern.java @@ -219,7 +219,7 @@ import java.util.stream.StreamSupport; * *   * Classes for Unicode scripts, blocks, categories and binary properties - * * {@code \p{IsLatin}} + * {@code \p{IsLatin}} * A Latin script character (script) * {@code \p{InGreek}} * A character in the Greek block (block) From 31584b6b19d1565c35d0ce4fe4fb2adc3b92f533 Mon Sep 17 00:00:00 2001 From: Dan Xu Date: Thu, 22 Aug 2013 11:43:18 -0700 Subject: [PATCH 082/102] 8023430: Replace File.mkdirs with Files.createDirectories to get MaxPathLength.java failure details Reviewed-by: alanb --- jdk/test/ProblemList.txt | 2 +- jdk/test/java/io/File/MaxPathLength.java | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index ab2eac5ecbd..1f594fe3d3b 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -208,7 +208,7 @@ sun/net/www/http/HttpClient/ProxyTest.java generic-all # jdk_io # 7160013 -java/io/File/MaxPathLength.java windows-all +#java/io/File/MaxPathLength.java windows-all ############################################################################ diff --git a/jdk/test/java/io/File/MaxPathLength.java b/jdk/test/java/io/File/MaxPathLength.java index 4111550bbd2..7ec379cf1d1 100644 --- a/jdk/test/java/io/File/MaxPathLength.java +++ b/jdk/test/java/io/File/MaxPathLength.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ */ import java.io.*; +import java.nio.file.Files; public class MaxPathLength { private static String sep = File.separator; @@ -87,10 +88,8 @@ public class MaxPathLength { System.err.println("Warning: Test directory structure exists already!"); return; } - boolean couldMakeTestDirectory = dirFile.mkdirs(); - if (!couldMakeTestDirectory) { - throw new RuntimeException ("Could not create test directory structure"); - } + Files.createDirectories(dirFile.toPath()); + try { if (tryAbsolute) dirFile = new File(dirFile.getCanonicalPath()); From 75a8f58cd15ecb61864255a403935cfe5e4305c8 Mon Sep 17 00:00:00 2001 From: Peter Levart Date: Tue, 20 Aug 2013 14:13:59 +0200 Subject: [PATCH 083/102] 8022721: AnnotationTypeDeadlockTest.java throws java.lang.IllegalStateException: unexpected condition Reviewed-by: alanb, jfranck --- .../AnnotationTypeDeadlockTest.java | 42 +++++++++---------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/jdk/test/java/lang/annotation/AnnotationType/AnnotationTypeDeadlockTest.java b/jdk/test/java/lang/annotation/AnnotationType/AnnotationTypeDeadlockTest.java index 65d171adf43..f60c33525a8 100644 --- a/jdk/test/java/lang/annotation/AnnotationType/AnnotationTypeDeadlockTest.java +++ b/jdk/test/java/lang/annotation/AnnotationType/AnnotationTypeDeadlockTest.java @@ -28,6 +28,9 @@ */ import java.lang.annotation.Retention; +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; @@ -66,17 +69,6 @@ public class AnnotationTypeDeadlockTest { } } - static void dumpState(Task task) { - System.err.println( - "Task[" + task.getName() + "].state: " + - task.getState() + " ..." - ); - for (StackTraceElement ste : task.getStackTrace()) { - System.err.println("\tat " + ste); - } - System.err.println(); - } - public static void main(String[] args) throws Exception { CountDownLatch prepareLatch = new CountDownLatch(2); AtomicInteger goLatch = new AtomicInteger(1); @@ -88,18 +80,22 @@ public class AnnotationTypeDeadlockTest { prepareLatch.await(); // let them go goLatch.set(0); - // attempt to join them - taskA.join(5000L); - taskB.join(5000L); - - if (taskA.isAlive() || taskB.isAlive()) { - dumpState(taskA); - dumpState(taskB); - throw new IllegalStateException( - taskA.getState() == Thread.State.BLOCKED && - taskB.getState() == Thread.State.BLOCKED - ? "deadlock detected" - : "unexpected condition"); + // obtain ThreadMXBean + ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); + // wait for threads to finish or dead-lock + while (taskA.isAlive() || taskB.isAlive()) { + // attempt to join threads + taskA.join(500L); + taskB.join(500L); + // detect dead-lock + long[] deadlockedIds = threadBean.findMonitorDeadlockedThreads(); + if (deadlockedIds != null && deadlockedIds.length > 0) { + StringBuilder sb = new StringBuilder("deadlock detected:\n\n"); + for (ThreadInfo ti : threadBean.getThreadInfo(deadlockedIds, Integer.MAX_VALUE)) { + sb.append(ti); + } + throw new IllegalStateException(sb.toString()); + } } } } From edd19c0f397d2a86a19899074dc3ff0bea88d602 Mon Sep 17 00:00:00 2001 From: Stuart Marks Date: Thu, 22 Aug 2013 15:54:50 -0700 Subject: [PATCH 084/102] 8022445: fix RMISocketFactory example to avoid using localhost Reviewed-by: chegar, alanb --- .../share/classes/java/rmi/server/RMISocketFactory.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/java/rmi/server/RMISocketFactory.java b/jdk/src/share/classes/java/rmi/server/RMISocketFactory.java index e7b7581820b..ec9ade2f54c 100644 --- a/jdk/src/share/classes/java/rmi/server/RMISocketFactory.java +++ b/jdk/src/share/classes/java/rmi/server/RMISocketFactory.java @@ -50,13 +50,13 @@ import java.net.*; * @implNote *

      You can use the {@code RMISocketFactory} class to create a server socket that * is bound to a specific address, restricting the origin of requests. For example, - * the following code implements a socket factory that binds server sockets to the + * the following code implements a socket factory that binds server sockets to an IPv4 * loopback address. This restricts RMI to processing requests only from the local host. * *

      {@code
        *     class LoopbackSocketFactory extends RMISocketFactory {
        *         public ServerSocket createServerSocket(int port) throws IOException {
      - *             return new ServerSocket(port, 5, InetAddress.getLoopbackAddress());
      + *             return new ServerSocket(port, 5, InetAddress.getByName("127.0.0.1"));
        *         }
        *
        *         public Socket createSocket(String host, int port) throws IOException {
      @@ -72,8 +72,8 @@ import java.net.*;
        * }
      * * Set the {@code java.rmi.server.hostname} system property - * to a host name (typically {@code localhost}) that resolves to the loopback - * interface to ensure that the generated stubs use the right network interface. + * to {@code 127.0.0.1} to ensure that the generated stubs connect to the right + * network interface. * * @author Ann Wollrath * @author Peter Jones From 422a4d5bc7ed2ed9c8324a94c78d95f061d2459e Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Wed, 21 Aug 2013 17:15:44 +0200 Subject: [PATCH 085/102] 6417649: -interval=0 is accepted and jconsole doesn't update window content at all Reviewed-by: alanb, jbachorik --- jdk/src/share/classes/sun/tools/jconsole/JConsole.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/jdk/src/share/classes/sun/tools/jconsole/JConsole.java b/jdk/src/share/classes/sun/tools/jconsole/JConsole.java index 46d9504dc15..cdb78f94ec9 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/JConsole.java +++ b/jdk/src/share/classes/sun/tools/jconsole/JConsole.java @@ -858,6 +858,10 @@ public class JConsole extends JFrame try { updateInterval = Integer.parseInt(arg.substring(10)) * 1000; + if (updateInterval <= 0) { + usage(); + return; + } } catch (NumberFormatException ex) { usage(); return; From 3cd2e9e0995fe4a2f36ba8fb69f01c51c8155e6f Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Wed, 21 Aug 2013 17:17:45 +0200 Subject: [PATCH 086/102] 6359971: Threads tab: Simple text to explain that one can click on a thread to get stack trace Reviewed-by: alanb, jbachorik --- jdk/src/share/classes/sun/tools/jconsole/Messages.java | 1 + jdk/src/share/classes/sun/tools/jconsole/ThreadTab.java | 1 + .../classes/sun/tools/jconsole/resources/messages.properties | 1 + 3 files changed, 3 insertions(+) diff --git a/jdk/src/share/classes/sun/tools/jconsole/Messages.java b/jdk/src/share/classes/sun/tools/jconsole/Messages.java index eee57adcc25..0a3a63e85ca 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/Messages.java +++ b/jdk/src/share/classes/sun/tools/jconsole/Messages.java @@ -271,6 +271,7 @@ final public class Messages { public static String THREADS; public static String THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME; public static String THREAD_TAB_THREAD_PLOTTER_ACCESSIBLE_NAME; + public static String THREAD_TAB_INITIAL_STACK_TRACE_MESSAGE; public static String THRESHOLD; public static String TILE; public static String TIME_RANGE_COLON; diff --git a/jdk/src/share/classes/sun/tools/jconsole/ThreadTab.java b/jdk/src/share/classes/sun/tools/jconsole/ThreadTab.java index 3932ffa145e..6cf710a2dff 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/ThreadTab.java +++ b/jdk/src/share/classes/sun/tools/jconsole/ThreadTab.java @@ -596,6 +596,7 @@ class ThreadTab extends Tab implements ActionListener, DocumentListener, ListSel setBorder(thinEmptyBorder); setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + textArea.setText(Messages.THREAD_TAB_INITIAL_STACK_TRACE_MESSAGE); addListSelectionListener(ThreadTab.this); setCellRenderer(new DefaultListCellRenderer() { public Component getListCellRendererComponent(JList list, Object value, int index, diff --git a/jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties b/jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties index 70ff2f16c6e..832621731b9 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties +++ b/jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties @@ -229,6 +229,7 @@ SUMMARY_TAB_VM_VERSION={0} version {1} THREADS=Threads THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME=Thread Information THREAD_TAB_THREAD_PLOTTER_ACCESSIBLE_NAME=Chart for number of threads. +THREAD_TAB_INITIAL_STACK_TRACE_MESSAGE=[No thread selected] THRESHOLD=Threshold TILE=&Tile TIME_RANGE_COLON=&Time Range: From e391edefea181dc14cdb313d80f216a1a76491b1 Mon Sep 17 00:00:00 2001 From: "J. Duke" Date: Wed, 5 Jul 2017 19:07:32 +0200 Subject: [PATCH 087/102] Added tag jdk8-b103 for changeset 30a1d677a20c --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index a9f9153ddaa..d063220672f 100644 --- a/.hgtags +++ b/.hgtags @@ -224,3 +224,4 @@ ea73f01b9053e7165e7ba80f242bafecbc6af712 jdk8-b96 3d34036aae4ea90b2ca59712d5a69db3221f0875 jdk8-b100 edb01c460d4cab21ff0ff13512df7b746efaa0e7 jdk8-b101 bbe43d712fe08e650808d774861b256ccb34e500 jdk8-b102 +30a1d677a20c6a95f98043d8f20ce570304e3818 jdk8-b103 From 4bbc8e32301d226ae18840ae61ef4e2469bac060 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 22 Aug 2013 09:10:13 -0700 Subject: [PATCH 088/102] Added tag jdk8-b104 for changeset 805046a40f61 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index b185182241f..77378153e52 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -225,3 +225,4 @@ c4908732fef5235f1b98cafe0ce507771ef7892c jdk8-b98 6901612328239fbd471d20823113c1cf3fdaebee jdk8-b101 8ed8e2b4b90e0ac9aa5b3efef51cd576a9db96a9 jdk8-b102 e0f6039c0290b7381042a6fec3100a69a5a67e37 jdk8-b103 +f1d8d15bfcb5ada858a942f8a31f6598f23214d1 jdk8-b104 From ff7c51cd184ccf7c61561554eaaab800bf461fb9 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Thu, 22 Aug 2013 13:32:22 -0700 Subject: [PATCH 089/102] 6470700: Math.random() / Math.initRNG() uses "double checked locking" Replace class Random variable with a static final holder class Reviewed-by: alanb, mduigou, chegar --- jdk/src/share/classes/java/lang/Math.java | 11 +++-------- jdk/src/share/classes/java/lang/StrictMath.java | 11 +++-------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/jdk/src/share/classes/java/lang/Math.java b/jdk/src/share/classes/java/lang/Math.java index 23bc934688d..ae83e4265ad 100644 --- a/jdk/src/share/classes/java/lang/Math.java +++ b/jdk/src/share/classes/java/lang/Math.java @@ -698,11 +698,8 @@ public final class Math { return 0; } - private static Random randomNumberGenerator; - - private static synchronized Random initRNG() { - Random rnd = randomNumberGenerator; - return (rnd == null) ? (randomNumberGenerator = new Random()) : rnd; + private static final class RandomNumberGeneratorHolder { + static final Random randomNumberGenerator = new Random(); } /** @@ -729,9 +726,7 @@ public final class Math { * @see Random#nextDouble() */ public static double random() { - Random rnd = randomNumberGenerator; - if (rnd == null) rnd = initRNG(); - return rnd.nextDouble(); + return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble(); } /** diff --git a/jdk/src/share/classes/java/lang/StrictMath.java b/jdk/src/share/classes/java/lang/StrictMath.java index eb202d53202..52336484e75 100644 --- a/jdk/src/share/classes/java/lang/StrictMath.java +++ b/jdk/src/share/classes/java/lang/StrictMath.java @@ -678,11 +678,8 @@ public final class StrictMath { return Math.round(a); } - private static Random randomNumberGenerator; - - private static synchronized Random initRNG() { - Random rnd = randomNumberGenerator; - return (rnd == null) ? (randomNumberGenerator = new Random()) : rnd; + private static final class RandomNumberGeneratorHolder { + static final Random randomNumberGenerator = new Random(); } /** @@ -709,9 +706,7 @@ public final class StrictMath { * @see Random#nextDouble() */ public static double random() { - Random rnd = randomNumberGenerator; - if (rnd == null) rnd = initRNG(); - return rnd.nextDouble(); + return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble(); } /** From 6d2de008d77509d89344fddb3dc1dea74888278d Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Fri, 23 Aug 2013 20:59:34 +0200 Subject: [PATCH 090/102] 8005899: Logger.getLogger(name, null) should not allow to reset a non-null resource bundle Reviewed-by: mchung, lancea --- .../classes/java/util/logging/Logger.java | 16 +-- .../logging/Logger/getLogger/TestLogger.java | 98 +++++++++++++++++++ .../getLogger/testlogger/MyResource.java | 52 ++++++++++ 3 files changed, 159 insertions(+), 7 deletions(-) create mode 100644 jdk/test/java/util/logging/Logger/getLogger/TestLogger.java create mode 100644 jdk/test/java/util/logging/Logger/getLogger/testlogger/MyResource.java diff --git a/jdk/src/share/classes/java/util/logging/Logger.java b/jdk/src/share/classes/java/util/logging/Logger.java index 1c959ecd6a1..a7f0cc2cd4a 100644 --- a/jdk/src/share/classes/java/util/logging/Logger.java +++ b/jdk/src/share/classes/java/util/logging/Logger.java @@ -457,13 +457,15 @@ public class Logger { * of the subsystem, such as java.net * or javax.swing * @param resourceBundleName name of ResourceBundle to be used for localizing - * messages for this logger. May be null if none of - * the messages require localization. + * messages for this logger. May be {@code null} + * if none of the messages require localization. * @return a suitable Logger * @throws MissingResourceException if the resourceBundleName is non-null and * no corresponding resource can be found. * @throws IllegalArgumentException if the Logger already exists and uses - * a different resource bundle name. + * a different resource bundle name; or if + * {@code resourceBundleName} is {@code null} but the named + * logger has a resource bundle set. * @throws NullPointerException if the name is null. */ @@ -1731,10 +1733,6 @@ public class Logger { // Synchronized to prevent races in setting the fields. private synchronized void setupResourceInfo(String name, Class callersClass) { - if (name == null) { - return; - } - if (resourceBundleName != null) { // this Logger already has a ResourceBundle @@ -1748,6 +1746,10 @@ public class Logger { resourceBundleName + " != " + name); } + if (name == null) { + return; + } + setCallersClassLoaderRef(callersClass); if (findResourceBundle(name, true) == null) { // We've failed to find an expected ResourceBundle. diff --git a/jdk/test/java/util/logging/Logger/getLogger/TestLogger.java b/jdk/test/java/util/logging/Logger/getLogger/TestLogger.java new file mode 100644 index 00000000000..cf6abc449dd --- /dev/null +++ b/jdk/test/java/util/logging/Logger/getLogger/TestLogger.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013, 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.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +/** + * @test + * @bug 8005899 + * @build TestLogger testlogger.MyResource + * @run main/othervm TestLogger + * @run main/othervm -Dsecurity=on TestLogger + **/ +public class TestLogger { + + public static final String RESOURCE_BUNDLE = "testlogger.MyResource"; + public static final String ORG_LOGGER = "org"; + public static final String FOO_LOGGER = ORG_LOGGER + ".foo.Foo"; + public static final String BAR_LOGGER = ORG_LOGGER + ".bar.Bar"; + public static final String GEE_LOGGER = ORG_LOGGER + ".gee.Gee"; + public static final String GEE_GEE_LOGGER = GEE_LOGGER+".Gee"; + + public static void main(String[] args) { + final String security = System.getProperty("security", "off"); + System.out.println("Security is " + security); + if ("on".equals(security)) { + System.setSecurityManager(new SecurityManager()); + } + + newLogger(FOO_LOGGER, RESOURCE_BUNDLE); + newLogger(FOO_LOGGER); + newLogger(BAR_LOGGER); + newLogger(BAR_LOGGER, RESOURCE_BUNDLE); + newLogger(GEE_LOGGER, null); + newLogger(GEE_LOGGER, RESOURCE_BUNDLE); + newLogger(ORG_LOGGER); + newLogger(GEE_GEE_LOGGER); + + for (String log : new String[] { FOO_LOGGER, BAR_LOGGER, GEE_LOGGER }) { + if (!RESOURCE_BUNDLE.equals(Logger.getLogger(log).getResourceBundleName())) { + throw new RuntimeException("Shouldn't allow to reset the resource bundle for " + log); + } + try { + Logger logger = Logger.getLogger(log, null); + if (!RESOURCE_BUNDLE.equals(logger.getResourceBundleName())) { + throw new RuntimeException("Shouldn't allow to reset the resource bundle for " + log); + } + throw new RuntimeException("Expected IllegalArgumentException not thrown for " + log); + } catch (IllegalArgumentException e) { + System.out.println("Got expected exception for " + log +": " + e); + } + } + for (String log : new String[] { ORG_LOGGER, GEE_GEE_LOGGER }) { + if (Logger.getLogger(log).getResourceBundleName() != null) { + throw new RuntimeException("Resource bundle is not null for log: " + + Logger.getLogger(log).getResourceBundleName()); + } + try { + Logger logger = Logger.getLogger(log, null); + if (logger.getResourceBundleName() != null) { + throw new RuntimeException("Resource bundle is not null for log: " + + logger.getResourceBundleName()); + } + System.out.println("Success calling Logger.getLogger(\""+log+"\", null)"); + } catch (IllegalArgumentException e) { + throw new RuntimeException("Unexpected exception for " + log +": " + e, e); + } + } + } + + private static List strongRefs = new ArrayList<>(); + private static void newLogger(String name) { + strongRefs.add(Logger.getLogger(name)); + } + private static void newLogger(String name, String resourceBundleName) { + strongRefs.add(Logger.getLogger(name, resourceBundleName)); + } +} diff --git a/jdk/test/java/util/logging/Logger/getLogger/testlogger/MyResource.java b/jdk/test/java/util/logging/Logger/getLogger/testlogger/MyResource.java new file mode 100644 index 00000000000..84b0cd258cb --- /dev/null +++ b/jdk/test/java/util/logging/Logger/getLogger/testlogger/MyResource.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package testlogger; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; +import java.util.Properties; +import java.util.ResourceBundle; + +/** + * A dummy resource bundle for testing purposes. + * @author danielfuchs + */ +public class MyResource extends ResourceBundle { + Map bundle = new HashMap<>(); + + @Override + protected Object handleGetObject(String key) { + bundle.put(key,"Localized: " + key); + return bundle.get(key); + } + + @Override + public Enumeration getKeys() { + final Hashtable h = new Hashtable<>(bundle); + return h.keys(); + } + +} From 6c5c2d745abc81a91a7c169edb91538de513881e Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Fri, 23 Aug 2013 14:15:54 -0700 Subject: [PATCH 091/102] 6378503: In java.math.BigDecimal, division by one returns zero 6446965: Using BigDecimal.divideToIntegralValue with extreme scales can lead to an incorrect result Fix overflow of ints and ensure appropriate values passed to checkScaleNonZero() Reviewed-by: darcy, martin --- .../share/classes/java/math/BigDecimal.java | 32 +++++++++++-------- .../share/classes/java/math/BigInteger.java | 2 +- .../BigDecimal/IntegralDivisionTests.java | 5 ++- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/jdk/src/share/classes/java/math/BigDecimal.java b/jdk/src/share/classes/java/math/BigDecimal.java index 1a7ca811226..0abfb7522b5 100644 --- a/jdk/src/share/classes/java/math/BigDecimal.java +++ b/jdk/src/share/classes/java/math/BigDecimal.java @@ -2659,28 +2659,32 @@ public class BigDecimal extends Number implements Comparable { if (ys == 0) return 1; - int sdiff = this.scale - val.scale; + long sdiff = (long)this.scale - val.scale; if (sdiff != 0) { // Avoid matching scales if the (adjusted) exponents differ - int xae = this.precision() - this.scale; // [-1] - int yae = val.precision() - val.scale; // [-1] + long xae = (long)this.precision() - this.scale; // [-1] + long yae = (long)val.precision() - val.scale; // [-1] if (xae < yae) return -1; if (xae > yae) return 1; BigInteger rb = null; if (sdiff < 0) { - if ( (xs == INFLATED || - (xs = longMultiplyPowerTen(xs, -sdiff)) == INFLATED) && + // The cases sdiff <= Integer.MIN_VALUE intentionally fall through. + if ( sdiff > Integer.MIN_VALUE && + (xs == INFLATED || + (xs = longMultiplyPowerTen(xs, (int)-sdiff)) == INFLATED) && ys == INFLATED) { - rb = bigMultiplyPowerTen(-sdiff); + rb = bigMultiplyPowerTen((int)-sdiff); return rb.compareMagnitude(val.intVal); } } else { // sdiff > 0 - if ( (ys == INFLATED || - (ys = longMultiplyPowerTen(ys, sdiff)) == INFLATED) && + // The cases sdiff > Integer.MAX_VALUE intentionally fall through. + if ( sdiff <= Integer.MAX_VALUE && + (ys == INFLATED || + (ys = longMultiplyPowerTen(ys, (int)sdiff)) == INFLATED) && xs == INFLATED) { - rb = val.bigMultiplyPowerTen(sdiff); + rb = val.bigMultiplyPowerTen((int)sdiff); return this.intVal.compareMagnitude(rb); } } @@ -4545,7 +4549,7 @@ public class BigDecimal extends Number implements Comparable { if(cmp > 0) { // satisfy constraint (b) yscale -= 1; // [that is, divisor *= 10] int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp); - if (checkScaleNonZero((long) mcp + yscale) > xscale) { + if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) { // assert newScale >= xscale int raise = checkScaleNonZero((long) mcp + yscale - xscale); long scaledXs; @@ -4626,7 +4630,7 @@ public class BigDecimal extends Number implements Comparable { // return BigDecimal object whose scale will be set to 'scl'. int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp); BigDecimal quotient; - if (checkScaleNonZero((long) mcp + yscale) > xscale) { + if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) { int raise = checkScaleNonZero((long) mcp + yscale - xscale); long scaledXs; if ((scaledXs = longMultiplyPowerTen(xs, raise)) == INFLATED) { @@ -4673,7 +4677,7 @@ public class BigDecimal extends Number implements Comparable { // return BigDecimal object whose scale will be set to 'scl'. BigDecimal quotient; int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp); - if (checkScaleNonZero((long) mcp + yscale) > xscale) { + if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) { int raise = checkScaleNonZero((long) mcp + yscale - xscale); BigInteger rb = bigMultiplyPowerTen(xs,raise); quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale)); @@ -4714,7 +4718,7 @@ public class BigDecimal extends Number implements Comparable { // return BigDecimal object whose scale will be set to 'scl'. BigDecimal quotient; int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp); - if (checkScaleNonZero((long) mcp + yscale) > xscale) { + if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) { int raise = checkScaleNonZero((long) mcp + yscale - xscale); BigInteger rb = bigMultiplyPowerTen(xs,raise); quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale)); @@ -4745,7 +4749,7 @@ public class BigDecimal extends Number implements Comparable { // return BigDecimal object whose scale will be set to 'scl'. BigDecimal quotient; int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp); - if (checkScaleNonZero((long) mcp + yscale) > xscale) { + if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) { int raise = checkScaleNonZero((long) mcp + yscale - xscale); BigInteger rb = bigMultiplyPowerTen(xs,raise); quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale)); diff --git a/jdk/src/share/classes/java/math/BigInteger.java b/jdk/src/share/classes/java/math/BigInteger.java index e8cedf8a564..6beaed71bb3 100644 --- a/jdk/src/share/classes/java/math/BigInteger.java +++ b/jdk/src/share/classes/java/math/BigInteger.java @@ -2109,7 +2109,7 @@ public class BigInteger extends Number implements Comparable { // This is a quick way to approximate the size of the result, // similar to doing log2[n] * exponent. This will give an upper bound // of how big the result can be, and which algorithm to use. - int scaleFactor = remainingBits * exponent; + long scaleFactor = (long)remainingBits * exponent; // Use slightly different algorithms for small and large operands. // See if the result will safely fit into a long. (Largest 2^63-1) diff --git a/jdk/test/java/math/BigDecimal/IntegralDivisionTests.java b/jdk/test/java/math/BigDecimal/IntegralDivisionTests.java index 1e28e1d7543..ab6b624c98b 100644 --- a/jdk/test/java/math/BigDecimal/IntegralDivisionTests.java +++ b/jdk/test/java/math/BigDecimal/IntegralDivisionTests.java @@ -22,7 +22,7 @@ */ /* * @test - * @bug 4904082 4917089 6337226 + * @bug 4904082 4917089 6337226 6378503 * @summary Tests that integral division and related methods return the proper result and scale. * @author Joseph D. Darcy */ @@ -47,6 +47,9 @@ public class IntegralDivisionTests { {new BigDecimal("400e1"), new BigDecimal("5"), new BigDecimal("80e1")}, {new BigDecimal("400e1"), new BigDecimal("4.999999999"), new BigDecimal("8e2")}, {new BigDecimal("40e2"), new BigDecimal("5"), new BigDecimal("8e2")}, + {BigDecimal.valueOf(1, Integer.MIN_VALUE), + BigDecimal.valueOf(1, -(Integer.MAX_VALUE & 0x7fffff00)), + BigDecimal.valueOf(1, -256)}, }; for(BigDecimal [] testCase: moreTestCases) { From 423284cd203ee03a0d97dc2b63e68567f51b874d Mon Sep 17 00:00:00 2001 From: Yiming Wang Date: Mon, 26 Aug 2013 10:01:27 +0100 Subject: [PATCH 092/102] 8023139: java/nio/file/WatchService/SensitivityModifier.java failing intermittently (win8) Reviewed-by: alanb --- .../WatchService/SensitivityModifier.java | 104 +++++++++--------- 1 file changed, 55 insertions(+), 49 deletions(-) diff --git a/jdk/test/java/nio/file/WatchService/SensitivityModifier.java b/jdk/test/java/nio/file/WatchService/SensitivityModifier.java index 6f9a14cfd60..08722048b63 100644 --- a/jdk/test/java/nio/file/WatchService/SensitivityModifier.java +++ b/jdk/test/java/nio/file/WatchService/SensitivityModifier.java @@ -54,60 +54,66 @@ public class SensitivityModifier { @SuppressWarnings("unchecked") static void doTest(Path top) throws Exception { FileSystem fs = top.getFileSystem(); - WatchService watcher = fs.newWatchService(); + try (WatchService watcher = fs.newWatchService()) { - // create directories and files - int nDirs = 5 + rand.nextInt(20); - int nFiles = 50 + rand.nextInt(50); - Path[] dirs = new Path[nDirs]; - Path[] files = new Path[nFiles]; - for (int i=0; i event = key.pollEvents().iterator().next(); - if (event.kind() != ENTRY_MODIFY) - throw new RuntimeException("Unexpected event: " + event); - Path name = ((WatchEvent)event).context(); - if (!name.equals(file.getFileName())) - throw new RuntimeException("Unexpected context: " + name); - System.out.println("Event OK"); - // drain events (to avoid interference) - do { - key.pollEvents(); - key.reset(); - key = watcher.poll(1, TimeUnit.SECONDS); - } while (key != null); - - // re-register the directories to force changing their sensitivity - // level + // register the directories (random sensitivity) register(dirs, watcher); - } - // done - watcher.close(); + // sleep a bit here to ensure that modification to the first file + // can be detected by polling implementations (ie: last modified time + // may not change otherwise). + try { Thread.sleep(1000); } catch (InterruptedException e) { } + + // modify files and check that events are received + for (int i=0; i<10; i++) { + Path file = files[rand.nextInt(nFiles)]; + System.out.println("Modify: " + file); + try (OutputStream out = Files.newOutputStream(file)) { + out.write(new byte[100]); + } + + System.out.println("Waiting for event(s)..."); + boolean eventReceived = false; + WatchKey key = watcher.take(); + do { + for (WatchEvent event: key.pollEvents()) { + if (event.kind() != ENTRY_MODIFY) + throw new RuntimeException("Unexpected event: " + event); + Path name = ((WatchEvent)event).context(); + if (name.equals(file.getFileName())) { + eventReceived = true; + break; + } + } + key.reset(); + key = watcher.poll(1, TimeUnit.SECONDS); + } while (key != null && !eventReceived); + + // we should have received at least one ENTRY_MODIFY event + if (eventReceived) { + System.out.println("Event OK"); + } else { + throw new RuntimeException("No ENTRY_MODIFY event received for " + file); + } + + // re-register the directories to force changing their sensitivity + // level + register(dirs, watcher); + } + } } public static void main(String[] args) throws Exception { From 910d9b815cd7061261c72570c4d7eeddb0e2d3dc Mon Sep 17 00:00:00 2001 From: Ivan Gerasimov Date: Sun, 25 Aug 2013 23:20:59 +0400 Subject: [PATCH 093/102] 7129312: BufferedInputStream calculates negative array size with large streams and mark Reviewed-by: alanb --- .../classes/java/io/BufferedInputStream.java | 19 ++- .../LargeCopyWithMark.java | 117 ++++++++++++++++++ 2 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 jdk/test/java/io/BufferedInputStream/LargeCopyWithMark.java diff --git a/jdk/src/share/classes/java/io/BufferedInputStream.java b/jdk/src/share/classes/java/io/BufferedInputStream.java index a161a988109..fede2feeb7f 100644 --- a/jdk/src/share/classes/java/io/BufferedInputStream.java +++ b/jdk/src/share/classes/java/io/BufferedInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2013, 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 @@ -50,7 +50,15 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; public class BufferedInputStream extends FilterInputStream { - private static int defaultBufferSize = 8192; + private static int DEFAULT_BUFFER_SIZE = 8192; + + /** + * The maximum size of array to allocate. + * Some VMs reserve some header words in an array. + * Attempts to allocate larger arrays may result in + * OutOfMemoryError: Requested array size exceeds VM limit + */ + private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8; /** * The internal buffer array where the data is stored. When necessary, @@ -172,7 +180,7 @@ class BufferedInputStream extends FilterInputStream { * @param in the underlying input stream. */ public BufferedInputStream(InputStream in) { - this(in, defaultBufferSize); + this(in, DEFAULT_BUFFER_SIZE); } /** @@ -215,8 +223,11 @@ class BufferedInputStream extends FilterInputStream { } else if (buffer.length >= marklimit) { markpos = -1; /* buffer got too big, invalidate mark */ pos = 0; /* drop buffer contents */ + } else if (buffer.length >= MAX_BUFFER_SIZE) { + throw new OutOfMemoryError("Required array size too large"); } else { /* grow buffer */ - int nsz = pos * 2; + int nsz = (pos <= MAX_BUFFER_SIZE - pos) ? + pos * 2 : MAX_BUFFER_SIZE; if (nsz > marklimit) nsz = marklimit; byte nbuf[] = new byte[nsz]; diff --git a/jdk/test/java/io/BufferedInputStream/LargeCopyWithMark.java b/jdk/test/java/io/BufferedInputStream/LargeCopyWithMark.java new file mode 100644 index 00000000000..2555a1faa5f --- /dev/null +++ b/jdk/test/java/io/BufferedInputStream/LargeCopyWithMark.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013, 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 7129312 + * @summary BufferedInputStream calculates negative array size with large + * streams and mark + * @library /lib/testlibrary + * @run main/othervm LargeCopyWithMark + */ + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import static jdk.testlibrary.ProcessTools.*; + + +public class LargeCopyWithMark { + + public static void main(String[] args) throws Exception { + if (! System.getProperty("os.arch").contains("64")) { + System.out.println("Test runs on 64 bit platforms"); + return; + } + ProcessBuilder pb = createJavaProcessBuilder("-Xmx4G", + "-ea:LargeCopyWithMark$Child", + "LargeCopyWithMark$Child"); + int res = pb.inheritIO().start().waitFor(); + if (res != 0) { + throw new AssertionError("Test failed: exit code = " + res); + } + } + + public static class Child { + static final int BUFF_SIZE = 8192; + static final int BIS_BUFF_SIZE = Integer.MAX_VALUE / 2 + 100; + static final long BYTES_TO_COPY = 2L * Integer.MAX_VALUE; + + static { + assert BIS_BUFF_SIZE * 2 < 0 : "doubling must overflow"; + } + + public static void main(String[] args) throws Exception { + byte[] buff = new byte[BUFF_SIZE]; + + try (InputStream myis = new MyInputStream(BYTES_TO_COPY); + InputStream bis = new BufferedInputStream(myis, BIS_BUFF_SIZE); + OutputStream myos = new MyOutputStream()) { + + // will require a buffer bigger than BIS_BUFF_SIZE + bis.mark(BIS_BUFF_SIZE + 100); + + for (;;) { + int count = bis.read(buff, 0, BUFF_SIZE); + if (count == -1) + break; + myos.write(buff, 0, count); + } + } catch (java.lang.NegativeArraySizeException e) { + e.printStackTrace(); + System.exit(11); + } catch (Exception e) { + e.printStackTrace(); + } + } + } +} + +class MyInputStream extends InputStream { + private long bytesLeft; + public MyInputStream(long bytesLeft) { + this.bytesLeft = bytesLeft; + } + @Override public int read() throws IOException { + return 0; + } + @Override public int read(byte[] b) throws IOException { + return read(b, 0, b.length); + } + @Override public int read(byte[] b, int off, int len) throws IOException { + if (bytesLeft <= 0) + return -1; + long result = Math.min(bytesLeft, (long)len); + bytesLeft -= result; + return (int)result; + } + @Override public int available() throws IOException { + return (bytesLeft > 0) ? 1 : 0; + } +} + +class MyOutputStream extends OutputStream { + @Override public void write(int b) throws IOException {} + @Override public void write(byte[] b) throws IOException {} + @Override public void write(byte[] b, int off, int len) throws IOException {} +} From d4b28471ff7518d2800568b0739249ab4037e22a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Borggr=C3=A9n-Franck?= Date: Mon, 26 Aug 2013 13:38:14 +0200 Subject: [PATCH 094/102] 8022343: j.l.Class.getAnnotatedSuperclass() doesn't return null in some cases Reviewed-by: darcy, vromero, psandoz --- jdk/src/share/classes/java/lang/Class.java | 12 +++- .../annotation/TypeAnnotationReflection.java | 4 +- .../GetAnnotatedSuperclass.java | 56 +++++++++++++++++++ 3 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 jdk/test/java/lang/annotation/typeAnnotations/GetAnnotatedSuperclass.java diff --git a/jdk/src/share/classes/java/lang/Class.java b/jdk/src/share/classes/java/lang/Class.java index 9df0805167b..a3c962e0838 100644 --- a/jdk/src/share/classes/java/lang/Class.java +++ b/jdk/src/share/classes/java/lang/Class.java @@ -3338,8 +3338,16 @@ public final class Class implements java.io.Serializable, * @since 1.8 */ public AnnotatedType getAnnotatedSuperclass() { - return TypeAnnotationParser.buildAnnotatedSuperclass(getRawTypeAnnotations(), getConstantPool(), this); -} + if (this == Object.class || + isInterface() || + isArray() || + isPrimitive() || + this == Void.TYPE) { + return null; + } + + return TypeAnnotationParser.buildAnnotatedSuperclass(getRawTypeAnnotations(), getConstantPool(), this); + } /** * Returns an array of AnnotatedType objects that represent the use of types to diff --git a/jdk/test/java/lang/annotation/TypeAnnotationReflection.java b/jdk/test/java/lang/annotation/TypeAnnotationReflection.java index 6b4d167ef80..2c7da746a7f 100644 --- a/jdk/test/java/lang/annotation/TypeAnnotationReflection.java +++ b/jdk/test/java/lang/annotation/TypeAnnotationReflection.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8004698 8007073 + * @bug 8004698 8007073 8022343 * @summary Unit test for type annotations */ @@ -58,7 +58,7 @@ public class TypeAnnotationReflection { } private static void testSuper() throws Exception { - check(Object.class.getAnnotatedSuperclass().getAnnotations().length == 0); + check(Object.class.getAnnotatedSuperclass() == null); check(Class.class.getAnnotatedSuperclass().getAnnotations().length == 0); AnnotatedType a; diff --git a/jdk/test/java/lang/annotation/typeAnnotations/GetAnnotatedSuperclass.java b/jdk/test/java/lang/annotation/typeAnnotations/GetAnnotatedSuperclass.java new file mode 100644 index 00000000000..d112203a90f --- /dev/null +++ b/jdk/test/java/lang/annotation/typeAnnotations/GetAnnotatedSuperclass.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013, 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 8022343 + * @summary make sure Class.getAnnotatedSuperclass() returns null when specified to do so + */ + +public class GetAnnotatedSuperclass { + private static final Class[] testData = { + Object.class, + If.class, + Object[].class, + void.class, + int.class, + }; + + public static void main(String[] args) throws Exception { + int failed = 0; + for (Class toTest : testData) { + Object res = toTest.getAnnotatedSuperclass(); + + if (res != null) { + failed++; + System.out.println(toTest + ".getAnnotatedSuperclass() returns: " + + res + ", should be null"); + } + } + + if (failed != 0) + throw new RuntimeException("Test failed, check log for details"); + } + + interface If {} +} From 56dbd896c3173d6e0df7af1e92565e590b005869 Mon Sep 17 00:00:00 2001 From: Doug Lea Date: Mon, 26 Aug 2013 17:50:34 +0400 Subject: [PATCH 095/102] 8023234: StampedLock serializes readers on writer unlock Sync-up the fix from jsr166 CVS, signal more readers on writer unlock Reviewed-by: martin, shade --- .../util/concurrent/locks/StampedLock.java | 364 ++++++++++-------- .../ReadersUnlockAfterWriteUnlock.java | 88 +++++ 2 files changed, 286 insertions(+), 166 deletions(-) create mode 100644 jdk/test/java/util/concurrent/locks/StampedLock/ReadersUnlockAfterWriteUnlock.java diff --git a/jdk/src/share/classes/java/util/concurrent/locks/StampedLock.java b/jdk/src/share/classes/java/util/concurrent/locks/StampedLock.java index 1506e5a4e46..5fe20b6a578 100644 --- a/jdk/src/share/classes/java/util/concurrent/locks/StampedLock.java +++ b/jdk/src/share/classes/java/util/concurrent/locks/StampedLock.java @@ -226,7 +226,11 @@ public class StampedLock implements java.io.Serializable { * incoming reader arrives while read lock is held but there is a * queued writer, this incoming reader is queued. (This rule is * responsible for some of the complexity of method acquireRead, - * but without it, the lock becomes highly unfair.) + * but without it, the lock becomes highly unfair.) Method release + * does not (and sometimes cannot) itself wake up cowaiters. This + * is done by the primary thread, but helped by any other threads + * with nothing better to do in methods acquireRead and + * acquireWrite. * * These rules apply to threads actually queued. All tryLock forms * opportunistically try to acquire locks regardless of preference @@ -267,11 +271,14 @@ public class StampedLock implements java.io.Serializable { /** Number of processors, for spin control */ private static final int NCPU = Runtime.getRuntime().availableProcessors(); - /** Maximum number of retries before blocking on acquisition */ + /** Maximum number of retries before enqueuing on acquisition */ private static final int SPINS = (NCPU > 1) ? 1 << 6 : 0; + /** Maximum number of retries before blocking at head on acquisition */ + private static final int HEAD_SPINS = (NCPU > 1) ? 1 << 10 : 0; + /** Maximum number of retries before re-blocking */ - private static final int MAX_HEAD_SPINS = (NCPU > 1) ? 1 << 12 : 0; + private static final int MAX_HEAD_SPINS = (NCPU > 1) ? 1 << 16 : 0; /** The period for yielding when waiting for overflow spinlock */ private static final int OVERFLOW_YIELD_RATE = 7; // must be power 2 - 1 @@ -415,8 +422,8 @@ public class StampedLock implements java.io.Serializable { * @return a stamp that can be used to unlock or convert mode */ public long readLock() { - long s, next; // bypass acquireRead on fully unlocked case only - return ((((s = state) & ABITS) == 0L && + long s = state, next; // bypass acquireRead on common uncontended case + return ((whead == wtail && (s & ABITS) < RFULL && U.compareAndSwapLong(this, STATE, s, next = s + RUNIT)) ? next : acquireRead(false, 0L)); } @@ -1012,17 +1019,8 @@ public class StampedLock implements java.io.Serializable { if (t.status <= 0) q = t; } - if (q != null) { - for (WNode r = q;;) { // release co-waiters too - if ((w = r.thread) != null) { - r.thread = null; - U.unpark(w); - } - if ((r = q.cowait) == null) - break; - U.compareAndSwapObject(q, WCOWAIT, r, r.cowait); - } - } + if (q != null && (w = q.thread) != null) + U.unpark(w); } } @@ -1038,22 +1036,22 @@ public class StampedLock implements java.io.Serializable { private long acquireWrite(boolean interruptible, long deadline) { WNode node = null, p; for (int spins = -1;;) { // spin while enqueuing - long s, ns; - if (((s = state) & ABITS) == 0L) { + long m, s, ns; + if ((m = (s = state) & ABITS) == 0L) { if (U.compareAndSwapLong(this, STATE, s, ns = s + WBIT)) return ns; } + else if (spins < 0) + spins = (m == WBIT && wtail == whead) ? SPINS : 0; else if (spins > 0) { if (LockSupport.nextSecondarySeed() >= 0) --spins; } else if ((p = wtail) == null) { // initialize queue - WNode h = new WNode(WMODE, null); - if (U.compareAndSwapObject(this, WHEAD, null, h)) - wtail = h; + WNode hd = new WNode(WMODE, null); + if (U.compareAndSwapObject(this, WHEAD, null, hd)) + wtail = hd; } - else if (spins < 0) - spins = (p == whead) ? SPINS : 0; else if (node == null) node = new WNode(WMODE, p); else if (node.prev != p) @@ -1064,14 +1062,18 @@ public class StampedLock implements java.io.Serializable { } } - for (int spins = SPINS;;) { - WNode np, pp; int ps; long s, ns; Thread w; - while ((np = node.prev) != p && np != null) - (p = np).next = node; // stale - if (whead == p) { + for (int spins = -1;;) { + WNode h, np, pp; int ps; + if ((h = whead) == p) { + if (spins < 0) + spins = HEAD_SPINS; + else if (spins < MAX_HEAD_SPINS) + spins <<= 1; for (int k = spins;;) { // spin at head + long s, ns; if (((s = state) & ABITS) == 0L) { - if (U.compareAndSwapLong(this, STATE, s, ns = s+WBIT)) { + if (U.compareAndSwapLong(this, STATE, s, + ns = s + WBIT)) { whead = node; node.prev = null; return ns; @@ -1081,33 +1083,45 @@ public class StampedLock implements java.io.Serializable { --k <= 0) break; } - if (spins < MAX_HEAD_SPINS) - spins <<= 1; } - if ((ps = p.status) == 0) - U.compareAndSwapInt(p, WSTATUS, 0, WAITING); - else if (ps == CANCELLED) { - if ((pp = p.prev) != null) { - node.prev = pp; - pp.next = node; + else if (h != null) { // help release stale waiters + WNode c; Thread w; + while ((c = h.cowait) != null) { + if (U.compareAndSwapObject(h, WCOWAIT, c, c.cowait) && + (w = c.thread) != null) + U.unpark(w); } } - else { - long time; // 0 argument to park means no timeout - if (deadline == 0L) - time = 0L; - else if ((time = deadline - System.nanoTime()) <= 0L) - return cancelWaiter(node, node, false); - Thread wt = Thread.currentThread(); - U.putObject(wt, PARKBLOCKER, this); // emulate LockSupport.park - node.thread = wt; - if (node.prev == p && p.status == WAITING && // recheck - (p != whead || (state & ABITS) != 0L)) - U.park(false, time); - node.thread = null; - U.putObject(wt, PARKBLOCKER, null); - if (interruptible && Thread.interrupted()) - return cancelWaiter(node, node, true); + if (whead == h) { + if ((np = node.prev) != p) { + if (np != null) + (p = np).next = node; // stale + } + else if ((ps = p.status) == 0) + U.compareAndSwapInt(p, WSTATUS, 0, WAITING); + else if (ps == CANCELLED) { + if ((pp = p.prev) != null) { + node.prev = pp; + pp.next = node; + } + } + else { + long time; // 0 argument to park means no timeout + if (deadline == 0L) + time = 0L; + else if ((time = deadline - System.nanoTime()) <= 0L) + return cancelWaiter(node, node, false); + Thread wt = Thread.currentThread(); + U.putObject(wt, PARKBLOCKER, this); + node.thread = wt; + if (p.status < 0 && (p != h || (state & ABITS) != 0L) && + whead == h && node.prev == p) + U.park(false, time); // emulate LockSupport.park + node.thread = null; + U.putObject(wt, PARKBLOCKER, null); + if (interruptible && Thread.interrupted()) + return cancelWaiter(node, node, true); + } } } } @@ -1122,138 +1136,159 @@ public class StampedLock implements java.io.Serializable { * @return next state, or INTERRUPTED */ private long acquireRead(boolean interruptible, long deadline) { - WNode node = null, group = null, p; + WNode node = null, p; for (int spins = -1;;) { - for (;;) { - long s, m, ns; WNode h, q; Thread w; // anti-barging guard - if (group == null && (h = whead) != null && - (q = h.next) != null && q.mode != RMODE) - break; - if ((m = (s = state) & ABITS) < RFULL ? - U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT) : - (m < WBIT && (ns = tryIncReaderOverflow(s)) != 0L)) { - if (group != null) { // help release others - for (WNode r = group;;) { - if ((w = r.thread) != null) { - r.thread = null; - U.unpark(w); + WNode h; + if ((h = whead) == (p = wtail)) { + for (long m, s, ns;;) { + if ((m = (s = state) & ABITS) < RFULL ? + U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT) : + (m < WBIT && (ns = tryIncReaderOverflow(s)) != 0L)) + return ns; + else if (m >= WBIT) { + if (spins > 0) { + if (LockSupport.nextSecondarySeed() >= 0) + --spins; + } + else { + if (spins == 0) { + WNode nh = whead, np = wtail; + if ((nh == h && np == p) || (h = nh) != (p = np)) + break; } - if ((r = group.cowait) == null) - break; - U.compareAndSwapObject(group, WCOWAIT, r, r.cowait); + spins = SPINS; } } - return ns; } - if (m >= WBIT) - break; } - if (spins > 0) { - if (LockSupport.nextSecondarySeed() >= 0) - --spins; + if (p == null) { // initialize queue + WNode hd = new WNode(WMODE, null); + if (U.compareAndSwapObject(this, WHEAD, null, hd)) + wtail = hd; } - else if ((p = wtail) == null) { - WNode h = new WNode(WMODE, null); - if (U.compareAndSwapObject(this, WHEAD, null, h)) - wtail = h; - } - else if (spins < 0) - spins = (p == whead) ? SPINS : 0; else if (node == null) - node = new WNode(WMODE, p); - else if (node.prev != p) - node.prev = p; - else if (p.mode == RMODE && p != whead) { - WNode pp = p.prev; // become co-waiter with group p - if (pp != null && p == wtail && - U.compareAndSwapObject(p, WCOWAIT, - node.cowait = p.cowait, node)) { - node.thread = Thread.currentThread(); - for (long time;;) { + node = new WNode(RMODE, p); + else if (h == p || p.mode != RMODE) { + if (node.prev != p) + node.prev = p; + else if (U.compareAndSwapObject(this, WTAIL, p, node)) { + p.next = node; + break; + } + } + else if (!U.compareAndSwapObject(p, WCOWAIT, + node.cowait = p.cowait, node)) + node.cowait = null; + else { + for (;;) { + WNode pp, c; Thread w; + if ((h = whead) != null && (c = h.cowait) != null && + U.compareAndSwapObject(h, WCOWAIT, c, c.cowait) && + (w = c.thread) != null) // help release + U.unpark(w); + if (h == (pp = p.prev) || h == p || pp == null) { + long m, s, ns; + do { + if ((m = (s = state) & ABITS) < RFULL ? + U.compareAndSwapLong(this, STATE, s, + ns = s + RUNIT) : + (m < WBIT && + (ns = tryIncReaderOverflow(s)) != 0L)) + return ns; + } while (m < WBIT); + } + if (whead == h && p.prev == pp) { + long time; + if (pp == null || h == p || p.status > 0) { + node = null; // throw away + break; + } if (deadline == 0L) time = 0L; else if ((time = deadline - System.nanoTime()) <= 0L) return cancelWaiter(node, p, false); - if (node.thread == null) - break; - if (p.prev != pp || p.status == CANCELLED || - p == whead || p.prev != pp) { - node.thread = null; - break; - } Thread wt = Thread.currentThread(); U.putObject(wt, PARKBLOCKER, this); - if (node.thread == null) // must recheck - break; - U.park(false, time); + node.thread = wt; + if ((h != pp || (state & ABITS) == WBIT) && + whead == h && p.prev == pp) + U.park(false, time); + node.thread = null; U.putObject(wt, PARKBLOCKER, null); if (interruptible && Thread.interrupted()) return cancelWaiter(node, p, true); } - group = p; } - node = null; // throw away - } - else if (U.compareAndSwapObject(this, WTAIL, p, node)) { - p.next = node; - break; } } - for (int spins = SPINS;;) { - WNode np, pp, r; int ps; long m, s, ns; Thread w; - while ((np = node.prev) != p && np != null) - (p = np).next = node; - if (whead == p) { - for (int k = spins;;) { - if ((m = (s = state) & ABITS) != WBIT) { - if (m < RFULL ? - U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT): - (ns = tryIncReaderOverflow(s)) != 0L) { - whead = node; - node.prev = null; - while ((r = node.cowait) != null) { - if (U.compareAndSwapObject(node, WCOWAIT, - r, r.cowait) && - (w = r.thread) != null) { - r.thread = null; - U.unpark(w); // release co-waiter - } - } - return ns; + for (int spins = -1;;) { + WNode h, np, pp; int ps; + if ((h = whead) == p) { + if (spins < 0) + spins = HEAD_SPINS; + else if (spins < MAX_HEAD_SPINS) + spins <<= 1; + for (int k = spins;;) { // spin at head + long m, s, ns; + if ((m = (s = state) & ABITS) < RFULL ? + U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT) : + (m < WBIT && (ns = tryIncReaderOverflow(s)) != 0L)) { + WNode c; Thread w; + whead = node; + node.prev = null; + while ((c = node.cowait) != null) { + if (U.compareAndSwapObject(node, WCOWAIT, + c, c.cowait) && + (w = c.thread) != null) + U.unpark(w); } + return ns; } - else if (LockSupport.nextSecondarySeed() >= 0 && - --k <= 0) + else if (m >= WBIT && + LockSupport.nextSecondarySeed() >= 0 && --k <= 0) break; } - if (spins < MAX_HEAD_SPINS) - spins <<= 1; } - if ((ps = p.status) == 0) - U.compareAndSwapInt(p, WSTATUS, 0, WAITING); - else if (ps == CANCELLED) { - if ((pp = p.prev) != null) { - node.prev = pp; - pp.next = node; + else if (h != null) { + WNode c; Thread w; + while ((c = h.cowait) != null) { + if (U.compareAndSwapObject(h, WCOWAIT, c, c.cowait) && + (w = c.thread) != null) + U.unpark(w); } } - else { - long time; - if (deadline == 0L) - time = 0L; - else if ((time = deadline - System.nanoTime()) <= 0L) - return cancelWaiter(node, node, false); - Thread wt = Thread.currentThread(); - U.putObject(wt, PARKBLOCKER, this); - node.thread = wt; - if (node.prev == p && p.status == WAITING && - (p != whead || (state & ABITS) != WBIT)) - U.park(false, time); - node.thread = null; - U.putObject(wt, PARKBLOCKER, null); - if (interruptible && Thread.interrupted()) - return cancelWaiter(node, node, true); + if (whead == h) { + if ((np = node.prev) != p) { + if (np != null) + (p = np).next = node; // stale + } + else if ((ps = p.status) == 0) + U.compareAndSwapInt(p, WSTATUS, 0, WAITING); + else if (ps == CANCELLED) { + if ((pp = p.prev) != null) { + node.prev = pp; + pp.next = node; + } + } + else { + long time; + if (deadline == 0L) + time = 0L; + else if ((time = deadline - System.nanoTime()) <= 0L) + return cancelWaiter(node, node, false); + Thread wt = Thread.currentThread(); + U.putObject(wt, PARKBLOCKER, this); + node.thread = wt; + if (p.status < 0 && + (p != h || (state & ABITS) == WBIT) && + whead == h && node.prev == p) + U.park(false, time); + node.thread = null; + U.putObject(wt, PARKBLOCKER, null); + if (interruptible && Thread.interrupted()) + return cancelWaiter(node, node, true); + } } } } @@ -1278,22 +1313,19 @@ public class StampedLock implements java.io.Serializable { if (node != null && group != null) { Thread w; node.status = CANCELLED; - node.thread = null; // unsplice cancelled nodes from group for (WNode p = group, q; (q = p.cowait) != null;) { - if (q.status == CANCELLED) - U.compareAndSwapObject(p, WNEXT, q, q.next); + if (q.status == CANCELLED) { + U.compareAndSwapObject(p, WCOWAIT, q, q.cowait); + p = group; // restart + } else p = q; } if (group == node) { - WNode r; // detach and wake up uncancelled co-waiters - while ((r = node.cowait) != null) { - if (U.compareAndSwapObject(node, WCOWAIT, r, r.cowait) && - (w = r.thread) != null) { - r.thread = null; - U.unpark(w); - } + for (WNode r = group.cowait; r != null; r = r.cowait) { + if ((w = r.thread) != null) + U.unpark(w); // wake up uncancelled co-waiters } for (WNode pred = node.prev; pred != null; ) { // unsplice WNode succ, pp; // find valid successor diff --git a/jdk/test/java/util/concurrent/locks/StampedLock/ReadersUnlockAfterWriteUnlock.java b/jdk/test/java/util/concurrent/locks/StampedLock/ReadersUnlockAfterWriteUnlock.java new file mode 100644 index 00000000000..6d459372515 --- /dev/null +++ b/jdk/test/java/util/concurrent/locks/StampedLock/ReadersUnlockAfterWriteUnlock.java @@ -0,0 +1,88 @@ +/* + * 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 + * @run main/othervm/timeout=60 ReadersUnlockAfterWriteUnlock + * @bug 8023234 + * @summary StampedLock serializes readers on writer unlock + * @author Dmitry Chyuko + * @author Aleksey Shipilev + */ + +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.locks.StampedLock; + +public class ReadersUnlockAfterWriteUnlock { + static final int RNUM = 2; + static final StampedLock sl = new StampedLock(); + static volatile boolean isDone; + + static CyclicBarrier iterationStart = new CyclicBarrier(RNUM + 1); + static CyclicBarrier readersHaveLocks = new CyclicBarrier(RNUM); + static CyclicBarrier writerHasLock = new CyclicBarrier(RNUM + 1); + + static class Reader extends Thread { + final String name; + Reader(String name) { + super(); + this.name = name; + } + public void run() { + while (!isDone && !isInterrupted()) { + try { + iterationStart.await(); + writerHasLock.await(); + long rs = sl.readLock(); + + // single reader blocks here indefinitely if readers + // are serialized + readersHaveLocks.await(); + + sl.unlockRead(rs); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + } + } + + public static void main(String[] args) throws InterruptedException { + for (int r = 0 ; r < RNUM; ++r) { + new Reader("r" + r).start(); + } + int i; + for (i = 0; i < 1024; ++i) { + try { + iterationStart.await(); + long ws = sl.writeLock(); + writerHasLock.await(); + Thread.sleep(10); + sl.unlockWrite(ws); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + isDone = true; + } + +} From e0b682f2d8b912abc0f94c00cecf1709f746bfc7 Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Mon, 26 Aug 2013 11:46:05 -0400 Subject: [PATCH 096/102] 8011944: Sort fails with ArrayIndexOutOfBoundsException Increase the size of pending stack and add test cases Reviewed-by: alanb --- .../classes/java/util/ComparableTimSort.java | 3 +- jdk/src/share/classes/java/util/TimSort.java | 3 +- .../java/util/Arrays/TimSortStackSize.java | 116 ++++++++++++++++++ 3 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 jdk/test/java/util/Arrays/TimSortStackSize.java diff --git a/jdk/src/share/classes/java/util/ComparableTimSort.java b/jdk/src/share/classes/java/util/ComparableTimSort.java index 76b5fd56a00..e7c7ac020bd 100644 --- a/jdk/src/share/classes/java/util/ComparableTimSort.java +++ b/jdk/src/share/classes/java/util/ComparableTimSort.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright 2009 Google Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -146,7 +147,7 @@ class ComparableTimSort { */ int stackLen = (len < 120 ? 5 : len < 1542 ? 10 : - len < 119151 ? 19 : 40); + len < 119151 ? 24 : 40); runBase = new int[stackLen]; runLen = new int[stackLen]; } diff --git a/jdk/src/share/classes/java/util/TimSort.java b/jdk/src/share/classes/java/util/TimSort.java index 35493ff0bd6..9966f74df37 100644 --- a/jdk/src/share/classes/java/util/TimSort.java +++ b/jdk/src/share/classes/java/util/TimSort.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright 2009 Google Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -176,7 +177,7 @@ class TimSort { */ int stackLen = (len < 120 ? 5 : len < 1542 ? 10 : - len < 119151 ? 19 : 40); + len < 119151 ? 24 : 40); runBase = new int[stackLen]; runLen = new int[stackLen]; } diff --git a/jdk/test/java/util/Arrays/TimSortStackSize.java b/jdk/test/java/util/Arrays/TimSortStackSize.java new file mode 100644 index 00000000000..c05cc52a163 --- /dev/null +++ b/jdk/test/java/util/Arrays/TimSortStackSize.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2013, 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 8011944 + * @summary Test TimSort stack size + */ +import java.util.Arrays; +import java.util.ArrayDeque; + +public class TimSortStackSize { + + public static void main(String[] args) { + testComparableTimSort(); + testTimSort(); + } + + static void testComparableTimSort() { + System.out.printf("testComparableTimSort()%n"); + Arrays.sort(genData()); + } + + static void testTimSort() { + System.out.printf("testTimSort()%n"); + Arrays.sort(genData(), Integer::compare); + } + + private static final int MIN = 16; + + private static final int BOUND1 = 2 * MIN + 1; + private static final int BOUND2 = BOUND1 + MIN + 2; + private static final int BOUND3 = BOUND1 + 1 + BOUND2; + private static final int BOUND4 = BOUND2 + 1 + BOUND3; + private static final int BOUND5 = BOUND3 + 1 + BOUND4; + + static int build(int size, int B, ArrayDeque chunks) { + chunks.addFirst(B); + if (size < BOUND1) { + chunks.addFirst(size); + return size; + } + + int asize = (size + 2) / 2; + if (size >= BOUND2 && asize < BOUND1) { + asize = BOUND1; + } else if (size >= BOUND3 && asize < BOUND2) { + asize = BOUND2; + } else if (size >= BOUND4 && asize < BOUND3) { + asize = BOUND3; + } else if (size >= BOUND5 && asize < BOUND4) { + asize = BOUND4; + } + if (size - asize >= B) { + throw new AssertionError(" " + size + " , " + asize + " , " + B); + } + return build(asize, size - asize, chunks); + } + + static Integer[] genData() { + ArrayDeque chunks = new ArrayDeque(); + chunks.addFirst(MIN); + + int B = MIN + 4; + int A = B + MIN + 1; + + for (int i = 0; i < 8; i++) { + int eps = build(A, B, chunks); + B = B + A + 1; + A = B + eps + 1; + } + chunks.addFirst(B); + chunks.addFirst(A); + int total = 0; + for (Integer len : chunks) { + total += len; + } + int pow = MIN; + while (pow < total) { + pow += pow; + } + chunks.addLast(pow - total); + System.out.println(" Total: " + total); + Integer[] array = new Integer[pow]; + int off = 0; + int pos = 0; + for (Integer len : chunks) { + for (int i = 0; i < len; i++) { + array[pos++] = Integer.valueOf(i == 0 ? 0 : 1); + } + off++; + } + return array; + } + +} From 86af118ec0e78d3228fbd5647981005034a61ceb Mon Sep 17 00:00:00 2001 From: Ivan Gerasimov Date: Mon, 26 Aug 2013 18:26:35 +0400 Subject: [PATCH 097/102] 8016018: Typo in AbstractStringBuilder#indexOf and #lastIndexOf descriptions Reviewed-by: alanb, chegar --- jdk/src/share/classes/java/lang/AbstractStringBuilder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/java/lang/AbstractStringBuilder.java b/jdk/src/share/classes/java/lang/AbstractStringBuilder.java index a5bde616f8a..3260da6ae99 100644 --- a/jdk/src/share/classes/java/lang/AbstractStringBuilder.java +++ b/jdk/src/share/classes/java/lang/AbstractStringBuilder.java @@ -1307,7 +1307,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { * specified substring, starting at the specified index. The integer * returned is the smallest value {@code k} for which: *
      -     *     k >= Math.min(fromIndex, str.length()) &&
      +     *     k >= Math.min(fromIndex, this.length()) &&
            *                   this.toString().startsWith(str, k)
            * 
      * If no such value of k exists, then -1 is returned. @@ -1346,7 +1346,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { * specified substring. The integer returned is the largest value k * such that: *
      -     *     k <= Math.min(fromIndex, str.length()) &&
      +     *     k <= Math.min(fromIndex, this.length()) &&
            *                   this.toString().startsWith(str, k)
            * 
      * If no such value of k exists, then -1 is returned. From 5c937b723c0325ed52203efa9e707780b60dc57a Mon Sep 17 00:00:00 2001 From: Bill Pittore Date: Mon, 26 Aug 2013 11:27:48 -0400 Subject: [PATCH 098/102] 8014135: The JVMTI specification does not conform to recent changes in JNI specification Added support for statically linked agents Reviewed-by: alanb, sspitsyn, bobv, coleenp --- .../com/sun/tools/attach/VirtualMachine.java | 81 ++++++++++++------- 1 file changed, 50 insertions(+), 31 deletions(-) diff --git a/jdk/src/share/classes/com/sun/tools/attach/VirtualMachine.java b/jdk/src/share/classes/com/sun/tools/attach/VirtualMachine.java index aad0be2cfc9..29464d88da6 100644 --- a/jdk/src/share/classes/com/sun/tools/attach/VirtualMachine.java +++ b/jdk/src/share/classes/com/sun/tools/attach/VirtualMachine.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -59,7 +59,7 @@ import java.io.IOException; * {@link java.lang.instrument} for a detailed description on how these agents * are loaded and started). The {@link #loadAgentLibrary loadAgentLibrary} and * {@link #loadAgentPath loadAgentPath} methods are used to load agents that - * are deployed in a dynamic library and make use of the JVM Tools * Interface.

      * @@ -298,25 +298,29 @@ public abstract class VirtualMachine { *

      A JVM * TI client is called an agent. It is developed in a native language. * A JVM TI agent is deployed in a platform specific manner but it is typically the - * platform equivalent of a dynamic library. This method causes the given agent - * library to be loaded into the target VM (if not already loaded). + * platform equivalent of a dynamic library. Alternatively, it may be statically linked into the VM. + * This method causes the given agent library to be loaded into the target + * VM (if not already loaded or if not statically linked into the VM). * It then causes the target VM to invoke the Agent_OnAttach function + * or, for a statically linked agent named 'L', the Agent_OnAttach_L function * as specified in the * JVM Tools - * Interface specification. Note that the Agent_OnAttach + * Interface specification. Note that the Agent_OnAttach[_L] * function is invoked even if the agent library was loaded prior to invoking * this method. * *

      The agent library provided is the name of the agent library. It is interpreted * in the target virtual machine in an implementation-dependent manner. Typically an * implementation will expand the library name into an operating system specific file - * name. For example, on UNIX systems, the name foo might be expanded to - * libfoo.so, and located using the search path specified by the - * LD_LIBRARY_PATH environment variable.

      + * name. For example, on UNIX systems, the name L might be expanded to + * libL.so, and located using the search path specified by the + * LD_LIBRARY_PATH environment variable. If the agent named 'L' is + * statically linked into the VM then the VM must export a function named + * Agent_OnAttach_L.

      * - *

      If the Agent_OnAttach function in the agent library returns + *

      If the Agent_OnAttach[_L] function in the agent library returns * an error then an {@link com.sun.tools.attach.AgentInitializationException} is - * thrown. The return value from the Agent_OnAttach can then be + * thrown. The return value from the Agent_OnAttach[_L] can then be * obtained by invoking the {@link * com.sun.tools.attach.AgentInitializationException#returnValue() returnValue} * method on the exception.

      @@ -325,15 +329,16 @@ public abstract class VirtualMachine { * The name of the agent library. * * @param options - * The options to provide to the Agent_OnAttach + * The options to provide to the Agent_OnAttach[_L] * function (can be null). * * @throws AgentLoadException - * If the agent library does not exist, or cannot be loaded for - * another reason. + * If the agent library does not exist, the agent library is not + * statically linked with the VM, or the agent library cannot be + * loaded for another reason. * * @throws AgentInitializationException - * If the Agent_OnAttach function returns an error + * If the Agent_OnAttach[_L] function returns an error. * * @throws IOException * If an I/O error occurs @@ -359,11 +364,12 @@ public abstract class VirtualMachine { * The name of the agent library. * * @throws AgentLoadException - * If the agent library does not exist, or cannot be loaded for - * another reason. + * If the agent library does not exist, the agent library is not + * statically linked with the VM, or the agent library cannot be + * loaded for another reason. * * @throws AgentInitializationException - * If the Agent_OnAttach function returns an error + * If the Agent_OnAttach[_L] function returns an error. * * @throws IOException * If an I/O error occurs @@ -383,12 +389,23 @@ public abstract class VirtualMachine { *

      A JVM * TI client is called an agent. It is developed in a native language. * A JVM TI agent is deployed in a platform specific manner but it is typically the - * platform equivalent of a dynamic library. This method causes the given agent - * library to be loaded into the target VM (if not already loaded). - * It then causes the target VM to invoke the Agent_OnAttach function - * as specified in the + * platform equivalent of a dynamic library. Alternatively, the native + * library specified by the agentPath parameter may be statically + * linked with the VM. The parsing of the agentPath parameter into + * a statically linked library name is done in a platform + * specific manner in the VM. For example, in UNIX, an agentPath parameter + * of /a/b/libL.so would name a library 'L'. + * + * See the JVM TI Specification for more details. + * + * This method causes the given agent library to be loaded into the target + * VM (if not already loaded or if not statically linked into the VM). + * It then causes the target VM to invoke the Agent_OnAttach + * function or, for a statically linked agent named 'L', the + * Agent_OnAttach_L function as specified in the * JVM Tools - * Interface specification. Note that the Agent_OnAttach + * Interface specification. + * Note that the Agent_OnAttach[_L] * function is invoked even if the agent library was loaded prior to invoking * this method. * @@ -396,9 +413,9 @@ public abstract class VirtualMachine { * agent library. Unlike {@link #loadAgentLibrary loadAgentLibrary}, the library name * is not expanded in the target virtual machine.

      * - *

      If the Agent_OnAttach function in the agent library returns + *

      If the Agent_OnAttach[_L] function in the agent library returns * an error then an {@link com.sun.tools.attach.AgentInitializationException} is - * thrown. The return value from the Agent_OnAttach can then be + * thrown. The return value from the Agent_OnAttach[_L] can then be * obtained by invoking the {@link * com.sun.tools.attach.AgentInitializationException#returnValue() returnValue} * method on the exception.

      @@ -407,15 +424,16 @@ public abstract class VirtualMachine { * The full path of the agent library. * * @param options - * The options to provide to the Agent_OnAttach + * The options to provide to the Agent_OnAttach[_L] * function (can be null). * * @throws AgentLoadException - * If the agent library does not exist, or cannot be loaded for - * another reason. + * If the agent library does not exist, the agent library is not + * statically linked with the VM, or the agent library cannot be + * loaded for another reason. * * @throws AgentInitializationException - * If the Agent_OnAttach function returns an error + * If the Agent_OnAttach[_L] function returns an error. * * @throws IOException * If an I/O error occurs @@ -441,11 +459,12 @@ public abstract class VirtualMachine { * The full path to the agent library. * * @throws AgentLoadException - * If the agent library does not exist, or cannot be loaded for - * another reason. + * If the agent library does not exist, the agent library is not + * statically linked with the VM, or the agent library cannot be + * loaded for another reason. * * @throws AgentInitializationException - * If the Agent_OnAttach function returns an error + * If the Agent_OnAttach[_L] function returns an error. * * @throws IOException * If an I/O error occurs From 231a351a47d4d3fb8034115584bef6847486bc68 Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Mon, 26 Aug 2013 22:55:03 +0200 Subject: [PATCH 099/102] 8020292: j.u.SplittableRandom Co-authored-by: Guy Steele Co-authored-by: Doug Lea Co-authored-by: Brian Goetz Reviewed-by: mduigou --- .../classes/java/util/SplittableRandom.java | 1002 +++++++++++++++++ .../SplittableRandomTest.java | 511 +++++++++ .../tests/java/util/SplittableRandomTest.java | 367 ++++++ 3 files changed, 1880 insertions(+) create mode 100644 jdk/src/share/classes/java/util/SplittableRandom.java create mode 100644 jdk/test/java/util/SplittableRandom/SplittableRandomTest.java create mode 100644 jdk/test/java/util/stream/test/org/openjdk/tests/java/util/SplittableRandomTest.java diff --git a/jdk/src/share/classes/java/util/SplittableRandom.java b/jdk/src/share/classes/java/util/SplittableRandom.java new file mode 100644 index 00000000000..5a990f4d215 --- /dev/null +++ b/jdk/src/share/classes/java/util/SplittableRandom.java @@ -0,0 +1,1002 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.util; + +import java.security.SecureRandom; +import java.net.InetAddress; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.IntConsumer; +import java.util.function.LongConsumer; +import java.util.function.DoubleConsumer; +import java.util.stream.StreamSupport; +import java.util.stream.IntStream; +import java.util.stream.LongStream; +import java.util.stream.DoubleStream; + +/** + * A generator of uniform pseudorandom values applicable for use in + * (among other contexts) isolated parallel computations that may + * generate subtasks. Class {@code SplittableRandom} supports methods for + * producing pseudorandom numbers of type {@code int}, {@code long}, + * and {@code double} with similar usages as for class + * {@link java.util.Random} but differs in the following ways: + * + *
        + * + *
      • Series of generated values pass the DieHarder suite testing + * independence and uniformity properties of random number generators. + * (Most recently validated with version + * 3.31.1.) These tests validate only the methods for certain + * types and ranges, but similar properties are expected to hold, at + * least approximately, for others as well. The period + * (length of any series of generated values before it repeats) is at + * least 264.
      • + * + *
      • Method {@link #split} constructs and returns a new + * SplittableRandom instance that shares no mutable state with the + * current instance. However, with very high probability, the + * values collectively generated by the two objects have the same + * statistical properties as if the same quantity of values were + * generated by a single thread using a single {@code + * SplittableRandom} object.
      • + * + *
      • Instances of SplittableRandom are not thread-safe. + * They are designed to be split, not shared, across threads. For + * example, a {@link java.util.concurrent.ForkJoinTask + * fork/join-style} computation using random numbers might include a + * construction of the form {@code new + * Subtask(aSplittableRandom.split()).fork()}. + * + *
      • This class provides additional methods for generating random + * streams, that employ the above techniques when used in {@code + * stream.parallel()} mode.
      • + * + *
      + * + *

      Instances of {@code SplittableRandom} are not cryptographically + * secure. Consider instead using {@link java.security.SecureRandom} + * in security-sensitive applications. Additionally, + * default-constructed instances do not use a cryptographically random + * seed unless the {@linkplain System#getProperty system property} + * {@code java.util.secureRandomSeed} is set to {@code true}. + * + * @author Guy Steele + * @author Doug Lea + * @since 1.8 + */ +public final class SplittableRandom { + + /* + * Implementation Overview. + * + * This algorithm was inspired by the "DotMix" algorithm by + * Leiserson, Schardl, and Sukha "Deterministic Parallel + * Random-Number Generation for Dynamic-Multithreading Platforms", + * PPoPP 2012, as well as those in "Parallel random numbers: as + * easy as 1, 2, 3" by Salmon, Morae, Dror, and Shaw, SC 2011. It + * differs mainly in simplifying and cheapening operations. + * + * The primary update step (method nextSeed()) is to add a + * constant ("gamma") to the current (64 bit) seed, forming a + * simple sequence. The seed and the gamma values for any two + * SplittableRandom instances are highly likely to be different. + * + * Methods nextLong, nextInt, and derivatives do not return the + * sequence (seed) values, but instead a hash-like bit-mix of + * their bits, producing more independently distributed sequences. + * For nextLong, the mix64 bit-mixing function computes the same + * value as the "64-bit finalizer" function in Austin Appleby's + * MurmurHash3 algorithm. See + * http://code.google.com/p/smhasher/wiki/MurmurHash3 , which + * comments: "The constants for the finalizers were generated by a + * simple simulated-annealing algorithm, and both avalanche all + * bits of 'h' to within 0.25% bias." The mix32 function is + * equivalent to (int)(mix64(seed) >>> 32), but faster because it + * omits a step that doesn't contribute to result. + * + * The split operation uses the current generator to form the seed + * and gamma for another SplittableRandom. To conservatively + * avoid potential correlations between seed and value generation, + * gamma selection (method nextGamma) uses the "Mix13" constants + * for MurmurHash3 described by David Stafford + * (http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html) + * To avoid potential weaknesses in bit-mixing transformations, we + * restrict gammas to odd values with at least 12 and no more than + * 52 bits set. Rather than rejecting candidates with too few or + * too many bits set, method nextGamma flips some bits (which has + * the effect of mapping at most 4 to any given gamma value). + * This reduces the effective set of 64bit odd gamma values by + * about 214, a very tiny percentage, and serves as an + * automated screening for sequence constant selection that is + * left as an empirical decision in some other hashing and crypto + * algorithms. + * + * The resulting generator thus transforms a sequence in which + * (typically) many bits change on each step, with an inexpensive + * mixer with good (but less than cryptographically secure) + * avalanching. + * + * The default (no-argument) constructor, in essence, invokes + * split() for a common "seeder" SplittableRandom. Unlike other + * cases, this split must be performed in a thread-safe manner, so + * we use an AtomicLong to represent the seed rather than use an + * explicit SplittableRandom. To bootstrap the seeder, we start + * off using a seed based on current time and host unless the + * java.util.secureRandomSeed property is set. This serves as a + * slimmed-down (and insecure) variant of SecureRandom that also + * avoids stalls that may occur when using /dev/random. + * + * It is a relatively simple matter to apply the basic design here + * to use 128 bit seeds. However, emulating 128bit arithmetic and + * carrying around twice the state add more overhead than appears + * warranted for current usages. + * + * File organization: First the non-public methods that constitute + * the main algorithm, then the main public methods, followed by + * some custom spliterator classes needed for stream methods. + */ + + /** + * The initial gamma value for (unsplit) SplittableRandoms. Must + * be odd with at least 12 and no more than 52 bits set. Currently + * set to the golden ratio scaled to 64bits. + */ + private static final long INITIAL_GAMMA = 0x9e3779b97f4a7c15L; + + /** + * The least non-zero value returned by nextDouble(). This value + * is scaled by a random value of 53 bits to produce a result. + */ + private static final double DOUBLE_UNIT = 1.0 / (1L << 53); + + /** + * The seed. Updated only via method nextSeed. + */ + private long seed; + + /** + * The step value. + */ + private final long gamma; + + /** + * Internal constructor used by all others except default constructor. + */ + private SplittableRandom(long seed, long gamma) { + this.seed = seed; + this.gamma = gamma; + } + + /** + * Computes MurmurHash3 64bit mix function. + */ + private static long mix64(long z) { + z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL; + z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L; + return z ^ (z >>> 33); + } + + /** + * Returns the 32 high bits of mix64(z) as int. + */ + private static int mix32(long z) { + z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL; + return (int)(((z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L) >>> 32); + } + + /** + * Returns the gamma value to use for a new split instance. + */ + private static long nextGamma(long z) { + z = (z ^ (z >>> 30)) * 0xbf58476d1ce4e5b9L; // Stafford "Mix13" + z = (z ^ (z >>> 27)) * 0x94d049bb133111ebL; + z = (z ^ (z >>> 31)) | 1L; // force to be odd + int n = Long.bitCount(z); // ensure enough 0 and 1 bits + return (n < 12 || n > 52) ? z ^ 0xaaaaaaaaaaaaaaaaL : z; + } + + /** + * Adds gamma to seed. + */ + private long nextSeed() { + return seed += gamma; + } + + /** + * The seed generator for default constructors. + */ + private static final AtomicLong seeder = new AtomicLong(initialSeed()); + + private static long initialSeed() { + String pp = java.security.AccessController.doPrivileged( + new sun.security.action.GetPropertyAction( + "java.util.secureRandomSeed")); + if (pp != null && pp.equalsIgnoreCase("true")) { + byte[] seedBytes = java.security.SecureRandom.getSeed(8); + long s = (long)(seedBytes[0]) & 0xffL; + for (int i = 1; i < 8; ++i) + s = (s << 8) | ((long)(seedBytes[i]) & 0xffL); + return s; + } + int hh = 0; // hashed host address + try { + hh = InetAddress.getLocalHost().hashCode(); + } catch (Exception ignore) { + } + return (mix64((((long)hh) << 32) ^ System.currentTimeMillis()) ^ + mix64(System.nanoTime())); + } + + // IllegalArgumentException messages + static final String BadBound = "bound must be positive"; + static final String BadRange = "bound must be greater than origin"; + static final String BadSize = "size must be non-negative"; + + /* + * Internal versions of nextX methods used by streams, as well as + * the public nextX(origin, bound) methods. These exist mainly to + * avoid the need for multiple versions of stream spliterators + * across the different exported forms of streams. + */ + + /** + * The form of nextLong used by LongStream Spliterators. If + * origin is greater than bound, acts as unbounded form of + * nextLong, else as bounded form. + * + * @param origin the least value, unless greater than bound + * @param bound the upper bound (exclusive), must not equal origin + * @return a pseudorandom value + */ + final long internalNextLong(long origin, long bound) { + /* + * Four Cases: + * + * 1. If the arguments indicate unbounded form, act as + * nextLong(). + * + * 2. If the range is an exact power of two, apply the + * associated bit mask. + * + * 3. If the range is positive, loop to avoid potential bias + * when the implicit nextLong() bound (264) is not + * evenly divisible by the range. The loop rejects candidates + * computed from otherwise over-represented values. The + * expected number of iterations under an ideal generator + * varies from 1 to 2, depending on the bound. The loop itself + * takes an unlovable form. Because the first candidate is + * already available, we need a break-in-the-middle + * construction, which is concisely but cryptically performed + * within the while-condition of a body-less for loop. + * + * 4. Otherwise, the range cannot be represented as a positive + * long. The loop repeatedly generates unbounded longs until + * obtaining a candidate meeting constraints (with an expected + * number of iterations of less than two). + */ + + long r = mix64(nextSeed()); + if (origin < bound) { + long n = bound - origin, m = n - 1; + if ((n & m) == 0L) // power of two + r = (r & m) + origin; + else if (n > 0L) { // reject over-represented candidates + for (long u = r >>> 1; // ensure nonnegative + u + m - (r = u % n) < 0L; // rejection check + u = mix64(nextSeed()) >>> 1) // retry + ; + r += origin; + } + else { // range not representable as long + while (r < origin || r >= bound) + r = mix64(nextSeed()); + } + } + return r; + } + + /** + * The form of nextInt used by IntStream Spliterators. + * Exactly the same as long version, except for types. + * + * @param origin the least value, unless greater than bound + * @param bound the upper bound (exclusive), must not equal origin + * @return a pseudorandom value + */ + final int internalNextInt(int origin, int bound) { + int r = mix32(nextSeed()); + if (origin < bound) { + int n = bound - origin, m = n - 1; + if ((n & m) == 0) + r = (r & m) + origin; + else if (n > 0) { + for (int u = r >>> 1; + u + m - (r = u % n) < 0; + u = mix32(nextSeed()) >>> 1) + ; + r += origin; + } + else { + while (r < origin || r >= bound) + r = mix32(nextSeed()); + } + } + return r; + } + + /** + * The form of nextDouble used by DoubleStream Spliterators. + * + * @param origin the least value, unless greater than bound + * @param bound the upper bound (exclusive), must not equal origin + * @return a pseudorandom value + */ + final double internalNextDouble(double origin, double bound) { + double r = (nextLong() >>> 11) * DOUBLE_UNIT; + if (origin < bound) { + r = r * (bound - origin) + origin; + if (r >= bound) // correct for rounding + r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1); + } + return r; + } + + /* ---------------- public methods ---------------- */ + + /** + * Creates a new SplittableRandom instance using the specified + * initial seed. SplittableRandom instances created with the same + * seed in the same program generate identical sequences of values. + * + * @param seed the initial seed + */ + public SplittableRandom(long seed) { + this(seed, INITIAL_GAMMA); + } + + /** + * Creates a new SplittableRandom instance that is likely to + * generate sequences of values that are statistically independent + * of those of any other instances in the current program; and + * may, and typically does, vary across program invocations. + */ + public SplittableRandom() { // emulate seeder.split() + this.gamma = nextGamma(this.seed = seeder.addAndGet(INITIAL_GAMMA)); + } + + /** + * Constructs and returns a new SplittableRandom instance that + * shares no mutable state with this instance. However, with very + * high probability, the set of values collectively generated by + * the two objects has the same statistical properties as if the + * same quantity of values were generated by a single thread using + * a single SplittableRandom object. Either or both of the two + * objects may be further split using the {@code split()} method, + * and the same expected statistical properties apply to the + * entire set of generators constructed by such recursive + * splitting. + * + * @return the new SplittableRandom instance + */ + public SplittableRandom split() { + long s = nextSeed(); + return new SplittableRandom(s, nextGamma(s)); + } + + /** + * Returns a pseudorandom {@code int} value. + * + * @return a pseudorandom {@code int} value + */ + public int nextInt() { + return mix32(nextSeed()); + } + + /** + * Returns a pseudorandom {@code int} value between zero (inclusive) + * and the specified bound (exclusive). + * + * @param bound the upper bound (exclusive). Must be positive. + * @return a pseudorandom {@code int} value between zero + * (inclusive) and the bound (exclusive) + * @throws IllegalArgumentException if {@code bound} is not positive + */ + public int nextInt(int bound) { + if (bound <= 0) + throw new IllegalArgumentException(BadBound); + // Specialize internalNextInt for origin 0 + int r = mix32(nextSeed()); + int m = bound - 1; + if ((bound & m) == 0) // power of two + r &= m; + else { // reject over-represented candidates + for (int u = r >>> 1; + u + m - (r = u % bound) < 0; + u = mix32(nextSeed()) >>> 1) + ; + } + return r; + } + + /** + * Returns a pseudorandom {@code int} value between the specified + * origin (inclusive) and the specified bound (exclusive). + * + * @param origin the least value returned + * @param bound the upper bound (exclusive) + * @return a pseudorandom {@code int} value between the origin + * (inclusive) and the bound (exclusive) + * @throws IllegalArgumentException if {@code origin} is greater than + * or equal to {@code bound} + */ + public int nextInt(int origin, int bound) { + if (origin >= bound) + throw new IllegalArgumentException(BadRange); + return internalNextInt(origin, bound); + } + + /** + * Returns a pseudorandom {@code long} value. + * + * @return a pseudorandom {@code long} value + */ + public long nextLong() { + return mix64(nextSeed()); + } + + /** + * Returns a pseudorandom {@code long} value between zero (inclusive) + * and the specified bound (exclusive). + * + * @param bound the upper bound (exclusive). Must be positive. + * @return a pseudorandom {@code long} value between zero + * (inclusive) and the bound (exclusive) + * @throws IllegalArgumentException if {@code bound} is not positive + */ + public long nextLong(long bound) { + if (bound <= 0) + throw new IllegalArgumentException(BadBound); + // Specialize internalNextLong for origin 0 + long r = mix64(nextSeed()); + long m = bound - 1; + if ((bound & m) == 0L) // power of two + r &= m; + else { // reject over-represented candidates + for (long u = r >>> 1; + u + m - (r = u % bound) < 0L; + u = mix64(nextSeed()) >>> 1) + ; + } + return r; + } + + /** + * Returns a pseudorandom {@code long} value between the specified + * origin (inclusive) and the specified bound (exclusive). + * + * @param origin the least value returned + * @param bound the upper bound (exclusive) + * @return a pseudorandom {@code long} value between the origin + * (inclusive) and the bound (exclusive) + * @throws IllegalArgumentException if {@code origin} is greater than + * or equal to {@code bound} + */ + public long nextLong(long origin, long bound) { + if (origin >= bound) + throw new IllegalArgumentException(BadRange); + return internalNextLong(origin, bound); + } + + /** + * Returns a pseudorandom {@code double} value between zero + * (inclusive) and one (exclusive). + * + * @return a pseudorandom {@code double} value between zero + * (inclusive) and one (exclusive) + */ + public double nextDouble() { + return (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT; + } + + /** + * Returns a pseudorandom {@code double} value between 0.0 + * (inclusive) and the specified bound (exclusive). + * + * @param bound the upper bound (exclusive). Must be positive. + * @return a pseudorandom {@code double} value between zero + * (inclusive) and the bound (exclusive) + * @throws IllegalArgumentException if {@code bound} is not positive + */ + public double nextDouble(double bound) { + if (!(bound > 0.0)) + throw new IllegalArgumentException(BadBound); + double result = (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT * bound; + return (result < bound) ? result : // correct for rounding + Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1); + } + + /** + * Returns a pseudorandom {@code double} value between the specified + * origin (inclusive) and bound (exclusive). + * + * @param origin the least value returned + * @param bound the upper bound (exclusive) + * @return a pseudorandom {@code double} value between the origin + * (inclusive) and the bound (exclusive) + * @throws IllegalArgumentException if {@code origin} is greater than + * or equal to {@code bound} + */ + public double nextDouble(double origin, double bound) { + if (!(origin < bound)) + throw new IllegalArgumentException(BadRange); + return internalNextDouble(origin, bound); + } + + /** + * Returns a pseudorandom {@code boolean} value. + * + * @return a pseudorandom {@code boolean} value + */ + public boolean nextBoolean() { + return mix32(nextSeed()) < 0; + } + + // stream methods, coded in a way intended to better isolate for + // maintenance purposes the small differences across forms. + + /** + * Returns a stream producing the given {@code streamSize} number + * of pseudorandom {@code int} values from this generator and/or + * one split from it. + * + * @param streamSize the number of values to generate + * @return a stream of pseudorandom {@code int} values + * @throws IllegalArgumentException if {@code streamSize} is + * less than zero + */ + public IntStream ints(long streamSize) { + if (streamSize < 0L) + throw new IllegalArgumentException(BadSize); + return StreamSupport.intStream + (new RandomIntsSpliterator + (this, 0L, streamSize, Integer.MAX_VALUE, 0), + false); + } + + /** + * Returns an effectively unlimited stream of pseudorandom {@code int} + * values from this generator and/or one split from it. + * + * @implNote This method is implemented to be equivalent to {@code + * ints(Long.MAX_VALUE)}. + * + * @return a stream of pseudorandom {@code int} values + */ + public IntStream ints() { + return StreamSupport.intStream + (new RandomIntsSpliterator + (this, 0L, Long.MAX_VALUE, Integer.MAX_VALUE, 0), + false); + } + + /** + * Returns a stream producing the given {@code streamSize} number + * of pseudorandom {@code int} values from this generator and/or one split + * from it; each value conforms to the given origin (inclusive) and bound + * (exclusive). + * + * @param streamSize the number of values to generate + * @param randomNumberOrigin the origin (inclusive) of each random value + * @param randomNumberBound the bound (exclusive) of each random value + * @return a stream of pseudorandom {@code int} values, + * each with the given origin (inclusive) and bound (exclusive) + * @throws IllegalArgumentException if {@code streamSize} is + * less than zero, or {@code randomNumberOrigin} + * is greater than or equal to {@code randomNumberBound} + */ + public IntStream ints(long streamSize, int randomNumberOrigin, + int randomNumberBound) { + if (streamSize < 0L) + throw new IllegalArgumentException(BadSize); + if (randomNumberOrigin >= randomNumberBound) + throw new IllegalArgumentException(BadRange); + return StreamSupport.intStream + (new RandomIntsSpliterator + (this, 0L, streamSize, randomNumberOrigin, randomNumberBound), + false); + } + + /** + * Returns an effectively unlimited stream of pseudorandom {@code + * int} values from this generator and/or one split from it; each value + * conforms to the given origin (inclusive) and bound (exclusive). + * + * @implNote This method is implemented to be equivalent to {@code + * ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}. + * + * @param randomNumberOrigin the origin (inclusive) of each random value + * @param randomNumberBound the bound (exclusive) of each random value + * @return a stream of pseudorandom {@code int} values, + * each with the given origin (inclusive) and bound (exclusive) + * @throws IllegalArgumentException if {@code randomNumberOrigin} + * is greater than or equal to {@code randomNumberBound} + */ + public IntStream ints(int randomNumberOrigin, int randomNumberBound) { + if (randomNumberOrigin >= randomNumberBound) + throw new IllegalArgumentException(BadRange); + return StreamSupport.intStream + (new RandomIntsSpliterator + (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound), + false); + } + + /** + * Returns a stream producing the given {@code streamSize} number + * of pseudorandom {@code long} values from this generator and/or + * one split from it. + * + * @param streamSize the number of values to generate + * @return a stream of pseudorandom {@code long} values + * @throws IllegalArgumentException if {@code streamSize} is + * less than zero + */ + public LongStream longs(long streamSize) { + if (streamSize < 0L) + throw new IllegalArgumentException(BadSize); + return StreamSupport.longStream + (new RandomLongsSpliterator + (this, 0L, streamSize, Long.MAX_VALUE, 0L), + false); + } + + /** + * Returns an effectively unlimited stream of pseudorandom {@code + * long} values from this generator and/or one split from it. + * + * @implNote This method is implemented to be equivalent to {@code + * longs(Long.MAX_VALUE)}. + * + * @return a stream of pseudorandom {@code long} values + */ + public LongStream longs() { + return StreamSupport.longStream + (new RandomLongsSpliterator + (this, 0L, Long.MAX_VALUE, Long.MAX_VALUE, 0L), + false); + } + + /** + * Returns a stream producing the given {@code streamSize} number of + * pseudorandom {@code long} values from this generator and/or one split + * from it; each value conforms to the given origin (inclusive) and bound + * (exclusive). + * + * @param streamSize the number of values to generate + * @param randomNumberOrigin the origin (inclusive) of each random value + * @param randomNumberBound the bound (exclusive) of each random value + * @return a stream of pseudorandom {@code long} values, + * each with the given origin (inclusive) and bound (exclusive) + * @throws IllegalArgumentException if {@code streamSize} is + * less than zero, or {@code randomNumberOrigin} + * is greater than or equal to {@code randomNumberBound} + */ + public LongStream longs(long streamSize, long randomNumberOrigin, + long randomNumberBound) { + if (streamSize < 0L) + throw new IllegalArgumentException(BadSize); + if (randomNumberOrigin >= randomNumberBound) + throw new IllegalArgumentException(BadRange); + return StreamSupport.longStream + (new RandomLongsSpliterator + (this, 0L, streamSize, randomNumberOrigin, randomNumberBound), + false); + } + + /** + * Returns an effectively unlimited stream of pseudorandom {@code + * long} values from this generator and/or one split from it; each value + * conforms to the given origin (inclusive) and bound (exclusive). + * + * @implNote This method is implemented to be equivalent to {@code + * longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}. + * + * @param randomNumberOrigin the origin (inclusive) of each random value + * @param randomNumberBound the bound (exclusive) of each random value + * @return a stream of pseudorandom {@code long} values, + * each with the given origin (inclusive) and bound (exclusive) + * @throws IllegalArgumentException if {@code randomNumberOrigin} + * is greater than or equal to {@code randomNumberBound} + */ + public LongStream longs(long randomNumberOrigin, long randomNumberBound) { + if (randomNumberOrigin >= randomNumberBound) + throw new IllegalArgumentException(BadRange); + return StreamSupport.longStream + (new RandomLongsSpliterator + (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound), + false); + } + + /** + * Returns a stream producing the given {@code streamSize} number of + * pseudorandom {@code double} values from this generator and/or one split + * from it; each value is between zero (inclusive) and one (exclusive). + * + * @param streamSize the number of values to generate + * @return a stream of {@code double} values + * @throws IllegalArgumentException if {@code streamSize} is + * less than zero + */ + public DoubleStream doubles(long streamSize) { + if (streamSize < 0L) + throw new IllegalArgumentException(BadSize); + return StreamSupport.doubleStream + (new RandomDoublesSpliterator + (this, 0L, streamSize, Double.MAX_VALUE, 0.0), + false); + } + + /** + * Returns an effectively unlimited stream of pseudorandom {@code + * double} values from this generator and/or one split from it; each value + * is between zero (inclusive) and one (exclusive). + * + * @implNote This method is implemented to be equivalent to {@code + * doubles(Long.MAX_VALUE)}. + * + * @return a stream of pseudorandom {@code double} values + */ + public DoubleStream doubles() { + return StreamSupport.doubleStream + (new RandomDoublesSpliterator + (this, 0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0), + false); + } + + /** + * Returns a stream producing the given {@code streamSize} number of + * pseudorandom {@code double} values from this generator and/or one split + * from it; each value conforms to the given origin (inclusive) and bound + * (exclusive). + * + * @param streamSize the number of values to generate + * @param randomNumberOrigin the origin (inclusive) of each random value + * @param randomNumberBound the bound (exclusive) of each random value + * @return a stream of pseudorandom {@code double} values, + * each with the given origin (inclusive) and bound (exclusive) + * @throws IllegalArgumentException if {@code streamSize} is + * less than zero + * @throws IllegalArgumentException if {@code randomNumberOrigin} + * is greater than or equal to {@code randomNumberBound} + */ + public DoubleStream doubles(long streamSize, double randomNumberOrigin, + double randomNumberBound) { + if (streamSize < 0L) + throw new IllegalArgumentException(BadSize); + if (!(randomNumberOrigin < randomNumberBound)) + throw new IllegalArgumentException(BadRange); + return StreamSupport.doubleStream + (new RandomDoublesSpliterator + (this, 0L, streamSize, randomNumberOrigin, randomNumberBound), + false); + } + + /** + * Returns an effectively unlimited stream of pseudorandom {@code + * double} values from this generator and/or one split from it; each value + * conforms to the given origin (inclusive) and bound (exclusive). + * + * @implNote This method is implemented to be equivalent to {@code + * doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}. + * + * @param randomNumberOrigin the origin (inclusive) of each random value + * @param randomNumberBound the bound (exclusive) of each random value + * @return a stream of pseudorandom {@code double} values, + * each with the given origin (inclusive) and bound (exclusive) + * @throws IllegalArgumentException if {@code randomNumberOrigin} + * is greater than or equal to {@code randomNumberBound} + */ + public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) { + if (!(randomNumberOrigin < randomNumberBound)) + throw new IllegalArgumentException(BadRange); + return StreamSupport.doubleStream + (new RandomDoublesSpliterator + (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound), + false); + } + + /** + * Spliterator for int streams. We multiplex the four int + * versions into one class by treating a bound less than origin as + * unbounded, and also by treating "infinite" as equivalent to + * Long.MAX_VALUE. For splits, it uses the standard divide-by-two + * approach. The long and double versions of this class are + * identical except for types. + */ + static final class RandomIntsSpliterator implements Spliterator.OfInt { + final SplittableRandom rng; + long index; + final long fence; + final int origin; + final int bound; + RandomIntsSpliterator(SplittableRandom rng, long index, long fence, + int origin, int bound) { + this.rng = rng; this.index = index; this.fence = fence; + this.origin = origin; this.bound = bound; + } + + public RandomIntsSpliterator trySplit() { + long i = index, m = (i + fence) >>> 1; + return (m <= i) ? null : + new RandomIntsSpliterator(rng.split(), i, index = m, origin, bound); + } + + public long estimateSize() { + return fence - index; + } + + public int characteristics() { + return (Spliterator.SIZED | Spliterator.SUBSIZED | + Spliterator.NONNULL | Spliterator.IMMUTABLE); + } + + public boolean tryAdvance(IntConsumer consumer) { + if (consumer == null) throw new NullPointerException(); + long i = index, f = fence; + if (i < f) { + consumer.accept(rng.internalNextInt(origin, bound)); + index = i + 1; + return true; + } + return false; + } + + public void forEachRemaining(IntConsumer consumer) { + if (consumer == null) throw new NullPointerException(); + long i = index, f = fence; + if (i < f) { + index = f; + SplittableRandom r = rng; + int o = origin, b = bound; + do { + consumer.accept(r.internalNextInt(o, b)); + } while (++i < f); + } + } + } + + /** + * Spliterator for long streams. + */ + static final class RandomLongsSpliterator implements Spliterator.OfLong { + final SplittableRandom rng; + long index; + final long fence; + final long origin; + final long bound; + RandomLongsSpliterator(SplittableRandom rng, long index, long fence, + long origin, long bound) { + this.rng = rng; this.index = index; this.fence = fence; + this.origin = origin; this.bound = bound; + } + + public RandomLongsSpliterator trySplit() { + long i = index, m = (i + fence) >>> 1; + return (m <= i) ? null : + new RandomLongsSpliterator(rng.split(), i, index = m, origin, bound); + } + + public long estimateSize() { + return fence - index; + } + + public int characteristics() { + return (Spliterator.SIZED | Spliterator.SUBSIZED | + Spliterator.NONNULL | Spliterator.IMMUTABLE); + } + + public boolean tryAdvance(LongConsumer consumer) { + if (consumer == null) throw new NullPointerException(); + long i = index, f = fence; + if (i < f) { + consumer.accept(rng.internalNextLong(origin, bound)); + index = i + 1; + return true; + } + return false; + } + + public void forEachRemaining(LongConsumer consumer) { + if (consumer == null) throw new NullPointerException(); + long i = index, f = fence; + if (i < f) { + index = f; + SplittableRandom r = rng; + long o = origin, b = bound; + do { + consumer.accept(r.internalNextLong(o, b)); + } while (++i < f); + } + } + + } + + /** + * Spliterator for double streams. + */ + static final class RandomDoublesSpliterator implements Spliterator.OfDouble { + final SplittableRandom rng; + long index; + final long fence; + final double origin; + final double bound; + RandomDoublesSpliterator(SplittableRandom rng, long index, long fence, + double origin, double bound) { + this.rng = rng; this.index = index; this.fence = fence; + this.origin = origin; this.bound = bound; + } + + public RandomDoublesSpliterator trySplit() { + long i = index, m = (i + fence) >>> 1; + return (m <= i) ? null : + new RandomDoublesSpliterator(rng.split(), i, index = m, origin, bound); + } + + public long estimateSize() { + return fence - index; + } + + public int characteristics() { + return (Spliterator.SIZED | Spliterator.SUBSIZED | + Spliterator.NONNULL | Spliterator.IMMUTABLE); + } + + public boolean tryAdvance(DoubleConsumer consumer) { + if (consumer == null) throw new NullPointerException(); + long i = index, f = fence; + if (i < f) { + consumer.accept(rng.internalNextDouble(origin, bound)); + index = i + 1; + return true; + } + return false; + } + + public void forEachRemaining(DoubleConsumer consumer) { + if (consumer == null) throw new NullPointerException(); + long i = index, f = fence; + if (i < f) { + index = f; + SplittableRandom r = rng; + double o = origin, b = bound; + do { + consumer.accept(r.internalNextDouble(o, b)); + } while (++i < f); + } + } + } + +} diff --git a/jdk/test/java/util/SplittableRandom/SplittableRandomTest.java b/jdk/test/java/util/SplittableRandom/SplittableRandomTest.java new file mode 100644 index 00000000000..23ed242d06d --- /dev/null +++ b/jdk/test/java/util/SplittableRandom/SplittableRandomTest.java @@ -0,0 +1,511 @@ +/* + * Copyright (c) 2012, 2013, 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 org.testng.Assert; +import org.testng.annotations.Test; + +import java.util.SplittableRandom; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.LongAdder; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +/** + * @test + * @run testng SplittableRandomTest + * @run testng/othervm -Djava.util.secureRandomSeed=true SplittableRandomTest + * @summary test methods on SplittableRandom + */ +@Test +public class SplittableRandomTest { + + // Note: this test was copied from the 166 TCK SplittableRandomTest test + // and modified to be a TestNG test + + /* + * Testing coverage notes: + * + * 1. Many of the test methods are adapted from ThreadLocalRandomTest. + * + * 2. These tests do not check for random number generator quality. + * But we check for minimal API compliance by requiring that + * repeated calls to nextX methods, up to NCALLS tries, produce at + * least two distinct results. (In some possible universe, a + * "correct" implementation might fail, but the odds are vastly + * less than that of encountering a hardware failure while running + * the test.) For bounded nextX methods, we sample various + * intervals across multiples of primes. In other tests, we repeat + * under REPS different values. + */ + + // max numbers of calls to detect getting stuck on one value + static final int NCALLS = 10000; + + // max sampled int bound + static final int MAX_INT_BOUND = (1 << 28); + + // max sampled long bound + static final long MAX_LONG_BOUND = (1L << 42); + + // Number of replications for other checks + static final int REPS = 20; + + /** + * Repeated calls to nextInt produce at least two distinct results + */ + public void testNextInt() { + SplittableRandom sr = new SplittableRandom(); + int f = sr.nextInt(); + int i = 0; + while (i < NCALLS && sr.nextInt() == f) + ++i; + assertTrue(i < NCALLS); + } + + /** + * Repeated calls to nextLong produce at least two distinct results + */ + public void testNextLong() { + SplittableRandom sr = new SplittableRandom(); + long f = sr.nextLong(); + int i = 0; + while (i < NCALLS && sr.nextLong() == f) + ++i; + assertTrue(i < NCALLS); + } + + /** + * Repeated calls to nextDouble produce at least two distinct results + */ + public void testNextDouble() { + SplittableRandom sr = new SplittableRandom(); + double f = sr.nextDouble(); + int i = 0; + while (i < NCALLS && sr.nextDouble() == f) + ++i; + assertTrue(i < NCALLS); + } + + /** + * Two SplittableRandoms created with the same seed produce the + * same values for nextLong. + */ + public void testSeedConstructor() { + for (long seed = 2; seed < MAX_LONG_BOUND; seed += 15485863) { + SplittableRandom sr1 = new SplittableRandom(seed); + SplittableRandom sr2 = new SplittableRandom(seed); + for (int i = 0; i < REPS; ++i) + assertEquals(sr1.nextLong(), sr2.nextLong()); + } + } + + /** + * A SplittableRandom produced by split() of a default-constructed + * SplittableRandom generates a different sequence + */ + public void testSplit1() { + SplittableRandom sr = new SplittableRandom(); + for (int reps = 0; reps < REPS; ++reps) { + SplittableRandom sc = sr.split(); + int i = 0; + while (i < NCALLS && sr.nextLong() == sc.nextLong()) + ++i; + assertTrue(i < NCALLS); + } + } + + /** + * A SplittableRandom produced by split() of a seeded-constructed + * SplittableRandom generates a different sequence + */ + public void testSplit2() { + SplittableRandom sr = new SplittableRandom(12345); + for (int reps = 0; reps < REPS; ++reps) { + SplittableRandom sc = sr.split(); + int i = 0; + while (i < NCALLS && sr.nextLong() == sc.nextLong()) + ++i; + assertTrue(i < NCALLS); + } + } + + /** + * nextInt(negative) throws IllegalArgumentException + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testNextIntBoundedNeg() { + SplittableRandom sr = new SplittableRandom(); + int f = sr.nextInt(-17); + } + + /** + * nextInt(least >= bound) throws IllegalArgumentException + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testNextIntBadBounds() { + SplittableRandom sr = new SplittableRandom(); + int f = sr.nextInt(17, 2); + } + + /** + * nextInt(bound) returns 0 <= value < bound; + * repeated calls produce at least two distinct results + */ + public void testNextIntBounded() { + SplittableRandom sr = new SplittableRandom(); + // sample bound space across prime number increments + for (int bound = 2; bound < MAX_INT_BOUND; bound += 524959) { + int f = sr.nextInt(bound); + assertTrue(0 <= f && f < bound); + int i = 0; + int j; + while (i < NCALLS && + (j = sr.nextInt(bound)) == f) { + assertTrue(0 <= j && j < bound); + ++i; + } + assertTrue(i < NCALLS); + } + } + + /** + * nextInt(least, bound) returns least <= value < bound; + * repeated calls produce at least two distinct results + */ + public void testNextIntBounded2() { + SplittableRandom sr = new SplittableRandom(); + for (int least = -15485863; least < MAX_INT_BOUND; least += 524959) { + for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 49979687) { + int f = sr.nextInt(least, bound); + assertTrue(least <= f && f < bound); + int i = 0; + int j; + while (i < NCALLS && + (j = sr.nextInt(least, bound)) == f) { + assertTrue(least <= j && j < bound); + ++i; + } + assertTrue(i < NCALLS); + } + } + } + + /** + * nextLong(negative) throws IllegalArgumentException + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testNextLongBoundedNeg() { + SplittableRandom sr = new SplittableRandom(); + long f = sr.nextLong(-17); + } + + /** + * nextLong(least >= bound) throws IllegalArgumentException + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testNextLongBadBounds() { + SplittableRandom sr = new SplittableRandom(); + long f = sr.nextLong(17, 2); + } + + /** + * nextLong(bound) returns 0 <= value < bound; + * repeated calls produce at least two distinct results + */ + public void testNextLongBounded() { + SplittableRandom sr = new SplittableRandom(); + for (long bound = 2; bound < MAX_LONG_BOUND; bound += 15485863) { + long f = sr.nextLong(bound); + assertTrue(0 <= f && f < bound); + int i = 0; + long j; + while (i < NCALLS && + (j = sr.nextLong(bound)) == f) { + assertTrue(0 <= j && j < bound); + ++i; + } + assertTrue(i < NCALLS); + } + } + + /** + * nextLong(least, bound) returns least <= value < bound; + * repeated calls produce at least two distinct results + */ + public void testNextLongBounded2() { + SplittableRandom sr = new SplittableRandom(); + for (long least = -86028121; least < MAX_LONG_BOUND; least += 982451653L) { + for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) { + long f = sr.nextLong(least, bound); + assertTrue(least <= f && f < bound); + int i = 0; + long j; + while (i < NCALLS && + (j = sr.nextLong(least, bound)) == f) { + assertTrue(least <= j && j < bound); + ++i; + } + assertTrue(i < NCALLS); + } + } + } + + /** + * nextDouble(least, bound) returns least <= value < bound; + * repeated calls produce at least two distinct results + */ + public void testNextDoubleBounded2() { + SplittableRandom sr = new SplittableRandom(); + for (double least = 0.0001; least < 1.0e20; least *= 8) { + for (double bound = least * 1.001; bound < 1.0e20; bound *= 16) { + double f = sr.nextDouble(least, bound); + assertTrue(least <= f && f < bound); + int i = 0; + double j; + while (i < NCALLS && + (j = sr.nextDouble(least, bound)) == f) { + assertTrue(least <= j && j < bound); + ++i; + } + assertTrue(i < NCALLS); + } + } + } + + /** + * Invoking sized ints, long, doubles, with negative sizes throws + * IllegalArgumentException + */ + public void testBadStreamSize() { + SplittableRandom r = new SplittableRandom(); + executeAndCatchIAE(() -> r.ints(-1L)); + executeAndCatchIAE(() -> r.ints(-1L, 2, 3)); + executeAndCatchIAE(() -> r.longs(-1L)); + executeAndCatchIAE(() -> r.longs(-1L, -1L, 1L)); + executeAndCatchIAE(() -> r.doubles(-1L)); + executeAndCatchIAE(() -> r.doubles(-1L, .5, .6)); + } + + /** + * Invoking bounded ints, long, doubles, with illegal bounds throws + * IllegalArgumentException + */ + public void testBadStreamBounds() { + SplittableRandom r = new SplittableRandom(); + executeAndCatchIAE(() -> r.ints(2, 1)); + executeAndCatchIAE(() -> r.ints(10, 42, 42)); + executeAndCatchIAE(() -> r.longs(-1L, -1L)); + executeAndCatchIAE(() -> r.longs(10, 1L, -2L)); + executeAndCatchIAE(() -> r.doubles(0.0, 0.0)); + executeAndCatchIAE(() -> r.doubles(10, .5, .4)); + } + + private void executeAndCatchIAE(Runnable r) { + executeAndCatch(IllegalArgumentException.class, r); + } + + private void executeAndCatch(Class expected, Runnable r) { + Exception caught = null; + try { + r.run(); + } + catch (Exception e) { + caught = e; + } + + assertNotNull(caught, + String.format("No Exception was thrown, expected an Exception of %s to be thrown", + expected.getName())); + Assert.assertTrue(expected.isInstance(caught), + String.format("Exception thrown %s not an instance of %s", + caught.getClass().getName(), expected.getName())); + } + + /** + * A parallel sized stream of ints generates the given number of values + */ + public void testIntsCount() { + LongAdder counter = new LongAdder(); + SplittableRandom r = new SplittableRandom(); + long size = 0; + for (int reps = 0; reps < REPS; ++reps) { + counter.reset(); + r.ints(size).parallel().forEach(x -> {counter.increment();}); + assertEquals(counter.sum(), size); + size += 524959; + } + } + + /** + * A parallel sized stream of longs generates the given number of values + */ + public void testLongsCount() { + LongAdder counter = new LongAdder(); + SplittableRandom r = new SplittableRandom(); + long size = 0; + for (int reps = 0; reps < REPS; ++reps) { + counter.reset(); + r.longs(size).parallel().forEach(x -> {counter.increment();}); + assertEquals(counter.sum(), size); + size += 524959; + } + } + + /** + * A parallel sized stream of doubles generates the given number of values + */ + public void testDoublesCount() { + LongAdder counter = new LongAdder(); + SplittableRandom r = new SplittableRandom(); + long size = 0; + for (int reps = 0; reps < REPS; ++reps) { + counter.reset(); + r.doubles(size).parallel().forEach(x -> {counter.increment();}); + assertEquals(counter.sum(), size); + size += 524959; + } + } + + /** + * Each of a parallel sized stream of bounded ints is within bounds + */ + public void testBoundedInts() { + AtomicInteger fails = new AtomicInteger(0); + SplittableRandom r = new SplittableRandom(); + long size = 12345L; + for (int least = -15485867; least < MAX_INT_BOUND; least += 524959) { + for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 67867967) { + final int lo = least, hi = bound; + r.ints(size, lo, hi).parallel(). + forEach(x -> {if (x < lo || x >= hi) + fails.getAndIncrement(); }); + } + } + assertEquals(fails.get(), 0); + } + + /** + * Each of a parallel sized stream of bounded longs is within bounds + */ + public void testBoundedLongs() { + AtomicInteger fails = new AtomicInteger(0); + SplittableRandom r = new SplittableRandom(); + long size = 123L; + for (long least = -86028121; least < MAX_LONG_BOUND; least += 1982451653L) { + for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) { + final long lo = least, hi = bound; + r.longs(size, lo, hi).parallel(). + forEach(x -> {if (x < lo || x >= hi) + fails.getAndIncrement(); }); + } + } + assertEquals(fails.get(), 0); + } + + /** + * Each of a parallel sized stream of bounded doubles is within bounds + */ + public void testBoundedDoubles() { + AtomicInteger fails = new AtomicInteger(0); + SplittableRandom r = new SplittableRandom(); + long size = 456; + for (double least = 0.00011; least < 1.0e20; least *= 9) { + for (double bound = least * 1.0011; bound < 1.0e20; bound *= 17) { + final double lo = least, hi = bound; + r.doubles(size, lo, hi).parallel(). + forEach(x -> {if (x < lo || x >= hi) + fails.getAndIncrement(); }); + } + } + assertEquals(fails.get(), 0); + } + + /** + * A parallel unsized stream of ints generates at least 100 values + */ + public void testUnsizedIntsCount() { + LongAdder counter = new LongAdder(); + SplittableRandom r = new SplittableRandom(); + long size = 100; + r.ints().limit(size).parallel().forEach(x -> {counter.increment();}); + assertEquals(counter.sum(), size); + } + + /** + * A parallel unsized stream of longs generates at least 100 values + */ + public void testUnsizedLongsCount() { + LongAdder counter = new LongAdder(); + SplittableRandom r = new SplittableRandom(); + long size = 100; + r.longs().limit(size).parallel().forEach(x -> {counter.increment();}); + assertEquals(counter.sum(), size); + } + + /** + * A parallel unsized stream of doubles generates at least 100 values + */ + public void testUnsizedDoublesCount() { + LongAdder counter = new LongAdder(); + SplittableRandom r = new SplittableRandom(); + long size = 100; + r.doubles().limit(size).parallel().forEach(x -> {counter.increment();}); + assertEquals(counter.sum(), size); + } + + /** + * A sequential unsized stream of ints generates at least 100 values + */ + public void testUnsizedIntsCountSeq() { + LongAdder counter = new LongAdder(); + SplittableRandom r = new SplittableRandom(); + long size = 100; + r.ints().limit(size).forEach(x -> {counter.increment();}); + assertEquals(counter.sum(), size); + } + + /** + * A sequential unsized stream of longs generates at least 100 values + */ + public void testUnsizedLongsCountSeq() { + LongAdder counter = new LongAdder(); + SplittableRandom r = new SplittableRandom(); + long size = 100; + r.longs().limit(size).forEach(x -> {counter.increment();}); + assertEquals(counter.sum(), size); + } + + /** + * A sequential unsized stream of doubles generates at least 100 values + */ + public void testUnsizedDoublesCountSeq() { + LongAdder counter = new LongAdder(); + SplittableRandom r = new SplittableRandom(); + long size = 100; + r.doubles().limit(size).forEach(x -> {counter.increment();}); + assertEquals(counter.sum(), size); + } + +} diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/SplittableRandomTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/SplittableRandomTest.java new file mode 100644 index 00000000000..30b5e7d6da8 --- /dev/null +++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/SplittableRandomTest.java @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.tests.java.util; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.Spliterator; +import java.util.SplittableRandom; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.stream.DoubleStream; +import java.util.stream.DoubleStreamTestScenario; +import java.util.stream.IntStream; +import java.util.stream.IntStreamTestScenario; +import java.util.stream.LongStream; +import java.util.stream.LongStreamTestScenario; +import java.util.stream.OpTestCase; +import java.util.stream.StreamSupport; +import java.util.stream.TestData; + +@Test +public class SplittableRandomTest extends OpTestCase { + + static class RandomBoxedSpliterator implements Spliterator { + final SplittableRandom rng; + long index; + final long fence; + final Function rngF; + + RandomBoxedSpliterator(SplittableRandom rng, long index, long fence, Function rngF) { + this.rng = rng; + this.index = index; + this.fence = fence; + this.rngF = rngF; + } + + public RandomBoxedSpliterator trySplit() { + long i = index, m = (i + fence) >>> 1; + return (m <= i) ? null : + new RandomBoxedSpliterator<>(rng.split(), i, index = m, rngF); + } + + public long estimateSize() { + return fence - index; + } + + public int characteristics() { + return (Spliterator.SIZED | Spliterator.SUBSIZED | + Spliterator.NONNULL | Spliterator.IMMUTABLE); + } + + @Override + public boolean tryAdvance(Consumer consumer) { + if (consumer == null) throw new NullPointerException(); + long i = index, f = fence; + if (i < f) { + consumer.accept(rngF.apply(rng)); + index = i + 1; + return true; + } + return false; + } + } + + static final int SIZE = 1 << 16; + + // Ensure there is a range of a power of 2 + static final int[] BOUNDS = {256}; + static final int[] ORIGINS = {-16, 0, 16}; + + static > ResultAsserter> randomAsserter(int size, T origin, T bound) { + return (act, exp, ord, par) -> { + int count = 0; + Set> values = new HashSet<>(); + for (Comparable t : act) { + if (origin.compareTo(bound) < 0) { + assertTrue(t.compareTo(origin) >= 0); + assertTrue(t.compareTo(bound) < 0); + } + values.add(t); + count++; + } + assertEquals(count, size); + // Assert that at least one different result is produced + // For the size of the data it is highly improbable that this + // will cause a false negative (i.e. a false failure) + assertTrue(values.size() > 1); + }; + } + + @DataProvider(name = "ints") + public static Object[][] intsDataProvider() { + List data = new ArrayList<>(); + + // Function to create a stream using a RandomBoxedSpliterator + + Function, IntStream> rbsf = + sf -> StreamSupport.stream(new RandomBoxedSpliterator<>(new SplittableRandom(), 0, SIZE, sf), false). + mapToInt(i -> i); + + // Unbounded + + data.add(new Object[]{ + TestData.Factory.ofIntSupplier( + String.format("new SplittableRandom().ints().limit(%d)", SIZE), + () -> new SplittableRandom().ints().limit(SIZE)), + randomAsserter(SIZE, Integer.MAX_VALUE, 0) + }); + + data.add(new Object[]{ + TestData.Factory.ofIntSupplier( + String.format("new SplittableRandom().ints(%d)", SIZE), + () -> new SplittableRandom().ints(SIZE)), + randomAsserter(SIZE, Integer.MAX_VALUE, 0) + }); + + data.add(new Object[]{ + TestData.Factory.ofIntSupplier( + String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextInt())", SIZE), + () -> rbsf.apply(sr -> sr.nextInt())), + randomAsserter(SIZE, Integer.MAX_VALUE, 0) + }); + + // Bounded + + for (int b : BOUNDS) { + for (int o : ORIGINS) { + final int origin = o; + final int bound = b; + + data.add(new Object[]{ + TestData.Factory.ofIntSupplier( + String.format("new SplittableRandom().ints(%d, %d).limit(%d)", origin, bound, SIZE), + () -> new SplittableRandom().ints(origin, bound).limit(SIZE)), + randomAsserter(SIZE, origin, bound) + }); + + data.add(new Object[]{ + TestData.Factory.ofIntSupplier( + String.format("new SplittableRandom().ints(%d, %d, %d)", SIZE, origin, bound), + () -> new SplittableRandom().ints(SIZE, origin, bound)), + randomAsserter(SIZE, origin, bound) + }); + + if (origin == 0) { + data.add(new Object[]{ + TestData.Factory.ofIntSupplier( + String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextInt(%d))", SIZE, bound), + () -> rbsf.apply(sr -> sr.nextInt(bound))), + randomAsserter(SIZE, origin, bound) + }); + } + + data.add(new Object[]{ + TestData.Factory.ofIntSupplier( + String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextInt(%d, %d))", SIZE, origin, bound), + () -> rbsf.apply(sr -> sr.nextInt(origin, bound))), + randomAsserter(SIZE, origin, bound) + }); + } + } + + return data.toArray(new Object[0][]); + } + + @Test(dataProvider = "ints") + public void testInts(TestData.OfInt data, ResultAsserter> ra) { + withData(data). + stream(s -> s). + without(IntStreamTestScenario.PAR_STREAM_TO_ARRAY_CLEAR_SIZED). + resultAsserter(ra). + exercise(); + } + + @DataProvider(name = "longs") + public static Object[][] longsDataProvider() { + List data = new ArrayList<>(); + + // Function to create a stream using a RandomBoxedSpliterator + + Function, LongStream> rbsf = + sf -> StreamSupport.stream(new RandomBoxedSpliterator<>(new SplittableRandom(), 0, SIZE, sf), false). + mapToLong(i -> i); + + // Unbounded + + data.add(new Object[]{ + TestData.Factory.ofLongSupplier( + String.format("new SplittableRandom().longs().limit(%d)", SIZE), + () -> new SplittableRandom().longs().limit(SIZE)), + randomAsserter(SIZE, Long.MAX_VALUE, 0L) + }); + + data.add(new Object[]{ + TestData.Factory.ofLongSupplier( + String.format("new SplittableRandom().longs(%d)", SIZE), + () -> new SplittableRandom().longs(SIZE)), + randomAsserter(SIZE, Long.MAX_VALUE, 0L) + }); + + data.add(new Object[]{ + TestData.Factory.ofLongSupplier( + String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextLong())", SIZE), + () -> rbsf.apply(sr -> sr.nextLong())), + randomAsserter(SIZE, Long.MAX_VALUE, 0L) + }); + + // Bounded + + for (int b : BOUNDS) { + for (int o : ORIGINS) { + final long origin = o; + final long bound = b; + + data.add(new Object[]{ + TestData.Factory.ofLongSupplier( + String.format("new SplittableRandom().longs(%d, %d).limit(%d)", origin, bound, SIZE), + () -> new SplittableRandom().longs(origin, bound).limit(SIZE)), + randomAsserter(SIZE, origin, bound) + }); + + data.add(new Object[]{ + TestData.Factory.ofLongSupplier( + String.format("new SplittableRandom().longs(%d, %d, %d)", SIZE, origin, bound), + () -> new SplittableRandom().longs(SIZE, origin, bound)), + randomAsserter(SIZE, origin, bound) + }); + + if (origin == 0) { + data.add(new Object[]{ + TestData.Factory.ofLongSupplier( + String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextLong(%d))", SIZE, bound), + () -> rbsf.apply(sr -> sr.nextLong(bound))), + randomAsserter(SIZE, origin, bound) + }); + } + + data.add(new Object[]{ + TestData.Factory.ofLongSupplier( + String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextLong(%d, %d))", SIZE, origin, bound), + () -> rbsf.apply(sr -> sr.nextLong(origin, bound))), + randomAsserter(SIZE, origin, bound) + }); + } + } + + return data.toArray(new Object[0][]); + } + + @Test(dataProvider = "longs") + public void testLongs(TestData.OfLong data, ResultAsserter> ra) { + withData(data). + stream(s -> s). + without(LongStreamTestScenario.PAR_STREAM_TO_ARRAY_CLEAR_SIZED). + resultAsserter(ra). + exercise(); + } + + @DataProvider(name = "doubles") + public static Object[][] doublesDataProvider() { + List data = new ArrayList<>(); + + // Function to create a stream using a RandomBoxedSpliterator + + Function, DoubleStream> rbsf = + sf -> StreamSupport.stream(new RandomBoxedSpliterator<>(new SplittableRandom(), 0, SIZE, sf), false). + mapToDouble(i -> i); + + // Unbounded + + data.add(new Object[]{ + TestData.Factory.ofDoubleSupplier( + String.format("new SplittableRandom().doubles().limit(%d)", SIZE), + () -> new SplittableRandom().doubles().limit(SIZE)), + randomAsserter(SIZE, Double.MAX_VALUE, 0d) + }); + + data.add(new Object[]{ + TestData.Factory.ofDoubleSupplier( + String.format("new SplittableRandom().doubles(%d)", SIZE), + () -> new SplittableRandom().doubles(SIZE)), + randomAsserter(SIZE, Double.MAX_VALUE, 0d) + }); + + data.add(new Object[]{ + TestData.Factory.ofDoubleSupplier( + String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextDouble())", SIZE), + () -> rbsf.apply(sr -> sr.nextDouble())), + randomAsserter(SIZE, Double.MAX_VALUE, 0d) + }); + + // Bounded + + for (int b : BOUNDS) { + for (int o : ORIGINS) { + final double origin = o; + final double bound = b; + + data.add(new Object[]{ + TestData.Factory.ofDoubleSupplier( + String.format("new SplittableRandom().doubles(%f, %f).limit(%d)", origin, bound, SIZE), + () -> new SplittableRandom().doubles(origin, bound).limit(SIZE)), + randomAsserter(SIZE, origin, bound) + }); + + data.add(new Object[]{ + TestData.Factory.ofDoubleSupplier( + String.format("new SplittableRandom().doubles(%d, %f, %f)", SIZE, origin, bound), + () -> new SplittableRandom().doubles(SIZE, origin, bound)), + randomAsserter(SIZE, origin, bound) + }); + + if (origin == 0) { + data.add(new Object[]{ + TestData.Factory.ofDoubleSupplier( + String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextDouble(%f))", SIZE, bound), + () -> rbsf.apply(sr -> sr.nextDouble(bound))), + randomAsserter(SIZE, origin, bound) + }); + } + + data.add(new Object[]{ + TestData.Factory.ofDoubleSupplier( + String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextDouble(%f, %f))", SIZE, origin, bound), + () -> rbsf.apply(sr -> sr.nextDouble(origin, bound))), + randomAsserter(SIZE, origin, bound) + }); + } + } + + return data.toArray(new Object[0][]); + } + + @Test(dataProvider = "doubles") + public void testDoubles(TestData.OfDouble data, ResultAsserter> ra) { + withData(data). + stream(s -> s). + without(DoubleStreamTestScenario.PAR_STREAM_TO_ARRAY_CLEAR_SIZED). + resultAsserter(ra). + exercise(); + } +} From 849788a425dcccfded4905f701d487773826751e Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Tue, 27 Aug 2013 17:50:52 +0800 Subject: [PATCH 100/102] 8015669: KerberosPrincipal::equals should ignore name-type Reviewed-by: mullan --- .../auth/kerberos/KerberosPrincipal.java | 14 ++--- jdk/test/sun/security/krb5/auto/KPEquals.java | 55 +++++++++++++++++++ 2 files changed, 59 insertions(+), 10 deletions(-) create mode 100644 jdk/test/sun/security/krb5/auto/KPEquals.java diff --git a/jdk/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java b/jdk/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java index 6962f2a43d3..1c033803cc7 100644 --- a/jdk/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java +++ b/jdk/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java @@ -197,8 +197,7 @@ public final class KerberosPrincipal * {@code KerberosPrincipal} and the two * {@code KerberosPrincipal} instances are equivalent. * More formally two {@code KerberosPrincipal} instances are equal - * if the values returned by {@code getName()} are equal and the - * values returned by {@code getNameType()} are equal. + * if the values returned by {@code getName()} are equal. * * @param other the Object to compare to * @return true if the Object passed in represents the same principal @@ -211,15 +210,10 @@ public final class KerberosPrincipal if (! (other instanceof KerberosPrincipal)) { return false; - } else { - String myFullName = getName(); - String otherFullName = ((KerberosPrincipal) other).getName(); - if (nameType == ((KerberosPrincipal)other).nameType && - myFullName.equals(otherFullName)) { - return true; - } } - return false; + String myFullName = getName(); + String otherFullName = ((KerberosPrincipal) other).getName(); + return myFullName.equals(otherFullName); } /** diff --git a/jdk/test/sun/security/krb5/auto/KPEquals.java b/jdk/test/sun/security/krb5/auto/KPEquals.java new file mode 100644 index 00000000000..7a7aaa34f24 --- /dev/null +++ b/jdk/test/sun/security/krb5/auto/KPEquals.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013, 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 8015669 + * @summary KerberosPrincipal::equals should ignore name-type + * @compile -XDignore.symbol.file KPEquals.java + * @run main/othervm KPEquals + */ + +import sun.security.jgss.GSSUtil; + +import javax.security.auth.kerberos.KerberosKey; +import javax.security.auth.kerberos.KerberosPrincipal; +import javax.security.auth.kerberos.KeyTab; + +public class KPEquals { + + public static void main(String[] args) throws Exception { + new OneKDC(null).writeJAASConf(); + Context c = Context.fromJAAS("client"); + Context s = Context.fromThinAir(); + KerberosPrincipal kp = new KerberosPrincipal( + OneKDC.SERVER + "@" + OneKDC.REALM, + KerberosPrincipal.KRB_NT_SRV_INST); + s.s().getPrincipals().add(kp); + for (KerberosKey k: KeyTab.getInstance(kp).getKeys(kp)) { + s.s().getPrivateCredentials().add(k); + } + c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID); + s.startAsServer(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID); + Context.handshake(c, s); + } +} From c5fd247e16d75945a5940f2a57f2f2e4febb3dbe Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Tue, 27 Aug 2013 17:50:55 +0800 Subject: [PATCH 101/102] 8022761: regression: SecurityException is NOT thrown while trying to pack a wrongly signed Indexed Jar file Reviewed-by: sherman --- .../classes/java/util/jar/JarVerifier.java | 4 +- .../sun/security/tools/jarsigner/jvindex.sh | 76 +++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 jdk/test/sun/security/tools/jarsigner/jvindex.sh diff --git a/jdk/src/share/classes/java/util/jar/JarVerifier.java b/jdk/src/share/classes/java/util/jar/JarVerifier.java index 73748c1083d..30459e54324 100644 --- a/jdk/src/share/classes/java/util/jar/JarVerifier.java +++ b/jdk/src/share/classes/java/util/jar/JarVerifier.java @@ -32,6 +32,7 @@ import java.security.*; import java.security.cert.CertificateException; import java.util.zip.ZipEntry; +import sun.misc.JarIndex; import sun.security.util.ManifestDigester; import sun.security.util.ManifestEntryVerifier; import sun.security.util.SignatureFileVerifier; @@ -139,7 +140,8 @@ class JarVerifier { return; } - if (uname.equals(JarFile.MANIFEST_NAME)) { + if (uname.equals(JarFile.MANIFEST_NAME) || + uname.equals(JarIndex.INDEX_NAME)) { return; } diff --git a/jdk/test/sun/security/tools/jarsigner/jvindex.sh b/jdk/test/sun/security/tools/jarsigner/jvindex.sh new file mode 100644 index 00000000000..c4435b68121 --- /dev/null +++ b/jdk/test/sun/security/tools/jarsigner/jvindex.sh @@ -0,0 +1,76 @@ +# +# Copyright (c) 2013, 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 8022761 +# @summary regression: SecurityException is NOT thrown while trying to pack a wrongly signed Indexed Jar file +# + +if [ "${TESTJAVA}" = "" ] ; then + JAVAC_CMD=`which javac` + TESTJAVA=`dirname $JAVAC_CMD`/.. +fi + +# set platform-dependent variables +OS=`uname -s` +case "$OS" in + Windows_* ) + FS="\\" + ;; + * ) + FS="/" + ;; +esac + +F=abcde +KS=jvindex.jks +JFILE=jvindex.jar + +KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit \ + -keystore $KS" +JAR=$TESTJAVA${FS}bin${FS}jar +JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner -keystore $KS -storepass changeit" + +rm $F $KS $JFILE 2> /dev/null + +echo 12345 > $F +$JAR cvf $JFILE $F + +ERR="" + +$KT -alias a -dname CN=a -genkey -validity 300 || ERR="$ERR 1" + +$JARSIGNER $JFILE a || ERR="$ERR 2" +$JAR i $JFILE + +# Make sure the $F line has "sm" (signed and in manifest) +$JARSIGNER -verify -verbose $JFILE | grep $F | grep sm || ERR="$ERR 3" + +if [ "$ERR" = "" ]; then + exit 0 +else + echo "ERR is $ERR" + exit 1 +fi + + From 05f2952a67a9b88e0283dbe3796e967d449cc688 Mon Sep 17 00:00:00 2001 From: Sean Mullan Date: Tue, 27 Aug 2013 10:46:03 -0400 Subject: [PATCH 102/102] 8023769: JDK-8016850 broke the old build Remove files that were moved/removed from com/sun/security/auth/FILES_java.gmk Reviewed-by: chegar, xuelei --- jdk/make/com/sun/security/auth/FILES_java.gmk | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/jdk/make/com/sun/security/auth/FILES_java.gmk b/jdk/make/com/sun/security/auth/FILES_java.gmk index 3e96e9d58b3..fa4f7d4b8d0 100644 --- a/jdk/make/com/sun/security/auth/FILES_java.gmk +++ b/jdk/make/com/sun/security/auth/FILES_java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2013, 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 @@ -43,8 +43,6 @@ FILES_java = \ com/sun/security/auth/UserPrincipal.java \ com/sun/security/auth/LdapPrincipal.java \ com/sun/security/auth/PolicyFile.java \ - com/sun/security/auth/SubjectCodeSource.java \ - com/sun/security/auth/PolicyParser.java \ com/sun/security/auth/PrincipalComparator.java \ com/sun/security/auth/callback/TextCallbackHandler.java \ com/sun/security/auth/callback/DialogCallbackHandler.java