Mercurial > hg > graal-compiler
comparison c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/server/ReplacingStreams.java @ 2288:8c426c2891c8
client/server: new interface Remote marks classes that should not be serialized, but called remotely
author | Lukas Stadler <lukas.stadler@jku.at> |
---|---|
date | Mon, 11 Apr 2011 10:37:24 +0200 |
parents | 762de4b26788 |
children | 160aacf936ad |
comparison
equal
deleted
inserted
replaced
2287:66ffa0e99cef | 2288:8c426c2891c8 |
---|---|
19 * Company, Ltd. | 19 * Company, Ltd. |
20 */ | 20 */ |
21 package com.sun.hotspot.c1x.server; | 21 package com.sun.hotspot.c1x.server; |
22 | 22 |
23 import java.io.*; | 23 import java.io.*; |
24 import java.lang.reflect.*; | |
24 import java.util.*; | 25 import java.util.*; |
25 | 26 |
26 import com.sun.cri.ci.*; | 27 import com.sun.cri.ci.*; |
28 import com.sun.hotspot.c1x.*; | |
27 import com.sun.hotspot.c1x.Compiler; | 29 import com.sun.hotspot.c1x.Compiler; |
28 | 30 |
29 public class ReplacingStreams { | 31 public class ReplacingStreams { |
30 IdentityHashMap<Object, Long> objectMap = new IdentityHashMap<Object, Long>(); | 32 |
31 ArrayList<Object> objectList = new ArrayList<Object>(); | 33 private IdentityHashMap<Object, Placeholder> objectMap = new IdentityHashMap<Object, Placeholder>(); |
32 | 34 private ArrayList<Object> objectList = new ArrayList<Object>(); |
33 public static class Container implements Serializable { | 35 |
34 | 36 private ReplacingOutputStream output; |
35 public final Class<?> clazz; | 37 private ReplacingInputStream input; |
36 public final Object[] values; | 38 |
37 | 39 private InvocationSocket invocation; |
38 public Container(Class<?> clazz, Object... values) { | 40 |
39 this.clazz = clazz; | 41 public ReplacingStreams(OutputStream outputStream, InputStream inputStream) throws IOException { |
40 this.values = values; | 42 output = new ReplacingOutputStream(new BufferedOutputStream(outputStream)); |
41 } | 43 // required, because creating an ObjectOutputStream writes a header, but doesn't flush the stream |
42 } | 44 output.flush(); |
43 | 45 input = new ReplacingInputStream(new BufferedInputStream(inputStream)); |
44 public static enum PlaceholderType { | 46 invocation = new InvocationSocket(output, input); |
45 CI_CONSTANT_CONTENTS, RI_TYPE | 47 |
48 addStaticObject(CiValue.IllegalValue); | |
49 } | |
50 | |
51 public void setInvocationSocket(InvocationSocket invocation) { | |
52 this.invocation = invocation; | |
53 } | |
54 | |
55 public ReplacingOutputStream getOutput() { | |
56 return output; | |
57 } | |
58 | |
59 public ReplacingInputStream getInput() { | |
60 return input; | |
61 } | |
62 | |
63 public InvocationSocket getInvocation() { | |
64 return invocation; | |
65 } | |
66 | |
67 private void addStaticObject(Object obj) { | |
68 int id = objectList.size(); | |
69 objectList.add(obj); | |
70 objectMap.put(obj, new Placeholder(id)); | |
46 } | 71 } |
47 | 72 |
48 public static class Placeholder implements Serializable { | 73 public static class Placeholder implements Serializable { |
49 | 74 |
50 public final int id; | 75 public final int id; |
51 public final PlaceholderType type; | 76 |
52 | 77 public Placeholder(int id) { |
53 public Placeholder(int id, PlaceholderType type) { | |
54 this.id = id; | 78 this.id = id; |
55 this.type = type; | 79 } |
56 } | 80 |
57 | 81 @Override |
82 public String toString() { | |
83 return "#<" + id + ">"; | |
84 } | |
85 } | |
86 | |
87 public static class NewRemoteCallPlaceholder implements Serializable { | |
88 | |
89 public final Class<?>[] interfaces; | |
90 | |
91 public NewRemoteCallPlaceholder(Class<?>[] interfaces) { | |
92 this.interfaces = interfaces; | |
93 } | |
94 } | |
95 | |
96 public static class NewDummyPlaceholder implements Serializable { | |
58 } | 97 } |
59 | 98 |
60 /** | 99 /** |
61 * Replaces certain cir objects that cannot easily be made Serializable. | 100 * Replaces certain cir objects that cannot easily be made Serializable. |
62 */ | 101 */ |
73 this.compiler = compiler; | 112 this.compiler = compiler; |
74 } | 113 } |
75 | 114 |
76 @Override | 115 @Override |
77 protected Object resolveObject(Object obj) throws IOException { | 116 protected Object resolveObject(Object obj) throws IOException { |
78 if (obj instanceof Container) { | 117 // see ReplacingInputStream.replaceObject for details on when these types of objects are created |
79 Container c = (Container) obj; | 118 |
80 if (c.clazz == CiConstant.class) { | 119 if (obj instanceof Placeholder) { |
81 return CiConstant.forBoxed((CiKind) c.values[0], c.values[1]); | 120 Placeholder placeholder = (Placeholder) obj; |
82 } else if (c.clazz == CiValue.class) { | 121 obj = objectList.get(placeholder.id); |
83 return CiValue.IllegalValue; | 122 return obj; |
84 } else if (c.clazz == Compiler.class) { | 123 } |
85 assert compiler != null; | 124 |
86 return compiler; | 125 if (obj instanceof NewRemoteCallPlaceholder) { |
87 } | 126 NewRemoteCallPlaceholder newPlaceholder = (NewRemoteCallPlaceholder) obj; |
88 throw new RuntimeException("unexpected container class: " + c.clazz); | 127 Placeholder placeholder = new Placeholder(objectList.size()); |
89 } /*else if (obj instanceof Placeholder) { | 128 obj = Proxy.newProxyInstance(getClass().getClassLoader(), newPlaceholder.interfaces, invocation.new Handler(placeholder)); |
90 Placeholder ph = (Placeholder)obj; | 129 objectMap.put(obj, placeholder); |
91 if (ph.id >= objectList.size()) { | 130 objectList.add(obj); |
92 assert ph.id == objectList.size(); | 131 return obj; |
93 switch (ph.type) { | 132 } |
94 case CI_CONSTANT_CONTENTS: | 133 |
95 objectList.add(ph); | 134 if (obj instanceof NewDummyPlaceholder) { |
96 break; | 135 obj = new Placeholder(objectList.size()); |
97 case RI_TYPE: | 136 objectMap.put(obj, (Placeholder) obj); |
98 objectList.add(e) | 137 objectList.add(obj); |
99 break; | 138 return obj; |
100 } | 139 } |
101 } | 140 |
102 return objectList.get(ph.id); | |
103 | |
104 }*/ | |
105 return obj; | 141 return obj; |
106 } | 142 } |
107 } | 143 } |
108 | 144 |
109 /** | 145 /** |
116 enableReplaceObject(true); | 152 enableReplaceObject(true); |
117 } | 153 } |
118 | 154 |
119 @Override | 155 @Override |
120 protected Object replaceObject(Object obj) throws IOException { | 156 protected Object replaceObject(Object obj) throws IOException { |
121 Class<? extends Object> clazz = obj.getClass(); | 157 // is the object a known instance? |
122 if (clazz == CiConstant.class) { | 158 Placeholder placeholder = objectMap.get(obj); |
123 CiConstant o = (CiConstant) obj; | 159 if (placeholder != null) { |
124 return new Container(clazz, o.kind, o.boxedValue()); | 160 return placeholder; |
125 } else if (obj == CiValue.IllegalValue) { | 161 } |
126 return new Container(CiValue.class); | 162 |
127 } else if (obj instanceof Compiler) { | 163 // is the object an instance of a class that will always be executed remotely? |
128 return new Container(Compiler.class); | 164 if (obj instanceof Remote) { |
165 return createRemoteCallPlaceholder(obj); | |
166 } | |
167 | |
168 // is the object a constant of object type? | |
169 if (obj.getClass() == CiConstant.class) { | |
170 System.out.println("CiConstant " + obj); | |
171 CiConstant constant = (CiConstant) obj; | |
172 // don't replace if the object already is a placeholder | |
173 if (constant.kind == CiKind.Object && !(constant.asObject() instanceof Placeholder) && constant.asObject() != null) { | |
174 return CiConstant.forObject(createDummyPlaceholder(constant.asObject())); | |
175 } | |
129 } | 176 } |
130 return obj; | 177 return obj; |
131 } | 178 } |
132 } | 179 } |
133 | 180 |
181 public static Class<?>[] getAllInterfaces(Class<?> clazz) { | |
182 HashSet<Class< ? >> interfaces = new HashSet<Class<?>>(); | |
183 getAllInterfaces(clazz, interfaces); | |
184 return interfaces.toArray(new Class<?>[interfaces.size()]); | |
185 } | |
186 | |
187 private static void getAllInterfaces(Class<?> clazz, HashSet<Class<?>> interfaces) { | |
188 for (Class< ? > iface : clazz.getInterfaces()) { | |
189 if (!interfaces.contains(iface)) { | |
190 interfaces.add(iface); | |
191 getAllInterfaces(iface, interfaces); | |
192 } | |
193 } | |
194 if (clazz.getSuperclass() != null) { | |
195 getAllInterfaces(clazz.getSuperclass(), interfaces); | |
196 } | |
197 } | |
198 | |
199 private Object createRemoteCallPlaceholder(Object obj) { | |
200 // collect all interfaces that this object's class implements (proxies only support interfaces) | |
201 objectMap.put(obj, new Placeholder(objectList.size())); | |
202 objectList.add(obj); | |
203 return new NewRemoteCallPlaceholder(getAllInterfaces(obj.getClass())); | |
204 } | |
205 | |
206 public Object createDummyPlaceholder(Object obj) { | |
207 objectMap.put(obj, new Placeholder(objectList.size())); | |
208 objectList.add(obj); | |
209 return new NewDummyPlaceholder(); | |
210 } | |
134 } | 211 } |