C: fix bugs in GC

This commit is contained in:
Alexey Andreev 2019-04-05 13:08:16 +03:00
parent ec8bae1d40
commit 7551cd1ec6
9 changed files with 53 additions and 14 deletions

View File

@ -592,7 +592,7 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
String mainMethod = names.forMethod(entryPoint.getMethod()); String mainMethod = names.forMethod(entryPoint.getMethod());
context.writer().print(mainMethod + "("); context.writer().print(mainMethod + "(");
context.emit(invocation.getArguments().get(0)); context.emit(invocation.getArguments().get(0));
context.writer().println(");"); context.writer().print(")");
} }
} }

View File

@ -32,6 +32,7 @@ import org.teavm.dependency.DependencyInfo;
import org.teavm.diagnostics.Diagnostics; import org.teavm.diagnostics.Diagnostics;
import org.teavm.interop.Address; import org.teavm.interop.Address;
import org.teavm.interop.DelegateTo; import org.teavm.interop.DelegateTo;
import org.teavm.interop.NoGcRoot;
import org.teavm.interop.Structure; import org.teavm.interop.Structure;
import org.teavm.model.AnnotationHolder; import org.teavm.model.AnnotationHolder;
import org.teavm.model.ClassHolder; import org.teavm.model.ClassHolder;
@ -278,7 +279,7 @@ public class ClassGenerator {
String fieldName = context.getNames().forStaticField(field.getReference()); String fieldName = context.getNames().forStaticField(field.getReference());
fieldsWriter.print("static ").printStrictType(field.getType()).print(" ").print(fieldName) fieldsWriter.print("static ").printStrictType(field.getType()).print(" ").print(fieldName)
.println(";"); .println(";");
if (isReferenceType(field.getType())) { if (isReferenceType(field.getType()) && field.getAnnotations().get(NoGcRoot.class.getName()) == null) {
staticFields[staticIndex++] = field.getReference(); staticFields[staticIndex++] = field.getReference();
} }

View File

@ -102,7 +102,6 @@ public class CodeGenerationVisitor implements ExprVisitor, StatementVisitor {
private int[] maxTemporaryVariableLevel = new int[5]; private int[] maxTemporaryVariableLevel = new int[5];
private MethodReference callingMethod; private MethodReference callingMethod;
private Set<? super String> includes; private Set<? super String> includes;
private int currentPart;
private boolean end; private boolean end;
private boolean async; private boolean async;
@ -384,7 +383,11 @@ public class CodeGenerationVisitor implements ExprVisitor, StatementVisitor {
writer.print(", "); writer.print(", ");
MethodReader method = context.getClassSource().resolve(expr.getMethod()); MethodReader method = context.getClassSource().resolve(expr.getMethod());
writer.print(names.forMethod(method.getReference())); MethodReference reference = expr.getMethod();
if (method != null) {
reference = method.getReference();
}
writer.print(names.forMethod(reference));
writer.print("(" + receiver); writer.print("(" + receiver);
for (Expr arg : expr.getArguments()) { for (Expr arg : expr.getArguments()) {
@ -400,10 +403,14 @@ public class CodeGenerationVisitor implements ExprVisitor, StatementVisitor {
case SPECIAL: case SPECIAL:
case STATIC: { case STATIC: {
MethodReader method = context.getClassSource().resolve(expr.getMethod()); MethodReader method = context.getClassSource().resolve(expr.getMethod());
if (isWrappedNativeCall(method)) { if (method != null && isWrappedNativeCall(method)) {
generateWrappedNativeCall(method, expr); generateWrappedNativeCall(method, expr);
} else { } else {
writer.print(names.forMethod(method.getReference())); MethodReference reference = expr.getMethod();
if (method != null) {
reference = method.getReference();
}
writer.print(names.forMethod(reference));
writer.print("("); writer.print("(");
if (!expr.getArguments().isEmpty()) { if (!expr.getArguments().isEmpty()) {

View File

@ -81,7 +81,7 @@ public class GCShadowStackContributor {
int usedColors = 0; int usedColors = 0;
for (int var = 0; var < colors.length; ++var) { for (int var = 0; var < colors.length; ++var) {
if (spilled[var]) { if (spilled[var]) {
usedColors = Math.max(usedColors, colors[var]); usedColors = Math.max(usedColors, colors[var] + 1);
colors[var]--; colors[var]--;
} }
} }

View File

@ -50,7 +50,7 @@ public class RedundantNullCheckElimination implements MethodOptimization {
} else if (nullness.isNull(nullCheck.getValue())) { } else if (nullness.isNull(nullCheck.getValue())) {
block.detachSuccessors(); block.detachSuccessors();
while (nullCheck.getNext() != null) { while (nullCheck.getNext() != null) {
nullCheck.delete(); nullCheck.getNext().delete();
} }
nullCheck.insertPreviousAll(ProgramUtils.createThrowNPEInstructions( nullCheck.insertPreviousAll(ProgramUtils.createThrowNPEInstructions(

View File

@ -479,12 +479,13 @@ public class PhiUpdater {
return; return;
} }
boolean exists = frontierBlock.getPhis().stream() for (Phi phi : frontierBlock.getPhis()) {
.flatMap(phi -> phi.getIncomings().stream()) for (Incoming incoming : phi.getIncomings()) {
.anyMatch(incoming -> incoming.getSource() == block && incoming.getValue() == var); if (incoming.getSource() == block && incoming.getValue() == var) {
if (exists) {
return; return;
} }
}
}
Phi phi = phiMap[frontier][var.getIndex()]; Phi phi = phiMap[frontier][var.getIndex()];
if (phi == null) { if (phi == null) {

View File

@ -977,7 +977,9 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
ListableClassReaderSourceAdapter(ClassReaderSource classSource, Set<String> classes) { ListableClassReaderSourceAdapter(ClassReaderSource classSource, Set<String> classes) {
this.classSource = classSource; this.classSource = classSource;
this.classes = Collections.unmodifiableSet(classes); this.classes = Collections.unmodifiableSet(classes.stream()
.filter(className -> classSource.get(className) != null)
.collect(Collectors.toSet()));
} }
@Override @Override

View File

@ -0,0 +1,26 @@
/*
* Copyright 2019 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.interop;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface NoGcRoot {
}

View File

@ -18,6 +18,7 @@ package org.teavm.platform.plugin;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.teavm.backend.javascript.spi.GeneratedBy; import org.teavm.backend.javascript.spi.GeneratedBy;
import org.teavm.interop.NoGcRoot;
import org.teavm.interop.NoSideEffects; import org.teavm.interop.NoSideEffects;
import org.teavm.model.AccessLevel; import org.teavm.model.AccessLevel;
import org.teavm.model.AnnotationHolder; import org.teavm.model.AnnotationHolder;
@ -56,6 +57,7 @@ class MetadataProviderTransformer implements ClassHolderTransformer {
field.setType(method.getResultType()); field.setType(method.getResultType());
field.setLevel(AccessLevel.PRIVATE); field.setLevel(AccessLevel.PRIVATE);
field.getModifiers().add(ElementModifier.STATIC); field.getModifiers().add(ElementModifier.STATIC);
field.getAnnotations().add(new AnnotationHolder(NoGcRoot.class.getName()));
cls.addField(field); cls.addField(field);
MethodHolder createMethod = new MethodHolder(method.getName() + "$$create", method.getSignature()); MethodHolder createMethod = new MethodHolder(method.getName() + "$$create", method.getSignature());