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
