Skip to content

Commit

Permalink
Improve the specialization logic for field accesses
Browse files Browse the repository at this point in the history
Things to consider:
 - what to do when the expected layout is invalid?
 - what to do when the accesses object is outdated? don’t want a cache entry for that, since it gets removed immedietly
 - how to handle the transition from expected primitive write to something else?

Signed-off-by: Stefan Marr <[email protected]>
  • Loading branch information
smarr committed Aug 26, 2024
1 parent a672998 commit 2089e48
Showing 1 changed file with 40 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,6 @@ public double readDouble(final SObject obj) throws UnexpectedResultException {
return TypesGen.expectDouble(read(obj));
}

protected final Object specializeAndRead(final SObject obj, final String reason,
final AbstractReadFieldNode next) {
return specialize(obj, reason, next).read(obj);
}

@InliningCutoff
protected final AbstractReadFieldNode specialize(final SObject obj,
final String reason, final AbstractReadFieldNode next) {
Expand All @@ -94,8 +89,8 @@ private static final class UninitializedReadFieldNode extends AbstractReadFieldN
@InliningCutoff
public Object read(final SObject obj) {
CompilerDirectives.transferToInterpreterAndInvalidate();
return specializeAndRead(obj, "uninitalized node",
new UninitializedReadFieldNode(fieldIndex));
return specialize(obj, "uninitialized node",
new UninitializedReadFieldNode(fieldIndex)).read(obj);
}
}

Expand All @@ -115,14 +110,6 @@ protected final boolean hasExpectedLayout(final SObject obj)
layout.checkIsLatest();
return layout == obj.getObjectLayout();
}

protected final AbstractReadFieldNode respecializedNodeOrNext(final SObject obj) {
if (layout.layoutForSameClass(obj.getObjectLayout())) {
return specialize(obj, "update outdated read node", nextInCache);
} else {
return nextInCache;
}
}
}

