universe.hpp

Go to the documentation of this file.
00001 /* Copyright 1994 - 1996 LongView Technologies L.L.C. $Revision: 1.76 $ */
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 extern bool NeedScavenge;       // set when eden overflows
00026 
00027 extern  bool GCInProgress;       // GC/scavenge in progress
00028 extern  bool bootstrapping;      // true only at the very beginning
00029 
00030 // When you add a new root is added to Universe remember to:
00031 //   1. add a private static variable prefixed with _.
00032 //   2. add a public static accessor function.
00033 //   3. define the static variable in universe.cpp.
00034 //   4. update Universe::do_oops to iterate over the new root.
00035 
00036 // Used classes by the interpreter
00037 extern "C" klassOop smiKlassObj;
00038 extern "C" klassOop contextKlassObj;
00039 extern "C" klassOop doubleKlassObj;
00040 extern "C" klassOop symbolKlassObj;
00041 
00042 // Used objects by the interpreter
00043 extern "C" oop nilObj;
00044 extern "C" oop trueObj;
00045 extern "C" oop falseObj;
00046 
00047 // Used objects by the block primitives
00048 extern "C" klassOop zeroArgumentBlockKlassObj;
00049 extern "C" klassOop oneArgumentBlockKlassObj;
00050 extern "C" klassOop twoArgumentBlockKlassObj;
00051 extern "C" klassOop threeArgumentBlockKlassObj;
00052 extern "C" klassOop fourArgumentBlockKlassObj;
00053 extern "C" klassOop fiveArgumentBlockKlassObj;
00054 extern "C" klassOop sixArgumentBlockKlassObj;
00055 extern "C" klassOop sevenArgumentBlockKlassObj;
00056 extern "C" klassOop eightArgumentBlockKlassObj;
00057 extern "C" klassOop nineArgumentBlockKlassObj;
00058 
00059 extern "C" klassOop doubleValueArrayKlassObj;
00060 
00061 class Universe: AllStatic {
00062  private:
00063   // Known classes in the VM
00064   static klassOop _memOopKlassObj;
00065   static klassOop _objArrayKlassObj;
00066   static klassOop _byteArrayKlassObj;
00067   static klassOop _associationKlassObj;
00068   static klassOop _doubleKlassObj;
00069   static klassOop _methodKlassObj;
00070   static klassOop _characterKlassObj;
00071   static klassOop _vframeKlassObj;
00072 
00073   // Known objects in tbe VM
00074   static objArrayOop _asciiCharacters;
00075   static objArrayOop _systemDictionaryObj;
00076   static objArrayOop _objectIDTable;
00077   static objArrayOop _pic_free_list; 
00078 
00079   static oop         _callBack_receiver;
00080   static symbolOop   _callBack_selector;
00081 
00082   static oop         _dll_lookup_receiver;
00083   static symbolOop   _dll_lookup_selector;
00084 
00085   static methodOop   _sweeper_method; // Variable used by Sweeper only
00086 
00087   friend class bootstrap;
00088  public:
00089   // Known classes in tbe VM
00090   static klassOop smiKlassObj()                { return ::smiKlassObj;               }
00091   static klassOop contextKlassObj()            { return ::contextKlassObj;           }
00092   static klassOop doubleKlassObj()             { return ::doubleKlassObj;            }
00093   static klassOop memOopKlassObj()             { return _memOopKlassObj;             }
00094   static klassOop objArrayKlassObj()           { return _objArrayKlassObj;           }
00095   static klassOop byteArrayKlassObj()          { return _byteArrayKlassObj;          }
00096   static klassOop symbolKlassObj()             { return ::symbolKlassObj;            }
00097   static klassOop associationKlassObj()        { return _associationKlassObj;        }
00098   static klassOop zeroArgumentBlockKlassObj()  { return ::zeroArgumentBlockKlassObj; }
00099   static klassOop oneArgumentBlockKlassObj()   { return ::oneArgumentBlockKlassObj;  }
00100   static klassOop twoArgumentBlockKlassObj()   { return ::twoArgumentBlockKlassObj;  }
00101   static klassOop threeArgumentBlockKlassObj() { return ::threeArgumentBlockKlassObj;}
00102   static klassOop fourArgumentBlockKlassObj()  { return ::fourArgumentBlockKlassObj; }
00103   static klassOop fiveArgumentBlockKlassObj()  { return ::fiveArgumentBlockKlassObj; }
00104   static klassOop sixArgumentBlockKlassObj()   { return ::sixArgumentBlockKlassObj;  }
00105   static klassOop sevenArgumentBlockKlassObj() { return ::sevenArgumentBlockKlassObj;}
00106   static klassOop eightArgumentBlockKlassObj() { return ::eightArgumentBlockKlassObj;}
00107   static klassOop nineArgumentBlockKlassObj()  { return ::nineArgumentBlockKlassObj; }
00108   static klassOop methodKlassObj()             { return _methodKlassObj;             }
00109   static klassOop characterKlassObj()          { return _characterKlassObj;          }
00110   static klassOop doubleValueArrayKlassObj()   { return ::doubleValueArrayKlassObj;  }
00111   static klassOop vframeKlassObj()             { return _vframeKlassObj;             }
00112 
00113   // Known objects in tbe VM
00114   static oop         nilObj()                  { return ::nilObj;                    }
00115   static oop         trueObj()                 { return ::trueObj;                   }
00116   static oop         falseObj()                { return ::falseObj;                  }
00117   static objArrayOop asciiCharacters()         { return _asciiCharacters;            }
00118   static objArrayOop systemDictionaryObj()     { return _systemDictionaryObj;        }
00119   static objArrayOop pic_free_list()           { return _pic_free_list;              }
00120 
00121   
00122   static oop         callBack_receiver()       { return _callBack_receiver;          }
00123   static symbolOop   callBack_selector()       { return _callBack_selector;          }
00124   static void set_callBack(oop receiver, symbolOop selector) {
00125     _callBack_receiver = receiver;
00126     _callBack_selector = selector;
00127   }
00128 
00129   static oop         dll_lookup_receiver()     { return _dll_lookup_receiver;        }
00130   static symbolOop   dll_lookup_selector()     { return _dll_lookup_selector;        }
00131   static void set_dll_lookup(oop receiver, symbolOop selector) {
00132     _dll_lookup_receiver = receiver;
00133     _dll_lookup_selector = selector;
00134   }
00135 
00136   static methodOop         sweeper_method()        { return _sweeper_method;         }
00137   static void set_sweeper_method(methodOop method) { _sweeper_method = method;       }
00138 
00139   static objArrayOop objectIDTable()           { return _objectIDTable;              }
00140   static void set_objectIDTable(objArrayOop array) {
00141     _objectIDTable = array;
00142   }
00143 
00144   // Version numbers
00145   //   increment snapshot_version whenever old snapshots will break; reset
00146   //   it to zero when changing the minor or major version
00147   static int major_version()    { return 1; }
00148   static int minor_version()    { return 1; }
00149   //static int minor_version()    { return 0; }
00150   static char* beta_version()   { return "alpha5"; }
00151   static int snapshot_version() { return 3; }
00152 
00153   // Check root is not badOop
00154   static void check_root(oop* p);
00155 
00156   // Iterates over roots defined in Universe
00157   static void roots_do(void f(oop*));
00158 
00159   // Iterates through all oops of Universe/Zone
00160   static void oops_do(void f(oop*));
00161 
00162   // Iterates over all active classes and mixins in the system.
00163   // Active means reachable from the clases in the system dictionary.
00164   static void classes_do(klassOopClosure* iterator);
00165 
00166   static void methods_do(void f(methodOop method));
00167 
00168  private:
00169   static void classes_for_do(klassOop klass, klassOopClosure* iterator);
00170   static void methods_in_array_do(objArrayOop array, void f(methodOop method));
00171   static void methods_for_do(klassOop klass, void f(methodOop method));
00172   friend class MethodsClosure;
00173 
00174  public:
00175 
00176   static newGeneration new_gen;
00177   static oldGeneration old_gen;
00178 
00179   static symbolTable* symbol_table;
00180   static rSet*        remembered_set;
00181   static ageTable*    age_table;
00182 
00183 #ifdef DELTA_COMPILER
00184   static zone* code;
00185 #endif
00186 
00187   // additional variables
00188   static int tenuring_threshold;
00189   static int scavengeCount;
00190 
00191     // space operations
00192   static bool is_heap(oop* p) {
00193     return new_gen.contains(p) || old_gen.contains(p); }
00194 
00195   static oop* object_start(oop* p);
00196   
00197   // relocate is used for moving objects around after reading in a snapshot
00198   static memOop relocate(memOop p);
00199 
00200   static bool verify_oop(memOop p);
00201   static bool really_contains(void *p);
00202   static space* spaceFor(void* p);
00203 
00204   static generation* generation_containing(oop p) {
00205     return new_gen.contains(p) ? (generation*)&new_gen : (generation*)&old_gen; }
00206   
00207   // allocators
00208   static oop* allocate(int size, memOop* p = NULL) {
00209     oop* obj = new_gen.allocate(size);
00210     return obj ? obj : scavenge_and_allocate(size, (oop*) p);
00211   }
00212 
00213   static oop* allocate_without_scavenge(int size) {
00214     oop* obj = new_gen.allocate(size);
00215     return obj ? obj : allocate_tenured(size);
00216   }
00217 
00218   static oop* allocate_tenured(int size) {
00219     return old_gen.allocate(size); 
00220   }
00221 
00222   // Tells whether we should force a garbage collection
00223   static bool needs_garbage_collection();
00224 
00225   // tells if the vm is in a state where we can scavenge.
00226   static bool can_scavenge();
00227 
00228   // scavenging operations.
00229   static oop* scavenge_and_allocate(int size, oop* p);
00230 
00231   static void scavenge(oop* p = NULL);
00232   static oop tenure(oop p = NULL);
00233   static void default_low_space_handler(oop p= NULL);
00234   
00235   static void need_scavenge() {
00236     if (! NeedScavenge) {
00237       NeedScavenge = true;
00238       // setupPreemption();
00239     }
00240   }
00241   static bool needs_scavenge() { return NeedScavenge; }
00242   
00243   static bool should_scavenge(memOop p) {
00244     return !(((char*) p > Universe::old_gen.low_boundary) || Universe::new_gen.to()->contains(p)); }
00245 
00246   static inline oop* allocate_in_survivor_space(memOop p, int size, bool &is_new);
00247   
00248   static int free()      { return old_gen.free();      }
00249   
00250 private:
00251   static void  get_space_sizes();
00252 
00253   static char* check_eden_size(spaceSizes &snap_sizes);
00254   static char* check_surv_size(spaceSizes &snap_sizes);
00255   static char* check_old_size(spaceSizes &snap_sizes);
00256 
00257 public:
00258   static void  genesis();
00259   static spaceSizes current_sizes;
00260 
00261 public:  
00262   // operations: we need extras because of include file orderings
00263   static void store(oop* p, smiOop contents) { *(smiOop*)p = contents;}
00264   static inline void store(oop* p, oop contents, bool cs= true);
00265   
00266   static void cleanup_after_bootstrap();
00267   
00268   static void switch_pointers(oop from, oop to);
00269 
00270   static void verify(bool postScavenge = false);
00271 
00272   // printing operations
00273   static void print();
00274   static void print_layout();
00275   static void decode_methods();
00276   static void objectSizeHistogram(int maxSize);
00277 
00278   // Iterator
00279   static void object_iterate(ObjectClosure* blk);
00280   static void root_iterate(OopClosure* blk);
00281 
00282   // System dictionary manipulation
00283   static void add_global(oop value);
00284   static void remove_global_at(int index);
00285 
00286 public:
00287   static char* printAddr; // used for debug printing
00288 
00289   static void printRegion(char *&caddr, int count= 16);
00290 
00291   // for debugging
00292   static void print_klass_name(klassOop k);
00293   static char* klass_name(klassOop k);
00294   static klassOop method_holder_of(methodOop m);
00295   static symbolOop find_global_key_for(oop value, bool* meta);
00296   static oop find_global(char* name, bool must_be_constant = false);
00297   static associationOop find_global_association(char* name);
00298 
00299  public:
00300   static void scavenge_oop(oop* p);
00301 
00302   // flushes inline caches in all methodOops
00303   static void flush_inline_caches_in_methods();
00304 
00305   // clean all inline caches in methodOops and nmethods
00306   static void cleanup_all_inline_caches();
00307 
00308  private:
00309   static void methodOops_do(void f(methodOop));
00310   static void flush_inline_caches_in_method(methodOop method);
00311 
00312  public:
00313   static bool on_page_boundary(void* addr);
00314   static int  page_size();
00315 };
00316 
00317 # define STORE_OOP(ADDR, VALUE) Universe::store((oop*) ADDR, (oop) VALUE)
00318 inline void scavenge_oop(oop* p) { *p = (*p)->scavenge(); }
00319 
00320 inline void scavenge_tenured_oop(oop* p) {
00321   scavenge_oop(p);
00322   if ((*p)->is_new()) {
00323     Universe::remembered_set->record_store(p);
00324   }
00325 }
00326 
00327 inline oop* min(oop* a, oop* b) { return a > b ? b : a; }
00328 inline oop* max(oop* a, oop* b) { return a > b ? a : b; }
00329   
00330 
00331 class BlockScavenge {
00332  private:
00333   static int counter;
00334  public:
00335   static bool is_blocked() { return counter > 0; }
00336 
00337   BlockScavenge()  { counter++; }
00338   ~BlockScavenge() { counter--; }
00339 };
00340 
00341 
00342 // Lars, please complete this at some point
00343 class VerifyNoScavenge : public StackObj {
00344  private:
00345   int  _scavengeCount;
00346 
00347  public:
00348   VerifyNoScavenge() {
00349     _scavengeCount   = Universe::scavengeCount;
00350   }
00351 
00352   virtual ~VerifyNoScavenge() {
00353     if (_scavengeCount != Universe::scavengeCount ) {
00354       fatal("scavenge should not have happened");
00355     }
00356   }
00357 };
00358 
00359 class VerifyNoAllocation : public VerifyNoScavenge {
00360  private:
00361   oop* _top_of_eden;
00362 
00363  public:
00364   VerifyNoAllocation()  {
00365     _top_of_eden     = Universe::new_gen.eden()->top();
00366   }
00367 
00368   virtual ~VerifyNoAllocation() {
00369     if (_top_of_eden != Universe::new_gen.eden()->top()) {
00370       fatal("allocation should not have happened");
00371     }
00372   }
00373 };
00374 
00375 
00376 # define OOPS_DO_TEMPLATE(p, f)                                               \
00377     (*f)((oop*)p);
00378 
00379 # define SCAVENGE_TEMPLATE(p)                                                 \
00380     *((oop*) p) = oop(*p)->scavenge();
00381 
00382 # define VERIFY_TEMPLATE(p)                                                   \
00383     if (!oop(*p)->verify()) lprintf("\tof object at %#lx\n", p);
00384 
00385 # define SWITCH_POINTERS_TEMPLATE(p)                                          \
00386     if ((oop) *p == (oop) from) *((oop*) p) = (oop) to;
00387 
00388 # define RELOCATE_TEMPLATE(p)                                                 \
00389     *((oop*) p) = oop(*p)->relocate();
00390     
00391 # define APPLY_TO_YOUNG_SPACE_NAMES(template)                                 \
00392     template(eden())                                                            \
00393     template(from())                                                            \
00394     template(to())                                                      
00395 
00396 # define APPLY_TO_YOUNG_SPACES(template)                                      \
00397     template(new_gen.eden())                                             \
00398     template(new_gen.from())                                             \
00399     template(new_gen.to())                                               
00400 
00401 #define APPLY_TO_OLD_SPACES(template)                                         \
00402     {FOR_EACH_OLD_SPACE(s) {template(s);}}
00403 
00404 # define APPLY_TO_SPACES(template)                                            \
00405     APPLY_TO_YOUNG_SPACES(template)                                           \
00406     APPLY_TO_OLD_SPACES(template)
00407 
00408 # define YOUNG_SPACE_COMPACT_TEMPLATE(s)                                      \
00409     c2= s; s->compact(c2, d);
00410 
00411 # define OLD_SPACE_COMPACT_TEMPLATE(s)                                        \
00412     s->compact(c2, d);
00413 
00414 # define SPACE_VERIFY_TEMPLATE(s)                                             \
00415     s->verify();
00416 
00417 # define SPACE_RELOCATE_TEMPLATE(s)                                           \
00418     s->relocate();
00419 
00420 # define SPACE_NEED_TO_RELOCATE_TEMPLATE(s)                                   \
00421     need_to_relocate |= s->need_to_relocate();
00422 
00423 # define SPACE_FIXUP_KILLABLES_TEMPLATE(s)                                    \
00424     s->fixup_killables(okZone);
00425 
00426 # define SPACE_OOP_RELOCATE_TEMPLATE(s)                                       \
00427     if (s->old_contains(p)) return s->relocate_objs(p);
00428 
00429 # define SPACE_VERIFY_OOP_TEMPLATE(s)                                         \
00430     if (s->contains(p)) return true;

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