Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Delay instantiation of cachedValues to save memory #831

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
16 changes: 12 additions & 4 deletions pkl-core/src/main/java/org/pkl/core/runtime/VmDynamic.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ public boolean isSequence() {
@Override
@TruffleBoundary
public PObject export() {
var properties =
CollectionUtils.<String, Object>newLinkedHashMap(EconomicMaps.size(cachedValues));
var properties = CollectionUtils.<String, Object>newLinkedHashMap(getCacheSize());

iterateMemberValues(
(key, member, value) -> {
Expand Down Expand Up @@ -107,7 +106,9 @@ public boolean equals(Object obj) {
force(false);
other.force(false);
if (getRegularMemberCount() != other.getRegularMemberCount()) return false;
if (getCacheSize() == 0) return true;

assert cachedValues != null;
var cursor = cachedValues.getEntries();
while (cursor.advance()) {
Object key = cursor.getKey();
Expand All @@ -129,6 +130,10 @@ public int hashCode() {

force(false);
var result = 0;
if (getCacheSize() == 0) {
return 0;
}
assert cachedValues != null;
var cursor = cachedValues.getEntries();

while (cursor.advance()) {
Expand All @@ -149,8 +154,11 @@ public int getRegularMemberCount() {
if (cachedRegularMemberCount != -1) return cachedRegularMemberCount;

var result = 0;
for (var key : cachedValues.getKeys()) {
if (!isHiddenOrLocalProperty(key)) result += 1;
if (getCacheSize() != 0) {
assert cachedValues != null;
for (var key : cachedValues.getKeys()) {
if (!isHiddenOrLocalProperty(key)) result += 1;
}
}
cachedRegularMemberCount = result;
return result;
Expand Down
5 changes: 5 additions & 0 deletions pkl-core/src/main/java/org/pkl/core/runtime/VmFunction.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ public UnmodifiableEconomicMap<Object, ObjectMember> getMembers() {
return EconomicMaps.create();
}

@Override
public int getCacheSize() {
return 0;
}

@Override
public @Nullable Object getCachedValue(Object key) {
return null;
Expand Down
2 changes: 1 addition & 1 deletion pkl-core/src/main/java/org/pkl/core/runtime/VmListing.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public VmClass getVmClass() {
@Override
@TruffleBoundary
public List<Object> export() {
var properties = new ArrayList<>(EconomicMaps.size(cachedValues));
var properties = new ArrayList<>(getCacheSize());

iterateMemberValues(
(key, prop, value) -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ public boolean hasCachedValue(Object key) {
var objectMember = findMember(key);
var ret = typecastObjectMember(objectMember, memberValue, IndirectCallNode.getUncached());
if (ret != memberValue) {
if (cachedValues == null) {
cachedValues = EconomicMaps.create();
}
EconomicMaps.put(cachedValues, key, ret);
} else {
// optimization: don't add to own cached values if typecast results in the same value
Expand Down
2 changes: 1 addition & 1 deletion pkl-core/src/main/java/org/pkl/core/runtime/VmMapping.java
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public VmSet getAllKeys() {
@Override
@TruffleBoundary
public Map<Object, Object> export() {
var properties = CollectionUtils.newLinkedHashMap(EconomicMaps.size(cachedValues));
var properties = CollectionUtils.newLinkedHashMap(getCacheSize());

iterateMemberValues(
(key, prop, value) -> {
Expand Down
30 changes: 18 additions & 12 deletions pkl-core/src/main/java/org/pkl/core/runtime/VmObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,31 +31,23 @@
public abstract class VmObject extends VmObjectLike {
@CompilationFinal protected @Nullable VmObject parent;
protected final UnmodifiableEconomicMap<Object, ObjectMember> members;
protected final EconomicMap<Object, Object> cachedValues;
protected @Nullable EconomicMap<Object, Object> cachedValues;

protected int cachedHash;
private boolean forced;

public VmObject(
MaterializedFrame enclosingFrame,
@Nullable VmObject parent,
UnmodifiableEconomicMap<Object, ObjectMember> members,
EconomicMap<Object, Object> cachedValues) {
UnmodifiableEconomicMap<Object, ObjectMember> members) {
super(enclosingFrame);
this.parent = parent;
this.members = members;
this.cachedValues = cachedValues;
this.cachedValues = null;

assert parent != this;
}

public VmObject(
MaterializedFrame enclosingFrame,
@Nullable VmObject parent,
UnmodifiableEconomicMap<Object, ObjectMember> members) {
this(enclosingFrame, parent, members, EconomicMaps.create());
}

public final void lateInitParent(VmObject parent) {
assert this.parent == null;
this.parent = parent;
Expand All @@ -81,18 +73,32 @@ public final UnmodifiableEconomicMap<Object, ObjectMember> getMembers() {
return members;
}

@Override
public int getCacheSize() {
return cachedValues == null ? 0 : cachedValues.size();
}

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

@Override
public void setCachedValue(Object key, Object value, ObjectMember objectMember) {
if (cachedValues == null) {
cachedValues = EconomicMaps.create();
}
EconomicMaps.put(cachedValues, key, value);
}

@Override
public boolean hasCachedValue(Object key) {
if (cachedValues == null) {
return false;
}
return EconomicMaps.containsKey(cachedValues, key);
}

Expand Down Expand Up @@ -208,7 +214,7 @@ public final String toString() {
*/
@TruffleBoundary
protected final Map<String, Object> exportMembers() {
var result = CollectionUtils.<String, Object>newLinkedHashMap(EconomicMaps.size(cachedValues));
var result = CollectionUtils.<String, Object>newLinkedHashMap(getCacheSize());

iterateMemberValues(
(key, member, value) -> {
Expand Down
6 changes: 6 additions & 0 deletions pkl-core/src/main/java/org/pkl/core/runtime/VmObjectLike.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ public boolean isModuleObject() {
/** Returns the declared members of this object. */
public abstract UnmodifiableEconomicMap<Object, ObjectMember> getMembers();

/**
* @return The (current) size of the properties cache for this object.
*/
@TruffleBoundary
public abstract @Nullable int getCacheSize();

/**
* Reads from the properties cache for this object. The cache contains the values of all members
* defined in this object or an ancestor thereof which have been requested with this object as the
Expand Down