bootstrap.cpp

Go to the documentation of this file.
00001 /* Copyright 1994, 1995 LongView Technologies L.L.C. $Revision: 1.53 $ */
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 # include "incls/_precompiled.incl"
00025 # include "incls/_bootstrap.cpp.incl"
00026 
00027 #include <io.h>
00028 
00029 bootstrap::bootstrap(char* name) {
00030   file_name = name;
00031   _has_error = false;
00032   open_file();
00033   if (!has_error()) {
00034     initialize_tables(file_size > 0 ? (file_size / 32) : (10 * K));
00035     parse_file();
00036     close_file();
00037     Universe  ::cleanup_after_bootstrap();
00038   }
00039 }
00040 
00041 void bootstrap::initialize_tables(int initial_table_size) {
00042   oop_table          = NEW_C_HEAP_ARRAY(oop, initial_table_size);
00043   max_number_of_oops = initial_table_size;
00044   number_of_oops     = 0;
00045   position           = 0;
00046 }
00047 
00048 bootstrap::~bootstrap() {
00049   FreeHeap(oop_table);
00050 }
00051 
00052 oop bootstrap::at(int index) {
00053   if (index < 0 || index > number_of_oops)
00054     error("bootstrap oop table overflow");
00055   return oop_table[index];
00056 }
00057 
00058 void bootstrap::add(oop obj) {
00059   if (number_of_oops >= max_number_of_oops) {
00060     int new_size = max_number_of_oops  * 2;
00061     printf("Expanding boot table to %d\n", new_size);
00062     oop* new_oop_table = NEW_C_HEAP_ARRAY(oop, new_size);
00063     for(int index = 0; index < max_number_of_oops; index++)
00064       new_oop_table[index] = oop_table[index];
00065    
00066     max_number_of_oops = new_size;
00067     FreeHeap(oop_table);
00068     oop_table = new_oop_table;
00069   }
00070   oop_table[number_of_oops++] = obj;
00071 }
00072 
00073 void bootstrap::open_file() {
00074   stream = fopen(file_name, "rb");
00075   if (stream == NULL) {
00076     _has_error = true;
00077     lprintf("\nCould not open file (%s) for reading!\n", file_name);
00078     exit(-1);
00079   }
00080   int no    = _fileno(stream);
00081   file_size = _filelength(no);
00082 }
00083 
00084 char bootstrap::get_char() {
00085   position++;
00086   return getc(stream);
00087 }
00088 
00089 int bootstrap::get_integer() {
00090   position++;
00091   int result = getc(stream);
00092   if (result == EOF) fatal("end of file");
00093   assert(result >= 0, "must be positive");
00094   if (result < 128 ) return result;
00095   return get_integer() * 128 + result - 128;
00096 }
00097 
00098 void bootstrap::parse_file() {
00099   // Check version number
00100   int version_number = get_integer();
00101 
00102   if (version_number > 100) {
00103     _new_format = true;
00104     lprintf(", n");
00105     version_number -= 100;
00106   } else {
00107     _new_format = false;
00108   }
00109 
00110   if (Bytecodes::version() == version_number) {
00111 
00112   } else {
00113     lprintf("\n");
00114     lprintf("Bytecode version conflict\n");
00115     lprintf(" excpected: %d\n", Bytecodes::version());
00116     lprintf(" received:  %d\n", version_number);
00117     exit(-1);
00118   }
00119 
00120   Universe::_systemDictionaryObj         = objArrayOop(get_object());
00121   nilObj                                 = memOop(get_object());
00122   trueObj                                = memOop(get_object());
00123   falseObj                               = memOop(get_object());
00124   smiKlassObj                            = klassOop(get_object());
00125   Universe::_memOopKlassObj              = klassOop(get_object());
00126   Universe::_objArrayKlassObj            = klassOop(get_object());
00127   Universe::_byteArrayKlassObj           = klassOop(get_object());
00128   symbolKlassObj                         = klassOop(get_object());
00129   doubleKlassObj                         = klassOop(get_object());
00130   Universe::_methodKlassObj              = klassOop(get_object());
00131   Universe::_associationKlassObj         = klassOop(get_object());
00132   zeroArgumentBlockKlassObj              = klassOop(get_object());
00133   oneArgumentBlockKlassObj               = klassOop(get_object());
00134   twoArgumentBlockKlassObj               = klassOop(get_object());
00135   threeArgumentBlockKlassObj             = klassOop(get_object());
00136   fourArgumentBlockKlassObj              = klassOop(get_object());
00137   fiveArgumentBlockKlassObj              = klassOop(get_object());
00138   sixArgumentBlockKlassObj               = klassOop(get_object());
00139   sevenArgumentBlockKlassObj             = klassOop(get_object());
00140   eightArgumentBlockKlassObj             = klassOop(get_object());
00141   nineArgumentBlockKlassObj              = klassOop(get_object());
00142   contextKlassObj                        = klassOop(get_object());
00143   Universe::_asciiCharacters             = objArrayOop(get_object());
00144   Universe::_vframeKlassObj              = HasActivationClass ? klassOop(get_object()) : klassOop(nilObj);
00145 }
00146 
00147 void bootstrap::insert_symbol(memOop obj) {
00148   if (Universe::symbol_table->is_present(symbolOop(obj))) {
00149     lprintf("Symbol ");
00150     symbolOop(obj)->print_value();
00151     lprintf(" already present in symbol_table!\n");
00152   } else {
00153     Universe::symbol_table->add_symbol(symbolOop(obj));
00154   }
00155 }
00156 
00157 # define KLASS_CASE(func)  func(klassOop(m)->klass_part()); klassOop(m)->bootstrap_object(this); break;
00158 # define OBJECT_CASE(cast) cast(m)->bootstrap_object(this); break;
00159 # define OBJECT_ERROR(str) fatal(str); break;
00160 # define SYMBOL_CASE(cast) cast(m)->bootstrap_object(this); insert_symbol(cast(m)); break;
00161 
00162 
00163 oop bootstrap::get_object() {
00164   char type = get_char();
00165   
00166   if (type == '0') {
00167     int v = get_integer();
00168     // if (TraceBootstrap) std->print_cr("i %d", v);
00169     return as_smiOop(v);
00170   }
00171   if (type == '-') { 
00172     int v = get_integer();
00173     // if (TraceBootstrap) std->print_cr("i %d", -v);
00174     return as_smiOop(-v);
00175   }
00176   if (type == '3') {
00177     int v = get_integer();
00178     // if (TraceBootstrap) std->print_cr("r %d", v);
00179     return at(v);
00180   }
00181 
00182   int    size = get_integer();
00183   memOop m    = as_memOop(Universe::allocate_tenured(size));
00184 
00185   // Clear eventual padding area for byteArray, symbol, doubleByteArray.
00186   m->raw_at_put(size-1, smiOop_zero);
00187 
00188   // if (TraceBootstrap) lprintf("%c %d = 0x%lx\n", type, size, m);
00189 
00190   add(m);
00191   switch (type) {
00192     // Classes
00193     case 'A': KLASS_CASE(set_klassKlass_vtbl)
00194     case 'B': KLASS_CASE(set_smiKlass_vtbl)
00195     case 'C': KLASS_CASE(set_memOopKlass_vtbl)
00196     case 'D': KLASS_CASE(set_byteArrayKlass_vtbl)
00197     case 'E': KLASS_CASE(set_doubleByteArrayKlass_vtbl)
00198     case 'F': KLASS_CASE(set_objArrayKlass_vtbl)
00199     case 'G': KLASS_CASE(set_symbolKlass_vtbl)
00200     case 'H': KLASS_CASE(set_doubleKlass_vtbl)
00201     case 'I': KLASS_CASE(set_associationKlass_vtbl)
00202     case 'J': KLASS_CASE(set_methodKlass_vtbl)
00203     case 'K': KLASS_CASE(set_blockClosureKlass_vtbl)
00204     case 'L': KLASS_CASE(set_contextKlass_vtbl)
00205     case 'M': KLASS_CASE(set_proxyKlass_vtbl)
00206     case 'N': KLASS_CASE(set_mixinKlass_vtbl)
00207     case 'O': KLASS_CASE(set_weakArrayKlass_vtbl)
00208     case 'P': KLASS_CASE(set_processKlass_vtbl)
00209     case 'Q': KLASS_CASE(set_doubleValueArrayKlass_vtbl)
00210     case 'R': KLASS_CASE(set_vframeKlass_vtbl)
00211     // Objects
00212     case 'a': OBJECT_ERROR("klass")
00213     case 'b': OBJECT_ERROR("smi")
00214     case 'c': OBJECT_CASE(memOop);
00215     case 'd': OBJECT_CASE(byteArrayOop);
00216     case 'e': OBJECT_CASE(doubleByteArrayOop);
00217     case 'f': OBJECT_CASE(objArrayOop)
00218     case 'g': SYMBOL_CASE(symbolOop);
00219     case 'h': OBJECT_CASE(doubleOop);
00220     case 'i': OBJECT_CASE(associationOop);
00221     case 'j': OBJECT_CASE(methodOop);
00222     case 'k': OBJECT_ERROR("blockClosure")
00223     case 'l': OBJECT_ERROR("context")
00224     case 'm': OBJECT_ERROR("proxy")
00225     case 'n': OBJECT_CASE(mixinOop)
00226     case 'o': OBJECT_ERROR("weakArrayOop")
00227     case 'p': OBJECT_CASE(processOop)
00228     default: fatal("unknown object type");
00229   }
00230 
00231   return m;
00232 }
00233 
00234 void bootstrap::close_file() {
00235   fclose(stream);
00236 }
00237 
00238 void bootstrap::read_mark(markOop* mark_addr) {
00239   char type = get_char();
00240   markOop m;
00241   if      (type == '1') m = markOopDesc::untagged_prototype();
00242   else if (type == '2') m = markOopDesc::tagged_prototype();
00243   else fatal("expecting a markup");
00244   *mark_addr = m;
00245 }
00246 
00247 double bootstrap::read_double() {
00248   double value;
00249   unsigned char* str = (unsigned char*) &value;
00250   for (int index = 0; index < 8; index++) {
00251     position++;
00252     str[index] = getc(stream);
00253   }
00254   return value; 
00255 }

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