Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ private boolean verifyFieldValue(JavaConstant receiver, AnalysisField field, Jav
verifyStaticFieldValue(typeData, field, fieldSnapshot, fieldValue, reason);
} else {
ImageHeapInstance receiverObject = (ImageHeapInstance) getSnapshot(receiver, reason);
if (receiverObject == null || (receiverObject.isInBaseLayer() && !bb.getUniverse().getImageLayerLoader().getRelinkedFields(receiverObject.getType()).contains(field.getPosition()))) {
if (receiverObject == null || (receiverObject.isInSharedLayer() && !bb.getUniverse().getImageLayerLoader().getRelinkedFields(receiverObject.getType()).contains(field.getPosition()))) {
return false;
}
JavaConstant fieldSnapshot = receiverObject.readFieldValue(field);
Expand All @@ -211,7 +211,7 @@ private void verifyStaticFieldValue(TypeData typeData, AnalysisField field, Java
}

private void verifyInstanceFieldValue(AnalysisField field, JavaConstant receiver, ImageHeapInstance receiverObject, JavaConstant fieldSnapshot, JavaConstant fieldValue, ScanReason reason) {
if (fieldSnapshot instanceof ImageHeapConstant ihc && ihc.isInBaseLayer() && ihc.getHostedObject() == null && !(ihc instanceof ImageHeapRelocatableConstant)) {
if (fieldSnapshot instanceof ImageHeapConstant ihc && ihc.isInSharedLayer() && ihc.getHostedObject() == null && !(ihc instanceof ImageHeapRelocatableConstant)) {
/*
* We cannot verify a base layer constant which doesn't have a backing hosted
* object. Since the hosted object is missing the constant would be replaced with
Expand Down Expand Up @@ -268,7 +268,7 @@ private boolean verifyArrayElementValue(JavaConstant elementValue, int index, Sc
* the future, then compare the produced value.
*/
JavaConstant elementSnapshot = arrayObject.readElementValue(index);
if (elementSnapshot instanceof ImageHeapConstant ihc && ihc.isInBaseLayer() && ihc.getHostedObject() == null) {
if (elementSnapshot instanceof ImageHeapConstant ihc && ihc.isInSharedLayer() && ihc.getHostedObject() == null) {
/*
* We cannot verify a base layer constant which doesn't have a backing hosted
* object. Since the hosted object is missing the constant would be replaced with
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public Object getSnapshot(JavaConstant constant) {
* A base layer constant was in the objectsCache from the base image. It might not have
* been put in the objectsCache of the extension image yet.
*/
assert imageHeapConstant.getHostedObject() == null || imageHeapConstant.isInBaseLayer() || objectsCache.get(imageHeapConstant.getHostedObject()).equals(imageHeapConstant);
assert imageHeapConstant.getHostedObject() == null || imageHeapConstant.isInSharedLayer() || objectsCache.get(imageHeapConstant.getHostedObject()).equals(imageHeapConstant);
return imageHeapConstant;
}
return objectsCache.get(uncompressed);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,12 @@ abstract static class ConstantData {
*/
@SuppressWarnings("unused") private volatile Object isReachable;
/**
* A boolean allowing to distinguish a constant that was persisted from a base layer and a
* A boolean allowing to distinguish a constant that was persisted from a shared layer and a
* constant created in the current layer.
*/
private boolean isInBaseLayer;
private boolean isInSharedLayer;
/**
* A boolean telling if the constant was written in the image heap of the base layer.
* A boolean telling if the constant was written in the image heap of the shared layer.
*/
private boolean writtenInPreviousLayer;
/**
Expand Down Expand Up @@ -209,16 +209,16 @@ public int getIdentityHashCode() {
return constantData.identityHashCode;
}

public void markInBaseLayer() {
constantData.isInBaseLayer = true;
public void markInSharedLayer() {
constantData.isInSharedLayer = true;
}

public boolean isInBaseLayer() {
return constantData.isInBaseLayer;
public boolean isInSharedLayer() {
return constantData.isInSharedLayer;
}

public void markWrittenInPreviousLayer() {
AnalysisError.guarantee(isInBaseLayer(), "Constant must be in base layer to be marked as written in the base layer.");
AnalysisError.guarantee(isInSharedLayer(), "Constant must be in base layer to be marked as written in the base layer.");
constantData.writtenInPreviousLayer = true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public void setFieldValue(AnalysisField field, JavaConstant value) {
* or the result of executing the task, i.e., a {@link JavaConstant}.
*/
public Object getFieldValue(AnalysisField field) {
if (isInBaseLayer()) {
if (isInSharedLayer()) {
/* Base layer constants that are not relinked might not have field positions computed */
field.getType().getInstanceFields(true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ public void rescanField(Object receiver, AnalysisField field, ScanReason reason)
JavaConstant fieldSnapshot = receiverObject.readFieldValue(field);
JavaConstant unwrappedSnapshot = ScanningObserver.maybeUnwrapSnapshot(fieldSnapshot, fieldValue instanceof ImageHeapConstant);

if (fieldSnapshot instanceof ImageHeapConstant ihc && ihc.isInBaseLayer() && ihc.getHostedObject() == null) {
if (fieldSnapshot instanceof ImageHeapConstant ihc && ihc.isInSharedLayer() && ihc.getHostedObject() == null) {
/*
* We cannot verify a base layer constant which doesn't have a backing
* hosted object. Since the hosted object is missing the constant would be
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,13 @@ public abstract class AnalysisField extends AnalysisElement implements WrappedJa

private static final AtomicReferenceFieldUpdater<AnalysisField, Object> isUnsafeAccessedUpdater = AtomicReferenceFieldUpdater
.newUpdater(AnalysisField.class, Object.class, "isUnsafeAccessed");
/**
* Unique id assigned to each {@link AnalysisField}. This id is consistent across layers and can
* be used to load or match a field in an extension layer.
*/
private final int id;
/** Marks a field loaded from a base layer. */
private final boolean isInBaseLayer;
/** Marks a field loaded from a shared layer. */
private final boolean isInSharedLayer;

public final ResolvedJavaField wrapped;

Expand All @@ -81,7 +85,10 @@ public abstract class AnalysisField extends AnalysisElement implements WrappedJa
private ConcurrentMap<Object, Boolean> readBy;
private ConcurrentMap<Object, Boolean> writtenBy;

/** Field's position in the list of declaring type's fields, including inherited fields. */
/**
* Field's position in the list of declaring type's fields, including inherited fields. The
* position needs to be consistent across layers.
*/
protected int position;

protected final AnalysisType declaringClass;
Expand Down Expand Up @@ -117,22 +124,22 @@ public AnalysisField(AnalysisUniverse universe, ResolvedJavaField wrappedField)
declaringClass = universe.lookup(wrappedField.getDeclaringClass());
fieldType = getDeclaredType(universe, wrappedField);

if (universe.hostVM().buildingExtensionLayer() && declaringClass.isInBaseLayer()) {
if (universe.hostVM().buildingExtensionLayer() && declaringClass.isInSharedLayer()) {
int fid = universe.getImageLayerLoader().lookupHostedFieldInBaseLayer(this);
if (fid != -1) {
/*
* This id is the actual link between the corresponding field from the base layer
* This id is the actual link between the corresponding field from the shared layer
* and this new field.
*/
id = fid;
isInBaseLayer = true;
isInSharedLayer = true;
} else {
id = universe.computeNextFieldId();
isInBaseLayer = false;
isInSharedLayer = false;
}
} else {
id = universe.computeNextFieldId();
isInBaseLayer = false;
isInSharedLayer = false;
}
isLayeredStaticField = isStatic() && universe.hostVM.buildingImageLayer();
}
Expand Down Expand Up @@ -167,8 +174,8 @@ public int getId() {
return id;
}

public boolean isInBaseLayer() {
return isInBaseLayer;
public boolean isInSharedLayer() {
return isInSharedLayer;
}

public boolean installableInLayer() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,16 @@ public record Signature(String name, AnalysisType[] parameterTypes) {

public final ResolvedJavaMethod wrapped;

/**
* Unique id assigned to each {@link AnalysisMethod}. This id is consistent across layers and
* can be used to load or match a method in an extension layer.
*/
private final int id;
/** True when the current layer built is a shared layer. */
private final boolean buildingSharedLayer;
/** Marks a method loaded from a base layer. */
private final boolean isInBaseLayer;
/** Marks a method loaded from a shared layer. */
private final boolean isInSharedLayer;
/** Marks a method analyzed in a prior layer. */
private final boolean analyzedInPriorLayer;
private final boolean hasNeverInlineDirective;
private final ExceptionHandler[] exceptionHandlers;
Expand Down Expand Up @@ -228,24 +234,24 @@ protected AnalysisMethod(AnalysisUniverse universe, ResolvedJavaMethod wrapped,
modifiers = wrapped.getModifiers();

buildingSharedLayer = hostVM.buildingSharedLayer();
if (hostVM.buildingExtensionLayer() && declaringClass.isInBaseLayer()) {
if (hostVM.buildingExtensionLayer() && declaringClass.isInSharedLayer()) {
int mid = universe.getImageLayerLoader().lookupHostedMethodInBaseLayer(this);
if (mid != -1) {
/*
* This id is the actual link between the corresponding method from the base layer
* This id is the actual link between the corresponding method from the shared layer
* and this new method.
*/
id = mid;
isInBaseLayer = true;
isInSharedLayer = true;
} else {
id = universe.computeNextMethodId();
isInBaseLayer = false;
isInSharedLayer = false;
}
} else {
id = universe.computeNextMethodId();
isInBaseLayer = false;
isInSharedLayer = false;
}
analyzedInPriorLayer = isInBaseLayer && hostVM.analyzedInPriorLayer(this);
analyzedInPriorLayer = isInSharedLayer && hostVM.analyzedInPriorLayer(this);

ExceptionHandler[] original = wrapped.getExceptionHandlers();
exceptionHandlers = new ExceptionHandler[original.length];
Expand Down Expand Up @@ -288,7 +294,7 @@ protected AnalysisMethod(AnalysisUniverse universe, ResolvedJavaMethod wrapped,
LayeredCompilationBehavior behavior = AnnotationUtil.getAnnotation(wrapped, LayeredCompilationBehavior.class);
if (behavior != null) {
compilationBehavior = behavior.value();
if (compilationBehavior == LayeredCompilationBehavior.Behavior.PINNED_TO_INITIAL_LAYER && universe.hostVM.buildingExtensionLayer() && !isInBaseLayer) {
if (compilationBehavior == LayeredCompilationBehavior.Behavior.PINNED_TO_INITIAL_LAYER && universe.hostVM.buildingExtensionLayer() && !isInSharedLayer) {
var errorMessage = String.format("User methods with layered compilation behavior %s must be registered via %s in the initial layer",
LayeredCompilationBehavior.Behavior.PINNED_TO_INITIAL_LAYER, LayeredCompilationSupport.class);
throw AnalysisError.userError(errorMessage);
Expand All @@ -303,7 +309,7 @@ protected AnalysisMethod(AnalysisMethod original, MultiMethodKey multiMethodKey)
wrapped = original.wrapped;
id = original.id;
buildingSharedLayer = original.buildingSharedLayer;
isInBaseLayer = original.isInBaseLayer;
isInSharedLayer = original.isInSharedLayer;
analyzedInPriorLayer = original.analyzedInPriorLayer;
declaringClass = original.declaringClass;
signature = original.signature;
Expand Down Expand Up @@ -338,7 +344,7 @@ public void setCompilationBehavior(LayeredCompilationBehavior.Behavior compilati
}

private void setNewCompilationBehavior(LayeredCompilationBehavior.Behavior compilationBehavior) {
assert (!isInBaseLayer && this.compilationBehavior == LayeredCompilationBehavior.Behavior.DEFAULT) || this.compilationBehavior == compilationBehavior : "The method was already assigned " +
assert (!isInSharedLayer && this.compilationBehavior == LayeredCompilationBehavior.Behavior.DEFAULT) || this.compilationBehavior == compilationBehavior : "The method was already assigned " +
this.compilationBehavior + ", but trying to assign " + compilationBehavior;
setCompilationBehavior(compilationBehavior);
}
Expand Down Expand Up @@ -480,8 +486,8 @@ public int getId() {
return id;
}

public boolean isInBaseLayer() {
return isInBaseLayer;
public boolean isInSharedLayer() {
return isInSharedLayer;
}

public boolean analyzedInPriorLayer() {
Expand Down Expand Up @@ -1169,7 +1175,7 @@ private AnalysisParsedGraph ensureGraphParsedHelper(BigBang bb, Stage stage, boo

if (curState.isUnparsed(stage) || (forceReparse && curState.isStageParsed(stage))) {
AnalysisParsedGraph graph;
if (isInBaseLayer && getUniverse().getImageLayerLoader().hasAnalysisParsedGraph(this)) {
if (isInSharedLayer && getUniverse().getImageLayerLoader().hasAnalysisParsedGraph(this)) {
graph = getBaseLayerGraph(bb, curState);
} else {
graph = createAnalysisParsedGraph(bb, stage, curState, forceReparse);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,13 @@ public abstract class AnalysisType extends AnalysisElement implements WrappedJav
@SuppressWarnings("unused") private volatile Object subTypes;
AnalysisType superClass;

/**
* Unique id assigned to each {@link AnalysisType}. This id is consistent across layers and can
* be used to load or match a type in an extension layer.
*/
private final int id;
/** Marks a type loaded from a base layer. */
private final boolean isInBaseLayer;
/** Marks a type loaded from a shared layer. */
private final boolean isInSharedLayer;

private final JavaKind storageKind;
private final boolean isCloneableWithAllocation;
Expand Down Expand Up @@ -302,24 +306,24 @@ public AnalysisType(AnalysisUniverse universe, ResolvedJavaType javaType, JavaKi
int tid = universe.getImageLayerLoader().lookupHostedTypeInBaseLayer(this);
if (tid != -1) {
/*
* This id is the actual link between the corresponding type from the base layer and
* this new type.
* This id is the actual link between the corresponding type from the shared layer
* and this new type.
*/
this.id = tid;
this.isInBaseLayer = true;
this.isInSharedLayer = true;
} else {
this.id = universe.computeNextTypeId();
/*
* If both the BaseLayerType and the complete type are created at the same time,
* there can be a race for the base layer id. It is possible that the complete type
* gets the base layer id even though the BaseLayerType is created. In this case,
* the AnalysisType should still be marked as isInBaseLayer.
* there can be a race for the shared layer id. It is possible that the complete
* type gets the shared layer id even though the BaseLayerType is created. In this
* case, the AnalysisType should still be marked as isInSharedLayer.
*/
this.isInBaseLayer = wrapped instanceof BaseLayerType;
this.isInSharedLayer = wrapped instanceof BaseLayerType;
}
} else {
this.id = universe.computeNextTypeId();
this.isInBaseLayer = false;
this.isInSharedLayer = false;
}

/*
Expand Down Expand Up @@ -398,8 +402,8 @@ public int getId() {
return id;
}

public boolean isInBaseLayer() {
return isInBaseLayer;
public boolean isInSharedLayer() {
return isInSharedLayer;
}

public AnalysisObject getContextInsensitiveAnalysisObject() {
Expand Down Expand Up @@ -595,7 +599,7 @@ protected void onReachable(Object reason) {
scheduledTypeReachableNotifications = futures;
}

if (isInBaseLayer && !(wrapped instanceof BaseLayerType)) {
if (isInSharedLayer && !(wrapped instanceof BaseLayerType)) {
/*
* Since the analysis of the type is skipped, the fields have to be created manually to
* ensure their flags are loaded from the base layer. Not creating the fields would
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ public JavaType lookupAllowUnresolved(JavaType rawType) {
AnalysisType result = optionalLookup(type);
if (result == null) {
result = createType(type);
if (hostVM.buildingExtensionLayer() && result.isInBaseLayer()) {
if (hostVM.buildingExtensionLayer() && result.isInSharedLayer()) {
imageLayerLoader.initializeBaseLayerType(result);
}
}
Expand Down Expand Up @@ -387,14 +387,14 @@ private AnalysisField createField(ResolvedJavaField field) {
}
AnalysisField newValue = analysisFactory.createField(this, field);
AnalysisField result = fields.computeIfAbsent(field, f -> {
if (newValue.isInBaseLayer()) {
if (newValue.isInSharedLayer()) {
getImageLayerLoader().addBaseLayerField(newValue);
}
return newValue;
});

if (result.equals(newValue)) {
if (newValue.isInBaseLayer()) {
if (newValue.isInSharedLayer()) {
getImageLayerLoader().initializeBaseLayerField(newValue);
}
}
Expand Down Expand Up @@ -441,7 +441,7 @@ private AnalysisMethod createMethod(ResolvedJavaMethod method) {
}
AnalysisMethod newValue = analysisFactory.createMethod(this, method);
AnalysisMethod result = methods.computeIfAbsent(method, m -> {
if (newValue.isInBaseLayer()) {
if (newValue.isInSharedLayer()) {
getImageLayerLoader().addBaseLayerMethod(newValue);
}
return newValue;
Expand Down
Loading