Skip to content

Commit

Permalink
Showing 4 changed files with 150 additions and 99 deletions.
41 changes: 29 additions & 12 deletions core/src/main/java/org/jruby/RubyModule.java
Original file line number Diff line number Diff line change
@@ -38,8 +38,6 @@
package org.jruby;

import com.headius.invokebinder.Binder;
import org.jcodings.Encoding;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Field;
@@ -58,7 +56,7 @@
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;

import org.jcodings.Encoding;
import org.jruby.anno.AnnotationBinder;
import org.jruby.anno.AnnotationHelper;
import org.jruby.anno.JRubyClass;
@@ -118,9 +116,21 @@
import org.jruby.util.log.Logger;
import org.jruby.util.log.LoggerFactory;

import static org.jruby.anno.FrameField.*;
import static org.jruby.anno.FrameField.BACKREF;
import static org.jruby.anno.FrameField.BLOCK;
import static org.jruby.anno.FrameField.CLASS;
import static org.jruby.anno.FrameField.FILENAME;
import static org.jruby.anno.FrameField.JUMPTARGET;
import static org.jruby.anno.FrameField.LASTLINE;
import static org.jruby.anno.FrameField.LINE;
import static org.jruby.anno.FrameField.METHODNAME;
import static org.jruby.anno.FrameField.SCOPE;
import static org.jruby.anno.FrameField.SELF;
import static org.jruby.anno.FrameField.VISIBILITY;
import static org.jruby.runtime.Visibility.*;
import static org.jruby.runtime.Visibility.MODULE_FUNCTION;
import static org.jruby.runtime.Visibility.PRIVATE;
import static org.jruby.runtime.Visibility.PROTECTED;
import static org.jruby.runtime.Visibility.PUBLIC;


