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. 51 template<typename T, typename TagType> 52 class FakeRttiSupport VALUE_OBJ_CLASS_SPEC { 53 public: 54 // Construct with the indicated concrete tag, and include the 55 // concrete tag in the associated tag set. 56 explicit FakeRttiSupport(TagType concrete_tag) : 57 _tag_set(tag_bit(concrete_tag)), _concrete_tag(concrete_tag) { } 58 59 // Construct with the indicated concrete tag and tag set. 60 // Note: This constructor is public only to allow clients to set up 61 // "unusual" (or perhaps buggy) fake RTTI configurations. 62 FakeRttiSupport(TagType concrete_tag, uintx tag_set) : 63 _tag_set(tag_set), _concrete_tag(validate_tag(concrete_tag)) { } 64 65 // Get the concrete tag. 66 TagType concrete_tag() const { return _concrete_tag; } 67 68 // Test whether tag is in the tag set. 69 bool has_tag(TagType tag) const { 70 return (_tag_set & tag_bit(tag)) != 0; 71 } 72 73 // Return a new support object which is the same as this, except tag 74 // has been added to the tag set. The tag must not already be 75 // present in the tag set. 76 FakeRttiSupport add_tag(TagType tag) const { 77 uintx tbit = tag_bit(tag); 78 assert((_tag_set & tbit) == 0, 79 err_msg("Tag " UINTX_FORMAT " is already present in tag set: " UINTX_FORMAT, 80 (uintx)tag, _tag_set)); 81 return FakeRttiSupport(_concrete_tag, _tag_set | tbit); 82 } 83 84 private: 85 uintx _tag_set; 86 TagType _concrete_tag; 87 88 static uintx tag_bit(TagType tag) { 89 return ((uintx)1) << validate_tag(tag); 90 } 91 92 static TagType validate_tag(TagType tag) { 93 assert(0 <= tag, err_msg("Tag " INTX_FORMAT " is negative", (intx)tag)); 94 assert(tag < BitsPerWord, 95 err_msg("Tag " UINTX_FORMAT " is too large", (uintx)tag)); 96 return tag; 97 } 98 }; 99 100 #endif // include guard