Skip to content

Commit

Permalink
change: use arrays for generated code
Browse files Browse the repository at this point in the history
  • Loading branch information
ishland committed Dec 12, 2024
1 parent b63d0ee commit 5082a14
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,12 @@
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.IntConsumer;
import java.util.stream.Collectors;

public class BytecodeGen {

Expand Down Expand Up @@ -113,14 +111,14 @@ public static synchronized CompiledEntry compile0(AstNode node) {
genContext.newSingleMethod0((adapter, localVarConsumer) -> rootNode.doBytecodeGenSingle(genContext, adapter, localVarConsumer), "evalSingle", true);
genContext.newMultiMethod0((adapter, localVarConsumer) -> rootNode.doBytecodeGenMulti(genContext, adapter, localVarConsumer), "evalMulti", true);

List<Object> args = genContext.args.entrySet().stream()
Object[] args = genContext.args.entrySet().stream()
.sorted(Comparator.comparingInt(o -> o.getValue().ordinal()))
.map(Map.Entry::getKey)
.collect(Collectors.toCollection(ArrayList::new));
.toArray(Object[]::new);

if (cached != null) {
try {
return (CompiledEntry) cached.getConstructor(List.class).newInstance(args);
return (CompiledEntry) cached.getConstructor(Object[].class).newInstance(new Object[]{args});
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
Expand All @@ -131,20 +129,20 @@ public static synchronized CompiledEntry compile0(AstNode node) {
genNewInstance(genContext);
// genFields(genContext);

ListIterator<Object> iterator = args.listIterator();
while (iterator.hasNext()) {
Object next = iterator.next();
// if (next instanceof DensityFunctionTypes.Wrapping wrapping && wrapping.type() == DensityFunctionTypes.Wrapping.Type.FLAT_CACHE) {
// iterator.set(new DensityFunctionTypes.Wrapping(wrapping.type(), compile(wrapping.wrapped())));
// }
}
// ListIterator<Object> iterator = args.listIterator();
// while (iterator.hasNext()) {
// Object next = iterator.next();
//// if (next instanceof DensityFunctionTypes.Wrapping wrapping && wrapping.type() == DensityFunctionTypes.Wrapping.Type.FLAT_CACHE) {
//// iterator.set(new DensityFunctionTypes.Wrapping(wrapping.type(), compile(wrapping.wrapped())));
//// }
// }

byte[] bytes = writer.toByteArray();
dumpClass(genContext.className, bytes);
Class<?> defined = defineClass(genContext.className, bytes);
compilationCache.put(node, defined);
try {
return (CompiledEntry) defined.getConstructor(List.class).newInstance(args);
return (CompiledEntry) defined.getConstructor(Object[].class).newInstance(new Object[]{args});
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
Expand All @@ -156,11 +154,11 @@ private static void genConstructor(Context context) {
context.className,
Opcodes.ACC_PUBLIC,
"<init>",
Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(List.class)),
Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Object[].class)),
context.classWriter.visitMethod(
Opcodes.ACC_PUBLIC,
"<init>",
Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(List.class)),
Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Object[].class)),
null,
null
)
Expand All @@ -182,7 +180,7 @@ private static void genConstructor(Context context) {
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.iconst(ordinal);
m.invokeinterface(Type.getInternalName(List.class), "get", Type.getMethodDescriptor(InstructionAdapter.OBJECT_TYPE, Type.INT_TYPE));
m.aload(InstructionAdapter.OBJECT_TYPE);
m.checkcast(Type.getType(type));
m.putfield(context.className, name, Type.getDescriptor(type));
}
Expand All @@ -195,7 +193,7 @@ private static void genConstructor(Context context) {
m.areturn(Type.VOID_TYPE);
m.visitLabel(end);
m.visitLocalVariable("this", context.classDesc, null, start, end, 0);
m.visitLocalVariable("list", Type.getDescriptor(List.class), null, start, end, 1);
m.visitLocalVariable("args", Type.getDescriptor(Object[].class), null, start, end, 1);
m.visitMaxs(0, 0);
}

Expand All @@ -205,11 +203,11 @@ private static void genGetArgs(Context context) {
context.className,
Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL,
"getArgs",
Type.getMethodDescriptor(Type.getType(List.class)),
Type.getMethodDescriptor(Type.getType(Object[].class)),
context.classWriter.visitMethod(
Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL,
"getArgs",
Type.getMethodDescriptor(Type.getType(List.class)),
Type.getMethodDescriptor(Type.getType(Object[].class)),
null,
null
)
Expand All @@ -220,28 +218,25 @@ private static void genGetArgs(Context context) {
Label end = new Label();
m.visitLabel(start);

m.anew(Type.getType(ArrayList.class));
m.dup();
m.iconst(context.args.size());
m.invokespecial(Type.getInternalName(ArrayList.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE), false);
m.store(1, InstructionAdapter.OBJECT_TYPE);
m.newarray(InstructionAdapter.OBJECT_TYPE);

int index = 0;
for (Map.Entry<Object, Context.FieldRecord> entry : context.args.entrySet().stream().sorted(Comparator.comparingInt(o -> o.getValue().ordinal())).toList()) {
String name = entry.getValue().name();
Class<?> type = entry.getValue().type();

m.load(1, InstructionAdapter.OBJECT_TYPE);
m.dup();
m.iconst(index ++);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, name, Type.getDescriptor(type));
m.invokeinterface(Type.getInternalName(List.class), "add", Type.getMethodDescriptor(Type.BOOLEAN_TYPE, InstructionAdapter.OBJECT_TYPE));
m.pop();
m.astore(InstructionAdapter.OBJECT_TYPE);
}

m.load(1, InstructionAdapter.OBJECT_TYPE);
m.areturn(InstructionAdapter.OBJECT_TYPE);
m.visitLabel(end);
m.visitLocalVariable("this", context.classDesc, null, start, end, 0);
m.visitLocalVariable("list", Type.getDescriptor(List.class), null, start, end, 1);
m.visitLocalVariable("args", Type.getDescriptor(Object[].class), null, start, end, 1);
m.visitMaxs(0, 0);
}

Expand All @@ -251,11 +246,11 @@ private static void genNewInstance(Context context) {
context.className,
Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL,
"newInstance",
Type.getMethodDescriptor(Type.getType(CompiledEntry.class), Type.getType(List.class)),
Type.getMethodDescriptor(Type.getType(CompiledEntry.class), Type.getType(Object[].class)),
context.classWriter.visitMethod(
Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL,
"newInstance",
Type.getMethodDescriptor(Type.getType(CompiledEntry.class), Type.getType(List.class)),
Type.getMethodDescriptor(Type.getType(CompiledEntry.class), Type.getType(Object[].class)),
null,
null
)
Expand All @@ -268,12 +263,12 @@ private static void genNewInstance(Context context) {
m.anew(Type.getType(context.classDesc));
m.dup();
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.invokespecial(context.className, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(List.class)), false);
m.invokespecial(context.className, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Object[].class)), false);
m.areturn(InstructionAdapter.OBJECT_TYPE);

