Mercurial > hg > truffle
comparison src/share/vm/classfile/genericSignatures.hpp @ 6934:4735d2c84362
7200776: Implement default methods in interfaces
Summary: Add generic type analysis and default method selection algorithms
Reviewed-by: coleenp, acorn
author | kamg |
---|---|
date | Thu, 11 Oct 2012 12:25:42 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
6921:a1b8cf9cf970 | 6934:4735d2c84362 |
---|---|
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 |