comparison src/share/vm/code/relocInfo.cpp @ 6725:da91efe96a93

6964458: Reimplement class meta-data storage to use native memory Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author coleenp
date Sat, 01 Sep 2012 13:25:18 -0400
parents 6c97c830fb6f
children cd3d6a6b95d9
comparison
equal deleted inserted replaced
6724:36d1d483d5d6 6725:da91efe96a93
1 /* 1 /*
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
437 case relocInfo::oop_type: 437 case relocInfo::oop_type:
438 { 438 {
439 oop_Relocation* r = (oop_Relocation*)reloc(); 439 oop_Relocation* r = (oop_Relocation*)reloc();
440 return oop_Relocation::spec(r->oop_index(), r->offset() + offset); 440 return oop_Relocation::spec(r->oop_index(), r->offset() + offset);
441 } 441 }
442 case relocInfo::metadata_type:
443 {
444 metadata_Relocation* r = (metadata_Relocation*)reloc();
445 return metadata_Relocation::spec(r->metadata_index(), r->offset() + offset);
446 }
442 default: 447 default:
443 ShouldNotReachHere(); 448 ShouldNotReachHere();
444 } 449 }
445 } 450 }
446 return (*this); 451 return (*this);
576 581
577 void oop_Relocation::unpack_data() { 582 void oop_Relocation::unpack_data() {
578 unpack_2_ints(_oop_index, _offset); 583 unpack_2_ints(_oop_index, _offset);
579 } 584 }
580 585
586 void metadata_Relocation::pack_data_to(CodeSection* dest) {
587 short* p = (short*) dest->locs_end();
588 p = pack_2_ints_to(p, _metadata_index, _offset);
589 dest->set_locs_end((relocInfo*) p);
590 }
591
592
593 void metadata_Relocation::unpack_data() {
594 unpack_2_ints(_metadata_index, _offset);
595 }
596
581 597
582 void virtual_call_Relocation::pack_data_to(CodeSection* dest) { 598 void virtual_call_Relocation::pack_data_to(CodeSection* dest) {
583 short* p = (short*) dest->locs_end(); 599 short* p = (short*) dest->locs_end();
584 address point = dest->locs_point(); 600 address point = dest->locs_point();
585 601
586 // Try to make a pointer NULL first. 602 normalize_address(_cached_value, dest);
587 if (_oop_limit >= point && 603 jint x0 = scaled_offset_null_special(_cached_value, point);
588 _oop_limit <= point + NativeCall::instruction_size) { 604 p = pack_1_int_to(p, x0);
589 _oop_limit = NULL;
590 }
591 // If the _oop_limit is NULL, it "defaults" to the end of the call.
592 // See ic_call_Relocation::oop_limit() below.
593
594 normalize_address(_first_oop, dest);
595 normalize_address(_oop_limit, dest);
596 jint x0 = scaled_offset_null_special(_first_oop, point);
597 jint x1 = scaled_offset_null_special(_oop_limit, point);
598 p = pack_2_ints_to(p, x0, x1);
599 dest->set_locs_end((relocInfo*) p); 605 dest->set_locs_end((relocInfo*) p);
600 } 606 }
601 607
602 608
603 void virtual_call_Relocation::unpack_data() { 609 void virtual_call_Relocation::unpack_data() {
604 jint x0, x1; unpack_2_ints(x0, x1); 610 jint x0 = unpack_1_int();
605 address point = addr(); 611 address point = addr();
606 _first_oop = x0==0? NULL: address_from_scaled_offset(x0, point); 612 _cached_value = x0==0? NULL: address_from_scaled_offset(x0, point);
607 _oop_limit = x1==0? NULL: address_from_scaled_offset(x1, point);
608 } 613 }
609 614
610 615
611 void static_stub_Relocation::pack_data_to(CodeSection* dest) { 616 void static_stub_Relocation::pack_data_to(CodeSection* dest) {
612 short* p = (short*) dest->locs_end(); 617 short* p = (short*) dest->locs_end();
797 // get the oop from the pool, and re-insert it into the instruction: 802 // get the oop from the pool, and re-insert it into the instruction:
798 verify_value(value()); 803 verify_value(value());
799 } 804 }
800 } 805 }
801 806
802 807 // meta data versions
803 RelocIterator virtual_call_Relocation::parse_ic(nmethod* &nm, address &ic_call, address &first_oop, 808 Metadata** metadata_Relocation::metadata_addr() {
804 oop* &oop_addr, bool *is_optimized) { 809 int n = _metadata_index;
805 assert(ic_call != NULL, "ic_call address must be set"); 810 if (n == 0) {
806 assert(ic_call != NULL || first_oop != NULL, "must supply a non-null input"); 811 // metadata is stored in the code stream
807 if (nm == NULL) { 812 return (Metadata**) pd_address_in_code();
808 CodeBlob* code;
809 if (ic_call != NULL) {
810 code = CodeCache::find_blob(ic_call);
811 } else if (first_oop != NULL) {
812 code = CodeCache::find_blob(first_oop);
813 }
814 nm = code->as_nmethod_or_null();
815 assert(nm != NULL, "address to parse must be in nmethod");
816 }
817 assert(ic_call == NULL || nm->contains(ic_call), "must be in nmethod");
818 assert(first_oop == NULL || nm->contains(first_oop), "must be in nmethod");
819
820 address oop_limit = NULL;
821
822 if (ic_call != NULL) {
823 // search for the ic_call at the given address
824 RelocIterator iter(nm, ic_call, ic_call+1);
825 bool ret = iter.next();
826 assert(ret == true, "relocInfo must exist at this address");
827 assert(iter.addr() == ic_call, "must find ic_call");
828 if (iter.type() == relocInfo::virtual_call_type) {
829 virtual_call_Relocation* r = iter.virtual_call_reloc();
830 first_oop = r->first_oop();
831 oop_limit = r->oop_limit();
832 *is_optimized = false;
833 } else { 813 } else {
834 assert(iter.type() == relocInfo::opt_virtual_call_type, "must be a virtual call"); 814 // metadata is stored in table at nmethod::metadatas_begin
835 *is_optimized = true; 815 return code()->metadata_addr_at(n);
836 oop_addr = NULL; 816 }
837 first_oop = NULL; 817 }
838 return iter; 818
839 } 819
840 } 820 Metadata* metadata_Relocation::metadata_value() {
841 821 Metadata* v = *metadata_addr();
842 // search for the first_oop, to get its oop_addr 822 // clean inline caches store a special pseudo-null
843 RelocIterator all_oops(nm, first_oop); 823 if (v == (Metadata*)Universe::non_oop_word()) v = NULL;
844 RelocIterator iter = all_oops; 824 return v;
845 iter.set_limit(first_oop+1); 825 }
846 bool found_oop = false; 826
847 while (iter.next()) { 827
848 if (iter.type() == relocInfo::oop_type) { 828 void metadata_Relocation::fix_metadata_relocation() {
849 assert(iter.addr() == first_oop, "must find first_oop"); 829 if (!metadata_is_immediate()) {
850 oop_addr = iter.oop_reloc()->oop_addr(); 830 // get the metadata from the pool, and re-insert it into the instruction:
851 found_oop = true; 831 pd_fix_value(value());
852 break; 832 }
853 } 833 }
854 } 834
855 assert(found_oop, "must find first_oop"); 835
856 836 void metadata_Relocation::verify_metadata_relocation() {
857 bool did_reset = false; 837 if (!metadata_is_immediate()) {
858 while (ic_call == NULL) { 838 // get the metadata from the pool, and re-insert it into the instruction:
859 // search forward for the ic_call matching the given first_oop 839 verify_value(value());
860 while (iter.next()) { 840 }
861 if (iter.type() == relocInfo::virtual_call_type) { 841 }
862 virtual_call_Relocation* r = iter.virtual_call_reloc(); 842
863 if (r->first_oop() == first_oop) { 843 address virtual_call_Relocation::cached_value() {
864 ic_call = r->addr(); 844 assert(_cached_value != NULL && _cached_value < addr(), "must precede ic_call");
865 oop_limit = r->oop_limit(); 845 return _cached_value;
866 break; 846 }
867 }
868 }
869 }
870 guarantee(!did_reset, "cannot find ic_call");
871 iter = RelocIterator(nm); // search the whole nmethod
872 did_reset = true;
873 }
874
875 assert(oop_limit != NULL && first_oop != NULL && ic_call != NULL, "");
876 all_oops.set_limit(oop_limit);
877 return all_oops;
878 }
879
880
881 address virtual_call_Relocation::first_oop() {
882 assert(_first_oop != NULL && _first_oop < addr(), "must precede ic_call");
883 return _first_oop;
884 }
885
886
887 address virtual_call_Relocation::oop_limit() {
888 if (_oop_limit == NULL)
889 return addr() + NativeCall::instruction_size;
890 else
891 return _oop_limit;
892 }
893
894 847
895 848
896 void virtual_call_Relocation::clear_inline_cache() { 849 void virtual_call_Relocation::clear_inline_cache() {
897 // No stubs for ICs 850 // No stubs for ICs
898 // Clean IC 851 // Clean IC
1137 tty->print("oop_value=" INTPTR_FORMAT ": ", (address)oop_value); 1090 tty->print("oop_value=" INTPTR_FORMAT ": ", (address)oop_value);
1138 oop_value->print_value_on(tty); 1091 oop_value->print_value_on(tty);
1139 } 1092 }
1140 break; 1093 break;
1141 } 1094 }
1095 case relocInfo::metadata_type:
1096 {
1097 metadata_Relocation* r = metadata_reloc();
1098 Metadata** metadata_addr = NULL;
1099 Metadata* raw_metadata = NULL;
1100 Metadata* metadata_value = NULL;
1101 if (code() != NULL || r->metadata_is_immediate()) {
1102 metadata_addr = r->metadata_addr();
1103 raw_metadata = *metadata_addr;
1104 metadata_value = r->metadata_value();
1105 }
1106 tty->print(" | [metadata_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT " offset=%d]",
1107 metadata_addr, (address)raw_metadata, r->offset());
1108 if (metadata_value != NULL) {
1109 tty->print("metadata_value=" INTPTR_FORMAT ": ", (address)metadata_value);
1110 metadata_value->print_value_on(tty);
1111 }
1112 break;
1113 }
1142 case relocInfo::external_word_type: 1114 case relocInfo::external_word_type:
1143 case relocInfo::internal_word_type: 1115 case relocInfo::internal_word_type:
1144 case relocInfo::section_word_type: 1116 case relocInfo::section_word_type:
1145 { 1117 {
1146 DataRelocation* r = (DataRelocation*) reloc(); 1118 DataRelocation* r = (DataRelocation*) reloc();
1155 break; 1127 break;
1156 } 1128 }
1157 case relocInfo::virtual_call_type: 1129 case relocInfo::virtual_call_type:
1158 { 1130 {
1159 virtual_call_Relocation* r = (virtual_call_Relocation*) reloc(); 1131 virtual_call_Relocation* r = (virtual_call_Relocation*) reloc();
1160 tty->print(" | [destination=" INTPTR_FORMAT " first_oop=" INTPTR_FORMAT " oop_limit=" INTPTR_FORMAT "]", 1132 tty->print(" | [destination=" INTPTR_FORMAT " cached_value=" INTPTR_FORMAT "]",
1161 r->destination(), r->first_oop(), r->oop_limit()); 1133 r->destination(), r->cached_value());
1162 break; 1134 break;
1163 } 1135 }
1164 case relocInfo::static_stub_type: 1136 case relocInfo::static_stub_type:
1165 { 1137 {
1166 static_stub_Relocation* r = (static_stub_Relocation*) reloc(); 1138 static_stub_Relocation* r = (static_stub_Relocation*) reloc();