-
Notifications
You must be signed in to change notification settings - Fork 281
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve lazy type checking of listings and mappings (#789)
Motivation: - simplify implementation of lazy type checking - fix correctness issues of lazy type checking (#785) Changes: - implement listing/mapping type cast via amendment (`parent`) instead of delegation (`delegate`) - handle type checking of *computed* elements/entries in the same way as type checking of computed properties - ElementOrEntryNode is the equivalent of TypeCheckedPropertyNode - remove fields VmListingOrMapping.delegate/typeNodeFrame/cachedMembers/checkedMembers - fix #785 by executing all type casts between a member's owner and receiver - fix #823 by storing owner and receiver directly instead of storing the mutable frame containing them (typeNodeFrame) - remove overrides of VmObject methods that are no longer required - good for Truffle partial evaluation and JVM inlining - revert a85a173 except for added tests - move `VmUtils.setOwner` and `VmUtils.setReceiver` and make them private - these methods aren't generally safe to use Result: - simpler code with greater optimization potential - VmListingOrMapping can now have both a type node and new members - fewer changes to surrounding code - smaller memory footprint - better performance in some cases - fixes #785 - fixes #823 Potential future optimizations: - avoid lazy type checking overhead for untyped listings/mappings - improve efficiency of forcing a typed listing/mapping - currently, lazy type checking will traverse the parent chain once per member, reducing the performance benefit of shallow-forcing a listing/mapping over evaluating each member individually - avoid creating an intermediate untyped listing/mapping in the following cases: - `new Listing<X> {...}` - amendment of `property: Listing<X>`
- Loading branch information
1 parent
7b850dd
commit aeace8b
Showing
34 changed files
with
486 additions
and
292 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 73 additions & 0 deletions
73
pkl-core/src/main/java/org/pkl/core/ast/member/ElementOrEntryNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
/* | ||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.pkl.core.ast.member; | ||
|
||
import com.oracle.truffle.api.dsl.Cached; | ||
import com.oracle.truffle.api.dsl.Cached.Shared; | ||
import com.oracle.truffle.api.dsl.Executed; | ||
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.frame.FrameDescriptor; | ||
import com.oracle.truffle.api.frame.VirtualFrame; | ||
import com.oracle.truffle.api.nodes.IndirectCallNode; | ||
import org.pkl.core.ast.ExpressionNode; | ||
import org.pkl.core.ast.expression.primary.GetReceiverNode; | ||
import org.pkl.core.runtime.VmDynamic; | ||
import org.pkl.core.runtime.VmLanguage; | ||
import org.pkl.core.runtime.VmListing; | ||
import org.pkl.core.runtime.VmMapping; | ||
import org.pkl.core.runtime.VmUtils; | ||
import org.pkl.core.util.Nullable; | ||
|
||
/** Equivalent of {@link TypedPropertyNode} for elements/entries. */ | ||
public abstract class ElementOrEntryNode extends RegularMemberNode { | ||
@Child @Executed protected ExpressionNode receiverNode = new GetReceiverNode(); | ||
|
||
protected ElementOrEntryNode( | ||
@Nullable VmLanguage language, | ||
FrameDescriptor descriptor, | ||
ObjectMember member, | ||
ExpressionNode bodyNode) { | ||
|
||
super(language, descriptor, member, bodyNode); | ||
} | ||
|
||
@Specialization | ||
protected Object evalListing( | ||
VirtualFrame frame, | ||
VmListing receiver, | ||
@Cached("create()") @Shared("callNode") IndirectCallNode callNode) { | ||
var result = executeBody(frame); | ||
return VmUtils.shouldRunTypeCheck(frame) | ||
? receiver.executeTypeCasts(result, VmUtils.getOwner(frame), callNode, null, null) | ||
: result; | ||
} | ||
|
||
@Specialization | ||
protected Object evalMapping( | ||
VirtualFrame frame, | ||
VmMapping receiver, | ||
@Cached("create()") @Shared("callNode") IndirectCallNode callNode) { | ||
var result = executeBody(frame); | ||
return VmUtils.shouldRunTypeCheck(frame) | ||
? receiver.executeTypeCasts(result, VmUtils.getOwner(frame), callNode, null, null) | ||
: result; | ||
} | ||
|
||
@Specialization | ||
protected Object evalDynamic(VirtualFrame frame, VmDynamic ignored) { | ||
return executeBody(frame); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.