Cache generated EventExecutors (fixes #786)
the first 'major' change in this PR is to cache the generated event executrs from the ASM class, by doing this we only generate a single class for every method that we need an executor for, thus reducing the number of classes that are needed, especially in cases where plugins re/unregister events all the time. The second change is to modify the generated classloader map, generated classloaders are not held against the plugin itself but the classloader that the event is declared in, the implication here is that we cannot drop generated classloaders when a plugin disable, and so we use a guava weak-key'd hashmap, downfall here is that classes won't be GC'd until guava drops the generated classloader, however the first change should deal with most of the grunt.
This commit is contained in:
parent
6d9375d222
commit
9c79dd3214
|
@ -1,4 +1,4 @@
|
|||
From 780e7e1c25c5f7857d4ce5b834f07f4aef6f6814 Mon Sep 17 00:00:00 2001
|
||||
From d6c062cb8c337535554a3fcb0008ede65a33c86b Mon Sep 17 00:00:00 2001
|
||||
From: Techcable <Techcable@outlook.com>
|
||||
Date: Thu, 3 Mar 2016 13:20:33 -0700
|
||||
Subject: [PATCH] Use ASM for event executors.
|
||||
|
@ -203,10 +203,10 @@ index 00000000..6941d9fb
|
|||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/executor/asm/SafeClassDefiner.java b/src/main/java/com/destroystokyo/paper/event/executor/asm/SafeClassDefiner.java
|
||||
new file mode 100644
|
||||
index 00000000..776a9a03
|
||||
index 00000000..1473ff8c
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/executor/asm/SafeClassDefiner.java
|
||||
@@ -0,0 +1,62 @@
|
||||
@@ -0,0 +1,63 @@
|
||||
+package com.destroystokyo.paper.event.executor.asm;
|
||||
+
|
||||
+import java.util.concurrent.ConcurrentHashMap;
|
||||
|
@ -214,6 +214,7 @@ index 00000000..776a9a03
|
|||
+
|
||||
+import com.google.common.base.Preconditions;
|
||||
+
|
||||
+import com.google.common.collect.MapMaker;
|
||||
+import org.objectweb.asm.Type;
|
||||
+
|
||||
+public class SafeClassDefiner implements ClassDefiner {
|
||||
|
@ -221,7 +222,7 @@ index 00000000..776a9a03
|
|||
+
|
||||
+ private SafeClassDefiner() {}
|
||||
+
|
||||
+ private final ConcurrentMap<ClassLoader, GeneratedClassLoader> loaders = new ConcurrentHashMap<>();
|
||||
+ private final ConcurrentMap<ClassLoader, GeneratedClassLoader> loaders = new MapMaker().weakKeys().makeMap();
|
||||
+
|
||||
+ @Override
|
||||
+ public Class<?> defineClass(ClassLoader parentLoader, String name, byte[] data) {
|
||||
|
@ -309,16 +310,20 @@ index 00000000..62acbf82
|
|||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/plugin/EventExecutor.java b/src/main/java/org/bukkit/plugin/EventExecutor.java
|
||||
index 3b2c99ea..f9316d65 100644
|
||||
index 3b2c99ea..b45b6c1c 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/EventExecutor.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/EventExecutor.java
|
||||
@@ -4,9 +4,55 @@ import org.bukkit.event.Event;
|
||||
@@ -4,9 +4,81 @@ import org.bukkit.event.Event;
|
||||
import org.bukkit.event.EventException;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
+// Paper start
|
||||
+import java.lang.reflect.Method;
|
||||
+import java.lang.reflect.Modifier;
|
||||
+import java.util.HashMap;
|
||||
+import java.util.concurrent.ConcurrentHashMap;
|
||||
+import java.util.concurrent.ConcurrentMap;
|
||||
+import java.util.function.Function;
|
||||
+
|
||||
+import com.destroystokyo.paper.event.executor.MethodHandleEventExecutor;
|
||||
+import com.destroystokyo.paper.event.executor.StaticMethodHandleEventExecutor;
|
||||
|
@ -334,6 +339,24 @@ index 3b2c99ea..f9316d65 100644
|
|||
public void execute(Listener listener, Event event) throws EventException;
|
||||
+
|
||||
+ // Paper start
|
||||
+ ConcurrentMap<Method, Class<? extends EventExecutor>> eventExecutorMap = new ConcurrentHashMap<Method, Class<? extends EventExecutor>>() {
|
||||
+ @Override
|
||||
+ public Class<? extends EventExecutor> computeIfAbsent(Method key, Function<? super Method, ? extends Class<? extends EventExecutor>> mappingFunction) {
|
||||
+ Class<? extends EventExecutor> executorClass = get(key);
|
||||
+ if (executorClass != null)
|
||||
+ return executorClass;
|
||||
+
|
||||
+ //noinspection SynchronizationOnLocalVariableOrMethodParameter
|
||||
+ synchronized (key) {
|
||||
+ executorClass = get(key);
|
||||
+ if (executorClass != null)
|
||||
+ return executorClass;
|
||||
+
|
||||
+ return super.computeIfAbsent(key, mappingFunction);
|
||||
+ }
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
+ public static EventExecutor create(Method m, Class<? extends Event> eventClass) {
|
||||
+ Preconditions.checkNotNull(m, "Null method");
|
||||
+ Preconditions.checkArgument(m.getParameterCount() != 0, "Incorrect number of arguments %s", m.getParameterCount());
|
||||
|
@ -341,12 +364,16 @@ index 3b2c99ea..f9316d65 100644
|
|||
+ ClassDefiner definer = ClassDefiner.getInstance();
|
||||
+ if (Modifier.isStatic(m.getModifiers())) {
|
||||
+ return new StaticMethodHandleEventExecutor(eventClass, m);
|
||||
+ } if (definer.isBypassAccessChecks() || Modifier.isPublic(m.getDeclaringClass().getModifiers()) && Modifier.isPublic(m.getModifiers())) {
|
||||
+ String name = ASMEventExecutorGenerator.generateName();
|
||||
+ byte[] classData = ASMEventExecutorGenerator.generateEventExecutor(m, name);
|
||||
+ Class<? extends EventExecutor> c = definer.defineClass(m.getDeclaringClass().getClassLoader(), name, classData).asSubclass(EventExecutor.class);
|
||||
+ } else if (definer.isBypassAccessChecks() || Modifier.isPublic(m.getDeclaringClass().getModifiers()) && Modifier.isPublic(m.getModifiers())) {
|
||||
+ // get the existing generated EventExecutor class for the Method or generate one
|
||||
+ Class<? extends EventExecutor> executorClass = eventExecutorMap.computeIfAbsent(m, (__) -> {
|
||||
+ String name = ASMEventExecutorGenerator.generateName();
|
||||
+ byte[] classData = ASMEventExecutorGenerator.generateEventExecutor(m, name);
|
||||
+ return definer.defineClass(m.getDeclaringClass().getClassLoader(), name, classData).asSubclass(EventExecutor.class);
|
||||
+ });
|
||||
+
|
||||
+ try {
|
||||
+ EventExecutor asmExecutor = c.newInstance();
|
||||
+ EventExecutor asmExecutor = executorClass.newInstance();
|
||||
+ // Define a wrapper to conform to bukkit stupidity (passing in events that don't match and wrapper exception)
|
||||
+ return new EventExecutor() {
|
||||
+ @Override
|
||||
|
@ -395,5 +422,5 @@ index d8b9c244..40fd71dc 100644
|
|||
eventSet.add(new TimedRegisteredListener(listener, executor, eh.priority(), plugin, eh.ignoreCancelled()));
|
||||
} else {
|
||||
--
|
||||
2.13.0
|
||||
2.14.1
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
From 749b81ac44634b7b41a61d72bf05086b872c39c6 Mon Sep 17 00:00:00 2001
|
||||
From 3a5f33ba756ff0587b88c7b6340ff6368131f51e Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 17 Jun 2017 15:04:51 -0400
|
||||
Subject: [PATCH] Shoulder Entities Release API
|
||||
|
@ -34,5 +34,5 @@ index 518aa2a9..3939d4af 100644
|
|||
* Gets the entity currently perched on the left shoulder or null if no
|
||||
* entity.
|
||||
--
|
||||
2.13.3
|
||||
2.14.1
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
From bf4c10675dba6aa49c9d4db585c9d70b1da00637 Mon Sep 17 00:00:00 2001
|
||||
From bcbcc7dd8033e55027d77c7eaeaea3b6288b643e Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 17 Jun 2017 16:30:44 -0400
|
||||
Subject: [PATCH] Profile Lookup Events
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
From 65b1c1ecda7de3d1b4fa683bc9942ec93db9d31f Mon Sep 17 00:00:00 2001
|
||||
From e7f452ae1e545a3dfa9adf5c634a3f17a8c0b791 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sun, 18 Jun 2017 18:17:05 -0500
|
||||
Subject: [PATCH] Entity#fromMobSpawner()
|
||||
|
@ -22,5 +22,5 @@ index c86c1c5f..57f62ae4 100644
|
|||
// Paper end
|
||||
}
|
||||
--
|
||||
2.13.3
|
||||
2.14.1
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
From 8aa765ebb7b4bb1ba7b65a662bff871d50f90422 Mon Sep 17 00:00:00 2001
|
||||
From 19295da8c04248bdc579640f5931b9818f1a61a2 Mon Sep 17 00:00:00 2001
|
||||
From: willies952002 <admin@domnian.com>
|
||||
Date: Thu, 20 Jul 2017 18:05:36 -0400
|
||||
Subject: [PATCH] Allow Changing of Player Sample in ServerListPingEvent
|
||||
|
@ -33,5 +33,5 @@ index 3c38d857..84de3ce4 100644
|
|||
+
|
||||
}
|
||||
--
|
||||
2.13.3
|
||||
2.14.1
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
From 50ad728a3cfb0af96a191960a256d0288ffb22bf Mon Sep 17 00:00:00 2001
|
||||
From a3b4ea5396b88e411599100f60091cbfe68dc242 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 10 Dec 2016 16:12:48 -0500
|
||||
Subject: [PATCH] Improve the Saddle API for Horses
|
||||
|
@ -94,5 +94,5 @@ index 00000000..010dc364
|
|||
+ void setSaddle(ItemStack stack);
|
||||
+}
|
||||
--
|
||||
2.13.3
|
||||
2.14.1
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
From d97890f63015395b9fcf7bc382686ddfe5f3e266 Mon Sep 17 00:00:00 2001
|
||||
From c6ffdd4bda7232c5e22d96bc0c5e6f6a9c995401 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 4 May 2016 23:55:48 -0400
|
||||
Subject: [PATCH] ensureServerConversions API
|
||||
|
@ -61,5 +61,5 @@ index 188ae6d7..6bb19b9d 100644
|
|||
+ // Paper end
|
||||
}
|
||||
--
|
||||
2.13.3
|
||||
2.14.1
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
From 7c28e3c2d2ebf454068b75f615be4feb5ebaeede Mon Sep 17 00:00:00 2001
|
||||
From f2f0642e3bce08e006218abf9e98fb735a641963 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 4 May 2016 23:55:48 -0400
|
||||
Subject: [PATCH] Add getI18NDisplayName API
|
||||
|
@ -49,5 +49,5 @@ index 6bb19b9d..7a52da9b 100644
|
|||
// Paper end
|
||||
}
|
||||
--
|
||||
2.13.3
|
||||
2.14.1
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
From c814474d6c5d9c4d7142d141e6dabf3935a577cb Mon Sep 17 00:00:00 2001
|
||||
From 225e4e635f54b9f4ba440a4a849a4bddde5c6309 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 3 Jul 2017 18:11:34 -0500
|
||||
Subject: [PATCH] ProfileWhitelistVerifyEvent
|
||||
|
@ -124,5 +124,5 @@ index 00000000..59b69b23
|
|||
+ }
|
||||
+}
|
||||
--
|
||||
2.13.3
|
||||
2.14.1
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
From fcaf4875363c340138dd0f7111ece67e1982e078 Mon Sep 17 00:00:00 2001
|
||||
From 662bd9bbf378ed4d06831c1e4de040ea3282ce3e Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Mon, 31 Jul 2017 02:08:55 -0500
|
||||
Subject: [PATCH] Make /plugins list alphabetical
|
||||
|
@ -51,5 +51,5 @@ index e21d1679..e2274fa2 100644
|
|||
|
||||
// Spigot Start
|
||||
--
|
||||
2.11.0
|
||||
2.14.1
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
From b97b934d735fcb6dceca929737d660db73602ccd Mon Sep 17 00:00:00 2001
|
||||
From 9eeca99eb63a2892a12da3c26bcee01f402c337e Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Mon, 31 Jul 2017 01:49:43 -0500
|
||||
Subject: [PATCH] LivingEntity#setKiller
|
||||
|
@ -34,5 +34,5 @@ index be51e389..4a51c519 100644
|
|||
* Adds the given {@link PotionEffect} to the living entity.
|
||||
* <p>
|
||||
--
|
||||
2.14.1.windows.1
|
||||
2.14.1
|
||||
|
||||
|
|
Loading…
Reference in New Issue