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: 1d8ac7b76d2e
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 05a8efa9736d
Choose a head ref
  • 4 commits
  • 6 files changed
  • 1 contributor

Commits on Feb 24, 2016

  1. Copy the full SHA
    6e349f3 View commit details
  2. Copy the full SHA
    180a8d2 View commit details
  3. Copy the full SHA
    d8ab6eb View commit details
  4. Copy the full SHA
    05a8efa View commit details
1 change: 0 additions & 1 deletion core/pom.rb
Original file line number Diff line number Diff line change
@@ -218,7 +218,6 @@
'forkCount' => '1',
'reuseForks' => 'false',
'systemProperties' => {
'jruby.compat.version' => '1.9',
'jruby.home' => '${basedir}/..'
},
'argLine' => '-Xmx${jruby.test.memory} -XX:MaxPermSize=${jruby.test.memory.permgen} -Dfile.encoding=UTF-8 -Djava.awt.headless=true',
1 change: 0 additions & 1 deletion core/pom.xml
Original file line number Diff line number Diff line change
@@ -563,7 +563,6 @@ DO NOT MODIFIY - GENERATED CODE
<forkCount>1</forkCount>
<reuseForks>false</reuseForks>
<systemProperties>
<jruby.compat.version>1.9</jruby.compat.version>
<jruby.home>${basedir}/..</jruby.home>
</systemProperties>
<argLine>-Xmx${jruby.test.memory} -XX:MaxPermSize=${jruby.test.memory.permgen} -Dfile.encoding=UTF-8 -Djava.awt.headless=true</argLine>
95 changes: 61 additions & 34 deletions core/src/main/java/org/jruby/ir/targets/IRBytecodeAdapter6.java
Original file line number Diff line number Diff line change
@@ -172,27 +172,41 @@ public void run() {
});
}

