hotspot/src/share/vm/memory/defNewGeneration.cpp
changeset 360 21d113ecbf6a
parent 1 489c9b5090e2
child 971 f0b20be4165d
child 670 ddf3e9583f2f
child 1374 4c24294029a9
equal deleted inserted replaced
357:f4edb0d9f109 360:21d113ecbf6a
    45   GenRemSet* rs = GenCollectedHeap::heap()->rem_set();
    45   GenRemSet* rs = GenCollectedHeap::heap()->rem_set();
    46   assert(rs->rs_kind() == GenRemSet::CardTable, "Wrong rem set kind.");
    46   assert(rs->rs_kind() == GenRemSet::CardTable, "Wrong rem set kind.");
    47   _rs = (CardTableRS*)rs;
    47   _rs = (CardTableRS*)rs;
    48 }
    48 }
    49 
    49 
    50 void DefNewGeneration::KeepAliveClosure::do_oop(oop* p) {
    50 void DefNewGeneration::KeepAliveClosure::do_oop(oop* p)       { DefNewGeneration::KeepAliveClosure::do_oop_work(p); }
    51   // We never expect to see a null reference being processed
    51 void DefNewGeneration::KeepAliveClosure::do_oop(narrowOop* p) { DefNewGeneration::KeepAliveClosure::do_oop_work(p); }
    52   // as a weak reference.
    52 
    53   assert (*p != NULL, "expected non-null ref");
       
    54   assert ((*p)->is_oop(), "expected an oop while scanning weak refs");
       
    55 
       
    56   _cl->do_oop_nv(p);
       
    57 
       
    58   // Card marking is trickier for weak refs.
       
    59   // This oop is a 'next' field which was filled in while we
       
    60   // were discovering weak references. While we might not need
       
    61   // to take a special action to keep this reference alive, we
       
    62   // will need to dirty a card as the field was modified.
       
    63   //
       
    64   // Alternatively, we could create a method which iterates through
       
    65   // each generation, allowing them in turn to examine the modified
       
    66   // field.
       
    67   //
       
    68   // We could check that p is also in an older generation, but
       
    69   // dirty cards in the youngest gen are never scanned, so the
       
    70   // extra check probably isn't worthwhile.
       
    71   if (Universe::heap()->is_in_reserved(p)) {
       
    72     _rs->inline_write_ref_field_gc(p, *p);
       
    73   }
       
    74 }
       
    75 
    53 
    76 DefNewGeneration::FastKeepAliveClosure::
    54 DefNewGeneration::FastKeepAliveClosure::
    77 FastKeepAliveClosure(DefNewGeneration* g, ScanWeakRefClosure* cl) :
    55 FastKeepAliveClosure(DefNewGeneration* g, ScanWeakRefClosure* cl) :
    78   DefNewGeneration::KeepAliveClosure(cl) {
    56   DefNewGeneration::KeepAliveClosure(cl) {
    79   _boundary = g->reserved().end();
    57   _boundary = g->reserved().end();
    80 }
    58 }
    81 
    59 
    82 void DefNewGeneration::FastKeepAliveClosure::do_oop(oop* p) {
    60 void DefNewGeneration::FastKeepAliveClosure::do_oop(oop* p)       { DefNewGeneration::FastKeepAliveClosure::do_oop_work(p); }
    83   assert (*p != NULL, "expected non-null ref");
    61 void DefNewGeneration::FastKeepAliveClosure::do_oop(narrowOop* p) { DefNewGeneration::FastKeepAliveClosure::do_oop_work(p); }
    84   assert ((*p)->is_oop(), "expected an oop while scanning weak refs");
       
    85 
       
    86   _cl->do_oop_nv(p);
       
    87 
       
    88   // Optimized for Defnew generation if it's the youngest generation:
       
    89   // we set a younger_gen card if we have an older->youngest
       
    90   // generation pointer.
       
    91   if (((HeapWord*)(*p) < _boundary) && Universe::heap()->is_in_reserved(p)) {
       
    92     _rs->inline_write_ref_field_gc(p, *p);
       
    93   }
       
    94 }
       
    95 
    62 
    96 DefNewGeneration::EvacuateFollowersClosure::
    63 DefNewGeneration::EvacuateFollowersClosure::
    97 EvacuateFollowersClosure(GenCollectedHeap* gch, int level,
    64 EvacuateFollowersClosure(GenCollectedHeap* gch, int level,
    98                          ScanClosure* cur, ScanClosure* older) :
    65                          ScanClosure* cur, ScanClosure* older) :
    99   _gch(gch), _level(level),
    66   _gch(gch), _level(level),
   130 {
    97 {
   131   assert(_g->level() == 0, "Optimized for youngest generation");
    98   assert(_g->level() == 0, "Optimized for youngest generation");
   132   _boundary = _g->reserved().end();
    99   _boundary = _g->reserved().end();
   133 }
   100 }
   134 
   101 
       
   102 void ScanClosure::do_oop(oop* p)       { ScanClosure::do_oop_work(p); }
       
   103 void ScanClosure::do_oop(narrowOop* p) { ScanClosure::do_oop_work(p); }
       
   104 
   135 FastScanClosure::FastScanClosure(DefNewGeneration* g, bool gc_barrier) :
   105 FastScanClosure::FastScanClosure(DefNewGeneration* g, bool gc_barrier) :
   136   OopsInGenClosure(g), _g(g), _gc_barrier(gc_barrier)
   106   OopsInGenClosure(g), _g(g), _gc_barrier(gc_barrier)
   137 {
   107 {
   138   assert(_g->level() == 0, "Optimized for youngest generation");
   108   assert(_g->level() == 0, "Optimized for youngest generation");
   139   _boundary = _g->reserved().end();
   109   _boundary = _g->reserved().end();
   140 }
   110 }
   141 
   111 
       
   112 void FastScanClosure::do_oop(oop* p)       { FastScanClosure::do_oop_work(p); }
       
   113 void FastScanClosure::do_oop(narrowOop* p) { FastScanClosure::do_oop_work(p); }
       
   114 
   142 ScanWeakRefClosure::ScanWeakRefClosure(DefNewGeneration* g) :
   115 ScanWeakRefClosure::ScanWeakRefClosure(DefNewGeneration* g) :
   143   OopClosure(g->ref_processor()), _g(g)
   116   OopClosure(g->ref_processor()), _g(g)
   144 {
   117 {
   145   assert(_g->level() == 0, "Optimized for youngest generation");
   118   assert(_g->level() == 0, "Optimized for youngest generation");
   146   _boundary = _g->reserved().end();
   119   _boundary = _g->reserved().end();
   147 }
   120 }
   148 
   121 
       
   122 void ScanWeakRefClosure::do_oop(oop* p)       { ScanWeakRefClosure::do_oop_work(p); }
       
   123 void ScanWeakRefClosure::do_oop(narrowOop* p) { ScanWeakRefClosure::do_oop_work(p); }
       
   124 
       
   125 void FilteringClosure::do_oop(oop* p)       { FilteringClosure::do_oop_work(p); }
       
   126 void FilteringClosure::do_oop(narrowOop* p) { FilteringClosure::do_oop_work(p); }
   149 
   127 
   150 DefNewGeneration::DefNewGeneration(ReservedSpace rs,
   128 DefNewGeneration::DefNewGeneration(ReservedSpace rs,
   151                                    size_t initial_size,
   129                                    size_t initial_size,
   152                                    int level,
   130                                    int level,
   153                                    const char* policy)
   131                                    const char* policy)
   654     drain_promo_failure_scan_stack();
   632     drain_promo_failure_scan_stack();
   655     _promo_failure_drain_in_progress = false;
   633     _promo_failure_drain_in_progress = false;
   656   }
   634   }
   657 }
   635 }
   658 
   636 
   659 oop DefNewGeneration::copy_to_survivor_space(oop old, oop* from) {
   637 oop DefNewGeneration::copy_to_survivor_space(oop old) {
   660   assert(is_in_reserved(old) && !old->is_forwarded(),
   638   assert(is_in_reserved(old) && !old->is_forwarded(),
   661          "shouldn't be scavenging this oop");
   639          "shouldn't be scavenging this oop");
   662   size_t s = old->size();
   640   size_t s = old->size();
   663   oop obj = NULL;
   641   oop obj = NULL;
   664 
   642 
   667     obj = (oop) to()->allocate(s);
   645     obj = (oop) to()->allocate(s);
   668   }
   646   }
   669 
   647 
   670   // Otherwise try allocating obj tenured
   648   // Otherwise try allocating obj tenured
   671   if (obj == NULL) {
   649   if (obj == NULL) {
   672     obj = _next_gen->promote(old, s, from);
   650     obj = _next_gen->promote(old, s);
   673     if (obj == NULL) {
   651     if (obj == NULL) {
   674       if (!HandlePromotionFailure) {
   652       if (!HandlePromotionFailure) {
   675         // A failed promotion likely means the MaxLiveObjectEvacuationRatio flag
   653         // A failed promotion likely means the MaxLiveObjectEvacuationRatio flag
   676         // is incorrectly set. In any case, its seriously wrong to be here!
   654         // is incorrectly set. In any case, its seriously wrong to be here!
   677         vm_exit_out_of_memory(s*wordSize, "promotion");
   655         vm_exit_out_of_memory(s*wordSize, "promotion");
   860 
   838 
   861 
   839 
   862 const char* DefNewGeneration::name() const {
   840 const char* DefNewGeneration::name() const {
   863   return "def new generation";
   841   return "def new generation";
   864 }
   842 }
       
   843 
       
   844 // Moved from inline file as they are not called inline
       
   845 CompactibleSpace* DefNewGeneration::first_compaction_space() const {
       
   846   return eden();
       
   847 }
       
   848 
       
   849 HeapWord* DefNewGeneration::allocate(size_t word_size,
       
   850                                      bool is_tlab) {
       
   851   // This is the slow-path allocation for the DefNewGeneration.
       
   852   // Most allocations are fast-path in compiled code.
       
   853   // We try to allocate from the eden.  If that works, we are happy.
       
   854   // Note that since DefNewGeneration supports lock-free allocation, we
       
   855   // have to use it here, as well.
       
   856   HeapWord* result = eden()->par_allocate(word_size);
       
   857   if (result != NULL) {
       
   858     return result;
       
   859   }
       
   860   do {
       
   861     HeapWord* old_limit = eden()->soft_end();
       
   862     if (old_limit < eden()->end()) {
       
   863       // Tell the next generation we reached a limit.
       
   864       HeapWord* new_limit =
       
   865         next_gen()->allocation_limit_reached(eden(), eden()->top(), word_size);
       
   866       if (new_limit != NULL) {
       
   867         Atomic::cmpxchg_ptr(new_limit, eden()->soft_end_addr(), old_limit);
       
   868       } else {
       
   869         assert(eden()->soft_end() == eden()->end(),
       
   870                "invalid state after allocation_limit_reached returned null");
       
   871       }
       
   872     } else {
       
   873       // The allocation failed and the soft limit is equal to the hard limit,
       
   874       // there are no reasons to do an attempt to allocate
       
   875       assert(old_limit == eden()->end(), "sanity check");
       
   876       break;
       
   877     }
       
   878     // Try to allocate until succeeded or the soft limit can't be adjusted
       
   879     result = eden()->par_allocate(word_size);
       
   880   } while (result == NULL);
       
   881 
       
   882   // If the eden is full and the last collection bailed out, we are running
       
   883   // out of heap space, and we try to allocate the from-space, too.
       
   884   // allocate_from_space can't be inlined because that would introduce a
       
   885   // circular dependency at compile time.
       
   886   if (result == NULL) {
       
   887     result = allocate_from_space(word_size);
       
   888   }
       
   889   return result;
       
   890 }
       
   891 
       
   892 HeapWord* DefNewGeneration::par_allocate(size_t word_size,
       
   893                                          bool is_tlab) {
       
   894   return eden()->par_allocate(word_size);
       
   895 }
       
   896 
       
   897 void DefNewGeneration::gc_prologue(bool full) {
       
   898   // Ensure that _end and _soft_end are the same in eden space.
       
   899   eden()->set_soft_end(eden()->end());
       
   900 }
       
   901 
       
   902 size_t DefNewGeneration::tlab_capacity() const {
       
   903   return eden()->capacity();
       
   904 }
       
   905 
       
   906 size_t DefNewGeneration::unsafe_max_tlab_alloc() const {
       
   907   return unsafe_max_alloc_nogc();
       
   908 }