src/share/vm/classfile/genericSignatures.cpp

Wed, 13 Mar 2013 15:15:56 -0400

author
coleenp
date
Wed, 13 Mar 2013 15:15:56 -0400
changeset 4718
0ede345ec7c9
parent 4245
4735d2c84362
child 4960
41ed397cc0cd
permissions
-rw-r--r--

8009829: CDS: JDK JPRT test fails crash in Symbol::equals()
Summary: -Xshare:dump was creating a Symbol in C_heap. There's an assert there that jdk jprt wasn't hitting because it was only done in product
Reviewed-by: dholmes, hseigel, iklam

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()) {
kamg@4245 271 outer = SystemDictionary::resolve_super_or_fail(original_name,
kamg@4245 272 outer_name, class_loader, protection_domain, false, CHECK_NULL);
kamg@4245 273 }
kamg@4245 274
kamg@4245 275 InstanceKlass* outer_ik;
kamg@4245 276 ClassDescriptor* outer_spec = NULL;
kamg@4245 277 if (outer == NULL) {
kamg@4245 278 outer_spec = ClassDescriptor::placeholder(ik);
kamg@4245 279 assert(false, "Outer class not loaded and not loadable from here");
kamg@4245 280 } else {
kamg@4245 281 outer_ik = InstanceKlass::cast(outer);
kamg@4245 282 outer_spec = parse_generic_signature(outer, original_name, CHECK_NULL);
kamg@4245 283 }
kamg@4245 284 spec->set_outer_class(outer_spec);
kamg@4245 285
kamg@4245 286 u2 encl_method_idx = ik->enclosing_method_method_index();
kamg@4245 287 if (encl_method_idx != 0 && outer_ik != NULL) {
kamg@4245 288 ConstantPool* cp = ik->constants();
kamg@4245 289 u2 name_index = cp->name_ref_index_at(encl_method_idx);
kamg@4245 290 u2 sig_index = cp->signature_ref_index_at(encl_method_idx);
kamg@4245 291 Symbol* name = cp->symbol_at(name_index);
kamg@4245 292 Symbol* sig = cp->symbol_at(sig_index);
kamg@4245 293 Method* m = outer_ik->find_method(name, sig);
kamg@4245 294 if (m != NULL) {
kamg@4245 295 Symbol* gsig = m->generic_signature();
kamg@4245 296 if (gsig != NULL) {
kamg@4245 297 MethodDescriptor* gms = MethodDescriptor::parse_generic_signature(gsig, outer_spec);
kamg@4245 298 spec->set_outer_method(gms);
kamg@4245 299 }
kamg@4245 300 } else if (VerifyGenericSignatures) {
kamg@4245 301 ResourceMark rm;
kamg@4245 302 stringStream ss;
kamg@4245 303 ss.print("Could not find method %s %s in class %s",
kamg@4245 304 name->as_C_string(), sig->as_C_string(), outer_name->as_C_string());
kamg@4245 305 fatal(ss.as_string());
kamg@4245 306 }
kamg@4245 307 }
kamg@4245 308 }
kamg@4245 309
kamg@4245 310 spec->bind_variables_to_parameters();
kamg@4245 311 return spec;
kamg@4245 312 }
kamg@4245 313
kamg@4245 314 ClassDescriptor* ClassDescriptor::placeholder(InstanceKlass* klass) {
kamg@4245 315 GrowableArray<TypeParameter*> formals;
kamg@4245 316 GrowableArray<ClassType*> interfaces;
kamg@4245 317 ClassType* super_type = NULL;
kamg@4245 318
kamg@4245 319 Klass* super_klass = klass->super();
kamg@4245 320 if (super_klass != NULL) {
kamg@4245 321 InstanceKlass* super = InstanceKlass::cast(super_klass);
kamg@4245 322 super_type = ClassType::from_symbol(super->name());
kamg@4245 323 }
kamg@4245 324
kamg@4245 325 for (int i = 0; i < klass->local_interfaces()->length(); ++i) {
kamg@4245 326 InstanceKlass* iface = InstanceKlass::cast(klass->local_interfaces()->at(i));
kamg@4245 327 interfaces.append(ClassType::from_symbol(iface->name()));
kamg@4245 328 }
kamg@4245 329 return new ClassDescriptor(formals, super_type, interfaces);
kamg@4245 330 }
kamg@4245 331
kamg@4245 332 ClassDescriptor* ClassDescriptor::parse_generic_signature(Symbol* sym) {
kamg@4245 333
kamg@4245 334 DescriptorStream ds(sym);
kamg@4245 335 DescriptorStream* STREAM = &ds;
kamg@4245 336
kamg@4245 337 GrowableArray<TypeParameter*> parameters(8);
kamg@4245 338 char c = READ();
kamg@4245 339 if (c == '<') {
kamg@4245 340 c = READ();
kamg@4245 341 while (c != '>') {
kamg@4245 342 PUSH(c);
kamg@4245 343 TypeParameter* ftp = TypeParameter::parse_generic_signature(CHECK_STREAM);
kamg@4245 344 parameters.append(ftp);
kamg@4245 345 c = READ();
kamg@4245 346 }
kamg@4245 347 } else {
kamg@4245 348 PUSH(c);
kamg@4245 349 }
kamg@4245 350
kamg@4245 351 EXPECT('L');
kamg@4245 352 ClassType* super = ClassType::parse_generic_signature(CHECK_STREAM);
kamg@4245 353
kamg@4245 354 GrowableArray<ClassType*> signatures(2);
kamg@4245 355 while (!STREAM->at_end()) {
kamg@4245 356 EXPECT('L');
kamg@4245 357 ClassType* iface = ClassType::parse_generic_signature(CHECK_STREAM);
kamg@4245 358 signatures.append(iface);
kamg@4245 359 }
kamg@4245 360
kamg@4245 361 EXPECT_END();
kamg@4245 362
kamg@4245 363 return new ClassDescriptor(parameters, super, signatures);
kamg@4245 364 }
kamg@4245 365
kamg@4245 366 #ifndef PRODUCT
kamg@4245 367 void ClassDescriptor::print_on(outputStream* str) const {
kamg@4245 368 str->indent().print_cr("ClassDescriptor {");
kamg@4245 369 {
kamg@4245 370 streamIndentor si(str);
kamg@4245 371 if (_type_parameters.length() > 0) {
kamg@4245 372 str->indent().print_cr("Formals {");
kamg@4245 373 {
kamg@4245 374 streamIndentor si(str);
kamg@4245 375 for (int i = 0; i < _type_parameters.length(); ++i) {
kamg@4245 376 _type_parameters.at(i)->print_on(str);
kamg@4245 377 }
kamg@4245 378 }
kamg@4245 379 str->indent().print_cr("}");
kamg@4245 380 }
kamg@4245 381 if (_super != NULL) {
kamg@4245 382 str->indent().print_cr("Superclass: ");
kamg@4245 383 {
kamg@4245 384 streamIndentor si(str);
kamg@4245 385 _super->print_on(str);
kamg@4245 386 }
kamg@4245 387 }
kamg@4245 388 if (_interfaces.length() > 0) {
kamg@4245 389 str->indent().print_cr("SuperInterfaces: {");
kamg@4245 390 {
kamg@4245 391 streamIndentor si(str);
kamg@4245 392 for (int i = 0; i < _interfaces.length(); ++i) {
kamg@4245 393 _interfaces.at(i)->print_on(str);
kamg@4245 394 }
kamg@4245 395 }
kamg@4245 396 str->indent().print_cr("}");
kamg@4245 397 }
kamg@4245 398 if (_outer_method != NULL) {
kamg@4245 399 str->indent().print_cr("Outer Method: {");
kamg@4245 400 {
kamg@4245 401 streamIndentor si(str);
kamg@4245 402 _outer_method->print_on(str);
kamg@4245 403 }
kamg@4245 404 str->indent().print_cr("}");
kamg@4245 405 }
kamg@4245 406 if (_outer_class != NULL) {
kamg@4245 407 str->indent().print_cr("Outer Class: {");
kamg@4245 408 {
kamg@4245 409 streamIndentor si(str);
kamg@4245 410 _outer_class->print_on(str);
kamg@4245 411 }
kamg@4245 412 str->indent().print_cr("}");
kamg@4245 413 }
kamg@4245 414 }
kamg@4245 415 str->indent().print_cr("}");
kamg@4245 416 }
kamg@4245 417 #endif // ndef PRODUCT
kamg@4245 418
kamg@4245 419 ClassType* ClassDescriptor::interface_desc(Symbol* sym) {
kamg@4245 420 for (int i = 0; i < _interfaces.length(); ++i) {
kamg@4245 421 if (_interfaces.at(i)->identifier()->equals(sym)) {
kamg@4245 422 return _interfaces.at(i);
kamg@4245 423 }
kamg@4245 424 }
kamg@4245 425 if (VerifyGenericSignatures) {
kamg@4245 426 fatal("Did not find expected interface");
kamg@4245 427 }
kamg@4245 428 return NULL;
kamg@4245 429 }
kamg@4245 430
kamg@4245 431 void ClassDescriptor::bind_variables_to_parameters() {
kamg@4245 432 if (_outer_class != NULL) {
kamg@4245 433 _outer_class->bind_variables_to_parameters();
kamg@4245 434 }
kamg@4245 435 if (_outer_method != NULL) {
kamg@4245 436 _outer_method->bind_variables_to_parameters();
kamg@4245 437 }
kamg@4245 438 for (int i = 0; i < _type_parameters.length(); ++i) {
kamg@4245 439 _type_parameters.at(i)->bind_variables_to_parameters(this, i);
kamg@4245 440 }
kamg@4245 441 if (_super != NULL) {
kamg@4245 442 _super->bind_variables_to_parameters(this);
kamg@4245 443 }
kamg@4245 444 for (int i = 0; i < _interfaces.length(); ++i) {
kamg@4245 445 _interfaces.at(i)->bind_variables_to_parameters(this);
kamg@4245 446 }
kamg@4245 447 }
kamg@4245 448
kamg@4245 449 ClassDescriptor* ClassDescriptor::canonicalize(Context* ctx) {
kamg@4245 450
kamg@4245 451 GrowableArray<TypeParameter*> type_params(_type_parameters.length());
kamg@4245 452 for (int i = 0; i < _type_parameters.length(); ++i) {
kamg@4245 453 type_params.append(_type_parameters.at(i)->canonicalize(ctx, 0));
kamg@4245 454 }
kamg@4245 455
kamg@4245 456 ClassDescriptor* outer = _outer_class == NULL ? NULL :
kamg@4245 457 _outer_class->canonicalize(ctx);
kamg@4245 458
kamg@4245 459 ClassType* super = _super == NULL ? NULL : _super->canonicalize(ctx, 0);
kamg@4245 460
kamg@4245 461 GrowableArray<ClassType*> interfaces(_interfaces.length());
kamg@4245 462 for (int i = 0; i < _interfaces.length(); ++i) {
kamg@4245 463 interfaces.append(_interfaces.at(i)->canonicalize(ctx, 0));
kamg@4245 464 }
kamg@4245 465
kamg@4245 466 MethodDescriptor* md = _outer_method == NULL ? NULL :
kamg@4245 467 _outer_method->canonicalize(ctx);
kamg@4245 468
kamg@4245 469 return new ClassDescriptor(type_params, super, interfaces, outer, md);
kamg@4245 470 }
kamg@4245 471
kamg@4245 472 u2 ClassDescriptor::get_outer_class_index(InstanceKlass* klass, TRAPS) {
kamg@4245 473 int inner_index = InstanceKlass::inner_class_inner_class_info_offset;
kamg@4245 474 int outer_index = InstanceKlass::inner_class_outer_class_info_offset;
kamg@4245 475 int name_offset = InstanceKlass::inner_class_inner_name_offset;
kamg@4245 476 int next_offset = InstanceKlass::inner_class_next_offset;
kamg@4245 477
kamg@4245 478 if (klass->inner_classes() == NULL || klass->inner_classes()->length() == 0) {
kamg@4245 479 // No inner class info => no declaring class
kamg@4245 480 return 0;
kamg@4245 481 }
kamg@4245 482
kamg@4245 483 Array<u2>* i_icls = klass->inner_classes();
kamg@4245 484 ConstantPool* i_cp = klass->constants();
kamg@4245 485 int i_length = i_icls->length();
kamg@4245 486
kamg@4245 487 // Find inner_klass attribute
kamg@4245 488 for (int i = 0; i + next_offset < i_length; i += next_offset) {
kamg@4245 489 u2 ioff = i_icls->at(i + inner_index);
kamg@4245 490 u2 ooff = i_icls->at(i + outer_index);
kamg@4245 491 u2 noff = i_icls->at(i + name_offset);
kamg@4245 492 if (ioff != 0) {
kamg@4245 493 // Check to see if the name matches the class we're looking for
kamg@4245 494 // before attempting to find the class.
kamg@4245 495 if (i_cp->klass_name_at_matches(klass, ioff) && ooff != 0) {
kamg@4245 496 return ooff;
kamg@4245 497 }
kamg@4245 498 }
kamg@4245 499 }
kamg@4245 500
kamg@4245 501 // It may be anonymous; try for that.
kamg@4245 502 u2 encl_method_class_idx = klass->enclosing_method_class_index();
kamg@4245 503 if (encl_method_class_idx != 0) {
kamg@4245 504 return encl_method_class_idx;
kamg@4245 505 }
kamg@4245 506
kamg@4245 507 return 0;
kamg@4245 508 }
kamg@4245 509
kamg@4245 510 MethodDescriptor* MethodDescriptor::parse_generic_signature(Method* m, ClassDescriptor* outer) {
kamg@4245 511 Symbol* generic_sig = m->generic_signature();
kamg@4245 512 MethodDescriptor* md = NULL;
kamg@4245 513 if (generic_sig == NULL || (md = parse_generic_signature(generic_sig, outer)) == NULL) {
kamg@4245 514 md = parse_generic_signature(m->signature(), outer);
kamg@4245 515 }
kamg@4245 516 assert(md != NULL, "Could not parse method signature");
kamg@4245 517 md->bind_variables_to_parameters();
kamg@4245 518 return md;
kamg@4245 519 }
kamg@4245 520
kamg@4245 521 MethodDescriptor* MethodDescriptor::parse_generic_signature(Symbol* sym, ClassDescriptor* outer) {
kamg@4245 522
kamg@4245 523 DescriptorStream ds(sym);
kamg@4245 524 DescriptorStream* STREAM = &ds;
kamg@4245 525
kamg@4245 526 GrowableArray<TypeParameter*> params(8);
kamg@4245 527 char c = READ();
kamg@4245 528 if (c == '<') {
kamg@4245 529 c = READ();
kamg@4245 530 while (c != '>') {
kamg@4245 531 PUSH(c);
kamg@4245 532 TypeParameter* ftp = TypeParameter::parse_generic_signature(CHECK_STREAM);
kamg@4245 533 params.append(ftp);
kamg@4245 534 c = READ();
kamg@4245 535 }
kamg@4245 536 } else {
kamg@4245 537 PUSH(c);
kamg@4245 538 }
kamg@4245 539
kamg@4245 540 EXPECT('(');
kamg@4245 541
kamg@4245 542 GrowableArray<Type*> parameters(8);
kamg@4245 543 c = READ();
kamg@4245 544 while (c != ')') {
kamg@4245 545 PUSH(c);
kamg@4245 546 Type* arg = Type::parse_generic_signature(CHECK_STREAM);
kamg@4245 547 parameters.append(arg);
kamg@4245 548 c = READ();
kamg@4245 549 }
kamg@4245 550
kamg@4245 551 Type* rt = Type::parse_generic_signature(CHECK_STREAM);
kamg@4245 552
kamg@4245 553 GrowableArray<Type*> throws;
kamg@4245 554 while (!STREAM->at_end()) {
kamg@4245 555 EXPECT('^');
kamg@4245 556 Type* spec = Type::parse_generic_signature(CHECK_STREAM);
kamg@4245 557 throws.append(spec);
kamg@4245 558 }
kamg@4245 559
kamg@4245 560 return new MethodDescriptor(params, outer, parameters, rt, throws);
kamg@4245 561 }
kamg@4245 562
kamg@4245 563 void MethodDescriptor::bind_variables_to_parameters() {
kamg@4245 564 for (int i = 0; i < _type_parameters.length(); ++i) {
kamg@4245 565 _type_parameters.at(i)->bind_variables_to_parameters(this, i);
kamg@4245 566 }
kamg@4245 567 for (int i = 0; i < _parameters.length(); ++i) {
kamg@4245 568 _parameters.at(i)->bind_variables_to_parameters(this);
kamg@4245 569 }
kamg@4245 570 _return_type->bind_variables_to_parameters(this);
kamg@4245 571 for (int i = 0; i < _throws.length(); ++i) {
kamg@4245 572 _throws.at(i)->bind_variables_to_parameters(this);
kamg@4245 573 }
kamg@4245 574 }
kamg@4245 575
kamg@4245 576 bool MethodDescriptor::covariant_match(MethodDescriptor* other, Context* ctx) {
kamg@4245 577
kamg@4245 578 if (_parameters.length() == other->_parameters.length()) {
kamg@4245 579 for (int i = 0; i < _parameters.length(); ++i) {
kamg@4245 580 if (!_parameters.at(i)->covariant_match(other->_parameters.at(i), ctx)) {
kamg@4245 581 return false;
kamg@4245 582 }
kamg@4245 583 }
kamg@4245 584
kamg@4245 585 if (_return_type->as_primitive() != NULL) {
kamg@4245 586 return _return_type->covariant_match(other->_return_type, ctx);
kamg@4245 587 } else {
kamg@4245 588 // return type is a reference
kamg@4245 589 return other->_return_type->as_class() != NULL ||
kamg@4245 590 other->_return_type->as_variable() != NULL ||
kamg@4245 591 other->_return_type->as_array() != NULL;
kamg@4245 592 }
kamg@4245 593 } else {
kamg@4245 594 return false;
kamg@4245 595 }
kamg@4245 596 }
kamg@4245 597
kamg@4245 598 MethodDescriptor* MethodDescriptor::canonicalize(Context* ctx) {
kamg@4245 599
kamg@4245 600 GrowableArray<TypeParameter*> type_params(_type_parameters.length());
kamg@4245 601 for (int i = 0; i < _type_parameters.length(); ++i) {
kamg@4245 602 type_params.append(_type_parameters.at(i)->canonicalize(ctx, 0));
kamg@4245 603 }
kamg@4245 604
kamg@4245 605 ClassDescriptor* outer = _outer_class == NULL ? NULL :
kamg@4245 606 _outer_class->canonicalize(ctx);
kamg@4245 607
kamg@4245 608 GrowableArray<Type*> params(_parameters.length());
kamg@4245 609 for (int i = 0; i < _parameters.length(); ++i) {
kamg@4245 610 params.append(_parameters.at(i)->canonicalize(ctx, 0));
kamg@4245 611 }
kamg@4245 612
kamg@4245 613 Type* rt = _return_type->canonicalize(ctx, 0);
kamg@4245 614
kamg@4245 615 GrowableArray<Type*> throws(_throws.length());
kamg@4245 616 for (int i = 0; i < _throws.length(); ++i) {
kamg@4245 617 throws.append(_throws.at(i)->canonicalize(ctx, 0));
kamg@4245 618 }
kamg@4245 619
kamg@4245 620 return new MethodDescriptor(type_params, outer, params, rt, throws);
kamg@4245 621 }
kamg@4245 622
kamg@4245 623 #ifndef PRODUCT
kamg@4245 624 TempNewSymbol MethodDescriptor::reify_signature(Context* ctx, TRAPS) {
kamg@4245 625 stringStream ss(256);
kamg@4245 626
kamg@4245 627 ss.print("(");
kamg@4245 628 for (int i = 0; i < _parameters.length(); ++i) {
kamg@4245 629 _parameters.at(i)->reify_signature(&ss, ctx);
kamg@4245 630 }
kamg@4245 631 ss.print(")");
kamg@4245 632 _return_type->reify_signature(&ss, ctx);
kamg@4245 633 return SymbolTable::new_symbol(ss.base(), (int)ss.size(), THREAD);
kamg@4245 634 }
kamg@4245 635
kamg@4245 636 void MethodDescriptor::print_on(outputStream* str) const {
kamg@4245 637 str->indent().print_cr("MethodDescriptor {");
kamg@4245 638 {
kamg@4245 639 streamIndentor si(str);
kamg@4245 640 if (_type_parameters.length() > 0) {
kamg@4245 641 str->indent().print_cr("Formals: {");
kamg@4245 642 {
kamg@4245 643 streamIndentor si(str);
kamg@4245 644 for (int i = 0; i < _type_parameters.length(); ++i) {
kamg@4245 645 _type_parameters.at(i)->print_on(str);
kamg@4245 646 }
kamg@4245 647 }
kamg@4245 648 str->indent().print_cr("}");
kamg@4245 649 }
kamg@4245 650 str->indent().print_cr("Parameters: {");
kamg@4245 651 {
kamg@4245 652 streamIndentor si(str);
kamg@4245 653 for (int i = 0; i < _parameters.length(); ++i) {
kamg@4245 654 _parameters.at(i)->print_on(str);
kamg@4245 655 }
kamg@4245 656 }
kamg@4245 657 str->indent().print_cr("}");
kamg@4245 658 str->indent().print_cr("Return Type: ");
kamg@4245 659 {
kamg@4245 660 streamIndentor si(str);
kamg@4245 661 _return_type->print_on(str);
kamg@4245 662 }
kamg@4245 663
kamg@4245 664 if (_throws.length() > 0) {
kamg@4245 665 str->indent().print_cr("Throws: {");
kamg@4245 666 {
kamg@4245 667 streamIndentor si(str);
kamg@4245 668 for (int i = 0; i < _throws.length(); ++i) {
kamg@4245 669 _throws.at(i)->print_on(str);
kamg@4245 670 }
kamg@4245 671 }
kamg@4245 672 str->indent().print_cr("}");
kamg@4245 673 }
kamg@4245 674 }
kamg@4245 675 str->indent().print_cr("}");
kamg@4245 676 }
kamg@4245 677 #endif // ndef PRODUCT
kamg@4245 678
kamg@4245 679 TypeParameter* TypeParameter::parse_generic_signature(DescriptorStream* STREAM) {
kamg@4245 680 STREAM->set_mark();
kamg@4245 681 char c = READ();
kamg@4245 682 while (c != ':') {
kamg@4245 683 c = READ();
kamg@4245 684 }
kamg@4245 685
kamg@4245 686 Identifier* id = STREAM->identifier_from_mark();
kamg@4245 687
kamg@4245 688 ClassType* class_bound = NULL;
kamg@4245 689 GrowableArray<ClassType*> interface_bounds(8);
kamg@4245 690
kamg@4245 691 c = READ();
kamg@4245 692 if (c != '>') {
kamg@4245 693 if (c != ':') {
kamg@4245 694 EXPECTED(c, 'L');
kamg@4245 695 class_bound = ClassType::parse_generic_signature(CHECK_STREAM);
kamg@4245 696 c = READ();
kamg@4245 697 }
kamg@4245 698
kamg@4245 699 while (c == ':') {
kamg@4245 700 EXPECT('L');
kamg@4245 701 ClassType* fts = ClassType::parse_generic_signature(CHECK_STREAM);
kamg@4245 702 interface_bounds.append(fts);
kamg@4245 703 c = READ();
kamg@4245 704 }
kamg@4245 705 }
kamg@4245 706 PUSH(c);
kamg@4245 707
kamg@4245 708 return new TypeParameter(id, class_bound, interface_bounds);
kamg@4245 709 }
kamg@4245 710
kamg@4245 711 void TypeParameter::bind_variables_to_parameters(Descriptor* sig, int position) {
kamg@4245 712 if (_class_bound != NULL) {
kamg@4245 713 _class_bound->bind_variables_to_parameters(sig);
kamg@4245 714 }
kamg@4245 715 for (int i = 0; i < _interface_bounds.length(); ++i) {
kamg@4245 716 _interface_bounds.at(i)->bind_variables_to_parameters(sig);
kamg@4245 717 }
kamg@4245 718 _position = position;
kamg@4245 719 }
kamg@4245 720
kamg@4245 721 Type* TypeParameter::resolve(
kamg@4245 722 Context* ctx, int inner_depth, int ctx_depth) {
kamg@4245 723
kamg@4245 724 if (inner_depth == -1) {
kamg@4245 725 // This indicates that the parameter is a method type parameter, which
kamg@4245 726 // isn't resolveable using the class hierarchy context
kamg@4245 727 return bound();
kamg@4245 728 }
kamg@4245 729
kamg@4245 730 ClassType* provider = ctx->at_depth(ctx_depth);
kamg@4245 731 if (provider != NULL) {
kamg@4245 732 for (int i = 0; i < inner_depth && provider != NULL; ++i) {
kamg@4245 733 provider = provider->outer_class();
kamg@4245 734 }
kamg@4245 735 if (provider != NULL) {
kamg@4245 736 TypeArgument* arg = provider->type_argument_at(_position);
kamg@4245 737 if (arg != NULL) {
kamg@4245 738 Type* value = arg->lower_bound();
kamg@4245 739 return value->canonicalize(ctx, ctx_depth + 1);
kamg@4245 740 }
kamg@4245 741 }
kamg@4245 742 }
kamg@4245 743
kamg@4245 744 return bound();
kamg@4245 745 }
kamg@4245 746
kamg@4245 747 TypeParameter* TypeParameter::canonicalize(Context* ctx, int ctx_depth) {
kamg@4245 748 ClassType* bound = _class_bound == NULL ? NULL :
kamg@4245 749 _class_bound->canonicalize(ctx, ctx_depth);
kamg@4245 750
kamg@4245 751 GrowableArray<ClassType*> ifaces(_interface_bounds.length());
kamg@4245 752 for (int i = 0; i < _interface_bounds.length(); ++i) {
kamg@4245 753 ifaces.append(_interface_bounds.at(i)->canonicalize(ctx, ctx_depth));
kamg@4245 754 }
kamg@4245 755
kamg@4245 756 TypeParameter* ret = new TypeParameter(_identifier, bound, ifaces);
kamg@4245 757 ret->_position = _position;
kamg@4245 758 return ret;
kamg@4245 759 }
kamg@4245 760
kamg@4245 761 ClassType* TypeParameter::bound() {
kamg@4245 762 if (_class_bound != NULL) {
kamg@4245 763 return _class_bound;
kamg@4245 764 }
kamg@4245 765
kamg@4245 766 if (_interface_bounds.length() == 1) {
kamg@4245 767 return _interface_bounds.at(0);
kamg@4245 768 }
kamg@4245 769
kamg@4245 770 return ClassType::java_lang_Object(); // TODO: investigate this case
kamg@4245 771 }
kamg@4245 772
kamg@4245 773 #ifndef PRODUCT
kamg@4245 774 void TypeParameter::print_on(outputStream* str) const {
kamg@4245 775 str->indent().print_cr("Formal: {");
kamg@4245 776 {
kamg@4245 777 streamIndentor si(str);
kamg@4245 778
kamg@4245 779 str->indent().print("Identifier: ");
kamg@4245 780 _identifier->print_on(str);
kamg@4245 781 str->print_cr("");
kamg@4245 782 if (_class_bound != NULL) {
kamg@4245 783 str->indent().print_cr("Class Bound: ");
kamg@4245 784 streamIndentor si(str);
kamg@4245 785 _class_bound->print_on(str);
kamg@4245 786 }
kamg@4245 787 if (_interface_bounds.length() > 0) {
kamg@4245 788 str->indent().print_cr("Interface Bounds: {");
kamg@4245 789 {
kamg@4245 790 streamIndentor si(str);
kamg@4245 791 for (int i = 0; i < _interface_bounds.length(); ++i) {
kamg@4245 792 _interface_bounds.at(i)->print_on(str);
kamg@4245 793 }
kamg@4245 794 }
kamg@4245 795 str->indent().print_cr("}");
kamg@4245 796 }
kamg@4245 797 str->indent().print_cr("Ordinal Position: %d", _position);
kamg@4245 798 }
kamg@4245 799 str->indent().print_cr("}");
kamg@4245 800 }
kamg@4245 801 #endif // ndef PRODUCT
kamg@4245 802
kamg@4245 803 Type* Type::parse_generic_signature(DescriptorStream* STREAM) {
kamg@4245 804 char c = READ();
kamg@4245 805 switch (c) {
kamg@4245 806 case 'L':
kamg@4245 807 return ClassType::parse_generic_signature(CHECK_STREAM);
kamg@4245 808 case 'T':
kamg@4245 809 return TypeVariable::parse_generic_signature(CHECK_STREAM);
kamg@4245 810 case '[':
kamg@4245 811 return ArrayType::parse_generic_signature(CHECK_STREAM);
kamg@4245 812 default:
kamg@4245 813 return new PrimitiveType(c);
kamg@4245 814 }
kamg@4245 815 }
kamg@4245 816
kamg@4245 817 Identifier* ClassType::parse_generic_signature_simple(GrowableArray<TypeArgument*>* args,
kamg@4245 818 bool* has_inner, DescriptorStream* STREAM) {
kamg@4245 819 STREAM->set_mark();
kamg@4245 820
kamg@4245 821 char c = READ();
kamg@4245 822 while (c != ';' && c != '.' && c != '<') { c = READ(); }
kamg@4245 823 Identifier* id = STREAM->identifier_from_mark();
kamg@4245 824
kamg@4245 825 if (c == '<') {
kamg@4245 826 c = READ();
kamg@4245 827 while (c != '>') {
kamg@4245 828 PUSH(c);
kamg@4245 829 TypeArgument* arg = TypeArgument::parse_generic_signature(CHECK_STREAM);
kamg@4245 830 args->append(arg);
kamg@4245 831 c = READ();
kamg@4245 832 }
kamg@4245 833 c = READ();
kamg@4245 834 }
kamg@4245 835
kamg@4245 836 *has_inner = (c == '.');
kamg@4245 837 if (!(*has_inner)) {
kamg@4245 838 EXPECTED(c, ';');
kamg@4245 839 }
kamg@4245 840
kamg@4245 841 return id;
kamg@4245 842 }
kamg@4245 843
kamg@4245 844 ClassType* ClassType::parse_generic_signature(DescriptorStream* STREAM) {
kamg@4245 845 return parse_generic_signature(NULL, CHECK_STREAM);
kamg@4245 846 }
kamg@4245 847
kamg@4245 848 ClassType* ClassType::parse_generic_signature(ClassType* outer, DescriptorStream* STREAM) {
kamg@4245 849 GrowableArray<TypeArgument*> args;
kamg@4245 850 ClassType* gct = NULL;
kamg@4245 851 bool has_inner = false;
kamg@4245 852
kamg@4245 853 Identifier* id = parse_generic_signature_simple(&args, &has_inner, STREAM);
kamg@4245 854 if (id != NULL) {
kamg@4245 855 gct = new ClassType(id, args, outer);
kamg@4245 856
kamg@4245 857 if (has_inner) {
kamg@4245 858 gct = parse_generic_signature(gct, CHECK_STREAM);
kamg@4245 859 }
kamg@4245 860 }
kamg@4245 861 return gct;
kamg@4245 862 }
kamg@4245 863
kamg@4245 864 ClassType* ClassType::from_symbol(Symbol* sym) {
kamg@4245 865 assert(sym != NULL, "Must not be null");
kamg@4245 866 GrowableArray<TypeArgument*> args;
kamg@4245 867 Identifier* id = new Identifier(sym, 0, sym->utf8_length());
kamg@4245 868 return new ClassType(id, args, NULL);
kamg@4245 869 }
kamg@4245 870
kamg@4245 871 ClassType* ClassType::java_lang_Object() {
kamg@4245 872 return from_symbol(vmSymbols::java_lang_Object());
kamg@4245 873 }
kamg@4245 874
kamg@4245 875 void ClassType::bind_variables_to_parameters(Descriptor* sig) {
kamg@4245 876 for (int i = 0; i < _type_arguments.length(); ++i) {
kamg@4245 877 _type_arguments.at(i)->bind_variables_to_parameters(sig);
kamg@4245 878 }
kamg@4245 879 if (_outer_class != NULL) {
kamg@4245 880 _outer_class->bind_variables_to_parameters(sig);
kamg@4245 881 }
kamg@4245 882 }
kamg@4245 883
kamg@4245 884 TypeArgument* ClassType::type_argument_at(int i) {
kamg@4245 885 if (i >= 0 && i < _type_arguments.length()) {
kamg@4245 886 return _type_arguments.at(i);
kamg@4245 887 } else {
kamg@4245 888 return NULL;
kamg@4245 889 }
kamg@4245 890 }
kamg@4245 891
kamg@4245 892 #ifndef PRODUCT
kamg@4245 893 void ClassType::reify_signature(stringStream* ss, Context* ctx) {
kamg@4245 894 ss->print("L");
kamg@4245 895 _identifier->print_on(ss);
kamg@4245 896 ss->print(";");
kamg@4245 897 }
kamg@4245 898
kamg@4245 899 void ClassType::print_on(outputStream* str) const {
kamg@4245 900 str->indent().print_cr("Class {");
kamg@4245 901 {
kamg@4245 902 streamIndentor si(str);
kamg@4245 903 str->indent().print("Name: ");
kamg@4245 904 _identifier->print_on(str);
kamg@4245 905 str->print_cr("");
kamg@4245 906 if (_type_arguments.length() != 0) {
kamg@4245 907 str->indent().print_cr("Type Arguments: {");
kamg@4245 908 {
kamg@4245 909 streamIndentor si(str);
kamg@4245 910 for (int j = 0; j < _type_arguments.length(); ++j) {
kamg@4245 911 _type_arguments.at(j)->print_on(str);
kamg@4245 912 }
kamg@4245 913 }
kamg@4245 914 str->indent().print_cr("}");
kamg@4245 915 }
kamg@4245 916 if (_outer_class != NULL) {
kamg@4245 917 str->indent().print_cr("Outer Class: ");
kamg@4245 918 streamIndentor sir(str);
kamg@4245 919 _outer_class->print_on(str);
kamg@4245 920 }
kamg@4245 921 }
kamg@4245 922 str->indent().print_cr("}");
kamg@4245 923 }
kamg@4245 924 #endif // ndef PRODUCT
kamg@4245 925
kamg@4245 926 bool ClassType::covariant_match(Type* other, Context* ctx) {
kamg@4245 927
kamg@4245 928 if (other == this) {
kamg@4245 929 return true;
kamg@4245 930 }
kamg@4245 931
kamg@4245 932 TypeVariable* variable = other->as_variable();
kamg@4245 933 if (variable != NULL) {
kamg@4245 934 other = variable->resolve(ctx, 0);
kamg@4245 935 }
kamg@4245 936
kamg@4245 937 ClassType* outer = outer_class();
kamg@4245 938 ClassType* other_class = other->as_class();
kamg@4245 939
kamg@4245 940 if (other_class == NULL ||
kamg@4245 941 (outer == NULL) != (other_class->outer_class() == NULL)) {
kamg@4245 942 return false;
kamg@4245 943 }
kamg@4245 944
kamg@4245 945 if (!_identifier->equals(other_class->_identifier)) {
kamg@4245 946 return false;
kamg@4245 947 }
kamg@4245 948
kamg@4245 949 if (outer != NULL && !outer->covariant_match(other_class->outer_class(), ctx)) {
kamg@4245 950 return false;
kamg@4245 951 }
kamg@4245 952
kamg@4245 953 return true;
kamg@4245 954 }
kamg@4245 955
kamg@4245 956 ClassType* ClassType::canonicalize(Context* ctx, int ctx_depth) {
kamg@4245 957
kamg@4245 958 GrowableArray<TypeArgument*> args(_type_arguments.length());
kamg@4245 959 for (int i = 0; i < _type_arguments.length(); ++i) {
kamg@4245 960 args.append(_type_arguments.at(i)->canonicalize(ctx, ctx_depth));
kamg@4245 961 }
kamg@4245 962
kamg@4245 963 ClassType* outer = _outer_class == NULL ? NULL :
kamg@4245 964 _outer_class->canonicalize(ctx, ctx_depth);
kamg@4245 965
kamg@4245 966 return new ClassType(_identifier, args, outer);
kamg@4245 967 }
kamg@4245 968
kamg@4245 969 TypeVariable* TypeVariable::parse_generic_signature(DescriptorStream* STREAM) {
kamg@4245 970 STREAM->set_mark();
kamg@4245 971 char c = READ();
kamg@4245 972 while (c != ';') {
kamg@4245 973 c = READ();
kamg@4245 974 }
kamg@4245 975 Identifier* id = STREAM->identifier_from_mark();
kamg@4245 976
kamg@4245 977 return new TypeVariable(id);
kamg@4245 978 }
kamg@4245 979
kamg@4245 980 void TypeVariable::bind_variables_to_parameters(Descriptor* sig) {
kamg@4245 981 _parameter = sig->find_type_parameter(_id, &_inner_depth);
kamg@4245 982 if (VerifyGenericSignatures && _parameter == NULL) {
kamg@4245 983 fatal("Could not find formal parameter");
kamg@4245 984 }
kamg@4245 985 }
kamg@4245 986
kamg@4245 987 Type* TypeVariable::resolve(Context* ctx, int ctx_depth) {
kamg@4245 988 if (parameter() != NULL) {
kamg@4245 989 return parameter()->resolve(ctx, inner_depth(), ctx_depth);
kamg@4245 990 } else {
kamg@4245 991 if (VerifyGenericSignatures) {
kamg@4245 992 fatal("Type variable matches no parameter");
kamg@4245 993 }
kamg@4245 994 return NULL;
kamg@4245 995 }
kamg@4245 996 }
kamg@4245 997
kamg@4245 998 bool TypeVariable::covariant_match(Type* other, Context* ctx) {
kamg@4245 999
kamg@4245 1000 if (other == this) {
kamg@4245 1001 return true;
kamg@4245 1002 }
kamg@4245 1003
kamg@4245 1004 Context my_context(NULL); // empty, results in erasure
kamg@4245 1005 Type* my_type = resolve(&my_context, 0);
kamg@4245 1006 if (my_type == NULL) {
kamg@4245 1007 return false;
kamg@4245 1008 }
kamg@4245 1009
kamg@4245 1010 return my_type->covariant_match(other, ctx);
kamg@4245 1011 }
kamg@4245 1012
kamg@4245 1013 Type* TypeVariable::canonicalize(Context* ctx, int ctx_depth) {
kamg@4245 1014 return resolve(ctx, ctx_depth);
kamg@4245 1015 }
kamg@4245 1016
kamg@4245 1017 #ifndef PRODUCT
kamg@4245 1018 void TypeVariable::reify_signature(stringStream* ss, Context* ctx) {
kamg@4245 1019 Type* type = resolve(ctx, 0);
kamg@4245 1020 if (type != NULL) {
kamg@4245 1021 type->reify_signature(ss, ctx);
kamg@4245 1022 }
kamg@4245 1023 }
kamg@4245 1024
kamg@4245 1025 void TypeVariable::print_on(outputStream* str) const {
kamg@4245 1026 str->indent().print_cr("Type Variable {");
kamg@4245 1027 {
kamg@4245 1028 streamIndentor si(str);
kamg@4245 1029 str->indent().print("Name: ");
kamg@4245 1030 _id->print_on(str);
kamg@4245 1031 str->print_cr("");
kamg@4245 1032 str->indent().print_cr("Inner depth: %d", _inner_depth);
kamg@4245 1033 }
kamg@4245 1034 str->indent().print_cr("}");
kamg@4245 1035 }
kamg@4245 1036 #endif // ndef PRODUCT
kamg@4245 1037
kamg@4245 1038 ArrayType* ArrayType::parse_generic_signature(DescriptorStream* STREAM) {
kamg@4245 1039 Type* base = Type::parse_generic_signature(CHECK_STREAM);
kamg@4245 1040 return new ArrayType(base);
kamg@4245 1041 }
kamg@4245 1042
kamg@4245 1043 void ArrayType::bind_variables_to_parameters(Descriptor* sig) {
kamg@4245 1044 assert(_base != NULL, "Invalid base");
kamg@4245 1045 _base->bind_variables_to_parameters(sig);
kamg@4245 1046 }
kamg@4245 1047
kamg@4245 1048 bool ArrayType::covariant_match(Type* other, Context* ctx) {
kamg@4245 1049 assert(_base != NULL, "Invalid base");
kamg@4245 1050
kamg@4245 1051 if (other == this) {
kamg@4245 1052 return true;
kamg@4245 1053 }
kamg@4245 1054
kamg@4245 1055 ArrayType* other_array = other->as_array();
kamg@4245 1056 return (other_array != NULL && _base->covariant_match(other_array->_base, ctx));
kamg@4245 1057 }
kamg@4245 1058
kamg@4245 1059 ArrayType* ArrayType::canonicalize(Context* ctx, int ctx_depth) {
kamg@4245 1060 assert(_base != NULL, "Invalid base");
kamg@4245 1061 return new ArrayType(_base->canonicalize(ctx, ctx_depth));
kamg@4245 1062 }
kamg@4245 1063
kamg@4245 1064 #ifndef PRODUCT
kamg@4245 1065 void ArrayType::reify_signature(stringStream* ss, Context* ctx) {
kamg@4245 1066 assert(_base != NULL, "Invalid base");
kamg@4245 1067 ss->print("[");
kamg@4245 1068 _base->reify_signature(ss, ctx);
kamg@4245 1069 }
kamg@4245 1070
kamg@4245 1071 void ArrayType::print_on(outputStream* str) const {
kamg@4245 1072 str->indent().print_cr("Array {");
kamg@4245 1073 {
kamg@4245 1074 streamIndentor si(str);
kamg@4245 1075 _base->print_on(str);
kamg@4245 1076 }
kamg@4245 1077 str->indent().print_cr("}");
kamg@4245 1078 }
kamg@4245 1079 #endif // ndef PRODUCT
kamg@4245 1080
kamg@4245 1081 bool PrimitiveType::covariant_match(Type* other, Context* ctx) {
kamg@4245 1082
kamg@4245 1083 PrimitiveType* other_prim = other->as_primitive();
kamg@4245 1084 return (other_prim != NULL && _type == other_prim->_type);
kamg@4245 1085 }
kamg@4245 1086
kamg@4245 1087 PrimitiveType* PrimitiveType::canonicalize(Context* ctx, int ctxd) {
kamg@4245 1088 return this;
kamg@4245 1089 }
kamg@4245 1090
kamg@4245 1091 #ifndef PRODUCT
kamg@4245 1092 void PrimitiveType::reify_signature(stringStream* ss, Context* ctx) {
kamg@4245 1093 ss->print("%c", _type);
kamg@4245 1094 }
kamg@4245 1095
kamg@4245 1096 void PrimitiveType::print_on(outputStream* str) const {
kamg@4245 1097 str->indent().print_cr("Primitive: '%c'", _type);
kamg@4245 1098 }
kamg@4245 1099 #endif // ndef PRODUCT
kamg@4245 1100
kamg@4245 1101 void PrimitiveType::bind_variables_to_parameters(Descriptor* sig) {
kamg@4245 1102 }
kamg@4245 1103
kamg@4245 1104 TypeArgument* TypeArgument::parse_generic_signature(DescriptorStream* STREAM) {
kamg@4245 1105 char c = READ();
kamg@4245 1106 Type* type = NULL;
kamg@4245 1107
kamg@4245 1108 switch (c) {
kamg@4245 1109 case '*':
kamg@4245 1110 return new TypeArgument(ClassType::java_lang_Object(), NULL);
kamg@4245 1111 break;
kamg@4245 1112 default:
kamg@4245 1113 PUSH(c);
kamg@4245 1114 // fall-through
kamg@4245 1115 case '+':
kamg@4245 1116 case '-':
kamg@4245 1117 type = Type::parse_generic_signature(CHECK_STREAM);
kamg@4245 1118 if (c == '+') {
kamg@4245 1119 return new TypeArgument(type, NULL);
kamg@4245 1120 } else if (c == '-') {
kamg@4245 1121 return new TypeArgument(ClassType::java_lang_Object(), type);
kamg@4245 1122 } else {
kamg@4245 1123 return new TypeArgument(type, type);
kamg@4245 1124 }
kamg@4245 1125 }
kamg@4245 1126 }
kamg@4245 1127
kamg@4245 1128 void TypeArgument::bind_variables_to_parameters(Descriptor* sig) {
kamg@4245 1129 assert(_lower_bound != NULL, "Invalid lower bound");
kamg@4245 1130 _lower_bound->bind_variables_to_parameters(sig);
kamg@4245 1131 if (_upper_bound != NULL && _upper_bound != _lower_bound) {
kamg@4245 1132 _upper_bound->bind_variables_to_parameters(sig);
kamg@4245 1133 }
kamg@4245 1134 }
kamg@4245 1135
kamg@4245 1136 bool TypeArgument::covariant_match(TypeArgument* other, Context* ctx) {
kamg@4245 1137 assert(_lower_bound != NULL, "Invalid lower bound");
kamg@4245 1138
kamg@4245 1139 if (other == this) {
kamg@4245 1140 return true;
kamg@4245 1141 }
kamg@4245 1142
kamg@4245 1143 if (!_lower_bound->covariant_match(other->lower_bound(), ctx)) {
kamg@4245 1144 return false;
kamg@4245 1145 }
kamg@4245 1146 return true;
kamg@4245 1147 }
kamg@4245 1148
kamg@4245 1149 TypeArgument* TypeArgument::canonicalize(Context* ctx, int ctx_depth) {
kamg@4245 1150 assert(_lower_bound != NULL, "Invalid lower bound");
kamg@4245 1151 Type* lower = _lower_bound->canonicalize(ctx, ctx_depth);
kamg@4245 1152 Type* upper = NULL;
kamg@4245 1153
kamg@4245 1154 if (_upper_bound == _lower_bound) {
kamg@4245 1155 upper = lower;
kamg@4245 1156 } else if (_upper_bound != NULL) {
kamg@4245 1157 upper = _upper_bound->canonicalize(ctx, ctx_depth);
kamg@4245 1158 }
kamg@4245 1159
kamg@4245 1160 return new TypeArgument(lower, upper);
kamg@4245 1161 }
kamg@4245 1162
kamg@4245 1163 #ifndef PRODUCT
kamg@4245 1164 void TypeArgument::print_on(outputStream* str) const {
kamg@4245 1165 str->indent().print_cr("TypeArgument {");
kamg@4245 1166 {
kamg@4245 1167 streamIndentor si(str);
kamg@4245 1168 if (_lower_bound != NULL) {
kamg@4245 1169 str->indent().print("Lower bound: ");
kamg@4245 1170 _lower_bound->print_on(str);
kamg@4245 1171 }
kamg@4245 1172 if (_upper_bound != NULL) {
kamg@4245 1173 str->indent().print("Upper bound: ");
kamg@4245 1174 _upper_bound->print_on(str);
kamg@4245 1175 }
kamg@4245 1176 }
kamg@4245 1177 str->indent().print_cr("}");
kamg@4245 1178 }
kamg@4245 1179 #endif // ndef PRODUCT
kamg@4245 1180
kamg@4245 1181 void Context::Mark::destroy() {
kamg@4245 1182 if (is_active()) {
kamg@4245 1183 _context->reset_to_mark(_marked_size);
kamg@4245 1184 }
kamg@4245 1185 deactivate();
kamg@4245 1186 }
kamg@4245 1187
kamg@4245 1188 void Context::apply_type_arguments(
kamg@4245 1189 InstanceKlass* current, InstanceKlass* super, TRAPS) {
kamg@4245 1190 assert(_cache != NULL, "Cannot use an empty context");
kamg@4245 1191 ClassType* spec = NULL;
kamg@4245 1192 if (current != NULL) {
kamg@4245 1193 ClassDescriptor* descriptor = _cache->descriptor_for(current, CHECK);
kamg@4245 1194 if (super == current->super()) {
kamg@4245 1195 spec = descriptor->super();
kamg@4245 1196 } else {
kamg@4245 1197 spec = descriptor->interface_desc(super->name());
kamg@4245 1198 }
kamg@4245 1199 if (spec != NULL) {
kamg@4245 1200 _type_arguments.push(spec);
kamg@4245 1201 }
kamg@4245 1202 }
kamg@4245 1203 }
kamg@4245 1204
kamg@4245 1205 void Context::reset_to_mark(int size) {
kamg@4245 1206 _type_arguments.trunc_to(size);
kamg@4245 1207 }
kamg@4245 1208
kamg@4245 1209 ClassType* Context::at_depth(int i) const {
kamg@4245 1210 if (i < _type_arguments.length()) {
kamg@4245 1211 return _type_arguments.at(_type_arguments.length() - 1 - i);
kamg@4245 1212 }
kamg@4245 1213 return NULL;
kamg@4245 1214 }
kamg@4245 1215
kamg@4245 1216 #ifndef PRODUCT
kamg@4245 1217 void Context::print_on(outputStream* str) const {
kamg@4245 1218 str->indent().print_cr("Context {");
kamg@4245 1219 for (int i = 0; i < _type_arguments.length(); ++i) {
kamg@4245 1220 streamIndentor si(str);
kamg@4245 1221 str->indent().print("leval %d: ", i);
kamg@4245 1222 ClassType* ct = at_depth(i);
kamg@4245 1223 if (ct == NULL) {
kamg@4245 1224 str->print_cr("<empty>");
kamg@4245 1225 continue;
kamg@4245 1226 } else {
kamg@4245 1227 str->print_cr("{");
kamg@4245 1228 }
kamg@4245 1229
kamg@4245 1230 for (int j = 0; j < ct->type_arguments_length(); ++j) {
kamg@4245 1231 streamIndentor si(str);
kamg@4245 1232 TypeArgument* ta = ct->type_argument_at(j);
kamg@4245 1233 Type* bound = ta->lower_bound();
kamg@4245 1234 bound->print_on(str);
kamg@4245 1235 }
kamg@4245 1236 str->indent().print_cr("}");
kamg@4245 1237 }
kamg@4245 1238 str->indent().print_cr("}");
kamg@4245 1239 }
kamg@4245 1240 #endif // ndef PRODUCT
kamg@4245 1241
kamg@4245 1242 ClassDescriptor* DescriptorCache::descriptor_for(InstanceKlass* ik, TRAPS) {
kamg@4245 1243
kamg@4245 1244 ClassDescriptor** existing = _class_descriptors.get(ik);
kamg@4245 1245 if (existing == NULL) {
kamg@4245 1246 ClassDescriptor* cd = ClassDescriptor::parse_generic_signature(ik, CHECK_NULL);
kamg@4245 1247 _class_descriptors.put(ik, cd);
kamg@4245 1248 return cd;
kamg@4245 1249 } else {
kamg@4245 1250 return *existing;
kamg@4245 1251 }
kamg@4245 1252 }
kamg@4245 1253
kamg@4245 1254 MethodDescriptor* DescriptorCache::descriptor_for(
kamg@4245 1255 Method* mh, ClassDescriptor* cd, TRAPS) {
kamg@4245 1256 assert(mh != NULL && cd != NULL, "Should not be NULL");
kamg@4245 1257 MethodDescriptor** existing = _method_descriptors.get(mh);
kamg@4245 1258 if (existing == NULL) {
kamg@4245 1259 MethodDescriptor* md = MethodDescriptor::parse_generic_signature(mh, cd);
kamg@4245 1260 _method_descriptors.put(mh, md);
kamg@4245 1261 return md;
kamg@4245 1262 } else {
kamg@4245 1263 return *existing;
kamg@4245 1264 }
kamg@4245 1265 }
kamg@4245 1266 MethodDescriptor* DescriptorCache::descriptor_for(Method* mh, TRAPS) {
kamg@4245 1267 ClassDescriptor* cd = descriptor_for(
kamg@4245 1268 InstanceKlass::cast(mh->method_holder()), CHECK_NULL);
kamg@4245 1269 return descriptor_for(mh, cd, THREAD);
kamg@4245 1270 }
kamg@4245 1271
kamg@4245 1272 } // namespace generic

mercurial