1/* 2 * Copyright (c) 2015, 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#ifndef SHARE_VM_UTILITIES_FAKERTTISUPPORT_HPP 26#define SHARE_VM_UTILITIES_FAKERTTISUPPORT_HPP 27 28#include "utilities/globalDefinitions.hpp" 29#include "utilities/debug.hpp" 30 31// Provides support for checked downcasts in a hierarchy of classes. 32// The base class provides a member of this type, specialized on that 33// base class and an associated tag type. Tags are small non-negative 34// integer values uniquely associated with distinct classes in the 35// hierarchy. A tag type is often an enum type. 36// 37// The concrete class specifies the concrete tag. 38// 39// The tag set specifies the set of classes in the derivation 40// sequence. Classes in the derivation sequence add their associated 41// tag during construction. Given the tag associated with a class, an 42// object is an instance of that class if the tag is included in the 43// object's set of recorded tags. 44// 45// A tag T is present in a tag set if the T'th bit of the tag set is 46// one. 47// 48// Note: The representation of a tag set being uintx sets an upper 49// bound on the size of a class hierarchy this utility can be used 50// with. 51template<typename T, typename TagType> 52class FakeRttiSupport VALUE_OBJ_CLASS_SPEC { 53 friend class VMStructs; 54public: 55 // Construct with the indicated concrete tag, and include the 56 // concrete tag in the associated tag set. 57 explicit FakeRttiSupport(TagType concrete_tag) : 58 _tag_set(tag_bit(concrete_tag)), _concrete_tag(concrete_tag) { } 59 60 // Construct with the indicated concrete tag and tag set. 61 // Note: This constructor is public only to allow clients to set up 62 // "unusual" (or perhaps buggy) fake RTTI configurations. 63 FakeRttiSupport(TagType concrete_tag, uintx tag_set) : 64 _tag_set(tag_set), _concrete_tag(validate_tag(concrete_tag)) { } 65 66 // Get the concrete tag. 67 TagType concrete_tag() const { return _concrete_tag; } 68 69 // Test whether tag is in the tag set. 70 bool has_tag(TagType tag) const { 71 return (_tag_set & tag_bit(tag)) != 0; 72 } 73 74 // Return a new support object which is the same as this, except tag 75 // has been added to the tag set. The tag must not already be 76 // present in the tag set. 77 FakeRttiSupport add_tag(TagType tag) const { 78 uintx tbit = tag_bit(tag); 79 assert((_tag_set & tbit) == 0, 80 "Tag " UINTX_FORMAT " is already present in tag set: " UINTX_FORMAT, 81 (uintx)tag, _tag_set); 82 return FakeRttiSupport(_concrete_tag, _tag_set | tbit); 83 } 84 85private: 86 uintx _tag_set; 87 TagType _concrete_tag; 88 89 static uintx tag_bit(TagType tag) { 90 return ((uintx)1) << validate_tag(tag); 91 } 92 93 static TagType validate_tag(TagType tag) { 94 assert(0 <= tag, "Tag " INTX_FORMAT " is negative", (intx)tag); 95 assert(tag < BitsPerWord, 96 "Tag " UINTX_FORMAT " is too large", (uintx)tag); 97 return tag; 98 } 99}; 100 101#endif // include guard 102