00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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
00169 return as_smiOop(v);
00170 }
00171 if (type == '-') {
00172 int v = get_integer();
00173
00174 return as_smiOop(-v);
00175 }
00176 if (type == '3') {
00177 int v = get_integer();
00178
00179 return at(v);
00180 }
00181
00182 int size = get_integer();
00183 memOop m = as_memOop(Universe::allocate_tenured(size));
00184
00185
00186 m->raw_at_put(size-1, smiOop_zero);
00187
00188
00189
00190 add(m);
00191 switch (type) {
00192
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
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 }