8072725: Provide more granular levels for GC verification

Tue, 16 Feb 2016 21:42:29 +0000

author
poonam
date
Tue, 16 Feb 2016 21:42:29 +0000
changeset 8308
6acf14e730dd
parent 8306
81adfb064a4f
child 8309
240ea32410fa

8072725: Provide more granular levels for GC verification
Summary: Add option VerifySubSet to selectively verify the memory sub-systems
Reviewed-by: kevinw, jmasa

src/share/vm/memory/universe.cpp file | annotate | diff | comparison | revisions
src/share/vm/memory/universe.hpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/globals.hpp file | annotate | diff | comparison | revisions
test/gc/TestVerifySubSet.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/memory/universe.cpp	Tue Feb 16 13:56:12 2016 +0000
     1.2 +++ b/src/share/vm/memory/universe.cpp	Tue Feb 16 21:42:29 2016 +0000
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -124,6 +124,7 @@
    1.11  objArrayOop Universe::_preallocated_out_of_memory_error_array = NULL;
    1.12  volatile jint Universe::_preallocated_out_of_memory_error_avail_count = 0;
    1.13  bool Universe::_verify_in_progress                    = false;
    1.14 +long Universe::verify_flags                           = Universe::Verify_All;
    1.15  oop Universe::_null_ptr_exception_instance            = NULL;
    1.16  oop Universe::_arithmetic_exception_instance          = NULL;
    1.17  oop Universe::_virtual_machine_error_instance         = NULL;
    1.18 @@ -683,6 +684,9 @@
    1.19        MetaspaceShared::prepare_for_dumping();
    1.20      }
    1.21    }
    1.22 +  if (strlen(VerifySubSet) > 0) {
    1.23 +    Universe::initialize_verify_flags();
    1.24 +  }
    1.25  
    1.26    return JNI_OK;
    1.27  }
    1.28 @@ -1361,6 +1365,53 @@
    1.29    st->print_cr("}");
    1.30  }
    1.31  
    1.32 +void Universe::initialize_verify_flags() {
    1.33 +  verify_flags = 0;
    1.34 +  const char delimiter[] = " ,";
    1.35 +
    1.36 +  size_t length = strlen(VerifySubSet);
    1.37 +  char* subset_list = NEW_C_HEAP_ARRAY(char, length + 1, mtInternal);
    1.38 +  strncpy(subset_list, VerifySubSet, length + 1);
    1.39 +
    1.40 +  char* token = strtok(subset_list, delimiter);
    1.41 +  while (token != NULL) {
    1.42 +    if (strcmp(token, "threads") == 0) {
    1.43 +      verify_flags |= Verify_Threads;
    1.44 +    } else if (strcmp(token, "heap") == 0) {
    1.45 +      verify_flags |= Verify_Heap;
    1.46 +    } else if (strcmp(token, "symbol_table") == 0) {
    1.47 +      verify_flags |= Verify_SymbolTable;
    1.48 +    } else if (strcmp(token, "string_table") == 0) {
    1.49 +      verify_flags |= Verify_StringTable;
    1.50 +    } else if (strcmp(token, "codecache") == 0) {
    1.51 +      verify_flags |= Verify_CodeCache;
    1.52 +    } else if (strcmp(token, "dictionary") == 0) {
    1.53 +      verify_flags |= Verify_SystemDictionary;
    1.54 +    } else if (strcmp(token, "classloader_data_graph") == 0) {
    1.55 +      verify_flags |= Verify_ClassLoaderDataGraph;
    1.56 +    } else if (strcmp(token, "metaspace") == 0) {
    1.57 +      verify_flags |= Verify_MetaspaceAux;
    1.58 +    } else if (strcmp(token, "jni_handles") == 0) {
    1.59 +      verify_flags |= Verify_JNIHandles;
    1.60 +    } else if (strcmp(token, "c-heap") == 0) {
    1.61 +      verify_flags |= Verify_CHeap;
    1.62 +    } else if (strcmp(token, "codecache_oops") == 0) {
    1.63 +      verify_flags |= Verify_CodeCacheOops;
    1.64 +    } else {
    1.65 +      vm_exit_during_initialization(err_msg("VerifySubSet: \'%s\' memory sub-system is unknown, please correct it", token));
    1.66 +    }
    1.67 +    token = strtok(NULL, delimiter);
    1.68 +  }
    1.69 +  FREE_C_HEAP_ARRAY(char, subset_list, mtInternal);
    1.70 +}
    1.71 +
    1.72 +bool Universe::should_verify_subset(uint subset) {
    1.73 +  if (verify_flags & subset) {
    1.74 +    return true;
    1.75 +  }
    1.76 +  return false;
    1.77 +}
    1.78 +
    1.79  void Universe::verify(VerifyOption option, const char* prefix, bool silent) {
    1.80    // The use of _verify_in_progress is a temporary work around for
    1.81    // 6320749.  Don't bother with a creating a class to set and clear
    1.82 @@ -1380,33 +1431,55 @@
    1.83  
    1.84    if (!silent) gclog_or_tty->print("%s", prefix);
    1.85    if (!silent) gclog_or_tty->print("[Verifying ");
    1.86 -  if (!silent) gclog_or_tty->print("threads ");
    1.87 -  Threads::verify();
    1.88 -  if (!silent) gclog_or_tty->print("heap ");
    1.89 -  heap()->verify(silent, option);
    1.90 -  if (!silent) gclog_or_tty->print("syms ");
    1.91 -  SymbolTable::verify();
    1.92 -  if (!silent) gclog_or_tty->print("strs ");
    1.93 -  StringTable::verify();
    1.94 +  if (should_verify_subset(Verify_Threads)) {
    1.95 +    if (!silent) gclog_or_tty->print("Threads ");
    1.96 +    Threads::verify();
    1.97 +  }
    1.98 +  if (should_verify_subset(Verify_Heap)) {
    1.99 +    if (!silent) gclog_or_tty->print("Heap ");
   1.100 +    heap()->verify(silent, option);
   1.101 +  }
   1.102 +  if (should_verify_subset(Verify_SymbolTable)) {
   1.103 +    if (!silent) gclog_or_tty->print("SymbolTable ");
   1.104 +    SymbolTable::verify();
   1.105 +  }
   1.106 +  if (should_verify_subset(Verify_StringTable)) {
   1.107 +    if (!silent) gclog_or_tty->print("StringTable ");
   1.108 +    StringTable::verify();
   1.109 +  }
   1.110 +  if (should_verify_subset(Verify_CodeCache)) {
   1.111    {
   1.112      MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   1.113 -    if (!silent) gclog_or_tty->print("zone ");
   1.114 +    if (!silent) gclog_or_tty->print("CodeCache ");
   1.115      CodeCache::verify();
   1.116    }
   1.117 -  if (!silent) gclog_or_tty->print("dict ");
   1.118 -  SystemDictionary::verify();
   1.119 +  }
   1.120 +  if (should_verify_subset(Verify_SystemDictionary)) {
   1.121 +    if (!silent) gclog_or_tty->print("SystemDictionary ");
   1.122 +    SystemDictionary::verify();
   1.123 +  }
   1.124  #ifndef PRODUCT
   1.125 -  if (!silent) gclog_or_tty->print("cldg ");
   1.126 -  ClassLoaderDataGraph::verify();
   1.127 +  if (should_verify_subset(Verify_ClassLoaderDataGraph)) {
   1.128 +    if (!silent) gclog_or_tty->print("ClassLoaderDataGraph ");
   1.129 +    ClassLoaderDataGraph::verify();
   1.130 +  }
   1.131  #endif
   1.132 -  if (!silent) gclog_or_tty->print("metaspace chunks ");
   1.133 -  MetaspaceAux::verify_free_chunks();
   1.134 -  if (!silent) gclog_or_tty->print("hand ");
   1.135 -  JNIHandles::verify();
   1.136 -  if (!silent) gclog_or_tty->print("C-heap ");
   1.137 -  os::check_heap();
   1.138 -  if (!silent) gclog_or_tty->print("code cache ");
   1.139 -  CodeCache::verify_oops();
   1.140 +  if (should_verify_subset(Verify_MetaspaceAux)) {
   1.141 +    if (!silent) gclog_or_tty->print("MetaspaceAux ");
   1.142 +    MetaspaceAux::verify_free_chunks();
   1.143 +  }
   1.144 +  if (should_verify_subset(Verify_JNIHandles)) {
   1.145 +    if (!silent) gclog_or_tty->print("JNIHandles ");
   1.146 +    JNIHandles::verify();
   1.147 +  }
   1.148 +  if (should_verify_subset(Verify_CHeap)) {
   1.149 +    if (!silent) gclog_or_tty->print("C-heap ");
   1.150 +    os::check_heap();
   1.151 +  }
   1.152 +  if (should_verify_subset(Verify_CodeCacheOops)) {
   1.153 +    if (!silent) gclog_or_tty->print("CodeCache Oops ");
   1.154 +    CodeCache::verify_oops();
   1.155 +  }
   1.156    if (!silent) gclog_or_tty->print_cr("]");
   1.157  
   1.158    _verify_in_progress = false;
     2.1 --- a/src/share/vm/memory/universe.hpp	Tue Feb 16 13:56:12 2016 +0000
     2.2 +++ b/src/share/vm/memory/universe.hpp	Tue Feb 16 21:42:29 2016 +0000
     2.3 @@ -1,5 +1,5 @@
     2.4  /*
     2.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     2.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
     2.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.8   *
     2.9   * This code is free software; you can redistribute it and/or modify it
    2.10 @@ -247,6 +247,7 @@
    2.11    static int _verify_count;                           // number of verifies done
    2.12    // True during call to verify().  Should only be set/cleared in verify().
    2.13    static bool _verify_in_progress;
    2.14 +  static long verify_flags;
    2.15  
    2.16    static void compute_verify_oop_data();
    2.17  
    2.18 @@ -425,6 +426,22 @@
    2.19    static void init_self_patching_vtbl_list(void** list, int count);
    2.20  
    2.21    // Debugging
    2.22 +  enum VERIFY_FLAGS {
    2.23 +    Verify_Threads = 1,
    2.24 +    Verify_Heap = 2,
    2.25 +    Verify_SymbolTable = 4,
    2.26 +    Verify_StringTable = 8,
    2.27 +    Verify_CodeCache = 16,
    2.28 +    Verify_SystemDictionary = 32,
    2.29 +    Verify_ClassLoaderDataGraph = 64,
    2.30 +    Verify_MetaspaceAux = 128,
    2.31 +    Verify_JNIHandles = 256,
    2.32 +    Verify_CHeap = 512,
    2.33 +    Verify_CodeCacheOops = 1024,
    2.34 +    Verify_All = -1
    2.35 +  };
    2.36 +  static void initialize_verify_flags();
    2.37 +  static bool should_verify_subset(uint subset);
    2.38    static bool verify_in_progress() { return _verify_in_progress; }
    2.39    static void verify(VerifyOption option, const char* prefix, bool silent = VerifySilently);
    2.40    static void verify(const char* prefix, bool silent = VerifySilently) {
     3.1 --- a/src/share/vm/runtime/globals.hpp	Tue Feb 16 13:56:12 2016 +0000
     3.2 +++ b/src/share/vm/runtime/globals.hpp	Tue Feb 16 21:42:29 2016 +0000
     3.3 @@ -2259,6 +2259,14 @@
     3.4    diagnostic(bool, VerifyDuringGC, false,                                   \
     3.5            "Verify memory system during GC (between phases)")                \
     3.6                                                                              \
     3.7 +  diagnostic(ccstrlist, VerifySubSet, "",                                   \
     3.8 +          "Memory sub-systems to verify when Verify*GC flag(s) "            \
     3.9 +          "are enabled. One or more sub-systems can be specified "          \
    3.10 +          "in a comma separated string. Sub-systems are: "                  \
    3.11 +          "threads, heap, symbol_table, string_table, codecache, "          \
    3.12 +          "dictionary, classloader_data_graph, metaspace, jni_handles, "    \
    3.13 +          "c-heap, codecache_oops")                                         \
    3.14 +                                                                            \
    3.15    diagnostic(bool, GCParallelVerificationEnabled, true,                     \
    3.16            "Enable parallel memory system verification")                     \
    3.17                                                                              \
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/test/gc/TestVerifySubSet.java	Tue Feb 16 21:42:29 2016 +0000
     4.3 @@ -0,0 +1,91 @@
     4.4 +/*
     4.5 + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
     4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.7 + *
     4.8 + * This code is free software; you can redistribute it and/or modify it
     4.9 + * under the terms of the GNU General Public License version 2 only, as
    4.10 + * published by the Free Software Foundation.
    4.11 + *
    4.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    4.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    4.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    4.15 + * version 2 for more details (a copy is included in the LICENSE file that
    4.16 + * accompanied this code).
    4.17 + *
    4.18 + * You should have received a copy of the GNU General Public License version
    4.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    4.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    4.21 + *
    4.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    4.23 + * or visit www.oracle.com if you need additional information or have any
    4.24 + * questions.
    4.25 + */
    4.26 +
    4.27 +/* @test TestVerifySubSet.java
    4.28 + * @key gc
    4.29 + * @bug 8072725
    4.30 + * @summary Test VerifySubSet option
    4.31 + * @library /testlibrary
    4.32 + */
    4.33 +
    4.34 +import com.oracle.java.testlibrary.OutputAnalyzer;
    4.35 +import com.oracle.java.testlibrary.ProcessTools;
    4.36 +import java.util.ArrayList;
    4.37 +import java.util.Collections;
    4.38 +
    4.39 +class RunSystemGC {
    4.40 +    public static void main(String args[]) throws Exception {
    4.41 +        System.gc();
    4.42 +    }
    4.43 +}
    4.44 +
    4.45 +public class TestVerifySubSet {
    4.46 +    private static String[] getTestJavaOpts() {
    4.47 +        String testVmOptsStr = System.getProperty("test.java.opts");
    4.48 +        if (!testVmOptsStr.isEmpty()) {
    4.49 +            return testVmOptsStr.split(" ");
    4.50 +        } else {
    4.51 +            return new String[] {};
    4.52 +        }
    4.53 +    }
    4.54 +
    4.55 +    private static OutputAnalyzer runTest(String subset) throws Exception {
    4.56 +        ArrayList<String> vmOpts = new ArrayList();
    4.57 +
    4.58 +        Collections.addAll(vmOpts, getTestJavaOpts());
    4.59 +        Collections.addAll(vmOpts, new String[] {"-XX:+UnlockDiagnosticVMOptions",
    4.60 +                                                 "-XX:+VerifyBeforeGC",
    4.61 +                                                 "-XX:+VerifyAfterGC",
    4.62 +                                                 "-XX:VerifySubSet="+subset,
    4.63 +                                                 RunSystemGC.class.getName()});
    4.64 +        ProcessBuilder pb =
    4.65 +            ProcessTools.createJavaProcessBuilder(vmOpts.toArray(new String[vmOpts.size()]));
    4.66 +        OutputAnalyzer output = new OutputAnalyzer(pb.start());
    4.67 +
    4.68 +        System.out.println("Output:\n" + output.getOutput());
    4.69 +        return output;
    4.70 +    }
    4.71 +
    4.72 +    public static void main(String args[]) throws Exception {
    4.73 +
    4.74 +        OutputAnalyzer output;
    4.75 +
    4.76 +        output = runTest("heap, threads, codecache, metaspace");
    4.77 +        output.shouldContain("Heap");
    4.78 +        output.shouldContain("Threads");
    4.79 +        output.shouldContain("CodeCache");
    4.80 +        output.shouldContain("MetaspaceAux");
    4.81 +        output.shouldNotContain("SymbolTable");
    4.82 +        output.shouldNotContain("StringTable");
    4.83 +        output.shouldNotContain("SystemDictionary");
    4.84 +        output.shouldNotContain("CodeCache Oops");
    4.85 +        output.shouldHaveExitValue(0);
    4.86 +
    4.87 +        output = runTest("hello, threads, codecache, metaspace");
    4.88 +        output.shouldContain("memory sub-system is unknown, please correct it");
    4.89 +        output.shouldNotContain("Threads");
    4.90 +        output.shouldNotContain("CodeCache");
    4.91 +        output.shouldNotContain("MetaspaceAux");
    4.92 +        output.shouldHaveExitValue(1);
    4.93 +    }
    4.94 +}

mercurial