# HG changeset patch # User acorn # Date 1377591682 25200 # Node ID d80493ee6430945b6270525e7c825817bd8c18b9 # Parent a7d8baf4cca7b17eaf7cc09cbc0994a4ba035a81# Parent 91b93f523ec6396fc68d04059e73749ea242b8ab Merge diff -r a7d8baf4cca7 -r d80493ee6430 src/share/vm/classfile/classFileParser.cpp --- a/src/share/vm/classfile/classFileParser.cpp Mon Aug 26 18:34:29 2013 -0700 +++ b/src/share/vm/classfile/classFileParser.cpp Tue Aug 27 01:21:22 2013 -0700 @@ -28,7 +28,6 @@ #include "classfile/classLoaderData.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/defaultMethods.hpp" -#include "classfile/genericSignatures.hpp" #include "classfile/javaClasses.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" @@ -3039,35 +3038,6 @@ return annotations; } - -#ifdef ASSERT -static void parseAndPrintGenericSignatures( - instanceKlassHandle this_klass, TRAPS) { - assert(ParseAllGenericSignatures == true, "Shouldn't call otherwise"); - ResourceMark rm; - - if (this_klass->generic_signature() != NULL) { - using namespace generic; - ClassDescriptor* spec = ClassDescriptor::parse_generic_signature(this_klass(), CHECK); - - tty->print_cr("Parsing %s", this_klass->generic_signature()->as_C_string()); - spec->print_on(tty); - - for (int i = 0; i < this_klass->methods()->length(); ++i) { - Method* m = this_klass->methods()->at(i); - MethodDescriptor* method_spec = MethodDescriptor::parse_generic_signature(m, spec); - Symbol* sig = m->generic_signature(); - if (sig == NULL) { - sig = m->signature(); - } - tty->print_cr("Parsing %s", sig->as_C_string()); - method_spec->print_on(tty); - } - } -} -#endif // def ASSERT - - instanceKlassHandle ClassFileParser::parse_super_class(int super_class_index, TRAPS) { instanceKlassHandle super_klass; @@ -4060,12 +4030,6 @@ java_lang_Class::create_mirror(this_klass, protection_domain, CHECK_(nullHandle)); -#ifdef ASSERT - if (ParseAllGenericSignatures) { - parseAndPrintGenericSignatures(this_klass, CHECK_(nullHandle)); - } -#endif - // Generate any default methods - default methods are interface methods // that have a default implementation. This is new with Lambda project. if (has_default_methods && !access_flags.is_interface() && diff -r a7d8baf4cca7 -r d80493ee6430 src/share/vm/classfile/defaultMethods.cpp --- a/src/share/vm/classfile/defaultMethods.cpp Mon Aug 26 18:34:29 2013 -0700 +++ b/src/share/vm/classfile/defaultMethods.cpp Tue Aug 27 01:21:22 2013 -0700 @@ -25,7 +25,6 @@ #include "precompiled.hpp" #include "classfile/bytecodeAssembler.hpp" #include "classfile/defaultMethods.hpp" -#include "classfile/genericSignatures.hpp" #include "classfile/symbolTable.hpp" #include "memory/allocation.hpp" #include "memory/metadataFactory.hpp" @@ -75,14 +74,6 @@ } }; -class ContextMark : public PseudoScopeMark { - private: - generic::Context::Mark _mark; - public: - ContextMark(const generic::Context::Mark& cm) : _mark(cm) {} - virtual void destroy() { _mark.destroy(); } -}; - #ifndef PRODUCT static void print_slot(outputStream* str, Symbol* name, Symbol* signature) { ResourceMark rm; @@ -503,38 +494,6 @@ return SymbolTable::new_symbol(ss.base(), (int)ss.size(), CHECK_NULL); } -// A generic method family contains a set of all methods that implement a single -// language-level method. Because of erasure, these methods may have different -// signatures. As members of the set are collected while walking over the -// hierarchy, they are tagged with a qualification state. The qualification -// state for an erased method is set to disqualified if there exists a path -// from the root of hierarchy to the method that contains an interleaving -// language-equivalent method defined in an interface. -class GenericMethodFamily : public MethodFamily { - private: - - generic::MethodDescriptor* _descriptor; // language-level description - - public: - - GenericMethodFamily(generic::MethodDescriptor* canonical_desc) - : _descriptor(canonical_desc) {} - - generic::MethodDescriptor* descriptor() const { return _descriptor; } - - bool descriptor_matches(generic::MethodDescriptor* md, generic::Context* ctx) { - return descriptor()->covariant_match(md, ctx); - } - -#ifndef PRODUCT - Symbol* get_generic_sig() const { - - generic::Context ctx(NULL); // empty, as _descriptor already canonicalized - TempNewSymbol sig = descriptor()->reify_signature(&ctx, Thread::current()); - return sig; - } -#endif // ndef PRODUCT -}; class StateRestorer; @@ -571,26 +530,6 @@ StateRestorer* record_method_and_dq_further(Method* mo); }; - -// StatefulGenericMethodFamily is a wrapper around GenericMethodFamily that maintains the -// qualification state during hierarchy visitation, and applies that state -// when adding members to the GenericMethodFamily. -class StatefulGenericMethodFamily : public StatefulMethodFamily { - - public: - StatefulGenericMethodFamily(generic::MethodDescriptor* md, generic::Context* ctx) - : StatefulMethodFamily(new GenericMethodFamily(md->canonicalize(ctx))) { - - } - GenericMethodFamily* get_method_family() { - return (GenericMethodFamily*)_method_family; - } - - bool descriptor_matches(generic::MethodDescriptor* md, generic::Context* ctx) { - return get_method_family()->descriptor_matches(md, ctx); - } -}; - class StateRestorer : public PseudoScopeMark { private: StatefulMethodFamily* _method; @@ -616,39 +555,6 @@ return mark; } -class StatefulGenericMethodFamilies : public ResourceObj { - private: - GrowableArray _methods; - - public: - StatefulGenericMethodFamily* find_matching( - generic::MethodDescriptor* md, generic::Context* ctx) { - for (int i = 0; i < _methods.length(); ++i) { - StatefulGenericMethodFamily* existing = _methods.at(i); - if (existing->descriptor_matches(md, ctx)) { - return existing; - } - } - return NULL; - } - - StatefulGenericMethodFamily* find_matching_or_create( - generic::MethodDescriptor* md, generic::Context* ctx) { - StatefulGenericMethodFamily* method = find_matching(md, ctx); - if (method == NULL) { - method = new StatefulGenericMethodFamily(md, ctx); - _methods.append(method); - } - return method; - } - - void extract_families_into(GrowableArray* array) { - for (int i = 0; i < _methods.length(); ++i) { - array->append(_methods.at(i)->get_method_family()); - } - } -}; - // Represents a location corresponding to a vtable slot for methods that // neither the class nor any of it's ancestors provide an implementaion. // Default methods may be present to fill this slot. @@ -779,146 +685,11 @@ }; -// Iterates over the type hierarchy looking for all methods with a specific -// method name. The result of this is a set of method families each of -// which is populated with a set of methods that implement the same -// language-level signature. -class FindMethodsByGenericSig : public HierarchyVisitor { - private: - // Context data - Thread* THREAD; - generic::DescriptorCache* _cache; - Symbol* _method_name; - generic::Context* _ctx; - StatefulGenericMethodFamilies _families; - public: - - FindMethodsByGenericSig(generic::DescriptorCache* cache, Symbol* name, - generic::Context* ctx, Thread* thread) : - _cache(cache), _method_name(name), _ctx(ctx), THREAD(thread) {} - - void get_discovered_families(GrowableArray* methods) { - _families.extract_families_into(methods); - } - - void* new_node_data(InstanceKlass* cls) { return new PseudoScope(); } - void free_node_data(void* node_data) { - PseudoScope::cast(node_data)->destroy(); - } - - bool visit() { - PseudoScope* scope = PseudoScope::cast(current_data()); - InstanceKlass* klass = current_class(); - InstanceKlass* sub = current_depth() > 0 ? class_at_depth(1) : NULL; - - ContextMark* cm = new ContextMark(_ctx->mark()); - scope->add_mark(cm); // will restore context when scope is freed - - _ctx->apply_type_arguments(sub, klass, THREAD); - - int start, end = 0; - start = klass->find_method_by_name(_method_name, &end); - if (start != -1) { - for (int i = start; i < end; ++i) { - Method* m = klass->methods()->at(i); - // This gets the method's parameter list with its generic type - // parameters resolved - generic::MethodDescriptor* md = _cache->descriptor_for(m, THREAD); - - // Find all methods on this hierarchy that match this method - // (name, signature). This class collects other families of this - // method name. - StatefulGenericMethodFamily* family = - _families.find_matching_or_create(md, _ctx); - - if (klass->is_interface()) { - // ??? - StateRestorer* restorer = family->record_method_and_dq_further(m); - scope->add_mark(restorer); - } else { - // This is the rule that methods in classes "win" (bad word) over - // methods in interfaces. This works because of single inheritance - family->set_target_if_empty(m); - } - } - } - return true; - } -}; - -#ifndef PRODUCT -static void print_generic_families( - GrowableArray* methods, Symbol* match) { - streamIndentor si(tty, 4); - if (methods->length() == 0) { - tty->indent(); - tty->print_cr("No Logical Method found"); - } - for (int i = 0; i < methods->length(); ++i) { - tty->indent(); - GenericMethodFamily* lm = methods->at(i); - if (lm->contains_signature(match)) { - tty->print_cr(""); - } else { - tty->print_cr(""); - } - lm->print_sig_on(tty, lm->get_generic_sig(), 1); - } -} -#endif // ndef PRODUCT static void create_overpasses( GrowableArray* slots, InstanceKlass* klass, TRAPS); -static void generate_generic_defaults( - InstanceKlass* klass, GrowableArray* empty_slots, - EmptyVtableSlot* slot, int current_slot_index, TRAPS) { - - if (slot->is_bound()) { -#ifndef PRODUCT - if (TraceDefaultMethods) { - streamIndentor si(tty, 4); - tty->indent().print_cr("Already bound to logical method:"); - GenericMethodFamily* lm = (GenericMethodFamily*)(slot->get_binding()); - lm->print_sig_on(tty, lm->get_generic_sig(), 1); - } -#endif // ndef PRODUCT - return; // covered by previous processing - } - - generic::DescriptorCache cache; - - generic::Context ctx(&cache); - FindMethodsByGenericSig visitor(&cache, slot->name(), &ctx, CHECK); - visitor.run(klass); - - GrowableArray discovered_families; - visitor.get_discovered_families(&discovered_families); - -#ifndef PRODUCT - if (TraceDefaultMethods) { - print_generic_families(&discovered_families, slot->signature()); - } -#endif // ndef PRODUCT - - // Find and populate any other slots that match the discovered families - for (int j = current_slot_index; j < empty_slots->length(); ++j) { - EmptyVtableSlot* open_slot = empty_slots->at(j); - - if (slot->name() == open_slot->name()) { - for (int k = 0; k < discovered_families.length(); ++k) { - GenericMethodFamily* lm = discovered_families.at(k); - - if (lm->contains_signature(open_slot->signature())) { - lm->determine_target(klass, CHECK); - open_slot->bind_family(lm); - } - } - } - } -} - static void generate_erased_defaults( InstanceKlass* klass, GrowableArray* empty_slots, EmptyVtableSlot* slot, TRAPS) { @@ -943,21 +714,14 @@ // // First if finds any name/signature slots that need any implementation (either // because they are miranda or a superclass's implementation is an overpass -// itself). For each slot, iterate over the hierarchy, using generic signature -// information to partition any methods that match the name into method families -// where each family contains methods whose signatures are equivalent at the -// language level (i.e., their reified parameters match and return values are -// covariant). Check those sets to see if they contain a signature that matches -// the slot we're looking at (if we're lucky, there might be other empty slots -// that we can fill using the same analysis). +// itself). For each slot, iterate over the hierarchy, to see if they contain a +// signature that matches the slot we are looking at. // // For each slot filled, we generate an overpass method that either calls the // unique default method candidate using invokespecial, or throws an exception // (in the case of no default method candidates, or more than one valid -// candidate). These methods are then added to the class's method list. If -// the method set we're using contains methods (qualified or not) with a -// different runtime signature than the method we're creating, then we have to -// create bridges with those signatures too. +// candidate). These methods are then added to the class's method list. +// The JVM does not create bridges nor handle generic signatures here. void DefaultMethods::generate_default_methods( InstanceKlass* klass, GrowableArray* mirandas, TRAPS) { @@ -997,11 +761,7 @@ } #endif // ndef PRODUCT - if (ParseGenericDefaults) { - generate_generic_defaults(klass, empty_slots, slot, i, CHECK); - } else { - generate_erased_defaults(klass, empty_slots, slot, CHECK); - } + generate_erased_defaults(klass, empty_slots, slot, CHECK); } #ifndef PRODUCT if (TraceDefaultMethods) { @@ -1019,13 +779,13 @@ } /** - * Generic analysis was used upon interface '_target' and found a unique - * default method candidate with generic signature '_method_desc'. This + * Interface inheritance rules were used to find a unique default method + * candidate for the resolved class. This * method is only viable if it would also be in the set of default method * candidates if we ran a full analysis on the current class. * * The only reason that the method would not be in the set of candidates for - * the current class is if that there's another covariantly matching method + * the current class is if that there's another matching method * which is "more specific" than the found method -- i.e., one could find a * path in the interface hierarchy in which the matching method appears * before we get to '_target'. @@ -1110,48 +870,6 @@ : ShadowChecker(thread, name, holder, target) {} }; -class GenericShadowChecker : public ShadowChecker { - private: - generic::DescriptorCache* _cache; - generic::MethodDescriptor* _method_desc; - - bool path_has_shadow() { - generic::Context ctx(_cache); - - for (int i = current_depth() - 1; i > 0; --i) { - InstanceKlass* ik = class_at_depth(i); - InstanceKlass* sub = class_at_depth(i + 1); - ctx.apply_type_arguments(sub, ik, THREAD); - - if (ik->is_interface()) { - int end; - int start = ik->find_method_by_name(_method_name, &end); - if (start != -1) { - for (int j = start; j < end; ++j) { - Method* mo = ik->methods()->at(j); - generic::MethodDescriptor* md = _cache->descriptor_for(mo, THREAD); - if (_method_desc->covariant_match(md, &ctx)) { - return true; - } - } - } - } - } - return false; - } - - public: - - GenericShadowChecker(generic::DescriptorCache* cache, Thread* thread, - Symbol* name, InstanceKlass* holder, generic::MethodDescriptor* desc, - InstanceKlass* target) - : ShadowChecker(thread, name, holder, target) { - _cache = cache; - _method_desc = desc; - } -}; - - // Find the unique qualified candidate from the perspective of the super_class // which is the resolved_klass, which must be an immediate superinterface @@ -1203,66 +921,6 @@ } } -// super_class is assumed to be the direct super of current_class -Method* find_generic_super_default( InstanceKlass* current_class, - InstanceKlass* super_class, - Symbol* method_name, Symbol* sig, TRAPS) { - generic::DescriptorCache cache; - generic::Context ctx(&cache); - - // Prime the initial generic context for current -> super_class - ctx.apply_type_arguments(current_class, super_class, CHECK_NULL); - - FindMethodsByGenericSig visitor(&cache, method_name, &ctx, CHECK_NULL); - visitor.run(super_class); - - GrowableArray families; - visitor.get_discovered_families(&families); - -#ifndef PRODUCT - if (TraceDefaultMethods) { - print_generic_families(&families, sig); - } -#endif // ndef PRODUCT - - GenericMethodFamily* selected_family = NULL; - - for (int i = 0; i < families.length(); ++i) { - GenericMethodFamily* lm = families.at(i); - if (lm->contains_signature(sig)) { - lm->determine_target(current_class, CHECK_NULL); - selected_family = lm; - } - } - - if (selected_family->has_target()) { - Method* target = selected_family->get_selected_target(); - InstanceKlass* holder = InstanceKlass::cast(target->method_holder()); - - // Verify that the identified method is valid from the context of - // the current class - GenericShadowChecker checker(&cache, THREAD, target->name(), - holder, selected_family->descriptor(), super_class); - checker.run(current_class); - - if (checker.found_shadow()) { -#ifndef PRODUCT - if (TraceDefaultMethods) { - tty->print_cr(" Only candidate found was shadowed."); - } -#endif // ndef PRODUCT - THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), - "Accessible default method not found", NULL); - } else { - return target; - } - } else { - assert(selected_family->throws_exception(), "must have target or throw"); - THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), - selected_family->get_exception_message()->as_C_string(), NULL); - } -} - // This is called during linktime when we find an invokespecial call that // refers to a direct superinterface. It indicates that we should find the // default method in the hierarchy of that superinterface, and if that method @@ -1296,13 +954,8 @@ assert(super_class->is_interface(), "only call for default methods"); Method* target = NULL; - if (ParseGenericDefaults) { - target = find_generic_super_default(current_class, super_class, - method_name, sig, CHECK_NULL); - } else { - target = find_erased_super_default(current_class, super_class, - method_name, sig, CHECK_NULL); - } + target = find_erased_super_default(current_class, super_class, + method_name, sig, CHECK_NULL); #ifndef PRODUCT if (target != NULL) { diff -r a7d8baf4cca7 -r d80493ee6430 src/share/vm/classfile/genericSignatures.cpp --- a/src/share/vm/classfile/genericSignatures.cpp Mon Aug 26 18:34:29 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1279 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" - -#include "classfile/genericSignatures.hpp" -#include "classfile/symbolTable.hpp" -#include "classfile/systemDictionary.hpp" -#include "memory/resourceArea.hpp" - -namespace generic { - -// Helper class for parsing the generic signature Symbol in klass and methods -class DescriptorStream : public ResourceObj { - private: - Symbol* _symbol; - int _offset; - int _mark; - const char* _parse_error; - - void set_parse_error(const char* error) { - assert(error != NULL, "Can't set NULL error string"); - _parse_error = error; - } - - public: - DescriptorStream(Symbol* sym) - : _symbol(sym), _offset(0), _mark(-1), _parse_error(NULL) {} - - const char* parse_error() const { - return _parse_error; - } - - bool at_end() { return _offset >= _symbol->utf8_length(); } - - char peek() { - if (at_end()) { - set_parse_error("Peeking past end of signature"); - return '\0'; - } else { - return _symbol->byte_at(_offset); - } - } - - char read() { - if (at_end()) { - set_parse_error("Reading past end of signature"); - return '\0'; - } else { - return _symbol->byte_at(_offset++); - } - } - - void read(char expected) { - char c = read(); - assert_char(c, expected, 0); - } - - void assert_char(char c, char expected, int pos = -1) { - if (c != expected) { - const char* fmt = "Parse error at %d: expected %c but got %c"; - size_t len = strlen(fmt) + 5; - char* buffer = NEW_RESOURCE_ARRAY(char, len); - jio_snprintf(buffer, len, fmt, _offset + pos, expected, c); - set_parse_error(buffer); - } - } - - void push(char c) { - assert(c == _symbol->byte_at(_offset - 1), "Pushing back wrong value"); - --_offset; - } - - void expect_end() { - if (!at_end()) { - set_parse_error("Unexpected data trailing signature"); - } - } - - bool has_mark() { return _mark != -1; } - - void set_mark() { - _mark = _offset; - } - - Identifier* identifier_from_mark() { - assert(has_mark(), "Mark should be set"); - if (!has_mark()) { - set_parse_error("Expected mark to be set"); - return NULL; - } else { - Identifier* id = new Identifier(_symbol, _mark, _offset - 1); - _mark = -1; - return id; - } - } -}; - - -#define CHECK_FOR_PARSE_ERROR() \ - if (STREAM->parse_error() != NULL) { \ - if (VerifyGenericSignatures) { \ - fatal(STREAM->parse_error()); \ - } \ - return NULL; \ - } (void)0 - -#define READ() STREAM->read(); CHECK_FOR_PARSE_ERROR() -#define PEEK() STREAM->peek(); CHECK_FOR_PARSE_ERROR() -#define PUSH(c) STREAM->push(c) -#define EXPECT(c) STREAM->read(c); CHECK_FOR_PARSE_ERROR() -#define EXPECTED(c, ch) STREAM->assert_char(c, ch); CHECK_FOR_PARSE_ERROR() -#define EXPECT_END() STREAM->expect_end(); CHECK_FOR_PARSE_ERROR() - -#define CHECK_STREAM STREAM); CHECK_FOR_PARSE_ERROR(); ((void)0 - -#ifndef PRODUCT -void Identifier::print_on(outputStream* str) const { - for (int i = _begin; i < _end; ++i) { - str->print("%c", (char)_sym->byte_at(i)); - } -} -#endif // ndef PRODUCT - -bool Identifier::equals(Identifier* other) { - if (_sym == other->_sym && _begin == other->_begin && _end == other->_end) { - return true; - } else if (_end - _begin != other->_end - other->_begin) { - return false; - } else { - size_t len = _end - _begin; - char* addr = ((char*)_sym->bytes()) + _begin; - char* oaddr = ((char*)other->_sym->bytes()) + other->_begin; - return strncmp(addr, oaddr, len) == 0; - } -} - -bool Identifier::equals(Symbol* sym) { - Identifier id(sym, 0, sym->utf8_length()); - return equals(&id); -} - -/** - * A formal type parameter may be found in the the enclosing class, but it could - * also come from an enclosing method or outer class, in the case of inner-outer - * classes or anonymous classes. For example: - * - * class Outer { - * class Inner { - * void m(T t, V v, W w); - * } - * } - * - * In this case, the type variables in m()'s signature are not all found in the - * immediate enclosing class (Inner). class Inner has only type parameter W, - * but it's outer_class field will reference Outer's descriptor which contains - * T & V (no outer_method in this case). - * - * If you have an anonymous class, it has both an enclosing method *and* an - * enclosing class where type parameters can be declared: - * - * class MOuter { - * void bar(V v) { - * Runnable r = new Runnable() { - * public void run() {} - * public void foo(T t, V v) { ... } - * }; - * } - * } - * - * In this case, foo will be a member of some class, Runnable$1, which has no - * formal parameters itself, but has an outer_method (bar()) which provides - * type parameter V, and an outer class MOuter with type parameter T. - * - * It is also possible that the outer class is itself an inner class to some - * other class (or an anonymous class with an enclosing method), so we need to - * follow the outer_class/outer_method chain to it's end when looking for a - * type parameter. - */ -TypeParameter* Descriptor::find_type_parameter(Identifier* id, int* depth) { - - int current_depth = 0; - - MethodDescriptor* outer_method = as_method_signature(); - ClassDescriptor* outer_class = as_class_signature(); - - if (outer_class == NULL) { // 'this' is a method signature; use the holder - outer_class = outer_method->outer_class(); - } - - while (outer_method != NULL || outer_class != NULL) { - if (outer_method != NULL) { - for (int i = 0; i < outer_method->type_parameters().length(); ++i) { - TypeParameter* p = outer_method->type_parameters().at(i); - if (p->identifier()->equals(id)) { - *depth = -1; // indicates this this is a method parameter - return p; - } - } - } - if (outer_class != NULL) { - for (int i = 0; i < outer_class->type_parameters().length(); ++i) { - TypeParameter* p = outer_class->type_parameters().at(i); - if (p->identifier()->equals(id)) { - *depth = current_depth; - return p; - } - } - outer_method = outer_class->outer_method(); - outer_class = outer_class->outer_class(); - ++current_depth; - } - } - - if (VerifyGenericSignatures) { - fatal("Could not resolve identifier"); - } - - return NULL; -} - -ClassDescriptor* ClassDescriptor::parse_generic_signature(Klass* klass, TRAPS) { - return parse_generic_signature(klass, NULL, CHECK_NULL); -} - -ClassDescriptor* ClassDescriptor::parse_generic_signature( - Klass* klass, Symbol* original_name, TRAPS) { - - InstanceKlass* ik = InstanceKlass::cast(klass); - Symbol* sym = ik->generic_signature(); - - ClassDescriptor* spec; - - if (sym == NULL || (spec = ClassDescriptor::parse_generic_signature(sym)) == NULL) { - spec = ClassDescriptor::placeholder(ik); - } - - u2 outer_index = get_outer_class_index(ik, CHECK_NULL); - if (outer_index != 0) { - if (original_name == NULL) { - original_name = ik->name(); - } - Handle class_loader = Handle(THREAD, ik->class_loader()); - Handle protection_domain = Handle(THREAD, ik->protection_domain()); - - Symbol* outer_name = ik->constants()->klass_name_at(outer_index); - Klass* outer = SystemDictionary::find( - outer_name, class_loader, protection_domain, CHECK_NULL); - if (outer == NULL && !THREAD->is_Compiler_thread()) { - if (outer_name == ik->super()->name()) { - outer = SystemDictionary::resolve_super_or_fail(original_name, outer_name, - class_loader, protection_domain, - false, CHECK_NULL); - } - else { - outer = SystemDictionary::resolve_or_fail(outer_name, class_loader, - protection_domain, false, CHECK_NULL); - } - } - - InstanceKlass* outer_ik; - ClassDescriptor* outer_spec = NULL; - if (outer == NULL) { - outer_spec = ClassDescriptor::placeholder(ik); - assert(false, "Outer class not loaded and not loadable from here"); - } else { - outer_ik = InstanceKlass::cast(outer); - outer_spec = parse_generic_signature(outer, original_name, CHECK_NULL); - } - spec->set_outer_class(outer_spec); - - u2 encl_method_idx = ik->enclosing_method_method_index(); - if (encl_method_idx != 0 && outer_ik != NULL) { - ConstantPool* cp = ik->constants(); - u2 name_index = cp->name_ref_index_at(encl_method_idx); - u2 sig_index = cp->signature_ref_index_at(encl_method_idx); - Symbol* name = cp->symbol_at(name_index); - Symbol* sig = cp->symbol_at(sig_index); - Method* m = outer_ik->find_method(name, sig); - if (m != NULL) { - Symbol* gsig = m->generic_signature(); - if (gsig != NULL) { - MethodDescriptor* gms = MethodDescriptor::parse_generic_signature(gsig, outer_spec); - spec->set_outer_method(gms); - } - } else if (VerifyGenericSignatures) { - ResourceMark rm; - stringStream ss; - ss.print("Could not find method %s %s in class %s", - name->as_C_string(), sig->as_C_string(), outer_name->as_C_string()); - fatal(ss.as_string()); - } - } - } - - spec->bind_variables_to_parameters(); - return spec; -} - -ClassDescriptor* ClassDescriptor::placeholder(InstanceKlass* klass) { - GrowableArray formals; - GrowableArray interfaces; - ClassType* super_type = NULL; - - Klass* super_klass = klass->super(); - if (super_klass != NULL) { - InstanceKlass* super = InstanceKlass::cast(super_klass); - super_type = ClassType::from_symbol(super->name()); - } - - for (int i = 0; i < klass->local_interfaces()->length(); ++i) { - InstanceKlass* iface = InstanceKlass::cast(klass->local_interfaces()->at(i)); - interfaces.append(ClassType::from_symbol(iface->name())); - } - return new ClassDescriptor(formals, super_type, interfaces); -} - -ClassDescriptor* ClassDescriptor::parse_generic_signature(Symbol* sym) { - - DescriptorStream ds(sym); - DescriptorStream* STREAM = &ds; - - GrowableArray parameters(8); - char c = READ(); - if (c == '<') { - c = READ(); - while (c != '>') { - PUSH(c); - TypeParameter* ftp = TypeParameter::parse_generic_signature(CHECK_STREAM); - parameters.append(ftp); - c = READ(); - } - } else { - PUSH(c); - } - - EXPECT('L'); - ClassType* super = ClassType::parse_generic_signature(CHECK_STREAM); - - GrowableArray signatures(2); - while (!STREAM->at_end()) { - EXPECT('L'); - ClassType* iface = ClassType::parse_generic_signature(CHECK_STREAM); - signatures.append(iface); - } - - EXPECT_END(); - - return new ClassDescriptor(parameters, super, signatures); -} - -#ifndef PRODUCT -void ClassDescriptor::print_on(outputStream* str) const { - str->indent().print_cr("ClassDescriptor {"); - { - streamIndentor si(str); - if (_type_parameters.length() > 0) { - str->indent().print_cr("Formals {"); - { - streamIndentor si(str); - for (int i = 0; i < _type_parameters.length(); ++i) { - _type_parameters.at(i)->print_on(str); - } - } - str->indent().print_cr("}"); - } - if (_super != NULL) { - str->indent().print_cr("Superclass: "); - { - streamIndentor si(str); - _super->print_on(str); - } - } - if (_interfaces.length() > 0) { - str->indent().print_cr("SuperInterfaces: {"); - { - streamIndentor si(str); - for (int i = 0; i < _interfaces.length(); ++i) { - _interfaces.at(i)->print_on(str); - } - } - str->indent().print_cr("}"); - } - if (_outer_method != NULL) { - str->indent().print_cr("Outer Method: {"); - { - streamIndentor si(str); - _outer_method->print_on(str); - } - str->indent().print_cr("}"); - } - if (_outer_class != NULL) { - str->indent().print_cr("Outer Class: {"); - { - streamIndentor si(str); - _outer_class->print_on(str); - } - str->indent().print_cr("}"); - } - } - str->indent().print_cr("}"); -} -#endif // ndef PRODUCT - -ClassType* ClassDescriptor::interface_desc(Symbol* sym) { - for (int i = 0; i < _interfaces.length(); ++i) { - if (_interfaces.at(i)->identifier()->equals(sym)) { - return _interfaces.at(i); - } - } - if (VerifyGenericSignatures) { - fatal("Did not find expected interface"); - } - return NULL; -} - -void ClassDescriptor::bind_variables_to_parameters() { - if (_outer_class != NULL) { - _outer_class->bind_variables_to_parameters(); - } - if (_outer_method != NULL) { - _outer_method->bind_variables_to_parameters(); - } - for (int i = 0; i < _type_parameters.length(); ++i) { - _type_parameters.at(i)->bind_variables_to_parameters(this, i); - } - if (_super != NULL) { - _super->bind_variables_to_parameters(this); - } - for (int i = 0; i < _interfaces.length(); ++i) { - _interfaces.at(i)->bind_variables_to_parameters(this); - } -} - -ClassDescriptor* ClassDescriptor::canonicalize(Context* ctx) { - - GrowableArray type_params(_type_parameters.length()); - for (int i = 0; i < _type_parameters.length(); ++i) { - type_params.append(_type_parameters.at(i)->canonicalize(ctx, 0)); - } - - ClassDescriptor* outer = _outer_class == NULL ? NULL : - _outer_class->canonicalize(ctx); - - ClassType* super = _super == NULL ? NULL : _super->canonicalize(ctx, 0); - - GrowableArray interfaces(_interfaces.length()); - for (int i = 0; i < _interfaces.length(); ++i) { - interfaces.append(_interfaces.at(i)->canonicalize(ctx, 0)); - } - - MethodDescriptor* md = _outer_method == NULL ? NULL : - _outer_method->canonicalize(ctx); - - return new ClassDescriptor(type_params, super, interfaces, outer, md); -} - -u2 ClassDescriptor::get_outer_class_index(InstanceKlass* klass, TRAPS) { - int inner_index = InstanceKlass::inner_class_inner_class_info_offset; - int outer_index = InstanceKlass::inner_class_outer_class_info_offset; - int name_offset = InstanceKlass::inner_class_inner_name_offset; - int next_offset = InstanceKlass::inner_class_next_offset; - - if (klass->inner_classes() == NULL || klass->inner_classes()->length() == 0) { - // No inner class info => no declaring class - return 0; - } - - Array* i_icls = klass->inner_classes(); - ConstantPool* i_cp = klass->constants(); - int i_length = i_icls->length(); - - // Find inner_klass attribute - for (int i = 0; i + next_offset < i_length; i += next_offset) { - u2 ioff = i_icls->at(i + inner_index); - u2 ooff = i_icls->at(i + outer_index); - u2 noff = i_icls->at(i + name_offset); - if (ioff != 0) { - // Check to see if the name matches the class we're looking for - // before attempting to find the class. - if (i_cp->klass_name_at_matches(klass, ioff) && ooff != 0) { - return ooff; - } - } - } - - // It may be anonymous; try for that. - u2 encl_method_class_idx = klass->enclosing_method_class_index(); - if (encl_method_class_idx != 0) { - return encl_method_class_idx; - } - - return 0; -} - -MethodDescriptor* MethodDescriptor::parse_generic_signature(Method* m, ClassDescriptor* outer) { - Symbol* generic_sig = m->generic_signature(); - MethodDescriptor* md = NULL; - if (generic_sig == NULL || (md = parse_generic_signature(generic_sig, outer)) == NULL) { - md = parse_generic_signature(m->signature(), outer); - } - assert(md != NULL, "Could not parse method signature"); - md->bind_variables_to_parameters(); - return md; -} - -MethodDescriptor* MethodDescriptor::parse_generic_signature(Symbol* sym, ClassDescriptor* outer) { - - DescriptorStream ds(sym); - DescriptorStream* STREAM = &ds; - - GrowableArray params(8); - char c = READ(); - if (c == '<') { - c = READ(); - while (c != '>') { - PUSH(c); - TypeParameter* ftp = TypeParameter::parse_generic_signature(CHECK_STREAM); - params.append(ftp); - c = READ(); - } - } else { - PUSH(c); - } - - EXPECT('('); - - GrowableArray parameters(8); - c = READ(); - while (c != ')') { - PUSH(c); - Type* arg = Type::parse_generic_signature(CHECK_STREAM); - parameters.append(arg); - c = READ(); - } - - Type* rt = Type::parse_generic_signature(CHECK_STREAM); - - GrowableArray throws; - while (!STREAM->at_end()) { - EXPECT('^'); - Type* spec = Type::parse_generic_signature(CHECK_STREAM); - throws.append(spec); - } - - return new MethodDescriptor(params, outer, parameters, rt, throws); -} - -void MethodDescriptor::bind_variables_to_parameters() { - for (int i = 0; i < _type_parameters.length(); ++i) { - _type_parameters.at(i)->bind_variables_to_parameters(this, i); - } - for (int i = 0; i < _parameters.length(); ++i) { - _parameters.at(i)->bind_variables_to_parameters(this); - } - _return_type->bind_variables_to_parameters(this); - for (int i = 0; i < _throws.length(); ++i) { - _throws.at(i)->bind_variables_to_parameters(this); - } -} - -bool MethodDescriptor::covariant_match(MethodDescriptor* other, Context* ctx) { - - if (_parameters.length() == other->_parameters.length()) { - for (int i = 0; i < _parameters.length(); ++i) { - if (!_parameters.at(i)->covariant_match(other->_parameters.at(i), ctx)) { - return false; - } - } - - if (_return_type->as_primitive() != NULL) { - return _return_type->covariant_match(other->_return_type, ctx); - } else { - // return type is a reference - return other->_return_type->as_class() != NULL || - other->_return_type->as_variable() != NULL || - other->_return_type->as_array() != NULL; - } - } else { - return false; - } -} - -MethodDescriptor* MethodDescriptor::canonicalize(Context* ctx) { - - GrowableArray type_params(_type_parameters.length()); - for (int i = 0; i < _type_parameters.length(); ++i) { - type_params.append(_type_parameters.at(i)->canonicalize(ctx, 0)); - } - - ClassDescriptor* outer = _outer_class == NULL ? NULL : - _outer_class->canonicalize(ctx); - - GrowableArray params(_parameters.length()); - for (int i = 0; i < _parameters.length(); ++i) { - params.append(_parameters.at(i)->canonicalize(ctx, 0)); - } - - Type* rt = _return_type->canonicalize(ctx, 0); - - GrowableArray throws(_throws.length()); - for (int i = 0; i < _throws.length(); ++i) { - throws.append(_throws.at(i)->canonicalize(ctx, 0)); - } - - return new MethodDescriptor(type_params, outer, params, rt, throws); -} - -#ifndef PRODUCT -TempNewSymbol MethodDescriptor::reify_signature(Context* ctx, TRAPS) { - stringStream ss(256); - - ss.print("("); - for (int i = 0; i < _parameters.length(); ++i) { - _parameters.at(i)->reify_signature(&ss, ctx); - } - ss.print(")"); - _return_type->reify_signature(&ss, ctx); - return SymbolTable::new_symbol(ss.base(), (int)ss.size(), THREAD); -} - -void MethodDescriptor::print_on(outputStream* str) const { - str->indent().print_cr("MethodDescriptor {"); - { - streamIndentor si(str); - if (_type_parameters.length() > 0) { - str->indent().print_cr("Formals: {"); - { - streamIndentor si(str); - for (int i = 0; i < _type_parameters.length(); ++i) { - _type_parameters.at(i)->print_on(str); - } - } - str->indent().print_cr("}"); - } - str->indent().print_cr("Parameters: {"); - { - streamIndentor si(str); - for (int i = 0; i < _parameters.length(); ++i) { - _parameters.at(i)->print_on(str); - } - } - str->indent().print_cr("}"); - str->indent().print_cr("Return Type: "); - { - streamIndentor si(str); - _return_type->print_on(str); - } - - if (_throws.length() > 0) { - str->indent().print_cr("Throws: {"); - { - streamIndentor si(str); - for (int i = 0; i < _throws.length(); ++i) { - _throws.at(i)->print_on(str); - } - } - str->indent().print_cr("}"); - } - } - str->indent().print_cr("}"); -} -#endif // ndef PRODUCT - -TypeParameter* TypeParameter::parse_generic_signature(DescriptorStream* STREAM) { - STREAM->set_mark(); - char c = READ(); - while (c != ':') { - c = READ(); - } - - Identifier* id = STREAM->identifier_from_mark(); - - ClassType* class_bound = NULL; - GrowableArray interface_bounds(8); - - c = READ(); - if (c != '>') { - if (c != ':') { - EXPECTED(c, 'L'); - class_bound = ClassType::parse_generic_signature(CHECK_STREAM); - c = READ(); - } - - while (c == ':') { - EXPECT('L'); - ClassType* fts = ClassType::parse_generic_signature(CHECK_STREAM); - interface_bounds.append(fts); - c = READ(); - } - } - PUSH(c); - - return new TypeParameter(id, class_bound, interface_bounds); -} - -void TypeParameter::bind_variables_to_parameters(Descriptor* sig, int position) { - if (_class_bound != NULL) { - _class_bound->bind_variables_to_parameters(sig); - } - for (int i = 0; i < _interface_bounds.length(); ++i) { - _interface_bounds.at(i)->bind_variables_to_parameters(sig); - } - _position = position; -} - -Type* TypeParameter::resolve( - Context* ctx, int inner_depth, int ctx_depth) { - - if (inner_depth == -1) { - // This indicates that the parameter is a method type parameter, which - // isn't resolveable using the class hierarchy context - return bound(); - } - - ClassType* provider = ctx->at_depth(ctx_depth); - if (provider != NULL) { - for (int i = 0; i < inner_depth && provider != NULL; ++i) { - provider = provider->outer_class(); - } - if (provider != NULL) { - TypeArgument* arg = provider->type_argument_at(_position); - if (arg != NULL) { - Type* value = arg->lower_bound(); - return value->canonicalize(ctx, ctx_depth + 1); - } - } - } - - return bound(); -} - -TypeParameter* TypeParameter::canonicalize(Context* ctx, int ctx_depth) { - ClassType* bound = _class_bound == NULL ? NULL : - _class_bound->canonicalize(ctx, ctx_depth); - - GrowableArray ifaces(_interface_bounds.length()); - for (int i = 0; i < _interface_bounds.length(); ++i) { - ifaces.append(_interface_bounds.at(i)->canonicalize(ctx, ctx_depth)); - } - - TypeParameter* ret = new TypeParameter(_identifier, bound, ifaces); - ret->_position = _position; - return ret; -} - -ClassType* TypeParameter::bound() { - if (_class_bound != NULL) { - return _class_bound; - } - - if (_interface_bounds.length() == 1) { - return _interface_bounds.at(0); - } - - return ClassType::java_lang_Object(); // TODO: investigate this case -} - -#ifndef PRODUCT -void TypeParameter::print_on(outputStream* str) const { - str->indent().print_cr("Formal: {"); - { - streamIndentor si(str); - - str->indent().print("Identifier: "); - _identifier->print_on(str); - str->print_cr(""); - if (_class_bound != NULL) { - str->indent().print_cr("Class Bound: "); - streamIndentor si(str); - _class_bound->print_on(str); - } - if (_interface_bounds.length() > 0) { - str->indent().print_cr("Interface Bounds: {"); - { - streamIndentor si(str); - for (int i = 0; i < _interface_bounds.length(); ++i) { - _interface_bounds.at(i)->print_on(str); - } - } - str->indent().print_cr("}"); - } - str->indent().print_cr("Ordinal Position: %d", _position); - } - str->indent().print_cr("}"); -} -#endif // ndef PRODUCT - -Type* Type::parse_generic_signature(DescriptorStream* STREAM) { - char c = READ(); - switch (c) { - case 'L': - return ClassType::parse_generic_signature(CHECK_STREAM); - case 'T': - return TypeVariable::parse_generic_signature(CHECK_STREAM); - case '[': - return ArrayType::parse_generic_signature(CHECK_STREAM); - default: - return new PrimitiveType(c); - } -} - -Identifier* ClassType::parse_generic_signature_simple(GrowableArray* args, - bool* has_inner, DescriptorStream* STREAM) { - STREAM->set_mark(); - - char c = READ(); - while (c != ';' && c != '.' && c != '<') { c = READ(); } - Identifier* id = STREAM->identifier_from_mark(); - - if (c == '<') { - c = READ(); - while (c != '>') { - PUSH(c); - TypeArgument* arg = TypeArgument::parse_generic_signature(CHECK_STREAM); - args->append(arg); - c = READ(); - } - c = READ(); - } - - *has_inner = (c == '.'); - if (!(*has_inner)) { - EXPECTED(c, ';'); - } - - return id; -} - -ClassType* ClassType::parse_generic_signature(DescriptorStream* STREAM) { - return parse_generic_signature(NULL, CHECK_STREAM); -} - -ClassType* ClassType::parse_generic_signature(ClassType* outer, DescriptorStream* STREAM) { - GrowableArray args; - ClassType* gct = NULL; - bool has_inner = false; - - Identifier* id = parse_generic_signature_simple(&args, &has_inner, STREAM); - if (id != NULL) { - gct = new ClassType(id, args, outer); - - if (has_inner) { - gct = parse_generic_signature(gct, CHECK_STREAM); - } - } - return gct; -} - -ClassType* ClassType::from_symbol(Symbol* sym) { - assert(sym != NULL, "Must not be null"); - GrowableArray args; - Identifier* id = new Identifier(sym, 0, sym->utf8_length()); - return new ClassType(id, args, NULL); -} - -ClassType* ClassType::java_lang_Object() { - return from_symbol(vmSymbols::java_lang_Object()); -} - -void ClassType::bind_variables_to_parameters(Descriptor* sig) { - for (int i = 0; i < _type_arguments.length(); ++i) { - _type_arguments.at(i)->bind_variables_to_parameters(sig); - } - if (_outer_class != NULL) { - _outer_class->bind_variables_to_parameters(sig); - } -} - -TypeArgument* ClassType::type_argument_at(int i) { - if (i >= 0 && i < _type_arguments.length()) { - return _type_arguments.at(i); - } else { - return NULL; - } -} - -#ifndef PRODUCT -void ClassType::reify_signature(stringStream* ss, Context* ctx) { - ss->print("L"); - _identifier->print_on(ss); - ss->print(";"); -} - -void ClassType::print_on(outputStream* str) const { - str->indent().print_cr("Class {"); - { - streamIndentor si(str); - str->indent().print("Name: "); - _identifier->print_on(str); - str->print_cr(""); - if (_type_arguments.length() != 0) { - str->indent().print_cr("Type Arguments: {"); - { - streamIndentor si(str); - for (int j = 0; j < _type_arguments.length(); ++j) { - _type_arguments.at(j)->print_on(str); - } - } - str->indent().print_cr("}"); - } - if (_outer_class != NULL) { - str->indent().print_cr("Outer Class: "); - streamIndentor sir(str); - _outer_class->print_on(str); - } - } - str->indent().print_cr("}"); -} -#endif // ndef PRODUCT - -bool ClassType::covariant_match(Type* other, Context* ctx) { - - if (other == this) { - return true; - } - - TypeVariable* variable = other->as_variable(); - if (variable != NULL) { - other = variable->resolve(ctx, 0); - } - - ClassType* outer = outer_class(); - ClassType* other_class = other->as_class(); - - if (other_class == NULL || - (outer == NULL) != (other_class->outer_class() == NULL)) { - return false; - } - - if (!_identifier->equals(other_class->_identifier)) { - return false; - } - - if (outer != NULL && !outer->covariant_match(other_class->outer_class(), ctx)) { - return false; - } - - return true; -} - -ClassType* ClassType::canonicalize(Context* ctx, int ctx_depth) { - - GrowableArray args(_type_arguments.length()); - for (int i = 0; i < _type_arguments.length(); ++i) { - args.append(_type_arguments.at(i)->canonicalize(ctx, ctx_depth)); - } - - ClassType* outer = _outer_class == NULL ? NULL : - _outer_class->canonicalize(ctx, ctx_depth); - - return new ClassType(_identifier, args, outer); -} - -TypeVariable* TypeVariable::parse_generic_signature(DescriptorStream* STREAM) { - STREAM->set_mark(); - char c = READ(); - while (c != ';') { - c = READ(); - } - Identifier* id = STREAM->identifier_from_mark(); - - return new TypeVariable(id); -} - -void TypeVariable::bind_variables_to_parameters(Descriptor* sig) { - _parameter = sig->find_type_parameter(_id, &_inner_depth); - if (VerifyGenericSignatures && _parameter == NULL) { - fatal("Could not find formal parameter"); - } -} - -Type* TypeVariable::resolve(Context* ctx, int ctx_depth) { - if (parameter() != NULL) { - return parameter()->resolve(ctx, inner_depth(), ctx_depth); - } else { - if (VerifyGenericSignatures) { - fatal("Type variable matches no parameter"); - } - return NULL; - } -} - -bool TypeVariable::covariant_match(Type* other, Context* ctx) { - - if (other == this) { - return true; - } - - Context my_context(NULL); // empty, results in erasure - Type* my_type = resolve(&my_context, 0); - if (my_type == NULL) { - return false; - } - - return my_type->covariant_match(other, ctx); -} - -Type* TypeVariable::canonicalize(Context* ctx, int ctx_depth) { - return resolve(ctx, ctx_depth); -} - -#ifndef PRODUCT -void TypeVariable::reify_signature(stringStream* ss, Context* ctx) { - Type* type = resolve(ctx, 0); - if (type != NULL) { - type->reify_signature(ss, ctx); - } -} - -void TypeVariable::print_on(outputStream* str) const { - str->indent().print_cr("Type Variable {"); - { - streamIndentor si(str); - str->indent().print("Name: "); - _id->print_on(str); - str->print_cr(""); - str->indent().print_cr("Inner depth: %d", _inner_depth); - } - str->indent().print_cr("}"); -} -#endif // ndef PRODUCT - -ArrayType* ArrayType::parse_generic_signature(DescriptorStream* STREAM) { - Type* base = Type::parse_generic_signature(CHECK_STREAM); - return new ArrayType(base); -} - -void ArrayType::bind_variables_to_parameters(Descriptor* sig) { - assert(_base != NULL, "Invalid base"); - _base->bind_variables_to_parameters(sig); -} - -bool ArrayType::covariant_match(Type* other, Context* ctx) { - assert(_base != NULL, "Invalid base"); - - if (other == this) { - return true; - } - - ArrayType* other_array = other->as_array(); - return (other_array != NULL && _base->covariant_match(other_array->_base, ctx)); -} - -ArrayType* ArrayType::canonicalize(Context* ctx, int ctx_depth) { - assert(_base != NULL, "Invalid base"); - return new ArrayType(_base->canonicalize(ctx, ctx_depth)); -} - -#ifndef PRODUCT -void ArrayType::reify_signature(stringStream* ss, Context* ctx) { - assert(_base != NULL, "Invalid base"); - ss->print("["); - _base->reify_signature(ss, ctx); -} - -void ArrayType::print_on(outputStream* str) const { - str->indent().print_cr("Array {"); - { - streamIndentor si(str); - _base->print_on(str); - } - str->indent().print_cr("}"); -} -#endif // ndef PRODUCT - -bool PrimitiveType::covariant_match(Type* other, Context* ctx) { - - PrimitiveType* other_prim = other->as_primitive(); - return (other_prim != NULL && _type == other_prim->_type); -} - -PrimitiveType* PrimitiveType::canonicalize(Context* ctx, int ctxd) { - return this; -} - -#ifndef PRODUCT -void PrimitiveType::reify_signature(stringStream* ss, Context* ctx) { - ss->print("%c", _type); -} - -void PrimitiveType::print_on(outputStream* str) const { - str->indent().print_cr("Primitive: '%c'", _type); -} -#endif // ndef PRODUCT - -void PrimitiveType::bind_variables_to_parameters(Descriptor* sig) { -} - -TypeArgument* TypeArgument::parse_generic_signature(DescriptorStream* STREAM) { - char c = READ(); - Type* type = NULL; - - switch (c) { - case '*': - return new TypeArgument(ClassType::java_lang_Object(), NULL); - break; - default: - PUSH(c); - // fall-through - case '+': - case '-': - type = Type::parse_generic_signature(CHECK_STREAM); - if (c == '+') { - return new TypeArgument(type, NULL); - } else if (c == '-') { - return new TypeArgument(ClassType::java_lang_Object(), type); - } else { - return new TypeArgument(type, type); - } - } -} - -void TypeArgument::bind_variables_to_parameters(Descriptor* sig) { - assert(_lower_bound != NULL, "Invalid lower bound"); - _lower_bound->bind_variables_to_parameters(sig); - if (_upper_bound != NULL && _upper_bound != _lower_bound) { - _upper_bound->bind_variables_to_parameters(sig); - } -} - -bool TypeArgument::covariant_match(TypeArgument* other, Context* ctx) { - assert(_lower_bound != NULL, "Invalid lower bound"); - - if (other == this) { - return true; - } - - if (!_lower_bound->covariant_match(other->lower_bound(), ctx)) { - return false; - } - return true; -} - -TypeArgument* TypeArgument::canonicalize(Context* ctx, int ctx_depth) { - assert(_lower_bound != NULL, "Invalid lower bound"); - Type* lower = _lower_bound->canonicalize(ctx, ctx_depth); - Type* upper = NULL; - - if (_upper_bound == _lower_bound) { - upper = lower; - } else if (_upper_bound != NULL) { - upper = _upper_bound->canonicalize(ctx, ctx_depth); - } - - return new TypeArgument(lower, upper); -} - -#ifndef PRODUCT -void TypeArgument::print_on(outputStream* str) const { - str->indent().print_cr("TypeArgument {"); - { - streamIndentor si(str); - if (_lower_bound != NULL) { - str->indent().print("Lower bound: "); - _lower_bound->print_on(str); - } - if (_upper_bound != NULL) { - str->indent().print("Upper bound: "); - _upper_bound->print_on(str); - } - } - str->indent().print_cr("}"); -} -#endif // ndef PRODUCT - -void Context::Mark::destroy() { - if (is_active()) { - _context->reset_to_mark(_marked_size); - } - deactivate(); -} - -void Context::apply_type_arguments( - InstanceKlass* current, InstanceKlass* super, TRAPS) { - assert(_cache != NULL, "Cannot use an empty context"); - ClassType* spec = NULL; - if (current != NULL) { - ClassDescriptor* descriptor = _cache->descriptor_for(current, CHECK); - if (super == current->super()) { - spec = descriptor->super(); - } else { - spec = descriptor->interface_desc(super->name()); - } - if (spec != NULL) { - _type_arguments.push(spec); - } - } -} - -void Context::reset_to_mark(int size) { - _type_arguments.trunc_to(size); -} - -ClassType* Context::at_depth(int i) const { - if (i < _type_arguments.length()) { - return _type_arguments.at(_type_arguments.length() - 1 - i); - } - return NULL; -} - -#ifndef PRODUCT -void Context::print_on(outputStream* str) const { - str->indent().print_cr("Context {"); - for (int i = 0; i < _type_arguments.length(); ++i) { - streamIndentor si(str); - str->indent().print("leval %d: ", i); - ClassType* ct = at_depth(i); - if (ct == NULL) { - str->print_cr(""); - continue; - } else { - str->print_cr("{"); - } - - for (int j = 0; j < ct->type_arguments_length(); ++j) { - streamIndentor si(str); - TypeArgument* ta = ct->type_argument_at(j); - Type* bound = ta->lower_bound(); - bound->print_on(str); - } - str->indent().print_cr("}"); - } - str->indent().print_cr("}"); -} -#endif // ndef PRODUCT - -ClassDescriptor* DescriptorCache::descriptor_for(InstanceKlass* ik, TRAPS) { - - ClassDescriptor** existing = _class_descriptors.get(ik); - if (existing == NULL) { - ClassDescriptor* cd = ClassDescriptor::parse_generic_signature(ik, CHECK_NULL); - _class_descriptors.put(ik, cd); - return cd; - } else { - return *existing; - } -} - -MethodDescriptor* DescriptorCache::descriptor_for( - Method* mh, ClassDescriptor* cd, TRAPS) { - assert(mh != NULL && cd != NULL, "Should not be NULL"); - MethodDescriptor** existing = _method_descriptors.get(mh); - if (existing == NULL) { - MethodDescriptor* md = MethodDescriptor::parse_generic_signature(mh, cd); - _method_descriptors.put(mh, md); - return md; - } else { - return *existing; - } -} -MethodDescriptor* DescriptorCache::descriptor_for(Method* mh, TRAPS) { - ClassDescriptor* cd = descriptor_for( - InstanceKlass::cast(mh->method_holder()), CHECK_NULL); - return descriptor_for(mh, cd, THREAD); -} - -} // namespace generic diff -r a7d8baf4cca7 -r d80493ee6430 src/share/vm/classfile/genericSignatures.hpp --- a/src/share/vm/classfile/genericSignatures.hpp Mon Aug 26 18:34:29 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,467 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP -#define SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP - -#include "classfile/symbolTable.hpp" -#include "memory/allocation.hpp" -#include "runtime/signature.hpp" -#include "utilities/growableArray.hpp" -#include "utilities/resourceHash.hpp" - -class stringStream; - -namespace generic { - -class Identifier; -class ClassDescriptor; -class MethodDescriptor; - -class TypeParameter; // a formal type parameter declared in generic signatures -class TypeArgument; // The "type value" passed to fill parameters in supertypes -class TypeVariable; // A usage of a type parameter as a value -/** - * Example: - * - * class Foo extends Bar { int m(V v) {} } - * ^^^^^^ ^^^^^^ ^^ - * type parameters type argument type variable - * - * Note that a type variable could be passed as an argument too: - * class Foo extends Bar { int m(V v) {} } - * ^^^ - * type argument's value is a type variable - */ - - -class Type; -class ClassType; -class ArrayType; -class PrimitiveType; -class Context; -class DescriptorCache; - -class DescriptorStream; - -class Identifier : public ResourceObj { - private: - Symbol* _sym; - int _begin; - int _end; - - public: - Identifier(Symbol* sym, int begin, int end) : - _sym(sym), _begin(begin), _end(end) {} - - bool equals(Identifier* other); - bool equals(Symbol* sym); - -#ifndef PRODUCT - void print_on(outputStream* str) const; -#endif // ndef PRODUCT -}; - -class Descriptor : public ResourceObj { - protected: - GrowableArray _type_parameters; - ClassDescriptor* _outer_class; - - Descriptor(GrowableArray& params, - ClassDescriptor* outer) - : _type_parameters(params), _outer_class(outer) {} - - public: - - ClassDescriptor* outer_class() { return _outer_class; } - void set_outer_class(ClassDescriptor* sig) { _outer_class = sig; } - - virtual ClassDescriptor* as_class_signature() { return NULL; } - virtual MethodDescriptor* as_method_signature() { return NULL; } - - bool is_class_signature() { return as_class_signature() != NULL; } - bool is_method_signature() { return as_method_signature() != NULL; } - - GrowableArray& type_parameters() { - return _type_parameters; - } - - TypeParameter* find_type_parameter(Identifier* id, int* param_depth); - - virtual void bind_variables_to_parameters() = 0; - -#ifndef PRODUCT - virtual void print_on(outputStream* str) const = 0; -#endif -}; - -class ClassDescriptor : public Descriptor { - private: - ClassType* _super; - GrowableArray _interfaces; - MethodDescriptor* _outer_method; - - ClassDescriptor(GrowableArray& ftp, ClassType* scs, - GrowableArray& sis, ClassDescriptor* outer_class = NULL, - MethodDescriptor* outer_method = NULL) - : Descriptor(ftp, outer_class), _super(scs), _interfaces(sis), - _outer_method(outer_method) {} - - static u2 get_outer_class_index(InstanceKlass* k, TRAPS); - static ClassDescriptor* parse_generic_signature(Klass* k, Symbol* original_name, TRAPS); - - public: - - virtual ClassDescriptor* as_class_signature() { return this; } - - MethodDescriptor* outer_method() { return _outer_method; } - void set_outer_method(MethodDescriptor* m) { _outer_method = m; } - - ClassType* super() { return _super; } - ClassType* interface_desc(Symbol* sym); - - static ClassDescriptor* parse_generic_signature(Klass* k, TRAPS); - static ClassDescriptor* parse_generic_signature(Symbol* sym); - - // For use in superclass chains in positions where this is no generic info - static ClassDescriptor* placeholder(InstanceKlass* klass); - -#ifndef PRODUCT - void print_on(outputStream* str) const; -#endif - - ClassDescriptor* canonicalize(Context* ctx); - - // Linking sets the position index in any contained TypeVariable type - // to correspond to the location of that identifier in the formal type - // parameters. - void bind_variables_to_parameters(); -}; - -class MethodDescriptor : public Descriptor { - private: - GrowableArray _parameters; - Type* _return_type; - GrowableArray _throws; - - MethodDescriptor(GrowableArray& ftp, ClassDescriptor* outer, - GrowableArray& sigs, Type* rt, GrowableArray& throws) - : Descriptor(ftp, outer), _parameters(sigs), _return_type(rt), - _throws(throws) {} - - public: - - static MethodDescriptor* parse_generic_signature(Method* m, ClassDescriptor* outer); - static MethodDescriptor* parse_generic_signature(Symbol* sym, ClassDescriptor* outer); - - MethodDescriptor* as_method_signature() { return this; } - - // Performs generic analysis on the method parameters to determine - // if both methods refer to the same argument types. - bool covariant_match(MethodDescriptor* other, Context* ctx); - - // Returns a new method descriptor with all generic variables - // removed and replaced with whatever is indicated using the Context. - MethodDescriptor* canonicalize(Context* ctx); - - void bind_variables_to_parameters(); - -#ifndef PRODUCT - TempNewSymbol reify_signature(Context* ctx, TRAPS); - void print_on(outputStream* str) const; -#endif -}; - -class TypeParameter : public ResourceObj { - private: - Identifier* _identifier; - ClassType* _class_bound; - GrowableArray _interface_bounds; - - // The position is the ordinal location of the parameter within the - // formal parameter list (excluding outer classes). It is only set for - // formal type parameters that are associated with a class -- method - // type parameters are left as -1. When resolving a generic variable to - // find the actual type, this index is used to access the generic type - // argument in the provided context object. - int _position; // Assigned during variable linking - - TypeParameter(Identifier* id, ClassType* class_bound, - GrowableArray& interface_bounds) : - _identifier(id), _class_bound(class_bound), - _interface_bounds(interface_bounds), _position(-1) {} - - public: - static TypeParameter* parse_generic_signature(DescriptorStream* str); - - ClassType* bound(); - int position() { return _position; } - - void bind_variables_to_parameters(Descriptor* sig, int position); - Identifier* identifier() { return _identifier; } - - Type* resolve(Context* ctx, int inner_depth, int ctx_depth); - TypeParameter* canonicalize(Context* ctx, int ctx_depth); - -#ifndef PRODUCT - void print_on(outputStream* str) const; -#endif -}; - -class Type : public ResourceObj { - public: - static Type* parse_generic_signature(DescriptorStream* str); - - virtual ClassType* as_class() { return NULL; } - virtual TypeVariable* as_variable() { return NULL; } - virtual ArrayType* as_array() { return NULL; } - virtual PrimitiveType* as_primitive() { return NULL; } - - virtual bool covariant_match(Type* gt, Context* ctx) = 0; - virtual Type* canonicalize(Context* ctx, int ctx_depth) = 0; - - virtual void bind_variables_to_parameters(Descriptor* sig) = 0; - -#ifndef PRODUCT - virtual void reify_signature(stringStream* ss, Context* ctx) = 0; - virtual void print_on(outputStream* str) const = 0; -#endif -}; - -class ClassType : public Type { - friend class ClassDescriptor; - protected: - Identifier* _identifier; - GrowableArray _type_arguments; - ClassType* _outer_class; - - ClassType(Identifier* identifier, - GrowableArray& args, - ClassType* outer) - : _identifier(identifier), _type_arguments(args), _outer_class(outer) {} - - // Returns true if there are inner classes to read - static Identifier* parse_generic_signature_simple( - GrowableArray* args, - bool* has_inner, DescriptorStream* str); - - static ClassType* parse_generic_signature(ClassType* outer, - DescriptorStream* str); - static ClassType* from_symbol(Symbol* sym); - - public: - ClassType* as_class() { return this; } - - static ClassType* parse_generic_signature(DescriptorStream* str); - static ClassType* java_lang_Object(); - - Identifier* identifier() { return _identifier; } - int type_arguments_length() { return _type_arguments.length(); } - TypeArgument* type_argument_at(int i); - - virtual ClassType* outer_class() { return _outer_class; } - - bool covariant_match(Type* gt, Context* ctx); - ClassType* canonicalize(Context* ctx, int context_depth); - - void bind_variables_to_parameters(Descriptor* sig); - -#ifndef PRODUCT - void reify_signature(stringStream* ss, Context* ctx); - void print_on(outputStream* str) const; -#endif -}; - -class TypeVariable : public Type { - private: - Identifier* _id; - TypeParameter* _parameter; // assigned during linking - - // how many steps "out" from inner classes, -1 if method - int _inner_depth; - - TypeVariable(Identifier* id) - : _id(id), _parameter(NULL), _inner_depth(0) {} - - public: - TypeVariable* as_variable() { return this; } - - static TypeVariable* parse_generic_signature(DescriptorStream* str); - - Identifier* identifier() { return _id; } - TypeParameter* parameter() { return _parameter; } - int inner_depth() { return _inner_depth; } - - void bind_variables_to_parameters(Descriptor* sig); - - Type* resolve(Context* ctx, int ctx_depth); - bool covariant_match(Type* gt, Context* ctx); - Type* canonicalize(Context* ctx, int ctx_depth); - -#ifndef PRODUCT - void reify_signature(stringStream* ss, Context* ctx); - void print_on(outputStream* str) const; -#endif -}; - -class ArrayType : public Type { - private: - Type* _base; - - ArrayType(Type* base) : _base(base) {} - - public: - ArrayType* as_array() { return this; } - - static ArrayType* parse_generic_signature(DescriptorStream* str); - - bool covariant_match(Type* gt, Context* ctx); - ArrayType* canonicalize(Context* ctx, int ctx_depth); - - void bind_variables_to_parameters(Descriptor* sig); - -#ifndef PRODUCT - void reify_signature(stringStream* ss, Context* ctx); - void print_on(outputStream* str) const; -#endif -}; - -class PrimitiveType : public Type { - friend class Type; - private: - char _type; // includes V for void - - PrimitiveType(char& type) : _type(type) {} - - public: - PrimitiveType* as_primitive() { return this; } - - bool covariant_match(Type* gt, Context* ctx); - PrimitiveType* canonicalize(Context* ctx, int ctx_depth); - - void bind_variables_to_parameters(Descriptor* sig); - -#ifndef PRODUCT - void reify_signature(stringStream* ss, Context* ctx); - void print_on(outputStream* str) const; -#endif -}; - -class TypeArgument : public ResourceObj { - private: - Type* _lower_bound; - Type* _upper_bound; // may be null or == _lower_bound - - TypeArgument(Type* lower_bound, Type* upper_bound) - : _lower_bound(lower_bound), _upper_bound(upper_bound) {} - - public: - - static TypeArgument* parse_generic_signature(DescriptorStream* str); - - Type* lower_bound() { return _lower_bound; } - Type* upper_bound() { return _upper_bound; } - - void bind_variables_to_parameters(Descriptor* sig); - TypeArgument* canonicalize(Context* ctx, int ctx_depth); - - bool covariant_match(TypeArgument* a, Context* ctx); - -#ifndef PRODUCT - void print_on(outputStream* str) const; -#endif -}; - - -class Context : public ResourceObj { - private: - DescriptorCache* _cache; - GrowableArray _type_arguments; - - void reset_to_mark(int size); - - public: - // When this object goes out of scope or 'destroy' is - // called, then the application of the type to the - // context is wound-back (unless it's been deactivated). - class Mark : public StackObj { - private: - mutable Context* _context; - int _marked_size; - - bool is_active() const { return _context != NULL; } - void deactivate() const { _context = NULL; } - - public: - Mark() : _context(NULL), _marked_size(0) {} - Mark(Context* ctx, int sz) : _context(ctx), _marked_size(sz) {} - Mark(const Mark& m) : _context(m._context), _marked_size(m._marked_size) { - m.deactivate(); // Ownership is transferred - } - - Mark& operator=(const Mark& cm) { - destroy(); - _context = cm._context; - _marked_size = cm._marked_size; - cm.deactivate(); - return *this; - } - - void destroy(); - ~Mark() { destroy(); } - }; - - Context(DescriptorCache* cache) : _cache(cache) {} - - Mark mark() { return Mark(this, _type_arguments.length()); } - void apply_type_arguments(InstanceKlass* current, InstanceKlass* super,TRAPS); - - ClassType* at_depth(int i) const; - -#ifndef PRODUCT - void print_on(outputStream* str) const; -#endif -}; - -/** - * Contains a cache of descriptors for classes and methods so they can be - * looked-up instead of reparsing each time they are needed. - */ -class DescriptorCache : public ResourceObj { - private: - ResourceHashtable _class_descriptors; - ResourceHashtable _method_descriptors; - - public: - ClassDescriptor* descriptor_for(InstanceKlass* ikh, TRAPS); - - MethodDescriptor* descriptor_for(Method* mh, ClassDescriptor* cd, TRAPS); - // Class descriptor derived from method holder - MethodDescriptor* descriptor_for(Method* mh, TRAPS); -}; - -} // namespace generic - -#endif // SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP - diff -r a7d8baf4cca7 -r d80493ee6430 src/share/vm/runtime/globals.hpp --- a/src/share/vm/runtime/globals.hpp Mon Aug 26 18:34:29 2013 -0700 +++ b/src/share/vm/runtime/globals.hpp Tue Aug 27 01:21:22 2013 -0700 @@ -3685,15 +3685,9 @@ develop(bool, TraceDefaultMethods, false, \ "Trace the default method processing steps") \ \ - develop(bool, ParseAllGenericSignatures, false, \ - "Parse all generic signatures while classloading") \ - \ develop(bool, VerifyGenericSignatures, false, \ "Abort VM on erroneous or inconsistent generic signatures") \ \ - product(bool, ParseGenericDefaults, false, \ - "Parse generic signatures for default method handling") \ - \ product(bool, UseVMInterruptibleIO, false, \ "(Unstable, Solaris-specific) Thread interrupt before or with " \ "EINTR for I/O operations results in OS_INTRPT. The default value"\