1 /* 2 * Copyright (c) 2020, 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 27 #include "gc/shared/objectMarker.hpp" 28 #include "memory/iterator.hpp" 29 #include "oops/markWord.hpp" 30 #include "oops/oop.inline.hpp" 31 #include "runtime/biasedLocking.hpp" 32 33 // This implementation uses the existing mark bits in an object for 34 // marking. Objects that are marked must later have their headers restored. 35 // As most objects are unlocked and don't have their identity hash computed 36 // we don't have to save their headers. Instead we save the headers that 37 // are "interesting". Later when the headers are restored this implementation 38 // restores all headers to their initial value and then restores the few 39 // objects that had interesting headers. 40 // 41 // Future work: This implementation currently uses growable arrays to save 42 // the oop and header of interesting objects. As an optimization we could 43 // use the same technique as the GC and make use of the unused area 44 // between top() and end(). 45 // 46 47 // An ObjectClosure used to restore the mark bits of an object 48 class RestoreMarksClosure : public ObjectClosure { 49 public: 50 void do_object(oop o) { 51 if (o != NULL) { 52 markWord mark = o->mark(); 53 if (mark.is_marked()) { 54 o->init_mark(); 55 } 56 } 57 } 58 }; 59 60 DefaultObjectMarker::DefaultObjectMarker() : 61 _saved_oop_stack(NULL), 62 _saved_mark_stack(NULL) { 63 set_needs_reset(true); 64 } 65 66 // initialize ObjectMarker - prepares for object marking 67 bool DefaultObjectMarker::init() { 68 assert(Thread::current()->is_VM_thread(), "must be VMThread"); 69 70 // prepare heap for iteration 71 Universe::heap()->ensure_parsability(false); // no need to retire TLABs 72 73 // create stacks for interesting headers 74 _saved_mark_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<markWord>(4000, true); 75 _saved_oop_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(4000, true); 76 77 if (UseBiasedLocking) { 78 BiasedLocking::preserve_marks(); 79 } 80 81 return true; 82 } 83 84 // Object marking is done so restore object headers 85 void DefaultObjectMarker::done() { 86 // iterate over all objects and restore the mark bits to 87 // their initial value 88 RestoreMarksClosure blk; 89 if (needs_reset()) { 90 Universe::heap()->object_iterate(&blk); 91 } else { 92 // We don't need to reset mark bits on this call, but reset the 93 // flag to the default for the next call. 94 set_needs_reset(true); 95 } 96 97 // now restore the interesting headers 98 for (int i = 0; i < _saved_oop_stack->length(); i++) { 99 oop o = _saved_oop_stack->at(i); 100 markWord mark = _saved_mark_stack->at(i); 101 o->set_mark(mark); 102 } 103 104 if (UseBiasedLocking) { 105 BiasedLocking::restore_marks(); 106 } 107 108 // free the stacks 109 delete _saved_oop_stack; 110 delete _saved_mark_stack; 111 112 delete this; 113 } 114 115 // mark an object 116 bool DefaultObjectMarker::mark(oop o) { 117 assert(Universe::heap()->is_in(o), "sanity check"); 118 119 // object's mark word 120 markWord mark = o->mark(); 121 if (mark.is_marked()) { 122 return false; 123 } 124 125 if (o->mark_must_be_preserved(mark)) { 126 _saved_mark_stack->push(mark); 127 _saved_oop_stack->push(o); 128 } 129 130 // mark the object 131 o->set_mark(markWord::prototype().set_marked()); 132 return true; 133 } 134 135 // return true if object is marked 136 bool DefaultObjectMarker::marked(oop o) { 137 return o->mark().is_marked(); 138 }