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