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