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 #include "precompiled.hpp"
 26 #include "classfile/classLoaderData.hpp"
 27 #include "jfr/leakprofiler/utilities/saveRestore.hpp"
 28 #include "oops/oop.inline.hpp"
 29 
 30 MarkOopContext::MarkOopContext() : _obj(NULL), _mark_oop(NULL) {}
 31 
 32 MarkOopContext::MarkOopContext(const oop obj) : _obj(obj), _mark_oop(obj->mark()) {
 33   assert(_obj->mark() == _mark_oop, "invariant");
 34   // now we will "poison" the mark word of the object
 35   // to the intermediate monitor INFLATING state.
 36   // This is an "impossible" state during a safepoint,
 37   // hence we will use it to quickly identify objects
 38   // during the reachability search from gc roots.
 39   assert(NULL == markOopDesc::INFLATING(), "invariant");
 40   _obj->set_mark(markOopDesc::INFLATING());
 41   assert(NULL == obj->mark(), "invariant");
 42 }
 43 
 44 MarkOopContext::~MarkOopContext() {
 45   if (_obj != NULL) {
 46     _obj->set_mark(_mark_oop);
 47     assert(_obj->mark() == _mark_oop, "invariant");
 48   }
 49 }
 50 
 51 MarkOopContext::MarkOopContext(const MarkOopContext& rhs) : _obj(NULL), _mark_oop(NULL) {
 52   swap(const_cast<MarkOopContext&>(rhs));
 53 }
 54 
 55 void MarkOopContext::operator=(MarkOopContext rhs) {
 56   swap(rhs);
 57 }
 58 
 59 void MarkOopContext::swap(MarkOopContext& rhs) {
 60   oop temp_obj = rhs._obj;
 61   markOop temp_mark_oop = rhs._mark_oop;
 62   rhs._obj = _obj;
 63   rhs._mark_oop = _mark_oop;
 64   _obj = temp_obj;
 65   _mark_oop = temp_mark_oop;
 66 }
 67 
 68 CLDClaimContext::CLDClaimContext() : _cld(NULL) {}
 69 
 70 CLDClaimContext::CLDClaimContext(ClassLoaderData* cld) : _cld(cld) {
 71   assert(_cld->claimed(), "invariant");
 72   _cld->clear_claimed();
 73 }
 74 
 75 CLDClaimContext::~CLDClaimContext() {
 76   if (_cld != NULL) {
 77     _cld->claim();
 78     assert(_cld->claimed(), "invariant");
 79   }
 80 }
 81 
 82 CLDClaimContext::CLDClaimContext(const CLDClaimContext& rhs) : _cld(NULL) {
 83   swap(const_cast<CLDClaimContext&>(rhs));
 84 }
 85 
 86 void CLDClaimContext::operator=(CLDClaimContext rhs) {
 87   swap(rhs);
 88 }
 89 
 90 void CLDClaimContext::swap(CLDClaimContext& rhs) {
 91   ClassLoaderData* temp_cld = rhs._cld;
 92   rhs._cld = _cld;
 93   _cld = temp_cld;
 94 }
 95 
 96 CLDClaimStateClosure::CLDClaimStateClosure() : CLDClosure(), _state() {}
 97 
 98 void CLDClaimStateClosure::do_cld(ClassLoaderData* cld) {
 99   assert(cld != NULL, "invariant");
100   if (cld->claimed()) {
101     _state.save(cld);
102   }
103 }
104 
105 SaveRestoreCLDClaimBits::SaveRestoreCLDClaimBits() : _claim_state_closure() {
106   ClassLoaderDataGraph::cld_do(&_claim_state_closure);
107 }
108 
109 SaveRestoreCLDClaimBits::~SaveRestoreCLDClaimBits() {
110   ClassLoaderDataGraph::clear_claimed_marks();
111 }