Skip to content

Commit

Permalink
Cache a Float instance for literals, like other impls do.
Browse files Browse the repository at this point in the history
  • Loading branch information
headius committed Apr 27, 2011
1 parent d7365d5 commit 56b5c02
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 6 deletions.
14 changes: 13 additions & 1 deletion src/org/jruby/ast/FloatNode.java
Expand Up @@ -47,6 +47,7 @@
*/
public class FloatNode extends Node implements ILiteralNode {
private double value;
private RubyFloat flote;

public FloatNode(ISourcePosition position, double value) {
super(position);
Expand Down Expand Up @@ -74,15 +75,26 @@ public double getValue() {
* @param value to set
*/
public void setValue(double value) {
// This should never happen past parse, but just bulletproof this just in case
if (flote != null) {
flote = null;
}
this.value = value;
}

public RubyFloat getFloat(Ruby runtime) {
if (flote == null) {
return flote = RubyFloat.newFloat(runtime, value);
}
return flote;
}

public List<Node> childNodes() {
return EMPTY_LIST;
}

@Override
public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
return RubyFloat.newFloat(runtime, value);
return getFloat(runtime);
}
}
15 changes: 15 additions & 0 deletions src/org/jruby/ast/executable/AbstractScript.java
Expand Up @@ -10,6 +10,7 @@
import org.jcodings.EncodingDB;
import org.jruby.Ruby;
import org.jruby.RubyFixnum;
import org.jruby.RubyFloat;
import org.jruby.RubyModule;
import org.jruby.RubyRegexp;
import org.jruby.RubyString;
Expand Down Expand Up @@ -196,6 +197,20 @@ public IRubyObject run(ThreadContext context, IRubyObject self, IRubyObject[] ar
public final RubyFixnum getFixnum8(Ruby runtime, int value) {return runtimeCache.getFixnum(runtime, 8, value);}
public final RubyFixnum getFixnum9(Ruby runtime, int value) {return runtimeCache.getFixnum(runtime, 9, value);}

public static final int NUMBERED_FLOAT_COUNT = 10;

public final RubyFloat getFloat(Ruby runtime, int i, double value) {return runtimeCache.getFloat(runtime, i, value);}
public final RubyFloat getFloat0(Ruby runtime, double value) {return runtimeCache.getFloat(runtime, 0, value);}
public final RubyFloat getFloat1(Ruby runtime, double value) {return runtimeCache.getFloat(runtime, 1, value);}
public final RubyFloat getFloat2(Ruby runtime, double value) {return runtimeCache.getFloat(runtime, 2, value);}
public final RubyFloat getFloat3(Ruby runtime, double value) {return runtimeCache.getFloat(runtime, 3, value);}
public final RubyFloat getFloat4(Ruby runtime, double value) {return runtimeCache.getFloat(runtime, 4, value);}
public final RubyFloat getFloat5(Ruby runtime, double value) {return runtimeCache.getFloat(runtime, 5, value);}
public final RubyFloat getFloat6(Ruby runtime, double value) {return runtimeCache.getFloat(runtime, 6, value);}
public final RubyFloat getFloat7(Ruby runtime, double value) {return runtimeCache.getFloat(runtime, 7, value);}
public final RubyFloat getFloat8(Ruby runtime, double value) {return runtimeCache.getFloat(runtime, 8, value);}
public final RubyFloat getFloat9(Ruby runtime, double value) {return runtimeCache.getFloat(runtime, 9, value);}

public static final int NUMBERED_REGEXP_COUNT = 10;

public final RubyRegexp getRegexp(Ruby runtime, int i, ByteList pattern, int options) {return runtimeCache.getRegexp(runtime, i, pattern, options);}
Expand Down
20 changes: 19 additions & 1 deletion src/org/jruby/ast/executable/RuntimeCache.java
Expand Up @@ -7,6 +7,7 @@
import org.jruby.RubyClass;
import org.jruby.RubyClass.VariableAccessor;
import org.jruby.RubyFixnum;
import org.jruby.RubyFloat;
import org.jruby.RubyModule;
import org.jruby.RubyRegexp;
import org.jruby.RubyString;
Expand Down Expand Up @@ -130,6 +131,14 @@ public final RubyFixnum getFixnum(Ruby runtime, int index, long value) {
return fixnum;
}

public final RubyFloat getFloat(Ruby runtime, int index, double value) {
RubyFloat flote = floats[index];
if (flote == null) {
return floats[index] = RubyFloat.newFloat(runtime, value);
}
return flote;
}

public final RubyRegexp getRegexp(Ruby runtime, int index, ByteList pattern, int options) {
RubyRegexp regexp = regexps[index];
if (regexp == null || runtime.getKCode() != regexp.getKCode()) {
Expand Down Expand Up @@ -246,7 +255,8 @@ public final void initFromDescriptor(String descriptor) {
private static final int SCOPE = 0;
private static final int SYMBOL = SCOPE + 1;
private static final int FIXNUM = SYMBOL + 1;
private static final int CONSTANT = FIXNUM + 1;
private static final int FLOAT = FIXNUM + 1;
private static final int CONSTANT = FLOAT + 1;
private static final int REGEXP = CONSTANT + 1;
private static final int BIGINTEGER = REGEXP + 1;
private static final int VARIABLEREADER = BIGINTEGER + 1;
Expand Down Expand Up @@ -285,6 +295,8 @@ public final void initOthers(String descriptor) {
if (symbolCount > 0) initSymbols(symbolCount);
int fixnumCount = getDescriptorValue(descriptor, FIXNUM);
if (fixnumCount > 0) initFixnums(fixnumCount);
int floatCount = getDescriptorValue(descriptor, FLOAT);
if (floatCount > 0) initFloats(floatCount);
int constantCount = getDescriptorValue(descriptor, CONSTANT);
if (constantCount > 0) initConstants(constantCount);
int regexpCount = getDescriptorValue(descriptor, REGEXP);
Expand Down Expand Up @@ -335,6 +347,10 @@ public final void initFixnums(int size) {
fixnums = new RubyFixnum[size];
}

public final void initFloats(int size) {
floats = new RubyFloat[size];
}

public final void initRegexps(int size) {
regexps = new RubyRegexp[size];
}
Expand Down Expand Up @@ -626,6 +642,8 @@ private CacheEntry getCacheEntry(int index) {
public Encoding[] encodings = EMPTY_ENCODINGS;
private static final RubyFixnum[] EMPTY_FIXNUMS = {};
public RubyFixnum[] fixnums = EMPTY_FIXNUMS;
private static final RubyFloat[] EMPTY_FLOATS = {};
public RubyFloat[] floats = EMPTY_FLOATS;
private static final RubyRegexp[] EMPTY_RUBYREGEXPS = {};
public RubyRegexp[] regexps = EMPTY_RUBYREGEXPS;
private static final BigInteger[] EMPTY_BIGINTEGERS = {};
Expand Down
2 changes: 2 additions & 0 deletions src/org/jruby/compiler/CacheCompiler.java
Expand Up @@ -28,6 +28,8 @@ public interface CacheCompiler {

public void cacheFixnum(BaseBodyCompiler method, long value);

public void cacheFloat(BaseBodyCompiler method, double value);

public void cacheBigInteger(BaseBodyCompiler method, BigInteger bigint);

public void cachedGetVariable(BaseBodyCompiler method, String name);
Expand Down
5 changes: 1 addition & 4 deletions src/org/jruby/compiler/impl/BaseBodyCompiler.java
Expand Up @@ -434,10 +434,7 @@ public void declareClassVariable(String name, CompilerCallback value) {
}

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) {
Expand Down
21 changes: 21 additions & 0 deletions src/org/jruby/compiler/impl/InheritedCacheCompiler.java
Expand Up @@ -14,6 +14,7 @@
import org.jruby.Ruby;
import org.jruby.RubyEncoding;
import org.jruby.RubyFixnum;
import org.jruby.RubyFloat;
import org.jruby.RubyModule;
import org.jruby.RubyRegexp;
import org.jruby.RubyString;
Expand Down Expand Up @@ -53,6 +54,7 @@ public class InheritedCacheCompiler implements CacheCompiler {
Map<String, Integer> stringEncodings = new HashMap<String, Integer>();
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 inheritedEncodingCount = 0;
Expand All @@ -61,6 +63,7 @@ public class InheritedCacheCompiler implements CacheCompiler {
int inheritedVariableReaderCount = 0;
int inheritedVariableWriterCount = 0;
int inheritedFixnumCount = 0;
int inheritedFloatCount = 0;
int inheritedConstantCount = 0;
int inheritedBlockBodyCount = 0;
int inheritedBlockCallbackCount = 0;
Expand Down Expand Up @@ -220,6 +223,22 @@ public void cacheFixnum(BaseBodyCompiler method, long value) {
}
}
}

public void cacheFloat(BaseBodyCompiler method, double value) {
Integer index = Integer.valueOf(inheritedFloatCount++);
floatIndices.put(value, index);

method.loadThis();
method.loadRuntime();
if (index < AbstractScript.NUMBERED_FLOAT_COUNT) {
method.method.ldc(value);
method.method.invokevirtual(scriptCompiler.getClassname(), "getFloat" + index, sig(RubyFloat.class, Ruby.class, double.class));
} else {
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();
Expand Down Expand Up @@ -486,6 +505,7 @@ public void finish() {
int otherCount = scopeCount
+ inheritedSymbolCount
+ inheritedFixnumCount
+ inheritedFloatCount
+ inheritedConstantCount
+ inheritedRegexpCount
+ inheritedBigIntegerCount
Expand Down Expand Up @@ -523,6 +543,7 @@ public void finish() {
descriptor.append((char)scopeCount);
descriptor.append((char)inheritedSymbolCount);
descriptor.append((char)inheritedFixnumCount);
descriptor.append((char)inheritedFloatCount);
descriptor.append((char)inheritedConstantCount);
descriptor.append((char)inheritedRegexpCount);
descriptor.append((char)inheritedBigIntegerCount);
Expand Down

0 comments on commit 56b5c02

Please sign in to comment.