weakArrayKlass.cpp

Go to the documentation of this file.
00001 /* Copyright 1994, 1995 LongView Technologies L.L.C. $Revision: 1.7 $ */
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 
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   // Retrieve length information in case the iterator mutates the object
00047   oop* p   = objArrayOop(obj)->objs(0);
00048   int  len = objArrayOop(obj)->length();
00049   // header + instance variables
00050   memOopKlass::oop_layout_iterate(obj, blk);
00051   // indexables
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   // Retrieve length information in case the iterator mutates the object
00062   oop* p   = weakArrayOop(obj)->objs(0);
00063   int  len = weakArrayOop(obj)->length();
00064   // header + instance variables
00065   memOopKlass::oop_oop_iterate(obj, blk);
00066   // indexables
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   // header + instance variables
00075   memOopKlass::oop_scavenge_contents(obj);
00076   // indexables
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   // header + instance variables
00088   memOopKlass::oop_scavenge_tenured_contents(obj);
00089   // indexables
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   // indexables
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   // header + instance variables
00108   memOopKlass::oop_follow_contents(obj);
00109 }
00110 
00111 // WeakArrayRegister 
00112 // - static variables
00113 bool WeakArrayRegister::during_registration = false;
00114 GrowableArray<weakArrayOop>* WeakArrayRegister::weakArrays = NULL;
00115 GrowableArray<int>* WeakArrayRegister::nis                 = NULL;
00116 
00117 // - Scavenge operations
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   // must be memOop and unmarked (no forward pointer)
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 // - Mark sweep operations
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 // NotificationQueue
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     // allocate new_array
00249     oop* new_array = NEW_C_HEAP_ARRAY(oop, new_size);
00250     // copy from array to new_array
00251     for (int index = first; index != last; index = succ(index))
00252       new_array[new_last++] = array[index];
00253     free(array);
00254     // replace array
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 

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