private static String keyFor(Object... objs) {
StringBuilder sb = new StringBuilder();
for (Object obj : objs) {
sb.append(obj.toString());
if (obj instanceof ByteList) sb.append('_').append(((ByteList) obj).getEncoding());
sb.append("_");
}
private static String keyFor(Object obj1, Object obj2) {
StringBuilder sb = new StringBuilder(16);
keyFor(sb, obj1);
keyFor(sb, obj2);
return sb.toString();
}

private static String keyFor(Object obj1, Object obj2, Object obj3) {
StringBuilder sb = new StringBuilder(24);
keyFor(sb, obj1);
keyFor(sb, obj2);
keyFor(sb, obj3);
return sb.toString();
}

private static void keyFor(StringBuilder builder, Object obj) {
builder.append(obj.toString());
if (obj instanceof ByteList) builder.append('_').append(((ByteList) obj).getEncoding());
builder.append('_');
}

public void pushDRegexp(final Runnable callback, final RegexpOptions options, final int arity) {
if (arity > MAX_ARGUMENTS) throw new NotCompilableException("dynamic regexp has more than " + MAX_ARGUMENTS + " elements");

SkinnyMethodAdapter adapter2;
final String incomingSig = sig(RubyRegexp.class, params(ThreadContext.class, RubyString.class, arity, int.class));

if (!getClassData().dregexpMethodsDefined.contains(arity)) {
final String methodName = "dregexp:" + arity;
final ClassData classData = getClassData();

if (!classData.dregexpMethodsDefined.contains(arity)) {
adapter2 = new SkinnyMethodAdapter(
adapter.getClassVisitor(),
Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC,
"dregexp:" + arity,
methodName,
incomingSig,
null,
null);
@@ -205,32 +219,34 @@ public void pushDRegexp(final Runnable callback, final RegexpOptions options, fi
adapter2.areturn();
adapter2.end();

getClassData().dregexpMethodsDefined.add(arity);
classData.dregexpMethodsDefined.add(arity);
}

final String className = classData.clsName;

if (options.isOnce()) {
// need to cache result forever, but do it under sync to avoid double init
final String cacheField = "dregexp" + getClassData().callSiteCount.getAndIncrement();
final String cacheField = "dregexp" + classData.callSiteCount.getAndIncrement();
final Label done = new Label();
final String clsDesc = "L" + getClassData().clsName.replaceAll("\\.", "/") + ";";
final String clsDesc = 'L' + className.replace('.', '/') + ';';
adapter.ldc(Type.getType(clsDesc));
adapter.monitorenter();
adapter.trycatch(p(Throwable.class),
new Runnable() {
public void run() {
adapter.getClassVisitor().visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, cacheField, ci(RubyRegexp.class), null, null).visitEnd();
adapter.getstatic(getClassData().clsName, cacheField, ci(RubyRegexp.class));
adapter.getstatic(className, cacheField, ci(RubyRegexp.class));
adapter.dup();
adapter.ifnonnull(done);
adapter.pop();

// call synthetic method if we still need to build dregexp
callback.run();
adapter.ldc(options.toEmbeddedOptions());
adapter.invokestatic(getClassData().clsName, "dregexp:" + arity, incomingSig);
adapter.invokestatic(className, methodName, incomingSig);

adapter.dup();
adapter.putstatic(getClassData().clsName, cacheField, ci(RubyRegexp.class));
adapter.putstatic(className, cacheField, ci(RubyRegexp.class));
adapter.label(done);

adapter.ldc(Type.getType(clsDesc));
@@ -248,7 +264,7 @@ public void run() {
// call synthetic method if we still need to build dregexp
callback.run();
adapter.ldc(options.toEmbeddedOptions());
adapter.invokestatic(getClassData().clsName, "dregexp:" + arity, incomingSig);
adapter.invokestatic(className, methodName, incomingSig);
}
}

@@ -473,7 +489,7 @@ public void invokeOtherOneFloat(String name, double flote) {
String incomingSig = sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT));
String outgoingSig = sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, double.class));

String methodName = "invokeOtherOneFloat" + getClassData().callSiteCount.getAndIncrement() + ":" + JavaNameMangler.mangleMethodName(name);
String methodName = "invokeOtherOneFloat" + getClassData().callSiteCount.getAndIncrement() + ':' + JavaNameMangler.mangleMethodName(name);

adapter2 = new SkinnyMethodAdapter(
adapter.getClassVisitor(),
@@ -559,7 +575,7 @@ private void performSuper(String name, int arity, boolean hasClosure, boolean[]
sig(JVM.OBJECT, params(ThreadContext.class, IRubyObject.class, String.class, RubyModule.class, JVM.OBJECT_ARRAY, Block.class, boolean[].class));
}

String methodName = "invokeSuper" + getClassData().callSiteCount.getAndIncrement() + ":" + JavaNameMangler.mangleMethodName(name);
String methodName = "invokeSuper" + getClassData().callSiteCount.getAndIncrement() + ':' + JavaNameMangler.mangleMethodName(name);
adapter2 = new SkinnyMethodAdapter(
adapter.getClassVisitor(),
Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC,
@@ -661,7 +677,7 @@ private void cacheVariableAccessor(String name, boolean write) {
SkinnyMethodAdapter adapter2;
String incomingSig = sig(VariableAccessor.class, params(JVM.OBJECT));

String methodName = (write ? "ivarSet" : "ivarGet") + getClassData().callSiteCount.getAndIncrement() + ":" + JavaNameMangler.mangleMethodName(name);
String methodName = (write ? "ivarSet" : "ivarGet") + getClassData().callSiteCount.getAndIncrement() + ':' + JavaNameMangler.mangleMethodName(name);

adapter2 = new SkinnyMethodAdapter(
adapter.getClassVisitor(),
@@ -674,8 +690,10 @@ private void cacheVariableAccessor(String name, boolean write) {
// call site object field
adapter.getClassVisitor().visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC, methodName, ci(VariableAccessor.class), null, null).visitEnd();

final String className = getClassData().clsName;

// retrieve accessor, verifying if non-null
adapter2.getstatic(getClassData().clsName, methodName, ci(VariableAccessor.class));
adapter2.getstatic(className, methodName, ci(VariableAccessor.class));
adapter2.dup();
Label get = new Label();
adapter2.ifnull(get);
@@ -693,13 +711,13 @@ private void cacheVariableAccessor(String name, boolean write) {
adapter2.ldc(name);
adapter2.invokestatic(p(IRRuntimeHelpers.class), write ? "getVariableAccessorForWrite" : "getVariableAccessorForRead", sig(VariableAccessor.class, IRubyObject.class, String.class));
adapter2.dup();
adapter2.putstatic(getClassData().clsName, methodName, ci(VariableAccessor.class));
adapter2.putstatic(className, methodName, ci(VariableAccessor.class));
adapter2.areturn();

adapter2.end();

// call it from original method to get accessor
adapter.invokestatic(getClassData().clsName, methodName, incomingSig);
adapter.invokestatic(className, methodName, incomingSig);
}

public void array(int length) {
@@ -708,11 +726,14 @@ public void array(int length) {
SkinnyMethodAdapter adapter2;
String incomingSig = sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, length));

if (!getClassData().arrayMethodsDefined.contains(length)) {
final String methodName = "array:" + length;
final ClassData classData = getClassData();

if (!classData.arrayMethodsDefined.contains(length)) {
adapter2 = new SkinnyMethodAdapter(
adapter.getClassVisitor(),
Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC,
"array:" + length,
methodName,
incomingSig,
null,
null);
@@ -725,11 +746,11 @@ public void array(int length) {
adapter2.areturn();
adapter2.end();

getClassData().arrayMethodsDefined.add(length);
classData.arrayMethodsDefined.add(length);
}

// now call it
adapter.invokestatic(getClassData().clsName, "array:" + length, incomingSig);
adapter.invokestatic(classData.clsName, methodName, incomingSig);
}

public void hash(int length) {
@@ -738,11 +759,14 @@ public void hash(int length) {
SkinnyMethodAdapter adapter2;
String incomingSig = sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, length * 2));

if (!getClassData().hashMethodsDefined.contains(length)) {
final String methodName = "hash:" + length;
final ClassData classData = getClassData();

if (!classData.hashMethodsDefined.contains(length)) {
adapter2 = new SkinnyMethodAdapter(
adapter.getClassVisitor(),
Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC,
"hash:" + length,
methodName,
incomingSig,
null,
null);
@@ -755,11 +779,11 @@ public void hash(int length) {
adapter2.areturn();
adapter2.end();

getClassData().hashMethodsDefined.add(length);
classData.hashMethodsDefined.add(length);
}

// now call it
adapter.invokestatic(getClassData().clsName, "hash:" + length, incomingSig);
adapter.invokestatic(classData.clsName, methodName, incomingSig);
}

public void kwargsHash(int length) {
@@ -768,11 +792,14 @@ public void kwargsHash(int length) {
SkinnyMethodAdapter adapter2;
String incomingSig = sig(JVM.OBJECT, params(ThreadContext.class, RubyHash.class, IRubyObject.class, length * 2));

if (!getClassData().kwargsHashMethodsDefined.contains(length)) {
final String methodName = "kwargsHash:" + length;
final ClassData classData = getClassData();

if (!classData.kwargsHashMethodsDefined.contains(length)) {
adapter2 = new SkinnyMethodAdapter(
adapter.getClassVisitor(),
Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC,
"kwargsHash:" + length,
methodName,
incomingSig,
null,
null);
@@ -785,11 +812,11 @@ public void kwargsHash(int length) {
adapter2.areturn();
adapter2.end();

getClassData().kwargsHashMethodsDefined.add(length);
classData.kwargsHashMethodsDefined.add(length);
}

// now call it
adapter.invokestatic(getClassData().clsName, "kwargsHash:" + length, incomingSig);
adapter.invokestatic(classData.clsName, methodName, incomingSig);
}

public void checkpoint() {
20 changes: 9 additions & 11 deletions core/src/main/java/org/jruby/runtime/backtrace/BacktraceData.java
Original file line number Diff line number Diff line change
@@ -31,13 +31,14 @@ public BacktraceData(StackTraceElement[] javaTrace, BacktraceElement[] rubyTrace
false,
false);

public RubyStackTraceElement[] getBacktrace(Ruby runtime) {
public final RubyStackTraceElement[] getBacktrace(Ruby runtime) {
if (backtraceElements == null) {
backtraceElements = constructBacktrace(runtime.getBoundMethods());
}
return backtraceElements;
}

@SuppressWarnings("unchecked")
public RubyStackTraceElement[] getBacktraceWithoutRuby() {
return constructBacktrace(Collections.EMPTY_MAP);
}
@@ -109,23 +110,23 @@ private RubyStackTraceElement[] constructBacktrace(Map<String, Map<String, Strin
}

// Interpreted frames
if ( rubyFrameIndex >= 0 && FrameType.isInterpreterFrame(className, methodName) ) {
final FrameType frameType;
if ( rubyFrameIndex >= 0 && (frameType = FrameType.getInterpreterFrame(className, methodName)) != null ) {

// pop interpreter frame
BacktraceElement rubyFrame = rubyTrace[rubyFrameIndex--];

FrameType frameType = FrameType.getInterpreterFrame(methodName);

// construct Ruby trace element
String newName = rubyFrame.method;
final String newName;
switch (frameType) {
case METHOD: newName = rubyFrame.method; break;
case BLOCK: newName = "block in " + rubyFrame.method; break;
case CLASS: newName = "<class:" + rubyFrame.method + ">"; break;
case MODULE: newName = "<module:" + rubyFrame.method + ">"; break;
case CLASS: newName = "<class:" + rubyFrame.method + '>'; break;
case MODULE: newName = "<module:" + rubyFrame.method + '>'; break;
case METACLASS: newName = "singleton class"; break;
case ROOT: newName = "<top>"; break;
case EVAL: newName = "<eval>"; break;
default: newName = rubyFrame.method;
}
RubyStackTraceElement rubyElement = new RubyStackTraceElement("RUBY", newName, rubyFrame.filename, rubyFrame.line + 1, false);

@@ -151,10 +152,7 @@ private RubyStackTraceElement[] constructBacktrace(Map<String, Map<String, Strin

public static String getBoundMethodName(Map<String,Map<String,String>> boundMethods, String className, String methodName) {
Map<String, String> javaToRuby = boundMethods.get(className);

if (javaToRuby == null) return null;

return javaToRuby.get(methodName);
return javaToRuby == null ? null : javaToRuby.get(methodName);
}

private static String packagedFilenameFromElement(final String filename, final String className) {
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@

import org.jruby.lexer.yacc.ISourcePosition;

public class BacktraceElement {
public final class BacktraceElement implements Cloneable {

public BacktraceElement() {
}
13 changes: 9 additions & 4 deletions core/src/main/java/org/jruby/runtime/backtrace/FrameType.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.jruby.runtime.backtrace;

import java.util.HashSet;
import java.util.Set;

import org.jruby.internal.runtime.methods.InterpretedIRBodyMethod;
import org.jruby.internal.runtime.methods.InterpretedIRMethod;
@@ -11,7 +10,7 @@
public enum FrameType {
METHOD, BLOCK, EVAL, CLASS, MODULE, METACLASS, ROOT;

private static final Set<String> INTERPRETED_CLASSES = new HashSet<String>(4, 1);
private static final HashSet<String> INTERPRETED_CLASSES = new HashSet<String>(6, 1);

static {
INTERPRETED_CLASSES.add(Interpreter.class.getName());
@@ -21,8 +20,7 @@ public enum FrameType {
}

public static boolean isInterpreterFrame(final String className, final String methodName) {
if ( ! INTERPRETED_CLASSES.contains(className) ) return false;
return getInterpreterFrame(methodName) != null;
return getInterpreterFrame(className, methodName) != null;
}

public static FrameType getInterpreterFrame(final String methodName) {
@@ -38,4 +36,11 @@ public static FrameType getInterpreterFrame(final String methodName) {
return null;
}

public static FrameType getInterpreterFrame(final String className, final String methodName) {
if ( INTERPRETED_CLASSES.contains(className) ) {
return getInterpreterFrame(methodName);
}
return null;
}

}