src/hotspot/share/gc/shared/threadLocalAllocBuffer.cpp
changeset 51742 3dd95a83791b
parent 51385 be775229d3b3
child 51794 4129f43607cb
equal deleted inserted replaced
51741:ed9b1200dd81 51742:3dd95a83791b
    67     global_stats()->print();
    67     global_stats()->print();
    68   }
    68   }
    69 }
    69 }
    70 
    70 
    71 void ThreadLocalAllocBuffer::accumulate_statistics() {
    71 void ThreadLocalAllocBuffer::accumulate_statistics() {
    72   Thread* thread = myThread();
    72   Thread* thr     = thread();
    73   size_t capacity = Universe::heap()->tlab_capacity(thread);
    73   size_t capacity = Universe::heap()->tlab_capacity(thr);
    74   size_t used     = Universe::heap()->tlab_used(thread);
    74   size_t used     = Universe::heap()->tlab_used(thr);
    75 
    75 
    76   _gc_waste += (unsigned)remaining();
    76   _gc_waste += (unsigned)remaining();
    77   size_t total_allocated = thread->allocated_bytes();
    77   size_t total_allocated = thr->allocated_bytes();
    78   size_t allocated_since_last_gc = total_allocated - _allocated_before_last_gc;
    78   size_t allocated_since_last_gc = total_allocated - _allocated_before_last_gc;
    79   _allocated_before_last_gc = total_allocated;
    79   _allocated_before_last_gc = total_allocated;
    80 
    80 
    81   print_stats("gc");
    81   print_stats("gc");
    82 
    82 
   117 void ThreadLocalAllocBuffer::make_parsable(bool retire, bool zap) {
   117 void ThreadLocalAllocBuffer::make_parsable(bool retire, bool zap) {
   118   if (end() != NULL) {
   118   if (end() != NULL) {
   119     invariants();
   119     invariants();
   120 
   120 
   121     if (retire) {
   121     if (retire) {
   122       myThread()->incr_allocated_bytes(used_bytes());
   122       thread()->incr_allocated_bytes(used_bytes());
   123     }
   123     }
   124 
   124 
   125     Universe::heap()->fill_with_dummy_object(top(), hard_end(), retire && zap);
   125     Universe::heap()->fill_with_dummy_object(top(), hard_end(), retire && zap);
   126 
   126 
   127     if (retire || ZeroTLAB) {  // "Reset" the TLAB
   127     if (retire || ZeroTLAB) {  // "Reset" the TLAB
   148 
   148 
   149 void ThreadLocalAllocBuffer::resize() {
   149 void ThreadLocalAllocBuffer::resize() {
   150   // Compute the next tlab size using expected allocation amount
   150   // Compute the next tlab size using expected allocation amount
   151   assert(ResizeTLAB, "Should not call this otherwise");
   151   assert(ResizeTLAB, "Should not call this otherwise");
   152   size_t alloc = (size_t)(_allocation_fraction.average() *
   152   size_t alloc = (size_t)(_allocation_fraction.average() *
   153                           (Universe::heap()->tlab_capacity(myThread()) / HeapWordSize));
   153                           (Universe::heap()->tlab_capacity(thread()) / HeapWordSize));
   154   size_t new_size = alloc / _target_refills;
   154   size_t new_size = alloc / _target_refills;
   155 
   155 
   156   new_size = MIN2(MAX2(new_size, min_size()), max_size());
   156   new_size = MIN2(MAX2(new_size, min_size()), max_size());
   157 
   157 
   158   size_t aligned_new_size = align_object_size(new_size);
   158   size_t aligned_new_size = align_object_size(new_size);
   159 
   159 
   160   log_trace(gc, tlab)("TLAB new size: thread: " INTPTR_FORMAT " [id: %2d]"
   160   log_trace(gc, tlab)("TLAB new size: thread: " INTPTR_FORMAT " [id: %2d]"
   161                       " refills %d  alloc: %8.6f desired_size: " SIZE_FORMAT " -> " SIZE_FORMAT,
   161                       " refills %d  alloc: %8.6f desired_size: " SIZE_FORMAT " -> " SIZE_FORMAT,
   162                       p2i(myThread()), myThread()->osthread()->thread_id(),
   162                       p2i(thread()), thread()->osthread()->thread_id(),
   163                       _target_refills, _allocation_fraction.average(), desired_size(), aligned_new_size);
   163                       _target_refills, _allocation_fraction.average(), desired_size(), aligned_new_size);
   164 
   164 
   165   set_desired_size(aligned_new_size);
   165   set_desired_size(aligned_new_size);
   166   set_refill_waste_limit(initial_refill_waste_limit());
   166   set_refill_waste_limit(initial_refill_waste_limit());
   167 }
   167 }
   209 
   209 
   210   // Following check is needed because at startup the main
   210   // Following check is needed because at startup the main
   211   // thread is initialized before the heap is.  The initialization for
   211   // thread is initialized before the heap is.  The initialization for
   212   // this thread is redone in startup_initialization below.
   212   // this thread is redone in startup_initialization below.
   213   if (Universe::heap() != NULL) {
   213   if (Universe::heap() != NULL) {
   214     size_t capacity   = Universe::heap()->tlab_capacity(myThread()) / HeapWordSize;
   214     size_t capacity   = Universe::heap()->tlab_capacity(thread()) / HeapWordSize;
   215     double alloc_frac = desired_size() * target_refills() / (double) capacity;
   215     double alloc_frac = desired_size() * target_refills() / (double) capacity;
   216     _allocation_fraction.sample(alloc_frac);
   216     _allocation_fraction.sample(alloc_frac);
   217   }
   217   }
   218 
   218 
   219   set_refill_waste_limit(initial_refill_waste_limit());
   219   set_refill_waste_limit(initial_refill_waste_limit());
   272     init_sz = TLABSize / HeapWordSize;
   272     init_sz = TLABSize / HeapWordSize;
   273   } else if (global_stats() != NULL) {
   273   } else if (global_stats() != NULL) {
   274     // Initial size is a function of the average number of allocating threads.
   274     // Initial size is a function of the average number of allocating threads.
   275     unsigned nof_threads = global_stats()->allocating_threads_avg();
   275     unsigned nof_threads = global_stats()->allocating_threads_avg();
   276 
   276 
   277     init_sz  = (Universe::heap()->tlab_capacity(myThread()) / HeapWordSize) /
   277     init_sz  = (Universe::heap()->tlab_capacity(thread()) / HeapWordSize) /
   278                       (nof_threads * target_refills());
   278                       (nof_threads * target_refills());
   279     init_sz = align_object_size(init_sz);
   279     init_sz = align_object_size(init_sz);
   280   }
   280   }
   281   init_sz = MIN2(MAX2(init_sz, min_size()), max_size());
   281   init_sz = MIN2(MAX2(init_sz, min_size()), max_size());
   282   return init_sz;
   282   return init_sz;
   286   Log(gc, tlab) log;
   286   Log(gc, tlab) log;
   287   if (!log.is_trace()) {
   287   if (!log.is_trace()) {
   288     return;
   288     return;
   289   }
   289   }
   290 
   290 
   291   Thread* thrd = myThread();
   291   Thread* thrd = thread();
   292   size_t waste = _gc_waste + _slow_refill_waste + _fast_refill_waste;
   292   size_t waste = _gc_waste + _slow_refill_waste + _fast_refill_waste;
   293   double waste_percent = percent_of(waste, _allocated_size);
   293   double waste_percent = percent_of(waste, _allocated_size);
   294   size_t tlab_used  = Universe::heap()->tlab_used(thrd);
   294   size_t tlab_used  = Universe::heap()->tlab_used(thrd);
   295   log.trace("TLAB: %s thread: " INTPTR_FORMAT " [id: %2d]"
   295   log.trace("TLAB: %s thread: " INTPTR_FORMAT " [id: %2d]"
   296             " desired_size: " SIZE_FORMAT "KB"
   296             " desired_size: " SIZE_FORMAT "KB"
   320   guarantee(p == top(), "end of last object must match end of space");
   320   guarantee(p == top(), "end of last object must match end of space");
   321 }
   321 }
   322 
   322 
   323 void ThreadLocalAllocBuffer::set_sample_end() {
   323 void ThreadLocalAllocBuffer::set_sample_end() {
   324   size_t heap_words_remaining = pointer_delta(_end, _top);
   324   size_t heap_words_remaining = pointer_delta(_end, _top);
   325   size_t bytes_until_sample = myThread()->heap_sampler().bytes_until_sample();
   325   size_t bytes_until_sample = thread()->heap_sampler().bytes_until_sample();
   326   size_t words_until_sample = bytes_until_sample / HeapWordSize;
   326   size_t words_until_sample = bytes_until_sample / HeapWordSize;
   327 
   327 
   328   if (heap_words_remaining > words_until_sample) {
   328   if (heap_words_remaining > words_until_sample) {
   329     HeapWord* new_end = _top + words_until_sample;
   329     HeapWord* new_end = _top + words_until_sample;
   330     set_end(new_end);
   330     set_end(new_end);
   332   } else {
   332   } else {
   333     _bytes_since_last_sample_point = heap_words_remaining * HeapWordSize;
   333     _bytes_since_last_sample_point = heap_words_remaining * HeapWordSize;
   334   }
   334   }
   335 }
   335 }
   336 
   336 
   337 Thread* ThreadLocalAllocBuffer::myThread() {
   337 Thread* ThreadLocalAllocBuffer::thread() {
   338   return (Thread*)(((char *)this) +
   338   return (Thread*)(((char*)this) + in_bytes(start_offset()) - in_bytes(Thread::tlab_start_offset()));
   339                    in_bytes(start_offset()) -
       
   340                    in_bytes(Thread::tlab_start_offset()));
       
   341 }
   339 }
   342 
   340 
   343 void ThreadLocalAllocBuffer::set_back_allocation_end() {
   341 void ThreadLocalAllocBuffer::set_back_allocation_end() {
   344   _end = _allocation_end;
   342   _end = _allocation_end;
   345 }
   343 }