Skip to content

Commit

Permalink
Simplify the sync logic
Browse files Browse the repository at this point in the history
  • Loading branch information
heshanpadmasiri committed Dec 17, 2024
1 parent f723bee commit bf10b3e
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,12 @@ 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 int nTypeChecking = 0;
private Phase phase = Phase.INIT;
List<PhaseData> typeResolutionPhases = new ArrayList<>();
List<PhaseData> typeCheckPhases = new ArrayList<>();
private final boolean collectDiagnostic;
private int typeCheckDepth = 0;
private int typeResolutionDepth = 0;

private Context(Env env) {
this.env = env;
Expand Down Expand Up @@ -100,13 +101,15 @@ public boolean memoSubtypeIsEmpty(Map<Bdd, BddMemo> memoTable, BddIsEmptyPredica
public void enterTypeResolutionPhase(MutableSemType type) throws InterruptedException {
switch (phase) {
case INIT -> {
typeResolutionDepth++;
env.enterTypeResolutionPhase(this, type);
phase = Phase.TYPE_RESOLUTION;
if (collectDiagnostic) {
typeResolutionPhases.add(new PhaseData());
}
}
case TYPE_RESOLUTION -> {
typeResolutionDepth++;
}
case TYPE_CHECKING -> {
StringBuilder sb = new StringBuilder();
Expand All @@ -124,22 +127,22 @@ public void exitTypeResolutionPhaseAbruptly(Exception ex) {
}

public void enterTypeCheckingPhase(SemType t1, SemType t2) {
nTypeChecking += 1;
typeCheckDepth++;
switch (phase) {
case INIT -> {
// This can happen if both types are immutable semtypes
env.enterTypeCheckingPhase(this, t1, t2);
if (collectDiagnostic) {
typeCheckPhases.add(new PhaseData());
}
phase = Phase.TYPE_CHECKING;
}
case TYPE_RESOLUTION -> {
env.enterTypeCheckingPhase(this, t1, t2);
StringBuilder sb = new StringBuilder();
sb.append("Cannot enter type checking phase while in type resolution phase\n");
if (collectDiagnostic) {
typeCheckPhases.add(new PhaseData());
typeResolutionPhases.removeLast();
appendPhaseDataToError(sb);
}
phase = Phase.TYPE_CHECKING;
throw new IllegalStateException(sb.toString());
}
case TYPE_CHECKING -> {
}
Expand All @@ -148,16 +151,20 @@ public void enterTypeCheckingPhase(SemType t1, SemType t2) {

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

public void exitTypeCheckingPhase() {
nTypeChecking -= 1;
switch (phase) {
case INIT -> {
StringBuilder sb = new StringBuilder();
Expand All @@ -176,15 +183,11 @@ public void exitTypeCheckingPhase() {
throw new IllegalStateException(sb.toString());
}
case TYPE_CHECKING -> {
assert nTypeChecking >= 0;
if (nTypeChecking == 0) {
env.exitTypeCheckingPhase(this);
if (collectDiagnostic) {
typeCheckPhases.removeLast();
}
env.exitTypeCheckingPhase(this);
typeCheckDepth--;
if (typeCheckDepth == 0) {
phase = Phase.INIT;
}
assert nTypeChecking >= 0;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,18 +339,18 @@ private void releaseLock(ReentrantReadWriteLock lock) {
}

void exitTypeResolutionPhase(Context cx) {
pendingTypeResolutions.decrementAndGet();
long res = pendingTypeResolutions.decrementAndGet();
assert res >= 0;
this.selfDiagnosticsRunner.registerTypeResolutionExit(cx);
}

void enterTypeCheckingPhase(Context cx, SemType t1, SemType t2) {
long pendingResolutions = pendingTypeResolutions.decrementAndGet();
while (pendingResolutions > 0) {
assert pendingTypeResolutions.get() >= 0;
while (pendingTypeResolutions.get() != 0) {
try {
Thread.sleep(10);
} catch (InterruptedException ignored) {
}
pendingResolutions = pendingTypeResolutions.get();
}
this.selfDiagnosticsRunner.registerTypeCheckStart(cx, t1, t2);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,7 @@ protected void setSome(int some, SubType[] subTypeData) {

public static SemType tryInto(Context cx, Type type) {
if (type instanceof MutableSemType mutableSemType) {
try {
cx.enterTypeResolutionPhase(mutableSemType);
mutableSemType.updateInnerSemTypeIfNeeded(cx);
} catch (Exception ex) {
cx.exitTypeResolutionPhaseAbruptly(ex);
throw new RuntimeException("Error while resolving type: " + mutableSemType, ex);
}
mutableSemType.updateInnerSemTypeIfNeeded(cx);
}

return (SemType) type;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,9 @@ public static Object checkCast(Object sourceVal, Type targetType) {
}
Type sourceType = getType(sourceVal);
Context cx = context();
if (containsBasicType(cx, sourceType, ConvertibleCastMaskHolder.CONVERTIBLE_CAST_MASK) &&
containsBasicType(cx, targetType, ConvertibleCastMaskHolder.CONVERTIBLE_CAST_MASK)) {
if (Core.containsBasicType(SemType.tryInto(cx, sourceType), ConvertibleCastMaskHolder.CONVERTIBLE_CAST_MASK) &&
Core.containsBasicType(SemType.tryInto(cx, targetType),
ConvertibleCastMaskHolder.CONVERTIBLE_CAST_MASK)) {
// We need to maintain order for these?
if (targetType instanceof BUnionType unionType) {
for (Type memberType : unionType.getMemberTypes()) {
Expand All @@ -143,14 +144,6 @@ public static Object checkCast(Object sourceVal, Type targetType) {
throw createTypeCastError(sourceVal, targetType, errors);
}

public static boolean containsBasicType(Context cx, Type type, SemType semType) {
try {
return Core.containsBasicType(SemType.tryInto(context(), type), semType);
} finally {
cx.exitTypeResolutionPhase();
}
}

public static Context context() {
// We are pinning each context to thread. We can't use the same context with multiple type checks concurrently
return threadContext.get();
Expand Down Expand Up @@ -272,11 +265,8 @@ public static boolean checkIsType(Object sourceVal, Type targetType) {
return true;
}
SemType sourceSemType = SemType.tryInto(cx, sourceType);
if (!couldInherentTypeBeDifferent(sourceSemType)) {
cx.exitTypeResolutionPhase();
return false;
}
return isSubTypeWithInherentType(cx, sourceVal, SemType.tryInto(cx, targetType));
return couldInherentTypeBeDifferent(sourceSemType) &&
isSubTypeWithInherentType(cx, sourceVal, SemType.tryInto(cx, targetType));
}

/**
Expand Down Expand Up @@ -609,7 +599,6 @@ public static boolean isByteLiteral(long longValue) {
// Private methods

private static boolean isSubTypeWithInherentType(Context cx, Object sourceValue, SemType target) {
cx.exitTypeResolutionPhase();
return ShapeAnalyzer.inherentTypeOf(cx, sourceValue)
.map(source -> !Core.isEmpty(cx, source) && Core.isSubType(cx, source, target))
.orElse(false);
Expand Down Expand Up @@ -832,7 +821,6 @@ public static boolean isEqual(Object lhsValue, Object rhsValue, Set<ValuePair> c
private static boolean checkValueEqual(Context cx, Object lhsValue, Object rhsValue, Set<ValuePair> checkedValues) {
SemType lhsShape = ShapeAnalyzer.inherentTypeOf(cx, lhsValue).orElseThrow();
SemType rhsShape = ShapeAnalyzer.inherentTypeOf(cx, rhsValue).orElseThrow();
cx.exitTypeResolutionPhase();
Predicate<SemType> belongToSameBasicType = (basicType) -> Core.containsBasicType(lhsShape, basicType) &&
Core.containsBasicType(rhsShape, basicType);
if (belongToSameBasicType.test(Builder.getStringType()) ||
Expand Down Expand Up @@ -998,7 +986,6 @@ private enum FillerValueResult {
}

private static FillerValueResult hasFillerValueSemType(Context cx, SemType type) {
cx.exitTypeResolutionPhase();
if (Core.containsBasicType(type, Builder.getNilType())) {
return FillerValueResult.TRUE;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,9 +255,16 @@ public SemType createSemType(Context cx) {
@Override
public void updateInnerSemTypeIfNeeded(Context cx) {
if (cachedSemType == null) {
cachedSemType = createSemType(cx);
setAll(cachedSemType.all());
setSome(cachedSemType.some(), cachedSemType.subTypeData());
try {
cx.enterTypeResolutionPhase(this);
cachedSemType = createSemType(cx);
setAll(cachedSemType.all());
setSome(cachedSemType.some(), cachedSemType.subTypeData());
cx.exitTypeResolutionPhase();
} catch (InterruptedException e) {
cx.exitTypeResolutionPhaseAbruptly(e);
throw new RuntimeException(e);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import io.ballerina.runtime.api.types.Type;
import io.ballerina.runtime.api.types.TypeTags;
import io.ballerina.runtime.api.types.semtype.Builder;
import io.ballerina.runtime.api.types.semtype.Core;
import io.ballerina.runtime.api.types.semtype.SemType;
import io.ballerina.runtime.api.utils.TypeUtils;
import io.ballerina.runtime.api.values.BError;
import io.ballerina.runtime.api.values.BString;
Expand All @@ -35,7 +37,6 @@
import io.ballerina.runtime.internal.values.MapValue;

import static io.ballerina.runtime.api.constants.RuntimeConstants.MAP_LANG_LIB;
import static io.ballerina.runtime.internal.TypeChecker.containsBasicType;
import static io.ballerina.runtime.internal.errors.ErrorReasons.INHERENT_TYPE_VIOLATION_ERROR_IDENTIFIER;
import static io.ballerina.runtime.internal.errors.ErrorReasons.MAP_KEY_NOT_FOUND_ERROR;
import static io.ballerina.runtime.internal.errors.ErrorReasons.OPERATION_NOT_SUPPORTED_IDENTIFIER;
Expand Down Expand Up @@ -117,7 +118,7 @@ public static boolean handleInherentTypeViolatingRecordUpdate(
}

private static boolean containsNilType(Type type) {
return containsBasicType(TypeChecker.context(), type, Builder.getNilType());
return Core.containsBasicType(SemType.tryInto(TypeChecker.context(), type), Builder.getNilType());
}

public static BError createOpNotSupportedError(Type type, String op) {
Expand Down

0 comments on commit bf10b3e

Please sign in to comment.