the question of the day is, can i beat tiny-remapper?

i think there are 4 phases to remapping

fork-join with three phases. map reduce. idk.

INTERESTING: if it is acceptable to hold everything in-memory (which is probably okay), we can read all classes from the jar then start parsing mappings in parallel while we compute method owners (i’m assuming you can only read one file at a time cause of the realities of disks). while we’re doing the final remap phase we can also drop our copy of the original classes as soon as the ASM ClassReaders get their hands on them

observations

some tiny-remapper options and what they do

what are some non-obvious features of tiny-remapper to look at?

but yeah it basically has the same structure as i’m proposing :skull: read in parallel (with zipfs), propagate in parallel, write classes in parallel (with zipfs). i guess the main differences in mine are that i want to read mappings concurrently with propagation, i want propagation to be unidirectional, and i want to use plain java instead of zipfilesystem

tiny-remapper propagation is kinda weird, i think it renames at the same time. some insightful comments left in the source

/*
 * initial private member or static method in interface: only local
 * non-virtual: up to matching member (if not already in this), then down until matching again (exclusive)
 * virtual: all across the hierarchy, only non-private|static can change direction - skip private|static in interfaces
 */

as expected “up” propagation calls propagate() on superclasses/superinterfaces, and “down” propagation calls propagate() on subclasses

oough there’s also isAssignableFrom logic? i think it’s used as part of resolveMethod, comments there make talk of the jvm spec

article from proguard about it https://www.guardsquare.com/blog/behind-the-scenes-of-jvm-method-invocations#Virtual_methods

https://docs.oracle.com/javase/specs/jvms/se17/html/jvms-5.html#jvms-5.4.6

interesting: hotspot will IncompatibleClassChangeError in certain cases where method lookup is actually ambiguous https://jvilk.com/blog/java-8-specification-bug/

while i’m here, the specific overriding rules: https://docs.oracle.com/javase/specs/jvms/se21/html/jvms-5.html#jvms-5.4.5

that final constraint is very complicated, basically what it means is that if you’re scanning upwards for an overriding method and you find a public one, you are permitted to continue scanning upwards even through package-private methods you can’t see. the example from the spec is

public class A           {        void m() {} } //D.m can override this (!)
public class B extends A { public void m() {} } //D.m can override this
public class C extends B {        void m() {} } //D.m cannot override this
//different package
public class D extends P.C { void m() {} }