Skip to content

Commit

Permalink
8332243: Value classes implementing Cloneable
Browse files Browse the repository at this point in the history
Reviewed-by: dsimms
  • Loading branch information
fparain committed Jun 17, 2024
1 parent 2592304 commit db494c6
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 30 deletions.
24 changes: 0 additions & 24 deletions src/hotspot/share/classfile/classFileParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4310,25 +4310,6 @@ void OopMapBlocksBuilder::print_value_on(outputStream* st) const {
print_on(st);
}

void ClassFileParser::throwInlineTypeLimitation(THREAD_AND_LOCATION_DECL,
const char* msg,
const Symbol* name,
const Symbol* sig) const {

ResourceMark rm(THREAD);
if (name == nullptr || sig == nullptr) {
Exceptions::fthrow(THREAD_AND_LOCATION_ARGS,
vmSymbols::java_lang_ClassFormatError(),
"class: %s - %s", _class_name->as_C_string(), msg);
}
else {
Exceptions::fthrow(THREAD_AND_LOCATION_ARGS,
vmSymbols::java_lang_ClassFormatError(),
"\"%s\" sig: \"%s\" class: %s - %s", name->as_C_string(), sig->as_C_string(),
_class_name->as_C_string(), msg);
}
}

void ClassFileParser::set_precomputed_flags(InstanceKlass* ik) {
assert(ik != nullptr, "invariant");

Expand Down Expand Up @@ -4363,11 +4344,6 @@ void ClassFileParser::set_precomputed_flags(InstanceKlass* ik) {
// Check if this klass supports the java.lang.Cloneable interface
if (vmClasses::Cloneable_klass_loaded()) {
if (ik->is_subtype_of(vmClasses::Cloneable_klass())) {
if (ik->is_inline_klass()) {
JavaThread *THREAD = JavaThread::current();
throwInlineTypeLimitation(THREAD_AND_LOCATION, "Inline Types do not support Cloneable");
return;
}
ik->set_is_cloneable();
}
}
Expand Down
5 changes: 0 additions & 5 deletions src/hotspot/share/classfile/classFileParser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -478,11 +478,6 @@ class ClassFileParser {
const Symbol* sig,
TRAPS) const;

void throwInlineTypeLimitation(THREAD_AND_LOCATION_DECL,
const char* msg,
const Symbol* name = nullptr,
const Symbol* sig = nullptr) const;

void verify_constantvalue(const ConstantPool* const cp,
int constantvalue_index,
int signature_index,
Expand Down
7 changes: 6 additions & 1 deletion src/hotspot/share/prims/jvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -720,13 +720,18 @@ JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
// All arrays are considered to be cloneable (See JLS 20.1.5).
// All j.l.r.Reference classes are considered non-cloneable.
if (!klass->is_cloneable() ||
klass->is_inline_klass() ||
(klass->is_instance_klass() &&
InstanceKlass::cast(klass)->reference_type() != REF_NONE)) {
ResourceMark rm(THREAD);
THROW_MSG_0(vmSymbols::java_lang_CloneNotSupportedException(), klass->external_name());
}

if (klass->is_inline_klass()) {
// Value instances have no identity, so return the current instance instead of allocating a new one
// Value classes cannot have finalizers, so the method can return immediately
return JNIHandles::make_local(THREAD, obj());
}

// Make shallow object copy
const size_t size = obj->size();
oop new_obj_oop = nullptr;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

/**
* @test TestCloneableValue
* @library /test/lib
* @enablePreview
* @compile TestCloneableValue.java
* @run main/othervm runtime.valhalla.inlinetypes.TestCloneableValue
*/

package runtime.valhalla.inlinetypes;

import jdk.test.lib.Asserts;

import java.util.ArrayList;

public class TestCloneableValue {

static value class SimpleValue implements Cloneable {
int i;
double j;

public SimpleValue() {
i = 42;
j = Math.E;
}

@Override
public Object clone() throws CloneNotSupportedException {
return super.clone(); // delegate to Object's method performing a shallow copy
}
}

static value class NotSoSimpleValue implements Cloneable {
ArrayList list;

public NotSoSimpleValue() {
list = new ArrayList<>();
}

private NotSoSimpleValue(ArrayList l) {
list = l;
}

@Override
public Object clone() throws CloneNotSupportedException {
return new NotSoSimpleValue((ArrayList)list.clone());
}
}

public static void main(String[] args) {
var sv = new SimpleValue();
try {
var c1 = sv.clone();
Asserts.assertEQ(sv, c1);
Asserts.assertEQ(sv.hashCode(), c1.hashCode());
} catch(CloneNotSupportedException e) {
Asserts.fail("Unexpected exception", e);
}

var nssv = new NotSoSimpleValue();
try {
var c2 = nssv.clone();
Asserts.assertNE(nssv, c2);
Asserts.assertEQ(nssv.hashCode(), c2.hashCode());
} catch(CloneNotSupportedException e) {
Asserts.fail("Unexpected exception", e);
}
}
}

0 comments on commit db494c6

Please sign in to comment.