hotspot/src/share/vm/classfile/genericSignatures.hpp
changeset 20993 0c5d53cb5264
parent 20992 54817aa17609
parent 19749 892889f44575
child 20994 1169cfaf9f7d
equal deleted inserted replaced
20992:54817aa17609 20993:0c5d53cb5264
     1 /*
       
     2  * Copyright (c) 2012, 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_CLASSFILE_GENERICSIGNATURES_HPP
       
    26 #define SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP
       
    27 
       
    28 #include "classfile/symbolTable.hpp"
       
    29 #include "memory/allocation.hpp"
       
    30 #include "runtime/signature.hpp"
       
    31 #include "utilities/growableArray.hpp"
       
    32 #include "utilities/resourceHash.hpp"
       
    33 
       
    34 class stringStream;
       
    35 
       
    36 namespace generic {
       
    37 
       
    38 class Identifier;
       
    39 class ClassDescriptor;
       
    40 class MethodDescriptor;
       
    41 
       
    42 class TypeParameter; // a formal type parameter declared in generic signatures
       
    43 class TypeArgument;  // The "type value" passed to fill parameters in supertypes
       
    44 class TypeVariable;  // A usage of a type parameter as a value
       
    45 /**
       
    46  * Example:
       
    47  *
       
    48  * <T, V> class Foo extends Bar<String> { int m(V v) {} }
       
    49  * ^^^^^^                       ^^^^^^          ^^
       
    50  * type parameters            type argument    type variable
       
    51  *
       
    52  * Note that a type variable could be passed as an argument too:
       
    53  * <T, V> class Foo extends Bar<T> { int m(V v) {} }
       
    54  *                             ^^^
       
    55  *                             type argument's value is a type variable
       
    56  */
       
    57 
       
    58 
       
    59 class Type;
       
    60 class ClassType;
       
    61 class ArrayType;
       
    62 class PrimitiveType;
       
    63 class Context;
       
    64 class DescriptorCache;
       
    65 
       
    66 class DescriptorStream;
       
    67 
       
    68 class Identifier : public ResourceObj {
       
    69  private:
       
    70   Symbol* _sym;
       
    71   int _begin;
       
    72   int _end;
       
    73 
       
    74  public:
       
    75   Identifier(Symbol* sym, int begin, int end) :
       
    76     _sym(sym), _begin(begin), _end(end) {}
       
    77 
       
    78   bool equals(Identifier* other);
       
    79   bool equals(Symbol* sym);
       
    80 
       
    81 #ifndef PRODUCT
       
    82   void print_on(outputStream* str) const;
       
    83 #endif // ndef PRODUCT
       
    84 };
       
    85 
       
    86 class Descriptor : public ResourceObj {
       
    87  protected:
       
    88   GrowableArray<TypeParameter*> _type_parameters;
       
    89   ClassDescriptor* _outer_class;
       
    90 
       
    91   Descriptor(GrowableArray<TypeParameter*>& params,
       
    92     ClassDescriptor* outer)
       
    93     : _type_parameters(params), _outer_class(outer) {}
       
    94 
       
    95  public:
       
    96 
       
    97   ClassDescriptor* outer_class() { return _outer_class; }
       
    98   void set_outer_class(ClassDescriptor* sig) { _outer_class = sig; }
       
    99 
       
   100   virtual ClassDescriptor* as_class_signature() { return NULL; }
       
   101   virtual MethodDescriptor* as_method_signature() { return NULL; }
       
   102 
       
   103   bool is_class_signature() { return as_class_signature() != NULL; }
       
   104   bool is_method_signature() { return as_method_signature() != NULL; }
       
   105 
       
   106   GrowableArray<TypeParameter*>& type_parameters() {
       
   107     return _type_parameters;
       
   108   }
       
   109 
       
   110   TypeParameter* find_type_parameter(Identifier* id, int* param_depth);
       
   111 
       
   112   virtual void bind_variables_to_parameters() = 0;
       
   113 
       
   114 #ifndef PRODUCT
       
   115   virtual void print_on(outputStream* str) const = 0;
       
   116 #endif
       
   117 };
       
   118 
       
   119 class ClassDescriptor : public Descriptor {
       
   120  private:
       
   121   ClassType* _super;
       
   122   GrowableArray<ClassType*> _interfaces;
       
   123   MethodDescriptor* _outer_method;
       
   124 
       
   125   ClassDescriptor(GrowableArray<TypeParameter*>& ftp, ClassType* scs,
       
   126       GrowableArray<ClassType*>& sis, ClassDescriptor* outer_class = NULL,
       
   127       MethodDescriptor* outer_method = NULL)
       
   128         : Descriptor(ftp, outer_class), _super(scs), _interfaces(sis),
       
   129           _outer_method(outer_method) {}
       
   130 
       
   131   static u2 get_outer_class_index(InstanceKlass* k, TRAPS);
       
   132   static ClassDescriptor* parse_generic_signature(Klass* k, Symbol* original_name, TRAPS);
       
   133 
       
   134  public:
       
   135 
       
   136   virtual ClassDescriptor* as_class_signature() { return this; }
       
   137 
       
   138   MethodDescriptor* outer_method() { return _outer_method; }
       
   139   void set_outer_method(MethodDescriptor* m) { _outer_method = m; }
       
   140 
       
   141   ClassType* super() { return _super; }
       
   142   ClassType* interface_desc(Symbol* sym);
       
   143 
       
   144   static ClassDescriptor* parse_generic_signature(Klass* k, TRAPS);
       
   145   static ClassDescriptor* parse_generic_signature(Symbol* sym);
       
   146 
       
   147   // For use in superclass chains in positions where this is no generic info
       
   148   static ClassDescriptor* placeholder(InstanceKlass* klass);
       
   149 
       
   150 #ifndef PRODUCT
       
   151   void print_on(outputStream* str) const;
       
   152 #endif
       
   153 
       
   154   ClassDescriptor* canonicalize(Context* ctx);
       
   155 
       
   156   // Linking sets the position index in any contained TypeVariable type
       
   157   // to correspond to the location of that identifier in the formal type
       
   158   // parameters.
       
   159   void bind_variables_to_parameters();
       
   160 };
       
   161 
       
   162 class MethodDescriptor : public Descriptor {
       
   163  private:
       
   164   GrowableArray<Type*> _parameters;
       
   165   Type* _return_type;
       
   166   GrowableArray<Type*> _throws;
       
   167 
       
   168   MethodDescriptor(GrowableArray<TypeParameter*>& ftp, ClassDescriptor* outer,
       
   169       GrowableArray<Type*>& sigs, Type* rt, GrowableArray<Type*>& throws)
       
   170       : Descriptor(ftp, outer), _parameters(sigs), _return_type(rt),
       
   171         _throws(throws) {}
       
   172 
       
   173  public:
       
   174 
       
   175   static MethodDescriptor* parse_generic_signature(Method* m, ClassDescriptor* outer);
       
   176   static MethodDescriptor* parse_generic_signature(Symbol* sym, ClassDescriptor* outer);
       
   177 
       
   178   MethodDescriptor* as_method_signature() { return this; }
       
   179 
       
   180   // Performs generic analysis on the method parameters to determine
       
   181   // if both methods refer to the same argument types.
       
   182   bool covariant_match(MethodDescriptor* other, Context* ctx);
       
   183 
       
   184   // Returns a new method descriptor with all generic variables
       
   185   // removed and replaced with whatever is indicated using the Context.
       
   186   MethodDescriptor* canonicalize(Context* ctx);
       
   187 
       
   188   void bind_variables_to_parameters();
       
   189 
       
   190 #ifndef PRODUCT
       
   191   TempNewSymbol reify_signature(Context* ctx, TRAPS);
       
   192   void print_on(outputStream* str) const;
       
   193 #endif
       
   194 };
       
   195 
       
   196 class TypeParameter : public ResourceObj {
       
   197  private:
       
   198   Identifier* _identifier;
       
   199   ClassType* _class_bound;
       
   200   GrowableArray<ClassType*> _interface_bounds;
       
   201 
       
   202   // The position is the ordinal location of the parameter within the
       
   203   // formal parameter list (excluding outer classes).  It is only set for
       
   204   // formal type parameters that are associated with a class -- method
       
   205   // type parameters are left as -1.  When resolving a generic variable to
       
   206   // find the actual type, this index is used to access the generic type
       
   207   // argument in the provided context object.
       
   208   int _position; // Assigned during variable linking
       
   209 
       
   210   TypeParameter(Identifier* id, ClassType* class_bound,
       
   211     GrowableArray<ClassType*>& interface_bounds) :
       
   212       _identifier(id), _class_bound(class_bound),
       
   213       _interface_bounds(interface_bounds), _position(-1) {}
       
   214 
       
   215  public:
       
   216   static TypeParameter* parse_generic_signature(DescriptorStream* str);
       
   217 
       
   218   ClassType* bound();
       
   219   int position() { return _position; }
       
   220 
       
   221   void bind_variables_to_parameters(Descriptor* sig, int position);
       
   222   Identifier* identifier() { return _identifier; }
       
   223 
       
   224   Type* resolve(Context* ctx, int inner_depth, int ctx_depth);
       
   225   TypeParameter* canonicalize(Context* ctx, int ctx_depth);
       
   226 
       
   227 #ifndef PRODUCT
       
   228   void print_on(outputStream* str) const;
       
   229 #endif
       
   230 };
       
   231 
       
   232 class Type : public ResourceObj {
       
   233  public:
       
   234   static Type* parse_generic_signature(DescriptorStream* str);
       
   235 
       
   236   virtual ClassType* as_class() { return NULL; }
       
   237   virtual TypeVariable* as_variable() { return NULL; }
       
   238   virtual ArrayType* as_array() { return NULL; }
       
   239   virtual PrimitiveType* as_primitive() { return NULL; }
       
   240 
       
   241   virtual bool covariant_match(Type* gt, Context* ctx) = 0;
       
   242   virtual Type* canonicalize(Context* ctx, int ctx_depth) = 0;
       
   243 
       
   244   virtual void bind_variables_to_parameters(Descriptor* sig) = 0;
       
   245 
       
   246 #ifndef PRODUCT
       
   247   virtual void reify_signature(stringStream* ss, Context* ctx) = 0;
       
   248   virtual void print_on(outputStream* str) const = 0;
       
   249 #endif
       
   250 };
       
   251 
       
   252 class ClassType : public Type {
       
   253   friend class ClassDescriptor;
       
   254  protected:
       
   255   Identifier* _identifier;
       
   256   GrowableArray<TypeArgument*> _type_arguments;
       
   257   ClassType* _outer_class;
       
   258 
       
   259   ClassType(Identifier* identifier,
       
   260       GrowableArray<TypeArgument*>& args,
       
   261       ClassType* outer)
       
   262       : _identifier(identifier), _type_arguments(args), _outer_class(outer) {}
       
   263 
       
   264   // Returns true if there are inner classes to read
       
   265   static Identifier* parse_generic_signature_simple(
       
   266       GrowableArray<TypeArgument*>* args,
       
   267       bool* has_inner, DescriptorStream* str);
       
   268 
       
   269   static ClassType* parse_generic_signature(ClassType* outer,
       
   270       DescriptorStream* str);
       
   271   static ClassType* from_symbol(Symbol* sym);
       
   272 
       
   273  public:
       
   274   ClassType* as_class() { return this; }
       
   275 
       
   276   static ClassType* parse_generic_signature(DescriptorStream* str);
       
   277   static ClassType* java_lang_Object();
       
   278 
       
   279   Identifier* identifier() { return _identifier; }
       
   280   int type_arguments_length() { return _type_arguments.length(); }
       
   281   TypeArgument* type_argument_at(int i);
       
   282 
       
   283   virtual ClassType* outer_class() { return _outer_class; }
       
   284 
       
   285   bool covariant_match(Type* gt, Context* ctx);
       
   286   ClassType* canonicalize(Context* ctx, int context_depth);
       
   287 
       
   288   void bind_variables_to_parameters(Descriptor* sig);
       
   289 
       
   290 #ifndef PRODUCT
       
   291   void reify_signature(stringStream* ss, Context* ctx);
       
   292   void print_on(outputStream* str) const;
       
   293 #endif
       
   294 };
       
   295 
       
   296 class TypeVariable : public Type {
       
   297  private:
       
   298   Identifier* _id;
       
   299   TypeParameter* _parameter; // assigned during linking
       
   300 
       
   301   // how many steps "out" from inner classes, -1 if method
       
   302   int _inner_depth;
       
   303 
       
   304   TypeVariable(Identifier* id)
       
   305       : _id(id), _parameter(NULL), _inner_depth(0) {}
       
   306 
       
   307  public:
       
   308   TypeVariable* as_variable() { return this; }
       
   309 
       
   310   static TypeVariable* parse_generic_signature(DescriptorStream* str);
       
   311 
       
   312   Identifier* identifier() { return _id; }
       
   313   TypeParameter* parameter() { return _parameter; }
       
   314   int inner_depth() { return _inner_depth; }
       
   315 
       
   316   void bind_variables_to_parameters(Descriptor* sig);
       
   317 
       
   318   Type* resolve(Context* ctx, int ctx_depth);
       
   319   bool covariant_match(Type* gt, Context* ctx);
       
   320   Type* canonicalize(Context* ctx, int ctx_depth);
       
   321 
       
   322 #ifndef PRODUCT
       
   323   void reify_signature(stringStream* ss, Context* ctx);
       
   324   void print_on(outputStream* str) const;
       
   325 #endif
       
   326 };
       
   327 
       
   328 class ArrayType : public Type {
       
   329  private:
       
   330   Type* _base;
       
   331 
       
   332   ArrayType(Type* base) : _base(base) {}
       
   333 
       
   334  public:
       
   335   ArrayType* as_array() { return this; }
       
   336 
       
   337   static ArrayType* parse_generic_signature(DescriptorStream* str);
       
   338 
       
   339   bool covariant_match(Type* gt, Context* ctx);
       
   340   ArrayType* canonicalize(Context* ctx, int ctx_depth);
       
   341 
       
   342   void bind_variables_to_parameters(Descriptor* sig);
       
   343 
       
   344 #ifndef PRODUCT
       
   345   void reify_signature(stringStream* ss, Context* ctx);
       
   346   void print_on(outputStream* str) const;
       
   347 #endif
       
   348 };
       
   349 
       
   350 class PrimitiveType : public Type {
       
   351   friend class Type;
       
   352  private:
       
   353   char _type; // includes V for void
       
   354 
       
   355   PrimitiveType(char& type) : _type(type) {}
       
   356 
       
   357  public:
       
   358   PrimitiveType* as_primitive() { return this; }
       
   359 
       
   360   bool covariant_match(Type* gt, Context* ctx);
       
   361   PrimitiveType* canonicalize(Context* ctx, int ctx_depth);
       
   362 
       
   363   void bind_variables_to_parameters(Descriptor* sig);
       
   364 
       
   365 #ifndef PRODUCT
       
   366   void reify_signature(stringStream* ss, Context* ctx);
       
   367   void print_on(outputStream* str) const;
       
   368 #endif
       
   369 };
       
   370 
       
   371 class TypeArgument : public ResourceObj {
       
   372  private:
       
   373   Type* _lower_bound;
       
   374   Type* _upper_bound; // may be null or == _lower_bound
       
   375 
       
   376   TypeArgument(Type* lower_bound, Type* upper_bound)
       
   377       : _lower_bound(lower_bound), _upper_bound(upper_bound) {}
       
   378 
       
   379  public:
       
   380 
       
   381   static TypeArgument* parse_generic_signature(DescriptorStream* str);
       
   382 
       
   383   Type* lower_bound() { return _lower_bound; }
       
   384   Type* upper_bound() { return _upper_bound; }
       
   385 
       
   386   void bind_variables_to_parameters(Descriptor* sig);
       
   387   TypeArgument* canonicalize(Context* ctx, int ctx_depth);
       
   388 
       
   389   bool covariant_match(TypeArgument* a, Context* ctx);
       
   390 
       
   391 #ifndef PRODUCT
       
   392   void print_on(outputStream* str) const;
       
   393 #endif
       
   394 };
       
   395 
       
   396 
       
   397 class Context : public ResourceObj {
       
   398  private:
       
   399   DescriptorCache* _cache;
       
   400   GrowableArray<ClassType*> _type_arguments;
       
   401 
       
   402   void reset_to_mark(int size);
       
   403 
       
   404  public:
       
   405   // When this object goes out of scope or 'destroy' is
       
   406   // called, then the application of the type to the
       
   407   // context is wound-back (unless it's been deactivated).
       
   408   class Mark : public StackObj {
       
   409    private:
       
   410     mutable Context* _context;
       
   411     int _marked_size;
       
   412 
       
   413     bool is_active() const { return _context != NULL; }
       
   414     void deactivate() const { _context = NULL; }
       
   415 
       
   416    public:
       
   417     Mark() : _context(NULL), _marked_size(0) {}
       
   418     Mark(Context* ctx, int sz) : _context(ctx), _marked_size(sz) {}
       
   419     Mark(const Mark& m) : _context(m._context), _marked_size(m._marked_size) {
       
   420       m.deactivate(); // Ownership is transferred
       
   421     }
       
   422 
       
   423     Mark& operator=(const Mark& cm) {
       
   424       destroy();
       
   425       _context = cm._context;
       
   426       _marked_size = cm._marked_size;
       
   427       cm.deactivate();
       
   428       return *this;
       
   429     }
       
   430 
       
   431     void destroy();
       
   432     ~Mark() { destroy(); }
       
   433   };
       
   434 
       
   435   Context(DescriptorCache* cache) : _cache(cache) {}
       
   436 
       
   437   Mark mark() { return Mark(this, _type_arguments.length()); }
       
   438   void apply_type_arguments(InstanceKlass* current, InstanceKlass* super,TRAPS);
       
   439 
       
   440   ClassType* at_depth(int i) const;
       
   441 
       
   442 #ifndef PRODUCT
       
   443   void print_on(outputStream* str) const;
       
   444 #endif
       
   445 };
       
   446 
       
   447 /**
       
   448  * Contains a cache of descriptors for classes and methods so they can be
       
   449  * looked-up instead of reparsing each time they are needed.
       
   450  */
       
   451 class DescriptorCache : public ResourceObj {
       
   452  private:
       
   453   ResourceHashtable<InstanceKlass*, ClassDescriptor*> _class_descriptors;
       
   454   ResourceHashtable<Method*, MethodDescriptor*> _method_descriptors;
       
   455 
       
   456  public:
       
   457   ClassDescriptor* descriptor_for(InstanceKlass* ikh, TRAPS);
       
   458 
       
   459   MethodDescriptor* descriptor_for(Method* mh, ClassDescriptor* cd, TRAPS);
       
   460   // Class descriptor derived from method holder
       
   461   MethodDescriptor* descriptor_for(Method* mh, TRAPS);
       
   462 };
       
   463 
       
   464 } // namespace generic
       
   465 
       
   466 #endif // SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP
       
   467