comparison src/share/vm/ci/ciMethodData.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 f95d63e2154a
children bd7a7ce2e264
comparison
equal deleted inserted replaced
6724:36d1d483d5d6 6725:da91efe96a93
1 /* 1 /*
2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2001, 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.
21 * questions. 21 * questions.
22 * 22 *
23 */ 23 */
24 24
25 #include "precompiled.hpp" 25 #include "precompiled.hpp"
26 #include "ci/ciMetadata.hpp"
26 #include "ci/ciMethodData.hpp" 27 #include "ci/ciMethodData.hpp"
27 #include "ci/ciUtilities.hpp" 28 #include "ci/ciUtilities.hpp"
28 #include "memory/allocation.inline.hpp" 29 #include "memory/allocation.inline.hpp"
29 #include "memory/resourceArea.hpp" 30 #include "memory/resourceArea.hpp"
30 #include "runtime/deoptimization.hpp" 31 #include "runtime/deoptimization.hpp"
33 // ciMethodData 34 // ciMethodData
34 35
35 // ------------------------------------------------------------------ 36 // ------------------------------------------------------------------
36 // ciMethodData::ciMethodData 37 // ciMethodData::ciMethodData
37 // 38 //
38 ciMethodData::ciMethodData(methodDataHandle h_md) : ciObject(h_md) { 39 ciMethodData::ciMethodData(MethodData* md) : ciMetadata(md) {
39 assert(h_md() != NULL, "no null method data"); 40 assert(md != NULL, "no null method data");
40 Copy::zero_to_words((HeapWord*) &_orig, sizeof(_orig) / sizeof(HeapWord)); 41 Copy::zero_to_words((HeapWord*) &_orig, sizeof(_orig) / sizeof(HeapWord));
41 _data = NULL; 42 _data = NULL;
42 _data_size = 0; 43 _data_size = 0;
43 _extra_data_size = 0; 44 _extra_data_size = 0;
44 _current_mileage = 0; 45 _current_mileage = 0;
54 } 55 }
55 56
56 // ------------------------------------------------------------------ 57 // ------------------------------------------------------------------
57 // ciMethodData::ciMethodData 58 // ciMethodData::ciMethodData
58 // 59 //
59 // No methodDataOop. 60 // No MethodData*.
60 ciMethodData::ciMethodData() : ciObject() { 61 ciMethodData::ciMethodData() : ciMetadata(NULL) {
61 Copy::zero_to_words((HeapWord*) &_orig, sizeof(_orig) / sizeof(HeapWord)); 62 Copy::zero_to_words((HeapWord*) &_orig, sizeof(_orig) / sizeof(HeapWord));
62 _data = NULL; 63 _data = NULL;
63 _data_size = 0; 64 _data_size = 0;
64 _extra_data_size = 0; 65 _extra_data_size = 0;
65 _current_mileage = 0; 66 _current_mileage = 0;
73 // Initialize the escape information (to "don't know."); 74 // Initialize the escape information (to "don't know.");
74 _eflags = _arg_local = _arg_stack = _arg_returned = 0; 75 _eflags = _arg_local = _arg_stack = _arg_returned = 0;
75 } 76 }
76 77
77 void ciMethodData::load_data() { 78 void ciMethodData::load_data() {
78 methodDataOop mdo = get_methodDataOop(); 79 MethodData* mdo = get_MethodData();
79 if (mdo == NULL) return; 80 if (mdo == NULL) return;
80 81
81 // To do: don't copy the data if it is not "ripe" -- require a minimum # 82 // To do: don't copy the data if it is not "ripe" -- require a minimum #
82 // of invocations. 83 // of invocations.
83 84
84 // Snapshot the data -- actually, take an approximate snapshot of 85 // Snapshot the data -- actually, take an approximate snapshot of
85 // the data. Any concurrently executing threads may be changing the 86 // the data. Any concurrently executing threads may be changing the
86 // data as we copy it. 87 // data as we copy it.
87 int skip_header = oopDesc::header_size(); 88 Copy::disjoint_words((HeapWord*) mdo,
88 Copy::disjoint_words((HeapWord*) mdo + skip_header, 89 (HeapWord*) &_orig,
89 (HeapWord*) &_orig + skip_header, 90 sizeof(_orig) / HeapWordSize);
90 sizeof(_orig) / HeapWordSize - skip_header);
91 DEBUG_ONLY(*_orig.adr_method() = NULL); // no dangling oops, please
92 Arena* arena = CURRENT_ENV->arena(); 91 Arena* arena = CURRENT_ENV->arena();
93 _data_size = mdo->data_size(); 92 _data_size = mdo->data_size();
94 _extra_data_size = mdo->extra_data_size(); 93 _extra_data_size = mdo->extra_data_size();
95 int total_size = _data_size + _extra_data_size; 94 int total_size = _data_size + _extra_data_size;
96 _data = (intptr_t *) arena->Amalloc(total_size); 95 _data = (intptr_t *) arena->Amalloc(total_size);
105 ci_data->translate_from(data); 104 ci_data->translate_from(data);
106 ci_data = next_data(ci_data); 105 ci_data = next_data(ci_data);
107 data = mdo->next_data(data); 106 data = mdo->next_data(data);
108 } 107 }
109 // Note: Extra data are all BitData, and do not need translation. 108 // Note: Extra data are all BitData, and do not need translation.
110 _current_mileage = methodDataOopDesc::mileage_of(mdo->method()); 109 _current_mileage = MethodData::mileage_of(mdo->method());
111 _invocation_counter = mdo->invocation_count(); 110 _invocation_counter = mdo->invocation_count();
112 _backedge_counter = mdo->backedge_count(); 111 _backedge_counter = mdo->backedge_count();
113 _state = mdo->is_mature()? mature_state: immature_state; 112 _state = mdo->is_mature()? mature_state: immature_state;
114 113
115 _eflags = mdo->eflags(); 114 _eflags = mdo->eflags();
118 _arg_returned = mdo->arg_returned(); 117 _arg_returned = mdo->arg_returned();
119 } 118 }
120 119
121 void ciReceiverTypeData::translate_receiver_data_from(ProfileData* data) { 120 void ciReceiverTypeData::translate_receiver_data_from(ProfileData* data) {
122 for (uint row = 0; row < row_limit(); row++) { 121 for (uint row = 0; row < row_limit(); row++) {
123 klassOop k = data->as_ReceiverTypeData()->receiver(row); 122 Klass* k = data->as_ReceiverTypeData()->receiver(row);
124 if (k != NULL) { 123 if (k != NULL) {
125 ciKlass* klass = CURRENT_ENV->get_object(k)->as_klass(); 124 ciKlass* klass = CURRENT_ENV->get_klass(k);
126 set_receiver(row, klass); 125 set_receiver(row, klass);
127 } 126 }
128 } 127 }
129 } 128 }
130 129
182 } 181 }
183 } 182 }
184 // bci_to_extra_data(bci) ... 183 // bci_to_extra_data(bci) ...
185 DataLayout* dp = data_layout_at(data_size()); 184 DataLayout* dp = data_layout_at(data_size());
186 DataLayout* end = data_layout_at(data_size() + extra_data_size()); 185 DataLayout* end = data_layout_at(data_size() + extra_data_size());
187 for (; dp < end; dp = methodDataOopDesc::next_extra(dp)) { 186 for (; dp < end; dp = MethodData::next_extra(dp)) {
188 if (dp->tag() == DataLayout::no_tag) { 187 if (dp->tag() == DataLayout::no_tag) {
189 _saw_free_extra_data = true; // observed an empty slot (common case) 188 _saw_free_extra_data = true; // observed an empty slot (common case)
190 return NULL; 189 return NULL;
191 } 190 }
192 if (dp->tag() == DataLayout::arg_info_data_tag) { 191 if (dp->tag() == DataLayout::arg_info_data_tag) {
234 } 233 }
235 } 234 }
236 235
237 void ciMethodData::clear_escape_info() { 236 void ciMethodData::clear_escape_info() {
238 VM_ENTRY_MARK; 237 VM_ENTRY_MARK;
239 methodDataOop mdo = get_methodDataOop(); 238 MethodData* mdo = get_MethodData();
240 if (mdo != NULL) { 239 if (mdo != NULL) {
241 mdo->clear_escape_info(); 240 mdo->clear_escape_info();
242 ArgInfoData *aid = arg_info(); 241 ArgInfoData *aid = arg_info();
243 int arg_count = (aid == NULL) ? 0 : aid->number_of_args(); 242 int arg_count = (aid == NULL) ? 0 : aid->number_of_args();
244 for (int i = 0; i < arg_count; i++) { 243 for (int i = 0; i < arg_count; i++) {
246 } 245 }
247 } 246 }
248 _eflags = _arg_local = _arg_stack = _arg_returned = 0; 247 _eflags = _arg_local = _arg_stack = _arg_returned = 0;
249 } 248 }
250 249
251 // copy our escape info to the methodDataOop if it exists 250 // copy our escape info to the MethodData* if it exists
252 void ciMethodData::update_escape_info() { 251 void ciMethodData::update_escape_info() {
253 VM_ENTRY_MARK; 252 VM_ENTRY_MARK;
254 methodDataOop mdo = get_methodDataOop(); 253 MethodData* mdo = get_MethodData();
255 if ( mdo != NULL) { 254 if ( mdo != NULL) {
256 mdo->set_eflags(_eflags); 255 mdo->set_eflags(_eflags);
257 mdo->set_arg_local(_arg_local); 256 mdo->set_arg_local(_arg_local);
258 mdo->set_arg_stack(_arg_stack); 257 mdo->set_arg_stack(_arg_stack);
259 mdo->set_arg_returned(_arg_returned); 258 mdo->set_arg_returned(_arg_returned);
264 } 263 }
265 } 264 }
266 265
267 void ciMethodData::set_compilation_stats(short loops, short blocks) { 266 void ciMethodData::set_compilation_stats(short loops, short blocks) {
268 VM_ENTRY_MARK; 267 VM_ENTRY_MARK;
269 methodDataOop mdo = get_methodDataOop(); 268 MethodData* mdo = get_MethodData();
270 if (mdo != NULL) { 269 if (mdo != NULL) {
271 mdo->set_num_loops(loops); 270 mdo->set_num_loops(loops);
272 mdo->set_num_blocks(blocks); 271 mdo->set_num_blocks(blocks);
273 } 272 }
274 } 273 }
275 274
276 void ciMethodData::set_would_profile(bool p) { 275 void ciMethodData::set_would_profile(bool p) {
277 VM_ENTRY_MARK; 276 VM_ENTRY_MARK;
278 methodDataOop mdo = get_methodDataOop(); 277 MethodData* mdo = get_MethodData();
279 if (mdo != NULL) { 278 if (mdo != NULL) {
280 mdo->set_would_profile(p); 279 mdo->set_would_profile(p);
281 } 280 }
282 } 281 }
283 282
284 bool ciMethodData::has_escape_info() { 283 bool ciMethodData::has_escape_info() {
285 return eflag_set(methodDataOopDesc::estimated); 284 return eflag_set(MethodData::estimated);
286 } 285 }
287 286
288 void ciMethodData::set_eflag(methodDataOopDesc::EscapeFlag f) { 287 void ciMethodData::set_eflag(MethodData::EscapeFlag f) {
289 set_bits(_eflags, f); 288 set_bits(_eflags, f);
290 } 289 }
291 290
292 void ciMethodData::clear_eflag(methodDataOopDesc::EscapeFlag f) { 291 void ciMethodData::clear_eflag(MethodData::EscapeFlag f) {
293 clear_bits(_eflags, f); 292 clear_bits(_eflags, f);
294 } 293 }
295 294
296 bool ciMethodData::eflag_set(methodDataOopDesc::EscapeFlag f) const { 295 bool ciMethodData::eflag_set(MethodData::EscapeFlag f) const {
297 return mask_bits(_eflags, f) != 0; 296 return mask_bits(_eflags, f) != 0;
298 } 297 }
299 298
300 void ciMethodData::set_arg_local(int i) { 299 void ciMethodData::set_arg_local(int i) {
301 set_nth_bit(_arg_local, i); 300 set_nth_bit(_arg_local, i);
336 assert(arg >= 0 && arg < aid->number_of_args(), "valid argument number"); 335 assert(arg >= 0 && arg < aid->number_of_args(), "valid argument number");
337 return aid->arg_modified(arg); 336 return aid->arg_modified(arg);
338 } 337 }
339 338
340 ByteSize ciMethodData::offset_of_slot(ciProfileData* data, ByteSize slot_offset_in_data) { 339 ByteSize ciMethodData::offset_of_slot(ciProfileData* data, ByteSize slot_offset_in_data) {
341 // Get offset within methodDataOop of the data array 340 // Get offset within MethodData* of the data array
342 ByteSize data_offset = methodDataOopDesc::data_offset(); 341 ByteSize data_offset = MethodData::data_offset();
343 342
344 // Get cell offset of the ProfileData within data array 343 // Get cell offset of the ProfileData within data array
345 int cell_offset = dp_to_di(data->dp()); 344 int cell_offset = dp_to_di(data->dp());
346 345
347 // Add in counter_offset, the # of bytes into the ProfileData of counter or flag 346 // Add in counter_offset, the # of bytes into the ProfileData of counter or flag
352 351
353 ciArgInfoData *ciMethodData::arg_info() const { 352 ciArgInfoData *ciMethodData::arg_info() const {
354 // Should be last, have to skip all traps. 353 // Should be last, have to skip all traps.
355 DataLayout* dp = data_layout_at(data_size()); 354 DataLayout* dp = data_layout_at(data_size());
356 DataLayout* end = data_layout_at(data_size() + extra_data_size()); 355 DataLayout* end = data_layout_at(data_size() + extra_data_size());
357 for (; dp < end; dp = methodDataOopDesc::next_extra(dp)) { 356 for (; dp < end; dp = MethodData::next_extra(dp)) {
358 if (dp->tag() == DataLayout::arg_info_data_tag) 357 if (dp->tag() == DataLayout::arg_info_data_tag)
359 return new ciArgInfoData(dp); 358 return new ciArgInfoData(dp);
360 } 359 }
361 return NULL; 360 return NULL;
362 } 361 }
363 362
364 363
365 // Implementation of the print method. 364 // Implementation of the print method.
366 void ciMethodData::print_impl(outputStream* st) { 365 void ciMethodData::print_impl(outputStream* st) {
367 ciObject::print_impl(st); 366 ciMetadata::print_impl(st);
368 } 367 }
369 368
370 #ifndef PRODUCT 369 #ifndef PRODUCT
371 void ciMethodData::print() { 370 void ciMethodData::print() {
372 print_data_on(tty); 371 print_data_on(tty);
381 data->print_data_on(st); 380 data->print_data_on(st);
382 } 381 }
383 st->print_cr("--- Extra data:"); 382 st->print_cr("--- Extra data:");
384 DataLayout* dp = data_layout_at(data_size()); 383 DataLayout* dp = data_layout_at(data_size());
385 DataLayout* end = data_layout_at(data_size() + extra_data_size()); 384 DataLayout* end = data_layout_at(data_size() + extra_data_size());
386 for (; dp < end; dp = methodDataOopDesc::next_extra(dp)) { 385 for (; dp < end; dp = MethodData::next_extra(dp)) {
387 if (dp->tag() == DataLayout::no_tag) continue; 386 if (dp->tag() == DataLayout::no_tag) continue;
388 if (dp->tag() == DataLayout::bit_data_tag) { 387 if (dp->tag() == DataLayout::bit_data_tag) {
389 data = new BitData(dp); 388 data = new BitData(dp);
390 } else { 389 } else {
391 assert(dp->tag() == DataLayout::arg_info_data_tag, "must be BitData or ArgInfo"); 390 assert(dp->tag() == DataLayout::arg_info_data_tag, "must be BitData or ArgInfo");