src/share/vm/ci/ciMethodData.cpp

Tue, 24 Dec 2013 11:48:39 -0800

author
mikael
date
Tue, 24 Dec 2013 11:48:39 -0800
changeset 6198
55fb97c4c58d
parent 5987
5ccbab1c69f3
child 6377
b8413a9cbb84
permissions
-rw-r--r--

8029233: Update copyright year to match last edit in jdk8 hotspot repository for 2013
Summary: Copyright year updated for files modified during 2013
Reviewed-by: twisti, iveresov

duke@435 1 /*
mikael@6198 2 * Copyright (c) 2001, 2013, 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;
roland@5987 56 _parameters = NULL;
duke@435 57 }
duke@435 58
duke@435 59 // ------------------------------------------------------------------
duke@435 60 // ciMethodData::ciMethodData
duke@435 61 //
coleenp@4037 62 // No MethodData*.
coleenp@4037 63 ciMethodData::ciMethodData() : ciMetadata(NULL) {
duke@435 64 Copy::zero_to_words((HeapWord*) &_orig, sizeof(_orig) / sizeof(HeapWord));
duke@435 65 _data = NULL;
duke@435 66 _data_size = 0;
duke@435 67 _extra_data_size = 0;
duke@435 68 _current_mileage = 0;
iveresov@2138 69 _invocation_counter = 0;
iveresov@2138 70 _backedge_counter = 0;
duke@435 71 _state = empty_state;
duke@435 72 _saw_free_extra_data = false;
duke@435 73 // Set an initial hint. Don't use set_hint_di() because
duke@435 74 // first_di() may be out of bounds if data_size is 0.
duke@435 75 _hint_di = first_di();
kvn@480 76 // Initialize the escape information (to "don't know.");
kvn@480 77 _eflags = _arg_local = _arg_stack = _arg_returned = 0;
roland@5987 78 _parameters = NULL;
duke@435 79 }
duke@435 80
duke@435 81 void ciMethodData::load_data() {
coleenp@4037 82 MethodData* mdo = get_MethodData();
twisti@5907 83 if (mdo == NULL) {
twisti@5907 84 return;
twisti@5907 85 }
duke@435 86
duke@435 87 // To do: don't copy the data if it is not "ripe" -- require a minimum #
duke@435 88 // of invocations.
duke@435 89
duke@435 90 // Snapshot the data -- actually, take an approximate snapshot of
duke@435 91 // the data. Any concurrently executing threads may be changing the
duke@435 92 // data as we copy it.
coleenp@4037 93 Copy::disjoint_words((HeapWord*) mdo,
coleenp@4037 94 (HeapWord*) &_orig,
coleenp@4037 95 sizeof(_orig) / HeapWordSize);
duke@435 96 Arena* arena = CURRENT_ENV->arena();
duke@435 97 _data_size = mdo->data_size();
duke@435 98 _extra_data_size = mdo->extra_data_size();
duke@435 99 int total_size = _data_size + _extra_data_size;
duke@435 100 _data = (intptr_t *) arena->Amalloc(total_size);
duke@435 101 Copy::disjoint_words((HeapWord*) mdo->data_base(), (HeapWord*) _data, total_size / HeapWordSize);
duke@435 102
duke@435 103 // Traverse the profile data, translating any oops into their
duke@435 104 // ci equivalents.
duke@435 105 ResourceMark rm;
duke@435 106 ciProfileData* ci_data = first_data();
duke@435 107 ProfileData* data = mdo->first_data();
duke@435 108 while (is_valid(ci_data)) {
duke@435 109 ci_data->translate_from(data);
duke@435 110 ci_data = next_data(ci_data);
duke@435 111 data = mdo->next_data(data);
duke@435 112 }
roland@5987 113 if (mdo->parameters_type_data() != NULL) {
roland@5987 114 _parameters = data_layout_at(mdo->parameters_type_data_di());
roland@5987 115 ciParametersTypeData* parameters = new ciParametersTypeData(_parameters);
roland@5987 116 parameters->translate_from(mdo->parameters_type_data());
roland@5987 117 }
roland@5987 118
duke@435 119 // Note: Extra data are all BitData, and do not need translation.
coleenp@4037 120 _current_mileage = MethodData::mileage_of(mdo->method());
iveresov@2138 121 _invocation_counter = mdo->invocation_count();
iveresov@2138 122 _backedge_counter = mdo->backedge_count();
duke@435 123 _state = mdo->is_mature()? mature_state: immature_state;
duke@435 124
duke@435 125 _eflags = mdo->eflags();
duke@435 126 _arg_local = mdo->arg_local();
duke@435 127 _arg_stack = mdo->arg_stack();
duke@435 128 _arg_returned = mdo->arg_returned();
minqi@4267 129 #ifndef PRODUCT
minqi@4267 130 if (ReplayCompiles) {
minqi@4267 131 ciReplay::initialize(this);
minqi@4267 132 }
minqi@4267 133 #endif
duke@435 134 }
duke@435 135
roland@5914 136 void ciReceiverTypeData::translate_receiver_data_from(const ProfileData* data) {
duke@435 137 for (uint row = 0; row < row_limit(); row++) {
coleenp@4037 138 Klass* k = data->as_ReceiverTypeData()->receiver(row);
duke@435 139 if (k != NULL) {
coleenp@4037 140 ciKlass* klass = CURRENT_ENV->get_klass(k);
duke@435 141 set_receiver(row, klass);
duke@435 142 }
duke@435 143 }
duke@435 144 }
duke@435 145
duke@435 146
roland@5914 147 void ciTypeStackSlotEntries::translate_type_data_from(const TypeStackSlotEntries* entries) {
roland@5921 148 for (int i = 0; i < _number_of_entries; i++) {
roland@5914 149 intptr_t k = entries->type(i);
roland@5914 150 TypeStackSlotEntries::set_type(i, translate_klass(k));
roland@5914 151 }
roland@5914 152 }
roland@5914 153
roland@5921 154 void ciReturnTypeEntry::translate_type_data_from(const ReturnTypeEntry* ret) {
roland@5921 155 intptr_t k = ret->type();
roland@5921 156 set_type(translate_klass(k));
roland@5921 157 }
roland@5921 158
duke@435 159 // Get the data at an arbitrary (sort of) data index.
duke@435 160 ciProfileData* ciMethodData::data_at(int data_index) {
duke@435 161 if (out_of_bounds(data_index)) {
duke@435 162 return NULL;
duke@435 163 }
duke@435 164 DataLayout* data_layout = data_layout_at(data_index);
duke@435 165
duke@435 166 switch (data_layout->tag()) {
duke@435 167 case DataLayout::no_tag:
duke@435 168 default:
duke@435 169 ShouldNotReachHere();
duke@435 170 return NULL;
duke@435 171 case DataLayout::bit_data_tag:
duke@435 172 return new ciBitData(data_layout);
duke@435 173 case DataLayout::counter_data_tag:
duke@435 174 return new ciCounterData(data_layout);
duke@435 175 case DataLayout::jump_data_tag:
duke@435 176 return new ciJumpData(data_layout);
duke@435 177 case DataLayout::receiver_type_data_tag:
duke@435 178 return new ciReceiverTypeData(data_layout);
duke@435 179 case DataLayout::virtual_call_data_tag:
duke@435 180 return new ciVirtualCallData(data_layout);
duke@435 181 case DataLayout::ret_data_tag:
duke@435 182 return new ciRetData(data_layout);
duke@435 183 case DataLayout::branch_data_tag:
duke@435 184 return new ciBranchData(data_layout);
duke@435 185 case DataLayout::multi_branch_data_tag:
duke@435 186 return new ciMultiBranchData(data_layout);
kvn@480 187 case DataLayout::arg_info_data_tag:
kvn@480 188 return new ciArgInfoData(data_layout);
roland@5914 189 case DataLayout::call_type_data_tag:
roland@5914 190 return new ciCallTypeData(data_layout);
roland@5914 191 case DataLayout::virtual_call_type_data_tag:
roland@5914 192 return new ciVirtualCallTypeData(data_layout);
roland@5987 193 case DataLayout::parameters_type_data_tag:
roland@5987 194 return new ciParametersTypeData(data_layout);
duke@435 195 };
duke@435 196 }
duke@435 197
duke@435 198 // Iteration over data.
duke@435 199 ciProfileData* ciMethodData::next_data(ciProfileData* current) {
duke@435 200 int current_index = dp_to_di(current->dp());
duke@435 201 int next_index = current_index + current->size_in_bytes();
duke@435 202 ciProfileData* next = data_at(next_index);
duke@435 203 return next;
duke@435 204 }
duke@435 205
duke@435 206 // Translate a bci to its corresponding data, or NULL.
duke@435 207 ciProfileData* ciMethodData::bci_to_data(int bci) {
duke@435 208 ciProfileData* data = data_before(bci);
duke@435 209 for ( ; is_valid(data); data = next_data(data)) {
duke@435 210 if (data->bci() == bci) {
duke@435 211 set_hint_di(dp_to_di(data->dp()));
duke@435 212 return data;
duke@435 213 } else if (data->bci() > bci) {
duke@435 214 break;
duke@435 215 }
duke@435 216 }
duke@435 217 // bci_to_extra_data(bci) ...
duke@435 218 DataLayout* dp = data_layout_at(data_size());
duke@435 219 DataLayout* end = data_layout_at(data_size() + extra_data_size());
coleenp@4037 220 for (; dp < end; dp = MethodData::next_extra(dp)) {
duke@435 221 if (dp->tag() == DataLayout::no_tag) {
duke@435 222 _saw_free_extra_data = true; // observed an empty slot (common case)
duke@435 223 return NULL;
duke@435 224 }
kvn@480 225 if (dp->tag() == DataLayout::arg_info_data_tag) {
kvn@480 226 break; // ArgInfoData is at the end of extra data section.
kvn@480 227 }
duke@435 228 if (dp->bci() == bci) {
duke@435 229 assert(dp->tag() == DataLayout::bit_data_tag, "sane");
duke@435 230 return new ciBitData(dp);
duke@435 231 }
duke@435 232 }
duke@435 233 return NULL;
duke@435 234 }
duke@435 235
duke@435 236 // Conservatively decode the trap_state of a ciProfileData.
duke@435 237 int ciMethodData::has_trap_at(ciProfileData* data, int reason) {
duke@435 238 typedef Deoptimization::DeoptReason DR_t;
duke@435 239 int per_bc_reason
duke@435 240 = Deoptimization::reason_recorded_per_bytecode_if_any((DR_t) reason);
duke@435 241 if (trap_count(reason) == 0) {
duke@435 242 // Impossible for this trap to have occurred, regardless of trap_state.
duke@435 243 // Note: This happens if the MDO is empty.
duke@435 244 return 0;
duke@435 245 } else if (per_bc_reason == Deoptimization::Reason_none) {
duke@435 246 // We cannot conclude anything; a trap happened somewhere, maybe here.
duke@435 247 return -1;
duke@435 248 } else if (data == NULL) {
duke@435 249 // No profile here, not even an extra_data record allocated on the fly.
duke@435 250 // If there are empty extra_data records, and there had been a trap,
duke@435 251 // there would have been a non-null data pointer. If there are no
duke@435 252 // free extra_data records, we must return a conservative -1.
duke@435 253 if (_saw_free_extra_data)
duke@435 254 return 0; // Q.E.D.
duke@435 255 else
duke@435 256 return -1; // bail with a conservative answer
duke@435 257 } else {
duke@435 258 return Deoptimization::trap_state_has_reason(data->trap_state(), per_bc_reason);
duke@435 259 }
duke@435 260 }
duke@435 261
duke@435 262 int ciMethodData::trap_recompiled_at(ciProfileData* data) {
duke@435 263 if (data == NULL) {
duke@435 264 return (_saw_free_extra_data? 0: -1); // (see previous method)
duke@435 265 } else {
duke@435 266 return Deoptimization::trap_state_is_recompiled(data->trap_state())? 1: 0;
duke@435 267 }
duke@435 268 }
duke@435 269
duke@435 270 void ciMethodData::clear_escape_info() {
duke@435 271 VM_ENTRY_MARK;
coleenp@4037 272 MethodData* mdo = get_MethodData();
kvn@480 273 if (mdo != NULL) {
duke@435 274 mdo->clear_escape_info();
kvn@480 275 ArgInfoData *aid = arg_info();
kvn@480 276 int arg_count = (aid == NULL) ? 0 : aid->number_of_args();
kvn@480 277 for (int i = 0; i < arg_count; i++) {
kvn@480 278 set_arg_modified(i, 0);
kvn@480 279 }
kvn@480 280 }
duke@435 281 _eflags = _arg_local = _arg_stack = _arg_returned = 0;
duke@435 282 }
duke@435 283
coleenp@4037 284 // copy our escape info to the MethodData* if it exists
duke@435 285 void ciMethodData::update_escape_info() {
duke@435 286 VM_ENTRY_MARK;
coleenp@4037 287 MethodData* mdo = get_MethodData();
duke@435 288 if ( mdo != NULL) {
duke@435 289 mdo->set_eflags(_eflags);
duke@435 290 mdo->set_arg_local(_arg_local);
duke@435 291 mdo->set_arg_stack(_arg_stack);
duke@435 292 mdo->set_arg_returned(_arg_returned);
kvn@480 293 int arg_count = mdo->method()->size_of_parameters();
kvn@480 294 for (int i = 0; i < arg_count; i++) {
kvn@480 295 mdo->set_arg_modified(i, arg_modified(i));
kvn@480 296 }
duke@435 297 }
duke@435 298 }
duke@435 299
iveresov@2138 300 void ciMethodData::set_compilation_stats(short loops, short blocks) {
iveresov@2138 301 VM_ENTRY_MARK;
coleenp@4037 302 MethodData* mdo = get_MethodData();
iveresov@2138 303 if (mdo != NULL) {
iveresov@2138 304 mdo->set_num_loops(loops);
iveresov@2138 305 mdo->set_num_blocks(blocks);
iveresov@2138 306 }
iveresov@2138 307 }
iveresov@2138 308
iveresov@2138 309 void ciMethodData::set_would_profile(bool p) {
iveresov@2138 310 VM_ENTRY_MARK;
coleenp@4037 311 MethodData* mdo = get_MethodData();
iveresov@2138 312 if (mdo != NULL) {
iveresov@2138 313 mdo->set_would_profile(p);
iveresov@2138 314 }
iveresov@2138 315 }
iveresov@2138 316
roland@5914 317 void ciMethodData::set_argument_type(int bci, int i, ciKlass* k) {
roland@5914 318 VM_ENTRY_MARK;
roland@5914 319 MethodData* mdo = get_MethodData();
roland@5914 320 if (mdo != NULL) {
roland@5914 321 ProfileData* data = mdo->bci_to_data(bci);
roland@5914 322 if (data->is_CallTypeData()) {
roland@5914 323 data->as_CallTypeData()->set_argument_type(i, k->get_Klass());
roland@5914 324 } else {
roland@5914 325 assert(data->is_VirtualCallTypeData(), "no arguments!");
roland@5914 326 data->as_VirtualCallTypeData()->set_argument_type(i, k->get_Klass());
roland@5914 327 }
roland@5914 328 }
roland@5914 329 }
roland@5914 330
roland@5987 331 void ciMethodData::set_parameter_type(int i, ciKlass* k) {
roland@5987 332 VM_ENTRY_MARK;
roland@5987 333 MethodData* mdo = get_MethodData();
roland@5987 334 if (mdo != NULL) {
roland@5987 335 mdo->parameters_type_data()->set_type(i, k->get_Klass());
roland@5987 336 }
roland@5987 337 }
roland@5987 338
roland@5921 339 void ciMethodData::set_return_type(int bci, ciKlass* k) {
roland@5921 340 VM_ENTRY_MARK;
roland@5921 341 MethodData* mdo = get_MethodData();
roland@5921 342 if (mdo != NULL) {
roland@5921 343 ProfileData* data = mdo->bci_to_data(bci);
roland@5921 344 if (data->is_CallTypeData()) {
roland@5921 345 data->as_CallTypeData()->set_return_type(k->get_Klass());
roland@5921 346 } else {
roland@5921 347 assert(data->is_VirtualCallTypeData(), "no arguments!");
roland@5921 348 data->as_VirtualCallTypeData()->set_return_type(k->get_Klass());
roland@5921 349 }
roland@5921 350 }
roland@5921 351 }
roland@5921 352
duke@435 353 bool ciMethodData::has_escape_info() {
coleenp@4037 354 return eflag_set(MethodData::estimated);
duke@435 355 }
duke@435 356
coleenp@4037 357 void ciMethodData::set_eflag(MethodData::EscapeFlag f) {
duke@435 358 set_bits(_eflags, f);
duke@435 359 }
duke@435 360
coleenp@4037 361 void ciMethodData::clear_eflag(MethodData::EscapeFlag f) {
duke@435 362 clear_bits(_eflags, f);
duke@435 363 }
duke@435 364
coleenp@4037 365 bool ciMethodData::eflag_set(MethodData::EscapeFlag f) const {
duke@435 366 return mask_bits(_eflags, f) != 0;
duke@435 367 }
duke@435 368
duke@435 369 void ciMethodData::set_arg_local(int i) {
duke@435 370 set_nth_bit(_arg_local, i);
duke@435 371 }
duke@435 372
duke@435 373 void ciMethodData::set_arg_stack(int i) {
duke@435 374 set_nth_bit(_arg_stack, i);
duke@435 375 }
duke@435 376
duke@435 377 void ciMethodData::set_arg_returned(int i) {
duke@435 378 set_nth_bit(_arg_returned, i);
duke@435 379 }
duke@435 380
kvn@480 381 void ciMethodData::set_arg_modified(int arg, uint val) {
kvn@480 382 ArgInfoData *aid = arg_info();
kvn@480 383 if (aid == NULL)
kvn@480 384 return;
kvn@480 385 assert(arg >= 0 && arg < aid->number_of_args(), "valid argument number");
kvn@480 386 aid->set_arg_modified(arg, val);
kvn@480 387 }
kvn@480 388
duke@435 389 bool ciMethodData::is_arg_local(int i) const {
duke@435 390 return is_set_nth_bit(_arg_local, i);
duke@435 391 }
duke@435 392
duke@435 393 bool ciMethodData::is_arg_stack(int i) const {
duke@435 394 return is_set_nth_bit(_arg_stack, i);
duke@435 395 }
duke@435 396
duke@435 397 bool ciMethodData::is_arg_returned(int i) const {
duke@435 398 return is_set_nth_bit(_arg_returned, i);
duke@435 399 }
duke@435 400
kvn@480 401 uint ciMethodData::arg_modified(int arg) const {
kvn@480 402 ArgInfoData *aid = arg_info();
kvn@480 403 if (aid == NULL)
kvn@480 404 return 0;
kvn@480 405 assert(arg >= 0 && arg < aid->number_of_args(), "valid argument number");
kvn@480 406 return aid->arg_modified(arg);
kvn@480 407 }
kvn@480 408
duke@435 409 ByteSize ciMethodData::offset_of_slot(ciProfileData* data, ByteSize slot_offset_in_data) {
coleenp@4037 410 // Get offset within MethodData* of the data array
coleenp@4037 411 ByteSize data_offset = MethodData::data_offset();
duke@435 412
duke@435 413 // Get cell offset of the ProfileData within data array
duke@435 414 int cell_offset = dp_to_di(data->dp());
duke@435 415
duke@435 416 // Add in counter_offset, the # of bytes into the ProfileData of counter or flag
duke@435 417 int offset = in_bytes(data_offset) + cell_offset + in_bytes(slot_offset_in_data);
duke@435 418
duke@435 419 return in_ByteSize(offset);
duke@435 420 }
duke@435 421
kvn@480 422 ciArgInfoData *ciMethodData::arg_info() const {
kvn@480 423 // Should be last, have to skip all traps.
kvn@480 424 DataLayout* dp = data_layout_at(data_size());
kvn@480 425 DataLayout* end = data_layout_at(data_size() + extra_data_size());
coleenp@4037 426 for (; dp < end; dp = MethodData::next_extra(dp)) {
kvn@480 427 if (dp->tag() == DataLayout::arg_info_data_tag)
kvn@480 428 return new ciArgInfoData(dp);
kvn@480 429 }
kvn@480 430 return NULL;
kvn@480 431 }
kvn@480 432
kvn@480 433
duke@435 434 // Implementation of the print method.
duke@435 435 void ciMethodData::print_impl(outputStream* st) {
coleenp@4037 436 ciMetadata::print_impl(st);
duke@435 437 }
duke@435 438
minqi@4267 439 void ciMethodData::dump_replay_data(outputStream* out) {
vlivanov@4531 440 ResourceMark rm;
minqi@4267 441 MethodData* mdo = get_MethodData();
minqi@4267 442 Method* method = mdo->method();
minqi@4267 443 Klass* holder = method->method_holder();
minqi@4267 444 out->print("ciMethodData %s %s %s %d %d",
minqi@4267 445 holder->name()->as_quoted_ascii(),
minqi@4267 446 method->name()->as_quoted_ascii(),
minqi@4267 447 method->signature()->as_quoted_ascii(),
minqi@4267 448 _state,
minqi@4267 449 current_mileage());
minqi@4267 450
minqi@4267 451 // dump the contents of the MDO header as raw data
minqi@4267 452 unsigned char* orig = (unsigned char*)&_orig;
minqi@4267 453 int length = sizeof(_orig);
minqi@4267 454 out->print(" orig %d", length);
minqi@4267 455 for (int i = 0; i < length; i++) {
minqi@4267 456 out->print(" %d", orig[i]);
minqi@4267 457 }
minqi@4267 458
minqi@4267 459 // dump the MDO data as raw data
minqi@4267 460 int elements = data_size() / sizeof(intptr_t);
minqi@4267 461 out->print(" data %d", elements);
minqi@4267 462 for (int i = 0; i < elements; i++) {
minqi@4267 463 // We could use INTPTR_FORMAT here but that's a zero justified
minqi@4267 464 // which makes comparing it with the SA version of this output
minqi@4267 465 // harder.
minqi@4267 466 #ifdef _LP64
minqi@4267 467 out->print(" 0x%" FORMAT64_MODIFIER "x", data()[i]);
minqi@4267 468 #else
minqi@4267 469 out->print(" 0x%x", data()[i]);
minqi@4267 470 #endif
minqi@4267 471 }
minqi@4267 472
minqi@4267 473 // The MDO contained oop references as ciObjects, so scan for those
minqi@4267 474 // and emit pairs of offset and klass name so that they can be
minqi@4267 475 // reconstructed at runtime. The first round counts the number of
minqi@4267 476 // oop references and the second actually emits them.
minqi@4267 477 int count = 0;
minqi@4267 478 for (int round = 0; round < 2; round++) {
minqi@4267 479 if (round == 1) out->print(" oops %d", count);
minqi@4267 480 ProfileData* pdata = first_data();
minqi@4267 481 for ( ; is_valid(pdata); pdata = next_data(pdata)) {
minqi@4267 482 if (pdata->is_ReceiverTypeData()) {
minqi@4267 483 ciReceiverTypeData* vdata = (ciReceiverTypeData*)pdata;
minqi@4267 484 for (uint i = 0; i < vdata->row_limit(); i++) {
minqi@4267 485 ciKlass* k = vdata->receiver(i);
minqi@4267 486 if (k != NULL) {
minqi@4267 487 if (round == 0) {
minqi@4267 488 count++;
minqi@4267 489 } else {
minqi@4267 490 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 491 }
minqi@4267 492 }
minqi@4267 493 }
minqi@4267 494 } else if (pdata->is_VirtualCallData()) {
minqi@4267 495 ciVirtualCallData* vdata = (ciVirtualCallData*)pdata;
minqi@4267 496 for (uint i = 0; i < vdata->row_limit(); i++) {
minqi@4267 497 ciKlass* k = vdata->receiver(i);
minqi@4267 498 if (k != NULL) {
minqi@4267 499 if (round == 0) {
minqi@4267 500 count++;
minqi@4267 501 } else {
minqi@4267 502 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 503 }
minqi@4267 504 }
minqi@4267 505 }
minqi@4267 506 }
minqi@4267 507 }
minqi@4267 508 }
minqi@4267 509 out->cr();
minqi@4267 510 }
minqi@4267 511
duke@435 512 #ifndef PRODUCT
duke@435 513 void ciMethodData::print() {
duke@435 514 print_data_on(tty);
duke@435 515 }
duke@435 516
duke@435 517 void ciMethodData::print_data_on(outputStream* st) {
duke@435 518 ResourceMark rm;
duke@435 519 ciProfileData* data;
duke@435 520 for (data = first_data(); is_valid(data); data = next_data(data)) {
duke@435 521 st->print("%d", dp_to_di(data->dp()));
duke@435 522 st->fill_to(6);
duke@435 523 data->print_data_on(st);
duke@435 524 }
kvn@480 525 st->print_cr("--- Extra data:");
kvn@480 526 DataLayout* dp = data_layout_at(data_size());
kvn@480 527 DataLayout* end = data_layout_at(data_size() + extra_data_size());
coleenp@4037 528 for (; dp < end; dp = MethodData::next_extra(dp)) {
kvn@480 529 if (dp->tag() == DataLayout::no_tag) continue;
kvn@480 530 if (dp->tag() == DataLayout::bit_data_tag) {
kvn@480 531 data = new BitData(dp);
kvn@480 532 } else {
kvn@480 533 assert(dp->tag() == DataLayout::arg_info_data_tag, "must be BitData or ArgInfo");
kvn@480 534 data = new ciArgInfoData(dp);
kvn@480 535 dp = end; // ArgInfoData is at the end of extra data section.
kvn@480 536 }
kvn@480 537 st->print("%d", dp_to_di(data->dp()));
kvn@480 538 st->fill_to(6);
kvn@480 539 data->print_data_on(st);
kvn@480 540 }
duke@435 541 }
duke@435 542
roland@5914 543 void ciTypeEntries::print_ciklass(outputStream* st, intptr_t k) {
roland@5914 544 if (TypeEntries::is_type_none(k)) {
roland@5914 545 st->print("none");
roland@5914 546 } else if (TypeEntries::is_type_unknown(k)) {
roland@5914 547 st->print("unknown");
roland@5914 548 } else {
roland@5914 549 valid_ciklass(k)->print_name_on(st);
roland@5914 550 }
roland@5914 551 if (TypeEntries::was_null_seen(k)) {
roland@5914 552 st->print(" (null seen)");
roland@5914 553 }
roland@5914 554 }
roland@5914 555
roland@5914 556 void ciTypeStackSlotEntries::print_data_on(outputStream* st) const {
roland@5921 557 for (int i = 0; i < _number_of_entries; i++) {
roland@5914 558 _pd->tab(st);
roland@5914 559 st->print("%d: stack (%u) ", i, stack_slot(i));
roland@5914 560 print_ciklass(st, type(i));
roland@5914 561 st->cr();
roland@5914 562 }
roland@5914 563 }
roland@5914 564
roland@5921 565 void ciReturnTypeEntry::print_data_on(outputStream* st) const {
roland@5921 566 _pd->tab(st);
roland@5921 567 st->print("ret ");
roland@5921 568 print_ciklass(st, type());
roland@5921 569 st->cr();
roland@5921 570 }
roland@5921 571
roland@5914 572 void ciCallTypeData::print_data_on(outputStream* st) const {
roland@5914 573 print_shared(st, "ciCallTypeData");
roland@5921 574 if (has_arguments()) {
roland@5921 575 tab(st, true);
roland@5921 576 st->print("argument types");
roland@5921 577 args()->print_data_on(st);
roland@5921 578 }
roland@5921 579 if (has_return()) {
roland@5921 580 tab(st, true);
roland@5921 581 st->print("return type");
roland@5921 582 ret()->print_data_on(st);
roland@5921 583 }
roland@5914 584 }
roland@5914 585
roland@5914 586 void ciReceiverTypeData::print_receiver_data_on(outputStream* st) const {
duke@435 587 uint row;
duke@435 588 int entries = 0;
duke@435 589 for (row = 0; row < row_limit(); row++) {
duke@435 590 if (receiver(row) != NULL) entries++;
duke@435 591 }
duke@435 592 st->print_cr("count(%u) entries(%u)", count(), entries);
duke@435 593 for (row = 0; row < row_limit(); row++) {
duke@435 594 if (receiver(row) != NULL) {
duke@435 595 tab(st);
duke@435 596 receiver(row)->print_name_on(st);
duke@435 597 st->print_cr("(%u)", receiver_count(row));
duke@435 598 }
duke@435 599 }
duke@435 600 }
duke@435 601
roland@5914 602 void ciReceiverTypeData::print_data_on(outputStream* st) const {
duke@435 603 print_shared(st, "ciReceiverTypeData");
duke@435 604 print_receiver_data_on(st);
duke@435 605 }
duke@435 606
roland@5914 607 void ciVirtualCallData::print_data_on(outputStream* st) const {
duke@435 608 print_shared(st, "ciVirtualCallData");
duke@435 609 rtd_super()->print_receiver_data_on(st);
duke@435 610 }
roland@5914 611
roland@5914 612 void ciVirtualCallTypeData::print_data_on(outputStream* st) const {
roland@5914 613 print_shared(st, "ciVirtualCallTypeData");
roland@5914 614 rtd_super()->print_receiver_data_on(st);
roland@5921 615 if (has_arguments()) {
roland@5921 616 tab(st, true);
roland@5921 617 st->print("argument types");
roland@5921 618 args()->print_data_on(st);
roland@5921 619 }
roland@5921 620 if (has_return()) {
roland@5921 621 tab(st, true);
roland@5921 622 st->print("return type");
roland@5921 623 ret()->print_data_on(st);
roland@5921 624 }
roland@5914 625 }
roland@5987 626
roland@5987 627 void ciParametersTypeData::print_data_on(outputStream* st) const {
roland@5987 628 st->print_cr("Parametertypes");
roland@5987 629 parameters()->print_data_on(st);
roland@5987 630 }
duke@435 631 #endif

mercurial