public static final class ReadUnwrittenFieldNode extends ReadSpecializedFieldNode {
Expand All @@ -137,7 +124,7 @@ public Object read(final SObject obj) {
if (hasExpectedLayout(obj)) {
return Nil.nilObject;
} else {
return respecializedNodeOrNext(obj).read(obj);
return nextInCache.read(obj);
}
} catch (InvalidAssumptionException e) {
CompilerDirectives.transferToInterpreterAndInvalidate();
Expand Down Expand Up @@ -168,7 +155,7 @@ public long readLong(final SObject obj) throws UnexpectedResultException {
if (hasExpectedLayout(obj)) {
return storage.readLong(obj);
} else {
return respecializedNodeOrNext(obj).readLong(obj);
return nextInCache.readLong(obj);
}
} catch (InvalidAssumptionException e) {
CompilerDirectives.transferToInterpreterAndInvalidate();
Expand Down Expand Up @@ -200,7 +187,7 @@ public Object read(final SObject obj) {

return storage.readLongSet(obj);
} else {
return respecializedNodeOrNext(obj).read(obj);
return nextInCache.read(obj);
}
} catch (InvalidAssumptionException e) {
CompilerDirectives.transferToInterpreterAndInvalidate();
Expand All @@ -226,7 +213,7 @@ public double readDouble(final SObject obj) throws UnexpectedResultException {
if (hasExpectedLayout(obj)) {
return storage.readDouble(obj);
} else {
return respecializedNodeOrNext(obj).readDouble(obj);
return nextInCache.readDouble(obj);
}
} catch (InvalidAssumptionException e) {
CompilerDirectives.transferToInterpreterAndInvalidate();
Expand Down Expand Up @@ -258,7 +245,7 @@ public Object read(final SObject obj) {

return storage.readDoubleSet(obj);
} else {
return respecializedNodeOrNext(obj).read(obj);
return nextInCache.read(obj);
}
} catch (InvalidAssumptionException e) {
CompilerDirectives.transferToInterpreterAndInvalidate();
Expand All @@ -282,7 +269,7 @@ public Object read(final SObject obj) {
if (hasExpectedLayout(obj)) {
return storage.read(obj);
} else {
return respecializedNodeOrNext(obj).read(obj);
return nextInCache.read(obj);
}
} catch (InvalidAssumptionException e) {
CompilerDirectives.transferToInterpreterAndInvalidate();
Expand Down Expand Up @@ -314,16 +301,22 @@ public double write(final SObject obj, final double value) {
}

@InliningCutoff
protected final void writeAndRespecialize(final SObject obj, final Object value,
final String reason, final AbstractWriteFieldNode next) {
CompilerDirectives.transferToInterpreterAndInvalidate();
protected final void writeToOutdated(final SObject obj, final Object value) {
CompilerDirectives.transferToInterpreter();
assert !obj.getObjectLayout().isValid();
obj.setField(fieldIndex, value);
}

@InliningCutoff
protected final void writeUnexpectedTypeAndRespecialize(final SObject obj,
final Object value, final AbstractWriteFieldNode next) {
CompilerDirectives.transferToInterpreterAndInvalidate();
obj.setField(fieldIndex, value);

final ObjectLayout layout = obj.getObjectLayout();
final StorageLocation location = layout.getStorageLocation(fieldIndex);
AbstractWriteFieldNode newNode = location.getWriteNode(fieldIndex, layout, next);
replace(newNode, reason);
replace(newNode, "update outdated read node");
}
}

Expand All @@ -336,8 +329,15 @@ private static final class UninitializedWriteFieldNode extends AbstractWriteFiel
@InliningCutoff
public Object write(final SObject obj, final Object value) {
CompilerDirectives.transferToInterpreterAndInvalidate();
writeAndRespecialize(obj, value, "initialize write field node",

obj.setField(fieldIndex, value);

final ObjectLayout layout = obj.getObjectLayout();
final StorageLocation location = layout.getStorageLocation(fieldIndex);
AbstractWriteFieldNode newNode = location.getWriteNode(fieldIndex, layout,
new UninitializedWriteFieldNode(fieldIndex));
replace(newNode, "initialize write field node");

return value;
}
}
Expand All @@ -362,18 +362,18 @@ protected final boolean hasExpectedLayout(final SObject obj)
}

public static final class IncrementLongFieldNode extends FieldAccessorNode {
protected final ObjectLayout layout;
private final ObjectLayout layout;
private final LongStorageLocation storage;

@Child protected IncrementLongFieldNode nextInCache;
@Child private IncrementLongFieldNode nextInCache;

public IncrementLongFieldNode(final int fieldIndex, final ObjectLayout layout) {
super(fieldIndex);
this.layout = layout;
this.storage = (LongStorageLocation) layout.getStorageLocation(fieldIndex);
}

protected boolean hasExpectedLayout(final SObject obj)
private boolean hasExpectedLayout(final SObject obj)
throws InvalidAssumptionException {
layout.checkIsLatest();
return layout == obj.getObjectLayout();
Expand Down Expand Up @@ -424,7 +424,7 @@ public long write(final SObject obj, final long value) {
storage.writeLong(obj, value);
} else {
if (layout.layoutForSameClass(obj.getObjectLayout())) {
writeAndRespecialize(obj, value, "update outdated write node", nextInCache);
writeToOutdated(obj, value);
} else {
nextInCache.write(obj, value);
}
Expand All @@ -445,12 +445,10 @@ private void dropAndWriteNext(final SObject obj, final long value) {
public Object write(final SObject obj, final Object value) {
if (value instanceof Long) {
write(obj, (long) value);
} else if (layout.layoutForSameClass(obj.getObjectLayout())) {
writeUnexpectedTypeAndRespecialize(obj, value, nextInCache);
} else {
if (layout.layoutForSameClass(obj.getObjectLayout())) {
writeAndRespecialize(obj, value, "update outdated read node", nextInCache);
} else {
nextInCache.write(obj, (long) value);
}
nextInCache.write(obj, value);
}
return value;
}
Expand All @@ -472,7 +470,7 @@ public double write(final SObject obj, final double value) {
storage.writeDouble(obj, value);
} else {
if (layout.layoutForSameClass(obj.getObjectLayout())) {
writeAndRespecialize(obj, value, "update outdated read node", nextInCache);
writeToOutdated(obj, value);
} else {
nextInCache.write(obj, value);
}
Expand All @@ -493,12 +491,10 @@ private void dropAndWriteNext(final SObject obj, final double value) {
public Object write(final SObject obj, final Object value) {
if (value instanceof Double) {
write(obj, (double) value);
} else if (layout.layoutForSameClass(obj.getObjectLayout())) {
writeUnexpectedTypeAndRespecialize(obj, value, nextInCache);
} else {
if (layout.layoutForSameClass(obj.getObjectLayout())) {
writeAndRespecialize(obj, value, "update outdated read node", nextInCache);
} else {
nextInCache.write(obj, (double) value);
}
nextInCache.write(obj, value);
}
return value;
}
Expand All @@ -518,12 +514,10 @@ public Object write(final SObject obj, final Object value) {
try {
if (hasExpectedLayout(obj)) {
storage.write(obj, value);
} else if (layout.layoutForSameClass(obj.getObjectLayout())) {
writeToOutdated(obj, value);
} else {
if (layout.layoutForSameClass(obj.getObjectLayout())) {
writeAndRespecialize(obj, value, "update outdated read node", nextInCache);
} else {
nextInCache.write(obj, value);
}
nextInCache.write(obj, value);
}
} catch (InvalidAssumptionException e) {
CompilerDirectives.transferToInterpreterAndInvalidate();
Expand Down

0 comments on commit 2089e48

Please sign in to comment.