Skip to content

Commit

Permalink
remove Clone node and use class lib implementation
Browse files Browse the repository at this point in the history
Fixes qbicc#744.
Fixes qbicc#674.
  • Loading branch information
dgrove-oss committed Dec 20, 2021
1 parent 7ea3d27 commit 8a2ed21
Show file tree
Hide file tree
Showing 11 changed files with 11 additions and 174 deletions.
2 changes: 0 additions & 2 deletions compiler/src/main/java/org/qbicc/graph/BasicBlockBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -389,8 +389,6 @@ default ValueHandle pointerHandle(Value pointer) {

Value multiNewArray(ArrayTypeDescriptor desc, List<Value> dimensions);

Value clone(Value object);

default Value load(ValueHandle handle) {
return load(handle, SinglePlain);
}
Expand Down
60 changes: 0 additions & 60 deletions compiler/src/main/java/org/qbicc/graph/Clone.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -320,10 +320,6 @@ public Value multiNewArray(final ArrayTypeDescriptor desc, final List<Value> dim
return getDelegate().multiNewArray(desc, dimensions);
}

public Value clone(final Value object) {
return getDelegate().clone(object);
}

public Value load(final ValueHandle handle, final ReadAccessMode accessMode) {
return getDelegate().load(handle, accessMode);
}
Expand Down
5 changes: 0 additions & 5 deletions compiler/src/main/java/org/qbicc/graph/Node.java
Original file line number Diff line number Diff line change
Expand Up @@ -504,11 +504,6 @@ public Value visit(final Copier param, final ClassOf node) {
return param.getBlockBuilder().classOf(param.copyValue(node.getInput()), param.copyValue(node.getDimensions()));
}

public Value visit(final Copier param, final Clone node) {
param.copyNode(node.getDependency());
return param.getBlockBuilder().clone(param.copyValue(node.getInput()));
}

public Value visit(final Copier param, final CountLeadingZeros node) {
return param.getBlockBuilder().countLeadingZeros(param.copyValue(node.getInput()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -609,10 +609,6 @@ public Value multiNewArray(final ArrayTypeDescriptor desc, final List<Value> dim
throw new IllegalStateException("New of unresolved array type");
}

public Value clone(final Value object) {
return asDependency(new Clone(callSite, element, line, bci, requireDependency(), object));
}

public Value load(final ValueHandle handle, final ReadAccessMode mode) {
return asDependency(new Load(callSite, element, line, bci, requireDependency(), handle, mode));
}
Expand Down
8 changes: 0 additions & 8 deletions compiler/src/main/java/org/qbicc/graph/ValueVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,6 @@ default R visit(T param, ClassOf node) {
return visitUnknown(param, node);
}

default R visit(T param, Clone node) {
return visitUnknown(param, node);
}

default R visit(T param, Comp node) {
return visitUnknown(param, node);
}
Expand Down Expand Up @@ -455,10 +451,6 @@ default R visit(T param, ClassOf node) {
return getDelegateValueVisitor().visit(param, node);
}

default R visit(T param, Clone node) {
return getDelegateValueVisitor().visit(param, node);
}

default R visit(T param, Comp node) {
return getDelegateValueVisitor().visit(param, node);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import org.qbicc.graph.CheckCast;
import org.qbicc.graph.InitCheck;
import org.qbicc.graph.ClassOf;
import org.qbicc.graph.Clone;
import org.qbicc.graph.Cmp;
import org.qbicc.graph.CmpAndSwap;
import org.qbicc.graph.CmpG;
Expand Down Expand Up @@ -1454,13 +1453,6 @@ public Void visit(VmThreadImpl thread, InitCheck node) {
throw new UnsupportedOperationException();
}

@Override
public Object visit(VmThreadImpl thread, Clone node) {
// todo: implement according to #674
VmObjectImpl original = (VmObjectImpl) require(node.getInput());
return original.clone();
}

public Object visit(final VmThreadImpl param, final Comp node) {
Value input = node.getInput();
ValueType inputType = input.getType();
Expand Down
11 changes: 11 additions & 0 deletions interpreter/src/main/java/org/qbicc/interpreter/impl/VmImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import org.qbicc.interpreter.VmReferenceArray;
import org.qbicc.interpreter.VmString;
import org.qbicc.interpreter.VmThread;
import org.qbicc.interpreter.VmThrowable;
import org.qbicc.machine.arch.Platform;
import org.qbicc.plugin.coreclasses.CoreClasses;
import org.qbicc.plugin.layout.Layout;
Expand Down Expand Up @@ -383,6 +384,16 @@ public void initialize() {
// Object
VmClassImpl objectClass = bootstrapClassLoader.loadClass("java/lang/Object");

objectClass.registerInvokable("clone", (thread, target, args) -> {
VmClassImpl cloneableClass = bootstrapClassLoader.loadClass("java/lang/Cloneable");
if (!target.getVmClass().getTypeDefinition().isSubtypeOf(cloneableClass.getTypeDefinition())) {
VmClassImpl cnse = bootstrapClassLoader.loadClass("java/lang/CloneNotSupportedException");
VmThrowable throwable = manuallyInitialize((VmThrowable) cnse.newInstance());
((VmThreadImpl)thread).setThrown(throwable);
throw new Thrown(throwable);
}
return ((VmObjectImpl)target).clone();
});
objectClass.registerInvokable("wait", 0, (thread, target, args) -> {
try {
((VmObjectImpl)target).getCondition().await();
Expand Down
14 changes: 0 additions & 14 deletions plugins/dot/src/main/java/org/qbicc/plugin/dot/DotNodeVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import org.qbicc.graph.CastValue;
import org.qbicc.graph.InitCheck;
import org.qbicc.graph.ClassOf;
import org.qbicc.graph.Clone;
import org.qbicc.graph.Cmp;
import org.qbicc.graph.CmpAndSwap;
import org.qbicc.graph.CmpG;
Expand Down Expand Up @@ -844,19 +843,6 @@ public String visit(final Appendable param, final ClassOf node) {
return name;
}

public String visit(final Appendable param, final Clone node) {
String name = register(node);
appendTo(param, name);
attr(param, "shape", "rectangle");
attr(param, "label", "clone");
attr(param, "fixedsize", "shape");
nl(param);
dependencyList.add(name);
processDependency(param, node.getDependency());
addEdge(param, node, node.getInput(), EdgeType.VALUE_DEPENDENCY);
return name;
}

public String visit(final Appendable param, final Comp node) {
return node(param, "~", node);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import org.qbicc.context.CompilationContext;
import org.qbicc.graph.BasicBlockBuilder;
import org.qbicc.graph.BlockEarlyTermination;
import org.qbicc.graph.DelegatingBasicBlockBuilder;
import org.qbicc.graph.Value;
import org.qbicc.graph.literal.IntegerLiteral;
Expand All @@ -14,19 +13,14 @@
import org.qbicc.plugin.coreclasses.CoreClasses;
import org.qbicc.plugin.layout.Layout;
import org.qbicc.plugin.layout.LayoutInfo;
import org.qbicc.type.ArrayObjectType;
import org.qbicc.type.ClassObjectType;
import org.qbicc.type.CompoundType;
import org.qbicc.type.IntegerType;
import org.qbicc.type.PrimitiveArrayObjectType;
import org.qbicc.type.ReferenceArrayObjectType;
import org.qbicc.type.ValueType;
import org.qbicc.type.WordType;
import org.qbicc.type.definition.LoadedTypeDefinition;
import org.qbicc.type.definition.element.MethodElement;

import static org.qbicc.graph.atomic.AccessModes.GlobalRelease;

/**
*
*/
Expand Down Expand Up @@ -108,40 +102,4 @@ private Value allocateArray(CompoundType compoundType, Value size, long elementS

return ptrVal;
}

public Value clone(final Value object) {
ValueType objType = object.getType();
NoGc noGc = NoGc.get(ctxt);
Layout layout = Layout.get(ctxt);
if (objType instanceof ClassObjectType) {
// TODO: This implementation is actually not correct, because it is cloning based
// on the static type of the value; not the actual runtime type.
// I would remove it entirely, except it is actually needed to pass one of our
// integration tests (which is using Enums).
ClassObjectType type = (ClassObjectType) objType;
LayoutInfo info = layout.getInstanceLayoutInfo(type.getDefinition());
LiteralFactory lf = ctxt.getLiteralFactory();
CompoundType compoundType = info.getCompoundType();
IntegerLiteral size = lf.literalOf(compoundType.getSize());
IntegerLiteral align = lf.literalOf(compoundType.getAlign());
Value ptrVal;
if (type.isSubtypeOf(noGc.getStackObjectType())) {
ptrVal = stackAllocate(compoundType, lf.literalOf(1), align);
} else {
MethodElement method = noGc.getAllocateMethod();
ptrVal = notNull(call(staticMethod(method, method.getDescriptor(), method.getType()), List.of(size, align)));
}
// TODO: replace with field-by-field copy once we have a redundant assignment elimination optimization
// TODO: if/when we put a thinlock, default hashcode, or GC state bits in the object header we need to properly initialize them.
MethodElement method = noGc.getCopyMethod();
call(staticMethod(method, method.getDescriptor(), method.getType()), List.of(ptrVal, valueConvert(object, (WordType) ptrVal.getType()), size));
fence(GlobalRelease);
return valueConvert(ptrVal, type.getReference());
} else if (objType instanceof ArrayObjectType) {
ctxt.error(getLocation(), "Array allocations not supported until layout supports arrays");
throw new BlockEarlyTermination(unreachable());
} else {
return super.clone(object);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1028,33 +1028,6 @@ public static void registerJavaLangObjectIntrinsics(CompilationContext ctxt) {
ctxt.getLiteralFactory().zeroInitializerLiteralOfType(ctxt.getTypeSystem().getVoidType()); // Do nothing
intrinsics.registerIntrinsic(objDesc, "notifyAll", notifyAllDesc, notifyAllIntrinsic);

InstanceIntrinsic clone = (builder, instance, target, arguments) -> {
ValueType instanceType = instance.getType();
if (instanceType instanceof ReferenceType) {
ReferenceType referenceType = (ReferenceType) instanceType;
InterfaceObjectType cloneable = classContext.findDefinedType("java/lang/Cloneable").load().getInterfaceType();
if (! referenceType.instanceOf(cloneable)) {
// synthesize a run time check
BlockLabel goAhead = new BlockLabel();
BlockLabel throwIt = new BlockLabel();
builder.if_(builder.instanceOf(instance, cloneable, 0), goAhead, throwIt);
try {
builder.begin(throwIt);
ClassTypeDescriptor cnseDesc = ClassTypeDescriptor.synthesize(classContext, "java/lang/CloneNotSupportedException");
Value cnse = builder.getFirstBuilder().new_(cnseDesc);
builder.call(builder.getFirstBuilder().constructorOf(cnse, cnseDesc, MethodDescriptor.VOID_METHOD_DESCRIPTOR), List.of());
builder.throw_(cnse);
} catch (BlockEarlyTermination ignored) {
// continue
}
builder.begin(goAhead);
}
}
return builder.clone(instance);
};

intrinsics.registerIntrinsic(objDesc, "clone", MethodDescriptor.synthesize(classContext, objDesc, List.of()), clone);

// stub - public final native void wait(long timeoutMillis)
MethodDescriptor waitDesc = MethodDescriptor.synthesize(classContext, BaseTypeDescriptor.V, List.of(BaseTypeDescriptor.J));
InstanceIntrinsic wait = (builder, instance, target, arguments) -> ctxt.getLiteralFactory().zeroInitializerLiteralOfType(target.getExecutable().getType().getReturnType());
Expand Down

0 comments on commit 8a2ed21

Please sign in to comment.