Skip to content

Commit

Permalink
Associate a SwitchPoint with each CacheEntry for active inval'ing.
Browse files Browse the repository at this point in the history
headius committed Aug 25, 2017
1 parent fe1066a commit e76c974
Showing 4 changed files with 20 additions and 2 deletions.
3 changes: 2 additions & 1 deletion core/src/main/java/org/jruby/RubyModule.java
Original file line number Diff line number Diff line change
@@ -1201,6 +1201,7 @@ public void addMethod(String name, DynamicMethod method) {
}

public final void addMethodInternal(String name, DynamicMethod method) {
searchWithCache(name).invalidate();
synchronized(methodLocation.getMethodsForWrite()) {
addMethodAtBootTimeOnly(name, method);
invalidateCoreClasses();
@@ -1356,7 +1357,7 @@ private CacheEntry cacheHit(String name) {
CacheEntry cacheEntry = methodLocation.getCachedMethods().get(name);

if (cacheEntry != null) {
if (cacheEntry.token == getGeneration()) {
if (!cacheEntry.getValidator().hasBeenInvalidated()) {
return cacheEntry;
}
}
Original file line number Diff line number Diff line change
@@ -30,6 +30,7 @@

package org.jruby.internal.runtime.methods;

import java.lang.invoke.SwitchPoint;
import java.lang.reflect.Method;
import java.util.Arrays;
import org.jruby.MetaClass;
4 changes: 3 additions & 1 deletion core/src/main/java/org/jruby/ir/targets/InvokeSite.java
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@
import com.headius.invokebinder.SmartHandle;
import org.jruby.Ruby;
import org.jruby.RubyBasicObject;
import org.jruby.RubyBignum;
import org.jruby.RubyBoolean;
import org.jruby.RubyClass;
import org.jruby.RubyFixnum;
@@ -138,9 +139,9 @@ public static CallSite bootstrap(InvokeSite site, MethodHandles.Lookup lookup) {

public IRubyObject invoke(ThreadContext context, IRubyObject caller, IRubyObject self, IRubyObject[] args, Block block) throws Throwable {
RubyClass selfClass = pollAndGetClass(context, self);
SwitchPoint switchPoint = (SwitchPoint) selfClass.getInvalidator().getData();
CacheEntry entry = selfClass.searchWithCache(methodName);
DynamicMethod method = entry.method;
SwitchPoint switchPoint = entry.getValidator();

if (methodMissing(entry, caller)) {
// Test thresholds so we don't do this forever (#4596)
@@ -399,6 +400,7 @@ MethodHandle updateInvocationTarget(MethodHandle target, IRubyObject self, RubyM

if (self instanceof RubySymbol ||
self instanceof RubyFixnum ||
self instanceof RubyBignum ||
self instanceof RubyFloat ||
self instanceof RubyNil ||
self instanceof RubyBoolean.True ||
14 changes: 14 additions & 0 deletions core/src/main/java/org/jruby/runtime/callsite/CacheEntry.java
Original file line number Diff line number Diff line change
@@ -4,9 +4,23 @@
import org.jruby.internal.runtime.methods.DynamicMethod;
import org.jruby.internal.runtime.methods.UndefinedMethod;

import java.lang.invoke.SwitchPoint;

public class CacheEntry {
public static final CacheEntry NULL_CACHE = new CacheEntry(UndefinedMethod.INSTANCE, 0);
public final DynamicMethod method;

/** The current valid SwitchPoint for the method, invalidated when overridden */
protected final SwitchPoint[] validator = {new SwitchPoint()};

public void invalidate() {
SwitchPoint.invalidateAll(validator);
}

public SwitchPoint getValidator() {
return validator[0];
}

public final int token;

public CacheEntry(DynamicMethod method, int token) {

0 comments on commit e76c974

Please sign in to comment.