bcEscapeAnalyzer.cpp revision 196:d1605aabd0a1
1/* 2 * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 20 * CA 95054 USA or visit www.sun.com if you need additional information or 21 * have any questions. 22 * 23 */ 24 25 26#include "incls/_precompiled.incl" 27#include "incls/_bcEscapeAnalyzer.cpp.incl" 28 29 30#ifndef PRODUCT 31 #define TRACE_BCEA(level, code) \ 32 if (EstimateArgEscape && BCEATraceLevel >= level) { \ 33 code; \ 34 } 35#else 36 #define TRACE_BCEA(level, code) 37#endif 38 39// Maintain a map of which aguments a local variable or 40// stack slot may contain. In addition to tracking 41// arguments, it tracks two special values, "allocated" 42// which represents any object allocated in the current 43// method, and "unknown" which is any other object. 44// Up to 30 arguments are handled, with the last one 45// representing summary information for any extra arguments 46class BCEscapeAnalyzer::ArgumentMap { 47 uint _bits; 48 enum {MAXBIT = 29, 49 ALLOCATED = 1, 50 UNKNOWN = 2}; 51 52 uint int_to_bit(uint e) const { 53 if (e > MAXBIT) 54 e = MAXBIT; 55 return (1 << (e + 2)); 56 } 57 58public: 59 ArgumentMap() { _bits = 0;} 60 void set_bits(uint bits) { _bits = bits;} 61 uint get_bits() const { return _bits;} 62 void clear() { _bits = 0;} 63 void set_all() { _bits = ~0u; } 64 bool is_empty() const { return _bits == 0; } 65 bool contains(uint var) const { return (_bits & int_to_bit(var)) != 0; } 66 bool is_singleton(uint var) const { return (_bits == int_to_bit(var)); } 67 bool contains_unknown() const { return (_bits & UNKNOWN) != 0; } 68 bool contains_allocated() const { return (_bits & ALLOCATED) != 0; } 69 bool contains_vars() const { return (_bits & (((1 << MAXBIT) -1) << 2)) != 0; } 70 void set(uint var) { _bits = int_to_bit(var); } 71 void add(uint var) { _bits |= int_to_bit(var); } 72 void add_unknown() { _bits = UNKNOWN; } 73 void add_allocated() { _bits = ALLOCATED; } 74 void set_union(const ArgumentMap &am) { _bits |= am._bits; } 75 void set_intersect(const ArgumentMap &am) { _bits |= am._bits; } 76 void set_difference(const ArgumentMap &am) { _bits &= ~am._bits; } 77 void operator=(const ArgumentMap &am) { _bits = am._bits; } 78 bool operator==(const ArgumentMap &am) { return _bits == am._bits; } 79 bool operator!=(const ArgumentMap &am) { return _bits != am._bits; } 80}; 81 82class BCEscapeAnalyzer::StateInfo { 83public: 84 ArgumentMap *_vars; 85 ArgumentMap *_stack; 86 short _stack_height; 87 short _max_stack; 88 bool _initialized; 89 ArgumentMap empty_map; 90 91 StateInfo() { 92 empty_map.clear(); 93 } 94 95 ArgumentMap raw_pop() { assert(_stack_height > 0, "stack underflow"); return _stack[--_stack_height]; } 96 ArgumentMap apop() { return raw_pop(); } 97 void spop() { raw_pop(); } 98 void lpop() { spop(); spop(); } 99 void raw_push(ArgumentMap i) { assert(_stack_height < _max_stack, "stack overflow"); _stack[_stack_height++] = i; } 100 void apush(ArgumentMap i) { raw_push(i); } 101 void spush() { raw_push(empty_map); } 102 void lpush() { spush(); spush(); } 103 104}; 105 106void BCEscapeAnalyzer::set_returned(ArgumentMap vars) { 107 for (int i = 0; i < _arg_size; i++) { 108 if (vars.contains(i)) 109 _arg_returned.set_bit(i); 110 } 111 _return_local = _return_local && !(vars.contains_unknown() || vars.contains_allocated()); 112 _return_allocated = _return_allocated && vars.contains_allocated() && !(vars.contains_unknown() || vars.contains_vars()); 113} 114 115// return true if any element of vars is an argument 116bool BCEscapeAnalyzer::is_argument(ArgumentMap vars) { 117 for (int i = 0; i < _arg_size; i++) { 118 if (vars.contains(i)) 119 return true; 120 } 121 return false; 122} 123 124// return true if any element of vars is an arg_stack argument 125bool BCEscapeAnalyzer::is_arg_stack(ArgumentMap vars){ 126 if (_conservative) 127 return true; 128 for (int i = 0; i < _arg_size; i++) { 129 if (vars.contains(i) && _arg_stack.at(i)) 130 return true; 131 } 132 return false; 133} 134 135void BCEscapeAnalyzer::clear_bits(ArgumentMap vars, BitMap &bm) { 136 for (int i = 0; i < _arg_size; i++) { 137 if (vars.contains(i)) { 138 bm.clear_bit(i); 139 } 140 } 141} 142 143void BCEscapeAnalyzer::set_method_escape(ArgumentMap vars) { 144 clear_bits(vars, _arg_local); 145} 146 147void BCEscapeAnalyzer::set_global_escape(ArgumentMap vars) { 148 clear_bits(vars, _arg_local); 149 clear_bits(vars, _arg_stack); 150 if (vars.contains_allocated()) 151 _allocated_escapes = true; 152} 153 154void BCEscapeAnalyzer::set_dirty(ArgumentMap vars) { 155 clear_bits(vars, _dirty); 156} 157 158void BCEscapeAnalyzer::set_modified(ArgumentMap vars, int offs, int size) { 159 160 for (int i = 0; i < _arg_size; i++) { 161 if (vars.contains(i)) { 162 set_arg_modified(i, offs, size); 163 } 164 } 165 if (vars.contains_unknown()) 166 _unknown_modified = true; 167} 168 169bool BCEscapeAnalyzer::is_recursive_call(ciMethod* callee) { 170 for (BCEscapeAnalyzer* scope = this; scope != NULL; scope = scope->_parent) { 171 if (scope->method() == callee) { 172 return true; 173 } 174 } 175 return false; 176} 177 178bool BCEscapeAnalyzer::is_arg_modified(int arg, int offset, int size_in_bytes) { 179 if (offset == OFFSET_ANY) 180 return _arg_modified[arg] != 0; 181 assert(arg >= 0 && arg < _arg_size, "must be an argument."); 182 bool modified = false; 183 int l = offset / HeapWordSize; 184 int h = round_to(offset + size_in_bytes, HeapWordSize) / HeapWordSize; 185 if (l > ARG_OFFSET_MAX) 186 l = ARG_OFFSET_MAX; 187 if (h > ARG_OFFSET_MAX+1) 188 h = ARG_OFFSET_MAX + 1; 189 for (int i = l; i < h; i++) { 190 modified = modified || (_arg_modified[arg] & (1 << i)) != 0; 191 } 192 return modified; 193} 194 195void BCEscapeAnalyzer::set_arg_modified(int arg, int offset, int size_in_bytes) { 196 if (offset == OFFSET_ANY) { 197 _arg_modified[arg] = (uint) -1; 198 return; 199 } 200 assert(arg >= 0 && arg < _arg_size, "must be an argument."); 201 int l = offset / HeapWordSize; 202 int h = round_to(offset + size_in_bytes, HeapWordSize) / HeapWordSize; 203 if (l > ARG_OFFSET_MAX) 204 l = ARG_OFFSET_MAX; 205 if (h > ARG_OFFSET_MAX+1) 206 h = ARG_OFFSET_MAX + 1; 207 for (int i = l; i < h; i++) { 208 _arg_modified[arg] |= (1 << i); 209 } 210} 211 212void BCEscapeAnalyzer::invoke(StateInfo &state, Bytecodes::Code code, ciMethod* target, ciKlass* holder) { 213 int i; 214 215 // retrieve information about the callee 216 ciInstanceKlass* klass = target->holder(); 217 ciInstanceKlass* calling_klass = method()->holder(); 218 ciInstanceKlass* callee_holder = ciEnv::get_instance_klass_for_declared_method_holder(holder); 219 ciInstanceKlass* actual_recv = callee_holder; 220 221 // some methods are obviously bindable without any type checks so 222 // convert them directly to an invokespecial. 223 if (target->is_loaded() && !target->is_abstract() && 224 target->can_be_statically_bound() && code == Bytecodes::_invokevirtual) { 225 code = Bytecodes::_invokespecial; 226 } 227 228 // compute size of arguments 229 int arg_size = target->arg_size(); 230 if (!target->is_loaded() && code == Bytecodes::_invokestatic) { 231 arg_size--; 232 } 233 int arg_base = MAX2(state._stack_height - arg_size, 0); 234 235 // direct recursive calls are skipped if they can be bound statically without introducing 236 // dependencies and if parameters are passed at the same position as in the current method 237 // other calls are skipped if there are no unescaped arguments passed to them 238 bool directly_recursive = (method() == target) && 239 (code != Bytecodes::_invokevirtual || target->is_final_method() || state._stack[arg_base] .is_empty()); 240 241 // check if analysis of callee can safely be skipped 242 bool skip_callee = true; 243 for (i = state._stack_height - 1; i >= arg_base && skip_callee; i--) { 244 ArgumentMap arg = state._stack[i]; 245 skip_callee = !is_argument(arg) || !is_arg_stack(arg) || (directly_recursive && arg.is_singleton(i - arg_base)); 246 } 247 if (skip_callee) { 248 TRACE_BCEA(3, tty->print_cr("[EA] skipping method %s::%s", holder->name()->as_utf8(), target->name()->as_utf8())); 249 for (i = 0; i < arg_size; i++) { 250 set_method_escape(state.raw_pop()); 251 } 252 _unknown_modified = true; // assume the worst since we don't analyze the called method 253 return; 254 } 255 256 // determine actual method (use CHA if necessary) 257 ciMethod* inline_target = NULL; 258 if (target->is_loaded() && klass->is_loaded() 259 && (klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized()) 260 && target->will_link(klass, callee_holder, code)) { 261 if (code == Bytecodes::_invokestatic 262 || code == Bytecodes::_invokespecial 263 || code == Bytecodes::_invokevirtual && target->is_final_method()) { 264 inline_target = target; 265 } else { 266 inline_target = target->find_monomorphic_target(calling_klass, callee_holder, actual_recv); 267 } 268 } 269 270 if (inline_target != NULL && !is_recursive_call(inline_target)) { 271 // analyze callee 272 BCEscapeAnalyzer analyzer(inline_target, this); 273 274 // adjust escape state of actual parameters 275 bool must_record_dependencies = false; 276 for (i = arg_size - 1; i >= 0; i--) { 277 ArgumentMap arg = state.raw_pop(); 278 if (!is_argument(arg)) 279 continue; 280 for (int j = 0; j < _arg_size; j++) { 281 if (arg.contains(j)) { 282 _arg_modified[j] |= analyzer._arg_modified[i]; 283 } 284 } 285 if (!is_arg_stack(arg)) { 286 // arguments have already been recognized as escaping 287 } else if (analyzer.is_arg_stack(i) && !analyzer.is_arg_returned(i)) { 288 set_method_escape(arg); 289 must_record_dependencies = true; 290 } else { 291 set_global_escape(arg); 292 } 293 } 294 _unknown_modified = _unknown_modified || analyzer.has_non_arg_side_affects(); 295 296 // record dependencies if at least one parameter retained stack-allocatable 297 if (must_record_dependencies) { 298 if (code == Bytecodes::_invokeinterface || code == Bytecodes::_invokevirtual && !target->is_final_method()) { 299 _dependencies.append(actual_recv); 300 _dependencies.append(inline_target); 301 } 302 _dependencies.appendAll(analyzer.dependencies()); 303 } 304 } else { 305 TRACE_BCEA(1, tty->print_cr("[EA] virtual method %s is not monomorphic.", 306 target->name()->as_utf8())); 307 // conservatively mark all actual parameters as escaping globally 308 for (i = 0; i < arg_size; i++) { 309 ArgumentMap arg = state.raw_pop(); 310 if (!is_argument(arg)) 311 continue; 312 set_modified(arg, OFFSET_ANY, type2size[T_INT]*HeapWordSize); 313 set_global_escape(arg); 314 } 315 _unknown_modified = true; // assume the worst since we don't know the called method 316 } 317} 318 319bool BCEscapeAnalyzer::contains(uint arg_set1, uint arg_set2) { 320 return ((~arg_set1) | arg_set2) == 0; 321} 322 323 324void BCEscapeAnalyzer::iterate_one_block(ciBlock *blk, StateInfo &state, GrowableArray<ciBlock *> &successors) { 325 326 blk->set_processed(); 327 ciBytecodeStream s(method()); 328 int limit_bci = blk->limit_bci(); 329 bool fall_through = false; 330 ArgumentMap allocated_obj; 331 allocated_obj.add_allocated(); 332 ArgumentMap unknown_obj; 333 unknown_obj.add_unknown(); 334 ArgumentMap empty_map; 335 336 s.reset_to_bci(blk->start_bci()); 337 while (s.next() != ciBytecodeStream::EOBC() && s.cur_bci() < limit_bci) { 338 fall_through = true; 339 switch (s.cur_bc()) { 340 case Bytecodes::_nop: 341 break; 342 case Bytecodes::_aconst_null: 343 state.apush(empty_map); 344 break; 345 case Bytecodes::_iconst_m1: 346 case Bytecodes::_iconst_0: 347 case Bytecodes::_iconst_1: 348 case Bytecodes::_iconst_2: 349 case Bytecodes::_iconst_3: 350 case Bytecodes::_iconst_4: 351 case Bytecodes::_iconst_5: 352 case Bytecodes::_fconst_0: 353 case Bytecodes::_fconst_1: 354 case Bytecodes::_fconst_2: 355 case Bytecodes::_bipush: 356 case Bytecodes::_sipush: 357 state.spush(); 358 break; 359 case Bytecodes::_lconst_0: 360 case Bytecodes::_lconst_1: 361 case Bytecodes::_dconst_0: 362 case Bytecodes::_dconst_1: 363 state.lpush(); 364 break; 365 case Bytecodes::_ldc: 366 case Bytecodes::_ldc_w: 367 case Bytecodes::_ldc2_w: 368 if (type2size[s.get_constant().basic_type()] == 1) { 369 state.spush(); 370 } else { 371 state.lpush(); 372 } 373 break; 374 case Bytecodes::_aload: 375 state.apush(state._vars[s.get_index()]); 376 break; 377 case Bytecodes::_iload: 378 case Bytecodes::_fload: 379 case Bytecodes::_iload_0: 380 case Bytecodes::_iload_1: 381 case Bytecodes::_iload_2: 382 case Bytecodes::_iload_3: 383 case Bytecodes::_fload_0: 384 case Bytecodes::_fload_1: 385 case Bytecodes::_fload_2: 386 case Bytecodes::_fload_3: 387 state.spush(); 388 break; 389 case Bytecodes::_lload: 390 case Bytecodes::_dload: 391 case Bytecodes::_lload_0: 392 case Bytecodes::_lload_1: 393 case Bytecodes::_lload_2: 394 case Bytecodes::_lload_3: 395 case Bytecodes::_dload_0: 396 case Bytecodes::_dload_1: 397 case Bytecodes::_dload_2: 398 case Bytecodes::_dload_3: 399 state.lpush(); 400 break; 401 case Bytecodes::_aload_0: 402 state.apush(state._vars[0]); 403 break; 404 case Bytecodes::_aload_1: 405 state.apush(state._vars[1]); 406 break; 407 case Bytecodes::_aload_2: 408 state.apush(state._vars[2]); 409 break; 410 case Bytecodes::_aload_3: 411 state.apush(state._vars[3]); 412 break; 413 case Bytecodes::_iaload: 414 case Bytecodes::_faload: 415 case Bytecodes::_baload: 416 case Bytecodes::_caload: 417 case Bytecodes::_saload: 418 state.spop(); 419 set_method_escape(state.apop()); 420 state.spush(); 421 break; 422 case Bytecodes::_laload: 423 case Bytecodes::_daload: 424 state.spop(); 425 set_method_escape(state.apop()); 426 state.lpush(); 427 break; 428 case Bytecodes::_aaload: 429 { state.spop(); 430 ArgumentMap array = state.apop(); 431 set_method_escape(array); 432 state.apush(unknown_obj); 433 set_dirty(array); 434 } 435 break; 436 case Bytecodes::_istore: 437 case Bytecodes::_fstore: 438 case Bytecodes::_istore_0: 439 case Bytecodes::_istore_1: 440 case Bytecodes::_istore_2: 441 case Bytecodes::_istore_3: 442 case Bytecodes::_fstore_0: 443 case Bytecodes::_fstore_1: 444 case Bytecodes::_fstore_2: 445 case Bytecodes::_fstore_3: 446 state.spop(); 447 break; 448 case Bytecodes::_lstore: 449 case Bytecodes::_dstore: 450 case Bytecodes::_lstore_0: 451 case Bytecodes::_lstore_1: 452 case Bytecodes::_lstore_2: 453 case Bytecodes::_lstore_3: 454 case Bytecodes::_dstore_0: 455 case Bytecodes::_dstore_1: 456 case Bytecodes::_dstore_2: 457 case Bytecodes::_dstore_3: 458 state.lpop(); 459 break; 460 case Bytecodes::_astore: 461 state._vars[s.get_index()] = state.apop(); 462 break; 463 case Bytecodes::_astore_0: 464 state._vars[0] = state.apop(); 465 break; 466 case Bytecodes::_astore_1: 467 state._vars[1] = state.apop(); 468 break; 469 case Bytecodes::_astore_2: 470 state._vars[2] = state.apop(); 471 break; 472 case Bytecodes::_astore_3: 473 state._vars[3] = state.apop(); 474 break; 475 case Bytecodes::_iastore: 476 case Bytecodes::_fastore: 477 case Bytecodes::_bastore: 478 case Bytecodes::_castore: 479 case Bytecodes::_sastore: 480 { 481 state.spop(); 482 state.spop(); 483 ArgumentMap arr = state.apop(); 484 set_method_escape(arr); 485 set_modified(arr, OFFSET_ANY, type2size[T_INT]*HeapWordSize); 486 break; 487 } 488 case Bytecodes::_lastore: 489 case Bytecodes::_dastore: 490 { 491 state.lpop(); 492 state.spop(); 493 ArgumentMap arr = state.apop(); 494 set_method_escape(arr); 495 set_modified(arr, OFFSET_ANY, type2size[T_LONG]*HeapWordSize); 496 break; 497 } 498 case Bytecodes::_aastore: 499 { 500 set_global_escape(state.apop()); 501 state.spop(); 502 ArgumentMap arr = state.apop(); 503 set_modified(arr, OFFSET_ANY, type2size[T_OBJECT]*HeapWordSize); 504 break; 505 } 506 case Bytecodes::_pop: 507 state.raw_pop(); 508 break; 509 case Bytecodes::_pop2: 510 state.raw_pop(); 511 state.raw_pop(); 512 break; 513 case Bytecodes::_dup: 514 { ArgumentMap w1 = state.raw_pop(); 515 state.raw_push(w1); 516 state.raw_push(w1); 517 } 518 break; 519 case Bytecodes::_dup_x1: 520 { ArgumentMap w1 = state.raw_pop(); 521 ArgumentMap w2 = state.raw_pop(); 522 state.raw_push(w1); 523 state.raw_push(w2); 524 state.raw_push(w1); 525 } 526 break; 527 case Bytecodes::_dup_x2: 528 { ArgumentMap w1 = state.raw_pop(); 529 ArgumentMap w2 = state.raw_pop(); 530 ArgumentMap w3 = state.raw_pop(); 531 state.raw_push(w1); 532 state.raw_push(w3); 533 state.raw_push(w2); 534 state.raw_push(w1); 535 } 536 break; 537 case Bytecodes::_dup2: 538 { ArgumentMap w1 = state.raw_pop(); 539 ArgumentMap w2 = state.raw_pop(); 540 state.raw_push(w2); 541 state.raw_push(w1); 542 state.raw_push(w2); 543 state.raw_push(w1); 544 } 545 break; 546 case Bytecodes::_dup2_x1: 547 { ArgumentMap w1 = state.raw_pop(); 548 ArgumentMap w2 = state.raw_pop(); 549 ArgumentMap w3 = state.raw_pop(); 550 state.raw_push(w2); 551 state.raw_push(w1); 552 state.raw_push(w3); 553 state.raw_push(w2); 554 state.raw_push(w1); 555 } 556 break; 557 case Bytecodes::_dup2_x2: 558 { ArgumentMap w1 = state.raw_pop(); 559 ArgumentMap w2 = state.raw_pop(); 560 ArgumentMap w3 = state.raw_pop(); 561 ArgumentMap w4 = state.raw_pop(); 562 state.raw_push(w2); 563 state.raw_push(w1); 564 state.raw_push(w4); 565 state.raw_push(w3); 566 state.raw_push(w2); 567 state.raw_push(w1); 568 } 569 break; 570 case Bytecodes::_swap: 571 { ArgumentMap w1 = state.raw_pop(); 572 ArgumentMap w2 = state.raw_pop(); 573 state.raw_push(w1); 574 state.raw_push(w2); 575 } 576 break; 577 case Bytecodes::_iadd: 578 case Bytecodes::_fadd: 579 case Bytecodes::_isub: 580 case Bytecodes::_fsub: 581 case Bytecodes::_imul: 582 case Bytecodes::_fmul: 583 case Bytecodes::_idiv: 584 case Bytecodes::_fdiv: 585 case Bytecodes::_irem: 586 case Bytecodes::_frem: 587 case Bytecodes::_iand: 588 case Bytecodes::_ior: 589 case Bytecodes::_ixor: 590 state.spop(); 591 state.spop(); 592 state.spush(); 593 break; 594 case Bytecodes::_ladd: 595 case Bytecodes::_dadd: 596 case Bytecodes::_lsub: 597 case Bytecodes::_dsub: 598 case Bytecodes::_lmul: 599 case Bytecodes::_dmul: 600 case Bytecodes::_ldiv: 601 case Bytecodes::_ddiv: 602 case Bytecodes::_lrem: 603 case Bytecodes::_drem: 604 case Bytecodes::_land: 605 case Bytecodes::_lor: 606 case Bytecodes::_lxor: 607 state.lpop(); 608 state.lpop(); 609 state.lpush(); 610 break; 611 case Bytecodes::_ishl: 612 case Bytecodes::_ishr: 613 case Bytecodes::_iushr: 614 state.spop(); 615 state.spop(); 616 state.spush(); 617 break; 618 case Bytecodes::_lshl: 619 case Bytecodes::_lshr: 620 case Bytecodes::_lushr: 621 state.spop(); 622 state.lpop(); 623 state.lpush(); 624 break; 625 case Bytecodes::_ineg: 626 case Bytecodes::_fneg: 627 state.spop(); 628 state.spush(); 629 break; 630 case Bytecodes::_lneg: 631 case Bytecodes::_dneg: 632 state.lpop(); 633 state.lpush(); 634 break; 635 case Bytecodes::_iinc: 636 break; 637 case Bytecodes::_i2l: 638 case Bytecodes::_i2d: 639 case Bytecodes::_f2l: 640 case Bytecodes::_f2d: 641 state.spop(); 642 state.lpush(); 643 break; 644 case Bytecodes::_i2f: 645 case Bytecodes::_f2i: 646 state.spop(); 647 state.spush(); 648 break; 649 case Bytecodes::_l2i: 650 case Bytecodes::_l2f: 651 case Bytecodes::_d2i: 652 case Bytecodes::_d2f: 653 state.lpop(); 654 state.spush(); 655 break; 656 case Bytecodes::_l2d: 657 case Bytecodes::_d2l: 658 state.lpop(); 659 state.lpush(); 660 break; 661 case Bytecodes::_i2b: 662 case Bytecodes::_i2c: 663 case Bytecodes::_i2s: 664 state.spop(); 665 state.spush(); 666 break; 667 case Bytecodes::_lcmp: 668 case Bytecodes::_dcmpl: 669 case Bytecodes::_dcmpg: 670 state.lpop(); 671 state.lpop(); 672 state.spush(); 673 break; 674 case Bytecodes::_fcmpl: 675 case Bytecodes::_fcmpg: 676 state.spop(); 677 state.spop(); 678 state.spush(); 679 break; 680 case Bytecodes::_ifeq: 681 case Bytecodes::_ifne: 682 case Bytecodes::_iflt: 683 case Bytecodes::_ifge: 684 case Bytecodes::_ifgt: 685 case Bytecodes::_ifle: 686 { 687 state.spop(); 688 int dest_bci = s.get_dest(); 689 assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block"); 690 assert(s.next_bci() == limit_bci, "branch must end block"); 691 successors.push(_methodBlocks->block_containing(dest_bci)); 692 break; 693 } 694 case Bytecodes::_if_icmpeq: 695 case Bytecodes::_if_icmpne: 696 case Bytecodes::_if_icmplt: 697 case Bytecodes::_if_icmpge: 698 case Bytecodes::_if_icmpgt: 699 case Bytecodes::_if_icmple: 700 { 701 state.spop(); 702 state.spop(); 703 int dest_bci = s.get_dest(); 704 assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block"); 705 assert(s.next_bci() == limit_bci, "branch must end block"); 706 successors.push(_methodBlocks->block_containing(dest_bci)); 707 break; 708 } 709 case Bytecodes::_if_acmpeq: 710 case Bytecodes::_if_acmpne: 711 { 712 set_method_escape(state.apop()); 713 set_method_escape(state.apop()); 714 int dest_bci = s.get_dest(); 715 assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block"); 716 assert(s.next_bci() == limit_bci, "branch must end block"); 717 successors.push(_methodBlocks->block_containing(dest_bci)); 718 break; 719 } 720 case Bytecodes::_goto: 721 { 722 int dest_bci = s.get_dest(); 723 assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block"); 724 assert(s.next_bci() == limit_bci, "branch must end block"); 725 successors.push(_methodBlocks->block_containing(dest_bci)); 726 fall_through = false; 727 break; 728 } 729 case Bytecodes::_jsr: 730 { 731 int dest_bci = s.get_dest(); 732 assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block"); 733 assert(s.next_bci() == limit_bci, "branch must end block"); 734 state.apush(empty_map); 735 successors.push(_methodBlocks->block_containing(dest_bci)); 736 fall_through = false; 737 break; 738 } 739 case Bytecodes::_ret: 740 // we don't track the destination of a "ret" instruction 741 assert(s.next_bci() == limit_bci, "branch must end block"); 742 fall_through = false; 743 break; 744 case Bytecodes::_return: 745 assert(s.next_bci() == limit_bci, "return must end block"); 746 fall_through = false; 747 break; 748 case Bytecodes::_tableswitch: 749 { 750 state.spop(); 751 Bytecode_tableswitch* switch_ = Bytecode_tableswitch_at(s.cur_bcp()); 752 int len = switch_->length(); 753 int dest_bci; 754 for (int i = 0; i < len; i++) { 755 dest_bci = s.cur_bci() + switch_->dest_offset_at(i); 756 assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block"); 757 successors.push(_methodBlocks->block_containing(dest_bci)); 758 } 759 dest_bci = s.cur_bci() + switch_->default_offset(); 760 assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block"); 761 successors.push(_methodBlocks->block_containing(dest_bci)); 762 assert(s.next_bci() == limit_bci, "branch must end block"); 763 fall_through = false; 764 break; 765 } 766 case Bytecodes::_lookupswitch: 767 { 768 state.spop(); 769 Bytecode_lookupswitch* switch_ = Bytecode_lookupswitch_at(s.cur_bcp()); 770 int len = switch_->number_of_pairs(); 771 int dest_bci; 772 for (int i = 0; i < len; i++) { 773 dest_bci = s.cur_bci() + switch_->pair_at(i)->offset(); 774 assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block"); 775 successors.push(_methodBlocks->block_containing(dest_bci)); 776 } 777 dest_bci = s.cur_bci() + switch_->default_offset(); 778 assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block"); 779 successors.push(_methodBlocks->block_containing(dest_bci)); 780 fall_through = false; 781 break; 782 } 783 case Bytecodes::_ireturn: 784 case Bytecodes::_freturn: 785 state.spop(); 786 fall_through = false; 787 break; 788 case Bytecodes::_lreturn: 789 case Bytecodes::_dreturn: 790 state.lpop(); 791 fall_through = false; 792 break; 793 case Bytecodes::_areturn: 794 set_returned(state.apop()); 795 fall_through = false; 796 break; 797 case Bytecodes::_getstatic: 798 case Bytecodes::_getfield: 799 { bool will_link; 800 ciField* field = s.get_field(will_link); 801 BasicType field_type = field->type()->basic_type(); 802 if (s.cur_bc() != Bytecodes::_getstatic) { 803 set_method_escape(state.apop()); 804 } 805 if (field_type == T_OBJECT || field_type == T_ARRAY) { 806 state.apush(unknown_obj); 807 } else if (type2size[field_type] == 1) { 808 state.spush(); 809 } else { 810 state.lpush(); 811 } 812 } 813 break; 814 case Bytecodes::_putstatic: 815 case Bytecodes::_putfield: 816 { bool will_link; 817 ciField* field = s.get_field(will_link); 818 BasicType field_type = field->type()->basic_type(); 819 if (field_type == T_OBJECT || field_type == T_ARRAY) { 820 set_global_escape(state.apop()); 821 } else if (type2size[field_type] == 1) { 822 state.spop(); 823 } else { 824 state.lpop(); 825 } 826 if (s.cur_bc() != Bytecodes::_putstatic) { 827 ArgumentMap p = state.apop(); 828 set_method_escape(p); 829 set_modified(p, will_link ? field->offset() : OFFSET_ANY, type2size[field_type]*HeapWordSize); 830 } 831 } 832 break; 833 case Bytecodes::_invokevirtual: 834 case Bytecodes::_invokespecial: 835 case Bytecodes::_invokestatic: 836 case Bytecodes::_invokeinterface: 837 { bool will_link; 838 ciMethod* target = s.get_method(will_link); 839 ciKlass* holder = s.get_declared_method_holder(); 840 invoke(state, s.cur_bc(), target, holder); 841 ciType* return_type = target->return_type(); 842 if (!return_type->is_primitive_type()) { 843 state.apush(unknown_obj); 844 } else if (return_type->is_one_word()) { 845 state.spush(); 846 } else if (return_type->is_two_word()) { 847 state.lpush(); 848 } 849 } 850 break; 851 case Bytecodes::_xxxunusedxxx: 852 ShouldNotReachHere(); 853 break; 854 case Bytecodes::_new: 855 state.apush(allocated_obj); 856 break; 857 case Bytecodes::_newarray: 858 case Bytecodes::_anewarray: 859 state.spop(); 860 state.apush(allocated_obj); 861 break; 862 case Bytecodes::_multianewarray: 863 { int i = s.cur_bcp()[3]; 864 while (i-- > 0) state.spop(); 865 state.apush(allocated_obj); 866 } 867 break; 868 case Bytecodes::_arraylength: 869 set_method_escape(state.apop()); 870 state.spush(); 871 break; 872 case Bytecodes::_athrow: 873 set_global_escape(state.apop()); 874 fall_through = false; 875 break; 876 case Bytecodes::_checkcast: 877 { ArgumentMap obj = state.apop(); 878 set_method_escape(obj); 879 state.apush(obj); 880 } 881 break; 882 case Bytecodes::_instanceof: 883 set_method_escape(state.apop()); 884 state.spush(); 885 break; 886 case Bytecodes::_monitorenter: 887 case Bytecodes::_monitorexit: 888 state.apop(); 889 break; 890 case Bytecodes::_wide: 891 ShouldNotReachHere(); 892 break; 893 case Bytecodes::_ifnull: 894 case Bytecodes::_ifnonnull: 895 { 896 set_method_escape(state.apop()); 897 int dest_bci = s.get_dest(); 898 assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block"); 899 assert(s.next_bci() == limit_bci, "branch must end block"); 900 successors.push(_methodBlocks->block_containing(dest_bci)); 901 break; 902 } 903 case Bytecodes::_goto_w: 904 { 905 int dest_bci = s.get_far_dest(); 906 assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block"); 907 assert(s.next_bci() == limit_bci, "branch must end block"); 908 successors.push(_methodBlocks->block_containing(dest_bci)); 909 fall_through = false; 910 break; 911 } 912 case Bytecodes::_jsr_w: 913 { 914 int dest_bci = s.get_far_dest(); 915 assert(_methodBlocks->is_block_start(dest_bci), "branch destination must start a block"); 916 assert(s.next_bci() == limit_bci, "branch must end block"); 917 state.apush(empty_map); 918 successors.push(_methodBlocks->block_containing(dest_bci)); 919 fall_through = false; 920 break; 921 } 922 case Bytecodes::_breakpoint: 923 break; 924 default: 925 ShouldNotReachHere(); 926 break; 927 } 928 929 } 930 if (fall_through) { 931 int fall_through_bci = s.cur_bci(); 932 if (fall_through_bci < _method->code_size()) { 933 assert(_methodBlocks->is_block_start(fall_through_bci), "must fall through to block start."); 934 successors.push(_methodBlocks->block_containing(fall_through_bci)); 935 } 936 } 937} 938 939void BCEscapeAnalyzer::merge_block_states(StateInfo *blockstates, ciBlock *dest, StateInfo *s_state) { 940 StateInfo *d_state = blockstates + dest->index(); 941 int nlocals = _method->max_locals(); 942 943 // exceptions may cause transfer of control to handlers in the middle of a 944 // block, so we don't merge the incoming state of exception handlers 945 if (dest->is_handler()) 946 return; 947 if (!d_state->_initialized ) { 948 // destination not initialized, just copy 949 for (int i = 0; i < nlocals; i++) { 950 d_state->_vars[i] = s_state->_vars[i]; 951 } 952 for (int i = 0; i < s_state->_stack_height; i++) { 953 d_state->_stack[i] = s_state->_stack[i]; 954 } 955 d_state->_stack_height = s_state->_stack_height; 956 d_state->_max_stack = s_state->_max_stack; 957 d_state->_initialized = true; 958 } else if (!dest->processed()) { 959 // we have not yet walked the bytecodes of dest, we can merge 960 // the states 961 assert(d_state->_stack_height == s_state->_stack_height, "computed stack heights must match"); 962 for (int i = 0; i < nlocals; i++) { 963 d_state->_vars[i].set_union(s_state->_vars[i]); 964 } 965 for (int i = 0; i < s_state->_stack_height; i++) { 966 d_state->_stack[i].set_union(s_state->_stack[i]); 967 } 968 } else { 969 // the bytecodes of dest have already been processed, mark any 970 // arguments in the source state which are not in the dest state 971 // as global escape. 972 // Future refinement: we only need to mark these variable to the 973 // maximum escape of any variables in dest state 974 assert(d_state->_stack_height == s_state->_stack_height, "computed stack heights must match"); 975 ArgumentMap extra_vars; 976 for (int i = 0; i < nlocals; i++) { 977 ArgumentMap t; 978 t = s_state->_vars[i]; 979 t.set_difference(d_state->_vars[i]); 980 extra_vars.set_union(t); 981 } 982 for (int i = 0; i < s_state->_stack_height; i++) { 983 ArgumentMap t; 984 //extra_vars |= !d_state->_vars[i] & s_state->_vars[i]; 985 t.clear(); 986 t = s_state->_stack[i]; 987 t.set_difference(d_state->_stack[i]); 988 extra_vars.set_union(t); 989 } 990 set_global_escape(extra_vars); 991 } 992} 993 994void BCEscapeAnalyzer::iterate_blocks(Arena *arena) { 995 int numblocks = _methodBlocks->num_blocks(); 996 int stkSize = _method->max_stack(); 997 int numLocals = _method->max_locals(); 998 StateInfo state; 999 1000 int datacount = (numblocks + 1) * (stkSize + numLocals); 1001 int datasize = datacount * sizeof(ArgumentMap); 1002 StateInfo *blockstates = (StateInfo *) arena->Amalloc(numblocks * sizeof(StateInfo)); 1003 ArgumentMap *statedata = (ArgumentMap *) arena->Amalloc(datasize); 1004 for (int i = 0; i < datacount; i++) ::new ((void*)&statedata[i]) ArgumentMap(); 1005 ArgumentMap *dp = statedata; 1006 state._vars = dp; 1007 dp += numLocals; 1008 state._stack = dp; 1009 dp += stkSize; 1010 state._initialized = false; 1011 state._max_stack = stkSize; 1012 for (int i = 0; i < numblocks; i++) { 1013 blockstates[i]._vars = dp; 1014 dp += numLocals; 1015 blockstates[i]._stack = dp; 1016 dp += stkSize; 1017 blockstates[i]._initialized = false; 1018 blockstates[i]._stack_height = 0; 1019 blockstates[i]._max_stack = stkSize; 1020 } 1021 GrowableArray<ciBlock *> worklist(arena, numblocks / 4, 0, NULL); 1022 GrowableArray<ciBlock *> successors(arena, 4, 0, NULL); 1023 1024 _methodBlocks->clear_processed(); 1025 1026 // initialize block 0 state from method signature 1027 ArgumentMap allVars; // all oop arguments to method 1028 ciSignature* sig = method()->signature(); 1029 int j = 0; 1030 ciBlock* first_blk = _methodBlocks->block_containing(0); 1031 int fb_i = first_blk->index(); 1032 if (!method()->is_static()) { 1033 // record information for "this" 1034 blockstates[fb_i]._vars[j].set(j); 1035 allVars.add(j); 1036 j++; 1037 } 1038 for (int i = 0; i < sig->count(); i++) { 1039 ciType* t = sig->type_at(i); 1040 if (!t->is_primitive_type()) { 1041 blockstates[fb_i]._vars[j].set(j); 1042 allVars.add(j); 1043 } 1044 j += t->size(); 1045 } 1046 blockstates[fb_i]._initialized = true; 1047 assert(j == _arg_size, "just checking"); 1048 1049 ArgumentMap unknown_map; 1050 unknown_map.add_unknown(); 1051 1052 worklist.push(first_blk); 1053 while(worklist.length() > 0) { 1054 ciBlock *blk = worklist.pop(); 1055 StateInfo *blkState = blockstates + blk->index(); 1056 if (blk->is_handler() || blk->is_ret_target()) { 1057 // for an exception handler or a target of a ret instruction, we assume the worst case, 1058 // that any variable could contain any argument 1059 for (int i = 0; i < numLocals; i++) { 1060 state._vars[i] = allVars; 1061 } 1062 if (blk->is_handler()) { 1063 state._stack_height = 1; 1064 } else { 1065 state._stack_height = blkState->_stack_height; 1066 } 1067 for (int i = 0; i < state._stack_height; i++) { 1068// ??? should this be unknown_map ??? 1069 state._stack[i] = allVars; 1070 } 1071 } else { 1072 for (int i = 0; i < numLocals; i++) { 1073 state._vars[i] = blkState->_vars[i]; 1074 } 1075 for (int i = 0; i < blkState->_stack_height; i++) { 1076 state._stack[i] = blkState->_stack[i]; 1077 } 1078 state._stack_height = blkState->_stack_height; 1079 } 1080 iterate_one_block(blk, state, successors); 1081 // if this block has any exception handlers, push them 1082 // onto successor list 1083 if (blk->has_handler()) { 1084 DEBUG_ONLY(int handler_count = 0;) 1085 int blk_start = blk->start_bci(); 1086 int blk_end = blk->limit_bci(); 1087 for (int i = 0; i < numblocks; i++) { 1088 ciBlock *b = _methodBlocks->block(i); 1089 if (b->is_handler()) { 1090 int ex_start = b->ex_start_bci(); 1091 int ex_end = b->ex_limit_bci(); 1092 if ((ex_start >= blk_start && ex_start < blk_end) || 1093 (ex_end > blk_start && ex_end <= blk_end)) { 1094 successors.push(b); 1095 } 1096 DEBUG_ONLY(handler_count++;) 1097 } 1098 } 1099 assert(handler_count > 0, "must find at least one handler"); 1100 } 1101 // merge computed variable state with successors 1102 while(successors.length() > 0) { 1103 ciBlock *succ = successors.pop(); 1104 merge_block_states(blockstates, succ, &state); 1105 if (!succ->processed()) 1106 worklist.push(succ); 1107 } 1108 } 1109} 1110 1111bool BCEscapeAnalyzer::do_analysis() { 1112 Arena* arena = CURRENT_ENV->arena(); 1113 // identify basic blocks 1114 _methodBlocks = _method->get_method_blocks(); 1115 1116 iterate_blocks(arena); 1117 // TEMPORARY 1118 return true; 1119} 1120 1121vmIntrinsics::ID BCEscapeAnalyzer::known_intrinsic() { 1122 vmIntrinsics::ID iid = method()->intrinsic_id(); 1123 1124 if (iid == vmIntrinsics::_getClass || 1125 iid == vmIntrinsics::_fillInStackTrace || 1126 iid == vmIntrinsics::_hashCode) 1127 return iid; 1128 else 1129 return vmIntrinsics::_none; 1130} 1131 1132bool BCEscapeAnalyzer::compute_escape_for_intrinsic(vmIntrinsics::ID iid) { 1133 ArgumentMap arg; 1134 arg.clear(); 1135 switch (iid) { 1136 case vmIntrinsics::_getClass: 1137 _return_local = false; 1138 break; 1139 case vmIntrinsics::_fillInStackTrace: 1140 arg.set(0); // 'this' 1141 set_returned(arg); 1142 break; 1143 case vmIntrinsics::_hashCode: 1144 // initialized state is correct 1145 break; 1146 default: 1147 assert(false, "unexpected intrinsic"); 1148 } 1149 return true; 1150} 1151 1152void BCEscapeAnalyzer::initialize() { 1153 int i; 1154 1155 // clear escape information (method may have been deoptimized) 1156 methodData()->clear_escape_info(); 1157 1158 // initialize escape state of object parameters 1159 ciSignature* sig = method()->signature(); 1160 int j = 0; 1161 if (!method()->is_static()) { 1162 _arg_local.set_bit(0); 1163 _arg_stack.set_bit(0); 1164 j++; 1165 } 1166 for (i = 0; i < sig->count(); i++) { 1167 ciType* t = sig->type_at(i); 1168 if (!t->is_primitive_type()) { 1169 _arg_local.set_bit(j); 1170 _arg_stack.set_bit(j); 1171 } 1172 j += t->size(); 1173 } 1174 assert(j == _arg_size, "just checking"); 1175 1176 // start with optimistic assumption 1177 ciType *rt = _method->return_type(); 1178 if (rt->is_primitive_type()) { 1179 _return_local = false; 1180 _return_allocated = false; 1181 } else { 1182 _return_local = true; 1183 _return_allocated = true; 1184 } 1185 _allocated_escapes = false; 1186 _unknown_modified = false; 1187} 1188 1189void BCEscapeAnalyzer::clear_escape_info() { 1190 ciSignature* sig = method()->signature(); 1191 int arg_count = sig->count(); 1192 ArgumentMap var; 1193 if (!method()->is_static()) { 1194 arg_count++; // allow for "this" 1195 } 1196 for (int i = 0; i < arg_count; i++) { 1197 set_arg_modified(i, OFFSET_ANY, 4); 1198 var.clear(); 1199 var.set(i); 1200 set_modified(var, OFFSET_ANY, 4); 1201 set_global_escape(var); 1202 } 1203 _arg_local.clear(); 1204 _arg_stack.clear(); 1205 _arg_returned.clear(); 1206 _return_local = false; 1207 _return_allocated = false; 1208 _allocated_escapes = true; 1209 _unknown_modified = true; 1210} 1211 1212 1213void BCEscapeAnalyzer::compute_escape_info() { 1214 int i; 1215 assert(!methodData()->has_escape_info(), "do not overwrite escape info"); 1216 1217 vmIntrinsics::ID iid = known_intrinsic(); 1218 1219 // check if method can be analyzed 1220 if (iid == vmIntrinsics::_none && (method()->is_abstract() || method()->is_native() || !method()->holder()->is_initialized() 1221 || _level > MaxBCEAEstimateLevel 1222 || method()->code_size() > MaxBCEAEstimateSize)) { 1223 if (BCEATraceLevel >= 1) { 1224 tty->print("Skipping method because: "); 1225 if (method()->is_abstract()) 1226 tty->print_cr("method is abstract."); 1227 else if (method()->is_native()) 1228 tty->print_cr("method is native."); 1229 else if (!method()->holder()->is_initialized()) 1230 tty->print_cr("class of method is not initialized."); 1231 else if (_level > MaxBCEAEstimateLevel) 1232 tty->print_cr("level (%d) exceeds MaxBCEAEstimateLevel (%d).", 1233 _level, MaxBCEAEstimateLevel); 1234 else if (method()->code_size() > MaxBCEAEstimateSize) 1235 tty->print_cr("code size (%d) exceeds MaxBCEAEstimateSize.", 1236 method()->code_size(), MaxBCEAEstimateSize); 1237 else 1238 ShouldNotReachHere(); 1239 } 1240 clear_escape_info(); 1241 1242 return; 1243 } 1244 1245 if (BCEATraceLevel >= 1) { 1246 tty->print("[EA] estimating escape information for"); 1247 if (iid != vmIntrinsics::_none) 1248 tty->print(" intrinsic"); 1249 method()->print_short_name(); 1250 tty->print_cr(" (%d bytes)", method()->code_size()); 1251 } 1252 1253 bool success; 1254 1255 initialize(); 1256 1257 // Do not scan method if it has no object parameters and 1258 // does not returns an object (_return_allocated is set in initialize()). 1259 if (_arg_local.is_empty() && !_return_allocated) { 1260 // Clear all info since method's bytecode was not analysed and 1261 // set pessimistic escape information. 1262 clear_escape_info(); 1263 methodData()->set_eflag(methodDataOopDesc::allocated_escapes); 1264 methodData()->set_eflag(methodDataOopDesc::unknown_modified); 1265 methodData()->set_eflag(methodDataOopDesc::estimated); 1266 return; 1267 } 1268 1269 if (iid != vmIntrinsics::_none) 1270 success = compute_escape_for_intrinsic(iid); 1271 else { 1272 success = do_analysis(); 1273 } 1274 1275 // don't store interprocedural escape information if it introduces 1276 // dependencies or if method data is empty 1277 // 1278 if (!has_dependencies() && !methodData()->is_empty()) { 1279 for (i = 0; i < _arg_size; i++) { 1280 if (_arg_local.at(i)) { 1281 assert(_arg_stack.at(i), "inconsistent escape info"); 1282 methodData()->set_arg_local(i); 1283 methodData()->set_arg_stack(i); 1284 } else if (_arg_stack.at(i)) { 1285 methodData()->set_arg_stack(i); 1286 } 1287 if (_arg_returned.at(i)) { 1288 methodData()->set_arg_returned(i); 1289 } 1290 methodData()->set_arg_modified(i, _arg_modified[i]); 1291 } 1292 if (_return_local) { 1293 methodData()->set_eflag(methodDataOopDesc::return_local); 1294 } 1295 if (_return_allocated) { 1296 methodData()->set_eflag(methodDataOopDesc::return_allocated); 1297 } 1298 if (_allocated_escapes) { 1299 methodData()->set_eflag(methodDataOopDesc::allocated_escapes); 1300 } 1301 if (_unknown_modified) { 1302 methodData()->set_eflag(methodDataOopDesc::unknown_modified); 1303 } 1304 methodData()->set_eflag(methodDataOopDesc::estimated); 1305 } 1306} 1307 1308void BCEscapeAnalyzer::read_escape_info() { 1309 assert(methodData()->has_escape_info(), "no escape info available"); 1310 1311 // read escape information from method descriptor 1312 for (int i = 0; i < _arg_size; i++) { 1313 _arg_local.at_put(i, methodData()->is_arg_local(i)); 1314 _arg_stack.at_put(i, methodData()->is_arg_stack(i)); 1315 _arg_returned.at_put(i, methodData()->is_arg_returned(i)); 1316 _arg_modified[i] = methodData()->arg_modified(i); 1317 } 1318 _return_local = methodData()->eflag_set(methodDataOopDesc::return_local); 1319 _return_allocated = methodData()->eflag_set(methodDataOopDesc::return_allocated); 1320 _allocated_escapes = methodData()->eflag_set(methodDataOopDesc::allocated_escapes); 1321 _unknown_modified = methodData()->eflag_set(methodDataOopDesc::unknown_modified); 1322 1323} 1324 1325#ifndef PRODUCT 1326void BCEscapeAnalyzer::dump() { 1327 tty->print("[EA] estimated escape information for"); 1328 method()->print_short_name(); 1329 tty->print_cr(has_dependencies() ? " (not stored)" : ""); 1330 tty->print(" non-escaping args: "); 1331 _arg_local.print_on(tty); 1332 tty->print(" stack-allocatable args: "); 1333 _arg_stack.print_on(tty); 1334 if (_return_local) { 1335 tty->print(" returned args: "); 1336 _arg_returned.print_on(tty); 1337 } else if (is_return_allocated()) { 1338 tty->print_cr(" return allocated value"); 1339 } else { 1340 tty->print_cr(" return non-local value"); 1341 } 1342 tty->print(" modified args: "); 1343 for (int i = 0; i < _arg_size; i++) { 1344 if (_arg_modified[i] == 0) 1345 tty->print(" 0"); 1346 else 1347 tty->print(" 0x%x", _arg_modified[i]); 1348 } 1349 tty->cr(); 1350 tty->print(" flags: "); 1351 if (_return_allocated) 1352 tty->print(" return_allocated"); 1353 if (_allocated_escapes) 1354 tty->print(" allocated_escapes"); 1355 if (_unknown_modified) 1356 tty->print(" unknown_modified"); 1357 tty->cr(); 1358} 1359#endif 1360 1361BCEscapeAnalyzer::BCEscapeAnalyzer(ciMethod* method, BCEscapeAnalyzer* parent) 1362 : _conservative(method == NULL || !EstimateArgEscape) 1363 , _method(method) 1364 , _methodData(method ? method->method_data() : NULL) 1365 , _arg_size(method ? method->arg_size() : 0) 1366 , _stack() 1367 , _arg_local(_arg_size) 1368 , _arg_stack(_arg_size) 1369 , _arg_returned(_arg_size) 1370 , _dirty(_arg_size) 1371 , _return_local(false) 1372 , _return_allocated(false) 1373 , _allocated_escapes(false) 1374 , _unknown_modified(false) 1375 , _dependencies() 1376 , _parent(parent) 1377 , _level(parent == NULL ? 0 : parent->level() + 1) { 1378 if (!_conservative) { 1379 _arg_local.clear(); 1380 _arg_stack.clear(); 1381 _arg_returned.clear(); 1382 _dirty.clear(); 1383 Arena* arena = CURRENT_ENV->arena(); 1384 _arg_modified = (uint *) arena->Amalloc(_arg_size * sizeof(uint)); 1385 Copy::zero_to_bytes(_arg_modified, _arg_size * sizeof(uint)); 1386 1387 if (methodData() == NULL) 1388 return; 1389 bool printit = _method->should_print_assembly(); 1390 if (methodData()->has_escape_info()) { 1391 TRACE_BCEA(2, tty->print_cr("[EA] Reading previous results for %s.%s", 1392 method->holder()->name()->as_utf8(), 1393 method->name()->as_utf8())); 1394 read_escape_info(); 1395 } else { 1396 TRACE_BCEA(2, tty->print_cr("[EA] computing results for %s.%s", 1397 method->holder()->name()->as_utf8(), 1398 method->name()->as_utf8())); 1399 1400 compute_escape_info(); 1401 methodData()->update_escape_info(); 1402 } 1403#ifndef PRODUCT 1404 if (BCEATraceLevel >= 3) { 1405 // dump escape information 1406 dump(); 1407 } 1408#endif 1409 } 1410} 1411 1412void BCEscapeAnalyzer::copy_dependencies(Dependencies *deps) { 1413 if(!has_dependencies()) 1414 return; 1415 for (int i = 0; i < _dependencies.length(); i+=2) { 1416 ciKlass *k = _dependencies[i]->as_klass(); 1417 ciMethod *m = _dependencies[i+1]->as_method(); 1418 deps->assert_unique_concrete_method(k, m); 1419 } 1420} 1421