Skip to content

Commit f5d628d

Browse files
committed
Fix profiling in ReadCallerFrameNode
* The profile would always see the else branch because it was always taken on the first call.
1 parent 7c6aea1 commit f5d628d

File tree

1 file changed

+12
-2
lines changed

1 file changed

+12
-2
lines changed

src/main/java/org/truffleruby/language/arguments/ReadCallerFrameNode.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99
*/
1010
package org.truffleruby.language.arguments;
1111

12+
import com.oracle.truffle.api.CompilerDirectives;
1213
import com.oracle.truffle.api.frame.FrameInstance;
1314
import org.truffleruby.language.RubyBaseNode;
1415
import org.truffleruby.language.dispatch.CachedDispatchNode;
1516

17+
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
1618
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
1719
import com.oracle.truffle.api.frame.MaterializedFrame;
1820
import com.oracle.truffle.api.frame.VirtualFrame;
@@ -23,12 +25,21 @@
2325
public class ReadCallerFrameNode extends RubyBaseNode {
2426

2527
private final ConditionProfile callerFrameProfile = ConditionProfile.createBinaryProfile();
28+
@CompilationFinal private volatile boolean firstCall = true;
2629

2730
public static ReadCallerFrameNode create() {
2831
return new ReadCallerFrameNode();
2932
}
3033

3134
public MaterializedFrame execute(VirtualFrame frame) {
35+
// Avoid polluting the profile for the first call which has to use getCallerFrame()
36+
if (firstCall) {
37+
CompilerDirectives.transferToInterpreterAndInvalidate();
38+
firstCall = false;
39+
notifyCallerToSendFrame();
40+
return getCallerFrame();
41+
}
42+
3243
final MaterializedFrame callerFrame = RubyArguments.getCallerFrame(frame);
3344

3445
if (callerFrameProfile.profile(callerFrame != null)) {
@@ -38,7 +49,7 @@ public MaterializedFrame execute(VirtualFrame frame) {
3849
}
3950
}
4051

41-
private void replaceDispatchNode() {
52+
private void notifyCallerToSendFrame() {
4253
final Node callerNode = getContext().getCallStack().getCallerNode(0, false);
4354
if (callerNode instanceof DirectCallNode) {
4455
final Node parent = callerNode.getParent();
@@ -50,7 +61,6 @@ private void replaceDispatchNode() {
5061

5162
@TruffleBoundary
5263
private MaterializedFrame getCallerFrame() {
53-
replaceDispatchNode();
5464
return getContext().getCallStack().getCallerFrameIgnoringSend().getFrame(FrameInstance.FrameAccess.MATERIALIZE).materialize();
5565
}
5666

0 commit comments

Comments
 (0)