1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/runtime/reflectionUtils.hpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,240 @@ 1.4 +/* 1.5 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#ifndef SHARE_VM_RUNTIME_REFLECTIONUTILS_HPP 1.29 +#define SHARE_VM_RUNTIME_REFLECTIONUTILS_HPP 1.30 + 1.31 +#include "memory/allocation.hpp" 1.32 +#include "oops/instanceKlass.hpp" 1.33 +#include "oops/objArrayOop.hpp" 1.34 +#include "oops/oopsHierarchy.hpp" 1.35 +#include "runtime/handles.inline.hpp" 1.36 +#include "runtime/reflection.hpp" 1.37 +#include "utilities/accessFlags.hpp" 1.38 +#include "utilities/globalDefinitions.hpp" 1.39 + 1.40 +// A KlassStream is an abstract stream for streaming over self, superclasses 1.41 +// and (super)interfaces. Streaming is done in reverse order (subclasses first, 1.42 +// interfaces last). 1.43 +// 1.44 +// for (KlassStream st(k, false, false, false); !st.eos(); st.next()) { 1.45 +// Klass* k = st.klass(); 1.46 +// ... 1.47 +// } 1.48 + 1.49 +class KlassStream VALUE_OBJ_CLASS_SPEC { 1.50 + protected: 1.51 + instanceKlassHandle _klass; // current klass/interface iterated over 1.52 + instanceKlassHandle _base_klass; // initial klass/interface to iterate over 1.53 + Array<Klass*>* _interfaces; // transitive interfaces for initial class 1.54 + int _interface_index; // current interface being processed 1.55 + bool _local_only; // process initial class/interface only 1.56 + bool _classes_only; // process classes only (no interfaces) 1.57 + bool _walk_defaults; // process default methods 1.58 + bool _base_class_search_defaults; // time to process default methods 1.59 + bool _defaults_checked; // already checked for default methods 1.60 + int _index; 1.61 + 1.62 + virtual int length() = 0; 1.63 + 1.64 + public: 1.65 + // constructor 1.66 + KlassStream(instanceKlassHandle klass, bool local_only, bool classes_only, bool walk_defaults); 1.67 + 1.68 + // testing 1.69 + bool eos(); 1.70 + 1.71 + // iterating 1.72 + virtual void next() = 0; 1.73 + 1.74 + // accessors 1.75 + instanceKlassHandle klass() const { return _klass; } 1.76 + int index() const { return _index; } 1.77 + bool base_class_search_defaults() const { return _base_class_search_defaults; } 1.78 + void base_class_search_defaults(bool b) { _base_class_search_defaults = b; } 1.79 +}; 1.80 + 1.81 + 1.82 +// A MethodStream streams over all methods in a class, superclasses and (super)interfaces. 1.83 +// Streaming is done in reverse order (subclasses first, methods in reverse order) 1.84 +// Usage: 1.85 +// 1.86 +// for (MethodStream st(k, false, false); !st.eos(); st.next()) { 1.87 +// Method* m = st.method(); 1.88 +// ... 1.89 +// } 1.90 + 1.91 +class MethodStream : public KlassStream { 1.92 + private: 1.93 + int length() { return methods()->length(); } 1.94 + Array<Method*>* methods() { 1.95 + if (base_class_search_defaults()) { 1.96 + base_class_search_defaults(false); 1.97 + return _klass->default_methods(); 1.98 + } else { 1.99 + return _klass->methods(); 1.100 + } 1.101 + } 1.102 + public: 1.103 + MethodStream(instanceKlassHandle klass, bool local_only, bool classes_only) 1.104 + : KlassStream(klass, local_only, classes_only, true) { 1.105 + _index = length(); 1.106 + next(); 1.107 + } 1.108 + 1.109 + void next() { _index--; } 1.110 + Method* method() { return methods()->at(index()); } 1.111 +}; 1.112 + 1.113 + 1.114 +// A FieldStream streams over all fields in a class, superclasses and (super)interfaces. 1.115 +// Streaming is done in reverse order (subclasses first, fields in reverse order) 1.116 +// Usage: 1.117 +// 1.118 +// for (FieldStream st(k, false, false); !st.eos(); st.next()) { 1.119 +// Symbol* field_name = st.name(); 1.120 +// ... 1.121 +// } 1.122 + 1.123 + 1.124 +class FieldStream : public KlassStream { 1.125 + private: 1.126 + int length() { return _klass->java_fields_count(); } 1.127 + 1.128 + fieldDescriptor _fd_buf; 1.129 + 1.130 + public: 1.131 + FieldStream(instanceKlassHandle klass, bool local_only, bool classes_only) 1.132 + : KlassStream(klass, local_only, classes_only, false) { 1.133 + _index = length(); 1.134 + next(); 1.135 + } 1.136 + 1.137 + void next() { _index -= 1; } 1.138 + 1.139 + // Accessors for current field 1.140 + AccessFlags access_flags() const { 1.141 + AccessFlags flags; 1.142 + flags.set_flags(_klass->field_access_flags(_index)); 1.143 + return flags; 1.144 + } 1.145 + Symbol* name() const { 1.146 + return _klass->field_name(_index); 1.147 + } 1.148 + Symbol* signature() const { 1.149 + return _klass->field_signature(_index); 1.150 + } 1.151 + // missing: initval() 1.152 + int offset() const { 1.153 + return _klass->field_offset( index() ); 1.154 + } 1.155 + // bridge to a heavier API: 1.156 + fieldDescriptor& field_descriptor() const { 1.157 + fieldDescriptor& field = const_cast<fieldDescriptor&>(_fd_buf); 1.158 + field.reinitialize(_klass(), _index); 1.159 + return field; 1.160 + } 1.161 +}; 1.162 + 1.163 +class FilteredField : public CHeapObj<mtInternal> { 1.164 + private: 1.165 + Klass* _klass; 1.166 + int _field_offset; 1.167 + 1.168 + public: 1.169 + FilteredField(Klass* klass, int field_offset) { 1.170 + _klass = klass; 1.171 + _field_offset = field_offset; 1.172 + } 1.173 + Klass* klass() { return _klass; } 1.174 + int field_offset() { return _field_offset; } 1.175 +}; 1.176 + 1.177 +class FilteredFieldsMap : AllStatic { 1.178 + private: 1.179 + static GrowableArray<FilteredField *> *_filtered_fields; 1.180 + public: 1.181 + static void initialize(); 1.182 + static bool is_filtered_field(Klass* klass, int field_offset) { 1.183 + for (int i=0; i < _filtered_fields->length(); i++) { 1.184 + if (klass == _filtered_fields->at(i)->klass() && 1.185 + field_offset == _filtered_fields->at(i)->field_offset()) { 1.186 + return true; 1.187 + } 1.188 + } 1.189 + return false; 1.190 + } 1.191 + static int filtered_fields_count(Klass* klass, bool local_only) { 1.192 + int nflds = 0; 1.193 + for (int i=0; i < _filtered_fields->length(); i++) { 1.194 + if (local_only && klass == _filtered_fields->at(i)->klass()) { 1.195 + nflds++; 1.196 + } else if (klass->is_subtype_of(_filtered_fields->at(i)->klass())) { 1.197 + nflds++; 1.198 + } 1.199 + } 1.200 + return nflds; 1.201 + } 1.202 + // Enhance Class Redefinition Support 1.203 + static void classes_do(KlassClosure* f) { 1.204 + for (int i = 0; i < _filtered_fields->length(); i++) { 1.205 + f->do_klass(_filtered_fields->at(i)->klass()); 1.206 + } 1.207 + } 1.208 +}; 1.209 + 1.210 + 1.211 +// A FilteredFieldStream streams over all fields in a class, superclasses and 1.212 +// (super)interfaces. Streaming is done in reverse order (subclasses first, 1.213 +// fields in reverse order) 1.214 +// 1.215 +// Usage: 1.216 +// 1.217 +// for (FilteredFieldStream st(k, false, false); !st.eos(); st.next()) { 1.218 +// Symbol* field_name = st.name(); 1.219 +// ... 1.220 +// } 1.221 + 1.222 +class FilteredFieldStream : public FieldStream { 1.223 + private: 1.224 + int _filtered_fields_count; 1.225 + bool has_filtered_field() { return (_filtered_fields_count > 0); } 1.226 + 1.227 + public: 1.228 + FilteredFieldStream(instanceKlassHandle klass, bool local_only, bool classes_only) 1.229 + : FieldStream(klass, local_only, classes_only) { 1.230 + _filtered_fields_count = FilteredFieldsMap::filtered_fields_count((Klass*)klass(), local_only); 1.231 + } 1.232 + int field_count(); 1.233 + void next() { 1.234 + _index -= 1; 1.235 + if (has_filtered_field()) { 1.236 + while (_index >=0 && FilteredFieldsMap::is_filtered_field((Klass*)_klass(), offset())) { 1.237 + _index -= 1; 1.238 + } 1.239 + } 1.240 + } 1.241 +}; 1.242 + 1.243 +#endif // SHARE_VM_RUNTIME_REFLECTIONUTILS_HPP