src/share/vm/runtime/reflectionUtils.hpp

Fri, 27 Sep 2013 08:39:19 +0200

author
rbackman
date
Fri, 27 Sep 2013 08:39:19 +0200
changeset 5791
c9ccd7b85f20
parent 5732
b2e698d2276c
child 5848
ac9cb1d5a202
permissions
-rw-r--r--

8024924: Intrinsify java.lang.Math.addExact
Reviewed-by: kvn, twisti

     1 /*
     2  * Copyright (c) 1999, 2013, 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  */
    25 #ifndef SHARE_VM_RUNTIME_REFLECTIONUTILS_HPP
    26 #define SHARE_VM_RUNTIME_REFLECTIONUTILS_HPP
    28 #include "memory/allocation.hpp"
    29 #include "oops/instanceKlass.hpp"
    30 #include "oops/objArrayOop.hpp"
    31 #include "oops/oopsHierarchy.hpp"
    32 #include "runtime/handles.inline.hpp"
    33 #include "runtime/reflection.hpp"
    34 #include "utilities/accessFlags.hpp"
    35 #include "utilities/globalDefinitions.hpp"
    37 // A KlassStream is an abstract stream for streaming over self, superclasses
    38 // and (super)interfaces. Streaming is done in reverse order (subclasses first,
    39 // interfaces last).
    40 //
    41 //    for (KlassStream st(k, false, false); !st.eos(); st.next()) {
    42 //      Klass* k = st.klass();
    43 //      ...
    44 //    }
    46 class KlassStream VALUE_OBJ_CLASS_SPEC {
    47  protected:
    48   instanceKlassHandle _klass;           // current klass/interface iterated over
    49   Array<Klass*>*    _interfaces;      // transitive interfaces for initial class
    50   int                 _interface_index; // current interface being processed
    51   bool                _local_only;      // process initial class/interface only
    52   bool                _classes_only;    // process classes only (no interfaces)
    53   int                 _index;
    55   virtual int length() const = 0;
    57  public:
    58   // constructor
    59   KlassStream(instanceKlassHandle klass, bool local_only, bool classes_only);
    61   // testing
    62   bool eos();
    64   // iterating
    65   virtual void next() = 0;
    67   // accessors
    68   instanceKlassHandle klass() const { return _klass; }
    69   int index() const                 { return _index; }
    70 };
    73 // A MethodStream streams over all methods in a class, superclasses and (super)interfaces.
    74 // Streaming is done in reverse order (subclasses first, methods in reverse order)
    75 // Usage:
    76 //
    77 //    for (MethodStream st(k, false, false); !st.eos(); st.next()) {
    78 //      Method* m = st.method();
    79 //      ...
    80 //    }
    82 class MethodStream : public KlassStream {
    83  private:
    84   int length() const          { return methods()->length(); }
    85   Array<Method*>* methods() const { return _klass->methods(); }
    86  public:
    87   MethodStream(instanceKlassHandle klass, bool local_only, bool classes_only)
    88     : KlassStream(klass, local_only, classes_only) {
    89     _index = length();
    90     next();
    91   }
    93   void next() { _index--; }
    94   Method* method() const { return methods()->at(index()); }
    95 };
    98 // A FieldStream streams over all fields in a class, superclasses and (super)interfaces.
    99 // Streaming is done in reverse order (subclasses first, fields in reverse order)
   100 // Usage:
   101 //
   102 //    for (FieldStream st(k, false, false); !st.eos(); st.next()) {
   103 //      Symbol* field_name = st.name();
   104 //      ...
   105 //    }
   108 class FieldStream : public KlassStream {
   109  private:
   110   int length() const                { return _klass->java_fields_count(); }
   112   fieldDescriptor _fd_buf;
   114  public:
   115   FieldStream(instanceKlassHandle klass, bool local_only, bool classes_only)
   116     : KlassStream(klass, local_only, classes_only) {
   117     _index = length();
   118     next();
   119   }
   121   void next() { _index -= 1; }
   123   // Accessors for current field
   124   AccessFlags access_flags() const {
   125     AccessFlags flags;
   126     flags.set_flags(_klass->field_access_flags(_index));
   127     return flags;
   128   }
   129   Symbol* name() const {
   130     return _klass->field_name(_index);
   131   }
   132   Symbol* signature() const {
   133     return _klass->field_signature(_index);
   134   }
   135   // missing: initval()
   136   int offset() const {
   137     return _klass->field_offset( index() );
   138   }
   139   // bridge to a heavier API:
   140   fieldDescriptor& field_descriptor() const {
   141     fieldDescriptor& field = const_cast<fieldDescriptor&>(_fd_buf);
   142     field.reinitialize(_klass(), _index);
   143     return field;
   144   }
   145 };
   147 class FilteredField : public CHeapObj<mtInternal>  {
   148  private:
   149   Klass* _klass;
   150   int    _field_offset;
   152  public:
   153   FilteredField(Klass* klass, int field_offset) {
   154     _klass = klass;
   155     _field_offset = field_offset;
   156   }
   157   Klass* klass() { return _klass; }
   158   int  field_offset() { return _field_offset; }
   159 };
   161 class FilteredFieldsMap : AllStatic {
   162  private:
   163   static GrowableArray<FilteredField *> *_filtered_fields;
   164  public:
   165   static void initialize();
   166   static bool is_filtered_field(Klass* klass, int field_offset) {
   167     for (int i=0; i < _filtered_fields->length(); i++) {
   168       if (klass == _filtered_fields->at(i)->klass() &&
   169         field_offset == _filtered_fields->at(i)->field_offset()) {
   170         return true;
   171       }
   172     }
   173     return false;
   174   }
   175   static int  filtered_fields_count(Klass* klass, bool local_only) {
   176     int nflds = 0;
   177     for (int i=0; i < _filtered_fields->length(); i++) {
   178       if (local_only && klass == _filtered_fields->at(i)->klass()) {
   179         nflds++;
   180       } else if (klass->is_subtype_of(_filtered_fields->at(i)->klass())) {
   181         nflds++;
   182       }
   183     }
   184     return nflds;
   185   }
   186   // Enhance Class Redefinition Support
   187   static void classes_do(KlassClosure* f) {
   188     for (int i = 0; i < _filtered_fields->length(); i++) {
   189       f->do_klass(_filtered_fields->at(i)->klass());
   190     }
   191   }
   192 };
   195 // A FilteredFieldStream streams over all fields in a class, superclasses and
   196 // (super)interfaces. Streaming is done in reverse order (subclasses first,
   197 // fields in reverse order)
   198 //
   199 // Usage:
   200 //
   201 //    for (FilteredFieldStream st(k, false, false); !st.eos(); st.next()) {
   202 //      Symbol* field_name = st.name();
   203 //      ...
   204 //    }
   206 class FilteredFieldStream : public FieldStream {
   207  private:
   208   int  _filtered_fields_count;
   209   bool has_filtered_field() { return (_filtered_fields_count > 0); }
   211  public:
   212   FilteredFieldStream(instanceKlassHandle klass, bool local_only, bool classes_only)
   213     : FieldStream(klass, local_only, classes_only) {
   214     _filtered_fields_count = FilteredFieldsMap::filtered_fields_count((Klass*)klass(), local_only);
   215   }
   216   int field_count();
   217   void next() {
   218     _index -= 1;
   219     if (has_filtered_field()) {
   220       while (_index >=0 && FilteredFieldsMap::is_filtered_field((Klass*)_klass(), offset())) {
   221         _index -= 1;
   222       }
   223     }
   224   }
   225 };
   227 #endif // SHARE_VM_RUNTIME_REFLECTIONUTILS_HPP

mercurial