generation.cpp

Go to the documentation of this file.
00001 /* Copyright 1994, 1995 LongView Technologies L.L.C. $Revision: 1.25 $ */
00002 /* Copyright (c) 2006, Sun Microsystems, Inc.
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 
00006 following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
00010           disclaimer in the documentation and/or other materials provided with the distribution.
00011     * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived 
00012           from this software without specific prior written permission.
00013 
00014 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 
00015 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
00016 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
00017 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00018 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00019 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00020 
00021 
00022 */
00023 
00024 # include "incls/_precompiled.incl"
00025 # include "incls/_generation.cpp.incl"
00026 
00027 void generation::print() {
00028   std->print(" total %6dK, %d%% used ", capacity()/K, (100 * used())/capacity());
00029   std->print_cr(" [%#x, %#x[", low_boundary, high_boundary);
00030 }
00031 
00032 void newGeneration::swap_spaces() {
00033   eden()->clear();
00034   from()->clear();
00035   {
00036     survivorSpace* s = from();
00037     from_space = to();
00038     to_space    = s;
00039   }
00040   eden()->next_space = from();
00041 
00042   from()->set_name("from");
00043   from()->next_space = to();
00044 
00045   to()->set_name("to");
00046   to()->next_space = NULL;
00047 }
00048 
00049 void newGeneration::initialize(ReservedSpace rs, int eden_size, int surv_size) {  
00050   int new_size = eden_size + surv_size + surv_size;
00051 
00052   virtual_space.initialize(rs, rs.size());
00053 
00054   char *eden_start = virtual_space.low();
00055   char *from_start = eden_start + eden_size;
00056   char *to_start   = from_start + surv_size;
00057   char *to_end     = to_start   + surv_size;
00058 
00059   from_space= new survivorSpace();
00060   to_space  = new survivorSpace();
00061 
00062   eden()->initialize("eden", (oop*) eden_start, (oop*)from_start);
00063   from()->initialize("from", (oop*) from_start, (oop*) to_start);
00064     to()->initialize("to",   (oop*) to_start,   (oop*) to_end);
00065 
00066   eden()->next_space = from();
00067   from()->next_space =   to();
00068     to()->next_space =   NULL;
00069 
00070    low_boundary= virtual_space.low_boundary();
00071   high_boundary= virtual_space.high_boundary();
00072 }
00073 
00074 void newGeneration::prepare_for_compaction(OldWaterMark* mark) {
00075   // %note same order as in compact
00076   from()->prepare_for_compaction(mark);
00077   eden()->prepare_for_compaction(mark);
00078 }
00079 
00080 void newGeneration::compact(OldWaterMark* mark) {
00081   // %note same order as in prepare_for_compaction
00082   from()->compact(mark);
00083   from()->clear();
00084   eden()->compact(mark);
00085   eden()->clear();
00086 }
00087 
00088 oop* newGeneration::object_start(oop* p) {
00089   if (eden()->contains(p)) return eden()->object_start(p);
00090   return from()->object_start(p);
00091 }
00092 
00093 int newGeneration::capacity() {
00094   return eden()->capacity()
00095        + from()->capacity()
00096        +   to()->capacity();
00097 }
00098 
00099 int newGeneration::used() {
00100   return eden()->used()
00101        + from()->used()
00102        +   to()->used();
00103 }
00104 
00105 int newGeneration::free() {
00106   return eden()->free()
00107        + from()->free()
00108        +   to()->free();
00109 }
00110 
00111 void newGeneration::switch_pointers(oop f, oop t) {
00112   eden()->switch_pointers(f, t);
00113   from()->switch_pointers(f, t);
00114     to()->switch_pointers(f, t);
00115 }
00116 
00117 void newGeneration::print() {
00118   if (WizardMode) {
00119     std->print_cr(" New generation");
00120     generation::print();
00121   }
00122   eden()->print();
00123   from()->print();
00124   if (WizardMode) {
00125     to()->print();
00126   }
00127 }
00128 
00129 void newGeneration::object_iterate(ObjectClosure* blk) {
00130   eden()->object_iterate(blk);
00131   from()->object_iterate(blk);
00132 }
00133 
00134 void newGeneration::verify() {
00135   if (   eden()->next_space != from_space
00136       || from()->next_space !=   to_space
00137       || to()->next_space != NULL)
00138     error("misconnnected spaces in new gen");
00139 
00140   eden()->verify();
00141   from()->verify();
00142     to()->verify();
00143 }
00144 
00145 # undef FOR_EACH_OLD_SPACE
00146 // this version used with old_gen
00147 // ensure that you surround the call with {} to prevent s leaking out!
00148 #define FOR_EACH_OLD_SPACE(s)           \
00149   for (oldSpace *s= first_space;        \
00150        s != NULL;                       \
00151        s= s->next_space)
00152 
00153 void oldGeneration::initialize(ReservedSpace rs, int initial_size) {
00154 
00155   virtual_space.initialize(rs, initial_size);
00156 
00157   first_space = new oldSpace("old", initial_size);
00158   last_space  = current_space = first_space;
00159 
00160    low_boundary= virtual_space.low_boundary();
00161   high_boundary= virtual_space.high_boundary();
00162 }
00163 
00164 bool oldGeneration::contains(void* p) {
00165   FOR_EACH_OLD_SPACE(s) { if (s->contains(p)) return true; }
00166   return false;
00167 }
00168 
00169 int oldGeneration::capacity(){
00170   int sum= 0;
00171   FOR_EACH_OLD_SPACE(s) sum += s->capacity();
00172   return sum;
00173 }
00174 
00175 int oldGeneration::used(){
00176   int sum= 0;
00177   FOR_EACH_OLD_SPACE(s) sum += s->used();
00178   return sum;
00179 }
00180 
00181 int oldGeneration::free(){
00182   int sum= 0;
00183   FOR_EACH_OLD_SPACE(s) sum += s->free();
00184   return sum;
00185 }
00186 
00187 void oldGeneration::scavenge_contents_from(OldWaterMark* mark) {
00188   mark->_space->scavenge_contents_from(mark);
00189   while (mark->_space != current_space) {
00190     *mark = mark->_space->next_space->bottom_mark();
00191     mark->_space->scavenge_contents_from(mark);
00192   }
00193 }
00194 
00195 void oldGeneration::switch_pointers(oop from, oop to) {
00196  FOR_EACH_OLD_SPACE(space) space->switch_pointers(from, to);
00197 }
00198     
00199 // Expand the old space by size bytes. 
00200 // Returns the amount actually allocated (0, maybe, if expansion isn't
00201 // possible; or more than asked for, due to rounding).
00202 int oldGeneration::expand(int size) {
00203   EventMarker em("expanding heap by %d", (void*)size);
00204   assert(size >= 0, "negative expansion?");
00205   char *name= "old";
00206   oldSpace *s = new oldSpace(name, size); // modifies size for amount allocated
00207   if (size == 0) 
00208     delete s;
00209   else {
00210     if ((char*) s->bottom() < Universe::new_gen.high_boundary)
00211       fatal("allocation of old space before new space");
00212     
00213     // it's OK for the new oldSpace to go between the new spaces and
00214     // existing old space (as there is already a card bytemap for this
00215     // region), or between two old spaces (for the same reason), or after
00216     // the last old space (in which case we will extend the card byte map).
00217     
00218     append_space(s);
00219       
00220     char* sStart= (char*) s->bottom();
00221     char* sEnd  = (char*) s->end();
00222     if (sStart <  low_boundary)  low_boundary= sStart;
00223     if (sEnd   > high_boundary) high_boundary= sEnd;
00224     Universe::remembered_set->fixup(sStart, sEnd);
00225     Universe::current_sizes.old_size= capacity();
00226   }
00227   return size;
00228 }
00229 
00230 void oldGeneration::prepare_for_compaction(OldWaterMark* mark) {
00231   // %note same order as in compact
00232   FOR_EACH_OLD_SPACE(s) s->prepare_for_compaction(mark);
00233 }
00234 
00235 void oldGeneration::compact(OldWaterMark* mark) {
00236   // %note same order as in prepare_for_compaction
00237   FOR_EACH_OLD_SPACE(s) s->compact(mark);
00238 }
00239 
00240 void oldGeneration::append_space(oldSpace *last) {
00241   last_space->next_space= last;
00242   last_space= last;
00243   last->next_space= NULL;
00244 }  
00245 
00246 oop* oldGeneration::allocate_in_next_space(int size) {
00247   // Scavenge breaks the there is more than one old space chunks
00248   // Fix this with VirtualSpace
00249   // 4/5/96 Lars
00250   warning("Second old space chunk allocated, this could mean trouble");
00251   if (current_space == last_space) {
00252     int space_size = current_space->capacity();
00253     oldSpace *s = new oldSpace("old", space_size);
00254 
00255     if ((char*) s->bottom() < Universe::new_gen.high_boundary)
00256       fatal("allocation of old space before new space");
00257         
00258     append_space(s);
00259   }
00260   current_space = current_space->next_space;
00261 
00262   char* sStart= (char*) current_space->bottom();
00263   char* sEnd  = (char*) current_space->end();
00264   if (sStart <  low_boundary)  low_boundary= sStart;
00265   if (sEnd   > high_boundary) high_boundary= sEnd;
00266   Universe::remembered_set->fixup(sStart, sEnd);
00267   Universe::current_sizes.old_size = capacity();
00268 
00269   return allocate(size);
00270 }
00271 
00272 void oldGeneration::print() {
00273   if (WizardMode) {
00274     std->print_cr(" Old generation");
00275     generation::print();
00276   }
00277   FOR_EACH_OLD_SPACE(s) s->print();
00278 }
00279 
00280 void oldGeneration::print_remembered_set() {
00281   lprintf("Remembered set\n");
00282   FOR_EACH_OLD_SPACE(s) Universe::remembered_set->print_set_for_space(s);
00283 }
00284 
00285 int oldGeneration::number_of_dirty_pages() {
00286   int count = 0;
00287   FOR_EACH_OLD_SPACE(s) {
00288     count += Universe::remembered_set->number_of_dirty_pages_in(s);
00289   }
00290   return count;
00291 }
00292 
00293 int oldGeneration::number_of_pages_with_dirty_objects() {
00294   int count = 0;
00295   FOR_EACH_OLD_SPACE(s) {
00296     count += Universe::remembered_set->number_of_pages_with_dirty_objects_in(s);
00297   }
00298   return count;
00299 }
00300 
00301 void oldGeneration::object_iterate(ObjectClosure* blk) {
00302   FOR_EACH_OLD_SPACE(s) s->object_iterate(blk);
00303 }
00304 
00305 void oldGeneration::object_iterate_from(OldWaterMark* mark, ObjectClosure* blk) {
00306   mark->_space->object_iterate_from(mark, blk);
00307   for (oldSpace *s = mark->_space->next_space; s != NULL; s = s->next_space) {
00308     *mark = s->bottom_mark();
00309     s->object_iterate_from(mark, blk);
00310   }
00311 }
00312 
00313 void oldGeneration::verify() {
00314   int n= 0;
00315   oldSpace *p;
00316   FOR_EACH_OLD_SPACE(s) {
00317     n++;
00318     p= s;
00319   }
00320   if (p != last_space) error("Wrong last_space in old gen");
00321   APPLY_TO_OLD_SPACES(SPACE_VERIFY_TEMPLATE);
00322 }
00323 
00324 static int addr_cmp(oldSpace **s1, oldSpace **s2) {
00325   char* s1start= (char*) (*s1)->bottom();
00326   char* s2start= (char*) (*s2)->bottom();
00327   if (s1start < s2start) return -1;
00328   else if (s1start > s2start) return 1;
00329   else return 0;
00330 }
00331 
00332 oop* oldGeneration::object_start(oop* p) {
00333   FOR_EACH_OLD_SPACE(s) {
00334     if (s->contains(p)) return s->object_start(p);
00335   }
00336   return NULL;
00337 }
00338 
00339 
00340 

Generated on Mon Oct 9 13:37:10 2006 for Strongtalk VM by  doxygen 1.4.7