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/_weakArrayKlass.cpp.incl"
00027 
00028 klassOop weakArrayKlass::create_subclass(mixinOop mixin, Format format) {
00029   if (format == mem_klass || format == weakArray_klass) {
00030     return weakArrayKlass::create_class(as_klassOop(), mixin);
00031   }
00032   return NULL;
00033 }
00034 
00035 klassOop weakArrayKlass::create_class(klassOop super_class, mixinOop mixin) {
00036   weakArrayKlass o;
00037   return create_generic_class(super_class, mixin, o.vtbl_value());
00038 }
00039 
00040 void set_weakArrayKlass_vtbl(Klass* k) {
00041   weakArrayKlass o;
00042   k->set_vtbl_value(o.vtbl_value());
00043 }
00044 
00045 void weakArrayKlass::oop_layout_iterate(oop obj, ObjectLayoutClosure* blk) {
00046   
00047   oop* p   = objArrayOop(obj)->objs(0);
00048   int  len = objArrayOop(obj)->length();
00049   
00050   memOopKlass::oop_layout_iterate(obj, blk);
00051   
00052   blk->do_oop("length", p++);
00053   blk->begin_indexables();
00054   for (int index = 1; index <= len; index++) {
00055     blk->do_indexable_oop(index, p++);
00056   }
00057   blk->end_indexables();
00058 }
00059 
00060 void weakArrayKlass::oop_oop_iterate(oop obj, OopClosure* blk) {
00061   
00062   oop* p   = weakArrayOop(obj)->objs(0);
00063   int  len = weakArrayOop(obj)->length();
00064   
00065   memOopKlass::oop_oop_iterate(obj, blk);
00066   
00067   blk->do_oop(p++);
00068   for (int index = 1; index <= len; index++) {
00069     blk->do_oop(p++);
00070   }
00071 }
00072 
00073 int weakArrayKlass::oop_scavenge_contents(oop obj) {
00074   
00075   memOopKlass::oop_scavenge_contents(obj);
00076   
00077   weakArrayOop o = weakArrayOop(obj);
00078   if (!WeakArrayRegister::scavenge_register(o)) {
00079     oop* base = o->objs(1);
00080     oop* end  = base + o->length();
00081     while (base <= end) { scavenge_oop(base++); }
00082   }
00083   return object_size(o->length());  
00084 }
00085 
00086 int weakArrayKlass::oop_scavenge_tenured_contents(oop obj) {
00087   
00088   memOopKlass::oop_scavenge_tenured_contents(obj);
00089   
00090   weakArrayOop o = weakArrayOop(obj);
00091   if (!WeakArrayRegister::scavenge_register(o)){
00092     oop* base = o->objs(1);
00093     oop* end  = base + o->length();
00094     while (base <= end) scavenge_tenured_oop(base++);
00095   }
00096   return object_size(o->length());  
00097 }
00098 
00099 void weakArrayKlass::oop_follow_contents(oop obj) {
00100   
00101   if (!WeakArrayRegister::mark_sweep_register(weakArrayOop(obj), non_indexable_size())){
00102     oop* base = weakArrayOop(obj)->objs(1);
00103     oop* end  = base + weakArrayOop(obj)->length();
00104     while (base <= end) MarkSweep::reverse_and_follow(base++);
00105   } 
00106 
00107   
00108   memOopKlass::oop_follow_contents(obj);
00109 }
00110 
00111 
00112 
00113 bool WeakArrayRegister::during_registration = false;
00114 GrowableArray<weakArrayOop>* WeakArrayRegister::weakArrays = NULL;
00115 GrowableArray<int>* WeakArrayRegister::nis                 = NULL;
00116 
00117 
00118 void WeakArrayRegister::begin_scavenge() {
00119   during_registration = true;
00120   weakArrays          = new GrowableArray<weakArrayOop>(10); 
00121 }
00122 
00123 bool WeakArrayRegister::scavenge_register(weakArrayOop obj) {
00124   if (during_registration) weakArrays->push(obj);
00125   return during_registration;
00126 }
00127 
00128 void WeakArrayRegister::check_and_scavenge_contents() {
00129   scavenge_check_for_dying_objects();
00130   scavenge_contents();
00131   during_registration = false;
00132   weakArrays = NULL;
00133 }
00134 
00135 void WeakArrayRegister::scavenge_contents() {
00136   for(int index = 0; index < weakArrays->length(); index++)
00137     weakArrays->at(index)->scavenge_contents_after_registration(); 
00138 }
00139 
00140 inline bool WeakArrayRegister::scavenge_is_near_death(oop obj) {
00141   
00142   return obj->is_new() && !memOop(obj)->is_forwarded();
00143 }
00144 
00145 void WeakArrayRegister::scavenge_check_for_dying_objects() {
00146   NotificationQueue::mark_elements();
00147   for(int index = 0; index < weakArrays->length(); index++) {
00148     weakArrayOop w = weakArrays->at(index);
00149     bool encounted_near_death_objects = false;
00150     for(int i = 1; i <= w->length(); i++) {
00151       oop obj = w->obj_at(i);
00152       if (scavenge_is_near_death(obj)) {
00153         encounted_near_death_objects = true;
00154         memOop(obj)->mark_as_dying();
00155       }
00156     }
00157     if (encounted_near_death_objects && !w->is_queued())
00158       NotificationQueue::put(w);
00159   }
00160   NotificationQueue::clear_elements();
00161 }
00162 
00163 
00164 
00165 void WeakArrayRegister::begin_mark_sweep() {
00166   during_registration = true;
00167   weakArrays          = new GrowableArray<weakArrayOop>(100);
00168   nis                 = new GrowableArray<int>(100); 
00169 }
00170 
00171 bool WeakArrayRegister::mark_sweep_register(weakArrayOop obj, int non_indexable_size) {
00172   if (during_registration) {
00173     weakArrays->push(obj);
00174     nis->push(non_indexable_size);
00175   }
00176   return during_registration;
00177 }
00178 
00179 void WeakArrayRegister::check_and_follow_contents() {
00180   mark_sweep_check_for_dying_objects();
00181   follow_contents();
00182   during_registration = false;
00183   weakArrays = NULL;
00184   nis        = NULL;
00185 }
00186 
00187 void WeakArrayRegister::follow_contents() {
00188   for(int index = 0; index < weakArrays->length(); index++) {
00189     weakArrayOop w = weakArrays->at(index);
00190     int non_indexable_size = nis->at(index);
00191     bool encounted_near_death_objects = false;
00192     int length = smiOop(w->raw_at(non_indexable_size))->value();
00193     for(int i = 1; i <= length; i++) {
00194       MarkSweep::reverse_and_follow(w->oops(non_indexable_size+i));
00195     }
00196   }
00197 }
00198 
00199 inline bool WeakArrayRegister::mark_sweep_is_near_death(oop obj) {
00200   return obj->is_mem() && !memOop(obj)->is_gc_marked();
00201 }
00202 
00203 void WeakArrayRegister::mark_sweep_check_for_dying_objects() {
00204   for(int index = 0; index < weakArrays->length(); index++) {
00205     weakArrayOop w = weakArrays->at(index);
00206     int non_indexable_size = nis->at(index);
00207     bool encounted_near_death_objects = false;
00208     int length = smiOop(w->raw_at(non_indexable_size))->value();
00209     for(int i = 1; i <= length; i++) {
00210       oop obj = w->raw_at(non_indexable_size+i);
00211       if (mark_sweep_is_near_death(obj)) {
00212         encounted_near_death_objects = true;
00213         memOop(obj)->mark_as_dying();
00214       }
00215     }
00216     if (encounted_near_death_objects)
00217       NotificationQueue::put_if_absent(w);
00218   }
00219 }
00220 
00221 
00222 
00223 oop* NotificationQueue::array = NULL;
00224 int  NotificationQueue::size  = 100;
00225 int  NotificationQueue::first = 0;
00226 int  NotificationQueue::last  = 0;
00227 
00228 bool NotificationQueue::is_empty() {
00229   return first == last;
00230 }
00231 
00232 int NotificationQueue::succ(int index) {
00233   return (index+1) % size;
00234 }
00235 
00236 oop NotificationQueue::get() {
00237   assert(!is_empty(), "must contain elements");
00238   oop result = array[first];
00239   first = succ(first);
00240   return result;
00241 }
00242 
00243 void NotificationQueue::put(oop obj) {
00244   if (array == NULL) array = NEW_C_HEAP_ARRAY(oop, size);
00245   if (succ(last) == first) {
00246     int new_size = size * 2;
00247     int new_last = 0;
00248     
00249     oop* new_array = NEW_C_HEAP_ARRAY(oop, new_size);
00250     
00251     for (int index = first; index != last; index = succ(index))
00252       new_array[new_last++] = array[index];
00253     free(array);
00254     
00255     array = new_array;
00256     size  = new_size;
00257     first = 0;
00258     last  = new_last;
00259   } 
00260   array[last] = obj;
00261   last = succ(last);
00262 }
00263 
00264 void NotificationQueue::put_if_absent(oop obj) {
00265   for (int index = first; index != last; index = succ(index)) {
00266     if (array[index] == obj) return;
00267   }
00268   put(obj);
00269 }
00270 
00271 void NotificationQueue::oops_do(void f(oop*)) {
00272   for (int index = first; index != last; index = succ(index))
00273     f(&array[index]);
00274 }
00275 
00276 void NotificationQueue::mark_elements() {
00277   for (int index = first; index != last; index = succ(index)) {
00278     oop obj = array[index];
00279     if (obj->is_mem()) memOop(obj)->set_queued();
00280   }
00281 }
00282 
00283 void NotificationQueue::clear_elements() {
00284   for (int index = first; index != last; index = succ(index)) {
00285     oop obj = array[index];
00286     if (obj->is_mem()) memOop(obj)->clear_queued();
00287   }
00288 }
00289