Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/hotspot/share/ci/ciField.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -499,9 +499,7 @@ bool ciField::is_call_site_target() {

bool ciField::is_autobox_cache() {
ciSymbol* klass_name = holder()->name();
// The box cache is disabled when boxes are value classes.
return (!Arguments::is_valhalla_enabled() &&
name() == ciSymbols::cache_field_name() &&
return (name() == ciSymbols::cache_field_name() &&
holder()->uses_default_loader() &&
(klass_name == ciSymbols::java_lang_Character_CharacterCache() ||
klass_name == ciSymbols::java_lang_Byte_ByteCache() ||
Expand Down
13 changes: 6 additions & 7 deletions src/hotspot/share/runtime/deoptimization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1146,14 +1146,14 @@ template<typename PrimitiveType, typename CacheType, typename BoxType> class Box
protected:
static BoxCache<PrimitiveType, CacheType, BoxType> *_singleton;
BoxCache(Thread* thread) {
assert(!Arguments::is_valhalla_enabled(), "Should not use box caches with enable preview");
InstanceKlass* ik = BoxCacheBase<CacheType>::find_cache_klass(thread, CacheType::symbol());
if (ik->is_in_error_state()) {
_low = 1;
_high = 0;
_cache = nullptr;
} else {
refArrayOop cache = CacheType::cache(ik);
assert(!cache->is_flatArray(), "box caches must be reference arrays");
assert(cache->length() > 0, "Empty cache");
_low = BoxType::value(cache->obj_at(0));
_high = checked_cast<PrimitiveType>(_low + cache->length() - 1);
Expand Down Expand Up @@ -1218,8 +1218,11 @@ class BooleanBoxCache : public BoxCacheBase<java_lang_Boolean> {
_true_cache = nullptr;
_false_cache = nullptr;
} else {
_true_cache = JNIHandles::make_global(Handle(thread, java_lang_Boolean::get_TRUE(ik)));
_false_cache = JNIHandles::make_global(Handle(thread, java_lang_Boolean::get_FALSE(ik)));
oop true_cache = java_lang_Boolean::get_TRUE(ik);
oop false_cache = java_lang_Boolean::get_FALSE(ik);
assert(true_cache != nullptr && false_cache != nullptr, "Boolean cache fields must be initialized");
_true_cache = JNIHandles::make_global(Handle(thread, true_cache));
_false_cache = JNIHandles::make_global(Handle(thread, false_cache));
}
}
~BooleanBoxCache() {
Expand Down Expand Up @@ -1256,10 +1259,6 @@ class BooleanBoxCache : public BoxCacheBase<java_lang_Boolean> {
BooleanBoxCache* BooleanBoxCache::_singleton = nullptr;

oop Deoptimization::get_cached_box(AutoBoxObjectValue* bv, frame* fr, RegisterMap* reg_map, bool& cache_init_error, TRAPS) {
Comment thread
TobiHartmann marked this conversation as resolved.
if (Arguments::enable_preview()) {
// Box caches are not used with enable preview.
return nullptr;
}
Klass* k = java_lang_Class::as_Klass(bv->klass()->as_ConstantOopReadValue()->value()());
BasicType box_type = vmClasses::box_klass_type(k);
if (box_type != T_OBJECT) {
Expand Down
37 changes: 23 additions & 14 deletions src/java.base/share/classes/java/lang/Boolean.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1994, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 2026, 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
Expand All @@ -25,7 +25,6 @@

package java.lang;

import jdk.internal.misc.PreviewFeatures;
import jdk.internal.value.DeserializeConstructor;
import jdk.internal.vm.annotation.IntrinsicCandidate;

Expand Down Expand Up @@ -112,6 +111,7 @@ public final class Boolean implements java.io.Serializable,
* if possible.
*/
@Deprecated(since="9")
@DeserializeConstructor
public Boolean(boolean value) {
this.value = value;
}
Expand Down Expand Up @@ -168,25 +168,34 @@ public boolean booleanValue() {

/**
* Returns a {@code Boolean} instance representing the specified
* {@code boolean} value. If the specified {@code boolean} value
* is {@code true}, this method returns {@code Boolean.TRUE};
* if it is {@code false}, this method returns {@code Boolean.FALSE}.
* If a new {@code Boolean} instance is not required, this method
* should generally be used in preference to the constructor
* {@link #Boolean(boolean)}, as this method is likely to yield
* significantly better space and time performance.
* {@code boolean} value.
* <div class="preview-block">
* <div class="preview-comment">
* <p>
* - When preview features are NOT enabled, {@code Boolean} is an identity class.
* If the specified {@code boolean} value is {@code true},
* this method returns {@code Boolean.TRUE}; if it is
* {@code false}, this method returns {@code Boolean.FALSE}.
* If a new {@code Boolean} instance is not required, this
* method should generally be used in preference to the
* constructor {@link #Boolean(boolean)}, as this method is
* likely to yield significantly better space and time
* performance.
* </p>
* <p>
* - When preview features are enabled, {@code Boolean} is a {@linkplain Class#isValue value class}.
* The {@code valueOf} behavior is the same as invoking the constructor.
* </p>
* </div>
* </div>
*
* @param b a boolean value.
* @return a {@code Boolean} instance representing {@code b}.
* @since 1.4
*/
@IntrinsicCandidate
@DeserializeConstructor
public static Boolean valueOf(boolean b) {
if (!PreviewFeatures.isEnabled()) {
return (b ? TRUE : FALSE);
}
return new Boolean(b);
return (b ? TRUE : FALSE);
}

/**
Expand Down
47 changes: 24 additions & 23 deletions src/java.base/share/classes/java/lang/Byte.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import jdk.internal.misc.CDS;
import jdk.internal.misc.PreviewFeatures;
import jdk.internal.value.DeserializeConstructor;
import jdk.internal.value.ValueClass;
import jdk.internal.vm.annotation.AOTSafeClassInitializer;
import jdk.internal.vm.annotation.IntrinsicCandidate;
import jdk.internal.vm.annotation.Stable;
Expand Down Expand Up @@ -123,25 +124,28 @@ private ByteCache() {}
static Byte[] archivedCache;

static {
if (!PreviewFeatures.isEnabled()) {
final int size = -(-128) + 127 + 1;

// Load and use the archived cache if it exists
CDS.initializeFromArchive(ByteCache.class);
if (archivedCache == null) {
Byte[] c = new Byte[size];
byte value = (byte)-128;
for(int i = 0; i < size; i++) {
c[i] = new Byte(value++);
}
archivedCache = c;
final int size = -(-128) + 127 + 1;

// Load and use the archived cache if it exists
CDS.initializeFromArchive(ByteCache.class);
if (archivedCache == null) {
Byte[] c = newCacheArray(size);
byte value = (byte)-128;
for(int i = 0; i < size; i++) {
c[i] = new Byte(value++);
}
cache = archivedCache;
assert cache.length == size;
} else {
cache = null;
assert archivedCache == null;
archivedCache = c;
}
cache = archivedCache;
assert cache.length == size;
}

private static Byte[] newCacheArray(int size) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this - we should be able to revert to mainline code. The only code I think that need any update would be the old new Byte[size] should become (Byte[]) ValueClass.newReferenceArray(Byte.class, size) both with and without preview.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new Byte[size] should become (Byte[]) ValueClass.newReferenceArray(Byte.class, size) both with and without preview.

@liach That's not possible because ValueClass.newReferenceArray throws when preview is disabled because boxes are identity classes then.

// ValueClass.newReferenceArray requires a value class component.
if (PreviewFeatures.isEnabled()) {
return (Byte[]) ValueClass.newReferenceArray(Byte.class, size);
}
return new Byte[size];
}
}

Expand Down Expand Up @@ -171,13 +175,9 @@ private ByteCache() {}
* @since 1.5
*/
@IntrinsicCandidate
@DeserializeConstructor
public static Byte valueOf(byte b) {
if (!PreviewFeatures.isEnabled()) {
final int offset = 128;
return ByteCache.cache[(int) b + offset];
}
return new Byte(b);
final int offset = 128;
return ByteCache.cache[(int) b + offset];
}

/**
Expand Down Expand Up @@ -378,6 +378,7 @@ public static Byte decode(String nm) throws NumberFormatException {
* likely to yield significantly better space and time performance.
*/
@Deprecated(since="9")
@DeserializeConstructor
public Byte(byte value) {
this.value = value;
}
Expand Down
44 changes: 23 additions & 21 deletions src/java.base/share/classes/java/lang/Character.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import jdk.internal.misc.CDS;
import jdk.internal.misc.PreviewFeatures;
import jdk.internal.value.DeserializeConstructor;
import jdk.internal.value.ValueClass;
import jdk.internal.vm.annotation.AOTSafeClassInitializer;
import jdk.internal.vm.annotation.IntrinsicCandidate;
import jdk.internal.vm.annotation.Stable;
Expand Down Expand Up @@ -9422,6 +9423,7 @@ public static final UnicodeScript forName(String scriptName) {
* likely to yield significantly better space and time performance.
*/
@Deprecated(since="9")
@DeserializeConstructor
public Character(char value) {
this.value = value;
}
Expand All @@ -9435,24 +9437,27 @@ private CharacterCache(){}
static Character[] archivedCache;

static {
if (!PreviewFeatures.isEnabled()) {
int size = 127 + 1;

// Load and use the archived cache if it exists
CDS.initializeFromArchive(CharacterCache.class);
if (archivedCache == null) {
Character[] c = new Character[size];
for (int i = 0; i < size; i++) {
c[i] = new Character((char) i);
}
archivedCache = c;
int size = 127 + 1;

// Load and use the archived cache if it exists
CDS.initializeFromArchive(CharacterCache.class);
if (archivedCache == null) {
Character[] c = newCacheArray(size);
for (int i = 0; i < size; i++) {
c[i] = new Character((char) i);
}
cache = archivedCache;
assert cache.length == size;
} else {
cache = null;
assert archivedCache == null;
archivedCache = c;
}
cache = archivedCache;
assert cache.length == size;
}

private static Character[] newCacheArray(int size) {
// ValueClass.newReferenceArray requires a value class component.
if (PreviewFeatures.isEnabled()) {
return (Character[]) ValueClass.newReferenceArray(Character.class, size);
}
return new Character[size];
}
}

Expand Down Expand Up @@ -9485,12 +9490,9 @@ private CharacterCache(){}
* @since 1.5
*/
@IntrinsicCandidate
@DeserializeConstructor
public static Character valueOf(char c) {
if (!PreviewFeatures.isEnabled()) {
if (c <= 127) { // must cache
return CharacterCache.cache[(int) c];
}
if (c <= 127) { // must cache
return CharacterCache.cache[(int) c];
}
return new Character(c);
}
Expand Down
25 changes: 18 additions & 7 deletions src/java.base/share/classes/java/lang/Double.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1994, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 2026, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2025, Alibaba Group Holding Limited. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Expand Down Expand Up @@ -968,18 +968,28 @@ public static Double valueOf(String s) throws NumberFormatException {
/**
* Returns a {@code Double} instance representing the specified
* {@code double} value.
* If a new {@code Double} instance is not required, this method
* should generally be used in preference to the constructor
* {@link #Double(double)}, as this method is likely to yield
* significantly better space and time performance by caching
* frequently requested values.
* <div class="preview-block">
* <div class="preview-comment">
* <p>
* - When preview features are NOT enabled, {@code Double} is an identity class.
* If a new {@code Double} instance is not required, this
* method should generally be used in preference to the
* constructor {@link #Double(double)}, as this method is
* likely to yield significantly better space and time
* performance by caching frequently requested values.
* </p>
* <p>
* - When preview features are enabled, {@code Double} is a {@linkplain Class#isValue value class}.
* The {@code valueOf} behavior is the same as invoking the constructor.
* </p>
* </div>
* </div>
*
* @param d a double value.
* @return a {@code Double} instance representing {@code d}.
* @since 1.5
*/
@IntrinsicCandidate
@DeserializeConstructor
public static Double valueOf(double d) {
return new Double(d);
}
Expand Down Expand Up @@ -1075,6 +1085,7 @@ public static boolean isFinite(double d) {
* likely to yield significantly better space and time performance.
*/
@Deprecated(since="9")
@DeserializeConstructor
public Double(double value) {
this.value = value;
}
Expand Down
25 changes: 18 additions & 7 deletions src/java.base/share/classes/java/lang/Float.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1994, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 2026, 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
Expand Down Expand Up @@ -571,18 +571,28 @@ public static Float valueOf(String s) throws NumberFormatException {
/**
* Returns a {@code Float} instance representing the specified
* {@code float} value.
* If a new {@code Float} instance is not required, this method
* should generally be used in preference to the constructor
* {@link #Float(float)}, as this method is likely to yield
* significantly better space and time performance by caching
* frequently requested values.
* <div class="preview-block">
* <div class="preview-comment">
* <p>
* - When preview features are NOT enabled, {@code Float} is an identity class.
* If a new {@code Float} instance is not required, this
* method should generally be used in preference to the
* constructor {@link #Float(float)}, as this method is
* likely to yield significantly better space and time
* performance by caching frequently requested values.
* </p>
* <p>
* - When preview features are enabled, {@code Float} is a {@linkplain Class#isValue value class}.
* The {@code valueOf} behavior is the same as invoking the constructor.
* </p>
* </div>
* </div>
*
* @param f a float value.
* @return a {@code Float} instance representing {@code f}.
* @since 1.5
*/
@IntrinsicCandidate
@DeserializeConstructor
public static Float valueOf(float f) {
return new Float(f);
}
Expand Down Expand Up @@ -678,6 +688,7 @@ public static boolean isFinite(float f) {
* likely to yield significantly better space and time performance.
*/
@Deprecated(since="9")
@DeserializeConstructor
public Float(float value) {
this.value = value;
}
Expand Down
Loading