Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 7c55b3b1d4e6
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 256042b90d1f
Choose a head ref
  • 3 commits
  • 2 files changed
  • 2 contributors

Commits on Sep 30, 2016

  1. Inspect directly into a RubyString and avoid StringBuilder/char[].

    This should reduce the overhead of inspecting by avoiding the
    intermediate StringBuilder/char[] and subsequent conversion to
    byte[]. There are a few extra objects created along the way
    (java.lang.String.getBytes, RubyString for class name, etc) but
    overall memory use should reduce around 3x: a US-ASCII
    string would need 2x byte size in the StringBuilder, and the
    builder is still alive when we create the eventual byte[] for a
    total of 3x max memory use during inspect.
    
    Relates to #4127, but does not constitute a fix for memory issues
    there.
    headius committed Sep 30, 2016
    Copy the full SHA
    a40621d View commit details
  2. Copy the full SHA
    8131146 View commit details

Commits on Oct 12, 2016

  1. Merge pull request #4128 from headius/lighter_inspect

    Inspect directly into a RubyString and avoid StringBuilder/char[].
    enebo authored Oct 12, 2016
    Copy the full SHA
    256042b View commit details
Showing with 42 additions and 14 deletions.
  1. +32 −14 core/src/main/java/org/jruby/RubyBasicObject.java
  2. +10 −0 core/src/main/java/org/jruby/util/io/EncodingUtils.java
46 changes: 32 additions & 14 deletions core/src/main/java/org/jruby/RubyBasicObject.java
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@
package org.jruby;

import org.jcodings.Encoding;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.ir.interpreter.Interpreter;
import org.jruby.runtime.Constants;
import org.jruby.runtime.JavaSites;
@@ -69,6 +70,7 @@
import org.jruby.runtime.component.VariableEntry;
import org.jruby.runtime.marshal.CoreObjectType;
import org.jruby.util.ArraySupport;
import org.jruby.util.ConvertBytes;
import org.jruby.util.IdUtil;
import org.jruby.util.TypeConverter;
import org.jruby.util.unsafe.UnsafeHolder;
@@ -78,6 +80,9 @@
import static org.jruby.runtime.invokedynamic.MethodNames.OP_CMP;
import static org.jruby.runtime.invokedynamic.MethodNames.EQL;
import static org.jruby.runtime.invokedynamic.MethodNames.INSPECT;
import static org.jruby.util.io.EncodingUtils.encStrBufCat;
import static org.jruby.util.io.EncodingUtils.strBufCat;

import org.jruby.runtime.ivars.VariableTableManager;

/**
@@ -1096,21 +1101,30 @@ public IRubyObject inspect() {
return to_s();
}

private static final byte[] INSPECT_POUND_LT = "#<".getBytes();
private static final byte[] INSPECT_COLON_ZERO_X = ":0x".getBytes();
private static final byte[] INSPECT_SPACE_DOT_DOT_DOT_GT = " ...>".getBytes();
private static final byte[] INSPECT_COMMA = ",".getBytes();
private static final byte[] INSPECT_SPACE = " ".getBytes();
private static final byte[] INSPECT_EQUALS = "=".getBytes();
private static final byte[] INSPECT_GT = ">".getBytes();

public final IRubyObject hashyInspect() {
final Ruby runtime = getRuntime();
String cname = getMetaClass().getRealClass().getName();
StringBuilder part = new StringBuilder(2 + cname.length() + 3 + 8 + 1); // #<Object:0x5a1c0542>
part.append("#<").append(cname).append(":0x");
part.append(Integer.toHexString(inspectHashCode()));
byte[] name = getMetaClass().getRealClass().getName().getBytes(RubyEncoding.UTF8);
RubyString part = RubyString.newStringLight(runtime, 2 + name.length + 3 + 8 + 1); // #<Object:0x5a1c0542>
encStrBufCat(runtime, part, INSPECT_POUND_LT);
encStrBufCat(runtime, part, name, UTF8Encoding.INSTANCE);
encStrBufCat(runtime, part, INSPECT_COLON_ZERO_X);
encStrBufCat(runtime, part, ConvertBytes.longToHexBytes(inspectHashCode()));

if (runtime.isInspecting(this)) {
/* 6:tags 16:addr 1:eos */
part.append(" ...>");
return RubyString.newString(runtime, part);
encStrBufCat(runtime, part, INSPECT_SPACE_DOT_DOT_DOT_GT);
return part;
}
try {
runtime.registerInspecting(this);
return RubyString.newString(runtime, inspectObj(runtime, part));
return inspectObj(runtime, part);
} finally {
runtime.unregisterInspecting(this);
}
@@ -1150,21 +1164,25 @@ protected int inspectHashCode() {
* The internal helper method that takes care of the part of the
* inspection that inspects instance variables.
*/
private StringBuilder inspectObj(final Ruby runtime, StringBuilder part) {
private RubyString inspectObj(final Ruby runtime, RubyString part) {
final ThreadContext context = runtime.getCurrentContext();
String sep = "";

boolean first = true;
for (Map.Entry<String, VariableAccessor> entry : metaClass.getVariableTableManager().getVariableAccessorsForRead().entrySet()) {
Object value = entry.getValue().get(this);
if (!(value instanceof IRubyObject) || !IdUtil.isInstanceVariable(entry.getKey())) continue;

IRubyObject obj = (IRubyObject) value;

part.append(sep).append(' ').append(entry.getKey()).append('=');
part.append(sites(context).inspect.call(context, obj, obj));
sep = ",";
if (!first) encStrBufCat(runtime, part, INSPECT_COMMA);
encStrBufCat(runtime, part, INSPECT_SPACE);
encStrBufCat(runtime, part, entry.getKey().getBytes());
encStrBufCat(runtime, part, INSPECT_EQUALS);
encStrBufCat(runtime, part, sites(context).inspect.call(context, obj, obj).convertToString().getByteList());

first = false;
}
part.append('>');
encStrBufCat(runtime, part, INSPECT_GT);
return part;
}

10 changes: 10 additions & 0 deletions core/src/main/java/org/jruby/util/io/EncodingUtils.java
Original file line number Diff line number Diff line change
@@ -1647,6 +1647,16 @@ public static void encStrBufCat(Ruby runtime, RubyString str, ByteList ptr, Enco
encCrStrBufCat(runtime, str, ptr.getUnsafeBytes(), ptr.getBegin(), ptr.getRealSize(),
enc, StringSupport.CR_UNKNOWN, null);
}
public static void encStrBufCat(Ruby runtime, RubyString str, ByteList ptr) {
encCrStrBufCat(runtime, str, ptr.getUnsafeBytes(), ptr.getBegin(), ptr.getRealSize(),
ptr.getEncoding(), StringSupport.CR_UNKNOWN, null);
}
public static void encStrBufCat(Ruby runtime, RubyString str, byte[] ptrBytes) {
encCrStrBufCat(runtime, str, ptrBytes, 0, ptrBytes.length, USASCIIEncoding.INSTANCE, StringSupport.CR_UNKNOWN, null);
}
public static void encStrBufCat(Ruby runtime, RubyString str, byte[] ptrBytes, Encoding enc) {
encCrStrBufCat(runtime, str, ptrBytes, 0, ptrBytes.length, enc, StringSupport.CR_UNKNOWN, null);
}
public static void encStrBufCat(Ruby runtime, RubyString str, byte[] ptrBytes, int ptr, int len, Encoding enc) {
encCrStrBufCat(runtime, str, ptrBytes, ptr, len,
enc, StringSupport.CR_UNKNOWN, null);