<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>bench/bench_method_dispatch.ik</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -26,6 +26,9 @@ public class IokeObject implements TypeChecker {
 
     private boolean frozen = false;
 
+    // Used to handle recursive cell lookup chains more efficiently. Should in the end be a ThreadLocal of course.
+    private boolean marked = false;
+
     public IokeObject(Runtime runtime, String documentation) {
         this(runtime, documentation, IokeData.None);
     }
@@ -139,11 +142,11 @@ public class IokeObject implements TypeChecker {
     }
 
     public static Object findSuperCellOn(Object obj, IokeObject early, IokeObject message, IokeObject context, String name) {
-        return as(obj, context).findSuperCell(early, message, context, name, new boolean[]{false}, new IdentityHashMap&lt;IokeObject, Object&gt;());
+        return as(obj, context).markingFindSuperCell(early, message, context, name, new boolean[]{false});
     }
 
-    public Object findSuperCell(IokeObject early, IokeObject message, IokeObject context, String name, boolean[] found, IdentityHashMap&lt;IokeObject, Object&gt; visited) {
-        if(visited.containsKey(this)) {
+    protected Object markingFindSuperCell(IokeObject early, IokeObject message, IokeObject context, String name, boolean[] found) {
+        if(this.marked) {
             return runtime.nul;
         }
 
@@ -156,32 +159,30 @@ public class IokeObject implements TypeChecker {
             }
         }
 
-        visited.put(this, null);
-        
-        for(IokeObject mimic : mimics) {
-            Object cell = mimic.findSuperCell(early, message, context, name, found, visited);
-            if(cell != runtime.nul) {
-                return cell;
+        this.marked = true;
+        try {
+            for(IokeObject mimic : mimics) {
+                Object cell = mimic.markingFindSuperCell(early, message, context, name, found);
+                if(cell != runtime.nul) {
+                    return cell;
+                }
             }
+            return runtime.nul;
+        } finally {
+            this.marked = false;
         }
-
-        return runtime.nul;
     }
 
     public static Object findCell(Object obj, IokeObject m, IokeObject context, String name) {
-        return as(obj, context).findCell(m, context, name, new IdentityHashMap&lt;IokeObject, Object&gt;());
-    }
-
-    public static Object findCell(Object obj, IokeObject m, IokeObject context, String name, IdentityHashMap&lt;IokeObject, Object&gt; visited) {
-        return as(obj, context).findCell(m, context, name, visited);
+        return as(obj, context).markingFindCell(m, context, name);
     }
 
-    public static Object findPlace(Object obj, String name, IdentityHashMap&lt;IokeObject, Object&gt; visited) {
-        return as(obj, null).findPlace(name, visited);
+    public static Object findPlace(Object obj, String name) {
+        return as(obj, null).markingFindPlace(name);
     }
 
     public static Object findPlace(Object obj, IokeObject m, IokeObject context, String name) throws ControlFlow {
-        Object result = findPlace(obj, name, new IdentityHashMap&lt;IokeObject, Object&gt;());
+        Object result = findPlace(obj, name);
         if(result == m.runtime.nul) {
             final IokeObject condition = as(IokeObject.getCellChain(m.runtime.condition, 
                                                                     m, 
@@ -207,50 +208,58 @@ public class IokeObject implements TypeChecker {
      * findPlace is cycle aware and will not loop in an infinite chain. subclasses should copy this behavior.
      */
     public Object findPlace(String name) {
-        return findPlace(name, new IdentityHashMap&lt;IokeObject, Object&gt;());
+        return markingFindPlace(name);
     }
 
-    protected Object findPlace(String name, IdentityHashMap&lt;IokeObject, Object&gt; visited) {
-        if(visited.containsKey(this)) {
+    protected Object markingFindPlace(String name) {
+        if(this.marked) {
             return runtime.nul;
         }
+
         if(cells.containsKey(name)) {
             if(cells.get(name) == runtime.nul) {
                 return runtime.nul;
             }
             return this;
         } else {
-            visited.put(this, null);
-
-            for(IokeObject mimic : mimics) {
-                Object place = mimic.findPlace(name, visited);
-                if(place != runtime.nul) {
-                    return place;
+            this.marked = true;
+            try {
+                for(IokeObject mimic : mimics) {
+                    Object place = mimic.markingFindPlace(name);
+                    if(place != runtime.nul) {
+                        return place;
+                    }
                 }
-            }
 
-            return runtime.nul;
+                return runtime.nul;
+            } finally {
+                this.marked = false;
+            }
         }
     }
 
-    public Object findCell(IokeObject m, IokeObject context, String name, IdentityHashMap&lt;IokeObject, Object&gt; visited) {
-        if(visited.containsKey(this)) {
+    protected Object markingFindCell(IokeObject m, IokeObject context, String name) {
+        if(this.marked) {
             return runtime.nul;
         }
 
         if(cells.containsKey(name)) {
             return cells.get(name);
         } else {
-            visited.put(this, null);
+            this.marked = true;
 
-            for(IokeObject mimic : mimics) {
-                Object cell = mimic.findCell(m, context, name, visited);
-                if(cell != runtime.nul) {
-                    return cell;
+            try {
+                for(IokeObject mimic : mimics) {
+                    Object cell = mimic.markingFindCell(m, context, name);
+                    if(cell != runtime.nul) {
+                        return cell;
+                    }
                 }
-            }
 
-            return runtime.nul;
+                return runtime.nul;
+            } finally {
+                this.marked = false;
+            }
         }
     }
 
@@ -267,7 +276,7 @@ public class IokeObject implements TypeChecker {
     }
 
     public Object findCell(IokeObject m, IokeObject context, String name) {
-        return findCell(m, context, name, new IdentityHashMap&lt;IokeObject, Object&gt;());
+        return markingFindCell(m, context, name);
     }
 
     public static boolean isKind(Object on, String kind, IokeObject context) {</diff>
      <filename>src/ikj/main/ioke/lang/IokeObject.java</filename>
    </modified>
    <modified>
      <diff>@@ -3,8 +3,6 @@
  */
 package ioke.lang;
 
-import java.util.IdentityHashMap;
-
 /**
  *
  * @author &lt;a href=&quot;mailto:ola.bini@gmail.com&quot;&gt;Ola Bini&lt;/a&gt;
@@ -48,18 +46,18 @@ public class LexicalContext extends IokeObject {
     }
 
     @Override
-    protected Object findPlace(String name, IdentityHashMap&lt;IokeObject, Object&gt; visited) {
-        Object nn = super.findPlace(name, visited);
+    protected Object markingFindPlace(String name) {
+        Object nn = super.markingFindPlace(name);
         if(nn == runtime.nul) {
-            return IokeObject.findPlace(surroundingContext, name, visited);
+            return IokeObject.findPlace(surroundingContext, name);
         } else {
             return nn;
         }
     }
 
     @Override
-    public Object findSuperCell(IokeObject early, IokeObject message, IokeObject context, String name, boolean[] found, IdentityHashMap&lt;IokeObject, Object&gt; visited) {
-        Object nn = super.findSuperCell(early, message, context, name, found, visited);
+    protected Object markingFindSuperCell(IokeObject early, IokeObject message, IokeObject context, String name, boolean[] found) {
+        Object nn = super.markingFindSuperCell(early, message, context, name, found);
         if(nn == runtime.nul) {
             return IokeObject.findSuperCellOn(surroundingContext, early, message, context, name);
         } else {
@@ -68,11 +66,11 @@ public class LexicalContext extends IokeObject {
     }
 
     @Override
-    public Object findCell(IokeObject m, IokeObject context, String name, IdentityHashMap&lt;IokeObject, Object&gt; visited) {
-        Object nn = super.findCell(m, context, name, visited);
+    protected Object markingFindCell(IokeObject m, IokeObject context, String name) {
+        Object nn = super.markingFindCell(m, context, name);
         
         if(nn == runtime.nul) {
-            return IokeObject.findCell(surroundingContext, m, context, name, visited);
+            return IokeObject.findCell(surroundingContext, m, context, name);
         } else {
             return nn;
         }</diff>
      <filename>src/ikj/main/ioke/lang/LexicalContext.java</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>acfc6b74f7ee2d7faa80a304e3486dc44b1c4768</id>
    </parent>
  </parents>
  <author>
    <name>Ola Bini</name>
    <email>ola.bini@gmail.com</email>
  </author>
  <url>http://github.com/olabini/ioke/commit/e322e4fd7f3ec2f37ceeae4567a92dfff4721364</url>
  <id>e322e4fd7f3ec2f37ceeae4567a92dfff4721364</id>
  <committed-date>2009-09-08T09:35:53-07:00</committed-date>
  <authored-date>2009-09-08T09:35:53-07:00</authored-date>
  <message>Move some more algorithms to be marking versions</message>
  <tree>b487a8dc5a21426ca542de78c95d4538517e5693</tree>
  <committer>
    <name>Ola Bini</name>
    <email>ola.bini@gmail.com</email>
  </committer>
</commit>
