agent/src/share/classes/sun/jvm/hotspot/oops/GenerateOopMap.java

Print this page


   1 /*
   2  * Copyright (c) 2001, 2011, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 634 
 635   // Basicblock info
 636   BasicBlock[]    _basic_blocks;             // Array of basicblock info
 637   int             _gc_points;
 638   int             _bb_count;
 639   BitMap          _bb_hdr_bits;
 640 
 641   // Basicblocks methods
 642   void          initializeBB               () {
 643     _gc_points = 0;
 644     _bb_count  = 0;
 645     _bb_hdr_bits = new BitMap((int) _method.getCodeSize());
 646   }
 647 
 648   void          markBBHeadersAndCountGCPoints() {
 649     initializeBB();
 650 
 651     boolean fellThrough = false;  // False to get first BB marked.
 652 
 653     // First mark all exception handlers as start of a basic-block
 654     TypeArray excps = method().getExceptionTable();
 655     for(int i = 0; i < excps.getLength(); i += 4) {
 656       int handler_pc_idx = i+2;
 657       markBB(excps.getIntAt(handler_pc_idx), null);

 658     }
 659 
 660     // Then iterate through the code
 661     BytecodeStream bcs = new BytecodeStream(_method);
 662     int bytecode;
 663 
 664     while( (bytecode = bcs.next()) >= 0) {
 665       int bci = bcs.bci();
 666 
 667       if (!fellThrough)
 668         markBB(bci, null);
 669 
 670       fellThrough = jumpTargetsDo(bcs,
 671                                   new JumpClosure() {
 672                                       public void process(GenerateOopMap c, int bcpDelta, int[] data) {
 673                                         c.markBB(bcpDelta, data);
 674                                       }
 675                                     },
 676                                   null);
 677 


 874       Assert.that(bci>= 0 && bci < method().getCodeSize(), "index out of bounds");
 875     }
 876     if (isBBHeader(bci))
 877       return;
 878 
 879     // FIXME: remove
 880     //    if (TraceNewOopMapGeneration) {
 881     //      tty.print_cr("Basicblock#%d begins at: %d", c._bb_count, bci);
 882     //    }
 883     setBBMarkBit(bci);
 884     _bb_count++;
 885   }
 886 
 887   // Dead code detection
 888   void          markReachableCode() {
 889     final int[] change = new int[1];
 890     change[0] = 1;
 891 
 892     // Mark entry basic block as alive and all exception handlers
 893     _basic_blocks[0].markAsAlive();
 894     TypeArray excps = method().getExceptionTable();
 895     for(int i = 0; i < excps.getLength(); i += 4) {
 896       int handler_pc_idx = i+2;
 897       BasicBlock bb = getBasicBlockAt(excps.getIntAt(handler_pc_idx));
 898       // If block is not already alive (due to multiple exception handlers to same bb), then
 899       // make it alive
 900       if (bb.isDead())
 901         bb.markAsAlive();
 902     }

 903 
 904     BytecodeStream bcs = new BytecodeStream(_method);
 905 
 906     // Iterate through all basic blocks until we reach a fixpoint
 907     while (change[0] != 0) {
 908       change[0] = 0;
 909 
 910       for (int i = 0; i < _bb_count; i++) {
 911         BasicBlock bb = _basic_blocks[i];
 912         if (bb.isAlive()) {
 913           // Position bytecodestream at last bytecode in basicblock
 914           bcs.setStart(bb._end_bci);
 915           bcs.next();
 916           int bytecode = bcs.code();
 917           int bci = bcs.bci();
 918           if (Assert.ASSERTS_ENABLED) {
 919             Assert.that(bci == bb._end_bci, "wrong bci");
 920           }
 921 
 922           boolean fell_through = jumpTargetsDo(bcs, new JumpClosure() {


1451       // assume an exception could be taken here.
1452       if (_monitor_top == 0) {
1453         return;
1454       }
1455       break;
1456 
1457     case Bytecodes._monitorexit:
1458       // If the monitor stack height is bad_monitors, then we have detected a
1459       // monitor matching problem earlier in the analysis.  If the
1460       // monitor stack height is 0, we are about to pop a monitor
1461       // off of an empty stack.  In either case, the bytecode
1462       // could throw an exception.
1463       if (_monitor_top != bad_monitors && _monitor_top != 0) {
1464         return;
1465       }
1466       break;
1467     }
1468 
1469     if (_has_exceptions) {
1470       int bci = itr.bci();
1471       TypeArray exct   = method().getExceptionTable();
1472       for(int i = 0; i< exct.getLength(); i+=4) {
1473         int start_pc   = exct.getIntAt(i);
1474         int end_pc     = exct.getIntAt(i+1);
1475         int handler_pc = exct.getIntAt(i+2);
1476         int catch_type = exct.getIntAt(i+3);
1477 
1478         if (start_pc <= bci && bci < end_pc) {
1479           BasicBlock excBB = getBasicBlockAt(handler_pc);
1480           CellTypeStateList excStk  = excBB.stack();
1481           CellTypeStateList cOpStck = stack();
1482           CellTypeState cOpStck_0 = cOpStck.get(0).copy();
1483           int cOpStackTop = _stack_top;
1484 
1485           // Exception stacks are always the same.
1486           if (Assert.ASSERTS_ENABLED) {
1487             Assert.that(method().getMaxStack() > 0, "sanity check");
1488           }
1489 
1490           // We remembered the size and first element of "cOpStck"
1491           // above; now we temporarily set them to the appropriate
1492           // values for an exception handler.
1493           cOpStck.get(0).set(CellTypeState.makeSlotRef(_max_locals));
1494           _stack_top = 1;
1495 
1496           mergeStateIntoBB(excBB);


2134     _max_locals=0;
2135     _init_vars = null;
2136     _rt = new RetTable();
2137   }
2138 
2139 
2140   // Compute the map.
2141   public void computeMap() {
2142     if (DEBUG) {
2143       System.err.println("*** GenerateOopMap: computing for " +
2144                          method().getMethodHolder().getName().asString() + "." +
2145                          method().getName().asString() +
2146                          method().getSignature().asString());
2147     }
2148 
2149     // Initialize values
2150     _got_error      = false;
2151     _conflict       = false;
2152     _max_locals     = (int) method().getMaxLocals();
2153     _max_stack      = (int) method().getMaxStack();
2154     _has_exceptions = (method().getExceptionTable().getLength() > 0);
2155     _nof_refval_conflicts = 0;
2156     _init_vars      = new ArrayList(5);  // There are seldom more than 5 init_vars
2157     _report_result  = false;
2158     _report_result_for_send = false;
2159     _report_for_exit_bci = -1;
2160     _new_var_map    = null;
2161     //    _ret_adr_tos    = new GrowableArray<intptr_t>(5);  // 5 seems like a good number;
2162     //    _did_rewriting  = false;
2163     //    _did_relocation = false;
2164 
2165     // FIXME: remove
2166     /*
2167     if (TraceNewOopMapGeneration) {
2168       tty.print("Method name: %s\n", method().name().as_C_string());
2169       if (Verbose) {
2170         _method.print_codes();
2171         tty.print_cr("Exception table:");
2172         typeArrayOop excps = method().exception_table();
2173         for(int i = 0; i < excps.length(); i += 4) {
2174           tty.print_cr("[%d - %d] . %d", excps.int_at(i + 0), excps.int_at(i + 1), excps.int_at(i + 2));


   1 /*
   2  * Copyright (c) 2001, 2012, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 634 
 635   // Basicblock info
 636   BasicBlock[]    _basic_blocks;             // Array of basicblock info
 637   int             _gc_points;
 638   int             _bb_count;
 639   BitMap          _bb_hdr_bits;
 640 
 641   // Basicblocks methods
 642   void          initializeBB               () {
 643     _gc_points = 0;
 644     _bb_count  = 0;
 645     _bb_hdr_bits = new BitMap((int) _method.getCodeSize());
 646   }
 647 
 648   void          markBBHeadersAndCountGCPoints() {
 649     initializeBB();
 650 
 651     boolean fellThrough = false;  // False to get first BB marked.
 652 
 653     // First mark all exception handlers as start of a basic-block
 654     if (method().hasExceptionTable()) {
 655       ExceptionTableElement[] excps = method().getExceptionTable();
 656       for(int i = 0; i < excps.length; i++) {
 657         markBB(excps[i].getHandlerPC(), null);
 658       }
 659     }
 660 
 661     // Then iterate through the code
 662     BytecodeStream bcs = new BytecodeStream(_method);
 663     int bytecode;
 664 
 665     while( (bytecode = bcs.next()) >= 0) {
 666       int bci = bcs.bci();
 667 
 668       if (!fellThrough)
 669         markBB(bci, null);
 670 
 671       fellThrough = jumpTargetsDo(bcs,
 672                                   new JumpClosure() {
 673                                       public void process(GenerateOopMap c, int bcpDelta, int[] data) {
 674                                         c.markBB(bcpDelta, data);
 675                                       }
 676                                     },
 677                                   null);
 678 


 875       Assert.that(bci>= 0 && bci < method().getCodeSize(), "index out of bounds");
 876     }
 877     if (isBBHeader(bci))
 878       return;
 879 
 880     // FIXME: remove
 881     //    if (TraceNewOopMapGeneration) {
 882     //      tty.print_cr("Basicblock#%d begins at: %d", c._bb_count, bci);
 883     //    }
 884     setBBMarkBit(bci);
 885     _bb_count++;
 886   }
 887 
 888   // Dead code detection
 889   void          markReachableCode() {
 890     final int[] change = new int[1];
 891     change[0] = 1;
 892 
 893     // Mark entry basic block as alive and all exception handlers
 894     _basic_blocks[0].markAsAlive();
 895     if (method().hasExceptionTable()) {
 896       ExceptionTableElement[] excps = method().getExceptionTable();
 897       for(int i = 0; i < excps.length; i ++) {
 898         BasicBlock bb = getBasicBlockAt(excps[i].getHandlerPC());
 899         // If block is not already alive (due to multiple exception handlers to same bb), then
 900         // make it alive
 901         if (bb.isDead())
 902           bb.markAsAlive();
 903       }
 904     }
 905 
 906     BytecodeStream bcs = new BytecodeStream(_method);
 907 
 908     // Iterate through all basic blocks until we reach a fixpoint
 909     while (change[0] != 0) {
 910       change[0] = 0;
 911 
 912       for (int i = 0; i < _bb_count; i++) {
 913         BasicBlock bb = _basic_blocks[i];
 914         if (bb.isAlive()) {
 915           // Position bytecodestream at last bytecode in basicblock
 916           bcs.setStart(bb._end_bci);
 917           bcs.next();
 918           int bytecode = bcs.code();
 919           int bci = bcs.bci();
 920           if (Assert.ASSERTS_ENABLED) {
 921             Assert.that(bci == bb._end_bci, "wrong bci");
 922           }
 923 
 924           boolean fell_through = jumpTargetsDo(bcs, new JumpClosure() {


1453       // assume an exception could be taken here.
1454       if (_monitor_top == 0) {
1455         return;
1456       }
1457       break;
1458 
1459     case Bytecodes._monitorexit:
1460       // If the monitor stack height is bad_monitors, then we have detected a
1461       // monitor matching problem earlier in the analysis.  If the
1462       // monitor stack height is 0, we are about to pop a monitor
1463       // off of an empty stack.  In either case, the bytecode
1464       // could throw an exception.
1465       if (_monitor_top != bad_monitors && _monitor_top != 0) {
1466         return;
1467       }
1468       break;
1469     }
1470 
1471     if (_has_exceptions) {
1472       int bci = itr.bci();
1473       ExceptionTableElement[] exct   = method().getExceptionTable();
1474       for(int i = 0; i< exct.length; i++) {
1475         int start_pc   = exct[i].getStartPC();
1476         int end_pc     = exct[i].getEndPC();
1477         int handler_pc = exct[i].getHandlerPC();
1478         int catch_type = exct[i].getCatchTypeIndex();
1479 
1480         if (start_pc <= bci && bci < end_pc) {
1481           BasicBlock excBB = getBasicBlockAt(handler_pc);
1482           CellTypeStateList excStk  = excBB.stack();
1483           CellTypeStateList cOpStck = stack();
1484           CellTypeState cOpStck_0 = cOpStck.get(0).copy();
1485           int cOpStackTop = _stack_top;
1486 
1487           // Exception stacks are always the same.
1488           if (Assert.ASSERTS_ENABLED) {
1489             Assert.that(method().getMaxStack() > 0, "sanity check");
1490           }
1491 
1492           // We remembered the size and first element of "cOpStck"
1493           // above; now we temporarily set them to the appropriate
1494           // values for an exception handler.
1495           cOpStck.get(0).set(CellTypeState.makeSlotRef(_max_locals));
1496           _stack_top = 1;
1497 
1498           mergeStateIntoBB(excBB);


2136     _max_locals=0;
2137     _init_vars = null;
2138     _rt = new RetTable();
2139   }
2140 
2141 
2142   // Compute the map.
2143   public void computeMap() {
2144     if (DEBUG) {
2145       System.err.println("*** GenerateOopMap: computing for " +
2146                          method().getMethodHolder().getName().asString() + "." +
2147                          method().getName().asString() +
2148                          method().getSignature().asString());
2149     }
2150 
2151     // Initialize values
2152     _got_error      = false;
2153     _conflict       = false;
2154     _max_locals     = (int) method().getMaxLocals();
2155     _max_stack      = (int) method().getMaxStack();
2156     _has_exceptions = (method().hasExceptionTable());
2157     _nof_refval_conflicts = 0;
2158     _init_vars      = new ArrayList(5);  // There are seldom more than 5 init_vars
2159     _report_result  = false;
2160     _report_result_for_send = false;
2161     _report_for_exit_bci = -1;
2162     _new_var_map    = null;
2163     //    _ret_adr_tos    = new GrowableArray<intptr_t>(5);  // 5 seems like a good number;
2164     //    _did_rewriting  = false;
2165     //    _did_relocation = false;
2166 
2167     // FIXME: remove
2168     /*
2169     if (TraceNewOopMapGeneration) {
2170       tty.print("Method name: %s\n", method().name().as_C_string());
2171       if (Verbose) {
2172         _method.print_codes();
2173         tty.print_cr("Exception table:");
2174         typeArrayOop excps = method().exception_table();
2175         for(int i = 0; i < excps.length(); i += 4) {
2176           tty.print_cr("[%d - %d] . %d", excps.int_at(i + 0), excps.int_at(i + 1), excps.int_at(i + 2));