Skip to content

Commit 0e6efdd

Browse files
committedDec 5, 2017
Re-add an mbean for monitoring cache invalidations.
This is for #4384. For this initial version, methods and constants only have a single value indicating validation count globally. For constants, this will aggregate all constant names (which are invalidated separately). For methods, this will aggregate all class hierarchy invalidations, which will frequently mean a single invalidation event will increment this value many times, depending on the size of the hierarchy below it. This latter point could be improved but we don't really have a clear place to say "this is the top invalidation" at the moment.
1 parent 307f557 commit 0e6efdd

10 files changed

+90
-24
lines changed
 

Diff for: ‎core/src/main/java/org/jruby/Ruby.java

+19-2
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,11 @@
5959
import org.jruby.javasupport.JavaSupport;
6060
import org.jruby.javasupport.JavaSupportImpl;
6161
import org.jruby.lexer.yacc.ISourcePosition;
62+
import org.jruby.management.Caches;
6263
import org.jruby.parser.StaticScope;
6364
import org.jruby.runtime.JavaSites;
6465
import org.jruby.runtime.invokedynamic.InvokeDynamicSupport;
66+
import org.jruby.runtime.opto.ConstantInvalidator;
6567
import org.jruby.util.MRIRecursionGuard;
6668
import org.jruby.util.io.EncodingUtils;
6769
import org.objectweb.asm.util.TraceClassVisitor;
@@ -251,6 +253,7 @@ private Ruby(RubyInstanceConfig config) {
251253
this.beanManager = BeanManagerFactory.create(this, config.isManagementEnabled());
252254
this.jitCompiler = new JITCompiler(this);
253255
this.parserStats = new ParserStats(this);
256+
this.caches = new Caches();
254257

255258
Random myRandom;
256259
try {
@@ -277,7 +280,7 @@ private Ruby(RubyInstanceConfig config) {
277280
this.runtimeCache = new RuntimeCache();
278281
runtimeCache.initMethodCache(ClassIndex.MAX_CLASSES.ordinal() * MethodNames.values().length - 1);
279282

280-
checkpointInvalidator = OptoFactory.newConstantInvalidator();
283+
checkpointInvalidator = OptoFactory.newConstantInvalidator(this);
281284

282285
if (config.isObjectSpaceEnabled()) {
283286
objectSpacer = ENABLED_OBJECTSPACE;
@@ -296,6 +299,7 @@ public void registerMBeans() {
296299
this.beanManager.register(configBean);
297300
this.beanManager.register(parserStats);
298301
this.beanManager.register(runtimeBean);
302+
this.beanManager.register(caches);
299303
}
300304

301305
void reinitialize(boolean reinitCore) {
@@ -875,6 +879,15 @@ public JITCompiler getJITCompiler() {
875879
return jitCompiler;
876880
}
877881

882+
/**
883+
* Get the Caches management object.
884+
*
885+
* @return the current runtime's Caches management object
886+
*/
887+
public Caches getCaches() {
888+
return caches;
889+
}
890+
878891
/**
879892
* @deprecated use #newInstance()
880893
*/
@@ -4343,7 +4356,7 @@ public Invalidator getConstantInvalidator(String constantName) {
43434356
}
43444357

43454358
private Invalidator addConstantInvalidator(String constantName) {
4346-
Invalidator invalidator = OptoFactory.newConstantInvalidator();
4359+
final Invalidator invalidator = OptoFactory.newConstantInvalidator(this);
43474360
constantNameInvalidators.putIfAbsent(constantName, invalidator);
43484361

43494362
// fetch the invalidator back from the ConcurrentHashMap to ensure that
@@ -4921,6 +4934,9 @@ private MRIRecursionGuard oldRecursionGuard() {
49214934
// Compilation
49224935
private final JITCompiler jitCompiler;
49234936

4937+
// Cache invalidation
4938+
private final Caches caches;
4939+
49244940
// Note: this field and the following static initializer
49254941
// must be located be in this order!
49264942
private volatile static boolean securityRestricted = false;
@@ -5148,4 +5164,5 @@ private void deprecatedNetworkStackProperty() {
51485164
+ "Use JAVA_OPTS=-Djava.net.preferIPv4Stack=true OR prepend -J as a JRuby option.");
51495165
}
51505166
}
5167+
51515168
}

Diff for: ‎core/src/main/java/org/jruby/RubyModule.java

+2
Original file line numberDiff line numberDiff line change
@@ -1507,6 +1507,8 @@ protected DynamicMethod searchMethodCommon(String name) {
15071507
public void invalidateCacheDescendants() {
15081508
LOG.debug("{} invalidating descendants", baseName);
15091509

1510+
getRuntime().getCaches().incrementMethodInvalidations();
1511+
15101512
if (includingHierarchies.isEmpty()) {
15111513
// it's only us; just invalidate directly
15121514
methodInvalidator.invalidate();

Diff for: ‎core/src/main/java/org/jruby/management/BeanManager.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public interface BeanManager {
1010

1111
void register(ParserStatsMBean parserStats);
1212

13-
void register(MethodCacheMBean methodCache);
13+
void register(CachesMBean methodCache);
1414

1515
void register(Runtime runtime);
1616

Diff for: ‎core/src/main/java/org/jruby/management/BeanManagerFactory.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ private static class DummyBeanManager implements BeanManager {
3636
public void register(JITCompilerMBean jitCompiler) {}
3737
public void register(ConfigMBean config) {}
3838
public void register(ParserStatsMBean parserStats) {}
39-
public void register(MethodCacheMBean methodCache) {}
39+
public void register(CachesMBean methodCache) {}
4040
public void register(Runtime runtime) {}
4141
public void unregisterCompiler() {}
4242
public void unregisterConfig() {}

Diff for: ‎core/src/main/java/org/jruby/management/BeanManagerImpl.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ public void register(ParserStatsMBean parserStats) {
4646
if (managementEnabled) register(base + "service=ParserStats", parserStats);
4747
}
4848

49-
public void register(MethodCacheMBean methodCache) {
50-
if (managementEnabled) register(base + "service=MethodCache", methodCache);
49+
public void register(CachesMBean caches) {
50+
if (managementEnabled) register(base + "service=Caches", caches);
5151
}
5252

5353
public void register(Runtime runtime) {

Diff for: ‎core/src/main/java/org/jruby/management/Caches.java

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package org.jruby.management;
2+
3+
import java.util.concurrent.atomic.AtomicLong;
4+
5+
public class Caches implements CachesMBean {
6+
private final AtomicLong methodInvalidations = new AtomicLong(0);
7+
private final AtomicLong constantInvalidations = new AtomicLong(0);
8+
9+
@Override
10+
public long getMethodInvalidationCount() {
11+
return methodInvalidations.get();
12+
}
13+
14+
@Override
15+
public long getConstantInvalidationCount() {
16+
return constantInvalidations.get();
17+
}
18+
19+
public long incrementMethodInvalidations() {
20+
return methodInvalidations.incrementAndGet();
21+
}
22+
23+
public long incrementConstantInvalidations() {
24+
return constantInvalidations.incrementAndGet();
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package org.jruby.management;
2+
3+
public interface CachesMBean {
4+
public long getMethodInvalidationCount();
5+
public long getConstantInvalidationCount();
6+
}

Diff for: ‎core/src/main/java/org/jruby/management/MethodCacheMBean.java

-12
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package org.jruby.runtime.opto;
2+
3+
import org.jruby.management.Caches;
4+
5+
import java.util.List;
6+
7+
/**
8+
* A validator specific to how we manage Ruby constants.
9+
*/
10+
public class ConstantInvalidator extends SwitchPointInvalidator {
11+
private final Caches caches;
12+
13+
public ConstantInvalidator(Caches caches) {
14+
this.caches = caches;
15+
}
16+
17+
@Override
18+
public void invalidate() {
19+
// order is important; invalidate before increment
20+
super.invalidate();
21+
caches.incrementConstantInvalidations();
22+
}
23+
24+
@Override
25+
public void invalidateAll(List<Invalidator> invalidators) {
26+
// order is important; invalidate before increment
27+
super.invalidateAll(invalidators);
28+
caches.incrementConstantInvalidations();
29+
}
30+
}

Diff for: ‎core/src/main/java/org/jruby/runtime/opto/OptoFactory.java

+3-6
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
***** END LICENSE BLOCK *****/
2727
package org.jruby.runtime.opto;
2828

29+
import org.jruby.Ruby;
2930
import org.jruby.RubyModule;
3031
import org.jruby.runtime.ThreadContext;
3132
import org.jruby.util.cli.Options;
@@ -48,8 +49,8 @@ public static final Object newConstantWrapper(Class type, Object object) {
4849
return OptoFactory.CONSTANT_FACTORY.create(type, object);
4950
}
5051

51-
public static Invalidator newConstantInvalidator() {
52-
return new SwitchPointInvalidator();
52+
public static Invalidator newConstantInvalidator(Ruby runtime) {
53+
return new ConstantInvalidator(runtime.getCaches());
5354
}
5455

5556
private static Boolean indyEnabled() {
@@ -74,10 +75,6 @@ public static Invalidator newMethodInvalidator(RubyModule module) {
7475
return new GenerationInvalidator(module);
7576
}
7677

77-
private static Boolean indyConstants() {
78-
return Options.INVOKEDYNAMIC_CACHE_CONSTANTS.load();
79-
}
80-
8178
private static void disableIndy() {
8279
Options.COMPILE_INVOKEDYNAMIC.force("false");
8380
}

0 commit comments

Comments
 (0)
Please sign in to comment.