oop AOTCompiledMethod::oop_at(int index) const { if (index == 0) { // 0 is reserved return NULL; } Metadata** entry = _metadata_got + (index - 1); intptr_t meta = (intptr_t)*entry; if ((meta & 1) == 1) { // already resolved Klass* k = (Klass*)(meta & ~1); return k->java_mirror(); } // The entry is string which we need to resolve. const char* meta_name = _heap->get_name_at((int)meta); int klass_len = build_u2_from((address)meta_name); const char* klass_name = meta_name + 2; // Quick check the current method's holder. Klass* k = _method->method_holder(); ResourceMark rm; // for signature_name() if (strncmp(k->signature_name(), klass_name, klass_len) != 0) { // Does not match? // Search klass in got cells in DSO which have this compiled method. k = _heap->get_klass_from_got(klass_name, klass_len, _method); } int method_name_len = build_u2_from((address)klass_name + klass_len); guarantee(method_name_len == 0, "only klass is expected here"); meta = ((intptr_t)k) | 1; *entry = (Metadata*)meta; // Should be atomic on x64 return k->java_mirror(); }
Metadata* AOTCompiledMethod::metadata_at(int index) const { if (index == 0) { // 0 is reserved return NULL; } assert(index - 1 < _metadata_size, ""); { Metadata** entry = _metadata_got + (index - 1); intptr_t meta = (intptr_t)*entry; if ((meta & 1) == 1) { // already resolved Metadata *m = (Metadata*)(meta & ~1); return m; } // The entry is string which we need to resolve. const char* meta_name = _heap->get_name_at((int)meta); int klass_len = build_u2_from((address)meta_name); const char* klass_name = meta_name + 2; // Quick check the current method's holder. Klass* k = _method->method_holder(); bool klass_matched = true; ResourceMark rm; // for signature_name() and find_method() if (strncmp(k->signature_name(), klass_name, klass_len) != 0) { // Does not match? // Search klass in got cells in DSO which have this compiled method. k = _heap->get_klass_from_got(klass_name, klass_len, _method); klass_matched = false; } int method_name_len = build_u2_from((address)klass_name + klass_len); if (method_name_len == 0) { // Array or Klass name only? meta = ((intptr_t)k) | 1; *entry = (Metadata*)meta; // Should be atomic on x64 return (Metadata*)k; } else { // Method // Quick check the current method's name. Method* m = _method; int signature_len = build_u2_from((address)klass_name + klass_len + 2 + method_name_len); int full_len = 2 + klass_len + 2 + method_name_len + 2 + signature_len; if (!klass_matched || memcmp(_name, meta_name, full_len) != 0) { // Does not match? Thread* thread = Thread::current(); KlassHandle klass = KlassHandle(thread, k); const char* method_name = klass_name + klass_len; m = AOTCodeHeap::find_method(klass, thread, method_name); } meta = ((intptr_t)m) | 1; *entry = (Metadata*)meta; // Should be atomic on x64 return (Metadata*)m; } } ShouldNotReachHere(); return NULL; }