hotspot/src/share/vm/gc_interface/collectedHeap.cpp
author ysr
Thu, 05 Jun 2008 15:57:56 -0700
changeset 1374 4c24294029a9
parent 360 21d113ecbf6a
child 1388 3677f5f3d66b
permissions -rw-r--r--
6711316: Open source the Garbage-First garbage collector Summary: First mercurial integration of the code for the Garbage-First garbage collector. Reviewed-by: apetrusenko, iveresov, jmasa, sgoldman, tonyp, ysr
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
     2
 * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    19
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    20
 * CA 95054 USA or visit www.sun.com if you need additional information or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    21
 * have any questions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
# include "incls/_precompiled.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
# include "incls/_collectedHeap.cpp.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
int CollectedHeap::_fire_out_of_memory_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
// Memory state functions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
CollectedHeap::CollectedHeap() :
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
  _reserved(), _barrier_set(NULL), _is_gc_active(false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
  _total_collections(0), _total_full_collections(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
  _gc_cause(GCCause::_no_gc), _gc_lastcause(GCCause::_no_gc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
  NOT_PRODUCT(_promotion_failure_alot_count = 0;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
  NOT_PRODUCT(_promotion_failure_alot_gc_number = 0;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
  if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
    EXCEPTION_MARK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
    // create the gc cause jvmstat counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
    _perf_gc_cause = PerfDataManager::create_string_variable(SUN_GC, "cause",
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
                             80, GCCause::to_string(_gc_cause), CHECK);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
    _perf_gc_lastcause =
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
                PerfDataManager::create_string_variable(SUN_GC, "lastCause",
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
                             80, GCCause::to_string(_gc_lastcause), CHECK);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
void CollectedHeap::check_for_bad_heap_word_value(HeapWord* addr, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  if (CheckMemoryInitialization && ZapUnusedHeapArea) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
    for (size_t slot = 0; slot < size; slot += 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
      assert((*(intptr_t*) (addr + slot)) != ((intptr_t) badHeapWordVal),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
             "Found badHeapWordValue in post-allocation check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
void CollectedHeap::check_for_non_bad_heap_word_value(HeapWord* addr, size_t size)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
 {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
  if (CheckMemoryInitialization && ZapUnusedHeapArea) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
    for (size_t slot = 0; slot < size; slot += 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
      assert((*(intptr_t*) (addr + slot)) == ((intptr_t) badHeapWordVal),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
             "Found non badHeapWordValue in pre-allocation check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
#endif // PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
void CollectedHeap::check_for_valid_allocation_state() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
  Thread *thread = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
  // How to choose between a pending exception and a potential
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  // OutOfMemoryError?  Don't allow pending exceptions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
  // This is a VM policy failure, so how do we exhaustively test it?
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
  assert(!thread->has_pending_exception(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
         "shouldn't be allocating with pending exception");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
  if (StrictSafepointChecks) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
    assert(thread->allow_allocation(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
           "Allocation done by thread for which allocation is blocked "
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
           "by No_Allocation_Verifier!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
    // Allocation of an oop can always invoke a safepoint,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
    // hence, the true argument
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
    thread->check_for_valid_safepoint_state(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
HeapWord* CollectedHeap::allocate_from_tlab_slow(Thread* thread, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
  // Retain tlab and allocate object in shared space if
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
  // the amount free in the tlab is too large to discard.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
  if (thread->tlab().free() > thread->tlab().refill_waste_limit()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
    thread->tlab().record_slow_allocation(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
  // Discard tlab and allocate a new one.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
  // To minimize fragmentation, the last TLAB may be smaller than the rest.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  size_t new_tlab_size = thread->tlab().compute_size(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
  thread->tlab().clear_before_allocation();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
  if (new_tlab_size == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
  // Allocate a new TLAB...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
  HeapWord* obj = Universe::heap()->allocate_new_tlab(new_tlab_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
  if (obj == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
  if (ZeroTLAB) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
    // ..and clear it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
    Copy::zero_to_words(obj, new_tlab_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
    // ...and clear just the allocated object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
    Copy::zero_to_words(obj, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  thread->tlab().fill(obj, obj + size, new_tlab_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
  return obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
oop CollectedHeap::new_store_barrier(oop new_obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  // %%% This needs refactoring.  (It was imported from the server compiler.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
  guarantee(can_elide_tlab_store_barriers(), "store barrier elision not supported");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
  BarrierSet* bs = this->barrier_set();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
  assert(bs->has_write_region_opt(), "Barrier set does not have write_region");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
  int new_size = new_obj->size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
  bs->write_region(MemRegion((HeapWord*)new_obj, new_size));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
  return new_obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
HeapWord* CollectedHeap::allocate_new_tlab(size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
  guarantee(false, "thread-local allocation buffers not supported");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
void CollectedHeap::fill_all_tlabs(bool retire) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
  assert(UseTLAB, "should not reach here");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
  // See note in ensure_parsability() below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  assert(SafepointSynchronize::is_at_safepoint() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
         !is_init_completed(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
         "should only fill tlabs at safepoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
  // The main thread starts allocating via a TLAB even before it
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
  // has added itself to the threads list at vm boot-up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
  assert(Threads::first() != NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
         "Attempt to fill tlabs before main thread has been added"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
         " to threads list is doomed to failure!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
  for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
     thread->tlab().make_parsable(retire);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
void CollectedHeap::ensure_parsability(bool retire_tlabs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
  // The second disjunct in the assertion below makes a concession
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
  // for the start-up verification done while the VM is being
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
  // created. Callers be careful that you know that mutators
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
  // aren't going to interfere -- for instance, this is permissible
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
  // if we are still single-threaded and have either not yet
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
  // started allocating (nothing much to verify) or we have
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
  // started allocating but are now a full-fledged JavaThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
  // (and have thus made our TLAB's) available for filling.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
  assert(SafepointSynchronize::is_at_safepoint() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
         !is_init_completed(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
         "Should only be called at a safepoint or at start-up"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
         " otherwise concurrent mutator activity may make heap "
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
         " unparsable again");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
  if (UseTLAB) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
    fill_all_tlabs(retire_tlabs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
void CollectedHeap::accumulate_statistics_all_tlabs() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
  if (UseTLAB) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
    assert(SafepointSynchronize::is_at_safepoint() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
         !is_init_completed(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
         "should only accumulate statistics on tlabs at safepoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
    ThreadLocalAllocBuffer::accumulate_statistics_before_gc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
void CollectedHeap::resize_all_tlabs() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
  if (UseTLAB) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
    assert(SafepointSynchronize::is_at_safepoint() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
         !is_init_completed(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
         "should only resize tlabs at safepoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
    ThreadLocalAllocBuffer::resize_all_tlabs();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
}