2121 */
2222package som .interpreter .nodes ;
2323
24- import com .oracle .truffle .api .CompilerDirectives ;
25- import com .oracle .truffle .api .frame .VirtualFrame ;
26- import com .oracle .truffle .api .nodes .NodeInfo ;
27- import com .oracle .truffle .api .nodes .NodeInfo .Kind ;
28-
2924import som .interpreter .nodes .VariableNode .SuperReadNode ;
3025import som .vm .Universe ;
3126import som .vmobjects .Class ;
3227import som .vmobjects .Invokable ;
3328import som .vmobjects .Object ;
3429import som .vmobjects .Symbol ;
3530
31+ import com .oracle .truffle .api .CallTarget ;
32+ import com .oracle .truffle .api .CompilerDirectives ;
33+ import com .oracle .truffle .api .frame .VirtualFrame ;
34+ import com .oracle .truffle .api .nodes .FrameFactory ;
35+ import com .oracle .truffle .api .nodes .InlinableCallSite ;
36+ import com .oracle .truffle .api .nodes .InlinedCallSite ;
37+ import com .oracle .truffle .api .nodes .Node ;
38+
39+ // TODO: I need to add a check that the invokable has not changed
40+
3641// @NodeChildren({
3742// @NodeChild(value = "receiver", type = ExpressionNode.class),
3843// @NodeChild(value = "arguments", type = ExpressionNode[].class)})
39- @ NodeInfo (kind = Kind .UNINITIALIZED )
4044public class MessageNode extends ExpressionNode {
4145
4246 @ Child protected final ExpressionNode receiver ;
@@ -116,8 +120,10 @@ public Object executeGeneric(VirtualFrame frame) {
116120 CompilerDirectives .transferToInterpreter ();
117121
118122 // First let's rewrite this node
119- MonomorpicMessageNode mono = new MonomorpicMessageNode (receiver , arguments , selector , universe , rcvrClass , invokable );
120- this .replace (mono , "Let's assume it is a monomorphic send site." );
123+ MonomorpicMessageNode mono = new MonomorpicMessageNode (receiver ,
124+ arguments , selector , universe , rcvrClass , invokable );
125+
126+ replace (mono , "Let's assume it is a monomorphic send site." );
121127
122128 // Then execute the invokable, because it can exit this method with
123129 // control flow exceptions (non-local returns), which would leave node
@@ -128,23 +134,29 @@ public Object executeGeneric(VirtualFrame frame) {
128134 }
129135 }
130136
131- @ NodeInfo ( kind = Kind . SPECIALIZED )
132- public static class MonomorpicMessageNode extends MessageNode {
137+ public static class MonomorpicMessageNode extends MessageNode
138+ implements InlinableCallSite {
133139
134140 private final Class rcvrClass ;
135141 private final Invokable invokable ;
136142
143+ private int callCount ;
144+
137145 public MonomorpicMessageNode (final ExpressionNode receiver ,
138146 final ExpressionNode [] arguments , final Symbol selector ,
139147 final Universe universe , final Class rcvrClass ,
140148 final Invokable invokable ) {
141149 super (receiver , arguments , selector , universe );
142150 this .rcvrClass = rcvrClass ;
143151 this .invokable = invokable ;
152+
153+ callCount = 0 ;
144154 }
145155
146156 @ Override
147157 public Object executeGeneric (VirtualFrame frame ) {
158+ callCount ++;
159+
148160 // evaluate all the expressions: first determine receiver
149161 Object rcvr = receiver .executeGeneric (frame );
150162
@@ -160,13 +172,134 @@ public Object executeGeneric(VirtualFrame frame) {
160172 // So, it might just be a polymorphic send site.
161173 PolymorpicMessageNode poly = new PolymorpicMessageNode (receiver ,
162174 arguments , selector , universe , rcvrClass , invokable , currentRcvrClass );
163- this .replace (poly , "It is not a monomorpic send." );
175+
176+ replace (poly , "It is not a monomorpic send." );
164177 return doFullSend (frame , rcvr , args , currentRcvrClass );
165178 }
166179 }
180+
181+ @ Override
182+ public int getCallCount () {
183+ return callCount ;
184+ }
185+
186+ @ Override
187+ public void resetCallCount () {
188+ callCount = 0 ;
189+ }
190+
191+ @ Override
192+ public CallTarget getCallTarget () {
193+ return invokable .getCallTarget ();
194+ }
195+
196+ @ Override
197+ public Node getInlineTree () {
198+ if (invokable .isPrimitive ()) {
199+ return this ;
200+ } else {
201+ return invokable .getTruffleInvokable ();
202+ }
203+ }
204+
205+ private InlinedMonomorphicMessageNode newInlinedNode (
206+ final FrameFactory frameFactory ,
207+ final Method method ) {
208+ return new InlinedMonomorphicMessageNode (receiver , arguments , selector ,
209+ universe , rcvrClass , invokable , method .methodCloneForInlining (),
210+ frameFactory , method );
211+ }
212+
213+ @ Override
214+ public boolean inline (FrameFactory factory ) {
215+ Method method = invokable .getTruffleInvokable ();
216+ if (method == null ) {
217+ return false ;
218+ }
219+
220+ InlinedMonomorphicMessageNode inlinedNode = newInlinedNode (factory ,
221+ method );
222+
223+ replace (inlinedNode , "Node got inlined" );
224+
225+ return true ;
226+ }
227+ }
228+
229+ public static class InlinedMonomorphicMessageNode extends MessageNode
230+ implements InlinedCallSite {
231+
232+ private final Class rcvrClass ;
233+ private final Invokable invokable ;
234+
235+ @ Child private final ExpressionNode methodBody ;
236+
237+ private final FrameFactory frameFactory ;
238+ private final Method inlinedMethod ;
239+
240+ public InlinedMonomorphicMessageNode (final ExpressionNode receiver ,
241+ final ExpressionNode [] arguments , final Symbol selector ,
242+ final Universe universe , final Class rcvrClass ,
243+ final Invokable invokable , final ExpressionNode methodBody ,
244+ final FrameFactory frameFactory ,
245+ final Method inlinedMethod ) {
246+ super (receiver , arguments , selector , universe );
247+ this .rcvrClass = rcvrClass ;
248+ this .invokable = invokable ;
249+
250+ this .methodBody = adoptChild (methodBody );
251+
252+ this .frameFactory = frameFactory ;
253+ this .inlinedMethod = inlinedMethod ;
254+ }
255+
256+ @ Override
257+ public Object executeGeneric (VirtualFrame frame ) {
258+ // evaluate all the expressions: first determine receiver
259+ Object rcvr = receiver .executeGeneric (frame );
260+
261+ // then determine the arguments
262+ Object [] args = determineArguments (frame );
263+
264+ Class currentRcvrClass = classOfReceiver (rcvr , receiver );
265+
266+ if (currentRcvrClass == rcvrClass ) {
267+ return executeInlined (frame , rcvr , args );
268+ } else {
269+ return generalizeNode (frame , rcvr , args , currentRcvrClass );
270+ }
271+ }
272+
273+ private Object executeInlined (final VirtualFrame caller , final Object rcvr ,
274+ final Object [] args ) {
275+ // CompilerDirectives.transferToInterpreter();
276+ final VirtualFrame frame = frameFactory .create (
277+ inlinedMethod .getFrameDescriptor (), caller .pack (),
278+ new Arguments (rcvr , args ));
279+
280+ final FrameOnStackMarker marker = Method .initializeFrame (inlinedMethod ,
281+ frame .materialize ());
282+
283+ return Method .messageSendExecution (marker , frame , methodBody );
284+ }
285+
286+ private Object generalizeNode (final VirtualFrame frame , final Object rcvr ,
287+ final Object [] args , final Class currentRcvrClass ) {
288+ CompilerDirectives .transferToInterpreter ();
289+ // So, it might just be a polymorphic send site.
290+ PolymorpicMessageNode poly = new PolymorpicMessageNode (receiver ,
291+ arguments , selector , universe , rcvrClass , invokable , currentRcvrClass );
292+
293+ replace (poly , "It is not a monomorpic send." );
294+ return doFullSend (frame , rcvr , args , currentRcvrClass );
295+ }
296+
297+ @ Override
298+ public CallTarget getCallTarget () {
299+ return invokable .getCallTarget ();
300+ }
167301 }
168302
169- @ NodeInfo (kind = Kind .SPECIALIZED )
170303 public static class PolymorpicMessageNode extends MessageNode {
171304 private static final int CACHE_SIZE = 8 ;
172305
@@ -216,13 +349,13 @@ public Object executeGeneric(VirtualFrame frame) {
216349 CompilerDirectives .transferToInterpreter ();
217350 // So, it might just be a megamorphic send site.
218351 MegamorphicMessageNode mega = new MegamorphicMessageNode (receiver , arguments , selector , universe );
219- this .replace (mega , "It is not a polymorpic send." );
352+
353+ replace (mega , "It is not a polymorpic send." );
220354 return doFullSend (frame , rcvr , args , currentRcvrClass );
221355 }
222356 }
223357 }
224358
225- @ NodeInfo (kind = Kind .GENERIC )
226359 public static class MegamorphicMessageNode extends MessageNode {
227360
228361 public MegamorphicMessageNode (final ExpressionNode receiver ,
0 commit comments