-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement Object.clone()
#674
Comments
The overall approach of storing the instance size per class makes sense to me with the special handling of the header fields and memcpy of the body. We'll need to clear the instance hashcode and the lockword in the cloned object as well as any Couldn't we add an |
We could, in which case we'd need an intrinsic (or something) to read the array length ( |
We can write the array case entirely in normal Java: Class<?> type = obj.getClass().getComponentType();
int length = Array.getLength(obj);
Object cloned = Array.newInstance(type, length);
System.arraycopy(obj, 0, cloned, 0, length);
return cloned; (Borrowing the approach used in OpenJ9's JITHelpers class) This assumes we're willing to support reflective array creation (and I don't see why we wouldn't given we'll have all the data to support it by default) |
For the memcpy cases, we'll need to ensure that we can't hit a safepoint while doing the copy or the GC may see uninitialized / partly initialized objects. One way to avoid this is to write the code to do slot by slot copies |
OTOH if the (reference) array is very large it could end up blocking safepoints for an unreasonably long time, could it not? |
I don't think that's an issue. The array would need to be incredibly large and the system would need to have severely constrained memory bandwidth and even then... it's never come up to my knowledge. The benefit of reusing arraycopy is that we only need to get the gc barriers and array store checks right in one place rather than needing to duplicate that code... |
Do we need to keep the clone node during the ADD phase so we can interpret it? Then lower to the VMHelper call in a later phase? In any case, I'm going to start knocking off the easy parts of this (starting with the field on the java.lang.Class instance) |
A simpler (but less optimal) solution is for reference arrays to zero the backing storage of the new array, then call |
TBH I think we should eliminate the
FWIW the simple proposal from Dan above would already do this, since |
In addition to a field for instance size, I believe we also need to add a field for alignment to |
One of the Big Two sources of compilation warnings right now is because
Object.clone()
is not fully implemented.In order to implement this method, I propose something like this:
Class
which will be populated with the run time size of the corresponding object instanceObject$_native
implementation forObject.clone()
whose implementation allocates an object of the size from the corresponding class, and uses the LLVMmemcpy
intrinsic to populate that object (be sure to exclude the object header so it doesn't get overwritten), ending with a release fenceClone
node and corresponding intrinsics completely from the codebaseThe nodes needed to implement this method - specifically, reading an injected field from class and calling the
memcpy
intrinsic are not particularly easy to do on the Java side yet. For reading the injected field, we could define an intrinsic which returns the size given the correspondingClass
object. For thememcpy
intrinsic, I think we need to consider adding an LLVM runtime library module which defines a few intrinsic methods, starting withmemcpy
. Alternatively the standard Cmemcpy
could be used. The release fence is accomplished by callingVarHandle.releaseFence()
.Update: We do not presently have a good way to define native method bindings which apply to the array classes. We'll need to add a (public) override of
clone
onto the base array class at a minimum, or else overrides on to each subclass, when the core classes are created. The method bodies could be created by hand inCoreClasses
, or, if someone wants to go through the trouble, the could ensure that e.g. bindinginternal_array$_native
works correctly and implement the overrides there.The text was updated successfully, but these errors were encountered: