src/share/vm/runtime/reflectionUtils.hpp

Wed, 21 Oct 2009 09:15:33 -0700

author
kvn
date
Wed, 21 Oct 2009 09:15:33 -0700
changeset 1475
873ec3787992
parent 435
a61af66fc99e
child 1907
c18cbe5936b8
permissions
-rw-r--r--

6892186: SA does not dump debug info for scalar replaced objects
Summary: Implement scalar replaced objects debug info dump in SA.
Reviewed-by: twisti

     1 /*
     2  * Copyright 1999-2005 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
    21  * have any questions.
    22  *
    23  */
    25 // A KlassStream is an abstract stream for streaming over self, superclasses
    26 // and (super)interfaces. Streaming is done in reverse order (subclasses first,
    27 // interfaces last).
    28 //
    29 //    for (KlassStream st(k, false, false); !st.eos(); st.next()) {
    30 //      klassOop k = st.klass();
    31 //      ...
    32 //    }
    34 class KlassStream VALUE_OBJ_CLASS_SPEC {
    35  protected:
    36   instanceKlassHandle _klass;           // current klass/interface iterated over
    37   objArrayHandle      _interfaces;      // transitive interfaces for initial class
    38   int                 _interface_index; // current interface being processed
    39   bool                _local_only;      // process initial class/interface only
    40   bool                _classes_only;    // process classes only (no interfaces)
    41   int                 _index;
    43   virtual int length() const = 0;
    45  public:
    46   // constructor
    47   KlassStream(instanceKlassHandle klass, bool local_only, bool classes_only);
    49   // testing
    50   bool eos();
    52   // iterating
    53   virtual void next() = 0;
    55   // accessors
    56   instanceKlassHandle klass() const { return _klass; }
    57   int index() const                 { return _index; }
    58 };
    61 // A MethodStream streams over all methods in a class, superclasses and (super)interfaces.
    62 // Streaming is done in reverse order (subclasses first, methods in reverse order)
    63 // Usage:
    64 //
    65 //    for (MethodStream st(k, false, false); !st.eos(); st.next()) {
    66 //      methodOop m = st.method();
    67 //      ...
    68 //    }
    70 class MethodStream : public KlassStream {
    71  private:
    72   int length() const          { return methods()->length(); }
    73   objArrayOop methods() const { return _klass->methods(); }
    74  public:
    75   MethodStream(instanceKlassHandle klass, bool local_only, bool classes_only)
    76     : KlassStream(klass, local_only, classes_only) {
    77     _index = length();
    78     next();
    79   }
    81   void next() { _index--; }
    82   methodOop method() const { return methodOop(methods()->obj_at(index())); }
    83 };
    86 // A FieldStream streams over all fields in a class, superclasses and (super)interfaces.
    87 // Streaming is done in reverse order (subclasses first, fields in reverse order)
    88 // Usage:
    89 //
    90 //    for (FieldStream st(k, false, false); !st.eos(); st.next()) {
    91 //      symbolOop field_name = st.name();
    92 //      ...
    93 //    }
    96 class FieldStream : public KlassStream {
    97  private:
    98   int length() const                { return fields()->length(); }
    99   constantPoolOop constants() const { return _klass->constants(); }
   100  protected:
   101   typeArrayOop fields() const       { return _klass->fields(); }
   102  public:
   103   FieldStream(instanceKlassHandle klass, bool local_only, bool classes_only)
   104     : KlassStream(klass, local_only, classes_only) {
   105     _index = length();
   106     next();
   107   }
   109   void next() { _index -= instanceKlass::next_offset; }
   111   // Accessors for current field
   112   AccessFlags access_flags() const {
   113     AccessFlags flags;
   114     flags.set_flags(fields()->ushort_at(index() + instanceKlass::access_flags_offset));
   115     return flags;
   116   }
   117   symbolOop name() const {
   118     int name_index = fields()->ushort_at(index() + instanceKlass::name_index_offset);
   119     return constants()->symbol_at(name_index);
   120   }
   121   symbolOop signature() const {
   122     int signature_index = fields()->ushort_at(index() +
   123                                        instanceKlass::signature_index_offset);
   124     return constants()->symbol_at(signature_index);
   125   }
   126   // missing: initval()
   127   int offset() const {
   128     return _klass->offset_from_fields( index() );
   129   }
   130 };
   132 class FilteredField {
   133  private:
   134   klassOop _klass;
   135   int      _field_offset;
   137  public:
   138   FilteredField(klassOop klass, int field_offset) {
   139     _klass = klass;
   140     _field_offset = field_offset;
   141   }
   142   klassOop klass() { return _klass; }
   143   oop* klass_addr() { return (oop*) &_klass; }
   144   int  field_offset() { return _field_offset; }
   145 };
   147 class FilteredFieldsMap : AllStatic {
   148  private:
   149   static GrowableArray<FilteredField *> *_filtered_fields;
   150  public:
   151   static void initialize();
   152   static bool is_filtered_field(klassOop klass, int field_offset) {
   153     for (int i=0; i < _filtered_fields->length(); i++) {
   154       if (klass == _filtered_fields->at(i)->klass() &&
   155         field_offset == _filtered_fields->at(i)->field_offset()) {
   156         return true;
   157       }
   158     }
   159     return false;
   160   }
   161   static int  filtered_fields_count(klassOop klass, bool local_only) {
   162     int nflds = 0;
   163     for (int i=0; i < _filtered_fields->length(); i++) {
   164       if (local_only && klass == _filtered_fields->at(i)->klass()) {
   165         nflds++;
   166       } else if (klass->klass_part()->is_subtype_of(_filtered_fields->at(i)->klass())) {
   167         nflds++;
   168       }
   169     }
   170     return nflds;
   171   }
   172   // GC support.
   173   static void klasses_oops_do(OopClosure* f) {
   174     for (int i = 0; i < _filtered_fields->length(); i++) {
   175       f->do_oop((oop*)_filtered_fields->at(i)->klass_addr());
   176     }
   177   }
   178 };
   181 // A FilteredFieldStream streams over all fields in a class, superclasses and
   182 // (super)interfaces. Streaming is done in reverse order (subclasses first,
   183 // fields in reverse order)
   184 //
   185 // Usage:
   186 //
   187 //    for (FilteredFieldStream st(k, false, false); !st.eos(); st.next()) {
   188 //      symbolOop field_name = st.name();
   189 //      ...
   190 //    }
   192 class FilteredFieldStream : public FieldStream {
   193  private:
   194   int  _filtered_fields_count;
   195   bool has_filtered_field() { return (_filtered_fields_count > 0); }
   197  public:
   198   FilteredFieldStream(instanceKlassHandle klass, bool local_only, bool classes_only)
   199     : FieldStream(klass, local_only, classes_only) {
   200     _filtered_fields_count = FilteredFieldsMap::filtered_fields_count((klassOop)klass(), local_only);
   201   }
   202   int field_count();
   203   void next() {
   204     _index -= instanceKlass::next_offset;
   205     if (has_filtered_field()) {
   206       while (_index >=0 && FilteredFieldsMap::is_filtered_field((klassOop)_klass(), offset())) {
   207         _index -= instanceKlass::next_offset;
   208       }
   209     }
   210   }
   211 };

mercurial