diff -r 4ebc2e2fb97c -r 71c04702a3d5 src/hotspot/share/gc/shared/preservedMarks.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/gc/shared/preservedMarks.hpp Tue Sep 12 19:03:39 2017 +0200 @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_GC_SHARED_PRESERVEDMARKS_HPP +#define SHARE_VM_GC_SHARED_PRESERVEDMARKS_HPP + +#include "memory/allocation.hpp" +#include "memory/padded.hpp" +#include "oops/oop.hpp" +#include "utilities/stack.hpp" + +class PreservedMarksSet; +class WorkGang; + +class PreservedMarks VALUE_OBJ_CLASS_SPEC { +private: + class OopAndMarkOop { + private: + oop _o; + markOop _m; + + public: + OopAndMarkOop(oop obj, markOop m) : _o(obj), _m(m) { } + + void set_mark() const { + _o->set_mark(_m); + } + }; + typedef Stack OopAndMarkOopStack; + + OopAndMarkOopStack _stack; + + inline bool should_preserve_mark(oop obj, markOop m) const; + inline void push(oop obj, markOop m); + +public: + size_t size() const { return _stack.size(); } + inline void push_if_necessary(oop obj, markOop m); + // Iterate over the stack, restore all preserved marks, and + // reclaim the memory taken up by the stack segments. + void restore(); + + void restore_and_increment(volatile size_t* const _total_size_addr); + inline static void init_forwarded_mark(oop obj); + + // Assert the stack is empty and has no cached segments. + void assert_empty() PRODUCT_RETURN; + + inline PreservedMarks(); + ~PreservedMarks() { assert_empty(); } +}; + +class RemoveForwardedPointerClosure: public ObjectClosure { +public: + virtual void do_object(oop obj); +}; + +class RestorePreservedMarksTaskExecutor { +public: + void virtual restore(PreservedMarksSet* preserved_marks_set, + volatile size_t* total_size_addr) = 0; +}; + +class SharedRestorePreservedMarksTaskExecutor : public RestorePreservedMarksTaskExecutor { +private: + WorkGang* _workers; + +public: + SharedRestorePreservedMarksTaskExecutor(WorkGang* workers) : _workers(workers) { } + + void restore(PreservedMarksSet* preserved_marks_set, + volatile size_t* total_size_addr); + +}; + +class PreservedMarksSet : public CHeapObj { +private: + // true -> _stacks will be allocated in the C heap + // false -> _stacks will be allocated in the resource arena + const bool _in_c_heap; + + // Number of stacks we have allocated (typically, one stack per GC worker). + // This should be >= 1 if the stacks have been initialized, + // or == 0 if they have not. + uint _num; + + // Stack array (typically, one stack per GC worker) of length _num. + // This should be != NULL if the stacks have been initialized, + // or == NULL if they have not. + Padded* _stacks; + +public: + uint num() const { return _num; } + + // Return the i'th stack. + PreservedMarks* get(uint i = 0) const { + assert(_num > 0 && _stacks != NULL, "stacks should have been initialized"); + assert(i < _num, "pre-condition"); + return (_stacks + i); + } + + // Allocate stack array. + void init(uint num); + + // Iterate over all stacks, restore all preserved marks, and reclaim + // the memory taken up by the stack segments. + // Supported executors: SharedRestorePreservedMarksTaskExecutor (Serial, CMS, G1), + // PSRestorePreservedMarksTaskExecutor (PS). + inline void restore(RestorePreservedMarksTaskExecutor* executor); + + // Reclaim stack array. + void reclaim(); + + // Assert all the stacks are empty and have no cached segments. + void assert_empty() PRODUCT_RETURN; + + PreservedMarksSet(bool in_c_heap) + : _in_c_heap(in_c_heap), _num(0), _stacks(NULL) { } + + ~PreservedMarksSet() { + assert(_stacks == NULL && _num == 0, "stacks should have been reclaimed"); + } +}; + +#endif // SHARE_VM_GC_SHARED_PRESERVEDMARKS_HPP