9
9
*/
10
10
package org .truffleruby .language .exceptions ;
11
11
12
+ import com .oracle .truffle .api .dsl .Cached ;
13
+ import com .oracle .truffle .api .dsl .Specialization ;
12
14
import com .oracle .truffle .api .exception .AbstractTruffleException ;
13
15
import com .oracle .truffle .api .interop .InteropLibrary ;
14
- import com .oracle .truffle .api .profiles .ConditionProfile ;
15
16
import com .oracle .truffle .api .CompilerDirectives ;
16
17
import com .oracle .truffle .api .TruffleSafepoint ;
18
+ import com .oracle .truffle .api .profiles .InlinedBranchProfile ;
19
+ import com .oracle .truffle .api .profiles .InlinedConditionProfile ;
17
20
import org .truffleruby .core .exception .ExceptionOperations ;
18
21
import org .truffleruby .language .RubyContextSourceNode ;
19
22
import org .truffleruby .language .RubyNode ;
26
29
import com .oracle .truffle .api .frame .VirtualFrame ;
27
30
import com .oracle .truffle .api .nodes .ExplodeLoop ;
28
31
import com .oracle .truffle .api .nodes .ExplodeLoop .LoopExplosionKind ;
29
- import com .oracle .truffle .api .profiles .BranchProfile ;
30
32
import org .truffleruby .language .methods .TranslateExceptionNode ;
31
33
import org .truffleruby .language .threadlocal .ThreadLocalGlobals ;
32
34
33
- public class TryNode extends RubyContextSourceNode {
35
+ public abstract class TryNode extends RubyContextSourceNode {
34
36
35
37
@ Child private RubyNode tryPart ;
36
38
@ Children private final RescueNode [] rescueParts ;
37
39
@ Child private RubyNode elsePart ;
38
40
@ Child private TranslateExceptionNode translateExceptionNode ;
39
41
private final boolean canOmitBacktrace ;
40
42
41
- private final BranchProfile noExceptionProfile = BranchProfile .create ();
42
- private final BranchProfile killExceptionProfile = BranchProfile .create ();
43
- private final BranchProfile guestExceptionProfile = BranchProfile .create ();
44
- private final BranchProfile retryProfile = BranchProfile .create ();
45
- private final ConditionProfile raiseExceptionProfile = ConditionProfile .create ();
46
-
47
43
public TryNode (
48
44
RubyNode tryPart ,
49
45
RescueNode [] rescueParts ,
@@ -56,23 +52,28 @@ public TryNode(
56
52
}
57
53
58
54
/** Based on {@link InteropLibrary#throwException(Object)}'s {@code TryCatchNode} */
59
- @ Override
60
- public Object execute (VirtualFrame frame ) {
55
+ @ Specialization
56
+ protected Object doTry (VirtualFrame frame ,
57
+ @ Cached InlinedBranchProfile noExceptionProfile ,
58
+ @ Cached InlinedBranchProfile killExceptionProfile ,
59
+ @ Cached InlinedBranchProfile guestExceptionProfile ,
60
+ @ Cached InlinedBranchProfile retryProfile ,
61
+ @ Cached InlinedConditionProfile raiseExceptionProfile ) {
61
62
while (true ) {
62
63
Object result ;
63
64
64
65
try {
65
66
result = tryPart .execute (frame );
66
- noExceptionProfile .enter ();
67
+ noExceptionProfile .enter (this );
67
68
} catch (KillException e ) { // an AbstractTruffleException but must not set $! and cannot be rescue'd
68
- killExceptionProfile .enter ();
69
+ killExceptionProfile .enter (this );
69
70
throw e ;
70
71
} catch (AbstractTruffleException exception ) {
71
- guestExceptionProfile .enter ();
72
+ guestExceptionProfile .enter (this );
72
73
try {
73
- return handleException (frame , exception );
74
+ return handleException (frame , exception , raiseExceptionProfile );
74
75
} catch (RetryException e ) {
75
- retryProfile .enter ();
76
+ retryProfile .enter (this );
76
77
TruffleSafepoint .poll (this );
77
78
continue ;
78
79
}
@@ -93,8 +94,9 @@ public Object execute(VirtualFrame frame) {
93
94
}
94
95
95
96
@ ExplodeLoop (kind = LoopExplosionKind .FULL_UNROLL_UNTIL_RETURN )
96
- private Object handleException (VirtualFrame frame , AbstractTruffleException exception ) {
97
- final Object exceptionObject = ExceptionOperations .getExceptionObject (exception , raiseExceptionProfile );
97
+ private Object handleException (VirtualFrame frame , AbstractTruffleException exception ,
98
+ InlinedConditionProfile raiseExceptionProfile ) {
99
+ final Object exceptionObject = ExceptionOperations .getExceptionObject (this , exception , raiseExceptionProfile );
98
100
99
101
for (RescueNode rescue : rescueParts ) {
100
102
if (rescue .canHandle (frame , exceptionObject )) {
@@ -142,7 +144,7 @@ private void printBacktraceOnRescue(RescueNode rescue, AbstractTruffleException
142
144
143
145
@ Override
144
146
public RubyNode cloneUninitialized () {
145
- var copy = new TryNode (
147
+ var copy = TryNodeGen . create (
146
148
tryPart .cloneUninitialized (),
147
149
cloneUninitialized (rescueParts ),
148
150
cloneUninitialized (elsePart ),
0 commit comments