From 9d0a53175a58b53f7ab7cbc5f121438eaf6cab49 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Thu, 5 Dec 2019 15:36:32 +0300 Subject: [PATCH] Do not insert GC write barriers when value assigned to field is known to be null or constant literal --- .../model/lowlevel/WriteBarrierInsertion.java | 37 +++++++++++++++++-- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/teavm/model/lowlevel/WriteBarrierInsertion.java b/core/src/main/java/org/teavm/model/lowlevel/WriteBarrierInsertion.java index dd3efa77c..d9e6c48f0 100644 --- a/core/src/main/java/org/teavm/model/lowlevel/WriteBarrierInsertion.java +++ b/core/src/main/java/org/teavm/model/lowlevel/WriteBarrierInsertion.java @@ -30,6 +30,7 @@ import org.teavm.model.instructions.AbstractInstructionVisitor; import org.teavm.model.instructions.ArrayElementType; import org.teavm.model.instructions.AssignInstruction; import org.teavm.model.instructions.CastInstruction; +import org.teavm.model.instructions.ClassConstantInstruction; import org.teavm.model.instructions.CloneArrayInstruction; import org.teavm.model.instructions.ConstructArrayInstruction; import org.teavm.model.instructions.ConstructInstruction; @@ -40,8 +41,10 @@ import org.teavm.model.instructions.InvokeInstruction; import org.teavm.model.instructions.MonitorEnterInstruction; import org.teavm.model.instructions.MonitorExitInstruction; import org.teavm.model.instructions.NullCheckInstruction; +import org.teavm.model.instructions.NullConstantInstruction; import org.teavm.model.instructions.PutElementInstruction; import org.teavm.model.instructions.PutFieldInstruction; +import org.teavm.model.instructions.StringConstantInstruction; import org.teavm.model.util.DominatorWalker; import org.teavm.model.util.DominatorWalkerCallback; import org.teavm.model.util.DominatorWalkerContext; @@ -61,14 +64,19 @@ public class WriteBarrierInsertion { if (program.basicBlockCount() == 0) { return; } - new DominatorWalker(program).walk(new WalkerCallbackImpl()); + new DominatorWalker(program).walk(new WalkerCallbackImpl(program.variableCount())); } class WalkerCallbackImpl extends AbstractInstructionVisitor implements DominatorWalkerCallback { private DominatorWalkerContext context; + private boolean[] constantVariables; IntHashSet installedBarriers = new IntHashSet(); State state; + WalkerCallbackImpl(int variableCount) { + constantVariables = new boolean[variableCount]; + } + @Override public void setContext(DominatorWalkerContext context) { this.context = context; @@ -108,10 +116,25 @@ public class WriteBarrierInsertion { } } + @Override + public void visit(NullConstantInstruction insn) { + constantVariables[insn.getReceiver().getIndex()] = true; + } + + @Override + public void visit(ClassConstantInstruction insn) { + constantVariables[insn.getReceiver().getIndex()] = true; + } + + @Override + public void visit(StringConstantInstruction insn) { + constantVariables[insn.getReceiver().getIndex()] = true; + } + @Override public void visit(PutFieldInstruction insn) { if (insn.getInstance() != null && isManagedReferenceType(insn.getFieldType())) { - installBarrier(insn, insn.getInstance()); + installBarrier(insn, insn.getInstance(), insn.getValue()); } } @@ -169,7 +192,7 @@ public class WriteBarrierInsertion { @Override public void visit(PutElementInstruction insn) { if (insn.getType() == ArrayElementType.OBJECT) { - installBarrier(insn, insn.getArray()); + installBarrier(insn, insn.getArray(), insn.getValue()); } } @@ -192,9 +215,15 @@ public class WriteBarrierInsertion { if (installedBarriers.contains(from.getIndex())) { markAsInstalled(to.getIndex()); } + if (constantVariables[from.getIndex()]) { + constantVariables[to.getIndex()] = true; + } } - private void installBarrier(Instruction instruction, Variable variable) { + private void installBarrier(Instruction instruction, Variable variable, Variable value) { + if (constantVariables[value.getIndex()]) { + return; + } if (markAsInstalled(variable.getIndex())) { InvokeInstruction invoke = new InvokeInstruction(); invoke.setType(InvocationType.SPECIAL);