brutisso@7195: /* brutisso@7195: * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. brutisso@7195: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. brutisso@7195: * brutisso@7195: * This code is free software; you can redistribute it and/or modify it brutisso@7195: * under the terms of the GNU General Public License version 2 only, as brutisso@7195: * published by the Free Software Foundation. brutisso@7195: * brutisso@7195: * This code is distributed in the hope that it will be useful, but WITHOUT brutisso@7195: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or brutisso@7195: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License brutisso@7195: * version 2 for more details (a copy is included in the LICENSE file that brutisso@7195: * accompanied this code). brutisso@7195: * brutisso@7195: * You should have received a copy of the GNU General Public License version brutisso@7195: * 2 along with this work; if not, write to the Free Software Foundation, brutisso@7195: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. brutisso@7195: * brutisso@7195: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA brutisso@7195: * or visit www.oracle.com if you need additional information or have any brutisso@7195: * questions. brutisso@7195: * brutisso@7195: */ brutisso@7195: brutisso@7195: #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONTYPE_HPP brutisso@7195: #define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONTYPE_HPP brutisso@7195: brutisso@7195: #include "memory/allocation.hpp" brutisso@7195: brutisso@7195: #define hrt_assert_is_valid(tag) \ brutisso@7195: assert(is_valid((tag)), err_msg("invalid HR type: %u", (uint) (tag))) brutisso@7195: brutisso@7195: class HeapRegionType VALUE_OBJ_CLASS_SPEC { brutisso@7195: private: brutisso@7195: // We encode the value of the heap region type so the generation can be brutisso@7195: // determined quickly. The tag is split into two parts: brutisso@7195: // brutisso@7195: // major type (young, humongous) : top N-1 bits brutisso@7195: // minor type (eden / survivor, starts / cont hum, etc.) : bottom 1 bit brutisso@7195: // brutisso@7195: // If there's need to increase the number of minor types in the brutisso@7195: // future, we'll have to increase the size of the latter and hence brutisso@7195: // decrease the size of the former. brutisso@7195: // brutisso@7195: // 0000 0 [ 0] Free brutisso@7195: // brutisso@7195: // 0001 0 Young Mask brutisso@7195: // 0001 0 [ 2] Eden brutisso@7195: // 0001 1 [ 3] Survivor brutisso@7195: // brutisso@7195: // 0010 0 Humongous Mask brutisso@7195: // 0010 0 [ 4] Humongous Starts brutisso@7195: // 0010 1 [ 5] Humongous Continues brutisso@7195: // brutisso@7195: // 01000 [ 8] Old brutisso@7195: typedef enum { brutisso@7195: FreeTag = 0, brutisso@7195: brutisso@7195: YoungMask = 2, brutisso@7195: EdenTag = YoungMask, brutisso@7195: SurvTag = YoungMask + 1, brutisso@7195: brutisso@7195: HumMask = 4, brutisso@7195: HumStartsTag = HumMask, brutisso@7195: HumContTag = HumMask + 1, brutisso@7195: brutisso@7195: OldTag = 8 brutisso@7195: } Tag; brutisso@7195: brutisso@7195: volatile Tag _tag; brutisso@7195: brutisso@7195: static bool is_valid(Tag tag); brutisso@7195: brutisso@7195: Tag get() const { brutisso@7195: hrt_assert_is_valid(_tag); brutisso@7195: return _tag; brutisso@7195: } brutisso@7195: brutisso@7195: // Sets the type to 'tag'. brutisso@7195: void set(Tag tag) { brutisso@7195: hrt_assert_is_valid(tag); brutisso@7195: hrt_assert_is_valid(_tag); brutisso@7195: _tag = tag; brutisso@7195: } brutisso@7195: brutisso@7195: // Sets the type to 'tag', expecting the type to be 'before'. This brutisso@7195: // is available for when we want to add sanity checking to the type brutisso@7195: // transition. brutisso@7195: void set_from(Tag tag, Tag before) { brutisso@7195: hrt_assert_is_valid(tag); brutisso@7195: hrt_assert_is_valid(before); brutisso@7195: hrt_assert_is_valid(_tag); brutisso@7195: assert(_tag == before, brutisso@7195: err_msg("HR tag: %u, expected: %u new tag; %u", _tag, before, tag)); brutisso@7195: _tag = tag; brutisso@7195: } brutisso@7195: brutisso@7195: public: brutisso@7195: // Queries brutisso@7195: brutisso@7195: bool is_free() const { return get() == FreeTag; } brutisso@7195: brutisso@7195: bool is_young() const { return (get() & YoungMask) != 0; } brutisso@7195: bool is_eden() const { return get() == EdenTag; } brutisso@7195: bool is_survivor() const { return get() == SurvTag; } brutisso@7195: brutisso@7195: bool is_humongous() const { return (get() & HumMask) != 0; } brutisso@7195: bool is_starts_humongous() const { return get() == HumStartsTag; } brutisso@7195: bool is_continues_humongous() const { return get() == HumContTag; } brutisso@7195: brutisso@7195: bool is_old() const { return get() == OldTag; } brutisso@7195: brutisso@7195: // Setters brutisso@7195: brutisso@7195: void set_free() { set(FreeTag); } brutisso@7195: brutisso@7195: void set_eden() { set_from(EdenTag, FreeTag); } brutisso@7195: void set_eden_pre_gc() { set_from(EdenTag, SurvTag); } brutisso@7195: void set_survivor() { set_from(SurvTag, FreeTag); } brutisso@7195: brutisso@7195: void set_starts_humongous() { set_from(HumStartsTag, FreeTag); } brutisso@7195: void set_continues_humongous() { set_from(HumContTag, FreeTag); } brutisso@7195: brutisso@7195: void set_old() { set(OldTag); } brutisso@7195: brutisso@7195: // Misc brutisso@7195: brutisso@7195: const char* get_str() const; brutisso@7195: const char* get_short_str() const; brutisso@7195: brutisso@7195: HeapRegionType() : _tag(FreeTag) { hrt_assert_is_valid(_tag); } brutisso@7195: }; brutisso@7195: brutisso@7195: #endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONTYPE_HPP