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/_klass.cpp.incl"
00026
00027 void Klass::initialize() {
00028 set_untagged_contents(false);
00029 set_classVars(objArrayOop(oopFactory::new_objArray(0)));
00030 set_methods(objArrayOop(oopFactory::new_objArray(0)));
00031 set_superKlass(klassOop(nilObj));
00032 set_mixin(mixinOop(nilObj));
00033 }
00034
00035 oop Klass::allocateObject() {
00036 return markSymbol(vmSymbols::not_oops());
00037 }
00038 oop Klass::allocateObjectSize(int size) {
00039 return markSymbol(vmSymbols::not_oops());
00040 }
00041
00042 void Klass::mark_for_schema_change() {
00043 set_mixin(NULL);
00044 }
00045
00046 bool Klass::is_marked_for_schema_change() {
00047 return mixin() == NULL;
00048 }
00049
00050 Klass::Format Klass::format_from_symbol(symbolOop format) {
00051 if (format->equals("Oops")) return mem_klass;
00052 if (format->equals("ExternalProxy")) return proxy_klass;
00053
00054 if (format->equals("IndexedInstanceVariables")) return objArray_klass;
00055 if (format->equals("IndexedByteInstanceVariables")) return byteArray_klass;
00056 if (format->equals("IndexedDoubleByteInstanceVariables")) return doubleByteArray_klass;
00057 if (format->equals("IndexedNextOfKinInstanceVariables")) return weakArray_klass;
00058 if (format->equals("Special")) return special_klass;
00059 return Klass::no_klass;
00060 }
00061
00062 char* Klass::name_from_format(Format format) {
00063 switch (format) {
00064 case mem_klass: return "Oops";
00065 case proxy_klass: return "ExternalProxy";
00066
00067 case objArray_klass: return "IndexedInstanceVariables";
00068 case byteArray_klass: return "IndexedByteInstanceVariables";
00069 case doubleByteArray_klass: return "IndexedDoubleByteInstanceVariables";
00070 case weakArray_klass: return "IndexedNextOfKinInstanceVariables";
00071 }
00072 return "Special";
00073 }
00074
00075
00076
00077 bool Klass::has_same_layout_as(klassOop klass) {
00078 assert(klass->is_klass(), "argument must be klass");
00079
00080 if (as_klassOop() == klass) return true;
00081
00082
00083 if (format() != klass->klass_part()->format()) return false;
00084
00085
00086 if (non_indexable_size() != klass->klass_part()->non_indexable_size()) return false;
00087
00088
00089 for (int index = oop_header_size(); index < non_indexable_size(); index++) {
00090 if (inst_var_name_at(index) != klass->klass_part()->inst_var_name_at(index)) return false;
00091 }
00092 return true;
00093 }
00094
00095 klassOop Klass::create_subclass(mixinOop mixin, Format format) {
00096 ShouldNotCallThis();
00097 return NULL;
00098 }
00099
00100 klassOop Klass::create_generic_class(klassOop super_class, mixinOop mixin, int vtbl) {
00101 BlockScavenge bs;
00102
00103
00104
00105 assert(mixin->classVars()->is_objArray(), "checking instance side class var names");
00106 assert(mixin->class_mixin()->classVars()->is_objArray(), "checking class side class var names");
00107 assert(mixin->class_mixin()->classVars()->length() == 0, "checking class side class var names");
00108
00109 int length = mixin->number_of_classVars();
00110
00111 objArrayOop class_vars = oopFactory::new_objArray(mixin->number_of_classVars());
00112 for (int index = 1; index <= length; index++) {
00113 associationOop assoc = oopFactory::new_association(mixin->classVar_at(index), nilObj, false);
00114 class_vars->obj_at_put(index, assoc);
00115 }
00116
00117
00118 klassOop meta_klass = klassOop(super_class->klass()->klass()->klass_part()->allocateObject());
00119 Klass* mk = meta_klass->klass_part();
00120 mk->set_untagged_contents(false);
00121 mk->set_classVars(class_vars);
00122 mk->set_methods(oopFactory::new_objArray(0));
00123 mk->set_superKlass(super_class->klass());
00124 mk->set_mixin(mixin->class_mixin());
00125 mk->set_non_indexable_size(klassOopDesc::header_size() + mk->number_of_instance_variables());
00126 set_klassKlass_vtbl(mk);
00127
00128 klassOop klass = klassOop(mk->allocateObject());
00129 Klass* k = klass->klass_part();
00130
00131 k->set_untagged_contents(false);
00132 k->set_classVars(class_vars);
00133 k->set_methods(oopFactory::new_objArray(0));
00134 k->set_superKlass(super_class);
00135 k->set_mixin(mixin);
00136 k->set_vtbl_value(vtbl);
00137 k->set_non_indexable_size(k->oop_header_size() + k->number_of_instance_variables());
00138
00139 return klass;
00140 }
00141
00142 symbolOop Klass::inst_var_name_at(int offset) const {
00143 Klass* current_klass = (Klass*) this;
00144 int current_offset = non_indexable_size();
00145 do {
00146 mixinOop m = current_klass->mixin();
00147 for (int index = m->number_of_instVars(); index > 0; index--) {
00148 current_offset--;
00149 if (offset == current_offset) return m->instVar_at(index);
00150 }
00151 } while(current_klass = (current_klass->superKlass() == nilObj ? NULL : current_klass->superKlass()->klass_part()));
00152 return NULL;
00153 }
00154
00155 int Klass::lookup_inst_var(symbolOop name) const {
00156 int offset = mixin()->inst_var_offset(name, non_indexable_size());
00157 if (offset >= 0) return offset;
00158 return has_superKlass() ? superKlass()->klass_part()->lookup_inst_var(name) : -1;
00159 }
00160
00161 int Klass::number_of_instance_variables() const {
00162 return mixin()->number_of_instVars()
00163 + (has_superKlass() ? superKlass()->klass_part()->number_of_instance_variables() : 0);
00164 }
00165
00166
00167
00168 int Klass::number_of_methods() const {
00169 return methods()->length();
00170 }
00171
00172 methodOop Klass::method_at(int index) const {
00173 return methodOop(methods()->obj_at(index));
00174 }
00175
00176 void Klass::add_method(methodOop method) {
00177 objArrayOop old_array = methods();
00178 symbolOop selector = method->selector();
00179
00180 for (int index = 1; index <= old_array->length(); index++) {
00181 assert(old_array->obj_at(index)->is_method(), "must be method");
00182 methodOop m = methodOop(old_array->obj_at(index));
00183 if (m->selector() == selector) {
00184 old_array->obj_at_put(index, method);
00185 return;
00186 }
00187 }
00188
00189 set_methods(methods()->copy_add(method));
00190 }
00191
00192 methodOop Klass::remove_method_at(int index) {
00193 methodOop method = method_at(index);
00194 set_methods(methods()->copy_remove(index));
00195 return method;
00196 }
00197
00198 int Klass::number_of_classVars() const {
00199 return classVars()->length();
00200 }
00201
00202 associationOop Klass::classVar_at(int index) const {
00203 return associationOop(classVars()->obj_at(index));
00204 }
00205
00206 void Klass::add_classVar(associationOop assoc) {
00207 objArrayOop array = classVars();
00208
00209 for (int index = 1; index <= array->length(); index++) {
00210 assert(array->obj_at(index)->is_association(), "must be symbol");
00211 associationOop elem = associationOop(array->obj_at(index));
00212 if (elem->key() == assoc->key()) return;
00213 }
00214
00215 set_classVars(array->copy_add(assoc));
00216 }
00217
00218 associationOop Klass::remove_classVar_at(int index) {
00219 associationOop assoc = classVar_at(index);
00220 set_classVars(classVars()->copy_remove(index));
00221 return assoc;
00222 }
00223
00224 bool Klass::includes_classVar(symbolOop name) {
00225 objArrayOop array = classVars();
00226 for (int index = 1; index <= array->length(); index++) {
00227 associationOop elem = associationOop(array->obj_at(index));
00228 if (elem->key() == name) return true;
00229 }
00230 return false;
00231 }
00232
00233 associationOop Klass::local_lookup_class_var(symbolOop name) {
00234 objArrayOop array = classVars();
00235 for (int index = 1; index <= array->length(); index++) {
00236 assert(array->obj_at(index)->is_association(), "must be symbol");
00237 associationOop elem = associationOop(array->obj_at(index));
00238 if (elem->key() == name) return elem;
00239 }
00240 return NULL;
00241 }
00242
00243 associationOop Klass::lookup_class_var(symbolOop name) {
00244 associationOop result = local_lookup_class_var(name);
00245 if (result) return result;
00246 result = (superKlass() == nilObj)
00247 ? NULL
00248 : superKlass()->klass_part()->lookup_class_var(name);
00249 return result;
00250 }
00251
00252
00253 inline methodOop Klass::local_lookup(symbolOop selector) {
00254 objArrayOop array;
00255 int length;
00256 oop* current;
00257
00258
00259 array = methods();
00260 length = array->length();
00261 if (length > 0) {
00262 current = array->objs(1);
00263 do {
00264 methodOop method = methodOop(*current++);
00265 assert(method->is_method(), "must be method");
00266 if (method->selector() == selector)
00267 return method;
00268 } while (--length > 0);
00269 }
00270
00271 assert(mixin()->is_mixin(), "mixin must exist");
00272
00273 array = mixin()->methods();
00274 length = array->length();
00275 current = array->objs(1);
00276
00277 while (length-- > 0) {
00278 methodOop method = methodOop(*current++);
00279 assert(method->is_method(), "must be method");
00280 if (method->selector() == selector) {
00281 if (method->should_be_customized()) {
00282 if (as_klassOop() == mixin()->primary_invocation()){
00283 if (!method->is_customized()) method->customize_for(as_klassOop(), mixin());
00284 return method;
00285 } else {
00286 BlockScavenge bs;
00287
00288 methodOop new_method = method->copy_for_customization();
00289 new_method->customize_for(as_klassOop(), mixin());
00290 add_method(new_method);
00291 return new_method;
00292 }
00293 }
00294 return method;
00295 }
00296 }
00297 return NULL;
00298 }
00299
00300 methodOop Klass::lookup(symbolOop selector) {
00301 Klass* current = this;
00302 while (true) {
00303 methodOop result = current->local_lookup(selector);
00304 if (result) return result;
00305 if (current->superKlass() == nilObj) return NULL;
00306 current = current->superKlass()->klass_part();
00307 }
00308 return NULL;
00309 }
00310
00311 bool Klass::is_method_holder_for(methodOop method) {
00312
00313 methodOop m = method->home();
00314
00315 objArrayOop array = methods();
00316
00317 for (int index = 1; index <= array->length(); index++) {
00318 assert(array->obj_at(index)->is_method(), "must be method");
00319 if (methodOop(array->obj_at(index)) == m) return true;
00320 }
00321
00322 if (oop(mixin()) != nilObj) {
00323 assert(mixin()->is_mixin(), "must be mixin");
00324 array = mixin()->methods();
00325 for (int index = 1; index <= array->length(); index++) {
00326 assert(array->obj_at(index)->is_method(), "must be method");
00327 if (methodOop(array->obj_at(index)) == m) return true;
00328 }
00329 }
00330 return false;
00331 }
00332
00333 klassOop Klass::lookup_method_holder_for(methodOop method) {
00334 if (is_method_holder_for(method)) return as_klassOop();
00335 return (superKlass() == nilObj)
00336 ? NULL
00337 : superKlass()->klass_part()->lookup_method_holder_for(method);
00338 }
00339
00340 void Klass::flush_methods() {
00341 set_methods(oopFactory::new_objArray(0));
00342 }
00343
00344 bool Klass::is_specialized_class() const {
00345 memOopKlass m;
00346 return name() == m.name();
00347 }
00348
00349 bool Klass::is_named_class() const {
00350 return mixin()->primary_invocation() == as_klassOop();
00351 }
00352
00353 void Klass::print_klass() {
00354 lprintf("%sKlass (%s)", name(), name_from_format(format()));
00355 }
00356
00357 void Klass::print_name_on(outputStream* st) {
00358 int offset = as_klassOop()->blueprint()->lookup_inst_var(oopFactory::new_symbol("name"));
00359 symbolOop name = NULL;
00360 if (offset >= 0) {
00361 name = symbolOop(as_klassOop()->raw_at(offset));
00362 if (!name->is_symbol()) name = NULL;
00363 }
00364 if (name != NULL) name->print_symbol_on(st);
00365 else {
00366 bool meta;
00367 name = Universe::find_global_key_for(as_klassOop(), &meta);
00368 if (name) {
00369 name->print_symbol_on(st);
00370 if (meta) st->print(" class");
00371 } else {
00372 st->print("??");
00373 }
00374 }
00375 }
00376
00377 int Klass::oop_scavenge_contents(oop obj) {
00378 fatal("should not call Klass::oop_scavenge_contents");
00379 return 0;
00380 }
00381
00382 int Klass::oop_scavenge_tenured_contents(oop obj) {
00383 fatal("should not call Klass::oop_scavenge_promotion");
00384 return 0;
00385 }
00386
00387 void Klass::oop_follow_contents(oop obj) {
00388 fatal("should not call Klass::oop_follow_contents");
00389 }
00390
00391 void Klass::oop_layout_iterate(oop obj, ObjectLayoutClosure* blk) {
00392 fatal("should not call layout_iterate on Klass");
00393 }
00394
00395 void Klass::oop_oop_iterate(oop obj, OopClosure *blk) {
00396 fatal("should not call oop_iterate on Klass");
00397 }
00398
00399 void Klass::oop_print_on (oop obj, outputStream* st) { fatal("should not call Klass::oop_print_on"); }
00400 void Klass::oop_print_value_on(oop obj, outputStream* st) { oop_print_on(obj, st); }
00401 void Klass::oop_short_print_on(oop obj, outputStream* st) {
00402 if (obj == trueObj) {
00403 st->print("true");
00404 } else if (obj == falseObj) {
00405 st->print("false");
00406 } else if (obj == nilObj) {
00407 st->print("nil");
00408 } else {
00409 oop_print_value_on(obj, st);
00410 }
00411 }
00412
00413 bool Klass::oop_verify(oop obj) {
00414
00415 return true;
00416 }
00417
00418 void Klass::bootstrap_klass_part_one(bootstrap* st) {
00419 st->read_oop((oop*)&_non_indexable_size);
00420 st->read_oop((oop*)&_has_untagged_contents);
00421 }
00422
00423 void Klass::bootstrap_klass_part_two(bootstrap* st) {
00424 st->read_oop((oop*)&_classVars);
00425 st->read_oop((oop*)&_methods);
00426 st->read_oop((oop*)&_superKlass);
00427 st->read_oop((oop*)&_mixin);
00428 }
00429
00430 oop Klass::oop_primitive_allocate(oop obj) {
00431 return markSymbol(vmSymbols::not_klass()); }
00432
00433 oop Klass::oop_primitive_allocate_size(oop obj, int size) {
00434 return markSymbol(vmSymbols::not_klass()); }
00435
00436 oop Klass::oop_shallow_copy(oop obj, bool tenured) {
00437 return markSymbol(vmSymbols::not_oops()); }