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