Thu, 03 Oct 2013 16:38:21 +0400
Merge
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 /**