Skip to content

Commit

Permalink
[GR-60479] Improve linking process.
Browse files Browse the repository at this point in the history
PullRequest: graal/19607
  • Loading branch information
gilles-duboscq committed Dec 18, 2024
2 parents 9ae3aa8 + d8b4280 commit 827906d
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1821,6 +1821,18 @@ private ParserField parseField(boolean isInterface) throws ValidationException {
if (constantValue.getConstantValueIndex() == 0) {
throw classFormatError("Invalid ConstantValue index");
}
PoolConstant entry = pool.at(constantValue.getConstantValueIndex(), "constant value index");
boolean isValid = switch (entry.tag()) {
case INTEGER -> Types.getJavaKind(descriptor).isStackInt();
case FLOAT -> descriptor == Type._float;
case LONG -> descriptor == Type._long;
case DOUBLE -> descriptor == Type._double;
case STRING -> descriptor == Type.java_lang_String;
default -> false;
};
if (!isValid) {
throw classFormatError("Invalid ConstantValue index entry type");
}
} else if (attributeName.equals(Name.Synthetic)) {
fieldFlags |= ACC_SYNTHETIC;
fieldAttributes[i] = new Attribute(attributeName, null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ public final class ObjectKlass extends Klass {
@CompilationFinal //
private volatile int initState = LOADED;

@CompilationFinal //
private EspressoException linkError;

@CompilationFinal volatile KlassVersion klassVersion;

// instance and hidden fields declared in this class and in its super classes
Expand All @@ -156,12 +159,15 @@ public final class ObjectKlass extends Klass {

public static final int LOADED = 0;
public static final int LINKING = 1;
public static final int PREPARED = 2;
public static final int LINKED = 3;
public static final int VERIFYING = 2;
public static final int FAILED_LINK = 3;
public static final int VERIFIED = 4;
public static final int PREPARED = 5;
public static final int LINKED = 6;
public static final int INITIALIZING = 7;
// Can be erroneous only if initialization triggered !
public static final int ERRONEOUS = 4;
public static final int INITIALIZING = 5;
public static final int INITIALIZED = 6;
public static final int ERRONEOUS = 8;
public static final int INITIALIZED = 9;

private final StaticObject definingClassLoader;

Expand Down Expand Up @@ -378,7 +384,7 @@ boolean isInitializingOrInitializedImpl() {
* case, if the state is INITIALIZING we cannot really check the lock because an object
* might have been leaked to another thread by the clinit.
*/
return initState >= ERRONEOUS;
return initState >= INITIALIZING;
}

boolean isInitializedImpl() {
Expand Down Expand Up @@ -418,6 +424,12 @@ private void actualInit() {
initState = INITIALIZING;
getContext().getLogger().log(Level.FINEST, "Initializing: {0}", this.getNameAsString());

for (Field f : getInitialStaticFields()) {
if (!f.isRemoved()) {
initField(f);
}
}

var tls = getContext().getLanguage().getThreadLocalState();
tls.blockContinuationSuspension();
try {
Expand Down Expand Up @@ -477,11 +489,6 @@ private void prepare() {
try {
if (!isPrepared()) {
checkLoadingConstraints();
for (Field f : getInitialStaticFields()) {
if (!f.isRemoved()) {
initField(f);
}
}
initState = PREPARED;
if (getContext().isMainThreadCreated()) {
if (getContext().shouldReportVMEvents()) {
Expand Down Expand Up @@ -593,7 +600,7 @@ private void checkLoadingConstraints() {
@Override
public void ensureLinked() {
if (!isLinked()) {
checkErroneousVerification();
checkErroneousLink();
if (CompilerDirectives.isCompilationConstant(this)) {
CompilerDirectives.transferToInterpreterAndInvalidate();
}
Expand All @@ -607,20 +614,30 @@ private void doLink() {
try {
if (!isLinkingOrLinked()) {
initState = LINKING;
if (getSuperKlass() != null) {
getSuperKlass().ensureLinked();
}
for (ObjectKlass interf : getSuperInterfaces()) {
interf.ensureLinked();
try {
if (getSuperKlass() != null) {
getSuperKlass().ensureLinked();
}
for (ObjectKlass interf : getSuperInterfaces()) {
interf.ensureLinked();
}
} catch (EspressoException e) {
setErroneousLink(e);
throw e;
}
prepare();
verify();
try {
prepare();
} catch (EspressoException e) {
setErroneousLink(e);
throw e;
}
initState = LINKED;
}
} finally {
getInitLock().unlock();
}
checkErroneousVerification();
checkErroneousLink();
}

void initializeImpl() {
Expand All @@ -632,7 +649,7 @@ void initializeImpl() {

@HostCompilerDirectives.InliningCutoff
private void doInitialize() {
checkErroneousVerification();
checkErroneousLink();
checkErroneousInitialization();
if (CompilerDirectives.isCompilationConstant(this)) {
CompilerDirectives.transferToInterpreterAndInvalidate();
Expand All @@ -656,60 +673,45 @@ private void recursiveInitialize() {

// region Verification

@CompilationFinal //
private volatile int verificationStatus = UNVERIFIED;

@CompilationFinal //
private EspressoException verificationError = null;

private static final int FAILED_VERIFICATION = -1;
private static final int UNVERIFIED = 0;
private static final int VERIFYING = 1;
private static final int VERIFIED = 2;

private void setVerificationStatus(int status) {
verificationStatus = status;
}

private boolean isVerifyingOrVerified() {
return verificationStatus >= VERIFYING;
return initState >= VERIFYING;
}

boolean isVerified() {
return verificationStatus >= VERIFIED;
return initState >= VERIFIED;
}

private void checkErroneousVerification() {
if (verificationStatus == FAILED_VERIFICATION) {
throw verificationError;
private void checkErroneousLink() {
if (initState == FAILED_LINK) {
throw linkError;
}
}

private void setErroneousVerification(EspressoException e) {
verificationStatus = FAILED_VERIFICATION;
verificationError = e;
private void setErroneousLink(EspressoException e) {
initState = FAILED_LINK;
linkError = e;
}

private void verify() {
if (!isVerified()) {
checkErroneousVerification();
checkErroneousLink();
getInitLock().lock();
try {
if (!isVerifyingOrVerified()) {
CompilerDirectives.transferToInterpreterAndInvalidate();
setVerificationStatus(VERIFYING);
initState = VERIFYING;
try {
verifyImpl();
} catch (EspressoException e) {
setErroneousVerification(e);
setErroneousLink(e);
throw e;
}
setVerificationStatus(VERIFIED);
initState = VERIFIED;
}
} finally {
getInitLock().unlock();
}
checkErroneousVerification();
checkErroneousLink();
}
}

Expand Down

0 comments on commit 827906d

Please sign in to comment.