Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

IR: Prelim. support for listener to observer compiler pass activity

  • Loading branch information...
commit 5525c91cdc4f5365b37e9318422c604267658a59 1 parent df53c22
Thomas E Enebo authored April 04, 2012
19  src/org/jruby/ir/IRManager.java
... ...
@@ -1,9 +1,13 @@
1 1
 package org.jruby.ir;
2 2
 
  3
+import java.util.ArrayList;
  4
+import java.util.HashSet;
3 5
 import java.util.List;
4  
-import org.jruby.ir.passes.CompilerPass;
  6
+import java.util.Set;
5 7
 import org.jruby.ir.operands.BooleanLiteral;
6 8
 import org.jruby.ir.operands.Nil;
  9
+import org.jruby.ir.passes.CompilerPass;
  10
+import org.jruby.ir.passes.CompilerPassListener;
7 11
 
8 12
 /**
9 13
  */
@@ -14,6 +18,7 @@
14 18
     private final Nil nil = new Nil();
15 19
     private final BooleanLiteral trueObject = new BooleanLiteral(true);
16 20
     private final BooleanLiteral falseObject = new BooleanLiteral(false);
  21
+    private Set<CompilerPassListener> passListeners = new HashSet<CompilerPassListener>();
17 22
     
18 23
     public IRManager() {
19 24
     }
@@ -38,6 +43,18 @@ public IRModuleBody getObject() {
38 43
         return null;
39 44
     }
40 45
     
  46
+    public Set<CompilerPassListener> getListeners() {
  47
+        return passListeners;
  48
+    }
  49
+    
  50
+    public void addListener(CompilerPassListener listener) {
  51
+        passListeners.add(listener);
  52
+    }
  53
+    
  54
+    public void removeListener(CompilerPassListener listener) {
  55
+        passListeners.remove(listener);
  56
+    }
  57
+    
41 58
     public IRModuleBody getClassMetaClass() {
42 59
         return classMetaClass;
43 60
     }
27  src/org/jruby/ir/passes/CompilerPass.java
@@ -21,7 +21,9 @@
21 21
  * guarantee (re)execution, then you should call invalidate().
22 22
  */
23 23
 public abstract class CompilerPass {
24  
-    public List<Class<? extends CompilerPass>> NO_DEPENDENCIES = new ArrayList<Class<? extends CompilerPass>>();
  24
+    public static List<Class<? extends CompilerPass>> NO_DEPENDENCIES = new ArrayList<Class<? extends CompilerPass>>();
  25
+    
  26
+    private List<CompilerPassListener> listeners = new ArrayList<CompilerPassListener>();
25 27
     
26 28
     /**
27 29
      * What is the user-friendly name of this compiler pass
@@ -65,7 +67,6 @@ public Object previouslyRun(IRScope scope) {
65 67
     
66 68
     // Run the pass on the passed in scope!
67 69
     public Object run(IRScope scope) {
68  
-        // Make sure all dependencies are satisfied
69 70
         List<Class<? extends CompilerPass>> dependencies = getDependencies();
70 71
         Object data[] = new Object[dependencies.size()];
71 72
            
@@ -73,15 +74,31 @@ public Object run(IRScope scope) {
73 74
             data[i] = makeSureDependencyHasRunOnce(dependencies.get(i), scope);
74 75
         }
75 76
 
76  
-//        System.out.println("Executing Pass: " + getLabel());
77  
-        return execute(scope, data);
  77
+        for (CompilerPassListener listener: scope.getManager().getListeners()) {
  78
+            listener.startExecute(this, scope);
  79
+        }
  80
+        
  81
+        Object passData = execute(scope, data);
  82
+        
  83
+        for (CompilerPassListener listener: scope.getManager().getListeners()) {        
  84
+            listener.endExecute(this, scope, passData);
  85
+        }
  86
+        
  87
+        return passData;
78 88
     }
79 89
 
80 90
     private Object makeSureDependencyHasRunOnce(Class<? extends CompilerPass> passClass, IRScope scope) {
81 91
         CompilerPass pass = createPassInstance(passClass);
82 92
         Object data = pass.previouslyRun(scope);
83 93
         
84  
-        return data == null ? pass.run(scope) : data;
  94
+        if (data == null) {
  95
+            data = pass.run(scope);
  96
+        } else {
  97
+            for (CompilerPassListener listener: scope.getManager().getListeners()) {                    
  98
+                listener.alreadyExecuted(pass, scope, data);
  99
+            }
  100
+        }
  101
+        return data;
85 102
     }
86 103
 
87 104
     private CompilerPass createPassInstance(Class<? extends CompilerPass> passClass) {
31  src/org/jruby/ir/passes/CompilerPassListener.java
... ...
@@ -0,0 +1,31 @@
  1
+package org.jruby.ir.passes;
  2
+
  3
+import org.jruby.ir.IRScope;
  4
+
  5
+/**
  6
+ * To get information about all phases of executing a compiler pass.
  7
+ * 
  8
+ * Note: Any data you retrieve may be later mutated by other tasks.  If you
  9
+ * care about persistent state it is up to you to clone that information. Also
  10
+ * Note, if you clone remember this will affect time it takes for passes to run
  11
+ * since these callbacks are synchronously executed in the compiler pass logic.
  12
+ */
  13
+public interface CompilerPassListener {
  14
+    /**
  15
+     * This dependent pass has been determined to already be satisfied and is
  16
+     * not going to call execute().
  17
+     */
  18
+    public void alreadyExecuted(CompilerPass passClass, IRScope scope, Object data);
  19
+
  20
+    /**
  21
+     * This pass is about to begin execute'ing.
  22
+     * @param pass 
  23
+     */
  24
+    public void startExecute(CompilerPass pass, IRScope scope);
  25
+
  26
+    /**
  27
+     * This pass has just finished execute'ing.  data is the result it is 
  28
+     * returning.
  29
+     */
  30
+    public void endExecute(CompilerPass pass, IRScope scope, Object data);
  31
+}

0 notes on commit 5525c91

Please sign in to comment.
Something went wrong with that request. Please try again.