Mercurial > hg > truffle
annotate src/share/vm/oops/constMethodKlass.cpp @ 4181:319860ae697a
Simplify FrameMap: make offsets of spill slots and outgoing parameters independent so that they can be allocated at the same time, eliminating the separate phases. This makes the separate StackBlock unnecesary. Change CiStackSlot to use byte offsets instead of spill slot index. This makes CiTarget.spillSlotSize unnecessary.
author | Christian Wimmer <Christian.Wimmer@Oracle.com> |
---|---|
date | Mon, 02 Jan 2012 14:16:08 -0800 |
parents | c124e2e7463e |
children | 2fe087c3e814 |
rev | line source |
---|---|
0 | 1 /* |
2227 | 2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1155
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1155
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1155
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "gc_implementation/shared/markSweep.inline.hpp" | |
27 #include "interpreter/interpreter.hpp" | |
28 #include "memory/gcLocker.hpp" | |
29 #include "memory/resourceArea.hpp" | |
30 #include "oops/constMethodKlass.hpp" | |
31 #include "oops/constMethodOop.hpp" | |
32 #include "oops/oop.inline.hpp" | |
33 #include "oops/oop.inline2.hpp" | |
34 #include "runtime/handles.inline.hpp" | |
0 | 35 |
36 | |
37 klassOop constMethodKlass::create_klass(TRAPS) { | |
38 constMethodKlass o; | |
39 KlassHandle h_this_klass(THREAD, Universe::klassKlassObj()); | |
40 KlassHandle k = base_create_klass(h_this_klass, header_size(), | |
41 o.vtbl_value(), CHECK_NULL); | |
42 // Make sure size calculation is right | |
43 assert(k()->size() == align_object_size(header_size()), | |
44 "wrong size for object"); | |
45 //java_lang_Class::create_mirror(k, CHECK_NULL); // Allocate mirror | |
46 return k(); | |
47 } | |
48 | |
49 | |
50 int constMethodKlass::oop_size(oop obj) const { | |
51 assert(obj->is_constMethod(), "must be constMethod oop"); | |
52 return constMethodOop(obj)->object_size(); | |
53 } | |
54 | |
55 bool constMethodKlass::oop_is_parsable(oop obj) const { | |
56 assert(obj->is_constMethod(), "must be constMethod oop"); | |
57 return constMethodOop(obj)->object_is_parsable(); | |
58 } | |
59 | |
518
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
0
diff
changeset
|
60 bool constMethodKlass::oop_is_conc_safe(oop obj) const { |
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
0
diff
changeset
|
61 assert(obj->is_constMethod(), "must be constMethod oop"); |
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
0
diff
changeset
|
62 return constMethodOop(obj)->is_conc_safe(); |
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
0
diff
changeset
|
63 } |
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
0
diff
changeset
|
64 |
0 | 65 constMethodOop constMethodKlass::allocate(int byte_code_size, |
66 int compressed_line_number_size, | |
67 int localvariable_table_length, | |
68 int checked_exceptions_length, | |
518
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
0
diff
changeset
|
69 bool is_conc_safe, |
0 | 70 TRAPS) { |
71 | |
72 int size = constMethodOopDesc::object_size(byte_code_size, | |
73 compressed_line_number_size, | |
74 localvariable_table_length, | |
75 checked_exceptions_length); | |
76 KlassHandle h_k(THREAD, as_klassOop()); | |
77 constMethodOop cm = (constMethodOop) | |
78 CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL); | |
79 assert(!cm->is_parsable(), "Not yet safely parsable"); | |
80 No_Safepoint_Verifier no_safepoint; | |
81 cm->set_interpreter_kind(Interpreter::invalid); | |
82 cm->init_fingerprint(); | |
83 cm->set_method(NULL); | |
84 cm->set_stackmap_data(NULL); | |
85 cm->set_exception_table(NULL); | |
86 cm->set_code_size(byte_code_size); | |
87 cm->set_constMethod_size(size); | |
88 cm->set_inlined_tables_length(checked_exceptions_length, | |
89 compressed_line_number_size, | |
90 localvariable_table_length); | |
91 assert(cm->size() == size, "wrong size for object"); | |
518
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
0
diff
changeset
|
92 cm->set_is_conc_safe(is_conc_safe); |
0 | 93 cm->set_partially_loaded(); |
94 assert(cm->is_parsable(), "Is safely parsable by gc"); | |
95 return cm; | |
96 } | |
97 | |
98 void constMethodKlass::oop_follow_contents(oop obj) { | |
99 assert (obj->is_constMethod(), "object must be constMethod"); | |
100 constMethodOop cm = constMethodOop(obj); | |
101 MarkSweep::mark_and_push(cm->adr_method()); | |
102 MarkSweep::mark_and_push(cm->adr_stackmap_data()); | |
103 MarkSweep::mark_and_push(cm->adr_exception_table()); | |
104 // Performance tweak: We skip iterating over the klass pointer since we | |
105 // know that Universe::constMethodKlassObj never moves. | |
106 } | |
107 | |
108 #ifndef SERIALGC | |
109 void constMethodKlass::oop_follow_contents(ParCompactionManager* cm, | |
110 oop obj) { | |
111 assert (obj->is_constMethod(), "object must be constMethod"); | |
112 constMethodOop cm_oop = constMethodOop(obj); | |
113 PSParallelCompact::mark_and_push(cm, cm_oop->adr_method()); | |
114 PSParallelCompact::mark_and_push(cm, cm_oop->adr_stackmap_data()); | |
115 PSParallelCompact::mark_and_push(cm, cm_oop->adr_exception_table()); | |
116 // Performance tweak: We skip iterating over the klass pointer since we | |
117 // know that Universe::constMethodKlassObj never moves. | |
118 } | |
119 #endif // SERIALGC | |
120 | |
121 int constMethodKlass::oop_oop_iterate(oop obj, OopClosure* blk) { | |
122 assert (obj->is_constMethod(), "object must be constMethod"); | |
123 constMethodOop cm = constMethodOop(obj); | |
124 blk->do_oop(cm->adr_method()); | |
125 blk->do_oop(cm->adr_stackmap_data()); | |
126 blk->do_oop(cm->adr_exception_table()); | |
127 // Get size before changing pointers. | |
128 // Don't call size() or oop_size() since that is a virtual call. | |
129 int size = cm->object_size(); | |
130 return size; | |
131 } | |
132 | |
133 | |
134 int constMethodKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) { | |
135 assert (obj->is_constMethod(), "object must be constMethod"); | |
136 constMethodOop cm = constMethodOop(obj); | |
137 oop* adr; | |
138 adr = cm->adr_method(); | |
139 if (mr.contains(adr)) blk->do_oop(adr); | |
140 adr = cm->adr_stackmap_data(); | |
141 if (mr.contains(adr)) blk->do_oop(adr); | |
142 adr = cm->adr_exception_table(); | |
143 if (mr.contains(adr)) blk->do_oop(adr); | |
144 // Get size before changing pointers. | |
145 // Don't call size() or oop_size() since that is a virtual call. | |
146 int size = cm->object_size(); | |
147 // Performance tweak: We skip iterating over the klass pointer since we | |
148 // know that Universe::constMethodKlassObj never moves. | |
149 return size; | |
150 } | |
151 | |
152 | |
153 int constMethodKlass::oop_adjust_pointers(oop obj) { | |
154 assert(obj->is_constMethod(), "should be constMethod"); | |
155 constMethodOop cm = constMethodOop(obj); | |
156 MarkSweep::adjust_pointer(cm->adr_method()); | |
157 MarkSweep::adjust_pointer(cm->adr_stackmap_data()); | |
158 MarkSweep::adjust_pointer(cm->adr_exception_table()); | |
159 // Get size before changing pointers. | |
160 // Don't call size() or oop_size() since that is a virtual call. | |
161 int size = cm->object_size(); | |
162 // Performance tweak: We skip iterating over the klass pointer since we | |
163 // know that Universe::constMethodKlassObj never moves. | |
164 return size; | |
165 } | |
166 | |
167 #ifndef SERIALGC | |
168 void constMethodKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { | |
169 assert(obj->is_constMethod(), "should be constMethod"); | |
170 } | |
171 | |
172 int constMethodKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { | |
173 assert(obj->is_constMethod(), "should be constMethod"); | |
174 constMethodOop cm_oop = constMethodOop(obj); | |
175 oop* const beg_oop = cm_oop->oop_block_beg(); | |
176 oop* const end_oop = cm_oop->oop_block_end(); | |
177 for (oop* cur_oop = beg_oop; cur_oop < end_oop; ++cur_oop) { | |
178 PSParallelCompact::adjust_pointer(cur_oop); | |
179 } | |
180 return cm_oop->object_size(); | |
181 } | |
182 #endif // SERIALGC | |
183 | |
184 // Printing | |
185 | |
186 void constMethodKlass::oop_print_on(oop obj, outputStream* st) { | |
187 ResourceMark rm; | |
188 assert(obj->is_constMethod(), "must be constMethod"); | |
189 Klass::oop_print_on(obj, st); | |
190 constMethodOop m = constMethodOop(obj); | |
191 st->print(" - method: " INTPTR_FORMAT " ", (address)m->method()); | |
192 m->method()->print_value_on(st); st->cr(); | |
193 st->print(" - exceptions: " INTPTR_FORMAT "\n", (address)m->exception_table()); | |
194 if (m->has_stackmap_table()) { | |
195 st->print(" - stackmap data: "); | |
196 m->stackmap_data()->print_value_on(st); | |
197 st->cr(); | |
198 } | |
199 } | |
200 | |
201 // Short version of printing constMethodOop - just print the name of the | |
202 // method it belongs to. | |
203 void constMethodKlass::oop_print_value_on(oop obj, outputStream* st) { | |
204 assert(obj->is_constMethod(), "must be constMethod"); | |
205 constMethodOop m = constMethodOop(obj); | |
206 st->print(" const part of method " ); | |
207 m->method()->print_value_on(st); | |
208 } | |
209 | |
210 const char* constMethodKlass::internal_name() const { | |
211 return "{constMethod}"; | |
212 } | |
213 | |
214 | |
215 // Verification | |
216 | |
217 void constMethodKlass::oop_verify_on(oop obj, outputStream* st) { | |
218 Klass::oop_verify_on(obj, st); | |
219 guarantee(obj->is_constMethod(), "object must be constMethod"); | |
220 constMethodOop m = constMethodOop(obj); | |
221 guarantee(m->is_perm(), "should be in permspace"); | |
222 | |
223 // Verification can occur during oop construction before the method or | |
224 // other fields have been initialized. | |
225 if (!obj->partially_loaded()) { | |
226 guarantee(m->method()->is_perm(), "should be in permspace"); | |
227 guarantee(m->method()->is_method(), "should be method"); | |
228 typeArrayOop stackmap_data = m->stackmap_data(); | |
229 guarantee(stackmap_data == NULL || | |
230 stackmap_data->is_perm(), "should be in permspace"); | |
231 guarantee(m->exception_table()->is_perm(), "should be in permspace"); | |
232 guarantee(m->exception_table()->is_typeArray(), "should be type array"); | |
233 | |
234 address m_end = (address)((oop*) m + m->size()); | |
235 address compressed_table_start = m->code_end(); | |
236 guarantee(compressed_table_start <= m_end, "invalid method layout"); | |
237 address compressed_table_end = compressed_table_start; | |
238 // Verify line number table | |
239 if (m->has_linenumber_table()) { | |
240 CompressedLineNumberReadStream stream(m->compressed_linenumber_table()); | |
241 while (stream.read_pair()) { | |
242 guarantee(stream.bci() >= 0 && stream.bci() <= m->code_size(), "invalid bci in line number table"); | |
243 } | |
244 compressed_table_end += stream.position(); | |
245 } | |
246 guarantee(compressed_table_end <= m_end, "invalid method layout"); | |
247 // Verify checked exceptions and local variable tables | |
248 if (m->has_checked_exceptions()) { | |
249 u2* addr = m->checked_exceptions_length_addr(); | |
250 guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout"); | |
251 } | |
252 if (m->has_localvariable_table()) { | |
253 u2* addr = m->localvariable_table_length_addr(); | |
254 guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout"); | |
255 } | |
256 // Check compressed_table_end relative to uncompressed_table_start | |
257 u2* uncompressed_table_start; | |
258 if (m->has_localvariable_table()) { | |
259 uncompressed_table_start = (u2*) m->localvariable_table_start(); | |
260 } else { | |
261 if (m->has_checked_exceptions()) { | |
262 uncompressed_table_start = (u2*) m->checked_exceptions_start(); | |
263 } else { | |
264 uncompressed_table_start = (u2*) m_end; | |
265 } | |
266 } | |
267 int gap = (intptr_t) uncompressed_table_start - (intptr_t) compressed_table_end; | |
268 int max_gap = align_object_size(1)*BytesPerWord; | |
269 guarantee(gap >= 0 && gap < max_gap, "invalid method layout"); | |
270 } | |
271 } | |
272 | |
273 bool constMethodKlass::oop_partially_loaded(oop obj) const { | |
274 assert(obj->is_constMethod(), "object must be klass"); | |
275 constMethodOop m = constMethodOop(obj); | |
276 // check whether exception_table points to self (flag for partially loaded) | |
277 return m->exception_table() == (typeArrayOop)obj; | |
278 } | |
279 | |
280 | |
281 // The exception_table is the last field set when loading an object. | |
282 void constMethodKlass::oop_set_partially_loaded(oop obj) { | |
283 assert(obj->is_constMethod(), "object must be klass"); | |
284 constMethodOop m = constMethodOop(obj); | |
285 // Temporarily set exception_table to point to self | |
286 m->set_exception_table((typeArrayOop)obj); | |
287 } |