6614597: Performance variability in jvm2008 xml.validation

Mon, 01 Feb 2010 16:49:49 -0800

author
kvn
date
Mon, 01 Feb 2010 16:49:49 -0800
changeset 1641
87684f1a88b5
parent 1640
5fcfaa1ad96f
child 1642
74c848d437ab

6614597: Performance variability in jvm2008 xml.validation
Summary: Fix incorrect marking of methods as not compilable.
Reviewed-by: never

src/cpu/sparc/vm/interp_masm_sparc.cpp file | annotate | diff | comparison | revisions
src/cpu/sparc/vm/interp_masm_sparc.hpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/c1_LIRAssembler_x86.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/interp_masm_x86_32.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/interp_masm_x86_32.hpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/interp_masm_x86_64.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/interp_masm_x86_64.hpp file | annotate | diff | comparison | revisions
src/share/vm/ci/ciMethod.cpp file | annotate | diff | comparison | revisions
src/share/vm/code/dependencies.cpp file | annotate | diff | comparison | revisions
src/share/vm/code/nmethod.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/methodDataOop.hpp file | annotate | diff | comparison | revisions
src/share/vm/oops/methodOop.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/doCall.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/parseHelper.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/runtime.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/deoptimization.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/deoptimization.hpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/globals.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/cpu/sparc/vm/interp_masm_sparc.cpp	Mon Feb 01 23:18:47 2010 +0100
     1.2 +++ b/src/cpu/sparc/vm/interp_masm_sparc.cpp	Mon Feb 01 16:49:49 2010 -0800
     1.3 @@ -1681,11 +1681,8 @@
     1.4      // If no method data exists, go to profile_continue.
     1.5      test_method_data_pointer(profile_continue);
     1.6  
     1.7 -    // We are making a call.  Increment the count.
     1.8 -    increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch);
     1.9 -
    1.10      // Record the receiver type.
    1.11 -    record_klass_in_profile(receiver, scratch);
    1.12 +    record_klass_in_profile(receiver, scratch, true);
    1.13  
    1.14      // The method data pointer needs to be updated to reflect the new target.
    1.15      update_mdp_by_constant(in_bytes(VirtualCallData::virtual_call_data_size()));
    1.16 @@ -1695,9 +1692,13 @@
    1.17  
    1.18  void InterpreterMacroAssembler::record_klass_in_profile_helper(
    1.19                                          Register receiver, Register scratch,
    1.20 -                                        int start_row, Label& done) {
    1.21 -  if (TypeProfileWidth == 0)
    1.22 +                                        int start_row, Label& done, bool is_virtual_call) {
    1.23 +  if (TypeProfileWidth == 0) {
    1.24 +    if (is_virtual_call) {
    1.25 +      increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch);
    1.26 +    }
    1.27      return;
    1.28 +  }
    1.29  
    1.30    int last_row = VirtualCallData::row_limit() - 1;
    1.31    assert(start_row <= last_row, "must be work left to do");
    1.32 @@ -1714,6 +1715,7 @@
    1.33      // See if the receiver is receiver[n].
    1.34      int recvr_offset = in_bytes(VirtualCallData::receiver_offset(row));
    1.35      test_mdp_data_at(recvr_offset, receiver, next_test, scratch);
    1.36 +    // delayed()->tst(scratch);
    1.37  
    1.38      // The receiver is receiver[n].  Increment count[n].
    1.39      int count_offset = in_bytes(VirtualCallData::receiver_count_offset(row));
    1.40 @@ -1723,20 +1725,31 @@
    1.41      bind(next_test);
    1.42  
    1.43      if (test_for_null_also) {
    1.44 +      Label found_null;
    1.45        // Failed the equality check on receiver[n]...  Test for null.
    1.46        if (start_row == last_row) {
    1.47          // The only thing left to do is handle the null case.
    1.48 -        brx(Assembler::notZero, false, Assembler::pt, done);
    1.49 -        delayed()->nop();
    1.50 +        if (is_virtual_call) {
    1.51 +          brx(Assembler::zero, false, Assembler::pn, found_null);
    1.52 +          delayed()->nop();
    1.53 +          // Receiver did not match any saved receiver and there is no empty row for it.
    1.54 +          // Increment total counter to indicate polimorphic case.
    1.55 +          increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch);
    1.56 +          ba(false, done);
    1.57 +          delayed()->nop();
    1.58 +          bind(found_null);
    1.59 +        } else {
    1.60 +          brx(Assembler::notZero, false, Assembler::pt, done);
    1.61 +          delayed()->nop();
    1.62 +        }
    1.63          break;
    1.64        }
    1.65        // Since null is rare, make it be the branch-taken case.
    1.66 -      Label found_null;
    1.67        brx(Assembler::zero, false, Assembler::pn, found_null);
    1.68        delayed()->nop();
    1.69  
    1.70        // Put all the "Case 3" tests here.
    1.71 -      record_klass_in_profile_helper(receiver, scratch, start_row + 1, done);
    1.72 +      record_klass_in_profile_helper(receiver, scratch, start_row + 1, done, is_virtual_call);
    1.73  
    1.74        // Found a null.  Keep searching for a matching receiver,
    1.75        // but remember that this is an empty (unused) slot.
    1.76 @@ -1753,16 +1766,18 @@
    1.77    int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row));
    1.78    mov(DataLayout::counter_increment, scratch);
    1.79    set_mdp_data_at(count_offset, scratch);
    1.80 -  ba(false, done);
    1.81 -  delayed()->nop();
    1.82 +  if (start_row > 0) {
    1.83 +    ba(false, done);
    1.84 +    delayed()->nop();
    1.85 +  }
    1.86  }
    1.87  
    1.88  void InterpreterMacroAssembler::record_klass_in_profile(Register receiver,
    1.89 -                                                        Register scratch) {
    1.90 +                                                        Register scratch, bool is_virtual_call) {
    1.91    assert(ProfileInterpreter, "must be profiling");
    1.92    Label done;
    1.93  
    1.94 -  record_klass_in_profile_helper(receiver, scratch, 0, done);
    1.95 +  record_klass_in_profile_helper(receiver, scratch, 0, done, is_virtual_call);
    1.96  
    1.97    bind (done);
    1.98  }
    1.99 @@ -1840,7 +1855,7 @@
   1.100        mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size());
   1.101  
   1.102        // Record the object type.
   1.103 -      record_klass_in_profile(klass, scratch);
   1.104 +      record_klass_in_profile(klass, scratch, false);
   1.105      }
   1.106  
   1.107      // The method data pointer needs to be updated.
     2.1 --- a/src/cpu/sparc/vm/interp_masm_sparc.hpp	Mon Feb 01 23:18:47 2010 +0100
     2.2 +++ b/src/cpu/sparc/vm/interp_masm_sparc.hpp	Mon Feb 01 16:49:49 2010 -0800
     2.3 @@ -290,9 +290,9 @@
     2.4    void test_mdp_data_at(int offset, Register value, Label& not_equal_continue,
     2.5                          Register scratch);
     2.6  
     2.7 -  void record_klass_in_profile(Register receiver, Register scratch);
     2.8 +  void record_klass_in_profile(Register receiver, Register scratch, bool is_virtual_call);
     2.9    void record_klass_in_profile_helper(Register receiver, Register scratch,
    2.10 -                                      int start_row, Label& done);
    2.11 +                                      int start_row, Label& done, bool is_virtual_call);
    2.12  
    2.13    void update_mdp_by_offset(int offset_of_disp, Register scratch);
    2.14    void update_mdp_by_offset(Register reg, int offset_of_disp,
     3.1 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Mon Feb 01 23:18:47 2010 +0100
     3.2 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Mon Feb 01 16:49:49 2010 -0800
     3.3 @@ -3209,7 +3209,6 @@
     3.4    Register mdo  = op->mdo()->as_register();
     3.5    __ movoop(mdo, md->constant_encoding());
     3.6    Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));
     3.7 -  __ addl(counter_addr, DataLayout::counter_increment);
     3.8    Bytecodes::Code bc = method->java_code_at_bci(bci);
     3.9    // Perform additional virtual call profiling for invokevirtual and
    3.10    // invokeinterface bytecodes
    3.11 @@ -3276,14 +3275,18 @@
    3.12          __ jcc(Assembler::notEqual, next_test);
    3.13          __ movptr(recv_addr, recv);
    3.14          __ movl(Address(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))), DataLayout::counter_increment);
    3.15 -        if (i < (VirtualCallData::row_limit() - 1)) {
    3.16 -          __ jmp(update_done);
    3.17 -        }
    3.18 +        __ jmp(update_done);
    3.19          __ bind(next_test);
    3.20        }
    3.21 +      // Receiver did not match any saved receiver and there is no empty row for it.
    3.22 +      // Increment total counter to indicate polimorphic case.
    3.23 +      __ addl(counter_addr, DataLayout::counter_increment);
    3.24  
    3.25        __ bind(update_done);
    3.26      }
    3.27 +  } else {
    3.28 +    // Static call
    3.29 +    __ addl(counter_addr, DataLayout::counter_increment);
    3.30    }
    3.31  }
    3.32  
     4.1 --- a/src/cpu/x86/vm/interp_masm_x86_32.cpp	Mon Feb 01 23:18:47 2010 +0100
     4.2 +++ b/src/cpu/x86/vm/interp_masm_x86_32.cpp	Mon Feb 01 16:49:49 2010 -0800
     4.3 @@ -1239,17 +1239,19 @@
     4.4      // If no method data exists, go to profile_continue.
     4.5      test_method_data_pointer(mdp, profile_continue);
     4.6  
     4.7 -    // We are making a call.  Increment the count.
     4.8 -    increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
     4.9 -
    4.10      Label skip_receiver_profile;
    4.11      if (receiver_can_be_null) {
    4.12 +      Label not_null;
    4.13        testptr(receiver, receiver);
    4.14 -      jcc(Assembler::zero, skip_receiver_profile);
    4.15 +      jccb(Assembler::notZero, not_null);
    4.16 +      // We are making a call.  Increment the count for null receiver.
    4.17 +      increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
    4.18 +      jmp(skip_receiver_profile);
    4.19 +      bind(not_null);
    4.20      }
    4.21  
    4.22      // Record the receiver type.
    4.23 -    record_klass_in_profile(receiver, mdp, reg2);
    4.24 +    record_klass_in_profile(receiver, mdp, reg2, true);
    4.25      bind(skip_receiver_profile);
    4.26  
    4.27      // The method data pointer needs to be updated to reflect the new target.
    4.28 @@ -1263,10 +1265,14 @@
    4.29  
    4.30  void InterpreterMacroAssembler::record_klass_in_profile_helper(
    4.31                                          Register receiver, Register mdp,
    4.32 -                                        Register reg2,
    4.33 -                                        int start_row, Label& done) {
    4.34 -  if (TypeProfileWidth == 0)
    4.35 +                                        Register reg2, int start_row,
    4.36 +                                        Label& done, bool is_virtual_call) {
    4.37 +  if (TypeProfileWidth == 0) {
    4.38 +    if (is_virtual_call) {
    4.39 +      increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
    4.40 +    }
    4.41      return;
    4.42 +  }
    4.43  
    4.44    int last_row = VirtualCallData::row_limit() - 1;
    4.45    assert(start_row <= last_row, "must be work left to do");
    4.46 @@ -1294,19 +1300,28 @@
    4.47      bind(next_test);
    4.48  
    4.49      if (row == start_row) {
    4.50 +      Label found_null;
    4.51        // Failed the equality check on receiver[n]...  Test for null.
    4.52        testptr(reg2, reg2);
    4.53        if (start_row == last_row) {
    4.54          // The only thing left to do is handle the null case.
    4.55 -        jcc(Assembler::notZero, done);
    4.56 +        if (is_virtual_call) {
    4.57 +          jccb(Assembler::zero, found_null);
    4.58 +          // Receiver did not match any saved receiver and there is no empty row for it.
    4.59 +          // Increment total counter to indicate polimorphic case.
    4.60 +          increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
    4.61 +          jmp(done);
    4.62 +          bind(found_null);
    4.63 +        } else {
    4.64 +          jcc(Assembler::notZero, done);
    4.65 +        }
    4.66          break;
    4.67        }
    4.68        // Since null is rare, make it be the branch-taken case.
    4.69 -      Label found_null;
    4.70        jcc(Assembler::zero, found_null);
    4.71  
    4.72        // Put all the "Case 3" tests here.
    4.73 -      record_klass_in_profile_helper(receiver, mdp, reg2, start_row + 1, done);
    4.74 +      record_klass_in_profile_helper(receiver, mdp, reg2, start_row + 1, done, is_virtual_call);
    4.75  
    4.76        // Found a null.  Keep searching for a matching receiver,
    4.77        // but remember that this is an empty (unused) slot.
    4.78 @@ -1323,16 +1338,18 @@
    4.79    int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row));
    4.80    movptr(reg2, (int32_t)DataLayout::counter_increment);
    4.81    set_mdp_data_at(mdp, count_offset, reg2);
    4.82 -  jmp(done);
    4.83 +  if (start_row > 0) {
    4.84 +    jmp(done);
    4.85 +  }
    4.86  }
    4.87  
    4.88  void InterpreterMacroAssembler::record_klass_in_profile(Register receiver,
    4.89 -                                                        Register mdp,
    4.90 -                                                        Register reg2) {
    4.91 +                                                        Register mdp, Register reg2,
    4.92 +                                                        bool is_virtual_call) {
    4.93    assert(ProfileInterpreter, "must be profiling");
    4.94    Label done;
    4.95  
    4.96 -  record_klass_in_profile_helper(receiver, mdp, reg2, 0, done);
    4.97 +  record_klass_in_profile_helper(receiver, mdp, reg2, 0, done, is_virtual_call);
    4.98  
    4.99    bind (done);
   4.100  }
   4.101 @@ -1425,7 +1442,7 @@
   4.102        mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size());
   4.103  
   4.104        // Record the object type.
   4.105 -      record_klass_in_profile(klass, mdp, reg2);
   4.106 +      record_klass_in_profile(klass, mdp, reg2, false);
   4.107        assert(reg2 == rdi, "we know how to fix this blown reg");
   4.108        restore_locals();         // Restore EDI
   4.109      }
     5.1 --- a/src/cpu/x86/vm/interp_masm_x86_32.hpp	Mon Feb 01 23:18:47 2010 +0100
     5.2 +++ b/src/cpu/x86/vm/interp_masm_x86_32.hpp	Mon Feb 01 16:49:49 2010 -0800
     5.3 @@ -213,10 +213,10 @@
     5.4                          Label& not_equal_continue);
     5.5  
     5.6    void record_klass_in_profile(Register receiver, Register mdp,
     5.7 -                               Register reg2);
     5.8 +                               Register reg2, bool is_virtual_call);
     5.9    void record_klass_in_profile_helper(Register receiver, Register mdp,
    5.10 -                                      Register reg2,
    5.11 -                                      int start_row, Label& done);
    5.12 +                                      Register reg2, int start_row,
    5.13 +                                      Label& done, bool is_virtual_call);
    5.14  
    5.15    void update_mdp_by_offset(Register mdp_in, int offset_of_offset);
    5.16    void update_mdp_by_offset(Register mdp_in, Register reg, int offset_of_disp);
     6.1 --- a/src/cpu/x86/vm/interp_masm_x86_64.cpp	Mon Feb 01 23:18:47 2010 +0100
     6.2 +++ b/src/cpu/x86/vm/interp_masm_x86_64.cpp	Mon Feb 01 16:49:49 2010 -0800
     6.3 @@ -1262,17 +1262,19 @@
     6.4      // If no method data exists, go to profile_continue.
     6.5      test_method_data_pointer(mdp, profile_continue);
     6.6  
     6.7 -    // We are making a call.  Increment the count.
     6.8 -    increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
     6.9 -
    6.10      Label skip_receiver_profile;
    6.11      if (receiver_can_be_null) {
    6.12 +      Label not_null;
    6.13        testptr(receiver, receiver);
    6.14 -      jcc(Assembler::zero, skip_receiver_profile);
    6.15 +      jccb(Assembler::notZero, not_null);
    6.16 +      // We are making a call.  Increment the count for null receiver.
    6.17 +      increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
    6.18 +      jmp(skip_receiver_profile);
    6.19 +      bind(not_null);
    6.20      }
    6.21  
    6.22      // Record the receiver type.
    6.23 -    record_klass_in_profile(receiver, mdp, reg2);
    6.24 +    record_klass_in_profile(receiver, mdp, reg2, true);
    6.25      bind(skip_receiver_profile);
    6.26  
    6.27      // The method data pointer needs to be updated to reflect the new target.
    6.28 @@ -1296,10 +1298,14 @@
    6.29  // See below for example code.
    6.30  void InterpreterMacroAssembler::record_klass_in_profile_helper(
    6.31                                          Register receiver, Register mdp,
    6.32 -                                        Register reg2,
    6.33 -                                        int start_row, Label& done) {
    6.34 -  if (TypeProfileWidth == 0)
    6.35 +                                        Register reg2, int start_row,
    6.36 +                                        Label& done, bool is_virtual_call) {
    6.37 +  if (TypeProfileWidth == 0) {
    6.38 +    if (is_virtual_call) {
    6.39 +      increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
    6.40 +    }
    6.41      return;
    6.42 +  }
    6.43  
    6.44    int last_row = VirtualCallData::row_limit() - 1;
    6.45    assert(start_row <= last_row, "must be work left to do");
    6.46 @@ -1327,19 +1333,28 @@
    6.47      bind(next_test);
    6.48  
    6.49      if (test_for_null_also) {
    6.50 +      Label found_null;
    6.51        // Failed the equality check on receiver[n]...  Test for null.
    6.52        testptr(reg2, reg2);
    6.53        if (start_row == last_row) {
    6.54          // The only thing left to do is handle the null case.
    6.55 -        jcc(Assembler::notZero, done);
    6.56 +        if (is_virtual_call) {
    6.57 +          jccb(Assembler::zero, found_null);
    6.58 +          // Receiver did not match any saved receiver and there is no empty row for it.
    6.59 +          // Increment total counter to indicate polimorphic case.
    6.60 +          increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
    6.61 +          jmp(done);
    6.62 +          bind(found_null);
    6.63 +        } else {
    6.64 +          jcc(Assembler::notZero, done);
    6.65 +        }
    6.66          break;
    6.67        }
    6.68        // Since null is rare, make it be the branch-taken case.
    6.69 -      Label found_null;
    6.70        jcc(Assembler::zero, found_null);
    6.71  
    6.72        // Put all the "Case 3" tests here.
    6.73 -      record_klass_in_profile_helper(receiver, mdp, reg2, start_row + 1, done);
    6.74 +      record_klass_in_profile_helper(receiver, mdp, reg2, start_row + 1, done, is_virtual_call);
    6.75  
    6.76        // Found a null.  Keep searching for a matching receiver,
    6.77        // but remember that this is an empty (unused) slot.
    6.78 @@ -1356,7 +1371,9 @@
    6.79    int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row));
    6.80    movl(reg2, DataLayout::counter_increment);
    6.81    set_mdp_data_at(mdp, count_offset, reg2);
    6.82 -  jmp(done);
    6.83 +  if (start_row > 0) {
    6.84 +    jmp(done);
    6.85 +  }
    6.86  }
    6.87  
    6.88  // Example state machine code for three profile rows:
    6.89 @@ -1368,7 +1385,7 @@
    6.90  //     if (row[1].rec != NULL) {
    6.91  //       // degenerate decision tree, rooted at row[2]
    6.92  //       if (row[2].rec == rec) { row[2].incr(); goto done; }
    6.93 -//       if (row[2].rec != NULL) { goto done; } // overflow
    6.94 +//       if (row[2].rec != NULL) { count.incr(); goto done; } // overflow
    6.95  //       row[2].init(rec); goto done;
    6.96  //     } else {
    6.97  //       // remember row[1] is empty
    6.98 @@ -1381,14 +1398,15 @@
    6.99  //     if (row[2].rec == rec) { row[2].incr(); goto done; }
   6.100  //     row[0].init(rec); goto done;
   6.101  //   }
   6.102 +//   done:
   6.103  
   6.104  void InterpreterMacroAssembler::record_klass_in_profile(Register receiver,
   6.105 -                                                        Register mdp,
   6.106 -                                                        Register reg2) {
   6.107 +                                                        Register mdp, Register reg2,
   6.108 +                                                        bool is_virtual_call) {
   6.109    assert(ProfileInterpreter, "must be profiling");
   6.110    Label done;
   6.111  
   6.112 -  record_klass_in_profile_helper(receiver, mdp, reg2, 0, done);
   6.113 +  record_klass_in_profile_helper(receiver, mdp, reg2, 0, done, is_virtual_call);
   6.114  
   6.115    bind (done);
   6.116  }
   6.117 @@ -1484,7 +1502,7 @@
   6.118        mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size());
   6.119  
   6.120        // Record the object type.
   6.121 -      record_klass_in_profile(klass, mdp, reg2);
   6.122 +      record_klass_in_profile(klass, mdp, reg2, false);
   6.123      }
   6.124      update_mdp_by_constant(mdp, mdp_delta);
   6.125  
     7.1 --- a/src/cpu/x86/vm/interp_masm_x86_64.hpp	Mon Feb 01 23:18:47 2010 +0100
     7.2 +++ b/src/cpu/x86/vm/interp_masm_x86_64.hpp	Mon Feb 01 16:49:49 2010 -0800
     7.3 @@ -222,10 +222,10 @@
     7.4                          Label& not_equal_continue);
     7.5  
     7.6    void record_klass_in_profile(Register receiver, Register mdp,
     7.7 -                               Register reg2);
     7.8 +                               Register reg2, bool is_virtual_call);
     7.9    void record_klass_in_profile_helper(Register receiver, Register mdp,
    7.10 -                                      Register reg2,
    7.11 -                                      int start_row, Label& done);
    7.12 +                                      Register reg2, int start_row,
    7.13 +                                      Label& done, bool is_virtual_call);
    7.14  
    7.15    void update_mdp_by_offset(Register mdp_in, int offset_of_offset);
    7.16    void update_mdp_by_offset(Register mdp_in, Register reg, int offset_of_disp);
     8.1 --- a/src/share/vm/ci/ciMethod.cpp	Mon Feb 01 23:18:47 2010 +0100
     8.2 +++ b/src/share/vm/ci/ciMethod.cpp	Mon Feb 01 16:49:49 2010 -0800
     8.3 @@ -436,15 +436,20 @@
     8.4            // we will set result._method also.
     8.5          }
     8.6          // Determine call site's morphism.
     8.7 -        // The call site count could be == (receivers_count_total + 1)
     8.8 -        // not only in the case of a polymorphic call but also in the case
     8.9 -        // when a method data snapshot is taken after the site count was updated
    8.10 -        // but before receivers counters were updated.
    8.11 -        if (morphism == result._limit) {
    8.12 -           // There were no array klasses and morphism <= MorphismLimit.
    8.13 -           if (morphism <  ciCallProfile::MorphismLimit ||
    8.14 -               morphism == ciCallProfile::MorphismLimit &&
    8.15 -               (receivers_count_total+1) >= count) {
    8.16 +        // The call site count is 0 with known morphism (onlt 1 or 2 receivers)
    8.17 +        // or < 0 in the case of a type check failured for checkcast, aastore, instanceof.
    8.18 +        // The call site count is > 0 in the case of a polymorphic virtual call.
    8.19 +        if (morphism > 0 && morphism == result._limit) {
    8.20 +           // The morphism <= MorphismLimit.
    8.21 +           if ((morphism <  ciCallProfile::MorphismLimit) ||
    8.22 +               (morphism == ciCallProfile::MorphismLimit && count == 0)) {
    8.23 +#ifdef ASSERT
    8.24 +             if (count > 0) {
    8.25 +               tty->print_cr("bci: %d", bci);
    8.26 +               this->print_codes();
    8.27 +               assert(false, "this call site should not be polymorphic");
    8.28 +             }
    8.29 +#endif
    8.30               result._morphism = morphism;
    8.31             }
    8.32          }
    8.33 @@ -452,10 +457,8 @@
    8.34          // zero or less, presume that this is a typecheck profile and
    8.35          // do nothing.  Otherwise, increase count to be the sum of all
    8.36          // receiver's counts.
    8.37 -        if (count > 0) {
    8.38 -          if (count < receivers_count_total) {
    8.39 -            count = receivers_count_total;
    8.40 -          }
    8.41 +        if (count >= 0) {
    8.42 +          count += receivers_count_total;
    8.43          }
    8.44        }
    8.45        result._count = count;
     9.1 --- a/src/share/vm/code/dependencies.cpp	Mon Feb 01 23:18:47 2010 +0100
     9.2 +++ b/src/share/vm/code/dependencies.cpp	Mon Feb 01 16:49:49 2010 -0800
     9.3 @@ -843,13 +843,15 @@
     9.4      if (occasional_print || final_stats) {
     9.5        // Every now and then dump a little info about dependency searching.
     9.6        if (xtty != NULL) {
     9.7 -        xtty->elem("deps_find_witness calls='%d' steps='%d' recursions='%d' singles='%d'",
     9.8 +       ttyLocker ttyl;
     9.9 +       xtty->elem("deps_find_witness calls='%d' steps='%d' recursions='%d' singles='%d'",
    9.10                     deps_find_witness_calls,
    9.11                     deps_find_witness_steps,
    9.12                     deps_find_witness_recursions,
    9.13                     deps_find_witness_singles);
    9.14        }
    9.15        if (final_stats || (TraceDependencies && WizardMode)) {
    9.16 +        ttyLocker ttyl;
    9.17          tty->print_cr("Dependency check (find_witness) "
    9.18                        "calls=%d, steps=%d (avg=%.1f), recursions=%d, singles=%d",
    9.19                        deps_find_witness_calls,
    10.1 --- a/src/share/vm/code/nmethod.cpp	Mon Feb 01 23:18:47 2010 +0100
    10.2 +++ b/src/share/vm/code/nmethod.cpp	Mon Feb 01 16:49:49 2010 -0800
    10.3 @@ -1117,7 +1117,6 @@
    10.4      if (_method->code() == this) {
    10.5        _method->clear_code(); // Break a cycle
    10.6      }
    10.7 -    inc_decompile_count();     // Last chance to make a mark on the MDO
    10.8      _method = NULL;            // Clear the method of this dead nmethod
    10.9    }
   10.10    // Make the class unloaded - i.e., change state and notify sweeper
   10.11 @@ -1177,15 +1176,17 @@
   10.12  bool nmethod::make_not_entrant_or_zombie(unsigned int state) {
   10.13    assert(state == zombie || state == not_entrant, "must be zombie or not_entrant");
   10.14  
   10.15 -  // If the method is already zombie there is nothing to do
   10.16 -  if (is_zombie()) {
   10.17 -    return false;
   10.18 -  }
   10.19 +  bool was_alive = false;
   10.20  
   10.21    // Make sure the nmethod is not flushed in case of a safepoint in code below.
   10.22    nmethodLocker nml(this);
   10.23  
   10.24    {
   10.25 +    // If the method is already zombie there is nothing to do
   10.26 +    if (is_zombie()) {
   10.27 +      return false;
   10.28 +    }
   10.29 +
   10.30      // invalidate osr nmethod before acquiring the patching lock since
   10.31      // they both acquire leaf locks and we don't want a deadlock.
   10.32      // This logic is equivalent to the logic below for patching the
   10.33 @@ -1223,6 +1224,8 @@
   10.34        assert(state == not_entrant, "other cases may need to be handled differently");
   10.35      }
   10.36  
   10.37 +    was_alive = is_in_use(); // Read state under lock
   10.38 +
   10.39      // Change state
   10.40      flags.state = state;
   10.41  
   10.42 @@ -1249,8 +1252,11 @@
   10.43      mark_as_seen_on_stack();
   10.44    }
   10.45  
   10.46 -  // It's a true state change, so mark the method as decompiled.
   10.47 -  inc_decompile_count();
   10.48 +  if (was_alive) {
   10.49 +    // It's a true state change, so mark the method as decompiled.
   10.50 +    // Do it only for transition from alive.
   10.51 +    inc_decompile_count();
   10.52 +  }
   10.53  
   10.54    // zombie only - if a JVMTI agent has enabled the CompiledMethodUnload event
   10.55    // and it hasn't already been reported for this nmethod then report it now.
    11.1 --- a/src/share/vm/oops/methodDataOop.hpp	Mon Feb 01 23:18:47 2010 +0100
    11.2 +++ b/src/share/vm/oops/methodDataOop.hpp	Mon Feb 01 16:49:49 2010 -0800
    11.3 @@ -1391,6 +1391,9 @@
    11.4    }
    11.5    void inc_decompile_count() {
    11.6      _nof_decompiles += 1;
    11.7 +    if (decompile_count() > (uint)PerMethodRecompilationCutoff) {
    11.8 +      method()->set_not_compilable();
    11.9 +    }
   11.10    }
   11.11  
   11.12    // Support for code generation
    12.1 --- a/src/share/vm/oops/methodOop.cpp	Mon Feb 01 23:18:47 2010 +0100
    12.2 +++ b/src/share/vm/oops/methodOop.cpp	Mon Feb 01 16:49:49 2010 -0800
    12.3 @@ -575,12 +575,6 @@
    12.4      return true;
    12.5    }
    12.6  
    12.7 -  methodDataOop mdo = method_data();
    12.8 -  if (mdo != NULL
    12.9 -      && (uint)mdo->decompile_count() > (uint)PerMethodRecompilationCutoff) {
   12.10 -    // Since (uint)-1 is large, -1 really means 'no cutoff'.
   12.11 -    return true;
   12.12 -  }
   12.13  #ifdef COMPILER2
   12.14    if (is_tier1_compile(comp_level)) {
   12.15      if (is_not_tier1_compilable()) {
   12.16 @@ -594,6 +588,15 @@
   12.17  
   12.18  // call this when compiler finds that this method is not compilable
   12.19  void methodOopDesc::set_not_compilable(int comp_level) {
   12.20 +  if (PrintCompilation) {
   12.21 +    ttyLocker ttyl;
   12.22 +    tty->print("made not compilable ");
   12.23 +    this->print_short_name(tty);
   12.24 +    int size = this->code_size();
   12.25 +    if (size > 0)
   12.26 +      tty->print(" (%d bytes)", size);
   12.27 +    tty->cr();
   12.28 +  }
   12.29    if ((TraceDeoptimization || LogCompilation) && (xtty != NULL)) {
   12.30      ttyLocker ttyl;
   12.31      xtty->begin_elem("make_not_compilable thread='%d'", (int) os::current_thread_id());
    13.1 --- a/src/share/vm/opto/doCall.cpp	Mon Feb 01 23:18:47 2010 +0100
    13.2 +++ b/src/share/vm/opto/doCall.cpp	Mon Feb 01 16:49:49 2010 -0800
    13.3 @@ -182,26 +182,16 @@
    13.4              }
    13.5            }
    13.6            CallGenerator* miss_cg;
    13.7 +          Deoptimization::DeoptReason reason = (profile.morphism() == 2) ?
    13.8 +                                    Deoptimization::Reason_bimorphic :
    13.9 +                                    Deoptimization::Reason_class_check;
   13.10            if (( profile.morphism() == 1 ||
   13.11                 (profile.morphism() == 2 && next_hit_cg != NULL) ) &&
   13.12 -
   13.13 -              !too_many_traps(Deoptimization::Reason_class_check)
   13.14 -
   13.15 -              // Check only total number of traps per method to allow
   13.16 -              // the transition from monomorphic to bimorphic case between
   13.17 -              // compilations without falling into virtual call.
   13.18 -              // A monomorphic case may have the class_check trap flag is set
   13.19 -              // due to the time gap between the uncommon trap processing
   13.20 -              // when flags are set in MDO and the call site bytecode execution
   13.21 -              // in Interpreter when MDO counters are updated.
   13.22 -              // There was also class_check trap in monomorphic case due to
   13.23 -              // the bug 6225440.
   13.24 -
   13.25 +              !too_many_traps(jvms->method(), jvms->bci(), reason)
   13.26               ) {
   13.27              // Generate uncommon trap for class check failure path
   13.28              // in case of monomorphic or bimorphic virtual call site.
   13.29 -            miss_cg = CallGenerator::for_uncommon_trap(call_method,
   13.30 -                        Deoptimization::Reason_class_check,
   13.31 +            miss_cg = CallGenerator::for_uncommon_trap(call_method, reason,
   13.32                          Deoptimization::Action_maybe_recompile);
   13.33            } else {
   13.34              // Generate virtual call for class check failure path
    14.1 --- a/src/share/vm/opto/parseHelper.cpp	Mon Feb 01 23:18:47 2010 +0100
    14.2 +++ b/src/share/vm/opto/parseHelper.cpp	Mon Feb 01 16:49:49 2010 -0800
    14.3 @@ -414,8 +414,6 @@
    14.4  void Parse::profile_call(Node* receiver) {
    14.5    if (!method_data_update()) return;
    14.6  
    14.7 -  profile_generic_call();
    14.8 -
    14.9    switch (bc()) {
   14.10    case Bytecodes::_invokevirtual:
   14.11    case Bytecodes::_invokeinterface:
   14.12 @@ -424,6 +422,7 @@
   14.13    case Bytecodes::_invokestatic:
   14.14    case Bytecodes::_invokedynamic:
   14.15    case Bytecodes::_invokespecial:
   14.16 +    profile_generic_call();
   14.17      break;
   14.18    default: fatal("unexpected call bytecode");
   14.19    }
   14.20 @@ -444,13 +443,16 @@
   14.21  void Parse::profile_receiver_type(Node* receiver) {
   14.22    assert(method_data_update(), "must be generating profile code");
   14.23  
   14.24 -  // Skip if we aren't tracking receivers
   14.25 -  if (TypeProfileWidth < 1) return;
   14.26 -
   14.27    ciMethodData* md = method()->method_data();
   14.28    assert(md != NULL, "expected valid ciMethodData");
   14.29    ciProfileData* data = md->bci_to_data(bci());
   14.30    assert(data->is_ReceiverTypeData(), "need ReceiverTypeData here");
   14.31 +
   14.32 +  // Skip if we aren't tracking receivers
   14.33 +  if (TypeProfileWidth < 1) {
   14.34 +    increment_md_counter_at(md, data, CounterData::count_offset());
   14.35 +    return;
   14.36 +  }
   14.37    ciReceiverTypeData* rdata = (ciReceiverTypeData*)data->as_ReceiverTypeData();
   14.38  
   14.39    Node* method_data = method_data_addressing(md, rdata, in_ByteSize(0));
    15.1 --- a/src/share/vm/opto/runtime.cpp	Mon Feb 01 23:18:47 2010 +0100
    15.2 +++ b/src/share/vm/opto/runtime.cpp	Mon Feb 01 16:49:49 2010 -0800
    15.3 @@ -706,6 +706,11 @@
    15.4      // vc->set_receiver_count(empty_row, DataLayout::counter_increment);
    15.5      int count_off = ReceiverTypeData::receiver_count_cell_index(empty_row);
    15.6      *(mdp + count_off) = DataLayout::counter_increment;
    15.7 +  } else {
    15.8 +    // Receiver did not match any saved receiver and there is no empty row for it.
    15.9 +    // Increment total counter to indicate polimorphic case.
   15.10 +    intptr_t* count_p = (intptr_t*)(((byte*)(data)) + in_bytes(CounterData::count_offset()));
   15.11 +    *count_p += DataLayout::counter_increment;
   15.12    }
   15.13  JRT_END
   15.14  
    16.1 --- a/src/share/vm/runtime/deoptimization.cpp	Mon Feb 01 23:18:47 2010 +0100
    16.2 +++ b/src/share/vm/runtime/deoptimization.cpp	Mon Feb 01 16:49:49 2010 -0800
    16.3 @@ -1338,13 +1338,14 @@
    16.4      // Whether the interpreter is producing MDO data or not, we also need
    16.5      // to use the MDO to detect hot deoptimization points and control
    16.6      // aggressive optimization.
    16.7 +    bool inc_recompile_count = false;
    16.8 +    ProfileData* pdata = NULL;
    16.9      if (ProfileTraps && update_trap_state && trap_mdo.not_null()) {
   16.10        assert(trap_mdo() == get_method_data(thread, trap_method, false), "sanity");
   16.11        uint this_trap_count = 0;
   16.12        bool maybe_prior_trap = false;
   16.13        bool maybe_prior_recompile = false;
   16.14 -      ProfileData* pdata
   16.15 -        = query_update_method_data(trap_mdo, trap_bci, reason,
   16.16 +      pdata = query_update_method_data(trap_mdo, trap_bci, reason,
   16.17                                     //outputs:
   16.18                                     this_trap_count,
   16.19                                     maybe_prior_trap,
   16.20 @@ -1380,18 +1381,7 @@
   16.21          // Detect repeated recompilation at the same BCI, and enforce a limit.
   16.22          if (make_not_entrant && maybe_prior_recompile) {
   16.23            // More than one recompile at this point.
   16.24 -          trap_mdo->inc_overflow_recompile_count();
   16.25 -          if (maybe_prior_trap
   16.26 -              && ((uint)trap_mdo->overflow_recompile_count()
   16.27 -                  > (uint)PerBytecodeRecompilationCutoff)) {
   16.28 -            // Give up on the method containing the bad BCI.
   16.29 -            if (trap_method() == nm->method()) {
   16.30 -              make_not_compilable = true;
   16.31 -            } else {
   16.32 -              trap_method->set_not_compilable();
   16.33 -              // But give grace to the enclosing nm->method().
   16.34 -            }
   16.35 -          }
   16.36 +          inc_recompile_count = maybe_prior_trap;
   16.37          }
   16.38        } else {
   16.39          // For reasons which are not recorded per-bytecode, we simply
   16.40 @@ -1418,7 +1408,17 @@
   16.41          reset_counters = true;
   16.42        }
   16.43  
   16.44 -      if (make_not_entrant && pdata != NULL) {
   16.45 +    }
   16.46 +
   16.47 +    // Take requested actions on the method:
   16.48 +
   16.49 +    // Recompile
   16.50 +    if (make_not_entrant) {
   16.51 +      if (!nm->make_not_entrant()) {
   16.52 +        return; // the call did not change nmethod's state
   16.53 +      }
   16.54 +
   16.55 +      if (pdata != NULL) {
   16.56          // Record the recompilation event, if any.
   16.57          int tstate0 = pdata->trap_state();
   16.58          int tstate1 = trap_state_set_recompiled(tstate0, true);
   16.59 @@ -1427,7 +1427,19 @@
   16.60        }
   16.61      }
   16.62  
   16.63 -    // Take requested actions on the method:
   16.64 +    if (inc_recompile_count) {
   16.65 +      trap_mdo->inc_overflow_recompile_count();
   16.66 +      if ((uint)trap_mdo->overflow_recompile_count() >
   16.67 +          (uint)PerBytecodeRecompilationCutoff) {
   16.68 +        // Give up on the method containing the bad BCI.
   16.69 +        if (trap_method() == nm->method()) {
   16.70 +          make_not_compilable = true;
   16.71 +        } else {
   16.72 +          trap_method->set_not_compilable();
   16.73 +          // But give grace to the enclosing nm->method().
   16.74 +        }
   16.75 +      }
   16.76 +    }
   16.77  
   16.78      // Reset invocation counters
   16.79      if (reset_counters) {
   16.80 @@ -1437,13 +1449,8 @@
   16.81          reset_invocation_counter(trap_scope);
   16.82      }
   16.83  
   16.84 -    // Recompile
   16.85 -    if (make_not_entrant) {
   16.86 -      nm->make_not_entrant();
   16.87 -    }
   16.88 -
   16.89      // Give up compiling
   16.90 -    if (make_not_compilable) {
   16.91 +    if (make_not_compilable && !nm->method()->is_not_compilable()) {
   16.92        assert(make_not_entrant, "consistent");
   16.93        nm->method()->set_not_compilable();
   16.94      }
   16.95 @@ -1516,9 +1523,11 @@
   16.96        if (tstate1 != tstate0)
   16.97          pdata->set_trap_state(tstate1);
   16.98      } else {
   16.99 -      if (LogCompilation && xtty != NULL)
  16.100 +      if (LogCompilation && xtty != NULL) {
  16.101 +        ttyLocker ttyl;
  16.102          // Missing MDP?  Leave a small complaint in the log.
  16.103          xtty->elem("missing_mdp bci='%d'", trap_bci);
  16.104 +      }
  16.105      }
  16.106    }
  16.107  
  16.108 @@ -1672,6 +1681,7 @@
  16.109    "class_check",
  16.110    "array_check",
  16.111    "intrinsic",
  16.112 +  "bimorphic",
  16.113    "unloaded",
  16.114    "uninitialized",
  16.115    "unreached",
    17.1 --- a/src/share/vm/runtime/deoptimization.hpp	Mon Feb 01 23:18:47 2010 +0100
    17.2 +++ b/src/share/vm/runtime/deoptimization.hpp	Mon Feb 01 16:49:49 2010 -0800
    17.3 @@ -33,12 +33,15 @@
    17.4    enum DeoptReason {
    17.5      Reason_many = -1,             // indicates presence of several reasons
    17.6      Reason_none = 0,              // indicates absence of a relevant deopt.
    17.7 +    // Next 7 reasons are recorded per bytecode in DataLayout::trap_bits
    17.8      Reason_null_check,            // saw unexpected null or zero divisor (@bci)
    17.9      Reason_null_assert,           // saw unexpected non-null or non-zero (@bci)
   17.10      Reason_range_check,           // saw unexpected array index (@bci)
   17.11      Reason_class_check,           // saw unexpected object class (@bci)
   17.12      Reason_array_check,           // saw unexpected array class (aastore @bci)
   17.13      Reason_intrinsic,             // saw unexpected operand to intrinsic (@bci)
   17.14 +    Reason_bimorphic,             // saw unexpected object class in bimorphic inlining (@bci)
   17.15 +
   17.16      Reason_unloaded,              // unloaded class or constant pool entry
   17.17      Reason_uninitialized,         // bad class state (uninitialized)
   17.18      Reason_unreached,             // code is not reached, compiler
   17.19 @@ -49,7 +52,7 @@
   17.20      Reason_predicate,             // compiler generated predicate failed
   17.21      Reason_LIMIT,
   17.22      // Note:  Keep this enum in sync. with _trap_reason_name.
   17.23 -    Reason_RECORDED_LIMIT = Reason_unloaded   // some are not recorded per bc
   17.24 +    Reason_RECORDED_LIMIT = Reason_bimorphic  // some are not recorded per bc
   17.25      // Note:  Reason_RECORDED_LIMIT should be < 8 to fit into 3 bits of
   17.26      // DataLayout::trap_bits.  This dependency is enforced indirectly
   17.27      // via asserts, to avoid excessive direct header-to-header dependencies.
   17.28 @@ -279,7 +282,7 @@
   17.29                                         int trap_state);
   17.30  
   17.31    static bool reason_is_recorded_per_bytecode(DeoptReason reason) {
   17.32 -    return reason > Reason_none && reason < Reason_RECORDED_LIMIT;
   17.33 +    return reason > Reason_none && reason <= Reason_RECORDED_LIMIT;
   17.34    }
   17.35  
   17.36    static DeoptReason reason_recorded_per_bytecode_if_any(DeoptReason reason) {
    18.1 --- a/src/share/vm/runtime/globals.hpp	Mon Feb 01 23:18:47 2010 +0100
    18.2 +++ b/src/share/vm/runtime/globals.hpp	Mon Feb 01 16:49:49 2010 -0800
    18.3 @@ -2864,7 +2864,7 @@
    18.4    product(intx, PerMethodRecompilationCutoff, 400,                          \
    18.5            "After recompiling N times, stay in the interpreter (-1=>'Inf')") \
    18.6                                                                              \
    18.7 -  product(intx, PerBytecodeRecompilationCutoff, 100,                        \
    18.8 +  product(intx, PerBytecodeRecompilationCutoff, 200,                        \
    18.9            "Per-BCI limit on repeated recompilation (-1=>'Inf')")            \
   18.10                                                                              \
   18.11    product(intx, PerMethodTrapLimit,  100,                                   \

mercurial