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;