Tue, 14 May 2013 11:34:30 +0400
8014448: Purge PrintCompactFieldsSavings
Summary: Remove obsolete debugging code.
Reviewed-by: dholmes, kvn
Contributed-by: Aleksey Shipilev <aleksey.shipilev@oracle.com>
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 | #include "precompiled.hpp" |
kamg@4245 | 26 | |
kamg@4245 | 27 | #include "classfile/genericSignatures.hpp" |
kamg@4245 | 28 | #include "classfile/symbolTable.hpp" |
kamg@4245 | 29 | #include "classfile/systemDictionary.hpp" |
kamg@4245 | 30 | #include "memory/resourceArea.hpp" |
kamg@4245 | 31 | |
kamg@4245 | 32 | namespace generic { |
kamg@4245 | 33 | |
kamg@4245 | 34 | // Helper class for parsing the generic signature Symbol in klass and methods |
kamg@4245 | 35 | class DescriptorStream : public ResourceObj { |
kamg@4245 | 36 | private: |
kamg@4245 | 37 | Symbol* _symbol; |
kamg@4245 | 38 | int _offset; |
kamg@4245 | 39 | int _mark; |
kamg@4245 | 40 | const char* _parse_error; |
kamg@4245 | 41 | |
kamg@4245 | 42 | void set_parse_error(const char* error) { |
kamg@4245 | 43 | assert(error != NULL, "Can't set NULL error string"); |
kamg@4245 | 44 | _parse_error = error; |
kamg@4245 | 45 | } |
kamg@4245 | 46 | |
kamg@4245 | 47 | public: |
kamg@4245 | 48 | DescriptorStream(Symbol* sym) |
kamg@4245 | 49 | : _symbol(sym), _offset(0), _mark(-1), _parse_error(NULL) {} |
kamg@4245 | 50 | |
kamg@4245 | 51 | const char* parse_error() const { |
kamg@4245 | 52 | return _parse_error; |
kamg@4245 | 53 | } |
kamg@4245 | 54 | |
kamg@4245 | 55 | bool at_end() { return _offset >= _symbol->utf8_length(); } |
kamg@4245 | 56 | |
kamg@4245 | 57 | char peek() { |
kamg@4245 | 58 | if (at_end()) { |
kamg@4245 | 59 | set_parse_error("Peeking past end of signature"); |
kamg@4245 | 60 | return '\0'; |
kamg@4245 | 61 | } else { |
kamg@4245 | 62 | return _symbol->byte_at(_offset); |
kamg@4245 | 63 | } |
kamg@4245 | 64 | } |
kamg@4245 | 65 | |
kamg@4245 | 66 | char read() { |
kamg@4245 | 67 | if (at_end()) { |
kamg@4245 | 68 | set_parse_error("Reading past end of signature"); |
kamg@4245 | 69 | return '\0'; |
kamg@4245 | 70 | } else { |
kamg@4245 | 71 | return _symbol->byte_at(_offset++); |
kamg@4245 | 72 | } |
kamg@4245 | 73 | } |
kamg@4245 | 74 | |
kamg@4245 | 75 | void read(char expected) { |
kamg@4245 | 76 | char c = read(); |
kamg@4245 | 77 | assert_char(c, expected, 0); |
kamg@4245 | 78 | } |
kamg@4245 | 79 | |
kamg@4245 | 80 | void assert_char(char c, char expected, int pos = -1) { |
kamg@4245 | 81 | if (c != expected) { |
kamg@4245 | 82 | const char* fmt = "Parse error at %d: expected %c but got %c"; |
kamg@4245 | 83 | size_t len = strlen(fmt) + 5; |
kamg@4245 | 84 | char* buffer = NEW_RESOURCE_ARRAY(char, len); |
kamg@4245 | 85 | jio_snprintf(buffer, len, fmt, _offset + pos, expected, c); |
kamg@4245 | 86 | set_parse_error(buffer); |
kamg@4245 | 87 | } |
kamg@4245 | 88 | } |
kamg@4245 | 89 | |
kamg@4245 | 90 | void push(char c) { |
kamg@4245 | 91 | assert(c == _symbol->byte_at(_offset - 1), "Pushing back wrong value"); |
kamg@4245 | 92 | --_offset; |
kamg@4245 | 93 | } |
kamg@4245 | 94 | |
kamg@4245 | 95 | void expect_end() { |
kamg@4245 | 96 | if (!at_end()) { |
kamg@4245 | 97 | set_parse_error("Unexpected data trailing signature"); |
kamg@4245 | 98 | } |
kamg@4245 | 99 | } |
kamg@4245 | 100 | |
kamg@4245 | 101 | bool has_mark() { return _mark != -1; } |
kamg@4245 | 102 | |
kamg@4245 | 103 | void set_mark() { |
kamg@4245 | 104 | _mark = _offset; |
kamg@4245 | 105 | } |
kamg@4245 | 106 | |
kamg@4245 | 107 | Identifier* identifier_from_mark() { |
kamg@4245 | 108 | assert(has_mark(), "Mark should be set"); |
kamg@4245 | 109 | if (!has_mark()) { |
kamg@4245 | 110 | set_parse_error("Expected mark to be set"); |
kamg@4245 | 111 | return NULL; |
kamg@4245 | 112 | } else { |
kamg@4245 | 113 | Identifier* id = new Identifier(_symbol, _mark, _offset - 1); |
kamg@4245 | 114 | _mark = -1; |
kamg@4245 | 115 | return id; |
kamg@4245 | 116 | } |
kamg@4245 | 117 | } |
kamg@4245 | 118 | }; |
kamg@4245 | 119 | |
kamg@4245 | 120 | |
kamg@4245 | 121 | #define CHECK_FOR_PARSE_ERROR() \ |
kamg@4245 | 122 | if (STREAM->parse_error() != NULL) { \ |
kamg@4245 | 123 | if (VerifyGenericSignatures) { \ |
kamg@4245 | 124 | fatal(STREAM->parse_error()); \ |
kamg@4245 | 125 | } \ |
kamg@4245 | 126 | return NULL; \ |
kamg@4245 | 127 | } 0 |
kamg@4245 | 128 | |
kamg@4245 | 129 | #define READ() STREAM->read(); CHECK_FOR_PARSE_ERROR() |
kamg@4245 | 130 | #define PEEK() STREAM->peek(); CHECK_FOR_PARSE_ERROR() |
kamg@4245 | 131 | #define PUSH(c) STREAM->push(c) |
kamg@4245 | 132 | #define EXPECT(c) STREAM->read(c); CHECK_FOR_PARSE_ERROR() |
kamg@4245 | 133 | #define EXPECTED(c, ch) STREAM->assert_char(c, ch); CHECK_FOR_PARSE_ERROR() |
kamg@4245 | 134 | #define EXPECT_END() STREAM->expect_end(); CHECK_FOR_PARSE_ERROR() |
kamg@4245 | 135 | |
kamg@4245 | 136 | #define CHECK_STREAM STREAM); CHECK_FOR_PARSE_ERROR(); (0 |
kamg@4245 | 137 | |
kamg@4245 | 138 | #ifndef PRODUCT |
kamg@4245 | 139 | void Identifier::print_on(outputStream* str) const { |
kamg@4245 | 140 | for (int i = _begin; i < _end; ++i) { |
kamg@4245 | 141 | str->print("%c", (char)_sym->byte_at(i)); |
kamg@4245 | 142 | } |
kamg@4245 | 143 | } |
kamg@4245 | 144 | #endif // ndef PRODUCT |
kamg@4245 | 145 | |
kamg@4245 | 146 | bool Identifier::equals(Identifier* other) { |
kamg@4245 | 147 | if (_sym == other->_sym && _begin == other->_begin && _end == other->_end) { |
kamg@4245 | 148 | return true; |
kamg@4245 | 149 | } else if (_end - _begin != other->_end - other->_begin) { |
kamg@4245 | 150 | return false; |
kamg@4245 | 151 | } else { |
kamg@4245 | 152 | size_t len = _end - _begin; |
kamg@4245 | 153 | char* addr = ((char*)_sym->bytes()) + _begin; |
kamg@4245 | 154 | char* oaddr = ((char*)other->_sym->bytes()) + other->_begin; |
kamg@4245 | 155 | return strncmp(addr, oaddr, len) == 0; |
kamg@4245 | 156 | } |
kamg@4245 | 157 | } |
kamg@4245 | 158 | |
kamg@4245 | 159 | bool Identifier::equals(Symbol* sym) { |
kamg@4245 | 160 | Identifier id(sym, 0, sym->utf8_length()); |
kamg@4245 | 161 | return equals(&id); |
kamg@4245 | 162 | } |
kamg@4245 | 163 | |
kamg@4245 | 164 | /** |
kamg@4245 | 165 | * A formal type parameter may be found in the the enclosing class, but it could |
kamg@4245 | 166 | * also come from an enclosing method or outer class, in the case of inner-outer |
kamg@4245 | 167 | * classes or anonymous classes. For example: |
kamg@4245 | 168 | * |
kamg@4245 | 169 | * class Outer<T,V> { |
kamg@4245 | 170 | * class Inner<W> { |
kamg@4245 | 171 | * void m(T t, V v, W w); |
kamg@4245 | 172 | * } |
kamg@4245 | 173 | * } |
kamg@4245 | 174 | * |
kamg@4245 | 175 | * In this case, the type variables in m()'s signature are not all found in the |
kamg@4245 | 176 | * immediate enclosing class (Inner). class Inner has only type parameter W, |
kamg@4245 | 177 | * but it's outer_class field will reference Outer's descriptor which contains |
kamg@4245 | 178 | * T & V (no outer_method in this case). |
kamg@4245 | 179 | * |
kamg@4245 | 180 | * If you have an anonymous class, it has both an enclosing method *and* an |
kamg@4245 | 181 | * enclosing class where type parameters can be declared: |
kamg@4245 | 182 | * |
kamg@4245 | 183 | * class MOuter<T> { |
kamg@4245 | 184 | * <V> void bar(V v) { |
kamg@4245 | 185 | * Runnable r = new Runnable() { |
kamg@4245 | 186 | * public void run() {} |
kamg@4245 | 187 | * public void foo(T t, V v) { ... } |
kamg@4245 | 188 | * }; |
kamg@4245 | 189 | * } |
kamg@4245 | 190 | * } |
kamg@4245 | 191 | * |
kamg@4245 | 192 | * In this case, foo will be a member of some class, Runnable$1, which has no |
kamg@4245 | 193 | * formal parameters itself, but has an outer_method (bar()) which provides |
kamg@4245 | 194 | * type parameter V, and an outer class MOuter with type parameter T. |
kamg@4245 | 195 | * |
kamg@4245 | 196 | * It is also possible that the outer class is itself an inner class to some |
kamg@4245 | 197 | * other class (or an anonymous class with an enclosing method), so we need to |
kamg@4245 | 198 | * follow the outer_class/outer_method chain to it's end when looking for a |
kamg@4245 | 199 | * type parameter. |
kamg@4245 | 200 | */ |
kamg@4245 | 201 | TypeParameter* Descriptor::find_type_parameter(Identifier* id, int* depth) { |
kamg@4245 | 202 | |
kamg@4245 | 203 | int current_depth = 0; |
kamg@4245 | 204 | |
kamg@4245 | 205 | MethodDescriptor* outer_method = as_method_signature(); |
kamg@4245 | 206 | ClassDescriptor* outer_class = as_class_signature(); |
kamg@4245 | 207 | |
kamg@4245 | 208 | if (outer_class == NULL) { // 'this' is a method signature; use the holder |
kamg@4245 | 209 | outer_class = outer_method->outer_class(); |
kamg@4245 | 210 | } |
kamg@4245 | 211 | |
kamg@4245 | 212 | while (outer_method != NULL || outer_class != NULL) { |
kamg@4245 | 213 | if (outer_method != NULL) { |
kamg@4245 | 214 | for (int i = 0; i < outer_method->type_parameters().length(); ++i) { |
kamg@4245 | 215 | TypeParameter* p = outer_method->type_parameters().at(i); |
kamg@4245 | 216 | if (p->identifier()->equals(id)) { |
kamg@4245 | 217 | *depth = -1; // indicates this this is a method parameter |
kamg@4245 | 218 | return p; |
kamg@4245 | 219 | } |
kamg@4245 | 220 | } |
kamg@4245 | 221 | } |
kamg@4245 | 222 | if (outer_class != NULL) { |
kamg@4245 | 223 | for (int i = 0; i < outer_class->type_parameters().length(); ++i) { |
kamg@4245 | 224 | TypeParameter* p = outer_class->type_parameters().at(i); |
kamg@4245 | 225 | if (p->identifier()->equals(id)) { |
kamg@4245 | 226 | *depth = current_depth; |
kamg@4245 | 227 | return p; |
kamg@4245 | 228 | } |
kamg@4245 | 229 | } |
kamg@4245 | 230 | outer_method = outer_class->outer_method(); |
kamg@4245 | 231 | outer_class = outer_class->outer_class(); |
kamg@4245 | 232 | ++current_depth; |
kamg@4245 | 233 | } |
kamg@4245 | 234 | } |
kamg@4245 | 235 | |
kamg@4245 | 236 | if (VerifyGenericSignatures) { |
kamg@4245 | 237 | fatal("Could not resolve identifier"); |
kamg@4245 | 238 | } |
kamg@4245 | 239 | |
kamg@4245 | 240 | return NULL; |
kamg@4245 | 241 | } |
kamg@4245 | 242 | |
kamg@4245 | 243 | ClassDescriptor* ClassDescriptor::parse_generic_signature(Klass* klass, TRAPS) { |
kamg@4245 | 244 | return parse_generic_signature(klass, NULL, CHECK_NULL); |
kamg@4245 | 245 | } |
kamg@4245 | 246 | |
kamg@4245 | 247 | ClassDescriptor* ClassDescriptor::parse_generic_signature( |
kamg@4245 | 248 | Klass* klass, Symbol* original_name, TRAPS) { |
kamg@4245 | 249 | |
kamg@4245 | 250 | InstanceKlass* ik = InstanceKlass::cast(klass); |
kamg@4245 | 251 | Symbol* sym = ik->generic_signature(); |
kamg@4245 | 252 | |
kamg@4245 | 253 | ClassDescriptor* spec; |
kamg@4245 | 254 | |
kamg@4245 | 255 | if (sym == NULL || (spec = ClassDescriptor::parse_generic_signature(sym)) == NULL) { |
kamg@4245 | 256 | spec = ClassDescriptor::placeholder(ik); |
kamg@4245 | 257 | } |
kamg@4245 | 258 | |
kamg@4245 | 259 | u2 outer_index = get_outer_class_index(ik, CHECK_NULL); |
kamg@4245 | 260 | if (outer_index != 0) { |
kamg@4245 | 261 | if (original_name == NULL) { |
kamg@4245 | 262 | original_name = ik->name(); |
kamg@4245 | 263 | } |
kamg@4245 | 264 | Handle class_loader = Handle(THREAD, ik->class_loader()); |
kamg@4245 | 265 | Handle protection_domain = Handle(THREAD, ik->protection_domain()); |
kamg@4245 | 266 | |
kamg@4245 | 267 | Symbol* outer_name = ik->constants()->klass_name_at(outer_index); |
kamg@4245 | 268 | Klass* outer = SystemDictionary::find( |
kamg@4245 | 269 | outer_name, class_loader, protection_domain, CHECK_NULL); |
kamg@4245 | 270 | if (outer == NULL && !THREAD->is_Compiler_thread()) { |
bharadwaj@4960 | 271 | if (outer_name == ik->super()->name()) { |
bharadwaj@4960 | 272 | outer = SystemDictionary::resolve_super_or_fail(original_name, outer_name, |
bharadwaj@4960 | 273 | class_loader, protection_domain, |
bharadwaj@4960 | 274 | false, CHECK_NULL); |
bharadwaj@4960 | 275 | } |
bharadwaj@4960 | 276 | else { |
bharadwaj@4960 | 277 | outer = SystemDictionary::resolve_or_fail(outer_name, class_loader, |
bharadwaj@4960 | 278 | protection_domain, false, CHECK_NULL); |
bharadwaj@4960 | 279 | } |
kamg@4245 | 280 | } |
kamg@4245 | 281 | |
kamg@4245 | 282 | InstanceKlass* outer_ik; |
kamg@4245 | 283 | ClassDescriptor* outer_spec = NULL; |
kamg@4245 | 284 | if (outer == NULL) { |
kamg@4245 | 285 | outer_spec = ClassDescriptor::placeholder(ik); |
kamg@4245 | 286 | assert(false, "Outer class not loaded and not loadable from here"); |
kamg@4245 | 287 | } else { |
kamg@4245 | 288 | outer_ik = InstanceKlass::cast(outer); |
kamg@4245 | 289 | outer_spec = parse_generic_signature(outer, original_name, CHECK_NULL); |
kamg@4245 | 290 | } |
kamg@4245 | 291 | spec->set_outer_class(outer_spec); |
kamg@4245 | 292 | |
kamg@4245 | 293 | u2 encl_method_idx = ik->enclosing_method_method_index(); |
kamg@4245 | 294 | if (encl_method_idx != 0 && outer_ik != NULL) { |
kamg@4245 | 295 | ConstantPool* cp = ik->constants(); |
kamg@4245 | 296 | u2 name_index = cp->name_ref_index_at(encl_method_idx); |
kamg@4245 | 297 | u2 sig_index = cp->signature_ref_index_at(encl_method_idx); |
kamg@4245 | 298 | Symbol* name = cp->symbol_at(name_index); |
kamg@4245 | 299 | Symbol* sig = cp->symbol_at(sig_index); |
kamg@4245 | 300 | Method* m = outer_ik->find_method(name, sig); |
kamg@4245 | 301 | if (m != NULL) { |
kamg@4245 | 302 | Symbol* gsig = m->generic_signature(); |
kamg@4245 | 303 | if (gsig != NULL) { |
kamg@4245 | 304 | MethodDescriptor* gms = MethodDescriptor::parse_generic_signature(gsig, outer_spec); |
kamg@4245 | 305 | spec->set_outer_method(gms); |
kamg@4245 | 306 | } |
kamg@4245 | 307 | } else if (VerifyGenericSignatures) { |
kamg@4245 | 308 | ResourceMark rm; |
kamg@4245 | 309 | stringStream ss; |
kamg@4245 | 310 | ss.print("Could not find method %s %s in class %s", |
kamg@4245 | 311 | name->as_C_string(), sig->as_C_string(), outer_name->as_C_string()); |
kamg@4245 | 312 | fatal(ss.as_string()); |
kamg@4245 | 313 | } |
kamg@4245 | 314 | } |
kamg@4245 | 315 | } |
kamg@4245 | 316 | |
kamg@4245 | 317 | spec->bind_variables_to_parameters(); |
kamg@4245 | 318 | return spec; |
kamg@4245 | 319 | } |
kamg@4245 | 320 | |
kamg@4245 | 321 | ClassDescriptor* ClassDescriptor::placeholder(InstanceKlass* klass) { |
kamg@4245 | 322 | GrowableArray<TypeParameter*> formals; |
kamg@4245 | 323 | GrowableArray<ClassType*> interfaces; |
kamg@4245 | 324 | ClassType* super_type = NULL; |
kamg@4245 | 325 | |
kamg@4245 | 326 | Klass* super_klass = klass->super(); |
kamg@4245 | 327 | if (super_klass != NULL) { |
kamg@4245 | 328 | InstanceKlass* super = InstanceKlass::cast(super_klass); |
kamg@4245 | 329 | super_type = ClassType::from_symbol(super->name()); |
kamg@4245 | 330 | } |
kamg@4245 | 331 | |
kamg@4245 | 332 | for (int i = 0; i < klass->local_interfaces()->length(); ++i) { |
kamg@4245 | 333 | InstanceKlass* iface = InstanceKlass::cast(klass->local_interfaces()->at(i)); |
kamg@4245 | 334 | interfaces.append(ClassType::from_symbol(iface->name())); |
kamg@4245 | 335 | } |
kamg@4245 | 336 | return new ClassDescriptor(formals, super_type, interfaces); |
kamg@4245 | 337 | } |
kamg@4245 | 338 | |
kamg@4245 | 339 | ClassDescriptor* ClassDescriptor::parse_generic_signature(Symbol* sym) { |
kamg@4245 | 340 | |
kamg@4245 | 341 | DescriptorStream ds(sym); |
kamg@4245 | 342 | DescriptorStream* STREAM = &ds; |
kamg@4245 | 343 | |
kamg@4245 | 344 | GrowableArray<TypeParameter*> parameters(8); |
kamg@4245 | 345 | char c = READ(); |
kamg@4245 | 346 | if (c == '<') { |
kamg@4245 | 347 | c = READ(); |
kamg@4245 | 348 | while (c != '>') { |
kamg@4245 | 349 | PUSH(c); |
kamg@4245 | 350 | TypeParameter* ftp = TypeParameter::parse_generic_signature(CHECK_STREAM); |
kamg@4245 | 351 | parameters.append(ftp); |
kamg@4245 | 352 | c = READ(); |
kamg@4245 | 353 | } |
kamg@4245 | 354 | } else { |
kamg@4245 | 355 | PUSH(c); |
kamg@4245 | 356 | } |
kamg@4245 | 357 | |
kamg@4245 | 358 | EXPECT('L'); |
kamg@4245 | 359 | ClassType* super = ClassType::parse_generic_signature(CHECK_STREAM); |
kamg@4245 | 360 | |
kamg@4245 | 361 | GrowableArray<ClassType*> signatures(2); |
kamg@4245 | 362 | while (!STREAM->at_end()) { |
kamg@4245 | 363 | EXPECT('L'); |
kamg@4245 | 364 | ClassType* iface = ClassType::parse_generic_signature(CHECK_STREAM); |
kamg@4245 | 365 | signatures.append(iface); |
kamg@4245 | 366 | } |
kamg@4245 | 367 | |
kamg@4245 | 368 | EXPECT_END(); |
kamg@4245 | 369 | |
kamg@4245 | 370 | return new ClassDescriptor(parameters, super, signatures); |
kamg@4245 | 371 | } |
kamg@4245 | 372 | |
kamg@4245 | 373 | #ifndef PRODUCT |
kamg@4245 | 374 | void ClassDescriptor::print_on(outputStream* str) const { |
kamg@4245 | 375 | str->indent().print_cr("ClassDescriptor {"); |
kamg@4245 | 376 | { |
kamg@4245 | 377 | streamIndentor si(str); |
kamg@4245 | 378 | if (_type_parameters.length() > 0) { |
kamg@4245 | 379 | str->indent().print_cr("Formals {"); |
kamg@4245 | 380 | { |
kamg@4245 | 381 | streamIndentor si(str); |
kamg@4245 | 382 | for (int i = 0; i < _type_parameters.length(); ++i) { |
kamg@4245 | 383 | _type_parameters.at(i)->print_on(str); |
kamg@4245 | 384 | } |
kamg@4245 | 385 | } |
kamg@4245 | 386 | str->indent().print_cr("}"); |
kamg@4245 | 387 | } |
kamg@4245 | 388 | if (_super != NULL) { |
kamg@4245 | 389 | str->indent().print_cr("Superclass: "); |
kamg@4245 | 390 | { |
kamg@4245 | 391 | streamIndentor si(str); |
kamg@4245 | 392 | _super->print_on(str); |
kamg@4245 | 393 | } |
kamg@4245 | 394 | } |
kamg@4245 | 395 | if (_interfaces.length() > 0) { |
kamg@4245 | 396 | str->indent().print_cr("SuperInterfaces: {"); |
kamg@4245 | 397 | { |
kamg@4245 | 398 | streamIndentor si(str); |
kamg@4245 | 399 | for (int i = 0; i < _interfaces.length(); ++i) { |
kamg@4245 | 400 | _interfaces.at(i)->print_on(str); |
kamg@4245 | 401 | } |
kamg@4245 | 402 | } |
kamg@4245 | 403 | str->indent().print_cr("}"); |
kamg@4245 | 404 | } |
kamg@4245 | 405 | if (_outer_method != NULL) { |
kamg@4245 | 406 | str->indent().print_cr("Outer Method: {"); |
kamg@4245 | 407 | { |
kamg@4245 | 408 | streamIndentor si(str); |
kamg@4245 | 409 | _outer_method->print_on(str); |
kamg@4245 | 410 | } |
kamg@4245 | 411 | str->indent().print_cr("}"); |
kamg@4245 | 412 | } |
kamg@4245 | 413 | if (_outer_class != NULL) { |
kamg@4245 | 414 | str->indent().print_cr("Outer Class: {"); |
kamg@4245 | 415 | { |
kamg@4245 | 416 | streamIndentor si(str); |
kamg@4245 | 417 | _outer_class->print_on(str); |
kamg@4245 | 418 | } |
kamg@4245 | 419 | str->indent().print_cr("}"); |
kamg@4245 | 420 | } |
kamg@4245 | 421 | } |
kamg@4245 | 422 | str->indent().print_cr("}"); |
kamg@4245 | 423 | } |
kamg@4245 | 424 | #endif // ndef PRODUCT |
kamg@4245 | 425 | |
kamg@4245 | 426 | ClassType* ClassDescriptor::interface_desc(Symbol* sym) { |
kamg@4245 | 427 | for (int i = 0; i < _interfaces.length(); ++i) { |
kamg@4245 | 428 | if (_interfaces.at(i)->identifier()->equals(sym)) { |
kamg@4245 | 429 | return _interfaces.at(i); |
kamg@4245 | 430 | } |
kamg@4245 | 431 | } |
kamg@4245 | 432 | if (VerifyGenericSignatures) { |
kamg@4245 | 433 | fatal("Did not find expected interface"); |
kamg@4245 | 434 | } |
kamg@4245 | 435 | return NULL; |
kamg@4245 | 436 | } |
kamg@4245 | 437 | |
kamg@4245 | 438 | void ClassDescriptor::bind_variables_to_parameters() { |
kamg@4245 | 439 | if (_outer_class != NULL) { |
kamg@4245 | 440 | _outer_class->bind_variables_to_parameters(); |
kamg@4245 | 441 | } |
kamg@4245 | 442 | if (_outer_method != NULL) { |
kamg@4245 | 443 | _outer_method->bind_variables_to_parameters(); |
kamg@4245 | 444 | } |
kamg@4245 | 445 | for (int i = 0; i < _type_parameters.length(); ++i) { |
kamg@4245 | 446 | _type_parameters.at(i)->bind_variables_to_parameters(this, i); |
kamg@4245 | 447 | } |
kamg@4245 | 448 | if (_super != NULL) { |
kamg@4245 | 449 | _super->bind_variables_to_parameters(this); |
kamg@4245 | 450 | } |
kamg@4245 | 451 | for (int i = 0; i < _interfaces.length(); ++i) { |
kamg@4245 | 452 | _interfaces.at(i)->bind_variables_to_parameters(this); |
kamg@4245 | 453 | } |
kamg@4245 | 454 | } |
kamg@4245 | 455 | |
kamg@4245 | 456 | ClassDescriptor* ClassDescriptor::canonicalize(Context* ctx) { |
kamg@4245 | 457 | |
kamg@4245 | 458 | GrowableArray<TypeParameter*> type_params(_type_parameters.length()); |
kamg@4245 | 459 | for (int i = 0; i < _type_parameters.length(); ++i) { |
kamg@4245 | 460 | type_params.append(_type_parameters.at(i)->canonicalize(ctx, 0)); |
kamg@4245 | 461 | } |
kamg@4245 | 462 | |
kamg@4245 | 463 | ClassDescriptor* outer = _outer_class == NULL ? NULL : |
kamg@4245 | 464 | _outer_class->canonicalize(ctx); |
kamg@4245 | 465 | |
kamg@4245 | 466 | ClassType* super = _super == NULL ? NULL : _super->canonicalize(ctx, 0); |
kamg@4245 | 467 | |
kamg@4245 | 468 | GrowableArray<ClassType*> interfaces(_interfaces.length()); |
kamg@4245 | 469 | for (int i = 0; i < _interfaces.length(); ++i) { |
kamg@4245 | 470 | interfaces.append(_interfaces.at(i)->canonicalize(ctx, 0)); |
kamg@4245 | 471 | } |
kamg@4245 | 472 | |
kamg@4245 | 473 | MethodDescriptor* md = _outer_method == NULL ? NULL : |
kamg@4245 | 474 | _outer_method->canonicalize(ctx); |
kamg@4245 | 475 | |
kamg@4245 | 476 | return new ClassDescriptor(type_params, super, interfaces, outer, md); |
kamg@4245 | 477 | } |
kamg@4245 | 478 | |
kamg@4245 | 479 | u2 ClassDescriptor::get_outer_class_index(InstanceKlass* klass, TRAPS) { |
kamg@4245 | 480 | int inner_index = InstanceKlass::inner_class_inner_class_info_offset; |
kamg@4245 | 481 | int outer_index = InstanceKlass::inner_class_outer_class_info_offset; |
kamg@4245 | 482 | int name_offset = InstanceKlass::inner_class_inner_name_offset; |
kamg@4245 | 483 | int next_offset = InstanceKlass::inner_class_next_offset; |
kamg@4245 | 484 | |
kamg@4245 | 485 | if (klass->inner_classes() == NULL || klass->inner_classes()->length() == 0) { |
kamg@4245 | 486 | // No inner class info => no declaring class |
kamg@4245 | 487 | return 0; |
kamg@4245 | 488 | } |
kamg@4245 | 489 | |
kamg@4245 | 490 | Array<u2>* i_icls = klass->inner_classes(); |
kamg@4245 | 491 | ConstantPool* i_cp = klass->constants(); |
kamg@4245 | 492 | int i_length = i_icls->length(); |
kamg@4245 | 493 | |
kamg@4245 | 494 | // Find inner_klass attribute |
kamg@4245 | 495 | for (int i = 0; i + next_offset < i_length; i += next_offset) { |
kamg@4245 | 496 | u2 ioff = i_icls->at(i + inner_index); |
kamg@4245 | 497 | u2 ooff = i_icls->at(i + outer_index); |
kamg@4245 | 498 | u2 noff = i_icls->at(i + name_offset); |
kamg@4245 | 499 | if (ioff != 0) { |
kamg@4245 | 500 | // Check to see if the name matches the class we're looking for |
kamg@4245 | 501 | // before attempting to find the class. |
kamg@4245 | 502 | if (i_cp->klass_name_at_matches(klass, ioff) && ooff != 0) { |
kamg@4245 | 503 | return ooff; |
kamg@4245 | 504 | } |
kamg@4245 | 505 | } |
kamg@4245 | 506 | } |
kamg@4245 | 507 | |
kamg@4245 | 508 | // It may be anonymous; try for that. |
kamg@4245 | 509 | u2 encl_method_class_idx = klass->enclosing_method_class_index(); |
kamg@4245 | 510 | if (encl_method_class_idx != 0) { |
kamg@4245 | 511 | return encl_method_class_idx; |
kamg@4245 | 512 | } |
kamg@4245 | 513 | |
kamg@4245 | 514 | return 0; |
kamg@4245 | 515 | } |
kamg@4245 | 516 | |
kamg@4245 | 517 | MethodDescriptor* MethodDescriptor::parse_generic_signature(Method* m, ClassDescriptor* outer) { |
kamg@4245 | 518 | Symbol* generic_sig = m->generic_signature(); |
kamg@4245 | 519 | MethodDescriptor* md = NULL; |
kamg@4245 | 520 | if (generic_sig == NULL || (md = parse_generic_signature(generic_sig, outer)) == NULL) { |
kamg@4245 | 521 | md = parse_generic_signature(m->signature(), outer); |
kamg@4245 | 522 | } |
kamg@4245 | 523 | assert(md != NULL, "Could not parse method signature"); |
kamg@4245 | 524 | md->bind_variables_to_parameters(); |
kamg@4245 | 525 | return md; |
kamg@4245 | 526 | } |
kamg@4245 | 527 | |
kamg@4245 | 528 | MethodDescriptor* MethodDescriptor::parse_generic_signature(Symbol* sym, ClassDescriptor* outer) { |
kamg@4245 | 529 | |
kamg@4245 | 530 | DescriptorStream ds(sym); |
kamg@4245 | 531 | DescriptorStream* STREAM = &ds; |
kamg@4245 | 532 | |
kamg@4245 | 533 | GrowableArray<TypeParameter*> params(8); |
kamg@4245 | 534 | char c = READ(); |
kamg@4245 | 535 | if (c == '<') { |
kamg@4245 | 536 | c = READ(); |
kamg@4245 | 537 | while (c != '>') { |
kamg@4245 | 538 | PUSH(c); |
kamg@4245 | 539 | TypeParameter* ftp = TypeParameter::parse_generic_signature(CHECK_STREAM); |
kamg@4245 | 540 | params.append(ftp); |
kamg@4245 | 541 | c = READ(); |
kamg@4245 | 542 | } |
kamg@4245 | 543 | } else { |
kamg@4245 | 544 | PUSH(c); |
kamg@4245 | 545 | } |
kamg@4245 | 546 | |
kamg@4245 | 547 | EXPECT('('); |
kamg@4245 | 548 | |
kamg@4245 | 549 | GrowableArray<Type*> parameters(8); |
kamg@4245 | 550 | c = READ(); |
kamg@4245 | 551 | while (c != ')') { |
kamg@4245 | 552 | PUSH(c); |
kamg@4245 | 553 | Type* arg = Type::parse_generic_signature(CHECK_STREAM); |
kamg@4245 | 554 | parameters.append(arg); |
kamg@4245 | 555 | c = READ(); |
kamg@4245 | 556 | } |
kamg@4245 | 557 | |
kamg@4245 | 558 | Type* rt = Type::parse_generic_signature(CHECK_STREAM); |
kamg@4245 | 559 | |
kamg@4245 | 560 | GrowableArray<Type*> throws; |
kamg@4245 | 561 | while (!STREAM->at_end()) { |
kamg@4245 | 562 | EXPECT('^'); |
kamg@4245 | 563 | Type* spec = Type::parse_generic_signature(CHECK_STREAM); |
kamg@4245 | 564 | throws.append(spec); |
kamg@4245 | 565 | } |
kamg@4245 | 566 | |
kamg@4245 | 567 | return new MethodDescriptor(params, outer, parameters, rt, throws); |
kamg@4245 | 568 | } |
kamg@4245 | 569 | |
kamg@4245 | 570 | void MethodDescriptor::bind_variables_to_parameters() { |
kamg@4245 | 571 | for (int i = 0; i < _type_parameters.length(); ++i) { |
kamg@4245 | 572 | _type_parameters.at(i)->bind_variables_to_parameters(this, i); |
kamg@4245 | 573 | } |
kamg@4245 | 574 | for (int i = 0; i < _parameters.length(); ++i) { |
kamg@4245 | 575 | _parameters.at(i)->bind_variables_to_parameters(this); |
kamg@4245 | 576 | } |
kamg@4245 | 577 | _return_type->bind_variables_to_parameters(this); |
kamg@4245 | 578 | for (int i = 0; i < _throws.length(); ++i) { |
kamg@4245 | 579 | _throws.at(i)->bind_variables_to_parameters(this); |
kamg@4245 | 580 | } |
kamg@4245 | 581 | } |
kamg@4245 | 582 | |
kamg@4245 | 583 | bool MethodDescriptor::covariant_match(MethodDescriptor* other, Context* ctx) { |
kamg@4245 | 584 | |
kamg@4245 | 585 | if (_parameters.length() == other->_parameters.length()) { |
kamg@4245 | 586 | for (int i = 0; i < _parameters.length(); ++i) { |
kamg@4245 | 587 | if (!_parameters.at(i)->covariant_match(other->_parameters.at(i), ctx)) { |
kamg@4245 | 588 | return false; |
kamg@4245 | 589 | } |
kamg@4245 | 590 | } |
kamg@4245 | 591 | |
kamg@4245 | 592 | if (_return_type->as_primitive() != NULL) { |
kamg@4245 | 593 | return _return_type->covariant_match(other->_return_type, ctx); |
kamg@4245 | 594 | } else { |
kamg@4245 | 595 | // return type is a reference |
kamg@4245 | 596 | return other->_return_type->as_class() != NULL || |
kamg@4245 | 597 | other->_return_type->as_variable() != NULL || |
kamg@4245 | 598 | other->_return_type->as_array() != NULL; |
kamg@4245 | 599 | } |
kamg@4245 | 600 | } else { |
kamg@4245 | 601 | return false; |
kamg@4245 | 602 | } |
kamg@4245 | 603 | } |
kamg@4245 | 604 | |
kamg@4245 | 605 | MethodDescriptor* MethodDescriptor::canonicalize(Context* ctx) { |
kamg@4245 | 606 | |
kamg@4245 | 607 | GrowableArray<TypeParameter*> type_params(_type_parameters.length()); |
kamg@4245 | 608 | for (int i = 0; i < _type_parameters.length(); ++i) { |
kamg@4245 | 609 | type_params.append(_type_parameters.at(i)->canonicalize(ctx, 0)); |
kamg@4245 | 610 | } |
kamg@4245 | 611 | |
kamg@4245 | 612 | ClassDescriptor* outer = _outer_class == NULL ? NULL : |
kamg@4245 | 613 | _outer_class->canonicalize(ctx); |
kamg@4245 | 614 | |
kamg@4245 | 615 | GrowableArray<Type*> params(_parameters.length()); |
kamg@4245 | 616 | for (int i = 0; i < _parameters.length(); ++i) { |
kamg@4245 | 617 | params.append(_parameters.at(i)->canonicalize(ctx, 0)); |
kamg@4245 | 618 | } |
kamg@4245 | 619 | |
kamg@4245 | 620 | Type* rt = _return_type->canonicalize(ctx, 0); |
kamg@4245 | 621 | |
kamg@4245 | 622 | GrowableArray<Type*> throws(_throws.length()); |
kamg@4245 | 623 | for (int i = 0; i < _throws.length(); ++i) { |
kamg@4245 | 624 | throws.append(_throws.at(i)->canonicalize(ctx, 0)); |
kamg@4245 | 625 | } |
kamg@4245 | 626 | |
kamg@4245 | 627 | return new MethodDescriptor(type_params, outer, params, rt, throws); |
kamg@4245 | 628 | } |
kamg@4245 | 629 | |
kamg@4245 | 630 | #ifndef PRODUCT |
kamg@4245 | 631 | TempNewSymbol MethodDescriptor::reify_signature(Context* ctx, TRAPS) { |
kamg@4245 | 632 | stringStream ss(256); |
kamg@4245 | 633 | |
kamg@4245 | 634 | ss.print("("); |
kamg@4245 | 635 | for (int i = 0; i < _parameters.length(); ++i) { |
kamg@4245 | 636 | _parameters.at(i)->reify_signature(&ss, ctx); |
kamg@4245 | 637 | } |
kamg@4245 | 638 | ss.print(")"); |
kamg@4245 | 639 | _return_type->reify_signature(&ss, ctx); |
kamg@4245 | 640 | return SymbolTable::new_symbol(ss.base(), (int)ss.size(), THREAD); |
kamg@4245 | 641 | } |
kamg@4245 | 642 | |
kamg@4245 | 643 | void MethodDescriptor::print_on(outputStream* str) const { |
kamg@4245 | 644 | str->indent().print_cr("MethodDescriptor {"); |
kamg@4245 | 645 | { |
kamg@4245 | 646 | streamIndentor si(str); |
kamg@4245 | 647 | if (_type_parameters.length() > 0) { |
kamg@4245 | 648 | str->indent().print_cr("Formals: {"); |
kamg@4245 | 649 | { |
kamg@4245 | 650 | streamIndentor si(str); |
kamg@4245 | 651 | for (int i = 0; i < _type_parameters.length(); ++i) { |
kamg@4245 | 652 | _type_parameters.at(i)->print_on(str); |
kamg@4245 | 653 | } |
kamg@4245 | 654 | } |
kamg@4245 | 655 | str->indent().print_cr("}"); |
kamg@4245 | 656 | } |
kamg@4245 | 657 | str->indent().print_cr("Parameters: {"); |
kamg@4245 | 658 | { |
kamg@4245 | 659 | streamIndentor si(str); |
kamg@4245 | 660 | for (int i = 0; i < _parameters.length(); ++i) { |
kamg@4245 | 661 | _parameters.at(i)->print_on(str); |
kamg@4245 | 662 | } |
kamg@4245 | 663 | } |
kamg@4245 | 664 | str->indent().print_cr("}"); |
kamg@4245 | 665 | str->indent().print_cr("Return Type: "); |
kamg@4245 | 666 | { |
kamg@4245 | 667 | streamIndentor si(str); |
kamg@4245 | 668 | _return_type->print_on(str); |
kamg@4245 | 669 | } |
kamg@4245 | 670 | |
kamg@4245 | 671 | if (_throws.length() > 0) { |
kamg@4245 | 672 | str->indent().print_cr("Throws: {"); |
kamg@4245 | 673 | { |
kamg@4245 | 674 | streamIndentor si(str); |
kamg@4245 | 675 | for (int i = 0; i < _throws.length(); ++i) { |
kamg@4245 | 676 | _throws.at(i)->print_on(str); |
kamg@4245 | 677 | } |
kamg@4245 | 678 | } |
kamg@4245 | 679 | str->indent().print_cr("}"); |
kamg@4245 | 680 | } |
kamg@4245 | 681 | } |
kamg@4245 | 682 | str->indent().print_cr("}"); |
kamg@4245 | 683 | } |
kamg@4245 | 684 | #endif // ndef PRODUCT |
kamg@4245 | 685 | |
kamg@4245 | 686 | TypeParameter* TypeParameter::parse_generic_signature(DescriptorStream* STREAM) { |
kamg@4245 | 687 | STREAM->set_mark(); |
kamg@4245 | 688 | char c = READ(); |
kamg@4245 | 689 | while (c != ':') { |
kamg@4245 | 690 | c = READ(); |
kamg@4245 | 691 | } |
kamg@4245 | 692 | |
kamg@4245 | 693 | Identifier* id = STREAM->identifier_from_mark(); |
kamg@4245 | 694 | |
kamg@4245 | 695 | ClassType* class_bound = NULL; |
kamg@4245 | 696 | GrowableArray<ClassType*> interface_bounds(8); |
kamg@4245 | 697 | |
kamg@4245 | 698 | c = READ(); |
kamg@4245 | 699 | if (c != '>') { |
kamg@4245 | 700 | if (c != ':') { |
kamg@4245 | 701 | EXPECTED(c, 'L'); |
kamg@4245 | 702 | class_bound = ClassType::parse_generic_signature(CHECK_STREAM); |
kamg@4245 | 703 | c = READ(); |
kamg@4245 | 704 | } |
kamg@4245 | 705 | |
kamg@4245 | 706 | while (c == ':') { |
kamg@4245 | 707 | EXPECT('L'); |
kamg@4245 | 708 | ClassType* fts = ClassType::parse_generic_signature(CHECK_STREAM); |
kamg@4245 | 709 | interface_bounds.append(fts); |
kamg@4245 | 710 | c = READ(); |
kamg@4245 | 711 | } |
kamg@4245 | 712 | } |
kamg@4245 | 713 | PUSH(c); |
kamg@4245 | 714 | |
kamg@4245 | 715 | return new TypeParameter(id, class_bound, interface_bounds); |
kamg@4245 | 716 | } |
kamg@4245 | 717 | |
kamg@4245 | 718 | void TypeParameter::bind_variables_to_parameters(Descriptor* sig, int position) { |
kamg@4245 | 719 | if (_class_bound != NULL) { |
kamg@4245 | 720 | _class_bound->bind_variables_to_parameters(sig); |
kamg@4245 | 721 | } |
kamg@4245 | 722 | for (int i = 0; i < _interface_bounds.length(); ++i) { |
kamg@4245 | 723 | _interface_bounds.at(i)->bind_variables_to_parameters(sig); |
kamg@4245 | 724 | } |
kamg@4245 | 725 | _position = position; |
kamg@4245 | 726 | } |
kamg@4245 | 727 | |
kamg@4245 | 728 | Type* TypeParameter::resolve( |
kamg@4245 | 729 | Context* ctx, int inner_depth, int ctx_depth) { |
kamg@4245 | 730 | |
kamg@4245 | 731 | if (inner_depth == -1) { |
kamg@4245 | 732 | // This indicates that the parameter is a method type parameter, which |
kamg@4245 | 733 | // isn't resolveable using the class hierarchy context |
kamg@4245 | 734 | return bound(); |
kamg@4245 | 735 | } |
kamg@4245 | 736 | |
kamg@4245 | 737 | ClassType* provider = ctx->at_depth(ctx_depth); |
kamg@4245 | 738 | if (provider != NULL) { |
kamg@4245 | 739 | for (int i = 0; i < inner_depth && provider != NULL; ++i) { |
kamg@4245 | 740 | provider = provider->outer_class(); |
kamg@4245 | 741 | } |
kamg@4245 | 742 | if (provider != NULL) { |
kamg@4245 | 743 | TypeArgument* arg = provider->type_argument_at(_position); |
kamg@4245 | 744 | if (arg != NULL) { |
kamg@4245 | 745 | Type* value = arg->lower_bound(); |
kamg@4245 | 746 | return value->canonicalize(ctx, ctx_depth + 1); |
kamg@4245 | 747 | } |
kamg@4245 | 748 | } |
kamg@4245 | 749 | } |
kamg@4245 | 750 | |
kamg@4245 | 751 | return bound(); |
kamg@4245 | 752 | } |
kamg@4245 | 753 | |
kamg@4245 | 754 | TypeParameter* TypeParameter::canonicalize(Context* ctx, int ctx_depth) { |
kamg@4245 | 755 | ClassType* bound = _class_bound == NULL ? NULL : |
kamg@4245 | 756 | _class_bound->canonicalize(ctx, ctx_depth); |
kamg@4245 | 757 | |
kamg@4245 | 758 | GrowableArray<ClassType*> ifaces(_interface_bounds.length()); |
kamg@4245 | 759 | for (int i = 0; i < _interface_bounds.length(); ++i) { |
kamg@4245 | 760 | ifaces.append(_interface_bounds.at(i)->canonicalize(ctx, ctx_depth)); |
kamg@4245 | 761 | } |
kamg@4245 | 762 | |
kamg@4245 | 763 | TypeParameter* ret = new TypeParameter(_identifier, bound, ifaces); |
kamg@4245 | 764 | ret->_position = _position; |
kamg@4245 | 765 | return ret; |
kamg@4245 | 766 | } |
kamg@4245 | 767 | |
kamg@4245 | 768 | ClassType* TypeParameter::bound() { |
kamg@4245 | 769 | if (_class_bound != NULL) { |
kamg@4245 | 770 | return _class_bound; |
kamg@4245 | 771 | } |
kamg@4245 | 772 | |
kamg@4245 | 773 | if (_interface_bounds.length() == 1) { |
kamg@4245 | 774 | return _interface_bounds.at(0); |
kamg@4245 | 775 | } |
kamg@4245 | 776 | |
kamg@4245 | 777 | return ClassType::java_lang_Object(); // TODO: investigate this case |
kamg@4245 | 778 | } |
kamg@4245 | 779 | |
kamg@4245 | 780 | #ifndef PRODUCT |
kamg@4245 | 781 | void TypeParameter::print_on(outputStream* str) const { |
kamg@4245 | 782 | str->indent().print_cr("Formal: {"); |
kamg@4245 | 783 | { |
kamg@4245 | 784 | streamIndentor si(str); |
kamg@4245 | 785 | |
kamg@4245 | 786 | str->indent().print("Identifier: "); |
kamg@4245 | 787 | _identifier->print_on(str); |
kamg@4245 | 788 | str->print_cr(""); |
kamg@4245 | 789 | if (_class_bound != NULL) { |
kamg@4245 | 790 | str->indent().print_cr("Class Bound: "); |
kamg@4245 | 791 | streamIndentor si(str); |
kamg@4245 | 792 | _class_bound->print_on(str); |
kamg@4245 | 793 | } |
kamg@4245 | 794 | if (_interface_bounds.length() > 0) { |
kamg@4245 | 795 | str->indent().print_cr("Interface Bounds: {"); |
kamg@4245 | 796 | { |
kamg@4245 | 797 | streamIndentor si(str); |
kamg@4245 | 798 | for (int i = 0; i < _interface_bounds.length(); ++i) { |
kamg@4245 | 799 | _interface_bounds.at(i)->print_on(str); |
kamg@4245 | 800 | } |
kamg@4245 | 801 | } |
kamg@4245 | 802 | str->indent().print_cr("}"); |
kamg@4245 | 803 | } |
kamg@4245 | 804 | str->indent().print_cr("Ordinal Position: %d", _position); |
kamg@4245 | 805 | } |
kamg@4245 | 806 | str->indent().print_cr("}"); |
kamg@4245 | 807 | } |
kamg@4245 | 808 | #endif // ndef PRODUCT |
kamg@4245 | 809 | |
kamg@4245 | 810 | Type* Type::parse_generic_signature(DescriptorStream* STREAM) { |
kamg@4245 | 811 | char c = READ(); |
kamg@4245 | 812 | switch (c) { |
kamg@4245 | 813 | case 'L': |
kamg@4245 | 814 | return ClassType::parse_generic_signature(CHECK_STREAM); |
kamg@4245 | 815 | case 'T': |
kamg@4245 | 816 | return TypeVariable::parse_generic_signature(CHECK_STREAM); |
kamg@4245 | 817 | case '[': |
kamg@4245 | 818 | return ArrayType::parse_generic_signature(CHECK_STREAM); |
kamg@4245 | 819 | default: |
kamg@4245 | 820 | return new PrimitiveType(c); |
kamg@4245 | 821 | } |
kamg@4245 | 822 | } |
kamg@4245 | 823 | |
kamg@4245 | 824 | Identifier* ClassType::parse_generic_signature_simple(GrowableArray<TypeArgument*>* args, |
kamg@4245 | 825 | bool* has_inner, DescriptorStream* STREAM) { |
kamg@4245 | 826 | STREAM->set_mark(); |
kamg@4245 | 827 | |
kamg@4245 | 828 | char c = READ(); |
kamg@4245 | 829 | while (c != ';' && c != '.' && c != '<') { c = READ(); } |
kamg@4245 | 830 | Identifier* id = STREAM->identifier_from_mark(); |
kamg@4245 | 831 | |
kamg@4245 | 832 | if (c == '<') { |
kamg@4245 | 833 | c = READ(); |
kamg@4245 | 834 | while (c != '>') { |
kamg@4245 | 835 | PUSH(c); |
kamg@4245 | 836 | TypeArgument* arg = TypeArgument::parse_generic_signature(CHECK_STREAM); |
kamg@4245 | 837 | args->append(arg); |
kamg@4245 | 838 | c = READ(); |
kamg@4245 | 839 | } |
kamg@4245 | 840 | c = READ(); |
kamg@4245 | 841 | } |
kamg@4245 | 842 | |
kamg@4245 | 843 | *has_inner = (c == '.'); |
kamg@4245 | 844 | if (!(*has_inner)) { |
kamg@4245 | 845 | EXPECTED(c, ';'); |
kamg@4245 | 846 | } |
kamg@4245 | 847 | |
kamg@4245 | 848 | return id; |
kamg@4245 | 849 | } |
kamg@4245 | 850 | |
kamg@4245 | 851 | ClassType* ClassType::parse_generic_signature(DescriptorStream* STREAM) { |
kamg@4245 | 852 | return parse_generic_signature(NULL, CHECK_STREAM); |
kamg@4245 | 853 | } |
kamg@4245 | 854 | |
kamg@4245 | 855 | ClassType* ClassType::parse_generic_signature(ClassType* outer, DescriptorStream* STREAM) { |
kamg@4245 | 856 | GrowableArray<TypeArgument*> args; |
kamg@4245 | 857 | ClassType* gct = NULL; |
kamg@4245 | 858 | bool has_inner = false; |
kamg@4245 | 859 | |
kamg@4245 | 860 | Identifier* id = parse_generic_signature_simple(&args, &has_inner, STREAM); |
kamg@4245 | 861 | if (id != NULL) { |
kamg@4245 | 862 | gct = new ClassType(id, args, outer); |
kamg@4245 | 863 | |
kamg@4245 | 864 | if (has_inner) { |
kamg@4245 | 865 | gct = parse_generic_signature(gct, CHECK_STREAM); |
kamg@4245 | 866 | } |
kamg@4245 | 867 | } |
kamg@4245 | 868 | return gct; |
kamg@4245 | 869 | } |
kamg@4245 | 870 | |
kamg@4245 | 871 | ClassType* ClassType::from_symbol(Symbol* sym) { |
kamg@4245 | 872 | assert(sym != NULL, "Must not be null"); |
kamg@4245 | 873 | GrowableArray<TypeArgument*> args; |
kamg@4245 | 874 | Identifier* id = new Identifier(sym, 0, sym->utf8_length()); |
kamg@4245 | 875 | return new ClassType(id, args, NULL); |
kamg@4245 | 876 | } |
kamg@4245 | 877 | |
kamg@4245 | 878 | ClassType* ClassType::java_lang_Object() { |
kamg@4245 | 879 | return from_symbol(vmSymbols::java_lang_Object()); |
kamg@4245 | 880 | } |
kamg@4245 | 881 | |
kamg@4245 | 882 | void ClassType::bind_variables_to_parameters(Descriptor* sig) { |
kamg@4245 | 883 | for (int i = 0; i < _type_arguments.length(); ++i) { |
kamg@4245 | 884 | _type_arguments.at(i)->bind_variables_to_parameters(sig); |
kamg@4245 | 885 | } |
kamg@4245 | 886 | if (_outer_class != NULL) { |
kamg@4245 | 887 | _outer_class->bind_variables_to_parameters(sig); |
kamg@4245 | 888 | } |
kamg@4245 | 889 | } |
kamg@4245 | 890 | |
kamg@4245 | 891 | TypeArgument* ClassType::type_argument_at(int i) { |
kamg@4245 | 892 | if (i >= 0 && i < _type_arguments.length()) { |
kamg@4245 | 893 | return _type_arguments.at(i); |
kamg@4245 | 894 | } else { |
kamg@4245 | 895 | return NULL; |
kamg@4245 | 896 | } |
kamg@4245 | 897 | } |
kamg@4245 | 898 | |
kamg@4245 | 899 | #ifndef PRODUCT |
kamg@4245 | 900 | void ClassType::reify_signature(stringStream* ss, Context* ctx) { |
kamg@4245 | 901 | ss->print("L"); |
kamg@4245 | 902 | _identifier->print_on(ss); |
kamg@4245 | 903 | ss->print(";"); |
kamg@4245 | 904 | } |
kamg@4245 | 905 | |
kamg@4245 | 906 | void ClassType::print_on(outputStream* str) const { |
kamg@4245 | 907 | str->indent().print_cr("Class {"); |
kamg@4245 | 908 | { |
kamg@4245 | 909 | streamIndentor si(str); |
kamg@4245 | 910 | str->indent().print("Name: "); |
kamg@4245 | 911 | _identifier->print_on(str); |
kamg@4245 | 912 | str->print_cr(""); |
kamg@4245 | 913 | if (_type_arguments.length() != 0) { |
kamg@4245 | 914 | str->indent().print_cr("Type Arguments: {"); |
kamg@4245 | 915 | { |
kamg@4245 | 916 | streamIndentor si(str); |
kamg@4245 | 917 | for (int j = 0; j < _type_arguments.length(); ++j) { |
kamg@4245 | 918 | _type_arguments.at(j)->print_on(str); |
kamg@4245 | 919 | } |
kamg@4245 | 920 | } |
kamg@4245 | 921 | str->indent().print_cr("}"); |
kamg@4245 | 922 | } |
kamg@4245 | 923 | if (_outer_class != NULL) { |
kamg@4245 | 924 | str->indent().print_cr("Outer Class: "); |
kamg@4245 | 925 | streamIndentor sir(str); |
kamg@4245 | 926 | _outer_class->print_on(str); |
kamg@4245 | 927 | } |
kamg@4245 | 928 | } |
kamg@4245 | 929 | str->indent().print_cr("}"); |
kamg@4245 | 930 | } |
kamg@4245 | 931 | #endif // ndef PRODUCT |
kamg@4245 | 932 | |
kamg@4245 | 933 | bool ClassType::covariant_match(Type* other, Context* ctx) { |
kamg@4245 | 934 | |
kamg@4245 | 935 | if (other == this) { |
kamg@4245 | 936 | return true; |
kamg@4245 | 937 | } |
kamg@4245 | 938 | |
kamg@4245 | 939 | TypeVariable* variable = other->as_variable(); |
kamg@4245 | 940 | if (variable != NULL) { |
kamg@4245 | 941 | other = variable->resolve(ctx, 0); |
kamg@4245 | 942 | } |
kamg@4245 | 943 | |
kamg@4245 | 944 | ClassType* outer = outer_class(); |
kamg@4245 | 945 | ClassType* other_class = other->as_class(); |
kamg@4245 | 946 | |
kamg@4245 | 947 | if (other_class == NULL || |
kamg@4245 | 948 | (outer == NULL) != (other_class->outer_class() == NULL)) { |
kamg@4245 | 949 | return false; |
kamg@4245 | 950 | } |
kamg@4245 | 951 | |
kamg@4245 | 952 | if (!_identifier->equals(other_class->_identifier)) { |
kamg@4245 | 953 | return false; |
kamg@4245 | 954 | } |
kamg@4245 | 955 | |
kamg@4245 | 956 | if (outer != NULL && !outer->covariant_match(other_class->outer_class(), ctx)) { |
kamg@4245 | 957 | return false; |
kamg@4245 | 958 | } |
kamg@4245 | 959 | |
kamg@4245 | 960 | return true; |
kamg@4245 | 961 | } |
kamg@4245 | 962 | |
kamg@4245 | 963 | ClassType* ClassType::canonicalize(Context* ctx, int ctx_depth) { |
kamg@4245 | 964 | |
kamg@4245 | 965 | GrowableArray<TypeArgument*> args(_type_arguments.length()); |
kamg@4245 | 966 | for (int i = 0; i < _type_arguments.length(); ++i) { |
kamg@4245 | 967 | args.append(_type_arguments.at(i)->canonicalize(ctx, ctx_depth)); |
kamg@4245 | 968 | } |
kamg@4245 | 969 | |
kamg@4245 | 970 | ClassType* outer = _outer_class == NULL ? NULL : |
kamg@4245 | 971 | _outer_class->canonicalize(ctx, ctx_depth); |
kamg@4245 | 972 | |
kamg@4245 | 973 | return new ClassType(_identifier, args, outer); |
kamg@4245 | 974 | } |
kamg@4245 | 975 | |
kamg@4245 | 976 | TypeVariable* TypeVariable::parse_generic_signature(DescriptorStream* STREAM) { |
kamg@4245 | 977 | STREAM->set_mark(); |
kamg@4245 | 978 | char c = READ(); |
kamg@4245 | 979 | while (c != ';') { |
kamg@4245 | 980 | c = READ(); |
kamg@4245 | 981 | } |
kamg@4245 | 982 | Identifier* id = STREAM->identifier_from_mark(); |
kamg@4245 | 983 | |
kamg@4245 | 984 | return new TypeVariable(id); |
kamg@4245 | 985 | } |
kamg@4245 | 986 | |
kamg@4245 | 987 | void TypeVariable::bind_variables_to_parameters(Descriptor* sig) { |
kamg@4245 | 988 | _parameter = sig->find_type_parameter(_id, &_inner_depth); |
kamg@4245 | 989 | if (VerifyGenericSignatures && _parameter == NULL) { |
kamg@4245 | 990 | fatal("Could not find formal parameter"); |
kamg@4245 | 991 | } |
kamg@4245 | 992 | } |
kamg@4245 | 993 | |
kamg@4245 | 994 | Type* TypeVariable::resolve(Context* ctx, int ctx_depth) { |
kamg@4245 | 995 | if (parameter() != NULL) { |
kamg@4245 | 996 | return parameter()->resolve(ctx, inner_depth(), ctx_depth); |
kamg@4245 | 997 | } else { |
kamg@4245 | 998 | if (VerifyGenericSignatures) { |
kamg@4245 | 999 | fatal("Type variable matches no parameter"); |
kamg@4245 | 1000 | } |
kamg@4245 | 1001 | return NULL; |
kamg@4245 | 1002 | } |
kamg@4245 | 1003 | } |
kamg@4245 | 1004 | |
kamg@4245 | 1005 | bool TypeVariable::covariant_match(Type* other, Context* ctx) { |
kamg@4245 | 1006 | |
kamg@4245 | 1007 | if (other == this) { |
kamg@4245 | 1008 | return true; |
kamg@4245 | 1009 | } |
kamg@4245 | 1010 | |
kamg@4245 | 1011 | Context my_context(NULL); // empty, results in erasure |
kamg@4245 | 1012 | Type* my_type = resolve(&my_context, 0); |
kamg@4245 | 1013 | if (my_type == NULL) { |
kamg@4245 | 1014 | return false; |
kamg@4245 | 1015 | } |
kamg@4245 | 1016 | |
kamg@4245 | 1017 | return my_type->covariant_match(other, ctx); |
kamg@4245 | 1018 | } |
kamg@4245 | 1019 | |
kamg@4245 | 1020 | Type* TypeVariable::canonicalize(Context* ctx, int ctx_depth) { |
kamg@4245 | 1021 | return resolve(ctx, ctx_depth); |
kamg@4245 | 1022 | } |
kamg@4245 | 1023 | |
kamg@4245 | 1024 | #ifndef PRODUCT |
kamg@4245 | 1025 | void TypeVariable::reify_signature(stringStream* ss, Context* ctx) { |
kamg@4245 | 1026 | Type* type = resolve(ctx, 0); |
kamg@4245 | 1027 | if (type != NULL) { |
kamg@4245 | 1028 | type->reify_signature(ss, ctx); |
kamg@4245 | 1029 | } |
kamg@4245 | 1030 | } |
kamg@4245 | 1031 | |
kamg@4245 | 1032 | void TypeVariable::print_on(outputStream* str) const { |
kamg@4245 | 1033 | str->indent().print_cr("Type Variable {"); |
kamg@4245 | 1034 | { |
kamg@4245 | 1035 | streamIndentor si(str); |
kamg@4245 | 1036 | str->indent().print("Name: "); |
kamg@4245 | 1037 | _id->print_on(str); |
kamg@4245 | 1038 | str->print_cr(""); |
kamg@4245 | 1039 | str->indent().print_cr("Inner depth: %d", _inner_depth); |
kamg@4245 | 1040 | } |
kamg@4245 | 1041 | str->indent().print_cr("}"); |
kamg@4245 | 1042 | } |
kamg@4245 | 1043 | #endif // ndef PRODUCT |
kamg@4245 | 1044 | |
kamg@4245 | 1045 | ArrayType* ArrayType::parse_generic_signature(DescriptorStream* STREAM) { |
kamg@4245 | 1046 | Type* base = Type::parse_generic_signature(CHECK_STREAM); |
kamg@4245 | 1047 | return new ArrayType(base); |
kamg@4245 | 1048 | } |
kamg@4245 | 1049 | |
kamg@4245 | 1050 | void ArrayType::bind_variables_to_parameters(Descriptor* sig) { |
kamg@4245 | 1051 | assert(_base != NULL, "Invalid base"); |
kamg@4245 | 1052 | _base->bind_variables_to_parameters(sig); |
kamg@4245 | 1053 | } |
kamg@4245 | 1054 | |
kamg@4245 | 1055 | bool ArrayType::covariant_match(Type* other, Context* ctx) { |
kamg@4245 | 1056 | assert(_base != NULL, "Invalid base"); |
kamg@4245 | 1057 | |
kamg@4245 | 1058 | if (other == this) { |
kamg@4245 | 1059 | return true; |
kamg@4245 | 1060 | } |
kamg@4245 | 1061 | |
kamg@4245 | 1062 | ArrayType* other_array = other->as_array(); |
kamg@4245 | 1063 | return (other_array != NULL && _base->covariant_match(other_array->_base, ctx)); |
kamg@4245 | 1064 | } |
kamg@4245 | 1065 | |
kamg@4245 | 1066 | ArrayType* ArrayType::canonicalize(Context* ctx, int ctx_depth) { |
kamg@4245 | 1067 | assert(_base != NULL, "Invalid base"); |
kamg@4245 | 1068 | return new ArrayType(_base->canonicalize(ctx, ctx_depth)); |
kamg@4245 | 1069 | } |
kamg@4245 | 1070 | |
kamg@4245 | 1071 | #ifndef PRODUCT |
kamg@4245 | 1072 | void ArrayType::reify_signature(stringStream* ss, Context* ctx) { |
kamg@4245 | 1073 | assert(_base != NULL, "Invalid base"); |
kamg@4245 | 1074 | ss->print("["); |
kamg@4245 | 1075 | _base->reify_signature(ss, ctx); |
kamg@4245 | 1076 | } |
kamg@4245 | 1077 | |
kamg@4245 | 1078 | void ArrayType::print_on(outputStream* str) const { |
kamg@4245 | 1079 | str->indent().print_cr("Array {"); |
kamg@4245 | 1080 | { |
kamg@4245 | 1081 | streamIndentor si(str); |
kamg@4245 | 1082 | _base->print_on(str); |
kamg@4245 | 1083 | } |
kamg@4245 | 1084 | str->indent().print_cr("}"); |
kamg@4245 | 1085 | } |
kamg@4245 | 1086 | #endif // ndef PRODUCT |
kamg@4245 | 1087 | |
kamg@4245 | 1088 | bool PrimitiveType::covariant_match(Type* other, Context* ctx) { |
kamg@4245 | 1089 | |
kamg@4245 | 1090 | PrimitiveType* other_prim = other->as_primitive(); |
kamg@4245 | 1091 | return (other_prim != NULL && _type == other_prim->_type); |
kamg@4245 | 1092 | } |
kamg@4245 | 1093 | |
kamg@4245 | 1094 | PrimitiveType* PrimitiveType::canonicalize(Context* ctx, int ctxd) { |
kamg@4245 | 1095 | return this; |
kamg@4245 | 1096 | } |
kamg@4245 | 1097 | |
kamg@4245 | 1098 | #ifndef PRODUCT |
kamg@4245 | 1099 | void PrimitiveType::reify_signature(stringStream* ss, Context* ctx) { |
kamg@4245 | 1100 | ss->print("%c", _type); |
kamg@4245 | 1101 | } |
kamg@4245 | 1102 | |
kamg@4245 | 1103 | void PrimitiveType::print_on(outputStream* str) const { |
kamg@4245 | 1104 | str->indent().print_cr("Primitive: '%c'", _type); |
kamg@4245 | 1105 | } |
kamg@4245 | 1106 | #endif // ndef PRODUCT |
kamg@4245 | 1107 | |
kamg@4245 | 1108 | void PrimitiveType::bind_variables_to_parameters(Descriptor* sig) { |
kamg@4245 | 1109 | } |
kamg@4245 | 1110 | |
kamg@4245 | 1111 | TypeArgument* TypeArgument::parse_generic_signature(DescriptorStream* STREAM) { |
kamg@4245 | 1112 | char c = READ(); |
kamg@4245 | 1113 | Type* type = NULL; |
kamg@4245 | 1114 | |
kamg@4245 | 1115 | switch (c) { |
kamg@4245 | 1116 | case '*': |
kamg@4245 | 1117 | return new TypeArgument(ClassType::java_lang_Object(), NULL); |
kamg@4245 | 1118 | break; |
kamg@4245 | 1119 | default: |
kamg@4245 | 1120 | PUSH(c); |
kamg@4245 | 1121 | // fall-through |
kamg@4245 | 1122 | case '+': |
kamg@4245 | 1123 | case '-': |
kamg@4245 | 1124 | type = Type::parse_generic_signature(CHECK_STREAM); |
kamg@4245 | 1125 | if (c == '+') { |
kamg@4245 | 1126 | return new TypeArgument(type, NULL); |
kamg@4245 | 1127 | } else if (c == '-') { |
kamg@4245 | 1128 | return new TypeArgument(ClassType::java_lang_Object(), type); |
kamg@4245 | 1129 | } else { |
kamg@4245 | 1130 | return new TypeArgument(type, type); |
kamg@4245 | 1131 | } |
kamg@4245 | 1132 | } |
kamg@4245 | 1133 | } |
kamg@4245 | 1134 | |
kamg@4245 | 1135 | void TypeArgument::bind_variables_to_parameters(Descriptor* sig) { |
kamg@4245 | 1136 | assert(_lower_bound != NULL, "Invalid lower bound"); |
kamg@4245 | 1137 | _lower_bound->bind_variables_to_parameters(sig); |
kamg@4245 | 1138 | if (_upper_bound != NULL && _upper_bound != _lower_bound) { |
kamg@4245 | 1139 | _upper_bound->bind_variables_to_parameters(sig); |
kamg@4245 | 1140 | } |
kamg@4245 | 1141 | } |
kamg@4245 | 1142 | |
kamg@4245 | 1143 | bool TypeArgument::covariant_match(TypeArgument* other, Context* ctx) { |
kamg@4245 | 1144 | assert(_lower_bound != NULL, "Invalid lower bound"); |
kamg@4245 | 1145 | |
kamg@4245 | 1146 | if (other == this) { |
kamg@4245 | 1147 | return true; |
kamg@4245 | 1148 | } |
kamg@4245 | 1149 | |
kamg@4245 | 1150 | if (!_lower_bound->covariant_match(other->lower_bound(), ctx)) { |
kamg@4245 | 1151 | return false; |
kamg@4245 | 1152 | } |
kamg@4245 | 1153 | return true; |
kamg@4245 | 1154 | } |
kamg@4245 | 1155 | |
kamg@4245 | 1156 | TypeArgument* TypeArgument::canonicalize(Context* ctx, int ctx_depth) { |
kamg@4245 | 1157 | assert(_lower_bound != NULL, "Invalid lower bound"); |
kamg@4245 | 1158 | Type* lower = _lower_bound->canonicalize(ctx, ctx_depth); |
kamg@4245 | 1159 | Type* upper = NULL; |
kamg@4245 | 1160 | |
kamg@4245 | 1161 | if (_upper_bound == _lower_bound) { |
kamg@4245 | 1162 | upper = lower; |
kamg@4245 | 1163 | } else if (_upper_bound != NULL) { |
kamg@4245 | 1164 | upper = _upper_bound->canonicalize(ctx, ctx_depth); |
kamg@4245 | 1165 | } |
kamg@4245 | 1166 | |
kamg@4245 | 1167 | return new TypeArgument(lower, upper); |
kamg@4245 | 1168 | } |
kamg@4245 | 1169 | |
kamg@4245 | 1170 | #ifndef PRODUCT |
kamg@4245 | 1171 | void TypeArgument::print_on(outputStream* str) const { |
kamg@4245 | 1172 | str->indent().print_cr("TypeArgument {"); |
kamg@4245 | 1173 | { |
kamg@4245 | 1174 | streamIndentor si(str); |
kamg@4245 | 1175 | if (_lower_bound != NULL) { |
kamg@4245 | 1176 | str->indent().print("Lower bound: "); |
kamg@4245 | 1177 | _lower_bound->print_on(str); |
kamg@4245 | 1178 | } |
kamg@4245 | 1179 | if (_upper_bound != NULL) { |
kamg@4245 | 1180 | str->indent().print("Upper bound: "); |
kamg@4245 | 1181 | _upper_bound->print_on(str); |
kamg@4245 | 1182 | } |
kamg@4245 | 1183 | } |
kamg@4245 | 1184 | str->indent().print_cr("}"); |
kamg@4245 | 1185 | } |
kamg@4245 | 1186 | #endif // ndef PRODUCT |
kamg@4245 | 1187 | |
kamg@4245 | 1188 | void Context::Mark::destroy() { |
kamg@4245 | 1189 | if (is_active()) { |
kamg@4245 | 1190 | _context->reset_to_mark(_marked_size); |
kamg@4245 | 1191 | } |
kamg@4245 | 1192 | deactivate(); |
kamg@4245 | 1193 | } |
kamg@4245 | 1194 | |
kamg@4245 | 1195 | void Context::apply_type_arguments( |
kamg@4245 | 1196 | InstanceKlass* current, InstanceKlass* super, TRAPS) { |
kamg@4245 | 1197 | assert(_cache != NULL, "Cannot use an empty context"); |
kamg@4245 | 1198 | ClassType* spec = NULL; |
kamg@4245 | 1199 | if (current != NULL) { |
kamg@4245 | 1200 | ClassDescriptor* descriptor = _cache->descriptor_for(current, CHECK); |
kamg@4245 | 1201 | if (super == current->super()) { |
kamg@4245 | 1202 | spec = descriptor->super(); |
kamg@4245 | 1203 | } else { |
kamg@4245 | 1204 | spec = descriptor->interface_desc(super->name()); |
kamg@4245 | 1205 | } |
kamg@4245 | 1206 | if (spec != NULL) { |
kamg@4245 | 1207 | _type_arguments.push(spec); |
kamg@4245 | 1208 | } |
kamg@4245 | 1209 | } |
kamg@4245 | 1210 | } |
kamg@4245 | 1211 | |
kamg@4245 | 1212 | void Context::reset_to_mark(int size) { |
kamg@4245 | 1213 | _type_arguments.trunc_to(size); |
kamg@4245 | 1214 | } |
kamg@4245 | 1215 | |
kamg@4245 | 1216 | ClassType* Context::at_depth(int i) const { |
kamg@4245 | 1217 | if (i < _type_arguments.length()) { |
kamg@4245 | 1218 | return _type_arguments.at(_type_arguments.length() - 1 - i); |
kamg@4245 | 1219 | } |
kamg@4245 | 1220 | return NULL; |
kamg@4245 | 1221 | } |
kamg@4245 | 1222 | |
kamg@4245 | 1223 | #ifndef PRODUCT |
kamg@4245 | 1224 | void Context::print_on(outputStream* str) const { |
kamg@4245 | 1225 | str->indent().print_cr("Context {"); |
kamg@4245 | 1226 | for (int i = 0; i < _type_arguments.length(); ++i) { |
kamg@4245 | 1227 | streamIndentor si(str); |
kamg@4245 | 1228 | str->indent().print("leval %d: ", i); |
kamg@4245 | 1229 | ClassType* ct = at_depth(i); |
kamg@4245 | 1230 | if (ct == NULL) { |
kamg@4245 | 1231 | str->print_cr("<empty>"); |
kamg@4245 | 1232 | continue; |
kamg@4245 | 1233 | } else { |
kamg@4245 | 1234 | str->print_cr("{"); |
kamg@4245 | 1235 | } |
kamg@4245 | 1236 | |
kamg@4245 | 1237 | for (int j = 0; j < ct->type_arguments_length(); ++j) { |
kamg@4245 | 1238 | streamIndentor si(str); |
kamg@4245 | 1239 | TypeArgument* ta = ct->type_argument_at(j); |
kamg@4245 | 1240 | Type* bound = ta->lower_bound(); |
kamg@4245 | 1241 | bound->print_on(str); |
kamg@4245 | 1242 | } |
kamg@4245 | 1243 | str->indent().print_cr("}"); |
kamg@4245 | 1244 | } |
kamg@4245 | 1245 | str->indent().print_cr("}"); |
kamg@4245 | 1246 | } |
kamg@4245 | 1247 | #endif // ndef PRODUCT |
kamg@4245 | 1248 | |
kamg@4245 | 1249 | ClassDescriptor* DescriptorCache::descriptor_for(InstanceKlass* ik, TRAPS) { |
kamg@4245 | 1250 | |
kamg@4245 | 1251 | ClassDescriptor** existing = _class_descriptors.get(ik); |
kamg@4245 | 1252 | if (existing == NULL) { |
kamg@4245 | 1253 | ClassDescriptor* cd = ClassDescriptor::parse_generic_signature(ik, CHECK_NULL); |
kamg@4245 | 1254 | _class_descriptors.put(ik, cd); |
kamg@4245 | 1255 | return cd; |
kamg@4245 | 1256 | } else { |
kamg@4245 | 1257 | return *existing; |
kamg@4245 | 1258 | } |
kamg@4245 | 1259 | } |
kamg@4245 | 1260 | |
kamg@4245 | 1261 | MethodDescriptor* DescriptorCache::descriptor_for( |
kamg@4245 | 1262 | Method* mh, ClassDescriptor* cd, TRAPS) { |
kamg@4245 | 1263 | assert(mh != NULL && cd != NULL, "Should not be NULL"); |
kamg@4245 | 1264 | MethodDescriptor** existing = _method_descriptors.get(mh); |
kamg@4245 | 1265 | if (existing == NULL) { |
kamg@4245 | 1266 | MethodDescriptor* md = MethodDescriptor::parse_generic_signature(mh, cd); |
kamg@4245 | 1267 | _method_descriptors.put(mh, md); |
kamg@4245 | 1268 | return md; |
kamg@4245 | 1269 | } else { |
kamg@4245 | 1270 | return *existing; |
kamg@4245 | 1271 | } |
kamg@4245 | 1272 | } |
kamg@4245 | 1273 | MethodDescriptor* DescriptorCache::descriptor_for(Method* mh, TRAPS) { |
kamg@4245 | 1274 | ClassDescriptor* cd = descriptor_for( |
kamg@4245 | 1275 | InstanceKlass::cast(mh->method_holder()), CHECK_NULL); |
kamg@4245 | 1276 | return descriptor_for(mh, cd, THREAD); |
kamg@4245 | 1277 | } |
kamg@4245 | 1278 | |
kamg@4245 | 1279 | } // namespace generic |