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
60 bool constMethodKlass::oop_is_conc_safe(oop obj) const {
61 assert(obj->is_constMethod(), "must be constMethod oop");
62 return constMethodOop(obj)->is_conc_safe();
63 }
64
65 constMethodOop constMethodKlass::allocate(int byte_code_size,
66 int compressed_line_number_size,
67 int localvariable_table_length,
68 int checked_exceptions_length,
69 bool is_conc_safe,
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_result_type(T_VOID);
89 cm->set_inlined_tables_length(checked_exceptions_length,
90 compressed_line_number_size,
91 localvariable_table_length);
92 assert(cm->size() == size, "wrong size for object");
93 cm->set_is_conc_safe(is_conc_safe);
94 cm->set_partially_loaded();
95 assert(cm->is_parsable(), "Is safely parsable by gc");
96 return cm;
97 }
98
99 void constMethodKlass::oop_follow_contents(oop obj) {
100 assert (obj->is_constMethod(), "object must be constMethod");
101 constMethodOop cm = constMethodOop(obj);
102 MarkSweep::mark_and_push(cm->adr_method());
103 MarkSweep::mark_and_push(cm->adr_stackmap_data());
104 MarkSweep::mark_and_push(cm->adr_exception_table());
105 // Performance tweak: We skip iterating over the klass pointer since we
106 // know that Universe::constMethodKlassObj never moves.
107 }
108
109 #ifndef SERIALGC
110 void constMethodKlass::oop_follow_contents(ParCompactionManager* cm,
111 oop obj) {
112 assert (obj->is_constMethod(), "object must be constMethod");
113 constMethodOop cm_oop = constMethodOop(obj);
114 PSParallelCompact::mark_and_push(cm, cm_oop->adr_method());
115 PSParallelCompact::mark_and_push(cm, cm_oop->adr_stackmap_data());
116 PSParallelCompact::mark_and_push(cm, cm_oop->adr_exception_table());
117 // Performance tweak: We skip iterating over the klass pointer since we
118 // know that Universe::constMethodKlassObj never moves.
119 }
120 #endif // SERIALGC
121
122 int constMethodKlass::oop_oop_iterate(oop obj, OopClosure* blk) {
123 assert (obj->is_constMethod(), "object must be constMethod");
124 constMethodOop cm = constMethodOop(obj);
125 blk->do_oop(cm->adr_method());
126 blk->do_oop(cm->adr_stackmap_data());
127 blk->do_oop(cm->adr_exception_table());
128 // Get size before changing pointers.
129 // Don't call size() or oop_size() since that is a virtual call.
130 int size = cm->object_size();
131 return size;
132 }
133
134
135 int constMethodKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) {
136 assert (obj->is_constMethod(), "object must be constMethod");
137 constMethodOop cm = constMethodOop(obj);
138 oop* adr;
139 adr = cm->adr_method();
140 if (mr.contains(adr)) blk->do_oop(adr);
141 adr = cm->adr_stackmap_data();
142 if (mr.contains(adr)) blk->do_oop(adr);
143 adr = cm->adr_exception_table();
144 if (mr.contains(adr)) blk->do_oop(adr);
145 // Get size before changing pointers.
146 // Don't call size() or oop_size() since that is a virtual call.
147 int size = cm->object_size();
148 // Performance tweak: We skip iterating over the klass pointer since we
149 // know that Universe::constMethodKlassObj never moves.
150 return size;
151 }
152
153
154 int constMethodKlass::oop_adjust_pointers(oop obj) {
155 assert(obj->is_constMethod(), "should be constMethod");
156 constMethodOop cm = constMethodOop(obj);
157 MarkSweep::adjust_pointer(cm->adr_method());
158 MarkSweep::adjust_pointer(cm->adr_stackmap_data());
159 MarkSweep::adjust_pointer(cm->adr_exception_table());
160 // Get size before changing pointers.
161 // Don't call size() or oop_size() since that is a virtual call.
162 int size = cm->object_size();
163 // Performance tweak: We skip iterating over the klass pointer since we
164 // know that Universe::constMethodKlassObj never moves.
165 return size;
166 }
167
168 #ifndef SERIALGC
169 void constMethodKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
170 assert(obj->is_constMethod(), "should be constMethod");
171 }
172
173 int constMethodKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
174 assert(obj->is_constMethod(), "should be constMethod");
175 constMethodOop cm_oop = constMethodOop(obj);
176 oop* const beg_oop = cm_oop->oop_block_beg();
177 oop* const end_oop = cm_oop->oop_block_end();
178 for (oop* cur_oop = beg_oop; cur_oop < end_oop; ++cur_oop) {
179 PSParallelCompact::adjust_pointer(cur_oop);
180 }
181 return cm_oop->object_size();
182 }
183 #endif // SERIALGC
184
185 // Printing
186
187 void constMethodKlass::oop_print_on(oop obj, outputStream* st) {
188 ResourceMark rm;
189 assert(obj->is_constMethod(), "must be constMethod");
190 Klass::oop_print_on(obj, st);
191 constMethodOop m = constMethodOop(obj);
192 st->print(" - method: " INTPTR_FORMAT " ", (address)m->method());
193 m->method()->print_value_on(st); st->cr();
194 st->print(" - exceptions: " INTPTR_FORMAT "\n", (address)m->exception_table());
195 if (m->has_stackmap_table()) {
196 st->print(" - stackmap data: ");
197 m->stackmap_data()->print_value_on(st);
198 st->cr();
199 }
200 }
201
202 // Short version of printing constMethodOop - just print the name of the
203 // method it belongs to.
204 void constMethodKlass::oop_print_value_on(oop obj, outputStream* st) {
205 assert(obj->is_constMethod(), "must be constMethod");
206 constMethodOop m = constMethodOop(obj);
207 st->print(" const part of method " );
208 m->method()->print_value_on(st);
209 }
210
211 const char* constMethodKlass::internal_name() const {
212 return "{constMethod}";
213 }
214
215
216 // Verification
217
218 void constMethodKlass::oop_verify_on(oop obj, outputStream* st) {
219 Klass::oop_verify_on(obj, st);
220 guarantee(obj->is_constMethod(), "object must be constMethod");
221 constMethodOop m = constMethodOop(obj);
222 guarantee(m->is_perm(), "should be in permspace");
223
224 // Verification can occur during oop construction before the method or
225 // other fields have been initialized.
226 if (!obj->partially_loaded()) {
227 guarantee(m->method()->is_perm(), "should be in permspace");
228 guarantee(m->method()->is_method(), "should be method");
229 typeArrayOop stackmap_data = m->stackmap_data();
230 guarantee(stackmap_data == NULL ||
231 stackmap_data->is_perm(), "should be in permspace");
232 guarantee(m->exception_table()->is_perm(), "should be in permspace");
233 guarantee(m->exception_table()->is_typeArray(), "should be type array");
234
235 address m_end = (address)((oop*) m + m->size());
236 address compressed_table_start = m->code_end();
237 guarantee(compressed_table_start <= m_end, "invalid method layout");
238 address compressed_table_end = compressed_table_start;
239 // Verify line number table
240 if (m->has_linenumber_table()) {
241 CompressedLineNumberReadStream stream(m->compressed_linenumber_table());
242 while (stream.read_pair()) {
243 guarantee(stream.bci() >= 0 && stream.bci() <= m->code_size(), "invalid bci in line number table");
244 }
245 compressed_table_end += stream.position();
246 }
247 guarantee(compressed_table_end <= m_end, "invalid method layout");
248 // Verify checked exceptions and local variable tables
249 if (m->has_checked_exceptions()) {
250 u2* addr = m->checked_exceptions_length_addr();
251 guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
252 }
253 if (m->has_localvariable_table()) {
254 u2* addr = m->localvariable_table_length_addr();
255 guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
256 }
257 // Check compressed_table_end relative to uncompressed_table_start
258 u2* uncompressed_table_start;
259 if (m->has_localvariable_table()) {
260 uncompressed_table_start = (u2*) m->localvariable_table_start();
261 } else {
262 if (m->has_checked_exceptions()) {
263 uncompressed_table_start = (u2*) m->checked_exceptions_start();
264 } else {
265 uncompressed_table_start = (u2*) m_end;
266 }
267 }
268 int gap = (intptr_t) uncompressed_table_start - (intptr_t) compressed_table_end;
269 int max_gap = align_object_size(1)*BytesPerWord;
270 guarantee(gap >= 0 && gap < max_gap, "invalid method layout");
271 }
272 }
273
274 bool constMethodKlass::oop_partially_loaded(oop obj) const {
275 assert(obj->is_constMethod(), "object must be klass");
276 constMethodOop m = constMethodOop(obj);
277 // check whether exception_table points to self (flag for partially loaded)
278 return m->exception_table() == (typeArrayOop)obj;
279 }
280
281
282 // The exception_table is the last field set when loading an object.
283 void constMethodKlass::oop_set_partially_loaded(oop obj) {
284 assert(obj->is_constMethod(), "object must be klass");
285 constMethodOop m = constMethodOop(obj);
286 // Temporarily set exception_table to point to self
287 m->set_exception_table((typeArrayOop)obj);
288 }
|
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
60 bool constMethodKlass::oop_is_conc_safe(oop obj) const {
61 assert(obj->is_constMethod(), "must be constMethod oop");
62 return constMethodOop(obj)->is_conc_safe();
63 }
64
65 constMethodOop constMethodKlass::allocate(int byte_code_size,
66 int compressed_line_number_size,
67 int localvariable_table_length,
68 int exception_table_length,
69 int checked_exceptions_length,
70 bool is_conc_safe,
71 TRAPS) {
72
73 int size = constMethodOopDesc::object_size(byte_code_size,
74 compressed_line_number_size,
75 localvariable_table_length,
76 exception_table_length,
77 checked_exceptions_length);
78 KlassHandle h_k(THREAD, as_klassOop());
79 constMethodOop cm = (constMethodOop)
80 CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL);
81 assert(!cm->is_parsable(), "Not yet safely parsable");
82 No_Safepoint_Verifier no_safepoint;
83 cm->set_interpreter_kind(Interpreter::invalid);
84 cm->init_fingerprint();
85 cm->set_method(NULL);
86 cm->set_stackmap_data(NULL);
87 cm->set_code_size(byte_code_size);
88 cm->set_constMethod_size(size);
89 cm->set_result_type(T_VOID);
90 cm->set_inlined_tables_length(checked_exceptions_length,
91 compressed_line_number_size,
92 localvariable_table_length,
93 exception_table_length);
94 assert(cm->size() == size, "wrong size for object");
95 cm->set_is_conc_safe(is_conc_safe);
96 cm->set_partially_loaded();
97 assert(cm->is_parsable(), "Is safely parsable by gc");
98 return cm;
99 }
100
101 void constMethodKlass::oop_follow_contents(oop obj) {
102 assert (obj->is_constMethod(), "object must be constMethod");
103 constMethodOop cm = constMethodOop(obj);
104 MarkSweep::mark_and_push(cm->adr_method());
105 MarkSweep::mark_and_push(cm->adr_stackmap_data());
106 // Performance tweak: We skip iterating over the klass pointer since we
107 // know that Universe::constMethodKlassObj never moves.
108 }
109
110 #ifndef SERIALGC
111 void constMethodKlass::oop_follow_contents(ParCompactionManager* cm,
112 oop obj) {
113 assert (obj->is_constMethod(), "object must be constMethod");
114 constMethodOop cm_oop = constMethodOop(obj);
115 PSParallelCompact::mark_and_push(cm, cm_oop->adr_method());
116 PSParallelCompact::mark_and_push(cm, cm_oop->adr_stackmap_data());
117 // Performance tweak: We skip iterating over the klass pointer since we
118 // know that Universe::constMethodKlassObj never moves.
119 }
120 #endif // SERIALGC
121
122 int constMethodKlass::oop_oop_iterate(oop obj, OopClosure* blk) {
123 assert (obj->is_constMethod(), "object must be constMethod");
124 constMethodOop cm = constMethodOop(obj);
125 blk->do_oop(cm->adr_method());
126 blk->do_oop(cm->adr_stackmap_data());
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 // Get size before changing pointers.
143 // Don't call size() or oop_size() since that is a virtual call.
144 int size = cm->object_size();
145 // Performance tweak: We skip iterating over the klass pointer since we
146 // know that Universe::constMethodKlassObj never moves.
147 return size;
148 }
149
150
151 int constMethodKlass::oop_adjust_pointers(oop obj) {
152 assert(obj->is_constMethod(), "should be constMethod");
153 constMethodOop cm = constMethodOop(obj);
154 MarkSweep::adjust_pointer(cm->adr_method());
155 MarkSweep::adjust_pointer(cm->adr_stackmap_data());
156 // Get size before changing pointers.
157 // Don't call size() or oop_size() since that is a virtual call.
158 int size = cm->object_size();
159 // Performance tweak: We skip iterating over the klass pointer since we
160 // know that Universe::constMethodKlassObj never moves.
161 return size;
162 }
163
164 #ifndef SERIALGC
165 void constMethodKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
166 assert(obj->is_constMethod(), "should be constMethod");
167 }
168
169 int constMethodKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
170 assert(obj->is_constMethod(), "should be constMethod");
171 constMethodOop cm_oop = constMethodOop(obj);
172 oop* const beg_oop = cm_oop->oop_block_beg();
173 oop* const end_oop = cm_oop->oop_block_end();
174 for (oop* cur_oop = beg_oop; cur_oop < end_oop; ++cur_oop) {
175 PSParallelCompact::adjust_pointer(cur_oop);
176 }
177 return cm_oop->object_size();
178 }
179 #endif // SERIALGC
180
181 // Printing
182
183 void constMethodKlass::oop_print_on(oop obj, outputStream* st) {
184 ResourceMark rm;
185 assert(obj->is_constMethod(), "must be constMethod");
186 Klass::oop_print_on(obj, st);
187 constMethodOop m = constMethodOop(obj);
188 st->print(" - method: " INTPTR_FORMAT " ", (address)m->method());
189 m->method()->print_value_on(st); st->cr();
190 if (m->has_stackmap_table()) {
191 st->print(" - stackmap data: ");
192 m->stackmap_data()->print_value_on(st);
193 st->cr();
194 }
195 }
196
197 // Short version of printing constMethodOop - just print the name of the
198 // method it belongs to.
199 void constMethodKlass::oop_print_value_on(oop obj, outputStream* st) {
200 assert(obj->is_constMethod(), "must be constMethod");
201 constMethodOop m = constMethodOop(obj);
202 st->print(" const part of method " );
203 m->method()->print_value_on(st);
204 }
205
206 const char* constMethodKlass::internal_name() const {
207 return "{constMethod}";
208 }
209
210
211 // Verification
212
213 void constMethodKlass::oop_verify_on(oop obj, outputStream* st) {
214 Klass::oop_verify_on(obj, st);
215 guarantee(obj->is_constMethod(), "object must be constMethod");
216 constMethodOop m = constMethodOop(obj);
217 guarantee(m->is_perm(), "should be in permspace");
218
219 // Verification can occur during oop construction before the method or
220 // other fields have been initialized.
221 if (!obj->partially_loaded()) {
222 guarantee(m->method()->is_perm(), "should be in permspace");
223 guarantee(m->method()->is_method(), "should be method");
224 typeArrayOop stackmap_data = m->stackmap_data();
225 guarantee(stackmap_data == NULL ||
226 stackmap_data->is_perm(), "should be in permspace");
227
228 address m_end = (address)((oop*) m + m->size());
229 address compressed_table_start = m->code_end();
230 guarantee(compressed_table_start <= m_end, "invalid method layout");
231 address compressed_table_end = compressed_table_start;
232 // Verify line number table
233 if (m->has_linenumber_table()) {
234 CompressedLineNumberReadStream stream(m->compressed_linenumber_table());
235 while (stream.read_pair()) {
236 guarantee(stream.bci() >= 0 && stream.bci() <= m->code_size(), "invalid bci in line number table");
237 }
238 compressed_table_end += stream.position();
239 }
240 guarantee(compressed_table_end <= m_end, "invalid method layout");
241 // Verify checked exceptions, exception table and local variable tables
242 if (m->has_checked_exceptions()) {
243 u2* addr = m->checked_exceptions_length_addr();
244 guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
245 }
246 if (m->has_exception_handler()) {
247 u2* addr = m->exception_table_length_addr();
248 guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
249 }
250 if (m->has_localvariable_table()) {
251 u2* addr = m->localvariable_table_length_addr();
252 guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
253 }
254 // Check compressed_table_end relative to uncompressed_table_start
255 u2* uncompressed_table_start;
256 if (m->has_localvariable_table()) {
257 uncompressed_table_start = (u2*) m->localvariable_table_start();
258 } else if (m->has_exception_handler()) {
259 uncompressed_table_start = (u2*) m->exception_table_start();
260 } else if (m->has_checked_exceptions()) {
261 uncompressed_table_start = (u2*) m->checked_exceptions_start();
262 } else {
263 uncompressed_table_start = (u2*) m_end;
264 }
265 int gap = (intptr_t) uncompressed_table_start - (intptr_t) compressed_table_end;
266 int max_gap = align_object_size(1)*BytesPerWord;
267 guarantee(gap >= 0 && gap < max_gap, "invalid method layout");
268 }
269 }
270
271 bool constMethodKlass::oop_partially_loaded(oop obj) const {
272 assert(obj->is_constMethod(), "object must be klass");
273 constMethodOop m = constMethodOop(obj);
274 // check whether stackmap_data points to self (flag for partially loaded)
275 return m->stackmap_data() == (typeArrayOop)obj;
276 }
277
278
279 // The exception_table is the last field set when loading an object.
280 void constMethodKlass::oop_set_partially_loaded(oop obj) {
281 assert(obj->is_constMethod(), "object must be klass");
282 constMethodOop m = constMethodOop(obj);
283 // Temporarily set stackmap_data to point to self
284 m->set_stackmap_data((typeArrayOop)obj);
285 }
|