/**
@@ -1311,20 +1321,27 @@ public DynamicMethod searchWithRefinements(String name, StaticScope refinedScope
* @param cacheUndef Flag for caching UndefinedMethod. This should normally be true.
* @return The method, or UndefinedMethod if not found
*/
public CacheEntry searchWithCache(String name, boolean cacheUndef) {
CacheEntry entry = cacheHit(name);

if (entry != null) return entry;
public final CacheEntry searchWithCache(String name, boolean cacheUndef) {
final CacheEntry entry = cacheHit(name);
return entry != null ? entry : searchWithCacheMiss(name, cacheUndef);
}

/**
* Search through this module and supermodules for method definitions after {@link RubyModule#cacheHit(String)}
* failed to return a result. Cache superclass definitions in this class.
*
* @param name The name of the method to search for
* @param cacheUndef Flag for caching UndefinedMethod. This should normally be true.
* @return The method, or UndefinedMethod if not found
*/
private CacheEntry searchWithCacheMiss(final String name, final boolean cacheUndef) {
// we grab serial number first; the worst that will happen is we cache a later
// update with an earlier serial number, which would just flush anyway
int token = getGeneration();
final int token = generation;
DynamicMethod method = searchMethodInner(name);

if (method instanceof CacheableMethod) {
method = ((CacheableMethod) method).getMethodForCaching();
}

return method != null ? addToCache(name, method, token) : cacheUndef ? addToCache(name, UndefinedMethod.getInstance(), token) : cacheEntryFactory.newCacheEntry(name, method, token);
}

22 changes: 11 additions & 11 deletions core/src/main/java/org/jruby/ast/executable/RuntimeCache.java
Original file line number Diff line number Diff line change
@@ -405,7 +405,7 @@ public IRubyObject reCacheFrom(RubyModule target, ThreadContext context, String

public DynamicMethod getMethod(ThreadContext context, RubyClass selfType, int index, String methodName) {
CacheEntry myCache = getCacheEntry(index);
if (CacheEntry.typeOk(myCache, selfType)) {
if (myCache.typeOk(selfType)) {
return myCache.method;
}
return cacheAndGet(context, selfType, index, methodName);
@@ -448,7 +448,7 @@ private DynamicMethod searchWithCacheNoMethodMissing(RubyClass clazz, int index,
// used from byte-code generated by RealClassGenerator
public final DynamicMethod searchWithCacheNoMethodMissing(IRubyObject obj, int index, String name1) {
CacheEntry myCache = getCacheEntry(index);
if (CacheEntry.typeOk(myCache, obj.getMetaClass())) {
if (myCache.typeOk(obj.getMetaClass())) {
return myCache.method;
}
return searchWithCacheNoMethodMissing(obj.getMetaClass(), index, name1);
@@ -457,7 +457,7 @@ public final DynamicMethod searchWithCacheNoMethodMissing(IRubyObject obj, int i
// used from byte-code generated by RealClassGenerator
public final DynamicMethod searchWithCacheNoMethodMissing(IRubyObject obj, int index, String name1, String name2) {
CacheEntry myCache = getCacheEntry(index);
if (CacheEntry.typeOk(myCache, obj.getMetaClass())) {
if (myCache.typeOk(obj.getMetaClass())) {
return myCache.method;
}
return searchWithCacheNoMethodMissing(obj.getMetaClass(), index, name1, name2);
@@ -545,63 +545,63 @@ public DynamicMethod searchWithCache(RubyClass clazz, int index, String name1, S

public DynamicMethod searchWithCache(IRubyObject obj, int index, String name1) {
CacheEntry myCache = getCacheEntry(index);
if (CacheEntry.typeOk(myCache, obj.getMetaClass())) {
if (myCache.typeOk(obj.getMetaClass())) {
return myCache.method;
}
return searchWithCache(obj.getMetaClass(), index, name1);
}

public DynamicMethod searchWithCache(IRubyObject obj, int index, String name1, String name2) {
CacheEntry myCache = getCacheEntry(index);
if (CacheEntry.typeOk(myCache, obj.getMetaClass())) {
if (myCache.typeOk(obj.getMetaClass())) {
return myCache.method;
}
return searchWithCache(obj.getMetaClass(), index, name1, name2);
}

public DynamicMethod searchWithCache(IRubyObject obj, int index, String name1, String name2, String name3) {
CacheEntry myCache = getCacheEntry(index);
if (CacheEntry.typeOk(myCache, obj.getMetaClass())) {
if (myCache.typeOk(obj.getMetaClass())) {
return myCache.method;
}
return searchWithCache(obj.getMetaClass(), index, name1, name2, name3);
}

public DynamicMethod searchWithCache(IRubyObject obj, int index, String name1, String name2, String name3, String name4) {
CacheEntry myCache = getCacheEntry(index);
if (CacheEntry.typeOk(myCache, obj.getMetaClass())) {
if (myCache.typeOk(obj.getMetaClass())) {
return myCache.method;
}
return searchWithCache(obj.getMetaClass(), index, name1, name2, name3, name4);
}

public DynamicMethod searchWithCache(IRubyObject obj, int index, String name1, String name2, String name3, String name4, String name5) {
CacheEntry myCache = getCacheEntry(index);
if (CacheEntry.typeOk(myCache, obj.getMetaClass())) {
if (myCache.typeOk(obj.getMetaClass())) {
return myCache.method;
}
return searchWithCache(obj.getMetaClass(), index, name1, name2, name3, name4, name5);
}

public DynamicMethod searchWithCache(IRubyObject obj, int index, String name1, String name2, String name3, String name4, String name5, String name6) {
CacheEntry myCache = getCacheEntry(index);
if (CacheEntry.typeOk(myCache, obj.getMetaClass())) {
if (myCache.typeOk(obj.getMetaClass())) {
return myCache.method;
}
return searchWithCache(obj.getMetaClass(), index, name1, name2, name3, name4, name5, name6);
}

public DynamicMethod searchWithCache(IRubyObject obj, int index, String name1, String name2, String name3, String name4, String name5, String name6, String name7) {
CacheEntry myCache = getCacheEntry(index);
if (CacheEntry.typeOk(myCache, obj.getMetaClass())) {
if (myCache.typeOk(obj.getMetaClass())) {
return myCache.method;
}
return searchWithCache(obj.getMetaClass(), index, name1, name2, name3, name4, name5, name6, name7);
}

public DynamicMethod searchWithCache(IRubyObject obj, int index, String name1, String name2, String name3, String name4, String name5, String name6, String name7, String name8) {
CacheEntry myCache = getCacheEntry(index);
if (CacheEntry.typeOk(myCache, obj.getMetaClass())) {
if (myCache.typeOk(obj.getMetaClass())) {
return myCache.method;
}
return searchWithCache(obj.getMetaClass(), index, name1, name2, name3, name4, name5, name6, name7, name8);
Original file line number Diff line number Diff line change
@@ -15,11 +15,7 @@ public CacheEntry(DynamicMethod method, int token) {
}

public final boolean typeOk(RubyClass incomingType) {
return typeOk(this, incomingType);
}

public static final boolean typeOk(CacheEntry entry, RubyClass incomingType) {
return entry.token == incomingType.getGeneration();
return token == incomingType.getGeneration();
}

@Override
180 changes: 109 additions & 71 deletions core/src/main/java/org/jruby/runtime/callsite/CachingCallSite.java
Original file line number Diff line number Diff line change
@@ -27,12 +27,12 @@ public final CacheEntry getCache() {
return cache;
}

public boolean isOptimizable() {
return getCache() != CacheEntry.NULL_CACHE;// && !isPolymorphic.get();
public final boolean isOptimizable() {
return cache != CacheEntry.NULL_CACHE;// && !isPolymorphic.get();
}

public int getCachedClassIndex() {
CacheEntry cacheEntry = getCache();
public final int getCachedClassIndex() {
CacheEntry cacheEntry = cache;
if (cacheEntry != CacheEntry.NULL_CACHE) {
return cacheEntry.method.getImplementationClass().getClassIndex().ordinal();
}
@@ -43,27 +43,30 @@ public final String getMethodName() {
return methodName;
}

public long getCachedMethodSerial() {
CacheEntry cacheEntry = getCache();
public final long getCachedMethodSerial() {
CacheEntry cacheEntry = cache;
if (cacheEntry != CacheEntry.NULL_CACHE) {
return cacheEntry.method.getSerialNumber();
}
return -1;
}

@Override
public IRubyObject call(ThreadContext context, IRubyObject caller, IRubyObject self, long fixnum) {
return call(context, caller, self, RubyFixnum.newFixnum(context.runtime, fixnum));
}

@Override
public IRubyObject call(ThreadContext context, IRubyObject caller, IRubyObject self, double flote) {
return call(context, caller, self, RubyFloat.newFloat(context.runtime, flote));
}

@Override
public IRubyObject call(ThreadContext context, IRubyObject caller, IRubyObject self, IRubyObject... args) {
RubyClass selfType = getClass(self);
// This must be retrieved *once* to avoid racing with other threads.
CacheEntry cache = this.cache;
if (CacheEntry.typeOk(cache, selfType)) {
if (cache.typeOk(selfType)) {
return cache.method.call(context, self, selfType, methodName, args);
}
return cacheAndCall(caller, selfType, args, context, self);
@@ -73,25 +76,30 @@ private IRubyObject callBlock(ThreadContext context, IRubyObject caller, IRubyOb
RubyClass selfType = getClass(self);
// This must be retrieved *once* to avoid racing with other threads.
CacheEntry cache = this.cache;
if (CacheEntry.typeOk(cache, selfType)) {
if (cache.typeOk(selfType)) {
return cache.method.call(context, self, selfType, methodName, args, block);
}
return cacheAndCall(caller, selfType, block, args, context, self);
}

@Override
public IRubyObject call(ThreadContext context, IRubyObject caller, IRubyObject self, IRubyObject[] args, Block block) {
return callBlock(context, caller, self, args, block);
}

public IRubyObject callIter(ThreadContext context, IRubyObject caller, IRubyObject self, IRubyObject[] args, Block block) {
@Override
public final IRubyObject callIter(ThreadContext context, IRubyObject caller, IRubyObject self,
IRubyObject[] args, Block block) {
try {
return callBlock(context, caller, self, args, block);
} finally {
block.escape();
}
}

public IRubyObject callVarargs(ThreadContext context, IRubyObject caller, IRubyObject self, IRubyObject... args) {
@Override
public final IRubyObject callVarargs(ThreadContext context, IRubyObject caller,
IRubyObject self, IRubyObject... args) {
switch (args.length) {
case 0: return call(context, caller, self);
case 1: return call(context, caller, self, args[0]);
@@ -101,7 +109,9 @@ public IRubyObject callVarargs(ThreadContext context, IRubyObject caller, IRubyO
}
}

public IRubyObject callVarargs(ThreadContext context, IRubyObject caller, IRubyObject self, IRubyObject[] args, Block block) {
@Override
public final IRubyObject callVarargs(ThreadContext context, IRubyObject caller,
IRubyObject self, IRubyObject[] args, Block block) {
switch (args.length) {
case 0: return call(context, caller, self, block);
case 1: return call(context, caller, self, args[0], block);
@@ -111,7 +121,9 @@ public IRubyObject callVarargs(ThreadContext context, IRubyObject caller, IRubyO
}
}

public IRubyObject callVarargsIter(ThreadContext context, IRubyObject caller, IRubyObject self, IRubyObject[] args, Block block) {
@Override
public final IRubyObject callVarargsIter(ThreadContext context, IRubyObject caller,
IRubyObject self, IRubyObject[] args, Block block) {
switch (args.length) {
case 0: return callIter(context, caller, self, block);
case 1: return callIter(context, caller, self, args[0], block);
@@ -121,11 +133,12 @@ public IRubyObject callVarargsIter(ThreadContext context, IRubyObject caller, IR
}
}

@Override
public IRubyObject call(ThreadContext context, IRubyObject caller, IRubyObject self) {
RubyClass selfType = getClass(self);
// This must be retrieved *once* to avoid racing with other threads.
CacheEntry cache = this.cache;
if (CacheEntry.typeOk(cache, selfType)) {
if (cache.typeOk(selfType)) {
return cache.method.call(context, self, selfType, methodName);
}
return cacheAndCall(caller, selfType, context, self);
@@ -135,29 +148,33 @@ private IRubyObject callBlock(ThreadContext context, IRubyObject caller, IRubyOb
RubyClass selfType = getClass(self);
// This must be retrieved *once* to avoid racing with other threads.
CacheEntry cache = this.cache;
if (CacheEntry.typeOk(cache, selfType)) {
if (cache.typeOk(selfType)) {
return cache.method.call(context, self, selfType, methodName, block);
}
return cacheAndCall(caller, selfType, block, context, self);
}

@Override
public IRubyObject call(ThreadContext context, IRubyObject caller, IRubyObject self, Block block) {
return callBlock(context, caller, self, block);
}

public IRubyObject callIter(ThreadContext context, IRubyObject caller, IRubyObject self, Block block) {
@Override
public final IRubyObject callIter(ThreadContext context, IRubyObject caller, IRubyObject self,
Block block) {
try {
return callBlock(context, caller, self, block);
} finally {
block.escape();
}
}

@Override
public IRubyObject call(ThreadContext context, IRubyObject caller, IRubyObject self, IRubyObject arg1) {
RubyClass selfType = getClass(self);
// This must be retrieved *once* to avoid racing with other threads.
CacheEntry cache = this.cache;
if (CacheEntry.typeOk(cache, selfType)) {
if (cache.typeOk(selfType)) {
return cache.method.call(context, self, selfType, methodName, arg1);
}
return cacheAndCall(caller, selfType, context, self, arg1);
@@ -167,29 +184,33 @@ private IRubyObject callBlock(ThreadContext context, IRubyObject caller, IRubyOb
RubyClass selfType = getClass(self);
// This must be retrieved *once* to avoid racing with other threads.
CacheEntry cache = this.cache;
if (CacheEntry.typeOk(cache, selfType)) {
if (cache.typeOk(selfType)) {
return cache.method.call(context, self, selfType, methodName, arg1, block);
}
return cacheAndCall(caller, selfType, block, context, self, arg1);
}

@Override
public IRubyObject call(ThreadContext context, IRubyObject caller, IRubyObject self, IRubyObject arg1, Block block) {
return callBlock(context, caller, self, arg1, block);
}

public IRubyObject callIter(ThreadContext context, IRubyObject caller, IRubyObject self, IRubyObject arg1, Block block) {
@Override
public final IRubyObject callIter(ThreadContext context, IRubyObject caller, IRubyObject self,
IRubyObject arg1, Block block) {
try {
return callBlock(context, caller, self, arg1, block);
} finally {
block.escape();
}
}

@Override
public IRubyObject call(ThreadContext context, IRubyObject caller, IRubyObject self, IRubyObject arg1, IRubyObject arg2) {
RubyClass selfType = getClass(self);
// This must be retrieved *once* to avoid racing with other threads.
CacheEntry cache = this.cache;
if (CacheEntry.typeOk(cache, selfType)) {
if (cache.typeOk(selfType)) {
return cache.method.call(context, self, selfType, methodName, arg1, arg2);
}
return cacheAndCall(caller, selfType, context, self, arg1, arg2);
@@ -199,29 +220,33 @@ private IRubyObject callBlock(ThreadContext context, IRubyObject caller, IRubyOb
RubyClass selfType = getClass(self);
// This must be retrieved *once* to avoid racing with other threads.
CacheEntry cache = this.cache;
if (CacheEntry.typeOk(cache, selfType)) {
if (cache.typeOk(selfType)) {
return cache.method.call(context, self, selfType, methodName, arg1, arg2, block);
}
return cacheAndCall(caller, selfType, block, context, self, arg1, arg2);
}

@Override
public IRubyObject call(ThreadContext context, IRubyObject caller, IRubyObject self, IRubyObject arg1, IRubyObject arg2, Block block) {
return callBlock(context, caller, self, arg1, arg2, block);
}

public IRubyObject callIter(ThreadContext context, IRubyObject caller, IRubyObject self, IRubyObject arg1, IRubyObject arg2, Block block) {
@Override
public final IRubyObject callIter(ThreadContext context, IRubyObject caller, IRubyObject self,
IRubyObject arg1, IRubyObject arg2, Block block) {
try {
return callBlock(context, caller, self, arg1, arg2, block);
} finally {
block.escape();
}
}

@Override
public IRubyObject call(ThreadContext context, IRubyObject caller, IRubyObject self, IRubyObject arg1, IRubyObject arg2, IRubyObject arg3) {
RubyClass selfType = getClass(self);
// This must be retrieved *once* to avoid racing with other threads.
CacheEntry cache = this.cache;
if (CacheEntry.typeOk(cache, selfType)) {
if (cache.typeOk(selfType)) {
return cache.method.call(context, self, selfType, methodName, arg1, arg2, arg3);
}
return cacheAndCall(caller, selfType, context, self, arg1, arg2, arg3);
@@ -231,46 +256,49 @@ private IRubyObject callBlock(ThreadContext context, IRubyObject caller, IRubyOb
RubyClass selfType = getClass(self);
// This must be retrieved *once* to avoid racing with other threads.
CacheEntry cache = this.cache;
if (CacheEntry.typeOk(cache, selfType)) {
if (cache.typeOk(selfType)) {
return cache.method.call(context, self, selfType, methodName, arg1, arg2, arg3, block);
}
return cacheAndCall(caller, selfType, block, context, self, arg1, arg2, arg3);
}

@Override
public IRubyObject call(ThreadContext context, IRubyObject caller, IRubyObject self, IRubyObject arg1, IRubyObject arg2, IRubyObject arg3, Block block) {
return callBlock(context, caller, self, arg1, arg2, arg3, block);
}

public IRubyObject callIter(ThreadContext context, IRubyObject caller, IRubyObject self, IRubyObject arg1, IRubyObject arg2, IRubyObject arg3, Block block) {
@Override
public final IRubyObject callIter(ThreadContext context, IRubyObject caller, IRubyObject self,
IRubyObject arg1, IRubyObject arg2, IRubyObject arg3, Block block) {
try {
return callBlock(context, caller, self, arg1, arg2, arg3, block);
} finally {
block.escape();
}
}

public CacheEntry retrieveCache(RubyClass selfType) {
public final CacheEntry retrieveCache(RubyClass selfType) {
// This must be retrieved *once* to avoid racing with other threads.
CacheEntry cache = this.cache;
if (CacheEntry.typeOk(cache, selfType)) {
if (cache.typeOk(selfType)) {
return cache;
}
return cacheAndGet(selfType, methodName);
}

public CacheEntry retrieveCache(RubyClass selfType, String methodName) {
public final CacheEntry retrieveCache(RubyClass selfType, String methodName) {
// This must be retrieved *once* to avoid racing with other threads.
CacheEntry cache = this.cache;
if (CacheEntry.typeOk(cache, selfType)) {
if (cache.typeOk(selfType)) {
return cache;
}
return cacheAndGet(selfType, methodName);
}

public boolean isBuiltin(RubyClass selfType) {
public final boolean isBuiltin(RubyClass selfType) {
// This must be retrieved *once* to avoid racing with other threads.
CacheEntry cache = this.cache;
if (CacheEntry.typeOk(cache, selfType)) {
if (cache.typeOk(selfType)) {
return cache.method.isBuiltin();
}
return cacheAndGetBuiltin(selfType, methodName);
@@ -282,49 +310,52 @@ private CacheEntry cacheAndGet(RubyClass selfType, String methodName) {
return entry;
}

private boolean cacheAndGetBuiltin(RubyClass selfType, String methodName) {
CacheEntry entry = selfType.searchWithCache(methodName);
if (!entry.method.isUndefined()) return false;
return entry.method.isBuiltin();
private static boolean cacheAndGetBuiltin(RubyClass selfType, String methodName) {
final DynamicMethod method = selfType.searchWithCache(methodName).method;
return method.isUndefined() && method.isBuiltin();
}

protected IRubyObject cacheAndCall(IRubyObject caller, RubyClass selfType, Block block, IRubyObject[] args, ThreadContext context, IRubyObject self) {
private IRubyObject cacheAndCall(IRubyObject caller, RubyClass selfType, Block block,
IRubyObject[] args, ThreadContext context, IRubyObject self) {
CacheEntry entry = selfType.searchWithCache(methodName);
DynamicMethod method = entry.method;
if (methodMissing(method, caller)) {
return callMethodMissing(context, self, method, args, block);
}
updateCache(entry);
cache = entry;
return method.call(context, self, selfType, methodName, args, block);
}

protected IRubyObject cacheAndCall(IRubyObject caller, RubyClass selfType, IRubyObject[] args, ThreadContext context, IRubyObject self) {
private IRubyObject cacheAndCall(IRubyObject caller, RubyClass selfType,
IRubyObject[] args, ThreadContext context, IRubyObject self) {
CacheEntry entry = selfType.searchWithCache(methodName);
DynamicMethod method = entry.method;
if (methodMissing(method, caller)) {
return callMethodMissing(context, self, method, args);
}
updateCache(entry);
cache = entry;
return method.call(context, self, selfType, methodName, args);
}

protected IRubyObject cacheAndCall(IRubyObject caller, RubyClass selfType, ThreadContext context, IRubyObject self) {
private IRubyObject cacheAndCall(IRubyObject caller, RubyClass selfType,
ThreadContext context, IRubyObject self) {
CacheEntry entry = selfType.searchWithCache(methodName);
DynamicMethod method = entry.method;
if (methodMissing(method, caller)) {
return callMethodMissing(context, self, method);
}
updateCache(entry);
cache = entry;
return method.call(context, self, selfType, methodName);
}

protected IRubyObject cacheAndCall(IRubyObject caller, RubyClass selfType, Block block, ThreadContext context, IRubyObject self) {
private IRubyObject cacheAndCall(IRubyObject caller, RubyClass selfType, Block block,
ThreadContext context, IRubyObject self) {
CacheEntry entry = selfType.searchWithCache(methodName);
DynamicMethod method = entry.method;
if (methodMissing(method, caller)) {
return callMethodMissing(context, self, method, block);
}
updateCache(entry);
cache = entry;
return method.call(context, self, selfType, methodName, block);
}

@@ -334,17 +365,18 @@ protected IRubyObject cacheAndCall(IRubyObject caller, RubyClass selfType, Threa
if (methodMissing(method, caller)) {
return callMethodMissing(context, self, method, arg);
}
updateCache(entry);
cache = entry;
return method.call(context, self, selfType, methodName, arg);
}

protected IRubyObject cacheAndCall(IRubyObject caller, RubyClass selfType, Block block, ThreadContext context, IRubyObject self, IRubyObject arg) {
private IRubyObject cacheAndCall(IRubyObject caller, RubyClass selfType, Block block,
ThreadContext context, IRubyObject self, IRubyObject arg) {
CacheEntry entry = selfType.searchWithCache(methodName);
DynamicMethod method = entry.method;
if (methodMissing(method, caller)) {
return callMethodMissing(context, self, method, arg, block);
}
updateCache(entry);
cache = entry;
return method.call(context, self, selfType, methodName, arg, block);
}

@@ -354,86 +386,92 @@ protected IRubyObject cacheAndCall(IRubyObject caller, RubyClass selfType, Threa
if (methodMissing(method, caller)) {
return callMethodMissing(context, self, method, arg1, arg2);
}
updateCache(entry);
cache = entry;
return method.call(context, self, selfType, methodName, arg1, arg2);
}

protected IRubyObject cacheAndCall(IRubyObject caller, RubyClass selfType, Block block, ThreadContext context, IRubyObject self, IRubyObject arg1, IRubyObject arg2) {
private IRubyObject cacheAndCall(IRubyObject caller, RubyClass selfType, Block block,
ThreadContext context, IRubyObject self, IRubyObject arg1, IRubyObject arg2) {
CacheEntry entry = selfType.searchWithCache(methodName);
DynamicMethod method = entry.method;
if (methodMissing(method, caller)) {
return callMethodMissing(context, self, method, arg1, arg2, block);
}
updateCache(entry);
cache = entry;
return method.call(context, self, selfType, methodName, arg1, arg2, block);
}

protected IRubyObject cacheAndCall(IRubyObject caller, RubyClass selfType, ThreadContext context, IRubyObject self, IRubyObject arg1, IRubyObject arg2, IRubyObject arg3) {
private IRubyObject cacheAndCall(IRubyObject caller, RubyClass selfType,
ThreadContext context, IRubyObject self, IRubyObject arg1, IRubyObject arg2,
IRubyObject arg3) {
CacheEntry entry = selfType.searchWithCache(methodName);
DynamicMethod method = entry.method;
if (methodMissing(method, caller)) {
return callMethodMissing(context, self, method, arg1, arg2, arg3);
}
updateCache(entry);
cache = entry;
return method.call(context, self, selfType, methodName, arg1, arg2, arg3);
}

protected IRubyObject cacheAndCall(IRubyObject caller, RubyClass selfType, Block block, ThreadContext context, IRubyObject self, IRubyObject arg1, IRubyObject arg2, IRubyObject arg3) {
private IRubyObject cacheAndCall(IRubyObject caller, RubyClass selfType, Block block,
ThreadContext context, IRubyObject self, IRubyObject arg1, IRubyObject arg2,
IRubyObject arg3) {
CacheEntry entry = selfType.searchWithCache(methodName);
DynamicMethod method = entry.method;
if (methodMissing(method, caller)) {
return callMethodMissing(context, self, method, arg1, arg2, arg3, block);
}
updateCache(entry);
cache = entry;
return method.call(context, self, selfType, methodName, arg1, arg2, arg3, block);
}

protected void updateCache(CacheEntry newEntry) {
// not really working because it flags jitted methods as polymorphic
// CacheEntry oldCache = cache;
// if (oldCache != CacheEntry.NULL_CACHE && oldCache.method != newEntry.method) {
// isPolymorphic.set(true);
// }
cache = newEntry;
}

protected IRubyObject callMethodMissing(ThreadContext context, IRubyObject self, DynamicMethod method, IRubyObject[] args) {
protected final IRubyObject callMethodMissing(ThreadContext context, IRubyObject self,
DynamicMethod method, IRubyObject[] args) {
return Helpers.selectMethodMissing(context, self, method.getVisibility(), methodName, callType).call(context, self, self.getMetaClass(), methodName, args, Block.NULL_BLOCK);
}

protected IRubyObject callMethodMissing(ThreadContext context, IRubyObject self, DynamicMethod method) {
protected final IRubyObject callMethodMissing(ThreadContext context, IRubyObject self,
DynamicMethod method) {
return Helpers.selectMethodMissing(context, self, method.getVisibility(), methodName, callType).call(context, self, self.getMetaClass(), methodName, Block.NULL_BLOCK);
}

protected IRubyObject callMethodMissing(ThreadContext context, IRubyObject self, DynamicMethod method, Block block) {
protected final IRubyObject callMethodMissing(ThreadContext context, IRubyObject self,
DynamicMethod method, Block block) {
return Helpers.selectMethodMissing(context, self, method.getVisibility(), methodName, callType).call(context, self, self.getMetaClass(), methodName, block);
}

protected IRubyObject callMethodMissing(ThreadContext context, IRubyObject self, DynamicMethod method, IRubyObject arg) {
protected final IRubyObject callMethodMissing(ThreadContext context, IRubyObject self,
DynamicMethod method, IRubyObject arg) {
return Helpers.selectMethodMissing(context, self, method.getVisibility(), methodName, callType).call(context, self, self.getMetaClass(), methodName, arg, Block.NULL_BLOCK);
}

protected IRubyObject callMethodMissing(ThreadContext context, IRubyObject self, DynamicMethod method, IRubyObject[] args, Block block) {
protected final IRubyObject callMethodMissing(ThreadContext context, IRubyObject self,
DynamicMethod method, IRubyObject[] args, Block block) {
return Helpers.selectMethodMissing(context, self, method.getVisibility(), methodName, callType).call(context, self, self.getMetaClass(), methodName, args, block);
}

protected IRubyObject callMethodMissing(ThreadContext context, IRubyObject self, DynamicMethod method, IRubyObject arg0, Block block) {
protected final IRubyObject callMethodMissing(ThreadContext context, IRubyObject self,
DynamicMethod method, IRubyObject arg0, Block block) {
return Helpers.selectMethodMissing(context, self, method.getVisibility(), methodName, callType).call(context, self, self.getMetaClass(), methodName, arg0, block);
}

protected IRubyObject callMethodMissing(ThreadContext context, IRubyObject self, DynamicMethod method, IRubyObject arg0, IRubyObject arg1) {
protected final IRubyObject callMethodMissing(ThreadContext context, IRubyObject self,
DynamicMethod method, IRubyObject arg0, IRubyObject arg1) {
return Helpers.selectMethodMissing(context, self, method.getVisibility(), methodName, callType).call(context, self, self.getMetaClass(), methodName, arg0, arg1, Block.NULL_BLOCK);
}

protected IRubyObject callMethodMissing(ThreadContext context, IRubyObject self, DynamicMethod method, IRubyObject arg0, IRubyObject arg1, Block block) {
protected final IRubyObject callMethodMissing(ThreadContext context, IRubyObject self,
DynamicMethod method, IRubyObject arg0, IRubyObject arg1, Block block) {
return Helpers.selectMethodMissing(context, self, method.getVisibility(), methodName, callType).call(context, self, self.getMetaClass(), methodName, arg0, arg1, block);
}

protected IRubyObject callMethodMissing(ThreadContext context, IRubyObject self, DynamicMethod method, IRubyObject arg0, IRubyObject arg1, IRubyObject arg2) {
protected final IRubyObject callMethodMissing(ThreadContext context, IRubyObject self,
DynamicMethod method, IRubyObject arg0, IRubyObject arg1, IRubyObject arg2) {
return Helpers.selectMethodMissing(context, self, method.getVisibility(), methodName, callType).call(context, self, self.getMetaClass(), methodName, arg0, arg1, arg2, Block.NULL_BLOCK);
}

protected IRubyObject callMethodMissing(ThreadContext context, IRubyObject self, DynamicMethod method, IRubyObject arg0, IRubyObject arg1, IRubyObject arg2, Block block) {
protected final IRubyObject callMethodMissing(ThreadContext context, IRubyObject self,
DynamicMethod method, IRubyObject arg0, IRubyObject arg1, IRubyObject arg2, Block block) {
return Helpers.selectMethodMissing(context, self, method.getVisibility(), methodName, callType).call(context, self, self.getMetaClass(), methodName, arg0, arg1, arg2, block);
}

0 comments on commit 68d9779

Please sign in to comment.