void CodeBuffer::finalize_oop_references(methodHandle mh) { No_Safepoint_Verifier nsv; GrowableArray<oop> oops; // Make sure that immediate metadata records something in the OopRecorder for (int n = (int) SECT_FIRST; n < (int) SECT_LIMIT; n++) { // pull code out of each section CodeSection* cs = code_section(n); if (cs->is_empty()) continue; // skip trivial section RelocIterator iter(cs); while (iter.next()) { if (iter.type() == relocInfo::metadata_type) { metadata_Relocation* md = iter.metadata_reloc(); if (md->metadata_is_immediate()) { Metadata* m = md->metadata_value(); if (oop_recorder()->is_real(m)) { if (m->is_methodData()) { m = ((MethodData*)m)->method(); } if (m->is_method()) { m = ((Method*)m)->method_holder(); } if (m->is_klass()) { append_oop_references(&oops, (Klass*)m); } else { // XXX This will currently occur for MDO which don't // have a backpointer. This has to be fixed later. m->print(); ShouldNotReachHere(); } } } } } } if (!oop_recorder()->is_unused()) { for (int i = 0; i < oop_recorder()->metadata_count(); i++) { Metadata* m = oop_recorder()->metadata_at(i); if (oop_recorder()->is_real(m)) { if (m->is_methodData()) { m = ((MethodData*)m)->method(); } if (m->is_method()) { m = ((Method*)m)->method_holder(); } if (m->is_klass()) { append_oop_references(&oops, (Klass*)m); } else { m->print(); ShouldNotReachHere(); } } } } // Add the class loader of Method* for the nmethod itself append_oop_references(&oops, mh->method_holder()); // Add any oops that we've found Thread* thread = Thread::current(); for (int i = 0; i < oops.length(); i++) { oop_recorder()->find_index((jobject)thread->handle_area()->allocate_handle(oops.at(i))); } }