From 9c79dd3214ec847974ccd04e70f2c2c44abcc725 Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Wed, 6 Sep 2017 21:18:36 +0100 Subject: [PATCH] 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. --- .../0023-Use-ASM-for-event-executors.patch | 51 ++++++++++++++----- .../0057-Shoulder-Entities-Release-API.patch | 4 +- .../0058-Profile-Lookup-Events.patch | 2 +- .../0059-Entity-fromMobSpawner.patch | 4 +- ...f-Player-Sample-in-ServerListPingEve.patch | 4 +- ...61-Improve-the-Saddle-API-for-Horses.patch | 4 +- .../0062-ensureServerConversions-API.patch | 4 +- .../0063-Add-getI18NDisplayName-API.patch | 4 +- .../0064-ProfileWhitelistVerifyEvent.patch | 4 +- .../0065-Make-plugins-list-alphabetical.patch | 4 +- .../0066-LivingEntity-setKiller.patch | 4 +- 11 files changed, 58 insertions(+), 31 deletions(-) diff --git a/Spigot-API-Patches/0023-Use-ASM-for-event-executors.patch b/Spigot-API-Patches/0023-Use-ASM-for-event-executors.patch index 9df3944259..87bd56afcb 100644 --- a/Spigot-API-Patches/0023-Use-ASM-for-event-executors.patch +++ b/Spigot-API-Patches/0023-Use-ASM-for-event-executors.patch @@ -1,4 +1,4 @@ -From 780e7e1c25c5f7857d4ce5b834f07f4aef6f6814 Mon Sep 17 00:00:00 2001 +From d6c062cb8c337535554a3fcb0008ede65a33c86b Mon Sep 17 00:00:00 2001 From: Techcable 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 loaders = new ConcurrentHashMap<>(); ++ private final ConcurrentMap 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> eventExecutorMap = new ConcurrentHashMap>() { ++ @Override ++ public Class computeIfAbsent(Method key, Function> mappingFunction) { ++ Class 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 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 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 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 diff --git a/Spigot-API-Patches/0057-Shoulder-Entities-Release-API.patch b/Spigot-API-Patches/0057-Shoulder-Entities-Release-API.patch index b15b17f911..f3ed8e4a2a 100644 --- a/Spigot-API-Patches/0057-Shoulder-Entities-Release-API.patch +++ b/Spigot-API-Patches/0057-Shoulder-Entities-Release-API.patch @@ -1,4 +1,4 @@ -From 749b81ac44634b7b41a61d72bf05086b872c39c6 Mon Sep 17 00:00:00 2001 +From 3a5f33ba756ff0587b88c7b6340ff6368131f51e Mon Sep 17 00:00:00 2001 From: Aikar 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 diff --git a/Spigot-API-Patches/0058-Profile-Lookup-Events.patch b/Spigot-API-Patches/0058-Profile-Lookup-Events.patch index 6ed9d70c49..6812041bda 100644 --- a/Spigot-API-Patches/0058-Profile-Lookup-Events.patch +++ b/Spigot-API-Patches/0058-Profile-Lookup-Events.patch @@ -1,4 +1,4 @@ -From bf4c10675dba6aa49c9d4db585c9d70b1da00637 Mon Sep 17 00:00:00 2001 +From bcbcc7dd8033e55027d77c7eaeaea3b6288b643e Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 17 Jun 2017 16:30:44 -0400 Subject: [PATCH] Profile Lookup Events diff --git a/Spigot-API-Patches/0059-Entity-fromMobSpawner.patch b/Spigot-API-Patches/0059-Entity-fromMobSpawner.patch index a6dfeb4ee5..245ac9e0fe 100644 --- a/Spigot-API-Patches/0059-Entity-fromMobSpawner.patch +++ b/Spigot-API-Patches/0059-Entity-fromMobSpawner.patch @@ -1,4 +1,4 @@ -From 65b1c1ecda7de3d1b4fa683bc9942ec93db9d31f Mon Sep 17 00:00:00 2001 +From e7f452ae1e545a3dfa9adf5c634a3f17a8c0b791 Mon Sep 17 00:00:00 2001 From: BillyGalbreath 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 diff --git a/Spigot-API-Patches/0060-Allow-Changing-of-Player-Sample-in-ServerListPingEve.patch b/Spigot-API-Patches/0060-Allow-Changing-of-Player-Sample-in-ServerListPingEve.patch index 2b88bfb519..b0d89ee670 100644 --- a/Spigot-API-Patches/0060-Allow-Changing-of-Player-Sample-in-ServerListPingEve.patch +++ b/Spigot-API-Patches/0060-Allow-Changing-of-Player-Sample-in-ServerListPingEve.patch @@ -1,4 +1,4 @@ -From 8aa765ebb7b4bb1ba7b65a662bff871d50f90422 Mon Sep 17 00:00:00 2001 +From 19295da8c04248bdc579640f5931b9818f1a61a2 Mon Sep 17 00:00:00 2001 From: willies952002 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 diff --git a/Spigot-API-Patches/0061-Improve-the-Saddle-API-for-Horses.patch b/Spigot-API-Patches/0061-Improve-the-Saddle-API-for-Horses.patch index 2dc577539e..5072c2db96 100644 --- a/Spigot-API-Patches/0061-Improve-the-Saddle-API-for-Horses.patch +++ b/Spigot-API-Patches/0061-Improve-the-Saddle-API-for-Horses.patch @@ -1,4 +1,4 @@ -From 50ad728a3cfb0af96a191960a256d0288ffb22bf Mon Sep 17 00:00:00 2001 +From a3b4ea5396b88e411599100f60091cbfe68dc242 Mon Sep 17 00:00:00 2001 From: Aikar 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 diff --git a/Spigot-API-Patches/0062-ensureServerConversions-API.patch b/Spigot-API-Patches/0062-ensureServerConversions-API.patch index 8a33fc3598..c32ac84dbf 100644 --- a/Spigot-API-Patches/0062-ensureServerConversions-API.patch +++ b/Spigot-API-Patches/0062-ensureServerConversions-API.patch @@ -1,4 +1,4 @@ -From d97890f63015395b9fcf7bc382686ddfe5f3e266 Mon Sep 17 00:00:00 2001 +From c6ffdd4bda7232c5e22d96bc0c5e6f6a9c995401 Mon Sep 17 00:00:00 2001 From: Aikar 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 diff --git a/Spigot-API-Patches/0063-Add-getI18NDisplayName-API.patch b/Spigot-API-Patches/0063-Add-getI18NDisplayName-API.patch index a8116a6f03..1f687bac4c 100644 --- a/Spigot-API-Patches/0063-Add-getI18NDisplayName-API.patch +++ b/Spigot-API-Patches/0063-Add-getI18NDisplayName-API.patch @@ -1,4 +1,4 @@ -From 7c28e3c2d2ebf454068b75f615be4feb5ebaeede Mon Sep 17 00:00:00 2001 +From f2f0642e3bce08e006218abf9e98fb735a641963 Mon Sep 17 00:00:00 2001 From: Aikar 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 diff --git a/Spigot-API-Patches/0064-ProfileWhitelistVerifyEvent.patch b/Spigot-API-Patches/0064-ProfileWhitelistVerifyEvent.patch index 193ca1ca77..f4488049b8 100644 --- a/Spigot-API-Patches/0064-ProfileWhitelistVerifyEvent.patch +++ b/Spigot-API-Patches/0064-ProfileWhitelistVerifyEvent.patch @@ -1,4 +1,4 @@ -From c814474d6c5d9c4d7142d141e6dabf3935a577cb Mon Sep 17 00:00:00 2001 +From 225e4e635f54b9f4ba440a4a849a4bddde5c6309 Mon Sep 17 00:00:00 2001 From: Aikar 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 diff --git a/Spigot-API-Patches/0065-Make-plugins-list-alphabetical.patch b/Spigot-API-Patches/0065-Make-plugins-list-alphabetical.patch index da8870ddc7..311cb4ddd0 100644 --- a/Spigot-API-Patches/0065-Make-plugins-list-alphabetical.patch +++ b/Spigot-API-Patches/0065-Make-plugins-list-alphabetical.patch @@ -1,4 +1,4 @@ -From fcaf4875363c340138dd0f7111ece67e1982e078 Mon Sep 17 00:00:00 2001 +From 662bd9bbf378ed4d06831c1e4de040ea3282ce3e Mon Sep 17 00:00:00 2001 From: BillyGalbreath 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 diff --git a/Spigot-API-Patches/0066-LivingEntity-setKiller.patch b/Spigot-API-Patches/0066-LivingEntity-setKiller.patch index 8cc14fa1d8..8c657e03e3 100644 --- a/Spigot-API-Patches/0066-LivingEntity-setKiller.patch +++ b/Spigot-API-Patches/0066-LivingEntity-setKiller.patch @@ -1,4 +1,4 @@ -From b97b934d735fcb6dceca929737d660db73602ccd Mon Sep 17 00:00:00 2001 +From 9eeca99eb63a2892a12da3c26bcee01f402c337e Mon Sep 17 00:00:00 2001 From: BillyGalbreath 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. *

-- -2.14.1.windows.1 +2.14.1