1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/oops/methodDataOop.cpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,816 @@ 1.4 +/* 1.5 + * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +# include "incls/_precompiled.incl" 1.29 +# include "incls/_methodDataOop.cpp.incl" 1.30 + 1.31 +// ================================================================== 1.32 +// DataLayout 1.33 +// 1.34 +// Overlay for generic profiling data. 1.35 + 1.36 +// Some types of data layouts need a length field. 1.37 +bool DataLayout::needs_array_len(u1 tag) { 1.38 + return (tag == multi_branch_data_tag); 1.39 +} 1.40 + 1.41 +// Perform generic initialization of the data. More specific 1.42 +// initialization occurs in overrides of ProfileData::post_initialize. 1.43 +void DataLayout::initialize(u1 tag, u2 bci, int cell_count) { 1.44 + _header._bits = (intptr_t)0; 1.45 + _header._struct._tag = tag; 1.46 + _header._struct._bci = bci; 1.47 + for (int i = 0; i < cell_count; i++) { 1.48 + set_cell_at(i, (intptr_t)0); 1.49 + } 1.50 + if (needs_array_len(tag)) { 1.51 + set_cell_at(ArrayData::array_len_off_set, cell_count - 1); // -1 for header. 1.52 + } 1.53 +} 1.54 + 1.55 +// ================================================================== 1.56 +// ProfileData 1.57 +// 1.58 +// A ProfileData object is created to refer to a section of profiling 1.59 +// data in a structured way. 1.60 + 1.61 +// Constructor for invalid ProfileData. 1.62 +ProfileData::ProfileData() { 1.63 + _data = NULL; 1.64 +} 1.65 + 1.66 +#ifndef PRODUCT 1.67 +void ProfileData::print_shared(outputStream* st, const char* name) { 1.68 + st->print("bci: %d", bci()); 1.69 + st->fill_to(tab_width_one); 1.70 + st->print("%s", name); 1.71 + tab(st); 1.72 + int trap = trap_state(); 1.73 + if (trap != 0) { 1.74 + char buf[100]; 1.75 + st->print("trap(%s) ", Deoptimization::format_trap_state(buf, sizeof(buf), trap)); 1.76 + } 1.77 + int flags = data()->flags(); 1.78 + if (flags != 0) 1.79 + st->print("flags(%d) ", flags); 1.80 +} 1.81 + 1.82 +void ProfileData::tab(outputStream* st) { 1.83 + st->fill_to(tab_width_two); 1.84 +} 1.85 +#endif // !PRODUCT 1.86 + 1.87 +// ================================================================== 1.88 +// BitData 1.89 +// 1.90 +// A BitData corresponds to a one-bit flag. This is used to indicate 1.91 +// whether a checkcast bytecode has seen a null value. 1.92 + 1.93 + 1.94 +#ifndef PRODUCT 1.95 +void BitData::print_data_on(outputStream* st) { 1.96 + print_shared(st, "BitData"); 1.97 +} 1.98 +#endif // !PRODUCT 1.99 + 1.100 +// ================================================================== 1.101 +// CounterData 1.102 +// 1.103 +// A CounterData corresponds to a simple counter. 1.104 + 1.105 +#ifndef PRODUCT 1.106 +void CounterData::print_data_on(outputStream* st) { 1.107 + print_shared(st, "CounterData"); 1.108 + st->print_cr("count(%u)", count()); 1.109 +} 1.110 +#endif // !PRODUCT 1.111 + 1.112 +// ================================================================== 1.113 +// JumpData 1.114 +// 1.115 +// A JumpData is used to access profiling information for a direct 1.116 +// branch. It is a counter, used for counting the number of branches, 1.117 +// plus a data displacement, used for realigning the data pointer to 1.118 +// the corresponding target bci. 1.119 + 1.120 +void JumpData::post_initialize(BytecodeStream* stream, methodDataOop mdo) { 1.121 + assert(stream->bci() == bci(), "wrong pos"); 1.122 + int target; 1.123 + Bytecodes::Code c = stream->code(); 1.124 + if (c == Bytecodes::_goto_w || c == Bytecodes::_jsr_w) { 1.125 + target = stream->dest_w(); 1.126 + } else { 1.127 + target = stream->dest(); 1.128 + } 1.129 + int my_di = mdo->dp_to_di(dp()); 1.130 + int target_di = mdo->bci_to_di(target); 1.131 + int offset = target_di - my_di; 1.132 + set_displacement(offset); 1.133 +} 1.134 + 1.135 +#ifndef PRODUCT 1.136 +void JumpData::print_data_on(outputStream* st) { 1.137 + print_shared(st, "JumpData"); 1.138 + st->print_cr("taken(%u) displacement(%d)", taken(), displacement()); 1.139 +} 1.140 +#endif // !PRODUCT 1.141 + 1.142 +// ================================================================== 1.143 +// ReceiverTypeData 1.144 +// 1.145 +// A ReceiverTypeData is used to access profiling information about a 1.146 +// dynamic type check. It consists of a counter which counts the total times 1.147 +// that the check is reached, and a series of (klassOop, count) pairs 1.148 +// which are used to store a type profile for the receiver of the check. 1.149 + 1.150 +void ReceiverTypeData::follow_contents() { 1.151 + for (uint row = 0; row < row_limit(); row++) { 1.152 + if (receiver(row) != NULL) { 1.153 + MarkSweep::mark_and_push(adr_receiver(row)); 1.154 + } 1.155 + } 1.156 +} 1.157 + 1.158 +#ifndef SERIALGC 1.159 +void ReceiverTypeData::follow_contents(ParCompactionManager* cm) { 1.160 + for (uint row = 0; row < row_limit(); row++) { 1.161 + if (receiver(row) != NULL) { 1.162 + PSParallelCompact::mark_and_push(cm, adr_receiver(row)); 1.163 + } 1.164 + } 1.165 +} 1.166 +#endif // SERIALGC 1.167 + 1.168 +void ReceiverTypeData::oop_iterate(OopClosure* blk) { 1.169 + for (uint row = 0; row < row_limit(); row++) { 1.170 + if (receiver(row) != NULL) { 1.171 + blk->do_oop(adr_receiver(row)); 1.172 + } 1.173 + } 1.174 +} 1.175 + 1.176 +void ReceiverTypeData::oop_iterate_m(OopClosure* blk, MemRegion mr) { 1.177 + for (uint row = 0; row < row_limit(); row++) { 1.178 + if (receiver(row) != NULL) { 1.179 + oop* adr = adr_receiver(row); 1.180 + if (mr.contains(adr)) { 1.181 + blk->do_oop(adr); 1.182 + } 1.183 + } 1.184 + } 1.185 +} 1.186 + 1.187 +void ReceiverTypeData::adjust_pointers() { 1.188 + for (uint row = 0; row < row_limit(); row++) { 1.189 + if (receiver(row) != NULL) { 1.190 + MarkSweep::adjust_pointer(adr_receiver(row)); 1.191 + } 1.192 + } 1.193 +} 1.194 + 1.195 +#ifndef SERIALGC 1.196 +void ReceiverTypeData::update_pointers() { 1.197 + for (uint row = 0; row < row_limit(); row++) { 1.198 + if (receiver_unchecked(row) != NULL) { 1.199 + PSParallelCompact::adjust_pointer(adr_receiver(row)); 1.200 + } 1.201 + } 1.202 +} 1.203 + 1.204 +void ReceiverTypeData::update_pointers(HeapWord* beg_addr, HeapWord* end_addr) { 1.205 + // The loop bounds could be computed based on beg_addr/end_addr and the 1.206 + // boundary test hoisted outside the loop (see klassVTable for an example); 1.207 + // however, row_limit() is small enough (2) to make that less efficient. 1.208 + for (uint row = 0; row < row_limit(); row++) { 1.209 + if (receiver_unchecked(row) != NULL) { 1.210 + PSParallelCompact::adjust_pointer(adr_receiver(row), beg_addr, end_addr); 1.211 + } 1.212 + } 1.213 +} 1.214 +#endif // SERIALGC 1.215 + 1.216 +#ifndef PRODUCT 1.217 +void ReceiverTypeData::print_receiver_data_on(outputStream* st) { 1.218 + uint row; 1.219 + int entries = 0; 1.220 + for (row = 0; row < row_limit(); row++) { 1.221 + if (receiver(row) != NULL) entries++; 1.222 + } 1.223 + st->print_cr("count(%u) entries(%u)", count(), entries); 1.224 + for (row = 0; row < row_limit(); row++) { 1.225 + if (receiver(row) != NULL) { 1.226 + tab(st); 1.227 + receiver(row)->print_value_on(st); 1.228 + st->print_cr("(%u)", receiver_count(row)); 1.229 + } 1.230 + } 1.231 +} 1.232 +void ReceiverTypeData::print_data_on(outputStream* st) { 1.233 + print_shared(st, "ReceiverTypeData"); 1.234 + print_receiver_data_on(st); 1.235 +} 1.236 +void VirtualCallData::print_data_on(outputStream* st) { 1.237 + print_shared(st, "VirtualCallData"); 1.238 + print_receiver_data_on(st); 1.239 +} 1.240 +#endif // !PRODUCT 1.241 + 1.242 +// ================================================================== 1.243 +// RetData 1.244 +// 1.245 +// A RetData is used to access profiling information for a ret bytecode. 1.246 +// It is composed of a count of the number of times that the ret has 1.247 +// been executed, followed by a series of triples of the form 1.248 +// (bci, count, di) which count the number of times that some bci was the 1.249 +// target of the ret and cache a corresponding displacement. 1.250 + 1.251 +void RetData::post_initialize(BytecodeStream* stream, methodDataOop mdo) { 1.252 + for (uint row = 0; row < row_limit(); row++) { 1.253 + set_bci_displacement(row, -1); 1.254 + set_bci(row, no_bci); 1.255 + } 1.256 + // release so other threads see a consistent state. bci is used as 1.257 + // a valid flag for bci_displacement. 1.258 + OrderAccess::release(); 1.259 +} 1.260 + 1.261 +// This routine needs to atomically update the RetData structure, so the 1.262 +// caller needs to hold the RetData_lock before it gets here. Since taking 1.263 +// the lock can block (and allow GC) and since RetData is a ProfileData is a 1.264 +// wrapper around a derived oop, taking the lock in _this_ method will 1.265 +// basically cause the 'this' pointer's _data field to contain junk after the 1.266 +// lock. We require the caller to take the lock before making the ProfileData 1.267 +// structure. Currently the only caller is InterpreterRuntime::update_mdp_for_ret 1.268 +address RetData::fixup_ret(int return_bci, methodDataHandle h_mdo) { 1.269 + // First find the mdp which corresponds to the return bci. 1.270 + address mdp = h_mdo->bci_to_dp(return_bci); 1.271 + 1.272 + // Now check to see if any of the cache slots are open. 1.273 + for (uint row = 0; row < row_limit(); row++) { 1.274 + if (bci(row) == no_bci) { 1.275 + set_bci_displacement(row, mdp - dp()); 1.276 + set_bci_count(row, DataLayout::counter_increment); 1.277 + // Barrier to ensure displacement is written before the bci; allows 1.278 + // the interpreter to read displacement without fear of race condition. 1.279 + release_set_bci(row, return_bci); 1.280 + break; 1.281 + } 1.282 + } 1.283 + return mdp; 1.284 +} 1.285 + 1.286 + 1.287 +#ifndef PRODUCT 1.288 +void RetData::print_data_on(outputStream* st) { 1.289 + print_shared(st, "RetData"); 1.290 + uint row; 1.291 + int entries = 0; 1.292 + for (row = 0; row < row_limit(); row++) { 1.293 + if (bci(row) != no_bci) entries++; 1.294 + } 1.295 + st->print_cr("count(%u) entries(%u)", count(), entries); 1.296 + for (row = 0; row < row_limit(); row++) { 1.297 + if (bci(row) != no_bci) { 1.298 + tab(st); 1.299 + st->print_cr("bci(%d: count(%u) displacement(%d))", 1.300 + bci(row), bci_count(row), bci_displacement(row)); 1.301 + } 1.302 + } 1.303 +} 1.304 +#endif // !PRODUCT 1.305 + 1.306 +// ================================================================== 1.307 +// BranchData 1.308 +// 1.309 +// A BranchData is used to access profiling data for a two-way branch. 1.310 +// It consists of taken and not_taken counts as well as a data displacement 1.311 +// for the taken case. 1.312 + 1.313 +void BranchData::post_initialize(BytecodeStream* stream, methodDataOop mdo) { 1.314 + assert(stream->bci() == bci(), "wrong pos"); 1.315 + int target = stream->dest(); 1.316 + int my_di = mdo->dp_to_di(dp()); 1.317 + int target_di = mdo->bci_to_di(target); 1.318 + int offset = target_di - my_di; 1.319 + set_displacement(offset); 1.320 +} 1.321 + 1.322 +#ifndef PRODUCT 1.323 +void BranchData::print_data_on(outputStream* st) { 1.324 + print_shared(st, "BranchData"); 1.325 + st->print_cr("taken(%u) displacement(%d)", 1.326 + taken(), displacement()); 1.327 + tab(st); 1.328 + st->print_cr("not taken(%u)", not_taken()); 1.329 +} 1.330 +#endif 1.331 + 1.332 +// ================================================================== 1.333 +// MultiBranchData 1.334 +// 1.335 +// A MultiBranchData is used to access profiling information for 1.336 +// a multi-way branch (*switch bytecodes). It consists of a series 1.337 +// of (count, displacement) pairs, which count the number of times each 1.338 +// case was taken and specify the data displacment for each branch target. 1.339 + 1.340 +int MultiBranchData::compute_cell_count(BytecodeStream* stream) { 1.341 + int cell_count = 0; 1.342 + if (stream->code() == Bytecodes::_tableswitch) { 1.343 + Bytecode_tableswitch* sw = Bytecode_tableswitch_at(stream->bcp()); 1.344 + cell_count = 1 + per_case_cell_count * (1 + sw->length()); // 1 for default 1.345 + } else { 1.346 + Bytecode_lookupswitch* sw = Bytecode_lookupswitch_at(stream->bcp()); 1.347 + cell_count = 1 + per_case_cell_count * (sw->number_of_pairs() + 1); // 1 for default 1.348 + } 1.349 + return cell_count; 1.350 +} 1.351 + 1.352 +void MultiBranchData::post_initialize(BytecodeStream* stream, 1.353 + methodDataOop mdo) { 1.354 + assert(stream->bci() == bci(), "wrong pos"); 1.355 + int target; 1.356 + int my_di; 1.357 + int target_di; 1.358 + int offset; 1.359 + if (stream->code() == Bytecodes::_tableswitch) { 1.360 + Bytecode_tableswitch* sw = Bytecode_tableswitch_at(stream->bcp()); 1.361 + int len = sw->length(); 1.362 + assert(array_len() == per_case_cell_count * (len + 1), "wrong len"); 1.363 + for (int count = 0; count < len; count++) { 1.364 + target = sw->dest_offset_at(count) + bci(); 1.365 + my_di = mdo->dp_to_di(dp()); 1.366 + target_di = mdo->bci_to_di(target); 1.367 + offset = target_di - my_di; 1.368 + set_displacement_at(count, offset); 1.369 + } 1.370 + target = sw->default_offset() + bci(); 1.371 + my_di = mdo->dp_to_di(dp()); 1.372 + target_di = mdo->bci_to_di(target); 1.373 + offset = target_di - my_di; 1.374 + set_default_displacement(offset); 1.375 + 1.376 + } else { 1.377 + Bytecode_lookupswitch* sw = Bytecode_lookupswitch_at(stream->bcp()); 1.378 + int npairs = sw->number_of_pairs(); 1.379 + assert(array_len() == per_case_cell_count * (npairs + 1), "wrong len"); 1.380 + for (int count = 0; count < npairs; count++) { 1.381 + LookupswitchPair *pair = sw->pair_at(count); 1.382 + target = pair->offset() + bci(); 1.383 + my_di = mdo->dp_to_di(dp()); 1.384 + target_di = mdo->bci_to_di(target); 1.385 + offset = target_di - my_di; 1.386 + set_displacement_at(count, offset); 1.387 + } 1.388 + target = sw->default_offset() + bci(); 1.389 + my_di = mdo->dp_to_di(dp()); 1.390 + target_di = mdo->bci_to_di(target); 1.391 + offset = target_di - my_di; 1.392 + set_default_displacement(offset); 1.393 + } 1.394 +} 1.395 + 1.396 +#ifndef PRODUCT 1.397 +void MultiBranchData::print_data_on(outputStream* st) { 1.398 + print_shared(st, "MultiBranchData"); 1.399 + st->print_cr("default_count(%u) displacement(%d)", 1.400 + default_count(), default_displacement()); 1.401 + int cases = number_of_cases(); 1.402 + for (int i = 0; i < cases; i++) { 1.403 + tab(st); 1.404 + st->print_cr("count(%u) displacement(%d)", 1.405 + count_at(i), displacement_at(i)); 1.406 + } 1.407 +} 1.408 +#endif 1.409 + 1.410 +// ================================================================== 1.411 +// methodDataOop 1.412 +// 1.413 +// A methodDataOop holds information which has been collected about 1.414 +// a method. 1.415 + 1.416 +int methodDataOopDesc::bytecode_cell_count(Bytecodes::Code code) { 1.417 + switch (code) { 1.418 + case Bytecodes::_checkcast: 1.419 + case Bytecodes::_instanceof: 1.420 + case Bytecodes::_aastore: 1.421 + if (TypeProfileCasts) { 1.422 + return ReceiverTypeData::static_cell_count(); 1.423 + } else { 1.424 + return BitData::static_cell_count(); 1.425 + } 1.426 + case Bytecodes::_invokespecial: 1.427 + case Bytecodes::_invokestatic: 1.428 + return CounterData::static_cell_count(); 1.429 + case Bytecodes::_goto: 1.430 + case Bytecodes::_goto_w: 1.431 + case Bytecodes::_jsr: 1.432 + case Bytecodes::_jsr_w: 1.433 + return JumpData::static_cell_count(); 1.434 + case Bytecodes::_invokevirtual: 1.435 + case Bytecodes::_invokeinterface: 1.436 + return VirtualCallData::static_cell_count(); 1.437 + case Bytecodes::_ret: 1.438 + return RetData::static_cell_count(); 1.439 + case Bytecodes::_ifeq: 1.440 + case Bytecodes::_ifne: 1.441 + case Bytecodes::_iflt: 1.442 + case Bytecodes::_ifge: 1.443 + case Bytecodes::_ifgt: 1.444 + case Bytecodes::_ifle: 1.445 + case Bytecodes::_if_icmpeq: 1.446 + case Bytecodes::_if_icmpne: 1.447 + case Bytecodes::_if_icmplt: 1.448 + case Bytecodes::_if_icmpge: 1.449 + case Bytecodes::_if_icmpgt: 1.450 + case Bytecodes::_if_icmple: 1.451 + case Bytecodes::_if_acmpeq: 1.452 + case Bytecodes::_if_acmpne: 1.453 + case Bytecodes::_ifnull: 1.454 + case Bytecodes::_ifnonnull: 1.455 + return BranchData::static_cell_count(); 1.456 + case Bytecodes::_lookupswitch: 1.457 + case Bytecodes::_tableswitch: 1.458 + return variable_cell_count; 1.459 + } 1.460 + return no_profile_data; 1.461 +} 1.462 + 1.463 +// Compute the size of the profiling information corresponding to 1.464 +// the current bytecode. 1.465 +int methodDataOopDesc::compute_data_size(BytecodeStream* stream) { 1.466 + int cell_count = bytecode_cell_count(stream->code()); 1.467 + if (cell_count == no_profile_data) { 1.468 + return 0; 1.469 + } 1.470 + if (cell_count == variable_cell_count) { 1.471 + cell_count = MultiBranchData::compute_cell_count(stream); 1.472 + } 1.473 + // Note: cell_count might be zero, meaning that there is just 1.474 + // a DataLayout header, with no extra cells. 1.475 + assert(cell_count >= 0, "sanity"); 1.476 + return DataLayout::compute_size_in_bytes(cell_count); 1.477 +} 1.478 + 1.479 +int methodDataOopDesc::compute_extra_data_count(int data_size, int empty_bc_count) { 1.480 + if (ProfileTraps) { 1.481 + // Assume that up to 3% of BCIs with no MDP will need to allocate one. 1.482 + int extra_data_count = (uint)(empty_bc_count * 3) / 128 + 1; 1.483 + // If the method is large, let the extra BCIs grow numerous (to ~1%). 1.484 + int one_percent_of_data 1.485 + = (uint)data_size / (DataLayout::header_size_in_bytes()*128); 1.486 + if (extra_data_count < one_percent_of_data) 1.487 + extra_data_count = one_percent_of_data; 1.488 + if (extra_data_count > empty_bc_count) 1.489 + extra_data_count = empty_bc_count; // no need for more 1.490 + return extra_data_count; 1.491 + } else { 1.492 + return 0; 1.493 + } 1.494 +} 1.495 + 1.496 +// Compute the size of the methodDataOop necessary to store 1.497 +// profiling information about a given method. Size is in bytes. 1.498 +int methodDataOopDesc::compute_allocation_size_in_bytes(methodHandle method) { 1.499 + int data_size = 0; 1.500 + BytecodeStream stream(method); 1.501 + Bytecodes::Code c; 1.502 + int empty_bc_count = 0; // number of bytecodes lacking data 1.503 + while ((c = stream.next()) >= 0) { 1.504 + int size_in_bytes = compute_data_size(&stream); 1.505 + data_size += size_in_bytes; 1.506 + if (size_in_bytes == 0) empty_bc_count += 1; 1.507 + } 1.508 + int object_size = in_bytes(data_offset()) + data_size; 1.509 + 1.510 + // Add some extra DataLayout cells (at least one) to track stray traps. 1.511 + int extra_data_count = compute_extra_data_count(data_size, empty_bc_count); 1.512 + object_size += extra_data_count * DataLayout::compute_size_in_bytes(0); 1.513 + 1.514 + return object_size; 1.515 +} 1.516 + 1.517 +// Compute the size of the methodDataOop necessary to store 1.518 +// profiling information about a given method. Size is in words 1.519 +int methodDataOopDesc::compute_allocation_size_in_words(methodHandle method) { 1.520 + int byte_size = compute_allocation_size_in_bytes(method); 1.521 + int word_size = align_size_up(byte_size, BytesPerWord) / BytesPerWord; 1.522 + return align_object_size(word_size); 1.523 +} 1.524 + 1.525 +// Initialize an individual data segment. Returns the size of 1.526 +// the segment in bytes. 1.527 +int methodDataOopDesc::initialize_data(BytecodeStream* stream, 1.528 + int data_index) { 1.529 + int cell_count = -1; 1.530 + int tag = DataLayout::no_tag; 1.531 + DataLayout* data_layout = data_layout_at(data_index); 1.532 + Bytecodes::Code c = stream->code(); 1.533 + switch (c) { 1.534 + case Bytecodes::_checkcast: 1.535 + case Bytecodes::_instanceof: 1.536 + case Bytecodes::_aastore: 1.537 + if (TypeProfileCasts) { 1.538 + cell_count = ReceiverTypeData::static_cell_count(); 1.539 + tag = DataLayout::receiver_type_data_tag; 1.540 + } else { 1.541 + cell_count = BitData::static_cell_count(); 1.542 + tag = DataLayout::bit_data_tag; 1.543 + } 1.544 + break; 1.545 + case Bytecodes::_invokespecial: 1.546 + case Bytecodes::_invokestatic: 1.547 + cell_count = CounterData::static_cell_count(); 1.548 + tag = DataLayout::counter_data_tag; 1.549 + break; 1.550 + case Bytecodes::_goto: 1.551 + case Bytecodes::_goto_w: 1.552 + case Bytecodes::_jsr: 1.553 + case Bytecodes::_jsr_w: 1.554 + cell_count = JumpData::static_cell_count(); 1.555 + tag = DataLayout::jump_data_tag; 1.556 + break; 1.557 + case Bytecodes::_invokevirtual: 1.558 + case Bytecodes::_invokeinterface: 1.559 + cell_count = VirtualCallData::static_cell_count(); 1.560 + tag = DataLayout::virtual_call_data_tag; 1.561 + break; 1.562 + case Bytecodes::_ret: 1.563 + cell_count = RetData::static_cell_count(); 1.564 + tag = DataLayout::ret_data_tag; 1.565 + break; 1.566 + case Bytecodes::_ifeq: 1.567 + case Bytecodes::_ifne: 1.568 + case Bytecodes::_iflt: 1.569 + case Bytecodes::_ifge: 1.570 + case Bytecodes::_ifgt: 1.571 + case Bytecodes::_ifle: 1.572 + case Bytecodes::_if_icmpeq: 1.573 + case Bytecodes::_if_icmpne: 1.574 + case Bytecodes::_if_icmplt: 1.575 + case Bytecodes::_if_icmpge: 1.576 + case Bytecodes::_if_icmpgt: 1.577 + case Bytecodes::_if_icmple: 1.578 + case Bytecodes::_if_acmpeq: 1.579 + case Bytecodes::_if_acmpne: 1.580 + case Bytecodes::_ifnull: 1.581 + case Bytecodes::_ifnonnull: 1.582 + cell_count = BranchData::static_cell_count(); 1.583 + tag = DataLayout::branch_data_tag; 1.584 + break; 1.585 + case Bytecodes::_lookupswitch: 1.586 + case Bytecodes::_tableswitch: 1.587 + cell_count = MultiBranchData::compute_cell_count(stream); 1.588 + tag = DataLayout::multi_branch_data_tag; 1.589 + break; 1.590 + } 1.591 + assert(tag == DataLayout::multi_branch_data_tag || 1.592 + cell_count == bytecode_cell_count(c), "cell counts must agree"); 1.593 + if (cell_count >= 0) { 1.594 + assert(tag != DataLayout::no_tag, "bad tag"); 1.595 + assert(bytecode_has_profile(c), "agree w/ BHP"); 1.596 + data_layout->initialize(tag, stream->bci(), cell_count); 1.597 + return DataLayout::compute_size_in_bytes(cell_count); 1.598 + } else { 1.599 + assert(!bytecode_has_profile(c), "agree w/ !BHP"); 1.600 + return 0; 1.601 + } 1.602 +} 1.603 + 1.604 +// Get the data at an arbitrary (sort of) data index. 1.605 +ProfileData* methodDataOopDesc::data_at(int data_index) { 1.606 + if (out_of_bounds(data_index)) { 1.607 + return NULL; 1.608 + } 1.609 + DataLayout* data_layout = data_layout_at(data_index); 1.610 + 1.611 + switch (data_layout->tag()) { 1.612 + case DataLayout::no_tag: 1.613 + default: 1.614 + ShouldNotReachHere(); 1.615 + return NULL; 1.616 + case DataLayout::bit_data_tag: 1.617 + return new BitData(data_layout); 1.618 + case DataLayout::counter_data_tag: 1.619 + return new CounterData(data_layout); 1.620 + case DataLayout::jump_data_tag: 1.621 + return new JumpData(data_layout); 1.622 + case DataLayout::receiver_type_data_tag: 1.623 + return new ReceiverTypeData(data_layout); 1.624 + case DataLayout::virtual_call_data_tag: 1.625 + return new VirtualCallData(data_layout); 1.626 + case DataLayout::ret_data_tag: 1.627 + return new RetData(data_layout); 1.628 + case DataLayout::branch_data_tag: 1.629 + return new BranchData(data_layout); 1.630 + case DataLayout::multi_branch_data_tag: 1.631 + return new MultiBranchData(data_layout); 1.632 + }; 1.633 +} 1.634 + 1.635 +// Iteration over data. 1.636 +ProfileData* methodDataOopDesc::next_data(ProfileData* current) { 1.637 + int current_index = dp_to_di(current->dp()); 1.638 + int next_index = current_index + current->size_in_bytes(); 1.639 + ProfileData* next = data_at(next_index); 1.640 + return next; 1.641 +} 1.642 + 1.643 +// Give each of the data entries a chance to perform specific 1.644 +// data initialization. 1.645 +void methodDataOopDesc::post_initialize(BytecodeStream* stream) { 1.646 + ResourceMark rm; 1.647 + ProfileData* data; 1.648 + for (data = first_data(); is_valid(data); data = next_data(data)) { 1.649 + stream->set_start(data->bci()); 1.650 + stream->next(); 1.651 + data->post_initialize(stream, this); 1.652 + } 1.653 +} 1.654 + 1.655 +// Initialize the methodDataOop corresponding to a given method. 1.656 +void methodDataOopDesc::initialize(methodHandle method) { 1.657 + ResourceMark rm; 1.658 + 1.659 + // Set the method back-pointer. 1.660 + _method = method(); 1.661 + set_creation_mileage(mileage_of(method())); 1.662 + 1.663 + // Initialize flags and trap history. 1.664 + _nof_decompiles = 0; 1.665 + _nof_overflow_recompiles = 0; 1.666 + _nof_overflow_traps = 0; 1.667 + assert(sizeof(_trap_hist) % sizeof(HeapWord) == 0, "align"); 1.668 + Copy::zero_to_words((HeapWord*) &_trap_hist, 1.669 + sizeof(_trap_hist) / sizeof(HeapWord)); 1.670 + 1.671 + // Go through the bytecodes and allocate and initialize the 1.672 + // corresponding data cells. 1.673 + int data_size = 0; 1.674 + int empty_bc_count = 0; // number of bytecodes lacking data 1.675 + BytecodeStream stream(method); 1.676 + Bytecodes::Code c; 1.677 + while ((c = stream.next()) >= 0) { 1.678 + int size_in_bytes = initialize_data(&stream, data_size); 1.679 + data_size += size_in_bytes; 1.680 + if (size_in_bytes == 0) empty_bc_count += 1; 1.681 + } 1.682 + _data_size = data_size; 1.683 + int object_size = in_bytes(data_offset()) + data_size; 1.684 + 1.685 + // Add some extra DataLayout cells (at least one) to track stray traps. 1.686 + int extra_data_count = compute_extra_data_count(data_size, empty_bc_count); 1.687 + object_size += extra_data_count * DataLayout::compute_size_in_bytes(0); 1.688 + 1.689 + // Set an initial hint. Don't use set_hint_di() because 1.690 + // first_di() may be out of bounds if data_size is 0. 1.691 + // In that situation, _hint_di is never used, but at 1.692 + // least well-defined. 1.693 + _hint_di = first_di(); 1.694 + 1.695 + post_initialize(&stream); 1.696 + 1.697 + set_object_is_parsable(object_size); 1.698 +} 1.699 + 1.700 +// Get a measure of how much mileage the method has on it. 1.701 +int methodDataOopDesc::mileage_of(methodOop method) { 1.702 + int mileage = 0; 1.703 + int iic = method->interpreter_invocation_count(); 1.704 + if (mileage < iic) mileage = iic; 1.705 + 1.706 + InvocationCounter* ic = method->invocation_counter(); 1.707 + InvocationCounter* bc = method->backedge_counter(); 1.708 + 1.709 + int icval = ic->count(); 1.710 + if (ic->carry()) icval += CompileThreshold; 1.711 + if (mileage < icval) mileage = icval; 1.712 + int bcval = bc->count(); 1.713 + if (bc->carry()) bcval += CompileThreshold; 1.714 + if (mileage < bcval) mileage = bcval; 1.715 + return mileage; 1.716 +} 1.717 + 1.718 +bool methodDataOopDesc::is_mature() const { 1.719 + uint current = mileage_of(_method); 1.720 + uint initial = creation_mileage(); 1.721 + if (current < initial) 1.722 + return true; // some sort of overflow 1.723 + uint target; 1.724 + if (ProfileMaturityPercentage <= 0) 1.725 + target = (uint) -ProfileMaturityPercentage; // absolute value 1.726 + else 1.727 + target = (uint)( (ProfileMaturityPercentage * CompileThreshold) / 100 ); 1.728 + return (current >= initial + target); 1.729 +} 1.730 + 1.731 +// Translate a bci to its corresponding data index (di). 1.732 +address methodDataOopDesc::bci_to_dp(int bci) { 1.733 + ResourceMark rm; 1.734 + ProfileData* data = data_before(bci); 1.735 + ProfileData* prev = NULL; 1.736 + for ( ; is_valid(data); data = next_data(data)) { 1.737 + if (data->bci() >= bci) { 1.738 + if (data->bci() == bci) set_hint_di(dp_to_di(data->dp())); 1.739 + else if (prev != NULL) set_hint_di(dp_to_di(prev->dp())); 1.740 + return data->dp(); 1.741 + } 1.742 + prev = data; 1.743 + } 1.744 + return (address)limit_data_position(); 1.745 +} 1.746 + 1.747 +// Translate a bci to its corresponding data, or NULL. 1.748 +ProfileData* methodDataOopDesc::bci_to_data(int bci) { 1.749 + ProfileData* data = data_before(bci); 1.750 + for ( ; is_valid(data); data = next_data(data)) { 1.751 + if (data->bci() == bci) { 1.752 + set_hint_di(dp_to_di(data->dp())); 1.753 + return data; 1.754 + } else if (data->bci() > bci) { 1.755 + break; 1.756 + } 1.757 + } 1.758 + return bci_to_extra_data(bci, false); 1.759 +} 1.760 + 1.761 +// Translate a bci to its corresponding extra data, or NULL. 1.762 +ProfileData* methodDataOopDesc::bci_to_extra_data(int bci, bool create_if_missing) { 1.763 + DataLayout* dp = extra_data_base(); 1.764 + DataLayout* end = extra_data_limit(); 1.765 + DataLayout* avail = NULL; 1.766 + for (; dp < end; dp = next_extra(dp)) { 1.767 + // No need for "OrderAccess::load_acquire" ops, 1.768 + // since the data structure is monotonic. 1.769 + if (dp->tag() == DataLayout::no_tag) break; 1.770 + if (dp->bci() == bci) { 1.771 + assert(dp->tag() == DataLayout::bit_data_tag, "sane"); 1.772 + return new BitData(dp); 1.773 + } 1.774 + } 1.775 + if (create_if_missing && dp < end) { 1.776 + // Allocate this one. There is no mutual exclusion, 1.777 + // so two threads could allocate different BCIs to the 1.778 + // same data layout. This means these extra data 1.779 + // records, like most other MDO contents, must not be 1.780 + // trusted too much. 1.781 + DataLayout temp; 1.782 + temp.initialize(DataLayout::bit_data_tag, bci, 0); 1.783 + dp->release_set_header(temp.header()); 1.784 + assert(dp->tag() == DataLayout::bit_data_tag, "sane"); 1.785 + //NO: assert(dp->bci() == bci, "no concurrent allocation"); 1.786 + return new BitData(dp); 1.787 + } 1.788 + return NULL; 1.789 +} 1.790 + 1.791 +#ifndef PRODUCT 1.792 +void methodDataOopDesc::print_data_on(outputStream* st) { 1.793 + ResourceMark rm; 1.794 + ProfileData* data = first_data(); 1.795 + for ( ; is_valid(data); data = next_data(data)) { 1.796 + st->print("%d", dp_to_di(data->dp())); 1.797 + st->fill_to(6); 1.798 + data->print_data_on(st); 1.799 + } 1.800 + DataLayout* dp = extra_data_base(); 1.801 + DataLayout* end = extra_data_limit(); 1.802 + for (; dp < end; dp = next_extra(dp)) { 1.803 + // No need for "OrderAccess::load_acquire" ops, 1.804 + // since the data structure is monotonic. 1.805 + if (dp->tag() == DataLayout::no_tag) break; 1.806 + if (dp == extra_data_base()) 1.807 + st->print_cr("--- Extra data:"); 1.808 + data = new BitData(dp); 1.809 + st->print("%d", dp_to_di(data->dp())); 1.810 + st->fill_to(6); 1.811 + data->print_data_on(st); 1.812 + } 1.813 +} 1.814 +#endif 1.815 + 1.816 +void methodDataOopDesc::verify_data_on(outputStream* st) { 1.817 + NEEDS_CLEANUP; 1.818 + // not yet implemented. 1.819 +}