src/share/vm/oops/methodDataOop.cpp

Thu, 07 Apr 2011 09:53:20 -0700

author
johnc
date
Thu, 07 Apr 2011 09:53:20 -0700
changeset 2781
e1162778c1c8
parent 2571
a97fd181b813
permissions
-rw-r--r--

7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
Summary: A referent object that is only weakly reachable at the start of concurrent marking but is re-attached to the strongly reachable object graph during marking may not be marked as live. This can cause the reference object to be processed prematurely and leave dangling pointers to the referent object. Implement a read barrier for the java.lang.ref.Reference::referent field by intrinsifying the Reference.get() method, and intercepting accesses though JNI, reflection, and Unsafe, so that when a non-null referent object is read it is also logged in an SATB buffer.
Reviewed-by: kvn, iveresov, never, tonyp, dholmes

duke@435 1 /*
never@2462 2 * Copyright (c) 2000, 2011, 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"
stefank@2314 26 #include "classfile/systemDictionary.hpp"
stefank@2314 27 #include "gc_implementation/shared/markSweep.inline.hpp"
stefank@2314 28 #include "interpreter/bytecode.hpp"
stefank@2314 29 #include "interpreter/bytecodeStream.hpp"
stefank@2314 30 #include "interpreter/linkResolver.hpp"
stefank@2314 31 #include "oops/methodDataOop.hpp"
stefank@2314 32 #include "oops/oop.inline.hpp"
stefank@2314 33 #include "runtime/compilationPolicy.hpp"
stefank@2314 34 #include "runtime/deoptimization.hpp"
stefank@2314 35 #include "runtime/handles.inline.hpp"
duke@435 36
duke@435 37 // ==================================================================
duke@435 38 // DataLayout
duke@435 39 //
duke@435 40 // Overlay for generic profiling data.
duke@435 41
duke@435 42 // Some types of data layouts need a length field.
duke@435 43 bool DataLayout::needs_array_len(u1 tag) {
kvn@480 44 return (tag == multi_branch_data_tag) || (tag == arg_info_data_tag);
duke@435 45 }
duke@435 46
duke@435 47 // Perform generic initialization of the data. More specific
duke@435 48 // initialization occurs in overrides of ProfileData::post_initialize.
duke@435 49 void DataLayout::initialize(u1 tag, u2 bci, int cell_count) {
duke@435 50 _header._bits = (intptr_t)0;
duke@435 51 _header._struct._tag = tag;
duke@435 52 _header._struct._bci = bci;
duke@435 53 for (int i = 0; i < cell_count; i++) {
duke@435 54 set_cell_at(i, (intptr_t)0);
duke@435 55 }
duke@435 56 if (needs_array_len(tag)) {
duke@435 57 set_cell_at(ArrayData::array_len_off_set, cell_count - 1); // -1 for header.
duke@435 58 }
duke@435 59 }
duke@435 60
ysr@1376 61 void DataLayout::follow_weak_refs(BoolObjectClosure* cl) {
ysr@1376 62 ResourceMark m;
ysr@1376 63 data_in()->follow_weak_refs(cl);
ysr@1376 64 }
ysr@1376 65
ysr@1376 66
duke@435 67 // ==================================================================
duke@435 68 // ProfileData
duke@435 69 //
duke@435 70 // A ProfileData object is created to refer to a section of profiling
duke@435 71 // data in a structured way.
duke@435 72
duke@435 73 // Constructor for invalid ProfileData.
duke@435 74 ProfileData::ProfileData() {
duke@435 75 _data = NULL;
duke@435 76 }
duke@435 77
duke@435 78 #ifndef PRODUCT
duke@435 79 void ProfileData::print_shared(outputStream* st, const char* name) {
duke@435 80 st->print("bci: %d", bci());
duke@435 81 st->fill_to(tab_width_one);
duke@435 82 st->print("%s", name);
duke@435 83 tab(st);
duke@435 84 int trap = trap_state();
duke@435 85 if (trap != 0) {
duke@435 86 char buf[100];
duke@435 87 st->print("trap(%s) ", Deoptimization::format_trap_state(buf, sizeof(buf), trap));
duke@435 88 }
duke@435 89 int flags = data()->flags();
duke@435 90 if (flags != 0)
duke@435 91 st->print("flags(%d) ", flags);
duke@435 92 }
duke@435 93
duke@435 94 void ProfileData::tab(outputStream* st) {
duke@435 95 st->fill_to(tab_width_two);
duke@435 96 }
duke@435 97 #endif // !PRODUCT
duke@435 98
duke@435 99 // ==================================================================
duke@435 100 // BitData
duke@435 101 //
duke@435 102 // A BitData corresponds to a one-bit flag. This is used to indicate
duke@435 103 // whether a checkcast bytecode has seen a null value.
duke@435 104
duke@435 105
duke@435 106 #ifndef PRODUCT
duke@435 107 void BitData::print_data_on(outputStream* st) {
duke@435 108 print_shared(st, "BitData");
duke@435 109 }
duke@435 110 #endif // !PRODUCT
duke@435 111
duke@435 112 // ==================================================================
duke@435 113 // CounterData
duke@435 114 //
duke@435 115 // A CounterData corresponds to a simple counter.
duke@435 116
duke@435 117 #ifndef PRODUCT
duke@435 118 void CounterData::print_data_on(outputStream* st) {
duke@435 119 print_shared(st, "CounterData");
duke@435 120 st->print_cr("count(%u)", count());
duke@435 121 }
duke@435 122 #endif // !PRODUCT
duke@435 123
duke@435 124 // ==================================================================
duke@435 125 // JumpData
duke@435 126 //
duke@435 127 // A JumpData is used to access profiling information for a direct
duke@435 128 // branch. It is a counter, used for counting the number of branches,
duke@435 129 // plus a data displacement, used for realigning the data pointer to
duke@435 130 // the corresponding target bci.
duke@435 131
duke@435 132 void JumpData::post_initialize(BytecodeStream* stream, methodDataOop mdo) {
duke@435 133 assert(stream->bci() == bci(), "wrong pos");
duke@435 134 int target;
duke@435 135 Bytecodes::Code c = stream->code();
duke@435 136 if (c == Bytecodes::_goto_w || c == Bytecodes::_jsr_w) {
duke@435 137 target = stream->dest_w();
duke@435 138 } else {
duke@435 139 target = stream->dest();
duke@435 140 }
duke@435 141 int my_di = mdo->dp_to_di(dp());
duke@435 142 int target_di = mdo->bci_to_di(target);
duke@435 143 int offset = target_di - my_di;
duke@435 144 set_displacement(offset);
duke@435 145 }
duke@435 146
duke@435 147 #ifndef PRODUCT
duke@435 148 void JumpData::print_data_on(outputStream* st) {
duke@435 149 print_shared(st, "JumpData");
duke@435 150 st->print_cr("taken(%u) displacement(%d)", taken(), displacement());
duke@435 151 }
duke@435 152 #endif // !PRODUCT
duke@435 153
duke@435 154 // ==================================================================
duke@435 155 // ReceiverTypeData
duke@435 156 //
duke@435 157 // A ReceiverTypeData is used to access profiling information about a
duke@435 158 // dynamic type check. It consists of a counter which counts the total times
duke@435 159 // that the check is reached, and a series of (klassOop, count) pairs
duke@435 160 // which are used to store a type profile for the receiver of the check.
duke@435 161
duke@435 162 void ReceiverTypeData::follow_contents() {
ysr@1376 163 // This is a set of weak references that need
ysr@1376 164 // to be followed at the end of the strong marking
ysr@1376 165 // phase. Memoize this object so it can be visited
ysr@1376 166 // in the weak roots processing phase.
ysr@1376 167 MarkSweep::revisit_mdo(data());
duke@435 168 }
duke@435 169
duke@435 170 #ifndef SERIALGC
duke@435 171 void ReceiverTypeData::follow_contents(ParCompactionManager* cm) {
ysr@1376 172 // This is a set of weak references that need
ysr@1376 173 // to be followed at the end of the strong marking
ysr@1376 174 // phase. Memoize this object so it can be visited
ysr@1376 175 // in the weak roots processing phase.
ysr@1376 176 PSParallelCompact::revisit_mdo(cm, data());
duke@435 177 }
duke@435 178 #endif // SERIALGC
duke@435 179
duke@435 180 void ReceiverTypeData::oop_iterate(OopClosure* blk) {
ysr@1376 181 if (blk->should_remember_mdo()) {
ysr@1376 182 // This is a set of weak references that need
ysr@1376 183 // to be followed at the end of the strong marking
ysr@1376 184 // phase. Memoize this object so it can be visited
ysr@1376 185 // in the weak roots processing phase.
ysr@1376 186 blk->remember_mdo(data());
ysr@1376 187 } else { // normal scan
ysr@1376 188 for (uint row = 0; row < row_limit(); row++) {
ysr@1376 189 if (receiver(row) != NULL) {
ysr@1376 190 oop* adr = adr_receiver(row);
duke@435 191 blk->do_oop(adr);
duke@435 192 }
duke@435 193 }
duke@435 194 }
duke@435 195 }
duke@435 196
ysr@1376 197 void ReceiverTypeData::oop_iterate_m(OopClosure* blk, MemRegion mr) {
ysr@1376 198 // Currently, this interface is called only during card-scanning for
ysr@1376 199 // a young gen gc, in which case this object cannot contribute anything,
ysr@1376 200 // since it does not contain any references that cross out of
ysr@1376 201 // the perm gen. However, for future more general use we allow
ysr@1376 202 // the possibility of calling for instance from more general
ysr@1376 203 // iterators (for example, a future regionalized perm gen for G1,
ysr@1376 204 // or the possibility of moving some references out of perm in
ysr@1376 205 // the case of other collectors). In that case, you will need
ysr@1376 206 // to relax or remove some of the assertions below.
ysr@1376 207 #ifdef ASSERT
ysr@1376 208 // Verify that none of the embedded oop references cross out of
ysr@1376 209 // this generation.
ysr@1376 210 for (uint row = 0; row < row_limit(); row++) {
ysr@1376 211 if (receiver(row) != NULL) {
ysr@1376 212 oop* adr = adr_receiver(row);
ysr@1376 213 CollectedHeap* h = Universe::heap();
ysr@1376 214 assert(h->is_permanent(adr) && h->is_permanent_or_null(*adr), "Not intra-perm");
ysr@1376 215 }
ysr@1376 216 }
ysr@1376 217 #endif // ASSERT
ysr@1376 218 assert(!blk->should_remember_mdo(), "Not expected to remember MDO");
ysr@1376 219 return; // Nothing to do, see comment above
ysr@1376 220 #if 0
ysr@1376 221 if (blk->should_remember_mdo()) {
ysr@1376 222 // This is a set of weak references that need
ysr@1376 223 // to be followed at the end of the strong marking
ysr@1376 224 // phase. Memoize this object so it can be visited
ysr@1376 225 // in the weak roots processing phase.
ysr@1376 226 blk->remember_mdo(data());
ysr@1376 227 } else { // normal scan
ysr@1376 228 for (uint row = 0; row < row_limit(); row++) {
ysr@1376 229 if (receiver(row) != NULL) {
ysr@1376 230 oop* adr = adr_receiver(row);
ysr@1376 231 if (mr.contains(adr)) {
ysr@1376 232 blk->do_oop(adr);
ysr@1376 233 } else if ((HeapWord*)adr >= mr.end()) {
ysr@1376 234 // Test that the current cursor and the two ends of the range
ysr@1376 235 // that we may have skipped iterating over are monotonically ordered;
ysr@1376 236 // this is just a paranoid assertion, just in case represetations
ysr@1376 237 // should change in the future rendering the short-circuit return
ysr@1376 238 // here invalid.
ysr@1376 239 assert((row+1 >= row_limit() || adr_receiver(row+1) > adr) &&
ysr@1376 240 (row+2 >= row_limit() || adr_receiver(row_limit()-1) > adr_receiver(row+1)), "Reducing?");
ysr@1376 241 break; // remaining should be outside this mr too
ysr@1376 242 }
ysr@1376 243 }
ysr@1376 244 }
ysr@1376 245 }
ysr@1376 246 #endif
ysr@1376 247 }
ysr@1376 248
duke@435 249 void ReceiverTypeData::adjust_pointers() {
duke@435 250 for (uint row = 0; row < row_limit(); row++) {
duke@435 251 if (receiver(row) != NULL) {
duke@435 252 MarkSweep::adjust_pointer(adr_receiver(row));
duke@435 253 }
duke@435 254 }
duke@435 255 }
duke@435 256
ysr@1376 257 void ReceiverTypeData::follow_weak_refs(BoolObjectClosure* is_alive_cl) {
ysr@1376 258 for (uint row = 0; row < row_limit(); row++) {
ysr@1376 259 klassOop p = receiver(row);
ysr@1376 260 if (p != NULL && !is_alive_cl->do_object_b(p)) {
ysr@1376 261 clear_row(row);
ysr@1376 262 }
ysr@1376 263 }
ysr@1376 264 }
ysr@1376 265
duke@435 266 #ifndef SERIALGC
duke@435 267 void ReceiverTypeData::update_pointers() {
duke@435 268 for (uint row = 0; row < row_limit(); row++) {
duke@435 269 if (receiver_unchecked(row) != NULL) {
duke@435 270 PSParallelCompact::adjust_pointer(adr_receiver(row));
duke@435 271 }
duke@435 272 }
duke@435 273 }
duke@435 274 #endif // SERIALGC
duke@435 275
duke@435 276 #ifndef PRODUCT
duke@435 277 void ReceiverTypeData::print_receiver_data_on(outputStream* st) {
duke@435 278 uint row;
duke@435 279 int entries = 0;
duke@435 280 for (row = 0; row < row_limit(); row++) {
duke@435 281 if (receiver(row) != NULL) entries++;
duke@435 282 }
duke@435 283 st->print_cr("count(%u) entries(%u)", count(), entries);
iveresov@2138 284 int total = count();
iveresov@2138 285 for (row = 0; row < row_limit(); row++) {
iveresov@2138 286 if (receiver(row) != NULL) {
iveresov@2138 287 total += receiver_count(row);
iveresov@2138 288 }
iveresov@2138 289 }
duke@435 290 for (row = 0; row < row_limit(); row++) {
duke@435 291 if (receiver(row) != NULL) {
duke@435 292 tab(st);
duke@435 293 receiver(row)->print_value_on(st);
iveresov@2138 294 st->print_cr("(%u %4.2f)", receiver_count(row), (float) receiver_count(row) / (float) total);
duke@435 295 }
duke@435 296 }
duke@435 297 }
duke@435 298 void ReceiverTypeData::print_data_on(outputStream* st) {
duke@435 299 print_shared(st, "ReceiverTypeData");
duke@435 300 print_receiver_data_on(st);
duke@435 301 }
duke@435 302 void VirtualCallData::print_data_on(outputStream* st) {
duke@435 303 print_shared(st, "VirtualCallData");
duke@435 304 print_receiver_data_on(st);
duke@435 305 }
duke@435 306 #endif // !PRODUCT
duke@435 307
duke@435 308 // ==================================================================
duke@435 309 // RetData
duke@435 310 //
duke@435 311 // A RetData is used to access profiling information for a ret bytecode.
duke@435 312 // It is composed of a count of the number of times that the ret has
duke@435 313 // been executed, followed by a series of triples of the form
duke@435 314 // (bci, count, di) which count the number of times that some bci was the
duke@435 315 // target of the ret and cache a corresponding displacement.
duke@435 316
duke@435 317 void RetData::post_initialize(BytecodeStream* stream, methodDataOop mdo) {
duke@435 318 for (uint row = 0; row < row_limit(); row++) {
duke@435 319 set_bci_displacement(row, -1);
duke@435 320 set_bci(row, no_bci);
duke@435 321 }
duke@435 322 // release so other threads see a consistent state. bci is used as
duke@435 323 // a valid flag for bci_displacement.
duke@435 324 OrderAccess::release();
duke@435 325 }
duke@435 326
duke@435 327 // This routine needs to atomically update the RetData structure, so the
duke@435 328 // caller needs to hold the RetData_lock before it gets here. Since taking
duke@435 329 // the lock can block (and allow GC) and since RetData is a ProfileData is a
duke@435 330 // wrapper around a derived oop, taking the lock in _this_ method will
duke@435 331 // basically cause the 'this' pointer's _data field to contain junk after the
duke@435 332 // lock. We require the caller to take the lock before making the ProfileData
duke@435 333 // structure. Currently the only caller is InterpreterRuntime::update_mdp_for_ret
duke@435 334 address RetData::fixup_ret(int return_bci, methodDataHandle h_mdo) {
duke@435 335 // First find the mdp which corresponds to the return bci.
duke@435 336 address mdp = h_mdo->bci_to_dp(return_bci);
duke@435 337
duke@435 338 // Now check to see if any of the cache slots are open.
duke@435 339 for (uint row = 0; row < row_limit(); row++) {
duke@435 340 if (bci(row) == no_bci) {
duke@435 341 set_bci_displacement(row, mdp - dp());
duke@435 342 set_bci_count(row, DataLayout::counter_increment);
duke@435 343 // Barrier to ensure displacement is written before the bci; allows
duke@435 344 // the interpreter to read displacement without fear of race condition.
duke@435 345 release_set_bci(row, return_bci);
duke@435 346 break;
duke@435 347 }
duke@435 348 }
duke@435 349 return mdp;
duke@435 350 }
duke@435 351
duke@435 352
duke@435 353 #ifndef PRODUCT
duke@435 354 void RetData::print_data_on(outputStream* st) {
duke@435 355 print_shared(st, "RetData");
duke@435 356 uint row;
duke@435 357 int entries = 0;
duke@435 358 for (row = 0; row < row_limit(); row++) {
duke@435 359 if (bci(row) != no_bci) entries++;
duke@435 360 }
duke@435 361 st->print_cr("count(%u) entries(%u)", count(), entries);
duke@435 362 for (row = 0; row < row_limit(); row++) {
duke@435 363 if (bci(row) != no_bci) {
duke@435 364 tab(st);
duke@435 365 st->print_cr("bci(%d: count(%u) displacement(%d))",
duke@435 366 bci(row), bci_count(row), bci_displacement(row));
duke@435 367 }
duke@435 368 }
duke@435 369 }
duke@435 370 #endif // !PRODUCT
duke@435 371
duke@435 372 // ==================================================================
duke@435 373 // BranchData
duke@435 374 //
duke@435 375 // A BranchData is used to access profiling data for a two-way branch.
duke@435 376 // It consists of taken and not_taken counts as well as a data displacement
duke@435 377 // for the taken case.
duke@435 378
duke@435 379 void BranchData::post_initialize(BytecodeStream* stream, methodDataOop mdo) {
duke@435 380 assert(stream->bci() == bci(), "wrong pos");
duke@435 381 int target = stream->dest();
duke@435 382 int my_di = mdo->dp_to_di(dp());
duke@435 383 int target_di = mdo->bci_to_di(target);
duke@435 384 int offset = target_di - my_di;
duke@435 385 set_displacement(offset);
duke@435 386 }
duke@435 387
duke@435 388 #ifndef PRODUCT
duke@435 389 void BranchData::print_data_on(outputStream* st) {
duke@435 390 print_shared(st, "BranchData");
duke@435 391 st->print_cr("taken(%u) displacement(%d)",
duke@435 392 taken(), displacement());
duke@435 393 tab(st);
duke@435 394 st->print_cr("not taken(%u)", not_taken());
duke@435 395 }
duke@435 396 #endif
duke@435 397
duke@435 398 // ==================================================================
duke@435 399 // MultiBranchData
duke@435 400 //
duke@435 401 // A MultiBranchData is used to access profiling information for
duke@435 402 // a multi-way branch (*switch bytecodes). It consists of a series
duke@435 403 // of (count, displacement) pairs, which count the number of times each
duke@435 404 // case was taken and specify the data displacment for each branch target.
duke@435 405
duke@435 406 int MultiBranchData::compute_cell_count(BytecodeStream* stream) {
duke@435 407 int cell_count = 0;
duke@435 408 if (stream->code() == Bytecodes::_tableswitch) {
never@2462 409 Bytecode_tableswitch sw(stream->method()(), stream->bcp());
never@2462 410 cell_count = 1 + per_case_cell_count * (1 + sw.length()); // 1 for default
duke@435 411 } else {
never@2462 412 Bytecode_lookupswitch sw(stream->method()(), stream->bcp());
never@2462 413 cell_count = 1 + per_case_cell_count * (sw.number_of_pairs() + 1); // 1 for default
duke@435 414 }
duke@435 415 return cell_count;
duke@435 416 }
duke@435 417
duke@435 418 void MultiBranchData::post_initialize(BytecodeStream* stream,
duke@435 419 methodDataOop mdo) {
duke@435 420 assert(stream->bci() == bci(), "wrong pos");
duke@435 421 int target;
duke@435 422 int my_di;
duke@435 423 int target_di;
duke@435 424 int offset;
duke@435 425 if (stream->code() == Bytecodes::_tableswitch) {
never@2462 426 Bytecode_tableswitch sw(stream->method()(), stream->bcp());
never@2462 427 int len = sw.length();
duke@435 428 assert(array_len() == per_case_cell_count * (len + 1), "wrong len");
duke@435 429 for (int count = 0; count < len; count++) {
never@2462 430 target = sw.dest_offset_at(count) + bci();
duke@435 431 my_di = mdo->dp_to_di(dp());
duke@435 432 target_di = mdo->bci_to_di(target);
duke@435 433 offset = target_di - my_di;
duke@435 434 set_displacement_at(count, offset);
duke@435 435 }
never@2462 436 target = sw.default_offset() + bci();
duke@435 437 my_di = mdo->dp_to_di(dp());
duke@435 438 target_di = mdo->bci_to_di(target);
duke@435 439 offset = target_di - my_di;
duke@435 440 set_default_displacement(offset);
duke@435 441
duke@435 442 } else {
never@2462 443 Bytecode_lookupswitch sw(stream->method()(), stream->bcp());
never@2462 444 int npairs = sw.number_of_pairs();
duke@435 445 assert(array_len() == per_case_cell_count * (npairs + 1), "wrong len");
duke@435 446 for (int count = 0; count < npairs; count++) {
never@2462 447 LookupswitchPair pair = sw.pair_at(count);
never@2462 448 target = pair.offset() + bci();
duke@435 449 my_di = mdo->dp_to_di(dp());
duke@435 450 target_di = mdo->bci_to_di(target);
duke@435 451 offset = target_di - my_di;
duke@435 452 set_displacement_at(count, offset);
duke@435 453 }
never@2462 454 target = sw.default_offset() + bci();
duke@435 455 my_di = mdo->dp_to_di(dp());
duke@435 456 target_di = mdo->bci_to_di(target);
duke@435 457 offset = target_di - my_di;
duke@435 458 set_default_displacement(offset);
duke@435 459 }
duke@435 460 }
duke@435 461
duke@435 462 #ifndef PRODUCT
duke@435 463 void MultiBranchData::print_data_on(outputStream* st) {
duke@435 464 print_shared(st, "MultiBranchData");
duke@435 465 st->print_cr("default_count(%u) displacement(%d)",
duke@435 466 default_count(), default_displacement());
duke@435 467 int cases = number_of_cases();
duke@435 468 for (int i = 0; i < cases; i++) {
duke@435 469 tab(st);
duke@435 470 st->print_cr("count(%u) displacement(%d)",
duke@435 471 count_at(i), displacement_at(i));
duke@435 472 }
duke@435 473 }
duke@435 474 #endif
duke@435 475
kvn@480 476 #ifndef PRODUCT
kvn@480 477 void ArgInfoData::print_data_on(outputStream* st) {
kvn@480 478 print_shared(st, "ArgInfoData");
kvn@480 479 int nargs = number_of_args();
kvn@480 480 for (int i = 0; i < nargs; i++) {
kvn@480 481 st->print(" 0x%x", arg_modified(i));
kvn@480 482 }
kvn@480 483 st->cr();
kvn@480 484 }
kvn@480 485
kvn@480 486 #endif
duke@435 487 // ==================================================================
duke@435 488 // methodDataOop
duke@435 489 //
duke@435 490 // A methodDataOop holds information which has been collected about
duke@435 491 // a method.
duke@435 492
duke@435 493 int methodDataOopDesc::bytecode_cell_count(Bytecodes::Code code) {
duke@435 494 switch (code) {
duke@435 495 case Bytecodes::_checkcast:
duke@435 496 case Bytecodes::_instanceof:
duke@435 497 case Bytecodes::_aastore:
duke@435 498 if (TypeProfileCasts) {
duke@435 499 return ReceiverTypeData::static_cell_count();
duke@435 500 } else {
duke@435 501 return BitData::static_cell_count();
duke@435 502 }
duke@435 503 case Bytecodes::_invokespecial:
duke@435 504 case Bytecodes::_invokestatic:
duke@435 505 return CounterData::static_cell_count();
duke@435 506 case Bytecodes::_goto:
duke@435 507 case Bytecodes::_goto_w:
duke@435 508 case Bytecodes::_jsr:
duke@435 509 case Bytecodes::_jsr_w:
duke@435 510 return JumpData::static_cell_count();
duke@435 511 case Bytecodes::_invokevirtual:
duke@435 512 case Bytecodes::_invokeinterface:
duke@435 513 return VirtualCallData::static_cell_count();
jrose@1161 514 case Bytecodes::_invokedynamic:
jrose@1161 515 return CounterData::static_cell_count();
duke@435 516 case Bytecodes::_ret:
duke@435 517 return RetData::static_cell_count();
duke@435 518 case Bytecodes::_ifeq:
duke@435 519 case Bytecodes::_ifne:
duke@435 520 case Bytecodes::_iflt:
duke@435 521 case Bytecodes::_ifge:
duke@435 522 case Bytecodes::_ifgt:
duke@435 523 case Bytecodes::_ifle:
duke@435 524 case Bytecodes::_if_icmpeq:
duke@435 525 case Bytecodes::_if_icmpne:
duke@435 526 case Bytecodes::_if_icmplt:
duke@435 527 case Bytecodes::_if_icmpge:
duke@435 528 case Bytecodes::_if_icmpgt:
duke@435 529 case Bytecodes::_if_icmple:
duke@435 530 case Bytecodes::_if_acmpeq:
duke@435 531 case Bytecodes::_if_acmpne:
duke@435 532 case Bytecodes::_ifnull:
duke@435 533 case Bytecodes::_ifnonnull:
duke@435 534 return BranchData::static_cell_count();
duke@435 535 case Bytecodes::_lookupswitch:
duke@435 536 case Bytecodes::_tableswitch:
duke@435 537 return variable_cell_count;
duke@435 538 }
duke@435 539 return no_profile_data;
duke@435 540 }
duke@435 541
duke@435 542 // Compute the size of the profiling information corresponding to
duke@435 543 // the current bytecode.
duke@435 544 int methodDataOopDesc::compute_data_size(BytecodeStream* stream) {
duke@435 545 int cell_count = bytecode_cell_count(stream->code());
duke@435 546 if (cell_count == no_profile_data) {
duke@435 547 return 0;
duke@435 548 }
duke@435 549 if (cell_count == variable_cell_count) {
duke@435 550 cell_count = MultiBranchData::compute_cell_count(stream);
duke@435 551 }
duke@435 552 // Note: cell_count might be zero, meaning that there is just
duke@435 553 // a DataLayout header, with no extra cells.
duke@435 554 assert(cell_count >= 0, "sanity");
duke@435 555 return DataLayout::compute_size_in_bytes(cell_count);
duke@435 556 }
duke@435 557
duke@435 558 int methodDataOopDesc::compute_extra_data_count(int data_size, int empty_bc_count) {
duke@435 559 if (ProfileTraps) {
duke@435 560 // Assume that up to 3% of BCIs with no MDP will need to allocate one.
duke@435 561 int extra_data_count = (uint)(empty_bc_count * 3) / 128 + 1;
duke@435 562 // If the method is large, let the extra BCIs grow numerous (to ~1%).
duke@435 563 int one_percent_of_data
duke@435 564 = (uint)data_size / (DataLayout::header_size_in_bytes()*128);
duke@435 565 if (extra_data_count < one_percent_of_data)
duke@435 566 extra_data_count = one_percent_of_data;
duke@435 567 if (extra_data_count > empty_bc_count)
duke@435 568 extra_data_count = empty_bc_count; // no need for more
duke@435 569 return extra_data_count;
duke@435 570 } else {
duke@435 571 return 0;
duke@435 572 }
duke@435 573 }
duke@435 574
duke@435 575 // Compute the size of the methodDataOop necessary to store
duke@435 576 // profiling information about a given method. Size is in bytes.
duke@435 577 int methodDataOopDesc::compute_allocation_size_in_bytes(methodHandle method) {
duke@435 578 int data_size = 0;
duke@435 579 BytecodeStream stream(method);
duke@435 580 Bytecodes::Code c;
duke@435 581 int empty_bc_count = 0; // number of bytecodes lacking data
duke@435 582 while ((c = stream.next()) >= 0) {
duke@435 583 int size_in_bytes = compute_data_size(&stream);
duke@435 584 data_size += size_in_bytes;
duke@435 585 if (size_in_bytes == 0) empty_bc_count += 1;
duke@435 586 }
duke@435 587 int object_size = in_bytes(data_offset()) + data_size;
duke@435 588
duke@435 589 // Add some extra DataLayout cells (at least one) to track stray traps.
duke@435 590 int extra_data_count = compute_extra_data_count(data_size, empty_bc_count);
duke@435 591 object_size += extra_data_count * DataLayout::compute_size_in_bytes(0);
duke@435 592
kvn@480 593 // Add a cell to record information about modified arguments.
kvn@480 594 int arg_size = method->size_of_parameters();
kvn@480 595 object_size += DataLayout::compute_size_in_bytes(arg_size+1);
duke@435 596 return object_size;
duke@435 597 }
duke@435 598
duke@435 599 // Compute the size of the methodDataOop necessary to store
duke@435 600 // profiling information about a given method. Size is in words
duke@435 601 int methodDataOopDesc::compute_allocation_size_in_words(methodHandle method) {
duke@435 602 int byte_size = compute_allocation_size_in_bytes(method);
duke@435 603 int word_size = align_size_up(byte_size, BytesPerWord) / BytesPerWord;
duke@435 604 return align_object_size(word_size);
duke@435 605 }
duke@435 606
duke@435 607 // Initialize an individual data segment. Returns the size of
duke@435 608 // the segment in bytes.
duke@435 609 int methodDataOopDesc::initialize_data(BytecodeStream* stream,
duke@435 610 int data_index) {
duke@435 611 int cell_count = -1;
duke@435 612 int tag = DataLayout::no_tag;
duke@435 613 DataLayout* data_layout = data_layout_at(data_index);
duke@435 614 Bytecodes::Code c = stream->code();
duke@435 615 switch (c) {
duke@435 616 case Bytecodes::_checkcast:
duke@435 617 case Bytecodes::_instanceof:
duke@435 618 case Bytecodes::_aastore:
duke@435 619 if (TypeProfileCasts) {
duke@435 620 cell_count = ReceiverTypeData::static_cell_count();
duke@435 621 tag = DataLayout::receiver_type_data_tag;
duke@435 622 } else {
duke@435 623 cell_count = BitData::static_cell_count();
duke@435 624 tag = DataLayout::bit_data_tag;
duke@435 625 }
duke@435 626 break;
duke@435 627 case Bytecodes::_invokespecial:
duke@435 628 case Bytecodes::_invokestatic:
duke@435 629 cell_count = CounterData::static_cell_count();
duke@435 630 tag = DataLayout::counter_data_tag;
duke@435 631 break;
duke@435 632 case Bytecodes::_goto:
duke@435 633 case Bytecodes::_goto_w:
duke@435 634 case Bytecodes::_jsr:
duke@435 635 case Bytecodes::_jsr_w:
duke@435 636 cell_count = JumpData::static_cell_count();
duke@435 637 tag = DataLayout::jump_data_tag;
duke@435 638 break;
duke@435 639 case Bytecodes::_invokevirtual:
duke@435 640 case Bytecodes::_invokeinterface:
duke@435 641 cell_count = VirtualCallData::static_cell_count();
duke@435 642 tag = DataLayout::virtual_call_data_tag;
duke@435 643 break;
jrose@1161 644 case Bytecodes::_invokedynamic:
jrose@1161 645 // %%% should make a type profile for any invokedynamic that takes a ref argument
jrose@1161 646 cell_count = CounterData::static_cell_count();
jrose@1161 647 tag = DataLayout::counter_data_tag;
jrose@1161 648 break;
duke@435 649 case Bytecodes::_ret:
duke@435 650 cell_count = RetData::static_cell_count();
duke@435 651 tag = DataLayout::ret_data_tag;
duke@435 652 break;
duke@435 653 case Bytecodes::_ifeq:
duke@435 654 case Bytecodes::_ifne:
duke@435 655 case Bytecodes::_iflt:
duke@435 656 case Bytecodes::_ifge:
duke@435 657 case Bytecodes::_ifgt:
duke@435 658 case Bytecodes::_ifle:
duke@435 659 case Bytecodes::_if_icmpeq:
duke@435 660 case Bytecodes::_if_icmpne:
duke@435 661 case Bytecodes::_if_icmplt:
duke@435 662 case Bytecodes::_if_icmpge:
duke@435 663 case Bytecodes::_if_icmpgt:
duke@435 664 case Bytecodes::_if_icmple:
duke@435 665 case Bytecodes::_if_acmpeq:
duke@435 666 case Bytecodes::_if_acmpne:
duke@435 667 case Bytecodes::_ifnull:
duke@435 668 case Bytecodes::_ifnonnull:
duke@435 669 cell_count = BranchData::static_cell_count();
duke@435 670 tag = DataLayout::branch_data_tag;
duke@435 671 break;
duke@435 672 case Bytecodes::_lookupswitch:
duke@435 673 case Bytecodes::_tableswitch:
duke@435 674 cell_count = MultiBranchData::compute_cell_count(stream);
duke@435 675 tag = DataLayout::multi_branch_data_tag;
duke@435 676 break;
duke@435 677 }
duke@435 678 assert(tag == DataLayout::multi_branch_data_tag ||
duke@435 679 cell_count == bytecode_cell_count(c), "cell counts must agree");
duke@435 680 if (cell_count >= 0) {
duke@435 681 assert(tag != DataLayout::no_tag, "bad tag");
duke@435 682 assert(bytecode_has_profile(c), "agree w/ BHP");
duke@435 683 data_layout->initialize(tag, stream->bci(), cell_count);
duke@435 684 return DataLayout::compute_size_in_bytes(cell_count);
duke@435 685 } else {
duke@435 686 assert(!bytecode_has_profile(c), "agree w/ !BHP");
duke@435 687 return 0;
duke@435 688 }
duke@435 689 }
duke@435 690
duke@435 691 // Get the data at an arbitrary (sort of) data index.
duke@435 692 ProfileData* methodDataOopDesc::data_at(int data_index) {
duke@435 693 if (out_of_bounds(data_index)) {
duke@435 694 return NULL;
duke@435 695 }
duke@435 696 DataLayout* data_layout = data_layout_at(data_index);
ysr@1376 697 return data_layout->data_in();
ysr@1376 698 }
duke@435 699
ysr@1376 700 ProfileData* DataLayout::data_in() {
ysr@1376 701 switch (tag()) {
duke@435 702 case DataLayout::no_tag:
duke@435 703 default:
duke@435 704 ShouldNotReachHere();
duke@435 705 return NULL;
duke@435 706 case DataLayout::bit_data_tag:
ysr@1376 707 return new BitData(this);
duke@435 708 case DataLayout::counter_data_tag:
ysr@1376 709 return new CounterData(this);
duke@435 710 case DataLayout::jump_data_tag:
ysr@1376 711 return new JumpData(this);
duke@435 712 case DataLayout::receiver_type_data_tag:
ysr@1376 713 return new ReceiverTypeData(this);
duke@435 714 case DataLayout::virtual_call_data_tag:
ysr@1376 715 return new VirtualCallData(this);
duke@435 716 case DataLayout::ret_data_tag:
ysr@1376 717 return new RetData(this);
duke@435 718 case DataLayout::branch_data_tag:
ysr@1376 719 return new BranchData(this);
duke@435 720 case DataLayout::multi_branch_data_tag:
ysr@1376 721 return new MultiBranchData(this);
kvn@480 722 case DataLayout::arg_info_data_tag:
ysr@1376 723 return new ArgInfoData(this);
duke@435 724 };
duke@435 725 }
duke@435 726
duke@435 727 // Iteration over data.
duke@435 728 ProfileData* methodDataOopDesc::next_data(ProfileData* current) {
duke@435 729 int current_index = dp_to_di(current->dp());
duke@435 730 int next_index = current_index + current->size_in_bytes();
duke@435 731 ProfileData* next = data_at(next_index);
duke@435 732 return next;
duke@435 733 }
duke@435 734
duke@435 735 // Give each of the data entries a chance to perform specific
duke@435 736 // data initialization.
duke@435 737 void methodDataOopDesc::post_initialize(BytecodeStream* stream) {
duke@435 738 ResourceMark rm;
duke@435 739 ProfileData* data;
duke@435 740 for (data = first_data(); is_valid(data); data = next_data(data)) {
duke@435 741 stream->set_start(data->bci());
duke@435 742 stream->next();
duke@435 743 data->post_initialize(stream, this);
duke@435 744 }
duke@435 745 }
duke@435 746
duke@435 747 // Initialize the methodDataOop corresponding to a given method.
duke@435 748 void methodDataOopDesc::initialize(methodHandle method) {
duke@435 749 ResourceMark rm;
duke@435 750 // Set the method back-pointer.
duke@435 751 _method = method();
iveresov@2138 752
iveresov@2138 753 if (TieredCompilation) {
iveresov@2138 754 _invocation_counter.init();
iveresov@2138 755 _backedge_counter.init();
iveresov@2559 756 _invocation_counter_start = 0;
iveresov@2559 757 _backedge_counter_start = 0;
iveresov@2138 758 _num_loops = 0;
iveresov@2138 759 _num_blocks = 0;
iveresov@2138 760 _highest_comp_level = 0;
iveresov@2138 761 _highest_osr_comp_level = 0;
iveresov@2559 762 _would_profile = true;
iveresov@2138 763 }
duke@435 764 set_creation_mileage(mileage_of(method()));
duke@435 765
duke@435 766 // Initialize flags and trap history.
duke@435 767 _nof_decompiles = 0;
duke@435 768 _nof_overflow_recompiles = 0;
duke@435 769 _nof_overflow_traps = 0;
duke@435 770 assert(sizeof(_trap_hist) % sizeof(HeapWord) == 0, "align");
duke@435 771 Copy::zero_to_words((HeapWord*) &_trap_hist,
duke@435 772 sizeof(_trap_hist) / sizeof(HeapWord));
duke@435 773
duke@435 774 // Go through the bytecodes and allocate and initialize the
duke@435 775 // corresponding data cells.
duke@435 776 int data_size = 0;
duke@435 777 int empty_bc_count = 0; // number of bytecodes lacking data
duke@435 778 BytecodeStream stream(method);
duke@435 779 Bytecodes::Code c;
duke@435 780 while ((c = stream.next()) >= 0) {
duke@435 781 int size_in_bytes = initialize_data(&stream, data_size);
duke@435 782 data_size += size_in_bytes;
duke@435 783 if (size_in_bytes == 0) empty_bc_count += 1;
duke@435 784 }
duke@435 785 _data_size = data_size;
duke@435 786 int object_size = in_bytes(data_offset()) + data_size;
duke@435 787
duke@435 788 // Add some extra DataLayout cells (at least one) to track stray traps.
duke@435 789 int extra_data_count = compute_extra_data_count(data_size, empty_bc_count);
kvn@480 790 int extra_size = extra_data_count * DataLayout::compute_size_in_bytes(0);
kvn@480 791
kvn@480 792 // Add a cell to record information about modified arguments.
kvn@480 793 // Set up _args_modified array after traps cells so that
kvn@480 794 // the code for traps cells works.
kvn@480 795 DataLayout *dp = data_layout_at(data_size + extra_size);
kvn@480 796
kvn@480 797 int arg_size = method->size_of_parameters();
kvn@480 798 dp->initialize(DataLayout::arg_info_data_tag, 0, arg_size+1);
kvn@480 799
kvn@480 800 object_size += extra_size + DataLayout::compute_size_in_bytes(arg_size+1);
duke@435 801
duke@435 802 // Set an initial hint. Don't use set_hint_di() because
duke@435 803 // first_di() may be out of bounds if data_size is 0.
duke@435 804 // In that situation, _hint_di is never used, but at
duke@435 805 // least well-defined.
duke@435 806 _hint_di = first_di();
duke@435 807
duke@435 808 post_initialize(&stream);
duke@435 809
duke@435 810 set_object_is_parsable(object_size);
duke@435 811 }
duke@435 812
duke@435 813 // Get a measure of how much mileage the method has on it.
duke@435 814 int methodDataOopDesc::mileage_of(methodOop method) {
duke@435 815 int mileage = 0;
iveresov@2138 816 if (TieredCompilation) {
iveresov@2138 817 mileage = MAX2(method->invocation_count(), method->backedge_count());
iveresov@2138 818 } else {
iveresov@2138 819 int iic = method->interpreter_invocation_count();
iveresov@2138 820 if (mileage < iic) mileage = iic;
iveresov@2138 821 InvocationCounter* ic = method->invocation_counter();
iveresov@2138 822 InvocationCounter* bc = method->backedge_counter();
iveresov@2138 823 int icval = ic->count();
iveresov@2138 824 if (ic->carry()) icval += CompileThreshold;
iveresov@2138 825 if (mileage < icval) mileage = icval;
iveresov@2138 826 int bcval = bc->count();
iveresov@2138 827 if (bc->carry()) bcval += CompileThreshold;
iveresov@2138 828 if (mileage < bcval) mileage = bcval;
iveresov@2138 829 }
duke@435 830 return mileage;
duke@435 831 }
duke@435 832
duke@435 833 bool methodDataOopDesc::is_mature() const {
iveresov@2138 834 return CompilationPolicy::policy()->is_mature(_method);
duke@435 835 }
duke@435 836
duke@435 837 // Translate a bci to its corresponding data index (di).
duke@435 838 address methodDataOopDesc::bci_to_dp(int bci) {
duke@435 839 ResourceMark rm;
duke@435 840 ProfileData* data = data_before(bci);
duke@435 841 ProfileData* prev = NULL;
duke@435 842 for ( ; is_valid(data); data = next_data(data)) {
duke@435 843 if (data->bci() >= bci) {
duke@435 844 if (data->bci() == bci) set_hint_di(dp_to_di(data->dp()));
duke@435 845 else if (prev != NULL) set_hint_di(dp_to_di(prev->dp()));
duke@435 846 return data->dp();
duke@435 847 }
duke@435 848 prev = data;
duke@435 849 }
duke@435 850 return (address)limit_data_position();
duke@435 851 }
duke@435 852
duke@435 853 // Translate a bci to its corresponding data, or NULL.
duke@435 854 ProfileData* methodDataOopDesc::bci_to_data(int bci) {
duke@435 855 ProfileData* data = data_before(bci);
duke@435 856 for ( ; is_valid(data); data = next_data(data)) {
duke@435 857 if (data->bci() == bci) {
duke@435 858 set_hint_di(dp_to_di(data->dp()));
duke@435 859 return data;
duke@435 860 } else if (data->bci() > bci) {
duke@435 861 break;
duke@435 862 }
duke@435 863 }
duke@435 864 return bci_to_extra_data(bci, false);
duke@435 865 }
duke@435 866
duke@435 867 // Translate a bci to its corresponding extra data, or NULL.
duke@435 868 ProfileData* methodDataOopDesc::bci_to_extra_data(int bci, bool create_if_missing) {
duke@435 869 DataLayout* dp = extra_data_base();
duke@435 870 DataLayout* end = extra_data_limit();
duke@435 871 DataLayout* avail = NULL;
duke@435 872 for (; dp < end; dp = next_extra(dp)) {
duke@435 873 // No need for "OrderAccess::load_acquire" ops,
duke@435 874 // since the data structure is monotonic.
duke@435 875 if (dp->tag() == DataLayout::no_tag) break;
kvn@480 876 if (dp->tag() == DataLayout::arg_info_data_tag) {
kvn@480 877 dp = end; // ArgInfoData is at the end of extra data section.
kvn@480 878 break;
kvn@480 879 }
duke@435 880 if (dp->bci() == bci) {
duke@435 881 assert(dp->tag() == DataLayout::bit_data_tag, "sane");
duke@435 882 return new BitData(dp);
duke@435 883 }
duke@435 884 }
duke@435 885 if (create_if_missing && dp < end) {
duke@435 886 // Allocate this one. There is no mutual exclusion,
duke@435 887 // so two threads could allocate different BCIs to the
duke@435 888 // same data layout. This means these extra data
duke@435 889 // records, like most other MDO contents, must not be
duke@435 890 // trusted too much.
duke@435 891 DataLayout temp;
duke@435 892 temp.initialize(DataLayout::bit_data_tag, bci, 0);
duke@435 893 dp->release_set_header(temp.header());
duke@435 894 assert(dp->tag() == DataLayout::bit_data_tag, "sane");
duke@435 895 //NO: assert(dp->bci() == bci, "no concurrent allocation");
duke@435 896 return new BitData(dp);
duke@435 897 }
duke@435 898 return NULL;
duke@435 899 }
duke@435 900
kvn@480 901 ArgInfoData *methodDataOopDesc::arg_info() {
kvn@480 902 DataLayout* dp = extra_data_base();
kvn@480 903 DataLayout* end = extra_data_limit();
kvn@480 904 for (; dp < end; dp = next_extra(dp)) {
kvn@480 905 if (dp->tag() == DataLayout::arg_info_data_tag)
kvn@480 906 return new ArgInfoData(dp);
kvn@480 907 }
kvn@480 908 return NULL;
kvn@480 909 }
kvn@480 910
duke@435 911 #ifndef PRODUCT
duke@435 912 void methodDataOopDesc::print_data_on(outputStream* st) {
duke@435 913 ResourceMark rm;
duke@435 914 ProfileData* data = first_data();
duke@435 915 for ( ; is_valid(data); data = next_data(data)) {
duke@435 916 st->print("%d", dp_to_di(data->dp()));
duke@435 917 st->fill_to(6);
duke@435 918 data->print_data_on(st);
duke@435 919 }
kvn@480 920 st->print_cr("--- Extra data:");
duke@435 921 DataLayout* dp = extra_data_base();
duke@435 922 DataLayout* end = extra_data_limit();
duke@435 923 for (; dp < end; dp = next_extra(dp)) {
duke@435 924 // No need for "OrderAccess::load_acquire" ops,
duke@435 925 // since the data structure is monotonic.
kvn@480 926 if (dp->tag() == DataLayout::no_tag) continue;
kvn@480 927 if (dp->tag() == DataLayout::bit_data_tag) {
kvn@480 928 data = new BitData(dp);
kvn@480 929 } else {
kvn@480 930 assert(dp->tag() == DataLayout::arg_info_data_tag, "must be BitData or ArgInfo");
kvn@480 931 data = new ArgInfoData(dp);
kvn@480 932 dp = end; // ArgInfoData is at the end of extra data section.
kvn@480 933 }
duke@435 934 st->print("%d", dp_to_di(data->dp()));
duke@435 935 st->fill_to(6);
duke@435 936 data->print_data_on(st);
duke@435 937 }
duke@435 938 }
duke@435 939 #endif
duke@435 940
duke@435 941 void methodDataOopDesc::verify_data_on(outputStream* st) {
duke@435 942 NEEDS_CLEANUP;
duke@435 943 // not yet implemented.
duke@435 944 }

mercurial