Skip to content

Commit ba20083

Browse files
Only save initialization exceptions, not linking ones
1 parent 675d148 commit ba20083

File tree

3 files changed

+87
-50
lines changed

3 files changed

+87
-50
lines changed

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/ObjectKlass.java

Lines changed: 30 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ public final class ObjectKlass extends Klass {
133133
private volatile int initState = LOADED;
134134

135135
@CompilationFinal //
136-
private EspressoException linkError;
136+
private StaticObject initializationError;
137137

138138
@CompilationFinal volatile KlassVersion klassVersion;
139139

@@ -159,14 +159,13 @@ public final class ObjectKlass extends Klass {
159159
public static final int LOADED = 0;
160160
public static final int LINKING = 1;
161161
public static final int VERIFYING = 2;
162-
public static final int FAILED_LINK = 3;
163-
public static final int VERIFIED = 4;
164-
public static final int PREPARED = 5;
165-
public static final int LINKED = 6;
166-
public static final int INITIALIZING = 7;
162+
public static final int VERIFIED = 3;
163+
public static final int PREPARED = 4;
164+
public static final int LINKED = 5;
165+
public static final int INITIALIZING = 6;
167166
// Can be erroneous only if initialization triggered !
168-
public static final int ERRONEOUS = 8;
169-
public static final int INITIALIZED = 9;
167+
public static final int ERRONEOUS = 7;
168+
public static final int INITIALIZED = 8;
170169

171170
private final StaticObject definingClassLoader;
172171

@@ -361,8 +360,10 @@ boolean isInitializedImpl() {
361360
return initState >= INITIALIZED;
362361
}
363362

364-
private void setErroneousInitialization() {
363+
private void setErroneousInitialization(StaticObject exception) {
364+
assert exception != null;
365365
initState = ERRONEOUS;
366+
initializationError = exception;
366367
}
367368

368369
boolean isErroneous() {
@@ -377,8 +378,13 @@ private void checkErroneousInitialization() {
377378

378379
@TruffleBoundary
379380
private EspressoException throwNoClassDefFoundError() {
381+
assert isErroneous();
380382
Meta meta = getMeta();
381-
throw meta.throwExceptionWithMessage(meta.java_lang_NoClassDefFoundError, "Erroneous class: " + getName());
383+
if (StaticObject.isNull(initializationError)) {
384+
throw meta.throwExceptionWithMessage(meta.java_lang_NoClassDefFoundError, "Could not initialize class: " + getExternalName());
385+
} else {
386+
throw meta.throwException(meta.java_lang_NoClassDefFoundError, "Could not initialize class: " + getExternalName(), initializationError);
387+
}
382388
}
383389

384390
@TruffleBoundary
@@ -426,15 +432,15 @@ private void actualInit() {
426432
clinit.invokeDirectStatic();
427433
}
428434
} catch (EspressoException e) {
429-
setErroneousInitialization();
435+
setErroneousInitialization(e.getGuestException());
430436
throw initializationFailed(e);
431437
} catch (AbstractTruffleException e) {
432-
setErroneousInitialization();
438+
setErroneousInitialization(StaticObject.NULL);
433439
throw e;
434440
} catch (Throwable e) {
435441
getContext().getLogger().log(Level.WARNING, "Host exception during class initialization: {0}", this.getNameAsString());
436442
e.printStackTrace();
437-
setErroneousInitialization();
443+
setErroneousInitialization(StaticObject.NULL);
438444
throw e;
439445
}
440446
checkErroneousInitialization();
@@ -566,7 +572,6 @@ private void checkLoadingConstraints() {
566572
@Override
567573
public void ensureLinked() {
568574
if (!isLinked()) {
569-
checkErroneousLink();
570575
if (CompilerDirectives.isCompilationConstant(this)) {
571576
CompilerDirectives.transferToInterpreterAndInvalidate();
572577
}
@@ -579,6 +584,7 @@ private void doLink() {
579584
getInitLock().lock();
580585
try {
581586
if (!isLinkingOrLinked()) {
587+
int initialState = initState;
582588
initState = LINKING;
583589
try {
584590
if (getSuperKlass() != null) {
@@ -587,23 +593,17 @@ private void doLink() {
587593
for (ObjectKlass interf : getSuperInterfaces()) {
588594
interf.ensureLinked();
589595
}
590-
} catch (EspressoException e) {
591-
setErroneousLink(e);
592-
throw e;
593-
}
594-
verify();
595-
try {
596+
verify();
596597
prepare();
597-
} catch (EspressoException e) {
598-
setErroneousLink(e);
599-
throw e;
598+
initState = LINKED;
599+
} catch (Throwable t) {
600+
initState = initialState;
601+
throw t;
600602
}
601-
initState = LINKED;
602603
}
603604
} finally {
604605
getInitLock().unlock();
605606
}
606-
checkErroneousLink();
607607
}
608608

609609
void initializeImpl() {
@@ -615,7 +615,6 @@ void initializeImpl() {
615615

616616
@HostCompilerDirectives.InliningCutoff
617617
private void doInitialize() {
618-
checkErroneousLink();
619618
checkErroneousInitialization();
620619
if (CompilerDirectives.isCompilationConstant(this)) {
621620
CompilerDirectives.transferToInterpreterAndInvalidate();
@@ -647,37 +646,25 @@ boolean isVerified() {
647646
return initState >= VERIFIED;
648647
}
649648

650-
private void checkErroneousLink() {
651-
if (initState == FAILED_LINK) {
652-
throw linkError;
653-
}
654-
}
655-
656-
private void setErroneousLink(EspressoException e) {
657-
initState = FAILED_LINK;
658-
linkError = e;
659-
}
660-
661649
private void verify() {
662650
if (!isVerified()) {
663-
checkErroneousLink();
664651
getInitLock().lock();
665652
try {
666653
if (!isVerifyingOrVerified()) {
667654
CompilerDirectives.transferToInterpreterAndInvalidate();
655+
int initialState = initState;
668656
initState = VERIFYING;
669657
try {
670658
verifyImpl();
671-
} catch (EspressoException e) {
672-
setErroneousLink(e);
673-
throw e;
659+
initState = VERIFIED;
660+
} catch (Throwable t) {
661+
initState = initialState;
662+
throw t;
674663
}
675-
initState = VERIFIED;
676664
}
677665
} finally {
678666
getInitLock().unlock();
679667
}
680-
checkErroneousLink();
681668
}
682669
}
683670

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/meta/ExceptionDispatch.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,21 @@ private void slowInitEx(StaticObject ex, ObjectKlass klass, StaticObject message
108108
} else {
109109
assert StaticObject.isNull(cause) || meta.java_lang_Throwable.isAssignableFrom(cause.getKlass());
110110
assert StaticObject.isNull(message) || meta.java_lang_String.isAssignableFrom(message.getKlass());
111-
doFullInit(ex, klass, message, cause);
111+
if (!doFullInit(ex, klass, message, cause)) {
112+
doMessageInit(ex, klass, message);
113+
meta.java_lang_Throwable_initCause.invokeDirectVirtual(ex, cause);
114+
}
112115
}
113116
}
114117

115118
@CompilerDirectives.TruffleBoundary
116-
private static void doFullInit(StaticObject ex, ObjectKlass klass, StaticObject message, StaticObject cause) {
119+
private static boolean doFullInit(StaticObject ex, ObjectKlass klass, StaticObject message, StaticObject cause) {
117120
Method method = klass.lookupDeclaredMethod(Names._init_, Signatures._void_String_Throwable);
118-
assert method != null : "No (String, Throwable) constructor in " + klass;
121+
if (method == null) {
122+
return false;
123+
}
119124
method.invokeDirectSpecial(ex, message, cause);
125+
return true;
120126
}
121127

122128
@CompilerDirectives.TruffleBoundary

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/meta/Meta.java

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2638,7 +2638,7 @@ public static StaticObject box(Meta meta, Object arg) {
26382638
* @param exceptionKlass guest exception class, subclass of guest {@link #java_lang_Throwable
26392639
* Throwable}.
26402640
*/
2641-
public @JavaType(Throwable.class) static StaticObject initExceptionWithMessage(@JavaType(Throwable.class) ObjectKlass exceptionKlass, @JavaType(String.class) StaticObject message) {
2641+
public static @JavaType(Throwable.class) StaticObject initExceptionWithMessage(ObjectKlass exceptionKlass, @JavaType(String.class) StaticObject message) {
26422642
assert exceptionKlass.getMeta().java_lang_Throwable.isAssignableFrom(exceptionKlass);
26432643
assert StaticObject.isNull(message) || exceptionKlass.getMeta().java_lang_String.isAssignableFrom(message.getKlass());
26442644
return exceptionKlass.getMeta().dispatch.initEx(exceptionKlass, message, null);
@@ -2655,7 +2655,7 @@ public static StaticObject box(Meta meta, Object arg) {
26552655
* @param exceptionKlass guest exception class, subclass of guest {@link #java_lang_Throwable
26562656
* Throwable}.
26572657
*/
2658-
public @JavaType(Throwable.class) static StaticObject initExceptionWithMessage(@JavaType(Throwable.class) ObjectKlass exceptionKlass, String message) {
2658+
public static @JavaType(Throwable.class) StaticObject initExceptionWithMessage(ObjectKlass exceptionKlass, String message) {
26592659
return initExceptionWithMessage(exceptionKlass, exceptionKlass.getMeta().toGuestString(message));
26602660
}
26612661

@@ -2669,7 +2669,7 @@ public static StaticObject box(Meta meta, Object arg) {
26692669
* @param exceptionKlass guest exception class, subclass of guest {@link #java_lang_Throwable
26702670
* Throwable}.
26712671
*/
2672-
public @JavaType(Throwable.class) static StaticObject initException(@JavaType(Throwable.class) ObjectKlass exceptionKlass) {
2672+
public static @JavaType(Throwable.class) StaticObject initException(ObjectKlass exceptionKlass) {
26732673
assert exceptionKlass.getMeta().java_lang_Throwable.isAssignableFrom(exceptionKlass);
26742674
return exceptionKlass.getMeta().dispatch.initEx(exceptionKlass, null, null);
26752675
}
@@ -2685,12 +2685,30 @@ public static StaticObject box(Meta meta, Object arg) {
26852685
* @param exceptionKlass guest exception class, subclass of guest {@link #java_lang_Throwable
26862686
* Throwable}.
26872687
*/
2688-
public @JavaType(Throwable.class) static StaticObject initExceptionWithCause(@JavaType(Throwable.class) ObjectKlass exceptionKlass, @JavaType(Throwable.class) StaticObject cause) {
2688+
public static @JavaType(Throwable.class) StaticObject initExceptionWithCause(ObjectKlass exceptionKlass, @JavaType(Throwable.class) StaticObject cause) {
26892689
assert exceptionKlass.getMeta().java_lang_Throwable.isAssignableFrom(exceptionKlass);
26902690
assert StaticObject.isNull(cause) || exceptionKlass.getMeta().java_lang_Throwable.isAssignableFrom(cause.getKlass());
26912691
return exceptionKlass.getMeta().dispatch.initEx(exceptionKlass, null, cause);
26922692
}
26932693

2694+
/**
2695+
* Allocate and initializes an exception of the given guest klass.
2696+
*
2697+
* <p>
2698+
* A guest instance is allocated and initialized by calling the
2699+
* {@link Throwable#Throwable(String, Throwable) constructor with message and cause}. The given
2700+
* guest class must have such constructor declared.
2701+
*
2702+
* @param exceptionKlass guest exception class, subclass of guest {@link #java_lang_Throwable
2703+
* Throwable}.
2704+
*/
2705+
public static @JavaType(Throwable.class) StaticObject initException(ObjectKlass exceptionKlass, @JavaType(String.class) StaticObject message, @JavaType(Throwable.class) StaticObject cause) {
2706+
assert exceptionKlass.getMeta().java_lang_Throwable.isAssignableFrom(exceptionKlass);
2707+
assert StaticObject.isNull(cause) || exceptionKlass.getMeta().java_lang_Throwable.isAssignableFrom(cause.getKlass());
2708+
assert StaticObject.isNull(message) || exceptionKlass.getMeta().java_lang_String.isAssignableFrom(message.getKlass());
2709+
return exceptionKlass.getMeta().dispatch.initEx(exceptionKlass, message, cause);
2710+
}
2711+
26942712
/**
26952713
* Initializes and throws an exception of the given guest klass.
26962714
*
@@ -2784,6 +2802,32 @@ public EspressoException throwExceptionWithCause(@JavaType(Throwable.class) Obje
27842802
throw throwException(initExceptionWithCause(exceptionKlass, cause));
27852803
}
27862804

2805+
/**
2806+
* Initializes and throws an exception of the given guest klass. A guest instance is allocated
2807+
* and initialized by calling the {@link Throwable#Throwable(String, Throwable) constructor with
2808+
* cause}. The given guest class must have such constructor declared.
2809+
*
2810+
* @param exceptionKlass guest exception class, subclass of guest {@link #java_lang_Throwable
2811+
* Throwable}.
2812+
*/
2813+
@HostCompilerDirectives.InliningCutoff
2814+
public EspressoException throwException(@JavaType(Throwable.class) ObjectKlass exceptionKlass, @JavaType(String.class) StaticObject message, @JavaType(Throwable.class) StaticObject cause) {
2815+
throw throwException(initException(exceptionKlass, message, cause));
2816+
}
2817+
2818+
/**
2819+
* Initializes and throws an exception of the given guest klass. A guest instance is allocated
2820+
* and initialized by calling the {@link Throwable#Throwable(String, Throwable) constructor with
2821+
* cause}. The given guest class must have such constructor declared.
2822+
*
2823+
* @param exceptionKlass guest exception class, subclass of guest {@link #java_lang_Throwable
2824+
* Throwable}.
2825+
*/
2826+
@HostCompilerDirectives.InliningCutoff
2827+
public EspressoException throwException(@JavaType(Throwable.class) ObjectKlass exceptionKlass, String message, @JavaType(Throwable.class) StaticObject cause) {
2828+
throw throwException(initException(exceptionKlass, exceptionKlass.getMeta().toGuestString(message), cause));
2829+
}
2830+
27872831
/**
27882832
* Throws a guest {@link NullPointerException}. A guest instance is allocated and initialized by
27892833
* calling the {@link NullPointerException#NullPointerException() default constructor}.

0 commit comments

Comments
 (0)