8257845: Integrate JEP 390

8254047: [JEP 390] Revise "value-based class" & apply to wrappers
8252181: [JEP 390] Define & apply annotation jdk.internal.ValueBased
8252183: [JEP 390] Add 'lint' warning for @ValueBased classes
8257027: [JEP 390] Diagnose synchronization on @ValueBased classes
8252180: [JEP 390] Deprecate wrapper class constructors for removal

Co-authored-by: Roger Riggs <rriggs@openjdk.org>
Co-authored-by: Srikanth Adayapalam <sadayapalam@openjdk.org>
Co-authored-by: Lois Foltan <lfoltan@openjdk.org>
Reviewed-by: rriggs, hseigel, mchung, darcy
This commit is contained in:
Dan Smith 2020-12-08 23:04:01 +00:00
parent ed4c4ee73b
commit 48d8650ae1
113 changed files with 695 additions and 327 deletions

View File

@ -3893,10 +3893,10 @@ encode %{
// Load markWord from object into displaced_header. // Load markWord from object into displaced_header.
__ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes())); __ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes()));
if (DiagnoseSyncOnPrimitiveWrappers != 0) { if (DiagnoseSyncOnValueBasedClasses != 0) {
__ load_klass(tmp, oop); __ load_klass(tmp, oop);
__ ldrw(tmp, Address(tmp, Klass::access_flags_offset())); __ ldrw(tmp, Address(tmp, Klass::access_flags_offset()));
__ tstw(tmp, JVM_ACC_IS_BOX_CLASS); __ tstw(tmp, JVM_ACC_IS_VALUE_BASED_CLASS);
__ br(Assembler::NE, cont); __ br(Assembler::NE, cont);
} }

View File

@ -75,10 +75,10 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr
null_check_offset = offset(); null_check_offset = offset();
if (DiagnoseSyncOnPrimitiveWrappers != 0) { if (DiagnoseSyncOnValueBasedClasses != 0) {
load_klass(hdr, obj); load_klass(hdr, obj);
ldrw(hdr, Address(hdr, Klass::access_flags_offset())); ldrw(hdr, Address(hdr, Klass::access_flags_offset()));
tstw(hdr, JVM_ACC_IS_BOX_CLASS); tstw(hdr, JVM_ACC_IS_VALUE_BASED_CLASS);
br(Assembler::NE, slow_case); br(Assembler::NE, slow_case);
} }

View File

@ -746,10 +746,10 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg)
// Load object pointer into obj_reg %c_rarg3 // Load object pointer into obj_reg %c_rarg3
ldr(obj_reg, Address(lock_reg, obj_offset)); ldr(obj_reg, Address(lock_reg, obj_offset));
if (DiagnoseSyncOnPrimitiveWrappers != 0) { if (DiagnoseSyncOnValueBasedClasses != 0) {
load_klass(tmp, obj_reg); load_klass(tmp, obj_reg);
ldrw(tmp, Address(tmp, Klass::access_flags_offset())); ldrw(tmp, Address(tmp, Klass::access_flags_offset()));
tstw(tmp, JVM_ACC_IS_BOX_CLASS); tstw(tmp, JVM_ACC_IS_VALUE_BASED_CLASS);
br(Assembler::NE, slow_case); br(Assembler::NE, slow_case);
} }

View File

@ -204,10 +204,10 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj,
null_check_offset = offset(); null_check_offset = offset();
if (DiagnoseSyncOnPrimitiveWrappers != 0) { if (DiagnoseSyncOnValueBasedClasses != 0) {
load_klass(tmp1, obj); load_klass(tmp1, obj);
ldr_u32(tmp1, Address(tmp1, Klass::access_flags_offset())); ldr_u32(tmp1, Address(tmp1, Klass::access_flags_offset()));
tst(tmp1, JVM_ACC_IS_BOX_CLASS); tst(tmp1, JVM_ACC_IS_VALUE_BASED_CLASS);
b(slow_case, ne); b(slow_case, ne);
} }

View File