m.visitLabel(end);
m.visitLocalVariable("this", context.classDesc, null, start, end, 0);
m.visitLocalVariable("list", Type.getDescriptor(List.class), null, start, end, 1);
m.visitLocalVariable("args", Type.getDescriptor(Object[].class), null, start, end, 1);
m.visitMaxs(0, 0);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,36 +41,36 @@ public DensityFunction apply(DensityFunctionVisitor visitor) {
return fallback1.apply(visitor);
}
boolean modified = false;
List<Object> args = this.compiledEntry.getArgs();
for (ListIterator<Object> iterator = args.listIterator(); iterator.hasNext(); ) {
Object next = iterator.next();
Object[] args = this.compiledEntry.getArgs();
for (int i = 0; i < args.length; i ++) {
Object next = args[i];
if (next instanceof DensityFunction df) {
if (!(df instanceof IFastCacheLike)) {
DensityFunction applied = df.apply(visitor);
if (df != applied) {
iterator.set(applied);
args[i] = applied;
modified = true;
}
}
}
if (next instanceof Noise noise) {
Noise applied = visitor.apply(noise);
if (noise != applied) {
iterator.set(applied);
args[i] = applied;
modified = true;
}
}
}

for (ListIterator<Object> iterator = args.listIterator(); iterator.hasNext(); ) {
Object next = iterator.next();
for (int i = 0; i < args.length; i ++) {
Object next = args[i];
if (next instanceof IFastCacheLike cacheLike) {
DensityFunction applied = visitor.apply(cacheLike);
if (applied == cacheLike.c2me$getDelegate()) {
iterator.set(null); // cache removed
args[i] = null; // cache removed
modified = true;
} else if (applied instanceof IFastCacheLike newCacheLike) {
iterator.set(newCacheLike);
args[i] = newCacheLike;
modified = true;
} else {
throw new UnsupportedOperationException("Unsupported transformation on Wrapping node");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@
import com.ishland.c2me.opts.dfc.common.ast.EvalType;
import com.ishland.c2me.opts.dfc.common.util.ArrayCache;

import java.util.List;

public interface CompiledEntry extends ISingleMethod, IMultiMethod {

double evalSingle(int x, int y, int z, EvalType type);

void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type, ArrayCache arrayCache);

CompiledEntry newInstance(List<?> args);
CompiledEntry newInstance(Object[] args);

List<Object> getArgs();
Object[] getArgs();

}

0 comments on commit 5082a14

Please sign in to comment.