0
|
1 /*
|
|
2 * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
|
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
4 *
|
|
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
|
|
7 * published by the Free Software Foundation.
|
|
8 *
|
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT
|
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
12 * version 2 for more details (a copy is included in the LICENSE file that
|
|
13 * accompanied this code).
|
|
14 *
|
|
15 * You should have received a copy of the GNU General Public License version
|
|
16 * 2 along with this work; if not, write to the Free Software Foundation,
|
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
18 *
|
|
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
20 * CA 95054 USA or visit www.sun.com if you need additional information or
|
|
21 * have any questions.
|
|
22 *
|
|
23 */
|
|
24
|
|
25 # include "incls/_precompiled.incl"
|
|
26 # include "incls/_methodDataKlass.cpp.incl"
|
|
27
|
|
28 klassOop methodDataKlass::create_klass(TRAPS) {
|
|
29 methodDataKlass o;
|
|
30 KlassHandle h_this_klass(THREAD, Universe::klassKlassObj());
|
|
31 KlassHandle k = base_create_klass(h_this_klass, header_size(),
|
|
32 o.vtbl_value(), CHECK_NULL);
|
|
33 // Make sure size calculation is right
|
|
34 assert(k()->size() == align_object_size(header_size()),
|
|
35 "wrong size for object");
|
|
36 return k();
|
|
37 }
|
|
38
|
|
39
|
|
40 int methodDataKlass::oop_size(oop obj) const {
|
|
41 assert(obj->is_methodData(), "must be method data oop");
|
|
42 return methodDataOop(obj)->object_size();
|
|
43 }
|
|
44
|
|
45
|
|
46 bool methodDataKlass::oop_is_parsable(oop obj) const {
|
|
47 assert(obj->is_methodData(), "must be method data oop");
|
|
48 return methodDataOop(obj)->object_is_parsable();
|
|
49 }
|
|
50
|
|
51
|
|
52 methodDataOop methodDataKlass::allocate(methodHandle method, TRAPS) {
|
|
53 int size = methodDataOopDesc::compute_allocation_size_in_words(method);
|
|
54 KlassHandle h_k(THREAD, as_klassOop());
|
|
55 methodDataOop mdo =
|
|
56 (methodDataOop)CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL);
|
|
57 assert(!mdo->is_parsable(), "not expecting parsability yet.");
|
|
58 No_Safepoint_Verifier no_safepoint; // init function atomic wrt GC
|
|
59 mdo->initialize(method);
|
|
60
|
|
61 assert(mdo->is_parsable(), "should be parsable here.");
|
|
62 assert(size == mdo->object_size(), "wrong size for methodDataOop");
|
|
63 return mdo;
|
|
64 }
|
|
65
|
|
66
|
|
67 void methodDataKlass::oop_follow_contents(oop obj) {
|
|
68 assert (obj->is_methodData(), "object must be method data");
|
|
69 methodDataOop m = methodDataOop(obj);
|
|
70
|
|
71 obj->follow_header();
|
|
72 MarkSweep::mark_and_push(m->adr_method());
|
|
73 ResourceMark rm;
|
|
74 for (ProfileData* data = m->first_data();
|
|
75 m->is_valid(data);
|
|
76 data = m->next_data(data)) {
|
|
77 data->follow_contents();
|
|
78 }
|
|
79 }
|
|
80
|
|
81 #ifndef SERIALGC
|
|
82 void methodDataKlass::oop_follow_contents(ParCompactionManager* cm,
|
|
83 oop obj) {
|
|
84 assert (obj->is_methodData(), "object must be method data");
|
|
85 methodDataOop m = methodDataOop(obj);
|
|
86
|
|
87 obj->follow_header(cm);
|
|
88 PSParallelCompact::mark_and_push(cm, m->adr_method());
|
|
89 ResourceMark rm;
|
|
90 for (ProfileData* data = m->first_data();
|
|
91 m->is_valid(data);
|
|
92 data = m->next_data(data)) {
|
|
93 data->follow_contents(cm);
|
|
94 }
|
|
95 }
|
|
96 #endif // SERIALGC
|
|
97
|
|
98 int methodDataKlass::oop_oop_iterate(oop obj, OopClosure* blk) {
|
|
99 assert (obj->is_methodData(), "object must be method data");
|
|
100 methodDataOop m = methodDataOop(obj);
|
|
101 // Get size before changing pointers
|
|
102 // Don't call size() or oop_size() since that is a virtual call.
|
|
103 int size = m->object_size();
|
|
104
|
|
105 obj->oop_iterate_header(blk);
|
|
106 blk->do_oop(m->adr_method());
|
|
107 ResourceMark rm;
|
|
108 for (ProfileData* data = m->first_data();
|
|
109 m->is_valid(data);
|
|
110 data = m->next_data(data)) {
|
|
111 data->oop_iterate(blk);
|
|
112 }
|
|
113 return size;
|
|
114 }
|
|
115
|
|
116
|
|
117 int methodDataKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) {
|
|
118 assert (obj->is_methodData(), "object must be method data");
|
|
119 methodDataOop m = methodDataOop(obj);
|
|
120 // Get size before changing pointers
|
|
121 // Don't call size() or oop_size() since that is a virtual call.
|
|
122 int size = m->object_size();
|
|
123
|
|
124 obj->oop_iterate_header(blk, mr);
|
|
125 oop* adr = m->adr_method();
|
|
126 if (mr.contains(adr)) {
|
|
127 blk->do_oop(m->adr_method());
|
|
128 }
|
|
129 ResourceMark rm;
|
|
130 for (ProfileData* data = m->first_data();
|
|
131 m->is_valid(data);
|
|
132 data = m->next_data(data)) {
|
|
133 data->oop_iterate_m(blk, mr);
|
|
134 }
|
|
135 return size;
|
|
136 }
|
|
137
|
|
138 int methodDataKlass::oop_adjust_pointers(oop obj) {
|
|
139 assert(obj->is_methodData(), "should be method data");
|
|
140 methodDataOop m = methodDataOop(obj);
|
|
141 // Get size before changing pointers
|
|
142 // Don't call size() or oop_size() since that is a virtual call.
|
|
143 int size = m->object_size();
|
|
144
|
|
145 obj->adjust_header();
|
|
146 MarkSweep::adjust_pointer(m->adr_method());
|
|
147 ResourceMark rm;
|
|
148 ProfileData* data;
|
|
149 for (data = m->first_data(); m->is_valid(data); data = m->next_data(data)) {
|
|
150 data->adjust_pointers();
|
|
151 }
|
|
152 return size;
|
|
153 }
|
|
154
|
|
155
|
|
156 #ifndef SERIALGC
|
|
157 void methodDataKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) {
|
|
158 assert (obj->is_methodData(), "object must be method data");
|
|
159 methodDataOop m = methodDataOop(obj);
|
|
160 // This should never point into the young gen.
|
|
161 assert(!PSScavenge::should_scavenge(oop(*m->adr_method())), "Sanity");
|
|
162 }
|
|
163
|
|
164 void methodDataKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
|
|
165 assert (obj->is_methodData(), "object must be method data");
|
|
166 methodDataOop m = methodDataOop(obj);
|
|
167 // This should never point into the young gen.
|
|
168 assert(!PSScavenge::should_scavenge(oop(*m->adr_method())), "Sanity");
|
|
169 }
|
|
170
|
|
171 int methodDataKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
|
|
172 assert(obj->is_methodData(), "should be method data");
|
|
173 methodDataOop m = methodDataOop(obj);
|
|
174
|
|
175 PSParallelCompact::adjust_pointer(m->adr_method());
|
|
176
|
|
177 ResourceMark rm;
|
|
178 ProfileData* data;
|
|
179 for (data = m->first_data(); m->is_valid(data); data = m->next_data(data)) {
|
|
180 data->update_pointers();
|
|
181 }
|
|
182 return m->object_size();
|
|
183 }
|
|
184
|
|
185 int
|
|
186 methodDataKlass::oop_update_pointers(ParCompactionManager* cm, oop obj,
|
|
187 HeapWord* beg_addr, HeapWord* end_addr) {
|
|
188 assert(obj->is_methodData(), "should be method data");
|
|
189
|
|
190 oop* p;
|
|
191 methodDataOop m = methodDataOop(obj);
|
|
192
|
|
193 p = m->adr_method();
|
|
194 PSParallelCompact::adjust_pointer(p, beg_addr, end_addr);
|
|
195
|
|
196 ResourceMark rm;
|
|
197 ProfileData* data;
|
|
198 for (data = m->first_data(); m->is_valid(data); data = m->next_data(data)) {
|
|
199 data->update_pointers(beg_addr, end_addr);
|
|
200 }
|
|
201 return m->object_size();
|
|
202 }
|
|
203 #endif // SERIALGC
|
|
204
|
|
205 #ifndef PRODUCT
|
|
206
|
|
207 // Printing
|
|
208 void methodDataKlass::oop_print_on(oop obj, outputStream* st) {
|
|
209 assert(obj->is_methodData(), "should be method data");
|
|
210 methodDataOop m = methodDataOop(obj);
|
|
211 st->print("method data for ");
|
|
212 m->method()->print_value_on(st);
|
|
213 st->cr();
|
|
214 m->print_data_on(st);
|
|
215 }
|
|
216
|
|
217 void methodDataKlass::oop_print_value_on(oop obj, outputStream* st) {
|
|
218 assert(obj->is_methodData(), "should be method data");
|
|
219 methodDataOop m = methodDataOop(obj);
|
|
220 st->print("method data for ");
|
|
221 m->method()->print_value_on(st);
|
|
222 }
|
|
223
|
|
224 #endif // !PRODUCT
|
|
225
|
|
226 const char* methodDataKlass::internal_name() const {
|
|
227 return "{method data}";
|
|
228 }
|
|
229
|
|
230
|
|
231 // Verification
|
|
232 void methodDataKlass::oop_verify_on(oop obj, outputStream* st) {
|
|
233 Klass::oop_verify_on(obj, st);
|
|
234 guarantee(obj->is_methodData(), "object must be method data");
|
|
235 methodDataOop m = methodDataOop(obj);
|
|
236 guarantee(m->is_perm(), "should be in permspace");
|
|
237 m->verify_data_on(st);
|
|
238 }
|