Mercurial > hg > truffle
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(); |