diff options
author | Jung-uk Kim <jkim@FreeBSD.org> | 2012-10-19 22:43:10 +0000 |
---|---|---|
committer | Jung-uk Kim <jkim@FreeBSD.org> | 2012-10-19 22:43:10 +0000 |
commit | 81a8a55b63815f66e325d8ba0051a10e48f90bd1 (patch) | |
tree | 583a72c17d448ec15fd905bf3467d0378376c4de /java | |
parent | aadc8c6b1d95b98cce7c5b824835d47ab2d010f2 (diff) |
Notes
Diffstat (limited to 'java')
24 files changed, 3729 insertions, 154 deletions
diff --git a/java/openjdk6-jre/Makefile b/java/openjdk6-jre/Makefile index 2ba20c72c8b2..e4c29c2ab185 100644 --- a/java/openjdk6-jre/Makefile +++ b/java/openjdk6-jre/Makefile @@ -1,6 +1,6 @@ # $FreeBSD$ -PORTREVISION= 0 +PORTREVISION= 1 CATEGORIES= java devel PKGNAMESUFFIX= -jre diff --git a/java/openjdk6/Makefile b/java/openjdk6/Makefile index 136e96742976..227ce1063f67 100644 --- a/java/openjdk6/Makefile +++ b/java/openjdk6/Makefile @@ -3,7 +3,7 @@ PORTNAME= openjdk6 PORTVERSION= b26 -PORTREVISION?= 0 +PORTREVISION?= 1 CATEGORIES= java devel MASTER_SITES= http://download.java.net/openjdk/jdk6/promoted/${PORTVERSION}/ \ http://download.java.net/jaxp/openjdk/jdk6/:jaxp \ @@ -40,8 +40,10 @@ RUN_DEPENDS= javavm:${PORTSDIR}/java/javavmwrapper \ OPENJDK_BUILDDATE= 21_sep_2012 +EXTRA_PATCHES= ${FILESDIR}/icedtea/security/*.patch + OPTIONS_DEFINE= ICEDTEA IPV6 POLICY SOUND TZUPDATE -OPTIONS_DEFAULT=ICEDTEA TZUPDATE +OPTIONS_DEFAULT=ICEDTEA IPV6 TZUPDATE ICEDTEA_DESC= Apply additional patches from IcedTea POLICY_DESC= Install the Unlimited Strength Policy Files SOUND_DESC= Enable sound support @@ -62,7 +64,6 @@ WRKSRC= ${WRKDIR} USE_GMAKE= yes USE_MOTIF= yes USE_XORG= x11 xext xi xt xtst -MAKE_JOBS_UNSAFE= yes JAXP_BUILD= 144_04 JAXPFILE= jaxp${JAXP_BUILD}.zip @@ -143,6 +144,16 @@ MAKE_ENV+= CCC="${CXX}" GCC="${CC}" # XXX Turn off -Werror from HotSpot. MAKE_ENV+= WARNINGS_ARE_ERRORS="${WARNINGS_ARE_ERRORS}" +# XXX Turn off parallel build by default. +.if defined(DISABLE_MAKE_JOBS) || !defined(FORCE_MAKE_JOBS) +BUILD_JOBS_NUMBER= 1 +.elif defined(FORCE_MAKE_JOBS) +BUILD_JOBS_NUMBER= ${MAKE_JOBS_NUMBER} +.endif +_MAKE_JOBS= # +MAKE_ENV+= ALT_PARALLEL_COMPILE_JOBS=${BUILD_JOBS_NUMBER} \ + HOTSPOT_BUILD_JOBS=${BUILD_JOBS_NUMBER} + .if ${PORT_OPTIONS:MDEBUG} ALL_TARGET= debug_build OPENJDK_OSARCH= bsd-${ARCH:S/i386/i586/}-debug @@ -183,15 +194,6 @@ BUILD_DEPENDS+= ${LOCALBASE}/lib/X11/fonts/dejavu:${PORTSDIR}/x11-fonts/dejavu USE_DISPLAY= yes .endif -.if !defined(DISABLE_MAKE_JOBS) -.if defined(MAKE_JOBS_NUMBER) -BUILD_JOBS_NUMBER= ${MAKE_JOBS_NUMBER} -.else -BUILD_JOBS_NUMBER= `${SYSCTL} -n kern.smp.cpus` -.endif -MAKE_ENV+= HOTSPOT_BUILD_JOBS=${BUILD_JOBS_NUMBER} -.endif - COPYDIRS= \ hotspot/src/os/linux/vm \ hotspot/src/os_cpu/linux_x86/vm \ diff --git a/java/openjdk6/files/icedtea/security/6631398.patch b/java/openjdk6/files/icedtea/security/6631398.patch new file mode 100644 index 000000000000..cc004dbc1c6f --- /dev/null +++ b/java/openjdk6/files/icedtea/security/6631398.patch @@ -0,0 +1,20 @@ +# HG changeset patch +# User weijun +# Date 1339724916 -28800 +# Node ID 0fdc422fba9b63be684f1229af75f0c1f3ceec87 +# Parent f09937f0b2e32aa60a2cdd23f03a7e2d45091b60 +6631398: FilePermission improved path checking +Reviewed-by: mullan, skoivu, jdn + +diff --git a/src/share/classes/java/io/FilePermission.java b/src/share/classes/java/io/FilePermission.java +--- jdk/src/share/classes/java/io/FilePermission.java ++++ jdk/src/share/classes/java/io/FilePermission.java +@@ -399,7 +399,7 @@ + */ + + public int hashCode() { +- return this.cpath.hashCode(); ++ return 0; + } + + /** diff --git a/java/openjdk6/files/icedtea/security/7093490.patch b/java/openjdk6/files/icedtea/security/7093490.patch new file mode 100644 index 000000000000..e4209a692f17 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/7093490.patch @@ -0,0 +1,28 @@ +# HG changeset patch +# User coffeys +# Date 1340913225 -3600 +# Node ID e7334bb16ad694bed492da52e5713c8391e79ce8 +# Parent 0fdc422fba9b63be684f1229af75f0c1f3ceec87 +7093490: adjust package access in rmiregistry +Reviewed-by: smarks + +diff --git a/src/share/classes/sun/rmi/registry/RegistryImpl.java b/src/share/classes/sun/rmi/registry/RegistryImpl.java +--- jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java ++++ jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1996, 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 +@@ -405,7 +405,8 @@ + */ + perms.add(new SocketPermission("*", "connect,accept")); + +- perms.add(new RuntimePermission("accessClassInPackage.sun.*")); ++ perms.add(new RuntimePermission("accessClassInPackage.sun.jvmstat.*")); ++ perms.add(new RuntimePermission("accessClassInPackage.sun.jvm.hotspot.*")); + + perms.add(new FilePermission("<<ALL FILES>>", "read")); + diff --git a/java/openjdk6/files/icedtea/security/7143535.patch b/java/openjdk6/files/icedtea/security/7143535.patch new file mode 100644 index 000000000000..99dcde0ecbb0 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/7143535.patch @@ -0,0 +1,31 @@ +# HG changeset patch +# User sundar +# Date 1345469787 -14400 +# Node ID 1e170e3c1b682d0f98a61a47e5049535c5bd4999 +# Parent e7334bb16ad694bed492da52e5713c8391e79ce8 +7143535: ScriptEngine corrected permissions +Reviewed-by: mschoene + +diff --git a/src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java b/src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java +--- jdk/src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java ++++ jdk/src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2005, 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 +@@ -130,7 +130,11 @@ + public RhinoScriptEngine() { + + if (System.getSecurityManager() != null) { +- accCtxt = AccessController.getContext(); ++ try { ++ AccessController.checkPermission(new AllPermission()); ++ } catch (AccessControlException ace) { ++ accCtxt = AccessController.getContext(); ++ } + } + + Context cx = enterContext(); diff --git a/java/openjdk6/files/icedtea/security/7158800.patch b/java/openjdk6/files/icedtea/security/7158800.patch new file mode 100644 index 000000000000..cf16db2f05b0 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/7158800.patch @@ -0,0 +1,1413 @@ +# HG changeset patch +# User kevinw +# Date 1345802362 -3600 +# Node ID 2faa3f7bad65189e69ab2f9a491743786bb8f07f +# Parent a080633e3a056dae9e94077c9ac4cf966137ade9 +7158800: Improve storage of symbol tables +7178670: runtime/7158800/BadUtf8.java fails in SymbolTable::rehash_table +7181200: JVM new hashing code breaks SA in product mode +7190262: Debug builds fail to verify String table with +UseCompressedStrings after 7158800 +Reviewed-by: coleenp + +diff --git a/src/share/vm/classfile/altHashing.cpp b/src/share/vm/classfile/altHashing.cpp +new file mode 100644 +--- /dev/null ++++ hotspot/src/share/vm/classfile/altHashing.cpp +@@ -0,0 +1,304 @@ ++/* ++ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "classfile/altHashing.hpp" ++#include "classfile/symbolTable.hpp" ++#include "classfile/systemDictionary.hpp" ++#include "oops/markOop.hpp" ++#include "runtime/thread.hpp" ++ ++// Get the hash code of the classes mirror if it exists, otherwise just ++// return a random number, which is one of the possible hash code used for ++// objects. We don't want to call the synchronizer hash code to install ++// this value because it may safepoint. ++intptr_t object_hash(klassOop k) { ++ intptr_t hc = Klass::cast(k)->java_mirror()->mark()->hash(); ++ return hc != markOopDesc::no_hash ? hc : os::random(); ++} ++ ++// Seed value used for each alternative hash calculated. ++jint AltHashing::compute_seed() { ++ jlong nanos = os::javaTimeNanos(); ++ jlong now = os::javaTimeMillis(); ++ jint SEED_MATERIAL[8] = { ++ (jint) object_hash(SystemDictionary::String_klass()), ++ (jint) object_hash(SystemDictionary::System_klass()), ++ (jint) os::random(), // current thread isn't a java thread ++ (jint) (((julong)nanos) >> 32), ++ (jint) nanos, ++ (jint) (((julong)now) >> 32), ++ (jint) now, ++ (jint) (os::javaTimeNanos() >> 2) ++ }; ++ ++ return murmur3_32(SEED_MATERIAL, 8); ++} ++ ++ ++// Murmur3 hashing for Symbol ++jint AltHashing::murmur3_32(jint seed, const jbyte* data, int len) { ++ jint h1 = seed; ++ int count = len; ++ int offset = 0; ++ ++ // body ++ while (count >= 4) { ++ jint k1 = (data[offset] & 0x0FF) ++ | (data[offset + 1] & 0x0FF) << 8 ++ | (data[offset + 2] & 0x0FF) << 16 ++ | data[offset + 3] << 24; ++ ++ count -= 4; ++ offset += 4; ++ ++ k1 *= 0xcc9e2d51; ++ k1 = Integer_rotateLeft(k1, 15); ++ k1 *= 0x1b873593; ++ ++ h1 ^= k1; ++ h1 = Integer_rotateLeft(h1, 13); ++ h1 = h1 * 5 + 0xe6546b64; ++ } ++ ++ // tail ++ ++ if (count > 0) { ++ jint k1 = 0; ++ ++ switch (count) { ++ case 3: ++ k1 ^= (data[offset + 2] & 0xff) << 16; ++ // fall through ++ case 2: ++ k1 ^= (data[offset + 1] & 0xff) << 8; ++ // fall through ++ case 1: ++ k1 ^= (data[offset] & 0xff); ++ // fall through ++ default: ++ k1 *= 0xcc9e2d51; ++ k1 = Integer_rotateLeft(k1, 15); ++ k1 *= 0x1b873593; ++ h1 ^= k1; ++ } ++ } ++ ++ // finalization ++ h1 ^= len; ++ ++ // finalization mix force all bits of a hash block to avalanche ++ h1 ^= ((unsigned int)h1) >> 16; ++ h1 *= 0x85ebca6b; ++ h1 ^= ((unsigned int)h1) >> 13; ++ h1 *= 0xc2b2ae35; ++ h1 ^= ((unsigned int)h1) >> 16; ++ ++ return h1; ++} ++ ++// Murmur3 hashing for Strings ++jint AltHashing::murmur3_32(jint seed, const jchar* data, int len) { ++ jint h1 = seed; ++ ++ int off = 0; ++ int count = len; ++ ++ // body ++ while (count >= 2) { ++ jchar d1 = data[off++] & 0xFFFF; ++ jchar d2 = data[off++]; ++ jint k1 = (d1 | d2 << 16); ++ ++ count -= 2; ++ ++ k1 *= 0xcc9e2d51; ++ k1 = Integer_rotateLeft(k1, 15); ++ k1 *= 0x1b873593; ++ ++ h1 ^= k1; ++ h1 = Integer_rotateLeft(h1, 13); ++ h1 = h1 * 5 + 0xe6546b64; ++ } ++ ++ // tail ++ ++ if (count > 0) { ++ int k1 = data[off]; ++ ++ k1 *= 0xcc9e2d51; ++ k1 = Integer_rotateLeft(k1, 15); ++ k1 *= 0x1b873593; ++ h1 ^= k1; ++ } ++ ++ // finalization ++ h1 ^= len * 2; // (Character.SIZE / Byte.SIZE); ++ ++ // finalization mix force all bits of a hash block to avalanche ++ h1 ^= ((unsigned int)h1) >> 16; ++ h1 *= 0x85ebca6b; ++ h1 ^= ((unsigned int)h1) >> 13; ++ h1 *= 0xc2b2ae35; ++ h1 ^= ((unsigned int)h1) >> 16; ++ ++ return h1; ++} ++ ++// Hash used for the seed. ++jint AltHashing::murmur3_32(jint seed, const int* data, int len) { ++ jint h1 = seed; ++ ++ int off = 0; ++ int end = len; ++ ++ // body ++ while (off < end) { ++ jint k1 = data[off++]; ++ ++ k1 *= 0xcc9e2d51; ++ k1 = Integer_rotateLeft(k1, 15); ++ k1 *= 0x1b873593; ++ ++ h1 ^= k1; ++ h1 = Integer_rotateLeft(h1, 13); ++ h1 = h1 * 5 + 0xe6546b64; ++ } ++ ++ // tail (always empty, as body is always 32-bit chunks) ++ ++ // finalization ++ ++ h1 ^= len * 4; // (Integer.SIZE / Byte.SIZE); ++ ++ // finalization mix force all bits of a hash block to avalanche ++ h1 ^= ((juint)h1) >> 16; ++ h1 *= 0x85ebca6b; ++ h1 ^= ((juint)h1) >> 13; ++ h1 *= 0xc2b2ae35; ++ h1 ^= ((juint)h1) >> 16; ++ ++ return h1; ++} ++ ++jint AltHashing::murmur3_32(const int* data, int len) { ++ return murmur3_32(0, data, len); ++} ++ ++#ifndef PRODUCT ++// Overloaded versions for internal test. ++jint AltHashing::murmur3_32(const jbyte* data, int len) { ++ return murmur3_32(0, data, len); ++} ++ ++jint AltHashing::murmur3_32(const jchar* data, int len) { ++ return murmur3_32(0, data, len); ++} ++ ++// Internal test for alternate hashing. Translated from JDK version ++// test/sun/misc/Hashing.java ++static const jbyte ONE_BYTE[] = { (jbyte) 0x80}; ++static const jbyte TWO_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81}; ++static const jchar ONE_CHAR[] = { (jchar) 0x8180}; ++static const jbyte THREE_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82}; ++static const jbyte FOUR_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82, (jbyte) 0x83}; ++static const jchar TWO_CHAR[] = { (jchar) 0x8180, (jchar) 0x8382}; ++static const jint ONE_INT[] = { 0x83828180}; ++static const jbyte SIX_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82, (jbyte) 0x83, (jbyte) 0x84, (jbyte) 0x85}; ++static const jchar THREE_CHAR[] = { (jchar) 0x8180, (jchar) 0x8382, (jchar) 0x8584}; ++static const jbyte EIGHT_BYTE[] = { ++ (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82, ++ (jbyte) 0x83, (jbyte) 0x84, (jbyte) 0x85, ++ (jbyte) 0x86, (jbyte) 0x87}; ++static const jchar FOUR_CHAR[] = { ++ (jchar) 0x8180, (jchar) 0x8382, ++ (jchar) 0x8584, (jchar) 0x8786}; ++ ++static const jint TWO_INT[] = { 0x83828180, 0x87868584}; ++ ++static const juint MURMUR3_32_X86_CHECK_VALUE = 0xB0F57EE3; ++ ++void AltHashing::testMurmur3_32_ByteArray() { ++ // printf("testMurmur3_32_ByteArray\n"); ++ ++ jbyte* vector = new jbyte[256]; ++ jbyte* hashes = new jbyte[4 * 256]; ++ ++ for (int i = 0; i < 256; i++) { ++ vector[i] = (jbyte) i; ++ } ++ ++ // Hash subranges {}, {0}, {0,1}, {0,1,2}, ..., {0,...,255} ++ for (int i = 0; i < 256; i++) { ++ jint hash = murmur3_32(256 - i, vector, i); ++ hashes[i * 4] = (jbyte) hash; ++ hashes[i * 4 + 1] = (jbyte) (((juint)hash) >> 8); ++ hashes[i * 4 + 2] = (jbyte) (((juint)hash) >> 16); ++ hashes[i * 4 + 3] = (jbyte) (((juint)hash) >> 24); ++ } ++ ++ // hash to get const result. ++ juint final_hash = murmur3_32(hashes, 4*256); ++ ++ assert (MURMUR3_32_X86_CHECK_VALUE == final_hash, ++ err_msg( ++ "Calculated hash result not as expected. Expected %08X got %08X\n", ++ MURMUR3_32_X86_CHECK_VALUE, ++ final_hash)); ++} ++ ++void AltHashing::testEquivalentHashes() { ++ jint jbytes, jchars, ints; ++ ++ // printf("testEquivalentHashes\n"); ++ ++ jbytes = murmur3_32(TWO_BYTE, 2); ++ jchars = murmur3_32(ONE_CHAR, 1); ++ assert (jbytes == jchars, ++ err_msg("Hashes did not match. b:%08x != c:%08x\n", jbytes, jchars)); ++ ++ jbytes = murmur3_32(FOUR_BYTE, 4); ++ jchars = murmur3_32(TWO_CHAR, 2); ++ ints = murmur3_32(ONE_INT, 1); ++ assert ((jbytes == jchars) && (jbytes == ints), ++ err_msg("Hashes did not match. b:%08x != c:%08x != i:%08x\n", jbytes, jchars, ints)); ++ ++ jbytes = murmur3_32(SIX_BYTE, 6); ++ jchars = murmur3_32(THREE_CHAR, 3); ++ assert (jbytes == jchars, ++ err_msg("Hashes did not match. b:%08x != c:%08x\n", jbytes, jchars)); ++ ++ jbytes = murmur3_32(EIGHT_BYTE, 8); ++ jchars = murmur3_32(FOUR_CHAR, 4); ++ ints = murmur3_32(TWO_INT, 2); ++ assert ((jbytes == jchars) && (jbytes == ints), ++ err_msg("Hashes did not match. b:%08x != c:%08x != i:%08x\n", jbytes, jchars, ints)); ++} ++ ++// Returns true if the alternate hashcode is correct ++void AltHashing::test_alt_hash() { ++ testMurmur3_32_ByteArray(); ++ testEquivalentHashes(); ++} ++#endif // PRODUCT +diff --git a/src/share/vm/classfile/altHashing.hpp b/src/share/vm/classfile/altHashing.hpp +new file mode 100644 +--- /dev/null ++++ hotspot/src/share/vm/classfile/altHashing.hpp +@@ -0,0 +1,62 @@ ++/* ++ * Copyright (c) 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. ++ * ++ */ ++ ++#ifndef SHARE_VM_CLASSFILE_ALTHASHING_HPP ++#define SHARE_VM_CLASSFILE_ALTHASHING_HPP ++ ++#include "prims/jni.h" ++#include "classfile/symbolTable.hpp" ++ ++/** ++ * Hashing utilities. ++ * ++ * Implementation of Murmur3 hashing. ++ * This code was translated from src/share/classes/sun/misc/Hashing.java ++ * code in the JDK. ++ */ ++ ++class AltHashing : AllStatic { ++ ++ // utility function copied from java/lang/Integer ++ static jint Integer_rotateLeft(jint i, int distance) { ++ return (i << distance) | (((juint)i) >> (32-distance)); ++ } ++ static jint murmur3_32(const int* data, int len); ++ static jint murmur3_32(jint seed, const int* data, int len); ++ ++#ifndef PRODUCT ++ // Hashing functions used for internal testing ++ static jint murmur3_32(const jbyte* data, int len); ++ static jint murmur3_32(const jchar* data, int len); ++ static void testMurmur3_32_ByteArray(); ++ static void testEquivalentHashes(); ++#endif // PRODUCT ++ ++ public: ++ static jint compute_seed(); ++ static jint murmur3_32(jint seed, const jbyte* data, int len); ++ static jint murmur3_32(jint seed, const jchar* data, int len); ++ NOT_PRODUCT(static void test_alt_hash();) ++}; ++#endif // SHARE_VM_CLASSFILE_ALTHASHING_HPP +diff --git a/src/share/vm/classfile/javaClasses.cpp b/src/share/vm/classfile/javaClasses.cpp +--- hotspot/src/share/vm/classfile/javaClasses.cpp ++++ hotspot/src/share/vm/classfile/javaClasses.cpp +@@ -278,6 +278,28 @@ + return result; + } + ++unsigned int java_lang_String::to_hash(oop java_string) { ++ int length = java_lang_String::length(java_string); ++ // Zero length string will hash to zero with String.toHash() function. ++ if (length == 0) return 0; ++ ++ typeArrayOop value = java_lang_String::value(java_string); ++ int offset = java_lang_String::offset(java_string); ++ return java_lang_String::to_hash(value->char_at_addr(offset), length); ++} ++ ++unsigned int java_lang_String::hash_string(oop java_string) { ++ int length = java_lang_String::length(java_string); ++ // Zero length string doesn't hash necessarily hash to zero. ++ if (length == 0) { ++ return StringTable::hash_string(NULL, 0); ++ } ++ ++ typeArrayOop value = java_lang_String::value(java_string); ++ int offset = java_lang_String::offset(java_string); ++ return StringTable::hash_string(value->char_at_addr(offset), length); ++} ++ + symbolHandle java_lang_String::as_symbol(Handle java_string, TRAPS) { + oop obj = java_string(); + typeArrayOop value = java_lang_String::value(obj); +diff --git a/src/share/vm/classfile/javaClasses.hpp b/src/share/vm/classfile/javaClasses.hpp +--- hotspot/src/share/vm/classfile/javaClasses.hpp ++++ hotspot/src/share/vm/classfile/javaClasses.hpp +@@ -109,6 +109,30 @@ + static char* as_platform_dependent_str(Handle java_string, TRAPS); + static jchar* as_unicode_string(oop java_string, int& length); + ++ // Compute the hash value for a java.lang.String object which would ++ // contain the characters passed in. ++ // ++ // As the hash value used by the String object itself, in ++ // String.hashCode(). This value is normally calculated in Java code ++ // in the String.hashCode method(), but is precomputed for String ++ // objects in the shared archive file. ++ // hash P(31) from Kernighan & Ritchie ++ // ++ // For this reason, THIS ALGORITHM MUST MATCH String.toHash(). ++ template <typename T> static unsigned int to_hash(T* s, int len) { ++ unsigned int h = 0; ++ while (len-- > 0) { ++ h = 31*h + (unsigned int) *s; ++ s++; ++ } ++ return h; ++ } ++ static unsigned int to_hash(oop java_string); ++ ++ // This is the string hash code used by the StringTable, which may be ++ // the same as String.toHash or an alternate hash code. ++ static unsigned int hash_string(oop java_string); ++ + static bool equals(oop java_string, jchar* chars, int len); + + // Conversion between '.' and '/' formats +diff --git a/src/share/vm/classfile/symbolTable.cpp b/src/share/vm/classfile/symbolTable.cpp +--- hotspot/src/share/vm/classfile/symbolTable.cpp ++++ hotspot/src/share/vm/classfile/symbolTable.cpp +@@ -23,6 +23,7 @@ + */ + + #include "precompiled.hpp" ++#include "classfile/altHashing.hpp" + #include "classfile/javaClasses.hpp" + #include "classfile/symbolTable.hpp" + #include "classfile/systemDictionary.hpp" +@@ -34,16 +35,40 @@ + #include "oops/symbolKlass.hpp" + #include "runtime/mutexLocker.hpp" + #include "utilities/hashtable.inline.hpp" ++#include "utilities/numberSeq.hpp" + + // -------------------------------------------------------------------------- + + SymbolTable* SymbolTable::_the_table = NULL; ++bool SymbolTable::_needs_rehashing = false; ++ ++// Create a new table and using alternate hash code, populate the new table ++// with the existing strings. Set flag to use the alternate hash code afterwards. ++void SymbolTable::rehash_table() { ++ ++ assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); ++ // This should never happen with -Xshare:dump but it might in testing mode. ++ if (DumpSharedSpaces) return; ++ // Create a new symbol table ++ SymbolTable* new_table = new SymbolTable(); ++ ++ the_table()->move_to(new_table); ++ ++ // Delete the table and buckets (entries are reused in new table). ++ delete _the_table; ++ // Don't check if we need rehashing until the table gets unbalanced again. ++ // Then rehash with a new global seed. ++ _needs_rehashing = false; ++ _the_table = new_table; ++} + + // Lookup a symbol in a bucket. + + symbolOop SymbolTable::lookup(int index, const char* name, + int len, unsigned int hash) { ++ int count = 0; + for (HashtableEntry* e = bucket(index); e != NULL; e = e->next()) { ++ count++; + if (e->hash() == hash) { + symbolOop sym = symbolOop(e->literal()); + if (sym->equals(name, len)) { +@@ -51,9 +76,20 @@ + } + } + } ++ // If the bucket size is too deep check if this hash code is insufficient. ++ if (count >= BasicHashtable::rehash_count && !needs_rehashing()) { ++ _needs_rehashing = check_rehash_table(count); ++ } + return NULL; + } + ++// Pick hashing algorithm. ++unsigned int SymbolTable::hash_symbol(const char* s, int len) { ++ return the_table()->use_alternate_hashcode() ? ++ AltHashing::murmur3_32(the_table()->seed(), (const jbyte*)s, len) : ++ java_lang_String::to_hash(s, len); ++} ++ + + // We take care not to be blocking while holding the + // SymbolTable_lock. Otherwise, the system might deadlock, since the +@@ -71,8 +107,17 @@ + // Found + if (s != NULL) return s; + ++ // We assume that lookup() has been called already, that it failed, ++ // and symbol was not found. We create the symbol here. ++ symbolKlass* sk = (symbolKlass*) Universe::symbolKlassObj()->klass_part(); ++ symbolOop s_oop = sk->allocate_symbol((u1*)name, len, CHECK_NULL); ++ symbolHandle sym (THREAD, s_oop); ++ ++ // Allocation must be done before grabbing the SymbolTable_lock lock ++ MutexLocker ml(SymbolTable_lock, THREAD); ++ + // Otherwise, add to symbol to table +- return the_table()->basic_add(index, (u1*)name, len, hashValue, CHECK_NULL); ++ return the_table()->basic_add(sym, index, (u1*)name, len, hashValue, CHECK_NULL); + } + + symbolOop SymbolTable::lookup(symbolHandle sym, int begin, int end, TRAPS) { +@@ -108,7 +153,16 @@ + // We can't include the code in No_Safepoint_Verifier because of the + // ResourceMark. + +- return the_table()->basic_add(index, (u1*)buffer, len, hashValue, CHECK_NULL); ++ // We assume that lookup() has been called already, that it failed, ++ // and symbol was not found. We create the symbol here. ++ symbolKlass* sk = (symbolKlass*) Universe::symbolKlassObj()->klass_part(); ++ symbolOop s_oop = sk->allocate_symbol((u1*)buffer, len, CHECK_NULL); ++ symbolHandle newsym (THREAD, s_oop); ++ ++ // Allocation must be done before grabbing the SymbolTable_lock lock ++ MutexLocker ml(SymbolTable_lock, THREAD); ++ ++ return the_table()->basic_add(newsym, index, (u1*)buffer, len, hashValue, CHECK_NULL); + } + + symbolOop SymbolTable::lookup_only(const char* name, int len, +@@ -156,36 +210,68 @@ + void SymbolTable::add(constantPoolHandle cp, int names_count, + const char** names, int* lengths, int* cp_indices, + unsigned int* hashValues, TRAPS) { +- SymbolTable* table = the_table(); +- bool added = table->basic_add(cp, names_count, names, lengths, +- cp_indices, hashValues, CHECK); +- if (!added) { ++ ++ symbolKlass* sk = (symbolKlass*) Universe::symbolKlassObj()->klass_part(); ++ symbolOop sym_oops[symbol_alloc_batch_size]; ++ bool allocated = sk->allocate_symbols(names_count, names, lengths, ++ sym_oops, CHECK); ++ if (!allocated) { + // do it the hard way + for (int i=0; i<names_count; i++) { ++ assert(!Universe::heap()->is_in_reserved(names[i]) || GC_locker::is_active(), ++ "proposed name of symbol must be stable"); ++ ++ // We assume that lookup() has been called already, that it failed, ++ // and symbol was not found. We create the symbol here. ++ symbolKlass* sk = (symbolKlass*) Universe::symbolKlassObj()->klass_part(); ++ symbolOop s_oop = sk->allocate_symbol((u1*)names[i], lengths[i], CHECK); ++ symbolHandle sym (THREAD, s_oop); ++ ++ // Allocation must be done before grabbing the SymbolTable_lock lock ++ MutexLocker ml(SymbolTable_lock, THREAD); ++ ++ SymbolTable* table = the_table(); + int index = table->hash_to_index(hashValues[i]); +- symbolOop sym = table->basic_add(index, (u1*)names[i], lengths[i], ++ symbolOop s = table->basic_add(sym, index, (u1*)names[i], lengths[i], + hashValues[i], CHECK); +- cp->symbol_at_put(cp_indices[i], sym); ++ cp->symbol_at_put(cp_indices[i], s); + } ++ return; + } ++ ++ symbolHandle syms[symbol_alloc_batch_size]; ++ for (int i=0; i<names_count; i++) { ++ syms[i] = symbolHandle(THREAD, sym_oops[i]); ++ } ++ ++ // Allocation must be done before grabbing the SymbolTable_lock lock ++ MutexLocker ml(SymbolTable_lock, THREAD); ++ ++ SymbolTable* table = the_table(); ++ bool added = table->basic_add(syms, cp, names_count, names, lengths, ++ cp_indices, hashValues, CHECK); ++ assert(added, "should always return true"); + } + +-symbolOop SymbolTable::basic_add(int index, u1 *name, int len, +- unsigned int hashValue, TRAPS) { +- assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(), +- "proposed name of symbol must be stable"); +- +- // We assume that lookup() has been called already, that it failed, +- // and symbol was not found. We create the symbol here. +- symbolKlass* sk = (symbolKlass*) Universe::symbolKlassObj()->klass_part(); +- symbolOop s_oop = sk->allocate_symbol(name, len, CHECK_NULL); +- symbolHandle sym (THREAD, s_oop); +- +- // Allocation must be done before grapping the SymbolTable_lock lock +- MutexLocker ml(SymbolTable_lock, THREAD); ++symbolOop SymbolTable::basic_add(symbolHandle sym, int index_arg, u1 *name, int len, ++ unsigned int hashValue_arg, TRAPS) { ++ // Cannot hit a safepoint in this function because the "this" pointer can move. ++ No_Safepoint_Verifier nsv; + + assert(sym->equals((char*)name, len), "symbol must be properly initialized"); + ++ // Check if the symbol table has been rehashed, if so, need to recalculate ++ // the hash value and index. ++ unsigned int hashValue; ++ int index; ++ if (use_alternate_hashcode()) { ++ hashValue = hash_symbol((const char*)name, len); ++ index = hash_to_index(hashValue); ++ } else { ++ hashValue = hashValue_arg; ++ index = index_arg; ++ } ++ + // Since look-up was done lock-free, we need to check if another + // thread beat us in the race to insert the symbol. + +@@ -201,48 +287,42 @@ + return sym(); + } + +-bool SymbolTable::basic_add(constantPoolHandle cp, int names_count, ++bool SymbolTable::basic_add(symbolHandle* syms, ++ constantPoolHandle cp, int names_count, + const char** names, int* lengths, + int* cp_indices, unsigned int* hashValues, + TRAPS) { +- symbolKlass* sk = (symbolKlass*) Universe::symbolKlassObj()->klass_part(); +- symbolOop sym_oops[symbol_alloc_batch_size]; +- bool allocated = sk->allocate_symbols(names_count, names, lengths, +- sym_oops, CHECK_false); +- if (!allocated) { +- return false; +- } +- symbolHandle syms[symbol_alloc_batch_size]; +- int i; +- for (i=0; i<names_count; i++) { +- syms[i] = symbolHandle(THREAD, sym_oops[i]); +- } ++ // Cannot hit a safepoint in this function because the "this" pointer can move. ++ No_Safepoint_Verifier nsv; + +- // Allocation must be done before grabbing the SymbolTable_lock lock +- MutexLocker ml(SymbolTable_lock, THREAD); +- +- for (i=0; i<names_count; i++) { ++ for (int i=0; i<names_count; i++) { + assert(syms[i]->equals(names[i], lengths[i]), "symbol must be properly initialized"); ++ // Check if the symbol table has been rehashed, if so, need to recalculate ++ // the hash value. ++ unsigned int hashValue; ++ if (use_alternate_hashcode()) { ++ hashValue = hash_symbol(names[i], lengths[i]); ++ } else { ++ hashValue = hashValues[i]; ++ } + // Since look-up was done lock-free, we need to check if another + // thread beat us in the race to insert the symbol. +- int index = hash_to_index(hashValues[i]); +- symbolOop test = lookup(index, names[i], lengths[i], hashValues[i]); ++ int index = hash_to_index(hashValue); ++ symbolOop test = lookup(index, names[i], lengths[i], hashValue); + if (test != NULL) { + // A race occurred and another thread introduced the symbol, this one + // will be dropped and collected. Use test instead. + cp->symbol_at_put(cp_indices[i], test); + } else { + symbolOop sym = syms[i](); +- HashtableEntry* entry = new_entry(hashValues[i], sym); ++ HashtableEntry* entry = new_entry(hashValue, sym); + add_entry(index, entry); + cp->symbol_at_put(cp_indices[i], sym); + } + } +- +- return true; ++ return true; // always returns true + } + +- + void SymbolTable::verify() { + for (int i = 0; i < the_table()->table_size(); ++i) { + HashtableEntry* p = the_table()->bucket(i); +@@ -251,7 +331,7 @@ + guarantee(s != NULL, "symbol is NULL"); + s->verify(); + guarantee(s->is_perm(), "symbol not in permspace"); +- unsigned int h = hash_symbol((char*)s->bytes(), s->utf8_length()); ++ unsigned int h = hash_symbol((const char*)s->bytes(), s->utf8_length()); + guarantee(p->hash() == h, "broken hash in symbol table entry"); + guarantee(the_table()->hash_to_index(h) == i, + "wrong index in symbol table"); +@@ -259,6 +339,23 @@ + } + } + ++void SymbolTable::dump(outputStream* st) { ++ NumberSeq summary; ++ for (int i = 0; i < the_table()->table_size(); ++i) { ++ int count = 0; ++ for (HashtableEntry* e = the_table()->bucket(i); ++ e != NULL; e = e->next()) { ++ count++; ++ } ++ summary.add((double)count); ++ } ++ st->print_cr("SymbolTable statistics:"); ++ st->print_cr("Number of buckets : %7d", summary.num()); ++ st->print_cr("Average bucket size : %7.0f", summary.avg()); ++ st->print_cr("Variance of bucket size : %7.0f", summary.variance()); ++ st->print_cr("Std. dev. of bucket size: %7.0f", summary.sd()); ++ st->print_cr("Maximum bucket size : %7.0f", summary.maximum()); ++} + + //--------------------------------------------------------------------------- + // Non-product code +@@ -321,7 +418,6 @@ + tty->print_cr(" %s %d: %d\n", "Number chains longer than", + results_length, out_of_range); + } +- + #endif // PRODUCT + + // -------------------------------------------------------------------------- +@@ -367,66 +463,56 @@ + // -------------------------------------------------------------------------- + + +-// Compute the hash value for a java.lang.String object which would +-// contain the characters passed in. This hash value is used for at +-// least two purposes. +-// +-// (a) As the hash value used by the StringTable for bucket selection +-// and comparison (stored in the HashtableEntry structures). This +-// is used in the String.intern() method. +-// +-// (b) As the hash value used by the String object itself, in +-// String.hashCode(). This value is normally calculate in Java code +-// in the String.hashCode method(), but is precomputed for String +-// objects in the shared archive file. +-// +-// For this reason, THIS ALGORITHM MUST MATCH String.hashCode(). ++StringTable* StringTable::_the_table = NULL; + +-int StringTable::hash_string(jchar* s, int len) { +- unsigned h = 0; +- while (len-- > 0) { +- h = 31*h + (unsigned) *s; +- s++; +- } +- return h; ++bool StringTable::_needs_rehashing = false; ++ ++// Pick hashing algorithm ++unsigned int StringTable::hash_string(const jchar* s, int len) { ++ return the_table()->use_alternate_hashcode() ? AltHashing::murmur3_32(the_table()->seed(), s, len) : ++ java_lang_String::to_hash(s, len); + } + +- +-StringTable* StringTable::_the_table = NULL; +- + oop StringTable::lookup(int index, jchar* name, + int len, unsigned int hash) { ++ int count = 0; + for (HashtableEntry* l = bucket(index); l != NULL; l = l->next()) { ++ count++; + if (l->hash() == hash) { + if (java_lang_String::equals(l->literal(), name, len)) { + return l->literal(); + } + } + } ++ // If the bucket size is too deep check if this hash code is insufficient. ++ if (count >= BasicHashtable::rehash_count && !needs_rehashing()) { ++ _needs_rehashing = check_rehash_table(count); ++ } + return NULL; + } + + +-oop StringTable::basic_add(int index, Handle string_or_null, jchar* name, +- int len, unsigned int hashValue, TRAPS) { +- debug_only(StableMemoryChecker smc(name, len * sizeof(name[0]))); +- assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(), +- "proposed name of symbol must be stable"); ++oop StringTable::basic_add(int index_arg, Handle string, jchar* name, ++ int len, unsigned int hashValue_arg, TRAPS) { + +- Handle string; +- // try to reuse the string if possible +- if (!string_or_null.is_null() && string_or_null()->is_perm()) { +- string = string_or_null; +- } else { +- string = java_lang_String::create_tenured_from_unicode(name, len, CHECK_NULL); +- } +- +- // Allocation must be done before grapping the SymbolTable_lock lock +- MutexLocker ml(StringTable_lock, THREAD); ++ // Cannot hit a safepoint in this function because the "this" pointer can move. ++ No_Safepoint_Verifier nsv; + + assert(java_lang_String::equals(string(), name, len), + "string must be properly initialized"); + ++ // Check if the symbol table has been rehashed, if so, need to recalculate ++ // the hash value and index before second lookup. ++ unsigned int hashValue; ++ int index; ++ if (use_alternate_hashcode()) { ++ hashValue = hash_string(name, len); ++ index = hash_to_index(hashValue); ++ } else { ++ hashValue = hashValue_arg; ++ index = index_arg; ++ } ++ + // Since look-up was done lock-free, we need to check if another + // thread beat us in the race to insert the symbol. + +@@ -456,13 +542,28 @@ + int len, TRAPS) { + unsigned int hashValue = hash_string(name, len); + int index = the_table()->hash_to_index(hashValue); +- oop string = the_table()->lookup(index, name, len, hashValue); ++ oop found_string = the_table()->lookup(index, name, len, hashValue); + + // Found +- if (string != NULL) return string; ++ if (found_string != NULL) return found_string; ++ ++ debug_only(StableMemoryChecker smc(name, len * sizeof(name[0]))); ++ assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(), ++ "proposed name of symbol must be stable"); ++ ++ Handle string; ++ // try to reuse the string if possible ++ if (!string_or_null.is_null() && string_or_null()->is_perm()) { ++ string = string_or_null; ++ } else { ++ string = java_lang_String::create_tenured_from_unicode(name, len, CHECK_NULL); ++ } ++ ++ // Allocation must be done before grabbing the StringTable_lock lock ++ MutexLocker ml(StringTable_lock, THREAD); + + // Otherwise, add to symbol to table +- return the_table()->basic_add(index, string_or_null, name, len, ++ return the_table()->basic_add(index, string, name, len, + hashValue, CHECK_NULL); + } + +@@ -517,3 +618,41 @@ + } + } + } ++ ++void StringTable::dump(outputStream* st) { ++ NumberSeq summary; ++ for (int i = 0; i < the_table()->table_size(); ++i) { ++ HashtableEntry* p = the_table()->bucket(i); ++ int count = 0; ++ for ( ; p != NULL; p = p->next()) { ++ count++; ++ } ++ summary.add((double)count); ++ } ++ st->print_cr("StringTable statistics:"); ++ st->print_cr("Number of buckets : %7d", summary.num()); ++ st->print_cr("Average bucket size : %7.0f", summary.avg()); ++ st->print_cr("Variance of bucket size : %7.0f", summary.variance()); ++ st->print_cr("Std. dev. of bucket size: %7.0f", summary.sd()); ++ st->print_cr("Maximum bucket size : %7.0f", summary.maximum()); ++} ++ ++ ++// Create a new table and using alternate hash code, populate the new table ++// with the existing strings. Set flag to use the alternate hash code afterwards. ++void StringTable::rehash_table() { ++ assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); ++ // This should never happen with -Xshare:dump but it might in testing mode. ++ if (DumpSharedSpaces) return; ++ StringTable* new_table = new StringTable(); ++ ++ // Rehash the table ++ the_table()->move_to(new_table); ++ ++ // Delete the table and buckets (entries are reused in new table). ++ delete _the_table; ++ // Don't check if we need rehashing until the table gets unbalanced again. ++ // Then rehash with a new global seed. ++ _needs_rehashing = false; ++ _the_table = new_table; ++} +diff --git a/src/share/vm/classfile/symbolTable.hpp b/src/share/vm/classfile/symbolTable.hpp +--- hotspot/src/share/vm/classfile/symbolTable.hpp ++++ hotspot/src/share/vm/classfile/symbolTable.hpp +@@ -40,6 +40,7 @@ + // - symbolTableEntrys are allocated in blocks to reduce the space overhead. + + class BoolObjectClosure; ++class outputStream; + + + class SymbolTable : public Hashtable { +@@ -49,10 +50,13 @@ + // The symbol table + static SymbolTable* _the_table; + ++ // Set if one bucket is out of balance due to hash algorithm deficiency ++ static bool _needs_rehashing; ++ + // Adding elements +- symbolOop basic_add(int index, u1* name, int len, ++ symbolOop basic_add(symbolHandle sym, int index, u1* name, int len, + unsigned int hashValue, TRAPS); +- bool basic_add(constantPoolHandle cp, int names_count, ++ bool basic_add(symbolHandle* syms, constantPoolHandle cp, int names_count, + const char** names, int* lengths, int* cp_indices, + unsigned int* hashValues, TRAPS); + +@@ -61,6 +65,8 @@ + symbol_table_size = 20011 + }; + ++ static unsigned int hash_symbol(const char* s, int len); ++ + symbolOop lookup(int index, const char* name, int len, unsigned int hash); + + SymbolTable() +@@ -70,7 +76,6 @@ + : Hashtable(symbol_table_size, sizeof (HashtableEntry), t, + number_of_entries) {} + +- + public: + enum { + symbol_alloc_batch_size = 8 +@@ -137,6 +142,7 @@ + + // Debugging + static void verify(); ++ static void dump(outputStream* st); + + // Sharing + static void copy_buckets(char** top, char*end) { +@@ -148,6 +154,10 @@ + static void reverse(void* boundary = NULL) { + ((Hashtable*)the_table())->reverse(boundary); + } ++ ++ // Rehash the symbol table if it gets out of balance ++ static void rehash_table(); ++ static bool needs_rehashing() { return _needs_rehashing; } + }; + + +@@ -158,8 +168,11 @@ + // The string table + static StringTable* _the_table; + ++ // Set if one bucket is out of balance due to hash algorithm deficiency ++ static bool _needs_rehashing; ++ + static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS); +- oop basic_add(int index, Handle string_or_null, jchar* name, int len, ++ oop basic_add(int index, Handle string, jchar* name, int len, + unsigned int hashValue, TRAPS); + + // Table size +@@ -192,10 +205,6 @@ + _the_table = new StringTable(t, number_of_entries); + } + +- +- static int hash_string(jchar* s, int len); +- +- + // GC support + // Delete pointers to otherwise-unreachable objects. + static void unlink(BoolObjectClosure* cl) { +@@ -207,6 +216,14 @@ + the_table()->Hashtable::oops_do(f); + } + ++ // Hashing algorithm, used as the hash value used by the ++ // StringTable for bucket selection and comparison (stored in the ++ // HashtableEntry structures). This is used in the String.intern() method. ++ static unsigned int hash_string(const jchar* s, int len); ++ ++ // Internal test. ++ static void test_alt_hash() PRODUCT_RETURN; ++ + // Probing + static oop lookup(symbolOop symbol); + +@@ -217,6 +234,7 @@ + + // Debugging + static void verify(); ++ static void dump(outputStream* st); + + // Sharing + static void copy_buckets(char** top, char*end) { +@@ -228,6 +246,9 @@ + static void reverse() { + ((BasicHashtable*)the_table())->reverse(); + } ++ ++ // Rehash the symbol table if it gets out of balance ++ static void rehash_table(); ++ static bool needs_rehashing() { return _needs_rehashing; } + }; +- + #endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP +diff --git a/src/share/vm/memory/dump.cpp b/src/share/vm/memory/dump.cpp +--- hotspot/src/share/vm/memory/dump.cpp ++++ hotspot/src/share/vm/memory/dump.cpp +@@ -62,8 +62,8 @@ + // written later, increasing the likelihood that the shared page contain + // the hash can be shared. + // +-// NOTE THAT the algorithm in StringTable::hash_string() MUST MATCH the +-// algorithm in java.lang.String.hashCode(). ++// NOTE THAT we have to call java_lang_String::to_hash() to match the ++// algorithm in java.lang.String.toHash(). + + class StringHashCodeClosure: public OopClosure { + private: +@@ -88,7 +88,7 @@ + } else { + int offset = java_lang_String::offset(obj); + jchar* s = value->char_at_addr(offset); +- hash = StringTable::hash_string(s, length); ++ hash = java_lang_String::to_hash(s, length); + } + obj->int_field_put(hash_offset, hash); + } +diff --git a/src/share/vm/runtime/globals.hpp b/src/share/vm/runtime/globals.hpp +--- hotspot/src/share/vm/runtime/globals.hpp ++++ hotspot/src/share/vm/runtime/globals.hpp +@@ -2511,6 +2511,9 @@ + product(bool, UseHeavyMonitors, false, \ + "use heavyweight instead of lightweight Java monitors") \ + \ ++ product(bool, PrintStringTableStatistics, false, \ ++ "print statistics about the StringTable and SymbolTable") \ ++ \ + notproduct(bool, PrintSymbolTableSizeHistogram, false, \ + "print histogram of the symbol table") \ + \ +diff --git a/src/share/vm/runtime/init.cpp b/src/share/vm/runtime/init.cpp +--- hotspot/src/share/vm/runtime/init.cpp ++++ hotspot/src/share/vm/runtime/init.cpp +@@ -23,6 +23,7 @@ + */ + + #include "precompiled.hpp" ++#include "classfile/symbolTable.hpp" + #include "code/icBuffer.hpp" + #include "gc_interface/collectedHeap.hpp" + #include "interpreter/bytecodes.hpp" +@@ -153,6 +154,10 @@ + // Print the collected safepoint statistics. + SafepointSynchronize::print_stat_on_exit(); + } ++ if (PrintStringTableStatistics) { ++ SymbolTable::dump(tty); ++ StringTable::dump(tty); ++ } + ostream_exit(); + } + } +diff --git a/src/share/vm/runtime/safepoint.cpp b/src/share/vm/runtime/safepoint.cpp +--- hotspot/src/share/vm/runtime/safepoint.cpp ++++ hotspot/src/share/vm/runtime/safepoint.cpp +@@ -23,6 +23,7 @@ + */ + + #include "precompiled.hpp" ++#include "classfile/symbolTable.hpp" + #include "classfile/systemDictionary.hpp" + #include "code/codeCache.hpp" + #include "code/icBuffer.hpp" +@@ -501,8 +502,20 @@ + CompilationPolicy::policy()->do_safepoint_work(); + } + +- TraceTime t4("sweeping nmethods", TraceSafepointCleanupTime); +- NMethodSweeper::scan_stacks(); ++ { ++ TraceTime t4("sweeping nmethods", TraceSafepointCleanupTime); ++ NMethodSweeper::scan_stacks(); ++ } ++ ++ if (SymbolTable::needs_rehashing()) { ++ TraceTime t5("rehashing symbol table", TraceSafepointCleanupTime); ++ SymbolTable::rehash_table(); ++ } ++ ++ if (StringTable::needs_rehashing()) { ++ TraceTime t6("rehashing string table", TraceSafepointCleanupTime); ++ StringTable::rehash_table(); ++ } + } + + +diff --git a/src/share/vm/utilities/hashtable.cpp b/src/share/vm/utilities/hashtable.cpp +--- hotspot/src/share/vm/utilities/hashtable.cpp ++++ hotspot/src/share/vm/utilities/hashtable.cpp +@@ -1,5 +1,4 @@ +-/* +- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. ++/* * 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 +@@ -23,7 +22,10 @@ + */ + + #include "precompiled.hpp" ++#include "classfile/altHashing.hpp" ++#include "classfile/javaClasses.hpp" + #include "memory/allocation.inline.hpp" ++#include "memory/filemap.hpp" + #include "memory/resourceArea.hpp" + #include "oops/oop.inline.hpp" + #include "runtime/safepoint.hpp" +@@ -69,7 +71,6 @@ + + HashtableEntry* Hashtable::new_entry(unsigned int hashValue, oop obj) { + HashtableEntry* entry; +- + entry = (HashtableEntry*)BasicHashtable::new_entry(hashValue); + entry->set_literal(obj); // clears literal string field + HS_DTRACE_PROBE4(hs_private, hashtable__new_entry, +@@ -85,18 +86,24 @@ + // entries at a safepoint. + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); + for (int i = 0; i < table_size(); ++i) { +- for (HashtableEntry** p = bucket_addr(i); *p != NULL; ) { +- HashtableEntry* entry = *p; +- if (entry->is_shared()) { ++ HashtableEntry** p = bucket_addr(i); ++ HashtableEntry* entry = bucket(i); ++ while (entry != NULL) { ++ // Shared entries are normally at the end of the bucket and if we run into ++ // a shared entry, then there is nothing more to remove. However, if we ++ // have rehashed the table, then the shared entries are no longer at the ++ // end of the bucket. ++ if (entry->is_shared() && !use_alternate_hashcode()) { + break; + } + assert(entry->literal() != NULL, "just checking"); +- if (is_alive->do_object_b(entry->literal())) { ++ if (entry->is_shared() || is_alive->do_object_b(entry->literal())) { + p = entry->next_addr(); + } else { + *p = entry->next(); + free_entry(entry); + } ++ entry = (HashtableEntry*)HashtableEntry::make_ptr(*p); + } + } + } +@@ -123,6 +130,96 @@ + } + + ++// Check to see if the hashtable is unbalanced. The caller set a flag to ++// rehash at the next safepoint. If this bucket is 60 times greater than the ++// expected average bucket length, it's an unbalanced hashtable. ++// This is somewhat an arbitrary heuristic but if one bucket gets to ++// rehash_count which is currently 100, there's probably something wrong. ++ ++bool BasicHashtable::check_rehash_table(int count) { ++ assert(table_size() != 0, "underflow"); ++ if (count > (((double)number_of_entries()/(double)table_size())*rehash_multiple)) { ++ // Set a flag for the next safepoint, which should be at some guaranteed ++ // safepoint interval. ++ return true; ++ } ++ return false; ++} ++ ++unsigned int Hashtable::new_hash(oop string) { ++ ResourceMark rm; ++ int length; ++ if (java_lang_String::is_instance(string)) { ++ jchar* chars = java_lang_String::as_unicode_string(string, length); ++ // Use alternate hashing algorithm on the string ++ return AltHashing::murmur3_32(seed(), chars, length); ++ } else { ++ // Use alternate hashing algorithm on this symbol. ++ symbolOop symOop = (symbolOop) string; ++ return AltHashing::murmur3_32(seed(), (const jbyte*)symOop->bytes(), symOop->utf8_length()); ++ } ++} ++ ++// Create a new table and using alternate hash code, populate the new table ++// with the existing elements. This can be used to change the hash code ++// and could in the future change the size of the table. ++ ++void Hashtable::move_to(Hashtable* new_table) { ++ // Initialize the global seed for hashing. ++ assert(new_table->seed() == 0, "should be zero"); ++ _seed = AltHashing::compute_seed(); ++ assert(seed() != 0, "shouldn't be zero"); ++ new_table->set_seed(_seed); ++ ++ int saved_entry_count = this->number_of_entries(); ++ ++ // Iterate through the table and create a new entry for the new table ++ for (int i = 0; i < new_table->table_size(); ++i) { ++ for (HashtableEntry* p = bucket(i); p != NULL; ) { ++ HashtableEntry* next = p->next(); ++ oop string = p->literal(); ++ // Use alternate hashing algorithm on the symbol in the first table ++ unsigned int hashValue = new_hash(string); ++ // Get a new index relative to the new table (can also change size) ++ int index = new_table->hash_to_index(hashValue); ++ p->set_hash(hashValue); ++ // Keep the shared bit in the Hashtable entry to indicate that this entry ++ // can't be deleted. The shared bit is the LSB in the _next field so ++ // walking the hashtable past these entries requires ++ // BasicHashtableEntry::make_ptr() call. ++ bool keep_shared = p->is_shared(); ++ unlink_entry(p); ++ new_table->add_entry(index, p); ++ if (keep_shared) { ++ p->set_shared(); ++ } ++ p = next; ++ } ++ } ++ // give the new table the free list as well ++ new_table->copy_freelist(this); ++ assert(new_table->number_of_entries() == saved_entry_count, "lost entry on dictionary copy?"); ++ ++ // Destroy memory used by the buckets in the hashtable. The memory ++ // for the elements has been used in a new table and is not ++ // destroyed. The memory reuse will benefit resizing the SystemDictionary ++ // to avoid a memory allocation spike at safepoint. ++ free_buckets(); ++} ++ ++void BasicHashtable::free_buckets() { ++ if (NULL != _buckets) { ++ // Don't delete the buckets in the shared space. They aren't ++ // allocated by os::malloc ++ if (!UseSharedSpaces || ++ !FileMapInfo::current_info()->is_in_shared_space(_buckets)) { ++ FREE_C_HEAP_ARRAY(HashtableBucket, _buckets); ++ } ++ _buckets = NULL; ++ } ++} ++ ++ + // Reverse the order of elements in the hash buckets. + + void BasicHashtable::reverse() { +diff --git a/src/share/vm/utilities/hashtable.hpp b/src/share/vm/utilities/hashtable.hpp +--- hotspot/src/share/vm/utilities/hashtable.hpp ++++ hotspot/src/share/vm/utilities/hashtable.hpp +@@ -177,6 +177,11 @@ + void verify_lookup_length(double load); + #endif + ++ enum { ++ rehash_count = 100, ++ rehash_multiple = 60 ++ }; ++ + void initialize(int table_size, int entry_size, int number_of_entries); + + // Accessor +@@ -192,6 +197,29 @@ + // Table entry management + BasicHashtableEntry* new_entry(unsigned int hashValue); + ++ // Check that the table is unbalanced ++ bool check_rehash_table(int count); ++ ++ // Used when moving the entry to another table ++ // Clean up links, but do not add to free_list ++ void unlink_entry(BasicHashtableEntry* entry) { ++ entry->set_next(NULL); ++ --_number_of_entries; ++ } ++ ++ // Move over freelist and free block for allocation ++ void copy_freelist(BasicHashtable* src) { ++ _free_list = src->_free_list; ++ src->_free_list = NULL; ++ _first_free_entry = src->_first_free_entry; ++ src->_first_free_entry = NULL; ++ _end_block = src->_end_block; ++ src->_end_block = NULL; ++ } ++ ++ // Free the buckets in this hashtable ++ void free_buckets(); ++ + public: + void set_entry(int index, BasicHashtableEntry* entry); + +@@ -210,11 +238,11 @@ + + public: + Hashtable(int table_size, int entry_size) +- : BasicHashtable(table_size, entry_size) { } ++ : BasicHashtable(table_size, entry_size), _seed(0) { } + + Hashtable(int table_size, int entry_size, + HashtableBucket* buckets, int number_of_entries) +- : BasicHashtable(table_size, entry_size, buckets, number_of_entries) { } ++ : BasicHashtable(table_size, entry_size, buckets, number_of_entries), _seed(0) { } + + // Invoke "f->do_oop" on the locations of all oops in the table. + void oops_do(OopClosure* f); +@@ -234,8 +262,6 @@ + + protected: + +- static unsigned int hash_symbol(const char* s, int len); +- + unsigned int compute_hash(symbolHandle name) { + return (unsigned int) name->identity_hash(); + } +@@ -256,6 +282,17 @@ + HashtableEntry** bucket_addr(int i) { + return (HashtableEntry**)BasicHashtable::bucket_addr(i); + } ++ ++ // Function to move these elements into the new table. ++ void move_to(Hashtable* new_table); ++ bool use_alternate_hashcode() { return _seed != 0; } ++ jint seed() { return _seed; } ++ void set_seed(jint seed) { _seed = seed; } ++ ++ private: ++ jint _seed; ++ ++ unsigned int new_hash(oop string); + }; + + +diff --git a/src/share/vm/utilities/hashtable.inline.hpp b/src/share/vm/utilities/hashtable.inline.hpp +--- hotspot/src/share/vm/utilities/hashtable.inline.hpp ++++ hotspot/src/share/vm/utilities/hashtable.inline.hpp +@@ -30,27 +30,6 @@ + + // Inline function definitions for hashtable.hpp. + +- +-// -------------------------------------------------------------------------- +-// Hash function +- +-// We originally used hashpjw, but hash P(31) gives just as good results +-// and is slighly faster. We would like a hash function that looks at every +-// character, since package names have large common prefixes, and also because +-// hash_or_fail does error checking while iterating. +- +-// hash P(31) from Kernighan & Ritchie +- +-inline unsigned int Hashtable::hash_symbol(const char* s, int len) { +- unsigned int h = 0; +- while (len-- > 0) { +- h = 31*h + (unsigned) *s; +- s++; +- } +- return h; +-} +- +- + // -------------------------------------------------------------------------- + + // Initialize a table. diff --git a/java/openjdk6/files/icedtea/security/7158801.patch b/java/openjdk6/files/icedtea/security/7158801.patch new file mode 100644 index 000000000000..91d1464eafbd --- /dev/null +++ b/java/openjdk6/files/icedtea/security/7158801.patch @@ -0,0 +1,30 @@ +# HG changeset patch +# User kvn +# Date 1337800285 25200 +# Node ID f7493d50b47d3946902e18153bcd912e37589d00 +# Parent 2faa3f7bad65189e69ab2f9a491743786bb8f07f +7158801: Improve VM CompileOnly option +Summary: Fixed buffer overflow during parsing flags -XX:CompileCommand=, -XX:CompileOnly= and command lines in .hotspot_compiler file. +Reviewed-by: never + +diff --git a/src/share/vm/compiler/compilerOracle.cpp b/src/share/vm/compiler/compilerOracle.cpp +--- hotspot/src/share/vm/compiler/compilerOracle.cpp ++++ hotspot/src/share/vm/compiler/compilerOracle.cpp +@@ -573,7 +573,7 @@ + char token[1024]; + int pos = 0; + int c = getc(stream); +- while(c != EOF) { ++ while(c != EOF && pos < (sizeof(token)-1)) { + if (c == '\n') { + token[pos++] = '\0'; + parse_from_line(token); +@@ -594,7 +594,7 @@ + int pos = 0; + const char* sp = str; + int c = *sp++; +- while (c != '\0') { ++ while (c != '\0' && pos < (sizeof(token)-1)) { + if (c == '\n') { + token[pos++] = '\0'; + parse_line(token); diff --git a/java/openjdk6/files/icedtea/security/7158804.patch b/java/openjdk6/files/icedtea/security/7158804.patch new file mode 100644 index 000000000000..318a1aa572db --- /dev/null +++ b/java/openjdk6/files/icedtea/security/7158804.patch @@ -0,0 +1,28 @@ +# HG changeset patch +# User dbuck +# Date 1342799006 25200 +# Node ID fde4cc8479824449b03abedd5357500aec92e990 +# Parent f7493d50b47d3946902e18153bcd912e37589d00 +7158804: Improve config file parsing +Summary: see bugdb 13784108 for details +Reviewed-by: vikram, kamg + +diff --git a/src/share/vm/runtime/arguments.cpp b/src/share/vm/runtime/arguments.cpp +--- hotspot/src/share/vm/runtime/arguments.cpp ++++ hotspot/src/share/vm/runtime/arguments.cpp +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1997, 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 +@@ -842,7 +842,7 @@ + bool result = true; + + int c = getc(stream); +- while(c != EOF) { ++ while(c != EOF && pos < (int)(sizeof(token)-1)) { + if (in_white_space) { + if (in_comment) { + if (c == '\n') in_comment = false; diff --git a/java/openjdk6/files/icedtea/security/7167656.patch b/java/openjdk6/files/icedtea/security/7167656.patch new file mode 100644 index 000000000000..105fe0140587 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/7167656.patch @@ -0,0 +1,75 @@ +# HG changeset patch +# User coffeys +# Date 1340139680 -3600 +# Node ID d04575148db287475168da344159e583f7bff02c +# Parent 1e170e3c1b682d0f98a61a47e5049535c5bd4999 +7167656: Multiple Seeders are being created +Reviewed-by: wetmore + +diff --git a/src/share/classes/sun/security/provider/SecureRandom.java b/src/share/classes/sun/security/provider/SecureRandom.java +--- jdk/src/share/classes/sun/security/provider/SecureRandom.java ++++ jdk/src/share/classes/sun/security/provider/SecureRandom.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1998, 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 +@@ -56,12 +56,6 @@ + + private static final long serialVersionUID = 3581829991155417889L; + +- /** +- * This static object will be seeded by SeedGenerator, and used +- * to seed future instances of SecureRandom +- */ +- private static SecureRandom seeder; +- + private static final int DIGEST_SIZE = 20; + private transient MessageDigest digest; + private byte[] state; +@@ -173,6 +167,28 @@ + } + + /** ++ * This static object will be seeded by SeedGenerator, and used ++ * to seed future instances of SHA1PRNG SecureRandoms. ++ * ++ * Bloch, Effective Java Second Edition: Item 71 ++ */ ++ private static class SeederHolder { ++ ++ private static final SecureRandom seeder; ++ ++ static { ++ /* ++ * Call to SeedGenerator.generateSeed() to add additional ++ * seed material (likely from the Native implementation). ++ */ ++ seeder = new SecureRandom(SeedGenerator.getSystemEntropy()); ++ byte [] b = new byte[DIGEST_SIZE]; ++ SeedGenerator.generateSeed(b); ++ seeder.engineSetSeed(b); ++ } ++ } ++ ++ /** + * Generates a user-specified number of random bytes. + * + * @param bytes the array to be filled in with random bytes. +@@ -183,13 +199,8 @@ + byte[] output = remainder; + + if (state == null) { +- if (seeder == null) { +- seeder = new SecureRandom(SeedGenerator.getSystemEntropy()); +- seeder.engineSetSeed(engineGenerateSeed(DIGEST_SIZE)); +- } +- + byte[] seed = new byte[DIGEST_SIZE]; +- seeder.engineNextBytes(seed); ++ SeederHolder.seeder.engineNextBytes(seed); + state = digest.digest(seed); + } + diff --git a/java/openjdk6/files/icedtea/security/7169884.patch b/java/openjdk6/files/icedtea/security/7169884.patch new file mode 100644 index 000000000000..e0f023038ade --- /dev/null +++ b/java/openjdk6/files/icedtea/security/7169884.patch @@ -0,0 +1,349 @@ +# HG changeset patch +# User robm +# Date 1347903606 -3600 +# Node ID 47e7c8e33cd82dade3e84af94bff125cdbdae062 +# Parent d04575148db287475168da344159e583f7bff02c +7169884: LogManager checks do not work correctly for sub-types +Reviewed-by: alanb + +diff --git a/src/share/classes/java/util/logging/FileHandler.java b/src/share/classes/java/util/logging/FileHandler.java +--- jdk/src/share/classes/java/util/logging/FileHandler.java ++++ jdk/src/share/classes/java/util/logging/FileHandler.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2000, 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 +@@ -220,7 +220,7 @@ + * @exception NullPointerException if pattern property is an empty String. + */ + public FileHandler() throws IOException, SecurityException { +- checkAccess(); ++ checkPermission(); + configure(); + openFiles(); + } +@@ -246,7 +246,7 @@ + if (pattern.length() < 1 ) { + throw new IllegalArgumentException(); + } +- checkAccess(); ++ checkPermission(); + configure(); + this.pattern = pattern; + this.limit = 0; +@@ -278,7 +278,7 @@ + if (pattern.length() < 1 ) { + throw new IllegalArgumentException(); + } +- checkAccess(); ++ checkPermission(); + configure(); + this.pattern = pattern; + this.limit = 0; +@@ -315,7 +315,7 @@ + if (limit < 0 || count < 1 || pattern.length() < 1) { + throw new IllegalArgumentException(); + } +- checkAccess(); ++ checkPermission(); + configure(); + this.pattern = pattern; + this.limit = limit; +@@ -354,7 +354,7 @@ + if (limit < 0 || count < 1 || pattern.length() < 1) { + throw new IllegalArgumentException(); + } +- checkAccess(); ++ checkPermission(); + configure(); + this.pattern = pattern; + this.limit = limit; +@@ -367,7 +367,7 @@ + // configured instance variables. + private void openFiles() throws IOException { + LogManager manager = LogManager.getLogManager(); +- manager.checkAccess(); ++ manager.checkPermission(); + if (count < 1) { + throw new IllegalArgumentException("file count = " + count); + } +diff --git a/src/share/classes/java/util/logging/Handler.java b/src/share/classes/java/util/logging/Handler.java +--- jdk/src/share/classes/java/util/logging/Handler.java ++++ jdk/src/share/classes/java/util/logging/Handler.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2000, 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 +@@ -111,7 +111,7 @@ + * the caller does not have <tt>LoggingPermission("control")</tt>. + */ + public void setFormatter(Formatter newFormatter) throws SecurityException { +- checkAccess(); ++ checkPermission(); + // Check for a null pointer: + newFormatter.getClass(); + formatter = newFormatter; +@@ -140,7 +140,7 @@ + */ + public void setEncoding(String encoding) + throws SecurityException, java.io.UnsupportedEncodingException { +- checkAccess(); ++ checkPermission(); + if (encoding != null) { + try { + if(!java.nio.charset.Charset.isSupported(encoding)) { +@@ -175,7 +175,7 @@ + * the caller does not have <tt>LoggingPermission("control")</tt>. + */ + public void setFilter(Filter newFilter) throws SecurityException { +- checkAccess(); ++ checkPermission(); + filter = newFilter; + } + +@@ -199,7 +199,7 @@ + * the caller does not have <tt>LoggingPermission("control")</tt>. + */ + public void setErrorManager(ErrorManager em) { +- checkAccess(); ++ checkPermission(); + if (em == null) { + throw new NullPointerException(); + } +@@ -213,7 +213,7 @@ + * the caller does not have <tt>LoggingPermission("control")</tt>. + */ + public ErrorManager getErrorManager() { +- checkAccess(); ++ checkPermission(); + return errorManager; + } + +@@ -253,7 +253,7 @@ + if (newLevel == null) { + throw new NullPointerException(); + } +- checkAccess(); ++ checkPermission(); + logLevel = newLevel; + } + +@@ -296,9 +296,9 @@ + // If "sealed" is true, we check that the caller has + // appropriate security privileges to update Handler + // state and if not throw a SecurityException. +- void checkAccess() throws SecurityException { ++ void checkPermission() throws SecurityException { + if (sealed) { +- manager.checkAccess(); ++ manager.checkPermission(); + } + } + } +diff --git a/src/share/classes/java/util/logging/LogManager.java b/src/share/classes/java/util/logging/LogManager.java +--- jdk/src/share/classes/java/util/logging/LogManager.java ++++ jdk/src/share/classes/java/util/logging/LogManager.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2000, 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 +@@ -303,7 +303,7 @@ + if (l == null) { + throw new NullPointerException(); + } +- checkAccess(); ++ checkPermission(); + changes.addPropertyChangeListener(l); + } + +@@ -322,7 +322,7 @@ + * the caller does not have LoggingPermission("control"). + */ + public void removePropertyChangeListener(PropertyChangeListener l) throws SecurityException { +- checkAccess(); ++ checkPermission(); + changes.removePropertyChangeListener(l); + } + +@@ -740,7 +740,7 @@ + * @exception IOException if there are IO problems reading the configuration. + */ + public void readConfiguration() throws IOException, SecurityException { +- checkAccess(); ++ checkPermission(); + + // if a configuration class is specified, load it and use it. + String cname = System.getProperty("java.util.logging.config.class"); +@@ -798,7 +798,7 @@ + */ + + public void reset() throws SecurityException { +- checkAccess(); ++ checkPermission(); + synchronized (this) { + props = new Properties(); + // Since we are doing a reset we no longer want to initialize +@@ -883,7 +883,7 @@ + * @exception IOException if there are problems reading from the stream. + */ + public void readConfiguration(InputStream ins) throws IOException, SecurityException { +- checkAccess(); ++ checkPermission(); + reset(); + + // Load the properties +@@ -1045,7 +1045,13 @@ + } + + +- private Permission ourPermission = new LoggingPermission("control", null); ++ private final Permission controlPermission = new LoggingPermission("control", null); ++ ++ void checkPermission() { ++ SecurityManager sm = System.getSecurityManager(); ++ if (sm != null) ++ sm.checkPermission(controlPermission); ++ } + + /** + * Check that the current context is trusted to modify the logging +@@ -1058,11 +1064,7 @@ + * the caller does not have LoggingPermission("control"). + */ + public void checkAccess() throws SecurityException { +- SecurityManager sm = System.getSecurityManager(); +- if (sm == null) { +- return; +- } +- sm.checkPermission(ourPermission); ++ checkPermission(); + } + + // Nested class to represent a node in our tree of named loggers. +diff --git a/src/share/classes/java/util/logging/Logger.java b/src/share/classes/java/util/logging/Logger.java +--- jdk/src/share/classes/java/util/logging/Logger.java ++++ jdk/src/share/classes/java/util/logging/Logger.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2000, 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 +@@ -266,13 +266,13 @@ + this.manager = manager; + } + +- private void checkAccess() throws SecurityException { ++ private void checkPermission() throws SecurityException { + if (!anonymous) { + if (manager == null) { + // Complete initialization of the global Logger. + manager = LogManager.getLogManager(); + } +- manager.checkAccess(); ++ manager.checkPermission(); + } + } + +@@ -454,7 +454,7 @@ + * the caller does not have LoggingPermission("control"). + */ + public synchronized void setFilter(Filter newFilter) throws SecurityException { +- checkAccess(); ++ checkPermission(); + filter = newFilter; + } + +@@ -1145,7 +1145,7 @@ + * the caller does not have LoggingPermission("control"). + */ + public void setLevel(Level newLevel) throws SecurityException { +- checkAccess(); ++ checkPermission(); + synchronized (treeLock) { + levelObject = newLevel; + updateEffectiveLevel(); +@@ -1200,7 +1200,7 @@ + public synchronized void addHandler(Handler handler) throws SecurityException { + // Check for null handler + handler.getClass(); +- checkAccess(); ++ checkPermission(); + if (handlers == null) { + handlers = new ArrayList<Handler>(); + } +@@ -1217,7 +1217,7 @@ + * the caller does not have LoggingPermission("control"). + */ + public synchronized void removeHandler(Handler handler) throws SecurityException { +- checkAccess(); ++ checkPermission(); + if (handler == null) { + return; + } +@@ -1251,7 +1251,7 @@ + * the caller does not have LoggingPermission("control"). + */ + public synchronized void setUseParentHandlers(boolean useParentHandlers) { +- checkAccess(); ++ checkPermission(); + this.useParentHandlers = useParentHandlers; + } + +@@ -1388,7 +1388,7 @@ + if (parent == null) { + throw new NullPointerException(); + } +- manager.checkAccess(); ++ manager.checkPermission(); + doSetParent(parent); + } + +diff --git a/src/share/classes/java/util/logging/MemoryHandler.java b/src/share/classes/java/util/logging/MemoryHandler.java +--- jdk/src/share/classes/java/util/logging/MemoryHandler.java ++++ jdk/src/share/classes/java/util/logging/MemoryHandler.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2000, 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 +@@ -238,7 +238,7 @@ + throw new NullPointerException(); + } + LogManager manager = LogManager.getLogManager(); +- checkAccess(); ++ checkPermission(); + pushLevel = newLevel; + } + +diff --git a/src/share/classes/java/util/logging/StreamHandler.java b/src/share/classes/java/util/logging/StreamHandler.java +--- jdk/src/share/classes/java/util/logging/StreamHandler.java ++++ jdk/src/share/classes/java/util/logging/StreamHandler.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2000, 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 +@@ -249,7 +249,7 @@ + } + + private synchronized void flushAndClose() throws SecurityException { +- checkAccess(); ++ checkPermission(); + if (writer != null) { + try { + if (!doneHeader) { diff --git a/java/openjdk6/files/icedtea/security/7169888.patch b/java/openjdk6/files/icedtea/security/7169888.patch new file mode 100644 index 000000000000..537648fc2ae8 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/7169888.patch @@ -0,0 +1,125 @@ +# HG changeset patch +# User dbuck +# Date 1342799616 25200 +# Node ID 39b599e90c7b33435ca42ae96ed673812a8be3d7 +# Parent 47e7c8e33cd82dade3e84af94bff125cdbdae062 +7169888: Narrowing resource definitions in JMX RMI connector +Summary: see bugdb 13932219 for details +Reviewed-by: fparain, vikram + +diff --git a/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java b/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java +--- jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java ++++ jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2002, 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 +@@ -39,11 +39,17 @@ + import java.rmi.MarshalledObject; + import java.rmi.UnmarshalException; + import java.rmi.server.Unreferenced; ++ + import java.security.AccessControlContext; + import java.security.AccessController; ++import java.security.Permission; ++import java.security.PermissionCollection; ++import java.security.Permissions; + import java.security.PrivilegedAction; + import java.security.PrivilegedActionException; + import java.security.PrivilegedExceptionAction; ++import java.security.ProtectionDomain; ++ + import java.util.Arrays; + import java.util.Collections; + import java.util.Map; +@@ -60,6 +66,7 @@ + import javax.management.MBeanException; + import javax.management.MBeanInfo; + import javax.management.MBeanRegistrationException; ++import javax.management.MBeanPermission; + import javax.management.MBeanServer; + import javax.management.NotCompliantMBeanException; + import javax.management.NotificationFilter; +@@ -144,15 +151,20 @@ + this.mbeanServer = rmiServer.getMBeanServer(); + + final ClassLoader dcl = defaultClassLoader; ++ + this.classLoaderWithRepository = + AccessController.doPrivileged( + new PrivilegedAction<ClassLoaderWithRepository>() { + public ClassLoaderWithRepository run() { + return new ClassLoaderWithRepository( +- getClassLoaderRepository(), ++ mbeanServer.getClassLoaderRepository(), + dcl); + } +- }); ++ }, ++ ++ withPermissions( new MBeanPermission("*", "getClassLoaderRepository"), ++ new RuntimePermission("createClassLoader")) ++ ); + + serverCommunicatorAdmin = new + RMIServerCommunicatorAdmin(EnvHelp.getServerConnectionTimeout(env)); +@@ -160,6 +172,17 @@ + this.env = env; + } + ++ private static AccessControlContext withPermissions(Permission ... perms){ ++ Permissions col = new Permissions(); ++ ++ for (Permission thePerm : perms ) { ++ col.add(thePerm); ++ } ++ ++ final ProtectionDomain pd = new ProtectionDomain(null, col); ++ return new AccessControlContext( new ProtectionDomain[] { pd }); ++ } ++ + private synchronized ServerNotifForwarder getServerNotifFwd() { + // Lazily created when first use. Mainly when + // addNotificationListener is first called. +@@ -1314,16 +1337,6 @@ + // private methods + //------------------------------------------------------------------------ + +- private ClassLoaderRepository getClassLoaderRepository() { +- return +- AccessController.doPrivileged( +- new PrivilegedAction<ClassLoaderRepository>() { +- public ClassLoaderRepository run() { +- return mbeanServer.getClassLoaderRepository(); +- } +- }); +- } +- + private ClassLoader getClassLoader(final ObjectName name) + throws InstanceNotFoundException { + try { +@@ -1333,7 +1346,9 @@ + public ClassLoader run() throws InstanceNotFoundException { + return mbeanServer.getClassLoader(name); + } +- }); ++ }, ++ withPermissions(new MBeanPermission("*", "getClassLoader")) ++ ); + } catch (PrivilegedActionException pe) { + throw (InstanceNotFoundException) extractException(pe); + } +@@ -1348,7 +1363,9 @@ + public Object run() throws InstanceNotFoundException { + return mbeanServer.getClassLoaderFor(name); + } +- }); ++ }, ++ withPermissions(new MBeanPermission("*", "getClassLoaderFor")) ++ ); + } catch (PrivilegedActionException pe) { + throw (InstanceNotFoundException) extractException(pe); + } diff --git a/java/openjdk6/files/icedtea/security/7172522.patch b/java/openjdk6/files/icedtea/security/7172522.patch new file mode 100644 index 000000000000..74c1aceacf59 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/7172522.patch @@ -0,0 +1,36 @@ +# HG changeset patch +# User coffeys +# Date 1340096399 -3600 +# Node ID 88243aa6e67b6b84ff529ccdfd3b476410f60057 +# Parent 39b599e90c7b33435ca42ae96ed673812a8be3d7 +7172522: Improve DomainCombiner checking +Reviewed-by: mullan + +diff --git a/src/share/classes/java/security/AccessController.java b/src/share/classes/java/security/AccessController.java +--- jdk/src/share/classes/java/security/AccessController.java ++++ jdk/src/share/classes/java/security/AccessController.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1997, 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 +@@ -293,7 +293,7 @@ + DomainCombiner dc = null; + AccessControlContext acc = getStackAccessControlContext(); + if (acc == null || (dc = acc.getAssignedCombiner()) == null) { +- return AccessController.doPrivileged(action); ++ return AccessController.doPrivileged(action, acc); + } + return AccessController.doPrivileged(action, preserveCombiner(dc)); + } +@@ -389,7 +389,7 @@ + DomainCombiner dc = null; + AccessControlContext acc = getStackAccessControlContext(); + if (acc == null || (dc = acc.getAssignedCombiner()) == null) { +- return AccessController.doPrivileged(action); ++ return AccessController.doPrivileged(action, acc); + } + return AccessController.doPrivileged(action, preserveCombiner(dc)); + } diff --git a/java/openjdk6/files/icedtea/security/7176337.patch b/java/openjdk6/files/icedtea/security/7176337.patch new file mode 100644 index 000000000000..c323d4155ee2 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/7176337.patch @@ -0,0 +1,29 @@ +# HG changeset patch +# User asaha +# Date 1340145914 25200 +# Node ID a148157cd348fe4c251063db7d3973a83cfcf483 +# Parent fde4cc8479824449b03abedd5357500aec92e990 +7176337: Additional changes needed for 7158801 fix +Reviewed-by: kvn + +diff --git a/src/share/vm/compiler/compilerOracle.cpp b/src/share/vm/compiler/compilerOracle.cpp +--- hotspot/src/share/vm/compiler/compilerOracle.cpp ++++ hotspot/src/share/vm/compiler/compilerOracle.cpp +@@ -573,7 +573,7 @@ + char token[1024]; + int pos = 0; + int c = getc(stream); +- while(c != EOF && pos < (sizeof(token)-1)) { ++ while(c != EOF && pos < (int)(sizeof(token)-1)) { + if (c == '\n') { + token[pos++] = '\0'; + parse_from_line(token); +@@ -594,7 +594,7 @@ + int pos = 0; + const char* sp = str; + int c = *sp++; +- while (c != '\0' && pos < (sizeof(token)-1)) { ++ while (c != '\0' && pos < (int)(sizeof(token)-1)) { + if (c == '\n') { + token[pos++] = '\0'; + parse_line(token); diff --git a/java/openjdk6/files/icedtea/security/7186286.patch b/java/openjdk6/files/icedtea/security/7186286.patch new file mode 100644 index 000000000000..cc5adc1a3cf9 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/7186286.patch @@ -0,0 +1,552 @@ +# HG changeset patch +# User xuelei +# Date 1343546404 25200 +# Node ID a6294da5a21f609b67a0d4d216028dda9f56e689 +# Parent 88243aa6e67b6b84ff529ccdfd3b476410f60057 +7186286: TLS implementation to better adhere to RFC +Summary: also reviewed by Alexander Fomin <Alexander.Fomin@Oracle.COM>, Andrew Gross<Andrew.Gross@Oracle.COM>, Sean Coffey<Sean.Coffey@Oracle.COM> +Reviewed-by: valeriep, wetmore + +diff --git a/src/share/classes/sun/security/pkcs11/P11Cipher.java b/src/share/classes/sun/security/pkcs11/P11Cipher.java +--- jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java ++++ jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. ++ * 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 +@@ -650,7 +650,7 @@ + // see JCE spec + protected int engineGetKeySize(Key key) throws InvalidKeyException { + int n = P11SecretKeyFactory.convertKey +- (token, key, keyAlgorithm).keyLength(); ++ (token, key, keyAlgorithm).length(); + return n; + } + } +diff --git a/src/share/classes/sun/security/pkcs11/P11Key.java b/src/share/classes/sun/security/pkcs11/P11Key.java +--- jdk/src/share/classes/sun/security/pkcs11/P11Key.java ++++ jdk/src/share/classes/sun/security/pkcs11/P11Key.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. ++ * 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 +@@ -46,6 +46,7 @@ + import static sun.security.pkcs11.wrapper.PKCS11Constants.*; + + import sun.security.util.DerValue; ++import sun.security.util.Length; + + /** + * Key implementation classes. +@@ -61,7 +62,7 @@ + * @author Andreas Sterbenz + * @since 1.5 + */ +-abstract class P11Key implements Key { ++abstract class P11Key implements Key, Length { + + private final static String PUBLIC = "public"; + private final static String PRIVATE = "private"; +@@ -212,7 +213,11 @@ + return s1; + } + +- int keyLength() { ++ /** ++ * Return bit length of the key. ++ */ ++ @Override ++ public int length() { + return keyLength; + } + +diff --git a/src/share/classes/sun/security/pkcs11/P11RSACipher.java b/src/share/classes/sun/security/pkcs11/P11RSACipher.java +--- jdk/src/share/classes/sun/security/pkcs11/P11RSACipher.java ++++ jdk/src/share/classes/sun/security/pkcs11/P11RSACipher.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. ++ * 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 +@@ -201,7 +201,7 @@ + } else { + throw new InvalidKeyException("Unknown key type: " + p11Key); + } +- int n = (p11Key.keyLength() + 7) >> 3; ++ int n = (p11Key.length() + 7) >> 3; + outputSize = n; + buffer = new byte[n]; + maxInputSize = encrypt ? (n - PKCS1_MIN_PADDING_LENGTH) : n; +@@ -458,7 +458,7 @@ + + // see JCE spec + protected int engineGetKeySize(Key key) throws InvalidKeyException { +- int n = P11KeyFactory.convertKey(token, key, algorithm).keyLength(); ++ int n = P11KeyFactory.convertKey(token, key, algorithm).length(); + return n; + } + } +diff --git a/src/share/classes/sun/security/pkcs11/P11Signature.java b/src/share/classes/sun/security/pkcs11/P11Signature.java +--- jdk/src/share/classes/sun/security/pkcs11/P11Signature.java ++++ jdk/src/share/classes/sun/security/pkcs11/P11Signature.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. ++ * 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 +@@ -274,7 +274,7 @@ + if (keyAlgorithm.equals("DSA")) { + signature = new byte[40]; + } else { +- signature = new byte[(p11Key.keyLength() + 7) >> 3]; ++ signature = new byte[(p11Key.length() + 7) >> 3]; + } + if (type == T_UPDATE) { + token.p11.C_VerifyFinal(session.id(), signature); +@@ -359,7 +359,7 @@ + if (keyAlgorithm.equals("RSA") && publicKey != p11Key) { + int keyLen; + if (publicKey instanceof P11Key) { +- keyLen = ((P11Key) publicKey).keyLength(); ++ keyLen = ((P11Key) publicKey).length(); + } else { + keyLen = ((RSAKey) publicKey).getModulus().bitLength(); + } +@@ -620,7 +620,7 @@ + + private byte[] pkcs1Pad(byte[] data) { + try { +- int len = (p11Key.keyLength() + 7) >> 3; ++ int len = (p11Key.length() + 7) >> 3; + RSAPadding padding = RSAPadding.getInstance + (RSAPadding.PAD_BLOCKTYPE_1, len); + byte[] padded = padding.pad(data); +diff --git a/src/share/classes/sun/security/ssl/HandshakeInStream.java b/src/share/classes/sun/security/ssl/HandshakeInStream.java +--- jdk/src/share/classes/sun/security/ssl/HandshakeInStream.java ++++ jdk/src/share/classes/sun/security/ssl/HandshakeInStream.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1996, 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 +@@ -190,6 +190,7 @@ + + byte[] getBytes8() throws IOException { + int len = getInt8(); ++ verifyLength(len); + byte b[] = new byte[len]; + + read(b, 0, len); +@@ -198,6 +199,7 @@ + + byte[] getBytes16() throws IOException { + int len = getInt16(); ++ verifyLength(len); + byte b[] = new byte[len]; + + read(b, 0, len); +@@ -206,10 +208,19 @@ + + byte[] getBytes24() throws IOException { + int len = getInt24(); ++ verifyLength(len); + byte b[] = new byte[len]; + + read(b, 0, len); + return b; + } + ++ // Is a length greater than available bytes in the record? ++ private void verifyLength(int len) throws SSLException { ++ if (len > available()) { ++ throw new SSLException( ++ "Not enough data to fill declared vector size"); ++ } ++ } ++ + } +diff --git a/src/share/classes/sun/security/ssl/Handshaker.java b/src/share/classes/sun/security/ssl/Handshaker.java +--- jdk/src/share/classes/sun/security/ssl/Handshaker.java ++++ jdk/src/share/classes/sun/security/ssl/Handshaker.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1996, 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 +@@ -776,9 +776,9 @@ + if (debug != null && Debug.isOn("handshake")) { + System.out.println("RSA master secret generation error:"); + e.printStackTrace(System.out); +- System.out.println("Generating new random premaster secret"); + } +- preMasterSecret = RSAClientKeyExchange.generateDummySecret(protocolVersion); ++ preMasterSecret = ++ RSAClientKeyExchange.generateDummySecret(protocolVersion); + // recursive call with new premaster secret + return calculateMasterSecret(preMasterSecret, null); + } +@@ -821,9 +821,9 @@ + System.out.println("RSA PreMasterSecret version error: expected" + + protocolVersion + " or " + requestedVersion + ", decrypted: " + + premasterVersion); +- System.out.println("Generating new random premaster secret"); + } +- preMasterSecret = RSAClientKeyExchange.generateDummySecret(protocolVersion); ++ preMasterSecret = ++ RSAClientKeyExchange.generateDummySecret(protocolVersion); + // recursive call with new premaster secret + return calculateMasterSecret(preMasterSecret, null); + } +diff --git a/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java b/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java +--- jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java ++++ jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1996, 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 +@@ -36,6 +36,7 @@ + import javax.net.ssl.*; + + import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec; ++import sun.security.util.KeyLength; + + /** + * This is the client key exchange message (CLIENT --> SERVER) used with +@@ -85,7 +86,8 @@ + * it, using its RSA private key. Result is the same size as the + * server's public key, and uses PKCS #1 block format 02. + */ +- RSAClientKeyExchange(ProtocolVersion protocolVersion, ProtocolVersion maxVersion, ++ RSAClientKeyExchange(ProtocolVersion protocolVersion, ++ ProtocolVersion maxVersion, + SecureRandom generator, PublicKey publicKey) throws IOException { + if (publicKey.getAlgorithm().equals("RSA") == false) { + throw new SSLKeyException("Public key not of type RSA"); +@@ -120,7 +122,8 @@ + * Server gets the PKCS #1 (block format 02) data, decrypts + * it with its private key. + */ +- RSAClientKeyExchange(ProtocolVersion currentVersion, HandshakeInStream input, ++ RSAClientKeyExchange(ProtocolVersion currentVersion, ++ ProtocolVersion maxVersion, HandshakeInStream input, + int messageSize, PrivateKey privateKey) throws IOException { + + if (privateKey.getAlgorithm().equals("RSA") == false) { +@@ -143,28 +146,119 @@ + cipher.init(Cipher.UNWRAP_MODE, privateKey); + preMaster = (SecretKey)cipher.unwrap(encrypted, + "TlsRsaPremasterSecret", Cipher.SECRET_KEY); ++ ++ // polish the premaster secret ++ preMaster = polishPreMasterSecretKey( ++ currentVersion, maxVersion, preMaster, null); + } catch (Exception e) { +- /* +- * Bogus decrypted ClientKeyExchange? If so, conjure a +- * a random preMaster secret that will fail later during +- * Finished message processing. This is a countermeasure against +- * the "interactive RSA PKCS#1 encryption envelop attack" reported +- * in June 1998. Preserving the executation path will +- * mitigate timing attacks and force consistent error handling +- * that will prevent an attacking client from differentiating +- * different kinds of decrypted ClientKeyExchange bogosities. +- */ +- if (debug != null && Debug.isOn("handshake")) { +- System.out.println("Error decrypting premaster secret:"); +- e.printStackTrace(System.out); +- System.out.println("Generating random secret"); ++ // polish the premaster secret ++ preMaster = polishPreMasterSecretKey( ++ currentVersion, maxVersion, preMaster, e); ++ } ++ } ++ ++ /** ++ * To avoid vulnerabilities described by section 7.4.7.1, RFC 5246, ++ * treating incorrectly formatted message blocks and/or mismatched ++ * version numbers in a manner indistinguishable from correctly ++ * formatted RSA blocks. ++ * ++ * RFC 5246 describes the approach as : ++ * ++ * 1. Generate a string R of 46 random bytes ++ * ++ * 2. Decrypt the message to recover the plaintext M ++ * ++ * 3. If the PKCS#1 padding is not correct, or the length of message ++ * M is not exactly 48 bytes: ++ * pre_master_secret = ClientHello.client_version || R ++ * else If ClientHello.client_version <= TLS 1.0, and version ++ * number check is explicitly disabled: ++ * pre_master_secret = M ++ * else: ++ * pre_master_secret = ClientHello.client_version || M[2..47] ++ * ++ * Note that although TLS 1.2 is not supported in this release, we still ++ * want to make use of the above approach to provide better protection. ++ */ ++ private SecretKey polishPreMasterSecretKey( ++ ProtocolVersion currentVersion, ProtocolVersion clientHelloVersion, ++ SecretKey secretKey, Exception failoverException) { ++ ++ if (failoverException == null && secretKey != null) { ++ // check the length ++ byte[] encoded = secretKey.getEncoded(); ++ if (encoded == null) { // unable to get the encoded key ++ if (debug != null && Debug.isOn("handshake")) { ++ System.out.println( ++ "unable to get the plaintext of the premaster secret"); ++ } ++ ++ int keySize = KeyLength.getKeySize(secretKey); ++ if (keySize > 0 && keySize != 384) { // 384 = 48 * 8 ++ if (debug != null && Debug.isOn("handshake")) { ++ System.out.println( ++ "incorrect length of premaster secret: " + ++ (keySize/8)); ++ } ++ ++ return generateDummySecret(currentVersion); ++ } ++ ++ // The key size is exactly 48 bytes or not accessible. ++ // ++ // Conservatively, pass the checking to master secret ++ // calculation. ++ return secretKey; ++ } else if (encoded.length == 48) { ++ // check the version ++ if (clientHelloVersion.major == encoded[0] && ++ clientHelloVersion.minor == encoded[1]) { ++ ++ return secretKey; ++ } else if (clientHelloVersion.v <= ProtocolVersion.TLS10.v && ++ currentVersion.major == encoded[0] && ++ currentVersion.minor == encoded[1]) { ++ /* ++ * For compatibility, we maintain the behavior that the ++ * version in pre_master_secret can be the negotiated ++ * version for TLS v1.0 and SSL v3.0. ++ */ ++ return secretKey; ++ } ++ ++ if (debug != null && Debug.isOn("handshake")) { ++ System.out.println("Mismatching Protocol Versions, " + ++ "ClientHello.client_version is " + clientHelloVersion + ++ ", while PreMasterSecret.client_version is " + ++ ProtocolVersion.valueOf(encoded[0], encoded[1])); ++ } ++ return generateDummySecret(currentVersion); ++ } else { ++ if (debug != null && Debug.isOn("handshake")) { ++ System.out.println( ++ "incorrect length of premaster secret: " + ++ encoded.length); ++ } ++ return generateDummySecret(currentVersion); + } +- preMaster = generateDummySecret(currentVersion); + } ++ ++ if (debug != null && Debug.isOn("handshake") && ++ failoverException != null) { ++ System.out.println("Error decrypting premaster secret:"); ++ failoverException.printStackTrace(System.out); ++ } ++ ++ return generateDummySecret(currentVersion); + } + + // generate a premaster secret with the specified version number + static SecretKey generateDummySecret(ProtocolVersion version) { ++ if (debug != null && Debug.isOn("handshake")) { ++ System.out.println("Generating a random fake premaster secret"); ++ } ++ + try { + KeyGenerator kg = + JsseJce.getKeyGenerator("SunTlsRsaPremasterSecret"); +diff --git a/src/share/classes/sun/security/ssl/ServerHandshaker.java b/src/share/classes/sun/security/ssl/ServerHandshaker.java +--- jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java ++++ jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1996, 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 +@@ -190,8 +190,9 @@ + * temporary one used for non-export or signing-only + * certificates/keys. + */ +- RSAClientKeyExchange pms = new RSAClientKeyExchange +- (protocolVersion, input, message_len, privateKey); ++ RSAClientKeyExchange pms = new RSAClientKeyExchange( ++ protocolVersion, clientRequestedVersion, ++ input, message_len, privateKey); + preMasterSecret = this.clientKeyExchange(pms); + break; + case K_KRB5: +diff --git a/src/share/classes/sun/security/util/KeyLength.java b/src/share/classes/sun/security/util/KeyLength.java +new file mode 100644 +--- /dev/null ++++ jdk/src/share/classes/sun/security/util/KeyLength.java +@@ -0,0 +1,91 @@ ++/* ++ * Copyright (c) 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. 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.util; ++ ++import java.security.Key; ++import java.security.PrivilegedAction; ++import java.security.AccessController; ++import java.security.interfaces.ECKey; ++import java.security.interfaces.RSAKey; ++import java.security.interfaces.DSAKey; ++import javax.crypto.SecretKey; ++import javax.crypto.interfaces.DHKey; ++ ++/** ++ * A utility class to get key length ++ */ ++public final class KeyLength { ++ ++ /** ++ * Returns the key size of the given key object in bits. ++ * ++ * @param key the key object, cannot be null ++ * @return the key size of the given key object in bits, or -1 if the ++ * key size is not accessible ++ */ ++ final public static int getKeySize(Key key) { ++ int size = -1; ++ ++ if (key instanceof Length) { ++ try { ++ Length ruler = (Length)key; ++ size = ruler.length(); ++ } catch (UnsupportedOperationException usoe) { ++ // ignore the exception ++ } ++ ++ if (size >= 0) { ++ return size; ++ } ++ } ++ ++ // try to parse the length from key specification ++ if (key instanceof SecretKey) { ++ SecretKey sk = (SecretKey)key; ++ String format = sk.getFormat(); ++ if ("RAW".equals(format) && sk.getEncoded() != null) { ++ size = (sk.getEncoded().length * 8); ++ } // Otherwise, it may be a unextractable key of PKCS#11, or ++ // a key we are not able to handle. ++ } else if (key instanceof RSAKey) { ++ RSAKey pubk = (RSAKey)key; ++ size = pubk.getModulus().bitLength(); ++ } else if (key instanceof ECKey) { ++ ECKey pubk = (ECKey)key; ++ size = pubk.getParams().getOrder().bitLength(); ++ } else if (key instanceof DSAKey) { ++ DSAKey pubk = (DSAKey)key; ++ size = pubk.getParams().getP().bitLength(); ++ } else if (key instanceof DHKey) { ++ DHKey pubk = (DHKey)key; ++ size = pubk.getParams().getP().bitLength(); ++ } // Otherwise, it may be a unextractable key of PKCS#11, or ++ // a key we are not able to handle. ++ ++ return size; ++ } ++} ++ +diff --git a/src/share/classes/sun/security/util/Length.java b/src/share/classes/sun/security/util/Length.java +new file mode 100644 +--- /dev/null ++++ jdk/src/share/classes/sun/security/util/Length.java +@@ -0,0 +1,43 @@ ++/* ++ * Copyright (c) 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. 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.util; ++ ++/** ++ * The Length interface defines the length of an object ++ */ ++public interface Length { ++ ++ /** ++ * Gets the length of this object ++ * <p> ++ * Note that if a class of java.security.Key implements this interfaces, ++ * the length should be measured in bits. ++ * ++ * @return the length of this object ++ * @throws UnsupportedOperationException if the operation is not supported ++ */ ++ public int length(); ++} diff --git a/java/openjdk6/files/icedtea/security/7189103.patch b/java/openjdk6/files/icedtea/security/7189103.patch new file mode 100644 index 000000000000..c855299d2ac2 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/7189103.patch @@ -0,0 +1,39 @@ +# HG changeset patch +# User coffeys +# Date 1345121690 -3600 +# Node ID b6a7a661db8a2141ebb2e79ba5739722d1be7bfd +# Parent a6294da5a21f609b67a0d4d216028dda9f56e689 +7189103: Executors needs to maintain state +Reviewed-by: chegar + +diff --git a/src/share/classes/java/util/concurrent/Executors.java b/src/share/classes/java/util/concurrent/Executors.java +--- jdk/src/share/classes/java/util/concurrent/Executors.java ++++ jdk/src/share/classes/java/util/concurrent/Executors.java +@@ -530,18 +530,17 @@ + return AccessController.doPrivileged( + new PrivilegedExceptionAction<T>() { + public T run() throws Exception { +- ClassLoader savedcl = null; + Thread t = Thread.currentThread(); +- try { +- ClassLoader cl = t.getContextClassLoader(); +- if (ccl != cl) { +- t.setContextClassLoader(ccl); +- savedcl = cl; ++ ClassLoader cl = t.getContextClassLoader(); ++ if (ccl == cl) { ++ return task.call(); ++ } else { ++ t.setContextClassLoader(ccl); ++ try { ++ return task.call(); ++ } finally { ++ t.setContextClassLoader(cl); + } +- return task.call(); +- } finally { +- if (savedcl != null) +- t.setContextClassLoader(savedcl); + } + } + }, acc); diff --git a/java/openjdk6/files/icedtea/security/7189490.patch b/java/openjdk6/files/icedtea/security/7189490.patch new file mode 100644 index 000000000000..3a8826dde48e --- /dev/null +++ b/java/openjdk6/files/icedtea/security/7189490.patch @@ -0,0 +1,55 @@ +# HG changeset patch +# User coffeys +# Date 1345121553 -3600 +# Node ID 7fe230af5036c83eb337b3560821b97c6dec08c9 +# Parent b6a7a661db8a2141ebb2e79ba5739722d1be7bfd +7189490: More improvements to DomainCombiner checking +Reviewed-by: mullan + +diff --git a/src/share/classes/java/security/AccessController.java b/src/share/classes/java/security/AccessController.java +--- jdk/src/share/classes/java/security/AccessController.java ++++ jdk/src/share/classes/java/security/AccessController.java +@@ -290,11 +290,11 @@ + */ + public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action) { + +- DomainCombiner dc = null; + AccessControlContext acc = getStackAccessControlContext(); +- if (acc == null || (dc = acc.getAssignedCombiner()) == null) { +- return AccessController.doPrivileged(action, acc); ++ if (acc == null) { ++ return AccessController.doPrivileged(action); + } ++ DomainCombiner dc = acc.getAssignedCombiner(); + return AccessController.doPrivileged(action, preserveCombiner(dc)); + } + +@@ -386,11 +386,11 @@ + public static <T> T doPrivilegedWithCombiner + (PrivilegedExceptionAction<T> action) throws PrivilegedActionException { + +- DomainCombiner dc = null; + AccessControlContext acc = getStackAccessControlContext(); +- if (acc == null || (dc = acc.getAssignedCombiner()) == null) { +- return AccessController.doPrivileged(action, acc); ++ if (acc == null) { ++ return AccessController.doPrivileged(action); + } ++ DomainCombiner dc = acc.getAssignedCombiner(); + return AccessController.doPrivileged(action, preserveCombiner(dc)); + } + +@@ -417,7 +417,12 @@ + // perform 'combine' on the caller of doPrivileged, + // even if the caller is from the bootclasspath + ProtectionDomain[] pds = new ProtectionDomain[] {callerPd}; +- return new AccessControlContext(combiner.combine(pds, null), combiner); ++ if (combiner == null) { ++ return new AccessControlContext(pds); ++ } else { ++ return new AccessControlContext(combiner.combine(pds, null), ++ combiner); ++ } + } + + diff --git a/java/openjdk6/files/icedtea/security/7189567.patch b/java/openjdk6/files/icedtea/security/7189567.patch new file mode 100644 index 000000000000..9ba015744f67 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/7189567.patch @@ -0,0 +1,95 @@ +# HG changeset patch +# User robm +# Date 1347900712 -3600 +# Node ID aa1fa3f96d77541a3bafd767001f3100fe6b8a5a +# Parent 7fe230af5036c83eb337b3560821b97c6dec08c9 +7189567: java net obselete protocol +Reviewed-by: chegar + +diff --git a/src/share/classes/java/net/URL.java b/src/share/classes/java/net/URL.java +--- jdk/src/share/classes/java/net/URL.java ++++ jdk/src/share/classes/java/net/URL.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1995, 2007, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1995, 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 +@@ -28,6 +28,8 @@ + import java.io.IOException; + import java.io.InputStream; + import java.io.OutputStream; ++import java.security.AccessController; ++import java.security.PrivilegedAction; + import java.util.Hashtable; + import java.util.StringTokenizer; + import sun.security.util.SecurityConstants; +@@ -1110,6 +1112,21 @@ + static Hashtable handlers = new Hashtable(); + private static Object streamHandlerLock = new Object(); + ++ // special case the gopher protocol, disabled by default ++ private static final String GOPHER = "gopher"; ++ private static final String ENABLE_GOPHER_PROP = "jdk.net.registerGopherProtocol"; ++ private static final boolean enableGopher = AccessController.doPrivileged( ++ new PrivilegedAction<Boolean>() { ++ public Boolean run() { ++ String prop = System.getProperty(ENABLE_GOPHER_PROP); ++ return prop == null ? false : ++ (prop.equalsIgnoreCase("false") ? false : true); ++ } ++ }); ++ ++ // package name of the JDK implementation protocol handlers ++ private static final String JDK_PACKAGE_PREFIX = "sun.net.www.protocol"; ++ + /** + * Returns the Stream Handler. + * @param protocol the protocol to use +@@ -1141,7 +1158,7 @@ + + // REMIND: decide whether to allow the "null" class prefix + // or not. +- packagePrefixList += "sun.net.www.protocol"; ++ packagePrefixList += JDK_PACKAGE_PREFIX; + + StringTokenizer packagePrefixIter = + new StringTokenizer(packagePrefixList, "|"); +@@ -1151,6 +1168,15 @@ + + String packagePrefix = + packagePrefixIter.nextToken().trim(); ++ ++ // do not try to instantiate the JDK gopher handler ++ // unless the system property had been explicitly set ++ if (protocol.equalsIgnoreCase(GOPHER) && ++ packagePrefix.equals(JDK_PACKAGE_PREFIX) && ++ !enableGopher) { ++ continue; ++ } ++ + try { + String clsName = packagePrefix + "." + protocol + + ".Handler"; +diff --git a/test/java/net/URL/Test.java b/test/java/net/URL/Test.java +--- jdk/test/java/net/URL/Test.java ++++ jdk/test/java/net/URL/Test.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2001, 2003, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it +@@ -322,10 +322,6 @@ + test("ftp://ftp.is.co.za/rfc/rfc1808.txt") + .s("ftp").h("ftp.is.co.za").p("/rfc/rfc1808.txt").z(); + +- test("gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles") +- .s("gopher").h("spinaltap.micro.umn.edu") +- .p("/00/Weather/California/Los%20Angeles").z(); +- + test("http://www.math.uio.no/faq/compression-faq/part1.html") + .s("http").h("www.math.uio.no").p("/faq/compression-faq/part1.html").z(); + diff --git a/java/openjdk6/files/icedtea/security/7192975.patch b/java/openjdk6/files/icedtea/security/7192975.patch new file mode 100644 index 000000000000..3d7188368211 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/7192975.patch @@ -0,0 +1,35 @@ +# HG changeset patch +# User asaha +# Date 1349309813 25200 +# Node ID d77bc9151c1dea1a4a396fb59d58ba7c8d77fd88 +# Parent aa1fa3f96d77541a3bafd767001f3100fe6b8a5a +7192975: Conditional usage check is wrong +Reviewed-by: dsamersoff +Contributed-by: andreas.eriksson@oracle.com + +diff --git a/src/share/classes/javax/management/modelmbean/DescriptorSupport.java b/src/share/classes/javax/management/modelmbean/DescriptorSupport.java +--- jdk/src/share/classes/javax/management/modelmbean/DescriptorSupport.java ++++ jdk/src/share/classes/javax/management/modelmbean/DescriptorSupport.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2000, 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 +@@ -1239,13 +1239,12 @@ + return s.substring(1, s.length() - 1); + } + final String className = s.substring(1, slash); ++ + final Constructor<?> constr; + try { ++ ReflectUtil.checkPackageAccess(className); + final ClassLoader contextClassLoader = + Thread.currentThread().getContextClassLoader(); +- if (contextClassLoader == null) { +- ReflectUtil.checkPackageAccess(className); +- } + final Class<?> c = + Class.forName(className, false, contextClassLoader); + constr = c.getConstructor(new Class[] {String.class}); diff --git a/java/openjdk6/files/icedtea/security/7195194.patch b/java/openjdk6/files/icedtea/security/7195194.patch new file mode 100644 index 000000000000..4251c0c35bf1 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/7195194.patch @@ -0,0 +1,29 @@ +# HG changeset patch +# User andrew +# Date 1349974205 -3600 +# Node ID 6a383aef225ab7bb99b723bbb29786e29747a4f0 +# Parent d77bc9151c1dea1a4a396fb59d58ba7c8d77fd88 +7195194: Better data validation for Swing +Reviewed-by: art, ahgross + +diff --git a/src/share/classes/javax/swing/text/DefaultFormatter.java b/src/share/classes/javax/swing/text/DefaultFormatter.java +--- jdk/src/share/classes/javax/swing/text/DefaultFormatter.java ++++ jdk/src/share/classes/javax/swing/text/DefaultFormatter.java +@@ -24,6 +24,8 @@ + */ + package javax.swing.text; + ++import sun.reflect.misc.ConstructorUtil; ++ + import java.io.Serializable; + import java.lang.reflect.*; + import java.text.ParseException; +@@ -245,7 +247,7 @@ + Constructor cons; + + try { +- cons = vc.getConstructor(new Class[] { String.class }); ++ cons = ConstructorUtil.getConstructor(vc, new Class[]{String.class}); + + } catch (NoSuchMethodException nsme) { + cons = null; diff --git a/java/openjdk6/files/icedtea/security/7195917.patch b/java/openjdk6/files/icedtea/security/7195917.patch new file mode 100644 index 000000000000..479e7fa78fa1 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/7195917.patch @@ -0,0 +1,88 @@ +# HG changeset patch +# User malenkov +# Date 1348148080 -14400 +# Node ID 074f132d65c91231ca989e4c757207e1cf25a476 +# Parent 6a383aef225ab7bb99b723bbb29786e29747a4f0 +7195917: XMLDecoder parsing at close-time should be improved +Reviewed-by: art, ahgross + +diff --git a/src/share/classes/java/beans/XMLDecoder.java b/src/share/classes/java/beans/XMLDecoder.java +--- jdk/src/share/classes/java/beans/XMLDecoder.java ++++ jdk/src/share/classes/java/beans/XMLDecoder.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2000, 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 +@@ -32,6 +32,10 @@ + import java.lang.ref.Reference; + import java.lang.ref.WeakReference; + ++import java.security.AccessControlContext; ++import java.security.AccessController; ++import java.security.PrivilegedAction; ++ + import org.xml.sax.SAXException; + + import javax.xml.parsers.SAXParserFactory; +@@ -66,6 +70,7 @@ + * @author Philip Milne + */ + public class XMLDecoder { ++ private final AccessControlContext acc = AccessController.getContext(); + private InputStream in; + private Object owner; + private ExceptionListener exceptionListener; +@@ -248,25 +253,33 @@ + */ + private ObjectHandler getHandler() { + if ( handler == null ) { +- SAXParserFactory factory = SAXParserFactory.newInstance(); +- try { +- SAXParser parser = factory.newSAXParser(); +- handler = new ObjectHandler( this, getClassLoader() ); +- parser.parse( in, handler ); ++ if ((this.acc == null) && (null != System.getSecurityManager())) { ++ throw new SecurityException("AccessControlContext is not set"); + } +- catch ( ParserConfigurationException e ) { +- getExceptionListener().exceptionThrown( e ); +- } +- catch ( SAXException se ) { +- Exception e = se.getException(); +- if ( e == null ) { +- e = se; ++ handler = AccessController.doPrivileged(new PrivilegedAction<ObjectHandler>() { ++ public ObjectHandler run() { ++ ObjectHandler handler = new ObjectHandler(XMLDecoder.this, getClassLoader()); ++ SAXParserFactory factory = SAXParserFactory.newInstance(); ++ try { ++ SAXParser parser = factory.newSAXParser(); ++ parser.parse( in, handler ); ++ } ++ catch ( ParserConfigurationException e ) { ++ getExceptionListener().exceptionThrown( e ); ++ } ++ catch ( SAXException se ) { ++ Exception e = se.getException(); ++ if ( e == null ) { ++ e = se; ++ } ++ getExceptionListener().exceptionThrown( e ); ++ } ++ catch ( IOException ioe ) { ++ getExceptionListener().exceptionThrown( ioe ); ++ } ++ return handler; + } +- getExceptionListener().exceptionThrown( e ); +- } +- catch ( IOException ioe ) { +- getExceptionListener().exceptionThrown( ioe ); +- } ++ }, this.acc); + } + return handler; + } diff --git a/java/openjdk6/files/icedtea/security/7195919.patch b/java/openjdk6/files/icedtea/security/7195919.patch new file mode 100644 index 000000000000..2d14c00701b8 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/7195919.patch @@ -0,0 +1,63 @@ +# HG changeset patch +# User dmeetry +# Date 1347313661 -14400 +# Node ID 5352a40bb0ff7e8a6e826478d7687fff695d9805 +# Parent 074f132d65c91231ca989e4c757207e1cf25a476 +7195919: (sl) ServiceLoader can throw CCE without needing to create instance +Reviewed-by: smarks + +diff --git a/src/share/classes/java/util/ServiceLoader.java b/src/share/classes/java/util/ServiceLoader.java +--- jdk/src/share/classes/java/util/ServiceLoader.java ++++ jdk/src/share/classes/java/util/ServiceLoader.java +@@ -358,14 +358,21 @@ + } + String cn = nextName; + nextName = null; ++ Class<?> c = null; + try { +- S p = service.cast(Class.forName(cn, true, loader) +- .newInstance()); +- providers.put(cn, p); +- return p; ++ c = Class.forName(cn, false, loader); + } catch (ClassNotFoundException x) { + fail(service, + "Provider " + cn + " not found"); ++ } ++ if (!service.isAssignableFrom(c)) { ++ fail(service, ++ "Provider " + cn + " not a subtype"); ++ } ++ try { ++ S p = service.cast(c.newInstance()); ++ providers.put(cn, p); ++ return p; + } catch (Throwable x) { + fail(service, + "Provider " + cn + " could not be instantiated: " + x, +diff --git a/src/share/classes/sun/misc/Service.java b/src/share/classes/sun/misc/Service.java +--- jdk/src/share/classes/sun/misc/Service.java ++++ jdk/src/share/classes/sun/misc/Service.java +@@ -284,12 +284,20 @@ + } + String cn = nextName; + nextName = null; ++ Class<?> c = null; + try { +- return Class.forName(cn, true, loader).newInstance(); ++ c = Class.forName(cn, false, loader); + } catch (ClassNotFoundException x) { + fail(service, + "Provider " + cn + " not found"); +- } catch (Exception x) { ++ } ++ if (!service.isAssignableFrom(c)) { ++ fail(service, ++ "Provider " + cn + " not a subtype"); ++ } ++ try { ++ return service.cast(c.newInstance()); ++ } catch (Throwable x) { + fail(service, + "Provider " + cn + " could not be instantiated: " + x, + x); diff --git a/java/openjdk6/files/icedtea/security/7198296.patch b/java/openjdk6/files/icedtea/security/7198296.patch new file mode 100644 index 000000000000..056090582212 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/7198296.patch @@ -0,0 +1,114 @@ +# HG changeset patch +# User asaha +# Date 1349309940 25200 +# Node ID a66bba985c2c46743d6780879278092c0fa5cf2b +# Parent 5352a40bb0ff7e8a6e826478d7687fff695d9805 +7198296: Refactor classloader usage +Reviewed-by: dsamersoff +Contributed-by: andreas.eriksson@oracle.com + +diff --git a/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java b/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java +--- jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java ++++ jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java +@@ -165,9 +165,17 @@ + withPermissions( new MBeanPermission("*", "getClassLoaderRepository"), + new RuntimePermission("createClassLoader")) + ); +- +- serverCommunicatorAdmin = new +- RMIServerCommunicatorAdmin(EnvHelp.getServerConnectionTimeout(env)); ++ this.defaultContextClassLoader = ++ AccessController.doPrivileged( ++ new PrivilegedAction<ClassLoader>() { ++ @Override ++ public ClassLoader run() { ++ return new CombinedClassLoader(Thread.currentThread().getContextClassLoader(), ++ dcl); ++ } ++ }); ++ serverCommunicatorAdmin = new ++ RMIServerCommunicatorAdmin(EnvHelp.getServerConnectionTimeout(env)); + + this.env = env; + } +@@ -529,7 +537,7 @@ + "connectionId=" + connectionId + +" unwrapping query with defaultClassLoader."); + +- queryValue = unwrap(query, defaultClassLoader, QueryExp.class); ++ queryValue = unwrap(query, defaultContextClassLoader, QueryExp.class); + + try { + final Object params[] = new Object[] { name, queryValue }; +@@ -563,7 +571,7 @@ + "connectionId=" + connectionId + +" unwrapping query with defaultClassLoader."); + +- queryValue = unwrap(query, defaultClassLoader, QueryExp.class); ++ queryValue = unwrap(query, defaultContextClassLoader, QueryExp.class); + + try { + final Object params[] = new Object[] { name, queryValue }; +@@ -1592,7 +1600,8 @@ + ClassLoader orderCL = AccessController.doPrivileged( + new PrivilegedExceptionAction<ClassLoader>() { + public ClassLoader run() throws Exception { +- return new OrderClassLoaders(cl1, cl2); ++ return new CombinedClassLoader(Thread.currentThread().getContextClassLoader(), ++ new OrderClassLoaders(cl1, cl2)); + } + } + ); +@@ -1684,6 +1693,8 @@ + + private final ClassLoader defaultClassLoader; + ++ private final ClassLoader defaultContextClassLoader; ++ + private final ClassLoaderWithRepository classLoaderWithRepository; + + private boolean terminated = false; +@@ -1768,4 +1779,43 @@ + + private static final ClassLogger logger = + new ClassLogger("javax.management.remote.rmi", "RMIConnectionImpl"); ++ ++ private static final class CombinedClassLoader extends ClassLoader { ++ ++ private final static class ClassLoaderWrapper extends ClassLoader { ++ ClassLoaderWrapper(ClassLoader cl) { ++ super(cl); ++ } ++ ++ @Override ++ protected Class<?> loadClass(String name, boolean resolve) ++ throws ClassNotFoundException { ++ return super.loadClass(name, resolve); ++ } ++ }; ++ ++ final ClassLoaderWrapper defaultCL; ++ ++ private CombinedClassLoader(ClassLoader parent, ClassLoader defaultCL) { ++ super(parent); ++ this.defaultCL = new ClassLoaderWrapper(defaultCL); ++ } ++ ++ @Override ++ protected Class<?> loadClass(String name, boolean resolve) ++ throws ClassNotFoundException { ++ try { ++ super.loadClass(name, resolve); ++ } catch(Exception e) { ++ for(Throwable t = e; t != null; t = t.getCause()) { ++ if(t instanceof SecurityException) { ++ throw t==e?(SecurityException)t:new SecurityException(t.getMessage(), e); ++ } ++ } ++ } ++ final Class<?> cl = defaultCL.loadClass(name, resolve); ++ return cl; ++ } ++ ++ } + } diff --git a/java/openjdk6/files/icedtea/security/7198606.patch b/java/openjdk6/files/icedtea/security/7198606.patch new file mode 100644 index 000000000000..e8a246828a65 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/7198606.patch @@ -0,0 +1,28 @@ +# HG changeset patch +# User andrew +# Date 1349974451 -3600 +# Node ID 8319efc7c840d099832e06db7a50dcfb95bfd4aa +# Parent a148157cd348fe4c251063db7d3973a83cfcf483 +7198606: Improve VM optimization +Reviewed-by: roland, twisti + +diff --git a/src/share/vm/opto/loopTransform.cpp b/src/share/vm/opto/loopTransform.cpp +--- hotspot/src/share/vm/opto/loopTransform.cpp ++++ hotspot/src/share/vm/opto/loopTransform.cpp +@@ -2721,6 +2721,8 @@ + result_mem = new (C, 1) ProjNode(call,TypeFunc::Memory); + _igvn.register_new_node_with_optimizer(result_mem); + ++/* Disable following optimization until proper fix (add missing checks). ++ + // If this fill is tightly coupled to an allocation and overwrites + // the whole body, allow it to take over the zeroing. + AllocateNode* alloc = AllocateNode::Ideal_allocation(base, this); +@@ -2744,6 +2746,7 @@ + #endif + } + } ++*/ + + // Redirect the old control and memory edges that are outside the loop. + Node* exit = head->loopexit()->proj_out(0); diff --git a/java/openjdk6/files/patch-set b/java/openjdk6/files/patch-set index 960b5c4eeb2f..d64c58204f17 100644 --- a/java/openjdk6/files/patch-set +++ b/java/openjdk6/files/patch-set @@ -4140,7 +4140,7 @@ # include <signal.h> # include <errno.h> # include <dlfcn.h> -@@ -102,21 +101,51 @@ +@@ -102,21 +101,57 @@ # include <sys/utsname.h> # include <sys/socket.h> # include <sys/wait.h> @@ -4166,6 +4166,12 @@ # include <sys/ioctl.h> +#ifdef __FreeBSD__ ++#if __FreeBSD_version > 700109 ++#include <bitset> ++#include <sys/cpuset.h> ++#endif ++#include <vm/swap_pager.h> ++#include <vm/vm_param.h> +#if __FreeBSD_version > 900030 +#include <pthread_np.h> +#else @@ -4193,7 +4199,7 @@ #define MAX_PATH (2 * K) // for timer info max values which include all bits -@@ -127,19 +156,25 @@ +@@ -127,19 +162,25 @@ // global variables julong os::Bsd::_physical_memory = 0; @@ -4219,7 +4225,7 @@ static jlong initial_time_count=0; -@@ -157,8 +192,6 @@ +@@ -157,8 +198,6 @@ static int SR_signum = SIGUSR2; sigset_t SR_sigset; @@ -4228,11 +4234,33 @@ //////////////////////////////////////////////////////////////////////////////// // utility functions -@@ -171,11 +204,16 @@ +@@ -171,11 +210,38 @@ } julong os::Bsd::available_memory() { +#ifdef _ALLBSD_SOURCE ++#ifdef __FreeBSD__ ++ static const char *vm_stats[] = { ++ "vm.stats.vm.v_free_count", ++ "vm.stats.vm.v_cache_count", ++ /* "vm.stats.vm.v_inactive_count", */ ++ NULL ++ }; ++ size_t size; ++ julong free_pages; ++ u_int i, npages; ++ ++ for (i = 0, free_pages = 0, size = sizeof(npages); vm_stats[i] != NULL; i++) { ++ if (sysctlbyname(vm_stats[i], &npages, &size, NULL, 0) == -1) { ++ free_pages = 0; ++ break; ++ } ++ free_pages += npages; ++ } ++ if (free_pages > 0) ++ free_pages *= os::vm_page_size(); ++ else ++#endif + // XXXBSD: this is just a stopgap implementation + return physical_memory() >> 2; +#else @@ -4245,7 +4273,7 @@ } julong os::physical_memory() { -@@ -223,6 +261,7 @@ +@@ -223,6 +289,7 @@ } @@ -4253,7 +4281,7 @@ #ifndef SYS_gettid // i386: 224, ia64: 1105, amd64: 186, sparc 143 #ifdef __ia64__ -@@ -237,6 +276,7 @@ +@@ -237,6 +304,7 @@ #error define gettid for the arch #endif #endif @@ -4261,7 +4289,7 @@ // Cpu architecture string #if defined(ZERO) -@@ -267,28 +307,58 @@ +@@ -267,28 +335,86 @@ // Returns the kernel thread id of the currently running thread. Kernel // thread id is used to access /proc. // @@ -4284,18 +4312,38 @@ + thr_self(&tid); + return (pid_t)tid; +#endif - } ++} +#endif - --// Most versions of bsd have a bug where the number of processors are --// determined by looking at the /proc file system. In a chroot environment, --// the system call returns 1. This causes the VM to act as if it is --// a single processor and elide locking (see is_MP() call). --static bool unsafe_chroot_detected = false; --static const char *unstable_chroot_error = "/proc file system not found.\n" -- "Java may be unstable running multithreaded in a chroot " -- "environment on Bsd when /proc filesystem is not mounted."; -+#ifdef _ALLBSD_SOURCE ++ ++#if defined(__FreeBSD__) ++void os::Bsd::initialize_system_info() { ++ int cpu_val = sysconf(_SC_NPROCESSORS_CONF); ++ if (cpu_val >= 1) ++ set_processor_count(cpu_val); ++ else ++ set_processor_count(1); // fallback ++ ++#ifdef _SC_PHYS_PAGES ++ long phys_pages = sysconf(_SC_PHYS_PAGES); ++ if (phys_pages > 0) ++ _physical_memory = (julong)phys_pages * _page_size; ++ else ++ _physical_memory = 256*1024*1024; // fallback (XXXBSD?) ++#else ++ int mib[2]; ++ size_t len; ++ u_long mem_val; ++ ++ mib[0] = CTL_HW; ++ mib[1] = HW_PHYSMEM; ++ len = sizeof(mem_val); ++ if (sysctl(mib, 2, &mem_val, &len, NULL, 0) != -1) ++ _physical_memory = mem_val; ++ else ++ _physical_memory = 256*1024*1024; // fallback (XXXBSD?) ++#endif + } ++#elif defined(_ALLBSD_SOURCE) +void os::Bsd::initialize_system_info() { + int mib[2]; + size_t len; @@ -4313,6 +4361,14 @@ + set_processor_count(1); // fallback + } +-// Most versions of bsd have a bug where the number of processors are +-// determined by looking at the /proc file system. In a chroot environment, +-// the system call returns 1. This causes the VM to act as if it is +-// a single processor and elide locking (see is_MP() call). +-static bool unsafe_chroot_detected = false; +-static const char *unstable_chroot_error = "/proc file system not found.\n" +- "Java may be unstable running multithreaded in a chroot " +- "environment on Bsd when /proc filesystem is not mounted."; + /* get physical memory via hw.usermem sysctl (hw.usermem is used + * instead of hw.physmem because we need size of allocatable memory + */ @@ -4323,7 +4379,7 @@ + _physical_memory = mem_val; + else + _physical_memory = 256*1024*1024; // fallback (XXXBSD?) -+ + +#ifdef __OpenBSD__ + { + // limit _physical_memory memory view on OpenBSD since @@ -4338,7 +4394,7 @@ void os::Bsd::initialize_system_info() { set_processor_count(sysconf(_SC_NPROCESSORS_CONF)); if (processor_count() == 1) { -@@ -305,6 +375,7 @@ +@@ -305,6 +431,7 @@ _physical_memory = (julong)sysconf(_SC_PHYS_PAGES) * (julong)sysconf(_SC_PAGESIZE); assert(processor_count() > 0, "bsd error"); } @@ -4346,7 +4402,7 @@ void os::init_system_properties_values() { // char arch[12]; -@@ -348,9 +419,7 @@ +@@ -348,9 +475,7 @@ * ... * 7: The default directories, normally /lib and /usr/lib. */ @@ -4357,7 +4413,7 @@ #define DEFAULT_LIBPATH "/lib:/usr/lib" #endif -@@ -429,7 +498,11 @@ +@@ -429,7 +554,11 @@ * should always exist (until the legacy problem cited above is * addressed). */ @@ -4369,7 +4425,7 @@ if (v != NULL) { char *t = ld_library_path; /* That's +1 for the colon and +1 for the trailing '\0' */ -@@ -588,6 +661,7 @@ +@@ -588,6 +717,7 @@ } } @@ -4377,7 +4433,7 @@ ////////////////////////////////////////////////////////////////////////////// // detecting pthread library -@@ -751,6 +825,7 @@ +@@ -751,6 +881,7 @@ } return false; } @@ -4385,7 +4441,7 @@ ////////////////////////////////////////////////////////////////////////////// // create new thread -@@ -759,6 +834,9 @@ +@@ -759,6 +890,9 @@ // check if it's safe to start a new thread static bool _thread_safety_check(Thread* thread) { @@ -4395,7 +4451,7 @@ if (os::Bsd::is_BsdThreads() && !os::Bsd::is_floating_stack()) { // Fixed stack BsdThreads (SuSE Bsd/x86, and some versions of Redhat) // Heap is mmap'ed at lower end of memory space. Thread stacks are -@@ -792,6 +870,7 @@ +@@ -792,6 +926,7 @@ // here, that means enough space has been reserved for stack. return true; } @@ -4403,7 +4459,7 @@ } // Thread start routine for all newly created threads -@@ -819,15 +898,22 @@ +@@ -819,15 +954,22 @@ return NULL; } @@ -4426,7 +4482,7 @@ // initialize signal mask for this thread os::Bsd::hotspot_sigmask(thread); -@@ -910,17 +996,22 @@ +@@ -910,17 +1052,22 @@ // let pthread_create() pick the default value. } @@ -4449,7 +4505,7 @@ pthread_t tid; int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread); -@@ -934,7 +1025,9 @@ +@@ -934,7 +1081,9 @@ // Need to clean up stuff we've allocated so far thread->set_osthread(NULL); delete osthread; @@ -4459,7 +4515,7 @@ return false; } -@@ -950,9 +1043,11 @@ +@@ -950,9 +1099,11 @@ } } @@ -4471,7 +4527,7 @@ } // Aborted due to thread limit being reached -@@ -990,7 +1085,11 @@ +@@ -990,7 +1141,11 @@ } // Store pthread info into the OSThread @@ -4483,7 +4539,7 @@ osthread->set_pthread_id(::pthread_self()); // initialize floating point control register -@@ -1001,6 +1100,7 @@ +@@ -1001,6 +1156,7 @@ thread->set_osthread(osthread); @@ -4491,7 +4547,7 @@ if (UseNUMA) { int lgrp_id = os::numa_get_group_id(); if (lgrp_id != -1) { -@@ -1027,6 +1127,7 @@ +@@ -1027,6 +1183,7 @@ os::Bsd::manually_expand_stack(jt, addr); osthread->clear_expanding_stack(); } @@ -4499,7 +4555,7 @@ // initialize signal mask for this thread // and save the caller's signal mask -@@ -1085,6 +1186,7 @@ +@@ -1085,6 +1242,7 @@ ////////////////////////////////////////////////////////////////////////////// // initial thread @@ -4507,7 +4563,7 @@ // Check if current thread is the initial thread, similar to Solaris thr_main. bool os::Bsd::is_initial_thread(void) { char dummy; -@@ -1321,6 +1423,7 @@ +@@ -1321,6 +1479,7 @@ _initial_thread_stack_size = align_size_down(_initial_thread_stack_size, page_size()); _initial_thread_stack_bottom = (address)stack_top - _initial_thread_stack_size; } @@ -4515,7 +4571,7 @@ //////////////////////////////////////////////////////////////////////////////// // time support -@@ -1342,9 +1445,7 @@ +@@ -1342,9 +1501,7 @@ return (1000 * 1000); } @@ -4526,7 +4582,7 @@ bool os::supports_vtime() { return false; } bool os::enable_vtime() { return false; } bool os::vtime_enabled() { return false; } -@@ -1364,6 +1465,21 @@ +@@ -1364,6 +1521,21 @@ #define CLOCK_MONOTONIC (1) #endif @@ -4548,7 +4604,7 @@ void os::Bsd::clock_init() { // we do dlopen's in this particular order due to bug in bsd // dynamical loader (see 6348968) leading to crash on exit -@@ -1399,7 +1515,9 @@ +@@ -1399,7 +1571,9 @@ } } } @@ -4558,7 +4614,7 @@ #ifndef SYS_clock_getres #if defined(IA32) || defined(AMD64) -@@ -1440,6 +1558,7 @@ +@@ -1440,6 +1614,7 @@ _pthread_getcpuclockid = pthread_getcpuclockid_func; } } @@ -4566,7 +4622,7 @@ jlong os::javaTimeNanos() { if (Bsd::supports_monotonic_clock()) { -@@ -1608,7 +1727,14 @@ +@@ -1608,7 +1783,14 @@ // DLL functions @@ -4582,7 +4638,7 @@ // This must be hard coded because it's the system's temporary // directory not the java application's temp directory, ala java.io.tmpdir. -@@ -1628,13 +1754,13 @@ +@@ -1628,13 +1810,13 @@ const size_t pnamelen = pname ? strlen(pname) : 0; // Quietly truncate on buffer overflow. Should be an error. @@ -4598,7 +4654,7 @@ } else if (strchr(pname, *os::path_separator()) != NULL) { int n; char** pelements = split_path(pname, &n); -@@ -1643,7 +1769,8 @@ +@@ -1643,7 +1825,8 @@ if (pelements[i] == NULL || strlen(pelements[i]) == 0) { continue; // skip the empty path values } @@ -4608,7 +4664,7 @@ if (file_exists(buffer)) { break; } -@@ -1658,7 +1785,7 @@ +@@ -1658,7 +1841,7 @@ FREE_C_HEAP_ARRAY(char*, pelements); } } else { @@ -4617,7 +4673,7 @@ } } -@@ -1708,6 +1835,23 @@ +@@ -1708,6 +1891,23 @@ return false; } @@ -4641,7 +4697,7 @@ struct _address_to_library_name { address addr; // input : memory address size_t buflen; // size of fname -@@ -1782,11 +1926,27 @@ +@@ -1782,11 +1982,27 @@ return false; } } @@ -4658,18 +4714,18 @@ + // Successful loading + return result; + } - ++ + // Read system error message into ebuf + ::strncpy(ebuf, ::dlerror(), ebuflen-1); + ebuf[ebuflen-1]='\0'; -+ + + return NULL; +} +#else void * os::dll_load(const char *filename, char *ebuf, int ebuflen) { void * result= ::dlopen(filename, RTLD_LAZY); -@@ -1839,6 +1999,26 @@ +@@ -1839,6 +2055,26 @@ #define EM_486 6 /* Intel 80486 */ #endif @@ -4696,7 +4752,7 @@ static const arch_t arch_array[]={ {EM_386, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"}, {EM_486, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"}, -@@ -1942,17 +2122,11 @@ +@@ -1942,17 +2178,11 @@ return NULL; } @@ -4717,7 +4773,7 @@ } -@@ -1975,7 +2149,51 @@ +@@ -1975,7 +2205,51 @@ void os::print_dll_info(outputStream *st) { st->print_cr("Dynamic libraries:"); @@ -4770,7 +4826,7 @@ char fname[32]; pid_t pid = os::Bsd::gettid(); -@@ -1984,6 +2202,7 @@ +@@ -1984,6 +2258,7 @@ if (!_print_ascii_file(fname, st)) { st->print("Can not get library information for pid = %d\n", pid); } @@ -4778,7 +4834,7 @@ } -@@ -2018,6 +2237,7 @@ +@@ -2018,6 +2293,7 @@ st->print(name.machine); st->cr(); @@ -4786,7 +4842,7 @@ // Print warning if unsafe chroot environment detected if (unsafe_chroot_detected) { st->print("WARNING!! "); -@@ -2032,6 +2252,7 @@ +@@ -2032,6 +2308,7 @@ st->print("(%s stack)", os::Bsd::is_floating_stack() ? "floating" : "fixed"); } st->cr(); @@ -4794,7 +4850,7 @@ // rlimit st->print("rlimit:"); -@@ -2057,6 +2278,7 @@ +@@ -2057,6 +2334,7 @@ if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); else st->print("%d", rlim.rlim_cur); @@ -4802,7 +4858,7 @@ st->print(", AS "); getrlimit(RLIMIT_AS, &rlim); if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); -@@ -2069,11 +2291,7 @@ +@@ -2069,11 +2347,7 @@ os::loadavg(loadavg, 3); st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]); st->cr(); @@ -4815,11 +4871,29 @@ } void os::print_memory_info(outputStream* st) { -@@ -2081,18 +2299,27 @@ +@@ -2081,19 +2355,55 @@ st->print("Memory:"); st->print(" %dk page", os::vm_page_size()>>10); -+#ifndef _ALLBSD_SOURCE ++#ifdef _ALLBSD_SOURCE ++#ifdef __FreeBSD__ ++ struct xswdev xsw; ++ size_t mibsize, size; ++ int mib[16], n, total = 0, used = 0; ++ ++ mibsize = sizeof(mib) / sizeof(mib[0]); ++ if (sysctlnametomib("vm.swap_info", mib, &mibsize) != -1) { ++ for (n = 0; ; n++) { ++ mib[mibsize] = n; ++ size = sizeof(xsw); ++ if (sysctl(mib, mibsize + 1, &xsw, &size, NULL, 0) == -1) ++ break; ++ total += xsw.xsw_nblks; ++ used += xsw.xsw_used; ++ } ++ } ++#endif ++#else // values in struct sysinfo are "unsigned long" struct sysinfo si; sysinfo(&si); @@ -4829,7 +4903,14 @@ os::physical_memory() >> 10); st->print("(" UINT64_FORMAT "k free)", os::available_memory() >> 10); -+#ifndef _ALLBSD_SOURCE ++#ifdef _ALLBSD_SOURCE ++#ifdef __FreeBSD__ ++ st->print(", swap " UINT64_FORMAT "k", ++ ((jlong)total * os::vm_page_size()) >> 10); ++ st->print("(" UINT64_FORMAT "k free)", ++ ((jlong)(total - used) * os::vm_page_size()) >> 10); ++#endif ++#else st->print(", swap " UINT64_FORMAT "k", ((jlong)si.totalswap * si.mem_unit) >> 10); st->print("(" UINT64_FORMAT "k free)", @@ -4837,13 +4918,16 @@ +#endif + st->cr(); + ++#ifndef _ALLBSD_SOURCE + // meminfo + st->print("\n/proc/meminfo:\n"); + _print_ascii_file("/proc/meminfo", st); st->cr(); ++#endif } -@@ -2333,19 +2560,29 @@ + // Taken from /usr/include/bits/siginfo.h Supposed to be architecture specific +@@ -2333,19 +2643,29 @@ static volatile jint pending_signals[NSIG+1] = { 0 }; // Bsd(POSIX) specific hand shaking semaphore. @@ -4875,7 +4959,7 @@ } static int check_pending_signals(bool wait) { -@@ -2367,7 +2604,7 @@ +@@ -2367,7 +2687,7 @@ do { thread->set_suspend_equivalent(); // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() @@ -4884,7 +4968,7 @@ // were we externally suspended while we were waiting? threadIsSuspended = thread->handle_special_suspend_equivalent_condition(); -@@ -2378,7 +2615,7 @@ +@@ -2378,7 +2698,7 @@ // while suspended because that would surprise the thread that // suspended us. // @@ -4893,7 +4977,7 @@ thread->java_suspend_self(); } -@@ -2422,10 +2659,10 @@ +@@ -2422,10 +2742,10 @@ return; } @@ -4906,7 +4990,7 @@ os::get_temp_directory(), os::current_process_id(), num); unlink(buf); -@@ -2451,9 +2688,14 @@ +@@ -2451,9 +2771,14 @@ // problem. bool os::commit_memory(char* addr, size_t size, bool exec) { int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; @@ -4921,7 +5005,7 @@ } bool os::commit_memory(char* addr, size_t size, size_t alignment_hint, -@@ -2469,36 +2711,27 @@ +@@ -2469,36 +2794,27 @@ } void os::numa_make_global(char *addr, size_t bytes) { @@ -4963,7 +5047,7 @@ } bool os::get_page_info(char *start, page_info* info) { -@@ -2509,6 +2742,7 @@ +@@ -2509,6 +2825,7 @@ return end; } @@ -4971,7 +5055,7 @@ extern "C" void numa_warn(int number, char *where, ...) { } extern "C" void numa_error(char *where) { } -@@ -2610,104 +2844,26 @@ +@@ -2610,104 +2927,26 @@ os::Bsd::numa_tonode_memory_func_t os::Bsd::_numa_tonode_memory; os::Bsd::numa_interleave_memory_func_t os::Bsd::_numa_interleave_memory; unsigned long* os::Bsd::_numa_all_nodes; @@ -5083,7 +5167,7 @@ return os::uncommit_memory(addr, size); } -@@ -2812,6 +2968,9 @@ +@@ -2812,6 +3051,9 @@ static size_t _large_page_size = 0; bool os::large_page_init() { @@ -5093,7 +5177,7 @@ if (!UseLargePages) return false; if (LargePageSizeInBytes) { -@@ -2869,6 +3028,7 @@ +@@ -2869,6 +3111,7 @@ // We optimistically assume the support is available. If later it turns out // not true, VM will automatically switch to use regular page size. return true; @@ -5101,7 +5185,7 @@ } #ifndef SHM_HUGETLB -@@ -3045,7 +3205,7 @@ +@@ -3045,7 +3288,7 @@ } size_t os::read(int fd, void *buf, unsigned int nBytes) { @@ -5110,7 +5194,7 @@ } // TODO-FIXME: reconcile Solaris' os::sleep with the bsd variation. -@@ -3181,6 +3341,44 @@ +@@ -3181,6 +3424,44 @@ // this reason, the code should not be used as default (ThreadPriorityPolicy=0). // It is only used when ThreadPriorityPolicy=1 and requires root privilege. @@ -5155,7 +5239,7 @@ int os::java_to_os_priority[MaxPriority + 1] = { 19, // 0 Entry should never be used -@@ -3198,6 +3396,7 @@ +@@ -3198,6 +3479,7 @@ -5 // 10 MaxPriority }; @@ -5163,7 +5247,7 @@ static int prio_init() { if (ThreadPriorityPolicy == 1) { -@@ -3217,8 +3416,28 @@ +@@ -3217,8 +3499,28 @@ OSReturn os::set_native_priority(Thread* thread, int newpri) { if ( !UseThreadPriorities || ThreadPriorityPolicy == 0 ) return OS_OK; @@ -5192,7 +5276,7 @@ } OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) { -@@ -3228,7 +3447,17 @@ +@@ -3228,7 +3530,17 @@ } errno = 0; @@ -5210,7 +5294,7 @@ return (*priority_ptr != -1 || errno == 0 ? OS_OK : OS_ERR); } -@@ -3338,7 +3567,7 @@ +@@ -3338,7 +3650,7 @@ /* Get signal number to use for suspend/resume */ if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) { int sig = ::strtol(s, 0, 10); @@ -5219,7 +5303,7 @@ SR_signum = sig; } } -@@ -3682,6 +3911,28 @@ +@@ -3682,6 +3994,28 @@ set_signal_handler(SIGFPE, true); set_signal_handler(SIGXFSZ, true); @@ -5248,7 +5332,7 @@ if (libjsig_is_loaded) { // Tell libjsig jvm finishes setting signal handlers (*end_signal_setting)(); -@@ -3702,6 +3953,7 @@ +@@ -3702,6 +4036,7 @@ } } @@ -5256,7 +5340,7 @@ // This is the fastest way to get thread cpu time on Bsd. // Returns cpu time (user+sys) for any thread, not only for current. // POSIX compliant clocks are implemented in the kernels 2.6.16+. -@@ -3716,6 +3968,7 @@ +@@ -3716,6 +4051,7 @@ return (tp.tv_sec * SEC_IN_NANOSECS) + tp.tv_nsec; } @@ -5264,7 +5348,7 @@ ///// // glibc on Bsd platform uses non-documented flag -@@ -3937,13 +4190,13 @@ +@@ -3937,13 +4273,13 @@ _initial_pid = (java_launcher_pid > 0) ? java_launcher_pid : getpid(); @@ -5280,7 +5364,7 @@ if (Bsd::page_size() == -1) { fatal(err_msg("os_bsd.cpp: os::init: sysconf failed (%s)", strerror(errno))); -@@ -3957,7 +4210,16 @@ +@@ -3957,7 +4293,16 @@ Bsd::clock_init(); initial_time_count = os::elapsed_counter(); @@ -5298,7 +5382,7 @@ } // To install functions for atexit system call -@@ -3970,7 +4232,9 @@ +@@ -3970,7 +4315,9 @@ // this is called _after_ the global arguments have been parsed jint os::init_2(void) { @@ -5308,7 +5392,7 @@ // Allocate a single page and mark it as readable for safepoint polling address polling_page = (address) ::mmap(NULL, Bsd::page_size(), PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); -@@ -4028,6 +4292,7 @@ +@@ -4028,6 +4375,7 @@ JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes, vm_page_size())); @@ -5316,7 +5400,7 @@ Bsd::capture_initial_stack(JavaThread::stack_size_at_create()); Bsd::libpthread_init(); -@@ -4050,6 +4315,7 @@ +@@ -4050,6 +4398,7 @@ UseNUMA = true; } } @@ -5324,7 +5408,7 @@ if (MaxFDLimit) { // set the number of file descriptors to max. print out error -@@ -4061,6 +4327,14 @@ +@@ -4061,6 +4410,14 @@ perror("os::init_2 getrlimit failed"); } else { nbr_files.rlim_cur = nbr_files.rlim_max; @@ -5339,7 +5423,7 @@ status = setrlimit(RLIMIT_NOFILE, &nbr_files); if (status != 0) { if (PrintMiscellaneous && (Verbose || WizardMode)) -@@ -4069,8 +4343,10 @@ +@@ -4069,8 +4426,10 @@ } } @@ -5350,11 +5434,25 @@ // at-exit methods are called in the reverse order of their registration. // atexit functions are called on return from main or as a result of a -@@ -4114,11 +4390,15 @@ +@@ -4114,11 +4473,29 @@ }; int os::active_processor_count() { +#ifdef _ALLBSD_SOURCE ++#ifdef __FreeBSD__ ++ int online_cpus = 0; ++#if __FreeBSD_version > 700109 ++ std::bitset<CPU_SETSIZE> mask; ++ assert(sizeof(mask) == sizeof(cpuset_t), "Invalid bitset for cpuset_t"); ++ if (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, sizeof(mask), ++ reinterpret_cast<cpuset_t*>(&mask)) == 0) ++ online_cpus = mask.count(); ++#else ++ online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN); ++#endif ++ if (online_cpus > 0 && online_cpus <= _processor_count) ++ return online_cpus; ++#endif + return _processor_count; +#else // Bsd doesn't yet have a (official) notion of processor sets, @@ -5366,7 +5464,7 @@ } bool os::distribute_processes(uint length, uint* distribution) { -@@ -4160,6 +4440,9 @@ +@@ -4160,6 +4537,9 @@ int os::Bsd::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime) { @@ -5376,7 +5474,7 @@ if (is_NPTL()) { return pthread_cond_timedwait(_cond, _mutex, _abstime); } else { -@@ -4175,6 +4458,7 @@ +@@ -4175,6 +4555,7 @@ #endif // IA64 return status; } @@ -5384,7 +5482,7 @@ } //////////////////////////////////////////////////////////////////////////////// -@@ -4322,14 +4606,14 @@ +@@ -4322,14 +4703,14 @@ int o_delete = (oflag & O_DELETE); oflag = oflag & ~O_DELETE; @@ -5403,7 +5501,7 @@ if (ret != -1) { if ((st_mode & S_IFMT) == S_IFDIR) { -@@ -4386,17 +4670,17 @@ +@@ -4386,17 +4767,17 @@ if (!rewrite_existing) { oflags |= O_EXCL; } @@ -5424,7 +5522,7 @@ } // This code originates from JDK's sysAvailable -@@ -4405,10 +4689,10 @@ +@@ -4405,10 +4786,10 @@ int os::available(int fd, jlong *bytes) { jlong cur, end; int mode; @@ -5438,7 +5536,7 @@ if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) { /* * XXX: is the following call interruptible? If so, this might -@@ -4422,11 +4706,11 @@ +@@ -4422,11 +4803,11 @@ } } } @@ -5453,7 +5551,7 @@ return 0; } *bytes = end - cur; -@@ -4489,6 +4773,7 @@ +@@ -4489,6 +4870,7 @@ return munmap(addr, bytes) == 0; } @@ -5461,7 +5559,7 @@ static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time); static clockid_t thread_cpu_clockid(Thread* thread) { -@@ -4500,6 +4785,7 @@ +@@ -4500,6 +4882,7 @@ assert(rc == 0, "pthread_getcpuclockid is expected to return 0 code"); return clockid; } @@ -5469,7 +5567,7 @@ // current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool) // are used by JVM M&M and JVMTI to get user+sys or user CPU time -@@ -4509,39 +4795,71 @@ +@@ -4509,39 +4892,71 @@ // the fast estimate available on the platform. jlong os::current_thread_cpu_time() { @@ -5541,7 +5639,7 @@ // // -1 on error. // -@@ -4631,6 +4949,7 @@ +@@ -4631,6 +5046,7 @@ return (jlong)user_time * (1000000000 / clock_tics_per_sec); } } @@ -5549,21 +5647,21 @@ void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) { info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits -@@ -4647,7 +4966,13 @@ +@@ -4647,7 +5063,13 @@ } bool os::is_thread_cpu_time_supported() { +#ifdef __APPLE__ -+ return true; + return true; +#elif defined(_ALLBSD_SOURCE) + return false; +#else - return true; ++ return true; +#endif } // System loadavg support. Returns -1 if load average cannot be obtained. -@@ -4780,7 +5105,7 @@ +@@ -4780,7 +5202,7 @@ // abstime will be the absolute timeout time // TODO: replace compute_abstime() with unpackTime() @@ -5572,7 +5670,7 @@ if (millis < 0) millis = 0; struct timeval now; int status = gettimeofday(&now, NULL); -@@ -4832,7 +5157,7 @@ +@@ -4832,7 +5254,7 @@ status = pthread_cond_wait(_cond, _mutex); // for some reason, under 2.7 lwp_cond_wait() may return ETIME ... // Treat this the same as if the wait was interrupted @@ -5581,7 +5679,7 @@ assert_status(status == 0 || status == EINTR, status, "cond_wait"); } -- _nParked ; -@@ -4890,10 +5215,10 @@ +@@ -4890,10 +5312,10 @@ pthread_cond_init (_cond, NULL) ; } assert_status(status == 0 || status == EINTR || @@ -5594,7 +5692,7 @@ // We consume and ignore EINTR and spurious wakeups. } --_nParked ; -@@ -4985,7 +5310,7 @@ +@@ -4985,7 +5407,7 @@ * years from "now". */ @@ -5603,7 +5701,7 @@ assert (time > 0, "convertTime"); struct timeval now; -@@ -5045,7 +5370,7 @@ +@@ -5045,7 +5467,7 @@ } // Next, demultiplex/decode time arguments @@ -5612,7 +5710,7 @@ if (time < 0 || (isAbsolute && time == 0) ) { // don't wait at all return; } -@@ -5099,7 +5424,7 @@ +@@ -5099,7 +5521,7 @@ } } assert_status(status == 0 || status == EINTR || @@ -5621,7 +5719,7 @@ status, "cond_timedwait"); #ifdef ASSERT -@@ -5142,14 +5467,12 @@ +@@ -5142,14 +5564,12 @@ } @@ -5641,7 +5739,7 @@ #endif // Run the specified command in a separate process. Return its exit value, -@@ -5164,8 +5487,7 @@ +@@ -5164,8 +5584,7 @@ // separate process to execve. Make a direct syscall to fork process. // On IA64 there's no fork syscall, we have to use fork() and hope for // the best... @@ -5651,7 +5749,7 @@ if (pid < 0) { // fork failed -@@ -5181,8 +5503,7 @@ +@@ -5181,8 +5600,7 @@ // in the new process, so make a system call directly. // IA64 should use normal execve() from glibc to match the glibc fork() // above. @@ -5872,7 +5970,16 @@ os::fork_and_exec(buf); --- hotspot/src/os/posix/launcher/java_md.c +++ hotspot/src/os/posix/launcher/java_md.c -@@ -41,14 +41,21 @@ +@@ -35,20 +35,30 @@ + #include <sys/stat.h> + #include <unistd.h> + #include <sys/types.h> ++#ifndef _SC_PHYS_PAGES ++#include <sys/sysctl.h> ++#endif + + #ifndef GAMMA + #include "manifest_info.h" #include "version_comp.h" #endif @@ -5895,7 +6002,7 @@ #ifndef GAMMA /* launcher.make defines ARCH */ /* -@@ -89,7 +96,7 @@ +@@ -89,7 +99,7 @@ * A collection of useful strings. One should think of these as #define * entries, but actual strings can be more efficient (with many compilers). */ @@ -5904,7 +6011,7 @@ static const char *system_dir = "/usr/java"; static const char *user_dir = "/java"; #else /* Solaris */ -@@ -423,10 +430,10 @@ +@@ -423,10 +433,10 @@ * If not on Solaris, assume only a single LD_LIBRARY_PATH * variable. */ @@ -5917,7 +6024,7 @@ /* * On linux, if a binary is running as sgid or suid, glibc sets * LD_LIBRARY_PATH to the empty string for security purposes. (In -@@ -442,6 +449,22 @@ +@@ -442,6 +452,22 @@ if((getgid() != getegid()) || (getuid() != geteuid()) ) { return; } @@ -5940,7 +6047,7 @@ #endif /* runpath contains current effective LD_LIBRARY_PATH setting */ -@@ -450,7 +473,7 @@ +@@ -450,7 +476,7 @@ new_runpath = JLI_MemAlloc( ((runpath!=NULL)?strlen(runpath):0) + 2*strlen(jrepath) + 2*strlen(arch) + strlen(jvmpath) + 52); @@ -5949,7 +6056,7 @@ /* -@@ -465,7 +488,7 @@ +@@ -465,7 +491,7 @@ /* jvmpath, ((running != wanted)?((wanted==64)?"/"LIBARCH64NAME:"/.."):""), */ @@ -5958,7 +6065,16 @@ "%s:" "%s/lib/%s:" "%s/../lib/%s", -@@ -792,7 +815,7 @@ +@@ -503,7 +529,7 @@ + * LD_LIBRARY_PATH. Note that this prevents any possible infinite + * loop of execv() because we test for the prefix, above. + */ +- if (runpath != 0) { ++ if (runpath != 0 && runpath[0] != '\0') { + strcat(new_runpath, ":"); + strcat(new_runpath, runpath); + } +@@ -792,7 +818,7 @@ jboolean GetApplicationHome(char *buf, jint bufsize) { @@ -5967,7 +6083,7 @@ char *execname = GetExecname(); if (execname) { strncpy(buf, execname, bufsize-1); -@@ -961,9 +984,13 @@ +@@ -961,9 +987,13 @@ } } } @@ -5982,7 +6098,7 @@ char buf[PATH_MAX+1]; int len = readlink(self, buf, PATH_MAX); if (len >= 0) { -@@ -971,7 +998,7 @@ +@@ -971,7 +1001,7 @@ exec_path = JLI_StringDup(buf); } } @@ -5991,7 +6107,44 @@ { /* Not implemented */ } -@@ -1175,7 +1202,7 @@ +@@ -1069,6 +1099,7 @@ + /* Compute physical memory by asking the OS */ + uint64_t + physical_memory(void) { ++#ifdef _SC_PHYS_PAGES + const uint64_t pages = (uint64_t) sysconf(_SC_PHYS_PAGES); + const uint64_t page_size = (uint64_t) sysconf(_SC_PAGESIZE); + const uint64_t result = pages * page_size; +@@ -1080,6 +1111,28 @@ + " physical memory: " UINT64_FORMAT " (%.3fGB)\n", + pages, page_size, result, result / (double) GB); + } ++#else ++#ifdef HW_PHYSMEM64 ++ int64_t physmem; ++ int name[2] = { CTL_HW, HW_PHYSMEM64 }; ++#else ++ unsigned long physmem; ++ int name[2] = { CTL_HW, HW_PHYSMEM }; ++#endif ++ size_t physmem_len = sizeof(physmem); ++ uint64_t result; ++# define UINT64_FORMAT "%" PRIu64 ++ ++ if (sysctl(name, 2, &physmem, &physmem_len, NULL, 0) == -1) ++ physmem = 256 * MB; ++ ++ result = (uint64_t)physmem; ++ ++ if (_launcher_debug) { ++ printf("physical memory: " UINT64_FORMAT " (%.3fGB)\n", ++ result, result / (double) GB); ++ } ++#endif + return result; + } + +@@ -1175,7 +1228,7 @@ #endif /* __sun && i586 */ @@ -6000,7 +6153,7 @@ /* * A utility method for asking the CPU about itself. -@@ -1240,7 +1267,7 @@ +@@ -1240,7 +1293,7 @@ #endif } @@ -6009,7 +6162,7 @@ #ifdef i586 /* -@@ -1452,6 +1479,39 @@ +@@ -1452,6 +1505,39 @@ #endif /* __linux__ && i586 */ @@ -6038,7 +6191,7 @@ + } + } + if (_launcher_debug) { -+ printf("linux_" LIBARCHNAME "_ServerClassMachine: %s\n", ++ printf("bsd_" LIBARCHNAME "_ServerClassMachine: %s\n", + (result == JNI_TRUE ? "true" : "false")); + } + return result; @@ -6049,7 +6202,7 @@ /* Dispatch to the platform-specific definition of "server-class" */ jboolean ServerClassMachine(void) { -@@ -1466,6 +1526,8 @@ +@@ -1466,6 +1552,8 @@ result = solaris_i586_ServerClassMachine(); #elif defined(__linux__) && defined(i586) result = linux_i586_ServerClassMachine(); @@ -6058,7 +6211,16 @@ #else if (_launcher_debug) { printf("ServerClassMachine: returns default value of %s\n", -@@ -1821,7 +1883,7 @@ +@@ -1606,7 +1694,7 @@ + while (dp != NULL) { + cp = strchr(dp, (int)':'); + if (cp != NULL) +- *cp = (char)NULL; ++ *cp = '\0'; + if ((target = ProcessDir(info, dp)) != NULL) + break; + dp = cp; +@@ -1821,7 +1909,7 @@ int ContinueInNewThread(int (JNICALL *continuation)(void *), jlong stack_size, void * args) { int rslt; @@ -6067,6 +6229,17 @@ pthread_t tid; pthread_attr_t attr; pthread_attr_init(&attr); +@@ -1865,8 +1953,8 @@ + #define MAX_PID_STR_SZ 20 + + void SetJavaLauncherPlatformProps() { +- /* Linux only */ +-#ifdef __linux__ ++ /* Linux and BSDs only */ ++#if defined(__linux__) || defined(_ALLBSD_SOURCE) + const char *substr = "-Dsun.java.launcher.pid="; + char *pid_prop_str = (char *)JLI_MemAlloc(strlen(substr) + MAX_PID_STR_SZ + 1); + sprintf(pid_prop_str, "%s%d", substr, getpid()); --- hotspot/src/os/posix/launcher/launcher.script +++ hotspot/src/os/posix/launcher/launcher.script @@ -1,4 +1,4 @@ @@ -14099,11 +14272,34 @@ #endif /* __sun */ -#ifdef __linux -+#if defined(__linux__) || defined(_ALLBSD_SOURCE) ++#if defined(__linux__) /* * On linux, if a binary is running as sgid or suid, glibc sets * LD_LIBRARY_PATH to the empty string for security purposes. (In -@@ -431,7 +465,7 @@ +@@ -423,6 +457,22 @@ + if((getgid() != getegid()) || (getuid() != geteuid()) ) { + return; + } ++#elif defined(_ALLBSD_SOURCE) ++ /* ++ * On BSD, if a binary is running as sgid or suid, libc sets ++ * LD_LIBRARY_PATH to the empty string for security purposes. (In ++ * contrast, on Solaris the LD_LIBRARY_PATH variable for a ++ * privileged binary does not lose its settings; but the dynamic ++ * linker does apply more scrutiny to the path.) The launcher uses ++ * the value of LD_LIBRARY_PATH to prevent an exec loop. ++ * Therefore, if we are running sgid or suid, this function's ++ * setting of LD_LIBRARY_PATH will be ineffective and we should ++ * return from the function now. Getting the right libraries to ++ * be found must be handled through other mechanisms. ++ */ ++ if(issetugid()) { ++ return; ++ } + #endif + + /* runpath contains current effective LD_LIBRARY_PATH setting */ +@@ -431,7 +481,7 @@ new_runpath = JLI_MemAlloc( ((runpath!=NULL)?strlen(runpath):0) + 2*strlen(jrepath) + 2*strlen(arch) + strlen(jvmpath) + 52); @@ -14112,7 +14308,7 @@ /* -@@ -446,7 +480,7 @@ +@@ -446,7 +496,7 @@ /* jvmpath, ((running != wanted)?((wanted==64)?"/"LIBARCH64NAME:"/.."):""), */ @@ -14121,7 +14317,16 @@ "%s:" "%s/lib/%s:" "%s/../lib/%s", -@@ -878,9 +912,13 @@ +@@ -721,7 +771,7 @@ + jboolean + GetApplicationHome(char *buf, jint bufsize) + { +-#ifdef __linux__ ++#if defined(__linux__) || defined(_ALLBSD_SOURCE) + char *execname = GetExecname(); + if (execname) { + strncpy(buf, execname, bufsize-1); +@@ -878,9 +928,13 @@ } } } @@ -14136,7 +14341,7 @@ char buf[PATH_MAX+1]; int len = readlink(self, buf, PATH_MAX); if (len >= 0) { -@@ -888,7 +926,7 @@ +@@ -888,7 +942,7 @@ exec_path = JLI_StringDup(buf); } } @@ -14145,7 +14350,7 @@ { /* Not implemented */ } -@@ -977,6 +1015,7 @@ +@@ -977,6 +1031,7 @@ /* Compute physical memory by asking the OS */ uint64_t physical_memory(void) { @@ -14153,7 +14358,7 @@ const uint64_t pages = (uint64_t) sysconf(_SC_PHYS_PAGES); const uint64_t page_size = (uint64_t) sysconf(_SC_PAGESIZE); const uint64_t result = pages * page_size; -@@ -988,6 +1027,28 @@ +@@ -988,6 +1043,28 @@ " physical memory: " UINT64_FORMAT " (%.3fGB)\n", pages, page_size, result, result / (double) GB); } @@ -14182,7 +14387,7 @@ return result; } -@@ -1083,7 +1144,7 @@ +@@ -1083,7 +1160,7 @@ #endif /* __sun && i586 */ @@ -14191,7 +14396,74 @@ /* * A utility method for asking the CPU about itself. -@@ -1692,9 +1753,23 @@ +@@ -1148,7 +1225,7 @@ + #endif + } + +-#endif /* __linux__ && i586 */ ++#endif /* (__linux__ || _ALLBSD_SOURCE) && i586 */ + + #ifdef i586 + /* +@@ -1360,6 +1437,39 @@ + + #endif /* __linux__ && i586 */ + ++#if defined(_ALLBSD_SOURCE) && defined(i586) ++ ++/* The definition of a server-class machine for bsd-i586 */ ++jboolean ++bsd_i586_ServerClassMachine(void) { ++ jboolean result = JNI_FALSE; ++ /* How big is a server class machine? */ ++ const unsigned long server_processors = 2UL; ++ const uint64_t server_memory = 2UL * GB; ++ /* ++ * We seem not to get our full complement of memory. ++ * We allow some part (1/8?) of the memory to be "missing", ++ * based on the sizes of DIMMs, and maybe graphics cards. ++ */ ++ const uint64_t missing_memory = 256UL * MB; ++ const uint64_t actual_memory = physical_memory(); ++ ++ /* Is this a server class machine? */ ++ if (actual_memory >= (server_memory - missing_memory)) { ++ const unsigned long actual_processors = physical_processors(); ++ if (actual_processors >= server_processors) { ++ result = JNI_TRUE; ++ } ++ } ++ if (_launcher_debug) { ++ printf("bsd_" LIBARCHNAME "_ServerClassMachine: %s\n", ++ (result == JNI_TRUE ? "true" : "false")); ++ } ++ return result; ++} ++ ++#endif /* _ALLBSD_SOURCE && i586 */ ++ + /* Dispatch to the platform-specific definition of "server-class" */ + jboolean + ServerClassMachine(void) { +@@ -1374,6 +1484,8 @@ + result = solaris_i586_ServerClassMachine(); + #elif defined(__linux__) && defined(i586) + result = linux_i586_ServerClassMachine(); ++#elif defined(_ALLBSD_SOURCE) && defined(i586) ++ result = bsd_i586_ServerClassMachine(); + #else + if (_launcher_debug) { + printf("ServerClassMachine: returns default value of %s\n", +@@ -1514,7 +1626,7 @@ + while (dp != NULL) { + cp = strchr(dp, (int)':'); + if (cp != NULL) +- *cp = (char)NULL; ++ *cp = '\0'; + if ((target = ProcessDir(info, dp)) != NULL) + break; + dp = cp; +@@ -1692,9 +1804,29 @@ return(borrowed_unsetenv(name)); } @@ -14202,9 +14474,15 @@ +int64_t +CounterGet() +{ ++#ifdef __FreeBSD__ ++ struct timespec tp; ++ clock_gettime(CLOCK_MONOTONIC, &tp); ++ return (uint64_t)tp.tv_sec * 1000000 + tp.tv_nsec / 1000; ++#else + struct timeval tv; + gettimeofday(&tv, NULL); -+ return (tv.tv_sec * 1000) + tv.tv_usec; ++ return (uint64_t)tv.tv_sec * 1000000 + tv.tv_usec; ++#endif +} +#endif + @@ -14216,7 +14494,7 @@ static void* hSplashLib = NULL; -@@ -1722,13 +1797,15 @@ +@@ -1722,13 +1854,15 @@ return "%lld"; } @@ -14234,7 +14512,23 @@ pthread_t tid; pthread_attr_t attr; pthread_attr_init(&attr); -@@ -1765,13 +1842,11 @@ +@@ -1741,7 +1875,7 @@ + if (pthread_create(&tid, &attr, (void *(*)(void*))continuation, (void*)args) == 0) { + void * tmp; + pthread_join(tid, &tmp); +- rslt = (int)tmp; ++ rslt = (int)(intptr_t)tmp; + } else { + /* + * Continue execution in current thread if for some reason (e.g. out of +@@ -1759,25 +1893,23 @@ + if (thr_create(NULL, stack_size, (void *(*)(void *))continuation, args, flags, &tid) == 0) { + void * tmp; + thr_join(tid, NULL, &tmp); +- rslt = (int)tmp; ++ rslt = (int)(intptr_t)tmp; + } else { + /* See above. Continue in current thread if thr_create() failed */ rslt = continuation(args); } #endif @@ -14251,6 +14545,14 @@ /* Coarse estimation of number of digits assuming the worst case is a 64-bit pid. */ #define MAX_PID_STR_SZ 20 + void SetJavaLauncherPlatformProps() { +- /* Linux only */ +-#ifdef __linux__ ++ /* Linux and BSDs only */ ++#if defined(__linux__) || defined(_ALLBSD_SOURCE) + const char *substr = "-Dsun.java.launcher.pid="; + char *pid_prop_str = (char *)JLI_MemAlloc(strlen(substr) + MAX_PID_STR_SZ + 1); + sprintf(pid_prop_str, "%s%d", substr, getpid()); --- jdk/src/solaris/bin/java_md.h +++ jdk/src/solaris/bin/java_md.h @@ -58,10 +58,14 @@ @@ -16453,17 +16755,26 @@ clk_tck = 100; #endif if (clk_tck == -1) { -@@ -244,32 +310,70 @@ +@@ -244,32 +310,79 @@ Java_com_sun_management_UnixOperatingSystem_getFreePhysicalMemorySize (JNIEnv *env, jobject mbean) { +#if defined (__FreeBSD__) -+ int npages; ++ static const char *vm_stats[] = { ++ "vm.stats.vm.v_free_count", ++ "vm.stats.vm.v_cache_count", ++ /* "vm.stats.vm.v_inactive_count", */ ++ NULL ++ }; + size_t size; -+ size = sizeof(npages); -+ if (sysctlbyname("vm.stats.vm.v_free_count", &npages, &size, NULL, 0) == - 1) -+ return (0); -+ return ((jlong)npages * page_size); ++ jlong free_pages; ++ u_int i, npages; ++ for (i = 0, free_pages = 0, size = sizeof(npages); vm_stats[i] != NULL; i++) { ++ if (sysctlbyname(vm_stats[i], &npages, &size, NULL, 0) == -1) ++ return 0; ++ free_pages += npages; ++ } ++ return (free_pages * page_size); +#elif defined(_ALLBSD_SOURCE) + // throw_internal_error(env, "Unimplemented in BSD"); + return (128 * MB); @@ -16524,7 +16835,7 @@ // iterate through directory entries, skipping '.' and '..' // each entry represents an open file descriptor. -@@ -282,6 +386,7 @@ +@@ -282,6 +395,7 @@ closedir(dirp); // subtract by 1 which was the fd open for this implementation return (fds - 1); |