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: 16b0f81a8b7f
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 3793a79aa394
Choose a head ref
  • 9 commits
  • 7 files changed
  • 1 contributor

Commits on Apr 10, 2016

  1. Copy the full SHA
    c81cb36 View commit details
  2. Copy the full SHA
    4628a72 View commit details
  3. Copy the full SHA
    c1a4ea2 View commit details
  4. Copy the full SHA
    8c157a2 View commit details
  5. Copy the full SHA
    39fc7e1 View commit details
  6. cleanup InvocationMethodFactory some - re-use Class array instead of …

    …allocating
    
    + make most of the private methods static
    + use singleton list for a single list element
    kares committed Apr 10, 2016
    Copy the full SHA
    f90e9a8 View commit details
  7. Copy the full SHA
    315bbc7 View commit details
  8. Copy the full SHA
    5553522 View commit details
  9. fix (and improve) incorrect String concat regression due 9c555c2

    ... was obviously playing find-bugs by hand WRONG!
    
    probably might have caused some hard-to-find regression ... resolves #3787
    kares committed Apr 10, 2016
    Copy the full SHA
    3793a79 View commit details
62 changes: 34 additions & 28 deletions core/src/main/java/org/jruby/RubyModule.java
Original file line number Diff line number Diff line change
@@ -931,12 +931,12 @@ public void defineAnnotatedMethods(Class clazz) {
defineAnnotatedMethodsIndividually(clazz);
}

