changeset 9182:c433aad055b9

Merge
author Christos Kotselidis <christos.kotselidis@oracle.com>
date Wed, 17 Apr 2013 22:59:36 +0200
parents e1f024e02597 (current diff) 4e6df9021a59 (diff)
children 34eba4e78a0a
files
diffstat 4 files changed, 137 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java	Wed Apr 17 22:58:51 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java	Wed Apr 17 22:59:36 2013 +0200
@@ -22,12 +22,18 @@
  */
 package com.oracle.graal.compiler.test;
 
+import java.io.*;
 import java.lang.reflect.*;
+import java.util.*;
+import java.util.concurrent.*;
 
 import org.junit.*;
 
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.Assumptions.Assumption;
+import com.oracle.graal.api.code.Assumptions.NoFinalizableSubclass;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.debug.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
@@ -36,21 +42,19 @@
 
 public class FinalizableSubclassTest extends GraalCompilerTest {
 
-    public static class NoFinalizerEver {
-
+    /**
+     * used as template to generate class files at runtime.
+     */
+    public static class NoFinalizerEverAAAA {
     }
 
-    public static class NoFinalizerYet {
-
+    public static class NoFinalizerYetAAAA {
     }
 
-    public static class WithFinalizer extends NoFinalizerYet {
-
-        static int someCounter = 0;
+    public static class WithFinalizerAAAA extends NoFinalizerYetAAAA {
 
         @Override
         protected void finalize() throws Throwable {
-            someCounter++;
             super.finalize();
         }
     }
@@ -72,17 +76,129 @@
         Assumptions assumptions = new Assumptions(optimistic);
         StructuredGraph graph = parseAndProcess(cl, assumptions);
         Assert.assertTrue(graph.getNodes().filter(RegisterFinalizerNode.class).count() == (shouldContainFinalizer ? 1 : 0));
+        int noFinalizerAssumption = 0;
+        for (Assumption a : assumptions) {
+            if (a instanceof NoFinalizableSubclass) {
+                noFinalizerAssumption++;
+            }
+        }
+        Assert.assertTrue(noFinalizerAssumption == (shouldContainFinalizer ? 0 : 1));
+    }
+
+    /**
+     * Use a custom class loader to generate classes, to make sure the given classes are loaded in
+     * correct order.
+     */
+    @Test
+    public void test1() throws ClassNotFoundException {
+        for (int i = 0; i < 2; i++) {
+            ClassTemplateLoader loader = new ClassTemplateLoader();
+            checkForRegisterFinalizeNode(loader.findClass("NoFinalizerEverAAAA"), true, false);
+            checkForRegisterFinalizeNode(loader.findClass("NoFinalizerEverAAAA"), false, true);
+
+            checkForRegisterFinalizeNode(loader.findClass("NoFinalizerYetAAAA"), false, true);
+
+            checkForRegisterFinalizeNode(loader.findClass("WithFinalizerAAAA"), true, true);
+            checkForRegisterFinalizeNode(loader.findClass("NoFinalizerYetAAAA"), true, true);
+        }
     }
 
-    @Test
-    public void test1() {
-        checkForRegisterFinalizeNode(NoFinalizerEver.class, true, false);
-        checkForRegisterFinalizeNode(NoFinalizerEver.class, false, true);
+    private static class ClassTemplateLoader extends ClassLoader {
+
+        private static int loaderInstance = 0;
+
+        private final String replaceTo;
+        private HashMap<String, Class> cache = new HashMap<>();
+
+        public ClassTemplateLoader() {
+            loaderInstance++;
+            replaceTo = String.format("%04d", loaderInstance);
+        }
+
+        @Override
+        protected Class<?> findClass(final String name) throws ClassNotFoundException {
+            return Debug.scope("FinalizableSubclassTest", new Callable<Class<?>>() {
+
+                @Override
+                public Class<?> call() throws Exception {
+                    String nameReplaced = name.replaceAll("AAAA", replaceTo);
+                    if (cache.containsKey(nameReplaced)) {
+                        return cache.get(nameReplaced);
+                    }
+
+                    // copy classfile to byte array
+                    byte[] classData = null;
+                    try {
+                        InputStream is = FinalizableSubclassTest.class.getResourceAsStream("FinalizableSubclassTest$" + name + ".class");
+                        assert is != null;
+                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+                        byte[] buf = new byte[1024];
+                        int size;
+                        while ((size = is.read(buf, 0, buf.length)) != -1) {
+                            baos.write(buf, 0, size);
+                        }
+                        baos.flush();
+                        classData = baos.toByteArray();
+                    } catch (IOException e) {
+                        Assert.fail("can't access class: " + name);
+                    }
+                    dumpStringsInByteArray(classData);
+
+                    // replace all occurrences of "AAAA" in classfile
+                    int index = -1;
+                    while ((index = indexOfAAAA(classData, index + 1)) != -1) {
+                        replaceAAAA(classData, index, replaceTo);
+                    }
+                    dumpStringsInByteArray(classData);
 
-        // fails if WithFinalizer is already loaded (e.g. on a second execution of this test)
-        checkForRegisterFinalizeNode(NoFinalizerYet.class, false, true);
+                    Class c = defineClass(null, classData, 0, classData.length);
+                    cache.put(nameReplaced, c);
+                    return c;
+                }
+            });
+        }
+
+        private static int indexOfAAAA(byte[] b, int index) {
+            for (int i = index; i < b.length; i++) {
+                boolean match = true;
+                for (int j = i; j < i + 4; j++) {
+                    if (b[j] != (byte) 'A') {
+                        match = false;
+                        break;
+                    }
+                }
+                if (match) {
+                    return i;
+                }
+            }
+            return -1;
+        }
 
-        checkForRegisterFinalizeNode(WithFinalizer.class, true, true);
-        checkForRegisterFinalizeNode(NoFinalizerYet.class, true, true);
+        private static void replaceAAAA(byte[] b, int index, String replacer) {
+            assert replacer.length() == 4;
+            for (int i = index; i < index + 4; i++) {
+                b[i] = (byte) replacer.charAt(i - index);
+            }
+        }
+
+        private static void dumpStringsInByteArray(byte[] b) {
+            boolean wasChar = true;
+            StringBuilder sb = new StringBuilder();
+            for (Byte x : b) {
+                // check for [a-zA-Z0-9]
+                if ((x >= 0x41 && x <= 0x7a) || (x >= 0x30 && x <= 0x39)) {
+                    if (!wasChar) {
+                        Debug.log(sb + "");
+                        sb.setLength(0);
+                    }
+                    sb.append(String.format("%c", x));
+                    wasChar = true;
+                } else {
+                    wasChar = false;
+                }
+            }
+            Debug.log(sb + "");
+        }
     }
 }
--- a/make/build-graal.xml	Wed Apr 17 22:58:51 2013 +0200
+++ b/make/build-graal.xml	Wed Apr 17 22:59:36 2013 +0200
@@ -31,7 +31,7 @@
   <target depends="jar" name="main"/>
   <target depends="cleanclasses" name="compile">
     <mkdir dir="${classes.dir}"/>
-    <javac debug="on" destdir="${classes.dir}" encoding="UTF-8" includeantruntime="false">
+    <javac debug="on" destdir="${classes.dir}" includeantruntime="false">
       <src path="${src.dir}/com.oracle.graal.api.runtime"/>
       <src path="${src.dir}/com.oracle.graal.api.meta"/>
       <src path="${src.dir}/com.oracle.graal.api.code"/>
--- a/mx/commands.py	Wed Apr 17 22:58:51 2013 +0200
+++ b/mx/commands.py	Wed Apr 17 22:59:36 2013 +0200
@@ -468,7 +468,7 @@
 
     out.open('target', {'name' : 'compile', 'depends' : 'cleanclasses'})
     out.element('mkdir', {'dir' : '${classes.dir}'})
-    out.open('javac', {'destdir' : '${classes.dir}', 'debug' : 'on', 'includeantruntime' : 'false', 'encoding' : 'UTF-8'})
+    out.open('javac', {'destdir' : '${classes.dir}', 'debug' : 'on', 'includeantruntime' : 'false', })
 
     for p in mx.sorted_deps(mx.distribution('GRAAL').deps):
         out.element('src', {'path' : '${src.dir}/' + p.name})
--- a/mx/sanitycheck.py	Wed Apr 17 22:58:51 2013 +0200
+++ b/mx/sanitycheck.py	Wed Apr 17 22:59:36 2013 +0200
@@ -224,19 +224,8 @@
     Full, NoInline, NoComplex = range(3)
 
 def getCTW(vm,mode):
-    
-    modeString = ''
-    if mode == CTWMode.Full:
-        modeString = 'Full'
-    elif mode == CTWMode.NoInline:
-        modeString = 'NoInline'
-    elif mode == CTWMode.NoComplex:
-        modeString = 'NoComplex'
-    else:
-        mx.abort("Unknown CTW mode")
-    
     time = re.compile(r"CompileTheWorld : Done \([0-9]+ classes, [0-9]+ methods, (?P<time>[0-9]+) ms\)")
-    scoreMatcher = ValuesMatcher(time, {'group' : 'CompileTheWorld', 'name' : modeString + '-CompileTime', 'score' : '<time>'})
+    scoreMatcher = ValuesMatcher(time, {'group' : 'CompileTheWorld', 'name' : 'CompileTime', 'score' : '<time>'})
     
     jre = os.environ.get('JAVA_HOME')
     if exists(join(jre, 'jre')):
@@ -254,9 +243,9 @@
             args.append('-G:-Inline')
     if mode >= CTWMode.NoComplex:
         if not vm.endswith('-nograal'):
-            args += ['-G:-OptLoopTransform', '-G:-OptTailDuplication', '-G:-FullUnroll', '-G:-MemoryAwareScheduling']
+            args += ['-G:-OptLoopTransform', '-G:-OptTailDuplication', '-G:-FullUnroll', '-G:-MemoryAwareScheduling', '-G:-PartialEscapeAnalysis']
         
-    return Test("CompileTheWorld-" + modeString, args, successREs=[time], scoreMatchers=[scoreMatcher], benchmarkCompilationRate=False)
+    return Test("CompileTheWorld", args, successREs=[time], scoreMatchers=[scoreMatcher], benchmarkCompilationRate=False)
     
 
 class Tee: