RFR: JDK-8199801: Finer grained primitive arrays bulk access barriers (original) (raw)
Roman Kennke rkennke at redhat.com
Tue Mar 20 08:57:42 UTC 2018
- Previous message (by thread): RFR: JDK-8199781: Don't use naked == for comparing oops
- Next message (by thread): RFR: 8199850: Move parsing of VerifyGCType to G1
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Currently, for any bulk access on primitive arrays (e.g. *_at_addr() family of methods, arraycopy, and the like), we do Access::resolve() on the base arrayOop (via arrayOopDesc::base() ). This is safe and does the right thing, but it is overly broad. In a garbage collector like Shenandoah, Access::resolve() would have to do a write-barrier, which is a copy-on-write. This could lead to double-copying of potentially large arrays, i.e. resolving the src array would copy it from from-space to to-space, and then it needs to be copied again from src to dst. This adds unnecessary latency to Java threads. Most of the accesses via _at_addr() are read-accesses, and they could use a weaker read-barrier, which only chases the forwarding pointer.
This change splits Access<>::resolve() into resolve_for_read() and resolve_for_write(). This is then used in all the relevant places. In particular:
typeArrayOop::at_addr() accessors now differentiate between getat_addr() and putat_addr(), with the get accessors returning a const T* to prevent/discourage writing to them. This percolates a little bit through the code base, but in a positive sense (i.e. can use all the utf8 methods with const arrays now).
The part in c1_Runtime1.cpp will have to be rebased/eliminated once Erik's patch goes in.
arrayOopDesc::base_raw() and objArrayOopDesc::base_raw() go away, and (remaining) uses replaced by ::base().
The arraycopy stuff now calls obj_at_addr_raw() instead of obj_at_addr(). The reason for this is that the actual objects are better resolved in HeapAccess<>::arraycopy() methods, and the pointer passed into it must really be within the array that's also passed in, and not in another copy.
objArrayOopDesc::atomic_compare_exchange_oop() now uses oop_atomic_cmpxchg_at() ... the existing version does not allow to resolve the target object. (this is only related in that it eliminates a last remaining use of obj_at_addr()).
oopDesc::field_addr() is only used in one place (DependencyContext) which should be refactored to use proper oopDesc accessors, and then field_addr() can be eliminated too. For now it uses resolve_for_write(), b/c DependencyContext may write to the field.
I noticed a bunch of memcpy() around the _at_addr() calls (e.g. in jni.cpp).. I wonder if they should be replaced by corresponding Copy:: functions instead?
jvmtiTagMap.cpp has an odd one:
// Don't use char_at_addr(0) if length is 0
value = (jchar*) s_value->base(T_CHAR);
- value = s_value->get_char_at_addr(0);
In my mind, base(T_CHAR) should be equivalent to get_char_at_addr(0), both return the address of the first element. I don't see the point. I can see why we are not going into possible latin1 inflation for length==0.
- I refactored some stuff in heapDumper to accept const void* instead of void* in write_raw().
Tests: build fastdebug/release (with+w/o PCH), passes hotspot/tier1 tests (fastdebug+release)
Bug: https://bugs.openjdk.java.net/browse/JDK-8199801 Webrev: http://cr.openjdk.java.net/~rkennke/JDK-8199801/webrev.00/
What do you think? Can I please get reviews?
Thanks, Roman
-------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: OpenPGP digital signature URL: <https://mail.openjdk.org/pipermail/hotspot-gc-dev/attachments/20180320/e0ddab37/signature.asc>
- Previous message (by thread): RFR: JDK-8199781: Don't use naked == for comparing oops
- Next message (by thread): RFR: 8199850: Move parsing of VerifyGCType to G1
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]