From f768f9316e364e00dcc3b88bffac6c586f0b1005 Mon Sep 17 00:00:00 2001 From: Adrian Siekierka Date: Wed, 24 Apr 2019 19:32:35 +0200 Subject: [PATCH] cease loading the same mappings file a million times --- .../loom/providers/MappingsProvider.java | 19 ++++++- .../java/net/fabricmc/loom/task/RemapJar.java | 3 +- .../net/fabricmc/loom/util/MapJarsTiny.java | 3 +- .../loom/util/ModCompileRemapper.java | 7 ++- .../net/fabricmc/loom/util/ModProcessor.java | 20 +++---- .../net/fabricmc/loom/util/ModRemapper.java | 5 +- .../fabricmc/loom/util/SourceRemapper.java | 15 +++--- .../loom/util/TinyRemapperMappingsHelper.java | 53 +++++++++++++++++++ 8 files changed, 96 insertions(+), 29 deletions(-) create mode 100644 src/main/java/net/fabricmc/loom/util/TinyRemapperMappingsHelper.java diff --git a/src/main/java/net/fabricmc/loom/providers/MappingsProvider.java b/src/main/java/net/fabricmc/loom/providers/MappingsProvider.java index 1416d7a..1eac733 100644 --- a/src/main/java/net/fabricmc/loom/providers/MappingsProvider.java +++ b/src/main/java/net/fabricmc/loom/providers/MappingsProvider.java @@ -28,10 +28,14 @@ import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.DependencyProvider; import net.fabricmc.loom.util.Version; +import net.fabricmc.mappings.Mappings; import net.fabricmc.stitch.commands.CommandProposeFieldNames; import org.gradle.api.Project; import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.lang.ref.SoftReference; import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Files; @@ -50,9 +54,22 @@ public class MappingsProvider extends DependencyProvider { private File MAPPINGS_DIR; public File MAPPINGS_TINY_BASE; public File MAPPINGS_TINY; - public File MAPPINGS_MIXIN_EXPORT; + private SoftReference mappings; + + public Mappings getMappings() throws IOException { + if (mappings == null || mappings.get() == null) { + try (FileInputStream stream = new FileInputStream(MAPPINGS_TINY)) { + mappings = new SoftReference<>( + net.fabricmc.mappings.MappingsProvider.readTinyMappings(stream, false) + ); + } + } + + return mappings.get(); + } + @Override public void provide(DependencyInfo dependency, Project project, LoomGradleExtension extension, Consumer postPopulationScheduler) throws Exception { MinecraftProvider minecraftProvider = getDependencyManager().getProvider(MinecraftProvider.class); diff --git a/src/main/java/net/fabricmc/loom/task/RemapJar.java b/src/main/java/net/fabricmc/loom/task/RemapJar.java index 8f35df0..1d69c90 100644 --- a/src/main/java/net/fabricmc/loom/task/RemapJar.java +++ b/src/main/java/net/fabricmc/loom/task/RemapJar.java @@ -30,6 +30,7 @@ import org.gradle.api.tasks.OutputFile; import org.gradle.api.tasks.TaskAction; import java.io.File; +import java.io.IOException; public class RemapJar extends DefaultLoomTask { public File jar; @@ -57,7 +58,7 @@ public class RemapJar extends DefaultLoomTask { } @TaskAction - public void remap() { + public void remap() throws IOException { ModRemapper.remap(this, nestJar); } } diff --git a/src/main/java/net/fabricmc/loom/util/MapJarsTiny.java b/src/main/java/net/fabricmc/loom/util/MapJarsTiny.java index ab5c636..285fa9d 100644 --- a/src/main/java/net/fabricmc/loom/util/MapJarsTiny.java +++ b/src/main/java/net/fabricmc/loom/util/MapJarsTiny.java @@ -47,7 +47,6 @@ public class MapJarsTiny { LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); MappingsProvider mappingsProvider = extension.getMappingsProvider(); - Path mappings = mappingsProvider.MAPPINGS_TINY.toPath(); Path[] classpath = mapProvider.getMapperPaths().stream() .map(File::toPath) .toArray(Path[]::new); @@ -62,7 +61,7 @@ public class MapJarsTiny { project.getLogger().lifecycle(":remapping minecraft (TinyRemapper, " + fromM + " -> " + toM + ")"); TinyRemapper remapper = TinyRemapper.newRemapper() - .withMappings(TinyUtils.createTinyMappingProvider(mappings, fromM, toM)) + .withMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM)) .renameInvalidLocals(true) .rebuildSourceFilenames(true) .build(); diff --git a/src/main/java/net/fabricmc/loom/util/ModCompileRemapper.java b/src/main/java/net/fabricmc/loom/util/ModCompileRemapper.java index 4e0071e..e7b5f6a 100644 --- a/src/main/java/net/fabricmc/loom/util/ModCompileRemapper.java +++ b/src/main/java/net/fabricmc/loom/util/ModCompileRemapper.java @@ -44,6 +44,7 @@ import org.gradle.jvm.JvmLibrary; import org.gradle.language.base.artifact.SourcesArtifact; import java.io.File; +import java.io.IOException; import java.util.Optional; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; @@ -116,7 +117,11 @@ public class ModCompileRemapper { File output = new File(modStore, remappedFilename + ".jar"); if (!output.exists() || input.lastModified() <= 0 || input.lastModified() > output.lastModified()) { //If the output doesn't exist, or appears to be outdated compared to the input we'll remap it - ModProcessor.handleMod(input, output, project); + try { + ModProcessor.handleMod(input, output, project); + } catch (IOException e) { + throw new RuntimeException("Failed to remap mod", e); + } if (!output.exists()){ throw new RuntimeException("Failed to remap mod"); diff --git a/src/main/java/net/fabricmc/loom/util/ModProcessor.java b/src/main/java/net/fabricmc/loom/util/ModProcessor.java index 00fe4a6..440efef 100644 --- a/src/main/java/net/fabricmc/loom/util/ModProcessor.java +++ b/src/main/java/net/fabricmc/loom/util/ModProcessor.java @@ -56,7 +56,7 @@ import java.util.zip.ZipEntry; public class ModProcessor { private static final Gson GSON = new Gson(); - public static void handleMod(File input, File output, Project project){ + public static void handleMod(File input, File output, Project project) throws IOException { if(output.exists()){ output.delete(); } @@ -64,11 +64,7 @@ public class ModProcessor { readInstallerJson(input, project); //Enable this if you want your nested jars to be extracted, this will extract **all** jars if(project.getExtensions().getByType(LoomGradleExtension.class).extractJars){ - try { - handleNestedJars(input, project); - } catch (IOException e) { - throw new RuntimeException("Failed to handle nested jar", e); - } + handleNestedJars(input, project); } //Always strip the nested jars stripNestedJars(output); @@ -95,7 +91,7 @@ public class ModProcessor { } } - private static void processNestedJar(JarFile parentJar, String fileName, Project project){ + private static void processNestedJar(JarFile parentJar, String fileName, Project project) throws IOException { LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); JarEntry entry = parentJar.getJarEntry(fileName); @@ -104,10 +100,8 @@ public class ModProcessor { } File nestedFile = new File(extension.getNestedModCache(), fileName.substring(fileName.lastIndexOf("/"))); - try(InputStream jarStream = parentJar.getInputStream(entry)){ + try(InputStream jarStream = parentJar.getInputStream(entry)) { FileUtils.copy(jarStream, nestedFile); - } catch (IOException e) { - throw new RuntimeException(e); } File remappedFile = new File(extension.getRemappedModCache(), fileName.substring(fileName.lastIndexOf("/"))); @@ -133,7 +127,7 @@ public class ModProcessor { }))}); } - private static void remapJar(File input, File output, Project project){ + private static void remapJar(File input, File output, Project project) throws IOException { LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); String fromM = "intermediary"; String toM = "named"; @@ -162,7 +156,7 @@ public class ModProcessor { project.getLogger().lifecycle(":remapping " + input.getName() + " (TinyRemapper, " + fromM + " -> " + toM + ")"); TinyRemapper remapper = TinyRemapper.newRemapper() - .withMappings(TinyUtils.createTinyMappingProvider(mappings, fromM, toM)) + .withMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM)) .build(); try (OutputConsumerPath outputConsumer = new OutputConsumerPath(Paths.get(output.getAbsolutePath()))) { @@ -172,8 +166,6 @@ public class ModProcessor { remapper.readClassPath(mcDeps); remapper.readInputs(inputPath); remapper.apply(outputConsumer); - } catch (Exception e){ - throw new RuntimeException("Failed to remap JAR to " + toM, e); } finally { remapper.finish(); } diff --git a/src/main/java/net/fabricmc/loom/util/ModRemapper.java b/src/main/java/net/fabricmc/loom/util/ModRemapper.java index 9649380..514d92c 100644 --- a/src/main/java/net/fabricmc/loom/util/ModRemapper.java +++ b/src/main/java/net/fabricmc/loom/util/ModRemapper.java @@ -42,7 +42,7 @@ import java.util.List; public class ModRemapper { - public static void remap(RemapJar task, boolean nest) { + public static void remap(RemapJar task, boolean nest) throws IOException { Project project = task.getProject(); LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); @@ -79,7 +79,8 @@ public class ModRemapper { Path mixinMapPath = mixinMapFile.toPath(); TinyRemapper.Builder remapperBuilder = TinyRemapper.newRemapper(); - remapperBuilder = remapperBuilder.withMappings(TinyUtils.createTinyMappingProvider(mappings, fromM, toM)); + + remapperBuilder = remapperBuilder.withMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM)); if (mixinMapFile.exists()) { remapperBuilder = remapperBuilder.withMappings(TinyUtils.createTinyMappingProvider(mixinMapPath, fromM, toM)); } diff --git a/src/main/java/net/fabricmc/loom/util/SourceRemapper.java b/src/main/java/net/fabricmc/loom/util/SourceRemapper.java index 4ad8389..32a2f73 100644 --- a/src/main/java/net/fabricmc/loom/util/SourceRemapper.java +++ b/src/main/java/net/fabricmc/loom/util/SourceRemapper.java @@ -62,9 +62,10 @@ public class SourceRemapper { MappingsProvider mappingsProvider = extension.getMappingsProvider(); MappingSet mappings = extension.getOrCreateSrcMappingCache(toNamed ? 1 : 0, () -> { - try (FileInputStream stream = new FileInputStream(mappingsProvider.MAPPINGS_TINY)) { + try { + Mappings m = mappingsProvider.getMappings(); project.getLogger().lifecycle(":loading " + (toNamed ? "intermediary -> named" : "named -> intermediary") + " source mappings"); - return new TinyReader(stream, toNamed ? "intermediary" : "named", toNamed ? "named" : "intermediary").read(); + return new TinyReader(m, toNamed ? "intermediary" : "named", toNamed ? "named" : "intermediary").read(); } catch (Exception e) { throw new RuntimeException(e); } @@ -140,19 +141,17 @@ public class SourceRemapper { } public static class TinyReader extends MappingsReader { - private final InputStream stream; + private final Mappings m; private final String from, to; - public TinyReader(InputStream stream, String from, String to) { - this.stream = stream; + public TinyReader(Mappings m, String from, String to) { + this.m = m; this.from = from; this.to = to; } @Override - public MappingSet read(final MappingSet mappings) throws IOException { - Mappings m = net.fabricmc.mappings.MappingsProvider.readTinyMappings(stream, false); - + public MappingSet read(final MappingSet mappings) { for (ClassEntry entry : m.getClassEntries()) { mappings.getOrCreateClassMapping(entry.get(from)) .setDeobfuscatedName(entry.get(to)); diff --git a/src/main/java/net/fabricmc/loom/util/TinyRemapperMappingsHelper.java b/src/main/java/net/fabricmc/loom/util/TinyRemapperMappingsHelper.java new file mode 100644 index 0000000..6b4f105 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/util/TinyRemapperMappingsHelper.java @@ -0,0 +1,53 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.util; + +import net.fabricmc.mappings.*; +import net.fabricmc.tinyremapper.IMappingProvider; +import net.fabricmc.tinyremapper.MemberInstance; + +public class TinyRemapperMappingsHelper { + private TinyRemapperMappingsHelper() { + + } + + public static IMappingProvider create(Mappings mappings, String from, String to) { + return (classMap, fieldMap, methodMap) -> { + for (ClassEntry entry : mappings.getClassEntries()) { + classMap.put(entry.get(from), entry.get(to)); + } + + for (FieldEntry entry : mappings.getFieldEntries()) { + EntryTriple fromTriple = entry.get(from); + fieldMap.put(fromTriple.getOwner() + "/" + MemberInstance.getFieldId(fromTriple.getName(), fromTriple.getDesc()), entry.get(to).getName()); + } + + for (MethodEntry entry : mappings.getMethodEntries()) { + EntryTriple fromTriple = entry.get(from); + methodMap.put(fromTriple.getOwner() + "/" + MemberInstance.getMethodId(fromTriple.getName(), fromTriple.getDesc()), entry.get(to).getName()); + } + }; + } +}