8272723: Don't use Access API to access primitive fields

Reviewed-by: stefank, eosterlund
This commit is contained in:
Roman Kennke 2021-10-11 10:37:54 +00:00
parent 49f8ce6e9c
commit 3edee1e1fe
9 changed files with 106 additions and 194 deletions

View file

@ -4220,8 +4220,8 @@ void java_lang_invoke_MethodHandleNatives_CallSiteContext::serialize_offsets(Ser
DependencyContext java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(oop call_site) { DependencyContext java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(oop call_site) {
assert(java_lang_invoke_MethodHandleNatives_CallSiteContext::is_instance(call_site), ""); assert(java_lang_invoke_MethodHandleNatives_CallSiteContext::is_instance(call_site), "");
nmethodBucket* volatile* vmdeps_addr = (nmethodBucket* volatile*)call_site->field_addr(_vmdependencies_offset); nmethodBucket* volatile* vmdeps_addr = call_site->field_addr<nmethodBucket* volatile>(_vmdependencies_offset);
volatile uint64_t* last_cleanup_addr = (volatile uint64_t*)call_site->field_addr(_last_cleanup_offset); volatile uint64_t* last_cleanup_addr = call_site->field_addr<volatile uint64_t>(_last_cleanup_offset);
DependencyContext dep_ctx(vmdeps_addr, last_cleanup_addr); DependencyContext dep_ctx(vmdeps_addr, last_cleanup_addr);
return dep_ctx; return dep_ctx;
} }
@ -4279,19 +4279,19 @@ int java_lang_ClassLoader::_parent_offset;
ClassLoaderData* java_lang_ClassLoader::loader_data_acquire(oop loader) { ClassLoaderData* java_lang_ClassLoader::loader_data_acquire(oop loader) {
assert(loader != NULL, "loader must not be NULL"); assert(loader != NULL, "loader must not be NULL");
assert(oopDesc::is_oop(loader), "loader must be oop"); assert(oopDesc::is_oop(loader), "loader must be oop");
return HeapAccess<MO_ACQUIRE>::load_at(loader, _loader_data_offset); return Atomic::load_acquire(loader->field_addr<ClassLoaderData*>(_loader_data_offset));
} }
ClassLoaderData* java_lang_ClassLoader::loader_data(oop loader) { ClassLoaderData* java_lang_ClassLoader::loader_data(oop loader) {
assert(loader != NULL, "loader must not be NULL"); assert(loader != NULL, "loader must not be NULL");
assert(oopDesc::is_oop(loader), "loader must be oop"); assert(oopDesc::is_oop(loader), "loader must be oop");
return HeapAccess<>::load_at(loader, _loader_data_offset); return *loader->field_addr<ClassLoaderData*>(_loader_data_offset);
} }
void java_lang_ClassLoader::release_set_loader_data(oop loader, ClassLoaderData* new_data) { void java_lang_ClassLoader::release_set_loader_data(oop loader, ClassLoaderData* new_data) {
assert(loader != NULL, "loader must not be NULL"); assert(loader != NULL, "loader must not be NULL");
assert(oopDesc::is_oop(loader), "loader must be oop"); assert(oopDesc::is_oop(loader), "loader must be oop");
HeapAccess<MO_RELEASE>::store_at(loader, _loader_data_offset, new_data); Atomic::release_store(loader->field_addr<ClassLoaderData*>(_loader_data_offset), new_data);
} }
#define CLASSLOADER_FIELDS_DO(macro) \ #define CLASSLOADER_FIELDS_DO(macro) \

View file

@ -77,7 +77,7 @@ bool java_lang_String::is_latin1(oop java_string) {
uint8_t* java_lang_String::flags_addr(oop java_string) { uint8_t* java_lang_String::flags_addr(oop java_string) {
assert(_initialized, "Must be initialized"); assert(_initialized, "Must be initialized");
assert(is_instance(java_string), "Must be java string"); assert(is_instance(java_string), "Must be java string");
return java_string->obj_field_addr<uint8_t>(_flags_offset); return java_string->field_addr<uint8_t>(_flags_offset);
} }
bool java_lang_String::is_flag_set(oop java_string, uint8_t flag_mask) { bool java_lang_String::is_flag_set(oop java_string, uint8_t flag_mask) {
@ -146,7 +146,7 @@ void java_lang_ref_Reference::clear_referent(oop ref) {
} }
HeapWord* java_lang_ref_Reference::referent_addr_raw(oop ref) { HeapWord* java_lang_ref_Reference::referent_addr_raw(oop ref) {
return ref->obj_field_addr<HeapWord>(_referent_offset); return ref->field_addr<HeapWord>(_referent_offset);
} }
oop java_lang_ref_Reference::next(oop ref) { oop java_lang_ref_Reference::next(oop ref) {
@ -162,7 +162,7 @@ void java_lang_ref_Reference::set_next_raw(oop ref, oop value) {
} }
HeapWord* java_lang_ref_Reference::next_addr_raw(oop ref) { HeapWord* java_lang_ref_Reference::next_addr_raw(oop ref) {
return ref->obj_field_addr<HeapWord>(_next_offset); return ref->field_addr<HeapWord>(_next_offset);
} }
oop java_lang_ref_Reference::discovered(oop ref) { oop java_lang_ref_Reference::discovered(oop ref) {
@ -178,7 +178,7 @@ void java_lang_ref_Reference::set_discovered_raw(oop ref, oop value) {
} }
HeapWord* java_lang_ref_Reference::discovered_addr_raw(oop ref) { HeapWord* java_lang_ref_Reference::discovered_addr_raw(oop ref) {
return ref->obj_field_addr<HeapWord>(_discovered_offset); return ref->field_addr<HeapWord>(_discovered_offset);
} }
bool java_lang_ref_Reference::is_final(oop ref) { bool java_lang_ref_Reference::is_final(oop ref) {

View file

@ -231,13 +231,13 @@ void HotSpotJVMCI::compute_offsets(TRAPS) {
assert(className::klass() != NULL && className::klass()->is_linked(), "Class not yet linked: " #className); \ assert(className::klass() != NULL && className::klass()->is_linked(), "Class not yet linked: " #className); \
InstanceKlass* ik = className::klass(); \ InstanceKlass* ik = className::klass(); \
oop base = ik->static_field_base_raw(); \ oop base = ik->static_field_base_raw(); \
return HeapAccess<>::load_at(base, className::_##name##_offset); \ return *base->field_addr<jtypename>(className::_##name##_offset); \
} \ } \
void HotSpotJVMCI::className::set_##name(JVMCIEnv* env, jtypename x) { \ void HotSpotJVMCI::className::set_##name(JVMCIEnv* env, jtypename x) { \
assert(className::klass() != NULL && className::klass()->is_linked(), "Class not yet linked: " #className); \ assert(className::klass() != NULL && className::klass()->is_linked(), "Class not yet linked: " #className); \
InstanceKlass* ik = className::klass(); \ InstanceKlass* ik = className::klass(); \
oop base = ik->static_field_base_raw(); \ oop base = ik->static_field_base_raw(); \
HeapAccess<>::store_at(base, _##name##_offset, x); \ *base->field_addr<jtypename>(className::_##name##_offset) = x; \
} }
#define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint) #define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint)

View file

@ -84,7 +84,7 @@ inline void InstanceKlass::release_set_methods_jmethod_ids(jmethodID* jmeths) {
template <typename T, class OopClosureType> template <typename T, class OopClosureType>
ALWAYSINLINE void InstanceKlass::oop_oop_iterate_oop_map(OopMapBlock* map, oop obj, OopClosureType* closure) { ALWAYSINLINE void InstanceKlass::oop_oop_iterate_oop_map(OopMapBlock* map, oop obj, OopClosureType* closure) {
T* p = (T*)obj->obj_field_addr<T>(map->offset()); T* p = obj->field_addr<T>(map->offset());
T* const end = p + map->count(); T* const end = p + map->count();
for (; p < end; ++p) { for (; p < end; ++p) {
@ -94,7 +94,7 @@ ALWAYSINLINE void InstanceKlass::oop_oop_iterate_oop_map(OopMapBlock* map, oop o
template <typename T, class OopClosureType> template <typename T, class OopClosureType>
ALWAYSINLINE void InstanceKlass::oop_oop_iterate_oop_map_reverse(OopMapBlock* map, oop obj, OopClosureType* closure) { ALWAYSINLINE void InstanceKlass::oop_oop_iterate_oop_map_reverse(OopMapBlock* map, oop obj, OopClosureType* closure) {
T* const start = (T*)obj->obj_field_addr<T>(map->offset()); T* const start = obj->field_addr<T>(map->offset());
T* p = start + map->count(); T* p = start + map->count();
while (start < p) { while (start < p) {
@ -105,7 +105,7 @@ ALWAYSINLINE void InstanceKlass::oop_oop_iterate_oop_map_reverse(OopMapBlock* ma
template <typename T, class OopClosureType> template <typename T, class OopClosureType>
ALWAYSINLINE void InstanceKlass::oop_oop_iterate_oop_map_bounded(OopMapBlock* map, oop obj, OopClosureType* closure, MemRegion mr) { ALWAYSINLINE void InstanceKlass::oop_oop_iterate_oop_map_bounded(OopMapBlock* map, oop obj, OopClosureType* closure, MemRegion mr) {
T* p = (T*)obj->obj_field_addr<T>(map->offset()); T* p = obj->field_addr<T>(map->offset());
T* end = p + map->count(); T* end = p + map->count();
T* const l = (T*)mr.start(); T* const l = (T*)mr.start();

View file

@ -179,41 +179,41 @@ void oopDesc::obj_field_put_raw(int offset, oop value) { RawAcces
void oopDesc::release_obj_field_put(int offset, oop value) { HeapAccess<MO_RELEASE>::oop_store_at(as_oop(), offset, value); } void oopDesc::release_obj_field_put(int offset, oop value) { HeapAccess<MO_RELEASE>::oop_store_at(as_oop(), offset, value); }
void oopDesc::obj_field_put_volatile(int offset, oop value) { HeapAccess<MO_SEQ_CST>::oop_store_at(as_oop(), offset, value); } void oopDesc::obj_field_put_volatile(int offset, oop value) { HeapAccess<MO_SEQ_CST>::oop_store_at(as_oop(), offset, value); }
address oopDesc::address_field(int offset) const { return HeapAccess<>::load_at(as_oop(), offset); } address oopDesc::address_field(int offset) const { return *field_addr<address>(offset); }
address oopDesc::address_field_acquire(int offset) const { return HeapAccess<MO_ACQUIRE>::load_at(as_oop(), offset); } address oopDesc::address_field_acquire(int offset) const { return Atomic::load_acquire(field_addr<address>(offset)); }
void oopDesc::address_field_put(int offset, address value) { HeapAccess<>::store_at(as_oop(), offset, value); } void oopDesc::address_field_put(int offset, address value) { *field_addr<address>(offset) = value; }
void oopDesc::release_address_field_put(int offset, address value) { HeapAccess<MO_RELEASE>::store_at(as_oop(), offset, value); } void oopDesc::release_address_field_put(int offset, address value) { Atomic::release_store(field_addr<address>(offset), value); }
Metadata* oopDesc::metadata_field(int offset) const { return HeapAccess<>::load_at(as_oop(), offset); } Metadata* oopDesc::metadata_field(int offset) const { return *field_addr<Metadata*>(offset); }
void oopDesc::metadata_field_put(int offset, Metadata* value) { HeapAccess<>::store_at(as_oop(), offset, value); } void oopDesc::metadata_field_put(int offset, Metadata* value) { *field_addr<Metadata*>(offset) = value; }
Metadata* oopDesc::metadata_field_acquire(int offset) const { return HeapAccess<MO_ACQUIRE>::load_at(as_oop(), offset); } Metadata* oopDesc::metadata_field_acquire(int offset) const { return Atomic::load_acquire(field_addr<Metadata*>(offset)); }
void oopDesc::release_metadata_field_put(int offset, Metadata* value) { HeapAccess<MO_RELEASE>::store_at(as_oop(), offset, value); } void oopDesc::release_metadata_field_put(int offset, Metadata* value) { Atomic::release_store(field_addr<Metadata*>(offset), value); }
jbyte oopDesc::byte_field_acquire(int offset) const { return HeapAccess<MO_ACQUIRE>::load_at(as_oop(), offset); } jbyte oopDesc::byte_field_acquire(int offset) const { return Atomic::load_acquire(field_addr<jbyte>(offset)); }
void oopDesc::release_byte_field_put(int offset, jbyte value) { HeapAccess<MO_RELEASE>::store_at(as_oop(), offset, value); } void oopDesc::release_byte_field_put(int offset, jbyte value) { Atomic::release_store(field_addr<jbyte>(offset), value); }
jchar oopDesc::char_field_acquire(int offset) const { return HeapAccess<MO_ACQUIRE>::load_at(as_oop(), offset); } jchar oopDesc::char_field_acquire(int offset) const { return Atomic::load_acquire(field_addr<jchar>(offset)); }
void oopDesc::release_char_field_put(int offset, jchar value) { HeapAccess<MO_RELEASE>::store_at(as_oop(), offset, value); } void oopDesc::release_char_field_put(int offset, jchar value) { Atomic::release_store(field_addr<jchar>(offset), value); }
jboolean oopDesc::bool_field_acquire(int offset) const { return HeapAccess<MO_ACQUIRE>::load_at(as_oop(), offset); } jboolean oopDesc::bool_field_acquire(int offset) const { return Atomic::load_acquire(field_addr<jboolean>(offset)); }
void oopDesc::release_bool_field_put(int offset, jboolean value) { HeapAccess<MO_RELEASE>::store_at(as_oop(), offset, jboolean(value & 1)); } void oopDesc::release_bool_field_put(int offset, jboolean value) { Atomic::release_store(field_addr<jboolean>(offset), jboolean(value & 1)); }
jint oopDesc::int_field_acquire(int offset) const { return HeapAccess<MO_ACQUIRE>::load_at(as_oop(), offset); } jint oopDesc::int_field_acquire(int offset) const { return Atomic::load_acquire(field_addr<jint>(offset)); }
void oopDesc::release_int_field_put(int offset, jint value) { HeapAccess<MO_RELEASE>::store_at(as_oop(), offset, value); } void oopDesc::release_int_field_put(int offset, jint value) { Atomic::release_store(field_addr<jint>(offset), value); }
jshort oopDesc::short_field_acquire(int offset) const { return HeapAccess<MO_ACQUIRE>::load_at(as_oop(), offset); } jshort oopDesc::short_field_acquire(int offset) const { return Atomic::load_acquire(field_addr<jshort>(offset)); }
void oopDesc::release_short_field_put(int offset, jshort value) { HeapAccess<MO_RELEASE>::store_at(as_oop(), offset, value); } void oopDesc::release_short_field_put(int offset, jshort value) { Atomic::release_store(field_addr<jshort>(offset), value); }
jlong oopDesc::long_field_acquire(int offset) const { return HeapAccess<MO_ACQUIRE>::load_at(as_oop(), offset); } jlong oopDesc::long_field_acquire(int offset) const { return Atomic::load_acquire(field_addr<jlong>(offset)); }
void oopDesc::release_long_field_put(int offset, jlong value) { HeapAccess<MO_RELEASE>::store_at(as_oop(), offset, value); } void oopDesc::release_long_field_put(int offset, jlong value) { Atomic::release_store(field_addr<jlong>(offset), value); }
jfloat oopDesc::float_field_acquire(int offset) const { return HeapAccess<MO_ACQUIRE>::load_at(as_oop(), offset); } jfloat oopDesc::float_field_acquire(int offset) const { return Atomic::load_acquire(field_addr<jfloat>(offset)); }
void oopDesc::release_float_field_put(int offset, jfloat value) { HeapAccess<MO_RELEASE>::store_at(as_oop(), offset, value); } void oopDesc::release_float_field_put(int offset, jfloat value) { Atomic::release_store(field_addr<jfloat>(offset), value); }
jdouble oopDesc::double_field_acquire(int offset) const { return HeapAccess<MO_ACQUIRE>::load_at(as_oop(), offset); } jdouble oopDesc::double_field_acquire(int offset) const { return Atomic::load_acquire(field_addr<jdouble>(offset)); }
void oopDesc::release_double_field_put(int offset, jdouble value) { HeapAccess<MO_RELEASE>::store_at(as_oop(), offset, value); } void oopDesc::release_double_field_put(int offset, jdouble value) { Atomic::release_store(field_addr<jdouble>(offset), value); }
#ifdef ASSERT #ifdef ASSERT
void oopDesc::verify_forwardee(oop forwardee) { void oopDesc::verify_forwardee(oop forwardee) {

View file

@ -124,11 +124,8 @@ class oopDesc {
inline oop as_oop() const { return const_cast<oopDesc*>(this); } inline oop as_oop() const { return const_cast<oopDesc*>(this); }
public: public:
// field addresses in oop template<typename T>
inline void* field_addr(int offset) const; inline T* field_addr(int offset) const;
// Need this as public for garbage collection.
template <class T> inline T* obj_field_addr(int offset) const;
template <typename T> inline size_t field_offset(T* p) const; template <typename T> inline size_t field_offset(T* p) const;

View file

@ -208,10 +208,8 @@ bool oopDesc::is_array() const { return klass()->is_array_klass(); }
bool oopDesc::is_objArray() const { return klass()->is_objArray_klass(); } bool oopDesc::is_objArray() const { return klass()->is_objArray_klass(); }
bool oopDesc::is_typeArray() const { return klass()->is_typeArray_klass(); } bool oopDesc::is_typeArray() const { return klass()->is_typeArray_klass(); }
void* oopDesc::field_addr(int offset) const { return reinterpret_cast<void*>(cast_from_oop<intptr_t>(as_oop()) + offset); } template<typename T>
T* oopDesc::field_addr(int offset) const { return reinterpret_cast<T*>(cast_from_oop<intptr_t>(as_oop()) + offset); }
template <class T>
T* oopDesc::obj_field_addr(int offset) const { return (T*) field_addr(offset); }
template <typename T> template <typename T>
size_t oopDesc::field_offset(T* p) const { return pointer_delta((void*)p, (void*)this, 1); } size_t oopDesc::field_offset(T* p) const { return pointer_delta((void*)p, (void*)this, 1); }
@ -222,30 +220,30 @@ inline oop oopDesc::obj_field(int offset) const { return Hea
inline void oopDesc::obj_field_put(int offset, oop value) { HeapAccess<>::oop_store_at(as_oop(), offset, value); } inline void oopDesc::obj_field_put(int offset, oop value) { HeapAccess<>::oop_store_at(as_oop(), offset, value); }
inline jbyte oopDesc::byte_field(int offset) const { return HeapAccess<>::load_at(as_oop(), offset); } inline jbyte oopDesc::byte_field(int offset) const { return *field_addr<jbyte>(offset); }
inline void oopDesc::byte_field_put(int offset, jbyte value) { HeapAccess<>::store_at(as_oop(), offset, value); } inline void oopDesc::byte_field_put(int offset, jbyte value) { *field_addr<jbyte>(offset) = value; }
inline jchar oopDesc::char_field(int offset) const { return HeapAccess<>::load_at(as_oop(), offset); } inline jchar oopDesc::char_field(int offset) const { return *field_addr<jchar>(offset); }
inline void oopDesc::char_field_put(int offset, jchar value) { HeapAccess<>::store_at(as_oop(), offset, value); } inline void oopDesc::char_field_put(int offset, jchar value) { *field_addr<jchar>(offset) = value; }
inline jboolean oopDesc::bool_field(int offset) const { return HeapAccess<>::load_at(as_oop(), offset); } inline jboolean oopDesc::bool_field(int offset) const { return *field_addr<jboolean>(offset); }
inline void oopDesc::bool_field_put(int offset, jboolean value) { HeapAccess<>::store_at(as_oop(), offset, jboolean(value & 1)); } inline void oopDesc::bool_field_put(int offset, jboolean value) { *field_addr<jboolean>(offset) = jboolean(value & 1); }
inline jboolean oopDesc::bool_field_volatile(int offset) const { return HeapAccess<MO_SEQ_CST>::load_at(as_oop(), offset); } inline jboolean oopDesc::bool_field_volatile(int offset) const { return RawAccess<MO_SEQ_CST>::load(field_addr<jboolean>(offset)); }
inline void oopDesc::bool_field_put_volatile(int offset, jboolean value) { HeapAccess<MO_SEQ_CST>::store_at(as_oop(), offset, jboolean(value & 1)); } inline void oopDesc::bool_field_put_volatile(int offset, jboolean value) { RawAccess<MO_SEQ_CST>::store(field_addr<jboolean>(offset), jboolean(value & 1)); }
inline jshort oopDesc::short_field(int offset) const { return HeapAccess<>::load_at(as_oop(), offset); } inline jshort oopDesc::short_field(int offset) const { return *field_addr<jshort>(offset); }
inline void oopDesc::short_field_put(int offset, jshort value) { HeapAccess<>::store_at(as_oop(), offset, value); } inline void oopDesc::short_field_put(int offset, jshort value) { *field_addr<jshort>(offset) = value; }
inline jint oopDesc::int_field(int offset) const { return HeapAccess<>::load_at(as_oop(), offset); } inline jint oopDesc::int_field(int offset) const { return *field_addr<jint>(offset); }
inline void oopDesc::int_field_put(int offset, jint value) { HeapAccess<>::store_at(as_oop(), offset, value); } inline void oopDesc::int_field_put(int offset, jint value) { *field_addr<jint>(offset) = value; }
inline jlong oopDesc::long_field(int offset) const { return HeapAccess<>::load_at(as_oop(), offset); } inline jlong oopDesc::long_field(int offset) const { return *field_addr<jlong>(offset); }
inline void oopDesc::long_field_put(int offset, jlong value) { HeapAccess<>::store_at(as_oop(), offset, value); } inline void oopDesc::long_field_put(int offset, jlong value) { *field_addr<jlong>(offset) = value; }
inline jfloat oopDesc::float_field(int offset) const { return HeapAccess<>::load_at(as_oop(), offset); } inline jfloat oopDesc::float_field(int offset) const { return *field_addr<jfloat>(offset); }
inline void oopDesc::float_field_put(int offset, jfloat value) { HeapAccess<>::store_at(as_oop(), offset, value); } inline void oopDesc::float_field_put(int offset, jfloat value) { *field_addr<jfloat>(offset) = value; }
inline jdouble oopDesc::double_field(int offset) const { return HeapAccess<>::load_at(as_oop(), offset); } inline jdouble oopDesc::double_field(int offset) const { return *field_addr<jdouble>(offset); }
inline void oopDesc::double_field_put(int offset, jdouble value) { HeapAccess<>::store_at(as_oop(), offset, value); } inline void oopDesc::double_field_put(int offset, jdouble value) { *field_addr<jdouble>(offset) = value; }
bool oopDesc::is_locked() const { bool oopDesc::is_locked() const {
return mark().is_locked(); return mark().is_locked();

View file

@ -90,113 +90,76 @@ inline jdouble* typeArrayOopDesc::double_at_addr(int which) const {
} }
inline jbyte typeArrayOopDesc::byte_at(int which) const { inline jbyte typeArrayOopDesc::byte_at(int which) const {
assert(is_within_bounds(which), "index %d out of bounds %d", which, length()); return *byte_at_addr(which);
ptrdiff_t offset = element_offset<jbyte>(which);
return HeapAccess<IS_ARRAY>::load_at(as_oop(), offset);
} }
inline void typeArrayOopDesc::byte_at_put(int which, jbyte contents) { inline void typeArrayOopDesc::byte_at_put(int which, jbyte contents) {
assert(is_within_bounds(which), "index %d out of bounds %d", which, length()); *byte_at_addr(which) = contents;
ptrdiff_t offset = element_offset<jbyte>(which);
HeapAccess<IS_ARRAY>::store_at(as_oop(), offset, contents);
} }
inline jboolean typeArrayOopDesc::bool_at(int which) const { inline jboolean typeArrayOopDesc::bool_at(int which) const {
assert(is_within_bounds(which), "index %d out of bounds %d", which, length()); return *bool_at_addr(which);
ptrdiff_t offset = element_offset<jboolean>(which);
return HeapAccess<IS_ARRAY>::load_at(as_oop(), offset);
} }
inline void typeArrayOopDesc::bool_at_put(int which, jboolean contents) { inline void typeArrayOopDesc::bool_at_put(int which, jboolean contents) {
assert(is_within_bounds(which), "index %d out of bounds %d", which, length()); *bool_at_addr(which) = jboolean(contents & 1);
ptrdiff_t offset = element_offset<jboolean>(which);
HeapAccess<IS_ARRAY>::store_at(as_oop(), offset, jboolean(contents & 1));
} }
inline jchar typeArrayOopDesc::char_at(int which) const { inline jchar typeArrayOopDesc::char_at(int which) const {
assert(is_within_bounds(which), "index %d out of bounds %d", which, length()); return *char_at_addr(which);
ptrdiff_t offset = element_offset<jchar>(which);
return HeapAccess<IS_ARRAY>::load_at(as_oop(), offset);
} }
inline void typeArrayOopDesc::char_at_put(int which, jchar contents) { inline void typeArrayOopDesc::char_at_put(int which, jchar contents) {
assert(is_within_bounds(which), "index %d out of bounds %d", which, length()); *char_at_addr(which) = contents;
ptrdiff_t offset = element_offset<jchar>(which);
HeapAccess<IS_ARRAY>::store_at(as_oop(), offset, contents);
} }
inline jint typeArrayOopDesc::int_at(int which) const { inline jint typeArrayOopDesc::int_at(int which) const {
assert(is_within_bounds(which), "index %d out of bounds %d", which, length()); return *int_at_addr(which);
ptrdiff_t offset = element_offset<jint>(which);
return HeapAccess<IS_ARRAY>::load_at(as_oop(), offset);
} }
inline void typeArrayOopDesc::int_at_put(int which, jint contents) { inline void typeArrayOopDesc::int_at_put(int which, jint contents) {
assert(is_within_bounds(which), "index %d out of bounds %d", which, length()); *int_at_addr(which) = contents;
ptrdiff_t offset = element_offset<jint>(which);
HeapAccess<IS_ARRAY>::store_at(as_oop(), offset, contents);
} }
inline jshort typeArrayOopDesc::short_at(int which) const { inline jshort typeArrayOopDesc::short_at(int which) const {
assert(is_within_bounds(which), "index %d out of bounds %d", which, length()); return *short_at_addr(which);
ptrdiff_t offset = element_offset<jshort>(which);
return HeapAccess<IS_ARRAY>::load_at(as_oop(), offset);
} }
inline void typeArrayOopDesc::short_at_put(int which, jshort contents) { inline void typeArrayOopDesc::short_at_put(int which, jshort contents) {
assert(is_within_bounds(which), "index %d out of bounds %d", which, length()); *short_at_addr(which) = contents;
ptrdiff_t offset = element_offset<jshort>(which);
HeapAccess<IS_ARRAY>::store_at(as_oop(), offset, contents);
} }
inline jushort typeArrayOopDesc::ushort_at(int which) const { inline jushort typeArrayOopDesc::ushort_at(int which) const {
assert(is_within_bounds(which), "index %d out of bounds %d", which, length()); return *ushort_at_addr(which);
ptrdiff_t offset = element_offset<jushort>(which);
return HeapAccess<IS_ARRAY>::load_at(as_oop(), offset);
} }
inline void typeArrayOopDesc::ushort_at_put(int which, jushort contents) { inline void typeArrayOopDesc::ushort_at_put(int which, jushort contents) {
assert(is_within_bounds(which), "index %d out of bounds %d", which, length()); *ushort_at_addr(which) = contents;
ptrdiff_t offset = element_offset<jushort>(which);
HeapAccess<IS_ARRAY>::store_at(as_oop(), offset, contents);
} }
inline jlong typeArrayOopDesc::long_at(int which) const { inline jlong typeArrayOopDesc::long_at(int which) const {
assert(is_within_bounds(which), "index %d out of bounds %d", which, length()); return *long_at_addr(which);
ptrdiff_t offset = element_offset<jlong>(which);
return HeapAccess<IS_ARRAY>::load_at(as_oop(), offset);
} }
inline void typeArrayOopDesc::long_at_put(int which, jlong contents) { inline void typeArrayOopDesc::long_at_put(int which, jlong contents) {
assert(is_within_bounds(which), "index %d out of bounds %d", which, length()); *long_at_addr(which) = contents;
ptrdiff_t offset = element_offset<jlong>(which);
HeapAccess<IS_ARRAY>::store_at(as_oop(), offset, contents);
} }
inline jfloat typeArrayOopDesc::float_at(int which) const { inline jfloat typeArrayOopDesc::float_at(int which) const {
assert(is_within_bounds(which), "index %d out of bounds %d", which, length()); return *float_at_addr(which);
ptrdiff_t offset = element_offset<jfloat>(which);
return HeapAccess<IS_ARRAY>::load_at(as_oop(), offset);
} }
inline void typeArrayOopDesc::float_at_put(int which, jfloat contents) { inline void typeArrayOopDesc::float_at_put(int which, jfloat contents) {
assert(is_within_bounds(which), "index %d out of bounds %d", which, length()); *float_at_addr(which) = contents;
ptrdiff_t offset = element_offset<jfloat>(which);
HeapAccess<IS_ARRAY>::store_at(as_oop(), offset, contents);
} }
inline jdouble typeArrayOopDesc::double_at(int which) const { inline jdouble typeArrayOopDesc::double_at(int which) const {
assert(is_within_bounds(which), "index %d out of bounds %d", which, length()); return *double_at_addr(which);
ptrdiff_t offset = element_offset<jdouble>(which);
return HeapAccess<IS_ARRAY>::load_at(as_oop(), offset);
} }
inline void typeArrayOopDesc::double_at_put(int which, jdouble contents) { inline void typeArrayOopDesc::double_at_put(int which, jdouble contents) {
assert(is_within_bounds(which), "index %d out of bounds %d", which, length()); *double_at_addr(which) = contents;
ptrdiff_t offset = element_offset<jdouble>(which);
HeapAccess<IS_ARRAY>::store_at(as_oop(), offset, contents);
} }
inline jbyte typeArrayOopDesc::byte_at_acquire(int which) const { inline jbyte typeArrayOopDesc::byte_at_acquire(int which) const {
assert(is_within_bounds(which), "index %d out of bounds %d", which, length()); return Atomic::load_acquire(byte_at_addr(which));
ptrdiff_t offset = element_offset<jbyte>(which);
return HeapAccess<MO_ACQUIRE | IS_ARRAY>::load_at(as_oop(), offset);
} }
inline void typeArrayOopDesc::release_byte_at_put(int which, jbyte contents) { inline void typeArrayOopDesc::release_byte_at_put(int which, jbyte contents) {
assert(is_within_bounds(which), "index %d out of bounds %d", which, length()); Atomic::release_store(byte_at_addr(which), contents);
ptrdiff_t offset = element_offset<jbyte>(which);
HeapAccess<MO_RELEASE | IS_ARRAY>::store_at(as_oop(), offset, contents);
} }
// Java thinks Symbol arrays are just arrays of either long or int, since // Java thinks Symbol arrays are just arrays of either long or int, since
@ -204,25 +167,18 @@ inline void typeArrayOopDesc::release_byte_at_put(int which, jbyte contents) {
// casting // casting
#ifdef _LP64 #ifdef _LP64
inline Symbol* typeArrayOopDesc::symbol_at(int which) const { inline Symbol* typeArrayOopDesc::symbol_at(int which) const {
assert(is_within_bounds(which), "index %d out of bounds %d", which, length()); return *reinterpret_cast<Symbol**>(long_at_addr(which));
ptrdiff_t offset = element_offset<jlong>(which);
return (Symbol*)(jlong) HeapAccess<IS_ARRAY>::load_at(as_oop(), offset);
} }
inline void typeArrayOopDesc::symbol_at_put(int which, Symbol* contents) { inline void typeArrayOopDesc::symbol_at_put(int which, Symbol* contents) {
assert(is_within_bounds(which), "index %d out of bounds %d", which, length()); *reinterpret_cast<Symbol**>(long_at_addr(which)) = contents;
ptrdiff_t offset = element_offset<jlong>(which);
HeapAccess<IS_ARRAY>::store_at(as_oop(), offset, (jlong)contents);
} }
#else #else
inline Symbol* typeArrayOopDesc::symbol_at(int which) const { inline Symbol* typeArrayOopDesc::symbol_at(int which) const {
assert(is_within_bounds(which), "index %d out of bounds %d", which, length()); return *reinterpret_cast<Symbol**>(int_at_addr(which));
ptrdiff_t offset = element_offset<jint>(which);
return (Symbol*)(jint) HeapAccess<IS_ARRAY>::load_at(as_oop(), offset);
} }
inline void typeArrayOopDesc::symbol_at_put(int which, Symbol* contents) { inline void typeArrayOopDesc::symbol_at_put(int which, Symbol* contents) {
assert(is_within_bounds(which), "index %d out of bounds %d", which, length()); *reinterpret_cast<Symbol**>(int_at_addr(which)) = contents;
ptrdiff_t offset = element_offset<jint>(which);
HeapAccess<IS_ARRAY>::store_at(as_oop(), offset, (jint)contents);
} }
#endif // _LP64 #endif // _LP64

View file

@ -119,7 +119,7 @@ static inline void assert_field_offset_sane(oop p, jlong field_offset) {
assert(byte_offset >= 0 && byte_offset <= (jlong)MAX_OBJECT_SIZE, "sane offset"); assert(byte_offset >= 0 && byte_offset <= (jlong)MAX_OBJECT_SIZE, "sane offset");
if (byte_offset == (jint)byte_offset) { if (byte_offset == (jint)byte_offset) {
void* ptr_plus_disp = cast_from_oop<address>(p) + byte_offset; void* ptr_plus_disp = cast_from_oop<address>(p) + byte_offset;
assert(p->field_addr((jint)byte_offset) == ptr_plus_disp, assert(p->field_addr<void>((jint)byte_offset) == ptr_plus_disp,
"raw [ptr+disp] must be consistent with oop::field_addr"); "raw [ptr+disp] must be consistent with oop::field_addr");
} }
jlong p_size = HeapWordSize * (jlong)(p->size()); jlong p_size = HeapWordSize * (jlong)(p->size());
@ -218,44 +218,25 @@ public:
} }
T get() { T get() {
if (_obj == NULL) { GuardUnsafeAccess guard(_thread);
GuardUnsafeAccess guard(_thread); return normalize_for_read(*addr());
T ret = RawAccess<>::load(addr());
return normalize_for_read(ret);
} else {
T ret = HeapAccess<>::load_at(_obj, _offset);
return normalize_for_read(ret);
}
} }
void put(T x) { void put(T x) {
if (_obj == NULL) { GuardUnsafeAccess guard(_thread);
GuardUnsafeAccess guard(_thread); *addr() = normalize_for_write(x);
RawAccess<>::store(addr(), normalize_for_write(x));
} else {
HeapAccess<>::store_at(_obj, _offset, normalize_for_write(x));
}
} }
T get_volatile() { T get_volatile() {
if (_obj == NULL) { GuardUnsafeAccess guard(_thread);
GuardUnsafeAccess guard(_thread); volatile T ret = RawAccess<MO_SEQ_CST>::load(addr());
volatile T ret = RawAccess<MO_SEQ_CST>::load(addr()); return normalize_for_read(ret);
return normalize_for_read(ret);
} else {
T ret = HeapAccess<MO_SEQ_CST>::load_at(_obj, _offset);
return normalize_for_read(ret);
}
} }
void put_volatile(T x) { void put_volatile(T x) {
if (_obj == NULL) { GuardUnsafeAccess guard(_thread);
GuardUnsafeAccess guard(_thread); RawAccess<MO_SEQ_CST>::store(addr(), normalize_for_write(x));
RawAccess<MO_SEQ_CST>::store(addr(), normalize_for_write(x));
} else {
HeapAccess<MO_SEQ_CST>::store_at(_obj, _offset, normalize_for_write(x));
}
} }
}; };
@ -745,24 +726,14 @@ UNSAFE_ENTRY(jobject, Unsafe_CompareAndExchangeReference(JNIEnv *env, jobject un
UNSAFE_ENTRY(jint, Unsafe_CompareAndExchangeInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) { UNSAFE_ENTRY(jint, Unsafe_CompareAndExchangeInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) {
oop p = JNIHandles::resolve(obj); oop p = JNIHandles::resolve(obj);
if (p == NULL) { volatile jint* addr = (volatile jint*)index_oop_from_field_offset_long(p, offset);
volatile jint* addr = (volatile jint*)index_oop_from_field_offset_long(p, offset); return Atomic::cmpxchg(addr, e, x);
return RawAccess<>::atomic_cmpxchg(addr, e, x);
} else {
assert_field_offset_sane(p, offset);
return HeapAccess<>::atomic_cmpxchg_at(p, (ptrdiff_t)offset, e, x);
}
} UNSAFE_END } UNSAFE_END
UNSAFE_ENTRY(jlong, Unsafe_CompareAndExchangeLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x)) { UNSAFE_ENTRY(jlong, Unsafe_CompareAndExchangeLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x)) {
oop p = JNIHandles::resolve(obj); oop p = JNIHandles::resolve(obj);
if (p == NULL) { volatile jlong* addr = (volatile jlong*)index_oop_from_field_offset_long(p, offset);
volatile jlong* addr = (volatile jlong*)index_oop_from_field_offset_long(p, offset); return Atomic::cmpxchg(addr, e, x);
return RawAccess<>::atomic_cmpxchg(addr, e, x);
} else {
assert_field_offset_sane(p, offset);
return HeapAccess<>::atomic_cmpxchg_at(p, (ptrdiff_t)offset, e, x);
}
} UNSAFE_END } UNSAFE_END
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSetReference(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject e_h, jobject x_h)) { UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSetReference(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject e_h, jobject x_h)) {
@ -776,24 +747,14 @@ UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSetReference(JNIEnv *env, jobject unsafe
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSetInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) { UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSetInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) {
oop p = JNIHandles::resolve(obj); oop p = JNIHandles::resolve(obj);
if (p == NULL) { volatile jint* addr = (volatile jint*)index_oop_from_field_offset_long(p, offset);
volatile jint* addr = (volatile jint*)index_oop_from_field_offset_long(p, offset); return Atomic::cmpxchg(addr, e, x) == e;
return RawAccess<>::atomic_cmpxchg(addr, e, x) == e;
} else {
assert_field_offset_sane(p, offset);
return HeapAccess<>::atomic_cmpxchg_at(p, (ptrdiff_t)offset, e, x) == e;
}
} UNSAFE_END } UNSAFE_END
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSetLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x)) { UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSetLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x)) {
oop p = JNIHandles::resolve(obj); oop p = JNIHandles::resolve(obj);
if (p == NULL) { volatile jlong* addr = (volatile jlong*)index_oop_from_field_offset_long(p, offset);
volatile jlong* addr = (volatile jlong*)index_oop_from_field_offset_long(p, offset); return Atomic::cmpxchg(addr, e, x) == e;
return RawAccess<>::atomic_cmpxchg(addr, e, x) == e;
} else {
assert_field_offset_sane(p, offset);
return HeapAccess<>::atomic_cmpxchg_at(p, (ptrdiff_t)offset, e, x) == e;
}
} UNSAFE_END } UNSAFE_END
static void post_thread_park_event(EventThreadPark* event, const oop obj, jlong timeout_nanos, jlong until_epoch_millis) { static void post_thread_park_event(EventThreadPark* event, const oop obj, jlong timeout_nanos, jlong until_epoch_millis) {