@ -90,10 +90,10 @@ void C2_MacroAssembler::fast_lock(Register Roop, Register Rbox, Register Rscratc
Label fast_lock, done; Label fast_lock, done;
if (DiagnoseSyncOnPrimitiveWrappers != 0) { if (DiagnoseSyncOnValueBasedClasses != 0) {
load_klass(Rscratch, Roop); load_klass(Rscratch, Roop);
ldr_u32(Rscratch, Address(Rscratch, Klass::access_flags_offset())); ldr_u32(Rscratch, Address(Rscratch, Klass::access_flags_offset()));
tst(Rscratch, JVM_ACC_IS_BOX_CLASS); tst(Rscratch, JVM_ACC_IS_VALUE_BASED_CLASS);
b(done, ne); b(done, ne);
} }

View File

@ -883,10 +883,10 @@ void InterpreterMacroAssembler::lock_object(Register Rlock) {
// Load object pointer // Load object pointer
ldr(Robj, Address(Rlock, obj_offset)); ldr(Robj, Address(Rlock, obj_offset));
if (DiagnoseSyncOnPrimitiveWrappers != 0) { if (DiagnoseSyncOnValueBasedClasses != 0) {
load_klass(R0, Robj); load_klass(R0, Robj);
ldr_u32(R0, Address(R0, Klass::access_flags_offset())); ldr_u32(R0, Address(R0, Klass::access_flags_offset()));
tst(R0, JVM_ACC_IS_BOX_CLASS); tst(R0, JVM_ACC_IS_VALUE_BASED_CLASS);
b(slow_case, ne); b(slow_case, ne);
} }

View File

@ -105,10 +105,10 @@ void C1_MacroAssembler::lock_object(Register Rmark, Register Roop, Register Rbox
// Save object being locked into the BasicObjectLock... // Save object being locked into the BasicObjectLock...
std(Roop, BasicObjectLock::obj_offset_in_bytes(), Rbox); std(Roop, BasicObjectLock::obj_offset_in_bytes(), Rbox);
if (DiagnoseSyncOnPrimitiveWrappers != 0) { if (DiagnoseSyncOnValueBasedClasses != 0) {
load_klass(Rscratch, Roop); load_klass(Rscratch, Roop);
lwz(Rscratch, in_bytes(Klass::access_flags_offset()), Rscratch); lwz(Rscratch, in_bytes(Klass::access_flags_offset()), Rscratch);
testbitdi(CCR0, R0, Rscratch, exact_log2(JVM_ACC_IS_BOX_CLASS)); testbitdi(CCR0, R0, Rscratch, exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS));
bne(CCR0, slow_int); bne(CCR0, slow_int);
} }

View File

@ -910,10 +910,10 @@ void InterpreterMacroAssembler::lock_object(Register monitor, Register object) {
// Load markWord from object into displaced_header. // Load markWord from object into displaced_header.
ld(displaced_header, oopDesc::mark_offset_in_bytes(), object); ld(displaced_header, oopDesc::mark_offset_in_bytes(), object);
if (DiagnoseSyncOnPrimitiveWrappers != 0) { if (DiagnoseSyncOnValueBasedClasses != 0) {
load_klass(tmp, object); load_klass(tmp, object);
lwz(tmp, in_bytes(Klass::access_flags_offset()), tmp); lwz(tmp, in_bytes(Klass::access_flags_offset()), tmp);
testbitdi(CCR0, R0, tmp, exact_log2(JVM_ACC_IS_BOX_CLASS)); testbitdi(CCR0, R0, tmp, exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS));
bne(CCR0, slow_case); bne(CCR0, slow_case);
} }

View File

@ -2818,10 +2818,10 @@ void MacroAssembler::compiler_fast_lock_object(ConditionRegister flag, Register
// Load markWord from object into displaced_header. // Load markWord from object into displaced_header.
ld(displaced_header, oopDesc::mark_offset_in_bytes(), oop); ld(displaced_header, oopDesc::mark_offset_in_bytes(), oop);
if (DiagnoseSyncOnPrimitiveWrappers != 0) { if (DiagnoseSyncOnValueBasedClasses != 0) {
load_klass(temp, oop); load_klass(temp, oop);
lwz(temp, in_bytes(Klass::access_flags_offset()), temp); lwz(temp, in_bytes(Klass::access_flags_offset()), temp);
testbitdi(flag, R0, temp, exact_log2(JVM_ACC_IS_BOX_CLASS)); testbitdi(flag, R0, temp, exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS));
bne(flag, cont); bne(flag, cont);
} }

View File

@ -91,9 +91,9 @@ void C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hd
// Save object being locked into the BasicObjectLock... // Save object being locked into the BasicObjectLock...
z_stg(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes())); z_stg(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
if (DiagnoseSyncOnPrimitiveWrappers != 0) { if (DiagnoseSyncOnValueBasedClasses != 0) {
load_klass(Z_R1_scratch, obj); load_klass(Z_R1_scratch, obj);
testbit(Address(Z_R1_scratch, Klass::access_flags_offset()), exact_log2(JVM_ACC_IS_BOX_CLASS)); testbit(Address(Z_R1_scratch, Klass::access_flags_offset()), exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS));
z_btrue(slow_case); z_btrue(slow_case);
} }

View File

@ -999,9 +999,9 @@ void InterpreterMacroAssembler::lock_object(Register monitor, Register object) {
// Load markWord from object into displaced_header. // Load markWord from object into displaced_header.
z_lg(displaced_header, oopDesc::mark_offset_in_bytes(), object); z_lg(displaced_header, oopDesc::mark_offset_in_bytes(), object);
if (DiagnoseSyncOnPrimitiveWrappers != 0) { if (DiagnoseSyncOnValueBasedClasses != 0) {
load_klass(Z_R1_scratch, object); load_klass(Z_R1_scratch, object);
testbit(Address(Z_R1_scratch, Klass::access_flags_offset()), exact_log2(JVM_ACC_IS_BOX_CLASS)); testbit(Address(Z_R1_scratch, Klass::access_flags_offset()), exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS));
z_btrue(slow_case); z_btrue(slow_case);
} }

View File

@ -3326,11 +3326,11 @@ void MacroAssembler::compiler_fast_lock_object(Register oop, Register box, Regis
// Load markWord from oop into mark. // Load markWord from oop into mark.
z_lg(displacedHeader, 0, oop); z_lg(displacedHeader, 0, oop);
if (DiagnoseSyncOnPrimitiveWrappers != 0) { if (DiagnoseSyncOnValueBasedClasses != 0) {
load_klass(Z_R1_scratch, oop); load_klass(Z_R1_scratch, oop);
z_l(Z_R1_scratch, Address(Z_R1_scratch, Klass::access_flags_offset())); z_l(Z_R1_scratch, Address(Z_R1_scratch, Klass::access_flags_offset()));
assert((JVM_ACC_IS_BOX_CLASS & 0xFFFF) == 0, "or change following instruction"); assert((JVM_ACC_IS_VALUE_BASED_CLASS & 0xFFFF) == 0, "or change following instruction");
z_nilh(Z_R1_scratch, JVM_ACC_IS_BOX_CLASS >> 16); z_nilh(Z_R1_scratch, JVM_ACC_IS_VALUE_BASED_CLASS >> 16);
z_brne(done); z_brne(done);
} }

View File

@ -54,10 +54,10 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr
null_check_offset = offset(); null_check_offset = offset();
if (DiagnoseSyncOnPrimitiveWrappers != 0) { if (DiagnoseSyncOnValueBasedClasses != 0) {
load_klass(hdr, obj, rklass_decode_tmp); load_klass(hdr, obj, rklass_decode_tmp);
movl(hdr, Address(hdr, Klass::access_flags_offset())); movl(hdr, Address(hdr, Klass::access_flags_offset()));
testl(hdr, JVM_ACC_IS_BOX_CLASS); testl(hdr, JVM_ACC_IS_VALUE_BASED_CLASS);
jcc(Assembler::notZero, slow_case); jcc(Assembler::notZero, slow_case);
} }

View File

@ -485,10 +485,10 @@ void C2_MacroAssembler::fast_lock(Register objReg, Register boxReg, Register tmp
Label IsInflated, DONE_LABEL; Label IsInflated, DONE_LABEL;
if (DiagnoseSyncOnPrimitiveWrappers != 0) { if (DiagnoseSyncOnValueBasedClasses != 0) {
load_klass(tmpReg, objReg, cx1Reg); load_klass(tmpReg, objReg, cx1Reg);
movl(tmpReg, Address(tmpReg, Klass::access_flags_offset())); movl(tmpReg, Address(tmpReg, Klass::access_flags_offset()));
testl(tmpReg, JVM_ACC_IS_BOX_CLASS); testl(tmpReg, JVM_ACC_IS_VALUE_BASED_CLASS);
jcc(Assembler::notZero, DONE_LABEL); jcc(Assembler::notZero, DONE_LABEL);
} }

View File

@ -1219,10 +1219,10 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg) {
// Load object pointer into obj_reg // Load object pointer into obj_reg
movptr(obj_reg, Address(lock_reg, obj_offset)); movptr(obj_reg, Address(lock_reg, obj_offset));
if (DiagnoseSyncOnPrimitiveWrappers != 0) { if (DiagnoseSyncOnValueBasedClasses != 0) {
load_klass(tmp_reg, obj_reg, rklass_decode_tmp); load_klass(tmp_reg, obj_reg, rklass_decode_tmp);
movl(tmp_reg, Address(tmp_reg, Klass::access_flags_offset())); movl(tmp_reg, Address(tmp_reg, Klass::access_flags_offset()));
testl(tmp_reg, JVM_ACC_IS_BOX_CLASS); testl(tmp_reg, JVM_ACC_IS_VALUE_BASED_CLASS);
jcc(Assembler::notZero, slow_case); jcc(Assembler::notZero, slow_case);
} }

View File

@ -1091,6 +1091,7 @@ public:
_jdk_internal_vm_annotation_Contended, _jdk_internal_vm_annotation_Contended,
_field_Stable, _field_Stable,
_jdk_internal_vm_annotation_ReservedStackAccess, _jdk_internal_vm_annotation_ReservedStackAccess,
_jdk_internal_ValueBased,
_annotation_LIMIT _annotation_LIMIT
}; };
const Location _location; const Location _location;
@ -2147,6 +2148,11 @@ AnnotationCollector::annotation_index(const ClassLoaderData* loader_data,
if (RestrictReservedStack && !privileged) break; // honor privileges if (RestrictReservedStack && !privileged) break; // honor privileges
return _jdk_internal_vm_annotation_ReservedStackAccess; return _jdk_internal_vm_annotation_ReservedStackAccess;
} }
case VM_SYMBOL_ENUM_NAME(jdk_internal_ValueBased_signature): {
if (_location != _in_class) break; // only allow for classes
if (!privileged) break; // only allow in priviledged code
return _jdk_internal_ValueBased;
}
default: { default: {
break; break;
} }
@ -2190,7 +2196,16 @@ void MethodAnnotationCollector::apply_to(const methodHandle& m) {
void ClassFileParser::ClassAnnotationCollector::apply_to(InstanceKlass* ik) { void ClassFileParser::ClassAnnotationCollector::apply_to(InstanceKlass* ik) {
assert(ik != NULL, "invariant"); assert(ik != NULL, "invariant");
ik->set_is_contended(is_contended()); if (has_annotation(_jdk_internal_vm_annotation_Contended)) {
ik->set_is_contended(is_contended());
}
if (has_annotation(_jdk_internal_ValueBased)) {
ik->set_has_value_based_class_annotation();
if (DiagnoseSyncOnValueBasedClasses) {
ik->set_is_value_based();
ik->set_prototype_header(markWord::prototype());
}
}
} }
#define MAX_ARGS_SIZE 255 #define MAX_ARGS_SIZE 255

View File

@ -2142,14 +2142,6 @@ void SystemDictionary::resolve_well_known_classes(TRAPS) {
//_box_klasses[T_OBJECT] = WK_KLASS(object_klass); //_box_klasses[T_OBJECT] = WK_KLASS(object_klass);
//_box_klasses[T_ARRAY] = WK_KLASS(object_klass); //_box_klasses[T_ARRAY] = WK_KLASS(object_klass);
if (DiagnoseSyncOnPrimitiveWrappers != 0) {
for (int i = T_BOOLEAN; i < T_LONG + 1; i++) {
assert(_box_klasses[i] != NULL, "NULL box class");
_box_klasses[i]->set_is_box();
_box_klasses[i]->set_prototype_header(markWord::prototype());
}
}
#ifdef ASSERT #ifdef ASSERT
if (UseSharedSpaces) { if (UseSharedSpaces) {
JVMTI_ONLY(assert(JvmtiExport::is_early_phase(), JVMTI_ONLY(assert(JvmtiExport::is_early_phase(),

View File

@ -249,6 +249,7 @@
template(java_util_concurrent_atomic_AtomicReferenceFieldUpdater_Impl, "java/util/concurrent/atomic/AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl") \ template(java_util_concurrent_atomic_AtomicReferenceFieldUpdater_Impl, "java/util/concurrent/atomic/AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl") \
template(jdk_internal_vm_annotation_Contended_signature, "Ljdk/internal/vm/annotation/Contended;") \ template(jdk_internal_vm_annotation_Contended_signature, "Ljdk/internal/vm/annotation/Contended;") \
template(jdk_internal_vm_annotation_ReservedStackAccess_signature, "Ljdk/internal/vm/annotation/ReservedStackAccess;") \ template(jdk_internal_vm_annotation_ReservedStackAccess_signature, "Ljdk/internal/vm/annotation/ReservedStackAccess;") \
template(jdk_internal_ValueBased_signature, "Ljdk/internal/ValueBased;") \
\ \
/* class symbols needed by intrinsics */ \ /* class symbols needed by intrinsics */ \
VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, template, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE) \ VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, template, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE) \

View File

@ -66,8 +66,8 @@
<Field type="InflateCause" name="cause" label="Monitor Inflation Cause" description="Cause of inflation" /> <Field type="InflateCause" name="cause" label="Monitor Inflation Cause" description="Cause of inflation" />
</Event> </Event>
<Event name="SyncOnPrimitiveWrapper" category="Java Virtual Machine, Diagnostics" label="Primitive Wrapper Synchronization" thread="true" stackTrace="true" startTime="false" experimental="true"> <Event name="SyncOnValueBasedClass" category="Java Virtual Machine, Diagnostics" label="Value Based Class Synchronization" thread="true" stackTrace="true" startTime="false" experimental="true">
<Field type="Class" name="boxClass" label="Boxing Class" /> <Field type="Class" name="valueBasedClass" label="Value Based Class" />
</Event> </Event>
<Event name="BiasedLockRevocation" category="Java Virtual Machine, Runtime" label="Biased Lock Revocation" description="Revoked bias of object" thread="true" <Event name="BiasedLockRevocation" category="Java Virtual Machine, Runtime" label="Biased Lock Revocation" description="Revoked bias of object" thread="true"

View File

@ -141,7 +141,6 @@
LOG_TAG(plab) \ LOG_TAG(plab) \
LOG_TAG(preorder) /* Trace all classes loaded in order referenced (not loaded) */ \ LOG_TAG(preorder) /* Trace all classes loaded in order referenced (not loaded) */ \
LOG_TAG(preview) /* Trace loading of preview feature types */ \ LOG_TAG(preview) /* Trace loading of preview feature types */ \
LOG_TAG(primitivewrappers) \
LOG_TAG(promotion) \ LOG_TAG(promotion) \
LOG_TAG(protectiondomain) /* "Trace protection domain verification" */ \ LOG_TAG(protectiondomain) /* "Trace protection domain verification" */ \
LOG_TAG(ptrqueue) \ LOG_TAG(ptrqueue) \
@ -187,6 +186,7 @@
LOG_TAG(unload) /* Trace unloading of classes */ \ LOG_TAG(unload) /* Trace unloading of classes */ \
LOG_TAG(unshareable) \ LOG_TAG(unshareable) \
LOG_TAG(update) \ LOG_TAG(update) \
LOG_TAG(valuebasedclasses) \
LOG_TAG(verification) \ LOG_TAG(verification) \
LOG_TAG(verify) \ LOG_TAG(verify) \
LOG_TAG(vmmutex) \ LOG_TAG(vmmutex) \

View File

@ -2600,6 +2600,12 @@ void InstanceKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handl
if (UseBiasedLocking && BiasedLocking::enabled()) { if (UseBiasedLocking && BiasedLocking::enabled()) {
set_prototype_header(markWord::biased_locking_prototype()); set_prototype_header(markWord::biased_locking_prototype());
} }
// Initialize @ValueBased class annotation
if (DiagnoseSyncOnValueBasedClasses && has_value_based_class_annotation()) {
set_is_value_based();
set_prototype_header(markWord::prototype());
}
} }
void InstanceKlass::set_shared_class_loader_type(s2 loader_type) { void InstanceKlass::set_shared_class_loader_type(s2 loader_type) {

View File

@ -176,7 +176,8 @@ private:
// Flags of the current shared class. // Flags of the current shared class.
u2 _shared_class_flags; u2 _shared_class_flags;
enum { enum {
_archived_lambda_proxy_is_available = 2 _archived_lambda_proxy_is_available = 2,
_has_value_based_class_annotation = 4
}; };
#endif #endif
@ -321,6 +322,18 @@ protected:
NOT_CDS(return false;) NOT_CDS(return false;)
} }
void set_has_value_based_class_annotation() {
CDS_ONLY(_shared_class_flags |= _has_value_based_class_annotation;)
}
void clear_has_value_based_class_annotation() {
CDS_ONLY(_shared_class_flags &= ~_has_value_based_class_annotation;)
}
bool has_value_based_class_annotation() const {
CDS_ONLY(return (_shared_class_flags & _has_value_based_class_annotation) != 0;)
NOT_CDS(return false;)
}
// Obtain the module or package for this class // Obtain the module or package for this class
virtual ModuleEntry* module() const = 0; virtual ModuleEntry* module() const = 0;
virtual PackageEntry* package() const = 0; virtual PackageEntry* package() const = 0;
@ -624,8 +637,8 @@ protected:
void set_is_hidden() { _access_flags.set_is_hidden_class(); } void set_is_hidden() { _access_flags.set_is_hidden_class(); }
bool is_non_strong_hidden() const { return access_flags().is_hidden_class() && bool is_non_strong_hidden() const { return access_flags().is_hidden_class() &&
class_loader_data()->has_class_mirror_holder(); } class_loader_data()->has_class_mirror_holder(); }
bool is_box() const { return access_flags().is_box_class(); } bool is_value_based() { return _access_flags.is_value_based_class(); }
void set_is_box() { _access_flags.set_is_box_class(); } void set_is_value_based() { _access_flags.set_is_value_based_class(); }
bool is_cloneable() const; bool is_cloneable() const;
void set_is_cloneable(); void set_is_cloneable();

View File

@ -4139,9 +4139,9 @@ jint Arguments::apply_ergo() {
} }
#endif // COMPILER2 #endif // COMPILER2
if (FLAG_IS_CMDLINE(DiagnoseSyncOnPrimitiveWrappers)) { if (FLAG_IS_CMDLINE(DiagnoseSyncOnValueBasedClasses)) {
if (DiagnoseSyncOnPrimitiveWrappers == ObjectSynchronizer::LOG_WARNING && !log_is_enabled(Info, primitivewrappers)) { if (DiagnoseSyncOnValueBasedClasses == ObjectSynchronizer::LOG_WARNING && !log_is_enabled(Info, valuebasedclasses)) {
LogConfiguration::configure_stdout(LogLevel::Info, true, LOG_TAGS(primitivewrappers)); LogConfiguration::configure_stdout(LogLevel::Info, true, LOG_TAGS(valuebasedclasses));
} }
} }
return JNI_OK; return JNI_OK;

View File

@ -851,13 +851,13 @@ const intx ObjectAlignmentInBytes = 8;
range(500, max_intx) \ range(500, max_intx) \
constraint(BiasedLockingDecayTimeFunc,AfterErgo) \ constraint(BiasedLockingDecayTimeFunc,AfterErgo) \
\ \
product(intx, DiagnoseSyncOnPrimitiveWrappers, 0, DIAGNOSTIC, \ product(intx, DiagnoseSyncOnValueBasedClasses, 0, DIAGNOSTIC, \
"Detect and take action upon identifying synchronization on " \ "Detect and take action upon identifying synchronization on " \
"primitive wrappers. Modes: " \ "value based classes. Modes: " \
"0: off; " \ "0: off; " \
"1: exit with fatal error; " \ "1: exit with fatal error; " \
"2: log message to stdout. Output file can be specified with " \ "2: log message to stdout. Output file can be specified with " \
" -Xlog:primitivewrappers. If JFR is running it will " \ " -Xlog:valuebasedclasses. If JFR is running it will " \
" also generate JFR events.") \ " also generate JFR events.") \
range(0, 2) \ range(0, 2) \
\ \

View File

@ -333,7 +333,7 @@ bool ObjectSynchronizer::quick_enter(oop obj, Thread* self,
NoSafepointVerifier nsv; NoSafepointVerifier nsv;
if (obj == NULL) return false; // Need to throw NPE if (obj == NULL) return false; // Need to throw NPE
if (DiagnoseSyncOnPrimitiveWrappers != 0 && obj->klass()->is_box()) { if (obj->klass()->is_value_based()) {
return false; return false;
} }
@ -387,17 +387,23 @@ bool ObjectSynchronizer::quick_enter(oop obj, Thread* self,
return false; // revert to slow-path return false; // revert to slow-path
} }
// Handle notifications when synchronizing on primitive wrappers // Handle notifications when synchronizing on value based classes
void ObjectSynchronizer::handle_sync_on_primitive_wrapper(Handle obj, Thread* current) { void ObjectSynchronizer::handle_sync_on_value_based_class(Handle obj, Thread* current) {
JavaThread* self = current->as_Java_thread(); JavaThread* self = current->as_Java_thread();
frame last_frame = self->last_frame(); frame last_frame = self->last_frame();
if (last_frame.is_interpreted_frame()) { bool bcp_was_adjusted = false;
// Don't decrement bcp if it points to the frame's first instruction. This happens when
// handle_sync_on_value_based_class() is called because of a synchronized method. There
// is no actual monitorenter instruction in the byte code in this case.
if (last_frame.is_interpreted_frame() &&
(last_frame.interpreter_frame_method()->code_base() < last_frame.interpreter_frame_bcp())) {
// adjust bcp to point back to monitorenter so that we print the correct line numbers // adjust bcp to point back to monitorenter so that we print the correct line numbers
last_frame.interpreter_frame_set_bcp(last_frame.interpreter_frame_bcp() - 1); last_frame.interpreter_frame_set_bcp(last_frame.interpreter_frame_bcp() - 1);
bcp_was_adjusted = true;
} }
if (DiagnoseSyncOnPrimitiveWrappers == FATAL_EXIT) { if (DiagnoseSyncOnValueBasedClasses == FATAL_EXIT) {
ResourceMark rm(self); ResourceMark rm(self);
stringStream ss; stringStream ss;
self->print_stack_on(&ss); self->print_stack_on(&ss);
@ -408,26 +414,26 @@ void ObjectSynchronizer::handle_sync_on_primitive_wrapper(Handle obj, Thread* cu
} }
fatal("Synchronizing on object " INTPTR_FORMAT " of klass %s %s", p2i(obj()), obj->klass()->external_name(), base); fatal("Synchronizing on object " INTPTR_FORMAT " of klass %s %s", p2i(obj()), obj->klass()->external_name(), base);
} else { } else {
assert(DiagnoseSyncOnPrimitiveWrappers == LOG_WARNING, "invalid value for DiagnoseSyncOnPrimitiveWrappers"); assert(DiagnoseSyncOnValueBasedClasses == LOG_WARNING, "invalid value for DiagnoseSyncOnValueBasedClasses");
ResourceMark rm(self); ResourceMark rm(self);
Log(primitivewrappers) pwlog; Log(valuebasedclasses) vblog;
pwlog.info("Synchronizing on object " INTPTR_FORMAT " of klass %s", p2i(obj()), obj->klass()->external_name()); vblog.info("Synchronizing on object " INTPTR_FORMAT " of klass %s", p2i(obj()), obj->klass()->external_name());
if (self->has_last_Java_frame()) { if (self->has_last_Java_frame()) {
LogStream info_stream(pwlog.info()); LogStream info_stream(vblog.info());
self->print_stack_on(&info_stream); self->print_stack_on(&info_stream);
} else { } else {
pwlog.info("Cannot find the last Java frame"); vblog.info("Cannot find the last Java frame");
} }
EventSyncOnPrimitiveWrapper event; EventSyncOnValueBasedClass event;
if (event.should_commit()) { if (event.should_commit()) {
event.set_boxClass(obj->klass()); event.set_valueBasedClass(obj->klass());
event.commit(); event.commit();
} }
} }
if (last_frame.is_interpreted_frame()) { if (bcp_was_adjusted) {
last_frame.interpreter_frame_set_bcp(last_frame.interpreter_frame_bcp() + 1); last_frame.interpreter_frame_set_bcp(last_frame.interpreter_frame_bcp() + 1);
} }
} }
@ -439,8 +445,8 @@ void ObjectSynchronizer::handle_sync_on_primitive_wrapper(Handle obj, Thread* cu
// changed. The implementation is extremely sensitive to race condition. Be careful. // changed. The implementation is extremely sensitive to race condition. Be careful.
void ObjectSynchronizer::enter(Handle obj, BasicLock* lock, TRAPS) { void ObjectSynchronizer::enter(Handle obj, BasicLock* lock, TRAPS) {
if (DiagnoseSyncOnPrimitiveWrappers != 0 && obj->klass()->is_box()) { if (obj->klass()->is_value_based()) {
handle_sync_on_primitive_wrapper(obj, THREAD); handle_sync_on_value_based_class(obj, THREAD);
} }
if (UseBiasedLocking) { if (UseBiasedLocking) {
@ -586,8 +592,8 @@ void ObjectSynchronizer::reenter(Handle obj, intx recursions, TRAPS) {
// JNI locks on java objects // JNI locks on java objects
// NOTE: must use heavy weight monitor to handle jni monitor enter // NOTE: must use heavy weight monitor to handle jni monitor enter
void ObjectSynchronizer::jni_enter(Handle obj, TRAPS) { void ObjectSynchronizer::jni_enter(Handle obj, TRAPS) {
if (DiagnoseSyncOnPrimitiveWrappers != 0 && obj->klass()->is_box()) { if (obj->klass()->is_value_based()) {
handle_sync_on_primitive_wrapper(obj, THREAD); handle_sync_on_value_based_class(obj, THREAD);
} }
// the current locking is from JNI instead of Java code // the current locking is from JNI instead of Java code

View File

@ -161,7 +161,7 @@ class ObjectSynchronizer : AllStatic {
static size_t get_gvars_size(); static size_t get_gvars_size();
static u_char* get_gvars_stw_random_addr(); static u_char* get_gvars_stw_random_addr();
static void handle_sync_on_primitive_wrapper(Handle obj, Thread* current); static void handle_sync_on_value_based_class(Handle obj, Thread* current);
}; };
// ObjectLocker enforces balanced locking and can never throw an // ObjectLocker enforces balanced locking and can never throw an

View File

@ -67,7 +67,7 @@ enum {
JVM_ACC_HAS_FINAL_METHOD = 0x01000000, // True if klass has final method JVM_ACC_HAS_FINAL_METHOD = 0x01000000, // True if klass has final method
JVM_ACC_IS_SHARED_CLASS = 0x02000000, // True if klass is shared JVM_ACC_IS_SHARED_CLASS = 0x02000000, // True if klass is shared
JVM_ACC_IS_HIDDEN_CLASS = 0x04000000, // True if klass is hidden JVM_ACC_IS_HIDDEN_CLASS = 0x04000000, // True if klass is hidden
JVM_ACC_IS_BOX_CLASS = 0x08000000, // True if klass is primitive wrapper JVM_ACC_IS_VALUE_BASED_CLASS = 0x08000000, // True if klass is marked as a ValueBased class
// Klass* and Method* flags // Klass* and Method* flags
JVM_ACC_HAS_LOCAL_VARIABLE_TABLE= 0x00200000, JVM_ACC_HAS_LOCAL_VARIABLE_TABLE= 0x00200000,
@ -152,7 +152,7 @@ class AccessFlags {
bool is_cloneable_fast () const { return (_flags & JVM_ACC_IS_CLONEABLE_FAST ) != 0; } bool is_cloneable_fast () const { return (_flags & JVM_ACC_IS_CLONEABLE_FAST ) != 0; }
bool is_shared_class () const { return (_flags & JVM_ACC_IS_SHARED_CLASS ) != 0; } bool is_shared_class () const { return (_flags & JVM_ACC_IS_SHARED_CLASS ) != 0; }
bool is_hidden_class () const { return (_flags & JVM_ACC_IS_HIDDEN_CLASS ) != 0; } bool is_hidden_class () const { return (_flags & JVM_ACC_IS_HIDDEN_CLASS ) != 0; }
bool is_box_class () const { return (_flags & JVM_ACC_IS_BOX_CLASS ) != 0; } bool is_value_based_class () const { return (_flags & JVM_ACC_IS_VALUE_BASED_CLASS ) != 0; }
// Klass* and Method* flags // Klass* and Method* flags
bool has_localvariable_table () const { return (_flags & JVM_ACC_HAS_LOCAL_VARIABLE_TABLE) != 0; } bool has_localvariable_table () const { return (_flags & JVM_ACC_HAS_LOCAL_VARIABLE_TABLE) != 0; }
@ -226,7 +226,7 @@ class AccessFlags {
void set_has_miranda_methods() { atomic_set_bits(JVM_ACC_HAS_MIRANDA_METHODS); } void set_has_miranda_methods() { atomic_set_bits(JVM_ACC_HAS_MIRANDA_METHODS); }
void set_is_shared_class() { atomic_set_bits(JVM_ACC_IS_SHARED_CLASS); } void set_is_shared_class() { atomic_set_bits(JVM_ACC_IS_SHARED_CLASS); }
void set_is_hidden_class() { atomic_set_bits(JVM_ACC_IS_HIDDEN_CLASS); } void set_is_hidden_class() { atomic_set_bits(JVM_ACC_IS_HIDDEN_CLASS); }
void set_is_box_class() { atomic_set_bits(JVM_ACC_IS_BOX_CLASS); } void set_is_value_based_class() { atomic_set_bits(JVM_ACC_IS_VALUE_BASED_CLASS); }
public: public:
// field flags // field flags

View File

@ -41,16 +41,23 @@ import static java.lang.constant.ConstantDescs.CD_Boolean;
* {@code boolean} in an object. An object of type * {@code boolean} in an object. An object of type
* {@code Boolean} contains a single field whose type is * {@code Boolean} contains a single field whose type is
* {@code boolean}. * {@code boolean}.
* <p> *
* In addition, this class provides many methods for * <p>In addition, this class provides many methods for
* converting a {@code boolean} to a {@code String} and a * converting a {@code boolean} to a {@code String} and a
* {@code String} to a {@code boolean}, as well as other * {@code String} to a {@code boolean}, as well as other
* constants and methods useful when dealing with a * constants and methods useful when dealing with a
* {@code boolean}. * {@code boolean}.
* *
* <p>This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; programmers should treat instances that are
* {@linkplain #equals(Object) equal} as interchangeable and should not
* use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
*
* @author Arthur van Hoff * @author Arthur van Hoff
* @since 1.0 * @since 1.0
*/ */
@jdk.internal.ValueBased
public final class Boolean implements java.io.Serializable, public final class Boolean implements java.io.Serializable,
Comparable<Boolean>, Constable Comparable<Boolean>, Constable
{ {
@ -98,7 +105,7 @@ public final class Boolean implements java.io.Serializable,
* Also consider using the final fields {@link #TRUE} and {@link #FALSE} * Also consider using the final fields {@link #TRUE} and {@link #FALSE}
* if possible. * if possible.
*/ */
@Deprecated(since="9") @Deprecated(since="9", forRemoval = true)
public Boolean(boolean value) { public Boolean(boolean value) {
this.value = value; this.value = value;
} }
@ -118,7 +125,7 @@ public final class Boolean implements java.io.Serializable,
* {@code boolean} primitive, or use {@link #valueOf(String)} * {@code boolean} primitive, or use {@link #valueOf(String)}
* to convert a string to a {@code Boolean} object. * to convert a string to a {@code Boolean} object.
*/ */
@Deprecated(since="9") @Deprecated(since="9", forRemoval = true)
public Boolean(String s) { public Boolean(String s) {
this(parseBoolean(s)); this(parseBoolean(s));
} }

View File

@ -48,11 +48,18 @@ import static java.lang.constant.ConstantDescs.DEFAULT_NAME;
* byte}, as well as other constants and methods useful when dealing * byte}, as well as other constants and methods useful when dealing
* with a {@code byte}. * with a {@code byte}.
* *
* <p>This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; programmers should treat instances that are
* {@linkplain #equals(Object) equal} as interchangeable and should not
* use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
*
* @author Nakul Saraiya * @author Nakul Saraiya
* @author Joseph D. Darcy * @author Joseph D. Darcy
* @see java.lang.Number * @see java.lang.Number
* @since 1.1 * @since 1.1
*/ */
@jdk.internal.ValueBased
public final class Byte extends Number implements Comparable<Byte>, Constable { public final class Byte extends Number implements Comparable<Byte>, Constable {
/** /**
@ -337,7 +344,7 @@ public final class Byte extends Number implements Comparable<Byte>, Constable {
* {@link #valueOf(byte)} is generally a better choice, as it is * {@link #valueOf(byte)} is generally a better choice, as it is
* likely to yield significantly better space and time performance. * likely to yield significantly better space and time performance.
*/ */
@Deprecated(since="9") @Deprecated(since="9", forRemoval = true)
public Byte(byte value) { public Byte(byte value) {
this.value = value; this.value = value;
} }
@ -360,7 +367,7 @@ public final class Byte extends Number implements Comparable<Byte>, Constable {
* {@code byte} primitive, or use {@link #valueOf(String)} * {@code byte} primitive, or use {@link #valueOf(String)}
* to convert a string to a {@code Byte} object. * to convert a string to a {@code Byte} object.
*/ */
@Deprecated(since="9") @Deprecated(since="9", forRemoval = true)
public Byte(String s) throws NumberFormatException { public Byte(String s) throws NumberFormatException {
this.value = parseByte(s, 10); this.value = parseByte(s, 10);
} }

View File

@ -122,6 +122,12 @@ import static java.lang.constant.ConstantDescs.DEFAULT_NAME;
* encoding. For more information on Unicode terminology, refer to the * encoding. For more information on Unicode terminology, refer to the
* <a href="http://www.unicode.org/glossary/">Unicode Glossary</a>. * <a href="http://www.unicode.org/glossary/">Unicode Glossary</a>.
* *
* <p>This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; programmers should treat instances that are
* {@linkplain #equals(Object) equal} as interchangeable and should not
* use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
*
* @author Lee Boynton * @author Lee Boynton
* @author Guy Steele * @author Guy Steele
* @author Akira Tanaka * @author Akira Tanaka
@ -129,6 +135,7 @@ import static java.lang.constant.ConstantDescs.DEFAULT_NAME;
* @author Ulf Zibis * @author Ulf Zibis
* @since 1.0 * @since 1.0
*/ */
@jdk.internal.ValueBased
public final public final
class Character implements java.io.Serializable, Comparable<Character>, Constable { class Character implements java.io.Serializable, Comparable<Character>, Constable {
/** /**
@ -8501,7 +8508,7 @@ class Character implements java.io.Serializable, Comparable<Character>, Constabl
* {@link #valueOf(char)} is generally a better choice, as it is * {@link #valueOf(char)} is generally a better choice, as it is
* likely to yield significantly better space and time performance. * likely to yield significantly better space and time performance.
*/ */
@Deprecated(since="9") @Deprecated(since="9", forRemoval = true)
public Character(char value) { public Character(char value) {
this.value = value; this.value = value;
} }

View File

@ -46,11 +46,18 @@ import jdk.internal.vm.annotation.IntrinsicCandidate;
* constants and methods useful when dealing with a * constants and methods useful when dealing with a
* {@code double}. * {@code double}.
* *
* <p>This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; programmers should treat instances that are
* {@linkplain #equals(Object) equal} as interchangeable and should not
* use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
*
* @author Lee Boynton * @author Lee Boynton
* @author Arthur van Hoff * @author Arthur van Hoff
* @author Joseph D. Darcy * @author Joseph D. Darcy
* @since 1.0 * @since 1.0
*/ */
@jdk.internal.ValueBased
public final class Double extends Number public final class Double extends Number
implements Comparable<Double>, Constable, ConstantDesc { implements Comparable<Double>, Constable, ConstantDesc {
/** /**
@ -605,7 +612,7 @@ public final class Double extends Number
* {@link #valueOf(double)} is generally a better choice, as it is * {@link #valueOf(double)} is generally a better choice, as it is
* likely to yield significantly better space and time performance. * likely to yield significantly better space and time performance.
*/ */
@Deprecated(since="9") @Deprecated(since="9", forRemoval = true)
public Double(double value) { public Double(double value) {
this.value = value; this.value = value;
} }
@ -626,7 +633,7 @@ public final class Double extends Number
* {@code double} primitive, or use {@link #valueOf(String)} * {@code double} primitive, or use {@link #valueOf(String)}
* to convert a string to a {@code Double} object. * to convert a string to a {@code Double} object.
*/ */
@Deprecated(since="9") @Deprecated(since="9", forRemoval = true)
public Double(String s) throws NumberFormatException { public Double(String s) throws NumberFormatException {
value = parseDouble(s); value = parseDouble(s);
} }

View File

@ -45,11 +45,18 @@ import jdk.internal.vm.annotation.IntrinsicCandidate;
* constants and methods useful when dealing with a * constants and methods useful when dealing with a
* {@code float}. * {@code float}.
* *
* <p>This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; programmers should treat instances that are
* {@linkplain #equals(Object) equal} as interchangeable and should not
* use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
*
* @author Lee Boynton * @author Lee Boynton
* @author Arthur van Hoff * @author Arthur van Hoff
* @author Joseph D. Darcy * @author Joseph D. Darcy
* @since 1.0 * @since 1.0
*/ */
@jdk.internal.ValueBased
public final class Float extends Number public final class Float extends Number
implements Comparable<Float>, Constable, ConstantDesc { implements Comparable<Float>, Constable, ConstantDesc {
/** /**
@ -518,7 +525,7 @@ public final class Float extends Number
* {@link #valueOf(float)} is generally a better choice, as it is * {@link #valueOf(float)} is generally a better choice, as it is
* likely to yield significantly better space and time performance. * likely to yield significantly better space and time performance.
*/ */
@Deprecated(since="9") @Deprecated(since="9", forRemoval = true)
public Float(float value) { public Float(float value) {
this.value = value; this.value = value;
} }
@ -534,7 +541,7 @@ public final class Float extends Number
* static factory method {@link #valueOf(float)} method as follows: * static factory method {@link #valueOf(float)} method as follows:
* {@code Float.valueOf((float)value)}. * {@code Float.valueOf((float)value)}.
*/ */
@Deprecated(since="9") @Deprecated(since="9", forRemoval = true)
public Float(double value) { public Float(double value) {
this.value = (float)value; this.value = (float)value;
} }
@ -555,7 +562,7 @@ public final class Float extends Number
* {@code float} primitive, or use {@link #valueOf(String)} * {@code float} primitive, or use {@link #valueOf(String)}
* to convert a string to a {@code Float} object. * to convert a string to a {@code Float} object.
*/ */
@Deprecated(since="9") @Deprecated(since="9", forRemoval = true)
public Float(String s) throws NumberFormatException { public Float(String s) throws NumberFormatException {
value = parseFloat(s); value = parseFloat(s);
} }

View File

@ -50,6 +50,12 @@ import static java.lang.String.UTF16;
* {@code int}, as well as other constants and methods useful when * {@code int}, as well as other constants and methods useful when
* dealing with an {@code int}. * dealing with an {@code int}.
* *
* <p>This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; programmers should treat instances that are
* {@linkplain #equals(Object) equal} as interchangeable and should not
* use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
*
* <p>Implementation note: The implementations of the "bit twiddling" * <p>Implementation note: The implementations of the "bit twiddling"
* methods (such as {@link #highestOneBit(int) highestOneBit} and * methods (such as {@link #highestOneBit(int) highestOneBit} and
* {@link #numberOfTrailingZeros(int) numberOfTrailingZeros}) are * {@link #numberOfTrailingZeros(int) numberOfTrailingZeros}) are
@ -62,6 +68,7 @@ import static java.lang.String.UTF16;
* @author Joseph D. Darcy * @author Joseph D. Darcy
* @since 1.0 * @since 1.0
*/ */
@jdk.internal.ValueBased
public final class Integer extends Number public final class Integer extends Number
implements Comparable<Integer>, Constable, ConstantDesc { implements Comparable<Integer>, Constable, ConstantDesc {
/** /**
@ -1085,7 +1092,7 @@ public final class Integer extends Number
* {@link #valueOf(int)} is generally a better choice, as it is * {@link #valueOf(int)} is generally a better choice, as it is
* likely to yield significantly better space and time performance. * likely to yield significantly better space and time performance.
*/ */
@Deprecated(since="9") @Deprecated(since="9", forRemoval = true)
public Integer(int value) { public Integer(int value) {
this.value = value; this.value = value;
} }
@ -1107,7 +1114,7 @@ public final class Integer extends Number
* {@code int} primitive, or use {@link #valueOf(String)} * {@code int} primitive, or use {@link #valueOf(String)}
* to convert a string to an {@code Integer} object. * to convert a string to an {@code Integer} object.
*/ */
@Deprecated(since="9") @Deprecated(since="9", forRemoval = true)
public Integer(String s) throws NumberFormatException { public Integer(String s) throws NumberFormatException {
this.value = parseInt(s, 10); this.value = parseInt(s, 10);
} }

View File

@ -50,6 +50,12 @@ import static java.lang.String.UTF16;
* long}, as well as other constants and methods useful when dealing * long}, as well as other constants and methods useful when dealing
* with a {@code long}. * with a {@code long}.
* *
* <p>This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; programmers should treat instances that are
* {@linkplain #equals(Object) equal} as interchangeable and should not
* use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
*
* <p>Implementation note: The implementations of the "bit twiddling" * <p>Implementation note: The implementations of the "bit twiddling"
* methods (such as {@link #highestOneBit(long) highestOneBit} and * methods (such as {@link #highestOneBit(long) highestOneBit} and
* {@link #numberOfTrailingZeros(long) numberOfTrailingZeros}) are * {@link #numberOfTrailingZeros(long) numberOfTrailingZeros}) are
@ -62,6 +68,7 @@ import static java.lang.String.UTF16;
* @author Joseph D. Darcy * @author Joseph D. Darcy
* @since 1.0 * @since 1.0
*/ */
@jdk.internal.ValueBased
public final class Long extends Number public final class Long extends Number
implements Comparable<Long>, Constable, ConstantDesc { implements Comparable<Long>, Constable, ConstantDesc {
/** /**
@ -1316,7 +1323,7 @@ public final class Long extends Number
* {@link #valueOf(long)} is generally a better choice, as it is * {@link #valueOf(long)} is generally a better choice, as it is
* likely to yield significantly better space and time performance. * likely to yield significantly better space and time performance.
*/ */
@Deprecated(since="9") @Deprecated(since="9", forRemoval = true)
public Long(long value) { public Long(long value) {
this.value = value; this.value = value;
} }
@ -1339,7 +1346,7 @@ public final class Long extends Number
* {@code long} primitive, or use {@link #valueOf(String)} * {@code long} primitive, or use {@link #valueOf(String)}
* to convert a string to a {@code Long} object. * to convert a string to a {@code Long} object.
*/ */
@Deprecated(since="9") @Deprecated(since="9", forRemoval = true)
public Long(String s) throws NumberFormatException { public Long(String s) throws NumberFormatException {
this.value = parseLong(s, 10); this.value = parseLong(s, 10);
} }

View File

@ -81,16 +81,17 @@ import java.util.stream.Stream;
* <p> * <p>
* The {@code ProcessHandle} static factory methods return instances that are * The {@code ProcessHandle} static factory methods return instances that are
* <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>, * <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>,
* immutable and thread-safe. * immutable and thread-safe. Programmers should treat instances that are
* Use of identity-sensitive operations (including reference equality * {@linkplain #equals(Object) equal} as interchangeable and should not
* ({@code ==}), identity hash code, or synchronization) on these instances of * use instances for synchronization, or unpredictable behavior may occur.
* {@code ProcessHandle} may have unpredictable results and should be avoided. * For example, in a future release, synchronization may fail.
* Use {@link #equals(Object) equals} or * Use the {@code equals} or {@link #compareTo(ProcessHandle) compareTo} methods
* {@link #compareTo(ProcessHandle) compareTo} methods to compare ProcessHandles. * to compare ProcessHandles.
* *
* @see Process * @see Process
* @since 9 * @since 9
*/ */
@jdk.internal.ValueBased
public interface ProcessHandle extends Comparable<ProcessHandle> { public interface ProcessHandle extends Comparable<ProcessHandle> {
/** /**

View File

@ -48,6 +48,7 @@ import static java.security.AccessController.doPrivileged;
* @see Process * @see Process
* @since 9 * @since 9
*/ */
@jdk.internal.ValueBased
final class ProcessHandleImpl implements ProcessHandle { final class ProcessHandleImpl implements ProcessHandle {
/** /**
* Default size of stack for reaper processes. * Default size of stack for reaper processes.

View File

@ -941,14 +941,15 @@ public class Runtime {
* $VNUM(-$PRE)? * $VNUM(-$PRE)?
* </pre></blockquote> * </pre></blockquote>
* *
* <p>This is a <a href="./doc-files/ValueBased.html">value-based</a> * <p>This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code Version} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* </p> * occur. For example, in a future release, synchronization may fail.</p>
* *
* @since 9 * @since 9
*/ */
@jdk.internal.ValueBased
public static final class Version public static final class Version
implements Comparable<Version> implements Comparable<Version>
{ {

View File

@ -47,11 +47,18 @@ import static java.lang.constant.ConstantDescs.DEFAULT_NAME;
* {@code short}, as well as other constants and methods useful when * {@code short}, as well as other constants and methods useful when
* dealing with a {@code short}. * dealing with a {@code short}.
* *
* <p>This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; programmers should treat instances that are
* {@linkplain #equals(Object) equal} as interchangeable and should not
* use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
*
* @author Nakul Saraiya * @author Nakul Saraiya
* @author Joseph D. Darcy * @author Joseph D. Darcy
* @see java.lang.Number * @see java.lang.Number
* @since 1.1 * @since 1.1
*/ */
@jdk.internal.ValueBased
public final class Short extends Number implements Comparable<Short>, Constable { public final class Short extends Number implements Comparable<Short>, Constable {
/** /**
@ -342,7 +349,7 @@ public final class Short extends Number implements Comparable<Short>, Constable
* {@link #valueOf(short)} is generally a better choice, as it is * {@link #valueOf(short)} is generally a better choice, as it is
* likely to yield significantly better space and time performance. * likely to yield significantly better space and time performance.
*/ */
@Deprecated(since="9") @Deprecated(since="9", forRemoval = true)
public Short(short value) { public Short(short value) {
this.value = value; this.value = value;
} }
@ -365,7 +372,7 @@ public final class Short extends Number implements Comparable<Short>, Constable
* {@code short} primitive, or use {@link #valueOf(String)} * {@code short} primitive, or use {@link #valueOf(String)}
* to convert a string to a {@code Short} object. * to convert a string to a {@code Short} object.
*/ */
@Deprecated(since="9") @Deprecated(since="9", forRemoval = true)
public Short(String s) throws NumberFormatException { public Short(String s) throws NumberFormatException {
this.value = parseShort(s, 10); this.value = parseShort(s, 10);
} }

View File

@ -57,8 +57,8 @@ import java.lang.invoke.VarHandle.VarHandleDesc;
* <p>Constants describing various common constants (such as {@link ClassDesc} * <p>Constants describing various common constants (such as {@link ClassDesc}
* instances for platform types) can be found in {@link ConstantDescs}. * instances for platform types) can be found in {@link ConstantDescs}.
* *
* <p>Implementations of {@linkplain ConstantDesc} must be * <p>Implementations of {@linkplain ConstantDesc} should be immutable
* <a href="../doc-files/ValueBased.html">value-based</a> classes. * and their behavior should not rely on object identity.
* *
* <p>Non-platform classes should not implement {@linkplain ConstantDesc} directly. * <p>Non-platform classes should not implement {@linkplain ConstantDesc} directly.
* Instead, they should extend {@link DynamicConstantDesc} (as {@link EnumDesc} * Instead, they should extend {@link DynamicConstantDesc} (as {@link EnumDesc}

View File

@ -41,8 +41,8 @@ import static java.util.stream.Collectors.joining;
* A <a href="package-summary.html#nominal">nominal descriptor</a> for an * A <a href="package-summary.html#nominal">nominal descriptor</a> for an
* {@code invokedynamic} call site. * {@code invokedynamic} call site.
* *
* <p>Concrete subtypes of {@linkplain DynamicCallSiteDesc} must be * <p>Concrete subtypes of {@linkplain DynamicCallSiteDesc} should be immutable
* <a href="../doc-files/ValueBased.html">value-based</a>. * and their behavior should not rely on object identity.
* *
* @since 12 * @since 12
*/ */

View File

@ -49,8 +49,8 @@ import static java.util.stream.Collectors.joining;
* dynamic constant (one described in the constant pool with * dynamic constant (one described in the constant pool with
* {@code Constant_Dynamic_info}.) * {@code Constant_Dynamic_info}.)
* *
* <p>Concrete subtypes of {@linkplain DynamicConstantDesc} must be * <p>Concrete subtypes of {@linkplain DynamicConstantDesc} should be immutable
* <a href="../doc-files/ValueBased.html">value-based</a>. * and their behavior should not rely on object identity.
* *
* @param <T> the type of the dynamic constant * @param <T> the type of the dynamic constant
* *

View File

@ -31,36 +31,43 @@
<body> <body>
<h1 id="ValueBased">{@index "Value-based Classes"}</h1> <h1 id="ValueBased">{@index "Value-based Classes"}</h1>
Some classes, such as <code>java.util.Optional</code> and Some classes, such as <code>java.lang.Integer</code> and
<code>java.time.LocalDateTime</code>, are <em>value-based</em>. Instances of a <code>java.time.LocalDate</code>, are <em>value-based</em>.
value-based class: A value-based class has the following properties:
<ul> <ul>
<li>are final and immutable (though may contain references to mutable <li>the class declares only final instance fields (though these may contain references
objects);</li> to mutable objects);</li>
<li>have implementations of <code>equals</code>, <li>the class's implementations of <code>equals</code>, <code>hashCode</code>,
<code>hashCode</code>, and <code>toString</code> which are computed and <code>toString</code> compute their results solely from the values
solely from the instance's state and not from its identity or the state of the class's instance fields (and the members of the objects they
of any other object or variable;</li> reference), not from the instance's identity;</li>
<li>make no use of identity-sensitive operations such as reference <li>the class's methods treat instances as <em>freely substitutable</em>
equality (<code>==</code>) between instances, identity hash code of when equal, meaning that interchanging any two instances <code>x</code> and
instances, or synchronization on an instances's intrinsic lock;</li> <code>y</code> that are equal according to <code>equals()</code> produces no
<li>are considered equal solely based on <code>equals()</code>, not visible change in the behavior of the class's methods;</li>
based on reference equality (<code>==</code>);</li> <li>the class performs no synchronization using an instance's monitor;</li>
<li>do not have accessible constructors, but are instead instantiated <li>the class does not declare (or has deprecated any) accessible constructors;</li>
through factory methods which make no commitment as to the identity <li>the class does not provide any instance creation mechanism that promises
of returned instances;</li> a unique identity on each method call&mdash;in particular, any factory
<li>are <em>freely substitutable</em> when equal, meaning that interchanging method's contract must allow for the possibility that if two independently-produced
any two instances <code>x</code> and <code>y</code> that are equal instances are equal according to <code>equals()</code>, they may also be
according to <code>equals()</code> in any computation or method equal according to <code>==</code>;</li>
invocation should produce no visible change in behavior. <li>the class is final, and extends either <code>Object</code> or a hierarchy of
</li> abstract classes that declare no instance fields or instance initializers
and whose constructors are empty.</li>
</ul> </ul>
<p>A program may produce unpredictable results if it attempts to distinguish two <p>When two instances of a value-based class are equal (according to `equals`), a program
references to equal values of a value-based class, whether directly via reference should not attempt to distinguish between their identities, whether directly via reference
equality or indirectly via an appeal to synchronization, identity hashing, equality or indirectly via an appeal to synchronization, identity hashing,
serialization, or any other identity-sensitive mechanism. Use of such serialization, or any other identity-sensitive mechanism.</p>
identity-sensitive operations on instances of value-based classes may have
unpredictable effects and should be avoided.</p> <p>Synchronization on instances of value-based classes is strongly discouraged,
because the programmer cannot guarantee exclusive ownership of the
associated monitor.</p>
<p>Identity-related behavior of value-based classes may change in a future release.
For example, synchronization may fail.</p>
</body> </body>
</html> </html>

View File

@ -773,7 +773,7 @@ final class MemberName implements Member, Cloneable {
} }
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings({"deprecation", "removal"})
public int hashCode() { public int hashCode() {
// Avoid autoboxing getReferenceKind(), since this is used early and will force // Avoid autoboxing getReferenceKind(), since this is used early and will force
// early initialization of Byte$ByteCache // early initialization of Byte$ByteCache

View File

@ -117,12 +117,12 @@ import java.util.regex.Pattern;
* This difference only impacts durations measured near a leap-second and should not affect * This difference only impacts durations measured near a leap-second and should not affect
* most applications. * most applications.
* See {@link Instant} for a discussion as to the meaning of the second and time-scales. * See {@link Instant} for a discussion as to the meaning of the second and time-scales.
*
* <p> * <p>
* This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a> * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code Duration} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* The {@code equals} method should be used for comparisons. * The {@code equals} method should be used for comparisons.
* *
* @implSpec * @implSpec
@ -130,6 +130,7 @@ import java.util.regex.Pattern;
* *
* @since 1.8 * @since 1.8
*/ */
@jdk.internal.ValueBased
public final class Duration public final class Duration
implements TemporalAmount, Comparable<Duration>, Serializable { implements TemporalAmount, Comparable<Duration>, Serializable {

View File

@ -191,12 +191,12 @@ import java.util.Objects;
* The Java time-scale is used for all date-time classes. * The Java time-scale is used for all date-time classes.
* This includes {@code Instant}, {@code LocalDate}, {@code LocalTime}, {@code OffsetDateTime}, * This includes {@code Instant}, {@code LocalDate}, {@code LocalTime}, {@code OffsetDateTime},
* {@code ZonedDateTime} and {@code Duration}. * {@code ZonedDateTime} and {@code Duration}.
*
* <p> * <p>
* This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a> * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code Instant} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* The {@code equals} method should be used for comparisons. * The {@code equals} method should be used for comparisons.
* *
* @implSpec * @implSpec
@ -204,6 +204,7 @@ import java.util.Objects;
* *
* @since 1.8 * @since 1.8
*/ */
@jdk.internal.ValueBased
public final class Instant public final class Instant
implements Temporal, TemporalAdjuster, Comparable<Instant>, Serializable { implements Temporal, TemporalAdjuster, Comparable<Instant>, Serializable {

View File

@ -123,12 +123,12 @@ import java.util.stream.Stream;
* For most applications written today, the ISO-8601 rules are entirely suitable. * For most applications written today, the ISO-8601 rules are entirely suitable.
* However, any application that makes use of historical dates, and requires them * However, any application that makes use of historical dates, and requires them
* to be accurate will find the ISO-8601 approach unsuitable. * to be accurate will find the ISO-8601 approach unsuitable.
*
* <p> * <p>
* This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a> * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code LocalDate} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* The {@code equals} method should be used for comparisons. * The {@code equals} method should be used for comparisons.
* *
* @implSpec * @implSpec
@ -136,6 +136,7 @@ import java.util.stream.Stream;
* *
* @since 1.8 * @since 1.8
*/ */
@jdk.internal.ValueBased
public final class LocalDate public final class LocalDate
implements Temporal, TemporalAdjuster, ChronoLocalDate, Serializable { implements Temporal, TemporalAdjuster, ChronoLocalDate, Serializable {

View File

@ -119,12 +119,12 @@ import java.util.Objects;
* For most applications written today, the ISO-8601 rules are entirely suitable. * For most applications written today, the ISO-8601 rules are entirely suitable.
* However, any application that makes use of historical dates, and requires them * However, any application that makes use of historical dates, and requires them
* to be accurate will find the ISO-8601 approach unsuitable. * to be accurate will find the ISO-8601 approach unsuitable.
*
* <p> * <p>
* This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a> * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code LocalDateTime} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* The {@code equals} method should be used for comparisons. * The {@code equals} method should be used for comparisons.
* *
* @implSpec * @implSpec
@ -132,6 +132,7 @@ import java.util.Objects;
* *
* @since 1.8 * @since 1.8
*/ */
@jdk.internal.ValueBased
public final class LocalDateTime public final class LocalDateTime
implements Temporal, TemporalAdjuster, ChronoLocalDateTime<LocalDate>, Serializable { implements Temporal, TemporalAdjuster, ChronoLocalDateTime<LocalDate>, Serializable {

View File

@ -109,12 +109,12 @@ import java.util.Objects;
* The ISO-8601 calendar system is the modern civil calendar system used today * The ISO-8601 calendar system is the modern civil calendar system used today
* in most of the world. This API assumes that all calendar systems use the same * in most of the world. This API assumes that all calendar systems use the same
* representation, this class, for time-of-day. * representation, this class, for time-of-day.
*
* <p> * <p>
* This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a> * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code LocalTime} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* The {@code equals} method should be used for comparisons. * The {@code equals} method should be used for comparisons.
* *
* @implSpec * @implSpec
@ -122,6 +122,7 @@ import java.util.Objects;
* *
* @since 1.8 * @since 1.8
*/ */
@jdk.internal.ValueBased
public final class LocalTime public final class LocalTime
implements Temporal, TemporalAdjuster, Comparable<LocalTime>, Serializable { implements Temporal, TemporalAdjuster, Comparable<LocalTime>, Serializable {

View File

@ -111,12 +111,12 @@ import java.util.Objects;
* For most applications written today, the ISO-8601 rules are entirely suitable. * For most applications written today, the ISO-8601 rules are entirely suitable.
* However, any application that makes use of historical dates, and requires them * However, any application that makes use of historical dates, and requires them
* to be accurate will find the ISO-8601 approach unsuitable. * to be accurate will find the ISO-8601 approach unsuitable.
*
* <p> * <p>
* This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a> * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code MonthDay} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* The {@code equals} method should be used for comparisons. * The {@code equals} method should be used for comparisons.
* *
* @implSpec * @implSpec
@ -124,6 +124,7 @@ import java.util.Objects;
* *
* @since 1.8 * @since 1.8
*/ */
@jdk.internal.ValueBased
public final class MonthDay public final class MonthDay
implements TemporalAccessor, TemporalAdjuster, Comparable<MonthDay>, Serializable { implements TemporalAccessor, TemporalAdjuster, Comparable<MonthDay>, Serializable {

View File

@ -112,12 +112,12 @@ import java.util.Objects;
* It is intended that {@code ZonedDateTime} or {@code Instant} is used to model data * It is intended that {@code ZonedDateTime} or {@code Instant} is used to model data
* in simpler applications. This class may be used when modeling date-time concepts in * in simpler applications. This class may be used when modeling date-time concepts in
* more detail, or when communicating to a database or in a network protocol. * more detail, or when communicating to a database or in a network protocol.
*
* <p> * <p>
* This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a> * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code OffsetDateTime} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* The {@code equals} method should be used for comparisons. * The {@code equals} method should be used for comparisons.
* *
* @implSpec * @implSpec
@ -125,6 +125,7 @@ import java.util.Objects;
* *
* @since 1.8 * @since 1.8
*/ */
@jdk.internal.ValueBased
public final class OffsetDateTime public final class OffsetDateTime
implements Temporal, TemporalAdjuster, Comparable<OffsetDateTime>, Serializable { implements Temporal, TemporalAdjuster, Comparable<OffsetDateTime>, Serializable {

View File

@ -102,12 +102,12 @@ import java.util.Objects;
* as well as a zone offset. * as well as a zone offset.
* For example, the value "13:45:30.123456789+02:00" can be stored * For example, the value "13:45:30.123456789+02:00" can be stored
* in an {@code OffsetTime}. * in an {@code OffsetTime}.
*
* <p> * <p>
* This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a> * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code OffsetTime} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* The {@code equals} method should be used for comparisons. * The {@code equals} method should be used for comparisons.
* *
* @implSpec * @implSpec
@ -115,6 +115,7 @@ import java.util.Objects;
* *
* @since 1.8 * @since 1.8
*/ */
@jdk.internal.ValueBased
public final class OffsetTime public final class OffsetTime
implements Temporal, TemporalAdjuster, Comparable<OffsetTime>, Serializable { implements Temporal, TemporalAdjuster, Comparable<OffsetTime>, Serializable {

View File

@ -117,12 +117,12 @@ import java.util.regex.Pattern;
* <p> * <p>
* The period is modeled as a directed amount of time, meaning that individual parts of the * The period is modeled as a directed amount of time, meaning that individual parts of the
* period may be negative. * period may be negative.
*
* <p> * <p>
* This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a> * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code Period} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* The {@code equals} method should be used for comparisons. * The {@code equals} method should be used for comparisons.
* *
* @implSpec * @implSpec
@ -130,6 +130,7 @@ import java.util.regex.Pattern;
* *
* @since 1.8 * @since 1.8
*/ */
@jdk.internal.ValueBased
public final class Period public final class Period
implements ChronoPeriod, Serializable { implements ChronoPeriod, Serializable {

View File

@ -119,12 +119,12 @@ import java.util.Objects;
* For most applications written today, the ISO-8601 rules are entirely suitable. * For most applications written today, the ISO-8601 rules are entirely suitable.
* However, any application that makes use of historical dates, and requires them * However, any application that makes use of historical dates, and requires them
* to be accurate will find the ISO-8601 approach unsuitable. * to be accurate will find the ISO-8601 approach unsuitable.
*
* <p> * <p>
* This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a> * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code Year} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* The {@code equals} method should be used for comparisons. * The {@code equals} method should be used for comparisons.
* *
* @implSpec * @implSpec
@ -132,6 +132,7 @@ import java.util.Objects;
* *
* @since 1.8 * @since 1.8
*/ */
@jdk.internal.ValueBased
public final class Year public final class Year
implements Temporal, TemporalAdjuster, Comparable<Year>, Serializable { implements Temporal, TemporalAdjuster, Comparable<Year>, Serializable {

View File

@ -115,12 +115,12 @@ import java.util.Objects;
* For most applications written today, the ISO-8601 rules are entirely suitable. * For most applications written today, the ISO-8601 rules are entirely suitable.
* However, any application that makes use of historical dates, and requires them * However, any application that makes use of historical dates, and requires them
* to be accurate will find the ISO-8601 approach unsuitable. * to be accurate will find the ISO-8601 approach unsuitable.
*
* <p> * <p>
* This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a> * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code YearMonth} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* The {@code equals} method should be used for comparisons. * The {@code equals} method should be used for comparisons.
* *
* @implSpec * @implSpec
@ -128,6 +128,7 @@ import java.util.Objects;
* *
* @since 1.8 * @since 1.8
*/ */
@jdk.internal.ValueBased
public final class YearMonth public final class YearMonth
implements Temporal, TemporalAdjuster, Comparable<YearMonth>, Serializable { implements Temporal, TemporalAdjuster, Comparable<YearMonth>, Serializable {

View File

@ -160,12 +160,12 @@ import static java.util.Map.entry;
* However, any call to {@code getRules} will fail with {@code ZoneRulesException}. * However, any call to {@code getRules} will fail with {@code ZoneRulesException}.
* This approach is designed to allow a {@link ZonedDateTime} to be loaded and * This approach is designed to allow a {@link ZonedDateTime} to be loaded and
* queried, but not modified, on a Java Runtime with incomplete time-zone information. * queried, but not modified, on a Java Runtime with incomplete time-zone information.
*
* <p> * <p>
* This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a> * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code ZoneId} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* The {@code equals} method should be used for comparisons. * The {@code equals} method should be used for comparisons.
* *
* @implSpec * @implSpec
@ -175,6 +175,7 @@ import static java.util.Map.entry;
* *
* @since 1.8 * @since 1.8
*/ */
@jdk.internal.ValueBased
public abstract class ZoneId implements Serializable { public abstract class ZoneId implements Serializable {
/** /**

View File

@ -114,12 +114,12 @@ import java.util.concurrent.ConcurrentMap;
* Instances of {@code ZoneOffset} must be compared using {@link #equals}. * Instances of {@code ZoneOffset} must be compared using {@link #equals}.
* Implementations may choose to cache certain common offsets, however * Implementations may choose to cache certain common offsets, however
* applications must not rely on such caching. * applications must not rely on such caching.
*
* <p> * <p>
* This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a> * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code ZoneOffset} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* The {@code equals} method should be used for comparisons. * The {@code equals} method should be used for comparisons.
* *
* @implSpec * @implSpec
@ -127,6 +127,7 @@ import java.util.concurrent.ConcurrentMap;
* *
* @since 1.8 * @since 1.8
*/ */
@jdk.internal.ValueBased
public final class ZoneOffset public final class ZoneOffset
extends ZoneId extends ZoneId
implements TemporalAccessor, TemporalAdjuster, Comparable<ZoneOffset>, Serializable { implements TemporalAccessor, TemporalAdjuster, Comparable<ZoneOffset>, Serializable {

View File

@ -142,12 +142,12 @@ import java.util.Objects;
* of a {@code LocalDateTime} and a {@code ZoneId}. The {@code ZoneOffset} is * of a {@code LocalDateTime} and a {@code ZoneId}. The {@code ZoneOffset} is
* a vital, but secondary, piece of information, used to ensure that the class * a vital, but secondary, piece of information, used to ensure that the class
* represents an instant, especially during a daylight savings overlap. * represents an instant, especially during a daylight savings overlap.
*
* <p> * <p>
* This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a> * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code ZonedDateTime} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* The {@code equals} method should be used for comparisons. * The {@code equals} method should be used for comparisons.
* *
* @implSpec * @implSpec
@ -161,6 +161,7 @@ import java.util.Objects;
* *
* @since 1.8 * @since 1.8
*/ */
@jdk.internal.ValueBased
public final class ZonedDateTime public final class ZonedDateTime
implements Temporal, ChronoZonedDateTime<LocalDate>, Serializable { implements Temporal, ChronoZonedDateTime<LocalDate>, Serializable {

View File

@ -103,12 +103,12 @@ import java.time.temporal.ValueRange;
* to create new HijrahDate instances. * to create new HijrahDate instances.
* Alternatively, the {@link #withVariant} method can be used to convert * Alternatively, the {@link #withVariant} method can be used to convert
* to a new HijrahChronology. * to a new HijrahChronology.
*
* <p> * <p>
* This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a> * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code HijrahDate} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* The {@code equals} method should be used for comparisons. * The {@code equals} method should be used for comparisons.
* *
* @implSpec * @implSpec
@ -116,6 +116,7 @@ import java.time.temporal.ValueRange;
* *
* @since 1.8 * @since 1.8
*/ */
@jdk.internal.ValueBased
public final class HijrahDate public final class HijrahDate
extends ChronoLocalDateImpl<HijrahDate> extends ChronoLocalDateImpl<HijrahDate>
implements ChronoLocalDate, Serializable { implements ChronoLocalDate, Serializable {

View File

@ -110,12 +110,12 @@ import sun.util.calendar.LocalGregorianCalendar;
* Calling {@code japaneseDate.get(YEAR)} will return 2012.<br> * Calling {@code japaneseDate.get(YEAR)} will return 2012.<br>
* Calling {@code japaneseDate.get(ERA)} will return 2, corresponding to * Calling {@code japaneseDate.get(ERA)} will return 2, corresponding to
* {@code JapaneseChronology.ERA_HEISEI}.<br> * {@code JapaneseChronology.ERA_HEISEI}.<br>
*
* <p> * <p>
* This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a> * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code JapaneseDate} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* The {@code equals} method should be used for comparisons. * The {@code equals} method should be used for comparisons.
* *
* @implSpec * @implSpec
@ -123,6 +123,7 @@ import sun.util.calendar.LocalGregorianCalendar;
* *
* @since 1.8 * @since 1.8
*/ */
@jdk.internal.ValueBased
public final class JapaneseDate public final class JapaneseDate
extends ChronoLocalDateImpl<JapaneseDate> extends ChronoLocalDateImpl<JapaneseDate>
implements ChronoLocalDate, Serializable { implements ChronoLocalDate, Serializable {
@ -140,11 +141,11 @@ public final class JapaneseDate
/** /**
* The JapaneseEra of this date. * The JapaneseEra of this date.
*/ */
private transient JapaneseEra era; private final transient JapaneseEra era;
/** /**
* The Japanese imperial calendar year of this date. * The Japanese imperial calendar year of this date.
*/ */
private transient int yearOfEra; private final transient int yearOfEra;
/** /**
* The first day supported by the JapaneseChronology is Meiji 6, January 1st. * The first day supported by the JapaneseChronology is Meiji 6, January 1st.

View File

@ -90,12 +90,12 @@ import java.util.Objects;
* This date operates using the {@linkplain MinguoChronology Minguo calendar}. * This date operates using the {@linkplain MinguoChronology Minguo calendar}.
* This calendar system is primarily used in the Republic of China, often known as Taiwan. * This calendar system is primarily used in the Republic of China, often known as Taiwan.
* Dates are aligned such that {@code 0001-01-01 (Minguo)} is {@code 1912-01-01 (ISO)}. * Dates are aligned such that {@code 0001-01-01 (Minguo)} is {@code 1912-01-01 (ISO)}.
*
* <p> * <p>
* This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a> * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code MinguoDate} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* The {@code equals} method should be used for comparisons. * The {@code equals} method should be used for comparisons.
* *
* @implSpec * @implSpec
@ -103,6 +103,7 @@ import java.util.Objects;
* *
* @since 1.8 * @since 1.8
*/ */
@jdk.internal.ValueBased
public final class MinguoDate public final class MinguoDate
extends ChronoLocalDateImpl<MinguoDate> extends ChronoLocalDateImpl<MinguoDate>
implements ChronoLocalDate, Serializable { implements ChronoLocalDate, Serializable {

View File

@ -72,7 +72,6 @@ import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalField; import java.time.temporal.TemporalField;
import java.time.temporal.ValueRange; import java.time.temporal.ValueRange;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;

View File

@ -90,12 +90,12 @@ import java.util.Objects;
* This date operates using the {@linkplain ThaiBuddhistChronology Thai Buddhist calendar}. * This date operates using the {@linkplain ThaiBuddhistChronology Thai Buddhist calendar}.
* This calendar system is primarily used in Thailand. * This calendar system is primarily used in Thailand.
* Dates are aligned such that {@code 2484-01-01 (Buddhist)} is {@code 1941-01-01 (ISO)}. * Dates are aligned such that {@code 2484-01-01 (Buddhist)} is {@code 1941-01-01 (ISO)}.
*
* <p> * <p>
* This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a> * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code ThaiBuddhistDate} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* The {@code equals} method should be used for comparisons. * The {@code equals} method should be used for comparisons.
* *
* @implSpec * @implSpec
@ -103,6 +103,7 @@ import java.util.Objects;
* *
* @since 1.8 * @since 1.8
*/ */
@jdk.internal.ValueBased
public final class ThaiBuddhistDate public final class ThaiBuddhistDate
extends ChronoLocalDateImpl<ThaiBuddhistDate> extends ChronoLocalDateImpl<ThaiBuddhistDate>
implements ChronoLocalDate, Serializable { implements ChronoLocalDate, Serializable {

View File

@ -81,7 +81,7 @@ import java.util.Calendar;
* to the word used for month in association with a day and year in a date. * to the word used for month in association with a day and year in a date.
* *
* @implSpec * @implSpec
* This is immutable and thread-safe enum. * This is an immutable and thread-safe enum.
* *
* @since 1.8 * @since 1.8
*/ */

View File

@ -141,6 +141,7 @@ class ImmutableCollections {
static UnsupportedOperationException uoe() { return new UnsupportedOperationException(); } static UnsupportedOperationException uoe() { return new UnsupportedOperationException(); }
@jdk.internal.ValueBased
static abstract class AbstractImmutableCollection<E> extends AbstractCollection<E> { static abstract class AbstractImmutableCollection<E> extends AbstractCollection<E> {
// all mutating methods throw UnsupportedOperationException // all mutating methods throw UnsupportedOperationException
@Override public boolean add(E e) { throw uoe(); } @Override public boolean add(E e) { throw uoe(); }
@ -247,6 +248,7 @@ class ImmutableCollections {
// ---------- List Implementations ---------- // ---------- List Implementations ----------
@jdk.internal.ValueBased
static abstract class AbstractImmutableList<E> extends AbstractImmutableCollection<E> static abstract class AbstractImmutableList<E> extends AbstractImmutableCollection<E>
implements List<E>, RandomAccess { implements List<E>, RandomAccess {
@ -540,6 +542,7 @@ class ImmutableCollections {
} }
} }
@jdk.internal.ValueBased
static final class List12<E> extends AbstractImmutableList<E> static final class List12<E> extends AbstractImmutableList<E>
implements Serializable { implements Serializable {
@ -646,6 +649,7 @@ class ImmutableCollections {
} }
} }
@jdk.internal.ValueBased
static final class ListN<E> extends AbstractImmutableList<E> static final class ListN<E> extends AbstractImmutableList<E>
implements Serializable { implements Serializable {
@ -737,6 +741,7 @@ class ImmutableCollections {
// ---------- Set Implementations ---------- // ---------- Set Implementations ----------
@jdk.internal.ValueBased
static abstract class AbstractImmutableSet<E> extends AbstractImmutableCollection<E> static abstract class AbstractImmutableSet<E> extends AbstractImmutableCollection<E>
implements Set<E> { implements Set<E> {
@ -764,6 +769,7 @@ class ImmutableCollections {
public abstract int hashCode(); public abstract int hashCode();
} }
@jdk.internal.ValueBased
static final class Set12<E> extends AbstractImmutableSet<E> static final class Set12<E> extends AbstractImmutableSet<E>
implements Serializable { implements Serializable {
@ -889,6 +895,7 @@ class ImmutableCollections {
* least one null is always present. * least one null is always present.
* @param <E> the element type * @param <E> the element type
*/ */
@jdk.internal.ValueBased
static final class SetN<E> extends AbstractImmutableSet<E> static final class SetN<E> extends AbstractImmutableSet<E>
implements Serializable { implements Serializable {
@ -1055,6 +1062,7 @@ class ImmutableCollections {
// ---------- Map Implementations ---------- // ---------- Map Implementations ----------
@jdk.internal.ValueBased
abstract static class AbstractImmutableMap<K,V> extends AbstractMap<K,V> implements Serializable { abstract static class AbstractImmutableMap<K,V> extends AbstractMap<K,V> implements Serializable {
@Override public void clear() { throw uoe(); } @Override public void clear() { throw uoe(); }
@Override public V compute(K key, BiFunction<? super K,? super V,? extends V> rf) { throw uoe(); } @Override public V compute(K key, BiFunction<? super K,? super V,? extends V> rf) { throw uoe(); }
@ -1085,6 +1093,7 @@ class ImmutableCollections {
} }
} }
@jdk.internal.ValueBased
static final class Map1<K,V> extends AbstractImmutableMap<K,V> { static final class Map1<K,V> extends AbstractImmutableMap<K,V> {
@Stable @Stable
private final K k0; private final K k0;
@ -1151,6 +1160,7 @@ class ImmutableCollections {
* @param <K> the key type * @param <K> the key type
* @param <V> the value type * @param <V> the value type
*/ */
@jdk.internal.ValueBased
static final class MapN<K,V> extends AbstractImmutableMap<K,V> { static final class MapN<K,V> extends AbstractImmutableMap<K,V> {
@Stable @Stable

View File

@ -31,10 +31,11 @@ import jdk.internal.vm.annotation.Stable;
* An immutable container for a key and a value, suitable for use * An immutable container for a key and a value, suitable for use
* in creating and populating {@code Map} instances. * in creating and populating {@code Map} instances.
* *
* <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a> * <p>This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code KeyValueHolder} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* *
* @apiNote * @apiNote
* This class is not public. Instances can be created using the * This class is not public. Instances can be created using the
@ -49,6 +50,7 @@ import jdk.internal.vm.annotation.Stable;
* @see Map#ofEntries Map.ofEntries() * @see Map#ofEntries Map.ofEntries()
* @since 9 * @since 9
*/ */
@jdk.internal.ValueBased
final class KeyValueHolder<K,V> implements Map.Entry<K,V> { final class KeyValueHolder<K,V> implements Map.Entry<K,V> {
@Stable @Stable
final K key; final K key;

View File

@ -107,10 +107,12 @@ import java.util.function.UnaryOperator;
* <li>The lists and their {@link #subList(int, int) subList} views implement the * <li>The lists and their {@link #subList(int, int) subList} views implement the
* {@link RandomAccess} interface. * {@link RandomAccess} interface.
* <li>They are <a href="../lang/doc-files/ValueBased.html">value-based</a>. * <li>They are <a href="../lang/doc-files/ValueBased.html">value-based</a>.
* Callers should make no assumptions about the identity of the returned instances. * Programmers should treat instances that are {@linkplain #equals(Object) equal}
* Factories are free to create new instances or reuse existing ones. Therefore, * as interchangeable and should not use them for synchronization, or
* identity-sensitive operations on these instances (reference equality ({@code ==}), * unpredictable behavior may occur. For example, in a future release,
* identity hash code, and synchronization) are unreliable and should be avoided. * synchronization may fail. Callers should make no assumptions about the
* identity of the returned instances. Factories are free to
* create new instances or reuse existing ones.
* <li>They are serialized as specified on the * <li>They are serialized as specified on the
* <a href="{@docRoot}/serialized-form.html#java.util.CollSer">Serialized Form</a> * <a href="{@docRoot}/serialized-form.html#java.util.CollSer">Serialized Form</a>
* page. * page.

View File

@ -131,10 +131,12 @@ import java.io.Serializable;
* passed to a static factory method result in {@code IllegalArgumentException}. * passed to a static factory method result in {@code IllegalArgumentException}.
* <li>The iteration order of mappings is unspecified and is subject to change. * <li>The iteration order of mappings is unspecified and is subject to change.
* <li>They are <a href="../lang/doc-files/ValueBased.html">value-based</a>. * <li>They are <a href="../lang/doc-files/ValueBased.html">value-based</a>.
* Callers should make no assumptions about the identity of the returned instances. * Programmers should treat instances that are {@linkplain #equals(Object) equal}
* Factories are free to create new instances or reuse existing ones. Therefore, * as interchangeable and should not use them for synchronization, or
* identity-sensitive operations on these instances (reference equality ({@code ==}), * unpredictable behavior may occur. For example, in a future release,
* identity hash code, and synchronization) are unreliable and should be avoided. * synchronization may fail. Callers should make no assumptions
* about the identity of the returned instances. Factories are free to
* create new instances or reuse existing ones.
* <li>They are serialized as specified on the * <li>They are serialized as specified on the
* <a href="{@docRoot}/serialized-form.html#java.util.CollSer">Serialized Form</a> * <a href="{@docRoot}/serialized-form.html#java.util.CollSer">Serialized Form</a>
* page. * page.
@ -1636,10 +1638,12 @@ public interface Map<K, V> {
* on a returned {@code Entry} result in {@code UnsupportedOperationException}. * on a returned {@code Entry} result in {@code UnsupportedOperationException}.
* <li>They are not serializable. * <li>They are not serializable.
* <li>They are <a href="../lang/doc-files/ValueBased.html">value-based</a>. * <li>They are <a href="../lang/doc-files/ValueBased.html">value-based</a>.
* Callers should make no assumptions about the identity of the returned instances. * Programmers should treat instances that are {@linkplain #equals(Object) equal}
* This method is free to create new instances or reuse existing ones. Therefore, * as interchangeable and should not use them for synchronization, or
* identity-sensitive operations on these instances (reference equality ({@code ==}), * unpredictable behavior may occur. For example, in a future release,
* identity hash code, and synchronization) are unreliable and should be avoided. * synchronization may fail. Callers should make no assumptions
* about the identity of the returned instances. This method is free to
* create new instances or reuse existing ones.
* </ul> * </ul>
* *
* @apiNote * @apiNote

View File

@ -42,10 +42,11 @@ import java.util.stream.Stream;
* {@link #ifPresent(Consumer) ifPresent()} (performs an * {@link #ifPresent(Consumer) ifPresent()} (performs an
* action if a value is present). * action if a value is present).
* *
* <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a> * <p>This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code Optional} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* *
* @apiNote * @apiNote
* {@code Optional} is primarily intended for use as a method return type where * {@code Optional} is primarily intended for use as a method return type where
@ -57,6 +58,7 @@ import java.util.stream.Stream;
* @param <T> the type of value * @param <T> the type of value
* @since 1.8 * @since 1.8
*/ */
@jdk.internal.ValueBased
public final class Optional<T> { public final class Optional<T> {
/** /**
* Common instance for {@code empty()}. * Common instance for {@code empty()}.

View File

@ -41,10 +41,11 @@ import java.util.stream.DoubleStream;
* {@link #ifPresent(DoubleConsumer) ifPresent()} (performs * {@link #ifPresent(DoubleConsumer) ifPresent()} (performs
* an action if a value is present). * an action if a value is present).
* *
* <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a> * <p>This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code OptionalDouble} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* *
* @apiNote * @apiNote
* {@code OptionalDouble} is primarily intended for use as a method return type where * {@code OptionalDouble} is primarily intended for use as a method return type where
@ -54,6 +55,7 @@ import java.util.stream.DoubleStream;
* *
* @since 1.8 * @since 1.8
*/ */
@jdk.internal.ValueBased
public final class OptionalDouble { public final class OptionalDouble {
/** /**
* Common instance for {@code empty()}. * Common instance for {@code empty()}.

View File

@ -41,10 +41,11 @@ import java.util.stream.IntStream;
* {@link #ifPresent(IntConsumer) ifPresent()} (performs an * {@link #ifPresent(IntConsumer) ifPresent()} (performs an
* action if a value is present). * action if a value is present).
* *
* <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a> * <p>This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code OptionalInt} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* *
* @apiNote * @apiNote
* {@code OptionalInt} is primarily intended for use as a method return type where * {@code OptionalInt} is primarily intended for use as a method return type where
@ -54,6 +55,7 @@ import java.util.stream.IntStream;
* *
* @since 1.8 * @since 1.8
*/ */
@jdk.internal.ValueBased
public final class OptionalInt { public final class OptionalInt {
/** /**
* Common instance for {@code empty()}. * Common instance for {@code empty()}.

View File

@ -41,10 +41,11 @@ import java.util.stream.LongStream;
* {@link #ifPresent(LongConsumer) ifPresent()} (performs an * {@link #ifPresent(LongConsumer) ifPresent()} (performs an
* action if a value is present). * action if a value is present).
* *
* <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a> * <p>This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code OptionalLong} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* *
* @apiNote * @apiNote
* {@code OptionalLong} is primarily intended for use as a method return type where * {@code OptionalLong} is primarily intended for use as a method return type where
@ -54,6 +55,7 @@ import java.util.stream.LongStream;
* *
* @since 1.8 * @since 1.8
*/ */
@jdk.internal.ValueBased
public final class OptionalLong { public final class OptionalLong {
/** /**
* Common instance for {@code empty()}. * Common instance for {@code empty()}.

View File

@ -82,10 +82,12 @@ package java.util;
* passed to a static factory method result in {@code IllegalArgumentException}. * passed to a static factory method result in {@code IllegalArgumentException}.
* <li>The iteration order of set elements is unspecified and is subject to change. * <li>The iteration order of set elements is unspecified and is subject to change.
* <li>They are <a href="../lang/doc-files/ValueBased.html">value-based</a>. * <li>They are <a href="../lang/doc-files/ValueBased.html">value-based</a>.
* Callers should make no assumptions about the identity of the returned instances. * Programmers should treat instances that are {@linkplain #equals(Object) equal}
* Factories are free to create new instances or reuse existing ones. Therefore, * as interchangeable and should not use them for synchronization, or
* identity-sensitive operations on these instances (reference equality ({@code ==}), * unpredictable behavior may occur. For example, in a future release,
* identity hash code, and synchronization) are unreliable and should be avoided. * synchronization may fail. Callers should make no assumptions
* about the identity of the returned instances. Factories are free to
* create new instances or reuse existing ones.
* <li>They are serialized as specified on the * <li>They are serialized as specified on the
* <a href="{@docRoot}/serialized-form.html#java.util.CollSer">Serialized Form</a> * <a href="{@docRoot}/serialized-form.html#java.util.CollSer">Serialized Form</a>
* page. * page.

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2020, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package jdk.internal;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.TYPE;
/**
* Indicates the API declaration in question is associated with a Value Based class.
* References to <a href="../lang/doc-files/ValueBased.html">value-based classes</a>
* should produce warnings about behavior that is inconsistent with value based semantics.
*
* @since 16
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(value={TYPE})
public @interface ValueBased {
}

View File

@ -258,7 +258,10 @@ public final class RMIConnectionImpl_Stub
public javax.management.remote.NotificationResult fetchNotifications(long $param_long_1, int $param_int_2, long $param_long_3) public javax.management.remote.NotificationResult fetchNotifications(long $param_long_1, int $param_int_2, long $param_long_3)
throws java.io.IOException { throws java.io.IOException {
try { try {
Object $result = ref.invoke(this, $method_fetchNotifications_7, new java.lang.Object[]{new java.lang.Long($param_long_1), new java.lang.Integer($param_int_2), new java.lang.Long($param_long_3)}, -5037523307973544478L); Object $result = ref.invoke(this, $method_fetchNotifications_7,
new java.lang.Object[]{$param_long_1,
$param_int_2,
$param_long_3}, -5037523307973544478L);
return ((javax.management.remote.NotificationResult) $result); return ((javax.management.remote.NotificationResult) $result);
} catch (java.lang.RuntimeException e) { } catch (java.lang.RuntimeException e) {
throw e; throw e;

View File

@ -4013,7 +4013,8 @@ public class XSDHandler {
","+oldName:currSchema.fTargetNamespace+","+oldName; ","+oldName:currSchema.fTargetNamespace+","+oldName;
int attGroupRefsCount = changeRedefineGroup(processedBaseName, componentType, newName, child, currSchema); int attGroupRefsCount = changeRedefineGroup(processedBaseName, componentType, newName, child, currSchema);
if (attGroupRefsCount > 1) { if (attGroupRefsCount > 1) {
reportSchemaError("src-redefine.7.1", new Object []{new Integer(attGroupRefsCount)}, child); reportSchemaError("src-redefine.7.1",
new Object []{attGroupRefsCount}, child);
} }
else if (attGroupRefsCount == 1) { else if (attGroupRefsCount == 1) {
// return true; // return true;
@ -4029,7 +4030,7 @@ public class XSDHandler {
","+oldName:currSchema.fTargetNamespace+","+oldName; ","+oldName:currSchema.fTargetNamespace+","+oldName;
int groupRefsCount = changeRedefineGroup(processedBaseName, componentType, newName, child, currSchema); int groupRefsCount = changeRedefineGroup(processedBaseName, componentType, newName, child, currSchema);
if (groupRefsCount > 1) { if (groupRefsCount > 1) {
reportSchemaError("src-redefine.6.1.1", new Object []{new Integer(groupRefsCount)}, child); reportSchemaError("src-redefine.6.1.1", new Object []{groupRefsCount}, child);
} }
else if (groupRefsCount == 1) { else if (groupRefsCount == 1) {
// return true; // return true;

View File

@ -438,8 +438,8 @@ public final class HTMLdtd
private static void defineEntity( String name, char value ) private static void defineEntity( String name, char value )
{ {
if ( _byName.get( name ) == null ) { if ( _byName.get( name ) == null ) {
_byName.put( name, new Integer( value ) ); _byName.put( name, (int) value);
_byChar.put( new Integer( value ), name ); _byChar.put( (int) value , name );
} }
} }

View File

@ -125,6 +125,7 @@ public class Lint
if (!options.isSet(Option.PREVIEW)) { if (!options.isSet(Option.PREVIEW)) {
values.add(LintCategory.PREVIEW); values.add(LintCategory.PREVIEW);
} }
values.add(LintCategory.SYNCHRONIZATION);
} }
// Look for specific overrides // Look for specific overrides
@ -282,6 +283,11 @@ public class Lint
*/ */
STATIC("static"), STATIC("static"),
/**
* Warn about synchronization attempts on instances of @ValueBased classes.
*/
SYNCHRONIZATION("synchronization"),
/** /**
* Warn about issues relating to use of text blocks * Warn about issues relating to use of text blocks
*/ */

View File

@ -220,6 +220,7 @@ public class Symtab {
public final Type previewFeatureInternalType; public final Type previewFeatureInternalType;
public final Type typeDescriptorType; public final Type typeDescriptorType;
public final Type recordType; public final Type recordType;
public final Type valueBasedType;
/** The symbol representing the length field of an array. /** The symbol representing the length field of an array.
*/ */
@ -584,6 +585,7 @@ public class Symtab {
previewFeatureInternalType = enterSyntheticAnnotation("jdk.internal.PreviewFeature+Annotation"); previewFeatureInternalType = enterSyntheticAnnotation("jdk.internal.PreviewFeature+Annotation");
typeDescriptorType = enterClass("java.lang.invoke.TypeDescriptor"); typeDescriptorType = enterClass("java.lang.invoke.TypeDescriptor");
recordType = enterClass("java.lang.Record"); recordType = enterClass("java.lang.Record");
valueBasedType = enterClass("jdk.internal.ValueBased");
synthesizeEmptyInterfaceIfMissing(autoCloseableType); synthesizeEmptyInterfaceIfMissing(autoCloseableType);
synthesizeEmptyInterfaceIfMissing(cloneableType); synthesizeEmptyInterfaceIfMissing(cloneableType);

View File

@ -1740,9 +1740,24 @@ public class Attr extends JCTree.Visitor {
public void visitSynchronized(JCSynchronized tree) { public void visitSynchronized(JCSynchronized tree) {
chk.checkRefType(tree.pos(), attribExpr(tree.lock, env)); chk.checkRefType(tree.pos(), attribExpr(tree.lock, env));
if (env.info.lint.isEnabled(LintCategory.SYNCHRONIZATION) && isValueBased(tree.lock.type)) {
log.warning(LintCategory.SYNCHRONIZATION, tree.pos(), Warnings.AttemptToSynchronizeOnInstanceOfValueBasedClass);
}
attribStat(tree.body, env); attribStat(tree.body, env);
result = null; result = null;
} }
// where
private boolean isValueBased(Type t) {
if (t != null && t.tsym != null) {
for (Attribute.Compound a: t.tsym.getDeclarationAttributes()) {
if (a.type.tsym == syms.valueBasedType.tsym) {
return true;
}
}
}
return false;
}
public void visitTry(JCTry tree) { public void visitTry(JCTry tree) {
// Create a new local environment with a local // Create a new local environment with a local

View File

@ -3740,3 +3740,7 @@ compiler.err.preview.not.latest=\
compiler.err.preview.without.source.or.release=\ compiler.err.preview.without.source.or.release=\
--enable-preview must be used with either -source or --release --enable-preview must be used with either -source or --release
compiler.warn.attempt.to.synchronize.on.instance.of.value.based.class=\
attempt to synchronize on an instance of a value-based class

View File

@ -256,10 +256,13 @@ javac.opt.Xlint.desc.unchecked=\
Warn about unchecked operations. Warn about unchecked operations.
javac.opt.Xlint.desc.varargs=\ javac.opt.Xlint.desc.varargs=\
Warn about potentially unsafe vararg methods Warn about potentially unsafe vararg methods.
javac.opt.Xlint.desc.preview=\ javac.opt.Xlint.desc.preview=\
Warn about use of preview language features Warn about use of preview language features.
javac.opt.Xlint.desc.synchronization=\
Warn about synchronization attempts on instances of value-based classes.
javac.opt.Xdoclint=\ javac.opt.Xdoclint=\
Enable recommended checks for problems in javadoc comments Enable recommended checks for problems in javadoc comments

View File

@ -44,12 +44,12 @@ import java.util.stream.Collectors;
* can be combined: if member layouts are laid out one after the other, the resulting group layout is said to be a <em>struct</em> * can be combined: if member layouts are laid out one after the other, the resulting group layout is said to be a <em>struct</em>
* (see {@link MemoryLayout#ofStruct(MemoryLayout...)}); conversely, if all member layouts are laid out at the same starting offset, * (see {@link MemoryLayout#ofStruct(MemoryLayout...)}); conversely, if all member layouts are laid out at the same starting offset,
* the resulting group layout is said to be a <em>union</em> (see {@link MemoryLayout#ofUnion(MemoryLayout...)}). * the resulting group layout is said to be a <em>union</em> (see {@link MemoryLayout#ofUnion(MemoryLayout...)}).
*
* <p> * <p>
* This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a> * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code GroupLayout} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* The {@code equals} method should be used for comparisons. * The {@code equals} method should be used for comparisons.
* *
* <p> Unless otherwise specified, passing a {@code null} argument, or an array argument containing one or more {@code null} * <p> Unless otherwise specified, passing a {@code null} argument, or an array argument containing one or more {@code null}

View File

@ -40,9 +40,9 @@ import java.lang.ref.Cleaner;
* when performing memory dereference operations using a memory access var handle (see {@link MemoryHandles}). * when performing memory dereference operations using a memory access var handle (see {@link MemoryHandles}).
* <p> * <p>
* All implementations of this interface must be <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>; * All implementations of this interface must be <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>;
* use of identity-sensitive operations (including reference equality ({@code ==}), identity hash code, or synchronization) on * programmers should treat instances that are {@linkplain #equals(Object) equal} as interchangeable and should not
* instances of {@code MemoryAddress} may have unpredictable results and should be avoided. The {@code equals} method should * use instances for synchronization, or unpredictable behavior may occur. For example, in a future release,
* be used for comparisons. * synchronization may fail. The {@code equals} method should be used for comparisons.
* <p> * <p>
* Non-platform classes should not implement {@linkplain MemoryAddress} directly. * Non-platform classes should not implement {@linkplain MemoryAddress} directly.
* *

View File

@ -78,9 +78,9 @@ SequenceLayout taggedValues = MemoryLayout.ofSequence(5,
* }</pre></blockquote> * }</pre></blockquote>
* <p> * <p>
* All implementations of this interface must be <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>; * All implementations of this interface must be <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>;
* use of identity-sensitive operations (including reference equality ({@code ==}), identity hash code, or synchronization) on * programmers should treat instances that are {@linkplain #equals(Object) equal} as interchangeable and should not
* instances of {@code MemoryLayout} may have unpredictable results and should be avoided. The {@code equals} method should * use instances for synchronization, or unpredictable behavior may occur. For example, in a future release,
* be used for comparisons. * synchronization may fail. The {@code equals} method should be used for comparisons.
* <p> * <p>
* Non-platform classes should not implement {@linkplain MemoryLayout} directly. * Non-platform classes should not implement {@linkplain MemoryLayout} directly.
* *

View File

@ -50,9 +50,9 @@ import java.util.Spliterator;
* operations on a segment cannot occur after a memory segment has been closed (see {@link MemorySegment#close()}). * operations on a segment cannot occur after a memory segment has been closed (see {@link MemorySegment#close()}).
* <p> * <p>
* All implementations of this interface must be <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>; * All implementations of this interface must be <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>;
* use of identity-sensitive operations (including reference equality ({@code ==}), identity hash code, or synchronization) on * programmers should treat instances that are {@linkplain #equals(Object) equal} as interchangeable and should not
* instances of {@code MemorySegment} may have unpredictable results and should be avoided. The {@code equals} method should * use instances for synchronization, or unpredictable behavior may occur. For example, in a future release,
* be used for comparisons. * synchronization may fail. The {@code equals} method should be used for comparisons.
* <p> * <p>
* Non-platform classes should not implement {@linkplain MemorySegment} directly. * Non-platform classes should not implement {@linkplain MemorySegment} directly.
* *

View File

@ -38,9 +38,10 @@ import java.util.OptionalLong;
* and is typically used for aligning member layouts around word boundaries. * and is typically used for aligning member layouts around word boundaries.
* <p> * <p>
* This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a> * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code PaddingLayout} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* The {@code equals} method should be used for comparisons. * The {@code equals} method should be used for comparisons.
* *
* <p> Unless otherwise specified, passing a {@code null} argument, or an array argument containing one or more {@code null} * <p> Unless otherwise specified, passing a {@code null} argument, or an array argument containing one or more {@code null}

View File

@ -55,9 +55,10 @@ MemoryLayout.ofStruct(
* *
* <p> * <p>
* This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a> * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code SequenceLayout} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* The {@code equals} method should be used for comparisons. * The {@code equals} method should be used for comparisons.
* *
* <p> Unless otherwise specified, passing a {@code null} argument, or an array argument containing one or more {@code null} * <p> Unless otherwise specified, passing a {@code null} argument, or an array argument containing one or more {@code null}

View File

@ -40,9 +40,10 @@ import java.util.OptionalLong;
* *
* <p> * <p>
* This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a> * This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality * class; programmers should treat instances that are
* ({@code ==}), identity hash code, or synchronization) on instances of * {@linkplain #equals(Object) equal} as interchangeable and should not
* {@code ValueLayout} may have unpredictable results and should be avoided. * use instances for synchronization, or unpredictable behavior may
* occur. For example, in a future release, synchronization may fail.
* The {@code equals} method should be used for comparisons. * The {@code equals} method should be used for comparisons.
* *
* <p> Unless otherwise specified, passing a {@code null} argument, or an array argument containing one or more {@code null} * <p> Unless otherwise specified, passing a {@code null} argument, or an array argument containing one or more {@code null}

View File

@ -133,7 +133,7 @@ public class EconomicMapImplTest {
Assert.assertTrue(set.add(newInteger(0))); Assert.assertTrue(set.add(newInteger(0)));
} }
@SuppressWarnings({"deprecation", "unused"}) @SuppressWarnings({"deprecation", "removal", "unused"})
private static Integer newInteger(int value) { private static Integer newInteger(int value) {
return new Integer(value); return new Integer(value);
} }

View File

@ -161,7 +161,7 @@ public class EconomicSetTest {
Assert.assertEquals(newInteger(9), finalList.get(0)); Assert.assertEquals(newInteger(9), finalList.get(0));
} }
@SuppressWarnings({"deprecation", "unused"}) @SuppressWarnings({"deprecation", "removal", "unused"})
private static Integer newInteger(int value) { private static Integer newInteger(int value) {
return new Integer(value); return new Integer(value);
} }

View File

@ -58,7 +58,7 @@ public class EscapeAnalysisTest extends EATestBase {
testEscapeAnalysis("test1Snippet", JavaConstant.forInt(101), false); testEscapeAnalysis("test1Snippet", JavaConstant.forInt(101), false);
} }
@SuppressWarnings("deprecation") @SuppressWarnings({"deprecation", "removal"})
public static int test1Snippet() { public static int test1Snippet() {
Integer x = new Integer(101); Integer x = new Integer(101);
return x.intValue(); return x.intValue();
@ -89,7 +89,7 @@ public class EscapeAnalysisTest extends EATestBase {
testEscapeAnalysis("testMonitorSnippet", JavaConstant.forInt(0), false); testEscapeAnalysis("testMonitorSnippet", JavaConstant.forInt(0), false);
} }
@SuppressWarnings("deprecation") @SuppressWarnings({"deprecation", "removal", "synchronization"})
public static int testMonitorSnippet() { public static int testMonitorSnippet() {
Integer x = new Integer(0); Integer x = new Integer(0);
Double y = new Double(0); Double y = new Double(0);
@ -113,7 +113,7 @@ public class EscapeAnalysisTest extends EATestBase {
* This test case differs from the last one in that it requires inlining within a synchronized * This test case differs from the last one in that it requires inlining within a synchronized
* region. * region.
*/ */
@SuppressWarnings("deprecation") @SuppressWarnings({"deprecation", "removal", "synchronization"})
public static int testMonitor2Snippet() { public static int testMonitor2Snippet() {
Integer x = new Integer(0); Integer x = new Integer(0);
Double y = new Double(0); Double y = new Double(0);
@ -335,7 +335,7 @@ public class EscapeAnalysisTest extends EATestBase {
public volatile Object field; public volatile Object field;
@SuppressWarnings("deprecation") @SuppressWarnings({"deprecation", "removal"})
public int testChangeHandlingSnippet(int a) { public int testChangeHandlingSnippet(int a) {
Object obj; Object obj;
Integer one = 1; Integer one = 1;

View File

@ -42,7 +42,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
public static Object field; public static Object field;
@SuppressWarnings({"deprecation", "unused"}) @SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippet1(int i) { public static void snippet1(int i) {
Integer object = new Integer(i); Integer object = new Integer(i);
GraalDirectives.ensureVirtualized(object); GraalDirectives.ensureVirtualized(object);
@ -53,7 +53,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
test("snippet1", 1); test("snippet1", 1);
} }
@SuppressWarnings({"deprecation", "unused"}) @SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippet2(int i) { public static void snippet2(int i) {
Integer object = new Integer(i); Integer object = new Integer(i);
GraalDirectives.ensureVirtualized(object); GraalDirectives.ensureVirtualized(object);
@ -65,7 +65,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
test("snippet2", 1); test("snippet2", 1);
} }
@SuppressWarnings({"deprecation", "unused"}) @SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippet3(int i) { public static void snippet3(int i) {
Integer object = new Integer(i); Integer object = new Integer(i);
field = object; field = object;
@ -77,7 +77,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
test("snippet3", 1); test("snippet3", 1);
} }
@SuppressWarnings({"deprecation", "unused"}) @SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippetHere1(int i) { public static void snippetHere1(int i) {
Integer object = new Integer(i); Integer object = new Integer(i);
GraalDirectives.ensureVirtualizedHere(object); GraalDirectives.ensureVirtualizedHere(object);
@ -88,7 +88,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
test("snippetHere1", 1); test("snippetHere1", 1);
} }
@SuppressWarnings({"deprecation", "unused"}) @SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippetHere2(int i) { public static void snippetHere2(int i) {
Integer object = new Integer(i); Integer object = new Integer(i);
GraalDirectives.ensureVirtualizedHere(object); GraalDirectives.ensureVirtualizedHere(object);
@ -100,7 +100,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
test("snippetHere2", 1); test("snippetHere2", 1);
} }
@SuppressWarnings({"deprecation", "unused"}) @SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippetHere3(int i) { public static void snippetHere3(int i) {
Integer object = new Integer(i); Integer object = new Integer(i);
field = object; field = object;
@ -133,7 +133,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
test("snippetBoxing2", 1); test("snippetBoxing2", 1);
} }
@SuppressWarnings({"deprecation", "unused"}) @SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippetControlFlow1(boolean b, int i) { public static void snippetControlFlow1(boolean b, int i) {
Integer object = new Integer(i); Integer object = new Integer(i);
if (b) { if (b) {
@ -148,7 +148,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
test("snippetControlFlow1", true, 1); test("snippetControlFlow1", true, 1);
} }
@SuppressWarnings({"deprecation", "unused"}) @SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippetControlFlow2(boolean b, int i) { public static void snippetControlFlow2(boolean b, int i) {
Integer object = new Integer(i); Integer object = new Integer(i);
if (b) { if (b) {
@ -165,7 +165,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
test("snippetControlFlow2", true, 1); test("snippetControlFlow2", true, 1);
} }
@SuppressWarnings({"deprecation", "unused"}) @SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippetControlFlow3(boolean b, int i) { public static void snippetControlFlow3(boolean b, int i) {
Integer object = new Integer(i); Integer object = new Integer(i);
GraalDirectives.ensureVirtualized(object); GraalDirectives.ensureVirtualized(object);
@ -183,7 +183,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
test("snippetControlFlow3", true, 1); test("snippetControlFlow3", true, 1);
} }
@SuppressWarnings({"deprecation", "unused"}) @SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippetControlFlow4(boolean b, int i) { public static void snippetControlFlow4(boolean b, int i) {
Integer object = new Integer(i); Integer object = new Integer(i);
if (b) { if (b) {
@ -199,7 +199,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
test("snippetControlFlow4", true, 1); test("snippetControlFlow4", true, 1);
} }
@SuppressWarnings({"deprecation", "unused"}) @SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippetControlFlow5(boolean b, int i) { public static void snippetControlFlow5(boolean b, int i) {
Integer object = new Integer(i); Integer object = new Integer(i);
if (b) { if (b) {
@ -220,7 +220,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
Object b; Object b;
} }
@SuppressWarnings({"deprecation", "unused"}) @SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippetIndirect1(boolean b, int i) { public static void snippetIndirect1(boolean b, int i) {
Integer object = new Integer(i); Integer object = new Integer(i);
TestClass t = new TestClass(); TestClass t = new TestClass();
@ -239,7 +239,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
test("snippetIndirect1", true, 1); test("snippetIndirect1", true, 1);
} }
@SuppressWarnings({"deprecation", "unused"}) @SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippetIndirect2(boolean b, int i) { public static void snippetIndirect2(boolean b, int i) {
Integer object = new Integer(i); Integer object = new Integer(i);
TestClass t = new TestClass(); TestClass t = new TestClass();

View File

@ -115,7 +115,7 @@ public class PartialEscapeAnalysisTest extends EATestBase {
testPartialEscapeAnalysis("test3Snippet", 0.5, 1, StoreFieldNode.class, LoadFieldNode.class); testPartialEscapeAnalysis("test3Snippet", 0.5, 1, StoreFieldNode.class, LoadFieldNode.class);
} }
@SuppressWarnings("deprecation") @SuppressWarnings({"deprecation", "removal"})
public static Object test3Snippet(int a) { public static Object test3Snippet(int a) {
if (a < 0) { if (a < 0) {
TestObject obj = new TestObject(1, 2); TestObject obj = new TestObject(1, 2);

View File

@ -114,7 +114,7 @@ public class StaticAnalysisTests {
assertEquals(m(sa, B.class, "foo").getFormalReturn(), t(Data.class)); assertEquals(m(sa, B.class, "foo").getFormalReturn(), t(Data.class));
} }
@SuppressWarnings({"deprecation", "unused"}) @SuppressWarnings({"deprecation", "removal", "unused"})
static void test03Entry() { static void test03Entry() {
Data data = new Data(); Data data = new Data();
data.f = new Integer(42); data.f = new Integer(42);
@ -142,7 +142,7 @@ public class StaticAnalysisTests {
assertEquals(m(sa, B.class, "foo").getFormalReturn(), t(Data.class), t(Integer.class)); assertEquals(m(sa, B.class, "foo").getFormalReturn(), t(Data.class), t(Integer.class));
} }
@SuppressWarnings({"deprecation", "unused"}) @SuppressWarnings({"deprecation", "removal", "unused"})
static void test04Entry() { static void test04Entry() {
Data data = null; Data data = null;
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {

View File

@ -373,7 +373,7 @@ public class GraalHotSpotVMConfigAccess {
/** /**
* @see HotSpotVMConfigAccess#getFlag(String, Class, Object) * @see HotSpotVMConfigAccess#getFlag(String, Class, Object)
*/ */
@SuppressWarnings("deprecation") @SuppressWarnings({"deprecation", "removal"})
public <T> T getFlag(String name, Class<T> type, T notPresent, boolean expectPresent) { public <T> T getFlag(String name, Class<T> type, T notPresent, boolean expectPresent) {
if (expectPresent) { if (expectPresent) {
return getFlag(name, type); return getFlag(name, type);

View File

@ -32,7 +32,7 @@ import org.graalvm.compiler.jtt.JTTTest;
*/ */
public class HP_allocate02 extends JTTTest { public class HP_allocate02 extends JTTTest {
@SuppressWarnings({"deprecation", "unused"}) @SuppressWarnings({"deprecation", "removal", "unused"})
public static int test(int count) { public static int test(int count) {
int sum = 0; int sum = 0;
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {

View File

@ -212,6 +212,7 @@ public class MonitorTest extends GraalCompilerTest {
return new String(dst); return new String(dst);
} }
@SuppressWarnings("synchronization")
public static String lockBoxedLong(long value) { public static String lockBoxedLong(long value) {
Long lock = value; Long lock = value;
synchronized (lock) { synchronized (lock) {

View File

@ -91,7 +91,7 @@
<setting name="threshold" control="synchronization-threshold">20 ms</setting> <setting name="threshold" control="synchronization-threshold">20 ms</setting>
</event> </event>
<event name="jdk.SyncOnPrimitiveWrapper"> <event name="jdk.SyncOnValueBasedClass">
<setting name="enabled">true</setting> <setting name="enabled">true</setting>
<setting name="stackTrace">true</setting> <setting name="stackTrace">true</setting>
</event> </event>

View File

@ -91,7 +91,7 @@
<setting name="threshold" control="synchronization-threshold">10 ms</setting> <setting name="threshold" control="synchronization-threshold">10 ms</setting>
</event> </event>
<event name="jdk.SyncOnPrimitiveWrapper"> <event name="jdk.SyncOnValueBasedClass">
<setting name="enabled">true</setting> <setting name="enabled">true</setting>
<setting name="stackTrace">true</setting> <setting name="stackTrace">true</setting>
</event> </event>

View File

@ -29,12 +29,12 @@ import java.util.stream.*;
/* /*
* @test * @test
* @bug 8242263 * @bug 8242263
* @summary Exercise DiagnoseSyncOnPrimitiveWrappers diagnostic flag * @summary Exercise DiagnoseSyncOnValueBasedClasses diagnostic flag
* @library /test/lib * @library /test/lib
* @run driver/timeout=180000 SyncOnPrimitiveWrapperTest * @run driver/timeout=180000 SyncOnValueBasedClassTest
*/ */
public class SyncOnPrimitiveWrapperTest { public class SyncOnValueBasedClassTest {
static final int LOOP_COUNT = 3000; static final int LOOP_COUNT = 3000;
static final int THREAD_COUNT = 2; static final int THREAD_COUNT = 2;
static String[] fatalTests[]; static String[] fatalTests[];
@ -64,20 +64,20 @@ public class SyncOnPrimitiveWrapperTest {
private static void generateTests() { private static void generateTests() {
initTestObjects(); initTestObjects();
String[] commonFatalTestsFlags = {"-XX:+UnlockDiagnosticVMOptions", "-XX:-CreateCoredumpOnCrash", "-XX:DiagnoseSyncOnPrimitiveWrappers=1"}; String[] commonFatalTestsFlags = {"-XX:+UnlockDiagnosticVMOptions", "-XX:-CreateCoredumpOnCrash", "-XX:DiagnoseSyncOnValueBasedClasses=1"};
fatalTests = new String[specificFlags.length * testObjects.size()][]; fatalTests = new String[specificFlags.length * testObjects.size()][];
for (int i = 0; i < specificFlags.length; i++) { for (int i = 0; i < specificFlags.length; i++) {
for (int j = 0; j < testObjects.size(); j++) { for (int j = 0; j < testObjects.size(); j++) {
int index = i * testObjects.size() + j; int index = i * testObjects.size() + j;
fatalTests[index] = Stream.of(commonFatalTestsFlags, specificFlags[i], new String[] {"SyncOnPrimitiveWrapperTest$FatalTest", Integer.toString(j)}) fatalTests[index] = Stream.of(commonFatalTestsFlags, specificFlags[i], new String[] {"SyncOnValueBasedClassTest$FatalTest", Integer.toString(j)})
.flatMap(Stream::of) .flatMap(Stream::of)
.toArray(String[]::new); .toArray(String[]::new);
} }
} }
String[] commonLogTestsFlags = {"-XX:+UnlockDiagnosticVMOptions", "-XX:DiagnoseSyncOnPrimitiveWrappers=2"}; String[] commonLogTestsFlags = {"-XX:+UnlockDiagnosticVMOptions", "-XX:DiagnoseSyncOnValueBasedClasses=2"};
logTests = new String[specificFlags.length][]; logTests = new String[specificFlags.length][];
for (int i = 0; i < specificFlags.length; i++) { for (int i = 0; i < specificFlags.length; i++) {
logTests[i] = Stream.of(commonLogTestsFlags, specificFlags[i], new String[] {"SyncOnPrimitiveWrapperTest$LogTest"}) logTests[i] = Stream.of(commonLogTestsFlags, specificFlags[i], new String[] {"SyncOnValueBasedClassTest$LogTest"})
.flatMap(Stream::of) .flatMap(Stream::of)
.toArray(String[]::new); .toArray(String[]::new);
} }
@ -89,7 +89,7 @@ public class SyncOnPrimitiveWrapperTest {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(fatalTests[i]); ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(fatalTests[i]);
OutputAnalyzer output = ProcessTools.executeProcess(pb); OutputAnalyzer output = ProcessTools.executeProcess(pb);
output.shouldContain("fatal error: Synchronizing on object"); output.shouldContain("fatal error: Synchronizing on object");
output.shouldNotContain("synchronization on primitive wrapper did not fail"); output.shouldNotContain("synchronization on value based class did not fail");
output.shouldNotHaveExitValue(0); output.shouldNotHaveExitValue(0);
} }
for (int i = 0; i < logTests.length; i++) { for (int i = 0; i < logTests.length; i++) {
@ -127,7 +127,7 @@ public class SyncOnPrimitiveWrapperTest {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
initTestObjects(); initTestObjects();
synchronized (testObjects.get(Integer.valueOf(args[0]))) { synchronized (testObjects.get(Integer.valueOf(args[0]))) {
throw new RuntimeException("synchronization on primitive wrapper did not fail"); throw new RuntimeException("synchronization on value based class did not fail");
} }
} }
} }
@ -164,4 +164,4 @@ public class SyncOnPrimitiveWrapperTest {
} }
} }
} }
} }

Some files were not shown because too many files have changed in this diff Show More