Skip to content

Commit

Permalink
Bring back previous optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
odenix committed Nov 28, 2024
1 parent 9d94540 commit fa73895
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@
package org.pkl.core.runtime;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.frame.MaterializedFrame;
import com.oracle.truffle.api.nodes.IndirectCallNode;
import org.graalvm.collections.UnmodifiableEconomicMap;
import org.pkl.core.ast.member.ListingOrMappingTypeCastNode;
import org.pkl.core.ast.member.ObjectMember;
import org.pkl.core.ast.type.TypeNode;
import org.pkl.core.util.EconomicMaps;
import org.pkl.core.util.Nullable;

public abstract class VmListingOrMapping extends VmObject {
Expand Down Expand Up @@ -51,7 +53,7 @@ public final Object doTypeCast(
var result =
this == owner
? value
: ((VmListingOrMapping) this.parent)
: ((VmListingOrMapping) parent)
.doTypeCast(value, owner, callNode, member, newNextTypeCastNode);
if (typeCastNode == null || typeCastNode == nextTypeCastNode) return result;
var callTarget = typeCastNode.getCallTarget();
Expand All @@ -66,6 +68,34 @@ public final Object doTypeCast(
}
}

@Override
@TruffleBoundary
public final @Nullable Object getCachedValue(Object key) {
var result = EconomicMaps.get(cachedValues, key);
if (result != null || !members.isEmpty()) return result;

// optimization: steal value from parent cache to avoid computing it multiple times

assert parent != null; // VmListingOrMapping always has a parent
result = parent.getCachedValue(key);
if (result == null) return null;

if (typeCastNode != null) {
var callNode = IndirectCallNode.getUncached();
var callTarget = typeCastNode.getCallTarget();
try {
result = callNode.call(callTarget, getEnclosingReceiver(), getEnclosingOwner(), result);
} catch (VmException e) {
var member = VmUtils.findMember(parent, key);
assert member != null; // already found the member's cached value
VmUtils.insertStackFrame(member, callTarget, e);
throw e;
}
}
setCachedValue(key, result);
return result;
}

/**
* Tells whether the reified element/value type of this listing/mapping is known to be a subtype
* of {@code typeNode}. (If {@code true}, it is redundant to check that elements/values have type
Expand Down
2 changes: 1 addition & 1 deletion pkl-core/src/main/java/org/pkl/core/runtime/VmObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public final UnmodifiableEconomicMap<Object, ObjectMember> getMembers() {
}

@Override
public @Nullable final Object getCachedValue(Object key) {
public @Nullable Object getCachedValue(Object key) {
return EconomicMaps.get(cachedValues, key);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// ensure that these members are only evaluated once (trace should only be emitted once)
listing = new Listing { trace(1) }

listing2: Listing<Int> = listing

listing3 = new Listing {
new Listing { trace(2) }
}

listing4: Listing<Listing<Int>> = listing3
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
listing {
1
}
listing2 {
1
}
listing3 {
new {
2
}
}
listing4 {
new {
2
}
}
pkl: TRACE: 1 = 1 (file:///$snippetsDir/input/listings/listing7.pkl)
pkl: TRACE: 2 = 2 (file:///$snippetsDir/input/listings/listing7.pkl)

0 comments on commit fa73895

Please sign in to comment.