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