Klass::Klass() { Klass* k = this; // Preinitialize supertype information. // A later call to initialize_supers() may update these settings: set_super(NULL); for (juint i = 0; i < Klass::primary_super_limit(); i++) { _primary_supers[i] = NULL; } set_secondary_supers(NULL); set_secondary_super_cache(NULL); _primary_supers[0] = k; set_super_check_offset(in_bytes(primary_supers_offset())); set_java_mirror(NULL); set_modifier_flags(0); set_layout_helper(Klass::_lh_neutral_value); set_name(NULL); AccessFlags af; af.set_flags(0); set_access_flags(af); set_subklass(NULL); set_next_sibling(NULL); set_next_link(NULL); TRACE_INIT_ID(this); set_prototype_header(markOopDesc::prototype()); set_biased_lock_revocation_count(0); set_last_biased_lock_bulk_revocation_time(0); // The klass doesn't have any references at this point. clear_modified_oops(); clear_accumulated_modified_oops(); }
// ------------------------------------------------------------------ // ciFieldLayout::fill_in_instance_fields // // Set up the instance fields in this ciFieldLayout. void ciFieldLayout::fill_in_instance_fields(GrowableArray<BasicType>* fieldtypes, GrowableArray<int>* fieldoffsets, GrowableArray<int>* aflags, int& pos, klassOop current) { Klass* k = current->klass_part(); assert(k->oop_is_instance(), "must be instanceKlass"); instanceKlass* ik = (instanceKlass*)k; klassOop super = k->super(); if (super) { fill_in_instance_fields(fieldtypes, fieldoffsets, aflags, pos, super); } // Fill in this klass's instance fields. typeArrayOop field_list = ik->fields(); constantPoolOop cpool = ik->constants(); uint num_fields = field_list->length(); for (uint i = 0; i < num_fields; i += instanceKlass::next_offset) { AccessFlags flags; flags.set_flags(field_list->short_at(i + instanceKlass::access_flags_offset)); if (!flags.is_static()) { // This is an instance field. Add it to our list. int field_offset = ik->offset_from_fields( i ); // Add the type to our list. symbolOop type_sym = cpool->symbol_at(field_list->short_at(i+ instanceKlass::signature_index_offset)); BasicType field_type; field_type = type2field[FieldType::basic_type(type_sym)]; fieldtypes->at_put_grow(pos, field_type, T_VOID); aflags->at_put_grow(pos, flags.as_int(), 0); // The field offset we set here includes the header_size fieldoffsets->at_put_grow(pos, field_offset, 0); pos++; } } }
klassOop Klass::base_create_klass_oop(KlassHandle& klass, int size, const Klass_vtbl& vtbl, TRAPS) { size = align_object_size(size); // allocate and initialize vtable Klass* kl = (Klass*) vtbl.allocate_permanent(klass, size, CHECK_NULL); klassOop k = kl->as_klassOop(); { // Preinitialize supertype information. // A later call to initialize_supers() may update these settings: kl->set_super(NULL); for (juint i = 0; i < Klass::primary_super_limit(); i++) { kl->_primary_supers[i] = NULL; } kl->set_secondary_supers(NULL); oop_store_without_check((oop*) &kl->_primary_supers[0], k); kl->set_super_check_offset(in_bytes(primary_supers_offset())); } kl->set_java_mirror(NULL); kl->set_modifier_flags(0); kl->set_layout_helper(Klass::_lh_neutral_value); kl->set_name(NULL); AccessFlags af; af.set_flags(0); kl->set_access_flags(af); kl->set_subklass(NULL); kl->set_next_sibling(NULL); kl->set_alloc_count(0); kl->set_alloc_size(0); TRACE_SET_KLASS_TRACE_ID(kl, 0); kl->set_prototype_header(markOopDesc::prototype()); kl->set_biased_lock_revocation_count(0); kl->set_last_biased_lock_bulk_revocation_time(0); return k; }
methodOop methodKlass::allocate(constMethodHandle xconst, AccessFlags access_flags, TRAPS) { int size = methodOopDesc::object_size(access_flags.is_native()); KlassHandle h_k(THREAD, as_klassOop()); assert(xconst()->is_parsable(), "possible publication protocol violation"); methodOop m = (methodOop)CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL); assert(!m->is_parsable(), "not expecting parsability yet."); No_Safepoint_Verifier no_safepoint; // until m becomes parsable below m->set_constMethod(xconst()); m->set_access_flags(access_flags); m->set_method_size(size); m->set_name_index(0); m->set_signature_index(0); #ifdef CC_INTERP m->set_result_index(T_VOID); #endif m->set_constants(NULL); m->set_max_stack(0); m->set_max_locals(0); m->set_intrinsic_id(vmIntrinsics::_none); m->set_method_data(NULL); m->set_interpreter_throwout_count(0); m->set_vtable_index(methodOopDesc::garbage_vtable_index); // Fix and bury in methodOop m->set_interpreter_entry(NULL); // sets i2i entry and from_int m->set_highest_tier_compile(CompLevel_none); m->set_adapter_entry(NULL); m->clear_code(); // from_c/from_i get set to c2i/i2i if (access_flags.is_native()) { m->clear_native_function(); m->set_signature_handler(NULL); } NOT_PRODUCT(m->set_compiled_invocation_count(0);)
methodOop oopFactory::new_method(int byte_code_size, AccessFlags access_flags, int compressed_line_number_size, int localvariable_table_length, int checked_exceptions_length, bool is_conc_safe, TRAPS) { methodKlass* mk = methodKlass::cast(Universe::methodKlassObj()); assert(!access_flags.is_native() || byte_code_size == 0, "native methods should not contain byte codes"); constMethodOop cm = new_constMethod(byte_code_size, compressed_line_number_size, localvariable_table_length, checked_exceptions_length, is_conc_safe, CHECK_NULL); constMethodHandle rw(THREAD, cm); return mk->allocate(rw, access_flags, CHECK_NULL); }
void set_access_flags(AccessFlags flags) const { set_access_flags(flags.as_short()); }
// Accessors for current field AccessFlags access_flags() const { AccessFlags flags; flags.set_flags(field()->access_flags()); return flags; }
ciFlags(AccessFlags flags) { _flags = flags.as_int(); }
// update the access_flags for the field in the klass void update_klass_field_access_flag() { instanceKlass* ik = instanceKlass::cast(field_holder()); ik->field(index())->set_access_flags(_access_flags.as_short()); }
// Install the redefinition of a class -- // The original instanceKlass object (k_h) always represents the latest // version of the respective class. However, during class redefinition we swap // or replace much of its content with that of the instanceKlass object created // from the bytes of the redefine (k_h_new). Specifically, k_h points to the new // constantpool and methods objects, which we take from k_h_new. k_h_new, in turn, // assumes the role of the previous class version, with the old constantpool and // methods (taken from k_h) attached to it. k_h links to k_h_new to create a // linked list of class versions. void VM_RedefineClasses::redefine_single_class(jclass j_clazz, instanceKlassHandle k_h_new, TRAPS) { oop mirror = JNIHandles::resolve_non_null(j_clazz); klassOop k_oop = java_lang_Class::as_klassOop(mirror); instanceKlassHandle k_h = instanceKlassHandle(THREAD, k_oop); // Remove all breakpoints in methods of this class JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints(); jvmti_breakpoints.clearall_in_class_at_safepoint(k_oop); // Deoptimize all compiled code that depends on this class NOT_CORE(Universe::flush_evol_dependents_on(k_h)); _old_methods = k_h->methods(); _new_methods = k_h_new->methods(); _evolving_koop = k_oop; _old_constants = k_h->constants(); // flush the cached jmethodID fields for _old_methods flush_method_jmethod_id_cache(); // Patch the indexes into the constantpool from the array of fields of the evolving // class. This is required, because the layout of the new constantpool can be different, // so old indexes corresponding to field names and signatures can become invalid. patch_indexes_for_fields(k_h, k_h_new); // Make new constantpool object (and methodOops via it) point to the original class object k_h_new->constants()->set_pool_holder(k_h()); // Replace methods and constantpool k_h->set_methods(_new_methods); k_h_new->set_methods(_old_methods); // To prevent potential GCing of the old methods, // and to be able to undo operation easily. constantPoolOop old_constants = k_h->constants(); k_h->set_constants(k_h_new->constants()); k_h_new->set_constants(old_constants); // See the previous comment. check_methods_and_mark_as_old(); transfer_old_native_function_registrations(); // Replace inner_classes typeArrayOop old_inner_classes = k_h->inner_classes(); k_h->set_inner_classes(k_h_new->inner_classes()); k_h_new->set_inner_classes(old_inner_classes); // Initialize the vtable and interface table after // methods have been rewritten { ResourceMark rm(THREAD); k_h->vtable()->initialize_vtable(THREAD); // No exception can happen here k_h->itable()->initialize_itable(); } // Copy the "source file name" attribute from new class version k_h->set_source_file_name(k_h_new->source_file_name()); // Copy the "source debug extension" attribute from new class version k_h->set_source_debug_extension(k_h_new->source_debug_extension()); // Use of javac -g could be different in the old and the new if (k_h_new->access_flags().has_localvariable_table() != k_h->access_flags().has_localvariable_table()) { AccessFlags flags = k_h->access_flags(); if (k_h_new->access_flags().has_localvariable_table()) { flags.set_has_localvariable_table(); } else { flags.clear_has_localvariable_table(); } k_h->set_access_flags(flags); } // Replace class annotation fields values typeArrayOop old_class_annotations = k_h->class_annotations(); k_h->set_class_annotations(k_h_new->class_annotations()); k_h_new->set_class_annotations(old_class_annotations); // Replace fields annotation fields values objArrayOop old_fields_annotations = k_h->fields_annotations(); k_h->set_fields_annotations(k_h_new->fields_annotations()); k_h_new->set_fields_annotations(old_fields_annotations); // Replace methods annotation fields values objArrayOop old_methods_annotations = k_h->methods_annotations(); k_h->set_methods_annotations(k_h_new->methods_annotations()); k_h_new->set_methods_annotations(old_methods_annotations); // Replace methods parameter annotation fields values objArrayOop old_methods_parameter_annotations = k_h->methods_parameter_annotations(); k_h->set_methods_parameter_annotations(k_h_new->methods_parameter_annotations()); k_h_new->set_methods_parameter_annotations(old_methods_parameter_annotations); // Replace methods default annotation fields values objArrayOop old_methods_default_annotations = k_h->methods_default_annotations(); k_h->set_methods_default_annotations(k_h_new->methods_default_annotations()); k_h_new->set_methods_default_annotations(old_methods_default_annotations); // Replace major version number of class file u2 old_major_version = k_h->major_version(); k_h->set_major_version(k_h_new->major_version()); k_h_new->set_major_version(old_major_version); // Replace CP indexes for class and name+type of enclosing method u2 old_class_idx = k_h->enclosing_method_class_index(); u2 old_method_idx = k_h->enclosing_method_method_index(); k_h->set_enclosing_method_indices(k_h_new->enclosing_method_class_index(), k_h_new->enclosing_method_method_index()); k_h_new->set_enclosing_method_indices(old_class_idx, old_method_idx); // Maintain a linked list of versions of this class. // List is in ascending age order. Current version (k_h) is the head. if (k_h->has_previous_version()) { k_h_new->set_previous_version(k_h->previous_version()); } k_h->set_previous_version(k_h_new); // Adjust constantpool caches and vtables for all classes // that reference methods of the evolved class. SystemDictionary::classes_do(adjust_cpool_cache_and_vtable); k_h->set_rewritten_by_redefine(true); }
void set_has_vanilla_constructor() { AccessFlags flags = access_flags(); flags.set_has_vanilla_constructor(); set_access_flags(flags); }
void set_is_verified() { AccessFlags flags = access_flags(); flags.set_is_verified(); set_access_flags(flags); }
void set_access_flags(AccessFlags access_flags) { int_field_put(access_flags_offset(), access_flags.as_int()); }
klassOop instanceKlassKlass::allocate_instance_klass(Symbol* name, int vtable_len, int itable_len, int static_field_size, unsigned nonstatic_oop_map_count, AccessFlags access_flags, ReferenceType rt, KlassHandle host_klass, TRAPS) { const int nonstatic_oop_map_size = instanceKlass::nonstatic_oop_map_size(nonstatic_oop_map_count); int size = align_object_offset(vtable_len) + align_object_offset(itable_len); if (access_flags.is_interface() || !host_klass.is_null()) { size += align_object_offset(nonstatic_oop_map_size); } else { size += nonstatic_oop_map_size; } if (access_flags.is_interface()) { size += (int)sizeof(klassOop)/HeapWordSize; } if (!host_klass.is_null()) { size += (int)sizeof(klassOop)/HeapWordSize; } size = instanceKlass::object_size(size); // Allocation KlassHandle h_this_klass(THREAD, as_klassOop()); KlassHandle k; if (rt == REF_NONE) { if (name != vmSymbols::java_lang_Class()) { // regular klass instanceKlass o; k = base_create_klass(h_this_klass, size, o.vtbl_value(), CHECK_NULL); } else { // Class instanceMirrorKlass o; k = base_create_klass(h_this_klass, size, o.vtbl_value(), CHECK_NULL); } } else { // reference klass instanceRefKlass o; k = base_create_klass(h_this_klass, size, o.vtbl_value(), CHECK_NULL); } { No_Safepoint_Verifier no_safepoint; // until k becomes parsable instanceKlass* ik = (instanceKlass*) k()->klass_part(); assert(!k()->is_parsable(), "not expecting parsability yet."); // The sizes of these these three variables are used for determining the // size of the instanceKlassOop. It is critical that these are set to the right // sizes before the first GC, i.e., when we allocate the mirror. ik->set_vtable_length(vtable_len); ik->set_itable_length(itable_len); ik->set_static_field_size(static_field_size); ik->set_nonstatic_oop_map_size(nonstatic_oop_map_size); ik->set_access_flags(access_flags); ik->set_is_anonymous(!host_klass.is_null()); assert(k()->size() == size, "wrong size for object"); ik->set_array_klasses(NULL); ik->set_methods(NULL); ik->set_method_ordering(NULL); ik->set_local_interfaces(NULL); ik->set_transitive_interfaces(NULL); ik->init_implementor(); ik->set_fields(NULL, 0); ik->set_constants(NULL); ik->set_class_loader(NULL); ik->set_protection_domain(NULL); ik->set_signers(NULL); ik->set_source_file_name(NULL); ik->set_source_debug_extension(NULL, 0); ik->set_array_name(NULL); ik->set_inner_classes(NULL); ik->set_static_oop_field_count(0); ik->set_nonstatic_field_size(0); ik->set_is_marked_dependent(false); ik->set_init_state(instanceKlass::allocated); ik->set_init_thread(NULL); ik->set_reference_type(rt); ik->set_oop_map_cache(NULL); ik->set_jni_ids(NULL); ik->set_osr_nmethods_head(NULL); ik->set_breakpoints(NULL); ik->init_previous_versions(); ik->set_generic_signature(NULL); ik->release_set_methods_jmethod_ids(NULL); ik->release_set_methods_cached_itable_indices(NULL); ik->set_class_annotations(NULL); ik->set_fields_annotations(NULL); ik->set_methods_annotations(NULL); ik->set_methods_parameter_annotations(NULL); ik->set_methods_default_annotations(NULL); ik->set_jvmti_cached_class_field_map(NULL); ik->set_initial_method_idnum(0); assert(k()->is_parsable(), "should be parsable here."); // initialize the non-header words to zero intptr_t* p = (intptr_t*)k(); for (int index = instanceKlass::header_size(); index < size; index++) { p[index] = NULL_WORD; } // To get verify to work - must be set to partial loaded before first GC point. k()->set_partially_loaded(); } Atomic::inc(&instanceKlass::_total_instanceKlass_count); return k(); }