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));
|