src/share/vm/ci/ciMethodData.cpp

Mon, 07 Oct 2013 14:11:49 +0400

author
vlivanov
date
Mon, 07 Oct 2013 14:11:49 +0400
changeset 5904
5cc2d82aa82a
parent 4531
fcc9e7681d63
child 5907
c775af091fe9
permissions
-rw-r--r--

8024943: ciReplay: fails to dump replay data during safepointing
Reviewed-by: kvn, twisti

duke@435 1 /*
coleenp@4037 2 * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
duke@435 22 *
duke@435 23 */
duke@435 24
stefank@2314 25 #include "precompiled.hpp"
coleenp@4037 26 #include "ci/ciMetadata.hpp"
stefank@2314 27 #include "ci/ciMethodData.hpp"
minqi@4267 28 #include "ci/ciReplay.hpp"
stefank@2314 29 #include "ci/ciUtilities.hpp"
stefank@2314 30 #include "memory/allocation.inline.hpp"
stefank@2314 31 #include "memory/resourceArea.hpp"
stefank@2314 32 #include "runtime/deoptimization.hpp"
stefank@2314 33 #include "utilities/copy.hpp"
duke@435 34
duke@435 35 // ciMethodData
duke@435 36
duke@435 37 // ------------------------------------------------------------------
duke@435 38 // ciMethodData::ciMethodData
duke@435 39 //
coleenp@4037 40 ciMethodData::ciMethodData(MethodData* md) : ciMetadata(md) {
coleenp@4037 41 assert(md != NULL, "no null method data");
duke@435 42 Copy::zero_to_words((HeapWord*) &_orig, sizeof(_orig) / sizeof(HeapWord));
duke@435 43 _data = NULL;
duke@435 44 _data_size = 0;
duke@435 45 _extra_data_size = 0;
duke@435 46 _current_mileage = 0;
iveresov@2138 47 _invocation_counter = 0;
iveresov@2138 48 _backedge_counter = 0;
duke@435 49 _state = empty_state;
duke@435 50 _saw_free_extra_data = false;
duke@435 51 // Set an initial hint. Don't use set_hint_di() because
duke@435 52 // first_di() may be out of bounds if data_size is 0.
duke@435 53 _hint_di = first_di();
kvn@480 54 // Initialize the escape information (to "don't know.");
kvn@480 55 _eflags = _arg_local = _arg_stack = _arg_returned = 0;
duke@435 56 }
duke@435 57
duke@435 58 // ------------------------------------------------------------------
duke@435 59 // ciMethodData::ciMethodData
duke@435 60 //
coleenp@4037 61 // No MethodData*.
coleenp@4037 62 ciMethodData::ciMethodData() : ciMetadata(NULL) {
duke@435 63 Copy::zero_to_words((HeapWord*) &_orig, sizeof(_orig) / sizeof(HeapWord));
duke@435 64 _data = NULL;
duke@435 65 _data_size = 0;
duke@435 66 _extra_data_size = 0;
duke@435 67 _current_mileage = 0;
iveresov@2138 68 _invocation_counter = 0;
iveresov@2138 69 _backedge_counter = 0;
duke@435 70 _state = empty_state;
duke@435 71 _saw_free_extra_data = false;
duke@435 72 // Set an initial hint. Don't use set_hint_di() because
duke@435 73 // first_di() may be out of bounds if data_size is 0.
duke@435 74 _hint_di = first_di();
kvn@480 75 // Initialize the escape information (to "don't know.");
kvn@480 76 _eflags = _arg_local = _arg_stack = _arg_returned = 0;
duke@435 77 }
duke@435 78
duke@435 79 void ciMethodData::load_data() {
coleenp@4037 80 MethodData* mdo = get_MethodData();
duke@435 81 if (mdo == NULL) return;
duke@435 82
duke@435 83 // To do: don't copy the data if it is not "ripe" -- require a minimum #
duke@435 84 // of invocations.
duke@435 85
duke@435 86 // Snapshot the data -- actually, take an approximate snapshot of
duke@435 87 // the data. Any concurrently executing threads may be changing the
duke@435 88 // data as we copy it.
coleenp@4037 89 Copy::disjoint_words((HeapWord*) mdo,
coleenp@4037 90 (HeapWord*) &_orig,
coleenp@4037 91 sizeof(_orig) / HeapWordSize);
duke@435 92 Arena* arena = CURRENT_ENV->arena();
duke@435 93 _data_size = mdo->data_size();
duke@435 94 _extra_data_size = mdo->extra_data_size();
duke@435 95 int total_size = _data_size + _extra_data_size;
duke@435 96 _data = (intptr_t *) arena->Amalloc(total_size);
duke@435 97 Copy::disjoint_words((HeapWord*) mdo->data_base(), (HeapWord*) _data, total_size / HeapWordSize);
duke@435 98
duke@435 99 // Traverse the profile data, translating any oops into their
duke@435 100 // ci equivalents.
duke@435 101 ResourceMark rm;
duke@435 102 ciProfileData* ci_data = first_data();
duke@435 103 ProfileData* data = mdo->first_data();
duke@435 104 while (is_valid(ci_data)) {
duke@435 105 ci_data->translate_from(data);
duke@435 106 ci_data = next_data(ci_data);
duke@435 107 data = mdo->next_data(data);
duke@435 108 }
duke@435 109 // Note: Extra data are all BitData, and do not need translation.
coleenp@4037 110 _current_mileage = MethodData::mileage_of(mdo->method());
iveresov@2138 111 _invocation_counter = mdo->invocation_count();
iveresov@2138 112 _backedge_counter = mdo->backedge_count();
duke@435 113 _state = mdo->is_mature()? mature_state: immature_state;
duke@435 114
duke@435 115 _eflags = mdo->eflags();
duke@435 116 _arg_local = mdo->arg_local();
duke@435 117 _arg_stack = mdo->arg_stack();
duke@435 118 _arg_returned = mdo->arg_returned();
minqi@4267 119 #ifndef PRODUCT
minqi@4267 120 if (ReplayCompiles) {
minqi@4267 121 ciReplay::initialize(this);
minqi@4267 122 }
minqi@4267 123 #endif
duke@435 124 }
duke@435 125
duke@435 126 void ciReceiverTypeData::translate_receiver_data_from(ProfileData* data) {
duke@435 127 for (uint row = 0; row < row_limit(); row++) {
coleenp@4037 128 Klass* k = data->as_ReceiverTypeData()->receiver(row);
duke@435 129 if (k != NULL) {
coleenp@4037 130 ciKlass* klass = CURRENT_ENV->get_klass(k);
duke@435 131 set_receiver(row, klass);
duke@435 132 }
duke@435 133 }
duke@435 134 }
duke@435 135
duke@435 136
duke@435 137 // Get the data at an arbitrary (sort of) data index.
duke@435 138 ciProfileData* ciMethodData::data_at(int data_index) {
duke@435 139 if (out_of_bounds(data_index)) {
duke@435 140 return NULL;
duke@435 141 }
duke@435 142 DataLayout* data_layout = data_layout_at(data_index);
duke@435 143
duke@435 144 switch (data_layout->tag()) {
duke@435 145 case DataLayout::no_tag:
duke@435 146 default:
duke@435 147 ShouldNotReachHere();
duke@435 148 return NULL;
duke@435 149 case DataLayout::bit_data_tag:
duke@435 150 return new ciBitData(data_layout);
duke@435 151 case DataLayout::counter_data_tag:
duke@435 152 return new ciCounterData(data_layout);
duke@435 153 case DataLayout::jump_data_tag:
duke@435 154 return new ciJumpData(data_layout);
duke@435 155 case DataLayout::receiver_type_data_tag:
duke@435 156 return new ciReceiverTypeData(data_layout);
duke@435 157 case DataLayout::virtual_call_data_tag:
duke@435 158 return new ciVirtualCallData(data_layout);
duke@435 159 case DataLayout::ret_data_tag:
duke@435 160 return new ciRetData(data_layout);
duke@435 161 case DataLayout::branch_data_tag:
duke@435 162 return new ciBranchData(data_layout);
duke@435 163 case DataLayout::multi_branch_data_tag:
duke@435 164 return new ciMultiBranchData(data_layout);
kvn@480 165 case DataLayout::arg_info_data_tag:
kvn@480 166 return new ciArgInfoData(data_layout);
duke@435 167 };
duke@435 168 }
duke@435 169
duke@435 170 // Iteration over data.
duke@435 171 ciProfileData* ciMethodData::next_data(ciProfileData* current) {
duke@435 172 int current_index = dp_to_di(current->dp());
duke@435 173 int next_index = current_index + current->size_in_bytes();
duke@435 174 ciProfileData* next = data_at(next_index);
duke@435 175 return next;
duke@435 176 }
duke@435 177
duke@435 178 // Translate a bci to its corresponding data, or NULL.
duke@435 179 ciProfileData* ciMethodData::bci_to_data(int bci) {
duke@435 180 ciProfileData* data = data_before(bci);
duke@435 181 for ( ; is_valid(data); data = next_data(data)) {
duke@435 182 if (data->bci() == bci) {
duke@435 183 set_hint_di(dp_to_di(data->dp()));
duke@435 184 return data;
duke@435 185 } else if (data->bci() > bci) {
duke@435 186 break;
duke@435 187 }
duke@435 188 }
duke@435 189 // bci_to_extra_data(bci) ...
duke@435 190 DataLayout* dp = data_layout_at(data_size());
duke@435 191 DataLayout* end = data_layout_at(data_size() + extra_data_size());
coleenp@4037 192 for (; dp < end; dp = MethodData::next_extra(dp)) {
duke@435 193 if (dp->tag() == DataLayout::no_tag) {
duke@435 194 _saw_free_extra_data = true; // observed an empty slot (common case)
duke@435 195 return NULL;
duke@435 196 }
kvn@480 197 if (dp->tag() == DataLayout::arg_info_data_tag) {
kvn@480 198 break; // ArgInfoData is at the end of extra data section.
kvn@480 199 }
duke@435 200 if (dp->bci() == bci) {
duke@435 201 assert(dp->tag() == DataLayout::bit_data_tag, "sane");
duke@435 202 return new ciBitData(dp);
duke@435 203 }
duke@435 204 }
duke@435 205 return NULL;
duke@435 206 }
duke@435 207
duke@435 208 // Conservatively decode the trap_state of a ciProfileData.
duke@435 209 int ciMethodData::has_trap_at(ciProfileData* data, int reason) {
duke@435 210 typedef Deoptimization::DeoptReason DR_t;
duke@435 211 int per_bc_reason
duke@435 212 = Deoptimization::reason_recorded_per_bytecode_if_any((DR_t) reason);
duke@435 213 if (trap_count(reason) == 0) {
duke@435 214 // Impossible for this trap to have occurred, regardless of trap_state.
duke@435 215 // Note: This happens if the MDO is empty.
duke@435 216 return 0;
duke@435 217 } else if (per_bc_reason == Deoptimization::Reason_none) {
duke@435 218 // We cannot conclude anything; a trap happened somewhere, maybe here.
duke@435 219 return -1;
duke@435 220 } else if (data == NULL) {
duke@435 221 // No profile here, not even an extra_data record allocated on the fly.
duke@435 222 // If there are empty extra_data records, and there had been a trap,
duke@435 223 // there would have been a non-null data pointer. If there are no
duke@435 224 // free extra_data records, we must return a conservative -1.
duke@435 225 if (_saw_free_extra_data)
duke@435 226 return 0; // Q.E.D.
duke@435 227 else
duke@435 228 return -1; // bail with a conservative answer
duke@435 229 } else {
duke@435 230 return Deoptimization::trap_state_has_reason(data->trap_state(), per_bc_reason);
duke@435 231 }
duke@435 232 }
duke@435 233
duke@435 234 int ciMethodData::trap_recompiled_at(ciProfileData* data) {
duke@435 235 if (data == NULL) {
duke@435 236 return (_saw_free_extra_data? 0: -1); // (see previous method)
duke@435 237 } else {
duke@435 238 return Deoptimization::trap_state_is_recompiled(data->trap_state())? 1: 0;
duke@435 239 }
duke@435 240 }
duke@435 241
duke@435 242 void ciMethodData::clear_escape_info() {
duke@435 243 VM_ENTRY_MARK;
coleenp@4037 244 MethodData* mdo = get_MethodData();
kvn@480 245 if (mdo != NULL) {
duke@435 246 mdo->clear_escape_info();
kvn@480 247 ArgInfoData *aid = arg_info();
kvn@480 248 int arg_count = (aid == NULL) ? 0 : aid->number_of_args();
kvn@480 249 for (int i = 0; i < arg_count; i++) {
kvn@480 250 set_arg_modified(i, 0);
kvn@480 251 }
kvn@480 252 }
duke@435 253 _eflags = _arg_local = _arg_stack = _arg_returned = 0;
duke@435 254 }
duke@435 255
coleenp@4037 256 // copy our escape info to the MethodData* if it exists
duke@435 257 void ciMethodData::update_escape_info() {
duke@435 258 VM_ENTRY_MARK;
coleenp@4037 259 MethodData* mdo = get_MethodData();
duke@435 260 if ( mdo != NULL) {
duke@435 261 mdo->set_eflags(_eflags);
duke@435 262 mdo->set_arg_local(_arg_local);
duke@435 263 mdo->set_arg_stack(_arg_stack);
duke@435 264 mdo->set_arg_returned(_arg_returned);
kvn@480 265 int arg_count = mdo->method()->size_of_parameters();
kvn@480 266 for (int i = 0; i < arg_count; i++) {
kvn@480 267 mdo->set_arg_modified(i, arg_modified(i));
kvn@480 268 }
duke@435 269 }
duke@435 270 }
duke@435 271
iveresov@2138 272 void ciMethodData::set_compilation_stats(short loops, short blocks) {
iveresov@2138 273 VM_ENTRY_MARK;
coleenp@4037 274 MethodData* mdo = get_MethodData();
iveresov@2138 275 if (mdo != NULL) {
iveresov@2138 276 mdo->set_num_loops(loops);
iveresov@2138 277 mdo->set_num_blocks(blocks);
iveresov@2138 278 }
iveresov@2138 279 }
iveresov@2138 280
iveresov@2138 281 void ciMethodData::set_would_profile(bool p) {
iveresov@2138 282 VM_ENTRY_MARK;
coleenp@4037 283 MethodData* mdo = get_MethodData();
iveresov@2138 284 if (mdo != NULL) {
iveresov@2138 285 mdo->set_would_profile(p);
iveresov@2138 286 }
iveresov@2138 287 }
iveresov@2138 288
duke@435 289 bool ciMethodData::has_escape_info() {
coleenp@4037 290 return eflag_set(MethodData::estimated);
duke@435 291 }
duke@435 292
coleenp@4037 293 void ciMethodData::set_eflag(MethodData::EscapeFlag f) {
duke@435 294 set_bits(_eflags, f);
duke@435 295 }
duke@435 296
coleenp@4037 297 void ciMethodData::clear_eflag(MethodData::EscapeFlag f) {
duke@435 298 clear_bits(_eflags, f);
duke@435 299 }
duke@435 300
coleenp@4037 301 bool ciMethodData::eflag_set(MethodData::EscapeFlag f) const {
duke@435 302 return mask_bits(_eflags, f) != 0;
duke@435 303 }
duke@435 304
duke@435 305 void ciMethodData::set_arg_local(int i) {
duke@435 306 set_nth_bit(_arg_local, i);
duke@435 307 }
duke@435 308
duke@435 309 void ciMethodData::set_arg_stack(int i) {
duke@435 310 set_nth_bit(_arg_stack, i);
duke@435 311 }
duke@435 312
duke@435 313 void ciMethodData::set_arg_returned(int i) {
duke@435 314 set_nth_bit(_arg_returned, i);
duke@435 315 }
duke@435 316
kvn@480 317 void ciMethodData::set_arg_modified(int arg, uint val) {
kvn@480 318 ArgInfoData *aid = arg_info();
kvn@480 319 if (aid == NULL)
kvn@480 320 return;
kvn@480 321 assert(arg >= 0 && arg < aid->number_of_args(), "valid argument number");
kvn@480 322 aid->set_arg_modified(arg, val);
kvn@480 323 }
kvn@480 324
duke@435 325 bool ciMethodData::is_arg_local(int i) const {
duke@435 326 return is_set_nth_bit(_arg_local, i);
duke@435 327 }
duke@435 328
duke@435 329 bool ciMethodData::is_arg_stack(int i) const {
duke@435 330 return is_set_nth_bit(_arg_stack, i);
duke@435 331 }
duke@435 332
duke@435 333 bool ciMethodData::is_arg_returned(int i) const {
duke@435 334 return is_set_nth_bit(_arg_returned, i);
duke@435 335 }
duke@435 336
kvn@480 337 uint ciMethodData::arg_modified(int arg) const {
kvn@480 338 ArgInfoData *aid = arg_info();
kvn@480 339 if (aid == NULL)
kvn@480 340 return 0;
kvn@480 341 assert(arg >= 0 && arg < aid->number_of_args(), "valid argument number");
kvn@480 342 return aid->arg_modified(arg);
kvn@480 343 }
kvn@480 344
duke@435 345 ByteSize ciMethodData::offset_of_slot(ciProfileData* data, ByteSize slot_offset_in_data) {
coleenp@4037 346 // Get offset within MethodData* of the data array
coleenp@4037 347 ByteSize data_offset = MethodData::data_offset();
duke@435 348
duke@435 349 // Get cell offset of the ProfileData within data array
duke@435 350 int cell_offset = dp_to_di(data->dp());
duke@435 351
duke@435 352 // Add in counter_offset, the # of bytes into the ProfileData of counter or flag
duke@435 353 int offset = in_bytes(data_offset) + cell_offset + in_bytes(slot_offset_in_data);
duke@435 354
duke@435 355 return in_ByteSize(offset);
duke@435 356 }
duke@435 357
kvn@480 358 ciArgInfoData *ciMethodData::arg_info() const {
kvn@480 359 // Should be last, have to skip all traps.
kvn@480 360 DataLayout* dp = data_layout_at(data_size());
kvn@480 361 DataLayout* end = data_layout_at(data_size() + extra_data_size());
coleenp@4037 362 for (; dp < end; dp = MethodData::next_extra(dp)) {
kvn@480 363 if (dp->tag() == DataLayout::arg_info_data_tag)
kvn@480 364 return new ciArgInfoData(dp);
kvn@480 365 }
kvn@480 366 return NULL;
kvn@480 367 }
kvn@480 368
kvn@480 369
duke@435 370 // Implementation of the print method.
duke@435 371 void ciMethodData::print_impl(outputStream* st) {
coleenp@4037 372 ciMetadata::print_impl(st);
duke@435 373 }
duke@435 374
minqi@4267 375 void ciMethodData::dump_replay_data(outputStream* out) {
vlivanov@4531 376 ResourceMark rm;
minqi@4267 377 MethodData* mdo = get_MethodData();
minqi@4267 378 Method* method = mdo->method();
minqi@4267 379 Klass* holder = method->method_holder();
minqi@4267 380 out->print("ciMethodData %s %s %s %d %d",
minqi@4267 381 holder->name()->as_quoted_ascii(),
minqi@4267 382 method->name()->as_quoted_ascii(),
minqi@4267 383 method->signature()->as_quoted_ascii(),
minqi@4267 384 _state,
minqi@4267 385 current_mileage());
minqi@4267 386
minqi@4267 387 // dump the contents of the MDO header as raw data
minqi@4267 388 unsigned char* orig = (unsigned char*)&_orig;
minqi@4267 389 int length = sizeof(_orig);
minqi@4267 390 out->print(" orig %d", length);
minqi@4267 391 for (int i = 0; i < length; i++) {
minqi@4267 392 out->print(" %d", orig[i]);
minqi@4267 393 }
minqi@4267 394
minqi@4267 395 // dump the MDO data as raw data
minqi@4267 396 int elements = data_size() / sizeof(intptr_t);
minqi@4267 397 out->print(" data %d", elements);
minqi@4267 398 for (int i = 0; i < elements; i++) {
minqi@4267 399 // We could use INTPTR_FORMAT here but that's a zero justified
minqi@4267 400 // which makes comparing it with the SA version of this output
minqi@4267 401 // harder.
minqi@4267 402 #ifdef _LP64
minqi@4267 403 out->print(" 0x%" FORMAT64_MODIFIER "x", data()[i]);
minqi@4267 404 #else
minqi@4267 405 out->print(" 0x%x", data()[i]);
minqi@4267 406 #endif
minqi@4267 407 }
minqi@4267 408
minqi@4267 409 // The MDO contained oop references as ciObjects, so scan for those
minqi@4267 410 // and emit pairs of offset and klass name so that they can be
minqi@4267 411 // reconstructed at runtime. The first round counts the number of
minqi@4267 412 // oop references and the second actually emits them.
minqi@4267 413 int count = 0;
minqi@4267 414 for (int round = 0; round < 2; round++) {
minqi@4267 415 if (round == 1) out->print(" oops %d", count);
minqi@4267 416 ProfileData* pdata = first_data();
minqi@4267 417 for ( ; is_valid(pdata); pdata = next_data(pdata)) {
minqi@4267 418 if (pdata->is_ReceiverTypeData()) {
minqi@4267 419 ciReceiverTypeData* vdata = (ciReceiverTypeData*)pdata;
minqi@4267 420 for (uint i = 0; i < vdata->row_limit(); i++) {
minqi@4267 421 ciKlass* k = vdata->receiver(i);
minqi@4267 422 if (k != NULL) {
minqi@4267 423 if (round == 0) {
minqi@4267 424 count++;
minqi@4267 425 } else {
minqi@4267 426 out->print(" %d %s", dp_to_di(vdata->dp() + in_bytes(vdata->receiver_offset(i))) / sizeof(intptr_t), k->name()->as_quoted_ascii());
minqi@4267 427 }
minqi@4267 428 }
minqi@4267 429 }
minqi@4267 430 } else if (pdata->is_VirtualCallData()) {
minqi@4267 431 ciVirtualCallData* vdata = (ciVirtualCallData*)pdata;
minqi@4267 432 for (uint i = 0; i < vdata->row_limit(); i++) {
minqi@4267 433 ciKlass* k = vdata->receiver(i);
minqi@4267 434 if (k != NULL) {
minqi@4267 435 if (round == 0) {
minqi@4267 436 count++;
minqi@4267 437 } else {
minqi@4267 438 out->print(" %d %s", dp_to_di(vdata->dp() + in_bytes(vdata->receiver_offset(i))) / sizeof(intptr_t), k->name()->as_quoted_ascii());
minqi@4267 439 }
minqi@4267 440 }
minqi@4267 441 }
minqi@4267 442 }
minqi@4267 443 }
minqi@4267 444 }
minqi@4267 445 out->cr();
minqi@4267 446 }
minqi@4267 447
duke@435 448 #ifndef PRODUCT
duke@435 449 void ciMethodData::print() {
duke@435 450 print_data_on(tty);
duke@435 451 }
duke@435 452
duke@435 453 void ciMethodData::print_data_on(outputStream* st) {
duke@435 454 ResourceMark rm;
duke@435 455 ciProfileData* data;
duke@435 456 for (data = first_data(); is_valid(data); data = next_data(data)) {
duke@435 457 st->print("%d", dp_to_di(data->dp()));
duke@435 458 st->fill_to(6);
duke@435 459 data->print_data_on(st);
duke@435 460 }
kvn@480 461 st->print_cr("--- Extra data:");
kvn@480 462 DataLayout* dp = data_layout_at(data_size());
kvn@480 463 DataLayout* end = data_layout_at(data_size() + extra_data_size());
coleenp@4037 464 for (; dp < end; dp = MethodData::next_extra(dp)) {
kvn@480 465 if (dp->tag() == DataLayout::no_tag) continue;
kvn@480 466 if (dp->tag() == DataLayout::bit_data_tag) {
kvn@480 467 data = new BitData(dp);
kvn@480 468 } else {
kvn@480 469 assert(dp->tag() == DataLayout::arg_info_data_tag, "must be BitData or ArgInfo");
kvn@480 470 data = new ciArgInfoData(dp);
kvn@480 471 dp = end; // ArgInfoData is at the end of extra data section.
kvn@480 472 }
kvn@480 473 st->print("%d", dp_to_di(data->dp()));
kvn@480 474 st->fill_to(6);
kvn@480 475 data->print_data_on(st);
kvn@480 476 }
duke@435 477 }
duke@435 478
duke@435 479 void ciReceiverTypeData::print_receiver_data_on(outputStream* st) {
duke@435 480 uint row;
duke@435 481 int entries = 0;
duke@435 482 for (row = 0; row < row_limit(); row++) {
duke@435 483 if (receiver(row) != NULL) entries++;
duke@435 484 }
duke@435 485 st->print_cr("count(%u) entries(%u)", count(), entries);
duke@435 486 for (row = 0; row < row_limit(); row++) {
duke@435 487 if (receiver(row) != NULL) {
duke@435 488 tab(st);
duke@435 489 receiver(row)->print_name_on(st);
duke@435 490 st->print_cr("(%u)", receiver_count(row));
duke@435 491 }
duke@435 492 }
duke@435 493 }
duke@435 494
duke@435 495 void ciReceiverTypeData::print_data_on(outputStream* st) {
duke@435 496 print_shared(st, "ciReceiverTypeData");
duke@435 497 print_receiver_data_on(st);
duke@435 498 }
duke@435 499
duke@435 500 void ciVirtualCallData::print_data_on(outputStream* st) {
duke@435 501 print_shared(st, "ciVirtualCallData");
duke@435 502 rtd_super()->print_receiver_data_on(st);
duke@435 503 }
duke@435 504 #endif

mercurial