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 }