From c24a7541c014ecd3c1019a80dba2be23ebaecac4 Mon Sep 17 00:00:00 2001 From: Heshan Padamsiri Date: Tue, 17 Dec 2024 14:24:23 +0530 Subject: [PATCH] Fix checkValueEqual --- .../runtime/api/types/semtype/Context.java | 22 +++++++++++-------- .../semtype/DebugSelfDiagnosticRunner.java | 9 ++++++++ .../runtime/api/types/semtype/Env.java | 10 ++++++++- .../semtype/NonOpSelfDiagnosticRunner.java | 5 +++++ .../TypeCheckSelfDiagnosticsRunner.java | 2 ++ .../runtime/internal/TypeChecker.java | 1 + 6 files changed, 39 insertions(+), 10 deletions(-) diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/Context.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/Context.java index 9b1f23e56e96..05ecfbe7d77a 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/Context.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/Context.java @@ -52,7 +52,7 @@ public final class Context { private int drainedPermits = 0; private int nTypeChecking = 0; private Phase phase = Phase.INIT; - // List typeCheckPhases = new ArrayList<>(); + List typeResolutionPhases = new ArrayList<>(); private Context(Env env) { this.env = env; @@ -100,6 +100,7 @@ public void enterTypeResolutionPhase(MutableSemType type) throws InterruptedExce case INIT -> { env.enterTypeResolutionPhase(this, type); phase = Phase.TYPE_RESOLUTION; + typeResolutionPhases.add(new PhaseData()); } case TYPE_RESOLUTION -> { } @@ -115,13 +116,13 @@ public void exitTypeResolutionPhaseAbruptly(Exception ex) { public void enterTypeCheckingPhase(SemType t1, SemType t2) { nTypeChecking += 1; -// typeCheckPhases.add(new PhaseData(phase, nTypeChecking, Thread.currentThread().getStackTrace())); switch (phase) { case INIT -> { // This can happen if both types are immutable semtypes phase = Phase.TYPE_CHECKING; } case TYPE_RESOLUTION -> { + typeResolutionPhases.removeLast(); drainedPermits = env.enterTypeCheckingPhase(this, t1, t2); phase = Phase.TYPE_CHECKING; } @@ -130,9 +131,14 @@ public void enterTypeCheckingPhase(SemType t1, SemType t2) { } } + public void exitTypeResolutionPhase() { + if (phase == Phase.TYPE_RESOLUTION) { + env.exitTypeResolutionPhase(this); + } + } + public void exitTypeCheckingPhase() { nTypeChecking -= 1; -// typeCheckPhases.removeLast(); switch (phase) { case INIT -> throw new IllegalStateException("Cannot exit type checking phase without entering it"); case TYPE_RESOLUTION -> @@ -227,17 +233,15 @@ enum Phase { INIT, TYPE_RESOLUTION, TYPE_CHECKING } - int getNTypeChecking() { - return nTypeChecking; - } + record PhaseData(StackTraceElement[] stackTrace) { - record PhaseData(Phase phase, int nTypeCheck, StackTraceElement[] stackTrace) { + PhaseData() { + this(Thread.currentThread().getStackTrace()); + } @Override public String toString() { StringBuilder builder = new StringBuilder(); - builder.append("Phase: ").append(phase).append("\n"); - builder.append("N type checking: ").append(nTypeCheck).append("\n"); for (StackTraceElement element : stackTrace) { builder.append("\tat ").append(element).append("\n"); } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/DebugSelfDiagnosticRunner.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/DebugSelfDiagnosticRunner.java index 7e8f1a20c2e9..c8309577505c 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/DebugSelfDiagnosticRunner.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/DebugSelfDiagnosticRunner.java @@ -147,6 +147,13 @@ public void registerAbruptTypeCheckEnd(Context cx, Exception ex) { } } + @Override + public void registerTypeResolutionExit(Context cx) { + synchronized (pendingTypeResolutions) { + pendingTypeResolutions.removeIf(data -> data.cx == cx); + } + } + private static String withIdentity(Object o) { return o + "[" + System.identityHashCode(o) + "]"; } @@ -174,6 +181,8 @@ private static String pendingTypeResolutionsToString(Collection logBuilder.append(each.toString()).append("\n")); }); return logBuilder.toString(); } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/Env.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/Env.java index 629a3fcbf430..cf4de644f553 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/Env.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/Env.java @@ -322,10 +322,12 @@ void enterTypeResolutionPhase(Context cx, MutableSemType t) throws InterruptedEx synchronized (this) { if (typeResolutionPhaser.isTerminated()) { typeResolutionPhaser = new Phaser(); + typeResolutionPhaser.register(); } } + } else { + typeResolutionPhaser.register(); } - typeResolutionPhaser.register(); this.selfDiagnosticsRunner.registerTypeResolutionStart(cx, t); } @@ -348,6 +350,12 @@ private void releaseLock(ReentrantReadWriteLock lock) { } } + void exitTypeResolutionPhase(Context cx) { + typeResolutionSemaphore.release(); + typeResolutionPhaser.arriveAndDeregister(); + this.selfDiagnosticsRunner.registerTypeResolutionExit(cx); + } + int enterTypeCheckingPhase(Context cx, SemType t1, SemType t2) { int drained = typeResolutionSemaphore.drainPermits(); typeResolutionPhaser.awaitAdvance(typeResolutionPhaser.arriveAndDeregister()); diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/NonOpSelfDiagnosticRunner.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/NonOpSelfDiagnosticRunner.java index 2320aff0c979..47aa4d078c60 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/NonOpSelfDiagnosticRunner.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/NonOpSelfDiagnosticRunner.java @@ -28,4 +28,9 @@ public void registerAbruptTypeResolutionEnd(Context cx, Exception ex) { public void registerAbruptTypeCheckEnd(Context cx, Exception ex) { } + + @Override + public void registerTypeResolutionExit(Context cx) { + + } } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/TypeCheckSelfDiagnosticsRunner.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/TypeCheckSelfDiagnosticsRunner.java index 2bd1afa91a61..aa3b65bc80f4 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/TypeCheckSelfDiagnosticsRunner.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/semtype/TypeCheckSelfDiagnosticsRunner.java @@ -13,4 +13,6 @@ interface TypeCheckSelfDiagnosticsRunner { void registerAbruptTypeResolutionEnd(Context cx, Exception ex); void registerAbruptTypeCheckEnd(Context cx, Exception ex); + + void registerTypeResolutionExit(Context cx); } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeChecker.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeChecker.java index ca706f2e484e..52f83f58846f 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeChecker.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeChecker.java @@ -822,6 +822,7 @@ public static boolean isEqual(Object lhsValue, Object rhsValue, Set c private static boolean checkValueEqual(Context cx, Object lhsValue, Object rhsValue, Set checkedValues) { SemType lhsShape = ShapeAnalyzer.inherentTypeOf(cx, lhsValue).orElseThrow(); SemType rhsShape = ShapeAnalyzer.inherentTypeOf(cx, rhsValue).orElseThrow(); + cx.exitTypeResolutionPhase(); Predicate belongToSameBasicType = (basicType) -> Core.containsBasicType(lhsShape, basicType) && Core.containsBasicType(rhsShape, basicType); if (belongToSameBasicType.test(Builder.getStringType()) ||