8149085: IntegrationTest1.java fails intermittently due to use of semi-initialized TLAB
authorsjohanss
Wed, 08 Jun 2016 16:29:12 +0200
changeset 39220 f08faf525113
parent 39219 1b33aa56ed18
child 39222 cf2d48fdf795
8149085: IntegrationTest1.java fails intermittently due to use of semi-initialized TLAB Reviewed-by: ehelin, mgerdin
hotspot/src/share/vm/gc/shared/threadLocalAllocBuffer.hpp
hotspot/src/share/vm/runtime/thread.inline.hpp
--- a/hotspot/src/share/vm/gc/shared/threadLocalAllocBuffer.hpp	Wed Jun 08 11:15:49 2016 +0200
+++ b/hotspot/src/share/vm/gc/shared/threadLocalAllocBuffer.hpp	Wed Jun 08 16:29:12 2016 +0200
@@ -110,6 +110,7 @@
 
   static const size_t min_size()                 { return align_object_size(MinTLABSize / HeapWordSize) + alignment_reserve(); }
   static const size_t max_size()                 { assert(_max_size != 0, "max_size not set up"); return _max_size; }
+  static const size_t max_size_in_bytes()        { return max_size() * BytesPerWord; }
   static void set_max_size(size_t max_size)      { _max_size = max_size; }
 
   HeapWord* start() const                        { return _start; }
--- a/hotspot/src/share/vm/runtime/thread.inline.hpp	Wed Jun 08 11:15:49 2016 +0200
+++ b/hotspot/src/share/vm/runtime/thread.inline.hpp	Wed Jun 08 16:29:12 2016 +0200
@@ -71,9 +71,12 @@
   jlong allocated_bytes = OrderAccess::load_acquire(&_allocated_bytes);
   if (UseTLAB) {
     size_t used_bytes = tlab().used_bytes();
-    if ((ssize_t)used_bytes > 0) {
-      // More-or-less valid tlab. The load_acquire above should ensure
-      // that the result of the add is <= the instantaneous value.
+    if (used_bytes <= ThreadLocalAllocBuffer::max_size_in_bytes()) {
+      // Comparing used_bytes with the maximum allowed size will ensure
+      // that we don't add the used bytes from a semi-initialized TLAB
+      // ending up with incorrect values. There is still a race between
+      // incrementing _allocated_bytes and clearing the TLAB, that might
+      // cause double counting in rare cases.
       return allocated_bytes + used_bytes;
     }
   }