On Sat, Feb 21, 2009 at 2:42 AM, Charles Oliver Nutter
<[email protected]> wrote:
> I noticed this evening we don't cache literal floats in either the
> interpreter or the compiler, but I could not remember why. I've attached a
> patch that fixes this, but does anyone remember if there's a reason why we
> couldn't cache floats? Are they mutable or something?

Weird.  I thought Floats could change state in some fashion, but I
cannot figure out what that would be in looking through it.  No reason
I can see that we shouldn't for literal floats...

-Tom

>
> - Charlie
>
> From c4a8d4b5c6625762f003d0debe54a659bb9a333e Mon Sep 17 00:00:00 2001
> From: Charles Nutter <[email protected]>
> Date: Sat, 21 Feb 2009 02:40:22 -0600
> Subject: [PATCH] Add Float caching to compiler and interpreter. Passes all
> tests, improves performance, but I feel like I didn't do it before on
> purpose...
>
> ---
>  src/org/jruby/ast/FloatNode.java                   |    8 +++++-
>  src/org/jruby/ast/executable/AbstractScript.java   |   25
> ++++++++++++++++++++
>  src/org/jruby/compiler/CacheCompiler.java          |    2 +
>  src/org/jruby/compiler/impl/BaseBodyCompiler.java  |    5 +---
>  .../compiler/impl/InheritedCacheCompiler.java      |   25
> ++++++++++++++++++++
>  5 files changed, 60 insertions(+), 5 deletions(-)
>
> diff --git a/src/org/jruby/ast/FloatNode.java
> b/src/org/jruby/ast/FloatNode.java
> index ee8b914..7b8fc20 100644
> --- a/src/org/jruby/ast/FloatNode.java
> +++ b/src/org/jruby/ast/FloatNode.java
> @@ -47,6 +47,7 @@ import org.jruby.runtime.builtin.IRubyObject;
>  */
>  public class FloatNode extends Node implements ILiteralNode {
>     private double value;
> +    private RubyFloat rubyFloat;
>
>     public FloatNode(ISourcePosition position, double value) {
>         super(position);
> @@ -68,6 +69,11 @@ public class FloatNode extends Node implements
> ILiteralNode {
>     public double getValue() {
>         return value;
>     }
> +
> +    public RubyFloat getRubyFloat(Ruby runtime) {
> +        if (rubyFloat == null) rubyFloat = RubyFloat.newFloat(runtime,
> value);
> +        return rubyFloat;
> +    }
>
>     /**
>      * Sets the value
> @@ -83,6 +89,6 @@ public class FloatNode extends Node implements
> ILiteralNode {
>
>     @Override
>     public IRubyObject interpret(Ruby runtime, ThreadContext context,
> IRubyObject self, Block aBlock) {
> -        return RubyFloat.newFloat(runtime, value);
> +        return getRubyFloat(runtime);
>     }
>  }
> diff --git a/src/org/jruby/ast/executable/AbstractScript.java
> b/src/org/jruby/ast/executable/AbstractScript.java
> index f73a21e..d0098db 100644
> --- a/src/org/jruby/ast/executable/AbstractScript.java
> +++ b/src/org/jruby/ast/executable/AbstractScript.java
> @@ -9,6 +9,7 @@ import java.math.BigInteger;
>  import java.util.Arrays;
>  import org.jruby.Ruby;
>  import org.jruby.RubyFixnum;
> +import org.jruby.RubyFloat;
>  import org.jruby.RubyModule;
>  import org.jruby.RubyRegexp;
>  import org.jruby.RubyString;
> @@ -250,6 +251,25 @@ public abstract class AbstractScript implements Script
> {
>         return fixnum;
>     }
>
> +    public static final double NUMBERED_FLOAT_COUNT = 10;
> +
> +    public final RubyFloat getFloat0(Ruby runtime, double value) {return
> getFloat(runtime, 0, value);}
> +    public final RubyFloat getFloat1(Ruby runtime, double value) {return
> getFloat(runtime, 1, value);}
> +    public final RubyFloat getFloat2(Ruby runtime, double value) {return
> getFloat(runtime, 2, value);}
> +    public final RubyFloat getFloat3(Ruby runtime, double value) {return
> getFloat(runtime, 3, value);}
> +    public final RubyFloat getFloat4(Ruby runtime, double value) {return
> getFloat(runtime, 4, value);}
> +    public final RubyFloat getFloat5(Ruby runtime, double value) {return
> getFloat(runtime, 5, value);}
> +    public final RubyFloat getFloat6(Ruby runtime, double value) {return
> getFloat(runtime, 6, value);}
> +    public final RubyFloat getFloat7(Ruby runtime, double value) {return
> getFloat(runtime, 7, value);}
> +    public final RubyFloat getFloat8(Ruby runtime, double value) {return
> getFloat(runtime, 8, value);}
> +    public final RubyFloat getFloat9(Ruby runtime, double value) {return
> getFloat(runtime, 9, value);}
> +
> +    public final RubyFloat getFloat(Ruby runtime, int index, double value)
> {
> +        RubyFloat flote = flotes[index];
> +        if (flote == null) return flotes[index] =
> RubyFloat.newFloat(runtime, value);
> +        return flote;
> +    }
> +
>     public final RubyRegexp getRegexp(Ruby runtime, int index, String
> pattern, int options) {
>         RubyRegexp regexp = regexps[index];
>         if (regexp == null) {
> @@ -332,6 +352,10 @@ public abstract class AbstractScript implements Script
> {
>         fixnums = new RubyFixnum[size];
>     }
>
> +    public final void initFloats(int size) {
> +        flotes = new RubyFloat[size];
> +    }
> +
>     public final void initRegexps(int size) {
>         regexps = new RubyRegexp[size];
>     }
> @@ -522,6 +546,7 @@ public abstract class AbstractScript implements Script {
>     public RubySymbol[] symbols;
>     public ByteList[] byteLists;
>     public RubyFixnum[] fixnums;
> +    public RubyFloat[] flotes;
>     public RubyRegexp[] regexps;
>     public BigInteger[] bigIntegers;
>     public String filename;
> diff --git a/src/org/jruby/compiler/CacheCompiler.java
> b/src/org/jruby/compiler/CacheCompiler.java
> index d10e1a8..4cbc01c 100644
> --- a/src/org/jruby/compiler/CacheCompiler.java
> +++ b/src/org/jruby/compiler/CacheCompiler.java
> @@ -24,6 +24,8 @@ public interface CacheCompiler {
>     public void cacheSymbol(BaseBodyCompiler method, String symbol);
>
>     public void cacheFixnum(BaseBodyCompiler method, long value);
> +
> +    public void cacheFloat(BaseBodyCompiler method, double value);
>
>     public void cacheBigInteger(BaseBodyCompiler method, BigInteger bigint);
>
> diff --git a/src/org/jruby/compiler/impl/BaseBodyCompiler.java
> b/src/org/jruby/compiler/impl/BaseBodyCompiler.java
> index befb8f6..6b37bc1 100644
> --- a/src/org/jruby/compiler/impl/BaseBodyCompiler.java
> +++ b/src/org/jruby/compiler/impl/BaseBodyCompiler.java
> @@ -443,10 +443,7 @@ public abstract class BaseBodyCompiler implements
> BodyCompiler {
>     }
>
>     public void createNewFloat(double value) {
> -        loadRuntime();
> -        method.ldc(new Double(value));
> -
> -        invokeRuby("newFloat", sig(RubyFloat.class, params(Double.TYPE)));
> +        script.getCacheCompiler().cacheFloat(this, value);
>     }
>
>     public void createNewFixnum(long value) {
> diff --git a/src/org/jruby/compiler/impl/InheritedCacheCompiler.java
> b/src/org/jruby/compiler/impl/InheritedCacheCompiler.java
> index 043612a..7eb3faf 100644
> --- a/src/org/jruby/compiler/impl/InheritedCacheCompiler.java
> +++ b/src/org/jruby/compiler/impl/InheritedCacheCompiler.java
> @@ -12,6 +12,7 @@ import java.util.List;
>  import java.util.Map;
>  import org.jruby.Ruby;
>  import org.jruby.RubyFixnum;
> +import org.jruby.RubyFloat;
>  import org.jruby.RubyModule;
>  import org.jruby.RubyRegexp;
>  import org.jruby.RubyString;
> @@ -47,11 +48,13 @@ public class InheritedCacheCompiler implements
> CacheCompiler {
>     Map<BigInteger, String> bigIntegers = new HashMap<BigInteger, String>();
>     Map<String, Integer> symbolIndices = new HashMap<String, Integer>();
>     Map<Long, Integer> fixnumIndices = new HashMap<Long, Integer>();
> +    Map<Double, Integer> floatIndices = new HashMap<Double, Integer>();
>     int inheritedSymbolCount = 0;
>     int inheritedStringCount = 0;
>     int inheritedRegexpCount = 0;
>     int inheritedBigIntegerCount = 0;
>     int inheritedFixnumCount = 0;
> +    int inheritedFloatCount = 0;
>     int inheritedConstantCount = 0;
>     int inheritedBlockBodyCount = 0;
>     int inheritedBlockCallbackCount = 0;
> @@ -213,6 +216,20 @@ public class InheritedCacheCompiler implements
> CacheCompiler {
>         }
>     }
>
> +    public void cacheFloat(BaseBodyCompiler method, double value) {
> +        Integer index = floatIndices.get(value);
> +        if (index == null) {
> +            index = new Integer(inheritedFloatCount++);
> +            floatIndices.put(value, index);
> +        }
> +
> +        method.loadThis();
> +        method.loadRuntime();
> +        method.method.pushInt(index.intValue());
> +        method.method.ldc(value);
> +        method.method.invokevirtual(scriptCompiler.getClassname(),
> "getFloat", sig(RubyFloat.class, Ruby.class, int.class, double.class));
> +    }
> +
>     public void cacheConstant(BaseBodyCompiler method, String constantName)
> {
>         method.loadThis();
>         method.loadThreadContext();
> @@ -405,6 +422,14 @@ public class InheritedCacheCompiler implements
> CacheCompiler {
>             initMethod.invokevirtual(scriptCompiler.getClassname(),
> "initFixnums", sig(void.class, params(int.class)));
>         }
>
> +        // generate fixnums initialization code
> +        size = inheritedFloatCount;
> +        if (size != 0) {
> +            initMethod.aload(0);
> +            initMethod.pushInt(size);
> +            initMethod.invokevirtual(scriptCompiler.getClassname(),
> "initFloats", sig(void.class, params(int.class)));
> +        }
> +
>         // generate constants initialization code
>         size = inheritedConstantCount;
>         if (size != 0) {
> --
> 1.6.0.2
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>



-- 
Blog: http://www.bloglines.com/blog/ThomasEEnebo
Email: [email protected] , [email protected]

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply via email to