diff options
author | Rich Hickey <richhickey@gmail.com> | 2010-04-18 10:06:16 -0400 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2010-04-18 10:06:16 -0400 |
commit | 19dd3c593e7a29cbca514c6ab7424ff22e353cc6 (patch) | |
tree | ce71e1c27b7ab772c5487b26702917c1e37276e1 | |
parent | a8e92018ce0ce32fc59fae2072369a8671fdea62 (diff) |
Remove perf hacks from MethodImplCache, restore new reduce impl
-rw-r--r-- | src/clj/clojure/core.clj | 2 | ||||
-rw-r--r-- | src/clj/clojure/core_deftype.clj | 13 | ||||
-rw-r--r-- | src/jvm/clojure/lang/AFunction.java | 3 | ||||
-rw-r--r-- | src/jvm/clojure/lang/MethodImplCache.java | 11 |
4 files changed, 9 insertions, 20 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj index f0f784ea..cb2f1d2b 100644 --- a/src/clj/clojure/core.clj +++ b/src/clj/clojure/core.clj @@ -4700,7 +4700,7 @@ (load "gvec") ;; redefine reduce with internal-reduce -(defn- reduce-new +(defn reduce "f should be a function of 2 arguments. If val is not supplied, returns the result of applying f to the first 2 items in coll, then applying f to that result and the 3rd item, etc. If coll contains no diff --git a/src/clj/clojure/core_deftype.clj b/src/clj/clojure/core_deftype.clj index c1b72ac2..4409ea75 100644 --- a/src/clj/clojure/core_deftype.clj +++ b/src/clj/clojure/core_deftype.clj @@ -430,7 +430,7 @@ (fn ~gthis ~@(map (fn [args] - (let [gargs (map #(gensym (str "g__" % "__")) args) + (let [gargs (map #(gensym (str "gf__" % "__")) args) target (first gargs)] `([~@gargs] (~@(if on-interface @@ -438,12 +438,11 @@ (. ~(with-meta target {:tag on-interface}) ~(or on-method method) ~@(rest gargs))) `(do)) (let [cache# (.__methodImplCache ~gthis)] - (if (clojure.lang.Util/identical (clojure.lang.Util/classOf ~target) - (.lastClass cache#)) - ((.lastImpl cache#) ~@gargs) - (let [f# (or (.fnFor cache# (clojure.lang.Util/classOf ~target)) - (-cache-protocol-fn ~gthis ~target))] - (f# ~@gargs)))))))) + ;(assert cache#) + (let [f# (or (.fnFor cache# (clojure.lang.Util/classOf ~target)) + (-cache-protocol-fn ~gthis ~target))] + ;(assert f#) + (f# ~@gargs))))))) arglists))] (set! (.__methodImplCache f#) cache#) f#)))) diff --git a/src/jvm/clojure/lang/AFunction.java b/src/jvm/clojure/lang/AFunction.java index 260bbb3e..baa11e1d 100644 --- a/src/jvm/clojure/lang/AFunction.java +++ b/src/jvm/clojure/lang/AFunction.java @@ -16,8 +16,7 @@ import java.util.Comparator; public abstract class AFunction extends AFn implements IObj, Comparator, Fn{ -//note - this is not even volatile by design -public MethodImplCache __methodImplCache; +public volatile MethodImplCache __methodImplCache; public int compare(Object o1, Object o2){ try diff --git a/src/jvm/clojure/lang/MethodImplCache.java b/src/jvm/clojure/lang/MethodImplCache.java index a8670a57..8d18a3b6 100644 --- a/src/jvm/clojure/lang/MethodImplCache.java +++ b/src/jvm/clojure/lang/MethodImplCache.java @@ -19,10 +19,6 @@ public final int shift; public final int mask; public final Object[] table; //[class, fn. class, fn ...] -//these are not volatile by design -public Object lastClass; -public IFn lastImpl; - public MethodImplCache(IPersistentMap protocol, Keyword methodk){ this(protocol, methodk, 0, 0, RT.EMPTY_ARRAY); } @@ -33,18 +29,13 @@ public MethodImplCache(IPersistentMap protocol, Keyword methodk, int shift, int this.shift = shift; this.mask = mask; this.table = table; - this.lastClass = this; } public IFn fnFor(Class c){ - if(c == lastClass) - return lastImpl; int idx = ((Util.hash(c) >> shift) & mask) << 1; if(idx < table.length && table[idx] == c) { - lastClass = c; - return lastImpl = - (IFn) table[idx + 1]; + return (IFn) table[idx + 1]; } return null; } |