Merge

Thu, 03 Oct 2013 16:38:21 +0400

author
iveresov
date
Thu, 03 Oct 2013 16:38:21 +0400
changeset 5802
268e7a2178d7
parent 5789
31f0118ea584
parent 5801
cacc4c6bfc80
child 5806
100614790c1e

Merge

src/cpu/x86/vm/methodHandles_x86.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/x86_32.ad file | annotate | diff | comparison | revisions
src/cpu/x86/vm/x86_64.ad file | annotate | diff | comparison | revisions
src/share/vm/classfile/classFileParser.cpp file | annotate | diff | comparison | revisions
src/share/vm/classfile/defaultMethods.cpp file | annotate | diff | comparison | revisions
src/share/vm/code/nmethod.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/safepoint.cpp file | annotate | diff | comparison | revisions
src/share/vm/services/classLoadingService.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/agent/src/os/linux/LinuxDebuggerLocal.c	Tue Oct 01 11:06:35 2013 -0400
     1.2 +++ b/agent/src/os/linux/LinuxDebuggerLocal.c	Thu Oct 03 16:38:21 2013 +0400
     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	Tue Oct 01 11:06:35 2013 -0400
     2.2 +++ b/agent/src/os/linux/ps_proc.c	Thu Oct 03 16:38:21 2013 +0400
     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	Tue Oct 01 11:06:35 2013 -0400
     3.2 +++ b/agent/src/os/linux/salibelf.c	Thu Oct 03 16:38:21 2013 +0400
     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	Tue Oct 01 11:06:35 2013 -0400
     4.2 +++ b/agent/src/os/linux/symtab.c	Thu Oct 03 16:38:21 2013 +0400
     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	Tue Oct 01 11:06:35 2013 -0400
     5.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java	Thu Oct 03 16:38:21 2013 +0400
     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	Tue Oct 01 11:06:35 2013 -0400
     6.2 +++ b/make/bsd/makefiles/gcc.make	Thu Oct 03 16:38:21 2013 +0400
     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	Tue Oct 01 11:06:35 2013 -0400
     7.2 +++ b/make/linux/makefiles/gcc.make	Thu Oct 03 16:38:21 2013 +0400
     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	Tue Oct 01 11:06:35 2013 -0400
     8.2 +++ b/src/cpu/sparc/vm/methodHandles_sparc.cpp	Thu Oct 03 16:38:21 2013 +0400
     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	Tue Oct 01 11:06:35 2013 -0400
     9.2 +++ b/src/cpu/sparc/vm/sparc.ad	Thu Oct 03 16:38:21 2013 +0400
     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	Tue Oct 01 11:06:35 2013 -0400
    10.2 +++ b/src/cpu/x86/vm/assembler_x86.cpp	Thu Oct 03 16:38:21 2013 +0400
    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	Tue Oct 01 11:06:35 2013 -0400
    11.2 +++ b/src/cpu/x86/vm/methodHandles_x86.cpp	Thu Oct 03 16:38:21 2013 +0400
    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	Tue Oct 01 11:06:35 2013 -0400
    12.2 +++ b/src/cpu/x86/vm/x86_32.ad	Thu Oct 03 16:38:21 2013 +0400
    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	Tue Oct 01 11:06:35 2013 -0400
    13.2 +++ b/src/cpu/x86/vm/x86_64.ad	Thu Oct 03 16:38:21 2013 +0400
    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	Tue Oct 01 11:06:35 2013 -0400
    14.2 +++ b/src/share/vm/adlc/adlparse.cpp	Thu Oct 03 16:38:21 2013 +0400
    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	Tue Oct 01 11:06:35 2013 -0400
    15.2 +++ b/src/share/vm/adlc/archDesc.cpp	Thu Oct 03 16:38:21 2013 +0400
    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	Tue Oct 01 11:06:35 2013 -0400
    16.2 +++ b/src/share/vm/adlc/formssel.cpp	Thu Oct 03 16:38:21 2013 +0400
    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	Tue Oct 01 11:06:35 2013 -0400
    17.2 +++ b/src/share/vm/adlc/formssel.hpp	Thu Oct 03 16:38:21 2013 +0400
    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	Tue Oct 01 11:06:35 2013 -0400
    18.2 +++ b/src/share/vm/adlc/output_h.cpp	Thu Oct 03 16:38:21 2013 +0400
    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/classfile/classFileParser.cpp	Tue Oct 01 11:06:35 2013 -0400
    19.2 +++ b/src/share/vm/classfile/classFileParser.cpp	Thu Oct 03 16:38:21 2013 +0400
    19.3 @@ -1787,7 +1787,7 @@
    19.4      if (_location != _in_method)  break;  // only allow for methods
    19.5      if (!privileged)              break;  // only allow in privileged code
    19.6      return _method_LambdaForm_Hidden;
    19.7 -  case vmSymbols::VM_SYMBOL_ENUM_NAME(sun_invoke_Stable_signature):
    19.8 +  case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_Stable_signature):
    19.9      if (_location != _in_field)   break;  // only allow for fields
   19.10      if (!privileged)              break;  // only allow in privileged code
   19.11      return _field_Stable;
    20.1 --- a/src/share/vm/classfile/defaultMethods.cpp	Tue Oct 01 11:06:35 2013 -0400
    20.2 +++ b/src/share/vm/classfile/defaultMethods.cpp	Thu Oct 03 16:38:21 2013 +0400
    20.3 @@ -793,7 +793,7 @@
    20.4  
    20.5  
    20.6  
    20.7 -#ifndef PRODUCT
    20.8 +#ifdef ASSERT
    20.9  // Return true is broad type is a covariant return of narrow type
   20.10  static bool covariant_return_type(BasicType narrow, BasicType broad) {
   20.11    if (narrow == broad) {
   20.12 @@ -804,7 +804,7 @@
   20.13    }
   20.14    return false;
   20.15  }
   20.16 -#endif // ndef PRODUCT
   20.17 +#endif
   20.18  
   20.19  static int assemble_redirect(
   20.20      BytecodeConstantPool* cp, BytecodeBuffer* buffer,
   20.21 @@ -1095,4 +1095,3 @@
   20.22      MetadataFactory::free_array(cld, original_ordering);
   20.23    }
   20.24  }
   20.25 -
    21.1 --- a/src/share/vm/classfile/vmSymbols.hpp	Tue Oct 01 11:06:35 2013 -0400
    21.2 +++ b/src/share/vm/classfile/vmSymbols.hpp	Thu Oct 03 16:38:21 2013 +0400
    21.3 @@ -270,7 +270,7 @@
    21.4    template(java_lang_invoke_LambdaForm,               "java/lang/invoke/LambdaForm")              \
    21.5    template(java_lang_invoke_ForceInline_signature,    "Ljava/lang/invoke/ForceInline;")           \
    21.6    template(java_lang_invoke_DontInline_signature,     "Ljava/lang/invoke/DontInline;")            \
    21.7 -  template(sun_invoke_Stable_signature,               "Lsun/invoke/Stable;")                      \
    21.8 +  template(java_lang_invoke_Stable_signature,         "Ljava/lang/invoke/Stable;")                \
    21.9    template(java_lang_invoke_LambdaForm_Compiled_signature, "Ljava/lang/invoke/LambdaForm$Compiled;") \
   21.10    template(java_lang_invoke_LambdaForm_Hidden_signature, "Ljava/lang/invoke/LambdaForm$Hidden;")  \
   21.11    template(java_lang_invoke_MagicLambdaImpl,          "java/lang/invoke/MagicLambdaImpl")         \
   21.12 @@ -631,6 +631,10 @@
   21.13    do_name(log_name,"log")       do_name(log10_name,"log10")     do_name(pow_name,"pow")                                 \
   21.14    do_name(exp_name,"exp")       do_name(min_name,"min")         do_name(max_name,"max")                                 \
   21.15                                                                                                                          \
   21.16 +  do_name(addExact_name,"addExact")                                                                                     \
   21.17 +  do_name(subtractExact_name,"subtractExact")                                                                           \
   21.18 +  do_name(multiplyExact_name,"multiplyExact")                                                                           \
   21.19 +                                                                                                                        \
   21.20    do_intrinsic(_dabs,                     java_lang_Math,         abs_name,   double_double_signature,           F_S)   \
   21.21    do_intrinsic(_dsin,                     java_lang_Math,         sin_name,   double_double_signature,           F_S)   \
   21.22    do_intrinsic(_dcos,                     java_lang_Math,         cos_name,   double_double_signature,           F_S)   \
   21.23 @@ -643,6 +647,7 @@
   21.24    do_intrinsic(_dexp,                     java_lang_Math,         exp_name,   double_double_signature,           F_S)   \
   21.25    do_intrinsic(_min,                      java_lang_Math,         min_name,   int2_int_signature,                F_S)   \
   21.26    do_intrinsic(_max,                      java_lang_Math,         max_name,   int2_int_signature,                F_S)   \
   21.27 +  do_intrinsic(_addExact,                 java_lang_Math,         addExact_name, int2_int_signature,             F_S)   \
   21.28                                                                                                                          \
   21.29    do_intrinsic(_floatToRawIntBits,        java_lang_Float,        floatToRawIntBits_name,   float_int_signature, F_S)   \
   21.30     do_name(     floatToRawIntBits_name,                          "floatToRawIntBits")                                   \
    22.1 --- a/src/share/vm/code/codeCache.cpp	Tue Oct 01 11:06:35 2013 -0400
    22.2 +++ b/src/share/vm/code/codeCache.cpp	Thu Oct 03 16:38:21 2013 +0400
    22.3 @@ -124,7 +124,6 @@
    22.4  int CodeCache::_number_of_nmethods_with_dependencies = 0;
    22.5  bool CodeCache::_needs_cache_clean = false;
    22.6  nmethod* CodeCache::_scavenge_root_nmethods = NULL;
    22.7 -nmethod* CodeCache::_saved_nmethods = NULL;
    22.8  
    22.9  int CodeCache::_codemem_full_count = 0;
   22.10  
   22.11 @@ -464,96 +463,11 @@
   22.12  }
   22.13  #endif //PRODUCT
   22.14  
   22.15 -/**
   22.16 - * Remove and return nmethod from the saved code list in order to reanimate it.
   22.17 - */
   22.18 -nmethod* CodeCache::reanimate_saved_code(Method* m) {
   22.19 -  MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   22.20 -  nmethod* saved = _saved_nmethods;
   22.21 -  nmethod* prev = NULL;
   22.22 -  while (saved != NULL) {
   22.23 -    if (saved->is_in_use() && saved->method() == m) {
   22.24 -      if (prev != NULL) {
   22.25 -        prev->set_saved_nmethod_link(saved->saved_nmethod_link());
   22.26 -      } else {
   22.27 -        _saved_nmethods = saved->saved_nmethod_link();
   22.28 -      }
   22.29 -      assert(saved->is_speculatively_disconnected(), "shouldn't call for other nmethods");
   22.30 -      saved->set_speculatively_disconnected(false);
   22.31 -      saved->set_saved_nmethod_link(NULL);
   22.32 -      if (PrintMethodFlushing) {
   22.33 -        saved->print_on(tty, " ### nmethod is reconnected");
   22.34 -      }
   22.35 -      if (LogCompilation && (xtty != NULL)) {
   22.36 -        ttyLocker ttyl;
   22.37 -        xtty->begin_elem("nmethod_reconnected compile_id='%3d'", saved->compile_id());
   22.38 -        xtty->method(m);
   22.39 -        xtty->stamp();
   22.40 -        xtty->end_elem();
   22.41 -      }
   22.42 -      return saved;
   22.43 -    }
   22.44 -    prev = saved;
   22.45 -    saved = saved->saved_nmethod_link();
   22.46 -  }
   22.47 -  return NULL;
   22.48 -}
   22.49 -
   22.50 -/**
   22.51 - * Remove nmethod from the saved code list in order to discard it permanently
   22.52 - */
   22.53 -void CodeCache::remove_saved_code(nmethod* nm) {
   22.54 -  // For conc swpr this will be called with CodeCache_lock taken by caller
   22.55 -  assert_locked_or_safepoint(CodeCache_lock);
   22.56 -  assert(nm->is_speculatively_disconnected(), "shouldn't call for other nmethods");
   22.57 -  nmethod* saved = _saved_nmethods;
   22.58 -  nmethod* prev = NULL;
   22.59 -  while (saved != NULL) {
   22.60 -    if (saved == nm) {
   22.61 -      if (prev != NULL) {
   22.62 -        prev->set_saved_nmethod_link(saved->saved_nmethod_link());
   22.63 -      } else {
   22.64 -        _saved_nmethods = saved->saved_nmethod_link();
   22.65 -      }
   22.66 -      if (LogCompilation && (xtty != NULL)) {
   22.67 -        ttyLocker ttyl;
   22.68 -        xtty->begin_elem("nmethod_removed compile_id='%3d'", nm->compile_id());
   22.69 -        xtty->stamp();
   22.70 -        xtty->end_elem();
   22.71 -      }
   22.72 -      return;
   22.73 -    }
   22.74 -    prev = saved;
   22.75 -    saved = saved->saved_nmethod_link();
   22.76 -  }
   22.77 -  ShouldNotReachHere();
   22.78 -}
   22.79 -
   22.80 -void CodeCache::speculatively_disconnect(nmethod* nm) {
   22.81 -  assert_locked_or_safepoint(CodeCache_lock);
   22.82 -  assert(nm->is_in_use() && !nm->is_speculatively_disconnected(), "should only disconnect live nmethods");
   22.83 -  nm->set_saved_nmethod_link(_saved_nmethods);
   22.84 -  _saved_nmethods = nm;
   22.85 -  if (PrintMethodFlushing) {
   22.86 -    nm->print_on(tty, " ### nmethod is speculatively disconnected");
   22.87 -  }
   22.88 -  if (LogCompilation && (xtty != NULL)) {
   22.89 -    ttyLocker ttyl;
   22.90 -    xtty->begin_elem("nmethod_disconnected compile_id='%3d'", nm->compile_id());
   22.91 -    xtty->method(nm->method());
   22.92 -    xtty->stamp();
   22.93 -    xtty->end_elem();
   22.94 -  }
   22.95 -  nm->method()->clear_code();
   22.96 -  nm->set_speculatively_disconnected(true);
   22.97 -}
   22.98 -
   22.99  
  22.100  void CodeCache::gc_prologue() {
  22.101    assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_epilogue must be called");
  22.102  }
  22.103  
  22.104 -
  22.105  void CodeCache::gc_epilogue() {
  22.106    assert_locked_or_safepoint(CodeCache_lock);
  22.107    FOR_ALL_ALIVE_BLOBS(cb) {
    23.1 --- a/src/share/vm/code/codeCache.hpp	Tue Oct 01 11:06:35 2013 -0400
    23.2 +++ b/src/share/vm/code/codeCache.hpp	Thu Oct 03 16:38:21 2013 +0400
    23.3 @@ -57,7 +57,6 @@
    23.4    static int _number_of_nmethods_with_dependencies;
    23.5    static bool _needs_cache_clean;
    23.6    static nmethod* _scavenge_root_nmethods;  // linked via nm->scavenge_root_link()
    23.7 -  static nmethod* _saved_nmethods;          // Linked list of speculatively disconnected nmethods.
    23.8  
    23.9    static void verify_if_often() PRODUCT_RETURN;
   23.10  
   23.11 @@ -167,17 +166,12 @@
   23.12    static size_t  capacity()                      { return _heap->capacity(); }
   23.13    static size_t  max_capacity()                  { return _heap->max_capacity(); }
   23.14    static size_t  unallocated_capacity()          { return _heap->unallocated_capacity(); }
   23.15 -  static bool    needs_flushing()                { return unallocated_capacity() < CodeCacheFlushingMinimumFreeSpace; }
   23.16    static double  reverse_free_ratio();
   23.17  
   23.18    static bool needs_cache_clean()                { return _needs_cache_clean; }
   23.19    static void set_needs_cache_clean(bool v)      { _needs_cache_clean = v;    }
   23.20    static void clear_inline_caches();             // clear all inline caches
   23.21  
   23.22 -  static nmethod* reanimate_saved_code(Method* m);
   23.23 -  static void remove_saved_code(nmethod* nm);
   23.24 -  static void speculatively_disconnect(nmethod* nm);
   23.25 -
   23.26    // Deoptimization
   23.27    static int  mark_for_deoptimization(DepChange& changes);
   23.28  #ifdef HOTSWAP
    24.1 --- a/src/share/vm/code/nmethod.cpp	Tue Oct 01 11:06:35 2013 -0400
    24.2 +++ b/src/share/vm/code/nmethod.cpp	Thu Oct 03 16:38:21 2013 +0400
    24.3 @@ -462,7 +462,6 @@
    24.4    _state                      = alive;
    24.5    _marked_for_reclamation     = 0;
    24.6    _has_flushed_dependencies   = 0;
    24.7 -  _speculatively_disconnected = 0;
    24.8    _has_unsafe_access          = 0;
    24.9    _has_method_handle_invokes  = 0;
   24.10    _lazy_critical_native       = 0;
   24.11 @@ -481,7 +480,6 @@
   24.12    _osr_link                = NULL;
   24.13    _scavenge_root_link      = NULL;
   24.14    _scavenge_root_state     = 0;
   24.15 -  _saved_nmethod_link      = NULL;
   24.16    _compiler                = NULL;
   24.17  
   24.18  #ifdef HAVE_DTRACE_H
   24.19 @@ -686,6 +684,7 @@
   24.20      _osr_entry_point         = NULL;
   24.21      _exception_cache         = NULL;
   24.22      _pc_desc_cache.reset_to(NULL);
   24.23 +    _hotness_counter         = NMethodSweeper::hotness_counter_reset_val();
   24.24  
   24.25      code_buffer->copy_values_to(this);
   24.26      if (ScavengeRootsInCode && detect_scavenge_root_oops()) {
   24.27 @@ -770,6 +769,7 @@
   24.28      _osr_entry_point         = NULL;
   24.29      _exception_cache         = NULL;
   24.30      _pc_desc_cache.reset_to(NULL);
   24.31 +    _hotness_counter         = NMethodSweeper::hotness_counter_reset_val();
   24.32  
   24.33      code_buffer->copy_values_to(this);
   24.34      debug_only(verify_scavenge_root_oops());
   24.35 @@ -842,6 +842,7 @@
   24.36      _comp_level              = comp_level;
   24.37      _compiler                = compiler;
   24.38      _orig_pc_offset          = orig_pc_offset;
   24.39 +    _hotness_counter         = NMethodSweeper::hotness_counter_reset_val();
   24.40  
   24.41      // Section offsets
   24.42      _consts_offset           = content_offset()      + code_buffer->total_offset_of(code_buffer->consts());
   24.43 @@ -1176,7 +1177,7 @@
   24.44  
   24.45  // This is a private interface with the sweeper.
   24.46  void nmethod::mark_as_seen_on_stack() {
   24.47 -  assert(is_not_entrant(), "must be a non-entrant method");
   24.48 +  assert(is_alive(), "Must be an alive method");
   24.49    // Set the traversal mark to ensure that the sweeper does 2
   24.50    // cleaning passes before moving to zombie.
   24.51    set_stack_traversal_mark(NMethodSweeper::traversal_count());
   24.52 @@ -1261,7 +1262,7 @@
   24.53  
   24.54    set_osr_link(NULL);
   24.55    //set_scavenge_root_link(NULL); // done by prune_scavenge_root_nmethods
   24.56 -  NMethodSweeper::notify(this);
   24.57 +  NMethodSweeper::notify();
   24.58  }
   24.59  
   24.60  void nmethod::invalidate_osr_method() {
   24.61 @@ -1351,6 +1352,15 @@
   24.62        nmethod_needs_unregister = true;
   24.63      }
   24.64  
   24.65 +    // Must happen before state change. Otherwise we have a race condition in
   24.66 +    // nmethod::can_not_entrant_be_converted(). I.e., a method can immediately
   24.67 +    // transition its state from 'not_entrant' to 'zombie' without having to wait
   24.68 +    // for stack scanning.
   24.69 +    if (state == not_entrant) {
   24.70 +      mark_as_seen_on_stack();
   24.71 +      OrderAccess::storestore();
   24.72 +    }
   24.73 +
   24.74      // Change state
   24.75      _state = state;
   24.76  
   24.77 @@ -1369,11 +1379,6 @@
   24.78        HandleMark hm;
   24.79        method()->clear_code();
   24.80      }
   24.81 -
   24.82 -    if (state == not_entrant) {
   24.83 -      mark_as_seen_on_stack();
   24.84 -    }
   24.85 -
   24.86    } // leave critical region under Patching_lock
   24.87  
   24.88    // When the nmethod becomes zombie it is no longer alive so the
   24.89 @@ -1416,7 +1421,7 @@
   24.90    }
   24.91  
   24.92    // Make sweeper aware that there is a zombie method that needs to be removed
   24.93 -  NMethodSweeper::notify(this);
   24.94 +  NMethodSweeper::notify();
   24.95  
   24.96    return true;
   24.97  }
   24.98 @@ -1451,10 +1456,6 @@
   24.99      CodeCache::drop_scavenge_root_nmethod(this);
  24.100    }
  24.101  
  24.102 -  if (is_speculatively_disconnected()) {
  24.103 -    CodeCache::remove_saved_code(this);
  24.104 -  }
  24.105 -
  24.106  #ifdef SHARK
  24.107    ((SharkCompiler *) compiler())->free_compiled_method(insts_begin());
  24.108  #endif // SHARK
    25.1 --- a/src/share/vm/code/nmethod.hpp	Tue Oct 01 11:06:35 2013 -0400
    25.2 +++ b/src/share/vm/code/nmethod.hpp	Thu Oct 03 16:38:21 2013 +0400
    25.3 @@ -119,7 +119,6 @@
    25.4    // To support simple linked-list chaining of nmethods:
    25.5    nmethod*  _osr_link;         // from InstanceKlass::osr_nmethods_head
    25.6    nmethod*  _scavenge_root_link; // from CodeCache::scavenge_root_nmethods
    25.7 -  nmethod*  _saved_nmethod_link; // from CodeCache::speculatively_disconnect
    25.8  
    25.9    static nmethod* volatile _oops_do_mark_nmethods;
   25.10    nmethod*        volatile _oops_do_mark_link;
   25.11 @@ -165,7 +164,6 @@
   25.12  
   25.13    // protected by CodeCache_lock
   25.14    bool _has_flushed_dependencies;            // Used for maintenance of dependencies (CodeCache_lock)
   25.15 -  bool _speculatively_disconnected;          // Marked for potential unload
   25.16  
   25.17    bool _marked_for_reclamation;              // Used by NMethodSweeper (set only by sweeper)
   25.18    bool _marked_for_deoptimization;           // Used for stack deoptimization
   25.19 @@ -180,7 +178,7 @@
   25.20    unsigned int _has_wide_vectors:1;          // Preserve wide vectors at safepoints
   25.21  
   25.22    // Protected by Patching_lock
   25.23 -  unsigned char _state;                      // {alive, not_entrant, zombie, unloaded}
   25.24 +  volatile unsigned char _state;             // {alive, not_entrant, zombie, unloaded}
   25.25  
   25.26  #ifdef ASSERT
   25.27    bool _oops_are_stale;  // indicates that it's no longer safe to access oops section
   25.28 @@ -202,11 +200,18 @@
   25.29  
   25.30    // not_entrant method removal. Each mark_sweep pass will update
   25.31    // this mark to current sweep invocation count if it is seen on the
   25.32 -  // stack.  An not_entrant method can be removed when there is no
   25.33 +  // stack.  An not_entrant method can be removed when there are no
   25.34    // more activations, i.e., when the _stack_traversal_mark is less than
   25.35    // current sweep traversal index.
   25.36    long _stack_traversal_mark;
   25.37  
   25.38 +  // The _hotness_counter indicates the hotness of a method. The higher
   25.39 +  // the value the hotter the method. The hotness counter of a nmethod is
   25.40 +  // set to [(ReservedCodeCacheSize / (1024 * 1024)) * 2] each time the method
   25.41 +  // is active while stack scanning (mark_active_nmethods()). The hotness
   25.42 +  // counter is decreased (by 1) while sweeping.
   25.43 +  int _hotness_counter;
   25.44 +
   25.45    ExceptionCache *_exception_cache;
   25.46    PcDescCache     _pc_desc_cache;
   25.47  
   25.48 @@ -382,6 +387,10 @@
   25.49  
   25.50    int total_size        () const;
   25.51  
   25.52 +  void dec_hotness_counter()        { _hotness_counter--; }
   25.53 +  void set_hotness_counter(int val) { _hotness_counter = val; }
   25.54 +  int  hotness_counter() const      { return _hotness_counter; }
   25.55 +
   25.56    // Containment
   25.57    bool consts_contains       (address addr) const { return consts_begin       () <= addr && addr < consts_end       (); }
   25.58    bool insts_contains        (address addr) const { return insts_begin        () <= addr && addr < insts_end        (); }
   25.59 @@ -408,8 +417,8 @@
   25.60    // alive.  It is used when an uncommon trap happens.  Returns true
   25.61    // if this thread changed the state of the nmethod or false if
   25.62    // another thread performed the transition.
   25.63 -  bool  make_not_entrant()                        { return make_not_entrant_or_zombie(not_entrant); }
   25.64 -  bool  make_zombie()                             { return make_not_entrant_or_zombie(zombie); }
   25.65 +  bool  make_not_entrant() { return make_not_entrant_or_zombie(not_entrant); }
   25.66 +  bool  make_zombie()      { return make_not_entrant_or_zombie(zombie); }
   25.67  
   25.68    // used by jvmti to track if the unload event has been reported
   25.69    bool  unload_reported()                         { return _unload_reported; }
   25.70 @@ -437,9 +446,6 @@
   25.71    bool  has_method_handle_invokes() const         { return _has_method_handle_invokes; }
   25.72    void  set_has_method_handle_invokes(bool z)     { _has_method_handle_invokes = z; }
   25.73  
   25.74 -  bool  is_speculatively_disconnected() const     { return _speculatively_disconnected; }
   25.75 -  void  set_speculatively_disconnected(bool z)    { _speculatively_disconnected = z; }
   25.76 -
   25.77    bool  is_lazy_critical_native() const           { return _lazy_critical_native; }
   25.78    void  set_lazy_critical_native(bool z)          { _lazy_critical_native = z; }
   25.79  
   25.80 @@ -499,9 +505,6 @@
   25.81    nmethod* scavenge_root_link() const                  { return _scavenge_root_link; }
   25.82    void     set_scavenge_root_link(nmethod *n)          { _scavenge_root_link = n; }
   25.83  
   25.84 -  nmethod* saved_nmethod_link() const                  { return _saved_nmethod_link; }
   25.85 -  void     set_saved_nmethod_link(nmethod *n)          { _saved_nmethod_link = n; }
   25.86 -
   25.87   public:
   25.88  
   25.89    // Sweeper support
    26.1 --- a/src/share/vm/compiler/compileBroker.cpp	Tue Oct 01 11:06:35 2013 -0400
    26.2 +++ b/src/share/vm/compiler/compileBroker.cpp	Thu Oct 03 16:38:21 2013 +0400
    26.3 @@ -634,19 +634,36 @@
    26.4    NMethodSweeper::possibly_sweep();
    26.5  
    26.6    MutexLocker locker(lock());
    26.7 -  // Wait for an available CompileTask.
    26.8 +  // If _first is NULL we have no more compile jobs. There are two reasons for
    26.9 +  // having no compile jobs: First, we compiled everything we wanted. Second,
   26.10 +  // we ran out of code cache so compilation has been disabled. In the latter
   26.11 +  // case we perform code cache sweeps to free memory such that we can re-enable
   26.12 +  // compilation.
   26.13    while (_first == NULL) {
   26.14 -    // There is no work to be done right now.  Wait.
   26.15 -    if (UseCodeCacheFlushing && (!CompileBroker::should_compile_new_jobs() || CodeCache::needs_flushing())) {
   26.16 -      // During the emergency sweeping periods, wake up and sweep occasionally
   26.17 -      bool timedout = lock()->wait(!Mutex::_no_safepoint_check_flag, NmethodSweepCheckInterval*1000);
   26.18 -      if (timedout) {
   26.19 +    if (UseCodeCacheFlushing && !CompileBroker::should_compile_new_jobs()) {
   26.20 +      // Wait a certain amount of time to possibly do another sweep.
   26.21 +      // We must wait until stack scanning has happened so that we can
   26.22 +      // transition a method's state from 'not_entrant' to 'zombie'.
   26.23 +      long wait_time = NmethodSweepCheckInterval * 1000;
   26.24 +      if (FLAG_IS_DEFAULT(NmethodSweepCheckInterval)) {
   26.25 +        // Only one thread at a time can do sweeping. Scale the
   26.26 +        // wait time according to the number of compiler threads.
   26.27 +        // As a result, the next sweep is likely to happen every 100ms
   26.28 +        // with an arbitrary number of threads that do sweeping.
   26.29 +        wait_time = 100 * CICompilerCount;
   26.30 +      }
   26.31 +      bool timeout = lock()->wait(!Mutex::_no_safepoint_check_flag, wait_time);
   26.32 +      if (timeout) {
   26.33          MutexUnlocker ul(lock());
   26.34 -        // When otherwise not busy, run nmethod sweeping
   26.35          NMethodSweeper::possibly_sweep();
   26.36        }
   26.37      } else {
   26.38 -      // During normal operation no need to wake up on timer
   26.39 +      // If there are no compilation tasks and we can compile new jobs
   26.40 +      // (i.e., there is enough free space in the code cache) there is
   26.41 +      // no need to invoke the sweeper. As a result, the hotness of methods
   26.42 +      // remains unchanged. This behavior is desired, since we want to keep
   26.43 +      // the stable state, i.e., we do not want to evict methods from the
   26.44 +      // code cache if it is unnecessary.
   26.45        lock()->wait();
   26.46      }
   26.47    }
   26.48 @@ -1227,16 +1244,9 @@
   26.49          return method_code;
   26.50        }
   26.51      }
   26.52 -    if (method->is_not_compilable(comp_level)) return NULL;
   26.53 -
   26.54 -    if (UseCodeCacheFlushing) {
   26.55 -      nmethod* saved = CodeCache::reanimate_saved_code(method());
   26.56 -      if (saved != NULL) {
   26.57 -        method->set_code(method, saved);
   26.58 -        return saved;
   26.59 -      }
   26.60 +    if (method->is_not_compilable(comp_level)) {
   26.61 +      return NULL;
   26.62      }
   26.63 -
   26.64    } else {
   26.65      // osr compilation
   26.66  #ifndef TIERED
   26.67 @@ -1585,9 +1595,6 @@
   26.68        if (CodeCache::unallocated_capacity() < CodeCacheMinimumFreeSpace) {
   26.69          // the code cache is really full
   26.70          handle_full_code_cache();
   26.71 -      } else if (UseCodeCacheFlushing && CodeCache::needs_flushing()) {
   26.72 -        // Attempt to start cleaning the code cache while there is still a little headroom
   26.73 -        NMethodSweeper::handle_full_code_cache(false);
   26.74        }
   26.75  
   26.76        CompileTask* task = queue->get();
   26.77 @@ -1943,7 +1950,11 @@
   26.78      }
   26.79  #endif
   26.80      if (UseCodeCacheFlushing) {
   26.81 -      NMethodSweeper::handle_full_code_cache(true);
   26.82 +      // Since code cache is full, immediately stop new compiles
   26.83 +      if (CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation)) {
   26.84 +        NMethodSweeper::log_sweep("disable_compiler");
   26.85 +        NMethodSweeper::possibly_sweep();
   26.86 +      }
   26.87      } else {
   26.88        UseCompiler               = false;
   26.89        AlwaysCompileLoopMethods  = false;
    27.1 --- a/src/share/vm/oops/method.cpp	Tue Oct 01 11:06:35 2013 -0400
    27.2 +++ b/src/share/vm/oops/method.cpp	Thu Oct 03 16:38:21 2013 +0400
    27.3 @@ -901,16 +901,6 @@
    27.4  // This function must not hit a safepoint!
    27.5  address Method::verified_code_entry() {
    27.6    debug_only(No_Safepoint_Verifier nsv;)
    27.7 -  nmethod *code = (nmethod *)OrderAccess::load_ptr_acquire(&_code);
    27.8 -  if (code == NULL && UseCodeCacheFlushing) {
    27.9 -    nmethod *saved_code = CodeCache::reanimate_saved_code(this);
   27.10 -    if (saved_code != NULL) {
   27.11 -      methodHandle method(this);
   27.12 -      assert( ! saved_code->is_osr_method(), "should not get here for osr" );
   27.13 -      set_code( method, saved_code );
   27.14 -    }
   27.15 -  }
   27.16 -
   27.17    assert(_from_compiled_entry != NULL, "must be set");
   27.18    return _from_compiled_entry;
   27.19  }
    28.1 --- a/src/share/vm/opto/c2_globals.hpp	Tue Oct 01 11:06:35 2013 -0400
    28.2 +++ b/src/share/vm/opto/c2_globals.hpp	Thu Oct 03 16:38:21 2013 +0400
    28.3 @@ -636,7 +636,9 @@
    28.4                                                                              \
    28.5    diagnostic(bool, OptimizeExpensiveOps, true,                              \
    28.6            "Find best control for expensive operations")                     \
    28.7 -
    28.8 +                                                                            \
    28.9 +  product(bool, UseMathExactIntrinsics, true,                               \
   28.10 +          "Enables intrinsification of various java.lang.Math funcitons")
   28.11  
   28.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)
   28.13  
    29.1 --- a/src/share/vm/opto/callGenerator.hpp	Tue Oct 01 11:06:35 2013 -0400
    29.2 +++ b/src/share/vm/opto/callGenerator.hpp	Thu Oct 03 16:38:21 2013 +0400
    29.3 @@ -65,6 +65,8 @@
    29.4    virtual bool      is_predicted() const        { return false; }
    29.5    // is_trap: Does not return to the caller.  (E.g., uncommon trap.)
    29.6    virtual bool      is_trap() const             { return false; }
    29.7 +  // does_virtual_dispatch: Should try inlining as normal method first.
    29.8 +  virtual bool      does_virtual_dispatch() const     { return false; }
    29.9  
   29.10    // is_late_inline: supports conversion of call into an inline
   29.11    virtual bool      is_late_inline() const      { return false; }
    30.1 --- a/src/share/vm/opto/classes.cpp	Tue Oct 01 11:06:35 2013 -0400
    30.2 +++ b/src/share/vm/opto/classes.cpp	Thu Oct 03 16:38:21 2013 +0400
    30.3 @@ -32,6 +32,7 @@
    30.4  #include "opto/loopnode.hpp"
    30.5  #include "opto/machnode.hpp"
    30.6  #include "opto/memnode.hpp"
    30.7 +#include "opto/mathexactnode.hpp"
    30.8  #include "opto/mulnode.hpp"
    30.9  #include "opto/multnode.hpp"
   30.10  #include "opto/node.hpp"
    31.1 --- a/src/share/vm/opto/classes.hpp	Tue Oct 01 11:06:35 2013 -0400
    31.2 +++ b/src/share/vm/opto/classes.hpp	Thu Oct 03 16:38:21 2013 +0400
    31.3 @@ -29,6 +29,7 @@
    31.4  macro(AbsF)
    31.5  macro(AbsI)
    31.6  macro(AddD)
    31.7 +macro(AddExactI)
    31.8  macro(AddF)
    31.9  macro(AddI)
   31.10  macro(AddL)
   31.11 @@ -133,6 +134,7 @@
   31.12  macro(ExpD)
   31.13  macro(FastLock)
   31.14  macro(FastUnlock)
   31.15 +macro(FlagsProj)
   31.16  macro(Goto)
   31.17  macro(Halt)
   31.18  macro(If)
   31.19 @@ -167,6 +169,7 @@
   31.20  macro(LoopLimit)
   31.21  macro(Mach)
   31.22  macro(MachProj)
   31.23 +macro(MathExact)
   31.24  macro(MaxI)
   31.25  macro(MemBarAcquire)
   31.26  macro(MemBarAcquireLock)
    32.1 --- a/src/share/vm/opto/doCall.cpp	Tue Oct 01 11:06:35 2013 -0400
    32.2 +++ b/src/share/vm/opto/doCall.cpp	Thu Oct 03 16:38:21 2013 +0400
    32.3 @@ -110,6 +110,7 @@
    32.4    // then we return it as the inlined version of the call.
    32.5    // We do this before the strict f.p. check below because the
    32.6    // intrinsics handle strict f.p. correctly.
    32.7 +  CallGenerator* cg_intrinsic = NULL;
    32.8    if (allow_inline && allow_intrinsics) {
    32.9      CallGenerator* cg = find_intrinsic(callee, call_does_dispatch);
   32.10      if (cg != NULL) {
   32.11 @@ -121,7 +122,16 @@
   32.12            cg = CallGenerator::for_predicted_intrinsic(cg, inline_cg);
   32.13          }
   32.14        }
   32.15 -      return cg;
   32.16 +
   32.17 +      // If intrinsic does the virtual dispatch, we try to use the type profile
   32.18 +      // first, and hopefully inline it as the regular virtual call below.
   32.19 +      // We will retry the intrinsic if nothing had claimed it afterwards.
   32.20 +      if (cg->does_virtual_dispatch()) {
   32.21 +        cg_intrinsic = cg;
   32.22 +        cg = NULL;
   32.23 +      } else {
   32.24 +        return cg;
   32.25 +      }
   32.26      }
   32.27    }
   32.28  
   32.29 @@ -266,6 +276,13 @@
   32.30      }
   32.31    }
   32.32  
   32.33 +  // Nothing claimed the intrinsic, we go with straight-forward inlining
   32.34 +  // for already discovered intrinsic.
   32.35 +  if (allow_inline && allow_intrinsics && cg_intrinsic != NULL) {
   32.36 +    assert(cg_intrinsic->does_virtual_dispatch(), "sanity");
   32.37 +    return cg_intrinsic;
   32.38 +  }
   32.39 +
   32.40    // There was no special inlining tactic, or it bailed out.
   32.41    // Use a more generic tactic, like a simple call.
   32.42    if (call_does_dispatch) {
    33.1 --- a/src/share/vm/opto/graphKit.cpp	Tue Oct 01 11:06:35 2013 -0400
    33.2 +++ b/src/share/vm/opto/graphKit.cpp	Thu Oct 03 16:38:21 2013 +0400
    33.3 @@ -3849,9 +3849,9 @@
    33.4    const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
    33.5                                                       false, NULL, 0);
    33.6    const TypePtr* value_field_type = string_type->add_offset(value_offset);
    33.7 -  int value_field_idx = C->get_alias_index(value_field_type);
    33.8 -  store_to_memory(ctrl, basic_plus_adr(str, value_offset),
    33.9 -                  value, T_OBJECT, value_field_idx);
   33.10 +
   33.11 +  store_oop_to_object(ctrl, str,  basic_plus_adr(str, value_offset), value_field_type,
   33.12 +      value, TypeAryPtr::CHARS, T_OBJECT);
   33.13  }
   33.14  
   33.15  void GraphKit::store_String_length(Node* ctrl, Node* str, Node* value) {
    34.1 --- a/src/share/vm/opto/ifnode.cpp	Tue Oct 01 11:06:35 2013 -0400
    34.2 +++ b/src/share/vm/opto/ifnode.cpp	Thu Oct 03 16:38:21 2013 +0400
    34.3 @@ -76,6 +76,7 @@
    34.4    if( !i1->is_Bool() ) return NULL;
    34.5    BoolNode *b = i1->as_Bool();
    34.6    Node *cmp = b->in(1);
    34.7 +  if( cmp->is_FlagsProj() ) return NULL;
    34.8    if( !cmp->is_Cmp() ) return NULL;
    34.9    i1 = cmp->in(1);
   34.10    if( i1 == NULL || !i1->is_Phi() ) return NULL;
    35.1 --- a/src/share/vm/opto/lcm.cpp	Tue Oct 01 11:06:35 2013 -0400
    35.2 +++ b/src/share/vm/opto/lcm.cpp	Thu Oct 03 16:38:21 2013 +0400
    35.3 @@ -472,6 +472,13 @@
    35.4            break;
    35.5          }
    35.6  
    35.7 +        // For nodes that produce a FlagsProj, make the node adjacent to the
    35.8 +        // use of the FlagsProj
    35.9 +        if (use->is_FlagsProj() && get_block_for_node(use) == block) {
   35.10 +          found_machif = true;
   35.11 +          break;
   35.12 +        }
   35.13 +
   35.14          // More than this instruction pending for successor to be ready,
   35.15          // don't choose this if other opportunities are ready
   35.16          if (ready_cnt.at(use->_idx) > 1)
    36.1 --- a/src/share/vm/opto/library_call.cpp	Tue Oct 01 11:06:35 2013 -0400
    36.2 +++ b/src/share/vm/opto/library_call.cpp	Thu Oct 03 16:38:21 2013 +0400
    36.3 @@ -32,6 +32,7 @@
    36.4  #include "opto/callGenerator.hpp"
    36.5  #include "opto/cfgnode.hpp"
    36.6  #include "opto/idealKit.hpp"
    36.7 +#include "opto/mathexactnode.hpp"
    36.8  #include "opto/mulnode.hpp"
    36.9  #include "opto/parse.hpp"
   36.10  #include "opto/runtime.hpp"
   36.11 @@ -46,19 +47,22 @@
   36.12   private:
   36.13    bool             _is_virtual;
   36.14    bool             _is_predicted;
   36.15 +  bool             _does_virtual_dispatch;
   36.16    vmIntrinsics::ID _intrinsic_id;
   36.17  
   36.18   public:
   36.19 -  LibraryIntrinsic(ciMethod* m, bool is_virtual, bool is_predicted, vmIntrinsics::ID id)
   36.20 +  LibraryIntrinsic(ciMethod* m, bool is_virtual, bool is_predicted, bool does_virtual_dispatch, vmIntrinsics::ID id)
   36.21      : InlineCallGenerator(m),
   36.22        _is_virtual(is_virtual),
   36.23        _is_predicted(is_predicted),
   36.24 +      _does_virtual_dispatch(does_virtual_dispatch),
   36.25        _intrinsic_id(id)
   36.26    {
   36.27    }
   36.28    virtual bool is_intrinsic() const { return true; }
   36.29    virtual bool is_virtual()   const { return _is_virtual; }
   36.30    virtual bool is_predicted()   const { return _is_predicted; }
   36.31 +  virtual bool does_virtual_dispatch()   const { return _does_virtual_dispatch; }
   36.32    virtual JVMState* generate(JVMState* jvms);
   36.33    virtual Node* generate_predicate(JVMState* jvms);
   36.34    vmIntrinsics::ID intrinsic_id() const { return _intrinsic_id; }
   36.35 @@ -199,6 +203,8 @@
   36.36    bool inline_math_native(vmIntrinsics::ID id);
   36.37    bool inline_trig(vmIntrinsics::ID id);
   36.38    bool inline_math(vmIntrinsics::ID id);
   36.39 +  bool inline_math_mathExact(Node* math);
   36.40 +  bool inline_math_addExact();
   36.41    bool inline_exp();
   36.42    bool inline_pow();
   36.43    void finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName);
   36.44 @@ -352,6 +358,7 @@
   36.45    }
   36.46  
   36.47    bool is_predicted = false;
   36.48 +  bool does_virtual_dispatch = false;
   36.49  
   36.50    switch (id) {
   36.51    case vmIntrinsics::_compareTo:
   36.52 @@ -378,8 +385,10 @@
   36.53      break;
   36.54    case vmIntrinsics::_hashCode:
   36.55      if (!InlineObjectHash)  return NULL;
   36.56 +    does_virtual_dispatch = true;
   36.57      break;
   36.58    case vmIntrinsics::_clone:
   36.59 +    does_virtual_dispatch = true;
   36.60    case vmIntrinsics::_copyOf:
   36.61    case vmIntrinsics::_copyOfRange:
   36.62      if (!InlineObjectCopy)  return NULL;
   36.63 @@ -498,6 +507,15 @@
   36.64      if (!UseCRC32Intrinsics) return NULL;
   36.65      break;
   36.66  
   36.67 +  case vmIntrinsics::_addExact:
   36.68 +    if (!Matcher::match_rule_supported(Op_AddExactI)) {
   36.69 +      return NULL;
   36.70 +    }
   36.71 +    if (!UseMathExactIntrinsics) {
   36.72 +      return NULL;
   36.73 +    }
   36.74 +    break;
   36.75 +
   36.76   default:
   36.77      assert(id <= vmIntrinsics::LAST_COMPILER_INLINE, "caller responsibility");
   36.78      assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?");
   36.79 @@ -529,7 +547,7 @@
   36.80      if (!InlineUnsafeOps)  return NULL;
   36.81    }
   36.82  
   36.83 -  return new LibraryIntrinsic(m, is_virtual, is_predicted, (vmIntrinsics::ID) id);
   36.84 +  return new LibraryIntrinsic(m, is_virtual, is_predicted, does_virtual_dispatch, (vmIntrinsics::ID) id);
   36.85  }
   36.86  
   36.87  //----------------------register_library_intrinsics-----------------------
   36.88 @@ -668,6 +686,8 @@
   36.89    case vmIntrinsics::_min:
   36.90    case vmIntrinsics::_max:                      return inline_min_max(intrinsic_id());
   36.91  
   36.92 +  case vmIntrinsics::_addExact:                 return inline_math_addExact();
   36.93 +
   36.94    case vmIntrinsics::_arraycopy:                return inline_arraycopy();
   36.95  
   36.96    case vmIntrinsics::_compareTo:                return inline_string_compareTo();
   36.97 @@ -1911,6 +1931,45 @@
   36.98    return true;
   36.99  }
  36.100  
  36.101 +bool LibraryCallKit::inline_math_mathExact(Node* math) {
  36.102 +  Node* result = _gvn.transform( new(C) ProjNode(math, MathExactNode::result_proj_node));
  36.103 +  Node* flags = _gvn.transform( new(C) FlagsProjNode(math, MathExactNode::flags_proj_node));
  36.104 +
  36.105 +  Node* bol = _gvn.transform( new (C) BoolNode(flags, BoolTest::overflow) );
  36.106 +  IfNode* check = create_and_map_if(control(), bol, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN);
  36.107 +  Node* fast_path = _gvn.transform( new (C) IfFalseNode(check));
  36.108 +  Node* slow_path = _gvn.transform( new (C) IfTrueNode(check) );
  36.109 +
  36.110 +  {
  36.111 +    PreserveJVMState pjvms(this);
  36.112 +    PreserveReexecuteState preexecs(this);
  36.113 +    jvms()->set_should_reexecute(true);
  36.114 +
  36.115 +    set_control(slow_path);
  36.116 +    set_i_o(i_o());
  36.117 +
  36.118 +    uncommon_trap(Deoptimization::Reason_intrinsic,
  36.119 +                  Deoptimization::Action_none);
  36.120 +  }
  36.121 +
  36.122 +  set_control(fast_path);
  36.123 +  set_result(result);
  36.124 +  return true;
  36.125 +}
  36.126 +
  36.127 +bool LibraryCallKit::inline_math_addExact() {
  36.128 +  Node* arg1 = argument(0);
  36.129 +  Node* arg2 = argument(1);
  36.130 +
  36.131 +  Node* add = _gvn.transform( new(C) AddExactINode(NULL, arg1, arg2) );
  36.132 +  if (add->Opcode() == Op_AddExactI) {
  36.133 +    return inline_math_mathExact(add);
  36.134 +  } else {
  36.135 +    set_result(add);
  36.136 +  }
  36.137 +  return true;
  36.138 +}
  36.139 +
  36.140  Node*
  36.141  LibraryCallKit::generate_min_max(vmIntrinsics::ID id, Node* x0, Node* y0) {
  36.142    // These are the candidate return value:
    37.1 --- a/src/share/vm/opto/loopTransform.cpp	Tue Oct 01 11:06:35 2013 -0400
    37.2 +++ b/src/share/vm/opto/loopTransform.cpp	Thu Oct 03 16:38:21 2013 +0400
    37.3 @@ -776,6 +776,9 @@
    37.4          continue; // not RC
    37.5  
    37.6        Node *cmp = bol->in(1);
    37.7 +      if (cmp->is_FlagsProj()) {
    37.8 +        continue;
    37.9 +      }
   37.10  
   37.11        Node *rc_exp = cmp->in(1);
   37.12        Node *limit = cmp->in(2);
    38.1 --- a/src/share/vm/opto/loopopts.cpp	Tue Oct 01 11:06:35 2013 -0400
    38.2 +++ b/src/share/vm/opto/loopopts.cpp	Thu Oct 03 16:38:21 2013 +0400
    38.3 @@ -2355,7 +2355,8 @@
    38.4          opc == Op_Catch     ||
    38.5          opc == Op_CatchProj ||
    38.6          opc == Op_Jump      ||
    38.7 -        opc == Op_JumpProj) {
    38.8 +        opc == Op_JumpProj  ||
    38.9 +        opc == Op_FlagsProj) {
   38.10  #if !defined(PRODUCT)
   38.11        if (TracePartialPeeling) {
   38.12          tty->print_cr("\nExit control too complex: lp: %d", head->_idx);
    39.1 --- a/src/share/vm/opto/matcher.cpp	Tue Oct 01 11:06:35 2013 -0400
    39.2 +++ b/src/share/vm/opto/matcher.cpp	Thu Oct 03 16:38:21 2013 +0400
    39.3 @@ -1964,6 +1964,7 @@
    39.4        case Op_Catch:
    39.5        case Op_CatchProj:
    39.6        case Op_CProj:
    39.7 +      case Op_FlagsProj:
    39.8        case Op_JumpProj:
    39.9        case Op_JProj:
   39.10        case Op_NeverBranch:
    40.1 --- a/src/share/vm/opto/matcher.hpp	Tue Oct 01 11:06:35 2013 -0400
    40.2 +++ b/src/share/vm/opto/matcher.hpp	Thu Oct 03 16:38:21 2013 +0400
    40.3 @@ -337,6 +337,9 @@
    40.4    // Register for MODL projection of divmodL
    40.5    static RegMask modL_proj_mask();
    40.6  
    40.7 +  static const RegMask mathExactI_result_proj_mask();
    40.8 +  static const RegMask mathExactI_flags_proj_mask();
    40.9 +
   40.10    // Use hardware DIV instruction when it is faster than
   40.11    // a code which use multiply for division by constant.
   40.12    static bool use_asm_for_ldiv_by_con( jlong divisor );
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/src/share/vm/opto/mathexactnode.cpp	Thu Oct 03 16:38:21 2013 +0400
    41.3 @@ -0,0 +1,143 @@
    41.4 +/*
    41.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    41.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    41.7 + *
    41.8 + * This code is free software; you can redistribute it and/or modify it
    41.9 + * under the terms of the GNU General Public License version 2 only, as
   41.10 + * published by the Free Software Foundation.
   41.11 + *
   41.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   41.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   41.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   41.15 + * version 2 for more details (a copy is included in the LICENSE file that
   41.16 + * accompanied this code).
   41.17 + *
   41.18 + * You should have received a copy of the GNU General Public License version
   41.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   41.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   41.21 + *
   41.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   41.23 + * or visit www.oracle.com if you need additional information or have any
   41.24 + * questions.
   41.25 + *
   41.26 + */
   41.27 +
   41.28 +#include "precompiled.hpp"
   41.29 +#include "memory/allocation.inline.hpp"
   41.30 +#include "opto/addnode.hpp"
   41.31 +#include "opto/machnode.hpp"
   41.32 +#include "opto/mathexactnode.hpp"
   41.33 +#include "opto/matcher.hpp"
   41.34 +#include "opto/subnode.hpp"
   41.35 +
   41.36 +MathExactNode::MathExactNode(Node* ctrl, Node* n1, Node* n2) : MultiNode(3) {
   41.37 +  init_req(0, ctrl);
   41.38 +  init_req(1, n1);
   41.39 +  init_req(2, n2);
   41.40 +}
   41.41 +
   41.42 +Node* AddExactINode::match(const ProjNode* proj, const Matcher* m) {
   41.43 +  uint ideal_reg = proj->ideal_reg();
   41.44 +  RegMask rm;
   41.45 +  if (proj->_con == result_proj_node) {
   41.46 +    rm = m->mathExactI_result_proj_mask();
   41.47 +  } else {
   41.48 +    assert(proj->_con == flags_proj_node, "must be result or flags");
   41.49 +    assert(ideal_reg == Op_RegFlags, "sanity");
   41.50 +    rm = m->mathExactI_flags_proj_mask();
   41.51 +  }
   41.52 +  return new (m->C) MachProjNode(this, proj->_con, rm, ideal_reg);
   41.53 +}
   41.54 +
   41.55 +// If the MathExactNode won't overflow we have to replace the
   41.56 +// FlagsProjNode and ProjNode that is generated by the MathExactNode
   41.57 +Node* MathExactNode::no_overflow(PhaseGVN *phase, Node* new_result) {
   41.58 +  PhaseIterGVN *igvn = phase->is_IterGVN();
   41.59 +  if (igvn) {
   41.60 +    ProjNode* result = result_node();
   41.61 +    ProjNode* flags = flags_node();
   41.62 +
   41.63 +    if (result != NULL) {
   41.64 +      igvn->replace_node(result, new_result);
   41.65 +    }
   41.66 +
   41.67 +    if (flags != NULL) {
   41.68 +      BoolNode* bolnode = (BoolNode *) flags->unique_out();
   41.69 +      switch (bolnode->_test._test) {
   41.70 +        case BoolTest::overflow:
   41.71 +          // if the check is for overflow - never taken
   41.72 +          igvn->replace_node(bolnode, phase->intcon(0));
   41.73 +          break;
   41.74 +        case BoolTest::no_overflow:
   41.75 +          // if the check is for no overflow - always taken
   41.76 +          igvn->replace_node(bolnode, phase->intcon(1));
   41.77 +          break;
   41.78 +        default:
   41.79 +          fatal("Unexpected value of BoolTest");
   41.80 +          break;
   41.81 +      }
   41.82 +      flags->del_req(0);
   41.83 +    }
   41.84 +  }
   41.85 +  return new_result;
   41.86 +}
   41.87 +
   41.88 +Node *AddExactINode::Ideal(PhaseGVN *phase, bool can_reshape) {
   41.89 +  Node *arg1 = in(1);
   41.90 +  Node *arg2 = in(2);
   41.91 +
   41.92 +  const Type* type1 = phase->type(arg1);
   41.93 +  const Type* type2 = phase->type(arg2);
   41.94 +
   41.95 +  if (type1 != Type::TOP && type1->singleton() &&
   41.96 +      type2 != Type::TOP && type2->singleton()) {
   41.97 +    jint val1 = arg1->get_int();
   41.98 +    jint val2 = arg2->get_int();
   41.99 +    jint result = val1 + val2;
  41.100 +    // Hacker's Delight 2-12 Overflow if both arguments have the opposite sign of the result
  41.101 +    if ( (((val1 ^ result) & (val2 ^ result)) >= 0)) {
  41.102 +      Node* con_result = ConINode::make(phase->C, result);
  41.103 +      return no_overflow(phase, con_result);
  41.104 +    }
  41.105 +    return NULL;
  41.106 +  }
  41.107 +
  41.108 +  if (type1 == TypeInt::ZERO) { // (Add 0 x) == x
  41.109 +    Node* add_result = new (phase->C) AddINode(arg1, arg2);
  41.110 +    return no_overflow(phase, add_result);
  41.111 +  }
  41.112 +
  41.113 +  if (type2 == TypeInt::ZERO) { // (Add x 0) == x
  41.114 +    Node* add_result = new (phase->C) AddINode(arg1, arg2);
  41.115 +    return no_overflow(phase, add_result);
  41.116 +  }
  41.117 +
  41.118 +  if (type2->singleton()) {
  41.119 +    return NULL; // no change - keep constant on the right
  41.120 +  }
  41.121 +
  41.122 +  if (type1->singleton()) {
  41.123 +    // Make it x + Constant - move constant to the right
  41.124 +    swap_edges(1, 2);
  41.125 +    return this;
  41.126 +  }
  41.127 +
  41.128 +  if (arg2->is_Load()) {
  41.129 +    return NULL; // no change - keep load on the right
  41.130 +  }
  41.131 +
  41.132 +  if (arg1->is_Load()) {
  41.133 +    // Make it x + Load - move load to the right
  41.134 +    swap_edges(1, 2);
  41.135 +    return this;
  41.136 +  }
  41.137 +
  41.138 +  if (arg1->_idx > arg2->_idx) {
  41.139 +    // Sort the edges
  41.140 +    swap_edges(1, 2);
  41.141 +    return this;
  41.142 +  }
  41.143 +
  41.144 +  return NULL;
  41.145 +}
  41.146 +
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/src/share/vm/opto/mathexactnode.hpp	Thu Oct 03 16:38:21 2013 +0400
    42.3 @@ -0,0 +1,81 @@
    42.4 +/*
    42.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    42.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    42.7 + *
    42.8 + * This code is free software; you can redistribute it and/or modify it
    42.9 + * under the terms of the GNU General Public License version 2 only, as
   42.10 + * published by the Free Software Foundation.
   42.11 + *
   42.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   42.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   42.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   42.15 + * version 2 for more details (a copy is included in the LICENSE file that
   42.16 + * accompanied this code).
   42.17 + *
   42.18 + * You should have received a copy of the GNU General Public License version
   42.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   42.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   42.21 + *
   42.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   42.23 + * or visit www.oracle.com if you need additional information or have any
   42.24 + * questions.
   42.25 + *
   42.26 + */
   42.27 +
   42.28 +#ifndef SHARE_VM_OPTO_MATHEXACTNODE_HPP
   42.29 +#define SHARE_VM_OPTO_MATHEXACTNODE_HPP
   42.30 +
   42.31 +#include "opto/multnode.hpp"
   42.32 +#include "opto/node.hpp"
   42.33 +#include "opto/type.hpp"
   42.34 +
   42.35 +class Node;
   42.36 +
   42.37 +class PhaseGVN;
   42.38 +class PhaseTransform;
   42.39 +
   42.40 +class MathExactNode : public MultiNode {
   42.41 +public:
   42.42 +  MathExactNode(Node* ctrl, Node* in1, Node* in2);
   42.43 +  enum {
   42.44 +    result_proj_node = 0,
   42.45 +    flags_proj_node = 1
   42.46 +  };
   42.47 +  virtual int Opcode() const;
   42.48 +  virtual Node* Identity(PhaseTransform* phase) { return this; }
   42.49 +  virtual Node* Ideal(PhaseGVN* phase, bool can_reshape) { return NULL; }
   42.50 +  virtual const Type* Value(PhaseTransform* phase) const { return bottom_type(); }
   42.51 +  virtual uint hash() const { return Node::hash(); }
   42.52 +  virtual bool is_CFG() const { return false; }
   42.53 +  virtual uint ideal_reg() const { return NotAMachineReg; }
   42.54 +
   42.55 +  ProjNode* result_node() { return proj_out(result_proj_node); }
   42.56 +  ProjNode* flags_node() { return proj_out(flags_proj_node); }
   42.57 +protected:
   42.58 +  Node* no_overflow(PhaseGVN *phase, Node* new_result);
   42.59 +};
   42.60 +
   42.61 +class AddExactINode : public MathExactNode {
   42.62 +public:
   42.63 +  AddExactINode(Node* ctrl, Node* in1, Node* in2) : MathExactNode(ctrl, in1, in2) {}
   42.64 +  virtual int Opcode() const;
   42.65 +  virtual const Type* bottom_type() const { return TypeTuple::INT_CC_PAIR; }
   42.66 +  virtual Node* match(const ProjNode* proj, const Matcher* m);
   42.67 +  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
   42.68 +};
   42.69 +
   42.70 +class FlagsProjNode : public ProjNode {
   42.71 +public:
   42.72 +  FlagsProjNode(Node* src, uint con) : ProjNode(src, con) {
   42.73 +    init_class_id(Class_FlagsProj);
   42.74 +  }
   42.75 +
   42.76 +  virtual int Opcode() const;
   42.77 +  virtual bool is_CFG() const { return false; }
   42.78 +  virtual const Type* bottom_type() const { return TypeInt::CC; }
   42.79 +  virtual uint ideal_reg() const { return Op_RegFlags; }
   42.80 +};
   42.81 +
   42.82 +
   42.83 +#endif
   42.84 +
    43.1 --- a/src/share/vm/opto/multnode.cpp	Tue Oct 01 11:06:35 2013 -0400
    43.2 +++ b/src/share/vm/opto/multnode.cpp	Thu Oct 03 16:38:21 2013 +0400
    43.3 @@ -25,6 +25,7 @@
    43.4  #include "precompiled.hpp"
    43.5  #include "opto/callnode.hpp"
    43.6  #include "opto/matcher.hpp"
    43.7 +#include "opto/mathexactnode.hpp"
    43.8  #include "opto/multnode.hpp"
    43.9  #include "opto/opcodes.hpp"
   43.10  #include "opto/phaseX.hpp"
   43.11 @@ -46,15 +47,21 @@
   43.12    assert(Opcode() != Op_If || outcnt() == 2, "bad if #1");
   43.13    for( DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++ ) {
   43.14      Node *p = fast_out(i);
   43.15 -    if( !p->is_Proj() ) {
   43.16 +    if (p->is_Proj()) {
   43.17 +      ProjNode *proj = p->as_Proj();
   43.18 +      if (proj->_con == which_proj) {
   43.19 +        assert(Opcode() != Op_If || proj->Opcode() == (which_proj?Op_IfTrue:Op_IfFalse), "bad if #2");
   43.20 +        return proj;
   43.21 +      }
   43.22 +    } else if (p->is_FlagsProj()) {
   43.23 +      FlagsProjNode *proj = p->as_FlagsProj();
   43.24 +      if (proj->_con == which_proj) {
   43.25 +        return proj;
   43.26 +      }
   43.27 +    } else {
   43.28        assert(p == this && this->is_Start(), "else must be proj");
   43.29        continue;
   43.30      }
   43.31 -    ProjNode *proj = p->as_Proj();
   43.32 -    if( proj->_con == which_proj ) {
   43.33 -      assert(Opcode() != Op_If || proj->Opcode() == (which_proj?Op_IfTrue:Op_IfFalse), "bad if #2");
   43.34 -      return proj;
   43.35 -    }
   43.36    }
   43.37    return NULL;
   43.38  }
    44.1 --- a/src/share/vm/opto/node.hpp	Tue Oct 01 11:06:35 2013 -0400
    44.2 +++ b/src/share/vm/opto/node.hpp	Thu Oct 03 16:38:21 2013 +0400
    44.3 @@ -69,6 +69,7 @@
    44.4  class EncodePKlassNode;
    44.5  class FastLockNode;
    44.6  class FastUnlockNode;
    44.7 +class FlagsProjNode;
    44.8  class IfNode;
    44.9  class IfFalseNode;
   44.10  class IfTrueNode;
   44.11 @@ -623,6 +624,7 @@
   44.12        DEFINE_CLASS_ID(Cmp,   Sub, 0)
   44.13          DEFINE_CLASS_ID(FastLock,   Cmp, 0)
   44.14          DEFINE_CLASS_ID(FastUnlock, Cmp, 1)
   44.15 +        DEFINE_CLASS_ID(FlagsProj, Cmp, 2)
   44.16  
   44.17      DEFINE_CLASS_ID(MergeMem, Node, 7)
   44.18      DEFINE_CLASS_ID(Bool,     Node, 8)
   44.19 @@ -726,6 +728,7 @@
   44.20    DEFINE_CLASS_QUERY(EncodePKlass)
   44.21    DEFINE_CLASS_QUERY(FastLock)
   44.22    DEFINE_CLASS_QUERY(FastUnlock)
   44.23 +  DEFINE_CLASS_QUERY(FlagsProj)
   44.24    DEFINE_CLASS_QUERY(If)
   44.25    DEFINE_CLASS_QUERY(IfFalse)
   44.26    DEFINE_CLASS_QUERY(IfTrue)
    45.1 --- a/src/share/vm/opto/subnode.cpp	Tue Oct 01 11:06:35 2013 -0400
    45.2 +++ b/src/share/vm/opto/subnode.cpp	Thu Oct 03 16:38:21 2013 +0400
    45.3 @@ -1064,7 +1064,7 @@
    45.4  // Print special per-node info
    45.5  #ifndef PRODUCT
    45.6  void BoolTest::dump_on(outputStream *st) const {
    45.7 -  const char *msg[] = {"eq","gt","??","lt","ne","le","??","ge"};
    45.8 +  const char *msg[] = {"eq","gt","of","lt","ne","le","nof","ge"};
    45.9    st->print(msg[_test]);
   45.10  }
   45.11  #endif
   45.12 @@ -1126,7 +1126,7 @@
   45.13    Node *cmp = in(1);
   45.14    if( !cmp->is_Sub() ) return NULL;
   45.15    int cop = cmp->Opcode();
   45.16 -  if( cop == Op_FastLock || cop == Op_FastUnlock ) return NULL;
   45.17 +  if( cop == Op_FastLock || cop == Op_FastUnlock || cop == Op_FlagsProj) return NULL;
   45.18    Node *cmp1 = cmp->in(1);
   45.19    Node *cmp2 = cmp->in(2);
   45.20    if( !cmp1 ) return NULL;
    46.1 --- a/src/share/vm/opto/subnode.hpp	Tue Oct 01 11:06:35 2013 -0400
    46.2 +++ b/src/share/vm/opto/subnode.hpp	Thu Oct 03 16:38:21 2013 +0400
    46.3 @@ -263,16 +263,16 @@
    46.4  // We pick the values as 3 bits; the low order 2 bits we compare against the
    46.5  // condition codes, the high bit flips the sense of the result.
    46.6  struct BoolTest VALUE_OBJ_CLASS_SPEC {
    46.7 -  enum mask { eq = 0, ne = 4, le = 5, ge = 7, lt = 3, gt = 1, illegal = 8 };
    46.8 +  enum mask { eq = 0, ne = 4, le = 5, ge = 7, lt = 3, gt = 1, overflow = 2, no_overflow = 6, illegal = 8 };
    46.9    mask _test;
   46.10    BoolTest( mask btm ) : _test(btm) {}
   46.11    const Type *cc2logical( const Type *CC ) const;
   46.12    // Commute the test.  I use a small table lookup.  The table is created as
   46.13    // a simple char array where each element is the ASCII version of a 'mask'
   46.14    // enum from above.
   46.15 -  mask commute( ) const { return mask("038147858"[_test]-'0'); }
   46.16 +  mask commute( ) const { return mask("032147658"[_test]-'0'); }
   46.17    mask negate( ) const { return mask(_test^4); }
   46.18 -  bool is_canonical( ) const { return (_test == BoolTest::ne || _test == BoolTest::lt || _test == BoolTest::le); }
   46.19 +  bool is_canonical( ) const { return (_test == BoolTest::ne || _test == BoolTest::lt || _test == BoolTest::le || _test == BoolTest::overflow); }
   46.20  #ifndef PRODUCT
   46.21    void dump_on(outputStream *st) const;
   46.22  #endif
    47.1 --- a/src/share/vm/opto/type.cpp	Tue Oct 01 11:06:35 2013 -0400
    47.2 +++ b/src/share/vm/opto/type.cpp	Thu Oct 03 16:38:21 2013 +0400
    47.3 @@ -430,6 +430,11 @@
    47.4    longpair[1] = TypeLong::LONG;
    47.5    TypeTuple::LONG_PAIR = TypeTuple::make(2, longpair);
    47.6  
    47.7 +  const Type **intccpair = TypeTuple::fields(2);
    47.8 +  intccpair[0] = TypeInt::INT;
    47.9 +  intccpair[1] = TypeInt::CC;
   47.10 +  TypeTuple::INT_CC_PAIR = TypeTuple::make(2, intccpair);
   47.11 +
   47.12    _const_basic_type[T_NARROWOOP]   = TypeNarrowOop::BOTTOM;
   47.13    _const_basic_type[T_NARROWKLASS] = Type::BOTTOM;
   47.14    _const_basic_type[T_BOOLEAN]     = TypeInt::BOOL;
   47.15 @@ -1646,6 +1651,7 @@
   47.16  const TypeTuple *TypeTuple::START_I2C;
   47.17  const TypeTuple *TypeTuple::INT_PAIR;
   47.18  const TypeTuple *TypeTuple::LONG_PAIR;
   47.19 +const TypeTuple *TypeTuple::INT_CC_PAIR;
   47.20  
   47.21  
   47.22  //------------------------------make-------------------------------------------
    48.1 --- a/src/share/vm/opto/type.hpp	Tue Oct 01 11:06:35 2013 -0400
    48.2 +++ b/src/share/vm/opto/type.hpp	Thu Oct 03 16:38:21 2013 +0400
    48.3 @@ -584,6 +584,7 @@
    48.4    static const TypeTuple *START_I2C;
    48.5    static const TypeTuple *INT_PAIR;
    48.6    static const TypeTuple *LONG_PAIR;
    48.7 +  static const TypeTuple *INT_CC_PAIR;
    48.8  #ifndef PRODUCT
    48.9    virtual void dump2( Dict &d, uint, outputStream *st  ) const; // Specialized per-Type dumping
   48.10  #endif
    49.1 --- a/src/share/vm/prims/jvm.cpp	Tue Oct 01 11:06:35 2013 -0400
    49.2 +++ b/src/share/vm/prims/jvm.cpp	Thu Oct 03 16:38:21 2013 +0400
    49.3 @@ -4226,13 +4226,13 @@
    49.4  
    49.5  JVM_LEAF(jboolean, JVM_AccessVMBooleanFlag(const char* name, jboolean* value, jboolean is_get))
    49.6    JVMWrapper("JVM_AccessBoolVMFlag");
    49.7 -  return is_get ? CommandLineFlags::boolAt((char*) name, (bool*) value) : CommandLineFlags::boolAtPut((char*) name, (bool*) value, INTERNAL);
    49.8 +  return is_get ? CommandLineFlags::boolAt((char*) name, (bool*) value) : CommandLineFlags::boolAtPut((char*) name, (bool*) value, Flag::INTERNAL);
    49.9  JVM_END
   49.10  
   49.11  JVM_LEAF(jboolean, JVM_AccessVMIntFlag(const char* name, jint* value, jboolean is_get))
   49.12    JVMWrapper("JVM_AccessVMIntFlag");
   49.13    intx v;
   49.14 -  jboolean result = is_get ? CommandLineFlags::intxAt((char*) name, &v) : CommandLineFlags::intxAtPut((char*) name, &v, INTERNAL);
   49.15 +  jboolean result = is_get ? CommandLineFlags::intxAt((char*) name, &v) : CommandLineFlags::intxAtPut((char*) name, &v, Flag::INTERNAL);
   49.16    *value = (jint)v;
   49.17    return result;
   49.18  JVM_END
    50.1 --- a/src/share/vm/runtime/arguments.cpp	Tue Oct 01 11:06:35 2013 -0400
    50.2 +++ b/src/share/vm/runtime/arguments.cpp	Thu Oct 03 16:38:21 2013 +0400
    50.3 @@ -625,11 +625,11 @@
    50.4    }
    50.5  }
    50.6  
    50.7 -static bool set_bool_flag(char* name, bool value, FlagValueOrigin origin) {
    50.8 +static bool set_bool_flag(char* name, bool value, Flag::Flags origin) {
    50.9    return CommandLineFlags::boolAtPut(name, &value, origin);
   50.10  }
   50.11  
   50.12 -static bool set_fp_numeric_flag(char* name, char* value, FlagValueOrigin origin) {
   50.13 +static bool set_fp_numeric_flag(char* name, char* value, Flag::Flags origin) {
   50.14    double v;
   50.15    if (sscanf(value, "%lf", &v) != 1) {
   50.16      return false;
   50.17 @@ -641,7 +641,7 @@
   50.18    return false;
   50.19  }
   50.20  
   50.21 -static bool set_numeric_flag(char* name, char* value, FlagValueOrigin origin) {
   50.22 +static bool set_numeric_flag(char* name, char* value, Flag::Flags origin) {
   50.23    julong v;
   50.24    intx intx_v;
   50.25    bool is_neg = false;
   50.26 @@ -674,14 +674,14 @@
   50.27    return false;
   50.28  }
   50.29  
   50.30 -static bool set_string_flag(char* name, const char* value, FlagValueOrigin origin) {
   50.31 +static bool set_string_flag(char* name, const char* value, Flag::Flags origin) {
   50.32    if (!CommandLineFlags::ccstrAtPut(name, &value, origin))  return false;
   50.33    // Contract:  CommandLineFlags always returns a pointer that needs freeing.
   50.34    FREE_C_HEAP_ARRAY(char, value, mtInternal);
   50.35    return true;
   50.36  }
   50.37  
   50.38 -static bool append_to_string_flag(char* name, const char* new_value, FlagValueOrigin origin) {
   50.39 +static bool append_to_string_flag(char* name, const char* new_value, Flag::Flags origin) {
   50.40    const char* old_value = "";
   50.41    if (!CommandLineFlags::ccstrAt(name, &old_value))  return false;
   50.42    size_t old_len = old_value != NULL ? strlen(old_value) : 0;
   50.43 @@ -709,7 +709,7 @@
   50.44    return true;
   50.45  }
   50.46  
   50.47 -bool Arguments::parse_argument(const char* arg, FlagValueOrigin origin) {
   50.48 +bool Arguments::parse_argument(const char* arg, Flag::Flags origin) {
   50.49  
   50.50    // range of acceptable characters spelled out for portability reasons
   50.51  #define NAME_RANGE  "[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]"
   50.52 @@ -850,7 +850,7 @@
   50.53  }
   50.54  
   50.55  bool Arguments::process_argument(const char* arg,
   50.56 -    jboolean ignore_unrecognized, FlagValueOrigin origin) {
   50.57 +    jboolean ignore_unrecognized, Flag::Flags origin) {
   50.58  
   50.59    JDK_Version since = JDK_Version();
   50.60  
   50.61 @@ -904,7 +904,7 @@
   50.62        jio_fprintf(defaultStream::error_stream(),
   50.63                    "Did you mean '%s%s%s'?\n",
   50.64                    (fuzzy_matched->is_bool()) ? "(+/-)" : "",
   50.65 -                  fuzzy_matched->name,
   50.66 +                  fuzzy_matched->_name,
   50.67                    (fuzzy_matched->is_bool()) ? "" : "=<value>");
   50.68      }
   50.69    }
   50.70 @@ -952,7 +952,7 @@
   50.71          // this allows a way to include spaces in string-valued options
   50.72          token[pos] = '\0';
   50.73          logOption(token);
   50.74 -        result &= process_argument(token, ignore_unrecognized, CONFIG_FILE);
   50.75 +        result &= process_argument(token, ignore_unrecognized, Flag::CONFIG_FILE);
   50.76          build_jvm_flags(token);
   50.77          pos = 0;
   50.78          in_white_space = true;
   50.79 @@ -970,7 +970,7 @@
   50.80    }
   50.81    if (pos > 0) {
   50.82      token[pos] = '\0';
   50.83 -    result &= process_argument(token, ignore_unrecognized, CONFIG_FILE);
   50.84 +    result &= process_argument(token, ignore_unrecognized, Flag::CONFIG_FILE);
   50.85      build_jvm_flags(token);
   50.86    }
   50.87    fclose(stream);
   50.88 @@ -1132,6 +1132,9 @@
   50.89      Tier3InvokeNotifyFreqLog = 0;
   50.90      Tier4InvocationThreshold = 0;
   50.91    }
   50.92 +  if (FLAG_IS_DEFAULT(NmethodSweepFraction)) {
   50.93 +    FLAG_SET_DEFAULT(NmethodSweepFraction, 1 + ReservedCodeCacheSize / (16 * M));
   50.94 +  }
   50.95  }
   50.96  
   50.97  #if INCLUDE_ALL_GCS
   50.98 @@ -2337,6 +2340,10 @@
   50.99                  (2*G)/M);
  50.100      status = false;
  50.101    }
  50.102 +
  50.103 +  status &= verify_interval(NmethodSweepFraction, 1, ReservedCodeCacheSize/K, "NmethodSweepFraction");
  50.104 +  status &= verify_interval(NmethodSweepActivity, 0, 2000, "NmethodSweepActivity");
  50.105 +
  50.106    return status;
  50.107  }
  50.108  
  50.109 @@ -2438,7 +2445,7 @@
  50.110    }
  50.111  
  50.112    // Parse JavaVMInitArgs structure passed in
  50.113 -  result = parse_each_vm_init_arg(args, &scp, &scp_assembly_required, COMMAND_LINE);
  50.114 +  result = parse_each_vm_init_arg(args, &scp, &scp_assembly_required, Flag::COMMAND_LINE);
  50.115    if (result != JNI_OK) {
  50.116      return result;
  50.117    }
  50.118 @@ -2510,7 +2517,7 @@
  50.119  jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
  50.120                                         SysClassPath* scp_p,
  50.121                                         bool* scp_assembly_required_p,
  50.122 -                                       FlagValueOrigin origin) {
  50.123 +                                       Flag::Flags origin) {
  50.124    // Remaining part of option string
  50.125    const char* tail;
  50.126  
  50.127 @@ -3333,7 +3340,7 @@
  50.128        }
  50.129      }
  50.130  
  50.131 -    return(parse_each_vm_init_arg(&vm_args, scp_p, scp_assembly_required_p, ENVIRON_VAR));
  50.132 +    return(parse_each_vm_init_arg(&vm_args, scp_p, scp_assembly_required_p, Flag::ENVIRON_VAR));
  50.133    }
  50.134    return JNI_OK;
  50.135  }
    51.1 --- a/src/share/vm/runtime/arguments.hpp	Tue Oct 01 11:06:35 2013 -0400
    51.2 +++ b/src/share/vm/runtime/arguments.hpp	Thu Oct 03 16:38:21 2013 +0400
    51.3 @@ -360,15 +360,15 @@
    51.4  
    51.5    // Argument parsing
    51.6    static void do_pd_flag_adjustments();
    51.7 -  static bool parse_argument(const char* arg, FlagValueOrigin origin);
    51.8 -  static bool process_argument(const char* arg, jboolean ignore_unrecognized, FlagValueOrigin origin);
    51.9 +  static bool parse_argument(const char* arg, Flag::Flags origin);
   51.10 +  static bool process_argument(const char* arg, jboolean ignore_unrecognized, Flag::Flags origin);
   51.11    static void process_java_launcher_argument(const char*, void*);
   51.12    static void process_java_compiler_argument(char* arg);
   51.13    static jint parse_options_environment_variable(const char* name, SysClassPath* scp_p, bool* scp_assembly_required_p);
   51.14    static jint parse_java_tool_options_environment_variable(SysClassPath* scp_p, bool* scp_assembly_required_p);
   51.15    static jint parse_java_options_environment_variable(SysClassPath* scp_p, bool* scp_assembly_required_p);
   51.16    static jint parse_vm_init_args(const JavaVMInitArgs* args);
   51.17 -  static jint parse_each_vm_init_arg(const JavaVMInitArgs* args, SysClassPath* scp_p, bool* scp_assembly_required_p, FlagValueOrigin origin);
   51.18 +  static jint parse_each_vm_init_arg(const JavaVMInitArgs* args, SysClassPath* scp_p, bool* scp_assembly_required_p, Flag::Flags origin);
   51.19    static jint finalize_vm_init_args(SysClassPath* scp_p, bool scp_assembly_required);
   51.20    static bool is_bad_option(const JavaVMOption* option, jboolean ignore,
   51.21      const char* option_type);
    52.1 --- a/src/share/vm/runtime/globals.cpp	Tue Oct 01 11:06:35 2013 -0400
    52.2 +++ b/src/share/vm/runtime/globals.cpp	Thu Oct 03 16:38:21 2013 +0400
    52.3 @@ -62,26 +62,174 @@
    52.4  MATERIALIZE_FLAGS_EXT
    52.5  
    52.6  
    52.7 +void Flag::check_writable() {
    52.8 +  if (is_constant_in_binary()) {
    52.9 +    fatal(err_msg("flag is constant: %s", _name));
   52.10 +  }
   52.11 +}
   52.12 +
   52.13 +bool Flag::is_bool() const {
   52.14 +  return strcmp(_type, "bool") == 0;
   52.15 +}
   52.16 +
   52.17 +bool Flag::get_bool() const {
   52.18 +  return *((bool*) _addr);
   52.19 +}
   52.20 +
   52.21 +void Flag::set_bool(bool value) {
   52.22 +  check_writable();
   52.23 +  *((bool*) _addr) = value;
   52.24 +}
   52.25 +
   52.26 +bool Flag::is_intx() const {
   52.27 +  return strcmp(_type, "intx")  == 0;
   52.28 +}
   52.29 +
   52.30 +intx Flag::get_intx() const {
   52.31 +  return *((intx*) _addr);
   52.32 +}
   52.33 +
   52.34 +void Flag::set_intx(intx value) {
   52.35 +  check_writable();
   52.36 +  *((intx*) _addr) = value;
   52.37 +}
   52.38 +
   52.39 +bool Flag::is_uintx() const {
   52.40 +  return strcmp(_type, "uintx") == 0;
   52.41 +}
   52.42 +
   52.43 +uintx Flag::get_uintx() const {
   52.44 +  return *((uintx*) _addr);
   52.45 +}
   52.46 +
   52.47 +void Flag::set_uintx(uintx value) {
   52.48 +  check_writable();
   52.49 +  *((uintx*) _addr) = value;
   52.50 +}
   52.51 +
   52.52 +bool Flag::is_uint64_t() const {
   52.53 +  return strcmp(_type, "uint64_t") == 0;
   52.54 +}
   52.55 +
   52.56 +uint64_t Flag::get_uint64_t() const {
   52.57 +  return *((uint64_t*) _addr);
   52.58 +}
   52.59 +
   52.60 +void Flag::set_uint64_t(uint64_t value) {
   52.61 +  check_writable();
   52.62 +  *((uint64_t*) _addr) = value;
   52.63 +}
   52.64 +
   52.65 +bool Flag::is_double() const {
   52.66 +  return strcmp(_type, "double") == 0;
   52.67 +}
   52.68 +
   52.69 +double Flag::get_double() const {
   52.70 +  return *((double*) _addr);
   52.71 +}
   52.72 +
   52.73 +void Flag::set_double(double value) {
   52.74 +  check_writable();
   52.75 +  *((double*) _addr) = value;
   52.76 +}
   52.77 +
   52.78 +bool Flag::is_ccstr() const {
   52.79 +  return strcmp(_type, "ccstr") == 0 || strcmp(_type, "ccstrlist") == 0;
   52.80 +}
   52.81 +
   52.82 +bool Flag::ccstr_accumulates() const {
   52.83 +  return strcmp(_type, "ccstrlist") == 0;
   52.84 +}
   52.85 +
   52.86 +ccstr Flag::get_ccstr() const {
   52.87 +  return *((ccstr*) _addr);
   52.88 +}
   52.89 +
   52.90 +void Flag::set_ccstr(ccstr value) {
   52.91 +  check_writable();
   52.92 +  *((ccstr*) _addr) = value;
   52.93 +}
   52.94 +
   52.95 +
   52.96 +Flag::Flags Flag::get_origin() {
   52.97 +  return Flags(_flags & VALUE_ORIGIN_MASK);
   52.98 +}
   52.99 +
  52.100 +void Flag::set_origin(Flags origin) {
  52.101 +  assert((origin & VALUE_ORIGIN_MASK) == origin, "sanity");
  52.102 +  _flags = Flags((_flags & ~VALUE_ORIGIN_MASK) | origin);
  52.103 +}
  52.104 +
  52.105 +bool Flag::is_default() {
  52.106 +  return (get_origin() == DEFAULT);
  52.107 +}
  52.108 +
  52.109 +bool Flag::is_ergonomic() {
  52.110 +  return (get_origin() == ERGONOMIC);
  52.111 +}
  52.112 +
  52.113 +bool Flag::is_command_line() {
  52.114 +  return (get_origin() == COMMAND_LINE);
  52.115 +}
  52.116 +
  52.117 +bool Flag::is_product() const {
  52.118 +  return (_flags & KIND_PRODUCT) != 0;
  52.119 +}
  52.120 +
  52.121 +bool Flag::is_manageable() const {
  52.122 +  return (_flags & KIND_MANAGEABLE) != 0;
  52.123 +}
  52.124 +
  52.125 +bool Flag::is_diagnostic() const {
  52.126 +  return (_flags & KIND_DIAGNOSTIC) != 0;
  52.127 +}
  52.128 +
  52.129 +bool Flag::is_experimental() const {
  52.130 +  return (_flags & KIND_EXPERIMENTAL) != 0;
  52.131 +}
  52.132 +
  52.133 +bool Flag::is_notproduct() const {
  52.134 +  return (_flags & KIND_NOT_PRODUCT) != 0;
  52.135 +}
  52.136 +
  52.137 +bool Flag::is_develop() const {
  52.138 +  return (_flags & KIND_DEVELOP) != 0;
  52.139 +}
  52.140 +
  52.141 +bool Flag::is_read_write() const {
  52.142 +  return (_flags & KIND_READ_WRITE) != 0;
  52.143 +}
  52.144 +
  52.145 +bool Flag::is_commercial() const {
  52.146 +  return (_flags & KIND_COMMERCIAL) != 0;
  52.147 +}
  52.148 +
  52.149 +/**
  52.150 + * Returns if this flag is a constant in the binary.  Right now this is
  52.151 + * true for notproduct and develop flags in product builds.
  52.152 + */
  52.153 +bool Flag::is_constant_in_binary() const {
  52.154 +#ifdef PRODUCT
  52.155 +    return is_notproduct() || is_develop();
  52.156 +#else
  52.157 +    return false;
  52.158 +#endif
  52.159 +}
  52.160 +
  52.161  bool Flag::is_unlocker() const {
  52.162 -  return strcmp(name, "UnlockDiagnosticVMOptions") == 0     ||
  52.163 -         strcmp(name, "UnlockExperimentalVMOptions") == 0   ||
  52.164 +  return strcmp(_name, "UnlockDiagnosticVMOptions") == 0     ||
  52.165 +         strcmp(_name, "UnlockExperimentalVMOptions") == 0   ||
  52.166           is_unlocker_ext();
  52.167  }
  52.168  
  52.169  bool Flag::is_unlocked() const {
  52.170 -  if (strcmp(kind, "{diagnostic}") == 0 ||
  52.171 -      strcmp(kind, "{C2 diagnostic}") == 0 ||
  52.172 -      strcmp(kind, "{ARCH diagnostic}") == 0 ||
  52.173 -      strcmp(kind, "{Shark diagnostic}") == 0) {
  52.174 +  if (is_diagnostic()) {
  52.175      return UnlockDiagnosticVMOptions;
  52.176 -  } else if (strcmp(kind, "{experimental}") == 0 ||
  52.177 -             strcmp(kind, "{C2 experimental}") == 0 ||
  52.178 -             strcmp(kind, "{ARCH experimental}") == 0 ||
  52.179 -             strcmp(kind, "{Shark experimental}") == 0) {
  52.180 +  }
  52.181 +  if (is_experimental()) {
  52.182      return UnlockExperimentalVMOptions;
  52.183 -  } else {
  52.184 -    return is_unlocked_ext();
  52.185    }
  52.186 +  return is_unlocked_ext();
  52.187  }
  52.188  
  52.189  // Get custom message for this locked flag, or return NULL if
  52.190 @@ -91,16 +239,14 @@
  52.191  }
  52.192  
  52.193  bool Flag::is_writeable() const {
  52.194 -  return strcmp(kind, "{manageable}") == 0 ||
  52.195 -         strcmp(kind, "{product rw}") == 0 ||
  52.196 -         is_writeable_ext();
  52.197 +  return is_manageable() || (is_product() && is_read_write()) || is_writeable_ext();
  52.198  }
  52.199  
  52.200  // All flags except "manageable" are assumed to be internal flags.
  52.201  // Long term, we need to define a mechanism to specify which flags
  52.202  // are external/stable and change this function accordingly.
  52.203  bool Flag::is_external() const {
  52.204 -  return strcmp(kind, "{manageable}") == 0 || is_external_ext();
  52.205 +  return is_manageable() || is_external_ext();
  52.206  }
  52.207  
  52.208  
  52.209 @@ -108,53 +254,113 @@
  52.210  #define FORMAT_BUFFER_LEN 16
  52.211  
  52.212  void Flag::print_on(outputStream* st, bool withComments) {
  52.213 -  st->print("%9s %-40s %c= ", type, name, (origin != DEFAULT ? ':' : ' '));
  52.214 -  if (is_bool())     st->print("%-16s", get_bool() ? "true" : "false");
  52.215 -  if (is_intx())     st->print("%-16ld", get_intx());
  52.216 -  if (is_uintx())    st->print("%-16lu", get_uintx());
  52.217 -  if (is_uint64_t()) st->print("%-16lu", get_uint64_t());
  52.218 -  if (is_double())   st->print("%-16f", get_double());
  52.219 +  // Don't print notproduct and develop flags in a product build.
  52.220 +  if (is_constant_in_binary()) {
  52.221 +    return;
  52.222 +  }
  52.223  
  52.224 +  st->print("%9s %-40s %c= ", _type, _name, (!is_default() ? ':' : ' '));
  52.225 +
  52.226 +  if (is_bool()) {
  52.227 +    st->print("%-16s", get_bool() ? "true" : "false");
  52.228 +  }
  52.229 +  if (is_intx()) {
  52.230 +    st->print("%-16ld", get_intx());
  52.231 +  }
  52.232 +  if (is_uintx()) {
  52.233 +    st->print("%-16lu", get_uintx());
  52.234 +  }
  52.235 +  if (is_uint64_t()) {
  52.236 +    st->print("%-16lu", get_uint64_t());
  52.237 +  }
  52.238 +  if (is_double()) {
  52.239 +    st->print("%-16f", get_double());
  52.240 +  }
  52.241    if (is_ccstr()) {
  52.242 -     const char* cp = get_ccstr();
  52.243 -     if (cp != NULL) {
  52.244 -       const char* eol;
  52.245 -       while ((eol = strchr(cp, '\n')) != NULL) {
  52.246 -         char format_buffer[FORMAT_BUFFER_LEN];
  52.247 -         size_t llen = pointer_delta(eol, cp, sizeof(char));
  52.248 -         jio_snprintf(format_buffer, FORMAT_BUFFER_LEN,
  52.249 -                     "%%." SIZE_FORMAT "s", llen);
  52.250 -         st->print(format_buffer, cp);
  52.251 -         st->cr();
  52.252 -         cp = eol+1;
  52.253 -         st->print("%5s %-35s += ", "", name);
  52.254 -       }
  52.255 -       st->print("%-16s", cp);
  52.256 -     }
  52.257 -     else st->print("%-16s", "");
  52.258 +    const char* cp = get_ccstr();
  52.259 +    if (cp != NULL) {
  52.260 +      const char* eol;
  52.261 +      while ((eol = strchr(cp, '\n')) != NULL) {
  52.262 +        char format_buffer[FORMAT_BUFFER_LEN];
  52.263 +        size_t llen = pointer_delta(eol, cp, sizeof(char));
  52.264 +        jio_snprintf(format_buffer, FORMAT_BUFFER_LEN,
  52.265 +            "%%." SIZE_FORMAT "s", llen);
  52.266 +        st->print(format_buffer, cp);
  52.267 +        st->cr();
  52.268 +        cp = eol+1;
  52.269 +        st->print("%5s %-35s += ", "", _name);
  52.270 +      }
  52.271 +      st->print("%-16s", cp);
  52.272 +    }
  52.273 +    else st->print("%-16s", "");
  52.274    }
  52.275 -  st->print("%-20s", kind);
  52.276 +
  52.277 +  st->print("%-20");
  52.278 +  print_kind(st);
  52.279 +
  52.280    if (withComments) {
  52.281  #ifndef PRODUCT
  52.282 -    st->print("%s", doc );
  52.283 +    st->print("%s", _doc);
  52.284  #endif
  52.285    }
  52.286    st->cr();
  52.287  }
  52.288  
  52.289 +void Flag::print_kind(outputStream* st) {
  52.290 +  struct Data {
  52.291 +    int flag;
  52.292 +    const char* name;
  52.293 +  };
  52.294 +
  52.295 +  Data data[] = {
  52.296 +      { KIND_C1, "C1" },
  52.297 +      { KIND_C2, "C2" },
  52.298 +      { KIND_ARCH, "ARCH" },
  52.299 +      { KIND_SHARK, "SHARK" },
  52.300 +      { KIND_PLATFORM_DEPENDENT, "pd" },
  52.301 +      { KIND_PRODUCT, "product" },
  52.302 +      { KIND_MANAGEABLE, "manageable" },
  52.303 +      { KIND_DIAGNOSTIC, "diagnostic" },
  52.304 +      { KIND_NOT_PRODUCT, "notproduct" },
  52.305 +      { KIND_DEVELOP, "develop" },
  52.306 +      { KIND_LP64_PRODUCT, "lp64_product" },
  52.307 +      { KIND_READ_WRITE, "rw" },
  52.308 +      { -1, "" }
  52.309 +  };
  52.310 +
  52.311 +  if ((_flags & KIND_MASK) != 0) {
  52.312 +    st->print("{");
  52.313 +    bool is_first = true;
  52.314 +
  52.315 +    for (int i = 0; data[i].flag != -1; i++) {
  52.316 +      Data d = data[i];
  52.317 +      if ((_flags & d.flag) != 0) {
  52.318 +        if (is_first) {
  52.319 +          is_first = false;
  52.320 +        } else {
  52.321 +          st->print(" ");
  52.322 +        }
  52.323 +        st->print(d.name);
  52.324 +      }
  52.325 +    }
  52.326 +
  52.327 +    st->print("}");
  52.328 +  }
  52.329 +}
  52.330 +
  52.331  void Flag::print_as_flag(outputStream* st) {
  52.332    if (is_bool()) {
  52.333 -    st->print("-XX:%s%s", get_bool() ? "+" : "-", name);
  52.334 +    st->print("-XX:%s%s", get_bool() ? "+" : "-", _name);
  52.335    } else if (is_intx()) {
  52.336 -    st->print("-XX:%s=" INTX_FORMAT, name, get_intx());
  52.337 +    st->print("-XX:%s=" INTX_FORMAT, _name, get_intx());
  52.338    } else if (is_uintx()) {
  52.339 -    st->print("-XX:%s=" UINTX_FORMAT, name, get_uintx());
  52.340 +    st->print("-XX:%s=" UINTX_FORMAT, _name, get_uintx());
  52.341    } else if (is_uint64_t()) {
  52.342 -    st->print("-XX:%s=" UINT64_FORMAT, name, get_uint64_t());
  52.343 +    st->print("-XX:%s=" UINT64_FORMAT, _name, get_uint64_t());
  52.344    } else if (is_double()) {
  52.345 -    st->print("-XX:%s=%f", name, get_double());
  52.346 +    st->print("-XX:%s=%f", _name, get_double());
  52.347    } else if (is_ccstr()) {
  52.348 -    st->print("-XX:%s=", name);
  52.349 +    st->print("-XX:%s=", _name);
  52.350      const char* cp = get_ccstr();
  52.351      if (cp != NULL) {
  52.352        // Need to turn embedded '\n's back into separate arguments
  52.353 @@ -167,7 +373,7 @@
  52.354              st->print("%c", *cp);
  52.355              break;
  52.356            case '\n':
  52.357 -            st->print(" -XX:%s=", name);
  52.358 +            st->print(" -XX:%s=", _name);
  52.359              break;
  52.360          }
  52.361        }
  52.362 @@ -180,79 +386,51 @@
  52.363  // 4991491 do not "optimize out" the was_set false values: omitting them
  52.364  // tickles a Microsoft compiler bug causing flagTable to be malformed
  52.365  
  52.366 -#define RUNTIME_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{product}", DEFAULT },
  52.367 -#define RUNTIME_PD_PRODUCT_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{pd product}", DEFAULT },
  52.368 -#define RUNTIME_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{diagnostic}", DEFAULT },
  52.369 -#define RUNTIME_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{experimental}", DEFAULT },
  52.370 -#define RUNTIME_MANAGEABLE_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{manageable}", DEFAULT },
  52.371 -#define RUNTIME_PRODUCT_RW_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{product rw}", DEFAULT },
  52.372 +#define NAME(name) NOT_PRODUCT(&name) PRODUCT_ONLY(&CONST_##name)
  52.373  
  52.374 -#ifdef PRODUCT
  52.375 -  #define RUNTIME_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
  52.376 -  #define RUNTIME_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     /* flag is constant */
  52.377 -  #define RUNTIME_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc)
  52.378 -#else
  52.379 -  #define RUNTIME_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "", DEFAULT },
  52.380 -  #define RUNTIME_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, doc, "{pd}", DEFAULT },
  52.381 -  #define RUNTIME_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{notproduct}", DEFAULT },
  52.382 -#endif
  52.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) },
  52.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) },
  52.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) },
  52.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) },
  52.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) },
  52.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) },
  52.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) },
  52.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) },
  52.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) },
  52.392  
  52.393  #ifdef _LP64
  52.394 -  #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{lp64_product}", DEFAULT },
  52.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) },
  52.396  #else
  52.397 -  #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
  52.398 +#define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
  52.399  #endif // _LP64
  52.400  
  52.401 -#define C1_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C1 product}", DEFAULT },
  52.402 -#define C1_PD_PRODUCT_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C1 pd product}", DEFAULT },
  52.403 -#define C1_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C1 diagnostic}", DEFAULT },
  52.404 -#ifdef PRODUCT
  52.405 -  #define C1_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
  52.406 -  #define C1_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     /* flag is constant */
  52.407 -  #define C1_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc)
  52.408 -#else
  52.409 -  #define C1_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C1}", DEFAULT },
  52.410 -  #define C1_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, doc, "{C1 pd}", DEFAULT },
  52.411 -  #define C1_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C1 notproduct}", DEFAULT },
  52.412 -#endif
  52.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) },
  52.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) },
  52.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) },
  52.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) },
  52.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) },
  52.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) },
  52.419  
  52.420 -#define C2_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 product}", DEFAULT },
  52.421 -#define C2_PD_PRODUCT_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 pd product}", DEFAULT },
  52.422 -#define C2_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 diagnostic}", DEFAULT },
  52.423 -#define C2_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 experimental}", DEFAULT },
  52.424 -#ifdef PRODUCT
  52.425 -  #define C2_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
  52.426 -  #define C2_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     /* flag is constant */
  52.427 -  #define C2_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc)
  52.428 -#else
  52.429 -  #define C2_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C2}", DEFAULT },
  52.430 -  #define C2_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, doc, "{C2 pd}", DEFAULT },
  52.431 -  #define C2_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C2 notproduct}", DEFAULT },
  52.432 -#endif
  52.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) },
  52.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) },
  52.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) },
  52.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) },
  52.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) },
  52.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) },
  52.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) },
  52.440  
  52.441 -#define ARCH_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{ARCH product}", DEFAULT },
  52.442 -#define ARCH_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{ARCH diagnostic}", DEFAULT },
  52.443 -#define ARCH_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{ARCH experimental}", DEFAULT },
  52.444 -#ifdef PRODUCT
  52.445 -  #define ARCH_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
  52.446 -  #define ARCH_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc)
  52.447 -#else
  52.448 -  #define ARCH_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{ARCH}", DEFAULT },
  52.449 -  #define ARCH_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{ARCH notproduct}", DEFAULT },
  52.450 -#endif
  52.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) },
  52.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) },
  52.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) },
  52.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) },
  52.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) },
  52.456  
  52.457 -#define SHARK_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{Shark product}", DEFAULT },
  52.458 -#define SHARK_PD_PRODUCT_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{Shark pd product}", DEFAULT },
  52.459 -#define SHARK_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{Shark diagnostic}", DEFAULT },
  52.460 -#ifdef PRODUCT
  52.461 -  #define SHARK_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
  52.462 -  #define SHARK_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     /* flag is constant */
  52.463 -  #define SHARK_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc)
  52.464 -#else
  52.465 -  #define SHARK_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{Shark}", DEFAULT },
  52.466 -  #define SHARK_PD_DEVELOP_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, doc, "{Shark pd}", DEFAULT },
  52.467 -  #define SHARK_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{Shark notproduct}", DEFAULT },
  52.468 -#endif
  52.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) },
  52.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) },
  52.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) },
  52.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) },
  52.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) },
  52.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) },
  52.475  
  52.476  static Flag flagTable[] = {
  52.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)
  52.478 @@ -285,9 +463,14 @@
  52.479  
  52.480  // Search the flag table for a named flag
  52.481  Flag* Flag::find_flag(const char* name, size_t length, bool allow_locked) {
  52.482 -  for (Flag* current = &flagTable[0]; current->name != NULL; current++) {
  52.483 -    if (str_equal(current->name, name, length)) {
  52.484 -      // Found a matching entry.  Report locked flags only if allowed.
  52.485 +  for (Flag* current = &flagTable[0]; current->_name != NULL; current++) {
  52.486 +    if (str_equal(current->_name, name, length)) {
  52.487 +      // Found a matching entry.
  52.488 +      // Don't report notproduct and develop flags in product builds.
  52.489 +      if (current->is_constant_in_binary()) {
  52.490 +        return NULL;
  52.491 +      }
  52.492 +      // Report locked flags only if allowed.
  52.493        if (!(current->is_unlocked() || current->is_unlocker())) {
  52.494          if (!allow_locked) {
  52.495            // disable use of locked flags, e.g. diagnostic, experimental,
  52.496 @@ -327,8 +510,8 @@
  52.497    float score;
  52.498    float max_score = -1;
  52.499  
  52.500 -  for (Flag* current = &flagTable[0]; current->name != NULL; current++) {
  52.501 -    score = str_similar(current->name, name, length);
  52.502 +  for (Flag* current = &flagTable[0]; current->_name != NULL; current++) {
  52.503 +    score = str_similar(current->_name, name, length);
  52.504      if (score > max_score) {
  52.505        max_score = score;
  52.506        match = current;
  52.507 @@ -357,25 +540,25 @@
  52.508  bool CommandLineFlagsEx::is_default(CommandLineFlag flag) {
  52.509    assert((size_t)flag < Flag::numFlags, "bad command line flag index");
  52.510    Flag* f = &Flag::flags[flag];
  52.511 -  return (f->origin == DEFAULT);
  52.512 +  return f->is_default();
  52.513  }
  52.514  
  52.515  bool CommandLineFlagsEx::is_ergo(CommandLineFlag flag) {
  52.516    assert((size_t)flag < Flag::numFlags, "bad command line flag index");
  52.517    Flag* f = &Flag::flags[flag];
  52.518 -  return (f->origin == ERGONOMIC);
  52.519 +  return f->is_ergonomic();
  52.520  }
  52.521  
  52.522  bool CommandLineFlagsEx::is_cmdline(CommandLineFlag flag) {
  52.523    assert((size_t)flag < Flag::numFlags, "bad command line flag index");
  52.524    Flag* f = &Flag::flags[flag];
  52.525 -  return (f->origin == COMMAND_LINE);
  52.526 +  return f->is_command_line();
  52.527  }
  52.528  
  52.529  bool CommandLineFlags::wasSetOnCmdline(const char* name, bool* value) {
  52.530    Flag* result = Flag::find_flag((char*)name, strlen(name));
  52.531    if (result == NULL) return false;
  52.532 -  *value = (result->origin == COMMAND_LINE);
  52.533 +  *value = result->is_command_line();
  52.534    return true;
  52.535  }
  52.536  
  52.537 @@ -387,22 +570,22 @@
  52.538    return true;
  52.539  }
  52.540  
  52.541 -bool CommandLineFlags::boolAtPut(char* name, size_t len, bool* value, FlagValueOrigin origin) {
  52.542 +bool CommandLineFlags::boolAtPut(char* name, size_t len, bool* value, Flag::Flags origin) {
  52.543    Flag* result = Flag::find_flag(name, len);
  52.544    if (result == NULL) return false;
  52.545    if (!result->is_bool()) return false;
  52.546    bool old_value = result->get_bool();
  52.547    result->set_bool(*value);
  52.548    *value = old_value;
  52.549 -  result->origin = origin;
  52.550 +  result->set_origin(origin);
  52.551    return true;
  52.552  }
  52.553  
  52.554 -void CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, FlagValueOrigin origin) {
  52.555 +void CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, Flag::Flags origin) {
  52.556    Flag* faddr = address_of_flag(flag);
  52.557    guarantee(faddr != NULL && faddr->is_bool(), "wrong flag type");
  52.558    faddr->set_bool(value);
  52.559 -  faddr->origin = origin;
  52.560 +  faddr->set_origin(origin);
  52.561  }
  52.562  
  52.563  bool CommandLineFlags::intxAt(char* name, size_t len, intx* value) {
  52.564 @@ -413,22 +596,22 @@
  52.565    return true;
  52.566  }
  52.567  
  52.568 -bool CommandLineFlags::intxAtPut(char* name, size_t len, intx* value, FlagValueOrigin origin) {
  52.569 +bool CommandLineFlags::intxAtPut(char* name, size_t len, intx* value, Flag::Flags origin) {
  52.570    Flag* result = Flag::find_flag(name, len);
  52.571    if (result == NULL) return false;
  52.572    if (!result->is_intx()) return false;
  52.573    intx old_value = result->get_intx();
  52.574    result->set_intx(*value);
  52.575    *value = old_value;
  52.576 -  result->origin = origin;
  52.577 +  result->set_origin(origin);
  52.578    return true;
  52.579  }
  52.580  
  52.581 -void CommandLineFlagsEx::intxAtPut(CommandLineFlagWithType flag, intx value, FlagValueOrigin origin) {
  52.582 +void CommandLineFlagsEx::intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin) {
  52.583    Flag* faddr = address_of_flag(flag);
  52.584    guarantee(faddr != NULL && faddr->is_intx(), "wrong flag type");
  52.585    faddr->set_intx(value);
  52.586 -  faddr->origin = origin;
  52.587 +  faddr->set_origin(origin);
  52.588  }
  52.589  
  52.590  bool CommandLineFlags::uintxAt(char* name, size_t len, uintx* value) {
  52.591 @@ -439,22 +622,22 @@
  52.592    return true;
  52.593  }
  52.594  
  52.595 -bool CommandLineFlags::uintxAtPut(char* name, size_t len, uintx* value, FlagValueOrigin origin) {
  52.596 +bool CommandLineFlags::uintxAtPut(char* name, size_t len, uintx* value, Flag::Flags origin) {
  52.597    Flag* result = Flag::find_flag(name, len);
  52.598    if (result == NULL) return false;
  52.599    if (!result->is_uintx()) return false;
  52.600    uintx old_value = result->get_uintx();
  52.601    result->set_uintx(*value);
  52.602    *value = old_value;
  52.603 -  result->origin = origin;
  52.604 +  result->set_origin(origin);
  52.605    return true;
  52.606  }
  52.607  
  52.608 -void CommandLineFlagsEx::uintxAtPut(CommandLineFlagWithType flag, uintx value, FlagValueOrigin origin) {
  52.609 +void CommandLineFlagsEx::uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin) {
  52.610    Flag* faddr = address_of_flag(flag);
  52.611    guarantee(faddr != NULL && faddr->is_uintx(), "wrong flag type");
  52.612    faddr->set_uintx(value);
  52.613 -  faddr->origin = origin;
  52.614 +  faddr->set_origin(origin);
  52.615  }
  52.616  
  52.617  bool CommandLineFlags::uint64_tAt(char* name, size_t len, uint64_t* value) {
  52.618 @@ -465,22 +648,22 @@
  52.619    return true;
  52.620  }
  52.621  
  52.622 -bool CommandLineFlags::uint64_tAtPut(char* name, size_t len, uint64_t* value, FlagValueOrigin origin) {
  52.623 +bool CommandLineFlags::uint64_tAtPut(char* name, size_t len, uint64_t* value, Flag::Flags origin) {
  52.624    Flag* result = Flag::find_flag(name, len);
  52.625    if (result == NULL) return false;
  52.626    if (!result->is_uint64_t()) return false;
  52.627    uint64_t old_value = result->get_uint64_t();
  52.628    result->set_uint64_t(*value);
  52.629    *value = old_value;
  52.630 -  result->origin = origin;
  52.631 +  result->set_origin(origin);
  52.632    return true;
  52.633  }
  52.634  
  52.635 -void CommandLineFlagsEx::uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, FlagValueOrigin origin) {
  52.636 +void CommandLineFlagsEx::uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin) {
  52.637    Flag* faddr = address_of_flag(flag);
  52.638    guarantee(faddr != NULL && faddr->is_uint64_t(), "wrong flag type");
  52.639    faddr->set_uint64_t(value);
  52.640 -  faddr->origin = origin;
  52.641 +  faddr->set_origin(origin);
  52.642  }
  52.643  
  52.644  bool CommandLineFlags::doubleAt(char* name, size_t len, double* value) {
  52.645 @@ -491,22 +674,22 @@
  52.646    return true;
  52.647  }
  52.648  
  52.649 -bool CommandLineFlags::doubleAtPut(char* name, size_t len, double* value, FlagValueOrigin origin) {
  52.650 +bool CommandLineFlags::doubleAtPut(char* name, size_t len, double* value, Flag::Flags origin) {
  52.651    Flag* result = Flag::find_flag(name, len);
  52.652    if (result == NULL) return false;
  52.653    if (!result->is_double()) return false;
  52.654    double old_value = result->get_double();
  52.655    result->set_double(*value);
  52.656    *value = old_value;
  52.657 -  result->origin = origin;
  52.658 +  result->set_origin(origin);
  52.659    return true;
  52.660  }
  52.661  
  52.662 -void CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value, FlagValueOrigin origin) {
  52.663 +void CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin) {
  52.664    Flag* faddr = address_of_flag(flag);
  52.665    guarantee(faddr != NULL && faddr->is_double(), "wrong flag type");
  52.666    faddr->set_double(value);
  52.667 -  faddr->origin = origin;
  52.668 +  faddr->set_origin(origin);
  52.669  }
  52.670  
  52.671  bool CommandLineFlags::ccstrAt(char* name, size_t len, ccstr* value) {
  52.672 @@ -519,7 +702,7 @@
  52.673  
  52.674  // Contract:  Flag will make private copy of the incoming value.
  52.675  // Outgoing value is always malloc-ed, and caller MUST call free.
  52.676 -bool CommandLineFlags::ccstrAtPut(char* name, size_t len, ccstr* value, FlagValueOrigin origin) {
  52.677 +bool CommandLineFlags::ccstrAtPut(char* name, size_t len, ccstr* value, Flag::Flags origin) {
  52.678    Flag* result = Flag::find_flag(name, len);
  52.679    if (result == NULL) return false;
  52.680    if (!result->is_ccstr()) return false;
  52.681 @@ -530,35 +713,35 @@
  52.682      strcpy(new_value, *value);
  52.683    }
  52.684    result->set_ccstr(new_value);
  52.685 -  if (result->origin == DEFAULT && old_value != NULL) {
  52.686 +  if (result->is_default() && old_value != NULL) {
  52.687      // Prior value is NOT heap allocated, but was a literal constant.
  52.688      char* old_value_to_free = NEW_C_HEAP_ARRAY(char, strlen(old_value)+1, mtInternal);
  52.689      strcpy(old_value_to_free, old_value);
  52.690      old_value = old_value_to_free;
  52.691    }
  52.692    *value = old_value;
  52.693 -  result->origin = origin;
  52.694 +  result->set_origin(origin);
  52.695    return true;
  52.696  }
  52.697  
  52.698  // Contract:  Flag will make private copy of the incoming value.
  52.699 -void CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, FlagValueOrigin origin) {
  52.700 +void CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin) {
  52.701    Flag* faddr = address_of_flag(flag);
  52.702    guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type");
  52.703    ccstr old_value = faddr->get_ccstr();
  52.704    char* new_value = NEW_C_HEAP_ARRAY(char, strlen(value)+1, mtInternal);
  52.705    strcpy(new_value, value);
  52.706    faddr->set_ccstr(new_value);
  52.707 -  if (faddr->origin != DEFAULT && old_value != NULL) {
  52.708 +  if (!faddr->is_default() && old_value != NULL) {
  52.709      // Prior value is heap allocated so free it.
  52.710      FREE_C_HEAP_ARRAY(char, old_value, mtInternal);
  52.711    }
  52.712 -  faddr->origin = origin;
  52.713 +  faddr->set_origin(origin);
  52.714  }
  52.715  
  52.716  extern "C" {
  52.717    static int compare_flags(const void* void_a, const void* void_b) {
  52.718 -    return strcmp((*((Flag**) void_a))->name, (*((Flag**) void_b))->name);
  52.719 +    return strcmp((*((Flag**) void_a))->_name, (*((Flag**) void_b))->_name);
  52.720    }
  52.721  }
  52.722  
  52.723 @@ -567,20 +750,19 @@
  52.724    // note: this method is called before the thread structure is in place
  52.725    //       which means resource allocation cannot be used.
  52.726  
  52.727 -  // Compute size
  52.728 -  int length= 0;
  52.729 -  while (flagTable[length].name != NULL) length++;
  52.730 +  // The last entry is the null entry.
  52.731 +  const size_t length = Flag::numFlags - 1;
  52.732  
  52.733    // Sort
  52.734    Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal);
  52.735 -  for (int index = 0; index < length; index++) {
  52.736 -    array[index] = &flagTable[index];
  52.737 +  for (size_t i = 0; i < length; i++) {
  52.738 +    array[i] = &flagTable[i];
  52.739    }
  52.740    qsort(array, length, sizeof(Flag*), compare_flags);
  52.741  
  52.742    // Print
  52.743 -  for (int i = 0; i < length; i++) {
  52.744 -    if (array[i]->origin /* naked field! */) {
  52.745 +  for (size_t i = 0; i < length; i++) {
  52.746 +    if (array[i]->get_origin() /* naked field! */) {
  52.747        array[i]->print_as_flag(out);
  52.748        out->print(" ");
  52.749      }
  52.750 @@ -603,20 +785,19 @@
  52.751    // note: this method is called before the thread structure is in place
  52.752    //       which means resource allocation cannot be used.
  52.753  
  52.754 -  // Compute size
  52.755 -  int length= 0;
  52.756 -  while (flagTable[length].name != NULL) length++;
  52.757 +  // The last entry is the null entry.
  52.758 +  const size_t length = Flag::numFlags - 1;
  52.759  
  52.760    // Sort
  52.761    Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal);
  52.762 -  for (int index = 0; index < length; index++) {
  52.763 -    array[index] = &flagTable[index];
  52.764 +  for (size_t i = 0; i < length; i++) {
  52.765 +    array[i] = &flagTable[i];
  52.766    }
  52.767    qsort(array, length, sizeof(Flag*), compare_flags);
  52.768  
  52.769    // Print
  52.770    out->print_cr("[Global flags]");
  52.771 -  for (int i = 0; i < length; i++) {
  52.772 +  for (size_t i = 0; i < length; i++) {
  52.773      if (array[i]->is_unlocked()) {
  52.774        array[i]->print_on(out, withComments);
  52.775      }
    53.1 --- a/src/share/vm/runtime/globals.hpp	Tue Oct 01 11:06:35 2013 -0400
    53.2 +++ b/src/share/vm/runtime/globals.hpp	Thu Oct 03 16:38:21 2013 +0400
    53.3 @@ -194,29 +194,49 @@
    53.4  typedef const char* ccstr;
    53.5  typedef const char* ccstrlist;   // represents string arguments which accumulate
    53.6  
    53.7 -enum FlagValueOrigin {
    53.8 -  DEFAULT          = 0,
    53.9 -  COMMAND_LINE     = 1,
   53.10 -  ENVIRON_VAR      = 2,
   53.11 -  CONFIG_FILE      = 3,
   53.12 -  MANAGEMENT       = 4,
   53.13 -  ERGONOMIC        = 5,
   53.14 -  ATTACH_ON_DEMAND = 6,
   53.15 -  INTERNAL         = 99
   53.16 -};
   53.17 +struct Flag {
   53.18 +  enum Flags {
   53.19 +    // value origin
   53.20 +    DEFAULT          = 0,
   53.21 +    COMMAND_LINE     = 1,
   53.22 +    ENVIRON_VAR      = 2,
   53.23 +    CONFIG_FILE      = 3,
   53.24 +    MANAGEMENT       = 4,
   53.25 +    ERGONOMIC        = 5,
   53.26 +    ATTACH_ON_DEMAND = 6,
   53.27 +    INTERNAL         = 7,
   53.28  
   53.29 -struct Flag {
   53.30 -  const char *type;
   53.31 -  const char *name;
   53.32 -  void*       addr;
   53.33 +    LAST_VALUE_ORIGIN = INTERNAL,
   53.34 +    VALUE_ORIGIN_BITS = 4,
   53.35 +    VALUE_ORIGIN_MASK = right_n_bits(VALUE_ORIGIN_BITS),
   53.36  
   53.37 -  NOT_PRODUCT(const char *doc;)
   53.38 +    // flag kind
   53.39 +    KIND_PRODUCT            = 1 << 4,
   53.40 +    KIND_MANAGEABLE         = 1 << 5,
   53.41 +    KIND_DIAGNOSTIC         = 1 << 6,
   53.42 +    KIND_EXPERIMENTAL       = 1 << 7,
   53.43 +    KIND_NOT_PRODUCT        = 1 << 8,
   53.44 +    KIND_DEVELOP            = 1 << 9,
   53.45 +    KIND_PLATFORM_DEPENDENT = 1 << 10,
   53.46 +    KIND_READ_WRITE         = 1 << 11,
   53.47 +    KIND_C1                 = 1 << 12,
   53.48 +    KIND_C2                 = 1 << 13,
   53.49 +    KIND_ARCH               = 1 << 14,
   53.50 +    KIND_SHARK              = 1 << 15,
   53.51 +    KIND_LP64_PRODUCT       = 1 << 16,
   53.52 +    KIND_COMMERCIAL         = 1 << 17,
   53.53  
   53.54 -  const char *kind;
   53.55 -  FlagValueOrigin origin;
   53.56 +    KIND_MASK = ~VALUE_ORIGIN_MASK
   53.57 +  };
   53.58 +
   53.59 +  const char* _type;
   53.60 +  const char* _name;
   53.61 +  void* _addr;
   53.62 +  NOT_PRODUCT(const char* _doc;)
   53.63 +  Flags _flags;
   53.64  
   53.65    // points to all Flags static array
   53.66 -  static Flag *flags;
   53.67 +  static Flag* flags;
   53.68  
   53.69    // number of flags
   53.70    static size_t numFlags;
   53.71 @@ -224,30 +244,50 @@
   53.72    static Flag* find_flag(const char* name, size_t length, bool allow_locked = false);
   53.73    static Flag* fuzzy_match(const char* name, size_t length, bool allow_locked = false);
   53.74  
   53.75 -  bool is_bool() const        { return strcmp(type, "bool") == 0; }
   53.76 -  bool get_bool() const       { return *((bool*) addr); }
   53.77 -  void set_bool(bool value)   { *((bool*) addr) = value; }
   53.78 +  void check_writable();
   53.79  
   53.80 -  bool is_intx()  const       { return strcmp(type, "intx")  == 0; }
   53.81 -  intx get_intx() const       { return *((intx*) addr); }
   53.82 -  void set_intx(intx value)   { *((intx*) addr) = value; }
   53.83 +  bool is_bool() const;
   53.84 +  bool get_bool() const;
   53.85 +  void set_bool(bool value);
   53.86  
   53.87 -  bool is_uintx() const       { return strcmp(type, "uintx") == 0; }
   53.88 -  uintx get_uintx() const     { return *((uintx*) addr); }
   53.89 -  void set_uintx(uintx value) { *((uintx*) addr) = value; }
   53.90 +  bool is_intx() const;
   53.91 +  intx get_intx() const;
   53.92 +  void set_intx(intx value);
   53.93  
   53.94 -  bool is_uint64_t() const          { return strcmp(type, "uint64_t") == 0; }
   53.95 -  uint64_t get_uint64_t() const     { return *((uint64_t*) addr); }
   53.96 -  void set_uint64_t(uint64_t value) { *((uint64_t*) addr) = value; }
   53.97 +  bool is_uintx() const;
   53.98 +  uintx get_uintx() const;
   53.99 +  void set_uintx(uintx value);
  53.100  
  53.101 -  bool is_double() const        { return strcmp(type, "double") == 0; }
  53.102 -  double get_double() const     { return *((double*) addr); }
  53.103 -  void set_double(double value) { *((double*) addr) = value; }
  53.104 +  bool is_uint64_t() const;
  53.105 +  uint64_t get_uint64_t() const;
  53.106 +  void set_uint64_t(uint64_t value);
  53.107  
  53.108 -  bool is_ccstr() const          { return strcmp(type, "ccstr") == 0 || strcmp(type, "ccstrlist") == 0; }
  53.109 -  bool ccstr_accumulates() const { return strcmp(type, "ccstrlist") == 0; }
  53.110 -  ccstr get_ccstr() const     { return *((ccstr*) addr); }
  53.111 -  void set_ccstr(ccstr value) { *((ccstr*) addr) = value; }
  53.112 +  bool is_double() const;
  53.113 +  double get_double() const;
  53.114 +  void set_double(double value);
  53.115 +
  53.116 +  bool is_ccstr() const;
  53.117 +  bool ccstr_accumulates() const;
  53.118 +  ccstr get_ccstr() const;
  53.119 +  void set_ccstr(ccstr value);
  53.120 +
  53.121 +  Flags get_origin();
  53.122 +  void set_origin(Flags origin);
  53.123 +
  53.124 +  bool is_default();
  53.125 +  bool is_ergonomic();
  53.126 +  bool is_command_line();
  53.127 +
  53.128 +  bool is_product() const;
  53.129 +  bool is_manageable() const;
  53.130 +  bool is_diagnostic() const;
  53.131 +  bool is_experimental() const;
  53.132 +  bool is_notproduct() const;
  53.133 +  bool is_develop() const;
  53.134 +  bool is_read_write() const;
  53.135 +  bool is_commercial() const;
  53.136 +
  53.137 +  bool is_constant_in_binary() const;
  53.138  
  53.139    bool is_unlocker() const;
  53.140    bool is_unlocked() const;
  53.141 @@ -263,6 +303,7 @@
  53.142    void get_locked_message_ext(char*, int) const;
  53.143  
  53.144    void print_on(outputStream* st, bool withComments = false );
  53.145 +  void print_kind(outputStream* st);
  53.146    void print_as_flag(outputStream* st);
  53.147  };
  53.148  
  53.149 @@ -310,33 +351,33 @@
  53.150   public:
  53.151    static bool boolAt(char* name, size_t len, bool* value);
  53.152    static bool boolAt(char* name, bool* value)      { return boolAt(name, strlen(name), value); }
  53.153 -  static bool boolAtPut(char* name, size_t len, bool* value, FlagValueOrigin origin);
  53.154 -  static bool boolAtPut(char* name, bool* value, FlagValueOrigin origin)   { return boolAtPut(name, strlen(name), value, origin); }
  53.155 +  static bool boolAtPut(char* name, size_t len, bool* value, Flag::Flags origin);
  53.156 +  static bool boolAtPut(char* name, bool* value, Flag::Flags origin)   { return boolAtPut(name, strlen(name), value, origin); }
  53.157  
  53.158    static bool intxAt(char* name, size_t len, intx* value);
  53.159    static bool intxAt(char* name, intx* value)      { return intxAt(name, strlen(name), value); }
  53.160 -  static bool intxAtPut(char* name, size_t len, intx* value, FlagValueOrigin origin);
  53.161 -  static bool intxAtPut(char* name, intx* value, FlagValueOrigin origin)   { return intxAtPut(name, strlen(name), value, origin); }
  53.162 +  static bool intxAtPut(char* name, size_t len, intx* value, Flag::Flags origin);
  53.163 +  static bool intxAtPut(char* name, intx* value, Flag::Flags origin)   { return intxAtPut(name, strlen(name), value, origin); }
  53.164  
  53.165    static bool uintxAt(char* name, size_t len, uintx* value);
  53.166    static bool uintxAt(char* name, uintx* value)    { return uintxAt(name, strlen(name), value); }
  53.167 -  static bool uintxAtPut(char* name, size_t len, uintx* value, FlagValueOrigin origin);
  53.168 -  static bool uintxAtPut(char* name, uintx* value, FlagValueOrigin origin) { return uintxAtPut(name, strlen(name), value, origin); }
  53.169 +  static bool uintxAtPut(char* name, size_t len, uintx* value, Flag::Flags origin);
  53.170 +  static bool uintxAtPut(char* name, uintx* value, Flag::Flags origin) { return uintxAtPut(name, strlen(name), value, origin); }
  53.171  
  53.172    static bool uint64_tAt(char* name, size_t len, uint64_t* value);
  53.173    static bool uint64_tAt(char* name, uint64_t* value) { return uint64_tAt(name, strlen(name), value); }
  53.174 -  static bool uint64_tAtPut(char* name, size_t len, uint64_t* value, FlagValueOrigin origin);
  53.175 -  static bool uint64_tAtPut(char* name, uint64_t* value, FlagValueOrigin origin) { return uint64_tAtPut(name, strlen(name), value, origin); }
  53.176 +  static bool uint64_tAtPut(char* name, size_t len, uint64_t* value, Flag::Flags origin);
  53.177 +  static bool uint64_tAtPut(char* name, uint64_t* value, Flag::Flags origin) { return uint64_tAtPut(name, strlen(name), value, origin); }
  53.178  
  53.179    static bool doubleAt(char* name, size_t len, double* value);
  53.180    static bool doubleAt(char* name, double* value)    { return doubleAt(name, strlen(name), value); }
  53.181 -  static bool doubleAtPut(char* name, size_t len, double* value, FlagValueOrigin origin);
  53.182 -  static bool doubleAtPut(char* name, double* value, FlagValueOrigin origin) { return doubleAtPut(name, strlen(name), value, origin); }
  53.183 +  static bool doubleAtPut(char* name, size_t len, double* value, Flag::Flags origin);
  53.184 +  static bool doubleAtPut(char* name, double* value, Flag::Flags origin) { return doubleAtPut(name, strlen(name), value, origin); }
  53.185  
  53.186    static bool ccstrAt(char* name, size_t len, ccstr* value);
  53.187    static bool ccstrAt(char* name, ccstr* value)    { return ccstrAt(name, strlen(name), value); }
  53.188 -  static bool ccstrAtPut(char* name, size_t len, ccstr* value, FlagValueOrigin origin);
  53.189 -  static bool ccstrAtPut(char* name, ccstr* value, FlagValueOrigin origin) { return ccstrAtPut(name, strlen(name), value, origin); }
  53.190 +  static bool ccstrAtPut(char* name, size_t len, ccstr* value, Flag::Flags origin);
  53.191 +  static bool ccstrAtPut(char* name, ccstr* value, Flag::Flags origin) { return ccstrAtPut(name, strlen(name), value, origin); }
  53.192  
  53.193    // Returns false if name is not a command line flag.
  53.194    static bool wasSetOnCmdline(const char* name, bool* value);
  53.195 @@ -2830,6 +2871,10 @@
  53.196    product(intx, NmethodSweepCheckInterval, 5,                               \
  53.197            "Compilers wake up every n seconds to possibly sweep nmethods")   \
  53.198                                                                              \
  53.199 +  product(intx, NmethodSweepActivity, 10,                                   \
  53.200 +          "Removes cold nmethods from code cache if > 0. Higher values "    \
  53.201 +          "result in more aggressive sweeping")                             \
  53.202 +                                                                            \
  53.203    notproduct(bool, LogSweeper, false,                                       \
  53.204              "Keep a ring buffer of sweeper activity")                       \
  53.205                                                                              \
  53.206 @@ -3201,15 +3246,6 @@
  53.207    product(bool, UseCodeCacheFlushing, true,                                 \
  53.208            "Attempt to clean the code cache before shutting off compiler")   \
  53.209                                                                              \
  53.210 -  product(intx,  MinCodeCacheFlushingInterval, 30,                          \
  53.211 -          "Min number of seconds between code cache cleaning sessions")     \
  53.212 -                                                                            \
  53.213 -  product(uintx,  CodeCacheFlushingMinimumFreeSpace, 1500*K,                \
  53.214 -          "When less than X space left, start code cache cleaning")         \
  53.215 -                                                                            \
  53.216 -  product(uintx, CodeCacheFlushingFraction, 2,                              \
  53.217 -          "Fraction of the code cache that is flushed when full")           \
  53.218 -                                                                            \
  53.219    /* interpreter debugging */                                               \
  53.220    develop(intx, BinarySwitchThreshold, 5,                                   \
  53.221            "Minimal number of lookupswitch entries for rewriting to binary " \
  53.222 @@ -3730,20 +3766,20 @@
  53.223   */
  53.224  
  53.225  // Interface macros
  53.226 -#define DECLARE_PRODUCT_FLAG(type, name, value, doc)    extern "C" type name;
  53.227 -#define DECLARE_PD_PRODUCT_FLAG(type, name, doc)        extern "C" type name;
  53.228 -#define DECLARE_DIAGNOSTIC_FLAG(type, name, value, doc) extern "C" type name;
  53.229 +#define DECLARE_PRODUCT_FLAG(type, name, value, doc)      extern "C" type name;
  53.230 +#define DECLARE_PD_PRODUCT_FLAG(type, name, doc)          extern "C" type name;
  53.231 +#define DECLARE_DIAGNOSTIC_FLAG(type, name, value, doc)   extern "C" type name;
  53.232  #define DECLARE_EXPERIMENTAL_FLAG(type, name, value, doc) extern "C" type name;
  53.233 -#define DECLARE_MANAGEABLE_FLAG(type, name, value, doc) extern "C" type name;
  53.234 -#define DECLARE_PRODUCT_RW_FLAG(type, name, value, doc) extern "C" type name;
  53.235 +#define DECLARE_MANAGEABLE_FLAG(type, name, value, doc)   extern "C" type name;
  53.236 +#define DECLARE_PRODUCT_RW_FLAG(type, name, value, doc)   extern "C" type name;
  53.237  #ifdef PRODUCT
  53.238 -#define DECLARE_DEVELOPER_FLAG(type, name, value, doc)  const type name = value;
  53.239 -#define DECLARE_PD_DEVELOPER_FLAG(type, name, doc)      const type name = pd_##name;
  53.240 -#define DECLARE_NOTPRODUCT_FLAG(type, name, value, doc)
  53.241 +#define DECLARE_DEVELOPER_FLAG(type, name, value, doc)    extern "C" type CONST_##name; const type name = value;
  53.242 +#define DECLARE_PD_DEVELOPER_FLAG(type, name, doc)        extern "C" type CONST_##name; const type name = pd_##name;
  53.243 +#define DECLARE_NOTPRODUCT_FLAG(type, name, value, doc)   extern "C" type CONST_##name;
  53.244  #else
  53.245 -#define DECLARE_DEVELOPER_FLAG(type, name, value, doc)  extern "C" type name;
  53.246 -#define DECLARE_PD_DEVELOPER_FLAG(type, name, doc)      extern "C" type name;
  53.247 -#define DECLARE_NOTPRODUCT_FLAG(type, name, value, doc)  extern "C" type name;
  53.248 +#define DECLARE_DEVELOPER_FLAG(type, name, value, doc)    extern "C" type name;
  53.249 +#define DECLARE_PD_DEVELOPER_FLAG(type, name, doc)        extern "C" type name;
  53.250 +#define DECLARE_NOTPRODUCT_FLAG(type, name, value, doc)   extern "C" type name;
  53.251  #endif
  53.252  // Special LP64 flags, product only needed for now.
  53.253  #ifdef _LP64
  53.254 @@ -3753,23 +3789,23 @@
  53.255  #endif // _LP64
  53.256  
  53.257  // Implementation macros
  53.258 -#define MATERIALIZE_PRODUCT_FLAG(type, name, value, doc)   type name = value;
  53.259 -#define MATERIALIZE_PD_PRODUCT_FLAG(type, name, doc)       type name = pd_##name;
  53.260 -#define MATERIALIZE_DIAGNOSTIC_FLAG(type, name, value, doc) type name = value;
  53.261 +#define MATERIALIZE_PRODUCT_FLAG(type, name, value, doc)      type name = value;
  53.262 +#define MATERIALIZE_PD_PRODUCT_FLAG(type, name, doc)          type name = pd_##name;
  53.263 +#define MATERIALIZE_DIAGNOSTIC_FLAG(type, name, value, doc)   type name = value;
  53.264  #define MATERIALIZE_EXPERIMENTAL_FLAG(type, name, value, doc) type name = value;
  53.265 -#define MATERIALIZE_MANAGEABLE_FLAG(type, name, value, doc) type name = value;
  53.266 -#define MATERIALIZE_PRODUCT_RW_FLAG(type, name, value, doc) type name = value;
  53.267 +#define MATERIALIZE_MANAGEABLE_FLAG(type, name, value, doc)   type name = value;
  53.268 +#define MATERIALIZE_PRODUCT_RW_FLAG(type, name, value, doc)   type name = value;
  53.269  #ifdef PRODUCT
  53.270 -#define MATERIALIZE_DEVELOPER_FLAG(type, name, value, doc) /* flag name is constant */
  53.271 -#define MATERIALIZE_PD_DEVELOPER_FLAG(type, name, doc)     /* flag name is constant */
  53.272 -#define MATERIALIZE_NOTPRODUCT_FLAG(type, name, value, doc)
  53.273 +#define MATERIALIZE_DEVELOPER_FLAG(type, name, value, doc)    type CONST_##name = value;
  53.274 +#define MATERIALIZE_PD_DEVELOPER_FLAG(type, name, doc)        type CONST_##name = pd_##name;
  53.275 +#define MATERIALIZE_NOTPRODUCT_FLAG(type, name, value, doc)   type CONST_##name = value;
  53.276  #else
  53.277 -#define MATERIALIZE_DEVELOPER_FLAG(type, name, value, doc) type name = value;
  53.278 -#define MATERIALIZE_PD_DEVELOPER_FLAG(type, name, doc)     type name = pd_##name;
  53.279 -#define MATERIALIZE_NOTPRODUCT_FLAG(type, name, value, doc) type name = value;
  53.280 +#define MATERIALIZE_DEVELOPER_FLAG(type, name, value, doc)    type name = value;
  53.281 +#define MATERIALIZE_PD_DEVELOPER_FLAG(type, name, doc)        type name = pd_##name;
  53.282 +#define MATERIALIZE_NOTPRODUCT_FLAG(type, name, value, doc)   type name = value;
  53.283  #endif
  53.284  #ifdef _LP64
  53.285 -#define MATERIALIZE_LP64_PRODUCT_FLAG(type, name, value, doc)   type name = value;
  53.286 +#define MATERIALIZE_LP64_PRODUCT_FLAG(type, name, value, doc) type name = value;
  53.287  #else
  53.288  #define MATERIALIZE_LP64_PRODUCT_FLAG(type, name, value, doc) /* flag is constant */
  53.289  #endif // _LP64
    54.1 --- a/src/share/vm/runtime/globals_extension.hpp	Tue Oct 01 11:06:35 2013 -0400
    54.2 +++ b/src/share/vm/runtime/globals_extension.hpp	Thu Oct 03 16:38:21 2013 +0400
    54.3 @@ -34,64 +34,42 @@
    54.4  // Parens left off in the following for the enum decl below.
    54.5  #define FLAG_MEMBER(flag) Flag_##flag
    54.6  
    54.7 -#define RUNTIME_PRODUCT_FLAG_MEMBER(type, name, value, doc)    FLAG_MEMBER(name),
    54.8 -#define RUNTIME_PD_PRODUCT_FLAG_MEMBER(type, name, doc)        FLAG_MEMBER(name),
    54.9 -#define RUNTIME_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
   54.10 +#define RUNTIME_PRODUCT_FLAG_MEMBER(type, name, value, doc)      FLAG_MEMBER(name),
   54.11 +#define RUNTIME_PD_PRODUCT_FLAG_MEMBER(type, name, doc)          FLAG_MEMBER(name),
   54.12 +#define RUNTIME_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc)   FLAG_MEMBER(name),
   54.13  #define RUNTIME_EXPERIMENTAL_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
   54.14 -#define RUNTIME_MANAGEABLE_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
   54.15 -#define RUNTIME_PRODUCT_RW_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
   54.16 -#ifdef PRODUCT
   54.17 -  #define RUNTIME_DEVELOP_FLAG_MEMBER(type, name, value, doc)  /* flag is constant */
   54.18 -  #define RUNTIME_PD_DEVELOP_FLAG_MEMBER(type, name, doc)      /* flag is constant */
   54.19 -  #define RUNTIME_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)
   54.20 +#define RUNTIME_MANAGEABLE_FLAG_MEMBER(type, name, value, doc)   FLAG_MEMBER(name),
   54.21 +#define RUNTIME_PRODUCT_RW_FLAG_MEMBER(type, name, value, doc)   FLAG_MEMBER(name),
   54.22 +#define RUNTIME_DEVELOP_FLAG_MEMBER(type, name, value, doc)      FLAG_MEMBER(name),
   54.23 +#define RUNTIME_PD_DEVELOP_FLAG_MEMBER(type, name, doc)          FLAG_MEMBER(name),
   54.24 +#define RUNTIME_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)   FLAG_MEMBER(name),
   54.25 +
   54.26 +#ifdef _LP64
   54.27 +#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
   54.28  #else
   54.29 -  #define RUNTIME_DEVELOP_FLAG_MEMBER(type, name, value, doc)  FLAG_MEMBER(name),
   54.30 -  #define RUNTIME_PD_DEVELOP_FLAG_MEMBER(type, name, doc)      FLAG_MEMBER(name),
   54.31 -  #define RUNTIME_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
   54.32 -#endif
   54.33 -#ifdef _LP64
   54.34 -#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER(type, name, value, doc)    FLAG_MEMBER(name),
   54.35 -#else
   54.36 -#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER(type, name, value, doc)    /* flag is constant */
   54.37 +#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER(type, name, value, doc) /* flag is constant */
   54.38  #endif // _LP64
   54.39  
   54.40 -#define C1_PRODUCT_FLAG_MEMBER(type, name, value, doc)         FLAG_MEMBER(name),
   54.41 -#define C1_PD_PRODUCT_FLAG_MEMBER(type, name, doc)             FLAG_MEMBER(name),
   54.42 -#define C1_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc)      FLAG_MEMBER(name),
   54.43 -#ifdef PRODUCT
   54.44 -  #define C1_DEVELOP_FLAG_MEMBER(type, name, value, doc)       /* flag is constant */
   54.45 -  #define C1_PD_DEVELOP_FLAG_MEMBER(type, name, doc)           /* flag is constant */
   54.46 -  #define C1_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)
   54.47 -#else
   54.48 -  #define C1_DEVELOP_FLAG_MEMBER(type, name, value, doc)       FLAG_MEMBER(name),
   54.49 -  #define C1_PD_DEVELOP_FLAG_MEMBER(type, name, doc)           FLAG_MEMBER(name),
   54.50 -  #define C1_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)    FLAG_MEMBER(name),
   54.51 -#endif
   54.52 +#define C1_PRODUCT_FLAG_MEMBER(type, name, value, doc)           FLAG_MEMBER(name),
   54.53 +#define C1_PD_PRODUCT_FLAG_MEMBER(type, name, doc)               FLAG_MEMBER(name),
   54.54 +#define C1_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc)        FLAG_MEMBER(name),
   54.55 +#define C1_DEVELOP_FLAG_MEMBER(type, name, value, doc)           FLAG_MEMBER(name),
   54.56 +#define C1_PD_DEVELOP_FLAG_MEMBER(type, name, doc)               FLAG_MEMBER(name),
   54.57 +#define C1_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)        FLAG_MEMBER(name),
   54.58  
   54.59 -#define C2_PRODUCT_FLAG_MEMBER(type, name, value, doc)         FLAG_MEMBER(name),
   54.60 -#define C2_PD_PRODUCT_FLAG_MEMBER(type, name, doc)             FLAG_MEMBER(name),
   54.61 -#define C2_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc)      FLAG_MEMBER(name),
   54.62 -#define C2_EXPERIMENTAL_FLAG_MEMBER(type, name, value, doc)    FLAG_MEMBER(name),
   54.63 -#ifdef PRODUCT
   54.64 -  #define C2_DEVELOP_FLAG_MEMBER(type, name, value, doc)       /* flag is constant */
   54.65 -  #define C2_PD_DEVELOP_FLAG_MEMBER(type, name, doc)           /* flag is constant */
   54.66 -  #define C2_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)
   54.67 -#else
   54.68 -  #define C2_DEVELOP_FLAG_MEMBER(type, name, value, doc)       FLAG_MEMBER(name),
   54.69 -  #define C2_PD_DEVELOP_FLAG_MEMBER(type, name, doc)           FLAG_MEMBER(name),
   54.70 -  #define C2_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)    FLAG_MEMBER(name),
   54.71 -#endif
   54.72 +#define C2_PRODUCT_FLAG_MEMBER(type, name, value, doc)           FLAG_MEMBER(name),
   54.73 +#define C2_PD_PRODUCT_FLAG_MEMBER(type, name, doc)               FLAG_MEMBER(name),
   54.74 +#define C2_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc)        FLAG_MEMBER(name),
   54.75 +#define C2_EXPERIMENTAL_FLAG_MEMBER(type, name, value, doc)      FLAG_MEMBER(name),
   54.76 +#define C2_DEVELOP_FLAG_MEMBER(type, name, value, doc)           FLAG_MEMBER(name),
   54.77 +#define C2_PD_DEVELOP_FLAG_MEMBER(type, name, doc)               FLAG_MEMBER(name),
   54.78 +#define C2_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)        FLAG_MEMBER(name),
   54.79  
   54.80  #define ARCH_PRODUCT_FLAG_MEMBER(type, name, value, doc)         FLAG_MEMBER(name),
   54.81  #define ARCH_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc)      FLAG_MEMBER(name),
   54.82  #define ARCH_EXPERIMENTAL_FLAG_MEMBER(type, name, value, doc)    FLAG_MEMBER(name),
   54.83 -#ifdef PRODUCT
   54.84 -  #define ARCH_DEVELOP_FLAG_MEMBER(type, name, value, doc)       /* flag is constant */
   54.85 -  #define ARCH_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)
   54.86 -#else
   54.87 -  #define ARCH_DEVELOP_FLAG_MEMBER(type, name, value, doc)       FLAG_MEMBER(name),
   54.88 -  #define ARCH_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)    FLAG_MEMBER(name),
   54.89 -#endif
   54.90 +#define ARCH_DEVELOP_FLAG_MEMBER(type, name, value, doc)         FLAG_MEMBER(name),
   54.91 +#define ARCH_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)      FLAG_MEMBER(name),
   54.92  
   54.93  typedef enum {
   54.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)
   54.95 @@ -114,64 +92,42 @@
   54.96  
   54.97  #define FLAG_MEMBER_WITH_TYPE(flag,type) Flag_##flag##_##type
   54.98  
   54.99 -#define RUNTIME_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)    FLAG_MEMBER_WITH_TYPE(name,type),
  54.100 -#define RUNTIME_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc)        FLAG_MEMBER_WITH_TYPE(name,type),
  54.101 -#define RUNTIME_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
  54.102 +#define RUNTIME_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)      FLAG_MEMBER_WITH_TYPE(name,type),
  54.103 +#define RUNTIME_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc)          FLAG_MEMBER_WITH_TYPE(name,type),
  54.104 +#define RUNTIME_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)   FLAG_MEMBER_WITH_TYPE(name,type),
  54.105  #define RUNTIME_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
  54.106 -#define RUNTIME_MANAGEABLE_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
  54.107 -#define RUNTIME_PRODUCT_RW_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
  54.108 -#ifdef PRODUCT
  54.109 -  #define RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)     /* flag is constant */
  54.110 -  #define RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc)         /* flag is constant */
  54.111 -  #define RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)
  54.112 +#define RUNTIME_MANAGEABLE_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)   FLAG_MEMBER_WITH_TYPE(name,type),
  54.113 +#define RUNTIME_PRODUCT_RW_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)   FLAG_MEMBER_WITH_TYPE(name,type),
  54.114 +#define RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)      FLAG_MEMBER_WITH_TYPE(name,type),
  54.115 +#define RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc)          FLAG_MEMBER_WITH_TYPE(name,type),
  54.116 +#define RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)   FLAG_MEMBER_WITH_TYPE(name,type),
  54.117 +
  54.118 +#define C1_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)           FLAG_MEMBER_WITH_TYPE(name,type),
  54.119 +#define C1_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc)               FLAG_MEMBER_WITH_TYPE(name,type),
  54.120 +#define C1_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)        FLAG_MEMBER_WITH_TYPE(name,type),
  54.121 +#define C1_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)           FLAG_MEMBER_WITH_TYPE(name,type),
  54.122 +#define C1_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc)               FLAG_MEMBER_WITH_TYPE(name,type),
  54.123 +#define C1_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)        FLAG_MEMBER_WITH_TYPE(name,type),
  54.124 +
  54.125 +#ifdef _LP64
  54.126 +#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
  54.127  #else
  54.128 -  #define RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)     FLAG_MEMBER_WITH_TYPE(name,type),
  54.129 -  #define RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc)         FLAG_MEMBER_WITH_TYPE(name,type),
  54.130 -  #define RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)  FLAG_MEMBER_WITH_TYPE(name,type),
  54.131 -#endif
  54.132 -
  54.133 -#define C1_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)         FLAG_MEMBER_WITH_TYPE(name,type),
  54.134 -#define C1_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc)             FLAG_MEMBER_WITH_TYPE(name,type),
  54.135 -#define C1_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)      FLAG_MEMBER_WITH_TYPE(name,type),
  54.136 -#ifdef PRODUCT
  54.137 -  #define C1_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)       /* flag is constant */
  54.138 -  #define C1_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc)           /* flag is constant */
  54.139 -  #define C1_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)
  54.140 -#else
  54.141 -  #define C1_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)       FLAG_MEMBER_WITH_TYPE(name,type),
  54.142 -  #define C1_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc)           FLAG_MEMBER_WITH_TYPE(name,type),
  54.143 -  #define C1_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)    FLAG_MEMBER_WITH_TYPE(name,type),
  54.144 -#endif
  54.145 -#ifdef _LP64
  54.146 -#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)    FLAG_MEMBER_WITH_TYPE(name,type),
  54.147 -#else
  54.148 -#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)    /* flag is constant */
  54.149 +#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) /* flag is constant */
  54.150  #endif // _LP64
  54.151  
  54.152 -#define C2_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)         FLAG_MEMBER_WITH_TYPE(name,type),
  54.153 -#define C2_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc)             FLAG_MEMBER_WITH_TYPE(name,type),
  54.154 -#define C2_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)      FLAG_MEMBER_WITH_TYPE(name,type),
  54.155 +#define C2_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)           FLAG_MEMBER_WITH_TYPE(name,type),
  54.156 +#define C2_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc)               FLAG_MEMBER_WITH_TYPE(name,type),
  54.157 +#define C2_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)        FLAG_MEMBER_WITH_TYPE(name,type),
  54.158  #define C2_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)      FLAG_MEMBER_WITH_TYPE(name,type),
  54.159 -#ifdef PRODUCT
  54.160 -  #define C2_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)       /* flag is constant */
  54.161 -  #define C2_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc)           /* flag is constant */
  54.162 -  #define C2_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)
  54.163 -#else
  54.164 -  #define C2_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)       FLAG_MEMBER_WITH_TYPE(name,type),
  54.165 -  #define C2_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc)           FLAG_MEMBER_WITH_TYPE(name,type),
  54.166 -  #define C2_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)    FLAG_MEMBER_WITH_TYPE(name,type),
  54.167 -#endif
  54.168 +#define C2_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)           FLAG_MEMBER_WITH_TYPE(name,type),
  54.169 +#define C2_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc)               FLAG_MEMBER_WITH_TYPE(name,type),
  54.170 +#define C2_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)        FLAG_MEMBER_WITH_TYPE(name,type),
  54.171  
  54.172  #define ARCH_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)         FLAG_MEMBER_WITH_TYPE(name,type),
  54.173  #define ARCH_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)      FLAG_MEMBER_WITH_TYPE(name,type),
  54.174 -#define ARCH_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)      FLAG_MEMBER_WITH_TYPE(name,type),
  54.175 -#ifdef PRODUCT
  54.176 -  #define ARCH_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)       /* flag is constant */
  54.177 -  #define ARCH_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)
  54.178 -#else
  54.179 -  #define ARCH_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)       FLAG_MEMBER_WITH_TYPE(name,type),
  54.180 -  #define ARCH_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)    FLAG_MEMBER_WITH_TYPE(name,type),
  54.181 -#endif
  54.182 +#define ARCH_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)    FLAG_MEMBER_WITH_TYPE(name,type),
  54.183 +#define ARCH_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)         FLAG_MEMBER_WITH_TYPE(name,type),
  54.184 +#define ARCH_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)      FLAG_MEMBER_WITH_TYPE(name,type),
  54.185  
  54.186  typedef enum {
  54.187   RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE,
  54.188 @@ -233,19 +189,19 @@
  54.189  
  54.190  #define FLAG_SET_DEFAULT(name, value) ((name) = (value))
  54.191  
  54.192 -#define FLAG_SET_CMDLINE(type, name, value) (CommandLineFlagsEx::type##AtPut(FLAG_MEMBER_WITH_TYPE(name,type), (type)(value), COMMAND_LINE))
  54.193 -#define FLAG_SET_ERGO(type, name, value)    (CommandLineFlagsEx::type##AtPut(FLAG_MEMBER_WITH_TYPE(name,type), (type)(value), ERGONOMIC))
  54.194 +#define FLAG_SET_CMDLINE(type, name, value) (CommandLineFlagsEx::type##AtPut(FLAG_MEMBER_WITH_TYPE(name,type), (type)(value), Flag::COMMAND_LINE))
  54.195 +#define FLAG_SET_ERGO(type, name, value)    (CommandLineFlagsEx::type##AtPut(FLAG_MEMBER_WITH_TYPE(name,type), (type)(value), Flag::ERGONOMIC))
  54.196  
  54.197  // Can't put the following in CommandLineFlags because
  54.198  // of a circular dependency on the enum definition.
  54.199  class CommandLineFlagsEx : CommandLineFlags {
  54.200   public:
  54.201 -  static void boolAtPut(CommandLineFlagWithType flag, bool value, FlagValueOrigin origin);
  54.202 -  static void intxAtPut(CommandLineFlagWithType flag, intx value, FlagValueOrigin origin);
  54.203 -  static void uintxAtPut(CommandLineFlagWithType flag, uintx value, FlagValueOrigin origin);
  54.204 -  static void uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, FlagValueOrigin origin);
  54.205 -  static void doubleAtPut(CommandLineFlagWithType flag, double value, FlagValueOrigin origin);
  54.206 -  static void ccstrAtPut(CommandLineFlagWithType flag, ccstr value, FlagValueOrigin origin);
  54.207 +  static void boolAtPut(CommandLineFlagWithType flag, bool value, Flag::Flags origin);
  54.208 +  static void intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin);
  54.209 +  static void uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin);
  54.210 +  static void uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin);
  54.211 +  static void doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin);
  54.212 +  static void ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin);
  54.213  
  54.214    static bool is_default(CommandLineFlag flag);
  54.215    static bool is_ergo(CommandLineFlag flag);
    55.1 --- a/src/share/vm/runtime/safepoint.cpp	Tue Oct 01 11:06:35 2013 -0400
    55.2 +++ b/src/share/vm/runtime/safepoint.cpp	Thu Oct 03 16:38:21 2013 +0400
    55.3 @@ -519,8 +519,8 @@
    55.4    }
    55.5  
    55.6    {
    55.7 -    TraceTime t4("sweeping nmethods", TraceSafepointCleanupTime);
    55.8 -    NMethodSweeper::scan_stacks();
    55.9 +    TraceTime t4("mark nmethods", TraceSafepointCleanupTime);
   55.10 +    NMethodSweeper::mark_active_nmethods();
   55.11    }
   55.12  
   55.13    if (SymbolTable::needs_rehashing()) {
    56.1 --- a/src/share/vm/runtime/sweeper.cpp	Tue Oct 01 11:06:35 2013 -0400
    56.2 +++ b/src/share/vm/runtime/sweeper.cpp	Thu Oct 03 16:38:21 2013 +0400
    56.3 @@ -127,64 +127,79 @@
    56.4  #define SWEEP(nm)
    56.5  #endif
    56.6  
    56.7 +nmethod*  NMethodSweeper::_current         = NULL; // Current nmethod
    56.8 +long      NMethodSweeper::_traversals      = 0;    // Nof. stack traversals performed
    56.9 +int       NMethodSweeper::_seen            = 0;    // Nof. nmethods we have currently processed in current pass of CodeCache
   56.10 +int       NMethodSweeper::_flushed_count   = 0;    // Nof. nmethods flushed in current sweep
   56.11 +int       NMethodSweeper::_zombified_count = 0;    // Nof. nmethods made zombie in current sweep
   56.12 +int       NMethodSweeper::_marked_count    = 0;    // Nof. nmethods marked for reclaim in current sweep
   56.13  
   56.14 -long      NMethodSweeper::_traversals = 0;   // No. of stack traversals performed
   56.15 -nmethod*  NMethodSweeper::_current = NULL;   // Current nmethod
   56.16 -int       NMethodSweeper::_seen = 0 ;        // No. of nmethods we have currently processed in current pass of CodeCache
   56.17 -int       NMethodSweeper::_flushed_count = 0;   // Nof. nmethods flushed in current sweep
   56.18 -int       NMethodSweeper::_zombified_count = 0; // Nof. nmethods made zombie in current sweep
   56.19 -int       NMethodSweeper::_marked_count = 0;    // Nof. nmethods marked for reclaim in current sweep
   56.20 -
   56.21 -volatile int NMethodSweeper::_invocations = 0;   // No. of invocations left until we are completed with this pass
   56.22 +volatile int NMethodSweeper::_invocations   = 0; // Nof. invocations left until we are completed with this pass
   56.23  volatile int NMethodSweeper::_sweep_started = 0; // Whether a sweep is in progress.
   56.24  
   56.25 -jint      NMethodSweeper::_locked_seen = 0;
   56.26 +jint      NMethodSweeper::_locked_seen               = 0;
   56.27  jint      NMethodSweeper::_not_entrant_seen_on_stack = 0;
   56.28 -bool      NMethodSweeper::_resweep = false;
   56.29 -jint      NMethodSweeper::_flush_token = 0;
   56.30 -jlong     NMethodSweeper::_last_full_flush_time = 0;
   56.31 -int       NMethodSweeper::_highest_marked = 0;
   56.32 -int       NMethodSweeper::_dead_compile_ids = 0;
   56.33 -long      NMethodSweeper::_last_flush_traversal_id = 0;
   56.34 +bool      NMethodSweeper::_request_mark_phase        = false;
   56.35  
   56.36 -int       NMethodSweeper::_number_of_flushes = 0; // Total of full traversals caused by full cache
   56.37  int       NMethodSweeper::_total_nof_methods_reclaimed = 0;
   56.38 -jlong     NMethodSweeper::_total_time_sweeping = 0;
   56.39 -jlong     NMethodSweeper::_total_time_this_sweep = 0;
   56.40 -jlong     NMethodSweeper::_peak_sweep_time = 0;
   56.41 -jlong     NMethodSweeper::_peak_sweep_fraction_time = 0;
   56.42 -jlong     NMethodSweeper::_total_disconnect_time = 0;
   56.43 -jlong     NMethodSweeper::_peak_disconnect_time = 0;
   56.44 +jlong     NMethodSweeper::_total_time_sweeping         = 0;
   56.45 +jlong     NMethodSweeper::_total_time_this_sweep       = 0;
   56.46 +jlong     NMethodSweeper::_peak_sweep_time             = 0;
   56.47 +jlong     NMethodSweeper::_peak_sweep_fraction_time    = 0;
   56.48 +int       NMethodSweeper::_hotness_counter_reset_val   = 0;
   56.49 +
   56.50  
   56.51  class MarkActivationClosure: public CodeBlobClosure {
   56.52  public:
   56.53    virtual void do_code_blob(CodeBlob* cb) {
   56.54 -    // If we see an activation belonging to a non_entrant nmethod, we mark it.
   56.55 -    if (cb->is_nmethod() && ((nmethod*)cb)->is_not_entrant()) {
   56.56 -      ((nmethod*)cb)->mark_as_seen_on_stack();
   56.57 +    if (cb->is_nmethod()) {
   56.58 +      nmethod* nm = (nmethod*)cb;
   56.59 +      nm->set_hotness_counter(NMethodSweeper::hotness_counter_reset_val());
   56.60 +      // If we see an activation belonging to a non_entrant nmethod, we mark it.
   56.61 +      if (nm->is_not_entrant()) {
   56.62 +        nm->mark_as_seen_on_stack();
   56.63 +      }
   56.64      }
   56.65    }
   56.66  };
   56.67  static MarkActivationClosure mark_activation_closure;
   56.68  
   56.69 +class SetHotnessClosure: public CodeBlobClosure {
   56.70 +public:
   56.71 +  virtual void do_code_blob(CodeBlob* cb) {
   56.72 +    if (cb->is_nmethod()) {
   56.73 +      nmethod* nm = (nmethod*)cb;
   56.74 +      nm->set_hotness_counter(NMethodSweeper::hotness_counter_reset_val());
   56.75 +    }
   56.76 +  }
   56.77 +};
   56.78 +static SetHotnessClosure set_hotness_closure;
   56.79 +
   56.80 +
   56.81 +int NMethodSweeper::hotness_counter_reset_val() {
   56.82 +  if (_hotness_counter_reset_val == 0) {
   56.83 +    _hotness_counter_reset_val = (ReservedCodeCacheSize < M) ? 1 : (ReservedCodeCacheSize / M) * 2;
   56.84 +  }
   56.85 +  return _hotness_counter_reset_val;
   56.86 +}
   56.87  bool NMethodSweeper::sweep_in_progress() {
   56.88    return (_current != NULL);
   56.89  }
   56.90  
   56.91 -void NMethodSweeper::scan_stacks() {
   56.92 +// Scans the stacks of all Java threads and marks activations of not-entrant methods.
   56.93 +// No need to synchronize access, since 'mark_active_nmethods' is always executed at a
   56.94 +// safepoint.
   56.95 +void NMethodSweeper::mark_active_nmethods() {
   56.96    assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint");
   56.97 -  if (!MethodFlushing) return;
   56.98 -
   56.99 -  // No need to synchronize access, since this is always executed at a
  56.100 -  // safepoint.
  56.101 -
  56.102 -  // Make sure CompiledIC_lock in unlocked, since we might update some
  56.103 -  // inline caches. If it is, we just bail-out and try later.
  56.104 -  if (CompiledIC_lock->is_locked() || Patching_lock->is_locked()) return;
  56.105 +  // If we do not want to reclaim not-entrant or zombie methods there is no need
  56.106 +  // to scan stacks
  56.107 +  if (!MethodFlushing) {
  56.108 +    return;
  56.109 +  }
  56.110  
  56.111    // Check for restart
  56.112    assert(CodeCache::find_blob_unsafe(_current) == _current, "Sweeper nmethod cached state invalid");
  56.113 -  if (!sweep_in_progress() && _resweep) {
  56.114 +  if (!sweep_in_progress() && need_marking_phase()) {
  56.115      _seen        = 0;
  56.116      _invocations = NmethodSweepFraction;
  56.117      _current     = CodeCache::first_nmethod();
  56.118 @@ -197,30 +212,22 @@
  56.119      Threads::nmethods_do(&mark_activation_closure);
  56.120  
  56.121      // reset the flags since we started a scan from the beginning.
  56.122 -    _resweep = false;
  56.123 +    reset_nmethod_marking();
  56.124      _locked_seen = 0;
  56.125      _not_entrant_seen_on_stack = 0;
  56.126 +  } else {
  56.127 +    // Only set hotness counter
  56.128 +    Threads::nmethods_do(&set_hotness_closure);
  56.129    }
  56.130  
  56.131 -  if (UseCodeCacheFlushing) {
  56.132 -    // only allow new flushes after the interval is complete.
  56.133 -    jlong now           = os::javaTimeMillis();
  56.134 -    jlong max_interval  = (jlong)MinCodeCacheFlushingInterval * (jlong)1000;
  56.135 -    jlong curr_interval = now - _last_full_flush_time;
  56.136 -    if (curr_interval > max_interval) {
  56.137 -      _flush_token = 0;
  56.138 -    }
  56.139 -
  56.140 -    if (!CodeCache::needs_flushing() && !CompileBroker::should_compile_new_jobs()) {
  56.141 -      CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation);
  56.142 -      log_sweep("restart_compiler");
  56.143 -    }
  56.144 -  }
  56.145 +  OrderAccess::storestore();
  56.146  }
  56.147  
  56.148  void NMethodSweeper::possibly_sweep() {
  56.149    assert(JavaThread::current()->thread_state() == _thread_in_vm, "must run in vm mode");
  56.150 -  if (!MethodFlushing || !sweep_in_progress()) return;
  56.151 +  if (!MethodFlushing || !sweep_in_progress()) {
  56.152 +    return;
  56.153 +  }
  56.154  
  56.155    if (_invocations > 0) {
  56.156      // Only one thread at a time will sweep
  56.157 @@ -258,8 +265,7 @@
  56.158    if (!CompileBroker::should_compile_new_jobs()) {
  56.159      // If we have turned off compilations we might as well do full sweeps
  56.160      // in order to reach the clean state faster. Otherwise the sleeping compiler
  56.161 -    // threads will slow down sweeping. After a few iterations the cache
  56.162 -    // will be clean and sweeping stops (_resweep will not be set)
  56.163 +    // threads will slow down sweeping.
  56.164      _invocations = 1;
  56.165    }
  56.166  
  56.167 @@ -271,9 +277,11 @@
  56.168    int todo = (CodeCache::nof_nmethods() - _seen) / _invocations;
  56.169    int swept_count = 0;
  56.170  
  56.171 +
  56.172    assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here");
  56.173    assert(!CodeCache_lock->owned_by_self(), "just checking");
  56.174  
  56.175 +  int freed_memory = 0;
  56.176    {
  56.177      MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
  56.178  
  56.179 @@ -299,7 +307,7 @@
  56.180        // Now ready to process nmethod and give up CodeCache_lock
  56.181        {
  56.182          MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
  56.183 -        process_nmethod(_current);
  56.184 +        freed_memory += process_nmethod(_current);
  56.185        }
  56.186        _seen++;
  56.187        _current = next;
  56.188 @@ -308,11 +316,11 @@
  56.189  
  56.190    assert(_invocations > 1 || _current == NULL, "must have scanned the whole cache");
  56.191  
  56.192 -  if (!sweep_in_progress() && !_resweep && (_locked_seen || _not_entrant_seen_on_stack)) {
  56.193 +  if (!sweep_in_progress() && !need_marking_phase() && (_locked_seen || _not_entrant_seen_on_stack)) {
  56.194      // we've completed a scan without making progress but there were
  56.195      // nmethods we were unable to process either because they were
  56.196 -    // locked or were still on stack.  We don't have to aggresively
  56.197 -    // clean them up so just stop scanning.  We could scan once more
  56.198 +    // locked or were still on stack. We don't have to aggressively
  56.199 +    // clean them up so just stop scanning. We could scan once more
  56.200      // but that complicates the control logic and it's unlikely to
  56.201      // matter much.
  56.202      if (PrintMethodFlushing) {
  56.203 @@ -351,9 +359,16 @@
  56.204      log_sweep("finished");
  56.205    }
  56.206  
  56.207 -  // Sweeper is the only case where memory is released,
  56.208 -  // check here if it is time to restart the compiler.
  56.209 -  if (UseCodeCacheFlushing && !CompileBroker::should_compile_new_jobs() && !CodeCache::needs_flushing()) {
  56.210 +  // Sweeper is the only case where memory is released, check here if it
  56.211 +  // is time to restart the compiler. Only checking if there is a certain
  56.212 +  // amount of free memory in the code cache might lead to re-enabling
  56.213 +  // compilation although no memory has been released. For example, there are
  56.214 +  // cases when compilation was disabled although there is 4MB (or more) free
  56.215 +  // memory in the code cache. The reason is code cache fragmentation. Therefore,
  56.216 +  // it only makes sense to re-enable compilation if we have actually freed memory.
  56.217 +  // Note that typically several kB are released for sweeping 16MB of the code
  56.218 +  // cache. As a result, 'freed_memory' > 0 to restart the compiler.
  56.219 +  if (UseCodeCacheFlushing && (!CompileBroker::should_compile_new_jobs() && (freed_memory > 0))) {
  56.220      CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation);
  56.221      log_sweep("restart_compiler");
  56.222    }
  56.223 @@ -367,8 +382,8 @@
  56.224      _thread = CompilerThread::current();
  56.225      if (!nm->is_zombie() && !nm->is_unloaded()) {
  56.226        // Only expose live nmethods for scanning
  56.227 -    _thread->set_scanned_nmethod(nm);
  56.228 -  }
  56.229 +      _thread->set_scanned_nmethod(nm);
  56.230 +    }
  56.231    }
  56.232    ~NMethodMarker() {
  56.233      _thread->set_scanned_nmethod(NULL);
  56.234 @@ -392,20 +407,20 @@
  56.235    nm->flush();
  56.236  }
  56.237  
  56.238 -void NMethodSweeper::process_nmethod(nmethod *nm) {
  56.239 +int NMethodSweeper::process_nmethod(nmethod *nm) {
  56.240    assert(!CodeCache_lock->owned_by_self(), "just checking");
  56.241  
  56.242 +  int freed_memory = 0;
  56.243    // Make sure this nmethod doesn't get unloaded during the scan,
  56.244 -  // since the locks acquired below might safepoint.
  56.245 +  // since safepoints may happen during acquired below locks.
  56.246    NMethodMarker nmm(nm);
  56.247 -
  56.248    SWEEP(nm);
  56.249  
  56.250    // Skip methods that are currently referenced by the VM
  56.251    if (nm->is_locked_by_vm()) {
  56.252      // But still remember to clean-up inline caches for alive nmethods
  56.253      if (nm->is_alive()) {
  56.254 -      // Clean-up all inline caches that points to zombie/non-reentrant methods
  56.255 +      // Clean inline caches that point to zombie/non-entrant methods
  56.256        MutexLocker cl(CompiledIC_lock);
  56.257        nm->cleanup_inline_caches();
  56.258        SWEEP(nm);
  56.259 @@ -413,18 +428,19 @@
  56.260        _locked_seen++;
  56.261        SWEEP(nm);
  56.262      }
  56.263 -    return;
  56.264 +    return freed_memory;
  56.265    }
  56.266  
  56.267    if (nm->is_zombie()) {
  56.268 -    // If it is first time, we see nmethod then we mark it. Otherwise,
  56.269 -    // we reclame it. When we have seen a zombie method twice, we know that
  56.270 +    // If it is the first time we see nmethod then we mark it. Otherwise,
  56.271 +    // we reclaim it. When we have seen a zombie method twice, we know that
  56.272      // there are no inline caches that refer to it.
  56.273      if (nm->is_marked_for_reclamation()) {
  56.274        assert(!nm->is_locked_by_vm(), "must not flush locked nmethods");
  56.275        if (PrintMethodFlushing && Verbose) {
  56.276          tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm);
  56.277        }
  56.278 +      freed_memory = nm->total_size();
  56.279        release_nmethod(nm);
  56.280        _flushed_count++;
  56.281      } else {
  56.282 @@ -432,19 +448,19 @@
  56.283          tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), nm);
  56.284        }
  56.285        nm->mark_for_reclamation();
  56.286 -      _resweep = true;
  56.287 +      request_nmethod_marking();
  56.288        _marked_count++;
  56.289        SWEEP(nm);
  56.290      }
  56.291    } else if (nm->is_not_entrant()) {
  56.292 -    // If there is no current activations of this method on the
  56.293 +    // If there are no current activations of this method on the
  56.294      // stack we can safely convert it to a zombie method
  56.295      if (nm->can_not_entrant_be_converted()) {
  56.296        if (PrintMethodFlushing && Verbose) {
  56.297          tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (not entrant) being made zombie", nm->compile_id(), nm);
  56.298        }
  56.299        nm->make_zombie();
  56.300 -      _resweep = true;
  56.301 +      request_nmethod_marking();
  56.302        _zombified_count++;
  56.303        SWEEP(nm);
  56.304      } else {
  56.305 @@ -459,159 +475,57 @@
  56.306      }
  56.307    } else if (nm->is_unloaded()) {
  56.308      // Unloaded code, just make it a zombie
  56.309 -    if (PrintMethodFlushing && Verbose)
  56.310 +    if (PrintMethodFlushing && Verbose) {
  56.311        tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), nm);
  56.312 -
  56.313 +    }
  56.314      if (nm->is_osr_method()) {
  56.315        SWEEP(nm);
  56.316        // No inline caches will ever point to osr methods, so we can just remove it
  56.317 +      freed_memory = nm->total_size();
  56.318        release_nmethod(nm);
  56.319        _flushed_count++;
  56.320      } else {
  56.321        nm->make_zombie();
  56.322 -      _resweep = true;
  56.323 +      request_nmethod_marking();
  56.324        _zombified_count++;
  56.325        SWEEP(nm);
  56.326      }
  56.327    } else {
  56.328 -    assert(nm->is_alive(), "should be alive");
  56.329 -
  56.330      if (UseCodeCacheFlushing) {
  56.331 -      if (nm->is_speculatively_disconnected() && !nm->is_locked_by_vm() && !nm->is_osr_method() &&
  56.332 -          (_traversals > _last_flush_traversal_id + 2) && (nm->compile_id() < _highest_marked)) {
  56.333 -        // This method has not been called since the forced cleanup happened
  56.334 -        nm->make_not_entrant();
  56.335 +      if (!nm->is_locked_by_vm() && !nm->is_osr_method() && !nm->is_native_method()) {
  56.336 +        // Do not make native methods and OSR-methods not-entrant
  56.337 +        nm->dec_hotness_counter();
  56.338 +        // Get the initial value of the hotness counter. This value depends on the
  56.339 +        // ReservedCodeCacheSize
  56.340 +        int reset_val = hotness_counter_reset_val();
  56.341 +        int time_since_reset = reset_val - nm->hotness_counter();
  56.342 +        double threshold = -reset_val + (CodeCache::reverse_free_ratio() * NmethodSweepActivity);
  56.343 +        // The less free space in the code cache we have - the bigger reverse_free_ratio() is.
  56.344 +        // I.e., 'threshold' increases with lower available space in the code cache and a higher
  56.345 +        // NmethodSweepActivity. If the current hotness counter - which decreases from its initial
  56.346 +        // value until it is reset by stack walking - is smaller than the computed threshold, the
  56.347 +        // corresponding nmethod is considered for removal.
  56.348 +        if ((NmethodSweepActivity > 0) && (nm->hotness_counter() < threshold) && (time_since_reset > 10)) {
  56.349 +          // A method is marked as not-entrant if the method is
  56.350 +          // 1) 'old enough': nm->hotness_counter() < threshold
  56.351 +          // 2) The method was in_use for a minimum amount of time: (time_since_reset > 10)
  56.352 +          //    The second condition is necessary if we are dealing with very small code cache
  56.353 +          //    sizes (e.g., <10m) and the code cache size is too small to hold all hot methods.
  56.354 +          //    The second condition ensures that methods are not immediately made not-entrant
  56.355 +          //    after compilation.
  56.356 +          nm->make_not_entrant();
  56.357 +          request_nmethod_marking();
  56.358 +        }
  56.359        }
  56.360      }
  56.361 -
  56.362 -    // Clean-up all inline caches that points to zombie/non-reentrant methods
  56.363 +    // Clean-up all inline caches that point to zombie/non-reentrant methods
  56.364      MutexLocker cl(CompiledIC_lock);
  56.365      nm->cleanup_inline_caches();
  56.366      SWEEP(nm);
  56.367    }
  56.368 +  return freed_memory;
  56.369  }
  56.370  
  56.371 -// Code cache unloading: when compilers notice the code cache is getting full,
  56.372 -// they will call a vm op that comes here. This code attempts to speculatively
  56.373 -// unload the oldest half of the nmethods (based on the compile job id) by
  56.374 -// saving the old code in a list in the CodeCache. Then
  56.375 -// execution resumes. If a method so marked is not called by the second sweeper
  56.376 -// stack traversal after the current one, the nmethod will be marked non-entrant and
  56.377 -// got rid of by normal sweeping. If the method is called, the Method*'s
  56.378 -// _code field is restored and the Method*/nmethod
  56.379 -// go back to their normal state.
  56.380 -void NMethodSweeper::handle_full_code_cache(bool is_full) {
  56.381 -
  56.382 -  if (is_full) {
  56.383 -    // Since code cache is full, immediately stop new compiles
  56.384 -    if (CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation)) {
  56.385 -      log_sweep("disable_compiler");
  56.386 -    }
  56.387 -  }
  56.388 -
  56.389 -  // Make sure only one thread can flush
  56.390 -  // The token is reset after CodeCacheMinimumFlushInterval in scan stacks,
  56.391 -  // no need to check the timeout here.
  56.392 -  jint old = Atomic::cmpxchg( 1, &_flush_token, 0 );
  56.393 -  if (old != 0) {
  56.394 -    return;
  56.395 -  }
  56.396 -
  56.397 -  VM_HandleFullCodeCache op(is_full);
  56.398 -  VMThread::execute(&op);
  56.399 -
  56.400 -  // resweep again as soon as possible
  56.401 -  _resweep = true;
  56.402 -}
  56.403 -
  56.404 -void NMethodSweeper::speculative_disconnect_nmethods(bool is_full) {
  56.405 -  // If there was a race in detecting full code cache, only run
  56.406 -  // one vm op for it or keep the compiler shut off
  56.407 -
  56.408 -  jlong disconnect_start_counter = os::elapsed_counter();
  56.409 -
  56.410 -  // Traverse the code cache trying to dump the oldest nmethods
  56.411 -  int curr_max_comp_id = CompileBroker::get_compilation_id();
  56.412 -  int flush_target = ((curr_max_comp_id - _dead_compile_ids) / CodeCacheFlushingFraction) + _dead_compile_ids;
  56.413 -
  56.414 -  log_sweep("start_cleaning");
  56.415 -
  56.416 -  nmethod* nm = CodeCache::alive_nmethod(CodeCache::first());
  56.417 -  jint disconnected = 0;
  56.418 -  jint made_not_entrant  = 0;
  56.419 -  jint nmethod_count = 0;
  56.420 -
  56.421 -  while ((nm != NULL)){
  56.422 -    int curr_comp_id = nm->compile_id();
  56.423 -
  56.424 -    // OSR methods cannot be flushed like this. Also, don't flush native methods
  56.425 -    // since they are part of the JDK in most cases
  56.426 -    if (!nm->is_osr_method() && !nm->is_locked_by_vm() && !nm->is_native_method()) {
  56.427 -
  56.428 -      // only count methods that can be speculatively disconnected
  56.429 -      nmethod_count++;
  56.430 -
  56.431 -      if (nm->is_in_use() && (curr_comp_id < flush_target)) {
  56.432 -        if ((nm->method()->code() == nm)) {
  56.433 -          // This method has not been previously considered for
  56.434 -          // unloading or it was restored already
  56.435 -          CodeCache::speculatively_disconnect(nm);
  56.436 -          disconnected++;
  56.437 -        } else if (nm->is_speculatively_disconnected()) {
  56.438 -          // This method was previously considered for preemptive unloading and was not called since then
  56.439 -          CompilationPolicy::policy()->delay_compilation(nm->method());
  56.440 -          nm->make_not_entrant();
  56.441 -          made_not_entrant++;
  56.442 -        }
  56.443 -
  56.444 -        if (curr_comp_id > _highest_marked) {
  56.445 -          _highest_marked = curr_comp_id;
  56.446 -        }
  56.447 -      }
  56.448 -    }
  56.449 -    nm = CodeCache::alive_nmethod(CodeCache::next(nm));
  56.450 -  }
  56.451 -
  56.452 -  // remember how many compile_ids wheren't seen last flush.
  56.453 -  _dead_compile_ids = curr_max_comp_id - nmethod_count;
  56.454 -
  56.455 -  log_sweep("stop_cleaning",
  56.456 -                       "disconnected='" UINT32_FORMAT "' made_not_entrant='" UINT32_FORMAT "'",
  56.457 -                       disconnected, made_not_entrant);
  56.458 -
  56.459 -  // Shut off compiler. Sweeper will start over with a new stack scan and
  56.460 -  // traversal cycle and turn it back on if it clears enough space.
  56.461 -  if (is_full) {
  56.462 -    _last_full_flush_time = os::javaTimeMillis();
  56.463 -  }
  56.464 -
  56.465 -  jlong disconnect_end_counter = os::elapsed_counter();
  56.466 -  jlong disconnect_time = disconnect_end_counter - disconnect_start_counter;
  56.467 -  _total_disconnect_time += disconnect_time;
  56.468 -  _peak_disconnect_time = MAX2(disconnect_time, _peak_disconnect_time);
  56.469 -
  56.470 -  EventCleanCodeCache event(UNTIMED);
  56.471 -  if (event.should_commit()) {
  56.472 -    event.set_starttime(disconnect_start_counter);
  56.473 -    event.set_endtime(disconnect_end_counter);
  56.474 -    event.set_disconnectedCount(disconnected);
  56.475 -    event.set_madeNonEntrantCount(made_not_entrant);
  56.476 -    event.commit();
  56.477 -  }
  56.478 -  _number_of_flushes++;
  56.479 -
  56.480 -  // After two more traversals the sweeper will get rid of unrestored nmethods
  56.481 -  _last_flush_traversal_id = _traversals;
  56.482 -  _resweep = true;
  56.483 -#ifdef ASSERT
  56.484 -
  56.485 -  if(PrintMethodFlushing && Verbose) {
  56.486 -    tty->print_cr("### sweeper: unload time: " INT64_FORMAT, (jlong)disconnect_time);
  56.487 -  }
  56.488 -#endif
  56.489 -}
  56.490 -
  56.491 -
  56.492  // Print out some state information about the current sweep and the
  56.493  // state of the code cache if it's requested.
  56.494  void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) {
    57.1 --- a/src/share/vm/runtime/sweeper.hpp	Tue Oct 01 11:06:35 2013 -0400
    57.2 +++ b/src/share/vm/runtime/sweeper.hpp	Thu Oct 03 16:38:21 2013 +0400
    57.3 @@ -27,8 +27,30 @@
    57.4  
    57.5  // An NmethodSweeper is an incremental cleaner for:
    57.6  //    - cleanup inline caches
    57.7 -//    - reclamation of unreferences zombie nmethods
    57.8 -//
    57.9 +//    - reclamation of nmethods
   57.10 +// Removing nmethods from the code cache includes two operations
   57.11 +//  1) mark active nmethods
   57.12 +//     Is done in 'mark_active_nmethods()'. This function is called at a
   57.13 +//     safepoint and marks all nmethods that are active on a thread's stack.
   57.14 +//  2) sweep nmethods
   57.15 +//     Is done in sweep_code_cache(). This function is the only place in the
   57.16 +//     sweeper where memory is reclaimed. Note that sweep_code_cache() is not
   57.17 +//     called at a safepoint. However, sweep_code_cache() stops executing if
   57.18 +//     another thread requests a safepoint. Consequently, 'mark_active_nmethods()'
   57.19 +//     and sweep_code_cache() cannot execute at the same time.
   57.20 +//     To reclaim memory, nmethods are first marked as 'not-entrant'. Methods can
   57.21 +//     be made not-entrant by (i) the sweeper, (ii) deoptimization, (iii) dependency
   57.22 +//     invalidation, and (iv) being replaced be a different method version (tiered
   57.23 +//     compilation). Not-entrant nmethod cannot be called by Java threads, but they
   57.24 +//     can still be active on the stack. To ensure that active nmethod are not reclaimed,
   57.25 +//     we have to wait until the next marking phase has completed. If a not-entrant
   57.26 +//     nmethod was NOT marked as active, it can be converted to 'zombie' state. To safely
   57.27 +//     remove the nmethod, all inline caches (IC) that point to the the nmethod must be
   57.28 +//     cleared. After that, the nmethod can be evicted from the code cache. Each nmethod's
   57.29 +//     state change happens during separate sweeps. It may take at least 3 sweeps before an
   57.30 +//     nmethod's space is freed. Sweeping is currently done by compiler threads between
   57.31 +//     compilations or at least each 5 sec (NmethodSweepCheckInterval) when the code cache
   57.32 +//     is full.
   57.33  
   57.34  class NMethodSweeper : public AllStatic {
   57.35    static long      _traversals;      // Stack scan count, also sweep ID.
   57.36 @@ -41,46 +63,38 @@
   57.37    static volatile int  _invocations;   // No. of invocations left until we are completed with this pass
   57.38    static volatile int  _sweep_started; // Flag to control conc sweeper
   57.39  
   57.40 -  //The following are reset in scan_stacks and synchronized by the safepoint
   57.41 -  static bool      _resweep;           // Indicates that a change has happend and we want another sweep,
   57.42 -                                       // always checked and reset at a safepoint so memory will be in sync.
   57.43 -  static int       _locked_seen;       // Number of locked nmethods encountered during the scan
   57.44 +  //The following are reset in mark_active_nmethods and synchronized by the safepoint
   57.45 +  static bool      _request_mark_phase;        // Indicates that a change has happend and we need another mark pahse,
   57.46 +                                               // always checked and reset at a safepoint so memory will be in sync.
   57.47 +  static int       _locked_seen;               // Number of locked nmethods encountered during the scan
   57.48    static int       _not_entrant_seen_on_stack; // Number of not entrant nmethod were are still on stack
   57.49 -  static jint      _flush_token;       // token that guards method flushing, making sure it is executed only once.
   57.50 -
   57.51 -  // These are set during a flush, a VM-operation
   57.52 -  static long      _last_flush_traversal_id; // trav number at last flush unloading
   57.53 -  static jlong     _last_full_flush_time;    // timestamp of last emergency unloading
   57.54 -
   57.55 -  // These are synchronized by the _sweep_started token
   57.56 -  static int       _highest_marked;   // highest compile id dumped at last emergency unloading
   57.57 -  static int       _dead_compile_ids; // number of compile ids that where not in the cache last flush
   57.58  
   57.59    // Stat counters
   57.60 -  static int       _number_of_flushes;            // Total of full traversals caused by full cache
   57.61    static int       _total_nof_methods_reclaimed;  // Accumulated nof methods flushed
   57.62    static jlong     _total_time_sweeping;          // Accumulated time sweeping
   57.63    static jlong     _total_time_this_sweep;        // Total time this sweep
   57.64    static jlong     _peak_sweep_time;              // Peak time for a full sweep
   57.65    static jlong     _peak_sweep_fraction_time;     // Peak time sweeping one fraction
   57.66 -  static jlong     _total_disconnect_time;        // Total time cleaning code mem
   57.67 -  static jlong     _peak_disconnect_time;         // Peak time cleaning code mem
   57.68  
   57.69 -  static void process_nmethod(nmethod *nm);
   57.70 +  static int  process_nmethod(nmethod *nm);
   57.71    static void release_nmethod(nmethod* nm);
   57.72  
   57.73 -  static void log_sweep(const char* msg, const char* format = NULL, ...);
   57.74    static bool sweep_in_progress();
   57.75 +  static void sweep_code_cache();
   57.76 +  static void request_nmethod_marking() { _request_mark_phase = true; }
   57.77 +  static void reset_nmethod_marking()   { _request_mark_phase = false; }
   57.78 +  static bool need_marking_phase()      { return _request_mark_phase; }
   57.79 +
   57.80 +  static int _hotness_counter_reset_val;
   57.81  
   57.82   public:
   57.83    static long traversal_count()              { return _traversals; }
   57.84 -  static int  number_of_flushes()            { return _number_of_flushes; }
   57.85    static int  total_nof_methods_reclaimed()  { return _total_nof_methods_reclaimed; }
   57.86    static jlong total_time_sweeping()         { return _total_time_sweeping; }
   57.87    static jlong peak_sweep_time()             { return _peak_sweep_time; }
   57.88    static jlong peak_sweep_fraction_time()    { return _peak_sweep_fraction_time; }
   57.89 -  static jlong total_disconnect_time()       { return _total_disconnect_time; }
   57.90 -  static jlong peak_disconnect_time()        { return _peak_disconnect_time; }
   57.91 +  static void log_sweep(const char* msg, const char* format = NULL, ...);
   57.92 +
   57.93  
   57.94  #ifdef ASSERT
   57.95    static bool is_sweeping(nmethod* which) { return _current == which; }
   57.96 @@ -90,19 +104,18 @@
   57.97    static void report_events();
   57.98  #endif
   57.99  
  57.100 -  static void scan_stacks();      // Invoked at the end of each safepoint
  57.101 -  static void sweep_code_cache(); // Concurrent part of sweep job
  57.102 -  static void possibly_sweep();   // Compiler threads call this to sweep
  57.103 +  static void mark_active_nmethods();      // Invoked at the end of each safepoint
  57.104 +  static void possibly_sweep();            // Compiler threads call this to sweep
  57.105  
  57.106 -  static void notify(nmethod* nm) {
  57.107 +  static int sort_nmethods_by_hotness(nmethod** nm1, nmethod** nm2);
  57.108 +  static int hotness_counter_reset_val();
  57.109 +
  57.110 +  static void notify() {
  57.111      // Request a new sweep of the code cache from the beginning. No
  57.112      // need to synchronize the setting of this flag since it only
  57.113      // changes to false at safepoint so we can never overwrite it with false.
  57.114 -     _resweep = true;
  57.115 +     request_nmethod_marking();
  57.116    }
  57.117 -
  57.118 -  static void handle_full_code_cache(bool is_full); // Called by compilers who fail to allocate
  57.119 -  static void speculative_disconnect_nmethods(bool was_full);   // Called by vm op to deal with alloc failure
  57.120  };
  57.121  
  57.122  #endif // SHARE_VM_RUNTIME_SWEEPER_HPP
    58.1 --- a/src/share/vm/runtime/vmStructs.cpp	Tue Oct 01 11:06:35 2013 -0400
    58.2 +++ b/src/share/vm/runtime/vmStructs.cpp	Thu Oct 03 16:38:21 2013 +0400
    58.3 @@ -176,6 +176,7 @@
    58.4  #include "opto/loopnode.hpp"
    58.5  #include "opto/machnode.hpp"
    58.6  #include "opto/matcher.hpp"
    58.7 +#include "opto/mathexactnode.hpp"
    58.8  #include "opto/mulnode.hpp"
    58.9  #include "opto/phaseX.hpp"
   58.10  #include "opto/parse.hpp"
   58.11 @@ -841,7 +842,7 @@
   58.12    nonstatic_field(nmethod,             _osr_link,                                     nmethod*)                              \
   58.13    nonstatic_field(nmethod,             _scavenge_root_link,                           nmethod*)                              \
   58.14    nonstatic_field(nmethod,             _scavenge_root_state,                          jbyte)                                 \
   58.15 -  nonstatic_field(nmethod,             _state,                                        unsigned char)                         \
   58.16 +  nonstatic_field(nmethod,             _state,                                        volatile unsigned char)                \
   58.17    nonstatic_field(nmethod,             _exception_offset,                             int)                                   \
   58.18    nonstatic_field(nmethod,             _deoptimize_offset,                            int)                                   \
   58.19    nonstatic_field(nmethod,             _deoptimize_mh_offset,                         int)                                   \
   58.20 @@ -1185,11 +1186,10 @@
   58.21    /* -XX flags         */                                                                                                            \
   58.22    /*********************/                                                                                                            \
   58.23                                                                                                                                       \
   58.24 -  nonstatic_field(Flag,                        type,                                          const char*)                           \
   58.25 -  nonstatic_field(Flag,                        name,                                          const char*)                           \
   58.26 -  unchecked_nonstatic_field(Flag,              addr,                                          sizeof(void*)) /* NOTE: no type */     \
   58.27 -  nonstatic_field(Flag,                        kind,                                          const char*)                           \
   58.28 -  nonstatic_field(Flag,                        origin,                                        FlagValueOrigin)                       \
   58.29 +  nonstatic_field(Flag,                        _type,                                         const char*)                           \
   58.30 +  nonstatic_field(Flag,                        _name,                                         const char*)                           \
   58.31 +  unchecked_nonstatic_field(Flag,              _addr,                                         sizeof(void*)) /* NOTE: no type */     \
   58.32 +  nonstatic_field(Flag,                        _flags,                                        Flag::Flags)                           \
   58.33    static_field(Flag,                           flags,                                         Flag*)                                 \
   58.34    static_field(Flag,                           numFlags,                                      size_t)                                \
   58.35                                                                                                                                       \
   58.36 @@ -1360,6 +1360,7 @@
   58.37    declare_integer_type(long)                                              \
   58.38    declare_integer_type(char)                                              \
   58.39    declare_unsigned_integer_type(unsigned char)                            \
   58.40 +  declare_unsigned_integer_type(volatile unsigned char)                   \
   58.41    declare_unsigned_integer_type(u_char)                                   \
   58.42    declare_unsigned_integer_type(unsigned int)                             \
   58.43    declare_unsigned_integer_type(uint)                                     \
   58.44 @@ -1382,6 +1383,7 @@
   58.45    declare_toplevel_type(char**)                                           \
   58.46    declare_toplevel_type(u_char*)                                          \
   58.47    declare_toplevel_type(unsigned char*)                                   \
   58.48 +  declare_toplevel_type(volatile unsigned char*)                          \
   58.49                                                                            \
   58.50    /*******************************************************************/   \
   58.51    /* Types which it will be handy to have available over in the SA   */   \
   58.52 @@ -1928,6 +1930,9 @@
   58.53    declare_c2_type(CmpF3Node, CmpFNode)                                    \
   58.54    declare_c2_type(CmpDNode, CmpNode)                                      \
   58.55    declare_c2_type(CmpD3Node, CmpDNode)                                    \
   58.56 +  declare_c2_type(MathExactNode, MultiNode)                               \
   58.57 +  declare_c2_type(AddExactINode, MathExactNode)                           \
   58.58 +  declare_c2_type(FlagsProjNode, ProjNode)                                \
   58.59    declare_c2_type(BoolNode, Node)                                         \
   58.60    declare_c2_type(AbsNode, Node)                                          \
   58.61    declare_c2_type(AbsINode, AbsNode)                                      \
   58.62 @@ -2074,7 +2079,7 @@
   58.63     declare_integer_type(JavaThreadState)                                  \
   58.64     declare_integer_type(Location::Type)                                   \
   58.65     declare_integer_type(Location::Where)                                  \
   58.66 -   declare_integer_type(FlagValueOrigin)                                  \
   58.67 +   declare_integer_type(Flag::Flags)                                      \
   58.68     COMPILER2_PRESENT(declare_integer_type(OptoReg::Name))                 \
   58.69                                                                            \
   58.70     declare_toplevel_type(CHeapObj<mtInternal>)                            \
   58.71 @@ -2082,7 +2087,7 @@
   58.72              declare_type(Array<u1>, MetaspaceObj)                         \
   58.73              declare_type(Array<u2>, MetaspaceObj)                         \
   58.74              declare_type(Array<Klass*>, MetaspaceObj)                     \
   58.75 -            declare_type(Array<Method*>, MetaspaceObj)             \
   58.76 +            declare_type(Array<Method*>, MetaspaceObj)                    \
   58.77                                                                            \
   58.78     declare_integer_type(AccessFlags)  /* FIXME: wrong type (not integer) */\
   58.79    declare_toplevel_type(address)      /* FIXME: should this be an integer type? */\
    59.1 --- a/src/share/vm/runtime/vm_operations.cpp	Tue Oct 01 11:06:35 2013 -0400
    59.2 +++ b/src/share/vm/runtime/vm_operations.cpp	Thu Oct 03 16:38:21 2013 +0400
    59.3 @@ -173,10 +173,6 @@
    59.4    SymbolTable::unlink();
    59.5  }
    59.6  
    59.7 -void VM_HandleFullCodeCache::doit() {
    59.8 -  NMethodSweeper::speculative_disconnect_nmethods(_is_full);
    59.9 -}
   59.10 -
   59.11  void VM_Verify::doit() {
   59.12    Universe::heap()->prepare_for_verify();
   59.13    Universe::verify(_silent);
    60.1 --- a/src/share/vm/runtime/vm_operations.hpp	Tue Oct 01 11:06:35 2013 -0400
    60.2 +++ b/src/share/vm/runtime/vm_operations.hpp	Thu Oct 03 16:38:21 2013 +0400
    60.3 @@ -51,7 +51,6 @@
    60.4    template(DeoptimizeAll)                         \
    60.5    template(ZombieAll)                             \
    60.6    template(UnlinkSymbols)                         \
    60.7 -  template(HandleFullCodeCache)                   \
    60.8    template(Verify)                                \
    60.9    template(PrintJNI)                              \
   60.10    template(HeapDumper)                            \
   60.11 @@ -261,16 +260,6 @@
   60.12    bool allow_nested_vm_operations() const        { return true;  }
   60.13  };
   60.14  
   60.15 -class VM_HandleFullCodeCache: public VM_Operation {
   60.16 - private:
   60.17 -  bool  _is_full;
   60.18 - public:
   60.19 -  VM_HandleFullCodeCache(bool is_full)           { _is_full = is_full; }
   60.20 -  VMOp_Type type() const                         { return VMOp_HandleFullCodeCache; }
   60.21 -  void doit();
   60.22 -  bool allow_nested_vm_operations() const        { return true; }
   60.23 -};
   60.24 -
   60.25  #ifndef PRODUCT
   60.26  class VM_DeoptimizeAll: public VM_Operation {
   60.27   private:
    61.1 --- a/src/share/vm/services/attachListener.cpp	Tue Oct 01 11:06:35 2013 -0400
    61.2 +++ b/src/share/vm/services/attachListener.cpp	Thu Oct 03 16:38:21 2013 +0400
    61.3 @@ -245,7 +245,7 @@
    61.4      }
    61.5      value = (tmp != 0);
    61.6    }
    61.7 -  bool res = CommandLineFlags::boolAtPut((char*)name, &value, ATTACH_ON_DEMAND);
    61.8 +  bool res = CommandLineFlags::boolAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND);
    61.9    if (! res) {
   61.10      out->print_cr("setting flag %s failed", name);
   61.11    }
   61.12 @@ -263,7 +263,7 @@
   61.13        return JNI_ERR;
   61.14      }
   61.15    }
   61.16 -  bool res = CommandLineFlags::intxAtPut((char*)name, &value, ATTACH_ON_DEMAND);
   61.17 +  bool res = CommandLineFlags::intxAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND);
   61.18    if (! res) {
   61.19      out->print_cr("setting flag %s failed", name);
   61.20    }
   61.21 @@ -282,7 +282,7 @@
   61.22        return JNI_ERR;
   61.23      }
   61.24    }
   61.25 -  bool res = CommandLineFlags::uintxAtPut((char*)name, &value, ATTACH_ON_DEMAND);
   61.26 +  bool res = CommandLineFlags::uintxAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND);
   61.27    if (! res) {
   61.28      out->print_cr("setting flag %s failed", name);
   61.29    }
   61.30 @@ -301,7 +301,7 @@
   61.31        return JNI_ERR;
   61.32      }
   61.33    }
   61.34 -  bool res = CommandLineFlags::uint64_tAtPut((char*)name, &value, ATTACH_ON_DEMAND);
   61.35 +  bool res = CommandLineFlags::uint64_tAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND);
   61.36    if (! res) {
   61.37      out->print_cr("setting flag %s failed", name);
   61.38    }
   61.39 @@ -316,7 +316,7 @@
   61.40      out->print_cr("flag value must be a string");
   61.41      return JNI_ERR;
   61.42    }
   61.43 -  bool res = CommandLineFlags::ccstrAtPut((char*)name, &value, ATTACH_ON_DEMAND);
   61.44 +  bool res = CommandLineFlags::ccstrAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND);
   61.45    if (res) {
   61.46      FREE_C_HEAP_ARRAY(char, value, mtInternal);
   61.47    } else {
    62.1 --- a/src/share/vm/services/classLoadingService.cpp	Tue Oct 01 11:06:35 2013 -0400
    62.2 +++ b/src/share/vm/services/classLoadingService.cpp	Thu Oct 03 16:38:21 2013 +0400
    62.3 @@ -202,7 +202,7 @@
    62.4    MutexLocker m(Management_lock);
    62.5  
    62.6    // verbose will be set to the previous value
    62.7 -  bool succeed = CommandLineFlags::boolAtPut((char*)"TraceClassLoading", &verbose, MANAGEMENT);
    62.8 +  bool succeed = CommandLineFlags::boolAtPut((char*)"TraceClassLoading", &verbose, Flag::MANAGEMENT);
    62.9    assert(succeed, "Setting TraceClassLoading flag fails");
   62.10    reset_trace_class_unloading();
   62.11  
   62.12 @@ -213,7 +213,7 @@
   62.13  void ClassLoadingService::reset_trace_class_unloading() {
   62.14    assert(Management_lock->owned_by_self(), "Must own the Management_lock");
   62.15    bool value = MemoryService::get_verbose() || ClassLoadingService::get_verbose();
   62.16 -  bool succeed = CommandLineFlags::boolAtPut((char*)"TraceClassUnloading", &value, MANAGEMENT);
   62.17 +  bool succeed = CommandLineFlags::boolAtPut((char*)"TraceClassUnloading", &value, Flag::MANAGEMENT);
   62.18    assert(succeed, "Setting TraceClassUnLoading flag fails");
   62.19  }
   62.20  
    63.1 --- a/src/share/vm/services/dtraceAttacher.cpp	Tue Oct 01 11:06:35 2013 -0400
    63.2 +++ b/src/share/vm/services/dtraceAttacher.cpp	Thu Oct 03 16:38:21 2013 +0400
    63.3 @@ -51,7 +51,7 @@
    63.4  
    63.5  static void set_bool_flag(const char* flag, bool value) {
    63.6    CommandLineFlags::boolAtPut((char*)flag, strlen(flag), &value,
    63.7 -                              ATTACH_ON_DEMAND);
    63.8 +                              Flag::ATTACH_ON_DEMAND);
    63.9  }
   63.10  
   63.11  // Enable only the "fine grained" flags. Do *not* touch
    64.1 --- a/src/share/vm/services/management.cpp	Tue Oct 01 11:06:35 2013 -0400
    64.2 +++ b/src/share/vm/services/management.cpp	Thu Oct 03 16:38:21 2013 +0400
    64.3 @@ -1643,9 +1643,13 @@
    64.4    int num_entries = 0;
    64.5    for (int i = 0; i < nFlags; i++) {
    64.6      Flag* flag = &Flag::flags[i];
    64.7 +    // Exclude notproduct and develop flags in product builds.
    64.8 +    if (flag->is_constant_in_binary()) {
    64.9 +      continue;
   64.10 +    }
   64.11      // Exclude the locked (experimental, diagnostic) flags
   64.12      if (flag->is_unlocked() || flag->is_unlocker()) {
   64.13 -      Handle s = java_lang_String::create_from_str(flag->name, CHECK_0);
   64.14 +      Handle s = java_lang_String::create_from_str(flag->_name, CHECK_0);
   64.15        flags_ah->obj_at_put(num_entries, s());
   64.16        num_entries++;
   64.17      }
   64.18 @@ -1669,7 +1673,7 @@
   64.19  bool add_global_entry(JNIEnv* env, Handle name, jmmVMGlobal *global, Flag *flag, TRAPS) {
   64.20    Handle flag_name;
   64.21    if (name() == NULL) {
   64.22 -    flag_name = java_lang_String::create_from_str(flag->name, CHECK_false);
   64.23 +    flag_name = java_lang_String::create_from_str(flag->_name, CHECK_false);
   64.24    } else {
   64.25      flag_name = name;
   64.26    }
   64.27 @@ -1698,23 +1702,23 @@
   64.28  
   64.29    global->writeable = flag->is_writeable();
   64.30    global->external = flag->is_external();
   64.31 -  switch (flag->origin) {
   64.32 -    case DEFAULT:
   64.33 +  switch (flag->get_origin()) {
   64.34 +    case Flag::DEFAULT:
   64.35        global->origin = JMM_VMGLOBAL_ORIGIN_DEFAULT;
   64.36        break;
   64.37 -    case COMMAND_LINE:
   64.38 +    case Flag::COMMAND_LINE:
   64.39        global->origin = JMM_VMGLOBAL_ORIGIN_COMMAND_LINE;
   64.40        break;
   64.41 -    case ENVIRON_VAR:
   64.42 +    case Flag::ENVIRON_VAR:
   64.43        global->origin = JMM_VMGLOBAL_ORIGIN_ENVIRON_VAR;
   64.44        break;
   64.45 -    case CONFIG_FILE:
   64.46 +    case Flag::CONFIG_FILE:
   64.47        global->origin = JMM_VMGLOBAL_ORIGIN_CONFIG_FILE;
   64.48        break;
   64.49 -    case MANAGEMENT:
   64.50 +    case Flag::MANAGEMENT:
   64.51        global->origin = JMM_VMGLOBAL_ORIGIN_MANAGEMENT;
   64.52        break;
   64.53 -    case ERGONOMIC:
   64.54 +    case Flag::ERGONOMIC:
   64.55        global->origin = JMM_VMGLOBAL_ORIGIN_ERGONOMIC;
   64.56        break;
   64.57      default:
   64.58 @@ -1781,6 +1785,10 @@
   64.59      int num_entries = 0;
   64.60      for (int i = 0; i < nFlags && num_entries < count;  i++) {
   64.61        Flag* flag = &Flag::flags[i];
   64.62 +      // Exclude notproduct and develop flags in product builds.
   64.63 +      if (flag->is_constant_in_binary()) {
   64.64 +        continue;
   64.65 +      }
   64.66        // Exclude the locked (diagnostic, experimental) flags
   64.67        if ((flag->is_unlocked() || flag->is_unlocker()) &&
   64.68            add_global_entry(env, null_h, &globals[num_entries], flag, THREAD)) {
   64.69 @@ -1813,23 +1821,23 @@
   64.70    bool succeed;
   64.71    if (flag->is_bool()) {
   64.72      bool bvalue = (new_value.z == JNI_TRUE ? true : false);
   64.73 -    succeed = CommandLineFlags::boolAtPut(name, &bvalue, MANAGEMENT);
   64.74 +    succeed = CommandLineFlags::boolAtPut(name, &bvalue, Flag::MANAGEMENT);
   64.75    } else if (flag->is_intx()) {
   64.76      intx ivalue = (intx)new_value.j;
   64.77 -    succeed = CommandLineFlags::intxAtPut(name, &ivalue, MANAGEMENT);
   64.78 +    succeed = CommandLineFlags::intxAtPut(name, &ivalue, Flag::MANAGEMENT);
   64.79    } else if (flag->is_uintx()) {
   64.80      uintx uvalue = (uintx)new_value.j;
   64.81 -    succeed = CommandLineFlags::uintxAtPut(name, &uvalue, MANAGEMENT);
   64.82 +    succeed = CommandLineFlags::uintxAtPut(name, &uvalue, Flag::MANAGEMENT);
   64.83    } else if (flag->is_uint64_t()) {
   64.84      uint64_t uvalue = (uint64_t)new_value.j;
   64.85 -    succeed = CommandLineFlags::uint64_tAtPut(name, &uvalue, MANAGEMENT);
   64.86 +    succeed = CommandLineFlags::uint64_tAtPut(name, &uvalue, Flag::MANAGEMENT);
   64.87    } else if (flag->is_ccstr()) {
   64.88      oop str = JNIHandles::resolve_external_guard(new_value.l);
   64.89      if (str == NULL) {
   64.90        THROW(vmSymbols::java_lang_NullPointerException());
   64.91      }
   64.92      ccstr svalue = java_lang_String::as_utf8_string(str);
   64.93 -    succeed = CommandLineFlags::ccstrAtPut(name, &svalue, MANAGEMENT);
   64.94 +    succeed = CommandLineFlags::ccstrAtPut(name, &svalue, Flag::MANAGEMENT);
   64.95    }
   64.96    assert(succeed, "Setting flag should succeed");
   64.97  JVM_END
    65.1 --- a/src/share/vm/services/memoryService.cpp	Tue Oct 01 11:06:35 2013 -0400
    65.2 +++ b/src/share/vm/services/memoryService.cpp	Thu Oct 03 16:38:21 2013 +0400
    65.3 @@ -515,7 +515,7 @@
    65.4  bool MemoryService::set_verbose(bool verbose) {
    65.5    MutexLocker m(Management_lock);
    65.6    // verbose will be set to the previous value
    65.7 -  bool succeed = CommandLineFlags::boolAtPut((char*)"PrintGC", &verbose, MANAGEMENT);
    65.8 +  bool succeed = CommandLineFlags::boolAtPut((char*)"PrintGC", &verbose, Flag::MANAGEMENT);
    65.9    assert(succeed, "Setting PrintGC flag fails");
   65.10    ClassLoadingService::reset_trace_class_unloading();
   65.11  
   65.12 @@ -618,4 +618,3 @@
   65.13    MemoryService::gc_end(_fullGC, _recordPostGCUsage, _recordAccumulatedGCTime,
   65.14                          _recordGCEndTime, _countCollection, _cause);
   65.15  }
   65.16 -
    66.1 --- a/src/share/vm/trace/trace.xml	Tue Oct 01 11:06:35 2013 -0400
    66.2 +++ b/src/share/vm/trace/trace.xml	Thu Oct 03 16:38:21 2013 +0400
    66.3 @@ -313,13 +313,6 @@
    66.4        <value type="UINT" field="zombifiedCount" label="Methods Zombified"/>
    66.5      </event>
    66.6  
    66.7 -    <event id="CleanCodeCache" path="vm/code_sweeper/clean" label="Clean Code Cache"
    66.8 -             description="Clean code cache from oldest methods"
    66.9 -             has_thread="true" is_requestable="false" is_constant="false">
   66.10 -      <value type="UINT" field="disconnectedCount" label="Methods Disconnected"/>
   66.11 -      <value type="UINT" field="madeNonEntrantCount" label="Methods Made Non-Entrant"/>
   66.12 -    </event>
   66.13 -
   66.14      <!-- Code cache events -->
   66.15  
   66.16      <event id="CodeCacheFull" path="vm/code_cache/full" label="Code Cache Full"
    67.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    67.2 +++ b/test/compiler/intrinsics/mathexact/CondTest.java	Thu Oct 03 16:38:21 2013 +0400
    67.3 @@ -0,0 +1,59 @@
    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 + * @test
   67.29 + * @bug 8024924
   67.30 + * @summary Test non constant addExact
   67.31 + * @compile CondTest.java Verify.java
   67.32 + * @run main CondTest
   67.33 + *
   67.34 + */
   67.35 +
   67.36 +import java.lang.ArithmeticException;
   67.37 +
   67.38 +public class CondTest {
   67.39 +  public static int result = 0;
   67.40 +
   67.41 +  public static void main(String[] args) {
   67.42 +    for (int i = 0; i < 50000; ++i) {
   67.43 +      runTest();
   67.44 +    }
   67.45 +  }
   67.46 +
   67.47 +  public static void runTest() {
   67.48 +    int i = 7;
   67.49 +    while (java.lang.Math.addExact(i, result) < 89361) {
   67.50 +        if ((java.lang.Math.addExact(i, i) & 1) == 1) {
   67.51 +            i += 3;
   67.52 +        } else if ((i & 5) == 4) {
   67.53 +            i += 7;
   67.54 +        } else if ((i & 0xf) == 6) {
   67.55 +            i += 2;
   67.56 +        } else {
   67.57 +            i += 1;
   67.58 +        }
   67.59 +        result += 2;
   67.60 +    }
   67.61 +  }
   67.62 +}
    68.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    68.2 +++ b/test/compiler/intrinsics/mathexact/ConstantTest.java	Thu Oct 03 16:38:21 2013 +0400
    68.3 @@ -0,0 +1,47 @@
    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 + * @test
   68.29 + * @bug 8024924
   68.30 + * @summary Test constant addExact
   68.31 + * @compile ConstantTest.java Verify.java
   68.32 + * @run main ConstantTest
   68.33 + *
   68.34 + */
   68.35 +
   68.36 +import java.lang.ArithmeticException;
   68.37 +
   68.38 +public class ConstantTest {
   68.39 +  public static void main(String[] args) {
   68.40 +    for (int i = 0; i < 50000; ++i) {
   68.41 +      Verify.verify(5, 7);
   68.42 +      Verify.verify(Integer.MAX_VALUE, 1);
   68.43 +      Verify.verify(Integer.MIN_VALUE, -1);
   68.44 +      Verify.verify(Integer.MAX_VALUE, -1);
   68.45 +      Verify.verify(Integer.MIN_VALUE, 1);
   68.46 +      Verify.verify(Integer.MAX_VALUE / 2, Integer.MAX_VALUE / 2);
   68.47 +      Verify.verify(Integer.MAX_VALUE / 2, (Integer.MAX_VALUE / 2) + 3);
   68.48 +    }
   68.49 +  }
   68.50 +}
    69.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.2 +++ b/test/compiler/intrinsics/mathexact/LoadTest.java	Thu Oct 03 16:38:21 2013 +0400
    69.3 @@ -0,0 +1,55 @@
    69.4 +/*
    69.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    69.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    69.7 + *
    69.8 + * This code is free software; you can redistribute it and/or modify it
    69.9 + * under the terms of the GNU General Public License version 2 only, as
   69.10 + * published by the Free Software Foundation.
   69.11 + *
   69.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   69.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   69.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   69.15 + * version 2 for more details (a copy is included in the LICENSE file that
   69.16 + * accompanied this code).
   69.17 + *
   69.18 + * You should have received a copy of the GNU General Public License version
   69.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   69.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   69.21 + *
   69.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   69.23 + * or visit www.oracle.com if you need additional information or have any
   69.24 + * questions.
   69.25 + */
   69.26 +
   69.27 +/*
   69.28 + * @test
   69.29 + * @bug 8024924
   69.30 + * @summary Test non constant addExact
   69.31 + * @compile LoadTest.java Verify.java
   69.32 + * @run main LoadTest
   69.33 + *
   69.34 + */
   69.35 +
   69.36 +import java.lang.ArithmeticException;
   69.37 +
   69.38 +public class LoadTest {
   69.39 +  public static java.util.Random rnd = new java.util.Random();
   69.40 +  public static int[] values = new int[256];
   69.41 +
   69.42 +  public static void main(String[] args) {
   69.43 +    for (int i = 0; i < values.length; ++i) {
   69.44 +        values[i] = rnd.nextInt();
   69.45 +    }
   69.46 +
   69.47 +    for (int i = 0; i < 50000; ++i) {
   69.48 +      Verify.verify(values[i & 255], values[i & 255] - i);
   69.49 +      Verify.verify(values[i & 255] + i, values[i & 255] - i);
   69.50 +      Verify.verify(values[i & 255], values[i & 255]);
   69.51 +      if ((i & 1) == 1 && i > 5) {
   69.52 +          Verify.verify(values[i & 255] + i, values[i & 255] - i);
   69.53 +      } else {
   69.54 +          Verify.verify(values[i & 255] - i, values[i & 255] + i);
   69.55 +      }
   69.56 +    }
   69.57 +  }
   69.58 +}
    70.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.2 +++ b/test/compiler/intrinsics/mathexact/LoopDependentTest.java	Thu Oct 03 16:38:21 2013 +0400
    70.3 @@ -0,0 +1,48 @@
    70.4 +/*
    70.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    70.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    70.7 + *
    70.8 + * This code is free software; you can redistribute it and/or modify it
    70.9 + * under the terms of the GNU General Public License version 2 only, as
   70.10 + * published by the Free Software Foundation.
   70.11 + *
   70.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   70.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   70.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   70.15 + * version 2 for more details (a copy is included in the LICENSE file that
   70.16 + * accompanied this code).
   70.17 + *
   70.18 + * You should have received a copy of the GNU General Public License version
   70.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   70.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   70.21 + *
   70.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   70.23 + * or visit www.oracle.com if you need additional information or have any
   70.24 + * questions.
   70.25 + */
   70.26 +
   70.27 +/*
   70.28 + * @test
   70.29 + * @bug 8024924
   70.30 + * @summary Test non constant addExact
   70.31 + * @compile LoopDependentTest.java Verify.java
   70.32 + * @run main LoopDependentTest
   70.33 + *
   70.34 + */
   70.35 +
   70.36 +import java.lang.ArithmeticException;
   70.37 +
   70.38 +public class LoopDependentTest {
   70.39 +  public static java.util.Random rnd = new java.util.Random();
   70.40 +
   70.41 +  public static void main(String[] args) {
   70.42 +    int rnd1 = rnd.nextInt(), rnd2 = rnd.nextInt();
   70.43 +    for (int i = 0; i < 50000; ++i) {
   70.44 +      Verify.verify(rnd1 + i, rnd2 + i);
   70.45 +      Verify.verify(rnd1 + i, rnd2 + (i & 0xff));
   70.46 +      Verify.verify(rnd1 - i, rnd2 - (i & 0xff));
   70.47 +      Verify.verify(rnd1 + i + 1, rnd2 + i + 2);
   70.48 +      Verify.verify(rnd1 + i * 2, rnd2 + i);
   70.49 +    }
   70.50 +  }
   70.51 +}
    71.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    71.2 +++ b/test/compiler/intrinsics/mathexact/NonConstantTest.java	Thu Oct 03 16:38:21 2013 +0400
    71.3 @@ -0,0 +1,48 @@
    71.4 +/*
    71.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    71.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    71.7 + *
    71.8 + * This code is free software; you can redistribute it and/or modify it
    71.9 + * under the terms of the GNU General Public License version 2 only, as
   71.10 + * published by the Free Software Foundation.
   71.11 + *
   71.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   71.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   71.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   71.15 + * version 2 for more details (a copy is included in the LICENSE file that
   71.16 + * accompanied this code).
   71.17 + *
   71.18 + * You should have received a copy of the GNU General Public License version
   71.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   71.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   71.21 + *
   71.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   71.23 + * or visit www.oracle.com if you need additional information or have any
   71.24 + * questions.
   71.25 + */
   71.26 +
   71.27 +/*
   71.28 + * @test
   71.29 + * @bug 8024924
   71.30 + * @summary Test non constant addExact
   71.31 + * @compile NonConstantTest.java Verify.java
   71.32 + * @run main NonConstantTest
   71.33 + *
   71.34 + */
   71.35 +
   71.36 +import java.lang.ArithmeticException;
   71.37 +
   71.38 +public class NonConstantTest {
   71.39 +  public static java.util.Random rnd = new java.util.Random();
   71.40 +
   71.41 +  public static void main(String[] args) {
   71.42 +    for (int i = 0; i < 50000; ++i) {
   71.43 +      int rnd1 = rnd.nextInt(), rnd2 = rnd.nextInt();
   71.44 +      Verify.verify(rnd1, rnd2);
   71.45 +      Verify.verify(rnd1, rnd2 + 1);
   71.46 +      Verify.verify(rnd1 + 1, rnd2);
   71.47 +      Verify.verify(rnd1 - 1, rnd2);
   71.48 +      Verify.verify(rnd1, rnd2 - 1);
   71.49 +    }
   71.50 +  }
   71.51 +}
    72.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    72.2 +++ b/test/compiler/intrinsics/mathexact/Verify.java	Thu Oct 03 16:38:21 2013 +0400
    72.3 @@ -0,0 +1,68 @@
    72.4 +/*
    72.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    72.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    72.7 + *
    72.8 + * This code is free software; you can redistribute it and/or modify it
    72.9 + * under the terms of the GNU General Public License version 2 only, as
   72.10 + * published by the Free Software Foundation.
   72.11 + *
   72.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   72.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   72.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   72.15 + * version 2 for more details (a copy is included in the LICENSE file that
   72.16 + * accompanied this code).
   72.17 + *
   72.18 + * You should have received a copy of the GNU General Public License version
   72.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   72.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   72.21 + *
   72.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   72.23 + * or visit www.oracle.com if you need additional information or have any
   72.24 + * questions.
   72.25 + */
   72.26 +
   72.27 +public class Verify {
   72.28 +  public static String throwWord(boolean threw) {
   72.29 +    return (threw ? "threw" : "didn't throw");
   72.30 +  }
   72.31 +
   72.32 +  public static void verify(int a, int b) {
   72.33 +    boolean exception1 = false, exception2 = false;
   72.34 +    int result1 = 0, result2 = 0;
   72.35 +    try {
   72.36 +      result1 = testIntrinsic(a, b);
   72.37 +    } catch (ArithmeticException e) {
   72.38 +      exception1 = true;
   72.39 +    }
   72.40 +    try {
   72.41 +      result2 = testNonIntrinsic(a, b);
   72.42 +    } catch (ArithmeticException e) {
   72.43 +      exception2 = true;
   72.44 +    }
   72.45 +
   72.46 +    if (exception1 != exception2) {
   72.47 +      throw new RuntimeException("Intrinsic version " + throwWord(exception1) + " exception, NonIntrinsic version " + throwWord(exception2) + " for: " + a + " + " + b);
   72.48 +    }
   72.49 +    if (result1 != result2) {
   72.50 +      throw new RuntimeException("Intrinsic version returned: " + a + " while NonIntrinsic version returned: " + b);
   72.51 +    }
   72.52 +  }
   72.53 +
   72.54 +  public static int testIntrinsic(int a, int b) {
   72.55 +    return java.lang.Math.addExact(a, b);
   72.56 +  }
   72.57 +
   72.58 +  public static int testNonIntrinsic(int a, int b) {
   72.59 +    return safeAddExact(a, b);
   72.60 +  }
   72.61 +
   72.62 +  // Copied java.lang.Math.addExact to avoid intrinsification
   72.63 +  public static int safeAddExact(int x, int y) {
   72.64 +    int r = x + y;
   72.65 +    // HD 2-12 Overflow iff both arguments have the opposite sign of the result
   72.66 +    if (((x ^ r) & (y ^ r)) < 0) {
   72.67 +      throw new ArithmeticException("integer overflow");
   72.68 +    }
   72.69 +    return r;
   72.70 +  }
   72.71 +}
    73.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    73.2 +++ b/test/compiler/jsr292/methodHandleExceptions/ByteClassLoader.java	Thu Oct 03 16:38:21 2013 +0400
    73.3 @@ -0,0 +1,44 @@
    73.4 +/*
    73.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    73.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    73.7 + *
    73.8 + * This code is free software; you can redistribute it and/or modify it
    73.9 + * under the terms of the GNU General Public License version 2 only, as
   73.10 + * published by the Free Software Foundation.
   73.11 + *
   73.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   73.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   73.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   73.15 + * version 2 for more details (a copy is included in the LICENSE file that
   73.16 + * accompanied this code).
   73.17 + *
   73.18 + * You should have received a copy of the GNU General Public License version
   73.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   73.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   73.21 + *
   73.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   73.23 + * or visit www.oracle.com if you need additional information or have any
   73.24 + * questions.
   73.25 + *
   73.26 + */
   73.27 +
   73.28 +/**
   73.29 + * A minimal classloader for loading bytecodes that could not result from
   73.30 + * properly compiled Java.
   73.31 + *
   73.32 + * @author dr2chase
   73.33 + */
   73.34 +public class ByteClassLoader extends ClassLoader {
   73.35 +    /**
   73.36 +     * (pre)load class name using classData for the definition.
   73.37 +     *
   73.38 +     * @param name
   73.39 +     * @param classData
   73.40 +     * @return
   73.41 +     */
   73.42 +    public Class<?> loadBytes(String name, byte[] classData) {
   73.43 +         Class<?> clazz = defineClass(name, classData, 0, classData.length);
   73.44 +                     resolveClass(clazz);
   73.45 +         return clazz;
   73.46 +    }
   73.47 +}
    74.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    74.2 +++ b/test/compiler/jsr292/methodHandleExceptions/C.java	Thu Oct 03 16:38:21 2013 +0400
    74.3 @@ -0,0 +1,33 @@
    74.4 +/*
    74.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    74.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    74.7 + *
    74.8 + * This code is free software; you can redistribute it and/or modify it
    74.9 + * under the terms of the GNU General Public License version 2 only, as
   74.10 + * published by the Free Software Foundation.
   74.11 + *
   74.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   74.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   74.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   74.15 + * version 2 for more details (a copy is included in the LICENSE file that
   74.16 + * accompanied this code).
   74.17 + *
   74.18 + * You should have received a copy of the GNU General Public License version
   74.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   74.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   74.21 + *
   74.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   74.23 + * or visit www.oracle.com if you need additional information or have any
   74.24 + * questions.
   74.25 + *
   74.26 + */
   74.27 +
   74.28 +/**
   74.29 + * Test class -- implements I, which provides default for m, but this class
   74.30 + * declares it abstract which (should) hide the interface default, and throw
   74.31 + * an abstract method error if it is called (calling it requires bytecode hacking
   74.32 + * or inconsistent compilation).
   74.33 + */
   74.34 +public abstract class C implements I {
   74.35 +       public abstract int m();
   74.36 +}
    75.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    75.2 +++ b/test/compiler/jsr292/methodHandleExceptions/I.java	Thu Oct 03 16:38:21 2013 +0400
    75.3 @@ -0,0 +1,27 @@
    75.4 +/*
    75.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    75.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    75.7 + *
    75.8 + * This code is free software; you can redistribute it and/or modify it
    75.9 + * under the terms of the GNU General Public License version 2 only, as
   75.10 + * published by the Free Software Foundation.
   75.11 + *
   75.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   75.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   75.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   75.15 + * version 2 for more details (a copy is included in the LICENSE file that
   75.16 + * accompanied this code).
   75.17 + *
   75.18 + * You should have received a copy of the GNU General Public License version
   75.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   75.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   75.21 + *
   75.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   75.23 + * or visit www.oracle.com if you need additional information or have any
   75.24 + * questions.
   75.25 + *
   75.26 + */
   75.27 +
   75.28 +public interface I {
   75.29 +    default public int m() { return 1; }
   75.30 +}
    76.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    76.2 +++ b/test/compiler/jsr292/methodHandleExceptions/TestAMEnotNPE.java	Thu Oct 03 16:38:21 2013 +0400
    76.3 @@ -0,0 +1,143 @@
    76.4 +/*
    76.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    76.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    76.7 + *
    76.8 + * This code is free software; you can redistribute it and/or modify it
    76.9 + * under the terms of the GNU General Public License version 2 only, as
   76.10 + * published by the Free Software Foundation.
   76.11 + *
   76.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   76.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   76.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   76.15 + * version 2 for more details (a copy is included in the LICENSE file that
   76.16 + * accompanied this code).
   76.17 + *
   76.18 + * You should have received a copy of the GNU General Public License version
   76.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   76.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   76.21 + *
   76.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   76.23 + * or visit www.oracle.com if you need additional information or have any
   76.24 + * questions.
   76.25 + *
   76.26 + */
   76.27 +
   76.28 +import java.lang.reflect.InvocationTargetException;
   76.29 +import jdk.internal.org.objectweb.asm.ClassWriter;
   76.30 +import jdk.internal.org.objectweb.asm.Handle;
   76.31 +import jdk.internal.org.objectweb.asm.MethodVisitor;
   76.32 +import jdk.internal.org.objectweb.asm.Opcodes;
   76.33 +
   76.34 +/**
   76.35 + * @test
   76.36 + * @bug 8025260
   76.37 + * @summary Ensure that AbstractMethodError is thrown, not NullPointerException, through MethodHandles::jump_from_method_handle code path
   76.38 + *
   76.39 + * @compile -XDignore.symbol.file ByteClassLoader.java I.java C.java TestAMEnotNPE.java
   76.40 + * @run main/othervm TestAMEnotNPE
   76.41 + */
   76.42 +
   76.43 +public class TestAMEnotNPE implements Opcodes {
   76.44 +
   76.45 +    /**
   76.46 +     * The bytes for D, a NOT abstract class extending abstract class C
   76.47 +     * without supplying an implementation for abstract method m.
   76.48 +     * There is a default method in the interface I, but it should lose to
   76.49 +     * the abstract class.
   76.50 +
   76.51 +     class D extends C {
   76.52 +        D() { super(); }
   76.53 +        // does not define m
   76.54 +     }
   76.55 +
   76.56 +     * @return
   76.57 +     * @throws Exception
   76.58 +     */
   76.59 +    public static byte[] bytesForD() throws Exception {
   76.60 +
   76.61 +        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
   76.62 +        MethodVisitor mv;
   76.63 +
   76.64 +        cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, "D", null, "C", null);
   76.65 +
   76.66 +        {
   76.67 +            mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
   76.68 +            mv.visitCode();
   76.69 +            mv.visitVarInsn(ALOAD, 0);
   76.70 +            mv.visitMethodInsn(INVOKESPECIAL, "C", "<init>", "()V");
   76.71 +            mv.visitInsn(RETURN);
   76.72 +            mv.visitMaxs(0, 0);
   76.73 +            mv.visitEnd();
   76.74 +        }
   76.75 +        cw.visitEnd();
   76.76 +
   76.77 +        return cw.toByteArray();
   76.78 +    }
   76.79 +
   76.80 +
   76.81 +    /**
   76.82 +     * The bytecodes for an invokeExact of a particular methodHandle, I.m, invoked on a D
   76.83 +
   76.84 +        class T {
   76.85 +           T() { super(); } // boring constructor
   76.86 +           int test() {
   76.87 +              MethodHandle mh = `I.m():int`;
   76.88 +              D d = new D();
   76.89 +              return mh.invokeExact(d); // Should explode here, AbstractMethodError
   76.90 +           }
   76.91 +        }
   76.92 +
   76.93 +     * @return
   76.94 +     * @throws Exception
   76.95 +     */
   76.96 +    public static byte[] bytesForT() throws Exception {
   76.97 +
   76.98 +        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
   76.99 +        MethodVisitor mv;
  76.100 +
  76.101 +        cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, "T", null, "java/lang/Object", null);
  76.102 +        {
  76.103 +            mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
  76.104 +            mv.visitCode();
  76.105 +            mv.visitVarInsn(ALOAD, 0);
  76.106 +            mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
  76.107 +            mv.visitInsn(RETURN);
  76.108 +            mv.visitMaxs(0,0);
  76.109 +            mv.visitEnd();
  76.110 +        }
  76.111 +        {
  76.112 +            mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "test", "()I", null, null);
  76.113 +            mv.visitCode();
  76.114 +            mv.visitLdcInsn(new Handle(Opcodes.H_INVOKEINTERFACE, "I", "m", "()I"));
  76.115 +            mv.visitTypeInsn(NEW, "D");
  76.116 +            mv.visitInsn(DUP);
  76.117 +            mv.visitMethodInsn(INVOKESPECIAL, "D", "<init>", "()V");
  76.118 +            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", "invokeExact", "(LI;)I");
  76.119 +            mv.visitInsn(IRETURN);
  76.120 +            mv.visitMaxs(0,0);
  76.121 +            mv.visitEnd();
  76.122 +        }
  76.123 +        cw.visitEnd();
  76.124 +        return cw.toByteArray();
  76.125 +    }
  76.126 +
  76.127 +    public static void main(String args[] ) throws Throwable {
  76.128 +        ByteClassLoader bcl = new ByteClassLoader();
  76.129 +        Class<?> d = bcl.loadBytes("D", bytesForD());
  76.130 +        Class<?> t = bcl.loadBytes("T", bytesForT());
  76.131 +        try {
  76.132 +          Object result = t.getMethod("test").invoke(null);
  76.133 +          System.out.println("Expected AbstractMethodError wrapped in InvocationTargetException, saw no exception");
  76.134 +          throw new Error("Missing expected exception");
  76.135 +        } catch (InvocationTargetException e) {
  76.136 +            Throwable th = e.getCause();
  76.137 +            if (th instanceof AbstractMethodError) {
  76.138 +                th.printStackTrace(System.out);
  76.139 +                System.out.println("PASS, saw expected exception (AbstractMethodError, wrapped in InvocationTargetException).");
  76.140 +            } else {
  76.141 +                System.out.println("Expected AbstractMethodError wrapped in InvocationTargetException, saw " + th);
  76.142 +                throw th;
  76.143 +            }
  76.144 +        }
  76.145 +    }
  76.146 +}
    77.1 --- a/test/compiler/whitebox/CompilerWhiteBoxTest.java	Tue Oct 01 11:06:35 2013 -0400
    77.2 +++ b/test/compiler/whitebox/CompilerWhiteBoxTest.java	Thu Oct 03 16:38:21 2013 +0400
    77.3 @@ -74,6 +74,9 @@
    77.4      protected static final int THRESHOLD;
    77.5      /** count of invocation to triger OSR compilation */
    77.6      protected static final long BACKEDGE_THRESHOLD;
    77.7 +    /** Value of {@code java.vm.info} (interpreted|mixed|comp mode) */
    77.8 +    protected static final String MODE
    77.9 +            = System.getProperty("java.vm.info");
   77.10  
   77.11      static {
   77.12          if (TIERED_COMPILATION) {
   77.13 @@ -202,7 +205,7 @@
   77.14          if (WHITE_BOX.getMethodCompilationLevel(method, true) != 0) {
   77.15              throw new RuntimeException(method + " osr_comp_level must be == 0");
   77.16          }
   77.17 -    }
   77.18 +   }
   77.19  
   77.20      /**
   77.21       * Checks, that {@linkplain #method} is compiled.
    78.1 --- a/test/compiler/whitebox/DeoptimizeAllTest.java	Tue Oct 01 11:06:35 2013 -0400
    78.2 +++ b/test/compiler/whitebox/DeoptimizeAllTest.java	Thu Oct 03 16:38:21 2013 +0400
    78.3 @@ -53,6 +53,12 @@
    78.4       */
    78.5      @Override
    78.6      protected void test() throws Exception {
    78.7 +        if (testCase.isOsr && CompilerWhiteBoxTest.MODE.startsWith(
    78.8 +                "compiled ")) {
    78.9 +          System.err.printf("Warning: %s is not applicable in %s%n",
   78.10 +                testCase.name(), CompilerWhiteBoxTest.MODE);
   78.11 +          return;
   78.12 +        }
   78.13          compile();
   78.14          checkCompiled();
   78.15          WHITE_BOX.deoptimizeAll();
    79.1 --- a/test/compiler/whitebox/DeoptimizeMethodTest.java	Tue Oct 01 11:06:35 2013 -0400
    79.2 +++ b/test/compiler/whitebox/DeoptimizeMethodTest.java	Thu Oct 03 16:38:21 2013 +0400
    79.3 @@ -53,6 +53,12 @@
    79.4       */
    79.5      @Override
    79.6      protected void test() throws Exception {
    79.7 +        if (testCase.isOsr && CompilerWhiteBoxTest.MODE.startsWith(
    79.8 +                "compiled ")) {
    79.9 +          System.err.printf("Warning: %s is not applicable in %s%n",
   79.10 +                testCase.name(), CompilerWhiteBoxTest.MODE);
   79.11 +          return;
   79.12 +        }
   79.13          compile();
   79.14          checkCompiled();
   79.15          deoptimize();
    80.1 --- a/test/compiler/whitebox/EnqueueMethodForCompilationTest.java	Tue Oct 01 11:06:35 2013 -0400
    80.2 +++ b/test/compiler/whitebox/EnqueueMethodForCompilationTest.java	Thu Oct 03 16:38:21 2013 +0400
    80.3 @@ -70,12 +70,10 @@
    80.4  
    80.5          int compLevel = getCompLevel();
    80.6          int bci = WHITE_BOX.getMethodEntryBci(method);
    80.7 -        System.out.println("bci = " + bci);
    80.8 -        printInfo();
    80.9          deoptimize();
   80.10 -        printInfo();
   80.11          checkNotCompiled();
   80.12 -        printInfo();
   80.13 +        WHITE_BOX.clearMethodState(method);
   80.14 +
   80.15          WHITE_BOX.enqueueMethodForCompilation(method, compLevel, bci);
   80.16          checkCompiled();
   80.17          deoptimize();
    81.1 --- a/test/compiler/whitebox/IsMethodCompilableTest.java	Tue Oct 01 11:06:35 2013 -0400
    81.2 +++ b/test/compiler/whitebox/IsMethodCompilableTest.java	Thu Oct 03 16:38:21 2013 +0400
    81.3 @@ -68,6 +68,12 @@
    81.4       */
    81.5      @Override
    81.6      protected void test() throws Exception {
    81.7 +        if (testCase.isOsr && CompilerWhiteBoxTest.MODE.startsWith(
    81.8 +                "compiled ")) {
    81.9 +          System.err.printf("Warning: %s is not applicable in %s%n",
   81.10 +                testCase.name(), CompilerWhiteBoxTest.MODE);
   81.11 +          return;
   81.12 +        }
   81.13          if (!isCompilable()) {
   81.14              throw new RuntimeException(method + " must be compilable");
   81.15          }
    82.1 --- a/test/compiler/whitebox/MakeMethodNotCompilableTest.java	Tue Oct 01 11:06:35 2013 -0400
    82.2 +++ b/test/compiler/whitebox/MakeMethodNotCompilableTest.java	Thu Oct 03 16:38:21 2013 +0400
    82.3 @@ -62,6 +62,12 @@
    82.4       */
    82.5      @Override
    82.6      protected void test() throws Exception {
    82.7 +        if (testCase.isOsr && CompilerWhiteBoxTest.MODE.startsWith(
    82.8 +                "compiled ")) {
    82.9 +          System.err.printf("Warning: %s is not applicable in %s%n",
   82.10 +                testCase.name(), CompilerWhiteBoxTest.MODE);
   82.11 +          return;
   82.12 +        }
   82.13          checkNotCompiled();
   82.14          if (!isCompilable()) {
   82.15              throw new RuntimeException(method + " must be compilable");
    83.1 --- a/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java	Tue Oct 01 11:06:35 2013 -0400
    83.2 +++ b/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java	Thu Oct 03 16:38:21 2013 +0400
    83.3 @@ -36,8 +36,7 @@
    83.4  import java.nio.file.attribute.*;
    83.5  
    83.6  /**
    83.7 - * * Handler for dirs containing classes to compile.
    83.8 - * @author igor.ignatyev@oracle.com
    83.9 + * Handler for dirs containing classes to compile.
   83.10   */
   83.11  public class ClassPathDirEntry extends PathHandler {
   83.12  
    84.1 --- a/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java	Tue Oct 01 11:06:35 2013 -0400
    84.2 +++ b/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java	Thu Oct 03 16:38:21 2013 +0400
    84.3 @@ -35,7 +35,6 @@
    84.4  
    84.5  /**
    84.6   * Handler for jar-files containing classes to compile.
    84.7 - * @author igor.ignatyev@oracle.com
    84.8   */
    84.9  public class ClassPathJarEntry extends PathHandler {
   84.10  
    85.1 --- a/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java	Tue Oct 01 11:06:35 2013 -0400
    85.2 +++ b/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java	Thu Oct 03 16:38:21 2013 +0400
    85.3 @@ -31,8 +31,6 @@
    85.4  
    85.5  /**
    85.6   * Handler for dirs containing jar-files with classes to compile.
    85.7 - *
    85.8 - * @author igor.ignatyev@oracle.com
    85.9   */
   85.10  public class ClassPathJarInDirEntry extends PathHandler {
   85.11  
    86.1 --- a/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java	Tue Oct 01 11:06:35 2013 -0400
    86.2 +++ b/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java	Thu Oct 03 16:38:21 2013 +0400
    86.3 @@ -32,8 +32,6 @@
    86.4  
    86.5  /**
    86.6   * Handler for files containing a list of classes to compile.
    86.7 - *
    86.8 - * @author igor.ignatyev@oracle.com
    86.9   */
   86.10  public class ClassesListInFile extends PathHandler {
   86.11      public ClassesListInFile(Path root, Executor executor) {
    87.1 --- a/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java	Tue Oct 01 11:06:35 2013 -0400
    87.2 +++ b/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java	Thu Oct 03 16:38:21 2013 +0400
    87.3 @@ -32,9 +32,6 @@
    87.4  import java.util.List;
    87.5  import java.util.concurrent.*;
    87.6  
    87.7 -/**
    87.8 - * @author igor.ignatyev@oracle.com
    87.9 - */
   87.10  public class CompileTheWorld {
   87.11      /**
   87.12       * Entry point. Compiles classes in {@code args}, or all classes in
    88.1 --- a/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java	Tue Oct 01 11:06:35 2013 -0400
    88.2 +++ b/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java	Thu Oct 03 16:38:21 2013 +0400
    88.3 @@ -36,8 +36,6 @@
    88.4  /**
    88.5   * Provide method to compile whole class.
    88.6   * Also contains compiled methods and classes counters.
    88.7 - *
    88.8 - * @author igor.ignatyev@oracle.com
    88.9   */
   88.10  public class Compiler {
   88.11      private Compiler() { }
    89.1 --- a/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java	Tue Oct 01 11:06:35 2013 -0400
    89.2 +++ b/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java	Thu Oct 03 16:38:21 2013 +0400
    89.3 @@ -35,10 +35,7 @@
    89.4  
    89.5  /**
    89.6   * Abstract handler for path.
    89.7 - * <p/>
    89.8   * Concrete subclasses should implement method {@link #process()}.
    89.9 - *
   89.10 - * @author igor.ignatyev@oracle.com
   89.11   */
   89.12  public abstract class PathHandler {
   89.13      private static final Pattern JAR_IN_DIR_PATTERN
    90.1 --- a/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java	Tue Oct 01 11:06:35 2013 -0400
    90.2 +++ b/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java	Thu Oct 03 16:38:21 2013 +0400
    90.3 @@ -31,8 +31,6 @@
    90.4  
    90.5  /**
    90.6   * Auxiliary methods.
    90.7 - *
    90.8 - * @author igor.ignatyev@oracle.com
    90.9   */
   90.10  public class Utils {
   90.11      /**

mercurial