Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordwagelaar2014-06-29 15:39:00 -0400
committerdwagelaar2014-06-29 15:39:00 -0400
commit099b22a34fd9bdc43dc884958fa9de2a82d0325b (patch)
tree32bf93062f2d03c4523bada63997f45531bdda23 /plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse
parentc2df5da00c691ff8f43e80cb210457124e58d1cd (diff)
downloadorg.eclipse.atl-099b22a34fd9bdc43dc884958fa9de2a82d0325b.tar.gz
org.eclipse.atl-099b22a34fd9bdc43dc884958fa9de2a82d0325b.tar.xz
org.eclipse.atl-099b22a34fd9bdc43dc884958fa9de2a82d0325b.zip
JIT performance improvement: compile FINDTYPE/NEW pairs for native types
to standard Java class instantiation.
Diffstat (limited to 'plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse')
-rw-r--r--plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/jit/ByteCodeSwitch.java49
1 files changed, 39 insertions, 10 deletions
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/jit/ByteCodeSwitch.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/jit/ByteCodeSwitch.java
index a7a52e8d..15d6024a 100644
--- a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/jit/ByteCodeSwitch.java
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/jit/ByteCodeSwitch.java
@@ -15,6 +15,7 @@ import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -151,6 +152,10 @@ public class ByteCodeSwitch extends EmftvmSwitch<MethodVisitor> implements Opcod
* Whether or not the current execution environment has a monitor attached.
*/
protected final boolean hasMonitor;
+ /**
+ * Set of instructions to skip while generating bytecode.
+ */
+ protected final java.util.Set<Instruction> skipInstructions = new HashSet<Instruction>();
/**
* Creates a new {@link ByteCodeSwitch}.
@@ -385,7 +390,15 @@ public class ByteCodeSwitch extends EmftvmSwitch<MethodVisitor> implements Opcod
if (EMFTVMUtil.NATIVE.equals(object.getModelname())) {
try {
final Class<?> type = NativeTypes.findType(object.getTypename());
- ldc(Type.getType(type)); // [..., type]
+ final Instruction nextInstr = nextInstruction(object);
+ if (nextInstr instanceof New) {
+ new_(type);
+ dup();
+ invokeSpec(type, "<init>", Void.TYPE);
+ skipInstructions.add(nextInstr);
+ } else {
+ ldc(Type.getType(type)); // [..., type]
+ }
return super.caseFindtype(object);
} catch (ClassNotFoundException e) {
// fall back - will generate same exception anyway
@@ -416,16 +429,18 @@ public class ByteCodeSwitch extends EmftvmSwitch<MethodVisitor> implements Opcod
*/
@Override
public MethodVisitor caseNew(final New object) {
- // [..., type]
- final String modelName = object.getModelname();
- if (modelName == null) {
- aconst_null(); // [..., type, null]
- } else {
- ldc(object.getModelname()) ; // [..., type, modelname]
+ if (!skipInstructions.contains(object)) {
+ // [..., type]
+ final String modelName = object.getModelname();
+ if (modelName == null) {
+ aconst_null(); // [..., type, null]
+ } else {
+ ldc(object.getModelname()) ; // [..., type, modelname]
+ }
+ aload(2); // env: [..., type, modelname, env]
+ invokeStat(JITCodeBlock.class, "newInstance", Object.class, // newInstance(type, modelname, env): [..., object]
+ Object.class, String.class, ExecEnv.class);
}
- aload(2); // env: [..., type, modelname, env]
- invokeStat(JITCodeBlock.class, "newInstance", Object.class, // newInstance(type, modelname, env): [..., object]
- Object.class, String.class, ExecEnv.class);
return super.caseNew(object);
}
@@ -2432,5 +2447,19 @@ public class ByteCodeSwitch extends EmftvmSwitch<MethodVisitor> implements Opcod
final Label handler, final Class<?> type) {
mv.visitTryCatchBlock(start, end, handler, Type.getInternalName(type));
}
+
+ /**
+ * Returns the next instruction for the given instruction, or <code>null</code>.
+ * @param instruction the instruction
+ * @return the next instruction for the given instruction, or <code>null</code>
+ */
+ protected Instruction nextInstruction(final Instruction instruction) {
+ final List<Instruction> code = instruction.getOwningBlock().getCode();
+ final int index = code.indexOf(instruction);
+ if (index < code.size() - 1) {
+ return code.get(index + 1);
+ }
+ return null;
+ }
} \ No newline at end of file

Back to the top