Permalink
Browse files

Improvements for DStr/DSymbol interpretation for #301.

* Special-case core classes in RubyString.append19 to avoid
dyncalls and transient objects.
* Special-case core classes in DNode's EvStr handling to use
append19 directly rather than coercing to a throw-away transient
String.
* Don't create a shared string in DNode, since it's a new ByteList
that's almost immediately written to anyway.
* DSymbol knows super will produce a String, so use more direct
path that doesn't immediately convert to Java String. See #300.
  • Loading branch information...
1 parent 369226e commit 4a5e3114f7358581c82c7ea8167b59da13b7a4a2 @headius headius committed with Prathamesh Sonpatki Sep 17, 2012
Showing with 33 additions and 5 deletions.
  1. +9 −0 src/org/jruby/RubyString.java
  2. +19 −4 src/org/jruby/ast/DNode.java
  3. +5 −1 src/org/jruby/ast/DSymbolNode.java
@@ -2547,6 +2547,15 @@ public RubyString append(IRubyObject other) {
}
public RubyString append19(IRubyObject other) {
+ if (other instanceof RubyFixnum) {
+ cat19(ConvertBytes.longToByteList(((RubyFixnum)other).getLongValue()), StringSupport.CR_7BIT);
+ return this;
+ } else if (other instanceof RubyFloat) {
+ return cat19((RubyString)((RubyFloat)other).to_s());
+ } else if (other instanceof RubySymbol) {
+ cat19(((RubySymbol)other).getBytes(), 0);
+ return this;
+ }
return cat19(other.convertToString());
}
@@ -2,7 +2,10 @@
import org.jcodings.Encoding;
import org.jruby.Ruby;
+import org.jruby.RubyFixnum;
+import org.jruby.RubyFloat;
import org.jruby.RubyString;
+import org.jruby.RubySymbol;
import org.jruby.lexer.yacc.ISourcePosition;
import org.jruby.runtime.Block;
import org.jruby.runtime.ThreadContext;
@@ -46,11 +49,11 @@ public boolean isSameEncoding(StrNode strNode) {
}
protected RubyString allocateString(Ruby runtime) {
- ByteList bytes = new ByteList();
-
- if (is19()) bytes.setEncoding(encoding);
+ RubyString string = RubyString.newString(runtime, new ByteList());
- return RubyString.newStringShared(runtime, bytes, StringSupport.CR_7BIT);
+ if (is19()) string.setEncoding(encoding);
+
+ return string;
}
public void appendToString(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock, RubyString string, Node node) {
@@ -61,6 +64,18 @@ public void appendToString(Ruby runtime, ThreadContext context, IRubyObject self
} else {
string.cat19(strNode.getValue(), strNode.getCodeRange());
}
+ } else if (node instanceof EvStrNode) {
+ EvStrNode evStrNode = (EvStrNode)node;
+
+ Node bodyNode = evStrNode.getBody();
+ if (bodyNode == null) return;
+
+ IRubyObject body = bodyNode.interpret(runtime, context, self, aBlock);
+ if (body instanceof RubyFixnum || body instanceof RubyFloat || body instanceof RubySymbol) {
+ string.append19(body);
+ } else {
+ string.append19(body.asString());
+ }
} else if (is19()) {
string.append19(node.interpret(runtime, context, self, aBlock));
} else {
@@ -30,6 +30,7 @@
package org.jruby.ast;
import org.jruby.Ruby;
+import org.jruby.RubyString;
import org.jruby.ast.visitor.NodeVisitor;
import org.jruby.lexer.yacc.ISourcePosition;
import org.jruby.runtime.Block;
@@ -69,6 +70,9 @@ public Object accept(NodeVisitor visitor) {
@Override
public IRubyObject interpret(Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) {
- return runtime.newSymbol(super.interpret(runtime, context, self, aBlock).toString());
+ RubyString str = (RubyString)super.interpret(runtime, context, self, aBlock);
+ return runtime.is1_9() ?
+ str.intern19() :
+ str.intern();
}
}

0 comments on commit 4a5e311

Please sign in to comment.