Expr* PrimInliner::obj_new() { // replace generic allocation primitive by size-specific primitive, if possible Expr* rcvr = parameter(0); if (!rcvr->isConstantExpr() || !rcvr->constant()->is_klass()) return NULL; Klass* klass = klassOop(rcvr->constant())->klass_part(); // class being instantiated if (klass->oop_is_indexable()) return NULL; // would fail (extremely unlikely) int size = klass->non_indexable_size(); // size in words if (klass->can_inline_allocation()) { // These special compiler primitives only work for memOop klasses int number_of_instance_variables = size - memOopDesc::header_size(); switch (number_of_instance_variables) { case 0: _pdesc = primitives::new0(); break; case 1: _pdesc = primitives::new1(); break; case 2: _pdesc = primitives::new2(); break; case 3: _pdesc = primitives::new3(); break; case 4: _pdesc = primitives::new4(); break; case 5: _pdesc = primitives::new5(); break; case 6: _pdesc = primitives::new6(); break; case 7: _pdesc = primitives::new7(); break; case 8: _pdesc = primitives::new8(); break; case 9: _pdesc = primitives::new9(); break; default: ; // use generic primitives } } Expr* u = genCall(true); return new KlassExpr(klass->as_klassOop(), u->preg(), u->node()); }
PRIM_DECL_1(behaviorPrimitives::mixinOf, oop behavior) { PROLOGUE_1("mixinOf", behavior); if (!behavior->is_klass()) return markSymbol(vmSymbols::first_argument_has_wrong_type()); return klassOop(behavior)->klass_part()->mixin(); }
void instanceKlassKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { assert(pm->depth_first(), "invariant"); instanceKlass* ik = instanceKlass::cast(klassOop(obj)); ik->push_static_fields(pm); oop* loader_addr = ik->adr_class_loader(); if (PSScavenge::should_scavenge(loader_addr)) { pm->claim_or_forward_depth(loader_addr); } oop* pd_addr = ik->adr_protection_domain(); if (PSScavenge::should_scavenge(pd_addr)) { pm->claim_or_forward_depth(pd_addr); } oop* hk_addr = ik->adr_host_klass(); if (PSScavenge::should_scavenge(hk_addr)) { pm->claim_or_forward_depth(hk_addr); } oop* sg_addr = ik->adr_signers(); if (PSScavenge::should_scavenge(sg_addr)) { pm->claim_or_forward_depth(sg_addr); } oop* bsm_addr = ik->adr_bootstrap_method(); if (PSScavenge::should_scavenge(bsm_addr)) { pm->claim_or_forward_depth(bsm_addr); } klassKlass::oop_copy_contents(pm, obj); }
PRIM_DECL_1(behaviorPrimitives::vm_type, oop behavior) { PROLOGUE_1("format", behavior); if (!behavior->is_klass()) return markSymbol(vmSymbols::first_argument_has_wrong_type()); Klass::Format f = klassOop(behavior)->klass_part()->format(); switch (f) { case Klass::mem_klass: return vmSymbols::mem_klass(); case Klass::association_klass: return vmSymbols::association_klass(); case Klass::blockClosure_klass: return vmSymbols::blockClosure_klass(); case Klass::byteArray_klass: return vmSymbols::byteArray_klass(); case Klass::symbol_klass: return vmSymbols::symbol_klass(); case Klass::context_klass: return vmSymbols::context_klass(); case Klass::doubleByteArray_klass: return vmSymbols::doubleByteArray_klass(); case Klass::doubleValueArray_klass: return vmSymbols::doubleValueArray_klass(); case Klass::double_klass: return vmSymbols::double_klass(); case Klass::klass_klass: return vmSymbols::klass_klass(); case Klass::method_klass: return vmSymbols::method_klass(); case Klass::mixin_klass: return vmSymbols::mixin_klass(); case Klass::objArray_klass: return vmSymbols::objArray_klass(); case Klass::weakArray_klass: return vmSymbols::weakArray_klass(); case Klass::process_klass: return vmSymbols::process_klass(); case Klass::vframe_klass: return vmSymbols::vframe_klass(); case Klass::proxy_klass: return vmSymbols::proxy_klass(); case Klass::smi_klass: return vmSymbols::smi_klass(); default: fatal("wrong format for klass"); } return markSymbol(vmSymbols::first_argument_has_wrong_type()); }
PRIM_DECL_1(behaviorPrimitives::is_specialized_class, oop behavior) { PROLOGUE_1("is_specialized_class", behavior); if (!behavior->is_klass()) return markSymbol(vmSymbols::first_argument_has_wrong_type()); return klassOop(behavior)->klass_part()->is_specialized_class() ? trueObj : falseObj; }
PRIM_DECL_1(behaviorPrimitives::nonIndexableSize, oop behavior) { PROLOGUE_1("nonIndexableSize", behavior); if (!behavior->is_klass()) return markSymbol(vmSymbols::first_argument_has_wrong_type()); return as_smiOop(klassOop(behavior)->klass_part()->non_indexable_size()); }
// The transitive_interfaces is the last field set when loading an object. void instanceKlassKlass::oop_set_partially_loaded(oop obj) { assert(obj->is_klass(), "object must be klass"); instanceKlass* ik = instanceKlass::cast(klassOop(obj)); assert(ik-oop_is_instance(), "object must be instanceKlass"); assert(ik->transitive_interfaces() == NULL, "just checking"); ik->set_transitive_interfaces((objArrayOop) obj); // Temporarily set transitive_interfaces to point to self }
PRIM_DECL_1(behaviorPrimitives::can_have_instance_variables, oop behavior) { PROLOGUE_1("can_have_instance_variables", behavior); if (!behavior->is_klass()) return markSymbol(vmSymbols::first_argument_has_wrong_type()); return klassOop(behavior)->klass_part()->can_have_instance_variables() ? trueObj : falseObj; }
PRIM_DECL_1(behaviorPrimitives::headerSize, oop behavior) { PROLOGUE_1("headerSize", behavior); if (!behavior->is_klass()) return markSymbol(vmSymbols::first_argument_has_wrong_type()); return as_smiOop(klassOop(behavior)->klass_part()->oop_header_size()); }
PRIM_DECL_1(behaviorPrimitives::can_be_subclassed, oop behavior) { PROLOGUE_1("can_be_subclassed", behavior); if (!behavior->is_klass()) return markSymbol(vmSymbols::first_argument_has_wrong_type()); return klassOop(behavior)->klass_part()->can_be_subclassed() ? trueObj : falseObj; }
int klassKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) { // Get size before changing pointers int size = oop_size(obj); Klass* k = Klass::cast(klassOop(obj)); oop* adr; adr = k->adr_super(); if (mr.contains(adr)) blk->do_oop(adr); for (juint i = 0; i < Klass::primary_super_limit(); i++) { adr = k->adr_primary_supers()+i; if (mr.contains(adr)) blk->do_oop(adr); } adr = k->adr_secondary_super_cache(); if (mr.contains(adr)) blk->do_oop(adr); adr = k->adr_secondary_supers(); if (mr.contains(adr)) blk->do_oop(adr); adr = k->adr_java_mirror(); if (mr.contains(adr)) blk->do_oop(adr); adr = k->adr_name(); if (mr.contains(adr)) blk->do_oop(adr); // The following are "weak links" in the perm gen and are // treated specially in a later phase of a perm gen collection. assert(oop(k)->is_perm(), "should be in perm"); assert(oop(k->adr_subklass())->is_perm(), "should be in perm"); assert(oop(k->adr_next_sibling())->is_perm(), "should be in perm"); if (blk->should_remember_klasses() && (mr.contains(k->adr_subklass()) || mr.contains(k->adr_next_sibling()))) { blk->remember_klass(k); } obj->oop_iterate_header(blk, mr); return size; }
int klassKlass::oop_oop_iterate(oop obj, OopClosure* blk) { // Get size before changing pointers int size = oop_size(obj); Klass* k = Klass::cast(klassOop(obj)); blk->do_oop(k->adr_super()); for (juint i = 0; i < Klass::primary_super_limit(); i++) blk->do_oop(k->adr_primary_supers()+i); blk->do_oop(k->adr_secondary_super_cache()); blk->do_oop(k->adr_secondary_supers()); blk->do_oop(k->adr_java_mirror()); blk->do_oop(k->adr_name()); // The following are in the perm gen and are treated // specially in a later phase of a perm gen collection; ... assert(oop(k)->is_perm(), "should be in perm"); assert(oop(k->subklass())->is_perm_or_null(), "should be in perm"); assert(oop(k->next_sibling())->is_perm_or_null(), "should be in perm"); // ... don't scan them normally, but remember this klassKlass // for later (see, for instance, oop_follow_contents above // for what MarkSweep does with it. if (blk->should_remember_klasses()) { blk->remember_klass(k); } obj->oop_iterate_header(blk); return size; }
void InlinedScope::initializeArguments() { const int nofArgs = _method->number_of_arguments(); _arguments = new GrowableArray<Expr*>(nofArgs, nofArgs, NULL); if (isTop()) { // create expr for self but do not allocate a location yet // (self is setup by the prologue node) _self = new KlassExpr(klassOop(selfKlass()), new SAPReg(this, unAllocated, false, false, PrologueBCI, EpilogueBCI), NULL); // preallocate incoming arguments, i.e., create their expressions // using SAPRegs that are already allocated for (int i = 0; i < nofArgs; i++) { SAPReg* arg = new SAPReg(this, Mapping::incomingArg(i, nofArgs), false, false, PrologueBCI, EpilogueBCI); _arguments->at_put(i, new UnknownExpr(arg)); } } else { _self = NULL; // will be initialized by sender // get args from sender's expression stack; top of expr stack = last arg, etc. const int top = sender()->exprStack()->length(); for (int i = 0; i < nofArgs; i++) { _arguments->at_put(i, sender()->exprStack()->at(top - nofArgs + i)); } } }
void instanceKlassKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { instanceKlass* ik = instanceKlass::cast(klassOop(obj)); oop* loader_addr = ik->adr_class_loader(); if (PSScavenge::should_scavenge(loader_addr)) { pm->claim_or_forward_depth(loader_addr); } oop* pd_addr = ik->adr_protection_domain(); if (PSScavenge::should_scavenge(pd_addr)) { pm->claim_or_forward_depth(pd_addr); } oop* hk_addr = ik->adr_host_klass(); if (hk_addr != NULL && PSScavenge::should_scavenge(hk_addr)) { pm->claim_or_forward_depth(hk_addr); } oop* sg_addr = ik->adr_signers(); if (PSScavenge::should_scavenge(sg_addr)) { pm->claim_or_forward_depth(sg_addr); } klassKlass::oop_push_contents(pm, obj); }
PRIM_DECL_1(behaviorPrimitives::format, oop behavior) { PROLOGUE_1("format", behavior); if (!behavior->is_klass()) return markSymbol(vmSymbols::first_argument_has_wrong_type()); char* format_name = Klass::name_from_format(klassOop(behavior)->klass_part()->format()); return oopFactory::new_symbol(format_name); }
int arrayKlassKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) { assert (obj->is_klass(), "must be klass"); arrayKlass* ak = arrayKlass::cast(klassOop(obj)); blk->do_oop(ak->adr_lower_dimension()); blk->do_oop(ak->adr_higher_dimension()); ak->vtable()->oop_oop_iterate_m(blk, mr); return klassKlass::oop_oop_iterate_m(obj, blk, mr); }
int arrayKlassKlass::oop_oop_iterate(oop obj, OopClosure* blk) { assert(obj->is_klass(), "must be klass"); arrayKlass* ak = arrayKlass::cast(klassOop(obj)); blk->do_oop(ak->adr_component_mirror()); blk->do_oop(ak->adr_lower_dimension()); blk->do_oop(ak->adr_higher_dimension()); ak->vtable()->oop_oop_iterate(blk); return klassKlass::oop_oop_iterate(obj, blk); }
// The transitive_interfaces is the last field set when loading an object. void instanceKlassKlass::oop_set_partially_loaded(oop obj) { assert(obj->is_klass(), "object must be klass"); instanceKlass* ik = instanceKlass::cast(klassOop(obj)); // Set the layout helper to a place-holder value, until fuller initialization. // (This allows asserts in oop_is_instance to succeed.) ik->set_layout_helper(Klass::instance_layout_helper(0, true)); assert(ik->oop_is_instance(), "object must be instanceKlass"); assert(ik->transitive_interfaces() == NULL, "just checking"); ik->set_transitive_interfaces((objArrayOop) obj); // Temporarily set transitive_interfaces to point to self }
int instanceKlassKlass::oop_oop_iterate(oop obj, OopClosure* blk) { assert(obj->is_klass(),"must be a klass"); assert(klassOop(obj)->klass_part()->oop_is_instance_slow(), "must be instance klass"); instanceKlass* ik = instanceKlass::cast(klassOop(obj)); // Get size before changing pointers. // Don't call size() or oop_size() since that is a virtual call. int size = ik->object_size(); ik->iterate_static_fields(blk); ik->vtable()->oop_oop_iterate(blk); ik->itable()->oop_oop_iterate(blk); blk->do_oop(ik->adr_array_klasses()); blk->do_oop(ik->adr_methods()); blk->do_oop(ik->adr_method_ordering()); blk->do_oop(ik->adr_local_interfaces()); blk->do_oop(ik->adr_transitive_interfaces()); blk->do_oop(ik->adr_fields()); blk->do_oop(ik->adr_constants()); blk->do_oop(ik->adr_class_loader()); blk->do_oop(ik->adr_protection_domain()); blk->do_oop(ik->adr_host_klass()); blk->do_oop(ik->adr_signers()); blk->do_oop(ik->adr_source_file_name()); blk->do_oop(ik->adr_source_debug_extension()); blk->do_oop(ik->adr_inner_classes()); for (int i = 0; i < instanceKlass::implementors_limit; i++) { blk->do_oop(&ik->adr_implementors()[i]); } blk->do_oop(ik->adr_generic_signature()); blk->do_oop(ik->adr_bootstrap_method()); blk->do_oop(ik->adr_class_annotations()); blk->do_oop(ik->adr_fields_annotations()); blk->do_oop(ik->adr_methods_annotations()); blk->do_oop(ik->adr_methods_parameter_annotations()); blk->do_oop(ik->adr_methods_default_annotations()); klassKlass::oop_oop_iterate(obj, blk); if(ik->oop_map_cache() != NULL) ik->oop_map_cache()->oop_iterate(blk); return size; }
int klassKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { Klass* k = Klass::cast(klassOop(obj)); oop* const beg_oop = k->oop_block_beg(); oop* const end_oop = k->oop_block_end(); for (oop* cur_oop = beg_oop; cur_oop < end_oop; ++cur_oop) { PSParallelCompact::adjust_pointer(cur_oop); } return oop_size(obj); }
int arrayKlassKlass::oop_adjust_pointers(oop obj) { assert (obj->is_klass(), "must be klass"); arrayKlass* ak = arrayKlass::cast(klassOop(obj)); MarkSweep::adjust_pointer(ak->adr_lower_dimension() ); MarkSweep::adjust_pointer(ak->adr_higher_dimension() ); { HandleMark hm; ak->vtable()->oop_adjust_pointers(); } return klassKlass::oop_adjust_pointers(obj); }
void arrayKlassKlass::oop_follow_contents(oop obj) { assert (obj->is_klass(), "must be klass"); arrayKlass* ak = arrayKlass::cast(klassOop(obj)); MarkSweep::mark_and_push(ak->adr_lower_dimension() ); MarkSweep::mark_and_push(ak->adr_higher_dimension() ); { HandleMark hm; ak->vtable()->oop_follow_contents(); } klassKlass::oop_follow_contents(obj); }
void arrayKlassKlass::oop_verify_on(oop obj, outputStream* st) { klassKlass::oop_verify_on(obj, st); arrayKlass* ak = arrayKlass::cast(klassOop(obj)); if (!obj->partially_loaded()) { if (ak->lower_dimension()) guarantee(ak->lower_dimension()->klass(), "should have a class"); if (ak->higher_dimension()) guarantee(ak->higher_dimension()->klass(), "should have a class"); } }
PRIM_DECL_2(behaviorPrimitives::printMethod, oop receiver, oop name){ PROLOGUE_2("printMethod", receiver, name); ASSERT_RECEIVER; if (!name->is_byteArray()) return markSymbol(vmSymbols::first_argument_has_wrong_type()); methodOop m = klassOop(receiver)->klass_part()->lookup(symbolOop(name)); if (!m) return markSymbol(vmSymbols::not_found()); m->print_codes(); return receiver; }
PRIM_DECL_2(behaviorPrimitives::methodFor, oop receiver, oop selector) { PROLOGUE_2("methodFor", receiver, selector); ASSERT_RECEIVER; if (!selector->is_symbol()) return markSymbol(vmSymbols::first_argument_has_wrong_type()); methodOop m = klassOop(receiver)->klass_part()->lookup(symbolOop(selector)); if (m) return m; return markSymbol(vmSymbols::not_found()); }
void instanceKlassKlass::oop_follow_contents(oop obj) { assert(obj->is_klass(),"must be a klass"); assert(klassOop(obj)->klass_part()->oop_is_instance_slow(), "must be instance klass"); instanceKlass* ik = instanceKlass::cast(klassOop(obj)); ik->follow_static_fields(); { HandleMark hm; ik->vtable()->oop_follow_contents(); ik->itable()->oop_follow_contents(); } MarkSweep::mark_and_push(ik->adr_array_klasses()); MarkSweep::mark_and_push(ik->adr_methods()); MarkSweep::mark_and_push(ik->adr_method_ordering()); MarkSweep::mark_and_push(ik->adr_local_interfaces()); MarkSweep::mark_and_push(ik->adr_transitive_interfaces()); MarkSweep::mark_and_push(ik->adr_fields()); MarkSweep::mark_and_push(ik->adr_constants()); MarkSweep::mark_and_push(ik->adr_class_loader()); MarkSweep::mark_and_push(ik->adr_source_file_name()); MarkSweep::mark_and_push(ik->adr_source_debug_extension()); MarkSweep::mark_and_push(ik->adr_inner_classes()); MarkSweep::mark_and_push(ik->adr_protection_domain()); MarkSweep::mark_and_push(ik->adr_host_klass()); MarkSweep::mark_and_push(ik->adr_signers()); MarkSweep::mark_and_push(ik->adr_generic_signature()); MarkSweep::mark_and_push(ik->adr_bootstrap_method()); MarkSweep::mark_and_push(ik->adr_class_annotations()); MarkSweep::mark_and_push(ik->adr_fields_annotations()); MarkSweep::mark_and_push(ik->adr_methods_annotations()); MarkSweep::mark_and_push(ik->adr_methods_parameter_annotations()); MarkSweep::mark_and_push(ik->adr_methods_default_annotations()); // We do not follow adr_implementors() here. It is followed later // in instanceKlass::follow_weak_klass_links() klassKlass::oop_follow_contents(obj); iterate_c_heap_oops(ik, &MarkSweep::mark_and_push_closure); }
void InterpretedIC::replace(nmethod* nm) { // replace entry with nm's klass by nm (if entry exists) smiOop entry_point = smiOop(nm->jump_table_entry()->entry_point()); assert(selector() == nm->key.selector(), "mismatched selector"); if (is_empty()) return; switch (send_type()) { case Bytecodes::accessor_send: // fall through case Bytecodes::primitive_send: // fall through case Bytecodes::predicted_send: // fall through case Bytecodes::interpreted_send: { // replace the monomorphic interpreted send with compiled send klassOop receiver_klass = klassOop(second_word()); assert(receiver_klass->is_klass(), "receiver klass must be a klass"); if (receiver_klass == nm->key.klass()) { set(Bytecodes::compiled_send_code_for(send_code()), entry_point, nm->key.klass()); } } break; case Bytecodes::compiled_send: // fall through case Bytecodes::megamorphic_send: // replace the monomorphic compiled send with compiled send set(send_code(), entry_point, nm->key.klass()); break; case Bytecodes::polymorphic_send: { objArrayOop pic = pic_array(); for (int index = pic->length(); index > 0; index -= 2) { klassOop receiver_klass = klassOop(pic->obj_at(index)); assert(receiver_klass->is_klass(), "receiver klass must be klass"); if (receiver_klass == nm->key.klass()) { pic->obj_at_put(index-1, entry_point); return; } } } // did not find klass break; default: fatal("unknown send type"); } LOG_EVENT3("interpreted IC at 0x%x: new nmethod 0x%x for klass 0x%x replaces old entry", this, nm, nm->key.klass()); }
int arrayKlassKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { assert(obj->is_klass(), "must be klass"); arrayKlass* ak = arrayKlass::cast(klassOop(obj)); PSParallelCompact::adjust_pointer(ak->adr_component_mirror()); PSParallelCompact::adjust_pointer(ak->adr_lower_dimension()); PSParallelCompact::adjust_pointer(ak->adr_higher_dimension()); { HandleMark hm; ak->vtable()->oop_update_pointers(cm); } return klassKlass::oop_update_pointers(cm, obj); }
void instanceKlassKlass::oop_follow_contents(oop obj) { assert(obj->is_klass(),"must be a klass"); assert(klassOop(obj)->klass_part()->oop_is_instance(), "must be instance klass"); instanceKlass* ik = instanceKlass::cast(klassOop(obj)); ik->follow_static_fields(); { HandleMark hm; ik->vtable()->oop_follow_contents(); ik->itable()->oop_follow_contents(); } MarkSweep::mark_and_push(ik->adr_array_klasses()); MarkSweep::mark_and_push(ik->adr_methods()); MarkSweep::mark_and_push(ik->adr_method_ordering()); MarkSweep::mark_and_push(ik->adr_local_interfaces()); MarkSweep::mark_and_push(ik->adr_transitive_interfaces()); MarkSweep::mark_and_push(ik->adr_fields()); MarkSweep::mark_and_push(ik->adr_constants()); MarkSweep::mark_and_push(ik->adr_class_loader()); MarkSweep::mark_and_push(ik->adr_source_file_name()); MarkSweep::mark_and_push(ik->adr_source_debug_extension()); MarkSweep::mark_and_push(ik->adr_inner_classes()); MarkSweep::mark_and_push(ik->adr_protection_domain()); MarkSweep::mark_and_push(ik->adr_signers()); MarkSweep::mark_and_push(ik->adr_previous_version()); // We do not follow adr_implementor() here. It is followed later // in instanceKlass::follow_weak_klass_links() klassKlass::oop_follow_contents(obj); if (ik->oop_map_cache() != NULL) { ik->oop_map_cache()->oop_iterate(&MarkSweep::mark_and_push_closure); } if (ik->jni_ids() != NULL) { ik->jni_ids()->oops_do(&MarkSweep::mark_and_push_closure); } }
virtual void do_object(oop obj) { if (obj->is_klass()) { Klass* k = klassOop(obj)->klass_part(); if (k->name() != NULL) { ResourceMark rm; const char* ext = k->external_name(); if ( strcmp(_target, ext) == 0 ) { tty->print_cr("Found " INTPTR_FORMAT, obj); obj->print(); } } } }