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:
parent
ed4c4ee73b
commit
48d8650ae1
@ -3893,10 +3893,10 @@ encode %{
|
||||
// Load markWord from object into displaced_header.
|
||||
__ ldr(disp_hdr, Address(oop, oopDesc::mark_offset_in_bytes()));
|
||||
|
||||
if (DiagnoseSyncOnPrimitiveWrappers != 0) {
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
__ load_klass(tmp, oop);
|
||||
__ 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);
|
||||
}
|
||||
|
||||
|
@ -75,10 +75,10 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr
|
||||
|
||||
null_check_offset = offset();
|
||||
|
||||
if (DiagnoseSyncOnPrimitiveWrappers != 0) {
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
load_klass(hdr, obj);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -746,10 +746,10 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg)
|
||||
// Load object pointer into obj_reg %c_rarg3
|
||||
ldr(obj_reg, Address(lock_reg, obj_offset));
|
||||
|
||||
if (DiagnoseSyncOnPrimitiveWrappers != 0) {
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
load_klass(tmp, obj_reg);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -204,10 +204,10 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj,
|
||||
|
||||
null_check_offset = offset();
|
||||
|
||||
if (DiagnoseSyncOnPrimitiveWrappers != 0) {
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
load_klass(tmp1, obj);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -90,10 +90,10 @@ void C2_MacroAssembler::fast_lock(Register Roop, Register Rbox, Register Rscratc
|
||||
|
||||
Label fast_lock, done;
|
||||
|
||||
if (DiagnoseSyncOnPrimitiveWrappers != 0) {
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
load_klass(Rscratch, Roop);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -883,10 +883,10 @@ void InterpreterMacroAssembler::lock_object(Register Rlock) {
|
||||
// Load object pointer
|
||||
ldr(Robj, Address(Rlock, obj_offset));
|
||||
|
||||
if (DiagnoseSyncOnPrimitiveWrappers != 0) {
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
load_klass(R0, Robj);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -105,10 +105,10 @@ void C1_MacroAssembler::lock_object(Register Rmark, Register Roop, Register Rbox
|
||||
// Save object being locked into the BasicObjectLock...
|
||||
std(Roop, BasicObjectLock::obj_offset_in_bytes(), Rbox);
|
||||
|
||||
if (DiagnoseSyncOnPrimitiveWrappers != 0) {
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
load_klass(Rscratch, Roop);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -910,10 +910,10 @@ void InterpreterMacroAssembler::lock_object(Register monitor, Register object) {
|
||||
// Load markWord from object into displaced_header.
|
||||
ld(displaced_header, oopDesc::mark_offset_in_bytes(), object);
|
||||
|
||||
if (DiagnoseSyncOnPrimitiveWrappers != 0) {
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
load_klass(tmp, object);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -2818,10 +2818,10 @@ void MacroAssembler::compiler_fast_lock_object(ConditionRegister flag, Register
|
||||
// Load markWord from object into displaced_header.
|
||||
ld(displaced_header, oopDesc::mark_offset_in_bytes(), oop);
|
||||
|
||||
if (DiagnoseSyncOnPrimitiveWrappers != 0) {
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
load_klass(temp, oop);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -91,9 +91,9 @@ void C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hd
|
||||
// Save object being locked into the BasicObjectLock...
|
||||
z_stg(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
|
||||
|
||||
if (DiagnoseSyncOnPrimitiveWrappers != 0) {
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -999,9 +999,9 @@ void InterpreterMacroAssembler::lock_object(Register monitor, Register object) {
|
||||
// Load markWord from object into displaced_header.
|
||||
z_lg(displaced_header, oopDesc::mark_offset_in_bytes(), object);
|
||||
|
||||
if (DiagnoseSyncOnPrimitiveWrappers != 0) {
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -3326,11 +3326,11 @@ void MacroAssembler::compiler_fast_lock_object(Register oop, Register box, Regis
|
||||
// Load markWord from oop into mark.
|
||||
z_lg(displacedHeader, 0, oop);
|
||||
|
||||
if (DiagnoseSyncOnPrimitiveWrappers != 0) {
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
load_klass(Z_R1_scratch, oop);
|
||||
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");
|
||||
z_nilh(Z_R1_scratch, JVM_ACC_IS_BOX_CLASS >> 16);
|
||||
assert((JVM_ACC_IS_VALUE_BASED_CLASS & 0xFFFF) == 0, "or change following instruction");
|
||||
z_nilh(Z_R1_scratch, JVM_ACC_IS_VALUE_BASED_CLASS >> 16);
|
||||
z_brne(done);
|
||||
}
|
||||
|
||||
|
@ -54,10 +54,10 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr
|
||||
|
||||
null_check_offset = offset();
|
||||
|
||||
if (DiagnoseSyncOnPrimitiveWrappers != 0) {
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
load_klass(hdr, obj, rklass_decode_tmp);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -485,10 +485,10 @@ void C2_MacroAssembler::fast_lock(Register objReg, Register boxReg, Register tmp
|
||||
|
||||
Label IsInflated, DONE_LABEL;
|
||||
|
||||
if (DiagnoseSyncOnPrimitiveWrappers != 0) {
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
load_klass(tmpReg, objReg, cx1Reg);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -1219,10 +1219,10 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg) {
|
||||
// Load object pointer into obj_reg
|
||||
movptr(obj_reg, Address(lock_reg, obj_offset));
|
||||
|
||||
if (DiagnoseSyncOnPrimitiveWrappers != 0) {
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
load_klass(tmp_reg, obj_reg, rklass_decode_tmp);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -1091,6 +1091,7 @@ public:
|
||||
_jdk_internal_vm_annotation_Contended,
|
||||
_field_Stable,
|
||||
_jdk_internal_vm_annotation_ReservedStackAccess,
|
||||
_jdk_internal_ValueBased,
|
||||
_annotation_LIMIT
|
||||
};
|
||||
const Location _location;
|
||||
@ -2147,6 +2148,11 @@ AnnotationCollector::annotation_index(const ClassLoaderData* loader_data,
|
||||
if (RestrictReservedStack && !privileged) break; // honor privileges
|
||||
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: {
|
||||
break;
|
||||
}
|
||||
@ -2190,7 +2196,16 @@ void MethodAnnotationCollector::apply_to(const methodHandle& m) {
|
||||
|
||||
void ClassFileParser::ClassAnnotationCollector::apply_to(InstanceKlass* ik) {
|
||||
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
|
||||
|
@ -2142,14 +2142,6 @@ void SystemDictionary::resolve_well_known_classes(TRAPS) {
|
||||
//_box_klasses[T_OBJECT] = 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
|
||||
if (UseSharedSpaces) {
|
||||
JVMTI_ONLY(assert(JvmtiExport::is_early_phase(),
|
||||
|
@ -249,6 +249,7 @@
|
||||
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_ReservedStackAccess_signature, "Ljdk/internal/vm/annotation/ReservedStackAccess;") \
|
||||
template(jdk_internal_ValueBased_signature, "Ljdk/internal/ValueBased;") \
|
||||
\
|
||||
/* class symbols needed by intrinsics */ \
|
||||
VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, template, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE) \
|
||||
|
@ -66,8 +66,8 @@
|
||||
<Field type="InflateCause" name="cause" label="Monitor Inflation Cause" description="Cause of inflation" />
|
||||
</Event>
|
||||
|
||||
<Event name="SyncOnPrimitiveWrapper" category="Java Virtual Machine, Diagnostics" label="Primitive Wrapper Synchronization" thread="true" stackTrace="true" startTime="false" experimental="true">
|
||||
<Field type="Class" name="boxClass" label="Boxing Class" />
|
||||
<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="valueBasedClass" label="Value Based Class" />
|
||||
</Event>
|
||||
|
||||
<Event name="BiasedLockRevocation" category="Java Virtual Machine, Runtime" label="Biased Lock Revocation" description="Revoked bias of object" thread="true"
|
||||
|
@ -141,7 +141,6 @@
|
||||
LOG_TAG(plab) \
|
||||
LOG_TAG(preorder) /* Trace all classes loaded in order referenced (not loaded) */ \
|
||||
LOG_TAG(preview) /* Trace loading of preview feature types */ \
|
||||
LOG_TAG(primitivewrappers) \
|
||||
LOG_TAG(promotion) \
|
||||
LOG_TAG(protectiondomain) /* "Trace protection domain verification" */ \
|
||||
LOG_TAG(ptrqueue) \
|
||||
@ -187,6 +186,7 @@
|
||||
LOG_TAG(unload) /* Trace unloading of classes */ \
|
||||
LOG_TAG(unshareable) \
|
||||
LOG_TAG(update) \
|
||||
LOG_TAG(valuebasedclasses) \
|
||||
LOG_TAG(verification) \
|
||||
LOG_TAG(verify) \
|
||||
LOG_TAG(vmmutex) \
|
||||
|
@ -2600,6 +2600,12 @@ void InstanceKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handl
|
||||
if (UseBiasedLocking && BiasedLocking::enabled()) {
|
||||
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) {
|
||||
|
@ -176,7 +176,8 @@ private:
|
||||
// Flags of the current shared class.
|
||||
u2 _shared_class_flags;
|
||||
enum {
|
||||
_archived_lambda_proxy_is_available = 2
|
||||
_archived_lambda_proxy_is_available = 2,
|
||||
_has_value_based_class_annotation = 4
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -321,6 +322,18 @@ protected:
|
||||
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
|
||||
virtual ModuleEntry* module() const = 0;
|
||||
virtual PackageEntry* package() const = 0;
|
||||
@ -624,8 +637,8 @@ protected:
|
||||
void set_is_hidden() { _access_flags.set_is_hidden_class(); }
|
||||
bool is_non_strong_hidden() const { return access_flags().is_hidden_class() &&
|
||||
class_loader_data()->has_class_mirror_holder(); }
|
||||
bool is_box() const { return access_flags().is_box_class(); }
|
||||
void set_is_box() { _access_flags.set_is_box_class(); }
|
||||
bool is_value_based() { return _access_flags.is_value_based_class(); }
|
||||
void set_is_value_based() { _access_flags.set_is_value_based_class(); }
|
||||
|
||||
bool is_cloneable() const;
|
||||
void set_is_cloneable();
|
||||
|
@ -4139,9 +4139,9 @@ jint Arguments::apply_ergo() {
|
||||
}
|
||||
#endif // COMPILER2
|
||||
|
||||
if (FLAG_IS_CMDLINE(DiagnoseSyncOnPrimitiveWrappers)) {
|
||||
if (DiagnoseSyncOnPrimitiveWrappers == ObjectSynchronizer::LOG_WARNING && !log_is_enabled(Info, primitivewrappers)) {
|
||||
LogConfiguration::configure_stdout(LogLevel::Info, true, LOG_TAGS(primitivewrappers));
|
||||
if (FLAG_IS_CMDLINE(DiagnoseSyncOnValueBasedClasses)) {
|
||||
if (DiagnoseSyncOnValueBasedClasses == ObjectSynchronizer::LOG_WARNING && !log_is_enabled(Info, valuebasedclasses)) {
|
||||
LogConfiguration::configure_stdout(LogLevel::Info, true, LOG_TAGS(valuebasedclasses));
|
||||
}
|
||||
}
|
||||
return JNI_OK;
|
||||
|
@ -851,13 +851,13 @@ const intx ObjectAlignmentInBytes = 8;
|
||||
range(500, max_intx) \
|
||||
constraint(BiasedLockingDecayTimeFunc,AfterErgo) \
|
||||
\
|
||||
product(intx, DiagnoseSyncOnPrimitiveWrappers, 0, DIAGNOSTIC, \
|
||||
product(intx, DiagnoseSyncOnValueBasedClasses, 0, DIAGNOSTIC, \
|
||||
"Detect and take action upon identifying synchronization on " \
|
||||
"primitive wrappers. Modes: " \
|
||||
"value based classes. Modes: " \
|
||||
"0: off; " \
|
||||
"1: exit with fatal error; " \
|
||||
"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.") \
|
||||
range(0, 2) \
|
||||
\
|
||||
|
@ -333,7 +333,7 @@ bool ObjectSynchronizer::quick_enter(oop obj, Thread* self,
|
||||
NoSafepointVerifier nsv;
|
||||
if (obj == NULL) return false; // Need to throw NPE
|
||||
|
||||
if (DiagnoseSyncOnPrimitiveWrappers != 0 && obj->klass()->is_box()) {
|
||||
if (obj->klass()->is_value_based()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -387,17 +387,23 @@ bool ObjectSynchronizer::quick_enter(oop obj, Thread* self,
|
||||
return false; // revert to slow-path
|
||||
}
|
||||
|
||||
// Handle notifications when synchronizing on primitive wrappers
|
||||
void ObjectSynchronizer::handle_sync_on_primitive_wrapper(Handle obj, Thread* current) {
|
||||
// Handle notifications when synchronizing on value based classes
|
||||
void ObjectSynchronizer::handle_sync_on_value_based_class(Handle obj, Thread* current) {
|
||||
JavaThread* self = current->as_Java_thread();
|
||||
|
||||
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
|
||||
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);
|
||||
stringStream 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);
|
||||
} else {
|
||||
assert(DiagnoseSyncOnPrimitiveWrappers == LOG_WARNING, "invalid value for DiagnoseSyncOnPrimitiveWrappers");
|
||||
assert(DiagnoseSyncOnValueBasedClasses == LOG_WARNING, "invalid value for DiagnoseSyncOnValueBasedClasses");
|
||||
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()) {
|
||||
LogStream info_stream(pwlog.info());
|
||||
LogStream info_stream(vblog.info());
|
||||
self->print_stack_on(&info_stream);
|
||||
} 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()) {
|
||||
event.set_boxClass(obj->klass());
|
||||
event.set_valueBasedClass(obj->klass());
|
||||
event.commit();
|
||||
}
|
||||
}
|
||||
|
||||
if (last_frame.is_interpreted_frame()) {
|
||||
if (bcp_was_adjusted) {
|
||||
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.
|
||||
|
||||
void ObjectSynchronizer::enter(Handle obj, BasicLock* lock, TRAPS) {
|
||||
if (DiagnoseSyncOnPrimitiveWrappers != 0 && obj->klass()->is_box()) {
|
||||
handle_sync_on_primitive_wrapper(obj, THREAD);
|
||||
if (obj->klass()->is_value_based()) {
|
||||
handle_sync_on_value_based_class(obj, THREAD);
|
||||
}
|
||||
|
||||
if (UseBiasedLocking) {
|
||||
@ -586,8 +592,8 @@ void ObjectSynchronizer::reenter(Handle obj, intx recursions, TRAPS) {
|
||||
// JNI locks on java objects
|
||||
// NOTE: must use heavy weight monitor to handle jni monitor enter
|
||||
void ObjectSynchronizer::jni_enter(Handle obj, TRAPS) {
|
||||
if (DiagnoseSyncOnPrimitiveWrappers != 0 && obj->klass()->is_box()) {
|
||||
handle_sync_on_primitive_wrapper(obj, THREAD);
|
||||
if (obj->klass()->is_value_based()) {
|
||||
handle_sync_on_value_based_class(obj, THREAD);
|
||||
}
|
||||
|
||||
// the current locking is from JNI instead of Java code
|
||||
|
@ -161,7 +161,7 @@ class ObjectSynchronizer : AllStatic {
|
||||
static size_t get_gvars_size();
|
||||
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
|
||||
|
@ -67,7 +67,7 @@ enum {
|
||||
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_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
|
||||
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_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_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
|
||||
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_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_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:
|
||||
// field flags
|
||||
|
@ -41,16 +41,23 @@ import static java.lang.constant.ConstantDescs.CD_Boolean;
|
||||
* {@code boolean} in an object. An object of type
|
||||
* {@code Boolean} contains a single field whose type is
|
||||
* {@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
|
||||
* {@code String} to a {@code boolean}, as well as other
|
||||
* constants and methods useful when dealing with a
|
||||
* {@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
|
||||
* @since 1.0
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class Boolean implements java.io.Serializable,
|
||||
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}
|
||||
* if possible.
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
@Deprecated(since="9", forRemoval = true)
|
||||
public Boolean(boolean value) {
|
||||
this.value = value;
|
||||
}
|
||||
@ -118,7 +125,7 @@ public final class Boolean implements java.io.Serializable,
|
||||
* {@code boolean} primitive, or use {@link #valueOf(String)}
|
||||
* to convert a string to a {@code Boolean} object.
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
@Deprecated(since="9", forRemoval = true)
|
||||
public Boolean(String s) {
|
||||
this(parseBoolean(s));
|
||||
}
|
||||
|
@ -48,11 +48,18 @@ import static java.lang.constant.ConstantDescs.DEFAULT_NAME;
|
||||
* byte}, as well as other constants and methods useful when dealing
|
||||
* 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 Joseph D. Darcy
|
||||
* @see java.lang.Number
|
||||
* @since 1.1
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
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
|
||||
* likely to yield significantly better space and time performance.
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
@Deprecated(since="9", forRemoval = true)
|
||||
public Byte(byte 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)}
|
||||
* to convert a string to a {@code Byte} object.
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
@Deprecated(since="9", forRemoval = true)
|
||||
public Byte(String s) throws NumberFormatException {
|
||||
this.value = parseByte(s, 10);
|
||||
}
|
||||
|
@ -122,6 +122,12 @@ import static java.lang.constant.ConstantDescs.DEFAULT_NAME;
|
||||
* encoding. For more information on Unicode terminology, refer to the
|
||||
* <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 Guy Steele
|
||||
* @author Akira Tanaka
|
||||
@ -129,6 +135,7 @@ import static java.lang.constant.ConstantDescs.DEFAULT_NAME;
|
||||
* @author Ulf Zibis
|
||||
* @since 1.0
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final
|
||||
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
|
||||
* likely to yield significantly better space and time performance.
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
@Deprecated(since="9", forRemoval = true)
|
||||
public Character(char value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
@ -46,11 +46,18 @@ import jdk.internal.vm.annotation.IntrinsicCandidate;
|
||||
* constants and methods useful when dealing with a
|
||||
* {@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 Arthur van Hoff
|
||||
* @author Joseph D. Darcy
|
||||
* @since 1.0
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class Double extends Number
|
||||
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
|
||||
* likely to yield significantly better space and time performance.
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
@Deprecated(since="9", forRemoval = true)
|
||||
public Double(double value) {
|
||||
this.value = value;
|
||||
}
|
||||
@ -626,7 +633,7 @@ public final class Double extends Number
|
||||
* {@code double} primitive, or use {@link #valueOf(String)}
|
||||
* to convert a string to a {@code Double} object.
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
@Deprecated(since="9", forRemoval = true)
|
||||
public Double(String s) throws NumberFormatException {
|
||||
value = parseDouble(s);
|
||||
}
|
||||
|
@ -45,11 +45,18 @@ import jdk.internal.vm.annotation.IntrinsicCandidate;
|
||||
* constants and methods useful when dealing with a
|
||||
* {@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 Arthur van Hoff
|
||||
* @author Joseph D. Darcy
|
||||
* @since 1.0
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class Float extends Number
|
||||
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
|
||||
* likely to yield significantly better space and time performance.
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
@Deprecated(since="9", forRemoval = true)
|
||||
public Float(float value) {
|
||||
this.value = value;
|
||||
}
|
||||
@ -534,7 +541,7 @@ public final class Float extends Number
|
||||
* static factory method {@link #valueOf(float)} method as follows:
|
||||
* {@code Float.valueOf((float)value)}.
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
@Deprecated(since="9", forRemoval = true)
|
||||
public Float(double value) {
|
||||
this.value = (float)value;
|
||||
}
|
||||
@ -555,7 +562,7 @@ public final class Float extends Number
|
||||
* {@code float} primitive, or use {@link #valueOf(String)}
|
||||
* to convert a string to a {@code Float} object.
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
@Deprecated(since="9", forRemoval = true)
|
||||
public Float(String s) throws NumberFormatException {
|
||||
value = parseFloat(s);
|
||||
}
|
||||
|
@ -50,6 +50,12 @@ import static java.lang.String.UTF16;
|
||||
* {@code int}, as well as other constants and methods useful when
|
||||
* 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"
|
||||
* methods (such as {@link #highestOneBit(int) highestOneBit} and
|
||||
* {@link #numberOfTrailingZeros(int) numberOfTrailingZeros}) are
|
||||
@ -62,6 +68,7 @@ import static java.lang.String.UTF16;
|
||||
* @author Joseph D. Darcy
|
||||
* @since 1.0
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class Integer extends Number
|
||||
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
|
||||
* likely to yield significantly better space and time performance.
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
@Deprecated(since="9", forRemoval = true)
|
||||
public Integer(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
@ -1107,7 +1114,7 @@ public final class Integer extends Number
|
||||
* {@code int} primitive, or use {@link #valueOf(String)}
|
||||
* to convert a string to an {@code Integer} object.
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
@Deprecated(since="9", forRemoval = true)
|
||||
public Integer(String s) throws NumberFormatException {
|
||||
this.value = parseInt(s, 10);
|
||||
}
|
||||
|
@ -50,6 +50,12 @@ import static java.lang.String.UTF16;
|
||||
* long}, as well as other constants and methods useful when dealing
|
||||
* 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"
|
||||
* methods (such as {@link #highestOneBit(long) highestOneBit} and
|
||||
* {@link #numberOfTrailingZeros(long) numberOfTrailingZeros}) are
|
||||
@ -62,6 +68,7 @@ import static java.lang.String.UTF16;
|
||||
* @author Joseph D. Darcy
|
||||
* @since 1.0
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class Long extends Number
|
||||
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
|
||||
* likely to yield significantly better space and time performance.
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
@Deprecated(since="9", forRemoval = true)
|
||||
public Long(long value) {
|
||||
this.value = value;
|
||||
}
|
||||
@ -1339,7 +1346,7 @@ public final class Long extends Number
|
||||
* {@code long} primitive, or use {@link #valueOf(String)}
|
||||
* to convert a string to a {@code Long} object.
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
@Deprecated(since="9", forRemoval = true)
|
||||
public Long(String s) throws NumberFormatException {
|
||||
this.value = parseLong(s, 10);
|
||||
}
|
||||
|
@ -81,16 +81,17 @@ import java.util.stream.Stream;
|
||||
* <p>
|
||||
* The {@code ProcessHandle} static factory methods return instances that are
|
||||
* <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>,
|
||||
* immutable and thread-safe.
|
||||
* Use of identity-sensitive operations (including reference equality
|
||||
* ({@code ==}), identity hash code, or synchronization) on these instances of
|
||||
* {@code ProcessHandle} may have unpredictable results and should be avoided.
|
||||
* Use {@link #equals(Object) equals} or
|
||||
* {@link #compareTo(ProcessHandle) compareTo} methods to compare ProcessHandles.
|
||||
* immutable and thread-safe. 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.
|
||||
* Use the {@code equals} or {@link #compareTo(ProcessHandle) compareTo} methods
|
||||
* to compare ProcessHandles.
|
||||
*
|
||||
* @see Process
|
||||
* @since 9
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public interface ProcessHandle extends Comparable<ProcessHandle> {
|
||||
|
||||
/**
|
||||
|
@ -48,6 +48,7 @@ import static java.security.AccessController.doPrivileged;
|
||||
* @see Process
|
||||
* @since 9
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
final class ProcessHandleImpl implements ProcessHandle {
|
||||
/**
|
||||
* Default size of stack for reaper processes.
|
||||
|
@ -941,14 +941,15 @@ public class Runtime {
|
||||
* $VNUM(-$PRE)?
|
||||
* </pre></blockquote>
|
||||
*
|
||||
* <p>This is a <a href="./doc-files/ValueBased.html">value-based</a>
|
||||
* class; use of identity-sensitive operations (including reference equality
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code Version} may have unpredictable results and should be avoided.
|
||||
* </p>
|
||||
* <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>
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public static final class Version
|
||||
implements Comparable<Version>
|
||||
{
|
||||
|
@ -47,11 +47,18 @@ import static java.lang.constant.ConstantDescs.DEFAULT_NAME;
|
||||
* {@code short}, as well as other constants and methods useful when
|
||||
* 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 Joseph D. Darcy
|
||||
* @see java.lang.Number
|
||||
* @since 1.1
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
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
|
||||
* likely to yield significantly better space and time performance.
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
@Deprecated(since="9", forRemoval = true)
|
||||
public Short(short 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)}
|
||||
* to convert a string to a {@code Short} object.
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
@Deprecated(since="9", forRemoval = true)
|
||||
public Short(String s) throws NumberFormatException {
|
||||
this.value = parseShort(s, 10);
|
||||
}
|
||||
|
@ -57,8 +57,8 @@ import java.lang.invoke.VarHandle.VarHandleDesc;
|
||||
* <p>Constants describing various common constants (such as {@link ClassDesc}
|
||||
* instances for platform types) can be found in {@link ConstantDescs}.
|
||||
*
|
||||
* <p>Implementations of {@linkplain ConstantDesc} must be
|
||||
* <a href="../doc-files/ValueBased.html">value-based</a> classes.
|
||||
* <p>Implementations of {@linkplain ConstantDesc} should be immutable
|
||||
* and their behavior should not rely on object identity.
|
||||
*
|
||||
* <p>Non-platform classes should not implement {@linkplain ConstantDesc} directly.
|
||||
* Instead, they should extend {@link DynamicConstantDesc} (as {@link EnumDesc}
|
||||
|
@ -41,8 +41,8 @@ import static java.util.stream.Collectors.joining;
|
||||
* A <a href="package-summary.html#nominal">nominal descriptor</a> for an
|
||||
* {@code invokedynamic} call site.
|
||||
*
|
||||
* <p>Concrete subtypes of {@linkplain DynamicCallSiteDesc} must be
|
||||
* <a href="../doc-files/ValueBased.html">value-based</a>.
|
||||
* <p>Concrete subtypes of {@linkplain DynamicCallSiteDesc} should be immutable
|
||||
* and their behavior should not rely on object identity.
|
||||
*
|
||||
* @since 12
|
||||
*/
|
||||
|
@ -49,8 +49,8 @@ import static java.util.stream.Collectors.joining;
|
||||
* dynamic constant (one described in the constant pool with
|
||||
* {@code Constant_Dynamic_info}.)
|
||||
*
|
||||
* <p>Concrete subtypes of {@linkplain DynamicConstantDesc} must be
|
||||
* <a href="../doc-files/ValueBased.html">value-based</a>.
|
||||
* <p>Concrete subtypes of {@linkplain DynamicConstantDesc} should be immutable
|
||||
* and their behavior should not rely on object identity.
|
||||
*
|
||||
* @param <T> the type of the dynamic constant
|
||||
*
|
||||
|
@ -31,36 +31,43 @@
|
||||
<body>
|
||||
<h1 id="ValueBased">{@index "Value-based Classes"}</h1>
|
||||
|
||||
Some classes, such as <code>java.util.Optional</code> and
|
||||
<code>java.time.LocalDateTime</code>, are <em>value-based</em>. Instances of a
|
||||
value-based class:
|
||||
Some classes, such as <code>java.lang.Integer</code> and
|
||||
<code>java.time.LocalDate</code>, are <em>value-based</em>.
|
||||
A value-based class has the following properties:
|
||||
<ul>
|
||||
<li>are final and immutable (though may contain references to mutable
|
||||
objects);</li>
|
||||
<li>have implementations of <code>equals</code>,
|
||||
<code>hashCode</code>, and <code>toString</code> which are computed
|
||||
solely from the instance's state and not from its identity or the state
|
||||
of any other object or variable;</li>
|
||||
<li>make no use of identity-sensitive operations such as reference
|
||||
equality (<code>==</code>) between instances, identity hash code of
|
||||
instances, or synchronization on an instances's intrinsic lock;</li>
|
||||
<li>are considered equal solely based on <code>equals()</code>, not
|
||||
based on reference equality (<code>==</code>);</li>
|
||||
<li>do not have accessible constructors, but are instead instantiated
|
||||
through factory methods which make no commitment as to the identity
|
||||
of returned instances;</li>
|
||||
<li>are <em>freely substitutable</em> when equal, meaning that interchanging
|
||||
any two instances <code>x</code> and <code>y</code> that are equal
|
||||
according to <code>equals()</code> in any computation or method
|
||||
invocation should produce no visible change in behavior.
|
||||
</li>
|
||||
<li>the class declares only final instance fields (though these may contain references
|
||||
to mutable objects);</li>
|
||||
<li>the class's implementations of <code>equals</code>, <code>hashCode</code>,
|
||||
and <code>toString</code> compute their results solely from the values
|
||||
of the class's instance fields (and the members of the objects they
|
||||
reference), not from the instance's identity;</li>
|
||||
<li>the class's methods treat instances as <em>freely substitutable</em>
|
||||
when equal, meaning that interchanging any two instances <code>x</code> and
|
||||
<code>y</code> that are equal according to <code>equals()</code> produces no
|
||||
visible change in the behavior of the class's methods;</li>
|
||||
<li>the class performs no synchronization using an instance's monitor;</li>
|
||||
<li>the class does not declare (or has deprecated any) accessible constructors;</li>
|
||||
<li>the class does not provide any instance creation mechanism that promises
|
||||
a unique identity on each method call—in particular, any factory
|
||||
method's contract must allow for the possibility that if two independently-produced
|
||||
instances are equal according to <code>equals()</code>, they may also be
|
||||
equal according to <code>==</code>;</li>
|
||||
<li>the class is final, and extends either <code>Object</code> or a hierarchy of
|
||||
abstract classes that declare no instance fields or instance initializers
|
||||
and whose constructors are empty.</li>
|
||||
</ul>
|
||||
|
||||
<p>A program may produce unpredictable results if it attempts to distinguish two
|
||||
references to equal values of a value-based class, whether directly via reference
|
||||
<p>When two instances of a value-based class are equal (according to `equals`), a program
|
||||
should not attempt to distinguish between their identities, whether directly via reference
|
||||
equality or indirectly via an appeal to synchronization, identity hashing,
|
||||
serialization, or any other identity-sensitive mechanism. Use of such
|
||||
identity-sensitive operations on instances of value-based classes may have
|
||||
unpredictable effects and should be avoided.</p>
|
||||
serialization, or any other identity-sensitive mechanism.</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>
|
||||
</html>
|
||||
|
@ -773,7 +773,7 @@ final class MemberName implements Member, Cloneable {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
@SuppressWarnings({"deprecation", "removal"})
|
||||
public int hashCode() {
|
||||
// Avoid autoboxing getReferenceKind(), since this is used early and will force
|
||||
// early initialization of Byte$ByteCache
|
||||
|
@ -117,12 +117,12 @@ import java.util.regex.Pattern;
|
||||
* This difference only impacts durations measured near a leap-second and should not affect
|
||||
* most applications.
|
||||
* See {@link Instant} for a discussion as to the meaning of the second and time-scales.
|
||||
*
|
||||
* <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
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code Duration} may have unpredictable results and should be avoided.
|
||||
* 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.
|
||||
* The {@code equals} method should be used for comparisons.
|
||||
*
|
||||
* @implSpec
|
||||
@ -130,6 +130,7 @@ import java.util.regex.Pattern;
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class Duration
|
||||
implements TemporalAmount, Comparable<Duration>, Serializable {
|
||||
|
||||
|
@ -191,12 +191,12 @@ import java.util.Objects;
|
||||
* The Java time-scale is used for all date-time classes.
|
||||
* This includes {@code Instant}, {@code LocalDate}, {@code LocalTime}, {@code OffsetDateTime},
|
||||
* {@code ZonedDateTime} and {@code Duration}.
|
||||
*
|
||||
* <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
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code Instant} may have unpredictable results and should be avoided.
|
||||
* 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.
|
||||
* The {@code equals} method should be used for comparisons.
|
||||
*
|
||||
* @implSpec
|
||||
@ -204,6 +204,7 @@ import java.util.Objects;
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class Instant
|
||||
implements Temporal, TemporalAdjuster, Comparable<Instant>, Serializable {
|
||||
|
||||
|
@ -123,12 +123,12 @@ import java.util.stream.Stream;
|
||||
* For most applications written today, the ISO-8601 rules are entirely suitable.
|
||||
* However, any application that makes use of historical dates, and requires them
|
||||
* to be accurate will find the ISO-8601 approach unsuitable.
|
||||
*
|
||||
* <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
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code LocalDate} may have unpredictable results and should be avoided.
|
||||
* 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.
|
||||
* The {@code equals} method should be used for comparisons.
|
||||
*
|
||||
* @implSpec
|
||||
@ -136,6 +136,7 @@ import java.util.stream.Stream;
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class LocalDate
|
||||
implements Temporal, TemporalAdjuster, ChronoLocalDate, Serializable {
|
||||
|
||||
|
@ -119,12 +119,12 @@ import java.util.Objects;
|
||||
* For most applications written today, the ISO-8601 rules are entirely suitable.
|
||||
* However, any application that makes use of historical dates, and requires them
|
||||
* to be accurate will find the ISO-8601 approach unsuitable.
|
||||
*
|
||||
* <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
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code LocalDateTime} may have unpredictable results and should be avoided.
|
||||
* 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.
|
||||
* The {@code equals} method should be used for comparisons.
|
||||
*
|
||||
* @implSpec
|
||||
@ -132,6 +132,7 @@ import java.util.Objects;
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class LocalDateTime
|
||||
implements Temporal, TemporalAdjuster, ChronoLocalDateTime<LocalDate>, Serializable {
|
||||
|
||||
|
@ -109,12 +109,12 @@ import java.util.Objects;
|
||||
* 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
|
||||
* representation, this class, for time-of-day.
|
||||
*
|
||||
* <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
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code LocalTime} may have unpredictable results and should be avoided.
|
||||
* 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.
|
||||
* The {@code equals} method should be used for comparisons.
|
||||
*
|
||||
* @implSpec
|
||||
@ -122,6 +122,7 @@ import java.util.Objects;
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class LocalTime
|
||||
implements Temporal, TemporalAdjuster, Comparable<LocalTime>, Serializable {
|
||||
|
||||
|
@ -111,12 +111,12 @@ import java.util.Objects;
|
||||
* For most applications written today, the ISO-8601 rules are entirely suitable.
|
||||
* However, any application that makes use of historical dates, and requires them
|
||||
* to be accurate will find the ISO-8601 approach unsuitable.
|
||||
*
|
||||
* <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
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code MonthDay} may have unpredictable results and should be avoided.
|
||||
* 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.
|
||||
* The {@code equals} method should be used for comparisons.
|
||||
*
|
||||
* @implSpec
|
||||
@ -124,6 +124,7 @@ import java.util.Objects;
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class MonthDay
|
||||
implements TemporalAccessor, TemporalAdjuster, Comparable<MonthDay>, Serializable {
|
||||
|
||||
|
@ -112,12 +112,12 @@ import java.util.Objects;
|
||||
* 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
|
||||
* more detail, or when communicating to a database or in a network protocol.
|
||||
*
|
||||
* <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
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code OffsetDateTime} may have unpredictable results and should be avoided.
|
||||
* 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.
|
||||
* The {@code equals} method should be used for comparisons.
|
||||
*
|
||||
* @implSpec
|
||||
@ -125,6 +125,7 @@ import java.util.Objects;
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class OffsetDateTime
|
||||
implements Temporal, TemporalAdjuster, Comparable<OffsetDateTime>, Serializable {
|
||||
|
||||
|
@ -102,12 +102,12 @@ import java.util.Objects;
|
||||
* as well as a zone offset.
|
||||
* For example, the value "13:45:30.123456789+02:00" can be stored
|
||||
* in an {@code OffsetTime}.
|
||||
*
|
||||
* <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
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code OffsetTime} may have unpredictable results and should be avoided.
|
||||
* 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.
|
||||
* The {@code equals} method should be used for comparisons.
|
||||
*
|
||||
* @implSpec
|
||||
@ -115,6 +115,7 @@ import java.util.Objects;
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class OffsetTime
|
||||
implements Temporal, TemporalAdjuster, Comparable<OffsetTime>, Serializable {
|
||||
|
||||
|
@ -117,12 +117,12 @@ import java.util.regex.Pattern;
|
||||
* <p>
|
||||
* The period is modeled as a directed amount of time, meaning that individual parts of the
|
||||
* period may be negative.
|
||||
*
|
||||
* <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
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code Period} may have unpredictable results and should be avoided.
|
||||
* 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.
|
||||
* The {@code equals} method should be used for comparisons.
|
||||
*
|
||||
* @implSpec
|
||||
@ -130,6 +130,7 @@ import java.util.regex.Pattern;
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class Period
|
||||
implements ChronoPeriod, Serializable {
|
||||
|
||||
|
@ -119,12 +119,12 @@ import java.util.Objects;
|
||||
* For most applications written today, the ISO-8601 rules are entirely suitable.
|
||||
* However, any application that makes use of historical dates, and requires them
|
||||
* to be accurate will find the ISO-8601 approach unsuitable.
|
||||
*
|
||||
* <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
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code Year} may have unpredictable results and should be avoided.
|
||||
* 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.
|
||||
* The {@code equals} method should be used for comparisons.
|
||||
*
|
||||
* @implSpec
|
||||
@ -132,6 +132,7 @@ import java.util.Objects;
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class Year
|
||||
implements Temporal, TemporalAdjuster, Comparable<Year>, Serializable {
|
||||
|
||||
|
@ -115,12 +115,12 @@ import java.util.Objects;
|
||||
* For most applications written today, the ISO-8601 rules are entirely suitable.
|
||||
* However, any application that makes use of historical dates, and requires them
|
||||
* to be accurate will find the ISO-8601 approach unsuitable.
|
||||
*
|
||||
* <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
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code YearMonth} may have unpredictable results and should be avoided.
|
||||
* 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.
|
||||
* The {@code equals} method should be used for comparisons.
|
||||
*
|
||||
* @implSpec
|
||||
@ -128,6 +128,7 @@ import java.util.Objects;
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class YearMonth
|
||||
implements Temporal, TemporalAdjuster, Comparable<YearMonth>, Serializable {
|
||||
|
||||
|
@ -160,12 +160,12 @@ import static java.util.Map.entry;
|
||||
* However, any call to {@code getRules} will fail with {@code ZoneRulesException}.
|
||||
* 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.
|
||||
*
|
||||
* <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
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code ZoneId} may have unpredictable results and should be avoided.
|
||||
* 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.
|
||||
* The {@code equals} method should be used for comparisons.
|
||||
*
|
||||
* @implSpec
|
||||
@ -175,6 +175,7 @@ import static java.util.Map.entry;
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public abstract class ZoneId implements Serializable {
|
||||
|
||||
/**
|
||||
|
@ -114,12 +114,12 @@ import java.util.concurrent.ConcurrentMap;
|
||||
* Instances of {@code ZoneOffset} must be compared using {@link #equals}.
|
||||
* Implementations may choose to cache certain common offsets, however
|
||||
* applications must not rely on such caching.
|
||||
*
|
||||
* <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
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code ZoneOffset} may have unpredictable results and should be avoided.
|
||||
* 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.
|
||||
* The {@code equals} method should be used for comparisons.
|
||||
*
|
||||
* @implSpec
|
||||
@ -127,6 +127,7 @@ import java.util.concurrent.ConcurrentMap;
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class ZoneOffset
|
||||
extends ZoneId
|
||||
implements TemporalAccessor, TemporalAdjuster, Comparable<ZoneOffset>, Serializable {
|
||||
|
@ -142,12 +142,12 @@ import java.util.Objects;
|
||||
* 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
|
||||
* represents an instant, especially during a daylight savings overlap.
|
||||
*
|
||||
* <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
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code ZonedDateTime} may have unpredictable results and should be avoided.
|
||||
* 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.
|
||||
* The {@code equals} method should be used for comparisons.
|
||||
*
|
||||
* @implSpec
|
||||
@ -161,6 +161,7 @@ import java.util.Objects;
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class ZonedDateTime
|
||||
implements Temporal, ChronoZonedDateTime<LocalDate>, Serializable {
|
||||
|
||||
|
@ -103,12 +103,12 @@ import java.time.temporal.ValueRange;
|
||||
* to create new HijrahDate instances.
|
||||
* Alternatively, the {@link #withVariant} method can be used to convert
|
||||
* to a new HijrahChronology.
|
||||
*
|
||||
* <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
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code HijrahDate} may have unpredictable results and should be avoided.
|
||||
* 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.
|
||||
* The {@code equals} method should be used for comparisons.
|
||||
*
|
||||
* @implSpec
|
||||
@ -116,6 +116,7 @@ import java.time.temporal.ValueRange;
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class HijrahDate
|
||||
extends ChronoLocalDateImpl<HijrahDate>
|
||||
implements ChronoLocalDate, Serializable {
|
||||
|
@ -110,12 +110,12 @@ import sun.util.calendar.LocalGregorianCalendar;
|
||||
* Calling {@code japaneseDate.get(YEAR)} will return 2012.<br>
|
||||
* Calling {@code japaneseDate.get(ERA)} will return 2, corresponding to
|
||||
* {@code JapaneseChronology.ERA_HEISEI}.<br>
|
||||
*
|
||||
* <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
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code JapaneseDate} may have unpredictable results and should be avoided.
|
||||
* 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.
|
||||
* The {@code equals} method should be used for comparisons.
|
||||
*
|
||||
* @implSpec
|
||||
@ -123,6 +123,7 @@ import sun.util.calendar.LocalGregorianCalendar;
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class JapaneseDate
|
||||
extends ChronoLocalDateImpl<JapaneseDate>
|
||||
implements ChronoLocalDate, Serializable {
|
||||
@ -140,11 +141,11 @@ public final class JapaneseDate
|
||||
/**
|
||||
* The JapaneseEra of this date.
|
||||
*/
|
||||
private transient JapaneseEra era;
|
||||
private final transient JapaneseEra era;
|
||||
/**
|
||||
* 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.
|
||||
|
@ -90,12 +90,12 @@ import java.util.Objects;
|
||||
* This date operates using the {@linkplain MinguoChronology Minguo calendar}.
|
||||
* 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)}.
|
||||
*
|
||||
* <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
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code MinguoDate} may have unpredictable results and should be avoided.
|
||||
* 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.
|
||||
* The {@code equals} method should be used for comparisons.
|
||||
*
|
||||
* @implSpec
|
||||
@ -103,6 +103,7 @@ import java.util.Objects;
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class MinguoDate
|
||||
extends ChronoLocalDateImpl<MinguoDate>
|
||||
implements ChronoLocalDate, Serializable {
|
||||
|
@ -72,7 +72,6 @@ import java.time.temporal.ChronoField;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.time.temporal.TemporalField;
|
||||
import java.time.temporal.ValueRange;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
@ -90,12 +90,12 @@ import java.util.Objects;
|
||||
* This date operates using the {@linkplain ThaiBuddhistChronology Thai Buddhist calendar}.
|
||||
* This calendar system is primarily used in Thailand.
|
||||
* Dates are aligned such that {@code 2484-01-01 (Buddhist)} is {@code 1941-01-01 (ISO)}.
|
||||
*
|
||||
* <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
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code ThaiBuddhistDate} may have unpredictable results and should be avoided.
|
||||
* 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.
|
||||
* The {@code equals} method should be used for comparisons.
|
||||
*
|
||||
* @implSpec
|
||||
@ -103,6 +103,7 @@ import java.util.Objects;
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class ThaiBuddhistDate
|
||||
extends ChronoLocalDateImpl<ThaiBuddhistDate>
|
||||
implements ChronoLocalDate, Serializable {
|
||||
|
@ -81,7 +81,7 @@ import java.util.Calendar;
|
||||
* to the word used for month in association with a day and year in a date.
|
||||
*
|
||||
* @implSpec
|
||||
* This is immutable and thread-safe enum.
|
||||
* This is an immutable and thread-safe enum.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
|
@ -141,6 +141,7 @@ class ImmutableCollections {
|
||||
|
||||
static UnsupportedOperationException uoe() { return new UnsupportedOperationException(); }
|
||||
|
||||
@jdk.internal.ValueBased
|
||||
static abstract class AbstractImmutableCollection<E> extends AbstractCollection<E> {
|
||||
// all mutating methods throw UnsupportedOperationException
|
||||
@Override public boolean add(E e) { throw uoe(); }
|
||||
@ -247,6 +248,7 @@ class ImmutableCollections {
|
||||
|
||||
// ---------- List Implementations ----------
|
||||
|
||||
@jdk.internal.ValueBased
|
||||
static abstract class AbstractImmutableList<E> extends AbstractImmutableCollection<E>
|
||||
implements List<E>, RandomAccess {
|
||||
|
||||
@ -540,6 +542,7 @@ class ImmutableCollections {
|
||||
}
|
||||
}
|
||||
|
||||
@jdk.internal.ValueBased
|
||||
static final class List12<E> extends AbstractImmutableList<E>
|
||||
implements Serializable {
|
||||
|
||||
@ -646,6 +649,7 @@ class ImmutableCollections {
|
||||
}
|
||||
}
|
||||
|
||||
@jdk.internal.ValueBased
|
||||
static final class ListN<E> extends AbstractImmutableList<E>
|
||||
implements Serializable {
|
||||
|
||||
@ -737,6 +741,7 @@ class ImmutableCollections {
|
||||
|
||||
// ---------- Set Implementations ----------
|
||||
|
||||
@jdk.internal.ValueBased
|
||||
static abstract class AbstractImmutableSet<E> extends AbstractImmutableCollection<E>
|
||||
implements Set<E> {
|
||||
|
||||
@ -764,6 +769,7 @@ class ImmutableCollections {
|
||||
public abstract int hashCode();
|
||||
}
|
||||
|
||||
@jdk.internal.ValueBased
|
||||
static final class Set12<E> extends AbstractImmutableSet<E>
|
||||
implements Serializable {
|
||||
|
||||
@ -889,6 +895,7 @@ class ImmutableCollections {
|
||||
* least one null is always present.
|
||||
* @param <E> the element type
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
static final class SetN<E> extends AbstractImmutableSet<E>
|
||||
implements Serializable {
|
||||
|
||||
@ -1055,6 +1062,7 @@ class ImmutableCollections {
|
||||
|
||||
// ---------- Map Implementations ----------
|
||||
|
||||
@jdk.internal.ValueBased
|
||||
abstract static class AbstractImmutableMap<K,V> extends AbstractMap<K,V> implements Serializable {
|
||||
@Override public void clear() { 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> {
|
||||
@Stable
|
||||
private final K k0;
|
||||
@ -1151,6 +1160,7 @@ class ImmutableCollections {
|
||||
* @param <K> the key type
|
||||
* @param <V> the value type
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
static final class MapN<K,V> extends AbstractImmutableMap<K,V> {
|
||||
|
||||
@Stable
|
||||
|
@ -31,10 +31,11 @@ import jdk.internal.vm.annotation.Stable;
|
||||
* An immutable container for a key and a value, suitable for use
|
||||
* in creating and populating {@code Map} instances.
|
||||
*
|
||||
* <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a>
|
||||
* class; use of identity-sensitive operations (including reference equality
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code KeyValueHolder} may have unpredictable results and should be avoided.
|
||||
* <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.
|
||||
*
|
||||
* @apiNote
|
||||
* 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()
|
||||
* @since 9
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
final class KeyValueHolder<K,V> implements Map.Entry<K,V> {
|
||||
@Stable
|
||||
final K key;
|
||||
|
@ -107,10 +107,12 @@ import java.util.function.UnaryOperator;
|
||||
* <li>The lists and their {@link #subList(int, int) subList} views implement the
|
||||
* {@link RandomAccess} interface.
|
||||
* <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.
|
||||
* Factories are free to create new instances or reuse existing ones. Therefore,
|
||||
* identity-sensitive operations on these instances (reference equality ({@code ==}),
|
||||
* identity hash code, and synchronization) are unreliable and should be avoided.
|
||||
* Programmers should treat instances that are {@linkplain #equals(Object) equal}
|
||||
* as interchangeable and should not use them for synchronization, or
|
||||
* unpredictable behavior may occur. For example, in a future release,
|
||||
* 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
|
||||
* <a href="{@docRoot}/serialized-form.html#java.util.CollSer">Serialized Form</a>
|
||||
* page.
|
||||
|
@ -131,10 +131,12 @@ import java.io.Serializable;
|
||||
* passed to a static factory method result in {@code IllegalArgumentException}.
|
||||
* <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>.
|
||||
* Callers should make no assumptions about the identity of the returned instances.
|
||||
* Factories are free to create new instances or reuse existing ones. Therefore,
|
||||
* identity-sensitive operations on these instances (reference equality ({@code ==}),
|
||||
* identity hash code, and synchronization) are unreliable and should be avoided.
|
||||
* Programmers should treat instances that are {@linkplain #equals(Object) equal}
|
||||
* as interchangeable and should not use them for synchronization, or
|
||||
* unpredictable behavior may occur. For example, in a future release,
|
||||
* 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
|
||||
* <a href="{@docRoot}/serialized-form.html#java.util.CollSer">Serialized Form</a>
|
||||
* page.
|
||||
@ -1636,10 +1638,12 @@ public interface Map<K, V> {
|
||||
* on a returned {@code Entry} result in {@code UnsupportedOperationException}.
|
||||
* <li>They are not serializable.
|
||||
* <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.
|
||||
* This method is free to create new instances or reuse existing ones. Therefore,
|
||||
* identity-sensitive operations on these instances (reference equality ({@code ==}),
|
||||
* identity hash code, and synchronization) are unreliable and should be avoided.
|
||||
* Programmers should treat instances that are {@linkplain #equals(Object) equal}
|
||||
* as interchangeable and should not use them for synchronization, or
|
||||
* unpredictable behavior may occur. For example, in a future release,
|
||||
* 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>
|
||||
*
|
||||
* @apiNote
|
||||
|
@ -42,10 +42,11 @@ import java.util.stream.Stream;
|
||||
* {@link #ifPresent(Consumer) ifPresent()} (performs an
|
||||
* action if a value is present).
|
||||
*
|
||||
* <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a>
|
||||
* class; use of identity-sensitive operations (including reference equality
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code Optional} may have unpredictable results and should be avoided.
|
||||
* <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.
|
||||
*
|
||||
* @apiNote
|
||||
* {@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
|
||||
* @since 1.8
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class Optional<T> {
|
||||
/**
|
||||
* Common instance for {@code empty()}.
|
||||
|
@ -41,10 +41,11 @@ import java.util.stream.DoubleStream;
|
||||
* {@link #ifPresent(DoubleConsumer) ifPresent()} (performs
|
||||
* an action if a value is present).
|
||||
*
|
||||
* <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a>
|
||||
* class; use of identity-sensitive operations (including reference equality
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code OptionalDouble} may have unpredictable results and should be avoided.
|
||||
* <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.
|
||||
*
|
||||
* @apiNote
|
||||
* {@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
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class OptionalDouble {
|
||||
/**
|
||||
* Common instance for {@code empty()}.
|
||||
|
@ -41,10 +41,11 @@ import java.util.stream.IntStream;
|
||||
* {@link #ifPresent(IntConsumer) ifPresent()} (performs an
|
||||
* action if a value is present).
|
||||
*
|
||||
* <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a>
|
||||
* class; use of identity-sensitive operations (including reference equality
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code OptionalInt} may have unpredictable results and should be avoided.
|
||||
* <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.
|
||||
*
|
||||
* @apiNote
|
||||
* {@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
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class OptionalInt {
|
||||
/**
|
||||
* Common instance for {@code empty()}.
|
||||
|
@ -41,10 +41,11 @@ import java.util.stream.LongStream;
|
||||
* {@link #ifPresent(LongConsumer) ifPresent()} (performs an
|
||||
* action if a value is present).
|
||||
*
|
||||
* <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a>
|
||||
* class; use of identity-sensitive operations (including reference equality
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code OptionalLong} may have unpredictable results and should be avoided.
|
||||
* <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.
|
||||
*
|
||||
* @apiNote
|
||||
* {@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
|
||||
*/
|
||||
@jdk.internal.ValueBased
|
||||
public final class OptionalLong {
|
||||
/**
|
||||
* Common instance for {@code empty()}.
|
||||
|
@ -82,10 +82,12 @@ package java.util;
|
||||
* 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>They are <a href="../lang/doc-files/ValueBased.html">value-based</a>.
|
||||
* Callers should make no assumptions about the identity of the returned instances.
|
||||
* Factories are free to create new instances or reuse existing ones. Therefore,
|
||||
* identity-sensitive operations on these instances (reference equality ({@code ==}),
|
||||
* identity hash code, and synchronization) are unreliable and should be avoided.
|
||||
* Programmers should treat instances that are {@linkplain #equals(Object) equal}
|
||||
* as interchangeable and should not use them for synchronization, or
|
||||
* unpredictable behavior may occur. For example, in a future release,
|
||||
* 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
|
||||
* <a href="{@docRoot}/serialized-form.html#java.util.CollSer">Serialized Form</a>
|
||||
* page.
|
||||
|
44
src/java.base/share/classes/jdk/internal/ValueBased.java
Normal file
44
src/java.base/share/classes/jdk/internal/ValueBased.java
Normal 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 {
|
||||
}
|
||||
|
@ -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)
|
||||
throws java.io.IOException {
|
||||
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);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
|
@ -4013,7 +4013,8 @@ public class XSDHandler {
|
||||
","+oldName:currSchema.fTargetNamespace+","+oldName;
|
||||
int attGroupRefsCount = changeRedefineGroup(processedBaseName, componentType, newName, child, currSchema);
|
||||
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) {
|
||||
// return true;
|
||||
@ -4029,7 +4030,7 @@ public class XSDHandler {
|
||||
","+oldName:currSchema.fTargetNamespace+","+oldName;
|
||||
int groupRefsCount = changeRedefineGroup(processedBaseName, componentType, newName, child, currSchema);
|
||||
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) {
|
||||
// return true;
|
||||
|
@ -438,8 +438,8 @@ public final class HTMLdtd
|
||||
private static void defineEntity( String name, char value )
|
||||
{
|
||||
if ( _byName.get( name ) == null ) {
|
||||
_byName.put( name, new Integer( value ) );
|
||||
_byChar.put( new Integer( value ), name );
|
||||
_byName.put( name, (int) value);
|
||||
_byChar.put( (int) value , name );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,6 +125,7 @@ public class Lint
|
||||
if (!options.isSet(Option.PREVIEW)) {
|
||||
values.add(LintCategory.PREVIEW);
|
||||
}
|
||||
values.add(LintCategory.SYNCHRONIZATION);
|
||||
}
|
||||
|
||||
// Look for specific overrides
|
||||
@ -282,6 +283,11 @@ public class Lint
|
||||
*/
|
||||
STATIC("static"),
|
||||
|
||||
/**
|
||||
* Warn about synchronization attempts on instances of @ValueBased classes.
|
||||
*/
|
||||
SYNCHRONIZATION("synchronization"),
|
||||
|
||||
/**
|
||||
* Warn about issues relating to use of text blocks
|
||||
*/
|
||||
|
@ -220,6 +220,7 @@ public class Symtab {
|
||||
public final Type previewFeatureInternalType;
|
||||
public final Type typeDescriptorType;
|
||||
public final Type recordType;
|
||||
public final Type valueBasedType;
|
||||
|
||||
/** The symbol representing the length field of an array.
|
||||
*/
|
||||
@ -584,6 +585,7 @@ public class Symtab {
|
||||
previewFeatureInternalType = enterSyntheticAnnotation("jdk.internal.PreviewFeature+Annotation");
|
||||
typeDescriptorType = enterClass("java.lang.invoke.TypeDescriptor");
|
||||
recordType = enterClass("java.lang.Record");
|
||||
valueBasedType = enterClass("jdk.internal.ValueBased");
|
||||
|
||||
synthesizeEmptyInterfaceIfMissing(autoCloseableType);
|
||||
synthesizeEmptyInterfaceIfMissing(cloneableType);
|
||||
|
@ -1740,9 +1740,24 @@ public class Attr extends JCTree.Visitor {
|
||||
|
||||
public void visitSynchronized(JCSynchronized tree) {
|
||||
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);
|
||||
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) {
|
||||
// Create a new local environment with a local
|
||||
|
@ -3740,3 +3740,7 @@ compiler.err.preview.not.latest=\
|
||||
|
||||
compiler.err.preview.without.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
|
||||
|
||||
|
@ -256,10 +256,13 @@ javac.opt.Xlint.desc.unchecked=\
|
||||
Warn about unchecked operations.
|
||||
|
||||
javac.opt.Xlint.desc.varargs=\
|
||||
Warn about potentially unsafe vararg methods
|
||||
Warn about potentially unsafe vararg methods.
|
||||
|
||||
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=\
|
||||
Enable recommended checks for problems in javadoc comments
|
||||
|
@ -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>
|
||||
* (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...)}).
|
||||
*
|
||||
* <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
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code GroupLayout} may have unpredictable results and should be avoided.
|
||||
* 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.
|
||||
* 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}
|
||||
|
@ -40,9 +40,9 @@ import java.lang.ref.Cleaner;
|
||||
* when performing memory dereference operations using a memory access var handle (see {@link MemoryHandles}).
|
||||
* <p>
|
||||
* 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
|
||||
* instances of {@code MemoryAddress} may have unpredictable results and should be avoided. The {@code equals} method should
|
||||
* be used for comparisons.
|
||||
* 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. The {@code equals} method should be used for comparisons.
|
||||
* <p>
|
||||
* Non-platform classes should not implement {@linkplain MemoryAddress} directly.
|
||||
*
|
||||
|
@ -78,9 +78,9 @@ SequenceLayout taggedValues = MemoryLayout.ofSequence(5,
|
||||
* }</pre></blockquote>
|
||||
* <p>
|
||||
* 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
|
||||
* instances of {@code MemoryLayout} may have unpredictable results and should be avoided. The {@code equals} method should
|
||||
* be used for comparisons.
|
||||
* 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. The {@code equals} method should be used for comparisons.
|
||||
* <p>
|
||||
* Non-platform classes should not implement {@linkplain MemoryLayout} directly.
|
||||
*
|
||||
|
@ -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()}).
|
||||
* <p>
|
||||
* 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
|
||||
* instances of {@code MemorySegment} may have unpredictable results and should be avoided. The {@code equals} method should
|
||||
* be used for comparisons.
|
||||
* 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. The {@code equals} method should be used for comparisons.
|
||||
* <p>
|
||||
* Non-platform classes should not implement {@linkplain MemorySegment} directly.
|
||||
*
|
||||
|
@ -38,9 +38,10 @@ import java.util.OptionalLong;
|
||||
* and is typically used for aligning member layouts around word boundaries.
|
||||
* <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
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code PaddingLayout} may have unpredictable results and should be avoided.
|
||||
* 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.
|
||||
* 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}
|
||||
|
@ -55,9 +55,10 @@ MemoryLayout.ofStruct(
|
||||
*
|
||||
* <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
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code SequenceLayout} may have unpredictable results and should be avoided.
|
||||
* 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.
|
||||
* 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}
|
||||
|
@ -40,9 +40,10 @@ import java.util.OptionalLong;
|
||||
*
|
||||
* <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
|
||||
* ({@code ==}), identity hash code, or synchronization) on instances of
|
||||
* {@code ValueLayout} may have unpredictable results and should be avoided.
|
||||
* 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.
|
||||
* 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}
|
||||
|
@ -133,7 +133,7 @@ public class EconomicMapImplTest {
|
||||
Assert.assertTrue(set.add(newInteger(0)));
|
||||
}
|
||||
|
||||
@SuppressWarnings({"deprecation", "unused"})
|
||||
@SuppressWarnings({"deprecation", "removal", "unused"})
|
||||
private static Integer newInteger(int value) {
|
||||
return new Integer(value);
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ public class EconomicSetTest {
|
||||
Assert.assertEquals(newInteger(9), finalList.get(0));
|
||||
}
|
||||
|
||||
@SuppressWarnings({"deprecation", "unused"})
|
||||
@SuppressWarnings({"deprecation", "removal", "unused"})
|
||||
private static Integer newInteger(int value) {
|
||||
return new Integer(value);
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ public class EscapeAnalysisTest extends EATestBase {
|
||||
testEscapeAnalysis("test1Snippet", JavaConstant.forInt(101), false);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@SuppressWarnings({"deprecation", "removal"})
|
||||
public static int test1Snippet() {
|
||||
Integer x = new Integer(101);
|
||||
return x.intValue();
|
||||
@ -89,7 +89,7 @@ public class EscapeAnalysisTest extends EATestBase {
|
||||
testEscapeAnalysis("testMonitorSnippet", JavaConstant.forInt(0), false);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@SuppressWarnings({"deprecation", "removal", "synchronization"})
|
||||
public static int testMonitorSnippet() {
|
||||
Integer x = new Integer(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
|
||||
* region.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@SuppressWarnings({"deprecation", "removal", "synchronization"})
|
||||
public static int testMonitor2Snippet() {
|
||||
Integer x = new Integer(0);
|
||||
Double y = new Double(0);
|
||||
@ -335,7 +335,7 @@ public class EscapeAnalysisTest extends EATestBase {
|
||||
|
||||
public volatile Object field;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@SuppressWarnings({"deprecation", "removal"})
|
||||
public int testChangeHandlingSnippet(int a) {
|
||||
Object obj;
|
||||
Integer one = 1;
|
||||
|
@ -42,7 +42,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
||||
|
||||
public static Object field;
|
||||
|
||||
@SuppressWarnings({"deprecation", "unused"})
|
||||
@SuppressWarnings({"deprecation", "removal", "unused"})
|
||||
public static void snippet1(int i) {
|
||||
Integer object = new Integer(i);
|
||||
GraalDirectives.ensureVirtualized(object);
|
||||
@ -53,7 +53,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
||||
test("snippet1", 1);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"deprecation", "unused"})
|
||||
@SuppressWarnings({"deprecation", "removal", "unused"})
|
||||
public static void snippet2(int i) {
|
||||
Integer object = new Integer(i);
|
||||
GraalDirectives.ensureVirtualized(object);
|
||||
@ -65,7 +65,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
||||
test("snippet2", 1);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"deprecation", "unused"})
|
||||
@SuppressWarnings({"deprecation", "removal", "unused"})
|
||||
public static void snippet3(int i) {
|
||||
Integer object = new Integer(i);
|
||||
field = object;
|
||||
@ -77,7 +77,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
||||
test("snippet3", 1);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"deprecation", "unused"})
|
||||
@SuppressWarnings({"deprecation", "removal", "unused"})
|
||||
public static void snippetHere1(int i) {
|
||||
Integer object = new Integer(i);
|
||||
GraalDirectives.ensureVirtualizedHere(object);
|
||||
@ -88,7 +88,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
||||
test("snippetHere1", 1);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"deprecation", "unused"})
|
||||
@SuppressWarnings({"deprecation", "removal", "unused"})
|
||||
public static void snippetHere2(int i) {
|
||||
Integer object = new Integer(i);
|
||||
GraalDirectives.ensureVirtualizedHere(object);
|
||||
@ -100,7 +100,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
||||
test("snippetHere2", 1);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"deprecation", "unused"})
|
||||
@SuppressWarnings({"deprecation", "removal", "unused"})
|
||||
public static void snippetHere3(int i) {
|
||||
Integer object = new Integer(i);
|
||||
field = object;
|
||||
@ -133,7 +133,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
||||
test("snippetBoxing2", 1);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"deprecation", "unused"})
|
||||
@SuppressWarnings({"deprecation", "removal", "unused"})
|
||||
public static void snippetControlFlow1(boolean b, int i) {
|
||||
Integer object = new Integer(i);
|
||||
if (b) {
|
||||
@ -148,7 +148,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
||||
test("snippetControlFlow1", true, 1);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"deprecation", "unused"})
|
||||
@SuppressWarnings({"deprecation", "removal", "unused"})
|
||||
public static void snippetControlFlow2(boolean b, int i) {
|
||||
Integer object = new Integer(i);
|
||||
if (b) {
|
||||
@ -165,7 +165,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
||||
test("snippetControlFlow2", true, 1);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"deprecation", "unused"})
|
||||
@SuppressWarnings({"deprecation", "removal", "unused"})
|
||||
public static void snippetControlFlow3(boolean b, int i) {
|
||||
Integer object = new Integer(i);
|
||||
GraalDirectives.ensureVirtualized(object);
|
||||
@ -183,7 +183,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
||||
test("snippetControlFlow3", true, 1);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"deprecation", "unused"})
|
||||
@SuppressWarnings({"deprecation", "removal", "unused"})
|
||||
public static void snippetControlFlow4(boolean b, int i) {
|
||||
Integer object = new Integer(i);
|
||||
if (b) {
|
||||
@ -199,7 +199,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
||||
test("snippetControlFlow4", true, 1);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"deprecation", "unused"})
|
||||
@SuppressWarnings({"deprecation", "removal", "unused"})
|
||||
public static void snippetControlFlow5(boolean b, int i) {
|
||||
Integer object = new Integer(i);
|
||||
if (b) {
|
||||
@ -220,7 +220,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
||||
Object b;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"deprecation", "unused"})
|
||||
@SuppressWarnings({"deprecation", "removal", "unused"})
|
||||
public static void snippetIndirect1(boolean b, int i) {
|
||||
Integer object = new Integer(i);
|
||||
TestClass t = new TestClass();
|
||||
@ -239,7 +239,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
||||
test("snippetIndirect1", true, 1);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"deprecation", "unused"})
|
||||
@SuppressWarnings({"deprecation", "removal", "unused"})
|
||||
public static void snippetIndirect2(boolean b, int i) {
|
||||
Integer object = new Integer(i);
|
||||
TestClass t = new TestClass();
|
||||
|
@ -115,7 +115,7 @@ public class PartialEscapeAnalysisTest extends EATestBase {
|
||||
testPartialEscapeAnalysis("test3Snippet", 0.5, 1, StoreFieldNode.class, LoadFieldNode.class);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@SuppressWarnings({"deprecation", "removal"})
|
||||
public static Object test3Snippet(int a) {
|
||||
if (a < 0) {
|
||||
TestObject obj = new TestObject(1, 2);
|
||||
|
@ -114,7 +114,7 @@ public class StaticAnalysisTests {
|
||||
assertEquals(m(sa, B.class, "foo").getFormalReturn(), t(Data.class));
|
||||
}
|
||||
|
||||
@SuppressWarnings({"deprecation", "unused"})
|
||||
@SuppressWarnings({"deprecation", "removal", "unused"})
|
||||
static void test03Entry() {
|
||||
Data data = new Data();
|
||||
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));
|
||||
}
|
||||
|
||||
@SuppressWarnings({"deprecation", "unused"})
|
||||
@SuppressWarnings({"deprecation", "removal", "unused"})
|
||||
static void test04Entry() {
|
||||
Data data = null;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
|
@ -373,7 +373,7 @@ public class GraalHotSpotVMConfigAccess {
|
||||
/**
|
||||
* @see HotSpotVMConfigAccess#getFlag(String, Class, Object)
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@SuppressWarnings({"deprecation", "removal"})
|
||||
public <T> T getFlag(String name, Class<T> type, T notPresent, boolean expectPresent) {
|
||||
if (expectPresent) {
|
||||
return getFlag(name, type);
|
||||
|
@ -32,7 +32,7 @@ import org.graalvm.compiler.jtt.JTTTest;
|
||||
*/
|
||||
public class HP_allocate02 extends JTTTest {
|
||||
|
||||
@SuppressWarnings({"deprecation", "unused"})
|
||||
@SuppressWarnings({"deprecation", "removal", "unused"})
|
||||
public static int test(int count) {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
|
@ -212,6 +212,7 @@ public class MonitorTest extends GraalCompilerTest {
|
||||
return new String(dst);
|
||||
}
|
||||
|
||||
@SuppressWarnings("synchronization")
|
||||
public static String lockBoxedLong(long value) {
|
||||
Long lock = value;
|
||||
synchronized (lock) {
|
||||
|
@ -91,7 +91,7 @@
|
||||
<setting name="threshold" control="synchronization-threshold">20 ms</setting>
|
||||
</event>
|
||||
|
||||
<event name="jdk.SyncOnPrimitiveWrapper">
|
||||
<event name="jdk.SyncOnValueBasedClass">
|
||||
<setting name="enabled">true</setting>
|
||||
<setting name="stackTrace">true</setting>
|
||||
</event>
|
||||
|
@ -91,7 +91,7 @@
|
||||
<setting name="threshold" control="synchronization-threshold">10 ms</setting>
|
||||
</event>
|
||||
|
||||
<event name="jdk.SyncOnPrimitiveWrapper">
|
||||
<event name="jdk.SyncOnValueBasedClass">
|
||||
<setting name="enabled">true</setting>
|
||||
<setting name="stackTrace">true</setting>
|
||||
</event>
|
||||
|
@ -29,12 +29,12 @@ import java.util.stream.*;
|
||||
/*
|
||||
* @test
|
||||
* @bug 8242263
|
||||
* @summary Exercise DiagnoseSyncOnPrimitiveWrappers diagnostic flag
|
||||
* @summary Exercise DiagnoseSyncOnValueBasedClasses diagnostic flag
|
||||
* @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 THREAD_COUNT = 2;
|
||||
static String[] fatalTests[];
|
||||
@ -64,20 +64,20 @@ public class SyncOnPrimitiveWrapperTest {
|
||||
|
||||
private static void generateTests() {
|
||||
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()][];
|
||||
for (int i = 0; i < specificFlags.length; i++) {
|
||||
for (int j = 0; j < 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)
|
||||
.toArray(String[]::new);
|
||||
}
|
||||
}
|
||||
String[] commonLogTestsFlags = {"-XX:+UnlockDiagnosticVMOptions", "-XX:DiagnoseSyncOnPrimitiveWrappers=2"};
|
||||
String[] commonLogTestsFlags = {"-XX:+UnlockDiagnosticVMOptions", "-XX:DiagnoseSyncOnValueBasedClasses=2"};
|
||||
logTests = new String[specificFlags.length][];
|
||||
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)
|
||||
.toArray(String[]::new);
|
||||
}
|
||||
@ -89,7 +89,7 @@ public class SyncOnPrimitiveWrapperTest {
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(fatalTests[i]);
|
||||
OutputAnalyzer output = ProcessTools.executeProcess(pb);
|
||||
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);
|
||||
}
|
||||
for (int i = 0; i < logTests.length; i++) {
|
||||
@ -127,7 +127,7 @@ public class SyncOnPrimitiveWrapperTest {
|
||||
public static void main(String[] args) throws Exception {
|
||||
initTestObjects();
|
||||
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
Loading…
Reference in New Issue
Block a user