1 /* 2 * Copyright (c) 2015, 2019, 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_UTILITIES_FAKERTTISUPPORT_HPP 26 #define SHARE_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. 51 template<typename T, typename TagType> 52 class FakeRttiSupport { 53 friend class VMStructs; 54 public: 55 // Construct with the indicated concrete tag, and include the 56 // concrete tag in the associated tag set. FakeRttiSupport(TagType concrete_tag)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. FakeRttiSupport(TagType concrete_tag,uintx tag_set)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. concrete_tag() const67 TagType concrete_tag() const { return _concrete_tag; } 68 69 // Test whether tag is in the tag set. has_tag(TagType tag) const70 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. add_tag(TagType tag) const77 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 85 private: 86 uintx _tag_set; 87 TagType _concrete_tag; 88 tag_bit(TagType tag)89 static uintx tag_bit(TagType tag) { 90 return ((uintx)1) << validate_tag(tag); 91 } 92 validate_tag(TagType tag)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 // SHARE_UTILITIES_FAKERTTISUPPORT_HPP 102