changeset 23139:661e2d8a7316

Simplify Truffle argument profiling code. Profile only for exact concrete class.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sun, 06 Dec 2015 00:13:06 -0800
parents 07f7a8d2de57
children 28613ae6b05d
files graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java
diffstat 1 files changed, 38 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Fri Dec 04 10:32:41 2015 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Sun Dec 06 00:13:06 2015 -0800
@@ -194,6 +194,7 @@
     public Object call(Object... args) {
         compilationProfile.reportIndirectCall();
         if (profiledArgumentTypesAssumption != null && profiledArgumentTypesAssumption.isValid()) {
+            // Argument profiling is not possible for targets of indirect calls.
             CompilerDirectives.transferToInterpreterAndInvalidate();
             profiledArgumentTypesAssumption.invalidate();
             profiledArgumentTypes = null;
@@ -232,20 +233,26 @@
 
     @ExplodeLoop
     void profileArguments(Object[] args) {
-        if (profiledArgumentTypesAssumption == null) {
+        Assumption typesAssumption = profiledArgumentTypesAssumption;
+        if (typesAssumption == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
             initializeProfiledArgumentTypes(args);
-        } else if (profiledArgumentTypes != null) {
-            if (profiledArgumentTypes.length != args.length) {
-                CompilerDirectives.transferToInterpreterAndInvalidate();
-                profiledArgumentTypesAssumption.invalidate();
-                profiledArgumentTypes = null;
-            } else if (TruffleArgumentTypeSpeculation.getValue() && profiledArgumentTypesAssumption.isValid()) {
-                for (int i = 0; i < profiledArgumentTypes.length; i++) {
-                    if (profiledArgumentTypes[i] != null && !profiledArgumentTypes[i].isInstance(args[i])) {
-                        CompilerDirectives.transferToInterpreterAndInvalidate();
-                        updateProfiledArgumentTypes(args);
-                        break;
+        } else {
+            Class<?>[] types = profiledArgumentTypes;
+            if (types != null) {
+                if (types.length != args.length) {
+                    CompilerDirectives.transferToInterpreterAndInvalidate();
+                    typesAssumption.invalidate();
+                    profiledArgumentTypes = null;
+                } else if (typesAssumption.isValid()) {
+                    for (int i = 0; i < types.length; i++) {
+                        Class<?> type = types[i];
+                        Object value = args[i];
+                        if (type != null && (value == null || value.getClass() != type)) {
+                            CompilerDirectives.transferToInterpreterAndInvalidate();
+                            updateProfiledArgumentTypes(args, types);
+                            break;
+                        }
                     }
                 }
             }
@@ -255,19 +262,21 @@
     private void initializeProfiledArgumentTypes(Object[] args) {
         CompilerAsserts.neverPartOfCompilation();
         profiledArgumentTypesAssumption = Truffle.getRuntime().createAssumption("Profiled Argument Types");
-        profiledArgumentTypes = new Class<?>[args.length];
         if (TruffleArgumentTypeSpeculation.getValue()) {
+            Class<?>[] result = new Class<?>[args.length];
             for (int i = 0; i < args.length; i++) {
-                profiledArgumentTypes[i] = classOf(args[i]);
+                result[i] = classOf(args[i]);
             }
+
+            profiledArgumentTypes = result;
         }
     }
 
-    private void updateProfiledArgumentTypes(Object[] args) {
+    private void updateProfiledArgumentTypes(Object[] args, Class<?>[] types) {
         CompilerAsserts.neverPartOfCompilation();
         profiledArgumentTypesAssumption.invalidate();
-        for (int j = 0; j < profiledArgumentTypes.length; j++) {
-            profiledArgumentTypes[j] = joinTypes(profiledArgumentTypes[j], classOf(args[j]));
+        for (int j = 0; j < types.length; j++) {
+            types[j] = joinTypes(types[j], classOf(args[j]));
         }
         profiledArgumentTypesAssumption = Truffle.getRuntime().createAssumption("Profiled Argument Types");
     }
@@ -279,14 +288,8 @@
     private static Class<?> joinTypes(Class<?> class1, Class<?> class2) {
         if (class1 == class2) {
             return class1;
-        } else if (class1 == null || class2 == null) {
+        } else {
             return null;
-        } else if (class1.isAssignableFrom(class2)) {
-            return class1;
-        } else if (class2.isAssignableFrom(class1)) {
-            return class2;
-        } else {
-            return Object.class;
         }
     }
 
@@ -308,9 +311,10 @@
 
     public final Object callRoot(Object[] originalArguments) {
         Object[] args = originalArguments;
-        if (this.profiledArgumentTypesAssumption != null && CompilerDirectives.inCompiledCode() && profiledArgumentTypesAssumption.isValid()) {
-            args = unsafeCast(castArrayFixedLength(args, profiledArgumentTypes.length), Object[].class, true, true);
-            if (TruffleArgumentTypeSpeculation.getValue()) {
+        if (CompilerDirectives.inCompiledCode()) {
+            Assumption argumentTypesAssumption = this.profiledArgumentTypesAssumption;
+            if (argumentTypesAssumption != null && argumentTypesAssumption.isValid()) {
+                args = unsafeCast(castArrayFixedLength(args, profiledArgumentTypes.length), Object[].class, true, true);
                 args = castArguments(args);
             }
         }
@@ -324,7 +328,8 @@
     }
 
     void profileReturnType(Object result) {
-        if (profiledReturnTypeAssumption == null) {
+        Assumption returnTypeAssumption = profiledReturnTypeAssumption;
+        if (returnTypeAssumption == null) {
             if (TruffleReturnTypeSpeculation.getValue()) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
                 profiledReturnType = (result == null ? null : result.getClass());
@@ -334,7 +339,7 @@
             if (result == null || profiledReturnType != result.getClass()) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
                 profiledReturnType = null;
-                profiledReturnTypeAssumption.invalidate();
+                returnTypeAssumption.invalidate();
             }
         }
     }
@@ -475,9 +480,10 @@
 
     @ExplodeLoop
     private Object[] castArguments(Object[] originalArguments) {
-        Object[] castArguments = new Object[profiledArgumentTypes.length];
-        for (int i = 0; i < profiledArgumentTypes.length; i++) {
-            castArguments[i] = profiledArgumentTypes[i] != null ? unsafeCast(originalArguments[i], profiledArgumentTypes[i], true, true) : originalArguments[i];
+        Class<?>[] types = profiledArgumentTypes;
+        Object[] castArguments = new Object[types.length];
+        for (int i = 0; i < types.length; i++) {
+            castArguments[i] = types[i] != null ? unsafeCast(originalArguments[i], types[i], true, true) : originalArguments[i];
         }
         return castArguments;
     }