1 /* 2 * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef SHARE_VM_JFR_LEAKPROFILER_UTILITIES_SAVERESTORE_HPP 26 #define SHARE_VM_JFR_LEAKPROFILER_UTILITIES_SAVERESTORE_HPP 27 28 #include "memory/allocation.hpp" 29 #include "memory/iterator.hpp" 30 #include "oops/markOop.hpp" 31 #include "utilities/growableArray.hpp" 32 33 template <typename T, typename Impl> 34 class SaveRestore { 35 private: 36 Impl _impl; 37 public: 38 SaveRestore() : _impl() { 39 _impl.setup(); 40 } 41 42 void save(T const& value) { 43 _impl.save(value); 44 } 45 46 ~SaveRestore() { 47 _impl.restore(); 48 } 49 }; 50 51 template <typename T, typename Context> 52 class ContextStore { 53 private: 54 GrowableArray<Context>* _storage; 55 public: 56 ContextStore() : _storage(NULL) {} 57 58 void setup() { 59 assert(_storage == NULL, "invariant"); 60 _storage = new GrowableArray<Context>(16); 61 } 62 63 void save(T const& value) { 64 _storage->push(Context(value)); 65 } 66 67 void restore() { 68 for (int i = 0; i < _storage->length(); ++i) { 69 _storage->at(i).~Context(); 70 } 71 } 72 }; 73 74 /* 75 * This class will save the original mark oop of an object sample object. 76 * It will then install an "identifier" mark oop to be used for 77 * identification purposes in the search for reference chains. 78 * The destructor will restore the original mark oop. 79 */ 80 81 class MarkOopContext { 82 private: 83 oop _obj; 84 markOop _mark_oop; 85 void swap(MarkOopContext& rhs); 86 public: 87 MarkOopContext(); 88 MarkOopContext(const oop obj); 89 MarkOopContext(const MarkOopContext& rhs); 90 void operator=(MarkOopContext rhs); 91 ~MarkOopContext(); 92 }; 93 94 typedef SaveRestore<oop, ContextStore<oop, MarkOopContext> > SaveRestoreMarkOops; 95 96 class ClassLoaderData; 97 98 class CLDClaimContext { 99 private: 100 ClassLoaderData* _cld; 101 void swap(CLDClaimContext& rhs); 102 public: 103 CLDClaimContext(); 104 CLDClaimContext(ClassLoaderData* cld); 105 CLDClaimContext(const CLDClaimContext& rhs); 106 void operator=(CLDClaimContext rhs); 107 ~CLDClaimContext(); 108 }; 109 110 typedef SaveRestore<ClassLoaderData*, ContextStore<ClassLoaderData*, CLDClaimContext> > SaveRestoreCLDClaimState; 111 112 class CLDClaimStateClosure : public CLDClosure { 113 private: 114 SaveRestoreCLDClaimState _state; 115 public: 116 CLDClaimStateClosure(); 117 void do_cld(ClassLoaderData* cld); 118 }; 119 120 class SaveRestoreCLDClaimBits : public StackObj { 121 private: 122 CLDClaimStateClosure _claim_state_closure; 123 public: 124 SaveRestoreCLDClaimBits(); 125 ~SaveRestoreCLDClaimBits(); 126 }; 127 128 #endif // SHARE_VM_JFR_LEAKPROFILER_UTILITIES_SAVERESTORE_HPP