src/share/vm/classfile/genericSignatures.cpp

Tue, 18 Jun 2013 12:31:07 -0700

author
johnc
date
Tue, 18 Jun 2013 12:31:07 -0700
changeset 5277
01522ca68fc7
parent 4960
41ed397cc0cd
child 5259
ef57c43512d6
permissions
-rw-r--r--

8015237: Parallelize string table scanning during strong root processing
Summary: Parallelize the scanning of the intern string table by having each GC worker claim a given number of buckets. Changes were also reviewed by Per Liden <per.liden@oracle.com>.
Reviewed-by: tschatzl, stefank, twisti

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

mercurial