Mercurial > hg > graal-compiler
diff 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 |
line wrap: on
line diff
--- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/server/ReplacingStreams.java Fri Apr 08 13:47:56 2011 +0200 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/server/ReplacingStreams.java Mon Apr 11 10:37:24 2011 +0200 @@ -21,40 +21,79 @@ package com.sun.hotspot.c1x.server; import java.io.*; +import java.lang.reflect.*; import java.util.*; import com.sun.cri.ci.*; +import com.sun.hotspot.c1x.*; import com.sun.hotspot.c1x.Compiler; public class ReplacingStreams { - IdentityHashMap<Object, Long> objectMap = new IdentityHashMap<Object, Long>(); - ArrayList<Object> objectList = new ArrayList<Object>(); + + private IdentityHashMap<Object, Placeholder> objectMap = new IdentityHashMap<Object, Placeholder>(); + private ArrayList<Object> objectList = new ArrayList<Object>(); - public static class Container implements Serializable { + private ReplacingOutputStream output; + private ReplacingInputStream input; + + private InvocationSocket invocation; - public final Class<?> clazz; - public final Object[] values; + public ReplacingStreams(OutputStream outputStream, InputStream inputStream) throws IOException { + output = new ReplacingOutputStream(new BufferedOutputStream(outputStream)); + // required, because creating an ObjectOutputStream writes a header, but doesn't flush the stream + output.flush(); + input = new ReplacingInputStream(new BufferedInputStream(inputStream)); + invocation = new InvocationSocket(output, input); - public Container(Class<?> clazz, Object... values) { - this.clazz = clazz; - this.values = values; - } + addStaticObject(CiValue.IllegalValue); } - public static enum PlaceholderType { - CI_CONSTANT_CONTENTS, RI_TYPE + public void setInvocationSocket(InvocationSocket invocation) { + this.invocation = invocation; + } + + public ReplacingOutputStream getOutput() { + return output; + } + + public ReplacingInputStream getInput() { + return input; + } + + public InvocationSocket getInvocation() { + return invocation; + } + + private void addStaticObject(Object obj) { + int id = objectList.size(); + objectList.add(obj); + objectMap.put(obj, new Placeholder(id)); } public static class Placeholder implements Serializable { public final int id; - public final PlaceholderType type; - public Placeholder(int id, PlaceholderType type) { + public Placeholder(int id) { this.id = id; - this.type = type; } + @Override + public String toString() { + return "#<" + id + ">"; + } + } + + public static class NewRemoteCallPlaceholder implements Serializable { + + public final Class<?>[] interfaces; + + public NewRemoteCallPlaceholder(Class<?>[] interfaces) { + this.interfaces = interfaces; + } + } + + public static class NewDummyPlaceholder implements Serializable { } /** @@ -75,33 +114,30 @@ @Override protected Object resolveObject(Object obj) throws IOException { - if (obj instanceof Container) { - Container c = (Container) obj; - if (c.clazz == CiConstant.class) { - return CiConstant.forBoxed((CiKind) c.values[0], c.values[1]); - } else if (c.clazz == CiValue.class) { - return CiValue.IllegalValue; - } else if (c.clazz == Compiler.class) { - assert compiler != null; - return compiler; - } - throw new RuntimeException("unexpected container class: " + c.clazz); - } /*else if (obj instanceof Placeholder) { - Placeholder ph = (Placeholder)obj; - if (ph.id >= objectList.size()) { - assert ph.id == objectList.size(); - switch (ph.type) { - case CI_CONSTANT_CONTENTS: - objectList.add(ph); - break; - case RI_TYPE: - objectList.add(e) - break; - } - } - return objectList.get(ph.id); + // see ReplacingInputStream.replaceObject for details on when these types of objects are created + + if (obj instanceof Placeholder) { + Placeholder placeholder = (Placeholder) obj; + obj = objectList.get(placeholder.id); + return obj; + } - }*/ + if (obj instanceof NewRemoteCallPlaceholder) { + NewRemoteCallPlaceholder newPlaceholder = (NewRemoteCallPlaceholder) obj; + Placeholder placeholder = new Placeholder(objectList.size()); + obj = Proxy.newProxyInstance(getClass().getClassLoader(), newPlaceholder.interfaces, invocation.new Handler(placeholder)); + objectMap.put(obj, placeholder); + objectList.add(obj); + return obj; + } + + if (obj instanceof NewDummyPlaceholder) { + obj = new Placeholder(objectList.size()); + objectMap.put(obj, (Placeholder) obj); + objectList.add(obj); + return obj; + } + return obj; } } @@ -118,17 +154,58 @@ @Override protected Object replaceObject(Object obj) throws IOException { - Class<? extends Object> clazz = obj.getClass(); - if (clazz == CiConstant.class) { - CiConstant o = (CiConstant) obj; - return new Container(clazz, o.kind, o.boxedValue()); - } else if (obj == CiValue.IllegalValue) { - return new Container(CiValue.class); - } else if (obj instanceof Compiler) { - return new Container(Compiler.class); + // is the object a known instance? + Placeholder placeholder = objectMap.get(obj); + if (placeholder != null) { + return placeholder; + } + + // is the object an instance of a class that will always be executed remotely? + if (obj instanceof Remote) { + return createRemoteCallPlaceholder(obj); + } + + // is the object a constant of object type? + if (obj.getClass() == CiConstant.class) { + System.out.println("CiConstant " + obj); + CiConstant constant = (CiConstant) obj; + // don't replace if the object already is a placeholder + if (constant.kind == CiKind.Object && !(constant.asObject() instanceof Placeholder) && constant.asObject() != null) { + return CiConstant.forObject(createDummyPlaceholder(constant.asObject())); + } } return obj; } } + public static Class<?>[] getAllInterfaces(Class<?> clazz) { + HashSet<Class< ? >> interfaces = new HashSet<Class<?>>(); + getAllInterfaces(clazz, interfaces); + return interfaces.toArray(new Class<?>[interfaces.size()]); + } + + private static void getAllInterfaces(Class<?> clazz, HashSet<Class<?>> interfaces) { + for (Class< ? > iface : clazz.getInterfaces()) { + if (!interfaces.contains(iface)) { + interfaces.add(iface); + getAllInterfaces(iface, interfaces); + } + } + if (clazz.getSuperclass() != null) { + getAllInterfaces(clazz.getSuperclass(), interfaces); + } + } + + private Object createRemoteCallPlaceholder(Object obj) { + // collect all interfaces that this object's class implements (proxies only support interfaces) + objectMap.put(obj, new Placeholder(objectList.size())); + objectList.add(obj); + return new NewRemoteCallPlaceholder(getAllInterfaces(obj.getClass())); + } + + public Object createDummyPlaceholder(Object obj) { + objectMap.put(obj, new Placeholder(objectList.size())); + objectList.add(obj); + return new NewDummyPlaceholder(); + } }