Skip to content

Commit

Permalink
Refactor rec atom synchronization
Browse files Browse the repository at this point in the history
  • Loading branch information
heshanpadmasiri committed Feb 8, 2025
1 parent 6f9ab37 commit 29a15d3
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 269 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ static CellAtomicType cellAtomicVal() {
}

public static BddNode getBddSubtypeRo() {
return bddAtom(RecAtom.createRecAtom(0));
return bddAtom(RecAtom.createUnBlockedRecAtom(0));
}

public static ListAtomicType getListAtomicInner() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import io.ballerina.runtime.internal.types.semtype.FunctionAtomicType;
import io.ballerina.runtime.internal.types.semtype.ListAtomicType;
import io.ballerina.runtime.internal.types.semtype.MappingAtomicType;
import io.ballerina.runtime.internal.types.semtype.MutableSemType;

import java.util.ArrayList;
import java.util.LinkedHashMap;
Expand All @@ -49,9 +48,6 @@ public final class Context {
public final Map<Bdd, BddMemo> functionMemo = new WeakHashMap<>();
private static final int MAX_CACHE_SIZE = 100;
private final Map<CacheableTypeDescriptor, TypeCheckCache<CacheableTypeDescriptor>> typeCheckCacheMemo;
private Phase phase = Phase.INIT;
private int typeCheckDepth = 0;
private int typeResolutionDepth = 0;

private Context(Env env) {
this.env = env;
Expand Down Expand Up @@ -94,64 +90,6 @@ public boolean memoSubtypeIsEmpty(Map<Bdd, BddMemo> memoTable, BddIsEmptyPredica
return m.isEmpty().orElseGet(() -> memoSubTypeIsEmptyInner(isEmptyPredicate, bdd, m));
}

public void enterTypeResolutionPhase(MutableSemType type) throws InterruptedException {
switch (phase) {
case INIT -> {
typeResolutionDepth++;
env.enterTypeResolutionPhase(this, type);
phase = Phase.TYPE_RESOLUTION;
}
case TYPE_RESOLUTION -> typeResolutionDepth++;
case TYPE_CHECKING -> throw new IllegalStateException(
"Cannot enter type resolution phase while in type checking phase\n");
}
}

public void exitTypeResolutionPhaseAbruptly(Exception ex) {
env.exitTypeResolutionPhaseAbruptly(this, ex);
}

public void enterTypeCheckingPhase(SemType t1, SemType t2) {
typeCheckDepth++;
switch (phase) {
case INIT -> {
env.enterTypeCheckingPhase(this, t1, t2);
phase = Phase.TYPE_CHECKING;
}
case TYPE_RESOLUTION -> throw new IllegalStateException(
"Cannot enter type checking phase while in type resolution phase\n");
case TYPE_CHECKING -> {
}
}
}

public void exitTypeResolutionPhase() {
if (phase == Phase.TYPE_RESOLUTION) {
typeResolutionDepth--;
if (typeResolutionDepth == 0) {
env.exitTypeResolutionPhase(this);
phase = Phase.INIT;
}
} else {
throw new IllegalStateException("Cannot exit type resolution phase without entering it");
}
}

public void exitTypeCheckingPhase() {
switch (phase) {
case INIT -> throw new IllegalStateException("Cannot exit type checking phase without entering it");
case TYPE_RESOLUTION ->
throw new IllegalStateException("Cannot exit type checking phase while in type resolution phase\n");
case TYPE_CHECKING -> {
env.exitTypeCheckingPhase(this);
typeCheckDepth--;
if (typeCheckDepth == 0) {
phase = Phase.INIT;
}
}
}
}

private boolean memoSubTypeIsEmptyInner(BddIsEmptyPredicate isEmptyPredicate, Bdd bdd, BddMemo m) {
// We are staring the type check with the assumption our type is empty (see: inductive type)
m.isEmpty = BddMemo.Status.PROVISIONAL;
Expand Down Expand Up @@ -192,40 +130,21 @@ private void resetMemoizedValues(int initStackDepth, boolean isEmpty, boolean is
}

public ListAtomicType listAtomType(Atom atom) {
if (atom instanceof RecAtom recAtom) {
assert this.env.getRecListAtomType(recAtom) != null;
return this.env.getRecListAtomType(recAtom);
} else {
return (ListAtomicType) ((TypeAtom) atom).atomicType();
}
return env.listAtomType(atom);
}

public MappingAtomicType mappingAtomType(Atom atom) {
if (atom instanceof RecAtom recAtom) {
assert this.env.getRecMappingAtomType(recAtom) != null;
return this.env.getRecMappingAtomType(recAtom);
} else {
return (MappingAtomicType) ((TypeAtom) atom).atomicType();
}
return env.mappingAtomType(atom);
}

public FunctionAtomicType functionAtomicType(Atom atom) {
if (atom instanceof RecAtom recAtom) {
assert this.env.getRecFunctionAtomType(recAtom) != null;
return this.env.getRecFunctionAtomType(recAtom);
} else {
return (FunctionAtomicType) ((TypeAtom) atom).atomicType();
}
return env.functionAtomType(atom);
}

public TypeCheckCache<CacheableTypeDescriptor> getTypeCheckCache(CacheableTypeDescriptor typeDescriptor) {
return typeCheckCacheMemo.computeIfAbsent(typeDescriptor, TypeCheckCache::new);
}

public void registerAbruptTypeCheckEnd(Exception ex) {
env.registerAbruptTypeCheckEnd(this, ex);
}

enum Phase {
INIT, TYPE_RESOLUTION, TYPE_CHECKING
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,18 +296,11 @@ public static boolean isNever(SemType t) {
}

public static boolean isSubType(Context cx, SemType t1, SemType t2) {
try {
cx.enterTypeCheckingPhase(t1, t2);
TypeCheckLogger logger = TypeCheckLogger.getInstance();
logger.semTypeCheckStarted(cx, t1, t2);
boolean res = isEmpty(cx, diff(t1, t2));
logger.semTypeCheckDone(cx, t1, t2, res);
cx.exitTypeCheckingPhase();
return res;
} catch (Exception e) {
cx.registerAbruptTypeCheckEnd(e);
throw e;
}
TypeCheckLogger logger = TypeCheckLogger.getInstance();
logger.semTypeCheckStarted(cx, t1, t2);
boolean res = isEmpty(cx, diff(t1, t2));
logger.semTypeCheckDone(cx, t1, t2, res);
return res;
}

public static boolean isSubtypeSimple(SemType t1, SemType t2) {
Expand Down
Loading

0 comments on commit 29a15d3

Please sign in to comment.