00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 # include "incls/_precompiled.incl"
00026 # include "incls/_space.cpp.incl"
00027 
00028 oop* OldWaterMark::pseudo_allocate(int size) {
00029   oop* p = _point;
00030   if (p + size  < _space->end()) {
00031     _point = p + size;
00032   } else {
00033     lprintf("crossing space\n");
00034     fatal("not implemented yet");
00035   }
00036   return p;
00037 }
00038 
00039 void space::clear() {
00040   set_top(bottom());
00041 # ifdef ASSERT 
00042     
00043     set_oops(bottom(), capacity()/oopSize, oop(1));
00044 # endif
00045 }
00046 
00047 void space::switch_pointers(oop from, oop to) {
00048   
00049   fatal("not implemented yet");
00050 }
00051 
00052 void space::initialize(char* name, oop* bottom, oop* end) {
00053   assert(Universe::on_page_boundary(bottom) && Universe::on_page_boundary(end), "invalid space boundaries");
00054 
00055   set_name(name);
00056   set_bottom(bottom);
00057   set_top(bottom);
00058   set_end(end);
00059 }
00060 
00061 void space::prepare_for_compaction(OldWaterMark* mark) {
00062   
00063   
00064   
00065   
00066   
00067   oop* q          = bottom();
00068   oop* t          = top();
00069   oop* new_top    = mark->_point;
00070   memOop first_free = NULL;
00071   while (q < t) {
00072     memOop m = as_memOop(q);
00073     if (m->is_gc_marked()) {
00074       if (first_free) { 
00075         first_free->set_mark(q);
00076         
00077         first_free = NULL;
00078       }
00079 
00080       
00081       oop* root_or_mark = (oop*) m->mark();
00082       while (is_oop_root(root_or_mark)) {
00083         oop* next = (oop*) *root_or_mark;
00084         *root_or_mark = (oop) as_memOop(new_top);
00085         root_or_mark = next;
00086       }
00087       m->set_mark(markOop(root_or_mark));
00088 
00089       int size = m->gc_retrieve_size(); 
00090                                         
00091       new_top += size;
00092       q       += size;
00093     } else {
00094       if (!first_free) {
00095         first_free = m;
00096         
00097       }
00098       q += m->size();
00099     }
00100   }
00101   if (first_free) { 
00102     first_free->set_mark(q);
00103     
00104   }
00105   mark->_point = new_top;
00106 }
00107 
00108 void space::compact(OldWaterMark* mark) {
00109   
00110   
00111   
00112   
00113   oop* q       = bottom();
00114   oop* t       = top();
00115   oop* new_top = mark->_point;
00116   while (q < t) {
00117     memOop m = as_memOop(q);
00118     if (m->mark()->is_smi()) {
00119       
00120       q = (oop*) *q;
00121     } else {
00122       int size = m->gc_retrieve_size();
00123       if (q != new_top) {
00124         copy_oops(q, new_top, size);
00125         
00126         assert((*new_top)->is_mark(), "should be header");
00127       }
00128       mark->_space->update_offsets(new_top, new_top + size);
00129       q       += size;
00130       new_top += size;
00131     }
00132   }
00133   mark->_point = new_top;
00134   mark->_space->set_top(new_top);
00135   set_top(new_top);
00136 }
00137 
00138 oop* newSpace::object_start(oop* p) {
00139   assert (bottom() <= p && p < top(), "p must be in space");
00140   oop* q = bottom();
00141   oop* t = top();
00142   while (q < t) {
00143     oop* prev = q;
00144     q += as_memOop(q)->size();
00145     if (q > p) return prev;
00146   }
00147   fatal("should never reach this point");
00148   return NULL;
00149 }
00150 
00151 void newSpace::object_iterate_from(NewWaterMark* mark, ObjectClosure* blk) {
00152   blk->begin_space(this);
00153   oop* p = mark->_point;
00154   oop* t = top();
00155   while (p < t) {
00156     memOop m = as_memOop(p);
00157     blk->do_object(m);
00158     p += m->size();
00159   }
00160   mark->_point = p;
00161   blk->end_space(this);
00162 }
00163 
00164 edenSpace::edenSpace() {}
00165 survivorSpace::survivorSpace() {}
00166 
00167 void survivorSpace::scavenge_contents_from(NewWaterMark* mark) {
00168 # ifdef VERBOSE_SCAVENGING  
00169   lprintf("{scavenge_contents [ %#lx <= %#lx <= %#lx]}\n",
00170           bottom(), mark->_point, top());
00171 # endif
00172 
00173   if (top() == mark->_point) return;
00174   assert(mark->_point < top(), "scavenging past top");
00175 
00176   oop* p = mark->_point; 
00177   oop* t = top();
00178   
00179   do {
00180     memOop m = as_memOop(p);
00181 
00182 # ifdef VERBOSE_SCAVENGING  
00183     lprintf("{scavenge %#lx (%#lx)} ", p, m->klass());
00184     lprintf("%s\n", m->klass()->name());
00185     oop *prev = p;
00186 # endif
00187 
00188     assert((*p)->is_mark(), "Header should be mark");
00189     p += m->scavenge_contents();
00190 
00191 # ifdef VERBOSE_SCAVENGING  
00192     if (p - prev != m->size())
00193       fatal("scavenge_contents is not returning the right size");
00194 # endif
00195 
00196   } while (p < t);
00197   mark->_point = p;
00198 }
00199 
00200 void oldSpace::initialize_threshold() {
00201   next_offset_index                 = 0;
00202   offset_array[next_offset_index++] = 0;
00203   next_offset_treshold = _bottom + card_size_in_oops;
00204 }
00205 
00206 oldSpace::oldSpace(char *name, int &size) {
00207   next_space= NULL;
00208 
00209   offset_array = NEW_C_HEAP_ARRAY(u_char, Universe::old_gen.virtual_space.reserved_size()/card_size);
00210   set_name(name);
00211   set_bottom((oop*) Universe::old_gen.virtual_space.low());
00212   set_top((oop*)    Universe::old_gen.virtual_space.low());
00213   set_end((oop*)    Universe::old_gen.virtual_space.high());
00214   initialize_threshold();
00215 }
00216 
00217 void oldSpace::update_offset_array(oop* p, oop* p_end) {
00218   assert( p_end >= next_offset_treshold, "should be past threshold");
00219   
00220   
00221   assert((next_offset_treshold - p) <= card_size_in_oops,
00222          "Offset should be <= card_size_in_oops");
00223   offset_array[next_offset_index++] = next_offset_treshold - p;
00224   next_offset_treshold += card_size_in_oops;
00225   while (next_offset_treshold < p_end) {
00226     offset_array[next_offset_index++] = card_size_in_oops;
00227     next_offset_treshold += card_size_in_oops;
00228   }
00229 }
00230 
00231 oop* oldSpace::expand_and_allocate(int size) {
00232   int min_size = ReservedSpace::page_align_size(size);
00233   int expand_size = max(min_size, ObjectHeapExpandSize * K);
00234   Universe::old_gen.virtual_space.expand(expand_size);
00235   set_end((oop*) Universe::old_gen.virtual_space.high());
00236   return allocate(size);
00237 }
00238 
00239 void oldSpace::scavenge_recorded_stores() {
00240   Universe::remembered_set->scavenge_contents(this);
00241 }
00242 
00243 void oldSpace::scavenge_contents_from(OldWaterMark* mark) {
00244   assert(this == mark->_space, "Match does not match space");
00245   oop* p = mark->_point;
00246   while (p < _top) {
00247     assert(oop(*p)->is_mark(),"must be mark");
00248     memOop x = as_memOop(p);
00249     p += x->scavenge_tenured_contents();
00250   }
00251   assert(p == _top, "p should be top");
00252   mark->_point = _top;
00253 }
00254 
00255 void oldSpace::object_iterate_from(OldWaterMark* mark, ObjectClosure* blk) {
00256   blk->begin_space(this);
00257   oop* p = mark->_point;
00258   oop* t = top();
00259   while (p < t) {
00260     memOop m = as_memOop(p);
00261     blk->do_object(m);
00262     p += m->size();
00263   }
00264   mark->_point = p;
00265   blk->end_space(this);
00266 }
00267 
00268 
00269 void space::oops_do(oopsDoFn f) {
00270   oop* p = bottom();
00271   oop* t = top();
00272   while (p < t) {
00273     memOop m = as_memOop(p);
00274     f((oop*) &m);
00275     p += m->size();
00276   }
00277 }
00278 
00279 void space::print() {
00280   std->print(" %5s %6dK, %d%% used", name(), capacity() / K, used() * 100 / capacity());
00281   if (WizardMode) {
00282     std->print(" [%#-6lx,%#-6lx[", bottom(), top());
00283   }
00284   std->cr();
00285 }
00286 
00287 void space::object_iterate(ObjectClosure* blk) {
00288   if (is_empty()) return;
00289   blk->begin_space(this);
00290   oop* p = bottom();
00291   oop* t = top();
00292   while (p < t) {
00293     memOop m = as_memOop(p);
00294     blk->do_object(m);
00295     p += m->size();
00296   }
00297   blk->end_space(this);
00298 }
00299 
00300 void newSpace::verify() {
00301   lprintf("%s ", name());
00302   oop* p = bottom();
00303   oop* t = top();
00304 
00305   memOop m;
00306   while (p < t) {
00307     assert(oop(*p)->is_mark(), "First word must be mark");
00308     m = as_memOop(p);
00309     m->verify();
00310     p += m->size();
00311   }
00312   assert(p == top(), "end of last object must match end of space");
00313 }
00314 
00315 class VerifyOldOopClosure : public OopClosure {
00316  public:
00317   memOop the_obj;
00318   void do_oop(oop* o) {
00319     oop obj = *o;
00320     if (obj->is_new()) {
00321       
00322       if (!Universe::remembered_set->is_object_dirty(the_obj)) {
00323         std->cr();
00324         std->print_cr("New obj reference found in non dirty page.");
00325         std->print_cr("- object containing the reference:");
00326         the_obj->print();
00327         std->print_cr("- the referred object:");
00328         std->print("[0x%lx]: 0x%lx = ", o, obj);
00329         obj->print_value();
00330         std->cr();
00331         Universe::remembered_set->print_set_for_object(the_obj);
00332         warning("gc problem");
00333       }
00334     }
00335   }
00336 };
00337 
00338 void oldSpace::verify() {
00339   lprintf("%s ", name());
00340   oop*   p = _bottom;
00341   memOop m;
00342   VerifyOldOopClosure blk;
00343   while (p < _top) {
00344     assert(oop(*p)->is_mark(), "First word must be mark");
00345     m = as_memOop(p);
00346 
00347     int size = m->size();
00348     assert(m == as_memOop(Universe::object_start(p + (size/2))), "check offset computation");
00349 
00350     m->verify();
00351     blk.the_obj = m;
00352     m->oop_iterate(&blk);
00353     p += m->size();
00354   }
00355   assert(p == _top, "end of last object must match end of space");
00356 }
00357 
00358 oop* oldSpace::object_start(oop* p) {
00359   
00360   oop* q = p;
00361   int b = (int) q;
00362   clearBits(b, nthMask(card_shift));
00363   q = (oop*) b;
00364   assert(contains(q), "q must be in this space");
00365   int index  = (q - bottom()) / card_size_in_oops;
00366 
00367   int offset = offset_array[index--];
00368   while(offset == card_size_in_oops) {
00369     q -= card_size_in_oops;
00370     offset = offset_array[index--];
00371   }
00372   q -= offset;
00373   oop* n = q;
00374   assert((*n)->is_mark(), "check for header");
00375   while (n <= p) {
00376     q = n;
00377     n += as_memOop(n)->size();
00378   }
00379   assert( as_memOop(q)->mark()->is_mark(), "Must be mark");
00380   return q;
00381 }
00382 
00383 extern "C" oop* eden_bottom = NULL;
00384 extern "C" oop* eden_top    = NULL;
00385 extern "C" oop* eden_end    = NULL;