comparison truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ObjectAccessNode.java @ 22123:329fe954f6f2

Can compile Truffle API with following javac lints: -Xlint:all,-auxiliaryclass,-try,-processing
author Jaroslav Tulach <jaroslav.tulach@oracle.com>
date Wed, 02 Sep 2015 13:15:51 +0200
parents 6203830a4f9a
children dc83cc1f94f2
comparison
equal deleted inserted replaced
22122:ac017ff52c07 22123:329fe954f6f2
22 * or visit www.oracle.com if you need additional information or have any 22 * or visit www.oracle.com if you need additional information or have any
23 * questions. 23 * questions.
24 */ 24 */
25 package com.oracle.truffle.api.interop; 25 package com.oracle.truffle.api.interop;
26 26
27 import com.oracle.truffle.api.*;
28 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
29 import com.oracle.truffle.api.frame.*; 27 import com.oracle.truffle.api.frame.*;
30 import com.oracle.truffle.api.nodes.*; 28 import com.oracle.truffle.api.nodes.*;
31 29
32 abstract class ObjectAccessNode extends Node { 30 abstract class ObjectAccessNode extends Node {
33 31
34 public abstract Object executeWith(VirtualFrame frame, TruffleObject receiver, Object[] arguments); 32 public abstract Object executeWith(VirtualFrame frame, TruffleObject receiver, Object[] arguments);
35 33
36 } 34 }
37
38 class UnresolvedObjectAccessNode extends ObjectAccessNode {
39
40 private static final int CACHE_SIZE = 8;
41 private int cacheLength = 1;
42
43 @Override
44 public Object executeWith(VirtualFrame frame, TruffleObject receiver, Object[] arguments) {
45 CompilerDirectives.transferToInterpreterAndInvalidate();
46 ForeignObjectAccessHeadNode nthParent = (ForeignObjectAccessHeadNode) NodeUtil.getNthParent(this, cacheLength);
47 ObjectAccessNode first = nthParent.getFirst();
48 if (cacheLength < CACHE_SIZE) {
49 CachedObjectAccessNode createCachedAccess = createCachedAccess(receiver, nthParent.getAccessTree(), first);
50 cacheLength++;
51 return first.replace(createCachedAccess).executeWith(frame, receiver, arguments);
52 } else {
53 return first.replace(createGenericAccess(nthParent.getAccessTree())).executeWith(frame, receiver, arguments);
54 }
55 }
56
57 private static CachedObjectAccessNode createCachedAccess(TruffleObject receiver, Message accessTree, ObjectAccessNode next) {
58 ForeignAccess fa = receiver.getForeignAccess();
59 final CallTarget ct = fa.access(accessTree);
60 if (ct == null) {
61 throw new IllegalArgumentException("Message " + accessTree + " not recognized by " + fa);
62 }
63 return new CachedObjectAccessNode(Truffle.getRuntime().createDirectCallNode(ct), next, fa);
64 }
65
66 private static GenericObjectAccessNode createGenericAccess(Message access) {
67 return new GenericObjectAccessNode(access);
68 }
69 }
70
71 class GenericObjectAccessNode extends ObjectAccessNode {
72
73 private final Message access;
74 @Child private IndirectCallNode indirectCallNode;
75
76 public GenericObjectAccessNode(Message access) {
77 this.access = access;
78 indirectCallNode = Truffle.getRuntime().createIndirectCallNode();
79 }
80
81 public GenericObjectAccessNode(GenericObjectAccessNode prev) {
82 this(prev.access);
83 }
84
85 @Override
86 public Object executeWith(VirtualFrame frame, TruffleObject truffleObject, Object[] arguments) {
87 final ForeignAccess fa = truffleObject.getForeignAccess();
88 final CallTarget ct = fa.access(access);
89 if (ct == null) {
90 throw messageNotRecognizedException(fa);
91 }
92 return indirectCallNode.call(frame, ct, ForeignAccessArguments.create(truffleObject, arguments));
93 }
94
95 @TruffleBoundary
96 private RuntimeException messageNotRecognizedException(final ForeignAccess fa) {
97 throw new IllegalStateException("Message " + access + " not recognized by " + fa);
98 }
99 }
100
101 class CachedObjectAccessNode extends ObjectAccessNode {
102 @Child private DirectCallNode callTarget;
103 @Child private ObjectAccessNode next;
104
105 private final ForeignAccess languageCheck;
106
107 protected CachedObjectAccessNode(DirectCallNode callTarget, ObjectAccessNode next, ForeignAccess languageCheck) {
108 this.callTarget = callTarget;
109 this.next = next;
110 this.languageCheck = languageCheck;
111 this.callTarget.forceInlining();
112 }
113
114 protected CachedObjectAccessNode(CachedObjectAccessNode prev) {
115 this(prev.callTarget, prev.next, prev.languageCheck);
116 }
117
118 @Override
119 public Object executeWith(VirtualFrame frame, TruffleObject receiver, Object[] arguments) {
120 return doAccess(frame, receiver, arguments);
121 }
122
123 private Object doAccess(VirtualFrame frame, TruffleObject receiver, Object[] arguments) {
124 if (languageCheck.canHandle(receiver)) {
125 return callTarget.call(frame, ForeignAccessArguments.create(receiver, arguments));
126 } else {
127 return doNext(frame, receiver, arguments);
128 }
129 }
130
131 private Object doNext(VirtualFrame frame, TruffleObject receiver, Object[] arguments) {
132 return next.executeWith(frame, receiver, arguments);
133 }
134 }