Wed, 05 May 2010 16:39:47 -0700
Merge
src/os/linux/vm/os_linux.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/make/hotspot_distro Mon May 03 16:31:07 2010 -0400 1.2 +++ b/make/hotspot_distro Wed May 05 16:39:47 2010 -0700 1.3 @@ -28,5 +28,5 @@ 1.4 1.5 # Don't put quotes (fail windows build). 1.6 HOTSPOT_VM_DISTRO=Java HotSpot(TM) 1.7 -COMPANY_NAME=Sun Microsystems, Inc. 1.8 +COMPANY_NAME=Oracle Corporation 1.9 PRODUCT_NAME=Java(TM) Platform SE
2.1 --- a/src/os/linux/vm/attachListener_linux.cpp Mon May 03 16:31:07 2010 -0400 2.2 +++ b/src/os/linux/vm/attachListener_linux.cpp Wed May 05 16:39:47 2010 -0700 2.3 @@ -461,7 +461,7 @@ 2.4 if (init_at_startup() || is_initialized()) { 2.5 return false; // initialized at startup or already initialized 2.6 } 2.7 - char fn[128]; 2.8 + char fn[PATH_MAX+1]; 2.9 sprintf(fn, ".attach_pid%d", os::current_process_id()); 2.10 int ret; 2.11 struct stat64 st;
3.1 --- a/src/os/linux/vm/os_linux.cpp Mon May 03 16:31:07 2010 -0400 3.2 +++ b/src/os/linux/vm/os_linux.cpp Wed May 05 16:39:47 2010 -0700 3.3 @@ -2305,7 +2305,7 @@ 3.4 return; 3.5 } 3.6 3.7 - char buf[40]; 3.8 + char buf[PATH_MAX+1]; 3.9 int num = Atomic::add(1, &cnt); 3.10 3.11 snprintf(buf, sizeof(buf), "%s/hs-vm-%d-%d",
4.1 --- a/src/os/solaris/vm/attachListener_solaris.cpp Mon May 03 16:31:07 2010 -0400 4.2 +++ b/src/os/solaris/vm/attachListener_solaris.cpp Wed May 05 16:39:47 2010 -0700 4.3 @@ -592,7 +592,7 @@ 4.4 if (init_at_startup() || is_initialized()) { 4.5 return false; // initialized at startup or already initialized 4.6 } 4.7 - char fn[128]; 4.8 + char fn[PATH_MAX+1]; 4.9 sprintf(fn, ".attach_pid%d", os::current_process_id()); 4.10 int ret; 4.11 struct stat64 st;
5.1 --- a/src/share/vm/oops/methodOop.cpp Mon May 03 16:31:07 2010 -0400 5.2 +++ b/src/share/vm/oops/methodOop.cpp Wed May 05 16:39:47 2010 -0700 5.3 @@ -1114,6 +1114,20 @@ 5.4 return ( a < b ? -1 : (a == b ? 0 : 1)); 5.5 } 5.6 5.7 + // We implement special compare versions for narrow oops to avoid 5.8 + // testing for UseCompressedOops on every comparison. 5.9 + static int method_compare_narrow(narrowOop* a, narrowOop* b) { 5.10 + methodOop m = (methodOop)oopDesc::load_decode_heap_oop(a); 5.11 + methodOop n = (methodOop)oopDesc::load_decode_heap_oop(b); 5.12 + return m->name()->fast_compare(n->name()); 5.13 + } 5.14 + 5.15 + static int method_compare_narrow_idempotent(narrowOop* a, narrowOop* b) { 5.16 + int i = method_compare_narrow(a, b); 5.17 + if (i != 0) return i; 5.18 + return ( a < b ? -1 : (a == b ? 0 : 1)); 5.19 + } 5.20 + 5.21 typedef int (*compareFn)(const void*, const void*); 5.22 } 5.23 5.24 @@ -1166,7 +1180,7 @@ 5.25 5.26 // Use a simple bubble sort for small number of methods since 5.27 // qsort requires a functional pointer call for each comparison. 5.28 - if (UseCompressedOops || length < 8) { 5.29 + if (length < 8) { 5.30 bool sorted = true; 5.31 for (int i=length-1; i>0; i--) { 5.32 for (int j=0; j<i; j++) { 5.33 @@ -1182,10 +1196,10 @@ 5.34 sorted = true; 5.35 } 5.36 } else { 5.37 - // XXX This doesn't work for UseCompressedOops because the compare fn 5.38 - // will have to decode the methodOop anyway making it not much faster 5.39 - // than above. 5.40 - compareFn compare = (compareFn) (idempotent ? method_compare_idempotent : method_compare); 5.41 + compareFn compare = 5.42 + (UseCompressedOops ? 5.43 + (compareFn) (idempotent ? method_compare_narrow_idempotent : method_compare_narrow): 5.44 + (compareFn) (idempotent ? method_compare_idempotent : method_compare)); 5.45 qsort(methods->base(), length, heapOopSize, compare); 5.46 } 5.47
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/test/runtime/6925573/SortMethodsTest.java Wed May 05 16:39:47 2010 -0700 6.3 @@ -0,0 +1,190 @@ 6.4 +/* 6.5 + * Copyright 2008-2010 Sun Microsystems, Inc. All Rights Reserved. 6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.7 + * 6.8 + * This code is free software; you can redistribute it and/or modify it 6.9 + * under the terms of the GNU General Public License version 2 only, as 6.10 + * published by the Free Software Foundation. 6.11 + * 6.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 6.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 6.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 6.15 + * version 2 for more details (a copy is included in the LICENSE file that 6.16 + * accompanied this code). 6.17 + * 6.18 + * You should have received a copy of the GNU General Public License version 6.19 + * 2 along with this work; if not, write to the Free Software Foundation, 6.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 6.21 + * 6.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 6.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 6.24 + * have any questions. 6.25 + * 6.26 + */ 6.27 + 6.28 +import java.io.ByteArrayOutputStream; 6.29 +import java.io.IOException; 6.30 +import java.io.OutputStream; 6.31 +import java.io.PrintWriter; 6.32 +import java.io.StringWriter; 6.33 + 6.34 +import java.lang.reflect.Method; 6.35 +import java.net.URI; 6.36 +import java.util.Arrays; 6.37 +import java.util.Vector; 6.38 + 6.39 +import javax.tools.Diagnostic; 6.40 +import javax.tools.DiagnosticCollector; 6.41 +import javax.tools.FileObject; 6.42 +import javax.tools.ForwardingJavaFileManager; 6.43 +import javax.tools.JavaCompiler; 6.44 +import javax.tools.JavaCompiler.CompilationTask; 6.45 +import javax.tools.JavaFileManager; 6.46 +import javax.tools.JavaFileObject; 6.47 +import javax.tools.JavaFileObject.Kind; 6.48 +import javax.tools.SimpleJavaFileObject; 6.49 +import javax.tools.StandardJavaFileManager; 6.50 +import javax.tools.ToolProvider; 6.51 + 6.52 +/* 6.53 + * @test SortMethodsTest 6.54 + * @bug 6925573 6.55 + * @summary verify that class loading does not need quadratic time with regard to the number of class 6.56 +methods. 6.57 + * @run main SortMethodsTest 6.58 + * @author volker.simonis@gmail.com 6.59 +*/ 6.60 + 6.61 +public class SortMethodsTest { 6.62 + 6.63 + static String createClass(String name, int nrOfMethods) { 6.64 + StringWriter sw = new StringWriter(); 6.65 + PrintWriter pw = new PrintWriter(sw); 6.66 + pw.println("public class " + name + "{"); 6.67 + for (int i = 0; i < nrOfMethods; i++) { 6.68 + pw.println(" public void m" + i + "() {}"); 6.69 + } 6.70 + pw.println(" public static String sayHello() {"); 6.71 + pw.println(" return \"Hello from class \" + " + name + 6.72 + ".class.getName() + \" with \" + " + name + 6.73 + ".class.getDeclaredMethods().length + \" methods\";"); 6.74 + pw.println(" }"); 6.75 + pw.println("}"); 6.76 + pw.close(); 6.77 + return sw.toString(); 6.78 + } 6.79 + 6.80 + public static void main(String args[]) { 6.81 + 6.82 + JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); 6.83 + DiagnosticCollector<JavaFileObject> diags = new DiagnosticCollector<JavaFileObject>(); 6.84 + final String cName = new String("ManyMethodsClass"); 6.85 + Vector<Long> results = new Vector<Long>(); 6.86 + 6.87 + for (int i = 6; i < 600000; i*=10) { 6.88 + String klass = createClass(cName, i); 6.89 + JavaMemoryFileObject file = new JavaMemoryFileObject(cName, klass); 6.90 + MemoryFileManager mfm = new MemoryFileManager(comp.getStandardFileManager(diags, null, null), file); 6.91 + CompilationTask task = comp.getTask(null, mfm, diags, null, null, Arrays.asList(file)); 6.92 + 6.93 + if (task.call()) { 6.94 + try { 6.95 + MemoryClassLoader mcl = new MemoryClassLoader(file); 6.96 + long start = System.nanoTime(); 6.97 + Class<? extends Object> c = Class.forName(cName, true, mcl); 6.98 + long end = System.nanoTime(); 6.99 + results.add(end - start); 6.100 + Method m = c.getDeclaredMethod("sayHello", new Class[0]); 6.101 + String ret = (String)m.invoke(null, new Object[0]); 6.102 + System.out.println(ret + " (loaded and resloved in " + (end - start) + "ns)"); 6.103 + } catch (Exception e) { 6.104 + System.err.println(e); 6.105 + } 6.106 + } 6.107 + else { 6.108 + System.out.println(klass); 6.109 + System.out.println(); 6.110 + for (Diagnostic diag : diags.getDiagnostics()) { 6.111 + System.out.println(diag.getCode() + "\n" + diag.getKind() + "\n" + diag.getPosition()); 6.112 + System.out.println(diag.getSource() + "\n" + diag.getMessage(null)); 6.113 + } 6.114 + } 6.115 + } 6.116 + 6.117 + long lastRatio = 0; 6.118 + for (int i = 2; i < results.size(); i++) { 6.119 + long normalized1 = Math.max(results.get(i-1) - results.get(0), 1); 6.120 + long normalized2 = Math.max(results.get(i) - results.get(0), 1); 6.121 + long ratio = normalized2/normalized1; 6.122 + lastRatio = ratio; 6.123 + System.out.println("10 x more methods requires " + ratio + " x more time"); 6.124 + } 6.125 + // The following is just vague estimation but seems to work on current x86_64 and sparcv9 machines 6.126 + if (lastRatio > 80) { 6.127 + throw new RuntimeException("ATTENTION: it seems that class loading needs quadratic time with regard to the number of class methods!!!"); 6.128 + } 6.129 + } 6.130 +} 6.131 + 6.132 +class JavaMemoryFileObject extends SimpleJavaFileObject { 6.133 + 6.134 + private final String code; 6.135 + private ByteArrayOutputStream byteCode; 6.136 + 6.137 + JavaMemoryFileObject(String name, String code) { 6.138 + super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension), Kind.SOURCE); 6.139 + this.code = code; 6.140 + } 6.141 + 6.142 + @Override 6.143 + public CharSequence getCharContent(boolean ignoreEncodingErrors) { 6.144 + return code; 6.145 + } 6.146 + 6.147 + @Override 6.148 + public OutputStream openOutputStream() { 6.149 + byteCode = new ByteArrayOutputStream(); 6.150 + return byteCode; 6.151 + } 6.152 + 6.153 + byte[] getByteCode() { 6.154 + return byteCode.toByteArray(); 6.155 + } 6.156 +} 6.157 + 6.158 +class MemoryClassLoader extends ClassLoader { 6.159 + 6.160 + private final JavaMemoryFileObject jfo; 6.161 + 6.162 + public MemoryClassLoader(JavaMemoryFileObject jfo) { 6.163 + this.jfo = jfo; 6.164 + } 6.165 + 6.166 + public Class findClass(String name) { 6.167 + byte[] b = jfo.getByteCode(); 6.168 + return defineClass(name, b, 0, b.length); 6.169 + } 6.170 +} 6.171 + 6.172 +class MemoryFileManager extends ForwardingJavaFileManager<JavaFileManager> { 6.173 + 6.174 + private final JavaFileObject jfo; 6.175 + 6.176 + public MemoryFileManager(StandardJavaFileManager jfm, JavaFileObject jfo) { 6.177 + super(jfm); 6.178 + this.jfo = jfo; 6.179 + } 6.180 + 6.181 + @Override 6.182 + public FileObject getFileForInput(Location location, String packageName, 6.183 + String relativeName) throws IOException { 6.184 + return jfo; 6.185 + } 6.186 + 6.187 + @Override 6.188 + public JavaFileObject getJavaFileForOutput(Location location, String qualifiedName, 6.189 + Kind kind, FileObject outputFile) throws IOException { 6.190 + return jfo; 6.191 + } 6.192 + 6.193 +}