Merge

Fri, 04 Oct 2013 21:00:43 -0700

author
ccheung
date
Fri, 04 Oct 2013 21:00:43 -0700
changeset 5841
2720ab7a0d70
parent 5840
4212bfb33d76
parent 5820
798522662fcd
child 5842
febab3a8f203

Merge

src/share/vm/prims/jvm.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/agent/src/os/linux/LinuxDebuggerLocal.c	Sat Oct 05 03:14:53 2013 +0200
     1.2 +++ b/agent/src/os/linux/LinuxDebuggerLocal.c	Fri Oct 04 21:00:43 2013 -0700
     1.3 @@ -29,6 +29,7 @@
     1.4  #include <sys/types.h>
     1.5  #include <sys/stat.h>
     1.6  #include <fcntl.h>
     1.7 +#include <stdlib.h>
     1.8  #include <string.h>
     1.9  #include <limits.h>
    1.10  
    1.11 @@ -80,7 +81,7 @@
    1.12    (JNIEnv *env, jclass cls) {
    1.13    jclass listClass;
    1.14  
    1.15 -  if (init_libproc(getenv("LIBSAPROC_DEBUG")) != true) {
    1.16 +  if (init_libproc(getenv("LIBSAPROC_DEBUG") != NULL) != true) {
    1.17       THROW_NEW_DEBUGGER_EXCEPTION("can't initialize libproc");
    1.18    }
    1.19  
     2.1 --- a/agent/src/os/linux/ps_proc.c	Sat Oct 05 03:14:53 2013 +0200
     2.2 +++ b/agent/src/os/linux/ps_proc.c	Fri Oct 04 21:00:43 2013 -0700
     2.3 @@ -27,6 +27,8 @@
     2.4  #include <string.h>
     2.5  #include <signal.h>
     2.6  #include <errno.h>
     2.7 +#include <sys/types.h>
     2.8 +#include <sys/wait.h>
     2.9  #include <sys/ptrace.h>
    2.10  #include "libproc_impl.h"
    2.11  
     3.1 --- a/agent/src/os/linux/salibelf.c	Sat Oct 05 03:14:53 2013 +0200
     3.2 +++ b/agent/src/os/linux/salibelf.c	Fri Oct 04 21:00:43 2013 -0700
     3.3 @@ -25,6 +25,7 @@
     3.4  #include "salibelf.h"
     3.5  #include <stdlib.h>
     3.6  #include <unistd.h>
     3.7 +#include <string.h>
     3.8  
     3.9  extern void print_debug(const char*,...);
    3.10  
     4.1 --- a/agent/src/os/linux/symtab.c	Sat Oct 05 03:14:53 2013 +0200
     4.2 +++ b/agent/src/os/linux/symtab.c	Fri Oct 04 21:00:43 2013 -0700
     4.3 @@ -305,7 +305,7 @@
     4.4  
     4.5    unsigned char *bytes
     4.6      = (unsigned char*)(note+1) + note->n_namesz;
     4.7 -  unsigned char *filename
     4.8 +  char *filename
     4.9      = (build_id_to_debug_filename (note->n_descsz, bytes));
    4.10  
    4.11    fd = pathmap_open(filename);
     5.1 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java	Sat Oct 05 03:14:53 2013 +0200
     5.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java	Fri Oct 04 21:00:43 2013 -0700
     5.3 @@ -134,15 +134,13 @@
     5.4       private String type;
     5.5       private String name;
     5.6       private Address addr;
     5.7 -     private String kind;
     5.8 -     private int origin;
     5.9 +     private int flags;
    5.10  
    5.11 -     private Flag(String type, String name, Address addr, String kind, int origin) {
    5.12 +     private Flag(String type, String name, Address addr, int flags) {
    5.13          this.type = type;
    5.14          this.name = name;
    5.15          this.addr = addr;
    5.16 -        this.kind = kind;
    5.17 -        this.origin = origin;
    5.18 +        this.flags = flags;
    5.19       }
    5.20  
    5.21       public String getType() {
    5.22 @@ -157,12 +155,8 @@
    5.23          return addr;
    5.24       }
    5.25  
    5.26 -     public String getKind() {
    5.27 -        return kind;
    5.28 -     }
    5.29 -
    5.30       public int getOrigin() {
    5.31 -        return origin;
    5.32 +        return flags & 0xF;  // XXX can we get the mask bits from somewhere?
    5.33       }
    5.34  
    5.35       public boolean isBool() {
    5.36 @@ -173,8 +167,7 @@
    5.37          if (Assert.ASSERTS_ENABLED) {
    5.38             Assert.that(isBool(), "not a bool flag!");
    5.39          }
    5.40 -        return addr.getCIntegerAt(0, boolType.getSize(), boolType.isUnsigned())
    5.41 -               != 0;
    5.42 +        return addr.getCIntegerAt(0, boolType.getSize(), boolType.isUnsigned()) != 0;
    5.43       }
    5.44  
    5.45       public boolean isIntx() {
    5.46 @@ -843,11 +836,10 @@
    5.47  
    5.48      Address flagAddr = flagType.getAddressField("flags").getValue();
    5.49  
    5.50 -    AddressField typeFld = flagType.getAddressField("type");
    5.51 -    AddressField nameFld = flagType.getAddressField("name");
    5.52 -    AddressField addrFld = flagType.getAddressField("addr");
    5.53 -    AddressField kindFld = flagType.getAddressField("kind");
    5.54 -    CIntField originFld = new CIntField(flagType.getCIntegerField("origin"), 0);
    5.55 +    AddressField typeFld = flagType.getAddressField("_type");
    5.56 +    AddressField nameFld = flagType.getAddressField("_name");
    5.57 +    AddressField addrFld = flagType.getAddressField("_addr");
    5.58 +    CIntField flagsFld = new CIntField(flagType.getCIntegerField("_flags"), 0);
    5.59  
    5.60      long flagSize = flagType.getSize(); // sizeof(Flag)
    5.61  
    5.62 @@ -856,9 +848,8 @@
    5.63        String type = CStringUtilities.getString(typeFld.getValue(flagAddr));
    5.64        String name = CStringUtilities.getString(nameFld.getValue(flagAddr));
    5.65        Address addr = addrFld.getValue(flagAddr);
    5.66 -      String kind = CStringUtilities.getString(kindFld.getValue(flagAddr));
    5.67 -      int origin = (int)originFld.getValue(flagAddr);
    5.68 -      commandLineFlags[f] = new Flag(type, name, addr, kind, origin);
    5.69 +      int flags = (int)flagsFld.getValue(flagAddr);
    5.70 +      commandLineFlags[f] = new Flag(type, name, addr, flags);
    5.71        flagAddr = flagAddr.addOffsetTo(flagSize);
    5.72      }
    5.73  
     6.1 --- a/make/bsd/makefiles/gcc.make	Sat Oct 05 03:14:53 2013 +0200
     6.2 +++ b/make/bsd/makefiles/gcc.make	Fri Oct 04 21:00:43 2013 -0700
     6.3 @@ -247,7 +247,7 @@
     6.4  
     6.5  ifeq ($(USE_CLANG), true)
     6.6    # However we need to clean the code up before we can unrestrictedly enable this option with Clang
     6.7 -  WARNINGS_ARE_ERRORS += -Wno-unused-value -Wno-logical-op-parentheses -Wno-parentheses-equality -Wno-parentheses
     6.8 +  WARNINGS_ARE_ERRORS += -Wno-logical-op-parentheses -Wno-parentheses-equality -Wno-parentheses
     6.9    WARNINGS_ARE_ERRORS += -Wno-switch -Wno-tautological-compare
    6.10  # Not yet supported by clang in Xcode 4.6.2
    6.11  #  WARNINGS_ARE_ERRORS += -Wno-tautological-constant-out-of-range-compare
    6.12 @@ -262,7 +262,7 @@
    6.13    # conversions which might affect the values. Only enable it in earlier versions.
    6.14    WARNING_FLAGS = -Wunused-function
    6.15    ifeq ($(USE_CLANG),)
    6.16 -    WARNINGS_FLAGS += -Wconversion
    6.17 +    WARNING_FLAGS += -Wconversion
    6.18    endif
    6.19  endif
    6.20  
     7.1 --- a/make/linux/makefiles/gcc.make	Sat Oct 05 03:14:53 2013 +0200
     7.2 +++ b/make/linux/makefiles/gcc.make	Fri Oct 04 21:00:43 2013 -0700
     7.3 @@ -208,7 +208,7 @@
     7.4  
     7.5  ifeq ($(USE_CLANG), true)
     7.6    # However we need to clean the code up before we can unrestrictedly enable this option with Clang
     7.7 -  WARNINGS_ARE_ERRORS += -Wno-unused-value -Wno-logical-op-parentheses -Wno-parentheses-equality -Wno-parentheses
     7.8 +  WARNINGS_ARE_ERRORS += -Wno-logical-op-parentheses -Wno-parentheses-equality -Wno-parentheses
     7.9    WARNINGS_ARE_ERRORS += -Wno-switch -Wno-tautological-constant-out-of-range-compare -Wno-tautological-compare
    7.10    WARNINGS_ARE_ERRORS += -Wno-delete-non-virtual-dtor -Wno-deprecated -Wno-format -Wno-dynamic-class-memaccess
    7.11    WARNINGS_ARE_ERRORS += -Wno-return-type -Wno-empty-body
     8.1 --- a/src/cpu/sparc/vm/methodHandles_sparc.cpp	Sat Oct 05 03:14:53 2013 +0200
     8.2 +++ b/src/cpu/sparc/vm/methodHandles_sparc.cpp	Fri Oct 04 21:00:43 2013 -0700
     8.3 @@ -1,5 +1,5 @@
     8.4  /*
     8.5 - * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
     8.6 + * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
     8.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     8.8   *
     8.9   * This code is free software; you can redistribute it and/or modify it
    8.10 @@ -121,6 +121,7 @@
    8.11  
    8.12  void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register method, Register target, Register temp,
    8.13                                              bool for_compiler_entry) {
    8.14 +  Label L_no_such_method;
    8.15    assert(method == G5_method, "interpreter calling convention");
    8.16    assert_different_registers(method, target, temp);
    8.17  
    8.18 @@ -133,6 +134,9 @@
    8.19      const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset());
    8.20      __ ld(interp_only, temp);
    8.21      __ cmp_and_br_short(temp, 0, Assembler::zero, Assembler::pt, run_compiled_code);
    8.22 +    // Null method test is replicated below in compiled case,
    8.23 +    // it might be able to address across the verify_thread()
    8.24 +    __ br_null_short(G5_method, Assembler::pn, L_no_such_method);
    8.25      __ ld_ptr(G5_method, in_bytes(Method::interpreter_entry_offset()), target);
    8.26      __ jmp(target, 0);
    8.27      __ delayed()->nop();
    8.28 @@ -141,11 +145,19 @@
    8.29      // it doesn't matter, since this is interpreter code.
    8.30    }
    8.31  
    8.32 +  // Compiled case, either static or fall-through from runtime conditional
    8.33 +  __ br_null_short(G5_method, Assembler::pn, L_no_such_method);
    8.34 +
    8.35    const ByteSize entry_offset = for_compiler_entry ? Method::from_compiled_offset() :
    8.36                                                       Method::from_interpreted_offset();
    8.37    __ ld_ptr(G5_method, in_bytes(entry_offset), target);
    8.38    __ jmp(target, 0);
    8.39    __ delayed()->nop();
    8.40 +
    8.41 +  __ bind(L_no_such_method);
    8.42 +  AddressLiteral ame(StubRoutines::throw_AbstractMethodError_entry());
    8.43 +  __ jump_to(ame, temp);
    8.44 +  __ delayed()->nop();
    8.45  }
    8.46  
    8.47  void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
     9.1 --- a/src/cpu/sparc/vm/sparc.ad	Sat Oct 05 03:14:53 2013 +0200
     9.2 +++ b/src/cpu/sparc/vm/sparc.ad	Fri Oct 04 21:00:43 2013 -0700
     9.3 @@ -2018,6 +2018,15 @@
     9.4    return L7_REGP_mask();
     9.5  }
     9.6  
     9.7 +const RegMask Matcher::mathExactI_result_proj_mask() {
     9.8 +  return G1_REGI_mask();
     9.9 +}
    9.10 +
    9.11 +const RegMask Matcher::mathExactI_flags_proj_mask() {
    9.12 +  return INT_FLAGS_mask();
    9.13 +}
    9.14 +
    9.15 +
    9.16  %}
    9.17  
    9.18  
    9.19 @@ -4245,12 +4254,16 @@
    9.20      greater_equal(0xB);
    9.21      less_equal(0x2);
    9.22      greater(0xA);
    9.23 +    overflow(0x7);
    9.24 +    no_overflow(0xF);
    9.25    %}
    9.26  %}
    9.27  
    9.28  // Comparison Op, unsigned
    9.29  operand cmpOpU() %{
    9.30    match(Bool);
    9.31 +  predicate(n->as_Bool()->_test._test != BoolTest::overflow &&
    9.32 +            n->as_Bool()->_test._test != BoolTest::no_overflow);
    9.33  
    9.34    format %{ "u" %}
    9.35    interface(COND_INTER) %{
    9.36 @@ -4260,12 +4273,16 @@
    9.37      greater_equal(0xD);
    9.38      less_equal(0x4);
    9.39      greater(0xC);
    9.40 +    overflow(0x7);
    9.41 +    no_overflow(0xF);
    9.42    %}
    9.43  %}
    9.44  
    9.45  // Comparison Op, pointer (same as unsigned)
    9.46  operand cmpOpP() %{
    9.47    match(Bool);
    9.48 +  predicate(n->as_Bool()->_test._test != BoolTest::overflow &&
    9.49 +            n->as_Bool()->_test._test != BoolTest::no_overflow);
    9.50  
    9.51    format %{ "p" %}
    9.52    interface(COND_INTER) %{
    9.53 @@ -4275,12 +4292,16 @@
    9.54      greater_equal(0xD);
    9.55      less_equal(0x4);
    9.56      greater(0xC);
    9.57 +    overflow(0x7);
    9.58 +    no_overflow(0xF);
    9.59    %}
    9.60  %}
    9.61  
    9.62  // Comparison Op, branch-register encoding
    9.63  operand cmpOp_reg() %{
    9.64    match(Bool);
    9.65 +  predicate(n->as_Bool()->_test._test != BoolTest::overflow &&
    9.66 +            n->as_Bool()->_test._test != BoolTest::no_overflow);
    9.67  
    9.68    format %{ "" %}
    9.69    interface(COND_INTER) %{
    9.70 @@ -4290,12 +4311,16 @@
    9.71      greater_equal(0x7);
    9.72      less_equal   (0x2);
    9.73      greater      (0x6);
    9.74 +    overflow(0x7); // not supported
    9.75 +    no_overflow(0xF); // not supported
    9.76    %}
    9.77  %}
    9.78  
    9.79  // Comparison Code, floating, unordered same as less
    9.80  operand cmpOpF() %{
    9.81    match(Bool);
    9.82 +  predicate(n->as_Bool()->_test._test != BoolTest::overflow &&
    9.83 +            n->as_Bool()->_test._test != BoolTest::no_overflow);
    9.84  
    9.85    format %{ "fl" %}
    9.86    interface(COND_INTER) %{
    9.87 @@ -4305,12 +4330,17 @@
    9.88      greater_equal(0xB);
    9.89      less_equal(0xE);
    9.90      greater(0x6);
    9.91 +
    9.92 +    overflow(0x7); // not supported
    9.93 +    no_overflow(0xF); // not supported
    9.94    %}
    9.95  %}
    9.96  
    9.97  // Used by long compare
    9.98  operand cmpOp_commute() %{
    9.99    match(Bool);
   9.100 +  predicate(n->as_Bool()->_test._test != BoolTest::overflow &&
   9.101 +            n->as_Bool()->_test._test != BoolTest::no_overflow);
   9.102  
   9.103    format %{ "" %}
   9.104    interface(COND_INTER) %{
   9.105 @@ -4320,6 +4350,8 @@
   9.106      greater_equal(0x2);
   9.107      less_equal(0xB);
   9.108      greater(0x3);
   9.109 +    overflow(0x7);
   9.110 +    no_overflow(0xF);
   9.111    %}
   9.112  %}
   9.113  
    10.1 --- a/src/cpu/x86/vm/assembler_x86.cpp	Sat Oct 05 03:14:53 2013 +0200
    10.2 +++ b/src/cpu/x86/vm/assembler_x86.cpp	Fri Oct 04 21:00:43 2013 -0700
    10.3 @@ -4769,7 +4769,7 @@
    10.4  }
    10.5  
    10.6  void Assembler::adcq(Register dst, Register src) {
    10.7 -  (int) prefixq_and_encode(dst->encoding(), src->encoding());
    10.8 +  (void) prefixq_and_encode(dst->encoding(), src->encoding());
    10.9    emit_arith(0x13, 0xC0, dst, src);
   10.10  }
   10.11  
   10.12 @@ -4824,7 +4824,7 @@
   10.13  }
   10.14  
   10.15  void Assembler::andq(Register dst, Register src) {
   10.16 -  (int) prefixq_and_encode(dst->encoding(), src->encoding());
   10.17 +  (void) prefixq_and_encode(dst->encoding(), src->encoding());
   10.18    emit_arith(0x23, 0xC0, dst, src);
   10.19  }
   10.20  
    11.1 --- a/src/cpu/x86/vm/methodHandles_x86.cpp	Sat Oct 05 03:14:53 2013 +0200
    11.2 +++ b/src/cpu/x86/vm/methodHandles_x86.cpp	Fri Oct 04 21:00:43 2013 -0700
    11.3 @@ -114,6 +114,11 @@
    11.4  void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register method, Register temp,
    11.5                                              bool for_compiler_entry) {
    11.6    assert(method == rbx, "interpreter calling convention");
    11.7 +
    11.8 +   Label L_no_such_method;
    11.9 +   __ testptr(rbx, rbx);
   11.10 +   __ jcc(Assembler::zero, L_no_such_method);
   11.11 +
   11.12    __ verify_method_ptr(method);
   11.13  
   11.14    if (!for_compiler_entry && JvmtiExport::can_post_interpreter_events()) {
   11.15 @@ -138,6 +143,9 @@
   11.16    const ByteSize entry_offset = for_compiler_entry ? Method::from_compiled_offset() :
   11.17                                                       Method::from_interpreted_offset();
   11.18    __ jmp(Address(method, entry_offset));
   11.19 +
   11.20 +  __ bind(L_no_such_method);
   11.21 +  __ jump(RuntimeAddress(StubRoutines::throw_AbstractMethodError_entry()));
   11.22  }
   11.23  
   11.24  void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
    12.1 --- a/src/cpu/x86/vm/x86_32.ad	Sat Oct 05 03:14:53 2013 +0200
    12.2 +++ b/src/cpu/x86/vm/x86_32.ad	Fri Oct 04 21:00:43 2013 -0700
    12.3 @@ -1534,6 +1534,14 @@
    12.4    return EBP_REG_mask();
    12.5  }
    12.6  
    12.7 +const RegMask Matcher::mathExactI_result_proj_mask() {
    12.8 +  return EAX_REG_mask();
    12.9 +}
   12.10 +
   12.11 +const RegMask Matcher::mathExactI_flags_proj_mask() {
   12.12 +  return INT_FLAGS_mask();
   12.13 +}
   12.14 +
   12.15  // Returns true if the high 32 bits of the value is known to be zero.
   12.16  bool is_operand_hi32_zero(Node* n) {
   12.17    int opc = n->Opcode();
   12.18 @@ -4922,6 +4930,8 @@
   12.19      greater_equal(0xD, "ge");
   12.20      less_equal(0xE, "le");
   12.21      greater(0xF, "g");
   12.22 +    overflow(0x0, "o");
   12.23 +    no_overflow(0x1, "no");
   12.24    %}
   12.25  %}
   12.26  
   12.27 @@ -4939,6 +4949,8 @@
   12.28      greater_equal(0x3, "nb");
   12.29      less_equal(0x6, "be");
   12.30      greater(0x7, "nbe");
   12.31 +    overflow(0x0, "o");
   12.32 +    no_overflow(0x1, "no");
   12.33    %}
   12.34  %}
   12.35  
   12.36 @@ -4957,6 +4969,8 @@
   12.37      greater_equal(0x3, "nb");
   12.38      less_equal(0x6, "be");
   12.39      greater(0x7, "nbe");
   12.40 +    overflow(0x0, "o");
   12.41 +    no_overflow(0x1, "no");
   12.42    %}
   12.43  %}
   12.44  
   12.45 @@ -4974,6 +4988,8 @@
   12.46      greater_equal(0x3, "nb");
   12.47      less_equal(0x6, "be");
   12.48      greater(0x7, "nbe");
   12.49 +    overflow(0x0, "o");
   12.50 +    no_overflow(0x1, "no");
   12.51    %}
   12.52  %}
   12.53  
   12.54 @@ -4981,6 +4997,8 @@
   12.55  operand cmpOp_fcmov() %{
   12.56    match(Bool);
   12.57  
   12.58 +  predicate(n->as_Bool()->_test._test != BoolTest::overflow &&
   12.59 +            n->as_Bool()->_test._test != BoolTest::no_overflow);
   12.60    format %{ "" %}
   12.61    interface(COND_INTER) %{
   12.62      equal        (0x0C8);
   12.63 @@ -4989,6 +5007,8 @@
   12.64      greater_equal(0x1C0);
   12.65      less_equal   (0x0D0);
   12.66      greater      (0x1D0);
   12.67 +    overflow(0x0, "o"); // not really supported by the instruction
   12.68 +    no_overflow(0x1, "no"); // not really supported by the instruction
   12.69    %}
   12.70  %}
   12.71  
   12.72 @@ -5004,6 +5024,8 @@
   12.73      greater_equal(0xE, "le");
   12.74      less_equal(0xD, "ge");
   12.75      greater(0xC, "l");
   12.76 +    overflow(0x0, "o");
   12.77 +    no_overflow(0x1, "no");
   12.78    %}
   12.79  %}
   12.80  
   12.81 @@ -7496,6 +7518,31 @@
   12.82  
   12.83  //----------Arithmetic Instructions--------------------------------------------
   12.84  //----------Addition Instructions----------------------------------------------
   12.85 +
   12.86 +instruct addExactI_rReg(eAXRegI dst, rRegI src, eFlagsReg cr)
   12.87 +%{
   12.88 +  match(AddExactI dst src);
   12.89 +  effect(DEF cr);
   12.90 +
   12.91 +  format %{ "ADD    $dst, $src\t# addExact int" %}
   12.92 +  ins_encode %{
   12.93 +    __ addl($dst$$Register, $src$$Register);
   12.94 +  %}
   12.95 +  ins_pipe(ialu_reg_reg);
   12.96 +%}
   12.97 +
   12.98 +instruct addExactI_rReg_imm(eAXRegI dst, immI src, eFlagsReg cr)
   12.99 +%{
  12.100 +  match(AddExactI dst src);
  12.101 +  effect(DEF cr);
  12.102 +
  12.103 +  format %{ "ADD    $dst, $src\t# addExact int" %}
  12.104 +  ins_encode %{
  12.105 +    __ addl($dst$$Register, $src$$constant);
  12.106 +  %}
  12.107 +  ins_pipe(ialu_reg_reg);
  12.108 +%}
  12.109 +
  12.110  // Integer Addition Instructions
  12.111  instruct addI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
  12.112    match(Set dst (AddI dst src));
    13.1 --- a/src/cpu/x86/vm/x86_64.ad	Sat Oct 05 03:14:53 2013 +0200
    13.2 +++ b/src/cpu/x86/vm/x86_64.ad	Fri Oct 04 21:00:43 2013 -0700
    13.3 @@ -1649,6 +1649,14 @@
    13.4    return PTR_RBP_REG_mask();
    13.5  }
    13.6  
    13.7 +const RegMask Matcher::mathExactI_result_proj_mask() {
    13.8 +  return INT_RAX_REG_mask();
    13.9 +}
   13.10 +
   13.11 +const RegMask Matcher::mathExactI_flags_proj_mask() {
   13.12 +  return INT_FLAGS_mask();
   13.13 +}
   13.14 +
   13.15  %}
   13.16  
   13.17  //----------ENCODING BLOCK-----------------------------------------------------
   13.18 @@ -4133,6 +4141,8 @@
   13.19      greater_equal(0xD, "ge");
   13.20      less_equal(0xE, "le");
   13.21      greater(0xF, "g");
   13.22 +    overflow(0x0, "o");
   13.23 +    no_overflow(0x1, "no");
   13.24    %}
   13.25  %}
   13.26  
   13.27 @@ -4151,6 +4161,8 @@
   13.28      greater_equal(0x3, "nb");
   13.29      less_equal(0x6, "be");
   13.30      greater(0x7, "nbe");
   13.31 +    overflow(0x0, "o");
   13.32 +    no_overflow(0x1, "no");
   13.33    %}
   13.34  %}
   13.35  
   13.36 @@ -4170,6 +4182,8 @@
   13.37      greater_equal(0x3, "nb");
   13.38      less_equal(0x6, "be");
   13.39      greater(0x7, "nbe");
   13.40 +    overflow(0x0, "o");
   13.41 +    no_overflow(0x1, "no");
   13.42    %}
   13.43  %}
   13.44  
   13.45 @@ -4187,6 +4201,8 @@
   13.46      greater_equal(0x3, "nb");
   13.47      less_equal(0x6, "be");
   13.48      greater(0x7, "nbe");
   13.49 +    overflow(0x0, "o");
   13.50 +    no_overflow(0x1, "no");
   13.51    %}
   13.52  %}
   13.53  
   13.54 @@ -6922,6 +6938,30 @@
   13.55  //----------Arithmetic Instructions--------------------------------------------
   13.56  //----------Addition Instructions----------------------------------------------
   13.57  
   13.58 +instruct addExactI_rReg(rax_RegI dst, rRegI src, rFlagsReg cr)
   13.59 +%{
   13.60 +  match(AddExactI dst src);
   13.61 +  effect(DEF cr);
   13.62 +
   13.63 +  format %{ "addl    $dst, $src\t# addExact int" %}
   13.64 +  ins_encode %{
   13.65 +    __ addl($dst$$Register, $src$$Register);
   13.66 +  %}
   13.67 +  ins_pipe(ialu_reg_reg);
   13.68 +%}
   13.69 +
   13.70 +instruct addExactI_rReg_imm(rax_RegI dst, immI src, rFlagsReg cr)
   13.71 +%{
   13.72 +  match(AddExactI dst src);
   13.73 +  effect(DEF cr);
   13.74 +
   13.75 +  format %{ "addl    $dst, $src\t# addExact int" %}
   13.76 +  ins_encode %{
   13.77 +    __ addl($dst$$Register, $src$$constant);
   13.78 +  %}
   13.79 +  ins_pipe(ialu_reg_reg);
   13.80 +%}
   13.81 +
   13.82  instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
   13.83  %{
   13.84    match(Set dst (AddI dst src));
    14.1 --- a/src/share/vm/adlc/adlparse.cpp	Sat Oct 05 03:14:53 2013 +0200
    14.2 +++ b/src/share/vm/adlc/adlparse.cpp	Fri Oct 04 21:00:43 2013 -0700
    14.3 @@ -3395,12 +3395,16 @@
    14.4    char *greater_equal;
    14.5    char *less_equal;
    14.6    char *greater;
    14.7 +  char *overflow;
    14.8 +  char *no_overflow;
    14.9    const char *equal_format = "eq";
   14.10    const char *not_equal_format = "ne";
   14.11    const char *less_format = "lt";
   14.12    const char *greater_equal_format = "ge";
   14.13    const char *less_equal_format = "le";
   14.14    const char *greater_format = "gt";
   14.15 +  const char *overflow_format = "o";
   14.16 +  const char *no_overflow_format = "no";
   14.17  
   14.18    if (_curchar != '%') {
   14.19      parse_err(SYNERR, "Missing '%%{' for 'cond_interface' block.\n");
   14.20 @@ -3437,6 +3441,12 @@
   14.21      else if ( strcmp(field,"greater") == 0 ) {
   14.22        greater = interface_field_parse(&greater_format);
   14.23      }
   14.24 +    else if ( strcmp(field,"overflow") == 0 ) {
   14.25 +      overflow = interface_field_parse(&overflow_format);
   14.26 +    }
   14.27 +    else if ( strcmp(field,"no_overflow") == 0 ) {
   14.28 +      no_overflow = interface_field_parse(&no_overflow_format);
   14.29 +    }
   14.30      else {
   14.31        parse_err(SYNERR, "Expected keyword, base|index|scale|disp,  or '%%}' ending interface.\n");
   14.32        return NULL;
   14.33 @@ -3455,7 +3465,9 @@
   14.34                                         less,          less_format,
   14.35                                         greater_equal, greater_equal_format,
   14.36                                         less_equal,    less_equal_format,
   14.37 -                                       greater,       greater_format);
   14.38 +                                       greater,       greater_format,
   14.39 +                                       overflow,      overflow_format,
   14.40 +                                       no_overflow,   no_overflow_format);
   14.41    return inter;
   14.42  }
   14.43  
    15.1 --- a/src/share/vm/adlc/archDesc.cpp	Sat Oct 05 03:14:53 2013 +0200
    15.2 +++ b/src/share/vm/adlc/archDesc.cpp	Fri Oct 04 21:00:43 2013 -0700
    15.3 @@ -1192,6 +1192,8 @@
    15.4           || strcmp(idealName,"CmpF") == 0
    15.5           || strcmp(idealName,"FastLock") == 0
    15.6           || strcmp(idealName,"FastUnlock") == 0
    15.7 +         || strcmp(idealName,"AddExactI") == 0
    15.8 +         || strcmp(idealName,"FlagsProj") == 0
    15.9           || strcmp(idealName,"Bool") == 0
   15.10           || strcmp(idealName,"Binary") == 0 ) {
   15.11        // Removed ConI from the must_clone list.  CPUs that cannot use
    16.1 --- a/src/share/vm/adlc/formssel.cpp	Sat Oct 05 03:14:53 2013 +0200
    16.2 +++ b/src/share/vm/adlc/formssel.cpp	Fri Oct 04 21:00:43 2013 -0700
    16.3 @@ -2757,14 +2757,18 @@
    16.4                               const char* less,          const char* less_format,
    16.5                               const char* greater_equal, const char* greater_equal_format,
    16.6                               const char* less_equal,    const char* less_equal_format,
    16.7 -                             const char* greater,       const char* greater_format)
    16.8 +                             const char* greater,       const char* greater_format,
    16.9 +                             const char* overflow,      const char* overflow_format,
   16.10 +                             const char* no_overflow,   const char* no_overflow_format)
   16.11    : Interface("COND_INTER"),
   16.12      _equal(equal),                 _equal_format(equal_format),
   16.13      _not_equal(not_equal),         _not_equal_format(not_equal_format),
   16.14      _less(less),                   _less_format(less_format),
   16.15      _greater_equal(greater_equal), _greater_equal_format(greater_equal_format),
   16.16      _less_equal(less_equal),       _less_equal_format(less_equal_format),
   16.17 -    _greater(greater),             _greater_format(greater_format) {
   16.18 +    _greater(greater),             _greater_format(greater_format),
   16.19 +    _overflow(overflow),           _overflow_format(overflow_format),
   16.20 +    _no_overflow(no_overflow),     _no_overflow_format(no_overflow_format) {
   16.21  }
   16.22  CondInterface::~CondInterface() {
   16.23    // not owner of any character arrays
   16.24 @@ -2777,12 +2781,14 @@
   16.25  // Write info to output files
   16.26  void CondInterface::output(FILE *fp) {
   16.27    Interface::output(fp);
   16.28 -  if ( _equal  != NULL )     fprintf(fp," equal       == %s\n", _equal);
   16.29 -  if ( _not_equal  != NULL ) fprintf(fp," not_equal   == %s\n", _not_equal);
   16.30 -  if ( _less  != NULL )      fprintf(fp," less        == %s\n", _less);
   16.31 -  if ( _greater_equal  != NULL ) fprintf(fp," greater_equal   == %s\n", _greater_equal);
   16.32 -  if ( _less_equal  != NULL ) fprintf(fp," less_equal  == %s\n", _less_equal);
   16.33 -  if ( _greater  != NULL )    fprintf(fp," greater     == %s\n", _greater);
   16.34 +  if ( _equal  != NULL )     fprintf(fp," equal        == %s\n", _equal);
   16.35 +  if ( _not_equal  != NULL ) fprintf(fp," not_equal    == %s\n", _not_equal);
   16.36 +  if ( _less  != NULL )      fprintf(fp," less         == %s\n", _less);
   16.37 +  if ( _greater_equal  != NULL ) fprintf(fp," greater_equal    == %s\n", _greater_equal);
   16.38 +  if ( _less_equal  != NULL ) fprintf(fp," less_equal   == %s\n", _less_equal);
   16.39 +  if ( _greater  != NULL )    fprintf(fp," greater      == %s\n", _greater);
   16.40 +  if ( _overflow != NULL )    fprintf(fp," overflow     == %s\n", _overflow);
   16.41 +  if ( _no_overflow != NULL ) fprintf(fp," no_overflow  == %s\n", _no_overflow);
   16.42    // fprintf(fp,"\n");
   16.43  }
   16.44  
    17.1 --- a/src/share/vm/adlc/formssel.hpp	Sat Oct 05 03:14:53 2013 +0200
    17.2 +++ b/src/share/vm/adlc/formssel.hpp	Fri Oct 04 21:00:43 2013 -0700
    17.3 @@ -798,12 +798,16 @@
    17.4    const char *_greater_equal;
    17.5    const char *_less_equal;
    17.6    const char *_greater;
    17.7 +  const char *_overflow;
    17.8 +  const char *_no_overflow;
    17.9    const char *_equal_format;
   17.10    const char *_not_equal_format;
   17.11    const char *_less_format;
   17.12    const char *_greater_equal_format;
   17.13    const char *_less_equal_format;
   17.14    const char *_greater_format;
   17.15 +  const char *_overflow_format;
   17.16 +  const char *_no_overflow_format;
   17.17  
   17.18    // Public Methods
   17.19    CondInterface(const char* equal,         const char* equal_format,
   17.20 @@ -811,7 +815,9 @@
   17.21                  const char* less,          const char* less_format,
   17.22                  const char* greater_equal, const char* greater_equal_format,
   17.23                  const char* less_equal,    const char* less_equal_format,
   17.24 -                const char* greater,       const char* greater_format);
   17.25 +                const char* greater,       const char* greater_format,
   17.26 +                const char* overflow,      const char* overflow_format,
   17.27 +                const char* no_overflow,   const char* no_overflow_format);
   17.28    ~CondInterface();
   17.29  
   17.30    void dump();
    18.1 --- a/src/share/vm/adlc/output_h.cpp	Sat Oct 05 03:14:53 2013 +0200
    18.2 +++ b/src/share/vm/adlc/output_h.cpp	Fri Oct 04 21:00:43 2013 -0700
    18.3 @@ -388,6 +388,8 @@
    18.4    fprintf(fp, "  else if( _c%d == BoolTest::ge ) st->print(\"%s\");\n",i,cond->_greater_equal_format);
    18.5    fprintf(fp, "  else if( _c%d == BoolTest::lt ) st->print(\"%s\");\n",i,cond->_less_format);
    18.6    fprintf(fp, "  else if( _c%d == BoolTest::gt ) st->print(\"%s\");\n",i,cond->_greater_format);
    18.7 +  fprintf(fp, "  else if( _c%d == BoolTest::overflow ) st->print(\"%s\");\n",i,cond->_overflow_format);
    18.8 +  fprintf(fp, "  else if( _c%d == BoolTest::no_overflow ) st->print(\"%s\");\n",i,cond->_no_overflow_format);
    18.9  }
   18.10  
   18.11  // Output code that dumps constant values, increment "i" if type is constant
   18.12 @@ -1208,6 +1210,8 @@
   18.13        fprintf(fp,"    case  BoolTest::ne : return not_equal();\n");
   18.14        fprintf(fp,"    case  BoolTest::le : return less_equal();\n");
   18.15        fprintf(fp,"    case  BoolTest::ge : return greater_equal();\n");
   18.16 +      fprintf(fp,"    case  BoolTest::overflow : return overflow();\n");
   18.17 +      fprintf(fp,"    case  BoolTest::no_overflow: return no_overflow();\n");
   18.18        fprintf(fp,"    default : ShouldNotReachHere(); return 0;\n");
   18.19        fprintf(fp,"    }\n");
   18.20        fprintf(fp,"  };\n");
   18.21 @@ -1373,6 +1377,14 @@
   18.22          if( greater != NULL ) {
   18.23            define_oper_interface(fp, *oper, _globalNames, "greater", greater);
   18.24          }
   18.25 +        const char *overflow = cInterface->_overflow;
   18.26 +        if( overflow != NULL ) {
   18.27 +          define_oper_interface(fp, *oper, _globalNames, "overflow", overflow);
   18.28 +        }
   18.29 +        const char *no_overflow = cInterface->_no_overflow;
   18.30 +        if( no_overflow != NULL ) {
   18.31 +          define_oper_interface(fp, *oper, _globalNames, "no_overflow", no_overflow);
   18.32 +        }
   18.33        } // end Conditional Interface
   18.34        // Check if it is a Constant Interface
   18.35        else if (oper->_interface->is_ConstInterface() != NULL ) {
    19.1 --- a/src/share/vm/c1/c1_Runtime1.cpp	Sat Oct 05 03:14:53 2013 +0200
    19.2 +++ b/src/share/vm/c1/c1_Runtime1.cpp	Fri Oct 04 21:00:43 2013 -0700
    19.3 @@ -1078,14 +1078,17 @@
    19.4            // replace instructions
    19.5            // first replace the tail, then the call
    19.6  #ifdef ARM
    19.7 -          if(load_klass_or_mirror_patch_id && !VM_Version::supports_movw()) {
    19.8 +          if((load_klass_or_mirror_patch_id ||
    19.9 +              stub_id == Runtime1::load_appendix_patching_id) &&
   19.10 +             !VM_Version::supports_movw()) {
   19.11              nmethod* nm = CodeCache::find_nmethod(instr_pc);
   19.12              address addr = NULL;
   19.13              assert(nm != NULL, "invalid nmethod_pc");
   19.14              RelocIterator mds(nm, copy_buff, copy_buff + 1);
   19.15              while (mds.next()) {
   19.16                if (mds.type() == relocInfo::oop_type) {
   19.17 -                assert(stub_id == Runtime1::load_mirror_patching_id, "wrong stub id");
   19.18 +                assert(stub_id == Runtime1::load_mirror_patching_id ||
   19.19 +                       stub_id == Runtime1::load_appendix_patching_id, "wrong stub id");
   19.20                  oop_Relocation* r = mds.oop_reloc();
   19.21                  addr = (address)r->oop_addr();
   19.22                  break;
    20.1 --- a/src/share/vm/classfile/classFileParser.cpp	Sat Oct 05 03:14:53 2013 +0200
    20.2 +++ b/src/share/vm/classfile/classFileParser.cpp	Fri Oct 04 21:00:43 2013 -0700
    20.3 @@ -1787,7 +1787,7 @@
    20.4      if (_location != _in_method)  break;  // only allow for methods
    20.5      if (!privileged)              break;  // only allow in privileged code
    20.6      return _method_LambdaForm_Hidden;
    20.7 -  case vmSymbols::VM_SYMBOL_ENUM_NAME(sun_invoke_Stable_signature):
    20.8 +  case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_Stable_signature):
    20.9      if (_location != _in_field)   break;  // only allow for fields
   20.10      if (!privileged)              break;  // only allow in privileged code
   20.11      return _field_Stable;
    21.1 --- a/src/share/vm/classfile/defaultMethods.cpp	Sat Oct 05 03:14:53 2013 +0200
    21.2 +++ b/src/share/vm/classfile/defaultMethods.cpp	Fri Oct 04 21:00:43 2013 -0700
    21.3 @@ -793,7 +793,7 @@
    21.4  
    21.5  
    21.6  
    21.7 -#ifndef PRODUCT
    21.8 +#ifdef ASSERT
    21.9  // Return true is broad type is a covariant return of narrow type
   21.10  static bool covariant_return_type(BasicType narrow, BasicType broad) {
   21.11    if (narrow == broad) {
   21.12 @@ -804,7 +804,7 @@
   21.13    }
   21.14    return false;
   21.15  }
   21.16 -#endif // ndef PRODUCT
   21.17 +#endif
   21.18  
   21.19  static int assemble_redirect(
   21.20      BytecodeConstantPool* cp, BytecodeBuffer* buffer,
   21.21 @@ -1095,4 +1095,3 @@
   21.22      MetadataFactory::free_array(cld, original_ordering);
   21.23    }
   21.24  }
   21.25 -
    22.1 --- a/src/share/vm/classfile/vmSymbols.hpp	Sat Oct 05 03:14:53 2013 +0200
    22.2 +++ b/src/share/vm/classfile/vmSymbols.hpp	Fri Oct 04 21:00:43 2013 -0700
    22.3 @@ -270,7 +270,7 @@
    22.4    template(java_lang_invoke_LambdaForm,               "java/lang/invoke/LambdaForm")              \
    22.5    template(java_lang_invoke_ForceInline_signature,    "Ljava/lang/invoke/ForceInline;")           \
    22.6    template(java_lang_invoke_DontInline_signature,     "Ljava/lang/invoke/DontInline;")            \
    22.7 -  template(sun_invoke_Stable_signature,               "Lsun/invoke/Stable;")                      \
    22.8 +  template(java_lang_invoke_Stable_signature,         "Ljava/lang/invoke/Stable;")                \
    22.9    template(java_lang_invoke_LambdaForm_Compiled_signature, "Ljava/lang/invoke/LambdaForm$Compiled;") \
   22.10    template(java_lang_invoke_LambdaForm_Hidden_signature, "Ljava/lang/invoke/LambdaForm$Hidden;")  \
   22.11    template(java_lang_invoke_MagicLambdaImpl,          "java/lang/invoke/MagicLambdaImpl")         \
   22.12 @@ -631,6 +631,10 @@
   22.13    do_name(log_name,"log")       do_name(log10_name,"log10")     do_name(pow_name,"pow")                                 \
   22.14    do_name(exp_name,"exp")       do_name(min_name,"min")         do_name(max_name,"max")                                 \
   22.15                                                                                                                          \
   22.16 +  do_name(addExact_name,"addExact")                                                                                     \
   22.17 +  do_name(subtractExact_name,"subtractExact")                                                                           \
   22.18 +  do_name(multiplyExact_name,"multiplyExact")                                                                           \
   22.19 +                                                                                                                        \
   22.20    do_intrinsic(_dabs,                     java_lang_Math,         abs_name,   double_double_signature,           F_S)   \
   22.21    do_intrinsic(_dsin,                     java_lang_Math,         sin_name,   double_double_signature,           F_S)   \
   22.22    do_intrinsic(_dcos,                     java_lang_Math,         cos_name,   double_double_signature,           F_S)   \
   22.23 @@ -643,6 +647,7 @@
   22.24    do_intrinsic(_dexp,                     java_lang_Math,         exp_name,   double_double_signature,           F_S)   \
   22.25    do_intrinsic(_min,                      java_lang_Math,         min_name,   int2_int_signature,                F_S)   \
   22.26    do_intrinsic(_max,                      java_lang_Math,         max_name,   int2_int_signature,                F_S)   \
   22.27 +  do_intrinsic(_addExact,                 java_lang_Math,         addExact_name, int2_int_signature,             F_S)   \
   22.28                                                                                                                          \
   22.29    do_intrinsic(_floatToRawIntBits,        java_lang_Float,        floatToRawIntBits_name,   float_int_signature, F_S)   \
   22.30     do_name(     floatToRawIntBits_name,                          "floatToRawIntBits")                                   \
    23.1 --- a/src/share/vm/code/codeCache.cpp	Sat Oct 05 03:14:53 2013 +0200
    23.2 +++ b/src/share/vm/code/codeCache.cpp	Fri Oct 04 21:00:43 2013 -0700
    23.3 @@ -124,7 +124,6 @@
    23.4  int CodeCache::_number_of_nmethods_with_dependencies = 0;
    23.5  bool CodeCache::_needs_cache_clean = false;
    23.6  nmethod* CodeCache::_scavenge_root_nmethods = NULL;
    23.7 -nmethod* CodeCache::_saved_nmethods = NULL;
    23.8  
    23.9  int CodeCache::_codemem_full_count = 0;
   23.10  
   23.11 @@ -464,96 +463,11 @@
   23.12  }
   23.13  #endif //PRODUCT
   23.14  
   23.15 -/**
   23.16 - * Remove and return nmethod from the saved code list in order to reanimate it.
   23.17 - */
   23.18 -nmethod* CodeCache::reanimate_saved_code(Method* m) {
   23.19 -  MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   23.20 -  nmethod* saved = _saved_nmethods;
   23.21 -  nmethod* prev = NULL;
   23.22 -  while (saved != NULL) {
   23.23 -    if (saved->is_in_use() && saved->method() == m) {
   23.24 -      if (prev != NULL) {
   23.25 -        prev->set_saved_nmethod_link(saved->saved_nmethod_link());
   23.26 -      } else {
   23.27 -        _saved_nmethods = saved->saved_nmethod_link();
   23.28 -      }
   23.29 -      assert(saved->is_speculatively_disconnected(), "shouldn't call for other nmethods");
   23.30 -      saved->set_speculatively_disconnected(false);
   23.31 -      saved->set_saved_nmethod_link(NULL);
   23.32 -      if (PrintMethodFlushing) {
   23.33 -        saved->print_on(tty, " ### nmethod is reconnected");
   23.34 -      }
   23.35 -      if (LogCompilation && (xtty != NULL)) {
   23.36 -        ttyLocker ttyl;
   23.37 -        xtty->begin_elem("nmethod_reconnected compile_id='%3d'", saved->compile_id());
   23.38 -        xtty->method(m);
   23.39 -        xtty->stamp();
   23.40 -        xtty->end_elem();
   23.41 -      }
   23.42 -      return saved;
   23.43 -    }
   23.44 -    prev = saved;
   23.45 -    saved = saved->saved_nmethod_link();
   23.46 -  }
   23.47 -  return NULL;
   23.48 -}
   23.49 -
   23.50 -/**
   23.51 - * Remove nmethod from the saved code list in order to discard it permanently
   23.52 - */
   23.53 -void CodeCache::remove_saved_code(nmethod* nm) {
   23.54 -  // For conc swpr this will be called with CodeCache_lock taken by caller
   23.55 -  assert_locked_or_safepoint(CodeCache_lock);
   23.56 -  assert(nm->is_speculatively_disconnected(), "shouldn't call for other nmethods");
   23.57 -  nmethod* saved = _saved_nmethods;
   23.58 -  nmethod* prev = NULL;
   23.59 -  while (saved != NULL) {
   23.60 -    if (saved == nm) {
   23.61 -      if (prev != NULL) {
   23.62 -        prev->set_saved_nmethod_link(saved->saved_nmethod_link());
   23.63 -      } else {
   23.64 -        _saved_nmethods = saved->saved_nmethod_link();
   23.65 -      }
   23.66 -      if (LogCompilation && (xtty != NULL)) {
   23.67 -        ttyLocker ttyl;
   23.68 -        xtty->begin_elem("nmethod_removed compile_id='%3d'", nm->compile_id());
   23.69 -        xtty->stamp();
   23.70 -        xtty->end_elem();
   23.71 -      }
   23.72 -      return;
   23.73 -    }
   23.74 -    prev = saved;
   23.75 -    saved = saved->saved_nmethod_link();
   23.76 -  }
   23.77 -  ShouldNotReachHere();
   23.78 -}
   23.79 -
   23.80 -void CodeCache::speculatively_disconnect(nmethod* nm) {
   23.81 -  assert_locked_or_safepoint(CodeCache_lock);
   23.82 -  assert(nm->is_in_use() && !nm->is_speculatively_disconnected(), "should only disconnect live nmethods");
   23.83 -  nm->set_saved_nmethod_link(_saved_nmethods);
   23.84 -  _saved_nmethods = nm;
   23.85 -  if (PrintMethodFlushing) {
   23.86 -    nm->print_on(tty, " ### nmethod is speculatively disconnected");
   23.87 -  }
   23.88 -  if (LogCompilation && (xtty != NULL)) {
   23.89 -    ttyLocker ttyl;
   23.90 -    xtty->begin_elem("nmethod_disconnected compile_id='%3d'", nm->compile_id());
   23.91 -    xtty->method(nm->method());
   23.92 -    xtty->stamp();
   23.93 -    xtty->end_elem();
   23.94 -  }
   23.95 -  nm->method()->clear_code();
   23.96 -  nm->set_speculatively_disconnected(true);
   23.97 -}
   23.98 -
   23.99  
  23.100  void CodeCache::gc_prologue() {
  23.101    assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_epilogue must be called");
  23.102  }
  23.103  
  23.104 -
  23.105  void CodeCache::gc_epilogue() {
  23.106    assert_locked_or_safepoint(CodeCache_lock);
  23.107    FOR_ALL_ALIVE_BLOBS(cb) {
    24.1 --- a/src/share/vm/code/codeCache.hpp	Sat Oct 05 03:14:53 2013 +0200
    24.2 +++ b/src/share/vm/code/codeCache.hpp	Fri Oct 04 21:00:43 2013 -0700
    24.3 @@ -57,7 +57,6 @@
    24.4    static int _number_of_nmethods_with_dependencies;
    24.5    static bool _needs_cache_clean;
    24.6    static nmethod* _scavenge_root_nmethods;  // linked via nm->scavenge_root_link()
    24.7 -  static nmethod* _saved_nmethods;          // Linked list of speculatively disconnected nmethods.
    24.8  
    24.9    static void verify_if_often() PRODUCT_RETURN;
   24.10  
   24.11 @@ -167,17 +166,12 @@
   24.12    static size_t  capacity()                      { return _heap->capacity(); }
   24.13    static size_t  max_capacity()                  { return _heap->max_capacity(); }
   24.14    static size_t  unallocated_capacity()          { return _heap->unallocated_capacity(); }
   24.15 -  static bool    needs_flushing()                { return unallocated_capacity() < CodeCacheFlushingMinimumFreeSpace; }
   24.16    static double  reverse_free_ratio();
   24.17  
   24.18    static bool needs_cache_clean()                { return _needs_cache_clean; }
   24.19    static void set_needs_cache_clean(bool v)      { _needs_cache_clean = v;    }
   24.20    static void clear_inline_caches();             // clear all inline caches
   24.21  
   24.22 -  static nmethod* reanimate_saved_code(Method* m);
   24.23 -  static void remove_saved_code(nmethod* nm);
   24.24 -  static void speculatively_disconnect(nmethod* nm);
   24.25 -
   24.26    // Deoptimization
   24.27    static int  mark_for_deoptimization(DepChange& changes);
   24.28  #ifdef HOTSWAP
    25.1 --- a/src/share/vm/code/nmethod.cpp	Sat Oct 05 03:14:53 2013 +0200
    25.2 +++ b/src/share/vm/code/nmethod.cpp	Fri Oct 04 21:00:43 2013 -0700
    25.3 @@ -462,7 +462,6 @@
    25.4    _state                      = alive;
    25.5    _marked_for_reclamation     = 0;
    25.6    _has_flushed_dependencies   = 0;
    25.7 -  _speculatively_disconnected = 0;
    25.8    _has_unsafe_access          = 0;
    25.9    _has_method_handle_invokes  = 0;
   25.10    _lazy_critical_native       = 0;
   25.11 @@ -481,7 +480,6 @@
   25.12    _osr_link                = NULL;
   25.13    _scavenge_root_link      = NULL;
   25.14    _scavenge_root_state     = 0;
   25.15 -  _saved_nmethod_link      = NULL;
   25.16    _compiler                = NULL;
   25.17  
   25.18  #ifdef HAVE_DTRACE_H
   25.19 @@ -686,6 +684,7 @@
   25.20      _osr_entry_point         = NULL;
   25.21      _exception_cache         = NULL;
   25.22      _pc_desc_cache.reset_to(NULL);
   25.23 +    _hotness_counter         = NMethodSweeper::hotness_counter_reset_val();
   25.24  
   25.25      code_buffer->copy_values_to(this);
   25.26      if (ScavengeRootsInCode && detect_scavenge_root_oops()) {
   25.27 @@ -770,6 +769,7 @@
   25.28      _osr_entry_point         = NULL;
   25.29      _exception_cache         = NULL;
   25.30      _pc_desc_cache.reset_to(NULL);
   25.31 +    _hotness_counter         = NMethodSweeper::hotness_counter_reset_val();
   25.32  
   25.33      code_buffer->copy_values_to(this);
   25.34      debug_only(verify_scavenge_root_oops());
   25.35 @@ -842,6 +842,7 @@
   25.36      _comp_level              = comp_level;
   25.37      _compiler                = compiler;
   25.38      _orig_pc_offset          = orig_pc_offset;
   25.39 +    _hotness_counter         = NMethodSweeper::hotness_counter_reset_val();
   25.40  
   25.41      // Section offsets
   25.42      _consts_offset           = content_offset()      + code_buffer->total_offset_of(code_buffer->consts());
   25.43 @@ -1176,7 +1177,7 @@
   25.44  
   25.45  // This is a private interface with the sweeper.
   25.46  void nmethod::mark_as_seen_on_stack() {
   25.47 -  assert(is_not_entrant(), "must be a non-entrant method");
   25.48 +  assert(is_alive(), "Must be an alive method");
   25.49    // Set the traversal mark to ensure that the sweeper does 2
   25.50    // cleaning passes before moving to zombie.
   25.51    set_stack_traversal_mark(NMethodSweeper::traversal_count());
   25.52 @@ -1261,7 +1262,7 @@
   25.53  
   25.54    set_osr_link(NULL);
   25.55    //set_scavenge_root_link(NULL); // done by prune_scavenge_root_nmethods
   25.56 -  NMethodSweeper::notify(this);
   25.57 +  NMethodSweeper::notify();
   25.58  }
   25.59  
   25.60  void nmethod::invalidate_osr_method() {
   25.61 @@ -1351,6 +1352,15 @@
   25.62        nmethod_needs_unregister = true;
   25.63      }
   25.64  
   25.65 +    // Must happen before state change. Otherwise we have a race condition in
   25.66 +    // nmethod::can_not_entrant_be_converted(). I.e., a method can immediately
   25.67 +    // transition its state from 'not_entrant' to 'zombie' without having to wait
   25.68 +    // for stack scanning.
   25.69 +    if (state == not_entrant) {
   25.70 +      mark_as_seen_on_stack();
   25.71 +      OrderAccess::storestore();
   25.72 +    }
   25.73 +
   25.74      // Change state
   25.75      _state = state;
   25.76  
   25.77 @@ -1369,11 +1379,6 @@
   25.78        HandleMark hm;
   25.79        method()->clear_code();
   25.80      }
   25.81 -
   25.82 -    if (state == not_entrant) {
   25.83 -      mark_as_seen_on_stack();
   25.84 -    }
   25.85 -
   25.86    } // leave critical region under Patching_lock
   25.87  
   25.88    // When the nmethod becomes zombie it is no longer alive so the
   25.89 @@ -1416,7 +1421,7 @@
   25.90    }
   25.91  
   25.92    // Make sweeper aware that there is a zombie method that needs to be removed
   25.93 -  NMethodSweeper::notify(this);
   25.94 +  NMethodSweeper::notify();
   25.95  
   25.96    return true;
   25.97  }
   25.98 @@ -1451,10 +1456,6 @@
   25.99      CodeCache::drop_scavenge_root_nmethod(this);
  25.100    }
  25.101  
  25.102 -  if (is_speculatively_disconnected()) {
  25.103 -    CodeCache::remove_saved_code(this);
  25.104 -  }
  25.105 -
  25.106  #ifdef SHARK
  25.107    ((SharkCompiler *) compiler())->free_compiled_method(insts_begin());
  25.108  #endif // SHARK
    26.1 --- a/src/share/vm/code/nmethod.hpp	Sat Oct 05 03:14:53 2013 +0200
    26.2 +++ b/src/share/vm/code/nmethod.hpp	Fri Oct 04 21:00:43 2013 -0700
    26.3 @@ -119,7 +119,6 @@
    26.4    // To support simple linked-list chaining of nmethods:
    26.5    nmethod*  _osr_link;         // from InstanceKlass::osr_nmethods_head
    26.6    nmethod*  _scavenge_root_link; // from CodeCache::scavenge_root_nmethods
    26.7 -  nmethod*  _saved_nmethod_link; // from CodeCache::speculatively_disconnect
    26.8  
    26.9    static nmethod* volatile _oops_do_mark_nmethods;
   26.10    nmethod*        volatile _oops_do_mark_link;
   26.11 @@ -165,7 +164,6 @@
   26.12  
   26.13    // protected by CodeCache_lock
   26.14    bool _has_flushed_dependencies;            // Used for maintenance of dependencies (CodeCache_lock)
   26.15 -  bool _speculatively_disconnected;          // Marked for potential unload
   26.16  
   26.17    bool _marked_for_reclamation;              // Used by NMethodSweeper (set only by sweeper)
   26.18    bool _marked_for_deoptimization;           // Used for stack deoptimization
   26.19 @@ -180,7 +178,7 @@
   26.20    unsigned int _has_wide_vectors:1;          // Preserve wide vectors at safepoints
   26.21  
   26.22    // Protected by Patching_lock
   26.23 -  unsigned char _state;                      // {alive, not_entrant, zombie, unloaded}
   26.24 +  volatile unsigned char _state;             // {alive, not_entrant, zombie, unloaded}
   26.25  
   26.26  #ifdef ASSERT
   26.27    bool _oops_are_stale;  // indicates that it's no longer safe to access oops section
   26.28 @@ -202,11 +200,18 @@
   26.29  
   26.30    // not_entrant method removal. Each mark_sweep pass will update
   26.31    // this mark to current sweep invocation count if it is seen on the
   26.32 -  // stack.  An not_entrant method can be removed when there is no
   26.33 +  // stack.  An not_entrant method can be removed when there are no
   26.34    // more activations, i.e., when the _stack_traversal_mark is less than
   26.35    // current sweep traversal index.
   26.36    long _stack_traversal_mark;
   26.37  
   26.38 +  // The _hotness_counter indicates the hotness of a method. The higher
   26.39 +  // the value the hotter the method. The hotness counter of a nmethod is
   26.40 +  // set to [(ReservedCodeCacheSize / (1024 * 1024)) * 2] each time the method
   26.41 +  // is active while stack scanning (mark_active_nmethods()). The hotness
   26.42 +  // counter is decreased (by 1) while sweeping.
   26.43 +  int _hotness_counter;
   26.44 +
   26.45    ExceptionCache *_exception_cache;
   26.46    PcDescCache     _pc_desc_cache;
   26.47  
   26.48 @@ -382,6 +387,10 @@
   26.49  
   26.50    int total_size        () const;
   26.51  
   26.52 +  void dec_hotness_counter()        { _hotness_counter--; }
   26.53 +  void set_hotness_counter(int val) { _hotness_counter = val; }
   26.54 +  int  hotness_counter() const      { return _hotness_counter; }
   26.55 +
   26.56    // Containment
   26.57    bool consts_contains       (address addr) const { return consts_begin       () <= addr && addr < consts_end       (); }
   26.58    bool insts_contains        (address addr) const { return insts_begin        () <= addr && addr < insts_end        (); }
   26.59 @@ -408,8 +417,8 @@
   26.60    // alive.  It is used when an uncommon trap happens.  Returns true
   26.61    // if this thread changed the state of the nmethod or false if
   26.62    // another thread performed the transition.
   26.63 -  bool  make_not_entrant()                        { return make_not_entrant_or_zombie(not_entrant); }
   26.64 -  bool  make_zombie()                             { return make_not_entrant_or_zombie(zombie); }
   26.65 +  bool  make_not_entrant() { return make_not_entrant_or_zombie(not_entrant); }
   26.66 +  bool  make_zombie()      { return make_not_entrant_or_zombie(zombie); }
   26.67  
   26.68    // used by jvmti to track if the unload event has been reported
   26.69    bool  unload_reported()                         { return _unload_reported; }
   26.70 @@ -437,9 +446,6 @@
   26.71    bool  has_method_handle_invokes() const         { return _has_method_handle_invokes; }
   26.72    void  set_has_method_handle_invokes(bool z)     { _has_method_handle_invokes = z; }
   26.73  
   26.74 -  bool  is_speculatively_disconnected() const     { return _speculatively_disconnected; }
   26.75 -  void  set_speculatively_disconnected(bool z)    { _speculatively_disconnected = z; }
   26.76 -
   26.77    bool  is_lazy_critical_native() const           { return _lazy_critical_native; }
   26.78    void  set_lazy_critical_native(bool z)          { _lazy_critical_native = z; }
   26.79  
   26.80 @@ -499,9 +505,6 @@
   26.81    nmethod* scavenge_root_link() const                  { return _scavenge_root_link; }
   26.82    void     set_scavenge_root_link(nmethod *n)          { _scavenge_root_link = n; }
   26.83  
   26.84 -  nmethod* saved_nmethod_link() const                  { return _saved_nmethod_link; }
   26.85 -  void     set_saved_nmethod_link(nmethod *n)          { _saved_nmethod_link = n; }
   26.86 -
   26.87   public:
   26.88  
   26.89    // Sweeper support
    27.1 --- a/src/share/vm/compiler/compileBroker.cpp	Sat Oct 05 03:14:53 2013 +0200
    27.2 +++ b/src/share/vm/compiler/compileBroker.cpp	Fri Oct 04 21:00:43 2013 -0700
    27.3 @@ -634,19 +634,36 @@
    27.4    NMethodSweeper::possibly_sweep();
    27.5  
    27.6    MutexLocker locker(lock());
    27.7 -  // Wait for an available CompileTask.
    27.8 +  // If _first is NULL we have no more compile jobs. There are two reasons for
    27.9 +  // having no compile jobs: First, we compiled everything we wanted. Second,
   27.10 +  // we ran out of code cache so compilation has been disabled. In the latter
   27.11 +  // case we perform code cache sweeps to free memory such that we can re-enable
   27.12 +  // compilation.
   27.13    while (_first == NULL) {
   27.14 -    // There is no work to be done right now.  Wait.
   27.15 -    if (UseCodeCacheFlushing && (!CompileBroker::should_compile_new_jobs() || CodeCache::needs_flushing())) {
   27.16 -      // During the emergency sweeping periods, wake up and sweep occasionally
   27.17 -      bool timedout = lock()->wait(!Mutex::_no_safepoint_check_flag, NmethodSweepCheckInterval*1000);
   27.18 -      if (timedout) {
   27.19 +    if (UseCodeCacheFlushing && !CompileBroker::should_compile_new_jobs()) {
   27.20 +      // Wait a certain amount of time to possibly do another sweep.
   27.21 +      // We must wait until stack scanning has happened so that we can
   27.22 +      // transition a method's state from 'not_entrant' to 'zombie'.
   27.23 +      long wait_time = NmethodSweepCheckInterval * 1000;
   27.24 +      if (FLAG_IS_DEFAULT(NmethodSweepCheckInterval)) {
   27.25 +        // Only one thread at a time can do sweeping. Scale the
   27.26 +        // wait time according to the number of compiler threads.
   27.27 +        // As a result, the next sweep is likely to happen every 100ms
   27.28 +        // with an arbitrary number of threads that do sweeping.
   27.29 +        wait_time = 100 * CICompilerCount;
   27.30 +      }
   27.31 +      bool timeout = lock()->wait(!Mutex::_no_safepoint_check_flag, wait_time);
   27.32 +      if (timeout) {
   27.33          MutexUnlocker ul(lock());
   27.34 -        // When otherwise not busy, run nmethod sweeping
   27.35          NMethodSweeper::possibly_sweep();
   27.36        }
   27.37      } else {
   27.38 -      // During normal operation no need to wake up on timer
   27.39 +      // If there are no compilation tasks and we can compile new jobs
   27.40 +      // (i.e., there is enough free space in the code cache) there is
   27.41 +      // no need to invoke the sweeper. As a result, the hotness of methods
   27.42 +      // remains unchanged. This behavior is desired, since we want to keep
   27.43 +      // the stable state, i.e., we do not want to evict methods from the
   27.44 +      // code cache if it is unnecessary.
   27.45        lock()->wait();
   27.46      }
   27.47    }
   27.48 @@ -1227,16 +1244,9 @@
   27.49          return method_code;
   27.50        }
   27.51      }
   27.52 -    if (method->is_not_compilable(comp_level)) return NULL;
   27.53 -
   27.54 -    if (UseCodeCacheFlushing) {
   27.55 -      nmethod* saved = CodeCache::reanimate_saved_code(method());
   27.56 -      if (saved != NULL) {
   27.57 -        method->set_code(method, saved);
   27.58 -        return saved;
   27.59 -      }
   27.60 +    if (method->is_not_compilable(comp_level)) {
   27.61 +      return NULL;
   27.62      }
   27.63 -
   27.64    } else {
   27.65      // osr compilation
   27.66  #ifndef TIERED
   27.67 @@ -1585,9 +1595,6 @@
   27.68        if (CodeCache::unallocated_capacity() < CodeCacheMinimumFreeSpace) {
   27.69          // the code cache is really full
   27.70          handle_full_code_cache();
   27.71 -      } else if (UseCodeCacheFlushing && CodeCache::needs_flushing()) {
   27.72 -        // Attempt to start cleaning the code cache while there is still a little headroom
   27.73 -        NMethodSweeper::handle_full_code_cache(false);
   27.74        }
   27.75  
   27.76        CompileTask* task = queue->get();
   27.77 @@ -1943,7 +1950,11 @@
   27.78      }
   27.79  #endif
   27.80      if (UseCodeCacheFlushing) {
   27.81 -      NMethodSweeper::handle_full_code_cache(true);
   27.82 +      // Since code cache is full, immediately stop new compiles
   27.83 +      if (CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation)) {
   27.84 +        NMethodSweeper::log_sweep("disable_compiler");
   27.85 +        NMethodSweeper::possibly_sweep();
   27.86 +      }
   27.87      } else {
   27.88        UseCompiler               = false;
   27.89        AlwaysCompileLoopMethods  = false;
    28.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp	Sat Oct 05 03:14:53 2013 +0200
    28.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp	Fri Oct 04 21:00:43 2013 -0700
    28.3 @@ -81,7 +81,7 @@
    28.4                                           size_t* marked_bytes_array,
    28.5                                           BitMap* task_card_bm) {
    28.6    G1CollectedHeap* g1h = _g1h;
    28.7 -  CardTableModRefBS* ct_bs = (CardTableModRefBS*) (g1h->barrier_set());
    28.8 +  CardTableModRefBS* ct_bs = g1h->g1_barrier_set();
    28.9  
   28.10    HeapWord* start = mr.start();
   28.11    HeapWord* end = mr.end();
    29.1 --- a/src/share/vm/gc_implementation/g1/g1CardCounts.cpp	Sat Oct 05 03:14:53 2013 +0200
    29.2 +++ b/src/share/vm/gc_implementation/g1/g1CardCounts.cpp	Fri Oct 04 21:00:43 2013 -0700
    29.3 @@ -65,9 +65,7 @@
    29.4      // threshold limit is no more than this.
    29.5      guarantee(G1ConcRSHotCardLimit <= max_jubyte, "sanity");
    29.6  
    29.7 -    ModRefBarrierSet* bs = _g1h->mr_bs();
    29.8 -    guarantee(bs->is_a(BarrierSet::CardTableModRef), "Precondition");
    29.9 -    _ct_bs = (CardTableModRefBS*)bs;
   29.10 +    _ct_bs = _g1h->g1_barrier_set();
   29.11      _ct_bot = _ct_bs->byte_for_const(_g1h->reserved_region().start());
   29.12  
   29.13      // Allocate/Reserve the counts table
    30.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Sat Oct 05 03:14:53 2013 +0200
    30.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Fri Oct 04 21:00:43 2013 -0700
    30.3 @@ -125,10 +125,8 @@
    30.4    int _histo[256];
    30.5  public:
    30.6    ClearLoggedCardTableEntryClosure() :
    30.7 -    _calls(0)
    30.8 +    _calls(0), _g1h(G1CollectedHeap::heap()), _ctbs(_g1h->g1_barrier_set())
    30.9    {
   30.10 -    _g1h = G1CollectedHeap::heap();
   30.11 -    _ctbs = (CardTableModRefBS*)_g1h->barrier_set();
   30.12      for (int i = 0; i < 256; i++) _histo[i] = 0;
   30.13    }
   30.14    bool do_card_ptr(jbyte* card_ptr, int worker_i) {
   30.15 @@ -158,11 +156,8 @@
   30.16    CardTableModRefBS* _ctbs;
   30.17  public:
   30.18    RedirtyLoggedCardTableEntryClosure() :
   30.19 -    _calls(0)
   30.20 -  {
   30.21 -    _g1h = G1CollectedHeap::heap();
   30.22 -    _ctbs = (CardTableModRefBS*)_g1h->barrier_set();
   30.23 -  }
   30.24 +    _calls(0), _g1h(G1CollectedHeap::heap()), _ctbs(_g1h->g1_barrier_set()) {}
   30.25 +
   30.26    bool do_card_ptr(jbyte* card_ptr, int worker_i) {
   30.27      if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) {
   30.28        _calls++;
   30.29 @@ -478,7 +473,7 @@
   30.30  
   30.31  void G1CollectedHeap::check_ct_logs_at_safepoint() {
   30.32    DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
   30.33 -  CardTableModRefBS* ct_bs = (CardTableModRefBS*)barrier_set();
   30.34 +  CardTableModRefBS* ct_bs = g1_barrier_set();
   30.35  
   30.36    // Count the dirty cards at the start.
   30.37    CountNonCleanMemRegionClosure count1(this);
   30.38 @@ -1205,7 +1200,7 @@
   30.39  };
   30.40  
   30.41  void G1CollectedHeap::clear_rsets_post_compaction() {
   30.42 -  PostMCRemSetClearClosure rs_clear(this, mr_bs());
   30.43 +  PostMCRemSetClearClosure rs_clear(this, g1_barrier_set());
   30.44    heap_region_iterate(&rs_clear);
   30.45  }
   30.46  
   30.47 @@ -1777,7 +1772,6 @@
   30.48  }
   30.49  
   30.50  bool G1CollectedHeap::expand(size_t expand_bytes) {
   30.51 -  size_t old_mem_size = _g1_storage.committed_size();
   30.52    size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes);
   30.53    aligned_expand_bytes = align_size_up(aligned_expand_bytes,
   30.54                                         HeapRegion::GrainBytes);
   30.55 @@ -1787,6 +1781,13 @@
   30.56                  ergo_format_byte("attempted expansion amount"),
   30.57                  expand_bytes, aligned_expand_bytes);
   30.58  
   30.59 +  if (_g1_storage.uncommitted_size() == 0) {
   30.60 +    ergo_verbose0(ErgoHeapSizing,
   30.61 +                      "did not expand the heap",
   30.62 +                      ergo_format_reason("heap already fully expanded"));
   30.63 +    return false;
   30.64 +  }
   30.65 +
   30.66    // First commit the memory.
   30.67    HeapWord* old_end = (HeapWord*) _g1_storage.high();
   30.68    bool successful = _g1_storage.expand_by(aligned_expand_bytes);
   30.69 @@ -1845,7 +1846,6 @@
   30.70  }
   30.71  
   30.72  void G1CollectedHeap::shrink_helper(size_t shrink_bytes) {
   30.73 -  size_t old_mem_size = _g1_storage.committed_size();
   30.74    size_t aligned_shrink_bytes =
   30.75      ReservedSpace::page_align_size_down(shrink_bytes);
   30.76    aligned_shrink_bytes = align_size_down(aligned_shrink_bytes,
   30.77 @@ -2045,20 +2045,13 @@
   30.78    // Create the gen rem set (and barrier set) for the entire reserved region.
   30.79    _rem_set = collector_policy()->create_rem_set(_reserved, 2);
   30.80    set_barrier_set(rem_set()->bs());
   30.81 -  if (barrier_set()->is_a(BarrierSet::ModRef)) {
   30.82 -    _mr_bs = (ModRefBarrierSet*)_barrier_set;
   30.83 -  } else {
   30.84 -    vm_exit_during_initialization("G1 requires a mod ref bs.");
   30.85 +  if (!barrier_set()->is_a(BarrierSet::G1SATBCTLogging)) {
   30.86 +    vm_exit_during_initialization("G1 requires a G1SATBLoggingCardTableModRefBS");
   30.87      return JNI_ENOMEM;
   30.88    }
   30.89  
   30.90    // Also create a G1 rem set.
   30.91 -  if (mr_bs()->is_a(BarrierSet::CardTableModRef)) {
   30.92 -    _g1_rem_set = new G1RemSet(this, (CardTableModRefBS*)mr_bs());
   30.93 -  } else {
   30.94 -    vm_exit_during_initialization("G1 requires a cardtable mod ref bs.");
   30.95 -    return JNI_ENOMEM;
   30.96 -  }
   30.97 +  _g1_rem_set = new G1RemSet(this, g1_barrier_set());
   30.98  
   30.99    // Carve out the G1 part of the heap.
  30.100  
  30.101 @@ -3681,6 +3674,11 @@
  30.102    assert(InlineCacheBuffer::is_empty(), "should have cleaned up ICBuffer");
  30.103    // Fill TLAB's and such
  30.104    ensure_parsability(true);
  30.105 +
  30.106 +  if (G1SummarizeRSetStats && (G1SummarizeRSetStatsPeriod > 0) &&
  30.107 +      (total_collections() % G1SummarizeRSetStatsPeriod == 0)) {
  30.108 +    g1_rem_set()->print_periodic_summary_info("Before GC RS summary");
  30.109 +  }
  30.110  }
  30.111  
  30.112  void G1CollectedHeap::gc_epilogue(bool full /* Ignored */) {
  30.113 @@ -3689,7 +3687,7 @@
  30.114        (G1SummarizeRSetStatsPeriod > 0) &&
  30.115        // we are at the end of the GC. Total collections has already been increased.
  30.116        ((total_collections() - 1) % G1SummarizeRSetStatsPeriod == 0)) {
  30.117 -    g1_rem_set()->print_periodic_summary_info();
  30.118 +    g1_rem_set()->print_periodic_summary_info("After GC RS summary");
  30.119    }
  30.120  
  30.121    // FIXME: what is this about?
  30.122 @@ -4550,7 +4548,7 @@
  30.123    : _g1h(g1h),
  30.124      _refs(g1h->task_queue(queue_num)),
  30.125      _dcq(&g1h->dirty_card_queue_set()),
  30.126 -    _ct_bs((CardTableModRefBS*)_g1h->barrier_set()),
  30.127 +    _ct_bs(g1h->g1_barrier_set()),
  30.128      _g1_rem(g1h->g1_rem_set()),
  30.129      _hash_seed(17), _queue_num(queue_num),
  30.130      _term_attempts(0),
  30.131 @@ -5979,11 +5977,11 @@
  30.132  }
  30.133  
  30.134  class G1ParCleanupCTTask : public AbstractGangTask {
  30.135 -  CardTableModRefBS* _ct_bs;
  30.136 +  G1SATBCardTableModRefBS* _ct_bs;
  30.137    G1CollectedHeap* _g1h;
  30.138    HeapRegion* volatile _su_head;
  30.139  public:
  30.140 -  G1ParCleanupCTTask(CardTableModRefBS* ct_bs,
  30.141 +  G1ParCleanupCTTask(G1SATBCardTableModRefBS* ct_bs,
  30.142                       G1CollectedHeap* g1h) :
  30.143      AbstractGangTask("G1 Par Cleanup CT Task"),
  30.144      _ct_bs(ct_bs), _g1h(g1h) { }
  30.145 @@ -6006,9 +6004,9 @@
  30.146  #ifndef PRODUCT
  30.147  class G1VerifyCardTableCleanup: public HeapRegionClosure {
  30.148    G1CollectedHeap* _g1h;
  30.149 -  CardTableModRefBS* _ct_bs;
  30.150 +  G1SATBCardTableModRefBS* _ct_bs;
  30.151  public:
  30.152 -  G1VerifyCardTableCleanup(G1CollectedHeap* g1h, CardTableModRefBS* ct_bs)
  30.153 +  G1VerifyCardTableCleanup(G1CollectedHeap* g1h, G1SATBCardTableModRefBS* ct_bs)
  30.154      : _g1h(g1h), _ct_bs(ct_bs) { }
  30.155    virtual bool doHeapRegion(HeapRegion* r) {
  30.156      if (r->is_survivor()) {
  30.157 @@ -6022,7 +6020,7 @@
  30.158  
  30.159  void G1CollectedHeap::verify_not_dirty_region(HeapRegion* hr) {
  30.160    // All of the region should be clean.
  30.161 -  CardTableModRefBS* ct_bs = (CardTableModRefBS*)barrier_set();
  30.162 +  G1SATBCardTableModRefBS* ct_bs = g1_barrier_set();
  30.163    MemRegion mr(hr->bottom(), hr->end());
  30.164    ct_bs->verify_not_dirty_region(mr);
  30.165  }
  30.166 @@ -6035,13 +6033,13 @@
  30.167    // not dirty that area (one less thing to have to do while holding
  30.168    // a lock). So we can only verify that [bottom(),pre_dummy_top()]
  30.169    // is dirty.
  30.170 -  CardTableModRefBS* ct_bs = (CardTableModRefBS*) barrier_set();
  30.171 +  G1SATBCardTableModRefBS* ct_bs = g1_barrier_set();
  30.172    MemRegion mr(hr->bottom(), hr->pre_dummy_top());
  30.173    ct_bs->verify_dirty_region(mr);
  30.174  }
  30.175  
  30.176  void G1CollectedHeap::verify_dirty_young_list(HeapRegion* head) {
  30.177 -  CardTableModRefBS* ct_bs = (CardTableModRefBS*) barrier_set();
  30.178 +  G1SATBCardTableModRefBS* ct_bs = g1_barrier_set();
  30.179    for (HeapRegion* hr = head; hr != NULL; hr = hr->get_next_young_region()) {
  30.180      verify_dirty_region(hr);
  30.181    }
  30.182 @@ -6053,7 +6051,7 @@
  30.183  #endif
  30.184  
  30.185  void G1CollectedHeap::cleanUpCardTable() {
  30.186 -  CardTableModRefBS* ct_bs = (CardTableModRefBS*) (barrier_set());
  30.187 +  G1SATBCardTableModRefBS* ct_bs = g1_barrier_set();
  30.188    double start = os::elapsedTime();
  30.189  
  30.190    {
    31.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Sat Oct 05 03:14:53 2013 +0200
    31.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Fri Oct 04 21:00:43 2013 -0700
    31.3 @@ -31,6 +31,7 @@
    31.4  #include "gc_implementation/g1/g1HRPrinter.hpp"
    31.5  #include "gc_implementation/g1/g1MonitoringSupport.hpp"
    31.6  #include "gc_implementation/g1/g1RemSet.hpp"
    31.7 +#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
    31.8  #include "gc_implementation/g1/g1YCTypes.hpp"
    31.9  #include "gc_implementation/g1/heapRegionSeq.hpp"
   31.10  #include "gc_implementation/g1/heapRegionSets.hpp"
   31.11 @@ -791,8 +792,6 @@
   31.12  
   31.13    // The g1 remembered set of the heap.
   31.14    G1RemSet* _g1_rem_set;
   31.15 -  // And it's mod ref barrier set, used to track updates for the above.
   31.16 -  ModRefBarrierSet* _mr_bs;
   31.17  
   31.18    // A set of cards that cover the objects for which the Rsets should be updated
   31.19    // concurrently after the collection.
   31.20 @@ -1127,7 +1126,6 @@
   31.21  
   31.22    // The rem set and barrier set.
   31.23    G1RemSet* g1_rem_set() const { return _g1_rem_set; }
   31.24 -  ModRefBarrierSet* mr_bs() const { return _mr_bs; }
   31.25  
   31.26    unsigned get_gc_time_stamp() {
   31.27      return _gc_time_stamp;
   31.28 @@ -1346,6 +1344,10 @@
   31.29  
   31.30    virtual bool is_in_closed_subset(const void* p) const;
   31.31  
   31.32 +  G1SATBCardTableModRefBS* g1_barrier_set() {
   31.33 +    return (G1SATBCardTableModRefBS*) barrier_set();
   31.34 +  }
   31.35 +
   31.36    // This resets the card table to all zeros.  It is used after
   31.37    // a collection pause which used the card table to claim cards.
   31.38    void cleanUpCardTable();
   31.39 @@ -1875,7 +1877,7 @@
   31.40    G1CollectedHeap* _g1h;
   31.41    RefToScanQueue*  _refs;
   31.42    DirtyCardQueue   _dcq;
   31.43 -  CardTableModRefBS* _ct_bs;
   31.44 +  G1SATBCardTableModRefBS* _ct_bs;
   31.45    G1RemSet* _g1_rem;
   31.46  
   31.47    G1ParGCAllocBufferContainer  _surviving_alloc_buffer;
   31.48 @@ -1914,7 +1916,7 @@
   31.49    void   add_to_undo_waste(size_t waste)         { _undo_waste += waste; }
   31.50  
   31.51    DirtyCardQueue& dirty_card_queue()             { return _dcq;  }
   31.52 -  CardTableModRefBS* ctbs()                      { return _ct_bs; }
   31.53 +  G1SATBCardTableModRefBS* ctbs()                { return _ct_bs; }
   31.54  
   31.55    template <class T> void immediate_rs_update(HeapRegion* from, T* p, int tid) {
   31.56      if (!from->is_survivor()) {
    32.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp	Sat Oct 05 03:14:53 2013 +0200
    32.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp	Fri Oct 04 21:00:43 2013 -0700
    32.3 @@ -134,7 +134,7 @@
    32.4    assert(containing_hr->is_in(end - 1), "it should also contain end - 1");
    32.5  
    32.6    MemRegion mr(start, end);
    32.7 -  ((CardTableModRefBS*)_g1h->barrier_set())->dirty(mr);
    32.8 +  g1_barrier_set()->dirty(mr);
    32.9  }
   32.10  
   32.11  inline RefToScanQueue* G1CollectedHeap::task_queue(int i) const {
    33.1 --- a/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp	Sat Oct 05 03:14:53 2013 +0200
    33.2 +++ b/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp	Fri Oct 04 21:00:43 2013 -0700
    33.3 @@ -41,11 +41,11 @@
    33.4  private:
    33.5    G1CollectedHeap* _g1;
    33.6    DirtyCardQueue *_dcq;
    33.7 -  CardTableModRefBS* _ct_bs;
    33.8 +  G1SATBCardTableModRefBS* _ct_bs;
    33.9  
   33.10  public:
   33.11    UpdateRSetDeferred(G1CollectedHeap* g1, DirtyCardQueue* dcq) :
   33.12 -    _g1(g1), _ct_bs((CardTableModRefBS*)_g1->barrier_set()), _dcq(dcq) {}
   33.13 +    _g1(g1), _ct_bs(_g1->g1_barrier_set()), _dcq(dcq) {}
   33.14  
   33.15    virtual void do_oop(narrowOop* p) { do_oop_work(p); }
   33.16    virtual void do_oop(      oop* p) { do_oop_work(p); }
    34.1 --- a/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Sat Oct 05 03:14:53 2013 +0200
    34.2 +++ b/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Fri Oct 04 21:00:43 2013 -0700
    34.3 @@ -220,7 +220,7 @@
    34.4  public:
    34.5    G1PrepareCompactClosure(CompactibleSpace* cs)
    34.6    : _g1h(G1CollectedHeap::heap()),
    34.7 -    _mrbs(G1CollectedHeap::heap()->mr_bs()),
    34.8 +    _mrbs(_g1h->g1_barrier_set()),
    34.9      _cp(NULL, cs, cs->initialize_threshold()),
   34.10      _humongous_proxy_set("G1MarkSweep Humongous Proxy Set") { }
   34.11  
    35.1 --- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Sat Oct 05 03:14:53 2013 +0200
    35.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Fri Oct 04 21:00:43 2013 -0700
    35.3 @@ -83,7 +83,9 @@
    35.4    for (uint i = 0; i < n_workers(); i++) {
    35.5      _cset_rs_update_cl[i] = NULL;
    35.6    }
    35.7 -  _prev_period_summary.initialize(this, n_workers());
    35.8 +  if (G1SummarizeRSetStats) {
    35.9 +    _prev_period_summary.initialize(this);
   35.10 +  }
   35.11  }
   35.12  
   35.13  G1RemSet::~G1RemSet() {
   35.14 @@ -109,7 +111,7 @@
   35.15    CodeBlobToOopClosure* _code_root_cl;
   35.16  
   35.17    G1BlockOffsetSharedArray* _bot_shared;
   35.18 -  CardTableModRefBS *_ct_bs;
   35.19 +  G1SATBCardTableModRefBS *_ct_bs;
   35.20  
   35.21    double _strong_code_root_scan_time_sec;
   35.22    int    _worker_i;
   35.23 @@ -130,7 +132,7 @@
   35.24    {
   35.25      _g1h = G1CollectedHeap::heap();
   35.26      _bot_shared = _g1h->bot_shared();
   35.27 -    _ct_bs = (CardTableModRefBS*) (_g1h->barrier_set());
   35.28 +    _ct_bs = _g1h->g1_barrier_set();
   35.29      _block_size = MAX2<int>(G1RSetScanBlockSize, 1);
   35.30    }
   35.31  
   35.32 @@ -505,12 +507,7 @@
   35.33    ScrubRSClosure(BitMap* region_bm, BitMap* card_bm) :
   35.34      _g1h(G1CollectedHeap::heap()),
   35.35      _region_bm(region_bm), _card_bm(card_bm),
   35.36 -    _ctbs(NULL)
   35.37 -  {
   35.38 -    ModRefBarrierSet* bs = _g1h->mr_bs();
   35.39 -    guarantee(bs->is_a(BarrierSet::CardTableModRef), "Precondition");
   35.40 -    _ctbs = (CardTableModRefBS*)bs;
   35.41 -  }
   35.42 +    _ctbs(_g1h->g1_barrier_set()) {}
   35.43  
   35.44    bool doHeapRegion(HeapRegion* r) {
   35.45      if (!r->continuesHumongous()) {
   35.46 @@ -731,19 +728,19 @@
   35.47    return has_refs_into_cset;
   35.48  }
   35.49  
   35.50 -void G1RemSet::print_periodic_summary_info() {
   35.51 +void G1RemSet::print_periodic_summary_info(const char* header) {
   35.52    G1RemSetSummary current;
   35.53 -  current.initialize(this, n_workers());
   35.54 +  current.initialize(this);
   35.55  
   35.56    _prev_period_summary.subtract_from(&current);
   35.57 -  print_summary_info(&_prev_period_summary);
   35.58 +  print_summary_info(&_prev_period_summary, header);
   35.59  
   35.60    _prev_period_summary.set(&current);
   35.61  }
   35.62  
   35.63  void G1RemSet::print_summary_info() {
   35.64    G1RemSetSummary current;
   35.65 -  current.initialize(this, n_workers());
   35.66 +  current.initialize(this);
   35.67  
   35.68    print_summary_info(&current, " Cumulative RS summary");
   35.69  }
    36.1 --- a/src/share/vm/gc_implementation/g1/g1RemSet.hpp	Sat Oct 05 03:14:53 2013 +0200
    36.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.hpp	Fri Oct 04 21:00:43 2013 -0700
    36.3 @@ -145,7 +145,7 @@
    36.4    virtual void print_summary_info();
    36.5  
    36.6    // Print accumulated summary info from the last time called.
    36.7 -  virtual void print_periodic_summary_info();
    36.8 +  virtual void print_periodic_summary_info(const char* header);
    36.9  
   36.10    // Prepare remembered set for verification.
   36.11    virtual void prepare_for_verify();
    37.1 --- a/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp	Sat Oct 05 03:14:53 2013 +0200
    37.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp	Fri Oct 04 21:00:43 2013 -0700
    37.3 @@ -77,12 +77,12 @@
    37.4    return _rs_threads_vtimes[thread];
    37.5  }
    37.6  
    37.7 -void G1RemSetSummary::initialize(G1RemSet* remset, uint num_workers) {
    37.8 +void G1RemSetSummary::initialize(G1RemSet* remset) {
    37.9    assert(_rs_threads_vtimes == NULL, "just checking");
   37.10    assert(remset != NULL, "just checking");
   37.11  
   37.12    _remset = remset;
   37.13 -  _num_vtimes = num_workers;
   37.14 +  _num_vtimes = ConcurrentG1Refine::thread_num();
   37.15    _rs_threads_vtimes = NEW_C_HEAP_ARRAY(double, _num_vtimes, mtGC);
   37.16    memset(_rs_threads_vtimes, 0, sizeof(double) * _num_vtimes);
   37.17  
   37.18 @@ -125,25 +125,115 @@
   37.19    _sampling_thread_vtime = other->sampling_thread_vtime() - _sampling_thread_vtime;
   37.20  }
   37.21  
   37.22 +static double percent_of(size_t numerator, size_t denominator) {
   37.23 +  if (denominator != 0) {
   37.24 +    return (double)numerator / denominator * 100.0f;
   37.25 +  } else {
   37.26 +    return 0.0f;
   37.27 +  }
   37.28 +}
   37.29 +
   37.30 +static size_t round_to_K(size_t value) {
   37.31 +  return value / K;
   37.32 +}
   37.33 +
   37.34 +class RegionTypeCounter VALUE_OBJ_CLASS_SPEC {
   37.35 +private:
   37.36 +  const char* _name;
   37.37 +
   37.38 +  size_t _rs_mem_size;
   37.39 +  size_t _cards_occupied;
   37.40 +  size_t _amount;
   37.41 +
   37.42 +  size_t _code_root_mem_size;
   37.43 +  size_t _code_root_elems;
   37.44 +
   37.45 +  double rs_mem_size_percent_of(size_t total) {
   37.46 +    return percent_of(_rs_mem_size, total);
   37.47 +  }
   37.48 +
   37.49 +  double cards_occupied_percent_of(size_t total) {
   37.50 +    return percent_of(_cards_occupied, total);
   37.51 +  }
   37.52 +
   37.53 +  double code_root_mem_size_percent_of(size_t total) {
   37.54 +    return percent_of(_code_root_mem_size, total);
   37.55 +  }
   37.56 +
   37.57 +  double code_root_elems_percent_of(size_t total) {
   37.58 +    return percent_of(_code_root_elems, total);
   37.59 +  }
   37.60 +
   37.61 +  size_t amount() const { return _amount; }
   37.62 +
   37.63 +public:
   37.64 +
   37.65 +  RegionTypeCounter(const char* name) : _name(name), _rs_mem_size(0), _cards_occupied(0),
   37.66 +    _amount(0), _code_root_mem_size(0), _code_root_elems(0) { }
   37.67 +
   37.68 +  void add(size_t rs_mem_size, size_t cards_occupied, size_t code_root_mem_size,
   37.69 +    size_t code_root_elems) {
   37.70 +    _rs_mem_size += rs_mem_size;
   37.71 +    _cards_occupied += cards_occupied;
   37.72 +    _code_root_mem_size += code_root_mem_size;
   37.73 +    _code_root_elems += code_root_elems;
   37.74 +    _amount++;
   37.75 +  }
   37.76 +
   37.77 +  size_t rs_mem_size() const { return _rs_mem_size; }
   37.78 +  size_t cards_occupied() const { return _cards_occupied; }
   37.79 +
   37.80 +  size_t code_root_mem_size() const { return _code_root_mem_size; }
   37.81 +  size_t code_root_elems() const { return _code_root_elems; }
   37.82 +
   37.83 +  void print_rs_mem_info_on(outputStream * out, size_t total) {
   37.84 +    out->print_cr("    %8dK (%5.1f%%) by %zd %s regions", round_to_K(rs_mem_size()), rs_mem_size_percent_of(total), amount(), _name);
   37.85 +  }
   37.86 +
   37.87 +  void print_cards_occupied_info_on(outputStream * out, size_t total) {
   37.88 +    out->print_cr("     %8d (%5.1f%%) entries by %zd %s regions", cards_occupied(), cards_occupied_percent_of(total), amount(), _name);
   37.89 +  }
   37.90 +
   37.91 +  void print_code_root_mem_info_on(outputStream * out, size_t total) {
   37.92 +    out->print_cr("    %8dK (%5.1f%%) by %zd %s regions", round_to_K(code_root_mem_size()), code_root_mem_size_percent_of(total), amount(), _name);
   37.93 +  }
   37.94 +
   37.95 +  void print_code_root_elems_info_on(outputStream * out, size_t total) {
   37.96 +    out->print_cr("     %8d (%5.1f%%) elements by %zd %s regions", code_root_elems(), code_root_elems_percent_of(total), amount(), _name);
   37.97 +  }
   37.98 +};
   37.99 +
  37.100 +
  37.101  class HRRSStatsIter: public HeapRegionClosure {
  37.102 -  size_t _occupied;
  37.103 +private:
  37.104 +  RegionTypeCounter _young;
  37.105 +  RegionTypeCounter _humonguous;
  37.106 +  RegionTypeCounter _free;
  37.107 +  RegionTypeCounter _old;
  37.108 +  RegionTypeCounter _all;
  37.109  
  37.110 -  size_t _total_rs_mem_sz;
  37.111    size_t _max_rs_mem_sz;
  37.112    HeapRegion* _max_rs_mem_sz_region;
  37.113  
  37.114 -  size_t _total_code_root_mem_sz;
  37.115 +  size_t total_rs_mem_sz() const            { return _all.rs_mem_size(); }
  37.116 +  size_t total_cards_occupied() const       { return _all.cards_occupied(); }
  37.117 +
  37.118 +  size_t max_rs_mem_sz() const              { return _max_rs_mem_sz; }
  37.119 +  HeapRegion* max_rs_mem_sz_region() const  { return _max_rs_mem_sz_region; }
  37.120 +
  37.121    size_t _max_code_root_mem_sz;
  37.122    HeapRegion* _max_code_root_mem_sz_region;
  37.123 +
  37.124 +  size_t total_code_root_mem_sz() const     { return _all.code_root_mem_size(); }
  37.125 +  size_t total_code_root_elems() const      { return _all.code_root_elems(); }
  37.126 +
  37.127 +  size_t max_code_root_mem_sz() const       { return _max_code_root_mem_sz; }
  37.128 +  HeapRegion* max_code_root_mem_sz_region() const { return _max_code_root_mem_sz_region; }
  37.129 +
  37.130  public:
  37.131 -  HRRSStatsIter() :
  37.132 -    _occupied(0),
  37.133 -    _total_rs_mem_sz(0),
  37.134 -    _max_rs_mem_sz(0),
  37.135 -    _max_rs_mem_sz_region(NULL),
  37.136 -    _total_code_root_mem_sz(0),
  37.137 -    _max_code_root_mem_sz(0),
  37.138 -    _max_code_root_mem_sz_region(NULL)
  37.139 +  HRRSStatsIter() : _all("All"), _young("Young"), _humonguous("Humonguous"),
  37.140 +    _free("Free"), _old("Old"), _max_code_root_mem_sz_region(NULL), _max_rs_mem_sz_region(NULL),
  37.141 +    _max_rs_mem_sz(0), _max_code_root_mem_sz(0)
  37.142    {}
  37.143  
  37.144    bool doHeapRegion(HeapRegion* r) {
  37.145 @@ -156,46 +246,95 @@
  37.146        _max_rs_mem_sz = rs_mem_sz;
  37.147        _max_rs_mem_sz_region = r;
  37.148      }
  37.149 -    _total_rs_mem_sz += rs_mem_sz;
  37.150 -
  37.151 +    size_t occupied_cards = hrrs->occupied();
  37.152      size_t code_root_mem_sz = hrrs->strong_code_roots_mem_size();
  37.153 -    if (code_root_mem_sz > _max_code_root_mem_sz) {
  37.154 -      _max_code_root_mem_sz = code_root_mem_sz;
  37.155 +    if (code_root_mem_sz > max_code_root_mem_sz()) {
  37.156        _max_code_root_mem_sz_region = r;
  37.157      }
  37.158 -    _total_code_root_mem_sz += code_root_mem_sz;
  37.159 +    size_t code_root_elems = hrrs->strong_code_roots_list_length();
  37.160  
  37.161 -    size_t occ = hrrs->occupied();
  37.162 -    _occupied += occ;
  37.163 +    RegionTypeCounter* current = NULL;
  37.164 +    if (r->is_young()) {
  37.165 +      current = &_young;
  37.166 +    } else if (r->isHumongous()) {
  37.167 +      current = &_humonguous;
  37.168 +    } else if (r->is_empty()) {
  37.169 +      current = &_free;
  37.170 +    } else {
  37.171 +      current = &_old;
  37.172 +    }
  37.173 +    current->add(rs_mem_sz, occupied_cards, code_root_mem_sz, code_root_elems);
  37.174 +    _all.add(rs_mem_sz, occupied_cards, code_root_mem_sz, code_root_elems);
  37.175 +
  37.176      return false;
  37.177    }
  37.178 -  size_t total_rs_mem_sz() { return _total_rs_mem_sz; }
  37.179 -  size_t max_rs_mem_sz() { return _max_rs_mem_sz; }
  37.180 -  HeapRegion* max_rs_mem_sz_region() { return _max_rs_mem_sz_region; }
  37.181 -  size_t total_code_root_mem_sz() { return _total_code_root_mem_sz; }
  37.182 -  size_t max_code_root_mem_sz() { return _max_code_root_mem_sz; }
  37.183 -  HeapRegion* max_code_root_mem_sz_region() { return _max_code_root_mem_sz_region; }
  37.184 -  size_t occupied() { return _occupied; }
  37.185 +
  37.186 +  void print_summary_on(outputStream* out) {
  37.187 +    RegionTypeCounter* counters[] = { &_young, &_humonguous, &_free, &_old, NULL };
  37.188 +
  37.189 +    out->print_cr("\n Current rem set statistics");
  37.190 +    out->print_cr("  Total per region rem sets sizes = "SIZE_FORMAT"K."
  37.191 +                  " Max = "SIZE_FORMAT"K.",
  37.192 +                  round_to_K(total_rs_mem_sz()), round_to_K(max_rs_mem_sz()));
  37.193 +    for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) {
  37.194 +      (*current)->print_rs_mem_info_on(out, total_rs_mem_sz());
  37.195 +    }
  37.196 +
  37.197 +    out->print_cr("   Static structures = "SIZE_FORMAT"K,"
  37.198 +                  " free_lists = "SIZE_FORMAT"K.",
  37.199 +                  round_to_K(HeapRegionRemSet::static_mem_size()),
  37.200 +                  round_to_K(HeapRegionRemSet::fl_mem_size()));
  37.201 +
  37.202 +    out->print_cr("    "SIZE_FORMAT" occupied cards represented.",
  37.203 +                  total_cards_occupied());
  37.204 +    for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) {
  37.205 +      (*current)->print_cards_occupied_info_on(out, total_cards_occupied());
  37.206 +    }
  37.207 +
  37.208 +    // Largest sized rem set region statistics
  37.209 +    HeapRegionRemSet* rem_set = max_rs_mem_sz_region()->rem_set();
  37.210 +    out->print_cr("    Region with largest rem set = "HR_FORMAT", "
  37.211 +                  "size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.",
  37.212 +                  HR_FORMAT_PARAMS(max_rs_mem_sz_region()),
  37.213 +                  round_to_K(rem_set->mem_size()),
  37.214 +                  round_to_K(rem_set->occupied()));
  37.215 +
  37.216 +    // Strong code root statistics
  37.217 +    HeapRegionRemSet* max_code_root_rem_set = max_code_root_mem_sz_region()->rem_set();
  37.218 +    out->print_cr("  Total heap region code root sets sizes = "SIZE_FORMAT"K."
  37.219 +                  "  Max = "SIZE_FORMAT"K.",
  37.220 +                  round_to_K(total_code_root_mem_sz()),
  37.221 +                  round_to_K(max_code_root_rem_set->strong_code_roots_mem_size()));
  37.222 +    for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) {
  37.223 +      (*current)->print_code_root_mem_info_on(out, total_code_root_mem_sz());
  37.224 +    }
  37.225 +
  37.226 +    out->print_cr("    "SIZE_FORMAT" code roots represented.",
  37.227 +                  total_code_root_elems());
  37.228 +    for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) {
  37.229 +      (*current)->print_code_root_elems_info_on(out, total_code_root_elems());
  37.230 +    }
  37.231 +
  37.232 +    out->print_cr("    Region with largest amount of code roots = "HR_FORMAT", "
  37.233 +                  "size = "SIZE_FORMAT "K, num_elems = "SIZE_FORMAT".",
  37.234 +                  HR_FORMAT_PARAMS(max_code_root_mem_sz_region()),
  37.235 +                  round_to_K(max_code_root_rem_set->strong_code_roots_mem_size()),
  37.236 +                  round_to_K(max_code_root_rem_set->strong_code_roots_list_length()));
  37.237 +  }
  37.238  };
  37.239  
  37.240 -double calc_percentage(size_t numerator, size_t denominator) {
  37.241 -  if (denominator != 0) {
  37.242 -    return (double)numerator / denominator * 100.0;
  37.243 -  } else {
  37.244 -    return 0.0f;
  37.245 -  }
  37.246 -}
  37.247 -
  37.248  void G1RemSetSummary::print_on(outputStream* out) {
  37.249 -  out->print_cr("\n Concurrent RS processed "SIZE_FORMAT" cards",
  37.250 +  out->print_cr("\n Recent concurrent refinement statistics");
  37.251 +  out->print_cr("  Processed "SIZE_FORMAT" cards",
  37.252                  num_concurrent_refined_cards());
  37.253    out->print_cr("  Of %d completed buffers:", num_processed_buf_total());
  37.254    out->print_cr("     %8d (%5.1f%%) by concurrent RS threads.",
  37.255                  num_processed_buf_total(),
  37.256 -                calc_percentage(num_processed_buf_rs_threads(), num_processed_buf_total()));
  37.257 +                percent_of(num_processed_buf_rs_threads(), num_processed_buf_total()));
  37.258    out->print_cr("     %8d (%5.1f%%) by mutator threads.",
  37.259                  num_processed_buf_mutator(),
  37.260 -                calc_percentage(num_processed_buf_mutator(), num_processed_buf_total()));
  37.261 +                percent_of(num_processed_buf_mutator(), num_processed_buf_total()));
  37.262 +  out->print_cr("  Did %d coarsenings.", num_coarsenings());
  37.263    out->print_cr("  Concurrent RS threads times (s)");
  37.264    out->print("     ");
  37.265    for (uint i = 0; i < _num_vtimes; i++) {
  37.266 @@ -207,33 +346,5 @@
  37.267  
  37.268    HRRSStatsIter blk;
  37.269    G1CollectedHeap::heap()->heap_region_iterate(&blk);
  37.270 -  // RemSet stats
  37.271 -  out->print_cr("  Total heap region rem set sizes = "SIZE_FORMAT"K."
  37.272 -                "  Max = "SIZE_FORMAT"K.",
  37.273 -                blk.total_rs_mem_sz()/K, blk.max_rs_mem_sz()/K);
  37.274 -  out->print_cr("  Static structures = "SIZE_FORMAT"K,"
  37.275 -                " free_lists = "SIZE_FORMAT"K.",
  37.276 -                HeapRegionRemSet::static_mem_size() / K,
  37.277 -                HeapRegionRemSet::fl_mem_size() / K);
  37.278 -  out->print_cr("    "SIZE_FORMAT" occupied cards represented.",
  37.279 -                blk.occupied());
  37.280 -  HeapRegion* max_rs_mem_sz_region = blk.max_rs_mem_sz_region();
  37.281 -  HeapRegionRemSet* max_rs_rem_set = max_rs_mem_sz_region->rem_set();
  37.282 -  out->print_cr("    Max size region = "HR_FORMAT", "
  37.283 -                "size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.",
  37.284 -                HR_FORMAT_PARAMS(max_rs_mem_sz_region),
  37.285 -                (max_rs_rem_set->mem_size() + K - 1)/K,
  37.286 -                (max_rs_rem_set->occupied() + K - 1)/K);
  37.287 -  out->print_cr("    Did %d coarsenings.", num_coarsenings());
  37.288 -  // Strong code root stats
  37.289 -  out->print_cr("  Total heap region code-root set sizes = "SIZE_FORMAT"K."
  37.290 -                "  Max = "SIZE_FORMAT"K.",
  37.291 -                blk.total_code_root_mem_sz()/K, blk.max_code_root_mem_sz()/K);
  37.292 -  HeapRegion* max_code_root_mem_sz_region = blk.max_code_root_mem_sz_region();
  37.293 -  HeapRegionRemSet* max_code_root_rem_set = max_code_root_mem_sz_region->rem_set();
  37.294 -  out->print_cr("    Max size region = "HR_FORMAT", "
  37.295 -                "size = "SIZE_FORMAT "K, num_elems = "SIZE_FORMAT".",
  37.296 -                HR_FORMAT_PARAMS(max_code_root_mem_sz_region),
  37.297 -                (max_code_root_rem_set->strong_code_roots_mem_size() + K - 1)/K,
  37.298 -                (max_code_root_rem_set->strong_code_roots_list_length()));
  37.299 +  blk.print_summary_on(out);
  37.300  }
    38.1 --- a/src/share/vm/gc_implementation/g1/g1RemSetSummary.hpp	Sat Oct 05 03:14:53 2013 +0200
    38.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSetSummary.hpp	Fri Oct 04 21:00:43 2013 -0700
    38.3 @@ -84,7 +84,7 @@
    38.4    void subtract_from(G1RemSetSummary* other);
    38.5  
    38.6    // initialize and get the first sampling
    38.7 -  void initialize(G1RemSet* remset, uint num_workers);
    38.8 +  void initialize(G1RemSet* remset);
    38.9  
   38.10    void print_on(outputStream* out);
   38.11  
    39.1 --- a/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp	Sat Oct 05 03:14:53 2013 +0200
    39.2 +++ b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp	Fri Oct 04 21:00:43 2013 -0700
    39.3 @@ -64,6 +64,27 @@
    39.4    }
    39.5  }
    39.6  
    39.7 +bool G1SATBCardTableModRefBS::mark_card_deferred(size_t card_index) {
    39.8 +  jbyte val = _byte_map[card_index];
    39.9 +  // It's already processed
   39.10 +  if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) {
   39.11 +    return false;
   39.12 +  }
   39.13 +  // Cached bit can be installed either on a clean card or on a claimed card.
   39.14 +  jbyte new_val = val;
   39.15 +  if (val == clean_card_val()) {
   39.16 +    new_val = (jbyte)deferred_card_val();
   39.17 +  } else {
   39.18 +    if (val & claimed_card_val()) {
   39.19 +      new_val = val | (jbyte)deferred_card_val();
   39.20 +    }
   39.21 +  }
   39.22 +  if (new_val != val) {
   39.23 +    Atomic::cmpxchg(new_val, &_byte_map[card_index], val);
   39.24 +  }
   39.25 +  return true;
   39.26 +}
   39.27 +
   39.28  G1SATBCardTableLoggingModRefBS::
   39.29  G1SATBCardTableLoggingModRefBS(MemRegion whole_heap,
   39.30                                 int max_covered_regions) :
    40.1 --- a/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp	Sat Oct 05 03:14:53 2013 +0200
    40.2 +++ b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp	Fri Oct 04 21:00:43 2013 -0700
    40.3 @@ -89,6 +89,42 @@
    40.4        write_ref_array_pre_work(dst, count);
    40.5      }
    40.6    }
    40.7 +
    40.8 +/*
    40.9 +   Claimed and deferred bits are used together in G1 during the evacuation
   40.10 +   pause. These bits can have the following state transitions:
   40.11 +   1. The claimed bit can be put over any other card state. Except that
   40.12 +      the "dirty -> dirty and claimed" transition is checked for in
   40.13 +      G1 code and is not used.
   40.14 +   2. Deferred bit can be set only if the previous state of the card
   40.15 +      was either clean or claimed. mark_card_deferred() is wait-free.
   40.16 +      We do not care if the operation is be successful because if
   40.17 +      it does not it will only result in duplicate entry in the update
   40.18 +      buffer because of the "cache-miss". So it's not worth spinning.
   40.19 + */
   40.20 +
   40.21 +  bool is_card_claimed(size_t card_index) {
   40.22 +    jbyte val = _byte_map[card_index];
   40.23 +    return (val & (clean_card_mask_val() | claimed_card_val())) == claimed_card_val();
   40.24 +  }
   40.25 +
   40.26 +  void set_card_claimed(size_t card_index) {
   40.27 +      jbyte val = _byte_map[card_index];
   40.28 +      if (val == clean_card_val()) {
   40.29 +        val = (jbyte)claimed_card_val();
   40.30 +      } else {
   40.31 +        val |= (jbyte)claimed_card_val();
   40.32 +      }
   40.33 +      _byte_map[card_index] = val;
   40.34 +  }
   40.35 +
   40.36 +  bool mark_card_deferred(size_t card_index);
   40.37 +
   40.38 +  bool is_card_deferred(size_t card_index) {
   40.39 +    jbyte val = _byte_map[card_index];
   40.40 +    return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val();
   40.41 +  }
   40.42 +
   40.43  };
   40.44  
   40.45  // Adds card-table logging to the post-barrier.
    41.1 --- a/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp	Sat Oct 05 03:14:53 2013 +0200
    41.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp	Fri Oct 04 21:00:43 2013 -0700
    41.3 @@ -40,10 +40,8 @@
    41.4  
    41.5    void initialize_flags() {
    41.6      // Do basic sizing work
    41.7 -    this->TwoGenerationCollectorPolicy::initialize_flags();
    41.8 +    TwoGenerationCollectorPolicy::initialize_flags();
    41.9  
   41.10 -    // If the user hasn't explicitly set the number of worker
   41.11 -    // threads, set the count.
   41.12      assert(UseSerialGC ||
   41.13             !FLAG_IS_DEFAULT(ParallelGCThreads) ||
   41.14             (ParallelGCThreads > 0),
    42.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp	Sat Oct 05 03:14:53 2013 +0200
    42.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp	Fri Oct 04 21:00:43 2013 -0700
    42.3 @@ -23,7 +23,6 @@
    42.4   */
    42.5  
    42.6  #include "precompiled.hpp"
    42.7 -#include "gc_implementation/parallelScavenge/generationSizer.hpp"
    42.8  #include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp"
    42.9  #include "gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp"
   42.10  #include "gc_implementation/parallelScavenge/psScavenge.hpp"
    43.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp	Sat Oct 05 03:14:53 2013 +0200
    43.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp	Fri Oct 04 21:00:43 2013 -0700
    43.3 @@ -53,7 +53,6 @@
    43.4  
    43.5  // Forward decls
    43.6  class elapsedTimer;
    43.7 -class GenerationSizer;
    43.8  
    43.9  class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {
   43.10   friend class PSGCAdaptivePolicyCounters;
    44.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Sat Oct 05 03:14:53 2013 +0200
    44.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Fri Oct 04 21:00:43 2013 -0700
    44.3 @@ -26,7 +26,6 @@
    44.4  #include "classfile/symbolTable.hpp"
    44.5  #include "classfile/systemDictionary.hpp"
    44.6  #include "code/codeCache.hpp"
    44.7 -#include "gc_implementation/parallelScavenge/generationSizer.hpp"
    44.8  #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
    44.9  #include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp"
   44.10  #include "gc_implementation/parallelScavenge/psMarkSweep.hpp"
    45.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Sat Oct 05 03:14:53 2013 +0200
    45.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Fri Oct 04 21:00:43 2013 -0700
    45.3 @@ -27,7 +27,6 @@
    45.4  #include "classfile/systemDictionary.hpp"
    45.5  #include "code/codeCache.hpp"
    45.6  #include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
    45.7 -#include "gc_implementation/parallelScavenge/generationSizer.hpp"
    45.8  #include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp"
    45.9  #include "gc_implementation/parallelScavenge/pcTasks.hpp"
   45.10  #include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp"
    46.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Sat Oct 05 03:14:53 2013 +0200
    46.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Fri Oct 04 21:00:43 2013 -0700
    46.3 @@ -27,7 +27,6 @@
    46.4  #include "code/codeCache.hpp"
    46.5  #include "gc_implementation/parallelScavenge/cardTableExtension.hpp"
    46.6  #include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
    46.7 -#include "gc_implementation/parallelScavenge/generationSizer.hpp"
    46.8  #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
    46.9  #include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp"
   46.10  #include "gc_implementation/parallelScavenge/psMarkSweep.hpp"
    47.1 --- a/src/share/vm/memory/cardTableModRefBS.cpp	Sat Oct 05 03:14:53 2013 +0200
    47.2 +++ b/src/share/vm/memory/cardTableModRefBS.cpp	Fri Oct 04 21:00:43 2013 -0700
    47.3 @@ -423,60 +423,6 @@
    47.4    inline_write_ref_field(field, newVal);
    47.5  }
    47.6  
    47.7 -/*
    47.8 -   Claimed and deferred bits are used together in G1 during the evacuation
    47.9 -   pause. These bits can have the following state transitions:
   47.10 -   1. The claimed bit can be put over any other card state. Except that
   47.11 -      the "dirty -> dirty and claimed" transition is checked for in
   47.12 -      G1 code and is not used.
   47.13 -   2. Deferred bit can be set only if the previous state of the card
   47.14 -      was either clean or claimed. mark_card_deferred() is wait-free.
   47.15 -      We do not care if the operation is be successful because if
   47.16 -      it does not it will only result in duplicate entry in the update
   47.17 -      buffer because of the "cache-miss". So it's not worth spinning.
   47.18 - */
   47.19 -
   47.20 -
   47.21 -bool CardTableModRefBS::claim_card(size_t card_index) {
   47.22 -  jbyte val = _byte_map[card_index];
   47.23 -  assert(val != dirty_card_val(), "Shouldn't claim a dirty card");
   47.24 -  while (val == clean_card_val() ||
   47.25 -         (val & (clean_card_mask_val() | claimed_card_val())) != claimed_card_val()) {
   47.26 -    jbyte new_val = val;
   47.27 -    if (val == clean_card_val()) {
   47.28 -      new_val = (jbyte)claimed_card_val();
   47.29 -    } else {
   47.30 -      new_val = val | (jbyte)claimed_card_val();
   47.31 -    }
   47.32 -    jbyte res = Atomic::cmpxchg(new_val, &_byte_map[card_index], val);
   47.33 -    if (res == val) {
   47.34 -      return true;
   47.35 -    }
   47.36 -    val = res;
   47.37 -  }
   47.38 -  return false;
   47.39 -}
   47.40 -
   47.41 -bool CardTableModRefBS::mark_card_deferred(size_t card_index) {
   47.42 -  jbyte val = _byte_map[card_index];
   47.43 -  // It's already processed
   47.44 -  if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) {
   47.45 -    return false;
   47.46 -  }
   47.47 -  // Cached bit can be installed either on a clean card or on a claimed card.
   47.48 -  jbyte new_val = val;
   47.49 -  if (val == clean_card_val()) {
   47.50 -    new_val = (jbyte)deferred_card_val();
   47.51 -  } else {
   47.52 -    if (val & claimed_card_val()) {
   47.53 -      new_val = val | (jbyte)deferred_card_val();
   47.54 -    }
   47.55 -  }
   47.56 -  if (new_val != val) {
   47.57 -    Atomic::cmpxchg(new_val, &_byte_map[card_index], val);
   47.58 -  }
   47.59 -  return true;
   47.60 -}
   47.61  
   47.62  void CardTableModRefBS::non_clean_card_iterate_possibly_parallel(Space* sp,
   47.63                                                                   MemRegion mr,
    48.1 --- a/src/share/vm/memory/cardTableModRefBS.hpp	Sat Oct 05 03:14:53 2013 +0200
    48.2 +++ b/src/share/vm/memory/cardTableModRefBS.hpp	Fri Oct 04 21:00:43 2013 -0700
    48.3 @@ -339,34 +339,10 @@
    48.4      _byte_map[card_index] = dirty_card_val();
    48.5    }
    48.6  
    48.7 -  bool is_card_claimed(size_t card_index) {
    48.8 -    jbyte val = _byte_map[card_index];
    48.9 -    return (val & (clean_card_mask_val() | claimed_card_val())) == claimed_card_val();
   48.10 -  }
   48.11 -
   48.12 -  void set_card_claimed(size_t card_index) {
   48.13 -      jbyte val = _byte_map[card_index];
   48.14 -      if (val == clean_card_val()) {
   48.15 -        val = (jbyte)claimed_card_val();
   48.16 -      } else {
   48.17 -        val |= (jbyte)claimed_card_val();
   48.18 -      }
   48.19 -      _byte_map[card_index] = val;
   48.20 -  }
   48.21 -
   48.22 -  bool claim_card(size_t card_index);
   48.23 -
   48.24    bool is_card_clean(size_t card_index) {
   48.25      return _byte_map[card_index] == clean_card_val();
   48.26    }
   48.27  
   48.28 -  bool is_card_deferred(size_t card_index) {
   48.29 -    jbyte val = _byte_map[card_index];
   48.30 -    return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val();
   48.31 -  }
   48.32 -
   48.33 -  bool mark_card_deferred(size_t card_index);
   48.34 -
   48.35    // Card marking array base (adjusted for heap low boundary)
   48.36    // This would be the 0th element of _byte_map, if the heap started at 0x0.
   48.37    // But since the heap starts at some higher address, this points to somewhere
    49.1 --- a/src/share/vm/memory/collectorPolicy.cpp	Sat Oct 05 03:14:53 2013 +0200
    49.2 +++ b/src/share/vm/memory/collectorPolicy.cpp	Fri Oct 04 21:00:43 2013 -0700
    49.3 @@ -64,19 +64,21 @@
    49.4      vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified");
    49.5    }
    49.6  
    49.7 -  if (!is_size_aligned(MaxMetaspaceSize, max_alignment())) {
    49.8 -    FLAG_SET_ERGO(uintx, MaxMetaspaceSize,
    49.9 -        restricted_align_down(MaxMetaspaceSize, max_alignment()));
   49.10 +  // Do not use FLAG_SET_ERGO to update MaxMetaspaceSize, since this will
   49.11 +  // override if MaxMetaspaceSize was set on the command line or not.
   49.12 +  // This information is needed later to conform to the specification of the
   49.13 +  // java.lang.management.MemoryUsage API.
   49.14 +  //
   49.15 +  // Ideally, we would be able to set the default value of MaxMetaspaceSize in
   49.16 +  // globals.hpp to the aligned value, but this is not possible, since the
   49.17 +  // alignment depends on other flags being parsed.
   49.18 +  MaxMetaspaceSize = restricted_align_down(MaxMetaspaceSize, max_alignment());
   49.19 +
   49.20 +  if (MetaspaceSize > MaxMetaspaceSize) {
   49.21 +    MetaspaceSize = MaxMetaspaceSize;
   49.22    }
   49.23  
   49.24 -  if (MetaspaceSize > MaxMetaspaceSize) {
   49.25 -    FLAG_SET_ERGO(uintx, MetaspaceSize, MaxMetaspaceSize);
   49.26 -  }
   49.27 -
   49.28 -  if (!is_size_aligned(MetaspaceSize, min_alignment())) {
   49.29 -    FLAG_SET_ERGO(uintx, MetaspaceSize,
   49.30 -        restricted_align_down(MetaspaceSize, min_alignment()));
   49.31 -  }
   49.32 +  MetaspaceSize = restricted_align_down(MetaspaceSize, min_alignment());
   49.33  
   49.34    assert(MetaspaceSize <= MaxMetaspaceSize, "Must be");
   49.35  
   49.36 @@ -135,15 +137,8 @@
   49.37  
   49.38  GenRemSet* CollectorPolicy::create_rem_set(MemRegion whole_heap,
   49.39                                             int max_covered_regions) {
   49.40 -  switch (rem_set_name()) {
   49.41 -  case GenRemSet::CardTable: {
   49.42 -    CardTableRS* res = new CardTableRS(whole_heap, max_covered_regions);
   49.43 -    return res;
   49.44 -  }
   49.45 -  default:
   49.46 -    guarantee(false, "unrecognized GenRemSet::Name");
   49.47 -    return NULL;
   49.48 -  }
   49.49 +  assert(rem_set_name() == GenRemSet::CardTable, "unrecognized GenRemSet::Name");
   49.50 +  return new CardTableRS(whole_heap, max_covered_regions);
   49.51  }
   49.52  
   49.53  void CollectorPolicy::cleared_all_soft_refs() {
    50.1 --- a/src/share/vm/memory/genRemSet.cpp	Sat Oct 05 03:14:53 2013 +0200
    50.2 +++ b/src/share/vm/memory/genRemSet.cpp	Fri Oct 04 21:00:43 2013 -0700
    50.3 @@ -32,13 +32,8 @@
    50.4  // enumeration.)
    50.5  
    50.6  uintx GenRemSet::max_alignment_constraint(Name nm) {
    50.7 -  switch (nm) {
    50.8 -  case GenRemSet::CardTable:
    50.9 -    return CardTableRS::ct_max_alignment_constraint();
   50.10 -  default:
   50.11 -    guarantee(false, "Unrecognized GenRemSet type.");
   50.12 -    return (0); // Make Windows compiler happy
   50.13 -  }
   50.14 +  assert(nm == GenRemSet::CardTable, "Unrecognized GenRemSet type.");
   50.15 +  return CardTableRS::ct_max_alignment_constraint();
   50.16  }
   50.17  
   50.18  class HasAccumulatedModifiedOopsClosure : public KlassClosure {
    51.1 --- a/src/share/vm/memory/metaspace.cpp	Sat Oct 05 03:14:53 2013 +0200
    51.2 +++ b/src/share/vm/memory/metaspace.cpp	Fri Oct 04 21:00:43 2013 -0700
    51.3 @@ -3104,7 +3104,7 @@
    51.4  MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) {
    51.5    // DumpSharedSpaces doesn't use class metadata area (yet)
    51.6    // Also, don't use class_vsm() unless UseCompressedClassPointers is true.
    51.7 -  if (mdtype == ClassType && using_class_space()) {
    51.8 +  if (is_class_space_allocation(mdtype)) {
    51.9      return  class_vsm()->allocate(word_size);
   51.10    } else {
   51.11      return  vsm()->allocate(word_size);
   51.12 @@ -3252,8 +3252,8 @@
   51.13          MetaspaceAux::dump(gclog_or_tty);
   51.14        }
   51.15        // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
   51.16 -      const char* space_string = (mdtype == ClassType) ? "Compressed class space" :
   51.17 -                                                         "Metadata space";
   51.18 +      const char* space_string = is_class_space_allocation(mdtype) ? "Compressed class space" :
   51.19 +                                                                     "Metadata space";
   51.20        report_java_out_of_memory(space_string);
   51.21  
   51.22        if (JvmtiExport::should_post_resource_exhausted()) {
   51.23 @@ -3261,7 +3261,7 @@
   51.24              JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR,
   51.25              space_string);
   51.26        }
   51.27 -      if (mdtype == ClassType) {
   51.28 +      if (is_class_space_allocation(mdtype)) {
   51.29          THROW_OOP_0(Universe::out_of_memory_error_class_metaspace());
   51.30        } else {
   51.31          THROW_OOP_0(Universe::out_of_memory_error_metaspace());
    52.1 --- a/src/share/vm/memory/metaspace.hpp	Sat Oct 05 03:14:53 2013 +0200
    52.2 +++ b/src/share/vm/memory/metaspace.hpp	Fri Oct 04 21:00:43 2013 -0700
    52.3 @@ -235,6 +235,9 @@
    52.4      return NOT_LP64(false) LP64_ONLY(UseCompressedClassPointers && !DumpSharedSpaces);
    52.5    }
    52.6  
    52.7 +  static bool is_class_space_allocation(MetadataType mdType) {
    52.8 +    return mdType == ClassType && using_class_space();
    52.9 +  }
   52.10  };
   52.11  
   52.12  class MetaspaceAux : AllStatic {
    53.1 --- a/src/share/vm/oops/method.cpp	Sat Oct 05 03:14:53 2013 +0200
    53.2 +++ b/src/share/vm/oops/method.cpp	Fri Oct 04 21:00:43 2013 -0700
    53.3 @@ -901,16 +901,6 @@
    53.4  // This function must not hit a safepoint!
    53.5  address Method::verified_code_entry() {
    53.6    debug_only(No_Safepoint_Verifier nsv;)
    53.7 -  nmethod *code = (nmethod *)OrderAccess::load_ptr_acquire(&_code);
    53.8 -  if (code == NULL && UseCodeCacheFlushing) {
    53.9 -    nmethod *saved_code = CodeCache::reanimate_saved_code(this);
   53.10 -    if (saved_code != NULL) {
   53.11 -      methodHandle method(this);
   53.12 -      assert( ! saved_code->is_osr_method(), "should not get here for osr" );
   53.13 -      set_code( method, saved_code );
   53.14 -    }
   53.15 -  }
   53.16 -
   53.17    assert(_from_compiled_entry != NULL, "must be set");
   53.18    return _from_compiled_entry;
   53.19  }
    54.1 --- a/src/share/vm/opto/c2_globals.hpp	Sat Oct 05 03:14:53 2013 +0200
    54.2 +++ b/src/share/vm/opto/c2_globals.hpp	Fri Oct 04 21:00:43 2013 -0700
    54.3 @@ -636,7 +636,9 @@
    54.4                                                                              \
    54.5    diagnostic(bool, OptimizeExpensiveOps, true,                              \
    54.6            "Find best control for expensive operations")                     \
    54.7 -
    54.8 +                                                                            \
    54.9 +  product(bool, UseMathExactIntrinsics, true,                               \
   54.10 +          "Enables intrinsification of various java.lang.Math funcitons")
   54.11  
   54.12  C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG)
   54.13  
    55.1 --- a/src/share/vm/opto/callGenerator.hpp	Sat Oct 05 03:14:53 2013 +0200
    55.2 +++ b/src/share/vm/opto/callGenerator.hpp	Fri Oct 04 21:00:43 2013 -0700
    55.3 @@ -65,6 +65,8 @@
    55.4    virtual bool      is_predicted() const        { return false; }
    55.5    // is_trap: Does not return to the caller.  (E.g., uncommon trap.)
    55.6    virtual bool      is_trap() const             { return false; }
    55.7 +  // does_virtual_dispatch: Should try inlining as normal method first.
    55.8 +  virtual bool      does_virtual_dispatch() const     { return false; }
    55.9  
   55.10    // is_late_inline: supports conversion of call into an inline
   55.11    virtual bool      is_late_inline() const      { return false; }
    56.1 --- a/src/share/vm/opto/classes.cpp	Sat Oct 05 03:14:53 2013 +0200
    56.2 +++ b/src/share/vm/opto/classes.cpp	Fri Oct 04 21:00:43 2013 -0700
    56.3 @@ -32,6 +32,7 @@
    56.4  #include "opto/loopnode.hpp"
    56.5  #include "opto/machnode.hpp"
    56.6  #include "opto/memnode.hpp"
    56.7 +#include "opto/mathexactnode.hpp"
    56.8  #include "opto/mulnode.hpp"
    56.9  #include "opto/multnode.hpp"
   56.10  #include "opto/node.hpp"
    57.1 --- a/src/share/vm/opto/classes.hpp	Sat Oct 05 03:14:53 2013 +0200
    57.2 +++ b/src/share/vm/opto/classes.hpp	Fri Oct 04 21:00:43 2013 -0700
    57.3 @@ -29,6 +29,7 @@
    57.4  macro(AbsF)
    57.5  macro(AbsI)
    57.6  macro(AddD)
    57.7 +macro(AddExactI)
    57.8  macro(AddF)
    57.9  macro(AddI)
   57.10  macro(AddL)
   57.11 @@ -133,6 +134,7 @@
   57.12  macro(ExpD)
   57.13  macro(FastLock)
   57.14  macro(FastUnlock)
   57.15 +macro(FlagsProj)
   57.16  macro(Goto)
   57.17  macro(Halt)
   57.18  macro(If)
   57.19 @@ -167,6 +169,7 @@
   57.20  macro(LoopLimit)
   57.21  macro(Mach)
   57.22  macro(MachProj)
   57.23 +macro(MathExact)
   57.24  macro(MaxI)
   57.25  macro(MemBarAcquire)
   57.26  macro(MemBarAcquireLock)
    58.1 --- a/src/share/vm/opto/doCall.cpp	Sat Oct 05 03:14:53 2013 +0200
    58.2 +++ b/src/share/vm/opto/doCall.cpp	Fri Oct 04 21:00:43 2013 -0700
    58.3 @@ -110,6 +110,7 @@
    58.4    // then we return it as the inlined version of the call.
    58.5    // We do this before the strict f.p. check below because the
    58.6    // intrinsics handle strict f.p. correctly.
    58.7 +  CallGenerator* cg_intrinsic = NULL;
    58.8    if (allow_inline && allow_intrinsics) {
    58.9      CallGenerator* cg = find_intrinsic(callee, call_does_dispatch);
   58.10      if (cg != NULL) {
   58.11 @@ -121,7 +122,16 @@
   58.12            cg = CallGenerator::for_predicted_intrinsic(cg, inline_cg);
   58.13          }
   58.14        }
   58.15 -      return cg;
   58.16 +
   58.17 +      // If intrinsic does the virtual dispatch, we try to use the type profile
   58.18 +      // first, and hopefully inline it as the regular virtual call below.
   58.19 +      // We will retry the intrinsic if nothing had claimed it afterwards.
   58.20 +      if (cg->does_virtual_dispatch()) {
   58.21 +        cg_intrinsic = cg;
   58.22 +        cg = NULL;
   58.23 +      } else {
   58.24 +        return cg;
   58.25 +      }
   58.26      }
   58.27    }
   58.28  
   58.29 @@ -266,6 +276,13 @@
   58.30      }
   58.31    }
   58.32  
   58.33 +  // Nothing claimed the intrinsic, we go with straight-forward inlining
   58.34 +  // for already discovered intrinsic.
   58.35 +  if (allow_inline && allow_intrinsics && cg_intrinsic != NULL) {
   58.36 +    assert(cg_intrinsic->does_virtual_dispatch(), "sanity");
   58.37 +    return cg_intrinsic;
   58.38 +  }
   58.39 +
   58.40    // There was no special inlining tactic, or it bailed out.
   58.41    // Use a more generic tactic, like a simple call.
   58.42    if (call_does_dispatch) {
    59.1 --- a/src/share/vm/opto/graphKit.cpp	Sat Oct 05 03:14:53 2013 +0200
    59.2 +++ b/src/share/vm/opto/graphKit.cpp	Fri Oct 04 21:00:43 2013 -0700
    59.3 @@ -3849,9 +3849,9 @@
    59.4    const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
    59.5                                                       false, NULL, 0);
    59.6    const TypePtr* value_field_type = string_type->add_offset(value_offset);
    59.7 -  int value_field_idx = C->get_alias_index(value_field_type);
    59.8 -  store_to_memory(ctrl, basic_plus_adr(str, value_offset),
    59.9 -                  value, T_OBJECT, value_field_idx);
   59.10 +
   59.11 +  store_oop_to_object(ctrl, str,  basic_plus_adr(str, value_offset), value_field_type,
   59.12 +      value, TypeAryPtr::CHARS, T_OBJECT);
   59.13  }
   59.14  
   59.15  void GraphKit::store_String_length(Node* ctrl, Node* str, Node* value) {
    60.1 --- a/src/share/vm/opto/ifnode.cpp	Sat Oct 05 03:14:53 2013 +0200
    60.2 +++ b/src/share/vm/opto/ifnode.cpp	Fri Oct 04 21:00:43 2013 -0700
    60.3 @@ -76,6 +76,7 @@
    60.4    if( !i1->is_Bool() ) return NULL;
    60.5    BoolNode *b = i1->as_Bool();
    60.6    Node *cmp = b->in(1);
    60.7 +  if( cmp->is_FlagsProj() ) return NULL;
    60.8    if( !cmp->is_Cmp() ) return NULL;
    60.9    i1 = cmp->in(1);
   60.10    if( i1 == NULL || !i1->is_Phi() ) return NULL;
    61.1 --- a/src/share/vm/opto/lcm.cpp	Sat Oct 05 03:14:53 2013 +0200
    61.2 +++ b/src/share/vm/opto/lcm.cpp	Fri Oct 04 21:00:43 2013 -0700
    61.3 @@ -472,6 +472,13 @@
    61.4            break;
    61.5          }
    61.6  
    61.7 +        // For nodes that produce a FlagsProj, make the node adjacent to the
    61.8 +        // use of the FlagsProj
    61.9 +        if (use->is_FlagsProj() && get_block_for_node(use) == block) {
   61.10 +          found_machif = true;
   61.11 +          break;
   61.12 +        }
   61.13 +
   61.14          // More than this instruction pending for successor to be ready,
   61.15          // don't choose this if other opportunities are ready
   61.16          if (ready_cnt.at(use->_idx) > 1)
    62.1 --- a/src/share/vm/opto/library_call.cpp	Sat Oct 05 03:14:53 2013 +0200
    62.2 +++ b/src/share/vm/opto/library_call.cpp	Fri Oct 04 21:00:43 2013 -0700
    62.3 @@ -32,6 +32,7 @@
    62.4  #include "opto/callGenerator.hpp"
    62.5  #include "opto/cfgnode.hpp"
    62.6  #include "opto/idealKit.hpp"
    62.7 +#include "opto/mathexactnode.hpp"
    62.8  #include "opto/mulnode.hpp"
    62.9  #include "opto/parse.hpp"
   62.10  #include "opto/runtime.hpp"
   62.11 @@ -46,19 +47,22 @@
   62.12   private:
   62.13    bool             _is_virtual;
   62.14    bool             _is_predicted;
   62.15 +  bool             _does_virtual_dispatch;
   62.16    vmIntrinsics::ID _intrinsic_id;
   62.17  
   62.18   public:
   62.19 -  LibraryIntrinsic(ciMethod* m, bool is_virtual, bool is_predicted, vmIntrinsics::ID id)
   62.20 +  LibraryIntrinsic(ciMethod* m, bool is_virtual, bool is_predicted, bool does_virtual_dispatch, vmIntrinsics::ID id)
   62.21      : InlineCallGenerator(m),
   62.22        _is_virtual(is_virtual),
   62.23        _is_predicted(is_predicted),
   62.24 +      _does_virtual_dispatch(does_virtual_dispatch),
   62.25        _intrinsic_id(id)
   62.26    {
   62.27    }
   62.28    virtual bool is_intrinsic() const { return true; }
   62.29    virtual bool is_virtual()   const { return _is_virtual; }
   62.30    virtual bool is_predicted()   const { return _is_predicted; }
   62.31 +  virtual bool does_virtual_dispatch()   const { return _does_virtual_dispatch; }
   62.32    virtual JVMState* generate(JVMState* jvms);
   62.33    virtual Node* generate_predicate(JVMState* jvms);
   62.34    vmIntrinsics::ID intrinsic_id() const { return _intrinsic_id; }
   62.35 @@ -199,6 +203,8 @@
   62.36    bool inline_math_native(vmIntrinsics::ID id);
   62.37    bool inline_trig(vmIntrinsics::ID id);
   62.38    bool inline_math(vmIntrinsics::ID id);
   62.39 +  bool inline_math_mathExact(Node* math);
   62.40 +  bool inline_math_addExact();
   62.41    bool inline_exp();
   62.42    bool inline_pow();
   62.43    void finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName);
   62.44 @@ -352,6 +358,7 @@
   62.45    }
   62.46  
   62.47    bool is_predicted = false;
   62.48 +  bool does_virtual_dispatch = false;
   62.49  
   62.50    switch (id) {
   62.51    case vmIntrinsics::_compareTo:
   62.52 @@ -378,8 +385,10 @@
   62.53      break;
   62.54    case vmIntrinsics::_hashCode:
   62.55      if (!InlineObjectHash)  return NULL;
   62.56 +    does_virtual_dispatch = true;
   62.57      break;
   62.58    case vmIntrinsics::_clone:
   62.59 +    does_virtual_dispatch = true;
   62.60    case vmIntrinsics::_copyOf:
   62.61    case vmIntrinsics::_copyOfRange:
   62.62      if (!InlineObjectCopy)  return NULL;
   62.63 @@ -498,6 +507,15 @@
   62.64      if (!UseCRC32Intrinsics) return NULL;
   62.65      break;
   62.66  
   62.67 +  case vmIntrinsics::_addExact:
   62.68 +    if (!Matcher::match_rule_supported(Op_AddExactI)) {
   62.69 +      return NULL;
   62.70 +    }
   62.71 +    if (!UseMathExactIntrinsics) {
   62.72 +      return NULL;
   62.73 +    }
   62.74 +    break;
   62.75 +
   62.76   default:
   62.77      assert(id <= vmIntrinsics::LAST_COMPILER_INLINE, "caller responsibility");
   62.78      assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?");
   62.79 @@ -529,7 +547,7 @@
   62.80      if (!InlineUnsafeOps)  return NULL;
   62.81    }
   62.82  
   62.83 -  return new LibraryIntrinsic(m, is_virtual, is_predicted, (vmIntrinsics::ID) id);
   62.84 +  return new LibraryIntrinsic(m, is_virtual, is_predicted, does_virtual_dispatch, (vmIntrinsics::ID) id);
   62.85  }
   62.86  
   62.87  //----------------------register_library_intrinsics-----------------------
   62.88 @@ -668,6 +686,8 @@
   62.89    case vmIntrinsics::_min:
   62.90    case vmIntrinsics::_max:                      return inline_min_max(intrinsic_id());
   62.91  
   62.92 +  case vmIntrinsics::_addExact:                 return inline_math_addExact();
   62.93 +
   62.94    case vmIntrinsics::_arraycopy:                return inline_arraycopy();
   62.95  
   62.96    case vmIntrinsics::_compareTo:                return inline_string_compareTo();
   62.97 @@ -1911,6 +1931,45 @@
   62.98    return true;
   62.99  }
  62.100  
  62.101 +bool LibraryCallKit::inline_math_mathExact(Node* math) {
  62.102 +  Node* result = _gvn.transform( new(C) ProjNode(math, MathExactNode::result_proj_node));
  62.103 +  Node* flags = _gvn.transform( new(C) FlagsProjNode(math, MathExactNode::flags_proj_node));
  62.104 +
  62.105 +  Node* bol = _gvn.transform( new (C) BoolNode(flags, BoolTest::overflow) );
  62.106 +  IfNode* check = create_and_map_if(control(), bol, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN);
  62.107 +  Node* fast_path = _gvn.transform( new (C) IfFalseNode(check));
  62.108 +  Node* slow_path = _gvn.transform( new (C) IfTrueNode(check) );
  62.109 +
  62.110 +  {
  62.111 +    PreserveJVMState pjvms(this);
  62.112 +    PreserveReexecuteState preexecs(this);
  62.113 +    jvms()->set_should_reexecute(true);
  62.114 +
  62.115 +    set_control(slow_path);
  62.116 +    set_i_o(i_o());
  62.117 +
  62.118 +    uncommon_trap(Deoptimization::Reason_intrinsic,
  62.119 +                  Deoptimization::Action_none);
  62.120 +  }
  62.121 +
  62.122 +  set_control(fast_path);
  62.123 +  set_result(result);
  62.124 +  return true;
  62.125 +}
  62.126 +
  62.127 +bool LibraryCallKit::inline_math_addExact() {
  62.128 +  Node* arg1 = argument(0);
  62.129 +  Node* arg2 = argument(1);
  62.130 +
  62.131 +  Node* add = _gvn.transform( new(C) AddExactINode(NULL, arg1, arg2) );
  62.132 +  if (add->Opcode() == Op_AddExactI) {
  62.133 +    return inline_math_mathExact(add);
  62.134 +  } else {
  62.135 +    set_result(add);
  62.136 +  }
  62.137 +  return true;
  62.138 +}
  62.139 +
  62.140  Node*
  62.141  LibraryCallKit::generate_min_max(vmIntrinsics::ID id, Node* x0, Node* y0) {
  62.142    // These are the candidate return value:
    63.1 --- a/src/share/vm/opto/loopTransform.cpp	Sat Oct 05 03:14:53 2013 +0200
    63.2 +++ b/src/share/vm/opto/loopTransform.cpp	Fri Oct 04 21:00:43 2013 -0700
    63.3 @@ -776,6 +776,9 @@
    63.4          continue; // not RC
    63.5  
    63.6        Node *cmp = bol->in(1);
    63.7 +      if (cmp->is_FlagsProj()) {
    63.8 +        continue;
    63.9 +      }
   63.10  
   63.11        Node *rc_exp = cmp->in(1);
   63.12        Node *limit = cmp->in(2);
    64.1 --- a/src/share/vm/opto/loopopts.cpp	Sat Oct 05 03:14:53 2013 +0200
    64.2 +++ b/src/share/vm/opto/loopopts.cpp	Fri Oct 04 21:00:43 2013 -0700
    64.3 @@ -2355,7 +2355,8 @@
    64.4          opc == Op_Catch     ||
    64.5          opc == Op_CatchProj ||
    64.6          opc == Op_Jump      ||
    64.7 -        opc == Op_JumpProj) {
    64.8 +        opc == Op_JumpProj  ||
    64.9 +        opc == Op_FlagsProj) {
   64.10  #if !defined(PRODUCT)
   64.11        if (TracePartialPeeling) {
   64.12          tty->print_cr("\nExit control too complex: lp: %d", head->_idx);
    65.1 --- a/src/share/vm/opto/matcher.cpp	Sat Oct 05 03:14:53 2013 +0200
    65.2 +++ b/src/share/vm/opto/matcher.cpp	Fri Oct 04 21:00:43 2013 -0700
    65.3 @@ -1964,6 +1964,7 @@
    65.4        case Op_Catch:
    65.5        case Op_CatchProj:
    65.6        case Op_CProj:
    65.7 +      case Op_FlagsProj:
    65.8        case Op_JumpProj:
    65.9        case Op_JProj:
   65.10        case Op_NeverBranch:
    66.1 --- a/src/share/vm/opto/matcher.hpp	Sat Oct 05 03:14:53 2013 +0200
    66.2 +++ b/src/share/vm/opto/matcher.hpp	Fri Oct 04 21:00:43 2013 -0700
    66.3 @@ -337,6 +337,9 @@
    66.4    // Register for MODL projection of divmodL
    66.5    static RegMask modL_proj_mask();
    66.6  
    66.7 +  static const RegMask mathExactI_result_proj_mask();
    66.8 +  static const RegMask mathExactI_flags_proj_mask();
    66.9 +
   66.10    // Use hardware DIV instruction when it is faster than
   66.11    // a code which use multiply for division by constant.
   66.12    static bool use_asm_for_ldiv_by_con( jlong divisor );
    67.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    67.2 +++ b/src/share/vm/opto/mathexactnode.cpp	Fri Oct 04 21:00:43 2013 -0700
    67.3 @@ -0,0 +1,143 @@
    67.4 +/*
    67.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    67.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    67.7 + *
    67.8 + * This code is free software; you can redistribute it and/or modify it
    67.9 + * under the terms of the GNU General Public License version 2 only, as
   67.10 + * published by the Free Software Foundation.
   67.11 + *
   67.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   67.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   67.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   67.15 + * version 2 for more details (a copy is included in the LICENSE file that
   67.16 + * accompanied this code).
   67.17 + *
   67.18 + * You should have received a copy of the GNU General Public License version
   67.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   67.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   67.21 + *
   67.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   67.23 + * or visit www.oracle.com if you need additional information or have any
   67.24 + * questions.
   67.25 + *
   67.26 + */
   67.27 +
   67.28 +#include "precompiled.hpp"
   67.29 +#include "memory/allocation.inline.hpp"
   67.30 +#include "opto/addnode.hpp"
   67.31 +#include "opto/machnode.hpp"
   67.32 +#include "opto/mathexactnode.hpp"
   67.33 +#include "opto/matcher.hpp"
   67.34 +#include "opto/subnode.hpp"
   67.35 +
   67.36 +MathExactNode::MathExactNode(Node* ctrl, Node* n1, Node* n2) : MultiNode(3) {
   67.37 +  init_req(0, ctrl);
   67.38 +  init_req(1, n1);
   67.39 +  init_req(2, n2);
   67.40 +}
   67.41 +
   67.42 +Node* AddExactINode::match(const ProjNode* proj, const Matcher* m) {
   67.43 +  uint ideal_reg = proj->ideal_reg();
   67.44 +  RegMask rm;
   67.45 +  if (proj->_con == result_proj_node) {
   67.46 +    rm = m->mathExactI_result_proj_mask();
   67.47 +  } else {
   67.48 +    assert(proj->_con == flags_proj_node, "must be result or flags");
   67.49 +    assert(ideal_reg == Op_RegFlags, "sanity");
   67.50 +    rm = m->mathExactI_flags_proj_mask();
   67.51 +  }
   67.52 +  return new (m->C) MachProjNode(this, proj->_con, rm, ideal_reg);
   67.53 +}
   67.54 +
   67.55 +// If the MathExactNode won't overflow we have to replace the
   67.56 +// FlagsProjNode and ProjNode that is generated by the MathExactNode
   67.57 +Node* MathExactNode::no_overflow(PhaseGVN *phase, Node* new_result) {
   67.58 +  PhaseIterGVN *igvn = phase->is_IterGVN();
   67.59 +  if (igvn) {
   67.60 +    ProjNode* result = result_node();
   67.61 +    ProjNode* flags = flags_node();
   67.62 +
   67.63 +    if (result != NULL) {
   67.64 +      igvn->replace_node(result, new_result);
   67.65 +    }
   67.66 +
   67.67 +    if (flags != NULL) {
   67.68 +      BoolNode* bolnode = (BoolNode *) flags->unique_out();
   67.69 +      switch (bolnode->_test._test) {
   67.70 +        case BoolTest::overflow:
   67.71 +          // if the check is for overflow - never taken
   67.72 +          igvn->replace_node(bolnode, phase->intcon(0));
   67.73 +          break;
   67.74 +        case BoolTest::no_overflow:
   67.75 +          // if the check is for no overflow - always taken
   67.76 +          igvn->replace_node(bolnode, phase->intcon(1));
   67.77 +          break;
   67.78 +        default:
   67.79 +          fatal("Unexpected value of BoolTest");
   67.80 +          break;
   67.81 +      }
   67.82 +      flags->del_req(0);
   67.83 +    }
   67.84 +  }
   67.85 +  return new_result;
   67.86 +}
   67.87 +
   67.88 +Node *AddExactINode::Ideal(PhaseGVN *phase, bool can_reshape) {
   67.89 +  Node *arg1 = in(1);
   67.90 +  Node *arg2 = in(2);
   67.91 +
   67.92 +  const Type* type1 = phase->type(arg1);
   67.93 +  const Type* type2 = phase->type(arg2);
   67.94 +
   67.95 +  if (type1 != Type::TOP && type1->singleton() &&
   67.96 +      type2 != Type::TOP && type2->singleton()) {
   67.97 +    jint val1 = arg1->get_int();
   67.98 +    jint val2 = arg2->get_int();
   67.99 +    jint result = val1 + val2;
  67.100 +    // Hacker's Delight 2-12 Overflow if both arguments have the opposite sign of the result
  67.101 +    if ( (((val1 ^ result) & (val2 ^ result)) >= 0)) {
  67.102 +      Node* con_result = ConINode::make(phase->C, result);
  67.103 +      return no_overflow(phase, con_result);
  67.104 +    }
  67.105 +    return NULL;
  67.106 +  }
  67.107 +
  67.108 +  if (type1 == TypeInt::ZERO) { // (Add 0 x) == x
  67.109 +    Node* add_result = new (phase->C) AddINode(arg1, arg2);
  67.110 +    return no_overflow(phase, add_result);
  67.111 +  }
  67.112 +
  67.113 +  if (type2 == TypeInt::ZERO) { // (Add x 0) == x
  67.114 +    Node* add_result = new (phase->C) AddINode(arg1, arg2);
  67.115 +    return no_overflow(phase, add_result);
  67.116 +  }
  67.117 +
  67.118 +  if (type2->singleton()) {
  67.119 +    return NULL; // no change - keep constant on the right
  67.120 +  }
  67.121 +
  67.122 +  if (type1->singleton()) {
  67.123 +    // Make it x + Constant - move constant to the right
  67.124 +    swap_edges(1, 2);
  67.125 +    return this;
  67.126 +  }
  67.127 +
  67.128 +  if (arg2->is_Load()) {
  67.129 +    return NULL; // no change - keep load on the right
  67.130 +  }
  67.131 +
  67.132 +  if (arg1->is_Load()) {
  67.133 +    // Make it x + Load - move load to the right
  67.134 +    swap_edges(1, 2);
  67.135 +    return this;
  67.136 +  }
  67.137 +
  67.138 +  if (arg1->_idx > arg2->_idx) {
  67.139 +    // Sort the edges
  67.140 +    swap_edges(1, 2);
  67.141 +    return this;
  67.142 +  }
  67.143 +
  67.144 +  return NULL;
  67.145 +}
  67.146 +
    68.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    68.2 +++ b/src/share/vm/opto/mathexactnode.hpp	Fri Oct 04 21:00:43 2013 -0700
    68.3 @@ -0,0 +1,81 @@
    68.4 +/*
    68.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    68.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    68.7 + *
    68.8 + * This code is free software; you can redistribute it and/or modify it
    68.9 + * under the terms of the GNU General Public License version 2 only, as
   68.10 + * published by the Free Software Foundation.
   68.11 + *
   68.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   68.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   68.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   68.15 + * version 2 for more details (a copy is included in the LICENSE file that
   68.16 + * accompanied this code).
   68.17 + *
   68.18 + * You should have received a copy of the GNU General Public License version
   68.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   68.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   68.21 + *
   68.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   68.23 + * or visit www.oracle.com if you need additional information or have any
   68.24 + * questions.
   68.25 + *
   68.26 + */
   68.27 +
   68.28 +#ifndef SHARE_VM_OPTO_MATHEXACTNODE_HPP
   68.29 +#define SHARE_VM_OPTO_MATHEXACTNODE_HPP
   68.30 +
   68.31 +#include "opto/multnode.hpp"
   68.32 +#include "opto/node.hpp"
   68.33 +#include "opto/type.hpp"
   68.34 +
   68.35 +class Node;
   68.36 +
   68.37 +class PhaseGVN;
   68.38 +class PhaseTransform;
   68.39 +
   68.40 +class MathExactNode : public MultiNode {
   68.41 +public:
   68.42 +  MathExactNode(Node* ctrl, Node* in1, Node* in2);
   68.43 +  enum {
   68.44 +    result_proj_node = 0,
   68.45 +    flags_proj_node = 1
   68.46 +  };
   68.47 +  virtual int Opcode() const;
   68.48 +  virtual Node* Identity(PhaseTransform* phase) { return this; }
   68.49 +  virtual Node* Ideal(PhaseGVN* phase, bool can_reshape) { return NULL; }
   68.50 +  virtual const Type* Value(PhaseTransform* phase) const { return bottom_type(); }
   68.51 +  virtual uint hash() const { return Node::hash(); }
   68.52 +  virtual bool is_CFG() const { return false; }
   68.53 +  virtual uint ideal_reg() const { return NotAMachineReg; }
   68.54 +
   68.55 +  ProjNode* result_node() { return proj_out(result_proj_node); }
   68.56 +  ProjNode* flags_node() { return proj_out(flags_proj_node); }
   68.57 +protected:
   68.58 +  Node* no_overflow(PhaseGVN *phase, Node* new_result);
   68.59 +};
   68.60 +
   68.61 +class AddExactINode : public MathExactNode {
   68.62 +public:
   68.63 +  AddExactINode(Node* ctrl, Node* in1, Node* in2) : MathExactNode(ctrl, in1, in2) {}
   68.64 +  virtual int Opcode() const;
   68.65 +  virtual const Type* bottom_type() const { return TypeTuple::INT_CC_PAIR; }
   68.66 +  virtual Node* match(const ProjNode* proj, const Matcher* m);
   68.67 +  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
   68.68 +};
   68.69 +
   68.70 +class FlagsProjNode : public ProjNode {
   68.71 +public:
   68.72 +  FlagsProjNode(Node* src, uint con) : ProjNode(src, con) {
   68.73 +    init_class_id(Class_FlagsProj);
   68.74 +  }
   68.75 +
   68.76 +  virtual int Opcode() const;
   68.77 +  virtual bool is_CFG() const { return false; }
   68.78 +  virtual const Type* bottom_type() const { return TypeInt::CC; }
   68.79 +  virtual uint ideal_reg() const { return Op_RegFlags; }
   68.80 +};
   68.81 +
   68.82 +
   68.83 +#endif
   68.84 +
    69.1 --- a/src/share/vm/opto/multnode.cpp	Sat Oct 05 03:14:53 2013 +0200
    69.2 +++ b/src/share/vm/opto/multnode.cpp	Fri Oct 04 21:00:43 2013 -0700
    69.3 @@ -25,6 +25,7 @@
    69.4  #include "precompiled.hpp"
    69.5  #include "opto/callnode.hpp"
    69.6  #include "opto/matcher.hpp"
    69.7 +#include "opto/mathexactnode.hpp"
    69.8  #include "opto/multnode.hpp"
    69.9  #include "opto/opcodes.hpp"
   69.10  #include "opto/phaseX.hpp"
   69.11 @@ -46,15 +47,21 @@
   69.12    assert(Opcode() != Op_If || outcnt() == 2, "bad if #1");
   69.13    for( DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++ ) {
   69.14      Node *p = fast_out(i);
   69.15 -    if( !p->is_Proj() ) {
   69.16 +    if (p->is_Proj()) {
   69.17 +      ProjNode *proj = p->as_Proj();
   69.18 +      if (proj->_con == which_proj) {
   69.19 +        assert(Opcode() != Op_If || proj->Opcode() == (which_proj?Op_IfTrue:Op_IfFalse), "bad if #2");
   69.20 +        return proj;
   69.21 +      }
   69.22 +    } else if (p->is_FlagsProj()) {
   69.23 +      FlagsProjNode *proj = p->as_FlagsProj();
   69.24 +      if (proj->_con == which_proj) {
   69.25 +        return proj;
   69.26 +      }
   69.27 +    } else {
   69.28        assert(p == this && this->is_Start(), "else must be proj");
   69.29        continue;
   69.30      }
   69.31 -    ProjNode *proj = p->as_Proj();
   69.32 -    if( proj->_con == which_proj ) {
   69.33 -      assert(Opcode() != Op_If || proj->Opcode() == (which_proj?Op_IfTrue:Op_IfFalse), "bad if #2");
   69.34 -      return proj;
   69.35 -    }
   69.36    }
   69.37    return NULL;
   69.38  }
    70.1 --- a/src/share/vm/opto/node.hpp	Sat Oct 05 03:14:53 2013 +0200
    70.2 +++ b/src/share/vm/opto/node.hpp	Fri Oct 04 21:00:43 2013 -0700
    70.3 @@ -69,6 +69,7 @@
    70.4  class EncodePKlassNode;
    70.5  class FastLockNode;
    70.6  class FastUnlockNode;
    70.7 +class FlagsProjNode;
    70.8  class IfNode;
    70.9  class IfFalseNode;
   70.10  class IfTrueNode;
   70.11 @@ -623,6 +624,7 @@
   70.12        DEFINE_CLASS_ID(Cmp,   Sub, 0)
   70.13          DEFINE_CLASS_ID(FastLock,   Cmp, 0)
   70.14          DEFINE_CLASS_ID(FastUnlock, Cmp, 1)
   70.15 +        DEFINE_CLASS_ID(FlagsProj, Cmp, 2)
   70.16  
   70.17      DEFINE_CLASS_ID(MergeMem, Node, 7)
   70.18      DEFINE_CLASS_ID(Bool,     Node, 8)
   70.19 @@ -726,6 +728,7 @@
   70.20    DEFINE_CLASS_QUERY(EncodePKlass)
   70.21    DEFINE_CLASS_QUERY(FastLock)
   70.22    DEFINE_CLASS_QUERY(FastUnlock)
   70.23 +  DEFINE_CLASS_QUERY(FlagsProj)
   70.24    DEFINE_CLASS_QUERY(If)
   70.25    DEFINE_CLASS_QUERY(IfFalse)
   70.26    DEFINE_CLASS_QUERY(IfTrue)
    71.1 --- a/src/share/vm/opto/subnode.cpp	Sat Oct 05 03:14:53 2013 +0200
    71.2 +++ b/src/share/vm/opto/subnode.cpp	Fri Oct 04 21:00:43 2013 -0700
    71.3 @@ -1064,7 +1064,7 @@
    71.4  // Print special per-node info
    71.5  #ifndef PRODUCT
    71.6  void BoolTest::dump_on(outputStream *st) const {
    71.7 -  const char *msg[] = {"eq","gt","??","lt","ne","le","??","ge"};
    71.8 +  const char *msg[] = {"eq","gt","of","lt","ne","le","nof","ge"};
    71.9    st->print(msg[_test]);
   71.10  }
   71.11  #endif
   71.12 @@ -1126,7 +1126,7 @@
   71.13    Node *cmp = in(1);
   71.14    if( !cmp->is_Sub() ) return NULL;
   71.15    int cop = cmp->Opcode();
   71.16 -  if( cop == Op_FastLock || cop == Op_FastUnlock ) return NULL;
   71.17 +  if( cop == Op_FastLock || cop == Op_FastUnlock || cop == Op_FlagsProj) return NULL;
   71.18    Node *cmp1 = cmp->in(1);
   71.19    Node *cmp2 = cmp->in(2);
   71.20    if( !cmp1 ) return NULL;
    72.1 --- a/src/share/vm/opto/subnode.hpp	Sat Oct 05 03:14:53 2013 +0200
    72.2 +++ b/src/share/vm/opto/subnode.hpp	Fri Oct 04 21:00:43 2013 -0700
    72.3 @@ -263,16 +263,16 @@
    72.4  // We pick the values as 3 bits; the low order 2 bits we compare against the
    72.5  // condition codes, the high bit flips the sense of the result.
    72.6  struct BoolTest VALUE_OBJ_CLASS_SPEC {
    72.7 -  enum mask { eq = 0, ne = 4, le = 5, ge = 7, lt = 3, gt = 1, illegal = 8 };
    72.8 +  enum mask { eq = 0, ne = 4, le = 5, ge = 7, lt = 3, gt = 1, overflow = 2, no_overflow = 6, illegal = 8 };
    72.9    mask _test;
   72.10    BoolTest( mask btm ) : _test(btm) {}
   72.11    const Type *cc2logical( const Type *CC ) const;
   72.12    // Commute the test.  I use a small table lookup.  The table is created as
   72.13    // a simple char array where each element is the ASCII version of a 'mask'
   72.14    // enum from above.
   72.15 -  mask commute( ) const { return mask("038147858"[_test]-'0'); }
   72.16 +  mask commute( ) const { return mask("032147658"[_test]-'0'); }
   72.17    mask negate( ) const { return mask(_test^4); }
   72.18 -  bool is_canonical( ) const { return (_test == BoolTest::ne || _test == BoolTest::lt || _test == BoolTest::le); }
   72.19 +  bool is_canonical( ) const { return (_test == BoolTest::ne || _test == BoolTest::lt || _test == BoolTest::le || _test == BoolTest::overflow); }
   72.20  #ifndef PRODUCT
   72.21    void dump_on(outputStream *st) const;
   72.22  #endif
    73.1 --- a/src/share/vm/opto/type.cpp	Sat Oct 05 03:14:53 2013 +0200
    73.2 +++ b/src/share/vm/opto/type.cpp	Fri Oct 04 21:00:43 2013 -0700
    73.3 @@ -430,6 +430,11 @@
    73.4    longpair[1] = TypeLong::LONG;
    73.5    TypeTuple::LONG_PAIR = TypeTuple::make(2, longpair);
    73.6  
    73.7 +  const Type **intccpair = TypeTuple::fields(2);
    73.8 +  intccpair[0] = TypeInt::INT;
    73.9 +  intccpair[1] = TypeInt::CC;
   73.10 +  TypeTuple::INT_CC_PAIR = TypeTuple::make(2, intccpair);
   73.11 +
   73.12    _const_basic_type[T_NARROWOOP]   = TypeNarrowOop::BOTTOM;
   73.13    _const_basic_type[T_NARROWKLASS] = Type::BOTTOM;
   73.14    _const_basic_type[T_BOOLEAN]     = TypeInt::BOOL;
   73.15 @@ -1646,6 +1651,7 @@
   73.16  const TypeTuple *TypeTuple::START_I2C;
   73.17  const TypeTuple *TypeTuple::INT_PAIR;
   73.18  const TypeTuple *TypeTuple::LONG_PAIR;
   73.19 +const TypeTuple *TypeTuple::INT_CC_PAIR;
   73.20  
   73.21  
   73.22  //------------------------------make-------------------------------------------
    74.1 --- a/src/share/vm/opto/type.hpp	Sat Oct 05 03:14:53 2013 +0200
    74.2 +++ b/src/share/vm/opto/type.hpp	Fri Oct 04 21:00:43 2013 -0700
    74.3 @@ -584,6 +584,7 @@
    74.4    static const TypeTuple *START_I2C;
    74.5    static const TypeTuple *INT_PAIR;
    74.6    static const TypeTuple *LONG_PAIR;
    74.7 +  static const TypeTuple *INT_CC_PAIR;
    74.8  #ifndef PRODUCT
    74.9    virtual void dump2( Dict &d, uint, outputStream *st  ) const; // Specialized per-Type dumping
   74.10  #endif
    75.1 --- a/src/share/vm/prims/jvm.cpp	Sat Oct 05 03:14:53 2013 +0200
    75.2 +++ b/src/share/vm/prims/jvm.cpp	Fri Oct 04 21:00:43 2013 -0700
    75.3 @@ -3984,13 +3984,13 @@
    75.4  
    75.5  JVM_LEAF(jboolean, JVM_AccessVMBooleanFlag(const char* name, jboolean* value, jboolean is_get))
    75.6    JVMWrapper("JVM_AccessBoolVMFlag");
    75.7 -  return is_get ? CommandLineFlags::boolAt((char*) name, (bool*) value) : CommandLineFlags::boolAtPut((char*) name, (bool*) value, INTERNAL);
    75.8 +  return is_get ? CommandLineFlags::boolAt((char*) name, (bool*) value) : CommandLineFlags::boolAtPut((char*) name, (bool*) value, Flag::INTERNAL);
    75.9  JVM_END
   75.10  
   75.11  JVM_LEAF(jboolean, JVM_AccessVMIntFlag(const char* name, jint* value, jboolean is_get))
   75.12    JVMWrapper("JVM_AccessVMIntFlag");
   75.13    intx v;
   75.14 -  jboolean result = is_get ? CommandLineFlags::intxAt((char*) name, &v) : CommandLineFlags::intxAtPut((char*) name, &v, INTERNAL);
   75.15 +  jboolean result = is_get ? CommandLineFlags::intxAt((char*) name, &v) : CommandLineFlags::intxAtPut((char*) name, &v, Flag::INTERNAL);
   75.16    *value = (jint)v;
   75.17    return result;
   75.18  JVM_END
    76.1 --- a/src/share/vm/runtime/arguments.cpp	Sat Oct 05 03:14:53 2013 +0200
    76.2 +++ b/src/share/vm/runtime/arguments.cpp	Fri Oct 04 21:00:43 2013 -0700
    76.3 @@ -625,11 +625,11 @@
    76.4    }
    76.5  }
    76.6  
    76.7 -static bool set_bool_flag(char* name, bool value, FlagValueOrigin origin) {
    76.8 +static bool set_bool_flag(char* name, bool value, Flag::Flags origin) {
    76.9    return CommandLineFlags::boolAtPut(name, &value, origin);
   76.10  }
   76.11  
   76.12 -static bool set_fp_numeric_flag(char* name, char* value, FlagValueOrigin origin) {
   76.13 +static bool set_fp_numeric_flag(char* name, char* value, Flag::Flags origin) {
   76.14    double v;
   76.15    if (sscanf(value, "%lf", &v) != 1) {
   76.16      return false;
   76.17 @@ -641,7 +641,7 @@
   76.18    return false;
   76.19  }
   76.20  
   76.21 -static bool set_numeric_flag(char* name, char* value, FlagValueOrigin origin) {
   76.22 +static bool set_numeric_flag(char* name, char* value, Flag::Flags origin) {
   76.23    julong v;
   76.24    intx intx_v;
   76.25    bool is_neg = false;
   76.26 @@ -674,14 +674,14 @@
   76.27    return false;
   76.28  }
   76.29  
   76.30 -static bool set_string_flag(char* name, const char* value, FlagValueOrigin origin) {
   76.31 +static bool set_string_flag(char* name, const char* value, Flag::Flags origin) {
   76.32    if (!CommandLineFlags::ccstrAtPut(name, &value, origin))  return false;
   76.33    // Contract:  CommandLineFlags always returns a pointer that needs freeing.
   76.34    FREE_C_HEAP_ARRAY(char, value, mtInternal);
   76.35    return true;
   76.36  }
   76.37  
   76.38 -static bool append_to_string_flag(char* name, const char* new_value, FlagValueOrigin origin) {
   76.39 +static bool append_to_string_flag(char* name, const char* new_value, Flag::Flags origin) {
   76.40    const char* old_value = "";
   76.41    if (!CommandLineFlags::ccstrAt(name, &old_value))  return false;
   76.42    size_t old_len = old_value != NULL ? strlen(old_value) : 0;
   76.43 @@ -709,7 +709,7 @@
   76.44    return true;
   76.45  }
   76.46  
   76.47 -bool Arguments::parse_argument(const char* arg, FlagValueOrigin origin) {
   76.48 +bool Arguments::parse_argument(const char* arg, Flag::Flags origin) {
   76.49  
   76.50    // range of acceptable characters spelled out for portability reasons
   76.51  #define NAME_RANGE  "[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]"
   76.52 @@ -850,7 +850,7 @@
   76.53  }
   76.54  
   76.55  bool Arguments::process_argument(const char* arg,
   76.56 -    jboolean ignore_unrecognized, FlagValueOrigin origin) {
   76.57 +    jboolean ignore_unrecognized, Flag::Flags origin) {
   76.58  
   76.59    JDK_Version since = JDK_Version();
   76.60  
   76.61 @@ -904,7 +904,7 @@
   76.62        jio_fprintf(defaultStream::error_stream(),
   76.63                    "Did you mean '%s%s%s'?\n",
   76.64                    (fuzzy_matched->is_bool()) ? "(+/-)" : "",
   76.65 -                  fuzzy_matched->name,
   76.66 +                  fuzzy_matched->_name,
   76.67                    (fuzzy_matched->is_bool()) ? "" : "=<value>");
   76.68      }
   76.69    }
   76.70 @@ -952,7 +952,7 @@
   76.71          // this allows a way to include spaces in string-valued options
   76.72          token[pos] = '\0';
   76.73          logOption(token);
   76.74 -        result &= process_argument(token, ignore_unrecognized, CONFIG_FILE);
   76.75 +        result &= process_argument(token, ignore_unrecognized, Flag::CONFIG_FILE);
   76.76          build_jvm_flags(token);
   76.77          pos = 0;
   76.78          in_white_space = true;
   76.79 @@ -970,7 +970,7 @@
   76.80    }
   76.81    if (pos > 0) {
   76.82      token[pos] = '\0';
   76.83 -    result &= process_argument(token, ignore_unrecognized, CONFIG_FILE);
   76.84 +    result &= process_argument(token, ignore_unrecognized, Flag::CONFIG_FILE);
   76.85      build_jvm_flags(token);
   76.86    }
   76.87    fclose(stream);
   76.88 @@ -1132,6 +1132,9 @@
   76.89      Tier3InvokeNotifyFreqLog = 0;
   76.90      Tier4InvocationThreshold = 0;
   76.91    }
   76.92 +  if (FLAG_IS_DEFAULT(NmethodSweepFraction)) {
   76.93 +    FLAG_SET_DEFAULT(NmethodSweepFraction, 1 + ReservedCodeCacheSize / (16 * M));
   76.94 +  }
   76.95  }
   76.96  
   76.97  #if INCLUDE_ALL_GCS
   76.98 @@ -2337,6 +2340,10 @@
   76.99                  (2*G)/M);
  76.100      status = false;
  76.101    }
  76.102 +
  76.103 +  status &= verify_interval(NmethodSweepFraction, 1, ReservedCodeCacheSize/K, "NmethodSweepFraction");
  76.104 +  status &= verify_interval(NmethodSweepActivity, 0, 2000, "NmethodSweepActivity");
  76.105 +
  76.106    return status;
  76.107  }
  76.108  
  76.109 @@ -2438,7 +2445,7 @@
  76.110    }
  76.111  
  76.112    // Parse JavaVMInitArgs structure passed in
  76.113 -  result = parse_each_vm_init_arg(args, &scp, &scp_assembly_required, COMMAND_LINE);
  76.114 +  result = parse_each_vm_init_arg(args, &scp, &scp_assembly_required, Flag::COMMAND_LINE);
  76.115    if (result != JNI_OK) {
  76.116      return result;
  76.117    }
  76.118 @@ -2510,7 +2517,7 @@
  76.119  jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
  76.120                                         SysClassPath* scp_p,
  76.121                                         bool* scp_assembly_required_p,
  76.122 -                                       FlagValueOrigin origin) {
  76.123 +                                       Flag::Flags origin) {
  76.124    // Remaining part of option string
  76.125    const char* tail;
  76.126  
  76.127 @@ -3333,7 +3340,7 @@
  76.128        }
  76.129      }
  76.130  
  76.131 -    return(parse_each_vm_init_arg(&vm_args, scp_p, scp_assembly_required_p, ENVIRON_VAR));
  76.132 +    return(parse_each_vm_init_arg(&vm_args, scp_p, scp_assembly_required_p, Flag::ENVIRON_VAR));
  76.133    }
  76.134    return JNI_OK;
  76.135  }
    77.1 --- a/src/share/vm/runtime/arguments.hpp	Sat Oct 05 03:14:53 2013 +0200
    77.2 +++ b/src/share/vm/runtime/arguments.hpp	Fri Oct 04 21:00:43 2013 -0700
    77.3 @@ -360,15 +360,15 @@
    77.4  
    77.5    // Argument parsing
    77.6    static void do_pd_flag_adjustments();
    77.7 -  static bool parse_argument(const char* arg, FlagValueOrigin origin);
    77.8 -  static bool process_argument(const char* arg, jboolean ignore_unrecognized, FlagValueOrigin origin);
    77.9 +  static bool parse_argument(const char* arg, Flag::Flags origin);
   77.10 +  static bool process_argument(const char* arg, jboolean ignore_unrecognized, Flag::Flags origin);
   77.11    static void process_java_launcher_argument(const char*, void*);
   77.12    static void process_java_compiler_argument(char* arg);
   77.13    static jint parse_options_environment_variable(const char* name, SysClassPath* scp_p, bool* scp_assembly_required_p);
   77.14    static jint parse_java_tool_options_environment_variable(SysClassPath* scp_p, bool* scp_assembly_required_p);
   77.15    static jint parse_java_options_environment_variable(SysClassPath* scp_p, bool* scp_assembly_required_p);
   77.16    static jint parse_vm_init_args(const JavaVMInitArgs* args);
   77.17 -  static jint parse_each_vm_init_arg(const JavaVMInitArgs* args, SysClassPath* scp_p, bool* scp_assembly_required_p, FlagValueOrigin origin);
   77.18 +  static jint parse_each_vm_init_arg(const JavaVMInitArgs* args, SysClassPath* scp_p, bool* scp_assembly_required_p, Flag::Flags origin);
   77.19    static jint finalize_vm_init_args(SysClassPath* scp_p, bool scp_assembly_required);
   77.20    static bool is_bad_option(const JavaVMOption* option, jboolean ignore,
   77.21      const char* option_type);
    78.1 --- a/src/share/vm/runtime/globals.cpp	Sat Oct 05 03:14:53 2013 +0200
    78.2 +++ b/src/share/vm/runtime/globals.cpp	Fri Oct 04 21:00:43 2013 -0700
    78.3 @@ -62,26 +62,174 @@
    78.4  MATERIALIZE_FLAGS_EXT
    78.5  
    78.6  
    78.7 +void Flag::check_writable() {
    78.8 +  if (is_constant_in_binary()) {
    78.9 +    fatal(err_msg("flag is constant: %s", _name));
   78.10 +  }
   78.11 +}
   78.12 +
   78.13 +bool Flag::is_bool() const {
   78.14 +  return strcmp(_type, "bool") == 0;
   78.15 +}
   78.16 +
   78.17 +bool Flag::get_bool() const {
   78.18 +  return *((bool*) _addr);
   78.19 +}
   78.20 +
   78.21 +void Flag::set_bool(bool value) {
   78.22 +  check_writable();
   78.23 +  *((bool*) _addr) = value;
   78.24 +}
   78.25 +
   78.26 +bool Flag::is_intx() const {
   78.27 +  return strcmp(_type, "intx")  == 0;
   78.28 +}
   78.29 +
   78.30 +intx Flag::get_intx() const {
   78.31 +  return *((intx*) _addr);
   78.32 +}
   78.33 +
   78.34 +void Flag::set_intx(intx value) {
   78.35 +  check_writable();
   78.36 +  *((intx*) _addr) = value;
   78.37 +}
   78.38 +
   78.39 +bool Flag::is_uintx() const {
   78.40 +  return strcmp(_type, "uintx") == 0;
   78.41 +}
   78.42 +
   78.43 +uintx Flag::get_uintx() const {
   78.44 +  return *((uintx*) _addr);
   78.45 +}
   78.46 +
   78.47 +void Flag::set_uintx(uintx value) {
   78.48 +  check_writable();
   78.49 +  *((uintx*) _addr) = value;
   78.50 +}
   78.51 +
   78.52 +bool Flag::is_uint64_t() const {
   78.53 +  return strcmp(_type, "uint64_t") == 0;
   78.54 +}
   78.55 +
   78.56 +uint64_t Flag::get_uint64_t() const {
   78.57 +  return *((uint64_t*) _addr);
   78.58 +}
   78.59 +
   78.60 +void Flag::set_uint64_t(uint64_t value) {
   78.61 +  check_writable();
   78.62 +  *((uint64_t*) _addr) = value;
   78.63 +}
   78.64 +
   78.65 +bool Flag::is_double() const {
   78.66 +  return strcmp(_type, "double") == 0;
   78.67 +}
   78.68 +
   78.69 +double Flag::get_double() const {
   78.70 +  return *((double*) _addr);
   78.71 +}
   78.72 +
   78.73 +void Flag::set_double(double value) {
   78.74 +  check_writable();
   78.75 +  *((double*) _addr) = value;
   78.76 +}
   78.77 +
   78.78 +bool Flag::is_ccstr() const {
   78.79 +  return strcmp(_type, "ccstr") == 0 || strcmp(_type, "ccstrlist") == 0;
   78.80 +}
   78.81 +
   78.82 +bool Flag::ccstr_accumulates() const {
   78.83 +  return strcmp(_type, "ccstrlist") == 0;
   78.84 +}
   78.85 +
   78.86 +ccstr Flag::get_ccstr() const {
   78.87 +  return *((ccstr*) _addr);
   78.88 +}
   78.89 +
   78.90 +void Flag::set_ccstr(ccstr value) {
   78.91 +  check_writable();
   78.92 +  *((ccstr*) _addr) = value;
   78.93 +}
   78.94 +
   78.95 +
   78.96 +Flag::Flags Flag::get_origin() {
   78.97 +  return Flags(_flags & VALUE_ORIGIN_MASK);
   78.98 +}
   78.99 +
  78.100 +void Flag::set_origin(Flags origin) {
  78.101 +  assert((origin & VALUE_ORIGIN_MASK) == origin, "sanity");
  78.102 +  _flags = Flags((_flags & ~VALUE_ORIGIN_MASK) | origin);
  78.103 +}
  78.104 +
  78.105 +bool Flag::is_default() {
  78.106 +  return (get_origin() == DEFAULT);
  78.107 +}
  78.108 +
  78.109 +bool Flag::is_ergonomic() {
  78.110 +  return (get_origin() == ERGONOMIC);
  78.111 +}
  78.112 +
  78.113 +bool Flag::is_command_line() {
  78.114 +  return (get_origin() == COMMAND_LINE);
  78.115 +}
  78.116 +
  78.117 +bool Flag::is_product() const {
  78.118 +  return (_flags & KIND_PRODUCT) != 0;
  78.119 +}
  78.120 +
  78.121 +bool Flag::is_manageable() const {
  78.122 +  return (_flags & KIND_MANAGEABLE) != 0;
  78.123 +}
  78.124 +
  78.125 +bool Flag::is_diagnostic() const {
  78.126 +  return (_flags & KIND_DIAGNOSTIC) != 0;
  78.127 +}
  78.128 +
  78.129 +bool Flag::is_experimental() const {
  78.130 +  return (_flags & KIND_EXPERIMENTAL) != 0;
  78.131 +}
  78.132 +
  78.133 +bool Flag::is_notproduct() const {
  78.134 +  return (_flags & KIND_NOT_PRODUCT) != 0;
  78.135 +}
  78.136 +
  78.137 +bool Flag::is_develop() const {
  78.138 +  return (_flags & KIND_DEVELOP) != 0;
  78.139 +}
  78.140 +
  78.141 +bool Flag::is_read_write() const {
  78.142 +  return (_flags & KIND_READ_WRITE) != 0;
  78.143 +}
  78.144 +
  78.145 +bool Flag::is_commercial() const {
  78.146 +  return (_flags & KIND_COMMERCIAL) != 0;
  78.147 +}
  78.148 +
  78.149 +/**
  78.150 + * Returns if this flag is a constant in the binary.  Right now this is
  78.151 + * true for notproduct and develop flags in product builds.
  78.152 + */
  78.153 +bool Flag::is_constant_in_binary() const {
  78.154 +#ifdef PRODUCT
  78.155 +    return is_notproduct() || is_develop();
  78.156 +#else
  78.157 +    return false;
  78.158 +#endif
  78.159 +}
  78.160 +
  78.161  bool Flag::is_unlocker() const {
  78.162 -  return strcmp(name, "UnlockDiagnosticVMOptions") == 0     ||
  78.163 -         strcmp(name, "UnlockExperimentalVMOptions") == 0   ||
  78.164 +  return strcmp(_name, "UnlockDiagnosticVMOptions") == 0     ||
  78.165 +         strcmp(_name, "UnlockExperimentalVMOptions") == 0   ||
  78.166           is_unlocker_ext();
  78.167  }
  78.168  
  78.169  bool Flag::is_unlocked() const {
  78.170 -  if (strcmp(kind, "{diagnostic}") == 0 ||
  78.171 -      strcmp(kind, "{C2 diagnostic}") == 0 ||
  78.172 -      strcmp(kind, "{ARCH diagnostic}") == 0 ||
  78.173 -      strcmp(kind, "{Shark diagnostic}") == 0) {
  78.174 +  if (is_diagnostic()) {
  78.175      return UnlockDiagnosticVMOptions;
  78.176 -  } else if (strcmp(kind, "{experimental}") == 0 ||
  78.177 -             strcmp(kind, "{C2 experimental}") == 0 ||
  78.178 -             strcmp(kind, "{ARCH experimental}") == 0 ||
  78.179 -             strcmp(kind, "{Shark experimental}") == 0) {
  78.180 +  }
  78.181 +  if (is_experimental()) {
  78.182      return UnlockExperimentalVMOptions;
  78.183 -  } else {
  78.184 -    return is_unlocked_ext();
  78.185    }
  78.186 +  return is_unlocked_ext();
  78.187  }
  78.188  
  78.189  // Get custom message for this locked flag, or return NULL if
  78.190 @@ -91,16 +239,14 @@
  78.191  }
  78.192  
  78.193  bool Flag::is_writeable() const {
  78.194 -  return strcmp(kind, "{manageable}") == 0 ||
  78.195 -         strcmp(kind, "{product rw}") == 0 ||
  78.196 -         is_writeable_ext();
  78.197 +  return is_manageable() || (is_product() && is_read_write()) || is_writeable_ext();
  78.198  }
  78.199  
  78.200  // All flags except "manageable" are assumed to be internal flags.
  78.201  // Long term, we need to define a mechanism to specify which flags
  78.202  // are external/stable and change this function accordingly.
  78.203  bool Flag::is_external() const {
  78.204 -  return strcmp(kind, "{manageable}") == 0 || is_external_ext();
  78.205 +  return is_manageable() || is_external_ext();
  78.206  }
  78.207  
  78.208  
  78.209 @@ -108,53 +254,113 @@
  78.210  #define FORMAT_BUFFER_LEN 16
  78.211  
  78.212  void Flag::print_on(outputStream* st, bool withComments) {
  78.213 -  st->print("%9s %-40s %c= ", type, name, (origin != DEFAULT ? ':' : ' '));
  78.214 -  if (is_bool())     st->print("%-16s", get_bool() ? "true" : "false");
  78.215 -  if (is_intx())     st->print("%-16ld", get_intx());
  78.216 -  if (is_uintx())    st->print("%-16lu", get_uintx());
  78.217 -  if (is_uint64_t()) st->print("%-16lu", get_uint64_t());
  78.218 -  if (is_double())   st->print("%-16f", get_double());
  78.219 +  // Don't print notproduct and develop flags in a product build.
  78.220 +  if (is_constant_in_binary()) {
  78.221 +    return;
  78.222 +  }
  78.223  
  78.224 +  st->print("%9s %-40s %c= ", _type, _name, (!is_default() ? ':' : ' '));
  78.225 +
  78.226 +  if (is_bool()) {
  78.227 +    st->print("%-16s", get_bool() ? "true" : "false");
  78.228 +  }
  78.229 +  if (is_intx()) {
  78.230 +    st->print("%-16ld", get_intx());
  78.231 +  }
  78.232 +  if (is_uintx()) {
  78.233 +    st->print("%-16lu", get_uintx());
  78.234 +  }
  78.235 +  if (is_uint64_t()) {
  78.236 +    st->print("%-16lu", get_uint64_t());
  78.237 +  }
  78.238 +  if (is_double()) {
  78.239 +    st->print("%-16f", get_double());
  78.240 +  }
  78.241    if (is_ccstr()) {
  78.242 -     const char* cp = get_ccstr();
  78.243 -     if (cp != NULL) {
  78.244 -       const char* eol;
  78.245 -       while ((eol = strchr(cp, '\n')) != NULL) {
  78.246 -         char format_buffer[FORMAT_BUFFER_LEN];
  78.247 -         size_t llen = pointer_delta(eol, cp, sizeof(char));
  78.248 -         jio_snprintf(format_buffer, FORMAT_BUFFER_LEN,
  78.249 -                     "%%." SIZE_FORMAT "s", llen);
  78.250 -         st->print(format_buffer, cp);
  78.251 -         st->cr();
  78.252 -         cp = eol+1;
  78.253 -         st->print("%5s %-35s += ", "", name);
  78.254 -       }
  78.255 -       st->print("%-16s", cp);
  78.256 -     }
  78.257 -     else st->print("%-16s", "");
  78.258 +    const char* cp = get_ccstr();
  78.259 +    if (cp != NULL) {
  78.260 +      const char* eol;
  78.261 +      while ((eol = strchr(cp, '\n')) != NULL) {
  78.262 +        char format_buffer[FORMAT_BUFFER_LEN];
  78.263 +        size_t llen = pointer_delta(eol, cp, sizeof(char));
  78.264 +        jio_snprintf(format_buffer, FORMAT_BUFFER_LEN,
  78.265 +            "%%." SIZE_FORMAT "s", llen);
  78.266 +        st->print(format_buffer, cp);
  78.267 +        st->cr();
  78.268 +        cp = eol+1;
  78.269 +        st->print("%5s %-35s += ", "", _name);
  78.270 +      }
  78.271 +      st->print("%-16s", cp);
  78.272 +    }
  78.273 +    else st->print("%-16s", "");
  78.274    }
  78.275 -  st->print("%-20s", kind);
  78.276 +
  78.277 +  st->print("%-20");
  78.278 +  print_kind(st);
  78.279 +
  78.280    if (withComments) {
  78.281  #ifndef PRODUCT
  78.282 -    st->print("%s", doc );
  78.283 +    st->print("%s", _doc);
  78.284  #endif
  78.285    }
  78.286    st->cr();
  78.287  }
  78.288  
  78.289 +void Flag::print_kind(outputStream* st) {
  78.290 +  struct Data {
  78.291 +    int flag;
  78.292 +    const char* name;
  78.293 +  };
  78.294 +
  78.295 +  Data data[] = {
  78.296 +      { KIND_C1, "C1" },
  78.297 +      { KIND_C2, "C2" },
  78.298 +      { KIND_ARCH, "ARCH" },
  78.299 +      { KIND_SHARK, "SHARK" },
  78.300 +      { KIND_PLATFORM_DEPENDENT, "pd" },
  78.301 +      { KIND_PRODUCT, "product" },
  78.302 +      { KIND_MANAGEABLE, "manageable" },
  78.303 +      { KIND_DIAGNOSTIC, "diagnostic" },
  78.304 +      { KIND_NOT_PRODUCT, "notproduct" },
  78.305 +      { KIND_DEVELOP, "develop" },
  78.306 +      { KIND_LP64_PRODUCT, "lp64_product" },
  78.307 +      { KIND_READ_WRITE, "rw" },
  78.308 +      { -1, "" }
  78.309 +  };
  78.310 +
  78.311 +  if ((_flags & KIND_MASK) != 0) {
  78.312 +    st->print("{");
  78.313 +    bool is_first = true;
  78.314 +
  78.315 +    for (int i = 0; data[i].flag != -1; i++) {
  78.316 +      Data d = data[i];
  78.317 +      if ((_flags & d.flag) != 0) {
  78.318 +        if (is_first) {
  78.319 +          is_first = false;
  78.320 +        } else {
  78.321 +          st->print(" ");
  78.322 +        }
  78.323 +        st->print(d.name);
  78.324 +      }
  78.325 +    }
  78.326 +
  78.327 +    st->print("}");
  78.328 +  }
  78.329 +}
  78.330 +
  78.331  void Flag::print_as_flag(outputStream* st) {
  78.332    if (is_bool()) {
  78.333 -    st->print("-XX:%s%s", get_bool() ? "+" : "-", name);
  78.334 +    st->print("-XX:%s%s", get_bool() ? "+" : "-", _name);
  78.335    } else if (is_intx()) {
  78.336 -    st->print("-XX:%s=" INTX_FORMAT, name, get_intx());
  78.337 +    st->print("-XX:%s=" INTX_FORMAT, _name, get_intx());
  78.338    } else if (is_uintx()) {
  78.339 -    st->print("-XX:%s=" UINTX_FORMAT, name, get_uintx());
  78.340 +    st->print("-XX:%s=" UINTX_FORMAT, _name, get_uintx());
  78.341    } else if (is_uint64_t()) {
  78.342 -    st->print("-XX:%s=" UINT64_FORMAT, name, get_uint64_t());
  78.343 +    st->print("-XX:%s=" UINT64_FORMAT, _name, get_uint64_t());
  78.344    } else if (is_double()) {
  78.345 -    st->print("-XX:%s=%f", name, get_double());
  78.346 +    st->print("-XX:%s=%f", _name, get_double());
  78.347    } else if (is_ccstr()) {
  78.348 -    st->print("-XX:%s=", name);
  78.349 +    st->print("-XX:%s=", _name);
  78.350      const char* cp = get_ccstr();
  78.351      if (cp != NULL) {
  78.352        // Need to turn embedded '\n's back into separate arguments
  78.353 @@ -167,7 +373,7 @@
  78.354              st->print("%c", *cp);
  78.355              break;
  78.356            case '\n':
  78.357 -            st->print(" -XX:%s=", name);
  78.358 +            st->print(" -XX:%s=", _name);
  78.359              break;
  78.360          }
  78.361        }
  78.362 @@ -180,79 +386,51 @@
  78.363  // 4991491 do not "optimize out" the was_set false values: omitting them
  78.364  // tickles a Microsoft compiler bug causing flagTable to be malformed
  78.365  
  78.366 -#define RUNTIME_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{product}", DEFAULT },
  78.367 -#define RUNTIME_PD_PRODUCT_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{pd product}", DEFAULT },
  78.368 -#define RUNTIME_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{diagnostic}", DEFAULT },
  78.369 -#define RUNTIME_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{experimental}", DEFAULT },
  78.370 -#define RUNTIME_MANAGEABLE_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{manageable}", DEFAULT },
  78.371 -#define RUNTIME_PRODUCT_RW_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{product rw}", DEFAULT },
  78.372 +#define NAME(name) NOT_PRODUCT(&name) PRODUCT_ONLY(&CONST_##name)
  78.373  
  78.374 -#ifdef PRODUCT
  78.375 -  #define RUNTIME_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
  78.376 -  #define RUNTIME_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     /* flag is constant */
  78.377 -  #define RUNTIME_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc)
  78.378 -#else
  78.379 -  #define RUNTIME_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "", DEFAULT },
  78.380 -  #define RUNTIME_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, doc, "{pd}", DEFAULT },
  78.381 -  #define RUNTIME_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{notproduct}", DEFAULT },
  78.382 -#endif
  78.383 +#define RUNTIME_PRODUCT_FLAG_STRUCT(     type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_PRODUCT) },
  78.384 +#define RUNTIME_PD_PRODUCT_FLAG_STRUCT(  type, name,        doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_PRODUCT | Flag::KIND_PLATFORM_DEPENDENT) },
  78.385 +#define RUNTIME_DIAGNOSTIC_FLAG_STRUCT(  type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_DIAGNOSTIC) },
  78.386 +#define RUNTIME_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_EXPERIMENTAL) },
  78.387 +#define RUNTIME_MANAGEABLE_FLAG_STRUCT(  type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_MANAGEABLE) },
  78.388 +#define RUNTIME_PRODUCT_RW_FLAG_STRUCT(  type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_PRODUCT | Flag::KIND_READ_WRITE) },
  78.389 +#define RUNTIME_DEVELOP_FLAG_STRUCT(     type, name, value, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_DEVELOP) },
  78.390 +#define RUNTIME_PD_DEVELOP_FLAG_STRUCT(  type, name,        doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_DEVELOP | Flag::KIND_PLATFORM_DEPENDENT) },
  78.391 +#define RUNTIME_NOTPRODUCT_FLAG_STRUCT(  type, name, value, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_NOT_PRODUCT) },
  78.392  
  78.393  #ifdef _LP64
  78.394 -  #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{lp64_product}", DEFAULT },
  78.395 +#define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_LP64_PRODUCT) },
  78.396  #else
  78.397 -  #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
  78.398 +#define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
  78.399  #endif // _LP64
  78.400  
  78.401 -#define C1_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C1 product}", DEFAULT },
  78.402 -#define C1_PD_PRODUCT_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C1 pd product}", DEFAULT },
  78.403 -#define C1_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C1 diagnostic}", DEFAULT },
  78.404 -#ifdef PRODUCT
  78.405 -  #define C1_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
  78.406 -  #define C1_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     /* flag is constant */
  78.407 -  #define C1_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc)
  78.408 -#else
  78.409 -  #define C1_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C1}", DEFAULT },
  78.410 -  #define C1_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, doc, "{C1 pd}", DEFAULT },
  78.411 -  #define C1_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C1 notproduct}", DEFAULT },
  78.412 -#endif
  78.413 +#define C1_PRODUCT_FLAG_STRUCT(          type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_PRODUCT) },
  78.414 +#define C1_PD_PRODUCT_FLAG_STRUCT(       type, name,        doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_PRODUCT | Flag::KIND_PLATFORM_DEPENDENT) },
  78.415 +#define C1_DIAGNOSTIC_FLAG_STRUCT(       type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_DIAGNOSTIC) },
  78.416 +#define C1_DEVELOP_FLAG_STRUCT(          type, name, value, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_DEVELOP) },
  78.417 +#define C1_PD_DEVELOP_FLAG_STRUCT(       type, name,        doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_DEVELOP | Flag::KIND_PLATFORM_DEPENDENT) },
  78.418 +#define C1_NOTPRODUCT_FLAG_STRUCT(       type, name, value, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_NOT_PRODUCT) },
  78.419  
  78.420 -#define C2_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 product}", DEFAULT },
  78.421 -#define C2_PD_PRODUCT_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 pd product}", DEFAULT },
  78.422 -#define C2_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 diagnostic}", DEFAULT },
  78.423 -#define C2_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 experimental}", DEFAULT },
  78.424 -#ifdef PRODUCT
  78.425 -  #define C2_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
  78.426 -  #define C2_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     /* flag is constant */
  78.427 -  #define C2_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc)
  78.428 -#else
  78.429 -  #define C2_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C2}", DEFAULT },
  78.430 -  #define C2_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, doc, "{C2 pd}", DEFAULT },
  78.431 -  #define C2_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C2 notproduct}", DEFAULT },
  78.432 -#endif
  78.433 +#define C2_PRODUCT_FLAG_STRUCT(          type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_PRODUCT) },
  78.434 +#define C2_PD_PRODUCT_FLAG_STRUCT(       type, name,        doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_PRODUCT | Flag::KIND_PLATFORM_DEPENDENT) },
  78.435 +#define C2_DIAGNOSTIC_FLAG_STRUCT(       type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_DIAGNOSTIC) },
  78.436 +#define C2_EXPERIMENTAL_FLAG_STRUCT(     type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_EXPERIMENTAL) },
  78.437 +#define C2_DEVELOP_FLAG_STRUCT(          type, name, value, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_DEVELOP) },
  78.438 +#define C2_PD_DEVELOP_FLAG_STRUCT(       type, name,        doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_DEVELOP | Flag::KIND_PLATFORM_DEPENDENT) },
  78.439 +#define C2_NOTPRODUCT_FLAG_STRUCT(       type, name, value, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_NOT_PRODUCT) },
  78.440  
  78.441 -#define ARCH_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{ARCH product}", DEFAULT },
  78.442 -#define ARCH_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{ARCH diagnostic}", DEFAULT },
  78.443 -#define ARCH_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{ARCH experimental}", DEFAULT },
  78.444 -#ifdef PRODUCT
  78.445 -  #define ARCH_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
  78.446 -  #define ARCH_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc)
  78.447 -#else
  78.448 -  #define ARCH_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{ARCH}", DEFAULT },
  78.449 -  #define ARCH_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{ARCH notproduct}", DEFAULT },
  78.450 -#endif
  78.451 +#define ARCH_PRODUCT_FLAG_STRUCT(        type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_ARCH | Flag::KIND_PRODUCT) },
  78.452 +#define ARCH_DIAGNOSTIC_FLAG_STRUCT(     type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_ARCH | Flag::KIND_DIAGNOSTIC) },
  78.453 +#define ARCH_EXPERIMENTAL_FLAG_STRUCT(   type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_ARCH | Flag::KIND_EXPERIMENTAL) },
  78.454 +#define ARCH_DEVELOP_FLAG_STRUCT(        type, name, value, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_ARCH | Flag::KIND_DEVELOP) },
  78.455 +#define ARCH_NOTPRODUCT_FLAG_STRUCT(     type, name, value, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_ARCH | Flag::KIND_NOT_PRODUCT) },
  78.456  
  78.457 -#define SHARK_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{Shark product}", DEFAULT },
  78.458 -#define SHARK_PD_PRODUCT_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{Shark pd product}", DEFAULT },
  78.459 -#define SHARK_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{Shark diagnostic}", DEFAULT },
  78.460 -#ifdef PRODUCT
  78.461 -  #define SHARK_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
  78.462 -  #define SHARK_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     /* flag is constant */
  78.463 -  #define SHARK_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc)
  78.464 -#else
  78.465 -  #define SHARK_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{Shark}", DEFAULT },
  78.466 -  #define SHARK_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, doc, "{Shark pd}", DEFAULT },
  78.467 -  #define SHARK_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{Shark notproduct}", DEFAULT },
  78.468 -#endif
  78.469 +#define SHARK_PRODUCT_FLAG_STRUCT(       type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_PRODUCT) },
  78.470 +#define SHARK_PD_PRODUCT_FLAG_STRUCT(    type, name,        doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_PRODUCT | Flag::KIND_PLATFORM_DEPENDENT) },
  78.471 +#define SHARK_DIAGNOSTIC_FLAG_STRUCT(    type, name, value, doc) { #type, XSTR(name), &name,      NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_DIAGNOSTIC) },
  78.472 +#define SHARK_DEVELOP_FLAG_STRUCT(       type, name, value, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_DEVELOP) },
  78.473 +#define SHARK_PD_DEVELOP_FLAG_STRUCT(    type, name,        doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_DEVELOP | Flag::KIND_PLATFORM_DEPENDENT) },
  78.474 +#define SHARK_NOTPRODUCT_FLAG_STRUCT(    type, name, value, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_NOT_PRODUCT) },
  78.475  
  78.476  static Flag flagTable[] = {
  78.477   RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_EXPERIMENTAL_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT, RUNTIME_MANAGEABLE_FLAG_STRUCT, RUNTIME_PRODUCT_RW_FLAG_STRUCT, RUNTIME_LP64_PRODUCT_FLAG_STRUCT)
  78.478 @@ -285,9 +463,14 @@
  78.479  
  78.480  // Search the flag table for a named flag
  78.481  Flag* Flag::find_flag(const char* name, size_t length, bool allow_locked) {
  78.482 -  for (Flag* current = &flagTable[0]; current->name != NULL; current++) {
  78.483 -    if (str_equal(current->name, name, length)) {
  78.484 -      // Found a matching entry.  Report locked flags only if allowed.
  78.485 +  for (Flag* current = &flagTable[0]; current->_name != NULL; current++) {
  78.486 +    if (str_equal(current->_name, name, length)) {
  78.487 +      // Found a matching entry.
  78.488 +      // Don't report notproduct and develop flags in product builds.
  78.489 +      if (current->is_constant_in_binary()) {
  78.490 +        return NULL;
  78.491 +      }
  78.492 +      // Report locked flags only if allowed.
  78.493        if (!(current->is_unlocked() || current->is_unlocker())) {
  78.494          if (!allow_locked) {
  78.495            // disable use of locked flags, e.g. diagnostic, experimental,
  78.496 @@ -327,8 +510,8 @@
  78.497    float score;
  78.498    float max_score = -1;
  78.499  
  78.500 -  for (Flag* current = &flagTable[0]; current->name != NULL; current++) {
  78.501 -    score = str_similar(current->name, name, length);
  78.502 +  for (Flag* current = &flagTable[0]; current->_name != NULL; current++) {
  78.503 +    score = str_similar(current->_name, name, length);
  78.504      if (score > max_score) {
  78.505        max_score = score;
  78.506        match = current;
  78.507 @@ -357,25 +540,25 @@
  78.508  bool CommandLineFlagsEx::is_default(CommandLineFlag flag) {
  78.509    assert((size_t)flag < Flag::numFlags, "bad command line flag index");
  78.510    Flag* f = &Flag::flags[flag];
  78.511 -  return (f->origin == DEFAULT);
  78.512 +  return f->is_default();
  78.513  }
  78.514  
  78.515  bool CommandLineFlagsEx::is_ergo(CommandLineFlag flag) {
  78.516    assert((size_t)flag < Flag::numFlags, "bad command line flag index");
  78.517    Flag* f = &Flag::flags[flag];
  78.518 -  return (f->origin == ERGONOMIC);
  78.519 +  return f->is_ergonomic();
  78.520  }
  78.521  
  78.522  bool CommandLineFlagsEx::is_cmdline(CommandLineFlag flag) {
  78.523    assert((size_t)flag < Flag::numFlags, "bad command line flag index");
  78.524    Flag* f = &Flag::flags[flag];
  78.525 -  return (f->origin == COMMAND_LINE);
  78.526 +  return f->is_command_line();
  78.527  }
  78.528  
  78.529  bool CommandLineFlags::wasSetOnCmdline(const char* name, bool* value) {
  78.530    Flag* result = Flag::find_flag((char*)name, strlen(name));
  78.531    if (result == NULL) return false;
  78.532 -  *value = (result->origin == COMMAND_LINE);
  78.533 +  *value = result->is_command_line();
  78.534    return true;
  78.535  }
  78.536  
  78.537 @@ -387,22 +570,22 @@
  78.538    return true;
  78.539  }
  78.540  
  78.541 -bool CommandLineFlags::boolAtPut(char* name, size_t len, bool* value, FlagValueOrigin origin) {
  78.542 +bool CommandLineFlags::boolAtPut(char* name, size_t len, bool* value, Flag::Flags origin) {
  78.543    Flag* result = Flag::find_flag(name, len);
  78.544    if (result == NULL) return false;
  78.545    if (!result->is_bool()) return false;
  78.546    bool old_value = result->get_bool();
  78.547    result->set_bool(*value);
  78.548    *value = old_value;
  78.549 -  result->origin = origin;
  78.550 +  result->set_origin(origin);
  78.551    return true;
  78.552  }
  78.553  
  78.554 -void CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, FlagValueOrigin origin) {
  78.555 +void CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, Flag::Flags origin) {
  78.556    Flag* faddr = address_of_flag(flag);
  78.557    guarantee(faddr != NULL && faddr->is_bool(), "wrong flag type");
  78.558    faddr->set_bool(value);
  78.559 -  faddr->origin = origin;
  78.560 +  faddr->set_origin(origin);
  78.561  }
  78.562  
  78.563  bool CommandLineFlags::intxAt(char* name, size_t len, intx* value) {
  78.564 @@ -413,22 +596,22 @@
  78.565    return true;
  78.566  }
  78.567  
  78.568 -bool CommandLineFlags::intxAtPut(char* name, size_t len, intx* value, FlagValueOrigin origin) {
  78.569 +bool CommandLineFlags::intxAtPut(char* name, size_t len, intx* value, Flag::Flags origin) {
  78.570    Flag* result = Flag::find_flag(name, len);
  78.571    if (result == NULL) return false;
  78.572    if (!result->is_intx()) return false;
  78.573    intx old_value = result->get_intx();
  78.574    result->set_intx(*value);
  78.575    *value = old_value;
  78.576 -  result->origin = origin;
  78.577 +  result->set_origin(origin);
  78.578    return true;
  78.579  }
  78.580  
  78.581 -void CommandLineFlagsEx::intxAtPut(CommandLineFlagWithType flag, intx value, FlagValueOrigin origin) {
  78.582 +void CommandLineFlagsEx::intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin) {
  78.583    Flag* faddr = address_of_flag(flag);
  78.584    guarantee(faddr != NULL && faddr->is_intx(), "wrong flag type");
  78.585    faddr->set_intx(value);
  78.586 -  faddr->origin = origin;
  78.587 +  faddr->set_origin(origin);
  78.588  }
  78.589  
  78.590  bool CommandLineFlags::uintxAt(char* name, size_t len, uintx* value) {
  78.591 @@ -439,22 +622,22 @@
  78.592    return true;
  78.593  }
  78.594  
  78.595 -bool CommandLineFlags::uintxAtPut(char* name, size_t len, uintx* value, FlagValueOrigin origin) {
  78.596 +bool CommandLineFlags::uintxAtPut(char* name, size_t len, uintx* value, Flag::Flags origin) {
  78.597    Flag* result = Flag::find_flag(name, len);
  78.598    if (result == NULL) return false;
  78.599    if (!result->is_uintx()) return false;
  78.600    uintx old_value = result->get_uintx();
  78.601    result->set_uintx(*value);
  78.602    *value = old_value;
  78.603 -  result->origin = origin;
  78.604 +  result->set_origin(origin);
  78.605    return true;
  78.606  }
  78.607  
  78.608 -void CommandLineFlagsEx::uintxAtPut(CommandLineFlagWithType flag, uintx value, FlagValueOrigin origin) {
  78.609 +void CommandLineFlagsEx::uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin) {
  78.610    Flag* faddr = address_of_flag(flag);
  78.611    guarantee(faddr != NULL && faddr->is_uintx(), "wrong flag type");
  78.612    faddr->set_uintx(value);
  78.613 -  faddr->origin = origin;
  78.614 +  faddr->set_origin(origin);
  78.615  }
  78.616  
  78.617  bool CommandLineFlags::uint64_tAt(char* name, size_t len, uint64_t* value) {
  78.618 @@ -465,22 +648,22 @@
  78.619    return true;
  78.620  }
  78.621  
  78.622 -bool CommandLineFlags::uint64_tAtPut(char* name, size_t len, uint64_t* value, FlagValueOrigin origin) {
  78.623 +bool CommandLineFlags::uint64_tAtPut(char* name, size_t len, uint64_t* value, Flag::Flags origin) {
  78.624    Flag* result = Flag::find_flag(name, len);
  78.625    if (result == NULL) return false;
  78.626    if (!result->is_uint64_t()) return false;
  78.627    uint64_t old_value = result->get_uint64_t();
  78.628    result->set_uint64_t(*value);
  78.629    *value = old_value;
  78.630 -  result->origin = origin;
  78.631 +  result->set_origin(origin);
  78.632    return true;
  78.633  }
  78.634  
  78.635 -void CommandLineFlagsEx::uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, FlagValueOrigin origin) {
  78.636 +void CommandLineFlagsEx::uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin) {
  78.637    Flag* faddr = address_of_flag(flag);
  78.638    guarantee(faddr != NULL && faddr->is_uint64_t(), "wrong flag type");
  78.639    faddr->set_uint64_t(value);
  78.640 -  faddr->origin = origin;
  78.641 +  faddr->set_origin(origin);
  78.642  }
  78.643  
  78.644  bool CommandLineFlags::doubleAt(char* name, size_t len, double* value) {
  78.645 @@ -491,22 +674,22 @@
  78.646    return true;
  78.647  }
  78.648  
  78.649 -bool CommandLineFlags::doubleAtPut(char* name, size_t len, double* value, FlagValueOrigin origin) {
  78.650 +bool CommandLineFlags::doubleAtPut(char* name, size_t len, double* value, Flag::Flags origin) {
  78.651    Flag* result = Flag::find_flag(name, len);
  78.652    if (result == NULL) return false;
  78.653    if (!result->is_double()) return false;
  78.654    double old_value = result->get_double();
  78.655    result->set_double(*value);
  78.656    *value = old_value;
  78.657 -  result->origin = origin;
  78.658 +  result->set_origin(origin);
  78.659    return true;
  78.660  }
  78.661  
  78.662 -void CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value, FlagValueOrigin origin) {
  78.663 +void CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin) {
  78.664    Flag* faddr = address_of_flag(flag);
  78.665    guarantee(faddr != NULL && faddr->is_double(), "wrong flag type");
  78.666    faddr->set_double(value);
  78.667 -  faddr->origin = origin;
  78.668 +  faddr->set_origin(origin);
  78.669  }
  78.670  
  78.671  bool CommandLineFlags::ccstrAt(char* name, size_t len, ccstr* value) {
  78.672 @@ -519,7 +702,7 @@
  78.673  
  78.674  // Contract:  Flag will make private copy of the incoming value.
  78.675  // Outgoing value is always malloc-ed, and caller MUST call free.
  78.676 -bool CommandLineFlags::ccstrAtPut(char* name, size_t len, ccstr* value, FlagValueOrigin origin) {
  78.677 +bool CommandLineFlags::ccstrAtPut(char* name, size_t len, ccstr* value, Flag::Flags origin) {
  78.678    Flag* result = Flag::find_flag(name, len);
  78.679    if (result == NULL) return false;
  78.680    if (!result->is_ccstr()) return false;
  78.681 @@ -530,35 +713,35 @@
  78.682      strcpy(new_value, *value);
  78.683    }
  78.684    result->set_ccstr(new_value);
  78.685 -  if (result->origin == DEFAULT && old_value != NULL) {
  78.686 +  if (result->is_default() && old_value != NULL) {
  78.687      // Prior value is NOT heap allocated, but was a literal constant.
  78.688      char* old_value_to_free = NEW_C_HEAP_ARRAY(char, strlen(old_value)+1, mtInternal);
  78.689      strcpy(old_value_to_free, old_value);
  78.690      old_value = old_value_to_free;
  78.691    }
  78.692    *value = old_value;
  78.693 -  result->origin = origin;
  78.694 +  result->set_origin(origin);
  78.695    return true;
  78.696  }
  78.697  
  78.698  // Contract:  Flag will make private copy of the incoming value.
  78.699 -void CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, FlagValueOrigin origin) {
  78.700 +void CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin) {
  78.701    Flag* faddr = address_of_flag(flag);
  78.702    guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type");
  78.703    ccstr old_value = faddr->get_ccstr();
  78.704    char* new_value = NEW_C_HEAP_ARRAY(char, strlen(value)+1, mtInternal);
  78.705    strcpy(new_value, value);
  78.706    faddr->set_ccstr(new_value);
  78.707 -  if (faddr->origin != DEFAULT && old_value != NULL) {
  78.708 +  if (!faddr->is_default() && old_value != NULL) {
  78.709      // Prior value is heap allocated so free it.
  78.710      FREE_C_HEAP_ARRAY(char, old_value, mtInternal);
  78.711    }
  78.712 -  faddr->origin = origin;
  78.713 +  faddr->set_origin(origin);
  78.714  }
  78.715  
  78.716  extern "C" {
  78.717    static int compare_flags(const void* void_a, const void* void_b) {
  78.718 -    return strcmp((*((Flag**) void_a))->name, (*((Flag**) void_b))->name);
  78.719 +    return strcmp((*((Flag**) void_a))->_name, (*((Flag**) void_b))->_name);
  78.720    }
  78.721  }
  78.722  
  78.723 @@ -567,20 +750,19 @@
  78.724    // note: this method is called before the thread structure is in place
  78.725    //       which means resource allocation cannot be used.
  78.726  
  78.727 -  // Compute size
  78.728 -  int length= 0;
  78.729 -  while (flagTable[length].name != NULL) length++;
  78.730 +  // The last entry is the null entry.
  78.731 +  const size_t length = Flag::numFlags - 1;
  78.732  
  78.733    // Sort
  78.734    Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal);
  78.735 -  for (int index = 0; index < length; index++) {
  78.736 -    array[index] = &flagTable[index];
  78.737 +  for (size_t i = 0; i < length; i++) {
  78.738 +    array[i] = &flagTable[i];
  78.739    }
  78.740    qsort(array, length, sizeof(Flag*), compare_flags);
  78.741  
  78.742    // Print
  78.743 -  for (int i = 0; i < length; i++) {
  78.744 -    if (array[i]->origin /* naked field! */) {
  78.745 +  for (size_t i = 0; i < length; i++) {
  78.746 +    if (array[i]->get_origin() /* naked field! */) {
  78.747        array[i]->print_as_flag(out);
  78.748        out->print(" ");
  78.749      }
  78.750 @@ -603,20 +785,19 @@
  78.751    // note: this method is called before the thread structure is in place
  78.752    //       which means resource allocation cannot be used.
  78.753  
  78.754 -  // Compute size
  78.755 -  int length= 0;
  78.756 -  while (flagTable[length].name != NULL) length++;
  78.757 +  // The last entry is the null entry.
  78.758 +  const size_t length = Flag::numFlags - 1;
  78.759  
  78.760    // Sort
  78.761    Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal);
  78.762 -  for (int index = 0; index < length; index++) {
  78.763 -    array[index] = &flagTable[index];
  78.764 +  for (size_t i = 0; i < length; i++) {
  78.765 +    array[i] = &flagTable[i];
  78.766    }
  78.767    qsort(array, length, sizeof(Flag*), compare_flags);
  78.768  
  78.769    // Print
  78.770    out->print_cr("[Global flags]");
  78.771 -  for (int i = 0; i < length; i++) {
  78.772 +  for (size_t i = 0; i < length; i++) {
  78.773      if (array[i]->is_unlocked()) {
  78.774        array[i]->print_on(out, withComments);
  78.775      }
    79.1 --- a/src/share/vm/runtime/globals.hpp	Sat Oct 05 03:14:53 2013 +0200
    79.2 +++ b/src/share/vm/runtime/globals.hpp	Fri Oct 04 21:00:43 2013 -0700
    79.3 @@ -194,29 +194,49 @@
    79.4  typedef const char* ccstr;
    79.5  typedef const char* ccstrlist;   // represents string arguments which accumulate
    79.6  
    79.7 -enum FlagValueOrigin {
    79.8 -  DEFAULT          = 0,
    79.9 -  COMMAND_LINE     = 1,
   79.10 -  ENVIRON_VAR      = 2,
   79.11 -  CONFIG_FILE      = 3,
   79.12 -  MANAGEMENT       = 4,
   79.13 -  ERGONOMIC        = 5,
   79.14 -  ATTACH_ON_DEMAND = 6,
   79.15 -  INTERNAL         = 99
   79.16 -};
   79.17 +struct Flag {
   79.18 +  enum Flags {
   79.19 +    // value origin
   79.20 +    DEFAULT          = 0,
   79.21 +    COMMAND_LINE     = 1,
   79.22 +    ENVIRON_VAR      = 2,
   79.23 +    CONFIG_FILE      = 3,
   79.24 +    MANAGEMENT       = 4,
   79.25 +    ERGONOMIC        = 5,
   79.26 +    ATTACH_ON_DEMAND = 6,
   79.27 +    INTERNAL         = 7,
   79.28  
   79.29 -struct Flag {
   79.30 -  const char *type;
   79.31 -  const char *name;
   79.32 -  void*       addr;
   79.33 +    LAST_VALUE_ORIGIN = INTERNAL,
   79.34 +    VALUE_ORIGIN_BITS = 4,
   79.35 +    VALUE_ORIGIN_MASK = right_n_bits(VALUE_ORIGIN_BITS),
   79.36  
   79.37 -  NOT_PRODUCT(const char *doc;)
   79.38 +    // flag kind
   79.39 +    KIND_PRODUCT            = 1 << 4,
   79.40 +    KIND_MANAGEABLE         = 1 << 5,
   79.41 +    KIND_DIAGNOSTIC         = 1 << 6,
   79.42 +    KIND_EXPERIMENTAL       = 1 << 7,
   79.43 +    KIND_NOT_PRODUCT        = 1 << 8,
   79.44 +    KIND_DEVELOP            = 1 << 9,
   79.45 +    KIND_PLATFORM_DEPENDENT = 1 << 10,
   79.46 +    KIND_READ_WRITE         = 1 << 11,
   79.47 +    KIND_C1                 = 1 << 12,
   79.48 +    KIND_C2                 = 1 << 13,
   79.49 +    KIND_ARCH               = 1 << 14,
   79.50 +    KIND_SHARK              = 1 << 15,
   79.51 +    KIND_LP64_PRODUCT       = 1 << 16,
   79.52 +    KIND_COMMERCIAL         = 1 << 17,
   79.53  
   79.54 -  const char *kind;
   79.55 -  FlagValueOrigin origin;
   79.56 +    KIND_MASK = ~VALUE_ORIGIN_MASK
   79.57 +  };
   79.58 +
   79.59 +  const char* _type;
   79.60 +  const char* _name;
   79.61 +  void* _addr;
   79.62 +  NOT_PRODUCT(const char* _doc;)
   79.63 +  Flags _flags;
   79.64  
   79.65    // points to all Flags static array
   79.66 -  static Flag *flags;
   79.67 +  static Flag* flags;
   79.68  
   79.69    // number of flags
   79.70    static size_t numFlags;
   79.71 @@ -224,30 +244,50 @@
   79.72    static Flag* find_flag(const char* name, size_t length, bool allow_locked = false);
   79.73    static Flag* fuzzy_match(const char* name, size_t length, bool allow_locked = false);
   79.74  
   79.75 -  bool is_bool() const        { return strcmp(type, "bool") == 0; }
   79.76 -  bool get_bool() const       { return *((bool*) addr); }
   79.77 -  void set_bool(bool value)   { *((bool*) addr) = value; }
   79.78 +  void check_writable();
   79.79  
   79.80 -  bool is_intx()  const       { return strcmp(type, "intx")  == 0; }
   79.81 -  intx get_intx() const       { return *((intx*) addr); }
   79.82 -  void set_intx(intx value)   { *((intx*) addr) = value; }
   79.83 +  bool is_bool() const;
   79.84 +  bool get_bool() const;
   79.85 +  void set_bool(bool value);
   79.86  
   79.87 -  bool is_uintx() const       { return strcmp(type, "uintx") == 0; }
   79.88 -  uintx get_uintx() const     { return *((uintx*) addr); }
   79.89 -  void set_uintx(uintx value) { *((uintx*) addr) = value; }
   79.90 +  bool is_intx() const;
   79.91 +  intx get_intx() const;
   79.92 +  void set_intx(intx value);
   79.93  
   79.94 -  bool is_uint64_t() const          { return strcmp(type, "uint64_t") == 0; }
   79.95 -  uint64_t get_uint64_t() const     { return *((uint64_t*) addr); }
   79.96 -  void set_uint64_t(uint64_t value) { *((uint64_t*) addr) = value; }
   79.97 +  bool is_uintx() const;
   79.98 +  uintx get_uintx() const;
   79.99 +  void set_uintx(uintx value);
  79.100  
  79.101 -  bool is_double() const        { return strcmp(type, "double") == 0; }
  79.102 -  double get_double() const     { return *((double*) addr); }
  79.103 -  void set_double(double value) { *((double*) addr) = value; }
  79.104 +  bool is_uint64_t() const;
  79.105 +  uint64_t get_uint64_t() const;
  79.106 +  void set_uint64_t(uint64_t value);
  79.107  
  79.108 -  bool is_ccstr() const          { return strcmp(type, "ccstr") == 0 || strcmp(type, "ccstrlist") == 0; }
  79.109 -  bool ccstr_accumulates() const { return strcmp(type, "ccstrlist") == 0; }
  79.110 -  ccstr get_ccstr() const     { return *((ccstr*) addr); }
  79.111 -  void set_ccstr(ccstr value) { *((ccstr*) addr) = value; }
  79.112 +  bool is_double() const;
  79.113 +  double get_double() const;
  79.114 +  void set_double(double value);
  79.115 +
  79.116 +  bool is_ccstr() const;
  79.117 +  bool ccstr_accumulates() const;
  79.118 +  ccstr get_ccstr() const;
  79.119 +  void set_ccstr(ccstr value);
  79.120 +
  79.121 +  Flags get_origin();
  79.122 +  void set_origin(Flags origin);
  79.123 +
  79.124 +  bool is_default();
  79.125 +  bool is_ergonomic();
  79.126 +  bool is_command_line();
  79.127 +
  79.128 +  bool is_product() const;
  79.129 +  bool is_manageable() const;
  79.130 +  bool is_diagnostic() const;
  79.131 +  bool is_experimental() const;
  79.132 +  bool is_notproduct() const;
  79.133 +  bool is_develop() const;
  79.134 +  bool is_read_write() const;
  79.135 +  bool is_commercial() const;
  79.136 +
  79.137 +  bool is_constant_in_binary() const;
  79.138  
  79.139    bool is_unlocker() const;
  79.140    bool is_unlocked() const;
  79.141 @@ -263,6 +303,7 @@
  79.142    void get_locked_message_ext(char*, int) const;
  79.143  
  79.144    void print_on(outputStream* st, bool withComments = false );
  79.145 +  void print_kind(outputStream* st);
  79.146    void print_as_flag(outputStream* st);
  79.147  };
  79.148  
  79.149 @@ -310,33 +351,33 @@
  79.150   public:
  79.151    static bool boolAt(char* name, size_t len, bool* value);
  79.152    static bool boolAt(char* name, bool* value)      { return boolAt(name, strlen(name), value); }
  79.153 -  static bool boolAtPut(char* name, size_t len, bool* value, FlagValueOrigin origin);
  79.154 -  static bool boolAtPut(char* name, bool* value, FlagValueOrigin origin)   { return boolAtPut(name, strlen(name), value, origin); }
  79.155 +  static bool boolAtPut(char* name, size_t len, bool* value, Flag::Flags origin);
  79.156 +  static bool boolAtPut(char* name, bool* value, Flag::Flags origin)   { return boolAtPut(name, strlen(name), value, origin); }
  79.157  
  79.158    static bool intxAt(char* name, size_t len, intx* value);
  79.159    static bool intxAt(char* name, intx* value)      { return intxAt(name, strlen(name), value); }
  79.160 -  static bool intxAtPut(char* name, size_t len, intx* value, FlagValueOrigin origin);
  79.161 -  static bool intxAtPut(char* name, intx* value, FlagValueOrigin origin)   { return intxAtPut(name, strlen(name), value, origin); }
  79.162 +  static bool intxAtPut(char* name, size_t len, intx* value, Flag::Flags origin);
  79.163 +  static bool intxAtPut(char* name, intx* value, Flag::Flags origin)   { return intxAtPut(name, strlen(name), value, origin); }
  79.164  
  79.165    static bool uintxAt(char* name, size_t len, uintx* value);
  79.166    static bool uintxAt(char* name, uintx* value)    { return uintxAt(name, strlen(name), value); }
  79.167 -  static bool uintxAtPut(char* name, size_t len, uintx* value, FlagValueOrigin origin);
  79.168 -  static bool uintxAtPut(char* name, uintx* value, FlagValueOrigin origin) { return uintxAtPut(name, strlen(name), value, origin); }
  79.169 +  static bool uintxAtPut(char* name, size_t len, uintx* value, Flag::Flags origin);
  79.170 +  static bool uintxAtPut(char* name, uintx* value, Flag::Flags origin) { return uintxAtPut(name, strlen(name), value, origin); }
  79.171  
  79.172    static bool uint64_tAt(char* name, size_t len, uint64_t* value);
  79.173    static bool uint64_tAt(char* name, uint64_t* value) { return uint64_tAt(name, strlen(name), value); }
  79.174 -  static bool uint64_tAtPut(char* name, size_t len, uint64_t* value, FlagValueOrigin origin);
  79.175 -  static bool uint64_tAtPut(char* name, uint64_t* value, FlagValueOrigin origin) { return uint64_tAtPut(name, strlen(name), value, origin); }
  79.176 +  static bool uint64_tAtPut(char* name, size_t len, uint64_t* value, Flag::Flags origin);
  79.177 +  static bool uint64_tAtPut(char* name, uint64_t* value, Flag::Flags origin) { return uint64_tAtPut(name, strlen(name), value, origin); }
  79.178  
  79.179    static bool doubleAt(char* name, size_t len, double* value);
  79.180    static bool doubleAt(char* name, double* value)    { return doubleAt(name, strlen(name), value); }
  79.181 -  static bool doubleAtPut(char* name, size_t len, double* value, FlagValueOrigin origin);
  79.182 -  static bool doubleAtPut(char* name, double* value, FlagValueOrigin origin) { return doubleAtPut(name, strlen(name), value, origin); }
  79.183 +  static bool doubleAtPut(char* name, size_t len, double* value, Flag::Flags origin);
  79.184 +  static bool doubleAtPut(char* name, double* value, Flag::Flags origin) { return doubleAtPut(name, strlen(name), value, origin); }
  79.185  
  79.186    static bool ccstrAt(char* name, size_t len, ccstr* value);
  79.187    static bool ccstrAt(char* name, ccstr* value)    { return ccstrAt(name, strlen(name), value); }
  79.188 -  static bool ccstrAtPut(char* name, size_t len, ccstr* value, FlagValueOrigin origin);
  79.189 -  static bool ccstrAtPut(char* name, ccstr* value, FlagValueOrigin origin) { return ccstrAtPut(name, strlen(name), value, origin); }
  79.190 +  static bool ccstrAtPut(char* name, size_t len, ccstr* value, Flag::Flags origin);
  79.191 +  static bool ccstrAtPut(char* name, ccstr* value, Flag::Flags origin) { return ccstrAtPut(name, strlen(name), value, origin); }
  79.192  
  79.193    // Returns false if name is not a command line flag.
  79.194    static bool wasSetOnCmdline(const char* name, bool* value);
  79.195 @@ -2830,6 +2871,10 @@
  79.196    product(intx, NmethodSweepCheckInterval, 5,                               \
  79.197            "Compilers wake up every n seconds to possibly sweep nmethods")   \
  79.198                                                                              \
  79.199 +  product(intx, NmethodSweepActivity, 10,                                   \
  79.200 +          "Removes cold nmethods from code cache if > 0. Higher values "    \
  79.201 +          "result in more aggressive sweeping")                             \
  79.202 +                                                                            \
  79.203    notproduct(bool, LogSweeper, false,                                       \
  79.204              "Keep a ring buffer of sweeper activity")                       \
  79.205                                                                              \
  79.206 @@ -3201,15 +3246,6 @@
  79.207    product(bool, UseCodeCacheFlushing, true,                                 \
  79.208            "Attempt to clean the code cache before shutting off compiler")   \
  79.209                                                                              \
  79.210 -  product(intx,  MinCodeCacheFlushingInterval, 30,                          \
  79.211 -          "Min number of seconds between code cache cleaning sessions")     \
  79.212 -                                                                            \
  79.213 -  product(uintx,  CodeCacheFlushingMinimumFreeSpace, 1500*K,                \
  79.214 -          "When less than X space left, start code cache cleaning")         \
  79.215 -                                                                            \
  79.216 -  product(uintx, CodeCacheFlushingFraction, 2,                              \
  79.217 -          "Fraction of the code cache that is flushed when full")           \
  79.218 -                                                                            \
  79.219    /* interpreter debugging */                                               \
  79.220    develop(intx, BinarySwitchThreshold, 5,                                   \
  79.221            "Minimal number of lookupswitch entries for rewriting to binary " \
  79.222 @@ -3730,20 +3766,20 @@
  79.223   */
  79.224  
  79.225  // Interface macros
  79.226 -#define DECLARE_PRODUCT_FLAG(type, name, value, doc)    extern "C" type name;
  79.227 -#define DECLARE_PD_PRODUCT_FLAG(type, name, doc)        extern "C" type name;
  79.228 -#define DECLARE_DIAGNOSTIC_FLAG(type, name, value, doc) extern "C" type name;
  79.229 +#define DECLARE_PRODUCT_FLAG(type, name, value, doc)      extern "C" type name;
  79.230 +#define DECLARE_PD_PRODUCT_FLAG(type, name, doc)          extern "C" type name;
  79.231 +#define DECLARE_DIAGNOSTIC_FLAG(type, name, value, doc)   extern "C" type name;
  79.232  #define DECLARE_EXPERIMENTAL_FLAG(type, name, value, doc) extern "C" type name;
  79.233 -#define DECLARE_MANAGEABLE_FLAG(type, name, value, doc) extern "C" type name;
  79.234 -#define DECLARE_PRODUCT_RW_FLAG(type, name, value, doc) extern "C" type name;
  79.235 +#define DECLARE_MANAGEABLE_FLAG(type, name, value, doc)   extern "C" type name;
  79.236 +#define DECLARE_PRODUCT_RW_FLAG(type, name, value, doc)   extern "C" type name;
  79.237  #ifdef PRODUCT
  79.238 -#define DECLARE_DEVELOPER_FLAG(type, name, value, doc)  const type name = value;
  79.239 -#define DECLARE_PD_DEVELOPER_FLAG(type, name, doc)      const type name = pd_##name;
  79.240 -#define DECLARE_NOTPRODUCT_FLAG(type, name, value, doc)
  79.241 +#define DECLARE_DEVELOPER_FLAG(type, name, value, doc)    extern "C" type CONST_##name; const type name = value;
  79.242 +#define DECLARE_PD_DEVELOPER_FLAG(type, name, doc)        extern "C" type CONST_##name; const type name = pd_##name;
  79.243 +#define DECLARE_NOTPRODUCT_FLAG(type, name, value, doc)   extern "C" type CONST_##name;
  79.244  #else
  79.245 -#define DECLARE_DEVELOPER_FLAG(type, name, value, doc)  extern "C" type name;
  79.246 -#define DECLARE_PD_DEVELOPER_FLAG(type, name, doc)      extern "C" type name;
  79.247 -#define DECLARE_NOTPRODUCT_FLAG(type, name, value, doc)  extern "C" type name;
  79.248 +#define DECLARE_DEVELOPER_FLAG(type, name, value, doc)    extern "C" type name;
  79.249 +#define DECLARE_PD_DEVELOPER_FLAG(type, name, doc)        extern "C" type name;
  79.250 +#define DECLARE_NOTPRODUCT_FLAG(type, name, value, doc)   extern "C" type name;
  79.251  #endif
  79.252  // Special LP64 flags, product only needed for now.
  79.253  #ifdef _LP64
  79.254 @@ -3753,23 +3789,23 @@
  79.255  #endif // _LP64
  79.256  
  79.257  // Implementation macros
  79.258 -#define MATERIALIZE_PRODUCT_FLAG(type, name, value, doc)   type name = value;
  79.259 -#define MATERIALIZE_PD_PRODUCT_FLAG(type, name, doc)       type name = pd_##name;
  79.260 -#define MATERIALIZE_DIAGNOSTIC_FLAG(type, name, value, doc) type name = value;
  79.261 +#define MATERIALIZE_PRODUCT_FLAG(type, name, value, doc)      type name = value;
  79.262 +#define MATERIALIZE_PD_PRODUCT_FLAG(type, name, doc)          type name = pd_##name;
  79.263 +#define MATERIALIZE_DIAGNOSTIC_FLAG(type, name, value, doc)   type name = value;
  79.264  #define MATERIALIZE_EXPERIMENTAL_FLAG(type, name, value, doc) type name = value;
  79.265 -#define MATERIALIZE_MANAGEABLE_FLAG(type, name, value, doc) type name = value;
  79.266 -#define MATERIALIZE_PRODUCT_RW_FLAG(type, name, value, doc) type name = value;
  79.267 +#define MATERIALIZE_MANAGEABLE_FLAG(type, name, value, doc)   type name = value;
  79.268 +#define MATERIALIZE_PRODUCT_RW_FLAG(type, name, value, doc)   type name = value;
  79.269  #ifdef PRODUCT
  79.270 -#define MATERIALIZE_DEVELOPER_FLAG(type, name, value, doc) /* flag name is constant */
  79.271 -#define MATERIALIZE_PD_DEVELOPER_FLAG(type, name, doc)     /* flag name is constant */
  79.272 -#define MATERIALIZE_NOTPRODUCT_FLAG(type, name, value, doc)
  79.273 +#define MATERIALIZE_DEVELOPER_FLAG(type, name, value, doc)    type CONST_##name = value;
  79.274 +#define MATERIALIZE_PD_DEVELOPER_FLAG(type, name, doc)        type CONST_##name = pd_##name;
  79.275 +#define MATERIALIZE_NOTPRODUCT_FLAG(type, name, value, doc)   type CONST_##name = value;
  79.276  #else
  79.277 -#define MATERIALIZE_DEVELOPER_FLAG(type, name, value, doc) type name = value;
  79.278 -#define MATERIALIZE_PD_DEVELOPER_FLAG(type, name, doc)     type name = pd_##name;
  79.279 -#define MATERIALIZE_NOTPRODUCT_FLAG(type, name, value, doc) type name = value;
  79.280 +#define MATERIALIZE_DEVELOPER_FLAG(type, name, value, doc)    type name = value;
  79.281 +#define MATERIALIZE_PD_DEVELOPER_FLAG(type, name, doc)        type name = pd_##name;
  79.282 +#define MATERIALIZE_NOTPRODUCT_FLAG(type, name, value, doc)   type name = value;
  79.283  #endif
  79.284  #ifdef _LP64
  79.285 -#define MATERIALIZE_LP64_PRODUCT_FLAG(type, name, value, doc)   type name = value;
  79.286 +#define MATERIALIZE_LP64_PRODUCT_FLAG(type, name, value, doc) type name = value;
  79.287  #else
  79.288  #define MATERIALIZE_LP64_PRODUCT_FLAG(type, name, value, doc) /* flag is constant */
  79.289  #endif // _LP64
    80.1 --- a/src/share/vm/runtime/globals_extension.hpp	Sat Oct 05 03:14:53 2013 +0200
    80.2 +++ b/src/share/vm/runtime/globals_extension.hpp	Fri Oct 04 21:00:43 2013 -0700
    80.3 @@ -34,64 +34,42 @@
    80.4  // Parens left off in the following for the enum decl below.
    80.5  #define FLAG_MEMBER(flag) Flag_##flag
    80.6  
    80.7 -#define RUNTIME_PRODUCT_FLAG_MEMBER(type, name, value, doc)    FLAG_MEMBER(name),
    80.8 -#define RUNTIME_PD_PRODUCT_FLAG_MEMBER(type, name, doc)        FLAG_MEMBER(name),
    80.9 -#define RUNTIME_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
   80.10 +#define RUNTIME_PRODUCT_FLAG_MEMBER(type, name, value, doc)      FLAG_MEMBER(name),
   80.11 +#define RUNTIME_PD_PRODUCT_FLAG_MEMBER(type, name, doc)          FLAG_MEMBER(name),
   80.12 +#define RUNTIME_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc)   FLAG_MEMBER(name),
   80.13  #define RUNTIME_EXPERIMENTAL_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
   80.14 -#define RUNTIME_MANAGEABLE_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
   80.15 -#define RUNTIME_PRODUCT_RW_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
   80.16 -#ifdef PRODUCT
   80.17 -  #define RUNTIME_DEVELOP_FLAG_MEMBER(type, name, value, doc)  /* flag is constant */
   80.18 -  #define RUNTIME_PD_DEVELOP_FLAG_MEMBER(type, name, doc)      /* flag is constant */
   80.19 -  #define RUNTIME_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)
   80.20 +#define RUNTIME_MANAGEABLE_FLAG_MEMBER(type, name, value, doc)   FLAG_MEMBER(name),
   80.21 +#define RUNTIME_PRODUCT_RW_FLAG_MEMBER(type, name, value, doc)   FLAG_MEMBER(name),
   80.22 +#define RUNTIME_DEVELOP_FLAG_MEMBER(type, name, value, doc)      FLAG_MEMBER(name),
   80.23 +#define RUNTIME_PD_DEVELOP_FLAG_MEMBER(type, name, doc)          FLAG_MEMBER(name),
   80.24 +#define RUNTIME_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)   FLAG_MEMBER(name),
   80.25 +
   80.26 +#ifdef _LP64
   80.27 +#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
   80.28  #else
   80.29 -  #define RUNTIME_DEVELOP_FLAG_MEMBER(type, name, value, doc)  FLAG_MEMBER(name),
   80.30 -  #define RUNTIME_PD_DEVELOP_FLAG_MEMBER(type, name, doc)      FLAG_MEMBER(name),
   80.31 -  #define RUNTIME_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
   80.32 -#endif
   80.33 -#ifdef _LP64
   80.34 -#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER(type, name, value, doc)    FLAG_MEMBER(name),
   80.35 -#else
   80.36 -#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER(type, name, value, doc)    /* flag is constant */
   80.37 +#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER(type, name, value, doc) /* flag is constant */
   80.38  #endif // _LP64
   80.39  
   80.40 -#define C1_PRODUCT_FLAG_MEMBER(type, name, value, doc)         FLAG_MEMBER(name),
   80.41 -#define C1_PD_PRODUCT_FLAG_MEMBER(type, name, doc)             FLAG_MEMBER(name),
   80.42 -#define C1_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc)      FLAG_MEMBER(name),
   80.43 -#ifdef PRODUCT
   80.44 -  #define C1_DEVELOP_FLAG_MEMBER(type, name, value, doc)       /* flag is constant */
   80.45 -  #define C1_PD_DEVELOP_FLAG_MEMBER(type, name, doc)           /* flag is constant */
   80.46 -  #define C1_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)
   80.47 -#else
   80.48 -  #define C1_DEVELOP_FLAG_MEMBER(type, name, value, doc)       FLAG_MEMBER(name),
   80.49 -  #define C1_PD_DEVELOP_FLAG_MEMBER(type, name, doc)           FLAG_MEMBER(name),
   80.50 -  #define C1_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)    FLAG_MEMBER(name),
   80.51 -#endif
   80.52 +#define C1_PRODUCT_FLAG_MEMBER(type, name, value, doc)           FLAG_MEMBER(name),
   80.53 +#define C1_PD_PRODUCT_FLAG_MEMBER(type, name, doc)               FLAG_MEMBER(name),
   80.54 +#define C1_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc)        FLAG_MEMBER(name),
   80.55 +#define C1_DEVELOP_FLAG_MEMBER(type, name, value, doc)           FLAG_MEMBER(name),
   80.56 +#define C1_PD_DEVELOP_FLAG_MEMBER(type, name, doc)               FLAG_MEMBER(name),
   80.57 +#define C1_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)        FLAG_MEMBER(name),
   80.58  
   80.59 -#define C2_PRODUCT_FLAG_MEMBER(type, name, value, doc)         FLAG_MEMBER(name),
   80.60 -#define C2_PD_PRODUCT_FLAG_MEMBER(type, name, doc)             FLAG_MEMBER(name),
   80.61 -#define C2_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc)      FLAG_MEMBER(name),
   80.62 -#define C2_EXPERIMENTAL_FLAG_MEMBER(type, name, value, doc)    FLAG_MEMBER(name),
   80.63 -#ifdef PRODUCT
   80.64 -  #define C2_DEVELOP_FLAG_MEMBER(type, name, value, doc)       /* flag is constant */
   80.65 -  #define C2_PD_DEVELOP_FLAG_MEMBER(type, name, doc)           /* flag is constant */
   80.66 -  #define C2_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)
   80.67 -#else
   80.68 -  #define C2_DEVELOP_FLAG_MEMBER(type, name, value, doc)       FLAG_MEMBER(name),
   80.69 -  #define C2_PD_DEVELOP_FLAG_MEMBER(type, name, doc)           FLAG_MEMBER(name),
   80.70 -  #define C2_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)    FLAG_MEMBER(name),
   80.71 -#endif
   80.72 +#define C2_PRODUCT_FLAG_MEMBER(type, name, value, doc)           FLAG_MEMBER(name),
   80.73 +#define C2_PD_PRODUCT_FLAG_MEMBER(type, name, doc)               FLAG_MEMBER(name),
   80.74 +#define C2_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc)        FLAG_MEMBER(name),
   80.75 +#define C2_EXPERIMENTAL_FLAG_MEMBER(type, name, value, doc)      FLAG_MEMBER(name),
   80.76 +#define C2_DEVELOP_FLAG_MEMBER(type, name, value, doc)           FLAG_MEMBER(name),
   80.77 +#define C2_PD_DEVELOP_FLAG_MEMBER(type, name, doc)               FLAG_MEMBER(name),
   80.78 +#define C2_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)        FLAG_MEMBER(name),
   80.79  
   80.80  #define ARCH_PRODUCT_FLAG_MEMBER(type, name, value, doc)         FLAG_MEMBER(name),
   80.81  #define ARCH_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc)      FLAG_MEMBER(name),
   80.82  #define ARCH_EXPERIMENTAL_FLAG_MEMBER(type, name, value, doc)    FLAG_MEMBER(name),
   80.83 -#ifdef PRODUCT
   80.84 -  #define ARCH_DEVELOP_FLAG_MEMBER(type, name, value, doc)       /* flag is constant */
   80.85 -  #define ARCH_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)
   80.86 -#else
   80.87 -  #define ARCH_DEVELOP_FLAG_MEMBER(type, name, value, doc)       FLAG_MEMBER(name),
   80.88 -  #define ARCH_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)    FLAG_MEMBER(name),
   80.89 -#endif
   80.90 +#define ARCH_DEVELOP_FLAG_MEMBER(type, name, value, doc)         FLAG_MEMBER(name),
   80.91 +#define ARCH_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)      FLAG_MEMBER(name),
   80.92  
   80.93  typedef enum {
   80.94   RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, RUNTIME_PD_DEVELOP_FLAG_MEMBER, RUNTIME_PRODUCT_FLAG_MEMBER, RUNTIME_PD_PRODUCT_FLAG_MEMBER, RUNTIME_DIAGNOSTIC_FLAG_MEMBER, RUNTIME_EXPERIMENTAL_FLAG_MEMBER, RUNTIME_NOTPRODUCT_FLAG_MEMBER, RUNTIME_MANAGEABLE_FLAG_MEMBER, RUNTIME_PRODUCT_RW_FLAG_MEMBER, RUNTIME_LP64_PRODUCT_FLAG_MEMBER)
   80.95 @@ -114,64 +92,42 @@
   80.96  
   80.97  #define FLAG_MEMBER_WITH_TYPE(flag,type) Flag_##flag##_##type
   80.98  
   80.99 -#define RUNTIME_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)    FLAG_MEMBER_WITH_TYPE(name,type),
  80.100 -#define RUNTIME_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc)        FLAG_MEMBER_WITH_TYPE(name,type),
  80.101 -#define RUNTIME_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
  80.102 +#define RUNTIME_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)      FLAG_MEMBER_WITH_TYPE(name,type),
  80.103 +#define RUNTIME_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc)          FLAG_MEMBER_WITH_TYPE(name,type),
  80.104 +#define RUNTIME_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)   FLAG_MEMBER_WITH_TYPE(name,type),
  80.105  #define RUNTIME_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
  80.106 -#define RUNTIME_MANAGEABLE_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
  80.107 -#define RUNTIME_PRODUCT_RW_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
  80.108 -#ifdef PRODUCT
  80.109 -  #define RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)     /* flag is constant */
  80.110 -  #define RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc)         /* flag is constant */
  80.111 -  #define RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)
  80.112 +#define RUNTIME_MANAGEABLE_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)   FLAG_MEMBER_WITH_TYPE(name,type),
  80.113 +#define RUNTIME_PRODUCT_RW_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)   FLAG_MEMBER_WITH_TYPE(name,type),
  80.114 +#define RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)      FLAG_MEMBER_WITH_TYPE(name,type),
  80.115 +#define RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc)          FLAG_MEMBER_WITH_TYPE(name,type),
  80.116 +#define RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)   FLAG_MEMBER_WITH_TYPE(name,type),
  80.117 +
  80.118 +#define C1_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)           FLAG_MEMBER_WITH_TYPE(name,type),
  80.119 +#define C1_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc)               FLAG_MEMBER_WITH_TYPE(name,type),
  80.120 +#define C1_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)        FLAG_MEMBER_WITH_TYPE(name,type),
  80.121 +#define C1_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)           FLAG_MEMBER_WITH_TYPE(name,type),
  80.122 +#define C1_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc)               FLAG_MEMBER_WITH_TYPE(name,type),
  80.123 +#define C1_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)        FLAG_MEMBER_WITH_TYPE(name,type),
  80.124 +
  80.125 +#ifdef _LP64
  80.126 +#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
  80.127  #else
  80.128 -  #define RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)     FLAG_MEMBER_WITH_TYPE(name,type),
  80.129 -  #define RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc)         FLAG_MEMBER_WITH_TYPE(name,type),
  80.130 -  #define RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)  FLAG_MEMBER_WITH_TYPE(name,type),
  80.131 -#endif
  80.132 -
  80.133 -#define C1_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)         FLAG_MEMBER_WITH_TYPE(name,type),
  80.134 -#define C1_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc)             FLAG_MEMBER_WITH_TYPE(name,type),
  80.135 -#define C1_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)      FLAG_MEMBER_WITH_TYPE(name,type),
  80.136 -#ifdef PRODUCT
  80.137 -  #define C1_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)       /* flag is constant */
  80.138 -  #define C1_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc)           /* flag is constant */
  80.139 -  #define C1_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)
  80.140 -#else
  80.141 -  #define C1_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)       FLAG_MEMBER_WITH_TYPE(name,type),
  80.142 -  #define C1_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc)           FLAG_MEMBER_WITH_TYPE(name,type),
  80.143 -  #define C1_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)    FLAG_MEMBER_WITH_TYPE(name,type),
  80.144 -#endif
  80.145 -#ifdef _LP64
  80.146 -#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)    FLAG_MEMBER_WITH_TYPE(name,type),
  80.147 -#else
  80.148 -#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)    /* flag is constant */
  80.149 +#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) /* flag is constant */
  80.150  #endif // _LP64
  80.151  
  80.152 -#define C2_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)         FLAG_MEMBER_WITH_TYPE(name,type),
  80.153 -#define C2_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc)             FLAG_MEMBER_WITH_TYPE(name,type),
  80.154 -#define C2_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)      FLAG_MEMBER_WITH_TYPE(name,type),
  80.155 +#define C2_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)           FLAG_MEMBER_WITH_TYPE(name,type),
  80.156 +#define C2_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc)               FLAG_MEMBER_WITH_TYPE(name,type),
  80.157 +#define C2_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)        FLAG_MEMBER_WITH_TYPE(name,type),
  80.158  #define C2_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)      FLAG_MEMBER_WITH_TYPE(name,type),
  80.159 -#ifdef PRODUCT
  80.160 -  #define C2_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)       /* flag is constant */
  80.161 -  #define C2_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc)           /* flag is constant */
  80.162 -  #define C2_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)
  80.163 -#else
  80.164 -  #define C2_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)       FLAG_MEMBER_WITH_TYPE(name,type),
  80.165 -  #define C2_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc)           FLAG_MEMBER_WITH_TYPE(name,type),
  80.166 -  #define C2_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)    FLAG_MEMBER_WITH_TYPE(name,type),
  80.167 -#endif
  80.168 +#define C2_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)           FLAG_MEMBER_WITH_TYPE(name,type),
  80.169 +#define C2_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc)               FLAG_MEMBER_WITH_TYPE(name,type),
  80.170 +#define C2_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)        FLAG_MEMBER_WITH_TYPE(name,type),
  80.171  
  80.172  #define ARCH_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)         FLAG_MEMBER_WITH_TYPE(name,type),
  80.173  #define ARCH_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)      FLAG_MEMBER_WITH_TYPE(name,type),
  80.174 -#define ARCH_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)      FLAG_MEMBER_WITH_TYPE(name,type),
  80.175 -#ifdef PRODUCT
  80.176 -  #define ARCH_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)       /* flag is constant */
  80.177 -  #define ARCH_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)
  80.178 -#else
  80.179 -  #define ARCH_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)       FLAG_MEMBER_WITH_TYPE(name,type),
  80.180 -  #define ARCH_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)    FLAG_MEMBER_WITH_TYPE(name,type),
  80.181 -#endif
  80.182 +#define ARCH_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)    FLAG_MEMBER_WITH_TYPE(name,type),
  80.183 +#define ARCH_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)         FLAG_MEMBER_WITH_TYPE(name,type),
  80.184 +#define ARCH_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)      FLAG_MEMBER_WITH_TYPE(name,type),
  80.185  
  80.186  typedef enum {
  80.187   RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE,
  80.188 @@ -233,19 +189,19 @@
  80.189  
  80.190  #define FLAG_SET_DEFAULT(name, value) ((name) = (value))
  80.191  
  80.192 -#define FLAG_SET_CMDLINE(type, name, value) (CommandLineFlagsEx::type##AtPut(FLAG_MEMBER_WITH_TYPE(name,type), (type)(value), COMMAND_LINE))
  80.193 -#define FLAG_SET_ERGO(type, name, value)    (CommandLineFlagsEx::type##AtPut(FLAG_MEMBER_WITH_TYPE(name,type), (type)(value), ERGONOMIC))
  80.194 +#define FLAG_SET_CMDLINE(type, name, value) (CommandLineFlagsEx::type##AtPut(FLAG_MEMBER_WITH_TYPE(name,type), (type)(value), Flag::COMMAND_LINE))
  80.195 +#define FLAG_SET_ERGO(type, name, value)    (CommandLineFlagsEx::type##AtPut(FLAG_MEMBER_WITH_TYPE(name,type), (type)(value), Flag::ERGONOMIC))
  80.196  
  80.197  // Can't put the following in CommandLineFlags because
  80.198  // of a circular dependency on the enum definition.
  80.199  class CommandLineFlagsEx : CommandLineFlags {
  80.200   public:
  80.201 -  static void boolAtPut(CommandLineFlagWithType flag, bool value, FlagValueOrigin origin);
  80.202 -  static void intxAtPut(CommandLineFlagWithType flag, intx value, FlagValueOrigin origin);
  80.203 -  static void uintxAtPut(CommandLineFlagWithType flag, uintx value, FlagValueOrigin origin);
  80.204 -  static void uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, FlagValueOrigin origin);
  80.205 -  static void doubleAtPut(CommandLineFlagWithType flag, double value, FlagValueOrigin origin);
  80.206 -  static void ccstrAtPut(CommandLineFlagWithType flag, ccstr value, FlagValueOrigin origin);
  80.207 +  static void boolAtPut(CommandLineFlagWithType flag, bool value, Flag::Flags origin);
  80.208 +  static void intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin);
  80.209 +  static void uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin);
  80.210 +  static void uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin);
  80.211 +  static void doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin);
  80.212 +  static void ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin);
  80.213  
  80.214    static bool is_default(CommandLineFlag flag);
  80.215    static bool is_ergo(CommandLineFlag flag);
    81.1 --- a/src/share/vm/runtime/safepoint.cpp	Sat Oct 05 03:14:53 2013 +0200
    81.2 +++ b/src/share/vm/runtime/safepoint.cpp	Fri Oct 04 21:00:43 2013 -0700
    81.3 @@ -519,8 +519,8 @@
    81.4    }
    81.5  
    81.6    {
    81.7 -    TraceTime t4("sweeping nmethods", TraceSafepointCleanupTime);
    81.8 -    NMethodSweeper::scan_stacks();
    81.9 +    TraceTime t4("mark nmethods", TraceSafepointCleanupTime);
   81.10 +    NMethodSweeper::mark_active_nmethods();
   81.11    }
   81.12  
   81.13    if (SymbolTable::needs_rehashing()) {
    82.1 --- a/src/share/vm/runtime/sweeper.cpp	Sat Oct 05 03:14:53 2013 +0200
    82.2 +++ b/src/share/vm/runtime/sweeper.cpp	Fri Oct 04 21:00:43 2013 -0700
    82.3 @@ -127,64 +127,79 @@
    82.4  #define SWEEP(nm)
    82.5  #endif
    82.6  
    82.7 +nmethod*  NMethodSweeper::_current         = NULL; // Current nmethod
    82.8 +long      NMethodSweeper::_traversals      = 0;    // Nof. stack traversals performed
    82.9 +int       NMethodSweeper::_seen            = 0;    // Nof. nmethods we have currently processed in current pass of CodeCache
   82.10 +int       NMethodSweeper::_flushed_count   = 0;    // Nof. nmethods flushed in current sweep
   82.11 +int       NMethodSweeper::_zombified_count = 0;    // Nof. nmethods made zombie in current sweep
   82.12 +int       NMethodSweeper::_marked_count    = 0;    // Nof. nmethods marked for reclaim in current sweep
   82.13  
   82.14 -long      NMethodSweeper::_traversals = 0;   // No. of stack traversals performed
   82.15 -nmethod*  NMethodSweeper::_current = NULL;   // Current nmethod
   82.16 -int       NMethodSweeper::_seen = 0 ;        // No. of nmethods we have currently processed in current pass of CodeCache
   82.17 -int       NMethodSweeper::_flushed_count = 0;   // Nof. nmethods flushed in current sweep
   82.18 -int       NMethodSweeper::_zombified_count = 0; // Nof. nmethods made zombie in current sweep
   82.19 -int       NMethodSweeper::_marked_count = 0;    // Nof. nmethods marked for reclaim in current sweep
   82.20 -
   82.21 -volatile int NMethodSweeper::_invocations = 0;   // No. of invocations left until we are completed with this pass
   82.22 +volatile int NMethodSweeper::_invocations   = 0; // Nof. invocations left until we are completed with this pass
   82.23  volatile int NMethodSweeper::_sweep_started = 0; // Whether a sweep is in progress.
   82.24  
   82.25 -jint      NMethodSweeper::_locked_seen = 0;
   82.26 +jint      NMethodSweeper::_locked_seen               = 0;
   82.27  jint      NMethodSweeper::_not_entrant_seen_on_stack = 0;
   82.28 -bool      NMethodSweeper::_resweep = false;
   82.29 -jint      NMethodSweeper::_flush_token = 0;
   82.30 -jlong     NMethodSweeper::_last_full_flush_time = 0;
   82.31 -int       NMethodSweeper::_highest_marked = 0;
   82.32 -int       NMethodSweeper::_dead_compile_ids = 0;
   82.33 -long      NMethodSweeper::_last_flush_traversal_id = 0;
   82.34 +bool      NMethodSweeper::_request_mark_phase        = false;
   82.35  
   82.36 -int       NMethodSweeper::_number_of_flushes = 0; // Total of full traversals caused by full cache
   82.37  int       NMethodSweeper::_total_nof_methods_reclaimed = 0;
   82.38 -jlong     NMethodSweeper::_total_time_sweeping = 0;
   82.39 -jlong     NMethodSweeper::_total_time_this_sweep = 0;
   82.40 -jlong     NMethodSweeper::_peak_sweep_time = 0;
   82.41 -jlong     NMethodSweeper::_peak_sweep_fraction_time = 0;
   82.42 -jlong     NMethodSweeper::_total_disconnect_time = 0;
   82.43 -jlong     NMethodSweeper::_peak_disconnect_time = 0;
   82.44 +jlong     NMethodSweeper::_total_time_sweeping         = 0;
   82.45 +jlong     NMethodSweeper::_total_time_this_sweep       = 0;
   82.46 +jlong     NMethodSweeper::_peak_sweep_time             = 0;
   82.47 +jlong     NMethodSweeper::_peak_sweep_fraction_time    = 0;
   82.48 +int       NMethodSweeper::_hotness_counter_reset_val   = 0;
   82.49 +
   82.50  
   82.51  class MarkActivationClosure: public CodeBlobClosure {
   82.52  public:
   82.53    virtual void do_code_blob(CodeBlob* cb) {
   82.54 -    // If we see an activation belonging to a non_entrant nmethod, we mark it.
   82.55 -    if (cb->is_nmethod() && ((nmethod*)cb)->is_not_entrant()) {
   82.56 -      ((nmethod*)cb)->mark_as_seen_on_stack();
   82.57 +    if (cb->is_nmethod()) {
   82.58 +      nmethod* nm = (nmethod*)cb;
   82.59 +      nm->set_hotness_counter(NMethodSweeper::hotness_counter_reset_val());
   82.60 +      // If we see an activation belonging to a non_entrant nmethod, we mark it.
   82.61 +      if (nm->is_not_entrant()) {
   82.62 +        nm->mark_as_seen_on_stack();
   82.63 +      }
   82.64      }
   82.65    }
   82.66  };
   82.67  static MarkActivationClosure mark_activation_closure;
   82.68  
   82.69 +class SetHotnessClosure: public CodeBlobClosure {
   82.70 +public:
   82.71 +  virtual void do_code_blob(CodeBlob* cb) {
   82.72 +    if (cb->is_nmethod()) {
   82.73 +      nmethod* nm = (nmethod*)cb;
   82.74 +      nm->set_hotness_counter(NMethodSweeper::hotness_counter_reset_val());
   82.75 +    }
   82.76 +  }
   82.77 +};
   82.78 +static SetHotnessClosure set_hotness_closure;
   82.79 +
   82.80 +
   82.81 +int NMethodSweeper::hotness_counter_reset_val() {
   82.82 +  if (_hotness_counter_reset_val == 0) {
   82.83 +    _hotness_counter_reset_val = (ReservedCodeCacheSize < M) ? 1 : (ReservedCodeCacheSize / M) * 2;
   82.84 +  }
   82.85 +  return _hotness_counter_reset_val;
   82.86 +}
   82.87  bool NMethodSweeper::sweep_in_progress() {
   82.88    return (_current != NULL);
   82.89  }
   82.90  
   82.91 -void NMethodSweeper::scan_stacks() {
   82.92 +// Scans the stacks of all Java threads and marks activations of not-entrant methods.
   82.93 +// No need to synchronize access, since 'mark_active_nmethods' is always executed at a
   82.94 +// safepoint.
   82.95 +void NMethodSweeper::mark_active_nmethods() {
   82.96    assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint");
   82.97 -  if (!MethodFlushing) return;
   82.98 -
   82.99 -  // No need to synchronize access, since this is always executed at a
  82.100 -  // safepoint.
  82.101 -
  82.102 -  // Make sure CompiledIC_lock in unlocked, since we might update some
  82.103 -  // inline caches. If it is, we just bail-out and try later.
  82.104 -  if (CompiledIC_lock->is_locked() || Patching_lock->is_locked()) return;
  82.105 +  // If we do not want to reclaim not-entrant or zombie methods there is no need
  82.106 +  // to scan stacks
  82.107 +  if (!MethodFlushing) {
  82.108 +    return;
  82.109 +  }
  82.110  
  82.111    // Check for restart
  82.112    assert(CodeCache::find_blob_unsafe(_current) == _current, "Sweeper nmethod cached state invalid");
  82.113 -  if (!sweep_in_progress() && _resweep) {
  82.114 +  if (!sweep_in_progress() && need_marking_phase()) {
  82.115      _seen        = 0;
  82.116      _invocations = NmethodSweepFraction;
  82.117      _current     = CodeCache::first_nmethod();
  82.118 @@ -197,30 +212,22 @@
  82.119      Threads::nmethods_do(&mark_activation_closure);
  82.120  
  82.121      // reset the flags since we started a scan from the beginning.
  82.122 -    _resweep = false;
  82.123 +    reset_nmethod_marking();
  82.124      _locked_seen = 0;
  82.125      _not_entrant_seen_on_stack = 0;
  82.126 +  } else {
  82.127 +    // Only set hotness counter
  82.128 +    Threads::nmethods_do(&set_hotness_closure);
  82.129    }
  82.130  
  82.131 -  if (UseCodeCacheFlushing) {
  82.132 -    // only allow new flushes after the interval is complete.
  82.133 -    jlong now           = os::javaTimeMillis();
  82.134 -    jlong max_interval  = (jlong)MinCodeCacheFlushingInterval * (jlong)1000;
  82.135 -    jlong curr_interval = now - _last_full_flush_time;
  82.136 -    if (curr_interval > max_interval) {
  82.137 -      _flush_token = 0;
  82.138 -    }
  82.139 -
  82.140 -    if (!CodeCache::needs_flushing() && !CompileBroker::should_compile_new_jobs()) {
  82.141 -      CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation);
  82.142 -      log_sweep("restart_compiler");
  82.143 -    }
  82.144 -  }
  82.145 +  OrderAccess::storestore();
  82.146  }
  82.147  
  82.148  void NMethodSweeper::possibly_sweep() {
  82.149    assert(JavaThread::current()->thread_state() == _thread_in_vm, "must run in vm mode");
  82.150 -  if (!MethodFlushing || !sweep_in_progress()) return;
  82.151 +  if (!MethodFlushing || !sweep_in_progress()) {
  82.152 +    return;
  82.153 +  }
  82.154  
  82.155    if (_invocations > 0) {
  82.156      // Only one thread at a time will sweep
  82.157 @@ -258,8 +265,7 @@
  82.158    if (!CompileBroker::should_compile_new_jobs()) {
  82.159      // If we have turned off compilations we might as well do full sweeps
  82.160      // in order to reach the clean state faster. Otherwise the sleeping compiler
  82.161 -    // threads will slow down sweeping. After a few iterations the cache
  82.162 -    // will be clean and sweeping stops (_resweep will not be set)
  82.163 +    // threads will slow down sweeping.
  82.164      _invocations = 1;
  82.165    }
  82.166  
  82.167 @@ -271,9 +277,11 @@
  82.168    int todo = (CodeCache::nof_nmethods() - _seen) / _invocations;
  82.169    int swept_count = 0;
  82.170  
  82.171 +
  82.172    assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here");
  82.173    assert(!CodeCache_lock->owned_by_self(), "just checking");
  82.174  
  82.175 +  int freed_memory = 0;
  82.176    {
  82.177      MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
  82.178  
  82.179 @@ -299,7 +307,7 @@
  82.180        // Now ready to process nmethod and give up CodeCache_lock
  82.181        {
  82.182          MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
  82.183 -        process_nmethod(_current);
  82.184 +        freed_memory += process_nmethod(_current);
  82.185        }
  82.186        _seen++;
  82.187        _current = next;
  82.188 @@ -308,11 +316,11 @@
  82.189  
  82.190    assert(_invocations > 1 || _current == NULL, "must have scanned the whole cache");
  82.191  
  82.192 -  if (!sweep_in_progress() && !_resweep && (_locked_seen || _not_entrant_seen_on_stack)) {
  82.193 +  if (!sweep_in_progress() && !need_marking_phase() && (_locked_seen || _not_entrant_seen_on_stack)) {
  82.194      // we've completed a scan without making progress but there were
  82.195      // nmethods we were unable to process either because they were
  82.196 -    // locked or were still on stack.  We don't have to aggresively
  82.197 -    // clean them up so just stop scanning.  We could scan once more
  82.198 +    // locked or were still on stack. We don't have to aggressively
  82.199 +    // clean them up so just stop scanning. We could scan once more
  82.200      // but that complicates the control logic and it's unlikely to
  82.201      // matter much.
  82.202      if (PrintMethodFlushing) {
  82.203 @@ -351,9 +359,16 @@
  82.204      log_sweep("finished");
  82.205    }
  82.206  
  82.207 -  // Sweeper is the only case where memory is released,
  82.208 -  // check here if it is time to restart the compiler.
  82.209 -  if (UseCodeCacheFlushing && !CompileBroker::should_compile_new_jobs() && !CodeCache::needs_flushing()) {
  82.210 +  // Sweeper is the only case where memory is released, check here if it
  82.211 +  // is time to restart the compiler. Only checking if there is a certain
  82.212 +  // amount of free memory in the code cache might lead to re-enabling
  82.213 +  // compilation although no memory has been released. For example, there are
  82.214 +  // cases when compilation was disabled although there is 4MB (or more) free
  82.215 +  // memory in the code cache. The reason is code cache fragmentation. Therefore,
  82.216 +  // it only makes sense to re-enable compilation if we have actually freed memory.
  82.217 +  // Note that typically several kB are released for sweeping 16MB of the code
  82.218 +  // cache. As a result, 'freed_memory' > 0 to restart the compiler.
  82.219 +  if (UseCodeCacheFlushing && (!CompileBroker::should_compile_new_jobs() && (freed_memory > 0))) {
  82.220      CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation);
  82.221      log_sweep("restart_compiler");
  82.222    }
  82.223 @@ -367,8 +382,8 @@
  82.224      _thread = CompilerThread::current();
  82.225      if (!nm->is_zombie() && !nm->is_unloaded()) {
  82.226        // Only expose live nmethods for scanning
  82.227 -    _thread->set_scanned_nmethod(nm);
  82.228 -  }
  82.229 +      _thread->set_scanned_nmethod(nm);
  82.230 +    }
  82.231    }
  82.232    ~NMethodMarker() {
  82.233      _thread->set_scanned_nmethod(NULL);
  82.234 @@ -392,20 +407,20 @@
  82.235    nm->flush();
  82.236  }
  82.237  
  82.238 -void NMethodSweeper::process_nmethod(nmethod *nm) {
  82.239 +int NMethodSweeper::process_nmethod(nmethod *nm) {
  82.240    assert(!CodeCache_lock->owned_by_self(), "just checking");
  82.241  
  82.242 +  int freed_memory = 0;
  82.243    // Make sure this nmethod doesn't get unloaded during the scan,
  82.244 -  // since the locks acquired below might safepoint.
  82.245 +  // since safepoints may happen during acquired below locks.
  82.246    NMethodMarker nmm(nm);
  82.247 -
  82.248    SWEEP(nm);
  82.249  
  82.250    // Skip methods that are currently referenced by the VM
  82.251    if (nm->is_locked_by_vm()) {
  82.252      // But still remember to clean-up inline caches for alive nmethods
  82.253      if (nm->is_alive()) {
  82.254 -      // Clean-up all inline caches that points to zombie/non-reentrant methods
  82.255 +      // Clean inline caches that point to zombie/non-entrant methods
  82.256        MutexLocker cl(CompiledIC_lock);
  82.257        nm->cleanup_inline_caches();
  82.258        SWEEP(nm);
  82.259 @@ -413,18 +428,19 @@
  82.260        _locked_seen++;
  82.261        SWEEP(nm);
  82.262      }
  82.263 -    return;
  82.264 +    return freed_memory;
  82.265    }
  82.266  
  82.267    if (nm->is_zombie()) {
  82.268 -    // If it is first time, we see nmethod then we mark it. Otherwise,
  82.269 -    // we reclame it. When we have seen a zombie method twice, we know that
  82.270 +    // If it is the first time we see nmethod then we mark it. Otherwise,
  82.271 +    // we reclaim it. When we have seen a zombie method twice, we know that
  82.272      // there are no inline caches that refer to it.
  82.273      if (nm->is_marked_for_reclamation()) {
  82.274        assert(!nm->is_locked_by_vm(), "must not flush locked nmethods");
  82.275        if (PrintMethodFlushing && Verbose) {
  82.276          tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm);
  82.277        }
  82.278 +      freed_memory = nm->total_size();
  82.279        release_nmethod(nm);
  82.280        _flushed_count++;
  82.281      } else {
  82.282 @@ -432,19 +448,19 @@
  82.283          tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), nm);
  82.284        }
  82.285        nm->mark_for_reclamation();
  82.286 -      _resweep = true;
  82.287 +      request_nmethod_marking();
  82.288        _marked_count++;
  82.289        SWEEP(nm);
  82.290      }
  82.291    } else if (nm->is_not_entrant()) {
  82.292 -    // If there is no current activations of this method on the
  82.293 +    // If there are no current activations of this method on the
  82.294      // stack we can safely convert it to a zombie method
  82.295      if (nm->can_not_entrant_be_converted()) {
  82.296        if (PrintMethodFlushing && Verbose) {
  82.297          tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (not entrant) being made zombie", nm->compile_id(), nm);
  82.298        }
  82.299        nm->make_zombie();
  82.300 -      _resweep = true;
  82.301 +      request_nmethod_marking();
  82.302        _zombified_count++;
  82.303        SWEEP(nm);
  82.304      } else {
  82.305 @@ -459,159 +475,57 @@
  82.306      }
  82.307    } else if (nm->is_unloaded()) {
  82.308      // Unloaded code, just make it a zombie
  82.309 -    if (PrintMethodFlushing && Verbose)
  82.310 +    if (PrintMethodFlushing && Verbose) {
  82.311        tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), nm);
  82.312 -
  82.313 +    }
  82.314      if (nm->is_osr_method()) {
  82.315        SWEEP(nm);
  82.316        // No inline caches will ever point to osr methods, so we can just remove it
  82.317 +      freed_memory = nm->total_size();
  82.318        release_nmethod(nm);
  82.319        _flushed_count++;
  82.320      } else {
  82.321        nm->make_zombie();
  82.322 -      _resweep = true;
  82.323 +      request_nmethod_marking();
  82.324        _zombified_count++;
  82.325        SWEEP(nm);
  82.326      }
  82.327    } else {
  82.328 -    assert(nm->is_alive(), "should be alive");
  82.329 -
  82.330      if (UseCodeCacheFlushing) {
  82.331 -      if (nm->is_speculatively_disconnected() && !nm->is_locked_by_vm() && !nm->is_osr_method() &&
  82.332 -          (_traversals > _last_flush_traversal_id + 2) && (nm->compile_id() < _highest_marked)) {
  82.333 -        // This method has not been called since the forced cleanup happened
  82.334 -        nm->make_not_entrant();
  82.335 +      if (!nm->is_locked_by_vm() && !nm->is_osr_method() && !nm->is_native_method()) {
  82.336 +        // Do not make native methods and OSR-methods not-entrant
  82.337 +        nm->dec_hotness_counter();
  82.338 +        // Get the initial value of the hotness counter. This value depends on the
  82.339 +        // ReservedCodeCacheSize
  82.340 +        int reset_val = hotness_counter_reset_val();
  82.341 +        int time_since_reset = reset_val - nm->hotness_counter();
  82.342 +        double threshold = -reset_val + (CodeCache::reverse_free_ratio() * NmethodSweepActivity);
  82.343 +        // The less free space in the code cache we have - the bigger reverse_free_ratio() is.
  82.344 +        // I.e., 'threshold' increases with lower available space in the code cache and a higher
  82.345 +        // NmethodSweepActivity. If the current hotness counter - which decreases from its initial
  82.346 +        // value until it is reset by stack walking - is smaller than the computed threshold, the
  82.347 +        // corresponding nmethod is considered for removal.
  82.348 +        if ((NmethodSweepActivity > 0) && (nm->hotness_counter() < threshold) && (time_since_reset > 10)) {
  82.349 +          // A method is marked as not-entrant if the method is
  82.350 +          // 1) 'old enough': nm->hotness_counter() < threshold
  82.351 +          // 2) The method was in_use for a minimum amount of time: (time_since_reset > 10)
  82.352 +          //    The second condition is necessary if we are dealing with very small code cache
  82.353 +          //    sizes (e.g., <10m) and the code cache size is too small to hold all hot methods.
  82.354 +          //    The second condition ensures that methods are not immediately made not-entrant
  82.355 +          //    after compilation.
  82.356 +          nm->make_not_entrant();
  82.357 +          request_nmethod_marking();
  82.358 +        }
  82.359        }
  82.360      }
  82.361 -
  82.362 -    // Clean-up all inline caches that points to zombie/non-reentrant methods
  82.363 +    // Clean-up all inline caches that point to zombie/non-reentrant methods
  82.364      MutexLocker cl(CompiledIC_lock);
  82.365      nm->cleanup_inline_caches();
  82.366      SWEEP(nm);
  82.367    }
  82.368 +  return freed_memory;
  82.369  }
  82.370  
  82.371 -// Code cache unloading: when compilers notice the code cache is getting full,
  82.372 -// they will call a vm op that comes here. This code attempts to speculatively
  82.373 -// unload the oldest half of the nmethods (based on the compile job id) by
  82.374 -// saving the old code in a list in the CodeCache. Then
  82.375 -// execution resumes. If a method so marked is not called by the second sweeper
  82.376 -// stack traversal after the current one, the nmethod will be marked non-entrant and
  82.377 -// got rid of by normal sweeping. If the method is called, the Method*'s
  82.378 -// _code field is restored and the Method*/nmethod
  82.379 -// go back to their normal state.
  82.380 -void NMethodSweeper::handle_full_code_cache(bool is_full) {
  82.381 -
  82.382 -  if (is_full) {
  82.383 -    // Since code cache is full, immediately stop new compiles
  82.384 -    if (CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation)) {
  82.385 -      log_sweep("disable_compiler");
  82.386 -    }
  82.387 -  }
  82.388 -
  82.389 -  // Make sure only one thread can flush
  82.390 -  // The token is reset after CodeCacheMinimumFlushInterval in scan stacks,
  82.391 -  // no need to check the timeout here.
  82.392 -  jint old = Atomic::cmpxchg( 1, &_flush_token, 0 );
  82.393 -  if (old != 0) {
  82.394 -    return;
  82.395 -  }
  82.396 -
  82.397 -  VM_HandleFullCodeCache op(is_full);
  82.398 -  VMThread::execute(&op);
  82.399 -
  82.400 -  // resweep again as soon as possible
  82.401 -  _resweep = true;
  82.402 -}
  82.403 -
  82.404 -void NMethodSweeper::speculative_disconnect_nmethods(bool is_full) {
  82.405 -  // If there was a race in detecting full code cache, only run
  82.406 -  // one vm op for it or keep the compiler shut off
  82.407 -
  82.408 -  jlong disconnect_start_counter = os::elapsed_counter();
  82.409 -
  82.410 -  // Traverse the code cache trying to dump the oldest nmethods
  82.411 -  int curr_max_comp_id = CompileBroker::get_compilation_id();
  82.412 -  int flush_target = ((curr_max_comp_id - _dead_compile_ids) / CodeCacheFlushingFraction) + _dead_compile_ids;
  82.413 -
  82.414 -  log_sweep("start_cleaning");
  82.415 -
  82.416 -  nmethod* nm = CodeCache::alive_nmethod(CodeCache::first());
  82.417 -  jint disconnected = 0;
  82.418 -  jint made_not_entrant  = 0;
  82.419 -  jint nmethod_count = 0;
  82.420 -
  82.421 -  while ((nm != NULL)){
  82.422 -    int curr_comp_id = nm->compile_id();
  82.423 -
  82.424 -    // OSR methods cannot be flushed like this. Also, don't flush native methods
  82.425 -    // since they are part of the JDK in most cases
  82.426 -    if (!nm->is_osr_method() && !nm->is_locked_by_vm() && !nm->is_native_method()) {
  82.427 -
  82.428 -      // only count methods that can be speculatively disconnected
  82.429 -      nmethod_count++;
  82.430 -
  82.431 -      if (nm->is_in_use() && (curr_comp_id < flush_target)) {
  82.432 -        if ((nm->method()->code() == nm)) {
  82.433 -          // This method has not been previously considered for
  82.434 -          // unloading or it was restored already
  82.435 -          CodeCache::speculatively_disconnect(nm);
  82.436 -          disconnected++;
  82.437 -        } else if (nm->is_speculatively_disconnected()) {
  82.438 -          // This method was previously considered for preemptive unloading and was not called since then
  82.439 -          CompilationPolicy::policy()->delay_compilation(nm->method());
  82.440 -          nm->make_not_entrant();
  82.441 -          made_not_entrant++;
  82.442 -        }
  82.443 -
  82.444 -        if (curr_comp_id > _highest_marked) {
  82.445 -          _highest_marked = curr_comp_id;
  82.446 -        }
  82.447 -      }
  82.448 -    }
  82.449 -    nm = CodeCache::alive_nmethod(CodeCache::next(nm));
  82.450 -  }
  82.451 -
  82.452 -  // remember how many compile_ids wheren't seen last flush.
  82.453 -  _dead_compile_ids = curr_max_comp_id - nmethod_count;
  82.454 -
  82.455 -  log_sweep("stop_cleaning",
  82.456 -                       "disconnected='" UINT32_FORMAT "' made_not_entrant='" UINT32_FORMAT "'",
  82.457 -                       disconnected, made_not_entrant);
  82.458 -
  82.459 -  // Shut off compiler. Sweeper will start over with a new stack scan and
  82.460 -  // traversal cycle and turn it back on if it clears enough space.
  82.461 -  if (is_full) {
  82.462 -    _last_full_flush_time = os::javaTimeMillis();
  82.463 -  }
  82.464 -
  82.465 -  jlong disconnect_end_counter = os::elapsed_counter();
  82.466 -  jlong disconnect_time = disconnect_end_counter - disconnect_start_counter;
  82.467 -  _total_disconnect_time += disconnect_time;
  82.468 -  _peak_disconnect_time = MAX2(disconnect_time, _peak_disconnect_time);
  82.469 -
  82.470 -  EventCleanCodeCache event(UNTIMED);
  82.471 -  if (event.should_commit()) {
  82.472 -    event.set_starttime(disconnect_start_counter);
  82.473 -    event.set_endtime(disconnect_end_counter);
  82.474 -    event.set_disconnectedCount(disconnected);
  82.475 -    event.set_madeNonEntrantCount(made_not_entrant);
  82.476 -    event.commit();
  82.477 -  }
  82.478 -  _number_of_flushes++;
  82.479 -
  82.480 -  // After two more traversals the sweeper will get rid of unrestored nmethods
  82.481 -  _last_flush_traversal_id = _traversals;
  82.482 -  _resweep = true;
  82.483 -#ifdef ASSERT
  82.484 -
  82.485 -  if(PrintMethodFlushing && Verbose) {
  82.486 -    tty->print_cr("### sweeper: unload time: " INT64_FORMAT, (jlong)disconnect_time);
  82.487 -  }
  82.488 -#endif
  82.489 -}
  82.490 -
  82.491 -
  82.492  // Print out some state information about the current sweep and the
  82.493  // state of the code cache if it's requested.
  82.494  void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) {
    83.1 --- a/src/share/vm/runtime/sweeper.hpp	Sat Oct 05 03:14:53 2013 +0200
    83.2 +++ b/src/share/vm/runtime/sweeper.hpp	Fri Oct 04 21:00:43 2013 -0700
    83.3 @@ -27,8 +27,30 @@
    83.4  
    83.5  // An NmethodSweeper is an incremental cleaner for:
    83.6  //    - cleanup inline caches
    83.7 -//    - reclamation of unreferences zombie nmethods
    83.8 -//
    83.9 +//    - reclamation of nmethods
   83.10 +// Removing nmethods from the code cache includes two operations
   83.11 +//  1) mark active nmethods
   83.12 +//     Is done in 'mark_active_nmethods()'. This function is called at a
   83.13 +//     safepoint and marks all nmethods that are active on a thread's stack.
   83.14 +//  2) sweep nmethods
   83.15 +//     Is done in sweep_code_cache(). This function is the only place in the
   83.16 +//     sweeper where memory is reclaimed. Note that sweep_code_cache() is not
   83.17 +//     called at a safepoint. However, sweep_code_cache() stops executing if
   83.18 +//     another thread requests a safepoint. Consequently, 'mark_active_nmethods()'
   83.19 +//     and sweep_code_cache() cannot execute at the same time.
   83.20 +//     To reclaim memory, nmethods are first marked as 'not-entrant'. Methods can
   83.21 +//     be made not-entrant by (i) the sweeper, (ii) deoptimization, (iii) dependency
   83.22 +//     invalidation, and (iv) being replaced be a different method version (tiered
   83.23 +//     compilation). Not-entrant nmethod cannot be called by Java threads, but they
   83.24 +//     can still be active on the stack. To ensure that active nmethod are not reclaimed,
   83.25 +//     we have to wait until the next marking phase has completed. If a not-entrant
   83.26 +//     nmethod was NOT marked as active, it can be converted to 'zombie' state. To safely
   83.27 +//     remove the nmethod, all inline caches (IC) that point to the the nmethod must be
   83.28 +//     cleared. After that, the nmethod can be evicted from the code cache. Each nmethod's
   83.29 +//     state change happens during separate sweeps. It may take at least 3 sweeps before an
   83.30 +//     nmethod's space is freed. Sweeping is currently done by compiler threads between
   83.31 +//     compilations or at least each 5 sec (NmethodSweepCheckInterval) when the code cache
   83.32 +//     is full.
   83.33  
   83.34  class NMethodSweeper : public AllStatic {
   83.35    static long      _traversals;      // Stack scan count, also sweep ID.
   83.36 @@ -41,46 +63,38 @@
   83.37    static volatile int  _invocations;   // No. of invocations left until we are completed with this pass
   83.38    static volatile int  _sweep_started; // Flag to control conc sweeper
   83.39  
   83.40 -  //The following are reset in scan_stacks and synchronized by the safepoint
   83.41 -  static bool      _resweep;           // Indicates that a change has happend and we want another sweep,
   83.42 -                                       // always checked and reset at a safepoint so memory will be in sync.
   83.43 -  static int       _locked_seen;       // Number of locked nmethods encountered during the scan
   83.44 +  //The following are reset in mark_active_nmethods and synchronized by the safepoint
   83.45 +  static bool      _request_mark_phase;        // Indicates that a change has happend and we need another mark pahse,
   83.46 +                                               // always checked and reset at a safepoint so memory will be in sync.
   83.47 +  static int       _locked_seen;               // Number of locked nmethods encountered during the scan
   83.48    static int       _not_entrant_seen_on_stack; // Number of not entrant nmethod were are still on stack
   83.49 -  static jint      _flush_token;       // token that guards method flushing, making sure it is executed only once.
   83.50 -
   83.51 -  // These are set during a flush, a VM-operation
   83.52 -  static long      _last_flush_traversal_id; // trav number at last flush unloading
   83.53 -  static jlong     _last_full_flush_time;    // timestamp of last emergency unloading
   83.54 -
   83.55 -  // These are synchronized by the _sweep_started token
   83.56 -  static int       _highest_marked;   // highest compile id dumped at last emergency unloading
   83.57 -  static int       _dead_compile_ids; // number of compile ids that where not in the cache last flush
   83.58  
   83.59    // Stat counters
   83.60 -  static int       _number_of_flushes;            // Total of full traversals caused by full cache
   83.61    static int       _total_nof_methods_reclaimed;  // Accumulated nof methods flushed
   83.62    static jlong     _total_time_sweeping;          // Accumulated time sweeping
   83.63    static jlong     _total_time_this_sweep;        // Total time this sweep
   83.64    static jlong     _peak_sweep_time;              // Peak time for a full sweep
   83.65    static jlong     _peak_sweep_fraction_time;     // Peak time sweeping one fraction
   83.66 -  static jlong     _total_disconnect_time;        // Total time cleaning code mem
   83.67 -  static jlong     _peak_disconnect_time;         // Peak time cleaning code mem
   83.68  
   83.69 -  static void process_nmethod(nmethod *nm);
   83.70 +  static int  process_nmethod(nmethod *nm);
   83.71    static void release_nmethod(nmethod* nm);
   83.72  
   83.73 -  static void log_sweep(const char* msg, const char* format = NULL, ...);
   83.74    static bool sweep_in_progress();
   83.75 +  static void sweep_code_cache();
   83.76 +  static void request_nmethod_marking() { _request_mark_phase = true; }
   83.77 +  static void reset_nmethod_marking()   { _request_mark_phase = false; }
   83.78 +  static bool need_marking_phase()      { return _request_mark_phase; }
   83.79 +
   83.80 +  static int _hotness_counter_reset_val;
   83.81  
   83.82   public:
   83.83    static long traversal_count()              { return _traversals; }
   83.84 -  static int  number_of_flushes()            { return _number_of_flushes; }
   83.85    static int  total_nof_methods_reclaimed()  { return _total_nof_methods_reclaimed; }
   83.86    static jlong total_time_sweeping()         { return _total_time_sweeping; }
   83.87    static jlong peak_sweep_time()             { return _peak_sweep_time; }
   83.88    static jlong peak_sweep_fraction_time()    { return _peak_sweep_fraction_time; }
   83.89 -  static jlong total_disconnect_time()       { return _total_disconnect_time; }
   83.90 -  static jlong peak_disconnect_time()        { return _peak_disconnect_time; }
   83.91 +  static void log_sweep(const char* msg, const char* format = NULL, ...);
   83.92 +
   83.93  
   83.94  #ifdef ASSERT
   83.95    static bool is_sweeping(nmethod* which) { return _current == which; }
   83.96 @@ -90,19 +104,18 @@
   83.97    static void report_events();
   83.98  #endif
   83.99  
  83.100 -  static void scan_stacks();      // Invoked at the end of each safepoint
  83.101 -  static void sweep_code_cache(); // Concurrent part of sweep job
  83.102 -  static void possibly_sweep();   // Compiler threads call this to sweep
  83.103 +  static void mark_active_nmethods();      // Invoked at the end of each safepoint
  83.104 +  static void possibly_sweep();            // Compiler threads call this to sweep
  83.105  
  83.106 -  static void notify(nmethod* nm) {
  83.107 +  static int sort_nmethods_by_hotness(nmethod** nm1, nmethod** nm2);
  83.108 +  static int hotness_counter_reset_val();
  83.109 +
  83.110 +  static void notify() {
  83.111      // Request a new sweep of the code cache from the beginning. No
  83.112      // need to synchronize the setting of this flag since it only
  83.113      // changes to false at safepoint so we can never overwrite it with false.
  83.114 -     _resweep = true;
  83.115 +     request_nmethod_marking();
  83.116    }
  83.117 -
  83.118 -  static void handle_full_code_cache(bool is_full); // Called by compilers who fail to allocate
  83.119 -  static void speculative_disconnect_nmethods(bool was_full);   // Called by vm op to deal with alloc failure
  83.120  };
  83.121  
  83.122  #endif // SHARE_VM_RUNTIME_SWEEPER_HPP
    84.1 --- a/src/share/vm/runtime/vmStructs.cpp	Sat Oct 05 03:14:53 2013 +0200
    84.2 +++ b/src/share/vm/runtime/vmStructs.cpp	Fri Oct 04 21:00:43 2013 -0700
    84.3 @@ -176,6 +176,7 @@
    84.4  #include "opto/loopnode.hpp"
    84.5  #include "opto/machnode.hpp"
    84.6  #include "opto/matcher.hpp"
    84.7 +#include "opto/mathexactnode.hpp"
    84.8  #include "opto/mulnode.hpp"
    84.9  #include "opto/phaseX.hpp"
   84.10  #include "opto/parse.hpp"
   84.11 @@ -841,7 +842,7 @@
   84.12    nonstatic_field(nmethod,             _osr_link,                                     nmethod*)                              \
   84.13    nonstatic_field(nmethod,             _scavenge_root_link,                           nmethod*)                              \
   84.14    nonstatic_field(nmethod,             _scavenge_root_state,                          jbyte)                                 \
   84.15 -  nonstatic_field(nmethod,             _state,                                        unsigned char)                         \
   84.16 +  nonstatic_field(nmethod,             _state,                                        volatile unsigned char)                \
   84.17    nonstatic_field(nmethod,             _exception_offset,                             int)                                   \
   84.18    nonstatic_field(nmethod,             _deoptimize_offset,                            int)                                   \
   84.19    nonstatic_field(nmethod,             _deoptimize_mh_offset,                         int)                                   \
   84.20 @@ -1185,11 +1186,10 @@
   84.21    /* -XX flags         */                                                                                                            \
   84.22    /*********************/                                                                                                            \
   84.23                                                                                                                                       \
   84.24 -  nonstatic_field(Flag,                        type,                                          const char*)                           \
   84.25 -  nonstatic_field(Flag,                        name,                                          const char*)                           \
   84.26 -  unchecked_nonstatic_field(Flag,              addr,                                          sizeof(void*)) /* NOTE: no type */     \
   84.27 -  nonstatic_field(Flag,                        kind,                                          const char*)                           \
   84.28 -  nonstatic_field(Flag,                        origin,                                        FlagValueOrigin)                       \
   84.29 +  nonstatic_field(Flag,                        _type,                                         const char*)                           \
   84.30 +  nonstatic_field(Flag,                        _name,                                         const char*)                           \
   84.31 +  unchecked_nonstatic_field(Flag,              _addr,                                         sizeof(void*)) /* NOTE: no type */     \
   84.32 +  nonstatic_field(Flag,                        _flags,                                        Flag::Flags)                           \
   84.33    static_field(Flag,                           flags,                                         Flag*)                                 \
   84.34    static_field(Flag,                           numFlags,                                      size_t)                                \
   84.35                                                                                                                                       \
   84.36 @@ -1360,6 +1360,7 @@
   84.37    declare_integer_type(long)                                              \
   84.38    declare_integer_type(char)                                              \
   84.39    declare_unsigned_integer_type(unsigned char)                            \
   84.40 +  declare_unsigned_integer_type(volatile unsigned char)                   \
   84.41    declare_unsigned_integer_type(u_char)                                   \
   84.42    declare_unsigned_integer_type(unsigned int)                             \
   84.43    declare_unsigned_integer_type(uint)                                     \
   84.44 @@ -1382,6 +1383,7 @@
   84.45    declare_toplevel_type(char**)                                           \
   84.46    declare_toplevel_type(u_char*)                                          \
   84.47    declare_toplevel_type(unsigned char*)                                   \
   84.48 +  declare_toplevel_type(volatile unsigned char*)                          \
   84.49                                                                            \
   84.50    /*******************************************************************/   \
   84.51    /* Types which it will be handy to have available over in the SA   */   \
   84.52 @@ -1928,6 +1930,9 @@
   84.53    declare_c2_type(CmpF3Node, CmpFNode)                                    \
   84.54    declare_c2_type(CmpDNode, CmpNode)                                      \
   84.55    declare_c2_type(CmpD3Node, CmpDNode)                                    \
   84.56 +  declare_c2_type(MathExactNode, MultiNode)                               \
   84.57 +  declare_c2_type(AddExactINode, MathExactNode)                           \
   84.58 +  declare_c2_type(FlagsProjNode, ProjNode)                                \
   84.59    declare_c2_type(BoolNode, Node)                                         \
   84.60    declare_c2_type(AbsNode, Node)                                          \
   84.61    declare_c2_type(AbsINode, AbsNode)                                      \
   84.62 @@ -2074,7 +2079,7 @@
   84.63     declare_integer_type(JavaThreadState)                                  \
   84.64     declare_integer_type(Location::Type)                                   \
   84.65     declare_integer_type(Location::Where)                                  \
   84.66 -   declare_integer_type(FlagValueOrigin)                                  \
   84.67 +   declare_integer_type(Flag::Flags)                                      \
   84.68     COMPILER2_PRESENT(declare_integer_type(OptoReg::Name))                 \
   84.69                                                                            \
   84.70     declare_toplevel_type(CHeapObj<mtInternal>)                            \
   84.71 @@ -2082,7 +2087,7 @@
   84.72              declare_type(Array<u1>, MetaspaceObj)                         \
   84.73              declare_type(Array<u2>, MetaspaceObj)                         \
   84.74              declare_type(Array<Klass*>, MetaspaceObj)                     \
   84.75 -            declare_type(Array<Method*>, MetaspaceObj)             \
   84.76 +            declare_type(Array<Method*>, MetaspaceObj)                    \
   84.77                                                                            \
   84.78     declare_integer_type(AccessFlags)  /* FIXME: wrong type (not integer) */\
   84.79    declare_toplevel_type(address)      /* FIXME: should this be an integer type? */\
    85.1 --- a/src/share/vm/runtime/vm_operations.cpp	Sat Oct 05 03:14:53 2013 +0200
    85.2 +++ b/src/share/vm/runtime/vm_operations.cpp	Fri Oct 04 21:00:43 2013 -0700
    85.3 @@ -173,10 +173,6 @@
    85.4    SymbolTable::unlink();
    85.5  }
    85.6  
    85.7 -void VM_HandleFullCodeCache::doit() {
    85.8 -  NMethodSweeper::speculative_disconnect_nmethods(_is_full);
    85.9 -}
   85.10 -
   85.11  void VM_Verify::doit() {
   85.12    Universe::heap()->prepare_for_verify();
   85.13    Universe::verify(_silent);
    86.1 --- a/src/share/vm/runtime/vm_operations.hpp	Sat Oct 05 03:14:53 2013 +0200
    86.2 +++ b/src/share/vm/runtime/vm_operations.hpp	Fri Oct 04 21:00:43 2013 -0700
    86.3 @@ -51,7 +51,6 @@
    86.4    template(DeoptimizeAll)                         \
    86.5    template(ZombieAll)                             \
    86.6    template(UnlinkSymbols)                         \
    86.7 -  template(HandleFullCodeCache)                   \
    86.8    template(Verify)                                \
    86.9    template(PrintJNI)                              \
   86.10    template(HeapDumper)                            \
   86.11 @@ -261,16 +260,6 @@
   86.12    bool allow_nested_vm_operations() const        { return true;  }
   86.13  };
   86.14  
   86.15 -class VM_HandleFullCodeCache: public VM_Operation {
   86.16 - private:
   86.17 -  bool  _is_full;
   86.18 - public:
   86.19 -  VM_HandleFullCodeCache(bool is_full)           { _is_full = is_full; }
   86.20 -  VMOp_Type type() const                         { return VMOp_HandleFullCodeCache; }
   86.21 -  void doit();
   86.22 -  bool allow_nested_vm_operations() const        { return true; }
   86.23 -};
   86.24 -
   86.25  #ifndef PRODUCT
   86.26  class VM_DeoptimizeAll: public VM_Operation {
   86.27   private:
    87.1 --- a/src/share/vm/services/attachListener.cpp	Sat Oct 05 03:14:53 2013 +0200
    87.2 +++ b/src/share/vm/services/attachListener.cpp	Fri Oct 04 21:00:43 2013 -0700
    87.3 @@ -245,7 +245,7 @@
    87.4      }
    87.5      value = (tmp != 0);
    87.6    }
    87.7 -  bool res = CommandLineFlags::boolAtPut((char*)name, &value, ATTACH_ON_DEMAND);
    87.8 +  bool res = CommandLineFlags::boolAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND);
    87.9    if (! res) {
   87.10      out->print_cr("setting flag %s failed", name);
   87.11    }
   87.12 @@ -263,7 +263,7 @@
   87.13        return JNI_ERR;
   87.14      }
   87.15    }
   87.16 -  bool res = CommandLineFlags::intxAtPut((char*)name, &value, ATTACH_ON_DEMAND);
   87.17 +  bool res = CommandLineFlags::intxAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND);
   87.18    if (! res) {
   87.19      out->print_cr("setting flag %s failed", name);
   87.20    }
   87.21 @@ -282,7 +282,7 @@
   87.22        return JNI_ERR;
   87.23      }
   87.24    }
   87.25 -  bool res = CommandLineFlags::uintxAtPut((char*)name, &value, ATTACH_ON_DEMAND);
   87.26 +  bool res = CommandLineFlags::uintxAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND);
   87.27    if (! res) {
   87.28      out->print_cr("setting flag %s failed", name);
   87.29    }
   87.30 @@ -301,7 +301,7 @@
   87.31        return JNI_ERR;
   87.32      }
   87.33    }
   87.34 -  bool res = CommandLineFlags::uint64_tAtPut((char*)name, &value, ATTACH_ON_DEMAND);
   87.35 +  bool res = CommandLineFlags::uint64_tAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND);
   87.36    if (! res) {
   87.37      out->print_cr("setting flag %s failed", name);
   87.38    }
   87.39 @@ -316,7 +316,7 @@
   87.40      out->print_cr("flag value must be a string");
   87.41      return JNI_ERR;
   87.42    }
   87.43 -  bool res = CommandLineFlags::ccstrAtPut((char*)name, &value, ATTACH_ON_DEMAND);
   87.44 +  bool res = CommandLineFlags::ccstrAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND);
   87.45    if (res) {
   87.46      FREE_C_HEAP_ARRAY(char, value, mtInternal);
   87.47    } else {
    88.1 --- a/src/share/vm/services/classLoadingService.cpp	Sat Oct 05 03:14:53 2013 +0200
    88.2 +++ b/src/share/vm/services/classLoadingService.cpp	Fri Oct 04 21:00:43 2013 -0700
    88.3 @@ -202,7 +202,7 @@
    88.4    MutexLocker m(Management_lock);
    88.5  
    88.6    // verbose will be set to the previous value
    88.7 -  bool succeed = CommandLineFlags::boolAtPut((char*)"TraceClassLoading", &verbose, MANAGEMENT);
    88.8 +  bool succeed = CommandLineFlags::boolAtPut((char*)"TraceClassLoading", &verbose, Flag::MANAGEMENT);
    88.9    assert(succeed, "Setting TraceClassLoading flag fails");
   88.10    reset_trace_class_unloading();
   88.11  
   88.12 @@ -213,7 +213,7 @@
   88.13  void ClassLoadingService::reset_trace_class_unloading() {
   88.14    assert(Management_lock->owned_by_self(), "Must own the Management_lock");
   88.15    bool value = MemoryService::get_verbose() || ClassLoadingService::get_verbose();
   88.16 -  bool succeed = CommandLineFlags::boolAtPut((char*)"TraceClassUnloading", &value, MANAGEMENT);
   88.17 +  bool succeed = CommandLineFlags::boolAtPut((char*)"TraceClassUnloading", &value, Flag::MANAGEMENT);
   88.18    assert(succeed, "Setting TraceClassUnLoading flag fails");
   88.19  }
   88.20  
    89.1 --- a/src/share/vm/services/dtraceAttacher.cpp	Sat Oct 05 03:14:53 2013 +0200
    89.2 +++ b/src/share/vm/services/dtraceAttacher.cpp	Fri Oct 04 21:00:43 2013 -0700
    89.3 @@ -51,7 +51,7 @@
    89.4  
    89.5  static void set_bool_flag(const char* flag, bool value) {
    89.6    CommandLineFlags::boolAtPut((char*)flag, strlen(flag), &value,
    89.7 -                              ATTACH_ON_DEMAND);
    89.8 +                              Flag::ATTACH_ON_DEMAND);
    89.9  }
   89.10  
   89.11  // Enable only the "fine grained" flags. Do *not* touch
    90.1 --- a/src/share/vm/services/management.cpp	Sat Oct 05 03:14:53 2013 +0200
    90.2 +++ b/src/share/vm/services/management.cpp	Fri Oct 04 21:00:43 2013 -0700
    90.3 @@ -1643,9 +1643,13 @@
    90.4    int num_entries = 0;
    90.5    for (int i = 0; i < nFlags; i++) {
    90.6      Flag* flag = &Flag::flags[i];
    90.7 +    // Exclude notproduct and develop flags in product builds.
    90.8 +    if (flag->is_constant_in_binary()) {
    90.9 +      continue;
   90.10 +    }
   90.11      // Exclude the locked (experimental, diagnostic) flags
   90.12      if (flag->is_unlocked() || flag->is_unlocker()) {
   90.13 -      Handle s = java_lang_String::create_from_str(flag->name, CHECK_0);
   90.14 +      Handle s = java_lang_String::create_from_str(flag->_name, CHECK_0);
   90.15        flags_ah->obj_at_put(num_entries, s());
   90.16        num_entries++;
   90.17      }
   90.18 @@ -1669,7 +1673,7 @@
   90.19  bool add_global_entry(JNIEnv* env, Handle name, jmmVMGlobal *global, Flag *flag, TRAPS) {
   90.20    Handle flag_name;
   90.21    if (name() == NULL) {
   90.22 -    flag_name = java_lang_String::create_from_str(flag->name, CHECK_false);
   90.23 +    flag_name = java_lang_String::create_from_str(flag->_name, CHECK_false);
   90.24    } else {
   90.25      flag_name = name;
   90.26    }
   90.27 @@ -1698,23 +1702,23 @@
   90.28  
   90.29    global->writeable = flag->is_writeable();
   90.30    global->external = flag->is_external();
   90.31 -  switch (flag->origin) {
   90.32 -    case DEFAULT:
   90.33 +  switch (flag->get_origin()) {
   90.34 +    case Flag::DEFAULT:
   90.35        global->origin = JMM_VMGLOBAL_ORIGIN_DEFAULT;
   90.36        break;
   90.37 -    case COMMAND_LINE:
   90.38 +    case Flag::COMMAND_LINE:
   90.39        global->origin = JMM_VMGLOBAL_ORIGIN_COMMAND_LINE;
   90.40        break;
   90.41 -    case ENVIRON_VAR:
   90.42 +    case Flag::ENVIRON_VAR:
   90.43        global->origin = JMM_VMGLOBAL_ORIGIN_ENVIRON_VAR;
   90.44        break;
   90.45 -    case CONFIG_FILE:
   90.46 +    case Flag::CONFIG_FILE:
   90.47        global->origin = JMM_VMGLOBAL_ORIGIN_CONFIG_FILE;
   90.48        break;
   90.49 -    case MANAGEMENT:
   90.50 +    case Flag::MANAGEMENT:
   90.51        global->origin = JMM_VMGLOBAL_ORIGIN_MANAGEMENT;
   90.52        break;
   90.53 -    case ERGONOMIC:
   90.54 +    case Flag::ERGONOMIC:
   90.55        global->origin = JMM_VMGLOBAL_ORIGIN_ERGONOMIC;
   90.56        break;
   90.57      default:
   90.58 @@ -1781,6 +1785,10 @@
   90.59      int num_entries = 0;
   90.60      for (int i = 0; i < nFlags && num_entries < count;  i++) {
   90.61        Flag* flag = &Flag::flags[i];
   90.62 +      // Exclude notproduct and develop flags in product builds.
   90.63 +      if (flag->is_constant_in_binary()) {
   90.64 +        continue;
   90.65 +      }
   90.66        // Exclude the locked (diagnostic, experimental) flags
   90.67        if ((flag->is_unlocked() || flag->is_unlocker()) &&
   90.68            add_global_entry(env, null_h, &globals[num_entries], flag, THREAD)) {
   90.69 @@ -1813,23 +1821,23 @@
   90.70    bool succeed;
   90.71    if (flag->is_bool()) {
   90.72      bool bvalue = (new_value.z == JNI_TRUE ? true : false);
   90.73 -    succeed = CommandLineFlags::boolAtPut(name, &bvalue, MANAGEMENT);
   90.74 +    succeed = CommandLineFlags::boolAtPut(name, &bvalue, Flag::MANAGEMENT);
   90.75    } else if (flag->is_intx()) {
   90.76      intx ivalue = (intx)new_value.j;
   90.77 -    succeed = CommandLineFlags::intxAtPut(name, &ivalue, MANAGEMENT);
   90.78 +    succeed = CommandLineFlags::intxAtPut(name, &ivalue, Flag::MANAGEMENT);
   90.79    } else if (flag->is_uintx()) {
   90.80      uintx uvalue = (uintx)new_value.j;
   90.81 -    succeed = CommandLineFlags::uintxAtPut(name, &uvalue, MANAGEMENT);
   90.82 +    succeed = CommandLineFlags::uintxAtPut(name, &uvalue, Flag::MANAGEMENT);
   90.83    } else if (flag->is_uint64_t()) {
   90.84      uint64_t uvalue = (uint64_t)new_value.j;
   90.85 -    succeed = CommandLineFlags::uint64_tAtPut(name, &uvalue, MANAGEMENT);
   90.86 +    succeed = CommandLineFlags::uint64_tAtPut(name, &uvalue, Flag::MANAGEMENT);
   90.87    } else if (flag->is_ccstr()) {
   90.88      oop str = JNIHandles::resolve_external_guard(new_value.l);
   90.89      if (str == NULL) {
   90.90        THROW(vmSymbols::java_lang_NullPointerException());
   90.91      }
   90.92      ccstr svalue = java_lang_String::as_utf8_string(str);
   90.93 -    succeed = CommandLineFlags::ccstrAtPut(name, &svalue, MANAGEMENT);
   90.94 +    succeed = CommandLineFlags::ccstrAtPut(name, &svalue, Flag::MANAGEMENT);
   90.95    }
   90.96    assert(succeed, "Setting flag should succeed");
   90.97  JVM_END
    91.1 --- a/src/share/vm/services/memoryService.cpp	Sat Oct 05 03:14:53 2013 +0200
    91.2 +++ b/src/share/vm/services/memoryService.cpp	Fri Oct 04 21:00:43 2013 -0700
    91.3 @@ -515,7 +515,7 @@
    91.4  bool MemoryService::set_verbose(bool verbose) {
    91.5    MutexLocker m(Management_lock);
    91.6    // verbose will be set to the previous value
    91.7 -  bool succeed = CommandLineFlags::boolAtPut((char*)"PrintGC", &verbose, MANAGEMENT);
    91.8 +  bool succeed = CommandLineFlags::boolAtPut((char*)"PrintGC", &verbose, Flag::MANAGEMENT);
    91.9    assert(succeed, "Setting PrintGC flag fails");
   91.10    ClassLoadingService::reset_trace_class_unloading();
   91.11  
   91.12 @@ -618,4 +618,3 @@
   91.13    MemoryService::gc_end(_fullGC, _recordPostGCUsage, _recordAccumulatedGCTime,
   91.14                          _recordGCEndTime, _countCollection, _cause);
   91.15  }
   91.16 -
    92.1 --- a/src/share/vm/trace/trace.xml	Sat Oct 05 03:14:53 2013 +0200
    92.2 +++ b/src/share/vm/trace/trace.xml	Fri Oct 04 21:00:43 2013 -0700
    92.3 @@ -313,13 +313,6 @@
    92.4        <value type="UINT" field="zombifiedCount" label="Methods Zombified"/>
    92.5      </event>
    92.6  
    92.7 -    <event id="CleanCodeCache" path="vm/code_sweeper/clean" label="Clean Code Cache"
    92.8 -             description="Clean code cache from oldest methods"
    92.9 -             has_thread="true" is_requestable="false" is_constant="false">
   92.10 -      <value type="UINT" field="disconnectedCount" label="Methods Disconnected"/>
   92.11 -      <value type="UINT" field="madeNonEntrantCount" label="Methods Made Non-Entrant"/>
   92.12 -    </event>
   92.13 -
   92.14      <!-- Code cache events -->
   92.15  
   92.16      <event id="CodeCacheFull" path="vm/code_cache/full" label="Code Cache Full"
    93.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    93.2 +++ b/test/compiler/intrinsics/mathexact/CondTest.java	Fri Oct 04 21:00:43 2013 -0700
    93.3 @@ -0,0 +1,59 @@
    93.4 +/*
    93.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    93.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    93.7 + *
    93.8 + * This code is free software; you can redistribute it and/or modify it
    93.9 + * under the terms of the GNU General Public License version 2 only, as
   93.10 + * published by the Free Software Foundation.
   93.11 + *
   93.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   93.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   93.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   93.15 + * version 2 for more details (a copy is included in the LICENSE file that
   93.16 + * accompanied this code).
   93.17 + *
   93.18 + * You should have received a copy of the GNU General Public License version
   93.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   93.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   93.21 + *
   93.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   93.23 + * or visit www.oracle.com if you need additional information or have any
   93.24 + * questions.
   93.25 + */
   93.26 +
   93.27 +/*
   93.28 + * @test
   93.29 + * @bug 8024924
   93.30 + * @summary Test non constant addExact
   93.31 + * @compile CondTest.java Verify.java
   93.32 + * @run main CondTest
   93.33 + *
   93.34 + */
   93.35 +
   93.36 +import java.lang.ArithmeticException;
   93.37 +
   93.38 +public class CondTest {
   93.39 +  public static int result = 0;
   93.40 +
   93.41 +  public static void main(String[] args) {
   93.42 +    for (int i = 0; i < 50000; ++i) {
   93.43 +      runTest();
   93.44 +    }
   93.45 +  }
   93.46 +
   93.47 +  public static void runTest() {
   93.48 +    int i = 7;
   93.49 +    while (java.lang.Math.addExact(i, result) < 89361) {
   93.50 +        if ((java.lang.Math.addExact(i, i) & 1) == 1) {
   93.51 +            i += 3;
   93.52 +        } else if ((i & 5) == 4) {
   93.53 +            i += 7;
   93.54 +        } else if ((i & 0xf) == 6) {
   93.55 +            i += 2;
   93.56 +        } else {
   93.57 +            i += 1;
   93.58 +        }
   93.59 +        result += 2;
   93.60 +    }
   93.61 +  }
   93.62 +}
    94.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    94.2 +++ b/test/compiler/intrinsics/mathexact/ConstantTest.java	Fri Oct 04 21:00:43 2013 -0700
    94.3 @@ -0,0 +1,47 @@
    94.4 +/*
    94.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    94.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    94.7 + *
    94.8 + * This code is free software; you can redistribute it and/or modify it
    94.9 + * under the terms of the GNU General Public License version 2 only, as
   94.10 + * published by the Free Software Foundation.
   94.11 + *
   94.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   94.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   94.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   94.15 + * version 2 for more details (a copy is included in the LICENSE file that
   94.16 + * accompanied this code).
   94.17 + *
   94.18 + * You should have received a copy of the GNU General Public License version
   94.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   94.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   94.21 + *
   94.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   94.23 + * or visit www.oracle.com if you need additional information or have any
   94.24 + * questions.
   94.25 + */
   94.26 +
   94.27 +/*
   94.28 + * @test
   94.29 + * @bug 8024924
   94.30 + * @summary Test constant addExact
   94.31 + * @compile ConstantTest.java Verify.java
   94.32 + * @run main ConstantTest
   94.33 + *
   94.34 + */
   94.35 +
   94.36 +import java.lang.ArithmeticException;
   94.37 +
   94.38 +public class ConstantTest {
   94.39 +  public static void main(String[] args) {
   94.40 +    for (int i = 0; i < 50000; ++i) {
   94.41 +      Verify.verify(5, 7);
   94.42 +      Verify.verify(Integer.MAX_VALUE, 1);
   94.43 +      Verify.verify(Integer.MIN_VALUE, -1);
   94.44 +      Verify.verify(Integer.MAX_VALUE, -1);
   94.45 +      Verify.verify(Integer.MIN_VALUE, 1);
   94.46 +      Verify.verify(Integer.MAX_VALUE / 2, Integer.MAX_VALUE / 2);
   94.47 +      Verify.verify(Integer.MAX_VALUE / 2, (Integer.MAX_VALUE / 2) + 3);
   94.48 +    }
   94.49 +  }
   94.50 +}
    95.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    95.2 +++ b/test/compiler/intrinsics/mathexact/LoadTest.java	Fri Oct 04 21:00:43 2013 -0700
    95.3 @@ -0,0 +1,55 @@
    95.4 +/*
    95.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    95.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    95.7 + *
    95.8 + * This code is free software; you can redistribute it and/or modify it
    95.9 + * under the terms of the GNU General Public License version 2 only, as
   95.10 + * published by the Free Software Foundation.
   95.11 + *
   95.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   95.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   95.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   95.15 + * version 2 for more details (a copy is included in the LICENSE file that
   95.16 + * accompanied this code).
   95.17 + *
   95.18 + * You should have received a copy of the GNU General Public License version
   95.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   95.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   95.21 + *
   95.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   95.23 + * or visit www.oracle.com if you need additional information or have any
   95.24 + * questions.
   95.25 + */
   95.26 +
   95.27 +/*
   95.28 + * @test
   95.29 + * @bug 8024924
   95.30 + * @summary Test non constant addExact
   95.31 + * @compile LoadTest.java Verify.java
   95.32 + * @run main LoadTest
   95.33 + *
   95.34 + */
   95.35 +
   95.36 +import java.lang.ArithmeticException;
   95.37 +
   95.38 +public class LoadTest {
   95.39 +  public static java.util.Random rnd = new java.util.Random();
   95.40 +  public static int[] values = new int[256];
   95.41 +
   95.42 +  public static void main(String[] args) {
   95.43 +    for (int i = 0; i < values.length; ++i) {
   95.44 +        values[i] = rnd.nextInt();
   95.45 +    }
   95.46 +
   95.47 +    for (int i = 0; i < 50000; ++i) {
   95.48 +      Verify.verify(values[i & 255], values[i & 255] - i);
   95.49 +      Verify.verify(values[i & 255] + i, values[i & 255] - i);
   95.50 +      Verify.verify(values[i & 255], values[i & 255]);
   95.51 +      if ((i & 1) == 1 && i > 5) {
   95.52 +          Verify.verify(values[i & 255] + i, values[i & 255] - i);
   95.53 +      } else {
   95.54 +          Verify.verify(values[i & 255] - i, values[i & 255] + i);
   95.55 +      }
   95.56 +    }
   95.57 +  }
   95.58 +}
    96.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    96.2 +++ b/test/compiler/intrinsics/mathexact/LoopDependentTest.java	Fri Oct 04 21:00:43 2013 -0700
    96.3 @@ -0,0 +1,48 @@
    96.4 +/*
    96.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    96.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    96.7 + *
    96.8 + * This code is free software; you can redistribute it and/or modify it
    96.9 + * under the terms of the GNU General Public License version 2 only, as
   96.10 + * published by the Free Software Foundation.
   96.11 + *
   96.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   96.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   96.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   96.15 + * version 2 for more details (a copy is included in the LICENSE file that
   96.16 + * accompanied this code).
   96.17 + *
   96.18 + * You should have received a copy of the GNU General Public License version
   96.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   96.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   96.21 + *
   96.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   96.23 + * or visit www.oracle.com if you need additional information or have any
   96.24 + * questions.
   96.25 + */
   96.26 +
   96.27 +/*
   96.28 + * @test
   96.29 + * @bug 8024924
   96.30 + * @summary Test non constant addExact
   96.31 + * @compile LoopDependentTest.java Verify.java
   96.32 + * @run main LoopDependentTest
   96.33 + *
   96.34 + */
   96.35 +
   96.36 +import java.lang.ArithmeticException;
   96.37 +
   96.38 +public class LoopDependentTest {
   96.39 +  public static java.util.Random rnd = new java.util.Random();
   96.40 +
   96.41 +  public static void main(String[] args) {
   96.42 +    int rnd1 = rnd.nextInt(), rnd2 = rnd.nextInt();
   96.43 +    for (int i = 0; i < 50000; ++i) {
   96.44 +      Verify.verify(rnd1 + i, rnd2 + i);
   96.45 +      Verify.verify(rnd1 + i, rnd2 + (i & 0xff));
   96.46 +      Verify.verify(rnd1 - i, rnd2 - (i & 0xff));
   96.47 +      Verify.verify(rnd1 + i + 1, rnd2 + i + 2);
   96.48 +      Verify.verify(rnd1 + i * 2, rnd2 + i);
   96.49 +    }
   96.50 +  }
   96.51 +}
    97.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    97.2 +++ b/test/compiler/intrinsics/mathexact/NonConstantTest.java	Fri Oct 04 21:00:43 2013 -0700
    97.3 @@ -0,0 +1,48 @@
    97.4 +/*
    97.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    97.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    97.7 + *
    97.8 + * This code is free software; you can redistribute it and/or modify it
    97.9 + * under the terms of the GNU General Public License version 2 only, as
   97.10 + * published by the Free Software Foundation.
   97.11 + *
   97.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   97.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   97.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   97.15 + * version 2 for more details (a copy is included in the LICENSE file that
   97.16 + * accompanied this code).
   97.17 + *
   97.18 + * You should have received a copy of the GNU General Public License version
   97.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   97.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   97.21 + *
   97.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   97.23 + * or visit www.oracle.com if you need additional information or have any
   97.24 + * questions.
   97.25 + */
   97.26 +
   97.27 +/*
   97.28 + * @test
   97.29 + * @bug 8024924
   97.30 + * @summary Test non constant addExact
   97.31 + * @compile NonConstantTest.java Verify.java
   97.32 + * @run main NonConstantTest
   97.33 + *
   97.34 + */
   97.35 +
   97.36 +import java.lang.ArithmeticException;
   97.37 +
   97.38 +public class NonConstantTest {
   97.39 +  public static java.util.Random rnd = new java.util.Random();
   97.40 +
   97.41 +  public static void main(String[] args) {
   97.42 +    for (int i = 0; i < 50000; ++i) {
   97.43 +      int rnd1 = rnd.nextInt(), rnd2 = rnd.nextInt();
   97.44 +      Verify.verify(rnd1, rnd2);
   97.45 +      Verify.verify(rnd1, rnd2 + 1);
   97.46 +      Verify.verify(rnd1 + 1, rnd2);
   97.47 +      Verify.verify(rnd1 - 1, rnd2);
   97.48 +      Verify.verify(rnd1, rnd2 - 1);
   97.49 +    }
   97.50 +  }
   97.51 +}
    98.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    98.2 +++ b/test/compiler/intrinsics/mathexact/Verify.java	Fri Oct 04 21:00:43 2013 -0700
    98.3 @@ -0,0 +1,68 @@
    98.4 +/*
    98.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    98.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    98.7 + *
    98.8 + * This code is free software; you can redistribute it and/or modify it
    98.9 + * under the terms of the GNU General Public License version 2 only, as
   98.10 + * published by the Free Software Foundation.
   98.11 + *
   98.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   98.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   98.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   98.15 + * version 2 for more details (a copy is included in the LICENSE file that
   98.16 + * accompanied this code).
   98.17 + *
   98.18 + * You should have received a copy of the GNU General Public License version
   98.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   98.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   98.21 + *
   98.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   98.23 + * or visit www.oracle.com if you need additional information or have any
   98.24 + * questions.
   98.25 + */
   98.26 +
   98.27 +public class Verify {
   98.28 +  public static String throwWord(boolean threw) {
   98.29 +    return (threw ? "threw" : "didn't throw");
   98.30 +  }
   98.31 +
   98.32 +  public static void verify(int a, int b) {
   98.33 +    boolean exception1 = false, exception2 = false;
   98.34 +    int result1 = 0, result2 = 0;
   98.35 +    try {
   98.36 +      result1 = testIntrinsic(a, b);
   98.37 +    } catch (ArithmeticException e) {
   98.38 +      exception1 = true;
   98.39 +    }
   98.40 +    try {
   98.41 +      result2 = testNonIntrinsic(a, b);
   98.42 +    } catch (ArithmeticException e) {
   98.43 +      exception2 = true;
   98.44 +    }
   98.45 +
   98.46 +    if (exception1 != exception2) {
   98.47 +      throw new RuntimeException("Intrinsic version " + throwWord(exception1) + " exception, NonIntrinsic version " + throwWord(exception2) + " for: " + a + " + " + b);
   98.48 +    }
   98.49 +    if (result1 != result2) {
   98.50 +      throw new RuntimeException("Intrinsic version returned: " + a + " while NonIntrinsic version returned: " + b);
   98.51 +    }
   98.52 +  }
   98.53 +
   98.54 +  public static int testIntrinsic(int a, int b) {
   98.55 +    return java.lang.Math.addExact(a, b);
   98.56 +  }
   98.57 +
   98.58 +  public static int testNonIntrinsic(int a, int b) {
   98.59 +    return safeAddExact(a, b);
   98.60 +  }
   98.61 +
   98.62 +  // Copied java.lang.Math.addExact to avoid intrinsification
   98.63 +  public static int safeAddExact(int x, int y) {
   98.64 +    int r = x + y;
   98.65 +    // HD 2-12 Overflow iff both arguments have the opposite sign of the result
   98.66 +    if (((x ^ r) & (y ^ r)) < 0) {
   98.67 +      throw new ArithmeticException("integer overflow");
   98.68 +    }
   98.69 +    return r;
   98.70 +  }
   98.71 +}
    99.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    99.2 +++ b/test/compiler/jsr292/methodHandleExceptions/ByteClassLoader.java	Fri Oct 04 21:00:43 2013 -0700
    99.3 @@ -0,0 +1,44 @@
    99.4 +/*
    99.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    99.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    99.7 + *
    99.8 + * This code is free software; you can redistribute it and/or modify it
    99.9 + * under the terms of the GNU General Public License version 2 only, as
   99.10 + * published by the Free Software Foundation.
   99.11 + *
   99.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   99.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   99.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   99.15 + * version 2 for more details (a copy is included in the LICENSE file that
   99.16 + * accompanied this code).
   99.17 + *
   99.18 + * You should have received a copy of the GNU General Public License version
   99.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   99.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   99.21 + *
   99.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   99.23 + * or visit www.oracle.com if you need additional information or have any
   99.24 + * questions.
   99.25 + *
   99.26 + */
   99.27 +
   99.28 +/**
   99.29 + * A minimal classloader for loading bytecodes that could not result from
   99.30 + * properly compiled Java.
   99.31 + *
   99.32 + * @author dr2chase
   99.33 + */
   99.34 +public class ByteClassLoader extends ClassLoader {
   99.35 +    /**
   99.36 +     * (pre)load class name using classData for the definition.
   99.37 +     *
   99.38 +     * @param name
   99.39 +     * @param classData
   99.40 +     * @return
   99.41 +     */
   99.42 +    public Class<?> loadBytes(String name, byte[] classData) {
   99.43 +         Class<?> clazz = defineClass(name, classData, 0, classData.length);
   99.44 +                     resolveClass(clazz);
   99.45 +         return clazz;
   99.46 +    }
   99.47 +}
   100.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   100.2 +++ b/test/compiler/jsr292/methodHandleExceptions/C.java	Fri Oct 04 21:00:43 2013 -0700
   100.3 @@ -0,0 +1,33 @@
   100.4 +/*
   100.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
   100.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   100.7 + *
   100.8 + * This code is free software; you can redistribute it and/or modify it
   100.9 + * under the terms of the GNU General Public License version 2 only, as
  100.10 + * published by the Free Software Foundation.
  100.11 + *
  100.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  100.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  100.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  100.15 + * version 2 for more details (a copy is included in the LICENSE file that
  100.16 + * accompanied this code).
  100.17 + *
  100.18 + * You should have received a copy of the GNU General Public License version
  100.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  100.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  100.21 + *
  100.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  100.23 + * or visit www.oracle.com if you need additional information or have any
  100.24 + * questions.
  100.25 + *
  100.26 + */
  100.27 +
  100.28 +/**
  100.29 + * Test class -- implements I, which provides default for m, but this class
  100.30 + * declares it abstract which (should) hide the interface default, and throw
  100.31 + * an abstract method error if it is called (calling it requires bytecode hacking
  100.32 + * or inconsistent compilation).
  100.33 + */
  100.34 +public abstract class C implements I {
  100.35 +       public abstract int m();
  100.36 +}
   101.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   101.2 +++ b/test/compiler/jsr292/methodHandleExceptions/I.java	Fri Oct 04 21:00:43 2013 -0700
   101.3 @@ -0,0 +1,27 @@
   101.4 +/*
   101.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
   101.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   101.7 + *
   101.8 + * This code is free software; you can redistribute it and/or modify it
   101.9 + * under the terms of the GNU General Public License version 2 only, as
  101.10 + * published by the Free Software Foundation.
  101.11 + *
  101.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  101.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  101.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  101.15 + * version 2 for more details (a copy is included in the LICENSE file that
  101.16 + * accompanied this code).
  101.17 + *
  101.18 + * You should have received a copy of the GNU General Public License version
  101.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  101.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  101.21 + *
  101.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  101.23 + * or visit www.oracle.com if you need additional information or have any
  101.24 + * questions.
  101.25 + *
  101.26 + */
  101.27 +
  101.28 +public interface I {
  101.29 +    default public int m() { return 1; }
  101.30 +}
   102.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   102.2 +++ b/test/compiler/jsr292/methodHandleExceptions/TestAMEnotNPE.java	Fri Oct 04 21:00:43 2013 -0700
   102.3 @@ -0,0 +1,143 @@
   102.4 +/*
   102.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
   102.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   102.7 + *
   102.8 + * This code is free software; you can redistribute it and/or modify it
   102.9 + * under the terms of the GNU General Public License version 2 only, as
  102.10 + * published by the Free Software Foundation.
  102.11 + *
  102.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  102.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  102.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  102.15 + * version 2 for more details (a copy is included in the LICENSE file that
  102.16 + * accompanied this code).
  102.17 + *
  102.18 + * You should have received a copy of the GNU General Public License version
  102.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  102.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  102.21 + *
  102.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  102.23 + * or visit www.oracle.com if you need additional information or have any
  102.24 + * questions.
  102.25 + *
  102.26 + */
  102.27 +
  102.28 +import java.lang.reflect.InvocationTargetException;
  102.29 +import jdk.internal.org.objectweb.asm.ClassWriter;
  102.30 +import jdk.internal.org.objectweb.asm.Handle;
  102.31 +import jdk.internal.org.objectweb.asm.MethodVisitor;
  102.32 +import jdk.internal.org.objectweb.asm.Opcodes;
  102.33 +
  102.34 +/**
  102.35 + * @test
  102.36 + * @bug 8025260
  102.37 + * @summary Ensure that AbstractMethodError is thrown, not NullPointerException, through MethodHandles::jump_from_method_handle code path
  102.38 + *
  102.39 + * @compile -XDignore.symbol.file ByteClassLoader.java I.java C.java TestAMEnotNPE.java
  102.40 + * @run main/othervm TestAMEnotNPE
  102.41 + */
  102.42 +
  102.43 +public class TestAMEnotNPE implements Opcodes {
  102.44 +
  102.45 +    /**
  102.46 +     * The bytes for D, a NOT abstract class extending abstract class C
  102.47 +     * without supplying an implementation for abstract method m.
  102.48 +     * There is a default method in the interface I, but it should lose to
  102.49 +     * the abstract class.
  102.50 +
  102.51 +     class D extends C {
  102.52 +        D() { super(); }
  102.53 +        // does not define m
  102.54 +     }
  102.55 +
  102.56 +     * @return
  102.57 +     * @throws Exception
  102.58 +     */
  102.59 +    public static byte[] bytesForD() throws Exception {
  102.60 +
  102.61 +        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
  102.62 +        MethodVisitor mv;
  102.63 +
  102.64 +        cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, "D", null, "C", null);
  102.65 +
  102.66 +        {
  102.67 +            mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
  102.68 +            mv.visitCode();
  102.69 +            mv.visitVarInsn(ALOAD, 0);
  102.70 +            mv.visitMethodInsn(INVOKESPECIAL, "C", "<init>", "()V");
  102.71 +            mv.visitInsn(RETURN);
  102.72 +            mv.visitMaxs(0, 0);
  102.73 +            mv.visitEnd();
  102.74 +        }
  102.75 +        cw.visitEnd();
  102.76 +
  102.77 +        return cw.toByteArray();
  102.78 +    }
  102.79 +
  102.80 +
  102.81 +    /**
  102.82 +     * The bytecodes for an invokeExact of a particular methodHandle, I.m, invoked on a D
  102.83 +
  102.84 +        class T {
  102.85 +           T() { super(); } // boring constructor
  102.86 +           int test() {
  102.87 +              MethodHandle mh = `I.m():int`;
  102.88 +              D d = new D();
  102.89 +              return mh.invokeExact(d); // Should explode here, AbstractMethodError
  102.90 +           }
  102.91 +        }
  102.92 +
  102.93 +     * @return
  102.94 +     * @throws Exception
  102.95 +     */
  102.96 +    public static byte[] bytesForT() throws Exception {
  102.97 +
  102.98 +        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
  102.99 +        MethodVisitor mv;
 102.100 +
 102.101 +        cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, "T", null, "java/lang/Object", null);
 102.102 +        {
 102.103 +            mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
 102.104 +            mv.visitCode();
 102.105 +            mv.visitVarInsn(ALOAD, 0);
 102.106 +            mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
 102.107 +            mv.visitInsn(RETURN);
 102.108 +            mv.visitMaxs(0,0);
 102.109 +            mv.visitEnd();
 102.110 +        }
 102.111 +        {
 102.112 +            mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "test", "()I", null, null);
 102.113 +            mv.visitCode();
 102.114 +            mv.visitLdcInsn(new Handle(Opcodes.H_INVOKEINTERFACE, "I", "m", "()I"));
 102.115 +            mv.visitTypeInsn(NEW, "D");
 102.116 +            mv.visitInsn(DUP);
 102.117 +            mv.visitMethodInsn(INVOKESPECIAL, "D", "<init>", "()V");
 102.118 +            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", "invokeExact", "(LI;)I");
 102.119 +            mv.visitInsn(IRETURN);
 102.120 +            mv.visitMaxs(0,0);
 102.121 +            mv.visitEnd();
 102.122 +        }
 102.123 +        cw.visitEnd();
 102.124 +        return cw.toByteArray();
 102.125 +    }
 102.126 +
 102.127 +    public static void main(String args[] ) throws Throwable {
 102.128 +        ByteClassLoader bcl = new ByteClassLoader();
 102.129 +        Class<?> d = bcl.loadBytes("D", bytesForD());
 102.130 +        Class<?> t = bcl.loadBytes("T", bytesForT());
 102.131 +        try {
 102.132 +          Object result = t.getMethod("test").invoke(null);
 102.133 +          System.out.println("Expected AbstractMethodError wrapped in InvocationTargetException, saw no exception");
 102.134 +          throw new Error("Missing expected exception");
 102.135 +        } catch (InvocationTargetException e) {
 102.136 +            Throwable th = e.getCause();
 102.137 +            if (th instanceof AbstractMethodError) {
 102.138 +                th.printStackTrace(System.out);
 102.139 +                System.out.println("PASS, saw expected exception (AbstractMethodError, wrapped in InvocationTargetException).");
 102.140 +            } else {
 102.141 +                System.out.println("Expected AbstractMethodError wrapped in InvocationTargetException, saw " + th);
 102.142 +                throw th;
 102.143 +            }
 102.144 +        }
 102.145 +    }
 102.146 +}
   103.1 --- a/test/compiler/whitebox/CompilerWhiteBoxTest.java	Sat Oct 05 03:14:53 2013 +0200
   103.2 +++ b/test/compiler/whitebox/CompilerWhiteBoxTest.java	Fri Oct 04 21:00:43 2013 -0700
   103.3 @@ -74,6 +74,9 @@
   103.4      protected static final int THRESHOLD;
   103.5      /** count of invocation to triger OSR compilation */
   103.6      protected static final long BACKEDGE_THRESHOLD;
   103.7 +    /** Value of {@code java.vm.info} (interpreted|mixed|comp mode) */
   103.8 +    protected static final String MODE
   103.9 +            = System.getProperty("java.vm.info");
  103.10  
  103.11      static {
  103.12          if (TIERED_COMPILATION) {
  103.13 @@ -202,7 +205,7 @@
  103.14          if (WHITE_BOX.getMethodCompilationLevel(method, true) != 0) {
  103.15              throw new RuntimeException(method + " osr_comp_level must be == 0");
  103.16          }
  103.17 -    }
  103.18 +   }
  103.19  
  103.20      /**
  103.21       * Checks, that {@linkplain #method} is compiled.
   104.1 --- a/test/compiler/whitebox/DeoptimizeAllTest.java	Sat Oct 05 03:14:53 2013 +0200
   104.2 +++ b/test/compiler/whitebox/DeoptimizeAllTest.java	Fri Oct 04 21:00:43 2013 -0700
   104.3 @@ -53,6 +53,12 @@
   104.4       */
   104.5      @Override
   104.6      protected void test() throws Exception {
   104.7 +        if (testCase.isOsr && CompilerWhiteBoxTest.MODE.startsWith(
   104.8 +                "compiled ")) {
   104.9 +          System.err.printf("Warning: %s is not applicable in %s%n",
  104.10 +                testCase.name(), CompilerWhiteBoxTest.MODE);
  104.11 +          return;
  104.12 +        }
  104.13          compile();
  104.14          checkCompiled();
  104.15          WHITE_BOX.deoptimizeAll();
   105.1 --- a/test/compiler/whitebox/DeoptimizeMethodTest.java	Sat Oct 05 03:14:53 2013 +0200
   105.2 +++ b/test/compiler/whitebox/DeoptimizeMethodTest.java	Fri Oct 04 21:00:43 2013 -0700
   105.3 @@ -53,6 +53,12 @@
   105.4       */
   105.5      @Override
   105.6      protected void test() throws Exception {
   105.7 +        if (testCase.isOsr && CompilerWhiteBoxTest.MODE.startsWith(
   105.8 +                "compiled ")) {
   105.9 +          System.err.printf("Warning: %s is not applicable in %s%n",
  105.10 +                testCase.name(), CompilerWhiteBoxTest.MODE);
  105.11 +          return;
  105.12 +        }
  105.13          compile();
  105.14          checkCompiled();
  105.15          deoptimize();
   106.1 --- a/test/compiler/whitebox/EnqueueMethodForCompilationTest.java	Sat Oct 05 03:14:53 2013 +0200
   106.2 +++ b/test/compiler/whitebox/EnqueueMethodForCompilationTest.java	Fri Oct 04 21:00:43 2013 -0700
   106.3 @@ -70,12 +70,10 @@
   106.4  
   106.5          int compLevel = getCompLevel();
   106.6          int bci = WHITE_BOX.getMethodEntryBci(method);
   106.7 -        System.out.println("bci = " + bci);
   106.8 -        printInfo();
   106.9          deoptimize();
  106.10 -        printInfo();
  106.11          checkNotCompiled();
  106.12 -        printInfo();
  106.13 +        WHITE_BOX.clearMethodState(method);
  106.14 +
  106.15          WHITE_BOX.enqueueMethodForCompilation(method, compLevel, bci);
  106.16          checkCompiled();
  106.17          deoptimize();
   107.1 --- a/test/compiler/whitebox/IsMethodCompilableTest.java	Sat Oct 05 03:14:53 2013 +0200
   107.2 +++ b/test/compiler/whitebox/IsMethodCompilableTest.java	Fri Oct 04 21:00:43 2013 -0700
   107.3 @@ -68,6 +68,12 @@
   107.4       */
   107.5      @Override
   107.6      protected void test() throws Exception {
   107.7 +        if (testCase.isOsr && CompilerWhiteBoxTest.MODE.startsWith(
   107.8 +                "compiled ")) {
   107.9 +          System.err.printf("Warning: %s is not applicable in %s%n",
  107.10 +                testCase.name(), CompilerWhiteBoxTest.MODE);
  107.11 +          return;
  107.12 +        }
  107.13          if (!isCompilable()) {
  107.14              throw new RuntimeException(method + " must be compilable");
  107.15          }
   108.1 --- a/test/compiler/whitebox/MakeMethodNotCompilableTest.java	Sat Oct 05 03:14:53 2013 +0200
   108.2 +++ b/test/compiler/whitebox/MakeMethodNotCompilableTest.java	Fri Oct 04 21:00:43 2013 -0700
   108.3 @@ -62,6 +62,12 @@
   108.4       */
   108.5      @Override
   108.6      protected void test() throws Exception {
   108.7 +        if (testCase.isOsr && CompilerWhiteBoxTest.MODE.startsWith(
   108.8 +                "compiled ")) {
   108.9 +          System.err.printf("Warning: %s is not applicable in %s%n",
  108.10 +                testCase.name(), CompilerWhiteBoxTest.MODE);
  108.11 +          return;
  108.12 +        }
  108.13          checkNotCompiled();
  108.14          if (!isCompilable()) {
  108.15              throw new RuntimeException(method + " must be compilable");
   109.1 --- a/test/gc/g1/TestSummarizeRSetStats.java	Sat Oct 05 03:14:53 2013 +0200
   109.2 +++ b/test/gc/g1/TestSummarizeRSetStats.java	Fri Oct 04 21:00:43 2013 -0700
   109.3 @@ -25,140 +25,61 @@
   109.4   * @test TestSummarizeRSetStats.java
   109.5   * @bug 8013895
   109.6   * @library /testlibrary
   109.7 - * @build TestSummarizeRSetStats
   109.8 + * @build TestSummarizeRSetStatsTools TestSummarizeRSetStats
   109.9   * @summary Verify output of -XX:+G1SummarizeRSetStats
  109.10   * @run main TestSummarizeRSetStats
  109.11   *
  109.12   * Test the output of G1SummarizeRSetStats in conjunction with G1SummarizeRSetStatsPeriod.
  109.13   */
  109.14  
  109.15 -import com.oracle.java.testlibrary.*;
  109.16 -import java.lang.Thread;
  109.17 -import java.util.ArrayList;
  109.18 -import java.util.Arrays;
  109.19 -
  109.20 -class RunSystemGCs {
  109.21 -    // 4M size, both are directly allocated into the old gen
  109.22 -    static Object[] largeObject1 = new Object[1024 * 1024];
  109.23 -    static Object[] largeObject2 = new Object[1024 * 1024];
  109.24 -
  109.25 -    static int[] temp;
  109.26 -
  109.27 -    public static void main(String[] args) {
  109.28 -        // create some cross-references between these objects
  109.29 -        for (int i = 0; i < largeObject1.length; i++) {
  109.30 -            largeObject1[i] = largeObject2;
  109.31 -        }
  109.32 -
  109.33 -        for (int i = 0; i < largeObject2.length; i++) {
  109.34 -            largeObject2[i] = largeObject1;
  109.35 -        }
  109.36 -
  109.37 -        int numGCs = Integer.parseInt(args[0]);
  109.38 -
  109.39 -        if (numGCs > 0) {
  109.40 -            // try to force a minor collection: the young gen is 4M, the
  109.41 -            // amount of data allocated below is roughly that (4*1024*1024 +
  109.42 -            // some header data)
  109.43 -            for (int i = 0; i < 1024 ; i++) {
  109.44 -                temp = new int[1024];
  109.45 -            }
  109.46 -        }
  109.47 -
  109.48 -        for (int i = 0; i < numGCs - 1; i++) {
  109.49 -            System.gc();
  109.50 -        }
  109.51 -    }
  109.52 -}
  109.53 -
  109.54  public class TestSummarizeRSetStats {
  109.55  
  109.56 -    public static String runTest(String[] additionalArgs, int numGCs) throws Exception {
  109.57 -        ArrayList<String> finalargs = new ArrayList<String>();
  109.58 -        String[] defaultArgs = new String[] {
  109.59 -            "-XX:+UseG1GC",
  109.60 -            "-Xmn4m",
  109.61 -            "-Xmx20m",
  109.62 -            "-XX:InitiatingHeapOccupancyPercent=100", // we don't want the additional GCs due to initial marking
  109.63 -            "-XX:+PrintGC",
  109.64 -            "-XX:+UnlockDiagnosticVMOptions",
  109.65 -            "-XX:G1HeapRegionSize=1M",
  109.66 -        };
  109.67 -
  109.68 -        finalargs.addAll(Arrays.asList(defaultArgs));
  109.69 -
  109.70 -        if (additionalArgs != null) {
  109.71 -            finalargs.addAll(Arrays.asList(additionalArgs));
  109.72 -        }
  109.73 -
  109.74 -        finalargs.add(RunSystemGCs.class.getName());
  109.75 -        finalargs.add(String.valueOf(numGCs));
  109.76 -
  109.77 -        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
  109.78 -            finalargs.toArray(new String[0]));
  109.79 -        OutputAnalyzer output = new OutputAnalyzer(pb.start());
  109.80 -
  109.81 -        output.shouldHaveExitValue(0);
  109.82 -
  109.83 -        String result = output.getStdout();
  109.84 -        return result;
  109.85 -    }
  109.86 -
  109.87 -    private static void expectStatistics(String result, int expectedCumulative, int expectedPeriodic) throws Exception {
  109.88 -        int actualTotal = result.split("Concurrent RS processed").length - 1;
  109.89 -        int actualCumulative = result.split("Cumulative RS summary").length - 1;
  109.90 -
  109.91 -        if (expectedCumulative != actualCumulative) {
  109.92 -            throw new Exception("Incorrect amount of RSet summaries at the end. Expected " + expectedCumulative + ", got " + actualCumulative);
  109.93 -        }
  109.94 -
  109.95 -        if (expectedPeriodic != (actualTotal - actualCumulative)) {
  109.96 -            throw new Exception("Incorrect amount of per-period RSet summaries at the end. Expected " + expectedPeriodic + ", got " + (actualTotal - actualCumulative));
  109.97 -        }
  109.98 -    }
  109.99 -
 109.100      public static void main(String[] args) throws Exception {
 109.101          String result;
 109.102  
 109.103 -        // no RSet statistics output
 109.104 -        result = runTest(null, 0);
 109.105 -        expectStatistics(result, 0, 0);
 109.106 +        if (!TestSummarizeRSetStatsTools.testingG1GC()) {
 109.107 +            return;
 109.108 +        }
 109.109  
 109.110 -        // no RSet statistics output
 109.111 -        result = runTest(null, 2);
 109.112 -        expectStatistics(result, 0, 0);
 109.113 +        // no remembered set summary output
 109.114 +        result = TestSummarizeRSetStatsTools.runTest(null, 0);
 109.115 +        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 0, 0);
 109.116  
 109.117 -        // no RSet statistics output
 109.118 -        result = runTest(new String[] { "-XX:G1SummarizeRSetStatsPeriod=1" }, 3);
 109.119 -        expectStatistics(result, 0, 0);
 109.120 +        // no remembered set summary output
 109.121 +        result = TestSummarizeRSetStatsTools.runTest(null, 2);
 109.122 +        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 0, 0);
 109.123  
 109.124 -        // single RSet statistics output at the end
 109.125 -        result = runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 0);
 109.126 -        expectStatistics(result, 1, 0);
 109.127 +        // no remembered set summary output
 109.128 +        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:G1SummarizeRSetStatsPeriod=1" }, 3);
 109.129 +        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 0, 0);
 109.130  
 109.131 -        // single RSet statistics output at the end
 109.132 -        result = runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 2);
 109.133 -        expectStatistics(result, 1, 0);
 109.134 +        // single remembered set summary output at the end
 109.135 +        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 0);
 109.136 +        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 0);
 109.137  
 109.138 -        // single RSet statistics output
 109.139 -        result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 0);
 109.140 -        expectStatistics(result, 1, 0);
 109.141 +        // single remembered set summary output at the end
 109.142 +        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 2);
 109.143 +        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 0);
 109.144  
 109.145 -        // two times RSet statistics output
 109.146 -        result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 1);
 109.147 -        expectStatistics(result, 1, 1);
 109.148 +        // single remembered set summary output
 109.149 +        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 0);
 109.150 +        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 0);
 109.151  
 109.152 -        // four times RSet statistics output
 109.153 -        result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 3);
 109.154 -        expectStatistics(result, 1, 3);
 109.155 +        // two times remembered set summary output
 109.156 +        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 1);
 109.157 +        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 2);
 109.158  
 109.159 -        // three times RSet statistics output
 109.160 -        result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=2" }, 3);
 109.161 -        expectStatistics(result, 1, 2);
 109.162 +        // four times remembered set summary output
 109.163 +        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 3);
 109.164 +        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 6);
 109.165  
 109.166 -        // single RSet statistics output
 109.167 -        result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=100" }, 3);
 109.168 -        expectStatistics(result, 1, 1);
 109.169 +        // three times remembered set summary output
 109.170 +        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=2" }, 3);
 109.171 +        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 4);
 109.172 +
 109.173 +        // single remembered set summary output
 109.174 +        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=100" }, 3);
 109.175 +        TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 2);
 109.176      }
 109.177  }
 109.178  
   110.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   110.2 +++ b/test/gc/g1/TestSummarizeRSetStatsPerRegion.java	Fri Oct 04 21:00:43 2013 -0700
   110.3 @@ -0,0 +1,55 @@
   110.4 +/*
   110.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
   110.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   110.7 + *
   110.8 + * This code is free software; you can redistribute it and/or modify it
   110.9 + * under the terms of the GNU General Public License version 2 only, as
  110.10 + * published by the Free Software Foundation.
  110.11 + *
  110.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  110.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  110.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  110.15 + * version 2 for more details (a copy is included in the LICENSE file that
  110.16 + * accompanied this code).
  110.17 + *
  110.18 + * You should have received a copy of the GNU General Public License version
  110.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  110.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  110.21 + *
  110.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  110.23 + * or visit www.oracle.com if you need additional information or have any
  110.24 + * questions.
  110.25 + */
  110.26 +
  110.27 +/*
  110.28 + * @test TestSummarizeRSetStatsPerRegion.java
  110.29 + * @bug 8014078
  110.30 + * @library /testlibrary
  110.31 + * @build TestSummarizeRSetStatsTools TestSummarizeRSetStatsPerRegion
  110.32 + * @summary Verify output of -XX:+G1SummarizeRSetStats in regards to per-region type output
  110.33 + * @run main TestSummarizeRSetStatsPerRegion
  110.34 + */
  110.35 +
  110.36 +import com.oracle.java.testlibrary.*;
  110.37 +import java.lang.Thread;
  110.38 +import java.util.ArrayList;
  110.39 +import java.util.Arrays;
  110.40 +
  110.41 +public class TestSummarizeRSetStatsPerRegion {
  110.42 +
  110.43 +    public static void main(String[] args) throws Exception {
  110.44 +        String result;
  110.45 +
  110.46 +        if (!TestSummarizeRSetStatsTools.testingG1GC()) {
  110.47 +            return;
  110.48 +        }
  110.49 +
  110.50 +        // single remembered set summary output at the end
  110.51 +        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 0);
  110.52 +        TestSummarizeRSetStatsTools.expectPerRegionRSetSummaries(result, 1, 0);
  110.53 +
  110.54 +        // two times remembered set summary output
  110.55 +        result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 1);
  110.56 +        TestSummarizeRSetStatsTools.expectPerRegionRSetSummaries(result, 1, 2);
  110.57 +    }
  110.58 +}
   111.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   111.2 +++ b/test/gc/g1/TestSummarizeRSetStatsThreads.java	Fri Oct 04 21:00:43 2013 -0700
   111.3 @@ -0,0 +1,83 @@
   111.4 +/*
   111.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
   111.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   111.7 + *
   111.8 + * This code is free software; you can redistribute it and/or modify it
   111.9 + * under the terms of the GNU General Public License version 2 only, as
  111.10 + * published by the Free Software Foundation.
  111.11 + *
  111.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  111.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  111.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  111.15 + * version 2 for more details (a copy is included in the LICENSE file that
  111.16 + * accompanied this code).
  111.17 + *
  111.18 + * You should have received a copy of the GNU General Public License version
  111.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  111.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  111.21 + *
  111.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  111.23 + * or visit www.oracle.com if you need additional information or have any
  111.24 + * questions.
  111.25 + */
  111.26 +
  111.27 +/*
  111.28 + * @test TestSummarizeRSetStatsThreads
  111.29 + * @bug 8025441
  111.30 + * @summary Ensure that various values of worker threads/concurrent
  111.31 + * refinement threads do not crash the VM.
  111.32 + * @key gc
  111.33 + * @library /testlibrary
  111.34 + */
  111.35 +
  111.36 +import java.util.regex.Matcher;
  111.37 +import java.util.regex.Pattern;
  111.38 +
  111.39 +import com.oracle.java.testlibrary.ProcessTools;
  111.40 +import com.oracle.java.testlibrary.OutputAnalyzer;
  111.41 +
  111.42 +public class TestSummarizeRSetStatsThreads {
  111.43 +
  111.44 +  private static void runTest(int refinementThreads, int workerThreads) throws Exception {
  111.45 +    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
  111.46 +                                                              "-XX:+UnlockDiagnosticVMOptions",
  111.47 +                                                              "-XX:+G1SummarizeRSetStats",
  111.48 +                                                              "-XX:G1ConcRefinementThreads=" + refinementThreads,
  111.49 +                                                              "-XX:ParallelGCThreads=" + workerThreads,
  111.50 +                                                              "-version");
  111.51 +
  111.52 +    OutputAnalyzer output = new OutputAnalyzer(pb.start());
  111.53 +
  111.54 +    // check output to contain the string "Concurrent RS threads times (s)" followed by
  111.55 +    // the correct number of values in the next line.
  111.56 +
  111.57 +    // a zero in refinement thread numbers indicates that the value in ParallelGCThreads should be used.
  111.58 +    // Additionally use at least one thread.
  111.59 +    int expectedNumRefinementThreads = refinementThreads == 0 ? workerThreads : refinementThreads;
  111.60 +    expectedNumRefinementThreads = Math.max(1, expectedNumRefinementThreads);
  111.61 +    // create the pattern made up of n copies of a floating point number pattern
  111.62 +    String numberPattern = String.format("%0" + expectedNumRefinementThreads + "d", 0)
  111.63 +      .replace("0", "\\s+\\d+\\.\\d+");
  111.64 +    String pattern = "Concurrent RS threads times \\(s\\)$" + numberPattern + "$";
  111.65 +    Matcher m = Pattern.compile(pattern, Pattern.MULTILINE).matcher(output.getStdout());
  111.66 +
  111.67 +    if (!m.find()) {
  111.68 +      throw new Exception("Could not find correct output for concurrent RS threads times in stdout," +
  111.69 +        " should match the pattern \"" + pattern + "\", but stdout is \n" + output.getStdout());
  111.70 +    }
  111.71 +    output.shouldHaveExitValue(0);
  111.72 +  }
  111.73 +
  111.74 +  public static void main(String[] args) throws Exception {
  111.75 +    if (!TestSummarizeRSetStatsTools.testingG1GC()) {
  111.76 +      return;
  111.77 +    }
  111.78 +    // different valid combinations of number of refinement and gc worker threads
  111.79 +    runTest(0, 0);
  111.80 +    runTest(0, 5);
  111.81 +    runTest(5, 0);
  111.82 +    runTest(10, 10);
  111.83 +    runTest(1, 2);
  111.84 +    runTest(4, 3);
  111.85 +  }
  111.86 +}
   112.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   112.2 +++ b/test/gc/g1/TestSummarizeRSetStatsTools.java	Fri Oct 04 21:00:43 2013 -0700
   112.3 @@ -0,0 +1,154 @@
   112.4 +/*
   112.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
   112.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   112.7 + *
   112.8 + * This code is free software; you can redistribute it and/or modify it
   112.9 + * under the terms of the GNU General Public License version 2 only, as
  112.10 + * published by the Free Software Foundation.
  112.11 + *
  112.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  112.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  112.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  112.15 + * version 2 for more details (a copy is included in the LICENSE file that
  112.16 + * accompanied this code).
  112.17 + *
  112.18 + * You should have received a copy of the GNU General Public License version
  112.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  112.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  112.21 + *
  112.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  112.23 + * or visit www.oracle.com if you need additional information or have any
  112.24 + * questions.
  112.25 + */
  112.26 +
  112.27 +/*
  112.28 + * Common helpers for TestSummarizeRSetStats* tests
  112.29 + */
  112.30 +
  112.31 +import sun.management.ManagementFactoryHelper;
  112.32 +import com.sun.management.HotSpotDiagnosticMXBean;
  112.33 +import com.sun.management.VMOption;
  112.34 +
  112.35 +import com.oracle.java.testlibrary.*;
  112.36 +import java.util.regex.Matcher;
  112.37 +import java.util.regex.Pattern;
  112.38 +import java.lang.Thread;
  112.39 +import java.util.ArrayList;
  112.40 +import java.util.Arrays;
  112.41 +
  112.42 +class VerifySummaryOutput {
  112.43 +    // 4M size, both are directly allocated into the old gen
  112.44 +    static Object[] largeObject1 = new Object[1024 * 1024];
  112.45 +    static Object[] largeObject2 = new Object[1024 * 1024];
  112.46 +
  112.47 +    static int[] temp;
  112.48 +
  112.49 +    public static void main(String[] args) {
  112.50 +        // create some cross-references between these objects
  112.51 +        for (int i = 0; i < largeObject1.length; i++) {
  112.52 +            largeObject1[i] = largeObject2;
  112.53 +        }
  112.54 +
  112.55 +        for (int i = 0; i < largeObject2.length; i++) {
  112.56 +            largeObject2[i] = largeObject1;
  112.57 +        }
  112.58 +
  112.59 +        int numGCs = Integer.parseInt(args[0]);
  112.60 +
  112.61 +        if (numGCs > 0) {
  112.62 +            // try to force a minor collection: the young gen is 4M, the
  112.63 +            // amount of data allocated below is roughly that (4*1024*1024 +
  112.64 +            // some header data)
  112.65 +            for (int i = 0; i < 1024 ; i++) {
  112.66 +                temp = new int[1024];
  112.67 +            }
  112.68 +        }
  112.69 +
  112.70 +        for (int i = 0; i < numGCs - 1; i++) {
  112.71 +            System.gc();
  112.72 +        }
  112.73 +    }
  112.74 +}
  112.75 +
  112.76 +public class TestSummarizeRSetStatsTools {
  112.77 +
  112.78 +    // the VM is currently run using G1GC, i.e. trying to test G1 functionality.
  112.79 +    public static boolean testingG1GC() {
  112.80 +        HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean();
  112.81 +
  112.82 +        VMOption option = diagnostic.getVMOption("UseG1GC");
  112.83 +        if (option.getValue().equals("false")) {
  112.84 +          System.out.println("Skipping this test. It is only a G1 test.");
  112.85 +          return false;
  112.86 +        }
  112.87 +        return true;
  112.88 +    }
  112.89 +
  112.90 +    public static String runTest(String[] additionalArgs, int numGCs) throws Exception {
  112.91 +        ArrayList<String> finalargs = new ArrayList<String>();
  112.92 +        String[] defaultArgs = new String[] {
  112.93 +            "-XX:+UseG1GC",
  112.94 +            "-XX:+UseCompressedOops",
  112.95 +            "-Xmn4m",
  112.96 +            "-Xmx20m",
  112.97 +            "-XX:InitiatingHeapOccupancyPercent=100", // we don't want the additional GCs due to initial marking
  112.98 +            "-XX:+PrintGC",
  112.99 +            "-XX:+UnlockDiagnosticVMOptions",
 112.100 +            "-XX:G1HeapRegionSize=1M",
 112.101 +        };
 112.102 +
 112.103 +        finalargs.addAll(Arrays.asList(defaultArgs));
 112.104 +
 112.105 +        if (additionalArgs != null) {
 112.106 +            finalargs.addAll(Arrays.asList(additionalArgs));
 112.107 +        }
 112.108 +
 112.109 +        finalargs.add(VerifySummaryOutput.class.getName());
 112.110 +        finalargs.add(String.valueOf(numGCs));
 112.111 +
 112.112 +        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
 112.113 +            finalargs.toArray(new String[0]));
 112.114 +        OutputAnalyzer output = new OutputAnalyzer(pb.start());
 112.115 +
 112.116 +        output.shouldHaveExitValue(0);
 112.117 +
 112.118 +        String result = output.getStdout();
 112.119 +        return result;
 112.120 +    }
 112.121 +
 112.122 +    private static void checkCounts(int expected, int actual, String which) throws Exception {
 112.123 +        if (expected != actual) {
 112.124 +            throw new Exception("RSet summaries mention " + which + " regions an incorrect number of times. Expected " + expected + ", got " + actual);
 112.125 +        }
 112.126 +    }
 112.127 +
 112.128 +    public static void expectPerRegionRSetSummaries(String result, int expectedCumulative, int expectedPeriodic) throws Exception {
 112.129 +        expectRSetSummaries(result, expectedCumulative, expectedPeriodic);
 112.130 +        int actualYoung = result.split("Young regions").length - 1;
 112.131 +        int actualHumonguous = result.split("Humonguous regions").length - 1;
 112.132 +        int actualFree = result.split("Free regions").length - 1;
 112.133 +        int actualOther = result.split("Old regions").length - 1;
 112.134 +
 112.135 +        // the strings we check for above are printed four times per summary
 112.136 +        int expectedPerRegionTypeInfo = (expectedCumulative + expectedPeriodic) * 4;
 112.137 +
 112.138 +        checkCounts(expectedPerRegionTypeInfo, actualYoung, "Young");
 112.139 +        checkCounts(expectedPerRegionTypeInfo, actualHumonguous, "Humonguous");
 112.140 +        checkCounts(expectedPerRegionTypeInfo, actualFree, "Free");
 112.141 +        checkCounts(expectedPerRegionTypeInfo, actualOther, "Old");
 112.142 +    }
 112.143 +
 112.144 +    public static void expectRSetSummaries(String result, int expectedCumulative, int expectedPeriodic) throws Exception {
 112.145 +        int actualTotal = result.split("concurrent refinement").length - 1;
 112.146 +        int actualCumulative = result.split("Cumulative RS summary").length - 1;
 112.147 +
 112.148 +        if (expectedCumulative != actualCumulative) {
 112.149 +            throw new Exception("Incorrect amount of RSet summaries at the end. Expected " + expectedCumulative + ", got " + actualCumulative);
 112.150 +        }
 112.151 +
 112.152 +        if (expectedPeriodic != (actualTotal - actualCumulative)) {
 112.153 +            throw new Exception("Incorrect amount of per-period RSet summaries at the end. Expected " + expectedPeriodic + ", got " + (actualTotal - actualCumulative));
 112.154 +        }
 112.155 +    }
 112.156 +}
 112.157 +
   113.1 --- a/test/gc/metaspace/G1AddMetaspaceDependency.java	Sat Oct 05 03:14:53 2013 +0200
   113.2 +++ b/test/gc/metaspace/G1AddMetaspaceDependency.java	Fri Oct 04 21:00:43 2013 -0700
   113.3 @@ -107,7 +107,6 @@
   113.4      Loader f_loader = new Loader(b_name, b_bytes, a_name, a_loader);
   113.5      Loader g_loader = new Loader(b_name, b_bytes, a_name, a_loader);
   113.6  
   113.7 -    byte[] b = new byte[20 * 2 << 20];
   113.8      Class<?> c;
   113.9      c = b_loader.loadClass(b_name);
  113.10      c = c_loader.loadClass(b_name);
   114.1 --- a/test/gc/metaspace/TestPerfCountersAndMemoryPools.java	Sat Oct 05 03:14:53 2013 +0200
   114.2 +++ b/test/gc/metaspace/TestPerfCountersAndMemoryPools.java	Fri Oct 04 21:00:43 2013 -0700
   114.3 @@ -29,10 +29,11 @@
   114.4  
   114.5  /* @test TestPerfCountersAndMemoryPools
   114.6   * @bug 8023476
   114.7 + * @library /testlibrary
   114.8   * @summary Tests that a MemoryPoolMXBeans and PerfCounters for metaspace
   114.9   *          report the same data.
  114.10 - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedKlassPointers -XX:+UseSerialGC -XX:+UsePerfData TestPerfCountersAndMemoryPools
  114.11 - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:+UseSerialGC -XX:+UsePerfData TestPerfCountersAndMemoryPools
  114.12 + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedKlassPointers -XX:+UseSerialGC -XX:+UsePerfData -Xint TestPerfCountersAndMemoryPools
  114.13 + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:+UseSerialGC -XX:+UsePerfData -Xint TestPerfCountersAndMemoryPools
  114.14   */
  114.15  public class TestPerfCountersAndMemoryPools {
  114.16      public static void main(String[] args) throws Exception {
  114.17 @@ -43,11 +44,11 @@
  114.18          }
  114.19      }
  114.20  
  114.21 -    private static MemoryUsage getMemoryUsage(String memoryPoolName) {
  114.22 +    private static MemoryPoolMXBean getMemoryPool(String memoryPoolName) {
  114.23          List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();
  114.24          for (MemoryPoolMXBean pool : pools) {
  114.25              if (pool.getName().equals(memoryPoolName)) {
  114.26 -                return pool.getUsage();
  114.27 +                return pool;
  114.28              }
  114.29          }
  114.30  
  114.31 @@ -57,19 +58,18 @@
  114.32  
  114.33      private static void checkMemoryUsage(String memoryPoolName, String perfNS)
  114.34          throws Exception {
  114.35 -        // Need to do a gc before each comparison to update the perf counters
  114.36 +        MemoryPoolMXBean pool = getMemoryPool(memoryPoolName);
  114.37  
  114.38 +        // Must do a GC to update performance counters
  114.39          System.gc();
  114.40 -        MemoryUsage mu = getMemoryUsage(memoryPoolName);
  114.41 -        assertEQ(getMinCapacity(perfNS), mu.getInit());
  114.42 +        assertEQ(getMinCapacity(perfNS), pool.getUsage().getInit());
  114.43  
  114.44 +        // Must do a second GC to update the perfomance counters again, since
  114.45 +        // the call pool.getUsage().getInit() could have allocated some
  114.46 +        // metadata.
  114.47          System.gc();
  114.48 -        mu = getMemoryUsage(memoryPoolName);
  114.49 -        assertEQ(getUsed(perfNS), mu.getUsed());
  114.50 -
  114.51 -        System.gc();
  114.52 -        mu = getMemoryUsage(memoryPoolName);
  114.53 -        assertEQ(getCapacity(perfNS), mu.getCommitted());
  114.54 +        assertEQ(getUsed(perfNS), pool.getUsage().getUsed());
  114.55 +        assertEQ(getCapacity(perfNS), pool.getUsage().getCommitted());
  114.56      }
  114.57  
  114.58      private static long getMinCapacity(String ns) throws Exception {
   115.1 --- a/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java	Sat Oct 05 03:14:53 2013 +0200
   115.2 +++ b/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java	Fri Oct 04 21:00:43 2013 -0700
   115.3 @@ -36,8 +36,7 @@
   115.4  import java.nio.file.attribute.*;
   115.5  
   115.6  /**
   115.7 - * * Handler for dirs containing classes to compile.
   115.8 - * @author igor.ignatyev@oracle.com
   115.9 + * Handler for dirs containing classes to compile.
  115.10   */
  115.11  public class ClassPathDirEntry extends PathHandler {
  115.12  
   116.1 --- a/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java	Sat Oct 05 03:14:53 2013 +0200
   116.2 +++ b/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java	Fri Oct 04 21:00:43 2013 -0700
   116.3 @@ -35,7 +35,6 @@
   116.4  
   116.5  /**
   116.6   * Handler for jar-files containing classes to compile.
   116.7 - * @author igor.ignatyev@oracle.com
   116.8   */
   116.9  public class ClassPathJarEntry extends PathHandler {
  116.10  
   117.1 --- a/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java	Sat Oct 05 03:14:53 2013 +0200
   117.2 +++ b/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java	Fri Oct 04 21:00:43 2013 -0700
   117.3 @@ -31,8 +31,6 @@
   117.4  
   117.5  /**
   117.6   * Handler for dirs containing jar-files with classes to compile.
   117.7 - *
   117.8 - * @author igor.ignatyev@oracle.com
   117.9   */
  117.10  public class ClassPathJarInDirEntry extends PathHandler {
  117.11  
   118.1 --- a/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java	Sat Oct 05 03:14:53 2013 +0200
   118.2 +++ b/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java	Fri Oct 04 21:00:43 2013 -0700
   118.3 @@ -32,8 +32,6 @@
   118.4  
   118.5  /**
   118.6   * Handler for files containing a list of classes to compile.
   118.7 - *
   118.8 - * @author igor.ignatyev@oracle.com
   118.9   */
  118.10  public class ClassesListInFile extends PathHandler {
  118.11      public ClassesListInFile(Path root, Executor executor) {
   119.1 --- a/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java	Sat Oct 05 03:14:53 2013 +0200
   119.2 +++ b/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java	Fri Oct 04 21:00:43 2013 -0700
   119.3 @@ -32,9 +32,6 @@
   119.4  import java.util.List;
   119.5  import java.util.concurrent.*;
   119.6  
   119.7 -/**
   119.8 - * @author igor.ignatyev@oracle.com
   119.9 - */
  119.10  public class CompileTheWorld {
  119.11      /**
  119.12       * Entry point. Compiles classes in {@code args}, or all classes in
   120.1 --- a/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java	Sat Oct 05 03:14:53 2013 +0200
   120.2 +++ b/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java	Fri Oct 04 21:00:43 2013 -0700
   120.3 @@ -36,8 +36,6 @@
   120.4  /**
   120.5   * Provide method to compile whole class.
   120.6   * Also contains compiled methods and classes counters.
   120.7 - *
   120.8 - * @author igor.ignatyev@oracle.com
   120.9   */
  120.10  public class Compiler {
  120.11      private Compiler() { }
   121.1 --- a/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java	Sat Oct 05 03:14:53 2013 +0200
   121.2 +++ b/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java	Fri Oct 04 21:00:43 2013 -0700
   121.3 @@ -35,10 +35,7 @@
   121.4  
   121.5  /**
   121.6   * Abstract handler for path.
   121.7 - * <p/>
   121.8   * Concrete subclasses should implement method {@link #process()}.
   121.9 - *
  121.10 - * @author igor.ignatyev@oracle.com
  121.11   */
  121.12  public abstract class PathHandler {
  121.13      private static final Pattern JAR_IN_DIR_PATTERN
   122.1 --- a/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java	Sat Oct 05 03:14:53 2013 +0200
   122.2 +++ b/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java	Fri Oct 04 21:00:43 2013 -0700
   122.3 @@ -31,8 +31,6 @@
   122.4  
   122.5  /**
   122.6   * Auxiliary methods.
   122.7 - *
   122.8 - * @author igor.ignatyev@oracle.com
   122.9   */
  122.10  public class Utils {
  122.11      /**

mercurial