public static class MethodClumper {
Map<String, List<JavaMethodDescriptor>> annotatedMethods = new HashMap<String, List<JavaMethodDescriptor>>();
Map<String, List<JavaMethodDescriptor>> staticAnnotatedMethods = new HashMap<String, List<JavaMethodDescriptor>>();
Map<String, List<JavaMethodDescriptor>> allAnnotatedMethods = new HashMap<String, List<JavaMethodDescriptor>>();
public static final class MethodClumper {
final HashMap<String, List<JavaMethodDescriptor>> annotatedMethods = new HashMap<>();
final HashMap<String, List<JavaMethodDescriptor>> staticAnnotatedMethods = new HashMap<>();
// final HashMap<String, List<JavaMethodDescriptor>> allAnnotatedMethods = new HashMap<>();

public void clump(Class cls) {
public void clump(final Class cls) {
Method[] declaredMethods = Initializer.DECLARED_METHODS.get(cls);
for (Method method: declaredMethods) {
JRubyMethod anno = method.getAnnotation(JRubyMethod.class);
@@ -961,40 +961,46 @@ public void clump(Class cls) {
// add to specific
methodDescs = methodsHash.get(name);
if (methodDescs == null) {
methodDescs = new ArrayList<JavaMethodDescriptor>();
methodsHash.put(name, methodDescs);
} else {
// optimize for most methods mapping to one method for a given name :
methodsHash.put(name, Collections.singletonList(desc));
}
else {
CompatVersion oldCompat = methodDescs.get(0).anno.compat();
CompatVersion newCompat = desc.anno.compat();

int comparison = newCompat.compareTo(oldCompat);
if (comparison == 1) {
// new method's compat is higher than old method's, so we throw old one away
methodDescs = new ArrayList<JavaMethodDescriptor>();
methodsHash.put(name, methodDescs);
methodsHash.put(name, methodDescs = new ArrayList<>(2));
} else if (comparison == 0) {
// same compat version, proceed to adding additional method
} else {
// lower compat, skip this method
continue;
}
}

methodDescs.add(desc);
if (methodDescs.getClass() != ArrayList.class) { // due singletonList
ArrayList<JavaMethodDescriptor> newDescs = new ArrayList<>(4);
newDescs.addAll(methodDescs);
methodsHash.put(name, methodDescs = newDescs);
}

// add to general
methodDescs = allAnnotatedMethods.get(name);
if (methodDescs == null) {
methodDescs = new ArrayList<JavaMethodDescriptor>();
allAnnotatedMethods.put(name, methodDescs);
methodDescs.add(desc);
}

methodDescs.add(desc);
// add to general
//methodDescs = allAnnotatedMethods.get(name);
//if (methodDescs == null) {
// methodDescs = new ArrayList<JavaMethodDescriptor>();
// allAnnotatedMethods.put(name, methodDescs);
//}
//methodDescs.add(desc);
}
}

@Deprecated // no-longer used
public Map<String, List<JavaMethodDescriptor>> getAllAnnotatedMethods() {
return allAnnotatedMethods;
return null; // return allAnnotatedMethods;
}

public Map<String, List<JavaMethodDescriptor>> getAnnotatedMethods() {
@@ -1032,23 +1038,23 @@ public static TypePopulator loadPopulatorFor(Class<?> type) {
return new TypePopulator.ReflectiveTypePopulator(type);
}

public void defineAnnotatedMethodsIndividually(Class clazz) {
public final void defineAnnotatedMethodsIndividually(Class clazz) {
getRuntime().POPULATORS.get(clazz).populate(this, clazz);
}

public boolean defineAnnotatedMethod(String name, List<JavaMethodDescriptor> methods, MethodFactory methodFactory) {
public final boolean defineAnnotatedMethod(String name, List<JavaMethodDescriptor> methods, MethodFactory methodFactory) {
JavaMethodDescriptor desc = methods.get(0);
if (methods.size() == 1) {
return defineAnnotatedMethod(name, desc, methodFactory);
} else {
DynamicMethod dynamicMethod = methodFactory.getAnnotatedMethod(this, methods);
define(this, desc, name, dynamicMethod);

return true;
}

DynamicMethod dynamicMethod = methodFactory.getAnnotatedMethod(this, methods);
define(this, desc, name, dynamicMethod);

return true;
}

public boolean defineAnnotatedMethod(Method method, MethodFactory methodFactory) {
public final boolean defineAnnotatedMethod(Method method, MethodFactory methodFactory) {
JRubyMethod jrubyMethod = method.getAnnotation(JRubyMethod.class);

if (jrubyMethod == null) return false;
@@ -1060,7 +1066,7 @@ public boolean defineAnnotatedMethod(Method method, MethodFactory methodFactory)
return true;
}

public boolean defineAnnotatedMethod(String name, JavaMethodDescriptor desc, MethodFactory methodFactory) {
public final boolean defineAnnotatedMethod(String name, JavaMethodDescriptor desc, MethodFactory methodFactory) {
JRubyMethod jrubyMethod = desc.anno;

if (jrubyMethod == null) return false;
24 changes: 15 additions & 9 deletions core/src/main/java/org/jruby/anno/TypePopulator.java
Original file line number Diff line number Diff line change
@@ -74,7 +74,7 @@ public void populate(RubyModule clsmod, Class clazz) {
}
}

public static class ReflectiveTypePopulator extends TypePopulator {
public static final class ReflectiveTypePopulator extends TypePopulator {
private final Class clazz;
private final RubyModule.MethodClumper clumper;

@@ -88,20 +88,26 @@ public void populate(RubyModule clsmod, Class clazz) {
assert clazz == this.clazz : "populator for " + this.clazz + " used for " + clazz;

// fallback on non-pregenerated logic
MethodFactory methodFactory = MethodFactory.createFactory(clsmod.getRuntime().getJRubyClassLoader());
Ruby runtime = clsmod.getRuntime();
final Ruby runtime = clsmod.getRuntime();
final MethodFactory methodFactory = MethodFactory.createFactory(runtime.getJRubyClassLoader());

for (Map.Entry<String, List<JavaMethodDescriptor>> entry : clumper.getStaticAnnotatedMethods().entrySet()) {
clsmod.defineAnnotatedMethod(entry.getKey(), entry.getValue(), methodFactory);
for (JavaMethodDescriptor desc : entry.getValue()) {
if (!desc.anno.omit()) runtime.addBoundMethod(desc.declaringClassName, desc.name, entry.getKey());
final String name = entry.getKey();
final List<JavaMethodDescriptor> methods = entry.getValue();
clsmod.defineAnnotatedMethod(name, methods, methodFactory);
for ( int i=0; i<methods.size(); i++ ) {
final JavaMethodDescriptor desc = methods.get(i);
if (!desc.anno.omit()) runtime.addBoundMethod(desc.declaringClassName, desc.name, name);
}
}

for (Map.Entry<String, List<JavaMethodDescriptor>> entry : clumper.getAnnotatedMethods().entrySet()) {
clsmod.defineAnnotatedMethod(entry.getKey(), entry.getValue(), methodFactory);
for (JavaMethodDescriptor desc : entry.getValue()) {
if (!desc.anno.omit()) runtime.addBoundMethod(desc.declaringClassName, desc.name, entry.getKey());
final String name = entry.getKey();
final List<JavaMethodDescriptor> methods = entry.getValue();
clsmod.defineAnnotatedMethod(name, methods, methodFactory);
for ( int i=0; i<methods.size(); i++ ) {
final JavaMethodDescriptor desc = methods.get(i);
if (!desc.anno.omit()) runtime.addBoundMethod(desc.declaringClassName, desc.name, name);
}
}
}
46 changes: 31 additions & 15 deletions core/src/main/java/org/jruby/compiler/impl/SkinnyMethodAdapter.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,34 @@
/*
* SkinnyMethodAdapter.java
/***** BEGIN LICENSE BLOCK *****
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
*
* Created on March 10, 2007, 2:52 AM
* The contents of this file are subject to the Eclipse Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.eclipse.org/legal/epl-v10.html
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/

* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the EPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/
package org.jruby.compiler.impl;

import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.Map;
import java.util.concurrent.Callable;

import org.jruby.util.SafePropertyAccessor;
import org.jruby.util.cli.Options;
import static org.jruby.util.CodegenUtils.*;

@@ -26,24 +40,26 @@
import org.objectweb.asm.Handle;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.util.Printer;
import org.objectweb.asm.util.Textifier;
import org.objectweb.asm.util.TraceMethodVisitor;
import static org.objectweb.asm.Opcodes.*;

/**
*
* @author headius
*/
public class SkinnyMethodAdapter extends MethodVisitor implements Opcodes {
public final class SkinnyMethodAdapter extends MethodVisitor {
private final static boolean DEBUG = Options.COMPILE_DUMP.load();

private final String name;
private final ClassVisitor cv;
private final Label start;
private final Label end;

private MethodVisitor method;
private Printer printer;
private String name;
private ClassVisitor cv;
private Label start;
private Label end;

public SkinnyMethodAdapter(ClassVisitor cv, int flags, String name, String signature, String something, String[] exceptions) {
super(ASM4);
Original file line number Diff line number Diff line change
@@ -84,9 +84,9 @@ public DescriptorInfo(List<? extends MethodDescriptor> descs) {
}

if (frame && !desc.anno.frame())
throw new RuntimeException("Unbalanced frame property on method " + desc.declaringClassName + "." + desc.name);
throw new RuntimeException("Unbalanced frame property on method " + desc.declaringClassName + '.' + desc.name);
if (scope && !desc.anno.scope())
throw new RuntimeException("Unbalanced scope property on method " + desc.declaringClassName + "." + desc.name);
throw new RuntimeException("Unbalanced scope property on method " + desc.declaringClassName + '.' + desc.name);
frame |= desc.anno.frame();
scope |= desc.anno.scope();
block |= desc.hasBlock;
@@ -104,27 +104,27 @@ public DescriptorInfo(List<? extends MethodDescriptor> descs) {
int i = 0;
for (; i < min; i++) {
if (i > 0) descBuilder.append(';');
descBuilder.append("n");
descBuilder.append('n');
}
// variable arity
} else if (RICH_NATIVE_METHOD_PARAMETERS) {
int i = 0;
for (; i < min; i++) {
if (i > 0) descBuilder.append(';');
descBuilder.append("n");
descBuilder.append('n');
}

for (; i < max; i++) {
if (i > 0) descBuilder.append(';');
descBuilder.append("O");
descBuilder.append('O');
}

if (rest) {
if (i > 0) descBuilder.append(';');
descBuilder.append("R");
descBuilder.append('R');
}
} else {
descBuilder.append("R");
descBuilder.append('R');
}

parameterDesc = descBuilder.toString();
Loading