universe.cpp

Go to the documentation of this file.
00001 /* Copyright 1994 - 1996 LongView Technologies L.L.C. $Revision: 1.94 $ */
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/_universe.cpp.incl"
00027 
00028 bool NeedScavenge  = false;
00029 bool bootstrapping = true;
00030 
00031 int BlockScavenge::counter = 0;
00032 
00033 
00034 void Universe::genesis() {
00035   ResourceMark rm;
00036 
00037   /*
00038   std->print_cr("Delta version %d.%d%s (%s %s).",
00039                 Universe::major_version(), Universe::minor_version(), Universe::beta_version(), 
00040                 __DATE__, __TIME__);
00041   std->print_cr("Copyright 1994 - 1996, LongView Technologies L.L.C. All rights reserved.");
00042   std->print_cr("(use argument -? for a list of flags)");
00043   */
00044   
00045   std->cr();
00046   Disclaimer::print_disclaimer();
00047   std->print_cr("Version %d.%d (build %s %s)", Universe::major_version(), Universe::minor_version(), __DATE__, __TIME__);
00048   std->print_cr("(use argument -? for a list of flags)");
00049   std->cr();
00050 
00051   if (UseNewBackend | TryNewBackend)    std->print_cr("- VM using new backend (%s makeConformant)", UseNewMakeConformant ? "new" : "old");
00052   //if (Disclaimer::is_product())       Disclaimer::print_disclaimer();
00053   if (Disclaimer::is_debug())           std->print_cr("- VM is in debug mode");
00054   if (!Interpreter::is_optimized())     Interpreter::print_code_status();
00055   
00056   scavengeCount = 0;
00057 
00058   current_sizes.initialize();
00059 
00060   symbol_table = new symbolTable;
00061 
00062   age_table = new ageTable;
00063 
00064   // Reserve space for object heap 
00065   ReservedSpace rs(current_sizes.reserved_object_size);
00066 
00067   if (!rs.is_reserved()) {
00068     fatal("could not reserve enough space for object heap");
00069   }
00070  
00071   int new_size = ReservedSpace::page_align_size(current_sizes.eden_size + 2 * current_sizes.surv_size);
00072 
00073   ReservedSpace new_rs = rs.first_part(new_size);
00074   ReservedSpace old_rs = rs.last_part(new_size);
00075 
00076   new_gen.initialize(new_rs, current_sizes.eden_size, current_sizes.surv_size);
00077   old_gen.initialize(old_rs, current_sizes.old_size);
00078 
00079   assert(new_gen.high_boundary <= old_gen.low_boundary, "old space allocated lower than new space!");
00080 
00081   remembered_set = new rSet; // uses _boundary's
00082 
00083   tenuring_threshold = ageTable::table_size;    // don't tenure anything at first
00084 
00085   lookupCache::flush();
00086 
00087 # ifdef DELTA_COMPILER
00088   code = new zone(current_sizes.code_size);
00089 # endif
00090 }
00091 
00092 
00093 void Universe::cleanup_after_bootstrap() {
00094   objectIDTable::cleanup_after_bootstrap();
00095 
00096   Universe::_callBack_receiver = nilObj();
00097   Universe::_callBack_selector = symbolOop(nilObj());
00098 
00099   Universe::_dll_lookup_receiver = nilObj();
00100   Universe::_dll_lookup_selector = symbolOop(nilObj());  
00101 
00102   Universe::_pic_free_list = objArrayKlass::allocate_tenured_pic(number_of_interpreterPIC_sizes);
00103 
00104   Universe::_characterKlassObj = klassOop(find_global("Character"));
00105   // Check if all roots are valid.
00106   Universe::roots_do(Universe::check_root);
00107 }
00108 
00109 
00110 void Universe::check_root(oop* p) {
00111   if (*p == badOop) fatal("badOop found in roots");
00112 }
00113 
00114 
00115 void Universe::switch_pointers(oop from, oop to) {
00116   assert(from->is_mem() && to->is_mem(),
00117          "unexpected kind of pointer switching");
00118   // FIX LATER  assert(!from->is_old() || to->is_old(),
00119   //            "shouldn't be switching an old oop to a new oop");
00120   //APPLY_TO_VM_OOPS(SWITCH_POINTERS_TEMPLATE);
00121   new_gen.switch_pointers(from, to);
00122   old_gen.switch_pointers(from, to);
00123   // FIX LATER  processes->switch_pointers(from, to);
00124   symbol_table->switch_pointers(from, to);
00125 }
00126 
00127 
00128 memOop Universe::relocate(memOop p) {
00129   //APPLY_TO_SPACES(SPACE_OOP_RELOCATE_TEMPLATE);
00130   ShouldNotReachHere(); // oop not in any old space
00131   return NULL;
00132 }
00133 
00134 
00135 bool Universe::verify_oop(memOop p) {
00136   if (new_gen.eden()->contains(p)) return true;
00137   if (new_gen.from()->contains(p)) return true;
00138   if (old_gen.contains(p)) return true;
00139   if (new_gen.to()->contains(p)) {
00140     error("memOop %#lx is in to_space", p);
00141   } else {
00142     error("memOop %#lx not in any space", p);
00143   }
00144   return false;
00145 }
00146 
00147 
00148 void Universe::verify(bool postScavenge) {
00149   ResourceMark rm;
00150   lprintf("verifying ");
00151   lprintf("newgen: ");  new_gen.verify();
00152   lprintf("oldgen: ");  old_gen.verify();
00153   lprintf("r ");        remembered_set->verify(postScavenge);
00154   lprintf("S ");        symbol_table->verify();
00155   lprintf("P ");        Processes::verify();
00156   lprintf(" done\n");
00157 }
00158 
00159 
00160 void Universe::print() {
00161   std->print_cr("Memory:");
00162   new_gen.print();
00163   old_gen.print();
00164   if (WizardMode) {
00165     std->print_cr("  (threshold=%d)", tenuring_threshold);
00166   }
00167 }
00168 
00169 
00170 oop* Universe::object_start(oop* p) {
00171   if(new_gen.contains(p)) return new_gen.object_start(p);
00172   return old_gen.object_start(p);
00173 }
00174 
00175 
00176 class PrintClosure: public ObjectClosure {
00177   void do_object(memOop obj) { 
00178     PrintObjectClosure blk(std);
00179     blk.do_object(obj);
00180     obj->layout_iterate(&blk);
00181   }
00182 };
00183 
00184 
00185 void Universe::print_layout() {
00186   PrintClosure blk;
00187   object_iterate(&blk);
00188 }
00189 
00190 
00191 static void decode_method(methodOop method, klassOop klass) {
00192   if (WizardMode) {
00193     ResourceMark rm;
00194     method->print_codes();
00195   }
00196   { ResourceMark rm;
00197     method->print();
00198     prettyPrinter::print(method, klass);
00199   }
00200 }
00201 
00202 
00203 static void decode_klass(symbolOop name, klassOop klass) {
00204   // Klass methods
00205   { 
00206     objArrayOop f = klass->klass_part()->methods();
00207     for (int index = 1; index <= f->length(); index ++)
00208     decode_method(methodOop(f->obj_at(index)), klass);
00209   }
00210   // Mixin methods
00211   {
00212     objArrayOop f = klass->klass_part()->mixin()->methods();
00213     for (int index = 1; index <= f->length(); index ++)
00214     decode_method(methodOop(f->obj_at(index)), klass);
00215   }
00216 }
00217 
00218 
00219 void Universe::decode_methods() {
00220   int l = Universe::systemDictionaryObj()->length();
00221   for (int index = 1; index <= l; index++) {
00222      associationOop assoc = 
00223        (associationOop) Universe::systemDictionaryObj()->obj_at(index);
00224      if (assoc->value()->is_klass())
00225         decode_klass(assoc->key(), klassOop(assoc->value()));
00226   }
00227 }
00228 
00229 
00230 void Universe::object_iterate(ObjectClosure* blk) {
00231   new_gen.object_iterate(blk);
00232   old_gen.object_iterate(blk);
00233 }
00234 
00235 
00236 static OopClosure* the_blk;
00237 static void the_func(oop* p) {
00238   the_blk->do_oop(p);
00239 }
00240 
00241 
00242 void Universe::root_iterate(OopClosure* blk) {
00243   the_blk = blk;
00244   Universe::oops_do(the_func);
00245 }
00246 
00247 
00248 // Traverses the system dictionary to find the 
00249 // association referring the class or meta class
00250 // and then prints the key.
00251 void Universe::print_klass_name(klassOop k) {
00252   int l = systemDictionaryObj()->length();
00253   for (int index = 1; index <= l; index++) {
00254      associationOop assoc = 
00255        (associationOop) systemDictionaryObj()->obj_at(index);
00256      if (assoc->value() == k) {
00257         assoc->key()->print_symbol_on();
00258         return;
00259      } else if (assoc->value()->klass() == k) {
00260         assoc->key()->print_symbol_on();
00261         lprintf(" class");
00262         return;
00263      }
00264   }
00265 }
00266 
00267 
00268 char* Universe::klass_name(klassOop k) {
00269   if (k == NULL) return "(NULL)";
00270   int l = systemDictionaryObj()->length();
00271   for (int index = 1; index <= l; index++) {
00272      associationOop assoc = 
00273        (associationOop) systemDictionaryObj()->obj_at(index);
00274      if (assoc->value() == k) {
00275         return assoc->key()->as_string();
00276      } else if (assoc->value()->klass() == k) {
00277         symbolOop name = assoc->key();
00278         char* result = NEW_RESOURCE_ARRAY(char, name->length()+7);
00279         sprintf(result, "%s class", name->as_string());
00280         return result;
00281      }
00282   }
00283   // it's an unknown class (mixin invocation)
00284   klassOop super = k->klass_part()->superKlass();
00285   if (super != ::nilObj) {
00286     char* superName = klass_name(super);
00287     const char* txt = "unnamed class inheriting from ";
00288     char* result = NEW_RESOURCE_ARRAY(char, strlen(txt) + strlen(superName) + 2);
00289     sprintf(result, "%s%s", txt, superName);
00290     return result;
00291   } else {
00292     return "<top>";
00293   }
00294 }
00295 
00296 
00297 klassOop Universe::method_holder_of(methodOop m) {
00298   m = m->home();        // so block methods can be found, too
00299   int l = systemDictionaryObj()->length();
00300   for (int index = 1; index <= l; index++) {
00301      associationOop assoc = 
00302        (associationOop) systemDictionaryObj()->obj_at(index);
00303      if (assoc->value()->is_klass()) {
00304        klassOop k = klassOop(assoc->value());
00305        klassOop res;
00306        if ((res = k->klass_part()->lookup_method_holder_for(m)) != NULL) {
00307          // note: do search this way because not all superclasses are in system dictionary
00308          return res;
00309        } else if ((res = k->klass()->klass_part()->lookup_method_holder_for(m)) != NULL) {
00310          return res;    // in metaclass hierarchy
00311        }
00312      }
00313   }
00314   if (WizardMode) warning("could not find methodHolder of method %#x", m);
00315   return NULL;  
00316 }
00317 
00318 
00319 symbolOop Universe::find_global_key_for(oop value, bool* meta) {
00320   *meta = false;
00321   int l = systemDictionaryObj()->length();
00322   for (int index = 1; index <= l; index++) {
00323      associationOop assoc =  associationOop(systemDictionaryObj()->obj_at(index));
00324      if (assoc->is_constant() && assoc->value()->is_klass()) {
00325        if (assoc->value() == value) {
00326          return assoc->key();
00327        } else {
00328          klassOop s = klassOop(assoc->value())->klass();
00329          if (s == value) {
00330            *meta = true;
00331            return assoc->key();
00332          }
00333        }
00334      }
00335   }
00336   return NULL;
00337 }
00338 
00339 
00340 oop Universe::find_global(char* name, bool must_be_constant) {
00341   if (!must_be_constant) {
00342     if (strcmp(name, "true")  == 0 ) return trueObj();
00343     if (strcmp(name, "false") == 0 ) return falseObj();
00344     if (strcmp(name, "nil")   == 0 ) return nilObj();
00345   }
00346 
00347   symbolOop sym = oopFactory::new_symbol(name);
00348 
00349   int l = systemDictionaryObj()->length();
00350   for (int index = 1; index <= l; index++) {
00351      associationOop assoc = associationOop(systemDictionaryObj()->obj_at(index));
00352      if (assoc->key() == sym) {
00353        if (!must_be_constant || assoc->is_constant()) {
00354          return assoc->value();
00355        }
00356      }
00357   }
00358   return NULL;
00359 }
00360 
00361 
00362 associationOop Universe::find_global_association(char* name) {
00363   symbolOop sym = oopFactory::new_symbol(name);
00364 
00365   int l = systemDictionaryObj()->length();
00366   for (int index = 1; index <= l; index++) {
00367      associationOop assoc = 
00368        (associationOop) systemDictionaryObj()->obj_at(index);
00369      if (assoc->key() == sym) return assoc;
00370   }
00371   return NULL;
00372 }
00373 
00374 
00375 void Universe::methods_in_array_do(objArrayOop array, void f(methodOop method)) {
00376   int length = array->length();
00377   for (int index = 1; index <= length; index++) {
00378     methodOop method = methodOop(array->obj_at(index));
00379     assert(method->is_method(), "just checking");
00380     f(method);
00381   }
00382 }
00383 
00384 void Universe::methods_for_do(klassOop klass, void f(methodOop method)) {
00385   Klass* k = klass->klass_part();
00386   methods_in_array_do(k->methods(), f);
00387   methods_in_array_do(klass->klass()->klass_part()->methods(), f);
00388   if (k->is_named_class()) {
00389     // Fix the mixin parts
00390     methods_in_array_do(k->mixin()->methods(), f);
00391     methods_in_array_do(klass->klass()->klass_part()->mixin()->methods(), f);
00392   }
00393 }
00394 
00395 class MethodsClosure : public klassOopClosure {
00396   void (*f)(methodOop method);
00397 public:  
00398   MethodsClosure(void f(methodOop method)) {
00399     this->f = f; 
00400   }
00401   void do_klass(klassOop klass) {
00402     Universe::methods_for_do(klass, f);
00403   }
00404 };
00405 
00406 void Universe::methods_do(void f(methodOop method)) {
00407   MethodsClosure it(f);
00408   classes_do(&it);
00409 }
00410 
00411 void Universe::classes_for_do(klassOop klass, klassOopClosure* iterator) {
00412   // call f with the class
00413   iterator->do_klass(klass);
00414   // recurse if the super class is a anonymous class
00415   if (!klass->klass_part()->has_superKlass()) return;
00416   if (!klass->klass_part()->superKlass()->klass_part()->is_named_class()) return;
00417   classes_for_do(klass->klass_part()->superKlass(), iterator);
00418 }
00419 
00420 
00421 void Universe::classes_do(klassOopClosure* iterator) {
00422   objArrayOop array  = Universe::systemDictionaryObj();
00423   int         length = array->length();
00424   for (int index = 1; index <= length; index++) {
00425     associationOop assoc = associationOop(array->obj_at(index));
00426     assert(assoc->is_association(), "just checking");
00427     if (assoc->is_constant() && assoc->value()->is_klass()) {
00428       classes_for_do(klassOop(assoc->value()), iterator);
00429     }
00430   }
00431 }
00432 
00433 void Universe::flush_inline_caches_in_method(methodOop method) {
00434   method->clear_inline_caches();
00435 }
00436 
00437 class FlushClosure: public ObjectClosure {
00438   void do_object(memOop obj) {
00439     if (obj->is_method()) 
00440       methodOop(obj)->clear_inline_caches();
00441   }
00442 };
00443 
00444 void Universe::flush_inline_caches_in_methods() {
00445   FlushClosure blk;
00446   object_iterate(&blk);
00447 }
00448 
00449 class AllMethodsClosure: public ObjectClosure {
00450   void (*f)(methodOop m);
00451  public:
00452   AllMethodsClosure(void f(methodOop m)) {
00453     this->f = f;
00454   }
00455    
00456   void do_object(memOop obj) {
00457     if (obj->is_method())
00458       f(methodOop(obj));
00459   }
00460 };
00461 
00462 void Universe::methodOops_do(void f(methodOop m)) {
00463   AllMethodsClosure blk(f);
00464   object_iterate(&blk);
00465 }
00466 
00467 static void cleanup_method(methodOop m) {
00468   m->cleanup_inline_caches();
00469 }
00470 
00471 void Universe::cleanup_all_inline_caches() {
00472   DeltaCallCache::clearAll();
00473   methodOops_do(cleanup_method);
00474   code->cleanup_inline_caches();
00475 }
00476 
00477 void universe_init() {
00478   Universe::genesis();
00479 }
00480 
00481 newGeneration Universe::new_gen;
00482 oldGeneration Universe::old_gen;
00483 
00484 symbolTable* Universe::symbol_table;
00485 rSet*        Universe::remembered_set;
00486 ageTable*    Universe::age_table;
00487 
00488 #ifdef DELTA_COMPILER
00489 zone* Universe::code;
00490 #endif
00491 
00492 spaceSizes Universe::current_sizes;
00493 
00494 int Universe::tenuring_threshold;
00495 int Universe::scavengeCount;
00496 
00497 // Classes
00498 klassOop smiKlassObj                           = klassOop(badOop);
00499 klassOop contextKlassObj                       = klassOop(badOop);
00500 klassOop doubleKlassObj                        = klassOop(badOop);
00501 klassOop Universe::_memOopKlassObj             = klassOop(badOop);
00502 klassOop Universe::_objArrayKlassObj           = klassOop(badOop);
00503 klassOop Universe::_byteArrayKlassObj          = klassOop(badOop);
00504 klassOop symbolKlassObj                        = klassOop(badOop);
00505 klassOop Universe::_associationKlassObj        = klassOop(badOop);
00506 klassOop zeroArgumentBlockKlassObj             = klassOop(badOop);
00507 klassOop oneArgumentBlockKlassObj              = klassOop(badOop);
00508 klassOop twoArgumentBlockKlassObj              = klassOop(badOop);
00509 klassOop threeArgumentBlockKlassObj            = klassOop(badOop);
00510 klassOop fourArgumentBlockKlassObj             = klassOop(badOop);
00511 klassOop fiveArgumentBlockKlassObj             = klassOop(badOop);
00512 klassOop sixArgumentBlockKlassObj              = klassOop(badOop);
00513 klassOop sevenArgumentBlockKlassObj            = klassOop(badOop);
00514 klassOop eightArgumentBlockKlassObj            = klassOop(badOop);
00515 klassOop nineArgumentBlockKlassObj             = klassOop(badOop);
00516 klassOop Universe::_methodKlassObj             = klassOop(badOop);
00517 klassOop Universe::_characterKlassObj          = klassOop(badOop);
00518 klassOop doubleValueArrayKlassObj              = klassOop(badOop);
00519 klassOop Universe::_vframeKlassObj             = klassOop(badOop);
00520 
00521 // Objects
00522 oop         nilObj                             = oop(badOop);
00523 oop         trueObj                            = oop(badOop);
00524 oop         falseObj                           = oop(badOop);
00525 objArrayOop Universe::_asciiCharacters         = objArrayOop(badOop);
00526 objArrayOop Universe::_systemDictionaryObj     = objArrayOop(badOop);
00527 objArrayOop Universe::_objectIDTable           = objArrayOop(badOop);
00528 objArrayOop Universe::_pic_free_list           = objArrayOop(badOop); 
00529 oop         Universe::_callBack_receiver       = oop(badOop);
00530 symbolOop   Universe::_callBack_selector       = symbolOop(badOop);
00531 oop         Universe::_dll_lookup_receiver     = oop(badOop);
00532 symbolOop   Universe::_dll_lookup_selector     = symbolOop(badOop);
00533 methodOop   Universe::_sweeper_method          = NULL;
00534 
00535 
00536 void Universe::roots_do(void f(oop*)) {
00537   // External Objects
00538   f((oop*)&::nilObj);
00539   f((oop*)&::trueObj);
00540   f((oop*)&::falseObj);
00541 
00542   // External Classes
00543   f((oop*)&::smiKlassObj);
00544   f((oop*)&::contextKlassObj);
00545   f((oop*)&::doubleKlassObj);
00546 
00547   // Classes
00548   f((oop*)&_memOopKlassObj);
00549   f((oop*)&_objArrayKlassObj);
00550   f((oop*)&_byteArrayKlassObj);
00551   f((oop*)&::symbolKlassObj);
00552   f((oop*)&_associationKlassObj);
00553   f((oop*)&::zeroArgumentBlockKlassObj);
00554   f((oop*)&::oneArgumentBlockKlassObj);
00555   f((oop*)&::twoArgumentBlockKlassObj);
00556   f((oop*)&::threeArgumentBlockKlassObj);
00557   f((oop*)&::fourArgumentBlockKlassObj);
00558   f((oop*)&::fiveArgumentBlockKlassObj);
00559   f((oop*)&::sixArgumentBlockKlassObj);
00560   f((oop*)&::sevenArgumentBlockKlassObj);
00561   f((oop*)&::eightArgumentBlockKlassObj);
00562   f((oop*)&::nineArgumentBlockKlassObj);
00563   f((oop*)&_methodKlassObj);
00564   f((oop*)&_characterKlassObj);
00565   // fix f((oop*)&::doubleValueArrayKlassObj);
00566 
00567   // Objects
00568   f((oop*)&_asciiCharacters);
00569   f((oop*)&_systemDictionaryObj);
00570   f((oop*)&_objectIDTable);
00571   f((oop*)&_callBack_receiver);
00572   f((oop*)&_callBack_selector);
00573   f((oop*)&_dll_lookup_receiver);
00574   f((oop*)&_dll_lookup_selector);
00575   f((oop*)&_pic_free_list);
00576 
00577   f((oop*)&_sweeper_method);
00578 
00579   f((oop*)&_vframeKlassObj);
00580 }
00581 
00582 
00583 void Universe::oops_do(void f(oop*)) {
00584   // Iterate over the local roots
00585   roots_do(f);
00586   // Iterate over the zone
00587   code->oops_do(f);
00588   // Iterate over all handles
00589   Handles::oops_do(f);
00590   // Iterate over the oops in the inlining database
00591   InliningDatabase::oops_do(f);
00592 }
00593 
00594 
00595 void Universe::add_global(oop value) {
00596   _systemDictionaryObj = _systemDictionaryObj->copy_add(value);
00597 }
00598 
00599 void Universe::remove_global_at(int index) {
00600   _systemDictionaryObj = _systemDictionaryObj->copy_remove(index);
00601 }
00602 
00603 bool Universe::on_page_boundary(void* addr) {
00604   return ((int) addr) % page_size() == 0;
00605 }
00606 
00607 int Universe::page_size() {
00608   return os::vm_page_size();
00609 }

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