From e8b3b892645030d8ac0bb7f374ae1234a3d2cc44 Mon Sep 17 00:00:00 2001 From: Jon Masamitsu Date: Mon, 3 Dec 2012 15:09:39 -0800 Subject: [PATCH 001/204] 8005082: NPG: Add specialized Metachunk sizes for reflection and anonymous classloaders Reviewed-by: johnc, coleenp --- .../share/vm/classfile/classLoaderData.cpp | 19 +- .../share/vm/memory/binaryTreeDictionary.cpp | 5 +- .../src/share/vm/memory/collectorPolicy.cpp | 9 + hotspot/src/share/vm/memory/metachunk.cpp | 11 +- hotspot/src/share/vm/memory/metachunk.hpp | 14 +- hotspot/src/share/vm/memory/metaspace.cpp | 566 +++++++++++------- hotspot/src/share/vm/memory/metaspace.hpp | 18 +- hotspot/src/share/vm/runtime/globals.hpp | 3 +- 8 files changed, 419 insertions(+), 226 deletions(-) diff --git a/hotspot/src/share/vm/classfile/classLoaderData.cpp b/hotspot/src/share/vm/classfile/classLoaderData.cpp index eaf829738d0..40c397de887 100644 --- a/hotspot/src/share/vm/classfile/classLoaderData.cpp +++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp @@ -330,10 +330,19 @@ Metaspace* ClassLoaderData::metaspace_non_null() { } if (this == the_null_class_loader_data()) { assert (class_loader() == NULL, "Must be"); - size_t word_size = Metaspace::first_chunk_word_size(); - set_metaspace(new Metaspace(_metaspace_lock, word_size)); + set_metaspace(new Metaspace(_metaspace_lock, Metaspace::BootMetaspaceType)); + } else if (is_anonymous()) { + if (TraceClassLoaderData && Verbose && class_loader() != NULL) { + tty->print_cr("is_anonymous: %s", class_loader()->klass()->internal_name()); + } + set_metaspace(new Metaspace(_metaspace_lock, Metaspace::AnonymousMetaspaceType)); + } else if (class_loader()->is_a(SystemDictionary::reflect_DelegatingClassLoader_klass())) { + if (TraceClassLoaderData && Verbose && class_loader() != NULL) { + tty->print_cr("is_reflection: %s", class_loader()->klass()->internal_name()); + } + set_metaspace(new Metaspace(_metaspace_lock, Metaspace::ReflectionMetaspaceType)); } else { - set_metaspace(new Metaspace(_metaspace_lock)); // default size for now. + set_metaspace(new Metaspace(_metaspace_lock, Metaspace::StandardMetaspaceType)); } } return _metaspace; @@ -672,8 +681,8 @@ void ClassLoaderData::initialize_shared_metaspaces() { "only supported for null loader data for now"); assert (!_shared_metaspaces_initialized, "only initialize once"); MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag); - _ro_metaspace = new Metaspace(_metaspace_lock, SharedReadOnlySize/wordSize); - _rw_metaspace = new Metaspace(_metaspace_lock, SharedReadWriteSize/wordSize); + _ro_metaspace = new Metaspace(_metaspace_lock, Metaspace::ROMetaspaceType); + _rw_metaspace = new Metaspace(_metaspace_lock, Metaspace::ReadWriteMetaspaceType); _shared_metaspaces_initialized = true; } diff --git a/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp index a08a389f8dc..725a71925dc 100644 --- a/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp +++ b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp @@ -67,7 +67,8 @@ void TreeChunk::verify_tree_chunk_list() const { } template class FreeList_t> -TreeList::TreeList() {} +TreeList::TreeList() : _parent(NULL), + _left(NULL), _right(NULL) {} template class FreeList_t> TreeList* @@ -82,7 +83,7 @@ TreeList::as_TreeList(TreeChunk* tc) { tl->link_head(tc); tl->link_tail(tc); tl->set_count(1); - + assert(tl->parent() == NULL, "Should be clear"); return tl; } diff --git a/hotspot/src/share/vm/memory/collectorPolicy.cpp b/hotspot/src/share/vm/memory/collectorPolicy.cpp index c6eee674d27..6857181a5be 100644 --- a/hotspot/src/share/vm/memory/collectorPolicy.cpp +++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp @@ -777,6 +777,15 @@ MetaWord* CollectorPolicy::satisfy_failed_metadata_allocation( full_gc_count, GCCause::_metadata_GC_threshold); VMThread::execute(&op); + + // If GC was locked out, try again. Check + // before checking success because the prologue + // could have succeeded and the GC still have + // been locked out. + if (op.gc_locked()) { + continue; + } + if (op.prologue_succeeded()) { return op.result(); } diff --git a/hotspot/src/share/vm/memory/metachunk.cpp b/hotspot/src/share/vm/memory/metachunk.cpp index 3b71a1165ef..4cb955862a8 100644 --- a/hotspot/src/share/vm/memory/metachunk.cpp +++ b/hotspot/src/share/vm/memory/metachunk.cpp @@ -56,6 +56,7 @@ Metachunk* Metachunk::initialize(MetaWord* ptr, size_t word_size) { assert(chunk_end > chunk_bottom, "Chunk must be too small"); chunk->set_end(chunk_end); chunk->set_next(NULL); + chunk->set_prev(NULL); chunk->set_word_size(word_size); #ifdef ASSERT size_t data_word_size = pointer_delta(chunk_end, chunk_bottom, sizeof(MetaWord)); @@ -76,15 +77,15 @@ MetaWord* Metachunk::allocate(size_t word_size) { } // _bottom points to the start of the chunk including the overhead. -size_t Metachunk::used_word_size() { +size_t Metachunk::used_word_size() const { return pointer_delta(_top, _bottom, sizeof(MetaWord)); } -size_t Metachunk::free_word_size() { +size_t Metachunk::free_word_size() const { return pointer_delta(_end, _top, sizeof(MetaWord)); } -size_t Metachunk::capacity_word_size() { +size_t Metachunk::capacity_word_size() const { return pointer_delta(_end, _bottom, sizeof(MetaWord)); } @@ -93,6 +94,10 @@ void Metachunk::print_on(outputStream* st) const { " bottom " PTR_FORMAT " top " PTR_FORMAT " end " PTR_FORMAT " size " SIZE_FORMAT, bottom(), top(), end(), word_size()); + if (Verbose) { + st->print_cr(" used " SIZE_FORMAT " free " SIZE_FORMAT, + used_word_size(), free_word_size()); + } } #ifndef PRODUCT diff --git a/hotspot/src/share/vm/memory/metachunk.hpp b/hotspot/src/share/vm/memory/metachunk.hpp index 693532d9da0..a10cba8dbbe 100644 --- a/hotspot/src/share/vm/memory/metachunk.hpp +++ b/hotspot/src/share/vm/memory/metachunk.hpp @@ -67,9 +67,11 @@ class Metachunk VALUE_OBJ_CLASS_SPEC { void set_word_size(size_t v) { _word_size = v; } public: #ifdef ASSERT - Metachunk() : _bottom(NULL), _end(NULL), _top(NULL), _is_free(false) {} + Metachunk() : _bottom(NULL), _end(NULL), _top(NULL), _is_free(false), + _next(NULL), _prev(NULL) {} #else - Metachunk() : _bottom(NULL), _end(NULL), _top(NULL) {} + Metachunk() : _bottom(NULL), _end(NULL), _top(NULL), + _next(NULL), _prev(NULL) {} #endif // Used to add a Metachunk to a list of Metachunks @@ -102,15 +104,15 @@ class Metachunk VALUE_OBJ_CLASS_SPEC { } // Reset top to bottom so chunk can be reused. - void reset_empty() { _top = (_bottom + _overhead); } + void reset_empty() { _top = (_bottom + _overhead); _next = NULL; _prev = NULL; } bool is_empty() { return _top == (_bottom + _overhead); } // used (has been allocated) // free (available for future allocations) // capacity (total size of chunk) - size_t used_word_size(); - size_t free_word_size(); - size_t capacity_word_size(); + size_t used_word_size() const; + size_t free_word_size() const; + size_t capacity_word_size()const; // Debug support #ifdef ASSERT diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 6c0b4210faa..c914adbbb78 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -58,11 +58,23 @@ MetaWord* last_allocated = 0; // Used in declarations in SpaceManager and ChunkManager enum ChunkIndex { - SmallIndex = 0, - MediumIndex = 1, - HumongousIndex = 2, - NumberOfFreeLists = 2, - NumberOfInUseLists = 3 + ZeroIndex = 0, + SpecializedIndex = ZeroIndex, + SmallIndex = SpecializedIndex + 1, + MediumIndex = SmallIndex + 1, + HumongousIndex = MediumIndex + 1, + NumberOfFreeLists = 3, + NumberOfInUseLists = 4 +}; + +enum ChunkSizes { // in words. + ClassSpecializedChunk = 128, + SpecializedChunk = 128, + ClassSmallChunk = 256, + SmallChunk = 512, + ClassMediumChunk = 1 * K, + MediumChunk = 8 * K, + HumongousChunkGranularity = 8 }; static ChunkIndex next_chunk_index(ChunkIndex i) { @@ -126,6 +138,7 @@ class ChunkManager VALUE_OBJ_CLASS_SPEC { // HumongousChunk ChunkList _free_chunks[NumberOfFreeLists]; + // HumongousChunk ChunkTreeDictionary _humongous_dictionary; @@ -169,6 +182,10 @@ class ChunkManager VALUE_OBJ_CLASS_SPEC { Metachunk* chunk_freelist_allocate(size_t word_size); void chunk_freelist_deallocate(Metachunk* chunk); + // Map a size to a list index assuming that there are lists + // for special, small, medium, and humongous chunks. + static ChunkIndex list_index(size_t size); + // Total of the space in the free chunks list size_t free_chunks_total(); size_t free_chunks_total_in_bytes(); @@ -180,8 +197,6 @@ class ChunkManager VALUE_OBJ_CLASS_SPEC { Atomic::add_ptr(count, &_free_chunks_count); Atomic::add_ptr(v, &_free_chunks_total); } - ChunkList* free_medium_chunks() { return &_free_chunks[1]; } - ChunkList* free_small_chunks() { return &_free_chunks[0]; } ChunkTreeDictionary* humongous_dictionary() { return &_humongous_dictionary; } @@ -400,7 +415,14 @@ class VirtualSpaceList : public CHeapObj { VirtualSpaceList(size_t word_size); VirtualSpaceList(ReservedSpace rs); - Metachunk* get_new_chunk(size_t word_size, size_t grow_chunks_by_words); + Metachunk* get_new_chunk(size_t word_size, + size_t grow_chunks_by_words, + size_t medium_chunk_bunch); + + // Get the first chunk for a Metaspace. Used for + // special cases such as the boot class loader, reflection + // class loader and anonymous class loader. + Metachunk* get_initialization_chunk(size_t word_size, size_t chunk_bunch); VirtualSpaceNode* current_virtual_space() { return _current_virtual_space; @@ -501,9 +523,13 @@ class SpaceManager : public CHeapObj { friend class Metadebug; private: + // protects allocations and contains. Mutex* const _lock; + // Chunk related size + size_t _medium_chunk_bunch; + // List of chunks in use by this SpaceManager. Allocations // are done from the current chunk. The list is used for deallocating // chunks when the SpaceManager is freed. @@ -532,6 +558,7 @@ class SpaceManager : public CHeapObj { static const int _expand_lock_rank; static Mutex* const _expand_lock; + private: // Accessors Metachunk* chunks_in_use(ChunkIndex index) const { return _chunks_in_use[index]; } void set_chunks_in_use(ChunkIndex index, Metachunk* v) { _chunks_in_use[index] = v; } @@ -554,23 +581,37 @@ class SpaceManager : public CHeapObj { Mutex* lock() const { return _lock; } + const char* chunk_size_name(ChunkIndex index) const; + + protected: + void initialize(); + public: - SpaceManager(Mutex* lock, VirtualSpaceList* vs_list); + SpaceManager(Mutex* lock, + VirtualSpaceList* vs_list); ~SpaceManager(); - enum ChunkSizes { // in words. - SmallChunk = 512, - MediumChunk = 8 * K, - MediumChunkBunch = 4 * MediumChunk + enum ChunkMultiples { + MediumChunkMultiple = 4 }; // Accessors + size_t specialized_chunk_size() { return SpecializedChunk; } + size_t small_chunk_size() { return (size_t) vs_list()->is_class() ? ClassSmallChunk : SmallChunk; } + size_t medium_chunk_size() { return (size_t) vs_list()->is_class() ? ClassMediumChunk : MediumChunk; } + size_t medium_chunk_bunch() { return medium_chunk_size() * MediumChunkMultiple; } + size_t allocation_total() const { return _allocation_total; } void inc_allocation_total(size_t v) { Atomic::add_ptr(v, &_allocation_total); } - static bool is_humongous(size_t word_size) { return word_size > MediumChunk; } + bool is_humongous(size_t word_size) { return word_size > medium_chunk_size(); } static Mutex* expand_lock() { return _expand_lock; } + // Set the sizes for the initial chunks. + void get_initial_chunk_sizes(Metaspace::MetaspaceType type, + size_t* chunk_word_size, + size_t* class_chunk_word_size); + size_t sum_capacity_in_chunks_in_use() const; size_t sum_used_in_chunks_in_use() const; size_t sum_free_in_chunks_in_use() const; @@ -580,6 +621,8 @@ class SpaceManager : public CHeapObj { size_t sum_count_in_chunks_in_use(); size_t sum_count_in_chunks_in_use(ChunkIndex i); + Metachunk* get_new_chunk(size_t word_size, size_t grow_chunks_by_words); + // Block allocation and deallocation. // Allocates a block from the current chunk MetaWord* allocate(size_t word_size); @@ -772,8 +815,10 @@ bool VirtualSpaceNode::initialize() { return false; } - // Commit only 1 page instead of the whole reserved space _rs.size() - size_t committed_byte_size = os::vm_page_size(); + // An allocation out of this Virtualspace that is larger + // than an initial commit size can waste that initial committed + // space. + size_t committed_byte_size = 0; bool result = virtual_space()->initialize(_rs, committed_byte_size); if (result) { set_top((MetaWord*)virtual_space()->low()); @@ -799,7 +844,8 @@ void VirtualSpaceNode::print_on(outputStream* st) const { st->print_cr(" space @ " PTR_FORMAT " " SIZE_FORMAT "K, %3d%% used " "[" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT ")", - vs, capacity / K, used * 100 / capacity, + vs, capacity / K, + capacity == 0 ? 0 : used * 100 / capacity, bottom(), top(), end(), vs->high_boundary()); } @@ -922,7 +968,8 @@ void VirtualSpaceList::link_vs(VirtualSpaceNode* new_entry, size_t vs_word_size) } Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size, - size_t grow_chunks_by_words) { + size_t grow_chunks_by_words, + size_t medium_chunk_bunch) { // Get a chunk from the chunk freelist Metachunk* next = chunk_manager()->chunk_freelist_allocate(grow_chunks_by_words); @@ -935,8 +982,8 @@ Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size, if (next == NULL) { // Not enough room in current virtual space. Try to commit // more space. - size_t expand_vs_by_words = MAX2((size_t)SpaceManager::MediumChunkBunch, - grow_chunks_by_words); + size_t expand_vs_by_words = MAX2(medium_chunk_bunch, + grow_chunks_by_words); size_t page_size_words = os::vm_page_size() / BytesPerWord; size_t aligned_expand_vs_by_words = align_size_up(expand_vs_by_words, page_size_words); @@ -954,12 +1001,6 @@ Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size, // Got it. It's on the list now. Get a chunk from it. next = current_virtual_space()->get_chunk_vs_with_expand(grow_chunks_by_words); } - if (TraceMetadataHumongousAllocation && SpaceManager::is_humongous(word_size)) { - gclog_or_tty->print_cr(" aligned_expand_vs_by_words " PTR_FORMAT, - aligned_expand_vs_by_words); - gclog_or_tty->print_cr(" grow_vs_words " PTR_FORMAT, - grow_vs_words); - } } else { // Allocation will fail and induce a GC if (TraceMetadataChunkAllocation && Verbose) { @@ -974,9 +1015,20 @@ Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size, } } + assert(next == NULL || (next->next() == NULL && next->prev() == NULL), + "New chunk is still on some list"); return next; } +Metachunk* VirtualSpaceList::get_initialization_chunk(size_t chunk_word_size, + size_t chunk_bunch) { + // Get a chunk from the chunk freelist + Metachunk* new_chunk = get_new_chunk(chunk_word_size, + chunk_word_size, + chunk_bunch); + return new_chunk; +} + void VirtualSpaceList::print_on(outputStream* st) const { if (TraceMetadataChunkAllocation && Verbose) { VirtualSpaceListIterator iter(virtual_space_list()); @@ -1373,16 +1425,17 @@ size_t ChunkList::sum_list_capacity() { void ChunkList::add_at_head(Metachunk* head, Metachunk* tail) { assert_lock_strong(SpaceManager::expand_lock()); - assert(tail->next() == NULL, "Not the tail"); + assert(head == tail || tail->next() == NULL, + "Not the tail or the head has already been added to a list"); if (TraceMetadataChunkAllocation && Verbose) { - tty->print("ChunkList::add_at_head: "); + gclog_or_tty->print("ChunkList::add_at_head(head, tail): "); Metachunk* cur = head; while (cur != NULL) { - tty->print(PTR_FORMAT " (" SIZE_FORMAT ") ", cur, cur->word_size()); + gclog_or_tty->print(PTR_FORMAT " (" SIZE_FORMAT ") ", cur, cur->word_size()); cur = cur->next(); } - tty->print_cr(""); + gclog_or_tty->print_cr(""); } if (tail != NULL) { @@ -1486,13 +1539,13 @@ void ChunkManager::locked_verify() { void ChunkManager::locked_print_free_chunks(outputStream* st) { assert_lock_strong(SpaceManager::expand_lock()); - st->print_cr("Free chunk total 0x%x count 0x%x", + st->print_cr("Free chunk total " SIZE_FORMAT " count " SIZE_FORMAT, _free_chunks_total, _free_chunks_count); } void ChunkManager::locked_print_sum_free_chunks(outputStream* st) { assert_lock_strong(SpaceManager::expand_lock()); - st->print_cr("Sum free chunk total 0x%x count 0x%x", + st->print_cr("Sum free chunk total " SIZE_FORMAT " count " SIZE_FORMAT, sum_free_chunks(), sum_free_chunks_count()); } ChunkList* ChunkManager::free_chunks(ChunkIndex index) { @@ -1504,7 +1557,7 @@ ChunkList* ChunkManager::free_chunks(ChunkIndex index) { size_t ChunkManager::sum_free_chunks() { assert_lock_strong(SpaceManager::expand_lock()); size_t result = 0; - for (ChunkIndex i = SmallIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) { + for (ChunkIndex i = ZeroIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) { ChunkList* list = free_chunks(i); if (list == NULL) { @@ -1520,7 +1573,7 @@ size_t ChunkManager::sum_free_chunks() { size_t ChunkManager::sum_free_chunks_count() { assert_lock_strong(SpaceManager::expand_lock()); size_t count = 0; - for (ChunkIndex i = SmallIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) { + for (ChunkIndex i = ZeroIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) { ChunkList* list = free_chunks(i); if (list == NULL) { continue; @@ -1532,15 +1585,9 @@ size_t ChunkManager::sum_free_chunks_count() { } ChunkList* ChunkManager::find_free_chunks_list(size_t word_size) { - switch (word_size) { - case SpaceManager::SmallChunk : - return &_free_chunks[0]; - case SpaceManager::MediumChunk : - return &_free_chunks[1]; - default: - assert(word_size > SpaceManager::MediumChunk, "List inconsistency"); - return &_free_chunks[2]; - } + ChunkIndex index = list_index(word_size); + assert(index < HumongousIndex, "No humongous list"); + return free_chunks(index); } void ChunkManager::free_chunks_put(Metachunk* chunk) { @@ -1574,7 +1621,7 @@ Metachunk* ChunkManager::free_chunks_get(size_t word_size) { slow_locked_verify(); Metachunk* chunk = NULL; - if (!SpaceManager::is_humongous(word_size)) { + if (list_index(word_size) != HumongousIndex) { ChunkList* free_list = find_free_chunks_list(word_size); assert(free_list != NULL, "Sanity check"); @@ -1587,8 +1634,8 @@ Metachunk* ChunkManager::free_chunks_get(size_t word_size) { // Remove the chunk as the head of the list. free_list->set_head(chunk->next()); - chunk->set_next(NULL); - // Chunk has been removed from the chunks free list. + + // Chunk is being removed from the chunks free list. dec_free_chunks_total(chunk->capacity_word_size()); if (TraceMetadataChunkAllocation && Verbose) { @@ -1614,8 +1661,14 @@ Metachunk* ChunkManager::free_chunks_get(size_t word_size) { #ifdef ASSERT chunk->set_is_free(false); #endif + } else { + return NULL; } } + + // Remove it from the links to this freelist + chunk->set_next(NULL); + chunk->set_prev(NULL); slow_locked_verify(); return chunk; } @@ -1630,13 +1683,20 @@ Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) { return NULL; } - assert(word_size <= chunk->word_size() || - SpaceManager::is_humongous(chunk->word_size()), - "Non-humongous variable sized chunk"); + assert((word_size <= chunk->word_size()) || + list_index(chunk->word_size() == HumongousIndex), + "Non-humongous variable sized chunk"); if (TraceMetadataChunkAllocation) { - tty->print("ChunkManager::chunk_freelist_allocate: chunk " - PTR_FORMAT " size " SIZE_FORMAT " ", - chunk, chunk->word_size()); + size_t list_count; + if (list_index(word_size) < HumongousIndex) { + ChunkList* list = find_free_chunks_list(word_size); + list_count = list->sum_list_count(); + } else { + list_count = humongous_dictionary()->total_count(); + } + tty->print("ChunkManager::chunk_freelist_allocate: " PTR_FORMAT " chunk " + PTR_FORMAT " size " SIZE_FORMAT " count " SIZE_FORMAT " ", + this, chunk, chunk->word_size(), list_count); locked_print_free_chunks(tty); } @@ -1651,10 +1711,42 @@ void ChunkManager::print_on(outputStream* out) { // SpaceManager methods +void SpaceManager::get_initial_chunk_sizes(Metaspace::MetaspaceType type, + size_t* chunk_word_size, + size_t* class_chunk_word_size) { + switch (type) { + case Metaspace::BootMetaspaceType: + *chunk_word_size = Metaspace::first_chunk_word_size(); + *class_chunk_word_size = Metaspace::first_class_chunk_word_size(); + break; + case Metaspace::ROMetaspaceType: + *chunk_word_size = SharedReadOnlySize / wordSize; + *class_chunk_word_size = ClassSpecializedChunk; + break; + case Metaspace::ReadWriteMetaspaceType: + *chunk_word_size = SharedReadWriteSize / wordSize; + *class_chunk_word_size = ClassSpecializedChunk; + break; + case Metaspace::AnonymousMetaspaceType: + case Metaspace::ReflectionMetaspaceType: + *chunk_word_size = SpecializedChunk; + *class_chunk_word_size = ClassSpecializedChunk; + break; + default: + *chunk_word_size = SmallChunk; + *class_chunk_word_size = ClassSmallChunk; + break; + } + assert(chunk_word_size != 0 && class_chunk_word_size != 0, + err_msg("Initial chunks sizes bad: data " SIZE_FORMAT + " class " SIZE_FORMAT, + chunk_word_size, class_chunk_word_size)); +} + size_t SpaceManager::sum_free_in_chunks_in_use() const { MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); size_t free = 0; - for (ChunkIndex i = SmallIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { + for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { Metachunk* chunk = chunks_in_use(i); while (chunk != NULL) { free += chunk->free_word_size(); @@ -1667,9 +1759,7 @@ size_t SpaceManager::sum_free_in_chunks_in_use() const { size_t SpaceManager::sum_waste_in_chunks_in_use() const { MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); size_t result = 0; - for (ChunkIndex i = SmallIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { - - + for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { result += sum_waste_in_chunks_in_use(i); } @@ -1678,7 +1768,6 @@ size_t SpaceManager::sum_waste_in_chunks_in_use() const { size_t SpaceManager::sum_waste_in_chunks_in_use(ChunkIndex index) const { size_t result = 0; - size_t count = 0; Metachunk* chunk = chunks_in_use(index); // Count the free space in all the chunk but not the // current chunk from which allocations are still being done. @@ -1688,7 +1777,6 @@ size_t SpaceManager::sum_waste_in_chunks_in_use(ChunkIndex index) const { result += chunk->free_word_size(); prev = chunk; chunk = chunk->next(); - count++; } } return result; @@ -1697,7 +1785,7 @@ size_t SpaceManager::sum_waste_in_chunks_in_use(ChunkIndex index) const { size_t SpaceManager::sum_capacity_in_chunks_in_use() const { MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); size_t sum = 0; - for (ChunkIndex i = SmallIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { + for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { Metachunk* chunk = chunks_in_use(i); while (chunk != NULL) { // Just changed this sum += chunk->capacity_word_size(); @@ -1711,7 +1799,7 @@ size_t SpaceManager::sum_capacity_in_chunks_in_use() const { size_t SpaceManager::sum_count_in_chunks_in_use() { size_t count = 0; - for (ChunkIndex i = SmallIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { + for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { count = count + sum_count_in_chunks_in_use(i); } @@ -1732,7 +1820,7 @@ size_t SpaceManager::sum_count_in_chunks_in_use(ChunkIndex i) { size_t SpaceManager::sum_used_in_chunks_in_use() const { MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); size_t used = 0; - for (ChunkIndex i = SmallIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { + for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { Metachunk* chunk = chunks_in_use(i); while (chunk != NULL) { used += chunk->used_word_size(); @@ -1744,19 +1832,17 @@ size_t SpaceManager::sum_used_in_chunks_in_use() const { void SpaceManager::locked_print_chunks_in_use_on(outputStream* st) const { - Metachunk* small_chunk = chunks_in_use(SmallIndex); - st->print_cr("SpaceManager: small chunk " PTR_FORMAT - " free " SIZE_FORMAT, - small_chunk, - small_chunk->free_word_size()); - - Metachunk* medium_chunk = chunks_in_use(MediumIndex); - st->print("medium chunk " PTR_FORMAT, medium_chunk); - Metachunk* tail = current_chunk(); - st->print_cr(" current chunk " PTR_FORMAT, tail); - - Metachunk* head = chunks_in_use(HumongousIndex); - st->print_cr("humongous chunk " PTR_FORMAT, head); + for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { + Metachunk* chunk = chunks_in_use(i); + st->print("SpaceManager: %s " PTR_FORMAT, + chunk_size_name(i), chunk); + if (chunk != NULL) { + st->print_cr(" free " SIZE_FORMAT, + chunk->free_word_size()); + } else { + st->print_cr(""); + } + } vs_list()->chunk_manager()->locked_print_free_chunks(st); vs_list()->chunk_manager()->locked_print_sum_free_chunks(st); @@ -1772,18 +1858,28 @@ size_t SpaceManager::calc_chunk_size(size_t word_size) { if (chunks_in_use(MediumIndex) == NULL && (!has_small_chunk_limit() || sum_count_in_chunks_in_use(SmallIndex) < _small_chunk_limit)) { - chunk_word_size = (size_t) SpaceManager::SmallChunk; - if (word_size + Metachunk::overhead() > SpaceManager::SmallChunk) { - chunk_word_size = MediumChunk; + chunk_word_size = (size_t) small_chunk_size(); + if (word_size + Metachunk::overhead() > small_chunk_size()) { + chunk_word_size = medium_chunk_size(); } } else { - chunk_word_size = MediumChunk; + chunk_word_size = medium_chunk_size(); } - // Might still need a humongous chunk + // Might still need a humongous chunk. Enforce an + // eight word granularity to facilitate reuse (some + // wastage but better chance of reuse). + size_t if_humongous_sized_chunk = + align_size_up(word_size + Metachunk::overhead(), + HumongousChunkGranularity); chunk_word_size = - MAX2((size_t) chunk_word_size, word_size + Metachunk::overhead()); + MAX2((size_t) chunk_word_size, if_humongous_sized_chunk); + assert(!SpaceManager::is_humongous(word_size) || + chunk_word_size == if_humongous_sized_chunk, + err_msg("Size calculation is wrong, word_size " SIZE_FORMAT + " chunk_word_size " SIZE_FORMAT, + word_size, chunk_word_size)); if (TraceMetadataHumongousAllocation && SpaceManager::is_humongous(word_size)) { gclog_or_tty->print_cr("Metadata humongous allocation:"); @@ -1805,15 +1901,21 @@ MetaWord* SpaceManager::grow_and_allocate(size_t word_size) { MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); if (TraceMetadataChunkAllocation && Verbose) { + size_t words_left = 0; + size_t words_used = 0; + if (current_chunk() != NULL) { + words_left = current_chunk()->free_word_size(); + words_used = current_chunk()->used_word_size(); + } gclog_or_tty->print_cr("SpaceManager::grow_and_allocate for " SIZE_FORMAT - " words " SIZE_FORMAT " space left", - word_size, current_chunk() != NULL ? - current_chunk()->free_word_size() : 0); + " words " SIZE_FORMAT " words used " SIZE_FORMAT + " words left", + word_size, words_used, words_left); } // Get another chunk out of the virtual space size_t grow_chunks_by_words = calc_chunk_size(word_size); - Metachunk* next = vs_list()->get_new_chunk(word_size, grow_chunks_by_words); + Metachunk* next = get_new_chunk(word_size, grow_chunks_by_words); // If a chunk was available, add it to the in-use chunk list // and do an allocation from it. @@ -1828,7 +1930,7 @@ MetaWord* SpaceManager::grow_and_allocate(size_t word_size) { void SpaceManager::print_on(outputStream* st) const { - for (ChunkIndex i = SmallIndex; + for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists ; i = next_chunk_index(i) ) { st->print_cr(" chunks_in_use " PTR_FORMAT " chunk size " PTR_FORMAT, @@ -1847,12 +1949,18 @@ void SpaceManager::print_on(outputStream* st) const { } } -SpaceManager::SpaceManager(Mutex* lock, VirtualSpaceList* vs_list) : +SpaceManager::SpaceManager(Mutex* lock, + VirtualSpaceList* vs_list) : _vs_list(vs_list), _allocation_total(0), - _lock(lock) { + _lock(lock) +{ + initialize(); +} + +void SpaceManager::initialize() { Metadebug::init_allocation_fail_alot_count(); - for (ChunkIndex i = SmallIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { + for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { _chunks_in_use[i] = NULL; } _current_chunk = NULL; @@ -1885,30 +1993,37 @@ SpaceManager::~SpaceManager() { // Add all the chunks in use by this space manager // to the global list of free chunks. - // Small chunks. There is one _current_chunk for each - // Metaspace. It could point to a small or medium chunk. - // Rather than determine which it is, follow the list of - // small chunks to add them to the free list - Metachunk* small_chunk = chunks_in_use(SmallIndex); - chunk_manager->free_small_chunks()->add_at_head(small_chunk); - set_chunks_in_use(SmallIndex, NULL); + // Follow each list of chunks-in-use and add them to the + // free lists. Each list is NULL terminated. - // After the small chunk are the medium chunks - Metachunk* medium_chunk = chunks_in_use(MediumIndex); - assert(medium_chunk == NULL || - medium_chunk->word_size() == MediumChunk, - "Chunk is on the wrong list"); - - if (medium_chunk != NULL) { - Metachunk* head = medium_chunk; - // If there is a medium chunk then the _current_chunk can only - // point to the last medium chunk. - Metachunk* tail = current_chunk(); - chunk_manager->free_medium_chunks()->add_at_head(head, tail); - set_chunks_in_use(MediumIndex, NULL); + for (ChunkIndex i = ZeroIndex; i < HumongousIndex; i = next_chunk_index(i)) { + if (TraceMetadataChunkAllocation && Verbose) { + gclog_or_tty->print_cr("returned %d %s chunks to freelist", + sum_count_in_chunks_in_use(i), + chunk_size_name(i)); + } + Metachunk* chunks = chunks_in_use(i); + chunk_manager->free_chunks(i)->add_at_head(chunks); + set_chunks_in_use(i, NULL); + if (TraceMetadataChunkAllocation && Verbose) { + gclog_or_tty->print_cr("updated freelist count %d %s", + chunk_manager->free_chunks(i)->sum_list_count(), + chunk_size_name(i)); + } + assert(i != HumongousIndex, "Humongous chunks are handled explicitly later"); } + // The medium chunk case may be optimized by passing the head and + // tail of the medium chunk list to add_at_head(). The tail is often + // the current chunk but there are probably exceptions. + // Humongous chunks + if (TraceMetadataChunkAllocation && Verbose) { + gclog_or_tty->print_cr("returned %d %s humongous chunks to dictionary", + sum_count_in_chunks_in_use(HumongousIndex), + chunk_size_name(HumongousIndex)); + gclog_or_tty->print("Humongous chunk dictionary: "); + } // Humongous chunks are never the current chunk. Metachunk* humongous_chunks = chunks_in_use(HumongousIndex); @@ -1916,14 +2031,65 @@ SpaceManager::~SpaceManager() { #ifdef ASSERT humongous_chunks->set_is_free(true); #endif + if (TraceMetadataChunkAllocation && Verbose) { + gclog_or_tty->print(PTR_FORMAT " (" SIZE_FORMAT ") ", + humongous_chunks, + humongous_chunks->word_size()); + } + assert(humongous_chunks->word_size() == (size_t) + align_size_up(humongous_chunks->word_size(), + HumongousChunkGranularity), + err_msg("Humongous chunk size is wrong: word size " SIZE_FORMAT + " granularity " SIZE_FORMAT, + humongous_chunks->word_size(), HumongousChunkGranularity)); Metachunk* next_humongous_chunks = humongous_chunks->next(); chunk_manager->humongous_dictionary()->return_chunk(humongous_chunks); humongous_chunks = next_humongous_chunks; } + if (TraceMetadataChunkAllocation && Verbose) { + gclog_or_tty->print_cr(""); + gclog_or_tty->print_cr("updated dictionary count %d %s", + chunk_manager->humongous_dictionary()->total_count(), + chunk_size_name(HumongousIndex)); + } set_chunks_in_use(HumongousIndex, NULL); chunk_manager->slow_locked_verify(); } +const char* SpaceManager::chunk_size_name(ChunkIndex index) const { + switch (index) { + case SpecializedIndex: + return "Specialized"; + case SmallIndex: + return "Small"; + case MediumIndex: + return "Medium"; + case HumongousIndex: + return "Humongous"; + default: + return NULL; + } +} + +ChunkIndex ChunkManager::list_index(size_t size) { + switch (size) { + case SpecializedChunk: + assert(SpecializedChunk == ClassSpecializedChunk, + "Need branch for ClassSpecializedChunk"); + return SpecializedIndex; + case SmallChunk: + case ClassSmallChunk: + return SmallIndex; + case MediumChunk: + case ClassMediumChunk: + return MediumIndex; + default: + assert(size > MediumChunk && size > ClassMediumChunk, + "Not a humongous chunk"); + return HumongousIndex; + } +} + void SpaceManager::deallocate(MetaWord* p, size_t word_size) { assert_lock_strong(_lock); size_t min_size = TreeChunk::min_size(); @@ -1942,52 +2108,13 @@ void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) { // Find the correct list and and set the current // chunk for that list. - switch (new_chunk->word_size()) { - case SpaceManager::SmallChunk : - if (chunks_in_use(SmallIndex) == NULL) { - // First chunk to add to the list - set_chunks_in_use(SmallIndex, new_chunk); - } else { - assert(current_chunk()->word_size() == SpaceManager::SmallChunk, - err_msg( "Incorrect mix of sizes in chunk list " - SIZE_FORMAT " new chunk " SIZE_FORMAT, - current_chunk()->word_size(), new_chunk->word_size())); - current_chunk()->set_next(new_chunk); - } - // Make current chunk - set_current_chunk(new_chunk); - break; - case SpaceManager::MediumChunk : - if (chunks_in_use(MediumIndex) == NULL) { - // About to add the first medium chunk so teminate the - // small chunk list. In general once medium chunks are - // being added, we're past the need for small chunks. - if (current_chunk() != NULL) { - // Only a small chunk or the initial chunk could be - // the current chunk if this is the first medium chunk. - assert(current_chunk()->word_size() == SpaceManager::SmallChunk || - chunks_in_use(SmallIndex) == NULL, - err_msg("Should be a small chunk or initial chunk, current chunk " - SIZE_FORMAT " new chunk " SIZE_FORMAT, - current_chunk()->word_size(), new_chunk->word_size())); - current_chunk()->set_next(NULL); - } - // First chunk to add to the list - set_chunks_in_use(MediumIndex, new_chunk); + ChunkIndex index = ChunkManager::list_index(new_chunk->word_size()); - } else { - // As a minimum the first medium chunk added would - // have become the _current_chunk - // so the _current_chunk has to be non-NULL here - // (although not necessarily still the first medium chunk). - assert(current_chunk()->word_size() == SpaceManager::MediumChunk, - "A medium chunk should the current chunk"); - current_chunk()->set_next(new_chunk); - } - // Make current chunk + if (index != HumongousIndex) { set_current_chunk(new_chunk); - break; - default: { + new_chunk->set_next(chunks_in_use(index)); + set_chunks_in_use(index, new_chunk); + } else { // For null class loader data and DumpSharedSpaces, the first chunk isn't // small, so small will be null. Link this first chunk as the current // chunk. @@ -2004,7 +2131,6 @@ void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) { assert(new_chunk->word_size() > MediumChunk, "List inconsistency"); } - } assert(new_chunk->is_empty(), "Not ready for reuse"); if (TraceMetadataChunkAllocation && Verbose) { @@ -2015,6 +2141,22 @@ void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) { } } +Metachunk* SpaceManager::get_new_chunk(size_t word_size, + size_t grow_chunks_by_words) { + + Metachunk* next = vs_list()->get_new_chunk(word_size, + grow_chunks_by_words, + medium_chunk_bunch()); + + if (TraceMetadataHumongousAllocation && + SpaceManager::is_humongous(next->word_size())) { + gclog_or_tty->print_cr(" new humongous chunk word size " PTR_FORMAT, + next->word_size()); + } + + return next; +} + MetaWord* SpaceManager::allocate(size_t word_size) { MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag); @@ -2090,12 +2232,7 @@ void SpaceManager::verify() { // verfication of chunks does not work since // being in the dictionary alters a chunk. if (block_freelists()->total_size() == 0) { - // Skip the small chunks because their next link points to - // medium chunks. This is because the small chunk is the - // current chunk (for allocations) until it is full and the - // the addition of the next chunk does not NULL the next - // like of the small chunk. - for (ChunkIndex i = MediumIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { + for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) { Metachunk* curr = chunks_in_use(i); while (curr != NULL) { curr->verify(); @@ -2108,15 +2245,15 @@ void SpaceManager::verify() { void SpaceManager::verify_chunk_size(Metachunk* chunk) { assert(is_humongous(chunk->word_size()) || - chunk->word_size() == MediumChunk || - chunk->word_size() == SmallChunk, + chunk->word_size() == medium_chunk_size() || + chunk->word_size() == small_chunk_size() || + chunk->word_size() == specialized_chunk_size(), "Chunk size is wrong"); return; } #ifdef ASSERT void SpaceManager::verify_allocation_total() { -#if 0 // Verification is only guaranteed at a safepoint. if (SafepointSynchronize::is_at_safepoint()) { gclog_or_tty->print_cr("Chunk " PTR_FORMAT " allocation_total " SIZE_FORMAT @@ -2129,7 +2266,6 @@ void SpaceManager::verify_allocation_total() { assert(allocation_total() == sum_used_in_chunks_in_use(), err_msg("allocation total is not consistent %d vs %d", allocation_total(), sum_used_in_chunks_in_use())); -#endif } #endif @@ -2142,7 +2278,7 @@ void SpaceManager::dump(outputStream* const out) const { size_t capacity = 0; // Add up statistics for all chunks in this SpaceManager. - for (ChunkIndex index = SmallIndex; + for (ChunkIndex index = ZeroIndex; index < NumberOfInUseLists; index = next_chunk_index(index)) { for (Metachunk* curr = chunks_in_use(index); @@ -2160,7 +2296,7 @@ void SpaceManager::dump(outputStream* const out) const { } } - size_t free = current_chunk()->free_word_size(); + size_t free = current_chunk() == NULL ? 0 : current_chunk()->free_word_size(); // Free space isn't wasted. waste -= free; @@ -2171,25 +2307,18 @@ void SpaceManager::dump(outputStream* const out) const { #ifndef PRODUCT void SpaceManager::mangle_freed_chunks() { - for (ChunkIndex index = SmallIndex; + for (ChunkIndex index = ZeroIndex; index < NumberOfInUseLists; index = next_chunk_index(index)) { for (Metachunk* curr = chunks_in_use(index); curr != NULL; curr = curr->next()) { - // Try to detect incorrectly terminated small chunk - // list. - assert(index == MediumIndex || curr != chunks_in_use(MediumIndex), - err_msg("Mangling medium chunks in small chunks? " - "curr " PTR_FORMAT " medium list " PTR_FORMAT, - curr, chunks_in_use(MediumIndex))); curr->mangle(); } } } #endif // PRODUCT - // MetaspaceAux size_t MetaspaceAux::used_in_bytes(Metaspace::MetadataType mdtype) { @@ -2236,7 +2365,7 @@ size_t MetaspaceAux::reserved_in_bytes(Metaspace::MetadataType mdtype) { return reserved * BytesPerWord; } -size_t MetaspaceAux::min_chunk_size() { return SpaceManager::MediumChunk; } +size_t MetaspaceAux::min_chunk_size() { return Metaspace::first_chunk_word_size(); } size_t MetaspaceAux::free_chunks_total(Metaspace::MetadataType mdtype) { ChunkManager* chunk = (mdtype == Metaspace::ClassType) ? @@ -2316,26 +2445,44 @@ void MetaspaceAux::print_on(outputStream* out, Metaspace::MetadataType mdtype) { // Print total fragmentation for class and data metaspaces separately void MetaspaceAux::print_waste(outputStream* out) { - size_t small_waste = 0, medium_waste = 0, large_waste = 0; - size_t cls_small_waste = 0, cls_medium_waste = 0, cls_large_waste = 0; + size_t specialized_waste = 0, small_waste = 0, medium_waste = 0, large_waste = 0; + size_t specialized_count = 0, small_count = 0, medium_count = 0, large_count = 0; + size_t cls_specialized_waste = 0, cls_small_waste = 0, cls_medium_waste = 0, cls_large_waste = 0; + size_t cls_specialized_count = 0, cls_small_count = 0, cls_medium_count = 0, cls_large_count = 0; ClassLoaderDataGraphMetaspaceIterator iter; while (iter.repeat()) { Metaspace* msp = iter.get_next(); if (msp != NULL) { + specialized_waste += msp->vsm()->sum_waste_in_chunks_in_use(SpecializedIndex); + specialized_count += msp->vsm()->sum_count_in_chunks_in_use(SpecializedIndex); small_waste += msp->vsm()->sum_waste_in_chunks_in_use(SmallIndex); + small_count += msp->vsm()->sum_count_in_chunks_in_use(SmallIndex); medium_waste += msp->vsm()->sum_waste_in_chunks_in_use(MediumIndex); + medium_count += msp->vsm()->sum_count_in_chunks_in_use(MediumIndex); large_waste += msp->vsm()->sum_waste_in_chunks_in_use(HumongousIndex); + large_count += msp->vsm()->sum_count_in_chunks_in_use(HumongousIndex); + cls_specialized_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(SpecializedIndex); + cls_specialized_count += msp->class_vsm()->sum_count_in_chunks_in_use(SpecializedIndex); cls_small_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(SmallIndex); + cls_small_count += msp->class_vsm()->sum_count_in_chunks_in_use(SmallIndex); cls_medium_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(MediumIndex); + cls_medium_count += msp->class_vsm()->sum_count_in_chunks_in_use(MediumIndex); cls_large_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(HumongousIndex); + cls_large_count += msp->class_vsm()->sum_count_in_chunks_in_use(HumongousIndex); } } out->print_cr("Total fragmentation waste (words) doesn't count free space"); - out->print(" data: small " SIZE_FORMAT " medium " SIZE_FORMAT, - small_waste, medium_waste); - out->print_cr(" class: small " SIZE_FORMAT, cls_small_waste); + out->print_cr(" data: " SIZE_FORMAT " specialized(s) " SIZE_FORMAT ", " + SIZE_FORMAT " small(s) " SIZE_FORMAT ", " + SIZE_FORMAT " medium(s) " SIZE_FORMAT, + specialized_count, specialized_waste, small_count, + small_waste, medium_count, medium_waste); + out->print_cr(" class: " SIZE_FORMAT " specialized(s) " SIZE_FORMAT ", " + SIZE_FORMAT " small(s) " SIZE_FORMAT, + cls_specialized_count, cls_specialized_waste, + cls_small_count, cls_small_waste); } // Dump global metaspace things from the end of ClassLoaderDataGraph @@ -2354,13 +2501,10 @@ void MetaspaceAux::verify_free_chunks() { // Metaspace methods size_t Metaspace::_first_chunk_word_size = 0; +size_t Metaspace::_first_class_chunk_word_size = 0; -Metaspace::Metaspace(Mutex* lock, size_t word_size) { - initialize(lock, word_size); -} - -Metaspace::Metaspace(Mutex* lock) { - initialize(lock); +Metaspace::Metaspace(Mutex* lock, MetaspaceType type) { + initialize(lock, type); } Metaspace::~Metaspace() { @@ -2412,11 +2556,18 @@ void Metaspace::global_initialize() { } } - // Initialize this before initializing the VirtualSpaceList + // Initialize these before initializing the VirtualSpaceList _first_chunk_word_size = InitialBootClassLoaderMetaspaceSize / BytesPerWord; + _first_chunk_word_size = align_word_size_up(_first_chunk_word_size); + // Make the first class chunk bigger than a medium chunk so it's not put + // on the medium chunk list. The next chunk will be small and progress + // from there. This size calculated by -version. + _first_class_chunk_word_size = MIN2((size_t)MediumChunk*6, + (ClassMetaspaceSize/BytesPerWord)*2); + _first_class_chunk_word_size = align_word_size_up(_first_class_chunk_word_size); // Arbitrarily set the initial virtual space to a multiple // of the boot class loader size. - size_t word_size = VIRTUALSPACEMULTIPLIER * Metaspace::first_chunk_word_size(); + size_t word_size = VIRTUALSPACEMULTIPLIER * first_chunk_word_size(); // Initialize the list of virtual spaces. _space_list = new VirtualSpaceList(word_size); } @@ -2431,23 +2582,8 @@ void Metaspace::initialize_class_space(ReservedSpace rs) { _class_space_list = new VirtualSpaceList(rs); } - -void Metaspace::initialize(Mutex* lock, size_t initial_size) { - // Use SmallChunk size if not specified. If specified, use this size for - // the data metaspace. - size_t word_size; - size_t class_word_size; - if (initial_size == 0) { - word_size = (size_t) SpaceManager::SmallChunk; - class_word_size = (size_t) SpaceManager::SmallChunk; - } else { - word_size = initial_size; - // Make the first class chunk bigger than a medium chunk so it's not put - // on the medium chunk list. The next chunk will be small and progress - // from there. This size calculated by -version. - class_word_size = MIN2((size_t)SpaceManager::MediumChunk*5, - (ClassMetaspaceSize/BytesPerWord)*2); - } +void Metaspace::initialize(Mutex* lock, + MetaspaceType type) { assert(space_list() != NULL, "Metadata VirtualSpaceList has not been initialized"); @@ -2456,6 +2592,11 @@ void Metaspace::initialize(Mutex* lock, size_t initial_size) { if (_vsm == NULL) { return; } + size_t word_size; + size_t class_word_size; + vsm()->get_initial_chunk_sizes(type, + &word_size, + &class_word_size); assert(class_space_list() != NULL, "Class VirtualSpaceList has not been initialized"); @@ -2470,7 +2611,8 @@ void Metaspace::initialize(Mutex* lock, size_t initial_size) { // Allocate chunk for metadata objects Metachunk* new_chunk = - space_list()->current_virtual_space()->get_chunk_vs_with_expand(word_size); + space_list()->get_initialization_chunk(word_size, + vsm()->medium_chunk_bunch()); assert(!DumpSharedSpaces || new_chunk != NULL, "should have enough space for both chunks"); if (new_chunk != NULL) { // Add to this manager's list of chunks in use and current_chunk(). @@ -2479,12 +2621,18 @@ void Metaspace::initialize(Mutex* lock, size_t initial_size) { // Allocate chunk for class metadata objects Metachunk* class_chunk = - class_space_list()->current_virtual_space()->get_chunk_vs_with_expand(class_word_size); + class_space_list()->get_initialization_chunk(class_word_size, + class_vsm()->medium_chunk_bunch()); if (class_chunk != NULL) { class_vsm()->add_chunk(class_chunk, true); } } +size_t Metaspace::align_word_size_up(size_t word_size) { + size_t byte_size = word_size * wordSize; + return ReservedSpace::allocation_align_size_up(byte_size) / wordSize; +} + MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) { // DumpSharedSpaces doesn't use class metadata area (yet) if (mdtype == ClassType && !DumpSharedSpaces) { @@ -2610,6 +2758,12 @@ Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size, // If result is still null, we are out of memory. if (result == NULL) { + if (Verbose && TraceMetadataChunkAllocation) { + gclog_or_tty->print_cr("Metaspace allocation failed for size " + SIZE_FORMAT, word_size); + if (loader_data->metaspace_or_null() != NULL) loader_data->metaspace_or_null()->dump(gclog_or_tty); + MetaspaceAux::dump(gclog_or_tty); + } // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support report_java_out_of_memory("Metadata space"); diff --git a/hotspot/src/share/vm/memory/metaspace.hpp b/hotspot/src/share/vm/memory/metaspace.hpp index bfc6d90ae65..f704804795f 100644 --- a/hotspot/src/share/vm/memory/metaspace.hpp +++ b/hotspot/src/share/vm/memory/metaspace.hpp @@ -87,11 +87,23 @@ class Metaspace : public CHeapObj { public: enum MetadataType {ClassType, NonClassType}; + enum MetaspaceType { + StandardMetaspaceType, + BootMetaspaceType, + ROMetaspaceType, + ReadWriteMetaspaceType, + AnonymousMetaspaceType, + ReflectionMetaspaceType + }; private: - void initialize(Mutex* lock, size_t initial_size = 0); + void initialize(Mutex* lock, MetaspaceType type); + + // Align up the word size to the allocation word size + static size_t align_word_size_up(size_t); static size_t _first_chunk_word_size; + static size_t _first_class_chunk_word_size; SpaceManager* _vsm; SpaceManager* vsm() const { return _vsm; } @@ -110,8 +122,7 @@ class Metaspace : public CHeapObj { public: - Metaspace(Mutex* lock, size_t initial_size); - Metaspace(Mutex* lock); + Metaspace(Mutex* lock, MetaspaceType type); ~Metaspace(); // Initialize globals for Metaspace @@ -119,6 +130,7 @@ class Metaspace : public CHeapObj { static void initialize_class_space(ReservedSpace rs); static size_t first_chunk_word_size() { return _first_chunk_word_size; } + static size_t first_class_chunk_word_size() { return _first_class_chunk_word_size; } char* bottom() const; size_t used_words(MetadataType mdtype) const; diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index dd3750cafb6..f63e8e2ae27 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -2217,7 +2217,8 @@ class CommandLineFlags { develop(bool, TraceClassLoaderData, false, \ "Trace class loader loader_data lifetime") \ \ - product(uintx, InitialBootClassLoaderMetaspaceSize, 3*M, \ + product(uintx, InitialBootClassLoaderMetaspaceSize, \ + NOT_LP64(2200*K) LP64_ONLY(4*M), \ "Initial size of the boot class loader data metaspace") \ \ product(bool, TraceGen0Time, false, \ From 9c761152db950d488a9c0853f222ebcc5022f723 Mon Sep 17 00:00:00 2001 From: Ron Durbin Date: Wed, 19 Dec 2012 10:35:08 -0800 Subject: [PATCH 002/204] 8005044: remove crufty '_g' support from HS runtime code Phase 2 is removing '_g' support from the Runtime code. Reviewed-by: dcubed, coleenp, hseigel --- hotspot/src/os/bsd/vm/os_bsd.cpp | 25 ++++++++----------- hotspot/src/os/linux/vm/os_linux.cpp | 25 ++++++++----------- hotspot/src/os/solaris/vm/os_solaris.cpp | 25 ++++++++----------- hotspot/src/os/windows/vm/os_windows.cpp | 4 +-- .../tools/ProjectCreator/ProjectCreator.java | 2 +- hotspot/src/share/vm/runtime/arguments.cpp | 1 - 6 files changed, 36 insertions(+), 46 deletions(-) diff --git a/hotspot/src/os/bsd/vm/os_bsd.cpp b/hotspot/src/os/bsd/vm/os_bsd.cpp index 81b4c9d0caf..db6f3e6a0ea 100644 --- a/hotspot/src/os/bsd/vm/os_bsd.cpp +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp @@ -298,12 +298,12 @@ void os::init_system_properties_values() { // The next steps are taken in the product version: // - // Obtain the JAVA_HOME value from the location of libjvm[_g].so. + // Obtain the JAVA_HOME value from the location of libjvm.so. // This library should be located at: - // /jre/lib//{client|server}/libjvm[_g].so. + // /jre/lib//{client|server}/libjvm.so. // // If "/jre/lib/" appears at the right place in the path, then we - // assume libjvm[_g].so is installed in a JDK and we use this path. + // assume libjvm.so is installed in a JDK and we use this path. // // Otherwise exit with message: "Could not create the Java virtual machine." // @@ -313,9 +313,9 @@ void os::init_system_properties_values() { // instead of exit check for $JAVA_HOME environment variable. // // If it is defined and we are able to locate $JAVA_HOME/jre/lib/, - // then we append a fake suffix "hotspot/libjvm[_g].so" to this path so - // it looks like libjvm[_g].so is installed there - // /jre/lib//hotspot/libjvm[_g].so. + // then we append a fake suffix "hotspot/libjvm.so" to this path so + // it looks like libjvm.so is installed there + // /jre/lib//hotspot/libjvm.so. // // Otherwise exit. // @@ -1228,7 +1228,7 @@ const char* os::get_current_directory(char *buf, int buflen) { return getcwd(buf, buflen); } -// check if addr is inside libjvm[_g].so +// check if addr is inside libjvm.so bool os::address_is_in_vm(address addr) { static address libjvm_base_addr; Dl_info dlinfo; @@ -1689,7 +1689,7 @@ void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) { static char saved_jvm_path[MAXPATHLEN] = {0}; -// Find the full path to the current module, libjvm or libjvm_g +// Find the full path to the current module, libjvm void os::jvm_path(char *buf, jint buflen) { // Error checking. if (buflen < MAXPATHLEN) { @@ -1732,10 +1732,9 @@ void os::jvm_path(char *buf, jint buflen) { char* jrelib_p; int len; - // Check the current module name "libjvm" or "libjvm_g". + // Check the current module name "libjvm" p = strrchr(buf, '/'); assert(strstr(p, "/libjvm") == p, "invalid library name"); - p = strstr(p, "_g") ? "_g" : ""; rp = realpath(java_home_var, buf); if (rp == NULL) @@ -1764,11 +1763,9 @@ void os::jvm_path(char *buf, jint buflen) { // to complete the path to JVM being overridden. Otherwise fallback // to the path to the current library. if (0 == access(buf, F_OK)) { - // Use current module name "libjvm[_g]" instead of - // "libjvm"debug_only("_g")"" since for fastdebug version - // we should have "libjvm" but debug_only("_g") adds "_g"! + // Use current module name "libjvm" len = strlen(buf); - snprintf(buf + len, buflen-len, "/libjvm%s%s", p, JNI_LIB_SUFFIX); + snprintf(buf + len, buflen-len, "/libjvm%s", JNI_LIB_SUFFIX); } else { // Fall back to path of current library rp = realpath(dli_fname, buf); diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index 45dea5e95a8..8377294d20a 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -321,12 +321,12 @@ void os::init_system_properties_values() { // The next steps are taken in the product version: // - // Obtain the JAVA_HOME value from the location of libjvm[_g].so. + // Obtain the JAVA_HOME value from the location of libjvm.so. // This library should be located at: - // /jre/lib//{client|server}/libjvm[_g].so. + // /jre/lib//{client|server}/libjvm.so. // // If "/jre/lib/" appears at the right place in the path, then we - // assume libjvm[_g].so is installed in a JDK and we use this path. + // assume libjvm.so is installed in a JDK and we use this path. // // Otherwise exit with message: "Could not create the Java virtual machine." // @@ -336,9 +336,9 @@ void os::init_system_properties_values() { // instead of exit check for $JAVA_HOME environment variable. // // If it is defined and we are able to locate $JAVA_HOME/jre/lib/, - // then we append a fake suffix "hotspot/libjvm[_g].so" to this path so - // it looks like libjvm[_g].so is installed there - // /jre/lib//hotspot/libjvm[_g].so. + // then we append a fake suffix "hotspot/libjvm.so" to this path so + // it looks like libjvm.so is installed there + // /jre/lib//hotspot/libjvm.so. // // Otherwise exit. // @@ -1679,7 +1679,7 @@ const char* os::get_current_directory(char *buf, int buflen) { return getcwd(buf, buflen); } -// check if addr is inside libjvm[_g].so +// check if addr is inside libjvm.so bool os::address_is_in_vm(address addr) { static address libjvm_base_addr; Dl_info dlinfo; @@ -2180,7 +2180,7 @@ void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) { static char saved_jvm_path[MAXPATHLEN] = {0}; -// Find the full path to the current module, libjvm.so or libjvm_g.so +// Find the full path to the current module, libjvm.so void os::jvm_path(char *buf, jint buflen) { // Error checking. if (buflen < MAXPATHLEN) { @@ -2223,10 +2223,9 @@ void os::jvm_path(char *buf, jint buflen) { char* jrelib_p; int len; - // Check the current module name "libjvm.so" or "libjvm_g.so". + // Check the current module name "libjvm.so". p = strrchr(buf, '/'); assert(strstr(p, "/libjvm") == p, "invalid library name"); - p = strstr(p, "_g") ? "_g" : ""; rp = realpath(java_home_var, buf); if (rp == NULL) @@ -2242,11 +2241,9 @@ void os::jvm_path(char *buf, jint buflen) { } if (0 == access(buf, F_OK)) { - // Use current module name "libjvm[_g].so" instead of - // "libjvm"debug_only("_g")".so" since for fastdebug version - // we should have "libjvm.so" but debug_only("_g") adds "_g"! + // Use current module name "libjvm.so" len = strlen(buf); - snprintf(buf + len, buflen-len, "/hotspot/libjvm%s.so", p); + snprintf(buf + len, buflen-len, "/hotspot/libjvm.so"); } else { // Go back to path of .so rp = realpath(dli_fname, buf); diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp index 05b2ec0a58a..41143af2d1a 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.cpp +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp @@ -734,12 +734,12 @@ void os::init_system_properties_values() { // The next steps are taken in the product version: // - // Obtain the JAVA_HOME value from the location of libjvm[_g].so. + // Obtain the JAVA_HOME value from the location of libjvm.so. // This library should be located at: - // /jre/lib//{client|server}/libjvm[_g].so. + // /jre/lib//{client|server}/libjvm.so. // // If "/jre/lib/" appears at the right place in the path, then we - // assume libjvm[_g].so is installed in a JDK and we use this path. + // assume libjvm.so is installed in a JDK and we use this path. // // Otherwise exit with message: "Could not create the Java virtual machine." // @@ -749,9 +749,9 @@ void os::init_system_properties_values() { // instead of exit check for $JAVA_HOME environment variable. // // If it is defined and we are able to locate $JAVA_HOME/jre/lib/, - // then we append a fake suffix "hotspot/libjvm[_g].so" to this path so - // it looks like libjvm[_g].so is installed there - // /jre/lib//hotspot/libjvm[_g].so. + // then we append a fake suffix "hotspot/libjvm.so" to this path so + // it looks like libjvm.so is installed there + // /jre/lib//hotspot/libjvm.so. // // Otherwise exit. // @@ -1934,7 +1934,7 @@ const char* os::get_current_directory(char *buf, int buflen) { return getcwd(buf, buflen); } -// check if addr is inside libjvm[_g].so +// check if addr is inside libjvm.so bool os::address_is_in_vm(address addr) { static address libjvm_base_addr; Dl_info dlinfo; @@ -2474,7 +2474,7 @@ void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) { static char saved_jvm_path[MAXPATHLEN] = { 0 }; -// Find the full path to the current module, libjvm.so or libjvm_g.so +// Find the full path to the current module, libjvm.so void os::jvm_path(char *buf, jint buflen) { // Error checking. if (buflen < MAXPATHLEN) { @@ -2522,10 +2522,9 @@ void os::jvm_path(char *buf, jint buflen) { strcpy(cpu_arch, "amd64"); } #endif - // Check the current module name "libjvm.so" or "libjvm_g.so". + // Check the current module name "libjvm.so". p = strrchr(buf, '/'); assert(strstr(p, "/libjvm") == p, "invalid library name"); - p = strstr(p, "_g") ? "_g" : ""; realpath(java_home_var, buf); // determine if this is a legacy image or modules image @@ -2538,11 +2537,9 @@ void os::jvm_path(char *buf, jint buflen) { } if (0 == access(buf, F_OK)) { - // Use current module name "libjvm[_g].so" instead of - // "libjvm"debug_only("_g")".so" since for fastdebug version - // we should have "libjvm.so" but debug_only("_g") adds "_g"! + // Use current module name "libjvm.so" len = strlen(buf); - snprintf(buf + len, buflen-len, "/hotspot/libjvm%s.so", p); + snprintf(buf + len, buflen-len, "/hotspot/libjvm.so"); } else { // Go back to path of .so realpath((char *)dlinfo.dli_fname, buf); diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index ddd3a79bfe2..2881bd51946 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -182,7 +182,7 @@ void os::init_system_properties_values() { if (!getenv("_ALT_JAVA_HOME_DIR", home_dir, MAX_PATH)) { os::jvm_path(home_dir, sizeof(home_dir)); - // Found the full path to jvm[_g].dll. + // Found the full path to jvm.dll. // Now cut the path to /jre if we can. *(strrchr(home_dir, '\\')) = '\0'; /* get rid of \jvm.dll */ pslash = strrchr(home_dir, '\\'); @@ -1715,7 +1715,7 @@ void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) { static char saved_jvm_path[MAX_PATH] = {0}; -// Find the full path to the current module, jvm.dll or jvm_g.dll +// Find the full path to the current module, jvm.dll void os::jvm_path(char *buf, jint buflen) { // Error checking. if (buflen < MAX_PATH) { diff --git a/hotspot/src/share/tools/ProjectCreator/ProjectCreator.java b/hotspot/src/share/tools/ProjectCreator/ProjectCreator.java index daa7a41ab81..a3065e51273 100644 --- a/hotspot/src/share/tools/ProjectCreator/ProjectCreator.java +++ b/hotspot/src/share/tools/ProjectCreator/ProjectCreator.java @@ -36,7 +36,7 @@ public class ProjectCreator { + "into .dsp file, substituting for path given in " + "-sourceBase. Example: HotSpotWorkSpace>"); System.err.println(" -dllLoc "); + + "jvm.dll; no trailing slash>"); System.err.println(" If any of the above are specified, " + "they must all be."); System.err.println(" Additional, optional arguments, which can be " diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index f850e05cbab..ef8bdab4798 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -3030,7 +3030,6 @@ jint Arguments::parse(const JavaVMInitArgs* args) { strcpy(shared_archive_path, jvm_path); strcat(shared_archive_path, os::file_separator()); strcat(shared_archive_path, "classes"); - DEBUG_ONLY(strcat(shared_archive_path, "_g");) strcat(shared_archive_path, ".jsa"); SharedArchivePath = shared_archive_path; From 6ed6cb5375d9b86c83e66884ca3e77be6ec7bcd3 Mon Sep 17 00:00:00 2001 From: Joel Borggren-Franck Date: Thu, 20 Dec 2012 10:22:19 +0100 Subject: [PATCH 003/204] 8004823: Add VM support for type annotation reflection Reviewed-by: dholmes, coleenp --- hotspot/make/bsd/makefiles/mapfile-vers-debug | 3 +- .../make/bsd/makefiles/mapfile-vers-product | 1 + .../make/linux/makefiles/mapfile-vers-debug | 1 + .../make/linux/makefiles/mapfile-vers-product | 1 + hotspot/make/solaris/makefiles/mapfile-vers | 1 + .../share/vm/classfile/classFileParser.cpp | 125 +++++++++++++++++- .../share/vm/classfile/classFileParser.hpp | 8 ++ .../src/share/vm/classfile/javaClasses.cpp | 56 ++++++++ .../src/share/vm/classfile/javaClasses.hpp | 15 +++ hotspot/src/share/vm/classfile/vmSymbols.hpp | 5 + hotspot/src/share/vm/oops/annotations.cpp | 3 + hotspot/src/share/vm/oops/annotations.hpp | 17 ++- hotspot/src/share/vm/oops/instanceKlass.cpp | 3 + hotspot/src/share/vm/oops/instanceKlass.hpp | 4 + hotspot/src/share/vm/oops/method.cpp | 6 +- hotspot/src/share/vm/oops/method.hpp | 8 ++ hotspot/src/share/vm/prims/jvm.cpp | 17 +++ hotspot/src/share/vm/prims/jvm.h | 4 + .../share/vm/prims/jvmtiRedefineClasses.cpp | 15 ++- .../src/share/vm/runtime/fieldDescriptor.cpp | 11 ++ .../src/share/vm/runtime/fieldDescriptor.hpp | 1 + hotspot/src/share/vm/runtime/reflection.cpp | 8 ++ 22 files changed, 302 insertions(+), 11 deletions(-) diff --git a/hotspot/make/bsd/makefiles/mapfile-vers-debug b/hotspot/make/bsd/makefiles/mapfile-vers-debug index 9a2d42fb695..52e8f435665 100644 --- a/hotspot/make/bsd/makefiles/mapfile-vers-debug +++ b/hotspot/make/bsd/makefiles/mapfile-vers-debug @@ -126,8 +126,9 @@ SUNWprivate_1.1 { JVM_GetClassModifiers; JVM_GetClassName; JVM_GetClassNameUTF; - JVM_GetClassSignature; + JVM_GetClassSignature; JVM_GetClassSigners; + JVM_GetClassTypeAnnotations; JVM_GetComponentType; JVM_GetDeclaredClasses; JVM_GetDeclaringClass; diff --git a/hotspot/make/bsd/makefiles/mapfile-vers-product b/hotspot/make/bsd/makefiles/mapfile-vers-product index 7a5d7c7dfe2..05e9a44a1fc 100644 --- a/hotspot/make/bsd/makefiles/mapfile-vers-product +++ b/hotspot/make/bsd/makefiles/mapfile-vers-product @@ -128,6 +128,7 @@ SUNWprivate_1.1 { JVM_GetClassNameUTF; JVM_GetClassSignature; JVM_GetClassSigners; + JVM_GetClassTypeAnnotations; JVM_GetComponentType; JVM_GetDeclaredClasses; JVM_GetDeclaringClass; diff --git a/hotspot/make/linux/makefiles/mapfile-vers-debug b/hotspot/make/linux/makefiles/mapfile-vers-debug index 1a0bc01a626..93ddc5666a0 100644 --- a/hotspot/make/linux/makefiles/mapfile-vers-debug +++ b/hotspot/make/linux/makefiles/mapfile-vers-debug @@ -124,6 +124,7 @@ SUNWprivate_1.1 { JVM_GetClassNameUTF; JVM_GetClassSignature; JVM_GetClassSigners; + JVM_GetClassTypeAnnotations; JVM_GetComponentType; JVM_GetDeclaredClasses; JVM_GetDeclaringClass; diff --git a/hotspot/make/linux/makefiles/mapfile-vers-product b/hotspot/make/linux/makefiles/mapfile-vers-product index e53bc5c0d8f..029c12c5ff9 100644 --- a/hotspot/make/linux/makefiles/mapfile-vers-product +++ b/hotspot/make/linux/makefiles/mapfile-vers-product @@ -124,6 +124,7 @@ SUNWprivate_1.1 { JVM_GetClassNameUTF; JVM_GetClassSignature; JVM_GetClassSigners; + JVM_GetClassTypeAnnotations; JVM_GetComponentType; JVM_GetDeclaredClasses; JVM_GetDeclaringClass; diff --git a/hotspot/make/solaris/makefiles/mapfile-vers b/hotspot/make/solaris/makefiles/mapfile-vers index eb5554858eb..76af87c0ce5 100644 --- a/hotspot/make/solaris/makefiles/mapfile-vers +++ b/hotspot/make/solaris/makefiles/mapfile-vers @@ -125,6 +125,7 @@ SUNWprivate_1.1 { JVM_GetClassSignature; JVM_GetClassSigners; JVM_GetComponentType; + JVM_GetClassTypeAnnotations; JVM_GetDeclaredClasses; JVM_GetDeclaringClass; JVM_GetEnclosingMethodInfo; diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index a13bdab006d..956acea7a25 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -906,6 +906,7 @@ void ClassFileParser::parse_field_attributes(ClassLoaderData* loader_data, bool* is_synthetic_addr, u2* generic_signature_index_addr, AnnotationArray** field_annotations, + AnnotationArray** field_type_annotations, ClassFileParser::FieldAnnotationCollector* parsed_annotations, TRAPS) { ClassFileStream* cfs = stream(); @@ -917,6 +918,10 @@ void ClassFileParser::parse_field_attributes(ClassLoaderData* loader_data, int runtime_visible_annotations_length = 0; u1* runtime_invisible_annotations = NULL; int runtime_invisible_annotations_length = 0; + u1* runtime_visible_type_annotations = NULL; + int runtime_visible_type_annotations_length = 0; + u1* runtime_invisible_type_annotations = NULL; + int runtime_invisible_type_annotations_length = 0; while (attributes_count--) { cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length u2 attribute_name_index = cfs->get_u2_fast(); @@ -971,6 +976,16 @@ void ClassFileParser::parse_field_attributes(ClassLoaderData* loader_data, runtime_invisible_annotations = cfs->get_u1_buffer(); assert(runtime_invisible_annotations != NULL, "null invisible annotations"); cfs->skip_u1(runtime_invisible_annotations_length, CHECK); + } else if (attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) { + runtime_visible_type_annotations_length = attribute_length; + runtime_visible_type_annotations = cfs->get_u1_buffer(); + assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); + cfs->skip_u1(runtime_visible_type_annotations_length, CHECK); + } else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { + runtime_invisible_type_annotations_length = attribute_length; + runtime_invisible_type_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); + cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK); } else { cfs->skip_u1(attribute_length, CHECK); // Skip unknown attributes } @@ -988,6 +1003,12 @@ void ClassFileParser::parse_field_attributes(ClassLoaderData* loader_data, runtime_invisible_annotations, runtime_invisible_annotations_length, CHECK); + *field_type_annotations = assemble_annotations(loader_data, + runtime_visible_type_annotations, + runtime_visible_type_annotations_length, + runtime_invisible_type_annotations, + runtime_invisible_type_annotations_length, + CHECK); return; } @@ -1084,6 +1105,7 @@ Array* ClassFileParser::parse_fields(ClassLoaderData* loader_data, bool is_interface, FieldAllocationCount *fac, Array** fields_annotations, + Array** fields_type_annotations, u2* java_fields_count_ptr, TRAPS) { ClassFileStream* cfs = stream(); cfs->guarantee_more(2, CHECK_NULL); // length @@ -1119,6 +1141,7 @@ Array* ClassFileParser::parse_fields(ClassLoaderData* loader_data, THREAD, u2, total_fields * (FieldInfo::field_slots + 1)); AnnotationArray* field_annotations = NULL; + AnnotationArray* field_type_annotations = NULL; // The generic signature slots start after all other fields' data. int generic_signature_slot = total_fields * FieldInfo::field_slots; int num_generic_signature = 0; @@ -1160,7 +1183,7 @@ Array* ClassFileParser::parse_fields(ClassLoaderData* loader_data, cp, attributes_count, is_static, signature_index, &constantvalue_index, &is_synthetic, &generic_signature_index, &field_annotations, - &parsed_annotations, + &field_type_annotations, &parsed_annotations, CHECK_NULL); if (field_annotations != NULL) { if (*fields_annotations == NULL) { @@ -1170,6 +1193,14 @@ Array* ClassFileParser::parse_fields(ClassLoaderData* loader_data, } (*fields_annotations)->at_put(n, field_annotations); } + if (field_type_annotations != NULL) { + if (*fields_type_annotations == NULL) { + *fields_type_annotations = MetadataFactory::new_array( + loader_data, length, NULL, + CHECK_NULL); + } + (*fields_type_annotations)->at_put(n, field_type_annotations); + } if (is_synthetic) { access_flags.set_is_synthetic(); } @@ -1831,6 +1862,7 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data, AnnotationArray** method_annotations, AnnotationArray** method_parameter_annotations, AnnotationArray** method_default_annotations, + AnnotationArray** method_type_annotations, TRAPS) { ClassFileStream* cfs = stream(); methodHandle nullHandle; @@ -1918,6 +1950,10 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data, int runtime_visible_parameter_annotations_length = 0; u1* runtime_invisible_parameter_annotations = NULL; int runtime_invisible_parameter_annotations_length = 0; + u1* runtime_visible_type_annotations = NULL; + int runtime_visible_type_annotations_length = 0; + u1* runtime_invisible_type_annotations = NULL; + int runtime_invisible_type_annotations_length = 0; u1* annotation_default = NULL; int annotation_default_length = 0; @@ -2159,6 +2195,17 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data, annotation_default = cfs->get_u1_buffer(); assert(annotation_default != NULL, "null annotation default"); cfs->skip_u1(annotation_default_length, CHECK_(nullHandle)); + } else if (method_attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) { + runtime_visible_type_annotations_length = method_attribute_length; + runtime_visible_type_annotations = cfs->get_u1_buffer(); + assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); + // No need for the VM to parse Type annotations + cfs->skip_u1(runtime_visible_type_annotations_length, CHECK_(nullHandle)); + } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { + runtime_invisible_type_annotations_length = method_attribute_length; + runtime_invisible_type_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); + cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK_(nullHandle)); } else { // Skip unknown attributes cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); @@ -2333,6 +2380,12 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data, NULL, 0, CHECK_(nullHandle)); + *method_type_annotations = assemble_annotations(loader_data, + runtime_visible_type_annotations, + runtime_visible_type_annotations_length, + runtime_invisible_type_annotations, + runtime_invisible_type_annotations_length, + CHECK_(nullHandle)); if (name == vmSymbols::finalize_method_name() && signature == vmSymbols::void_method_signature()) { @@ -2364,12 +2417,14 @@ Array* ClassFileParser::parse_methods(ClassLoaderData* loader_data, Array** methods_annotations, Array** methods_parameter_annotations, Array** methods_default_annotations, + Array** methods_type_annotations, bool* has_default_methods, TRAPS) { ClassFileStream* cfs = stream(); AnnotationArray* method_annotations = NULL; AnnotationArray* method_parameter_annotations = NULL; AnnotationArray* method_default_annotations = NULL; + AnnotationArray* method_type_annotations = NULL; cfs->guarantee_more(2, CHECK_NULL); // length u2 length = cfs->get_u2_fast(); if (length == 0) { @@ -2386,6 +2441,7 @@ Array* ClassFileParser::parse_methods(ClassLoaderData* loader_data, &method_annotations, &method_parameter_annotations, &method_default_annotations, + &method_type_annotations, CHECK_NULL); if (method->is_final()) { @@ -2411,7 +2467,13 @@ Array* ClassFileParser::parse_methods(ClassLoaderData* loader_data, MetadataFactory::new_array(loader_data, length, NULL, CHECK_NULL); } (*methods_default_annotations)->at_put(index, method_default_annotations); + if (*methods_type_annotations == NULL) { + *methods_type_annotations = + MetadataFactory::new_array(loader_data, length, NULL, CHECK_NULL); + } + (*methods_type_annotations)->at_put(index, method_type_annotations); } + if (_need_verify && length > 1) { // Check duplicated methods ResourceMark rm(THREAD); @@ -2445,6 +2507,7 @@ Array* ClassFileParser::sort_methods(ClassLoaderData* loader_data, Array* methods_annotations, Array* methods_parameter_annotations, Array* methods_default_annotations, + Array* methods_type_annotations, TRAPS) { int length = methods->length(); // If JVMTI original method ordering or sharing is enabled we have to @@ -2463,7 +2526,8 @@ Array* ClassFileParser::sort_methods(ClassLoaderData* loader_data, // Note that the ordering is not alphabetical, see Symbol::fast_compare Method::sort_methods(methods, methods_annotations, methods_parameter_annotations, - methods_default_annotations); + methods_default_annotations, + methods_type_annotations); // If JVMTI original method ordering or sharing is enabled construct int // array remembering the original ordering @@ -2728,6 +2792,10 @@ void ClassFileParser::parse_classfile_attributes(ClassLoaderData* loader_data, int runtime_visible_annotations_length = 0; u1* runtime_invisible_annotations = NULL; int runtime_invisible_annotations_length = 0; + u1* runtime_visible_type_annotations = NULL; + int runtime_visible_type_annotations_length = 0; + u1* runtime_invisible_type_annotations = NULL; + int runtime_invisible_type_annotations_length = 0; u1* inner_classes_attribute_start = NULL; u4 inner_classes_attribute_length = 0; u2 enclosing_method_class_index = 0; @@ -2834,6 +2902,17 @@ void ClassFileParser::parse_classfile_attributes(ClassLoaderData* loader_data, classfile_parse_error("Multiple BootstrapMethods attributes in class file %s", CHECK); parsed_bootstrap_methods_attribute = true; parse_classfile_bootstrap_methods_attribute(loader_data, cp, attribute_length, CHECK); + } else if (tag == vmSymbols::tag_runtime_visible_type_annotations()) { + runtime_visible_type_annotations_length = attribute_length; + runtime_visible_type_annotations = cfs->get_u1_buffer(); + assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); + // No need for the VM to parse Type annotations + cfs->skip_u1(runtime_visible_type_annotations_length, CHECK); + } else if (PreserveAllAnnotations && tag == vmSymbols::tag_runtime_invisible_type_annotations()) { + runtime_invisible_type_annotations_length = attribute_length; + runtime_invisible_type_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); + cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK); } else { // Unknown attribute cfs->skip_u1(attribute_length, CHECK); @@ -2850,6 +2929,13 @@ void ClassFileParser::parse_classfile_attributes(ClassLoaderData* loader_data, runtime_invisible_annotations_length, CHECK); set_class_annotations(annotations); + AnnotationArray* type_annotations = assemble_annotations(loader_data, + runtime_visible_type_annotations, + runtime_visible_type_annotations_length, + runtime_invisible_type_annotations, + runtime_invisible_type_annotations_length, + CHECK); + set_class_type_annotations(type_annotations); if (parsed_innerclasses_attribute || parsed_enclosingmethod_attribute) { u2 num_of_classes = parse_classfile_inner_classes_attribute( @@ -3190,7 +3276,9 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, // Fields (offsets are filled in later) FieldAllocationCount fac; Array* fields_annotations = NULL; + Array* fields_type_annotations = NULL; Array* fields = parse_fields(loader_data, class_name, cp, access_flags.is_interface(), &fac, &fields_annotations, + &fields_type_annotations, &java_fields_count, CHECK_(nullHandle)); // Methods @@ -3202,6 +3290,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, Array* methods_annotations = NULL; Array* methods_parameter_annotations = NULL; Array* methods_default_annotations = NULL; + Array* methods_type_annotations = NULL; Array* methods = parse_methods(loader_data, cp, access_flags.is_interface(), &promoted_flags, @@ -3209,6 +3298,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, &methods_annotations, &methods_parameter_annotations, &methods_default_annotations, + &methods_type_annotations, &has_default_methods, CHECK_(nullHandle)); @@ -3270,6 +3360,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, methods_annotations, methods_parameter_annotations, methods_default_annotations, + methods_type_annotations, CHECK_(nullHandle)); // promote flags from parse_methods() to the klass' flags @@ -3687,11 +3778,13 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, if (is_anonymous()) // I am well known to myself cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve + // Allocate an annotation type if needed. if (fields_annotations != NULL || methods_annotations != NULL || methods_parameter_annotations != NULL || - methods_default_annotations != NULL) { - // Allocate an annotation type if needed. + methods_default_annotations != NULL || + fields_type_annotations != NULL || + methods_type_annotations != NULL) { Annotations* anno = Annotations::allocate(loader_data, fields_annotations, methods_annotations, methods_parameter_annotations, @@ -3701,6 +3794,16 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, this_klass->set_annotations(NULL); } + if (fields_type_annotations != NULL || + methods_type_annotations != NULL) { + assert(this_klass->annotations() != NULL, "annotations should have been allocated"); + Annotations* anno = Annotations::allocate(loader_data, + fields_type_annotations, + methods_type_annotations, + NULL, + NULL, CHECK_(nullHandle)); + this_klass->annotations()->set_type_annotations(anno); + } this_klass->set_minor_version(minor_version); this_klass->set_major_version(major_version); @@ -3725,6 +3828,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, // Fill in field values obtained by parse_classfile_attributes if (parsed_annotations.has_any_annotations()) parsed_annotations.apply_to(this_klass); + // Create annotations if (_annotations != NULL && this_klass->annotations() == NULL) { Annotations* anno = Annotations::allocate(loader_data, CHECK_NULL); @@ -3732,6 +3836,19 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, } apply_parsed_class_attributes(this_klass); + // Create type annotations + if (_type_annotations != NULL) { + if (this_klass->annotations() == NULL) { + Annotations* anno = Annotations::allocate(loader_data, CHECK_NULL); + this_klass->set_annotations(anno); + } + if (this_klass->annotations()->type_annotations() == NULL) { + Annotations* anno = Annotations::allocate(loader_data, CHECK_NULL); + this_klass->annotations()->set_type_annotations(anno); + } + this_klass->annotations()->type_annotations()->set_class_annotations(_type_annotations); + } + // Miranda methods if ((num_miranda_methods > 0) || // if this class introduced new miranda methods or diff --git a/hotspot/src/share/vm/classfile/classFileParser.hpp b/hotspot/src/share/vm/classfile/classFileParser.hpp index c5b4701838a..5a5d3fc397a 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.hpp +++ b/hotspot/src/share/vm/classfile/classFileParser.hpp @@ -64,6 +64,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC { int _sde_length; Array* _inner_classes; AnnotationArray* _annotations; + AnnotationArray* _type_annotations; void set_class_synthetic_flag(bool x) { _synthetic_flag = x; } void set_class_sourcefile(Symbol* x) { _sourcefile = x; } @@ -71,12 +72,14 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC { void set_class_sde_buffer(char* x, int len) { _sde_buffer = x; _sde_length = len; } void set_class_inner_classes(Array* x) { _inner_classes = x; } void set_class_annotations(AnnotationArray* x) { _annotations = x; } + void set_class_type_annotations(AnnotationArray* x) { _type_annotations = x; } void init_parsed_class_attributes() { _synthetic_flag = false; _sourcefile = NULL; _generic_signature = NULL; _sde_buffer = NULL; _sde_length = 0; + _annotations = _type_annotations = NULL; // initialize the other flags too: _has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false; _max_bootstrap_specifier_index = -1; @@ -163,6 +166,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC { bool* is_synthetic_addr, u2* generic_signature_index_addr, AnnotationArray** field_annotations, + AnnotationArray** field_type_annotations, FieldAnnotationCollector* parsed_annotations, TRAPS); Array* parse_fields(ClassLoaderData* loader_data, @@ -170,6 +174,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC { constantPoolHandle cp, bool is_interface, FieldAllocationCount *fac, Array** fields_annotations, + Array** fields_type_annotations, u2* java_fields_count_ptr, TRAPS); // Method parsing @@ -180,6 +185,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC { AnnotationArray** method_annotations, AnnotationArray** method_parameter_annotations, AnnotationArray** method_default_annotations, + AnnotationArray** method_type_annotations, TRAPS); Array* parse_methods(ClassLoaderData* loader_data, constantPoolHandle cp, @@ -189,6 +195,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC { Array** methods_annotations, Array** methods_parameter_annotations, Array** methods_default_annotations, + Array** methods_type_annotations, bool* has_default_method, TRAPS); Array* sort_methods(ClassLoaderData* loader_data, @@ -196,6 +203,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC { Array* methods_annotations, Array* methods_parameter_annotations, Array* methods_default_annotations, + Array* methods_type_annotations, TRAPS); u2* parse_exception_table(ClassLoaderData* loader_data, u4 code_length, u4 exception_table_length, diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp index 80b15fbd2d1..79a35008575 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.cpp +++ b/hotspot/src/share/vm/classfile/javaClasses.cpp @@ -1813,10 +1813,12 @@ void java_lang_reflect_Method::compute_offsets() { annotations_offset = -1; parameter_annotations_offset = -1; annotation_default_offset = -1; + type_annotations_offset = -1; compute_optional_offset(signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature()); compute_optional_offset(annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature()); compute_optional_offset(parameter_annotations_offset, k, vmSymbols::parameter_annotations_name(), vmSymbols::byte_array_signature()); compute_optional_offset(annotation_default_offset, k, vmSymbols::annotation_default_name(), vmSymbols::byte_array_signature()); + compute_optional_offset(type_annotations_offset, k, vmSymbols::type_annotations_name(), vmSymbols::byte_array_signature()); } Handle java_lang_reflect_Method::create(TRAPS) { @@ -1962,6 +1964,22 @@ void java_lang_reflect_Method::set_annotation_default(oop method, oop value) { method->obj_field_put(annotation_default_offset, value); } +bool java_lang_reflect_Method::has_type_annotations_field() { + return (type_annotations_offset >= 0); +} + +oop java_lang_reflect_Method::type_annotations(oop method) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + assert(has_type_annotations_field(), "type_annotations field must be present"); + return method->obj_field(type_annotations_offset); +} + +void java_lang_reflect_Method::set_type_annotations(oop method, oop value) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + assert(has_type_annotations_field(), "type_annotations field must be present"); + method->obj_field_put(type_annotations_offset, value); +} + void java_lang_reflect_Constructor::compute_offsets() { Klass* k = SystemDictionary::reflect_Constructor_klass(); compute_offset(clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature()); @@ -1973,9 +1991,11 @@ void java_lang_reflect_Constructor::compute_offsets() { signature_offset = -1; annotations_offset = -1; parameter_annotations_offset = -1; + type_annotations_offset = -1; compute_optional_offset(signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature()); compute_optional_offset(annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature()); compute_optional_offset(parameter_annotations_offset, k, vmSymbols::parameter_annotations_name(), vmSymbols::byte_array_signature()); + compute_optional_offset(type_annotations_offset, k, vmSymbols::type_annotations_name(), vmSymbols::byte_array_signature()); } Handle java_lang_reflect_Constructor::create(TRAPS) { @@ -2086,6 +2106,22 @@ void java_lang_reflect_Constructor::set_parameter_annotations(oop method, oop va method->obj_field_put(parameter_annotations_offset, value); } +bool java_lang_reflect_Constructor::has_type_annotations_field() { + return (type_annotations_offset >= 0); +} + +oop java_lang_reflect_Constructor::type_annotations(oop constructor) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + assert(has_type_annotations_field(), "type_annotations field must be present"); + return constructor->obj_field(type_annotations_offset); +} + +void java_lang_reflect_Constructor::set_type_annotations(oop constructor, oop value) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + assert(has_type_annotations_field(), "type_annotations field must be present"); + constructor->obj_field_put(type_annotations_offset, value); +} + void java_lang_reflect_Field::compute_offsets() { Klass* k = SystemDictionary::reflect_Field_klass(); compute_offset(clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature()); @@ -2096,8 +2132,10 @@ void java_lang_reflect_Field::compute_offsets() { // The generic signature and annotations fields are only present in 1.5 signature_offset = -1; annotations_offset = -1; + type_annotations_offset = -1; compute_optional_offset(signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature()); compute_optional_offset(annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature()); + compute_optional_offset(type_annotations_offset, k, vmSymbols::type_annotations_name(), vmSymbols::byte_array_signature()); } Handle java_lang_reflect_Field::create(TRAPS) { @@ -2192,6 +2230,21 @@ void java_lang_reflect_Field::set_annotations(oop field, oop value) { field->obj_field_put(annotations_offset, value); } +bool java_lang_reflect_Field::has_type_annotations_field() { + return (type_annotations_offset >= 0); +} + +oop java_lang_reflect_Field::type_annotations(oop field) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + assert(has_type_annotations_field(), "type_annotations field must be present"); + return field->obj_field(type_annotations_offset); +} + +void java_lang_reflect_Field::set_type_annotations(oop field, oop value) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + assert(has_type_annotations_field(), "type_annotations field must be present"); + field->obj_field_put(type_annotations_offset, value); +} void sun_reflect_ConstantPool::compute_offsets() { Klass* k = SystemDictionary::reflect_ConstantPool_klass(); @@ -2857,6 +2910,7 @@ int java_lang_reflect_Method::signature_offset; int java_lang_reflect_Method::annotations_offset; int java_lang_reflect_Method::parameter_annotations_offset; int java_lang_reflect_Method::annotation_default_offset; +int java_lang_reflect_Method::type_annotations_offset; int java_lang_reflect_Constructor::clazz_offset; int java_lang_reflect_Constructor::parameterTypes_offset; int java_lang_reflect_Constructor::exceptionTypes_offset; @@ -2865,6 +2919,7 @@ int java_lang_reflect_Constructor::modifiers_offset; int java_lang_reflect_Constructor::signature_offset; int java_lang_reflect_Constructor::annotations_offset; int java_lang_reflect_Constructor::parameter_annotations_offset; +int java_lang_reflect_Constructor::type_annotations_offset; int java_lang_reflect_Field::clazz_offset; int java_lang_reflect_Field::name_offset; int java_lang_reflect_Field::type_offset; @@ -2872,6 +2927,7 @@ int java_lang_reflect_Field::slot_offset; int java_lang_reflect_Field::modifiers_offset; int java_lang_reflect_Field::signature_offset; int java_lang_reflect_Field::annotations_offset; +int java_lang_reflect_Field::type_annotations_offset; int java_lang_boxing_object::value_offset; int java_lang_boxing_object::long_value_offset; int java_lang_ref_Reference::referent_offset; diff --git a/hotspot/src/share/vm/classfile/javaClasses.hpp b/hotspot/src/share/vm/classfile/javaClasses.hpp index 9359d5b3c6e..1a4b51f5997 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.hpp +++ b/hotspot/src/share/vm/classfile/javaClasses.hpp @@ -554,6 +554,7 @@ class java_lang_reflect_Method : public java_lang_reflect_AccessibleObject { static int annotations_offset; static int parameter_annotations_offset; static int annotation_default_offset; + static int type_annotations_offset; static void compute_offsets(); @@ -599,6 +600,10 @@ class java_lang_reflect_Method : public java_lang_reflect_AccessibleObject { static oop annotation_default(oop method); static void set_annotation_default(oop method, oop value); + static bool has_type_annotations_field(); + static oop type_annotations(oop method); + static void set_type_annotations(oop method, oop value); + // Debugging friend class JavaClasses; }; @@ -618,6 +623,7 @@ class java_lang_reflect_Constructor : public java_lang_reflect_AccessibleObject static int signature_offset; static int annotations_offset; static int parameter_annotations_offset; + static int type_annotations_offset; static void compute_offsets(); @@ -653,6 +659,10 @@ class java_lang_reflect_Constructor : public java_lang_reflect_AccessibleObject static oop parameter_annotations(oop method); static void set_parameter_annotations(oop method, oop value); + static bool has_type_annotations_field(); + static oop type_annotations(oop constructor); + static void set_type_annotations(oop constructor, oop value); + // Debugging friend class JavaClasses; }; @@ -671,6 +681,7 @@ class java_lang_reflect_Field : public java_lang_reflect_AccessibleObject { static int modifiers_offset; static int signature_offset; static int annotations_offset; + static int type_annotations_offset; static void compute_offsets(); @@ -710,6 +721,10 @@ class java_lang_reflect_Field : public java_lang_reflect_AccessibleObject { static oop annotation_default(oop method); static void set_annotation_default(oop method, oop value); + static bool has_type_annotations_field(); + static oop type_annotations(oop field); + static void set_type_annotations(oop field, oop value); + // Debugging friend class JavaClasses; }; diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp index 940aac3c29b..5c9b6327eaa 100644 --- a/hotspot/src/share/vm/classfile/vmSymbols.hpp +++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp @@ -136,6 +136,8 @@ template(tag_runtime_visible_parameter_annotations, "RuntimeVisibleParameterAnnotations") \ template(tag_runtime_invisible_parameter_annotations,"RuntimeInvisibleParameterAnnotations") \ template(tag_annotation_default, "AnnotationDefault") \ + template(tag_runtime_visible_type_annotations, "RuntimeVisibleTypeAnnotations") \ + template(tag_runtime_invisible_type_annotations, "RuntimeInvisibleTypeAnnotations") \ template(tag_enclosing_method, "EnclosingMethod") \ template(tag_bootstrap_methods, "BootstrapMethods") \ \ @@ -239,6 +241,9 @@ template(ConstantPool_name, "constantPoolOop") \ template(sun_reflect_UnsafeStaticFieldAccessorImpl, "sun/reflect/UnsafeStaticFieldAccessorImpl")\ template(base_name, "base") \ + /* Type Annotations (JDK 8 and above) */ \ + template(type_annotations_name, "typeAnnotations") \ + \ \ /* Support for JSR 292 & invokedynamic (JDK 1.7 and above) */ \ template(java_lang_invoke_CallSite, "java/lang/invoke/CallSite") \ diff --git a/hotspot/src/share/vm/oops/annotations.cpp b/hotspot/src/share/vm/oops/annotations.cpp index 05ded22035b..72c5737f056 100644 --- a/hotspot/src/share/vm/oops/annotations.cpp +++ b/hotspot/src/share/vm/oops/annotations.cpp @@ -61,6 +61,9 @@ void Annotations::deallocate_contents(ClassLoaderData* loader_data) { free_contents(loader_data, methods_annotations()); free_contents(loader_data, methods_parameter_annotations()); free_contents(loader_data, methods_default_annotations()); + + // Recursively deallocate optional Annotations linked through this one + MetadataFactory::free_metadata(loader_data, type_annotations()); } // Set the annotation at 'idnum' to 'anno'. diff --git a/hotspot/src/share/vm/oops/annotations.hpp b/hotspot/src/share/vm/oops/annotations.hpp index 63a42bbda56..07d05467ba1 100644 --- a/hotspot/src/share/vm/oops/annotations.hpp +++ b/hotspot/src/share/vm/oops/annotations.hpp @@ -38,7 +38,8 @@ class outputStream; typedef Array AnnotationArray; // Class to hold the various types of annotations. The only metadata that points -// to this is InstanceKlass. +// to this is InstanceKlass, or another Annotations instance if this is a +// a type_annotation instance. class Annotations: public MetaspaceObj { @@ -58,6 +59,8 @@ class Annotations: public MetaspaceObj { // such annotations. // Index is the idnum, which is initially the same as the methods array index. Array* _methods_default_annotations; + // Type annotations for this class, or null if none. + Annotations* _type_annotations; // Constructor where some some values are known to not be null Annotations(Array* fa, Array* ma, @@ -66,7 +69,8 @@ class Annotations: public MetaspaceObj { _fields_annotations(fa), _methods_annotations(ma), _methods_parameter_annotations(mpa), - _methods_default_annotations(mda) {} + _methods_default_annotations(mda), + _type_annotations(NULL) {} public: // Allocate instance of this class @@ -81,22 +85,26 @@ class Annotations: public MetaspaceObj { static int size() { return sizeof(Annotations) / wordSize; } // Constructor to initialize to null - Annotations() : _class_annotations(NULL), _fields_annotations(NULL), + Annotations() : _class_annotations(NULL), + _fields_annotations(NULL), _methods_annotations(NULL), _methods_parameter_annotations(NULL), - _methods_default_annotations(NULL) {} + _methods_default_annotations(NULL), + _type_annotations(NULL) {} AnnotationArray* class_annotations() const { return _class_annotations; } Array* fields_annotations() const { return _fields_annotations; } Array* methods_annotations() const { return _methods_annotations; } Array* methods_parameter_annotations() const { return _methods_parameter_annotations; } Array* methods_default_annotations() const { return _methods_default_annotations; } + Annotations* type_annotations() const { return _type_annotations; } void set_class_annotations(AnnotationArray* md) { _class_annotations = md; } void set_fields_annotations(Array* md) { _fields_annotations = md; } void set_methods_annotations(Array* md) { _methods_annotations = md; } void set_methods_parameter_annotations(Array* md) { _methods_parameter_annotations = md; } void set_methods_default_annotations(Array* md) { _methods_default_annotations = md; } + void set_type_annotations(Annotations* annos) { _type_annotations = annos; } // Redefine classes support AnnotationArray* get_method_annotations_of(int idnum) @@ -129,6 +137,7 @@ class Annotations: public MetaspaceObj { inline AnnotationArray* get_method_annotations_from(int idnum, Array* annos); void set_annotations(Array* md, Array** md_p) { *md_p = md; } + bool is_klass() const { return false; } private: void set_methods_annotations_of(instanceKlassHandle ik, int idnum, AnnotationArray* anno, diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index 69d1910f2b1..ce30929f522 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -361,6 +361,9 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) { set_protection_domain(NULL); set_signers(NULL); set_init_lock(NULL); + + // We should deallocate the Annotations instance + MetadataFactory::free_metadata(loader_data, annotations()); set_annotations(NULL); } diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp index ddbdbd68024..426486dd965 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.hpp +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp @@ -657,6 +657,10 @@ class InstanceKlass: public Klass { if (annotations() == NULL) return NULL; return annotations()->fields_annotations(); } + Annotations* type_annotations() const { + if (annotations() == NULL) return NULL; + return annotations()->type_annotations(); + } // allocation instanceOop allocate_instance(TRAPS); diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp index 5818d58c298..c8aff7f36fd 100644 --- a/hotspot/src/share/vm/oops/method.cpp +++ b/hotspot/src/share/vm/oops/method.cpp @@ -1331,13 +1331,15 @@ void Method::sort_methods(Array* methods, Array* methods_annotations, Array* methods_parameter_annotations, Array* methods_default_annotations, + Array* methods_type_annotations, bool idempotent) { int length = methods->length(); if (length > 1) { bool do_annotations = false; if (methods_annotations != NULL || methods_parameter_annotations != NULL || - methods_default_annotations != NULL) { + methods_default_annotations != NULL || + methods_type_annotations != NULL) { do_annotations = true; } if (do_annotations) { @@ -1356,6 +1358,7 @@ void Method::sort_methods(Array* methods, assert(methods_annotations == NULL || methods_annotations->length() == methods->length(), ""); assert(methods_parameter_annotations == NULL || methods_parameter_annotations->length() == methods->length(), ""); assert(methods_default_annotations == NULL || methods_default_annotations->length() == methods->length(), ""); + assert(methods_type_annotations == NULL || methods_type_annotations->length() == methods->length(), ""); if (do_annotations) { ResourceMark rm; // Allocate temporary storage @@ -1363,6 +1366,7 @@ void Method::sort_methods(Array* methods, reorder_based_on_method_index(methods, methods_annotations, temp_array); reorder_based_on_method_index(methods, methods_parameter_annotations, temp_array); reorder_based_on_method_index(methods, methods_default_annotations, temp_array); + reorder_based_on_method_index(methods, methods_type_annotations, temp_array); } // Reset method ordering diff --git a/hotspot/src/share/vm/oops/method.hpp b/hotspot/src/share/vm/oops/method.hpp index ff7bc0ee53d..5cf15319789 100644 --- a/hotspot/src/share/vm/oops/method.hpp +++ b/hotspot/src/share/vm/oops/method.hpp @@ -228,6 +228,13 @@ class Method : public Metadata { } return ik->annotations()->get_method_default_annotations_of(method_idnum()); } + AnnotationArray* type_annotations() const { + InstanceKlass* ik = method_holder(); + Annotations* type_annos = ik->type_annotations(); + if (type_annos == NULL) + return NULL; + return type_annos->get_method_annotations_of(method_idnum()); +} #ifdef CC_INTERP void set_result_index(BasicType type); @@ -794,6 +801,7 @@ class Method : public Metadata { Array* methods_annotations, Array* methods_parameter_annotations, Array* methods_default_annotations, + Array* methods_type_annotations, bool idempotent = false); // size of parameters diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp index c381674ffb5..51d4a1d6e25 100644 --- a/hotspot/src/share/vm/prims/jvm.cpp +++ b/hotspot/src/share/vm/prims/jvm.cpp @@ -1573,6 +1573,23 @@ JVM_ENTRY(jbyteArray, JVM_GetMethodParameterAnnotations(JNIEnv *env, jobject met Annotations::make_java_array(m->parameter_annotations(), THREAD)); JVM_END +/* Type use annotations support (JDK 1.8) */ + +JVM_ENTRY(jbyteArray, JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls)) + assert (cls != NULL, "illegal class"); + JVMWrapper("JVM_GetClassTypeAnnotations"); + ResourceMark rm(THREAD); + // Return null for arrays and primitives + if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) { + Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls)); + if (k->oop_is_instance()) { + typeArrayOop a = Annotations::make_java_array(InstanceKlass::cast(k)->type_annotations()->class_annotations(), CHECK_NULL); + return (jbyteArray) JNIHandles::make_local(env, a); + } + } + return NULL; +JVM_END + // New (JDK 1.4) reflection implementation ///////////////////////////////////// diff --git a/hotspot/src/share/vm/prims/jvm.h b/hotspot/src/share/vm/prims/jvm.h index 2bbc3db4dbc..8dde7e90050 100644 --- a/hotspot/src/share/vm/prims/jvm.h +++ b/hotspot/src/share/vm/prims/jvm.h @@ -519,6 +519,10 @@ JVM_GetMethodDefaultAnnotationValue(JNIEnv *env, jobject method); JNIEXPORT jbyteArray JNICALL JVM_GetMethodParameterAnnotations(JNIEnv *env, jobject method); +/* Type use annotations support (JDK 1.8) */ + +JNIEXPORT jbyteArray JNICALL +JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls); /* * New (JDK 1.4) reflection implementation diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp index e3653000fea..6fb7243a872 100644 --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp @@ -3338,7 +3338,20 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass, the_class->set_access_flags(flags); } - // Replace annotation fields value + // Since there is currently no rewriting of type annotations indexes + // into the CP, we null out type annotations on scratch_class before + // we swap annotations with the_class rather than facing the + // possibility of shipping annotations with broken indexes to + // Java-land. + Annotations* new_annotations = scratch_class->annotations(); + if (new_annotations != NULL) { + Annotations* new_type_annotations = new_annotations->type_annotations(); + if (new_type_annotations != NULL) { + MetadataFactory::free_metadata(scratch_class->class_loader_data(), new_type_annotations); + new_annotations->set_type_annotations(NULL); + } + } + // Swap annotation fields values Annotations* old_annotations = the_class->annotations(); the_class->set_annotations(scratch_class->annotations()); scratch_class->set_annotations(old_annotations); diff --git a/hotspot/src/share/vm/runtime/fieldDescriptor.cpp b/hotspot/src/share/vm/runtime/fieldDescriptor.cpp index 001d5d23e11..54a225a5ffe 100644 --- a/hotspot/src/share/vm/runtime/fieldDescriptor.cpp +++ b/hotspot/src/share/vm/runtime/fieldDescriptor.cpp @@ -65,6 +65,17 @@ AnnotationArray* fieldDescriptor::annotations() const { return md->at(index()); } +AnnotationArray* fieldDescriptor::type_annotations() const { + InstanceKlass* ik = field_holder(); + Annotations* type_annos = ik->type_annotations(); + if (type_annos == NULL) + return NULL; + Array* md = type_annos->fields_annotations(); + if (md == NULL) + return NULL; + return md->at(index()); +} + constantTag fieldDescriptor::initial_value_tag() const { return constants()->tag_at(initial_value_index()); } diff --git a/hotspot/src/share/vm/runtime/fieldDescriptor.hpp b/hotspot/src/share/vm/runtime/fieldDescriptor.hpp index 00caf89844f..12b75cab144 100644 --- a/hotspot/src/share/vm/runtime/fieldDescriptor.hpp +++ b/hotspot/src/share/vm/runtime/fieldDescriptor.hpp @@ -68,6 +68,7 @@ class fieldDescriptor VALUE_OBJ_CLASS_SPEC { Symbol* generic_signature() const; int index() const { return _index; } AnnotationArray* annotations() const; + AnnotationArray* type_annotations() const; // Initial field value bool has_initial_value() const { return field()->initval_index() != 0; } diff --git a/hotspot/src/share/vm/runtime/reflection.cpp b/hotspot/src/share/vm/runtime/reflection.cpp index 448266cde41..7099d6c9396 100644 --- a/hotspot/src/share/vm/runtime/reflection.cpp +++ b/hotspot/src/share/vm/runtime/reflection.cpp @@ -771,6 +771,10 @@ oop Reflection::new_method(methodHandle method, bool intern_name, bool for_const typeArrayOop an_oop = Annotations::make_java_array(method->annotation_default(), CHECK_NULL); java_lang_reflect_Method::set_annotation_default(mh(), an_oop); } + if (java_lang_reflect_Method::has_type_annotations_field()) { + typeArrayOop an_oop = Annotations::make_java_array(method->type_annotations(), CHECK_NULL); + java_lang_reflect_Method::set_type_annotations(mh(), an_oop); + } return mh(); } @@ -849,6 +853,10 @@ oop Reflection::new_field(fieldDescriptor* fd, bool intern_name, TRAPS) { typeArrayOop an_oop = Annotations::make_java_array(fd->annotations(), CHECK_NULL); java_lang_reflect_Field::set_annotations(rh(), an_oop); } + if (java_lang_reflect_Field::has_type_annotations_field()) { + typeArrayOop an_oop = Annotations::make_java_array(fd->type_annotations(), CHECK_NULL); + java_lang_reflect_Field::set_type_annotations(rh(), an_oop); + } return rh(); } From 52a0bed8f5f3f0a4e94ab0312fb15f59a0540615 Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Fri, 21 Dec 2012 10:27:49 -0800 Subject: [PATCH 004/204] 8005382: new hotspot build - hs25-b15 Reviewed-by: jcoomes --- hotspot/make/hotspot_version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version index 60535db5496..d6959b3b86c 100644 --- a/hotspot/make/hotspot_version +++ b/hotspot/make/hotspot_version @@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2012 HS_MAJOR_VER=25 HS_MINOR_VER=0 -HS_BUILD_NUMBER=14 +HS_BUILD_NUMBER=15 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 From 86dd7963226a8c249cc1d92f2e2770df04a720e6 Mon Sep 17 00:00:00 2001 From: Jon Masamitsu Date: Wed, 26 Dec 2012 15:05:30 -0800 Subject: [PATCH 005/204] 8005486: NPG: Incorrect assertion in ChunkManager::list_index() Reviewed-by: coleenp --- hotspot/src/share/vm/memory/metaspace.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index c914adbbb78..f54803a190f 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -2084,7 +2084,7 @@ ChunkIndex ChunkManager::list_index(size_t size) { case ClassMediumChunk: return MediumIndex; default: - assert(size > MediumChunk && size > ClassMediumChunk, + assert(size > MediumChunk || size > ClassMediumChunk, "Not a humongous chunk"); return HumongousIndex; } @@ -2129,7 +2129,7 @@ void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) { new_chunk->set_next(chunks_in_use(HumongousIndex)); set_chunks_in_use(HumongousIndex, new_chunk); - assert(new_chunk->word_size() > MediumChunk, "List inconsistency"); + assert(new_chunk->word_size() > medium_chunk_size(), "List inconsistency"); } assert(new_chunk->is_empty(), "Not ready for reuse"); From 7cb614b0e50999668e7f5a16af775e05238da4b3 Mon Sep 17 00:00:00 2001 From: Tao Mao Date: Wed, 2 Jan 2013 11:32:41 -0800 Subject: [PATCH 006/204] 8004132: SerialGC: ValidateMarkSweep broken when running GCOld Remove bit-rotten ValidateMarkSweep functionality and flag. Reviewed-by: johnc, jmasa --- .../compactibleFreeListSpace.cpp | 1 - .../vm/gc_implementation/g1/g1MarkSweep.cpp | 2 - .../parallelScavenge/psMarkSweepDecorator.cpp | 10 -- .../parallelScavenge/psParallelCompact.cpp | 164 ------------------ .../parallelScavenge/psParallelCompact.hpp | 64 +------ .../vm/gc_implementation/shared/markSweep.cpp | 156 ----------------- .../vm/gc_implementation/shared/markSweep.hpp | 60 ------- .../shared/markSweep.inline.hpp | 16 -- hotspot/src/share/vm/memory/genMarkSweep.cpp | 61 ------- hotspot/src/share/vm/memory/space.cpp | 4 - hotspot/src/share/vm/memory/space.hpp | 12 -- hotspot/src/share/vm/runtime/globals.hpp | 7 - hotspot/src/share/vm/utilities/debug.cpp | 15 -- 13 files changed, 1 insertion(+), 571 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp index 2f43c987669..45e53170859 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp @@ -214,7 +214,6 @@ HeapWord* CompactibleFreeListSpace::forward(oop q, size_t size, assert(q->forwardee() == NULL, "should be forwarded to NULL"); } - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::register_live_oop(q, adjusted_size)); compact_top += adjusted_size; // we need to update the offset table so that the beginnings of objects can be diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp index 55925da896c..b987f7df4e7 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp @@ -282,10 +282,8 @@ class G1AdjustPointersClosure: public HeapRegionClosure { if (r->startsHumongous()) { // We must adjust the pointers on the single H object. oop obj = oop(r->bottom()); - debug_only(GenMarkSweep::track_interior_pointers(obj)); // point all the oops to the new location obj->adjust_pointers(); - debug_only(GenMarkSweep::check_interior_pointers()); } } else { // This really ought to be "as_CompactibleSpace"... diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp index 2b71c57d89f..9844d1afdf8 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp @@ -164,7 +164,6 @@ void PSMarkSweepDecorator::precompact() { start_array->allocate_block(compact_top); } - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::register_live_oop(oop(q), size)); compact_top += size; assert(compact_top <= dest->space()->end(), "Exceeding space in destination"); @@ -225,7 +224,6 @@ void PSMarkSweepDecorator::precompact() { start_array->allocate_block(compact_top); } - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::register_live_oop(oop(q), sz)); compact_top += sz; assert(compact_top <= dest->space()->end(), "Exceeding space in destination"); @@ -304,11 +302,8 @@ void PSMarkSweepDecorator::adjust_pointers() { HeapWord* end = _first_dead; while (q < end) { - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q))); // point all the oops to the new location size_t size = oop(q)->adjust_pointers(); - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers()); - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size)); q += size; } @@ -328,11 +323,8 @@ void PSMarkSweepDecorator::adjust_pointers() { Prefetch::write(q, interval); if (oop(q)->is_gc_marked()) { // q is alive - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q))); // point all the oops to the new location size_t size = oop(q)->adjust_pointers(); - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers()); - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size)); debug_only(prev_q = q); q += size; } else { @@ -366,7 +358,6 @@ void PSMarkSweepDecorator::compact(bool mangle_free_space ) { while (q < end) { size_t size = oop(q)->size(); assert(!oop(q)->is_gc_marked(), "should be unmarked (special dense prefix handling)"); - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::live_oop_moved_to(q, size, q)); debug_only(prev_q = q); q += size; } @@ -401,7 +392,6 @@ void PSMarkSweepDecorator::compact(bool mangle_free_space ) { Prefetch::write(compaction_top, copy_interval); // copy object and reinit its mark - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::live_oop_moved_to(q, size, compaction_top)); assert(q != compaction_top, "everything in this pass should be moving"); Copy::aligned_conjoint_words(q, compaction_top, size); oop(compaction_top)->init_mark(); diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp index 9fbf01169bf..d3d29aaf9f4 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp @@ -99,25 +99,6 @@ double PSParallelCompact::_dwl_adjustment; bool PSParallelCompact::_dwl_initialized = false; #endif // #ifdef ASSERT -#ifdef VALIDATE_MARK_SWEEP -GrowableArray* PSParallelCompact::_root_refs_stack = NULL; -GrowableArray * PSParallelCompact::_live_oops = NULL; -GrowableArray * PSParallelCompact::_live_oops_moved_to = NULL; -GrowableArray* PSParallelCompact::_live_oops_size = NULL; -size_t PSParallelCompact::_live_oops_index = 0; -GrowableArray* PSParallelCompact::_other_refs_stack = NULL; -GrowableArray* PSParallelCompact::_adjusted_pointers = NULL; -bool PSParallelCompact::_pointer_tracking = false; -bool PSParallelCompact::_root_tracking = true; - -GrowableArray* PSParallelCompact::_cur_gc_live_oops = NULL; -GrowableArray* PSParallelCompact::_cur_gc_live_oops_moved_to = NULL; -GrowableArray * PSParallelCompact::_cur_gc_live_oops_size = NULL; -GrowableArray* PSParallelCompact::_last_gc_live_oops = NULL; -GrowableArray* PSParallelCompact::_last_gc_live_oops_moved_to = NULL; -GrowableArray * PSParallelCompact::_last_gc_live_oops_size = NULL; -#endif - void SplitInfo::record(size_t src_region_idx, size_t partial_obj_size, HeapWord* destination) { @@ -2715,151 +2696,6 @@ void PSParallelCompact::verify_complete(SpaceId space_id) { } #endif // #ifdef ASSERT - -#ifdef VALIDATE_MARK_SWEEP - -void PSParallelCompact::track_adjusted_pointer(void* p, bool isroot) { - if (!ValidateMarkSweep) - return; - - if (!isroot) { - if (_pointer_tracking) { - guarantee(_adjusted_pointers->contains(p), "should have seen this pointer"); - _adjusted_pointers->remove(p); - } - } else { - ptrdiff_t index = _root_refs_stack->find(p); - if (index != -1) { - int l = _root_refs_stack->length(); - if (l > 0 && l - 1 != index) { - void* last = _root_refs_stack->pop(); - assert(last != p, "should be different"); - _root_refs_stack->at_put(index, last); - } else { - _root_refs_stack->remove(p); - } - } - } -} - - -void PSParallelCompact::check_adjust_pointer(void* p) { - _adjusted_pointers->push(p); -} - - -class AdjusterTracker: public OopClosure { - public: - AdjusterTracker() {}; - void do_oop(oop* o) { PSParallelCompact::check_adjust_pointer(o); } - void do_oop(narrowOop* o) { PSParallelCompact::check_adjust_pointer(o); } -}; - - -void PSParallelCompact::track_interior_pointers(oop obj) { - if (ValidateMarkSweep) { - _adjusted_pointers->clear(); - _pointer_tracking = true; - - AdjusterTracker checker; - obj->oop_iterate_no_header(&checker); - } -} - - -void PSParallelCompact::check_interior_pointers() { - if (ValidateMarkSweep) { - _pointer_tracking = false; - guarantee(_adjusted_pointers->length() == 0, "should have processed the same pointers"); - } -} - - -void PSParallelCompact::reset_live_oop_tracking() { - if (ValidateMarkSweep) { - guarantee((size_t)_live_oops->length() == _live_oops_index, "should be at end of live oops"); - _live_oops_index = 0; - } -} - - -void PSParallelCompact::register_live_oop(oop p, size_t size) { - if (ValidateMarkSweep) { - _live_oops->push(p); - _live_oops_size->push(size); - _live_oops_index++; - } -} - -void PSParallelCompact::validate_live_oop(oop p, size_t size) { - if (ValidateMarkSweep) { - oop obj = _live_oops->at((int)_live_oops_index); - guarantee(obj == p, "should be the same object"); - guarantee(_live_oops_size->at((int)_live_oops_index) == size, "should be the same size"); - _live_oops_index++; - } -} - -void PSParallelCompact::live_oop_moved_to(HeapWord* q, size_t size, - HeapWord* compaction_top) { - assert(oop(q)->forwardee() == NULL || oop(q)->forwardee() == oop(compaction_top), - "should be moved to forwarded location"); - if (ValidateMarkSweep) { - PSParallelCompact::validate_live_oop(oop(q), size); - _live_oops_moved_to->push(oop(compaction_top)); - } - if (RecordMarkSweepCompaction) { - _cur_gc_live_oops->push(q); - _cur_gc_live_oops_moved_to->push(compaction_top); - _cur_gc_live_oops_size->push(size); - } -} - - -void PSParallelCompact::compaction_complete() { - if (RecordMarkSweepCompaction) { - GrowableArray* _tmp_live_oops = _cur_gc_live_oops; - GrowableArray* _tmp_live_oops_moved_to = _cur_gc_live_oops_moved_to; - GrowableArray * _tmp_live_oops_size = _cur_gc_live_oops_size; - - _cur_gc_live_oops = _last_gc_live_oops; - _cur_gc_live_oops_moved_to = _last_gc_live_oops_moved_to; - _cur_gc_live_oops_size = _last_gc_live_oops_size; - _last_gc_live_oops = _tmp_live_oops; - _last_gc_live_oops_moved_to = _tmp_live_oops_moved_to; - _last_gc_live_oops_size = _tmp_live_oops_size; - } -} - - -void PSParallelCompact::print_new_location_of_heap_address(HeapWord* q) { - if (!RecordMarkSweepCompaction) { - tty->print_cr("Requires RecordMarkSweepCompaction to be enabled"); - return; - } - - if (_last_gc_live_oops == NULL) { - tty->print_cr("No compaction information gathered yet"); - return; - } - - for (int i = 0; i < _last_gc_live_oops->length(); i++) { - HeapWord* old_oop = _last_gc_live_oops->at(i); - size_t sz = _last_gc_live_oops_size->at(i); - if (old_oop <= q && q < (old_oop + sz)) { - HeapWord* new_oop = _last_gc_live_oops_moved_to->at(i); - size_t offset = (q - old_oop); - tty->print_cr("Address " PTR_FORMAT, q); - tty->print_cr(" Was in oop " PTR_FORMAT ", size %d, at offset %d", old_oop, sz, offset); - tty->print_cr(" Now in oop " PTR_FORMAT ", actual address " PTR_FORMAT, new_oop, new_oop + offset); - return; - } - } - - tty->print_cr("Address " PTR_FORMAT " not found in live oop information from last GC", q); -} -#endif //VALIDATE_MARK_SWEEP - // Update interior oops in the ranges of regions [beg_region, end_region). void PSParallelCompact::update_and_deadwood_in_dense_prefix(ParCompactionManager* cm, diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp index 0ce1706d34c..d26f5b0b72e 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp @@ -1006,34 +1006,6 @@ class PSParallelCompact : AllStatic { // Reset time since last full gc static void reset_millis_since_last_gc(); - protected: -#ifdef VALIDATE_MARK_SWEEP - static GrowableArray* _root_refs_stack; - static GrowableArray * _live_oops; - static GrowableArray * _live_oops_moved_to; - static GrowableArray* _live_oops_size; - static size_t _live_oops_index; - static size_t _live_oops_index_at_perm; - static GrowableArray* _other_refs_stack; - static GrowableArray* _adjusted_pointers; - static bool _pointer_tracking; - static bool _root_tracking; - - // The following arrays are saved since the time of the last GC and - // assist in tracking down problems where someone has done an errant - // store into the heap, usually to an oop that wasn't properly - // handleized across a GC. If we crash or otherwise fail before the - // next GC, we can query these arrays to find out the object we had - // intended to do the store to (assuming it is still alive) and the - // offset within that object. Covered under RecordMarkSweepCompaction. - static GrowableArray * _cur_gc_live_oops; - static GrowableArray * _cur_gc_live_oops_moved_to; - static GrowableArray* _cur_gc_live_oops_size; - static GrowableArray * _last_gc_live_oops; - static GrowableArray * _last_gc_live_oops_moved_to; - static GrowableArray* _last_gc_live_oops_size; -#endif - public: class MarkAndPushClosure: public OopClosure { private: @@ -1191,25 +1163,6 @@ class PSParallelCompact : AllStatic { // Time since last full gc (in milliseconds). static jlong millis_since_last_gc(); -#ifdef VALIDATE_MARK_SWEEP - static void track_adjusted_pointer(void* p, bool isroot); - static void check_adjust_pointer(void* p); - static void track_interior_pointers(oop obj); - static void check_interior_pointers(); - - static void reset_live_oop_tracking(); - static void register_live_oop(oop p, size_t size); - static void validate_live_oop(oop p, size_t size); - static void live_oop_moved_to(HeapWord* q, size_t size, HeapWord* compaction_top); - static void compaction_complete(); - - // Querying operation of RecordMarkSweepCompaction results. - // Finds and prints the current base oop and offset for a word - // within an oop that was live during the last GC. Helpful for - // tracking down heap stomps. - static void print_new_location_of_heap_address(HeapWord* q); -#endif // #ifdef VALIDATE_MARK_SWEEP - #ifndef PRODUCT // Debugging support. static const char* space_names[last_space_id]; @@ -1250,12 +1203,7 @@ template inline void PSParallelCompact::follow_root(ParCompactionManager* cm, T* p) { assert(!Universe::heap()->is_in_reserved(p), "roots shouldn't be things within the heap"); -#ifdef VALIDATE_MARK_SWEEP - if (ValidateMarkSweep) { - guarantee(!_root_refs_stack->contains(p), "should only be in here once"); - _root_refs_stack->push(p); - } -#endif + T heap_oop = oopDesc::load_heap_oop(p); if (!oopDesc::is_null(heap_oop)) { oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); @@ -1294,20 +1242,10 @@ inline void PSParallelCompact::adjust_pointer(T* p, bool isroot) { oopDesc::encode_store_heap_oop_not_null(p, new_obj); } } - VALIDATE_MARK_SWEEP_ONLY(track_adjusted_pointer(p, isroot)); } template inline void PSParallelCompact::KeepAliveClosure::do_oop_work(T* p) { -#ifdef VALIDATE_MARK_SWEEP - if (ValidateMarkSweep) { - if (!Universe::heap()->is_in_reserved(p)) { - _root_refs_stack->push(p); - } else { - _other_refs_stack->push(p); - } - } -#endif mark_and_push(_compaction_manager, p); } diff --git a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp index bbbd1a05532..6ea4097daa9 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp @@ -42,26 +42,6 @@ size_t MarkSweep::_preserved_count_max = 0; PreservedMark* MarkSweep::_preserved_marks = NULL; ReferenceProcessor* MarkSweep::_ref_processor = NULL; -#ifdef VALIDATE_MARK_SWEEP -GrowableArray* MarkSweep::_root_refs_stack = NULL; -GrowableArray * MarkSweep::_live_oops = NULL; -GrowableArray * MarkSweep::_live_oops_moved_to = NULL; -GrowableArray* MarkSweep::_live_oops_size = NULL; -size_t MarkSweep::_live_oops_index = 0; -size_t MarkSweep::_live_oops_index_at_perm = 0; -GrowableArray* MarkSweep::_other_refs_stack = NULL; -GrowableArray* MarkSweep::_adjusted_pointers = NULL; -bool MarkSweep::_pointer_tracking = false; -bool MarkSweep::_root_tracking = true; - -GrowableArray* MarkSweep::_cur_gc_live_oops = NULL; -GrowableArray* MarkSweep::_cur_gc_live_oops_moved_to = NULL; -GrowableArray * MarkSweep::_cur_gc_live_oops_size = NULL; -GrowableArray* MarkSweep::_last_gc_live_oops = NULL; -GrowableArray* MarkSweep::_last_gc_live_oops_moved_to = NULL; -GrowableArray * MarkSweep::_last_gc_live_oops_size = NULL; -#endif - MarkSweep::FollowRootClosure MarkSweep::follow_root_closure; CodeBlobToOopClosure MarkSweep::follow_code_root_closure(&MarkSweep::follow_root_closure, /*do_marking=*/ true); @@ -185,142 +165,6 @@ void MarkSweep::restore_marks() { } } -#ifdef VALIDATE_MARK_SWEEP - -void MarkSweep::track_adjusted_pointer(void* p, bool isroot) { - if (!ValidateMarkSweep) - return; - - if (!isroot) { - if (_pointer_tracking) { - guarantee(_adjusted_pointers->contains(p), "should have seen this pointer"); - _adjusted_pointers->remove(p); - } - } else { - ptrdiff_t index = _root_refs_stack->find(p); - if (index != -1) { - int l = _root_refs_stack->length(); - if (l > 0 && l - 1 != index) { - void* last = _root_refs_stack->pop(); - assert(last != p, "should be different"); - _root_refs_stack->at_put(index, last); - } else { - _root_refs_stack->remove(p); - } - } - } -} - -void MarkSweep::check_adjust_pointer(void* p) { - _adjusted_pointers->push(p); -} - -class AdjusterTracker: public OopClosure { - public: - AdjusterTracker() {} - void do_oop(oop* o) { MarkSweep::check_adjust_pointer(o); } - void do_oop(narrowOop* o) { MarkSweep::check_adjust_pointer(o); } -}; - -void MarkSweep::track_interior_pointers(oop obj) { - if (ValidateMarkSweep) { - _adjusted_pointers->clear(); - _pointer_tracking = true; - - AdjusterTracker checker; - obj->oop_iterate_no_header(&checker); - } -} - -void MarkSweep::check_interior_pointers() { - if (ValidateMarkSweep) { - _pointer_tracking = false; - guarantee(_adjusted_pointers->length() == 0, "should have processed the same pointers"); - } -} - -void MarkSweep::reset_live_oop_tracking() { - if (ValidateMarkSweep) { - guarantee((size_t)_live_oops->length() == _live_oops_index, "should be at end of live oops"); - _live_oops_index = 0; - } -} - -void MarkSweep::register_live_oop(oop p, size_t size) { - if (ValidateMarkSweep) { - _live_oops->push(p); - _live_oops_size->push(size); - _live_oops_index++; - } -} - -void MarkSweep::validate_live_oop(oop p, size_t size) { - if (ValidateMarkSweep) { - oop obj = _live_oops->at((int)_live_oops_index); - guarantee(obj == p, "should be the same object"); - guarantee(_live_oops_size->at((int)_live_oops_index) == size, "should be the same size"); - _live_oops_index++; - } -} - -void MarkSweep::live_oop_moved_to(HeapWord* q, size_t size, - HeapWord* compaction_top) { - assert(oop(q)->forwardee() == NULL || oop(q)->forwardee() == oop(compaction_top), - "should be moved to forwarded location"); - if (ValidateMarkSweep) { - MarkSweep::validate_live_oop(oop(q), size); - _live_oops_moved_to->push(oop(compaction_top)); - } - if (RecordMarkSweepCompaction) { - _cur_gc_live_oops->push(q); - _cur_gc_live_oops_moved_to->push(compaction_top); - _cur_gc_live_oops_size->push(size); - } -} - -void MarkSweep::compaction_complete() { - if (RecordMarkSweepCompaction) { - GrowableArray* _tmp_live_oops = _cur_gc_live_oops; - GrowableArray* _tmp_live_oops_moved_to = _cur_gc_live_oops_moved_to; - GrowableArray * _tmp_live_oops_size = _cur_gc_live_oops_size; - - _cur_gc_live_oops = _last_gc_live_oops; - _cur_gc_live_oops_moved_to = _last_gc_live_oops_moved_to; - _cur_gc_live_oops_size = _last_gc_live_oops_size; - _last_gc_live_oops = _tmp_live_oops; - _last_gc_live_oops_moved_to = _tmp_live_oops_moved_to; - _last_gc_live_oops_size = _tmp_live_oops_size; - } -} - -void MarkSweep::print_new_location_of_heap_address(HeapWord* q) { - if (!RecordMarkSweepCompaction) { - tty->print_cr("Requires RecordMarkSweepCompaction to be enabled"); - return; - } - - if (_last_gc_live_oops == NULL) { - tty->print_cr("No compaction information gathered yet"); - return; - } - - for (int i = 0; i < _last_gc_live_oops->length(); i++) { - HeapWord* old_oop = _last_gc_live_oops->at(i); - size_t sz = _last_gc_live_oops_size->at(i); - if (old_oop <= q && q < (old_oop + sz)) { - HeapWord* new_oop = _last_gc_live_oops_moved_to->at(i); - size_t offset = (q - old_oop); - tty->print_cr("Address " PTR_FORMAT, q); - tty->print_cr(" Was in oop " PTR_FORMAT ", size " SIZE_FORMAT ", at offset " SIZE_FORMAT, old_oop, sz, offset); - tty->print_cr(" Now in oop " PTR_FORMAT ", actual address " PTR_FORMAT, new_oop, new_oop + offset); - return; - } - } - - tty->print_cr("Address " PTR_FORMAT " not found in live oop information from last GC", q); -} -#endif //VALIDATE_MARK_SWEEP - MarkSweep::IsAliveClosure MarkSweep::is_alive; void MarkSweep::IsAliveClosure::do_object(oop p) { ShouldNotReachHere(); } diff --git a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp b/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp index 2153c99d168..1de7561ce55 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp @@ -44,21 +44,6 @@ class DataLayout; // // Class unloading will only occur when a full gc is invoked. -// If VALIDATE_MARK_SWEEP is defined, the -XX:+ValidateMarkSweep flag will -// be operational, and will provide slow but comprehensive self-checks within -// the GC. This is not enabled by default in product or release builds, -// since the extra call to track_adjusted_pointer() in _adjust_pointer() -// would be too much overhead, and would disturb performance measurement. -// However, debug builds are sometimes way too slow to run GC tests! -#ifdef ASSERT -#define VALIDATE_MARK_SWEEP 1 -#endif -#ifdef VALIDATE_MARK_SWEEP -#define VALIDATE_MARK_SWEEP_ONLY(code) code -#else -#define VALIDATE_MARK_SWEEP_ONLY(code) -#endif - // declared at end class PreservedMark; @@ -147,33 +132,6 @@ class MarkSweep : AllStatic { // Reference processing (used in ...follow_contents) static ReferenceProcessor* _ref_processor; -#ifdef VALIDATE_MARK_SWEEP - static GrowableArray* _root_refs_stack; - static GrowableArray * _live_oops; - static GrowableArray * _live_oops_moved_to; - static GrowableArray* _live_oops_size; - static size_t _live_oops_index; - static size_t _live_oops_index_at_perm; - static GrowableArray* _other_refs_stack; - static GrowableArray* _adjusted_pointers; - static bool _pointer_tracking; - static bool _root_tracking; - - // The following arrays are saved since the time of the last GC and - // assist in tracking down problems where someone has done an errant - // store into the heap, usually to an oop that wasn't properly - // handleized across a GC. If we crash or otherwise fail before the - // next GC, we can query these arrays to find out the object we had - // intended to do the store to (assuming it is still alive) and the - // offset within that object. Covered under RecordMarkSweepCompaction. - static GrowableArray * _cur_gc_live_oops; - static GrowableArray * _cur_gc_live_oops_moved_to; - static GrowableArray* _cur_gc_live_oops_size; - static GrowableArray * _last_gc_live_oops; - static GrowableArray * _last_gc_live_oops_moved_to; - static GrowableArray* _last_gc_live_oops_size; -#endif - // Non public closures static KeepAliveClosure keep_alive; @@ -227,24 +185,6 @@ class MarkSweep : AllStatic { static void adjust_pointer(oop* p) { adjust_pointer(p, false); } static void adjust_pointer(narrowOop* p) { adjust_pointer(p, false); } -#ifdef VALIDATE_MARK_SWEEP - static void track_adjusted_pointer(void* p, bool isroot); - static void check_adjust_pointer(void* p); - static void track_interior_pointers(oop obj); - static void check_interior_pointers(); - - static void reset_live_oop_tracking(); - static void register_live_oop(oop p, size_t size); - static void validate_live_oop(oop p, size_t size); - static void live_oop_moved_to(HeapWord* q, size_t size, HeapWord* compaction_top); - static void compaction_complete(); - - // Querying operation of RecordMarkSweepCompaction results. - // Finds and prints the current base oop and offset for a word - // within an oop that was live during the last GC. Helpful for - // tracking down heap stomps. - static void print_new_location_of_heap_address(HeapWord* q); -#endif }; class PreservedMark VALUE_OBJ_CLASS_SPEC { diff --git a/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp b/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp index 800b8dd1681..3a3cbdd8c96 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp @@ -46,12 +46,6 @@ inline void MarkSweep::mark_object(oop obj) { template inline void MarkSweep::follow_root(T* p) { assert(!Universe::heap()->is_in_reserved(p), "roots shouldn't be things within the heap"); -#ifdef VALIDATE_MARK_SWEEP - if (ValidateMarkSweep) { - guarantee(!_root_refs_stack->contains(p), "should only be in here once"); - _root_refs_stack->push(p); - } -#endif T heap_oop = oopDesc::load_heap_oop(p); if (!oopDesc::is_null(heap_oop)) { oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); @@ -97,19 +91,9 @@ template inline void MarkSweep::adjust_pointer(T* p, bool isroot) { oopDesc::encode_store_heap_oop_not_null(p, new_obj); } } - VALIDATE_MARK_SWEEP_ONLY(track_adjusted_pointer(p, isroot)); } template inline void MarkSweep::KeepAliveClosure::do_oop_work(T* p) { -#ifdef VALIDATE_MARK_SWEEP - if (ValidateMarkSweep) { - if (!Universe::heap()->is_in_reserved(p)) { - _root_refs_stack->push(p); - } else { - _other_refs_stack->push(p); - } - } -#endif mark_and_push(p); } diff --git a/hotspot/src/share/vm/memory/genMarkSweep.cpp b/hotspot/src/share/vm/memory/genMarkSweep.cpp index 5ae79947276..2180f63886f 100644 --- a/hotspot/src/share/vm/memory/genMarkSweep.cpp +++ b/hotspot/src/share/vm/memory/genMarkSweep.cpp @@ -100,21 +100,8 @@ void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp, mark_sweep_phase3(level); - VALIDATE_MARK_SWEEP_ONLY( - if (ValidateMarkSweep) { - guarantee(_root_refs_stack->length() == 0, "should be empty by now"); - } - ) - mark_sweep_phase4(); - VALIDATE_MARK_SWEEP_ONLY( - if (ValidateMarkSweep) { - guarantee(_live_oops->length() == _live_oops_moved_to->length(), - "should be the same size"); - } - ) - restore_marks(); // Set saved marks for allocation profiler (and other things? -- dld) @@ -187,31 +174,6 @@ void GenMarkSweep::allocate_stacks() { _preserved_marks = (PreservedMark*)scratch; _preserved_count = 0; - -#ifdef VALIDATE_MARK_SWEEP - if (ValidateMarkSweep) { - _root_refs_stack = new (ResourceObj::C_HEAP, mtGC) GrowableArray(100, true); - _other_refs_stack = new (ResourceObj::C_HEAP, mtGC) GrowableArray(100, true); - _adjusted_pointers = new (ResourceObj::C_HEAP, mtGC) GrowableArray(100, true); - _live_oops = new (ResourceObj::C_HEAP, mtGC) GrowableArray(100, true); - _live_oops_moved_to = new (ResourceObj::C_HEAP, mtGC) GrowableArray(100, true); - _live_oops_size = new (ResourceObj::C_HEAP, mtGC) GrowableArray(100, true); - } - if (RecordMarkSweepCompaction) { - if (_cur_gc_live_oops == NULL) { - _cur_gc_live_oops = new(ResourceObj::C_HEAP, mtGC) GrowableArray(100, true); - _cur_gc_live_oops_moved_to = new(ResourceObj::C_HEAP, mtGC) GrowableArray(100, true); - _cur_gc_live_oops_size = new(ResourceObj::C_HEAP, mtGC) GrowableArray(100, true); - _last_gc_live_oops = new(ResourceObj::C_HEAP, mtGC) GrowableArray(100, true); - _last_gc_live_oops_moved_to = new(ResourceObj::C_HEAP, mtGC) GrowableArray(100, true); - _last_gc_live_oops_size = new(ResourceObj::C_HEAP, mtGC) GrowableArray(100, true); - } else { - _cur_gc_live_oops->clear(); - _cur_gc_live_oops_moved_to->clear(); - _cur_gc_live_oops_size->clear(); - } - } -#endif } @@ -225,19 +187,6 @@ void GenMarkSweep::deallocate_stacks() { _preserved_oop_stack.clear(true); _marking_stack.clear(); _objarray_stack.clear(true); - -#ifdef VALIDATE_MARK_SWEEP - if (ValidateMarkSweep) { - delete _root_refs_stack; - delete _other_refs_stack; - delete _adjusted_pointers; - delete _live_oops; - delete _live_oops_size; - delete _live_oops_moved_to; - _live_oops_index = 0; - _live_oops_index_at_perm = 0; - } -#endif } void GenMarkSweep::mark_sweep_phase1(int level, @@ -246,8 +195,6 @@ void GenMarkSweep::mark_sweep_phase1(int level, TraceTime tm("phase 1", PrintGC && Verbose, true, gclog_or_tty); trace(" 1"); - VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking()); - GenCollectedHeap* gch = GenCollectedHeap::heap(); // Because follow_root_closure is created statically, cannot @@ -315,8 +262,6 @@ void GenMarkSweep::mark_sweep_phase2() { TraceTime tm("phase 2", PrintGC && Verbose, true, gclog_or_tty); trace("2"); - VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking()); - gch->prepare_for_compaction(); } @@ -337,8 +282,6 @@ void GenMarkSweep::mark_sweep_phase3(int level) { // Need new claim bits for the pointer adjustment tracing. ClassLoaderDataGraph::clear_claimed_marks(); - VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking()); - // Because the two closures below are created statically, cannot // use OopsInGenClosure constructor which takes a generation, // as the Universe has not been created when the static constructors @@ -393,10 +336,6 @@ void GenMarkSweep::mark_sweep_phase4() { TraceTime tm("phase 4", PrintGC && Verbose, true, gclog_or_tty); trace("4"); - VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking()); - GenCompactClosure blk; gch->generation_iterate(&blk, true); - - VALIDATE_MARK_SWEEP_ONLY(compaction_complete()); } diff --git a/hotspot/src/share/vm/memory/space.cpp b/hotspot/src/share/vm/memory/space.cpp index 7f9647f2e4a..ca3882df0ef 100644 --- a/hotspot/src/share/vm/memory/space.cpp +++ b/hotspot/src/share/vm/memory/space.cpp @@ -411,7 +411,6 @@ HeapWord* CompactibleSpace::forward(oop q, size_t size, assert(q->forwardee() == NULL, "should be forwarded to NULL"); } - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::register_live_oop(q, size)); compact_top += size; // we need to update the offset table so that the beginnings of objects can be @@ -470,13 +469,10 @@ void Space::adjust_pointers() { if (oop(q)->is_gc_marked()) { // q is alive - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q))); // point all the oops to the new location size_t size = oop(q)->adjust_pointers(); - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers()); debug_only(prev_q = q); - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size)); q += size; } else { diff --git a/hotspot/src/share/vm/memory/space.hpp b/hotspot/src/share/vm/memory/space.hpp index b2556079b5c..1dade4a26ed 100644 --- a/hotspot/src/share/vm/memory/space.hpp +++ b/hotspot/src/share/vm/memory/space.hpp @@ -655,16 +655,10 @@ protected: assert(block_is_obj(q), \ "should be at block boundaries, and should be looking at objs"); \ \ - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q))); \ - \ /* point all the oops to the new location */ \ size_t size = oop(q)->adjust_pointers(); \ size = adjust_obj_size(size); \ \ - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers()); \ - \ - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size)); \ - \ q += size; \ } \ \ @@ -685,12 +679,9 @@ protected: Prefetch::write(q, interval); \ if (oop(q)->is_gc_marked()) { \ /* q is alive */ \ - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q))); \ /* point all the oops to the new location */ \ size_t size = oop(q)->adjust_pointers(); \ size = adjust_obj_size(size); \ - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers()); \ - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size)); \ debug_only(prev_q = q); \ q += size; \ } else { \ @@ -725,7 +716,6 @@ protected: size_t size = obj_size(q); \ assert(!oop(q)->is_gc_marked(), \ "should be unmarked (special dense prefix handling)"); \ - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::live_oop_moved_to(q, size, q)); \ debug_only(prev_q = q); \ q += size; \ } \ @@ -759,8 +749,6 @@ protected: Prefetch::write(compaction_top, copy_interval); \ \ /* copy object and reinit its mark */ \ - VALIDATE_MARK_SWEEP_ONLY(MarkSweep::live_oop_moved_to(q, size, \ - compaction_top)); \ assert(q != compaction_top, "everything in this pass should be moving"); \ Copy::aligned_conjoint_words(q, compaction_top, size); \ oop(compaction_top)->init_mark(); \ diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index f63e8e2ae27..c5d4a627b63 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -1101,13 +1101,6 @@ class CommandLineFlags { product(bool, ReduceSignalUsage, false, \ "Reduce the use of OS signals in Java and/or the VM") \ \ - notproduct(bool, ValidateMarkSweep, false, \ - "Do extra validation during MarkSweep collection") \ - \ - notproduct(bool, RecordMarkSweepCompaction, false, \ - "Enable GC-to-GC recording and querying of compaction during " \ - "MarkSweep") \ - \ develop_pd(bool, ShareVtableStubs, \ "Share vtable stubs (smaller code but worse branch prediction") \ \ diff --git a/hotspot/src/share/vm/utilities/debug.cpp b/hotspot/src/share/vm/utilities/debug.cpp index e7dd8539c6f..7271879e470 100644 --- a/hotspot/src/share/vm/utilities/debug.cpp +++ b/hotspot/src/share/vm/utilities/debug.cpp @@ -612,21 +612,6 @@ extern "C" void events() { Events::print(); } -// Given a heap address that was valid before the most recent GC, if -// the oop that used to contain it is still live, prints the new -// location of the oop and the address. Useful for tracking down -// certain kinds of naked oop and oop map bugs. -extern "C" void pnl(intptr_t old_heap_addr) { - // Print New Location of old heap address - Command c("pnl"); -#ifndef VALIDATE_MARK_SWEEP - tty->print_cr("Requires build with VALIDATE_MARK_SWEEP defined (debug build) and RecordMarkSweepCompaction enabled"); -#else - MarkSweep::print_new_location_of_heap_address((HeapWord*) old_heap_addr); -#endif -} - - extern "C" Method* findm(intptr_t pc) { Command c("findm"); nmethod* nm = CodeCache::find_nmethod((address)pc); From 2df5f7cc5a19418d52f28d30269c97132b7051dd Mon Sep 17 00:00:00 2001 From: John Cuthbertson Date: Fri, 21 Dec 2012 11:45:34 -0800 Subject: [PATCH 007/204] 8001424: G1: Rename certain G1-specific flags Rename G1DefaultMinNewGenPercent, G1DefaultMaxNewGenPercent, and G1OldCSetRegionLiveThresholdPercent to G1NewSizePercent, G1MaxNewSizePercent, and G1MixedGCLiveThresholdPercent respectively. The previous names are no longer accepted. Reviewed-by: brutisso, ysr --- .../g1/collectionSetChooser.cpp | 2 +- .../g1/g1CollectorPolicy.cpp | 10 +++++----- .../g1/g1CollectorPolicy.hpp | 16 ++++++++-------- .../vm/gc_implementation/g1/g1_globals.hpp | 19 ++++++++++--------- 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp b/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp index 663011a77b1..f4c6a71439b 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp @@ -85,7 +85,7 @@ CollectionSetChooser::CollectionSetChooser() : _curr_index(0), _length(0), _first_par_unreserved_idx(0), _region_live_threshold_bytes(0), _remaining_reclaimable_bytes(0) { _region_live_threshold_bytes = - HeapRegion::GrainBytes * (size_t) G1OldCSetRegionLiveThresholdPercent / 100; + HeapRegion::GrainBytes * (size_t) G1MixedGCLiveThresholdPercent / 100; } #ifndef PRODUCT diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp index 6e9170a0006..168fc3376f6 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp @@ -309,9 +309,9 @@ void G1CollectorPolicy::initialize_flags() { } G1YoungGenSizer::G1YoungGenSizer() : _sizer_kind(SizerDefaults), _adaptive_size(true) { - assert(G1DefaultMinNewGenPercent <= G1DefaultMaxNewGenPercent, "Min larger than max"); - assert(G1DefaultMinNewGenPercent > 0 && G1DefaultMinNewGenPercent < 100, "Min out of bounds"); - assert(G1DefaultMaxNewGenPercent > 0 && G1DefaultMaxNewGenPercent < 100, "Max out of bounds"); + assert(G1NewSizePercent <= G1MaxNewSizePercent, "Min larger than max"); + assert(G1NewSizePercent > 0 && G1NewSizePercent < 100, "Min out of bounds"); + assert(G1MaxNewSizePercent > 0 && G1MaxNewSizePercent < 100, "Max out of bounds"); if (FLAG_IS_CMDLINE(NewRatio)) { if (FLAG_IS_CMDLINE(NewSize) || FLAG_IS_CMDLINE(MaxNewSize)) { @@ -344,12 +344,12 @@ G1YoungGenSizer::G1YoungGenSizer() : _sizer_kind(SizerDefaults), _adaptive_size( } uint G1YoungGenSizer::calculate_default_min_length(uint new_number_of_heap_regions) { - uint default_value = (new_number_of_heap_regions * G1DefaultMinNewGenPercent) / 100; + uint default_value = (new_number_of_heap_regions * G1NewSizePercent) / 100; return MAX2(1U, default_value); } uint G1YoungGenSizer::calculate_default_max_length(uint new_number_of_heap_regions) { - uint default_value = (new_number_of_heap_regions * G1DefaultMaxNewGenPercent) / 100; + uint default_value = (new_number_of_heap_regions * G1MaxNewSizePercent) / 100; return MAX2(1U, default_value); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp index b7d810dbb60..d32d1e66c10 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp @@ -94,18 +94,18 @@ class TraceGen1TimeData : public CHeapObj { // will occur. // // If nothing related to the the young gen size is set on the command -// line we should allow the young gen to be between -// G1DefaultMinNewGenPercent and G1DefaultMaxNewGenPercent of the -// heap size. This means that every time the heap size changes the -// limits for the young gen size will be updated. +// line we should allow the young gen to be between G1NewSizePercent +// and G1MaxNewSizePercent of the heap size. This means that every time +// the heap size changes, the limits for the young gen size will be +// recalculated. // // If only -XX:NewSize is set we should use the specified value as the -// minimum size for young gen. Still using G1DefaultMaxNewGenPercent -// of the heap as maximum. +// minimum size for young gen. Still using G1MaxNewSizePercent of the +// heap as maximum. // // If only -XX:MaxNewSize is set we should use the specified value as the -// maximum size for young gen. Still using G1DefaultMinNewGenPercent -// of the heap as minimum. +// maximum size for young gen. Still using G1NewSizePercent of the heap +// as minimum. // // If -XX:NewSize and -XX:MaxNewSize are both specified we use these values. // No updates when the heap size changes. There is a special case when diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp index a8405e0c50e..92b1cb3fc49 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp @@ -287,17 +287,18 @@ "The number of times we'll force an overflow during " \ "concurrent marking") \ \ - experimental(uintx, G1DefaultMinNewGenPercent, 20, \ - "Percentage (0-100) of the heap size to use as minimum " \ - "young gen size.") \ + experimental(uintx, G1NewSizePercent, 20, \ + "Percentage (0-100) of the heap size to use as default " \ + "minimum young gen size.") \ \ - experimental(uintx, G1DefaultMaxNewGenPercent, 80, \ - "Percentage (0-100) of the heap size to use as maximum " \ - "young gen size.") \ + experimental(uintx, G1MaxNewSizePercent, 80, \ + "Percentage (0-100) of the heap size to use as default " \ + " maximum young gen size.") \ \ - experimental(uintx, G1OldCSetRegionLiveThresholdPercent, 90, \ - "Threshold for regions to be added to the collection set. " \ - "Regions with more live bytes than this will not be collected.") \ + experimental(uintx, G1MixedGCLiveThresholdPercent, 90, \ + "Threshold for regions to be considered for inclusion in the " \ + "collection set of mixed GCs. " \ + "Regions with live bytes exceeding this will not be collected.") \ \ product(uintx, G1HeapWastePercent, 5, \ "Amount of space, expressed as a percentage of the heap size, " \ From 73d6d417be5a2ae4b6d1552fc24ac93e9456cc6b Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Sun, 23 Dec 2012 17:08:22 +0100 Subject: [PATCH 008/204] 8005071: Incremental inlining for JSR 292 Post parse inlining driven by number of live nodes. Reviewed-by: twisti, kvn, jrose --- hotspot/src/share/vm/opto/bytecodeInfo.cpp | 46 +++-- hotspot/src/share/vm/opto/c2_globals.hpp | 10 + hotspot/src/share/vm/opto/callGenerator.cpp | 153 +++++++++++++-- hotspot/src/share/vm/opto/callGenerator.hpp | 14 +- hotspot/src/share/vm/opto/callnode.cpp | 35 +++- hotspot/src/share/vm/opto/callnode.hpp | 20 +- hotspot/src/share/vm/opto/cfgnode.cpp | 52 ++++- hotspot/src/share/vm/opto/cfgnode.hpp | 3 +- hotspot/src/share/vm/opto/compile.cpp | 202 +++++++++++++++++--- hotspot/src/share/vm/opto/compile.hpp | 48 ++++- hotspot/src/share/vm/opto/doCall.cpp | 21 +- hotspot/src/share/vm/opto/graphKit.cpp | 26 ++- hotspot/src/share/vm/opto/parse.hpp | 4 +- hotspot/src/share/vm/opto/phaseX.cpp | 7 + hotspot/src/share/vm/opto/phaseX.hpp | 6 + hotspot/src/share/vm/opto/stringopts.cpp | 8 +- hotspot/src/share/vm/runtime/arguments.cpp | 12 ++ 17 files changed, 581 insertions(+), 86 deletions(-) diff --git a/hotspot/src/share/vm/opto/bytecodeInfo.cpp b/hotspot/src/share/vm/opto/bytecodeInfo.cpp index 7392ee0f614..5b80bd75c4b 100644 --- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp +++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp @@ -46,7 +46,8 @@ InlineTree::InlineTree(Compile* c, _method(callee), _site_invoke_ratio(site_invoke_ratio), _max_inline_level(max_inline_level), - _count_inline_bcs(method()->code_size_for_inlining()) + _count_inline_bcs(method()->code_size_for_inlining()), + _subtrees(c->comp_arena(), 2, 0, NULL) { NOT_PRODUCT(_count_inlines = 0;) if (_caller_jvms != NULL) { @@ -209,16 +210,18 @@ const char* InlineTree::should_not_inline(ciMethod *callee_method, ciMethod* cal if ( callee_method->dont_inline()) return "don't inline by annotation"; if ( callee_method->has_unloaded_classes_in_signature()) return "unloaded signature classes"; - if (callee_method->force_inline() || callee_method->should_inline()) { + if (callee_method->should_inline()) { // ignore heuristic controls on inlining return NULL; } // Now perform checks which are heuristic - if (callee_method->has_compiled_code() && - callee_method->instructions_size() > InlineSmallCode) { + if (!callee_method->force_inline()) { + if (callee_method->has_compiled_code() && + callee_method->instructions_size() > InlineSmallCode) { return "already compiled into a big method"; + } } // don't inline exception code unless the top method belongs to an @@ -277,12 +280,15 @@ const char* InlineTree::should_not_inline(ciMethod *callee_method, ciMethod* cal //-----------------------------try_to_inline----------------------------------- // return NULL if ok, reason for not inlining otherwise // Relocated from "InliningClosure::try_to_inline" -const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) { - +const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result, bool& should_delay) { // Old algorithm had funny accumulating BC-size counters if (UseOldInlining && ClipInlining && (int)count_inline_bcs() >= DesiredMethodLimit) { - return "size > DesiredMethodLimit"; + if (!callee_method->force_inline() || !IncrementalInline) { + return "size > DesiredMethodLimit"; + } else if (!C->inlining_incrementally()) { + should_delay = true; + } } const char *msg = NULL; @@ -303,8 +309,13 @@ const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_ if (callee_method->code_size() > MaxTrivialSize) { // don't inline into giant methods - if (C->unique() > (uint)NodeCountInliningCutoff) { - return "NodeCountInliningCutoff"; + if (C->over_inlining_cutoff()) { + if ((!callee_method->force_inline() && !caller_method->is_compiled_lambda_form()) + || !IncrementalInline) { + return "NodeCountInliningCutoff"; + } else { + should_delay = true; + } } if ((!UseInterpreter || CompileTheWorld) && @@ -323,7 +334,11 @@ const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_ return "not an accessor"; } if (inline_level() > _max_inline_level) { - return "inlining too deep"; + if (!callee_method->force_inline() || !IncrementalInline) { + return "inlining too deep"; + } else if (!C->inlining_incrementally()) { + should_delay = true; + } } // detect direct and indirect recursive inlining @@ -348,7 +363,11 @@ const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_ if (UseOldInlining && ClipInlining && (int)count_inline_bcs() + size >= DesiredMethodLimit) { - return "size > DesiredMethodLimit"; + if (!callee_method->force_inline() || !IncrementalInline) { + return "size > DesiredMethodLimit"; + } else if (!C->inlining_incrementally()) { + should_delay = true; + } } // ok, inline this method @@ -413,8 +432,9 @@ void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci, const c } //------------------------------ok_to_inline----------------------------------- -WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms, ciCallProfile& profile, WarmCallInfo* initial_wci) { +WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms, ciCallProfile& profile, WarmCallInfo* initial_wci, bool& should_delay) { assert(callee_method != NULL, "caller checks for optimized virtual!"); + assert(!should_delay, "should be initialized to false"); #ifdef ASSERT // Make sure the incoming jvms has the same information content as me. // This means that we can eventually make this whole class AllStatic. @@ -444,7 +464,7 @@ WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms, // Check if inlining policy says no. WarmCallInfo wci = *(initial_wci); - failure_msg = try_to_inline(callee_method, caller_method, caller_bci, profile, &wci); + failure_msg = try_to_inline(callee_method, caller_method, caller_bci, profile, &wci, should_delay); if (failure_msg != NULL && C->log() != NULL) { C->log()->inline_fail(failure_msg); } diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp index ba30d230cee..fa481caae22 100644 --- a/hotspot/src/share/vm/opto/c2_globals.hpp +++ b/hotspot/src/share/vm/opto/c2_globals.hpp @@ -606,6 +606,16 @@ \ develop(bool, VerifyAliases, false, \ "perform extra checks on the results of alias analysis") \ + \ + product(bool, IncrementalInline, true, \ + "do post parse inlining") \ + \ + develop(bool, AlwaysIncrementalInline, false, \ + "do all inlining incrementally") \ + \ + product(intx, LiveNodeCountInliningCutoff, 20000, \ + "max number of live nodes in a method") \ + C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG) diff --git a/hotspot/src/share/vm/opto/callGenerator.cpp b/hotspot/src/share/vm/opto/callGenerator.cpp index 66b53abf8ad..d82495f4a16 100644 --- a/hotspot/src/share/vm/opto/callGenerator.cpp +++ b/hotspot/src/share/vm/opto/callGenerator.cpp @@ -262,8 +262,11 @@ CallGenerator* CallGenerator::for_virtual_call(ciMethod* m, int vtable_index) { // Allow inlining decisions to be delayed class LateInlineCallGenerator : public DirectCallGenerator { + protected: CallGenerator* _inline_cg; + virtual bool do_late_inline_check(JVMState* jvms) { return true; } + public: LateInlineCallGenerator(ciMethod* method, CallGenerator* inline_cg) : DirectCallGenerator(method, true), _inline_cg(inline_cg) {} @@ -279,7 +282,9 @@ class LateInlineCallGenerator : public DirectCallGenerator { // Record that this call site should be revisited once the main // parse is finished. - Compile::current()->add_late_inline(this); + if (!is_mh_late_inline()) { + C->add_late_inline(this); + } // Emit the CallStaticJava and request separate projections so // that the late inlining logic can distinguish between fall @@ -287,8 +292,15 @@ class LateInlineCallGenerator : public DirectCallGenerator { // as is done for allocations and macro expansion. return DirectCallGenerator::generate(jvms); } -}; + virtual void print_inlining_late(const char* msg) { + CallNode* call = call_node(); + Compile* C = Compile::current(); + C->print_inlining_insert(this); + C->print_inlining(method(), call->jvms()->depth()-1, call->jvms()->bci(), msg); + } + +}; void LateInlineCallGenerator::do_late_inline() { // Can't inline it @@ -296,6 +308,18 @@ void LateInlineCallGenerator::do_late_inline() { call_node()->in(0) == NULL || call_node()->in(0)->is_top()) return; + for (int i1 = 0; i1 < method()->arg_size(); i1++) { + if (call_node()->in(TypeFunc::Parms + i1)->is_top()) { + assert(Compile::current()->inlining_incrementally(), "shouldn't happen during parsing"); + return; + } + } + + if (call_node()->in(TypeFunc::Memory)->is_top()) { + assert(Compile::current()->inlining_incrementally(), "shouldn't happen during parsing"); + return; + } + CallStaticJavaNode* call = call_node(); // Make a clone of the JVMState that appropriate to use for driving a parse @@ -324,6 +348,11 @@ void LateInlineCallGenerator::do_late_inline() { } } + if (!do_late_inline_check(jvms)) { + map->disconnect_inputs(NULL, C); + return; + } + C->print_inlining_insert(this); CompileLog* log = C->log(); @@ -360,6 +389,10 @@ void LateInlineCallGenerator::do_late_inline() { result = (result_size == 1) ? kit.pop() : kit.pop_pair(); } + C->set_has_loops(C->has_loops() || _inline_cg->method()->has_loops()); + C->env()->notice_inlined_method(_inline_cg->method()); + C->set_inlining_progress(true); + kit.replace_call(call, result); } @@ -368,6 +401,83 @@ CallGenerator* CallGenerator::for_late_inline(ciMethod* method, CallGenerator* i return new LateInlineCallGenerator(method, inline_cg); } +class LateInlineMHCallGenerator : public LateInlineCallGenerator { + ciMethod* _caller; + int _attempt; + bool _input_not_const; + + virtual bool do_late_inline_check(JVMState* jvms); + virtual bool already_attempted() const { return _attempt > 0; } + + public: + LateInlineMHCallGenerator(ciMethod* caller, ciMethod* callee, bool input_not_const) : + LateInlineCallGenerator(callee, NULL), _caller(caller), _attempt(0), _input_not_const(input_not_const) {} + + virtual bool is_mh_late_inline() const { return true; } + + virtual JVMState* generate(JVMState* jvms) { + JVMState* new_jvms = LateInlineCallGenerator::generate(jvms); + if (_input_not_const) { + // inlining won't be possible so no need to enqueue right now. + call_node()->set_generator(this); + } else { + Compile::current()->add_late_inline(this); + } + return new_jvms; + } + + virtual void print_inlining_late(const char* msg) { + if (!_input_not_const) return; + LateInlineCallGenerator::print_inlining_late(msg); + } +}; + +bool LateInlineMHCallGenerator::do_late_inline_check(JVMState* jvms) { + + CallGenerator* cg = for_method_handle_inline(jvms, _caller, method(), _input_not_const); + + if (!_input_not_const) { + _attempt++; + } + + if (cg != NULL) { + assert(!cg->is_late_inline() && cg->is_inline(), "we're doing late inlining"); + _inline_cg = cg; + Compile::current()->dec_number_of_mh_late_inlines(); + return true; + } + + call_node()->set_generator(this); + return false; +} + +CallGenerator* CallGenerator::for_mh_late_inline(ciMethod* caller, ciMethod* callee, bool input_not_const) { + Compile::current()->inc_number_of_mh_late_inlines(); + CallGenerator* cg = new LateInlineMHCallGenerator(caller, callee, input_not_const); + return cg; +} + +class LateInlineStringCallGenerator : public LateInlineCallGenerator { + + public: + LateInlineStringCallGenerator(ciMethod* method, CallGenerator* inline_cg) : + LateInlineCallGenerator(method, inline_cg) {} + + virtual JVMState* generate(JVMState* jvms) { + Compile *C = Compile::current(); + C->print_inlining_skip(this); + + C->add_string_late_inline(this); + + JVMState* new_jvms = DirectCallGenerator::generate(jvms); + return new_jvms; + } +}; + +CallGenerator* CallGenerator::for_string_late_inline(ciMethod* method, CallGenerator* inline_cg) { + return new LateInlineStringCallGenerator(method, inline_cg); +} + //---------------------------WarmCallGenerator-------------------------------- // Internal class which handles initial deferral of inlining decisions. @@ -586,35 +696,52 @@ JVMState* PredictedCallGenerator::generate(JVMState* jvms) { } -CallGenerator* CallGenerator::for_method_handle_call(JVMState* jvms, ciMethod* caller, ciMethod* callee) { +CallGenerator* CallGenerator::for_method_handle_call(JVMState* jvms, ciMethod* caller, ciMethod* callee, bool delayed_forbidden) { assert(callee->is_method_handle_intrinsic() || callee->is_compiled_lambda_form(), "for_method_handle_call mismatch"); - CallGenerator* cg = CallGenerator::for_method_handle_inline(jvms, caller, callee); - if (cg != NULL) - return cg; - return CallGenerator::for_direct_call(callee); + bool input_not_const; + CallGenerator* cg = CallGenerator::for_method_handle_inline(jvms, caller, callee, input_not_const); + Compile* C = Compile::current(); + if (cg != NULL) { + if (!delayed_forbidden && AlwaysIncrementalInline) { + return CallGenerator::for_late_inline(callee, cg); + } else { + return cg; + } + } + int bci = jvms->bci(); + ciCallProfile profile = caller->call_profile_at_bci(bci); + int call_site_count = caller->scale_count(profile.count()); + + if (IncrementalInline && call_site_count > 0 && + (input_not_const || !C->inlining_incrementally() || C->over_inlining_cutoff())) { + return CallGenerator::for_mh_late_inline(caller, callee, input_not_const); + } else { + return CallGenerator::for_direct_call(callee); + } } -CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* caller, ciMethod* callee) { +CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* caller, ciMethod* callee, bool& input_not_const) { GraphKit kit(jvms); PhaseGVN& gvn = kit.gvn(); Compile* C = kit.C; vmIntrinsics::ID iid = callee->intrinsic_id(); + input_not_const = true; switch (iid) { case vmIntrinsics::_invokeBasic: { // Get MethodHandle receiver: Node* receiver = kit.argument(0); if (receiver->Opcode() == Op_ConP) { + input_not_const = false; const TypeOopPtr* oop_ptr = receiver->bottom_type()->is_oopptr(); ciMethod* target = oop_ptr->const_oop()->as_method_handle()->get_vmtarget(); guarantee(!target->is_method_handle_intrinsic(), "should not happen"); // XXX remove const int vtable_index = Method::invalid_vtable_index; - CallGenerator* cg = C->call_generator(target, vtable_index, false, jvms, true, PROB_ALWAYS); + CallGenerator* cg = C->call_generator(target, vtable_index, false, jvms, true, PROB_ALWAYS, true, true); + assert (!cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here"); if (cg != NULL && cg->is_inline()) return cg; - } else { - if (PrintInlining) C->print_inlining(callee, jvms->depth() - 1, jvms->bci(), "receiver not constant"); } } break; @@ -627,6 +754,7 @@ CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* // Get MemberName argument: Node* member_name = kit.argument(callee->arg_size() - 1); if (member_name->Opcode() == Op_ConP) { + input_not_const = false; const TypeOopPtr* oop_ptr = member_name->bottom_type()->is_oopptr(); ciMethod* target = oop_ptr->const_oop()->as_member_name()->get_vmtarget(); @@ -661,7 +789,8 @@ CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* } const int vtable_index = Method::invalid_vtable_index; const bool call_is_virtual = target->is_abstract(); // FIXME workaround - CallGenerator* cg = C->call_generator(target, vtable_index, call_is_virtual, jvms, true, PROB_ALWAYS); + CallGenerator* cg = C->call_generator(target, vtable_index, call_is_virtual, jvms, true, PROB_ALWAYS, true, true); + assert (!cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here"); if (cg != NULL && cg->is_inline()) return cg; } diff --git a/hotspot/src/share/vm/opto/callGenerator.hpp b/hotspot/src/share/vm/opto/callGenerator.hpp index 8b3bdada39f..7051dbe5c2e 100644 --- a/hotspot/src/share/vm/opto/callGenerator.hpp +++ b/hotspot/src/share/vm/opto/callGenerator.hpp @@ -68,6 +68,12 @@ class CallGenerator : public ResourceObj { // is_late_inline: supports conversion of call into an inline virtual bool is_late_inline() const { return false; } + // same but for method handle calls + virtual bool is_mh_late_inline() const { return false; } + + // for method handle calls: have we tried inlinining the call already? + virtual bool already_attempted() const { ShouldNotReachHere(); return false; } + // Replace the call with an inline version of the code virtual void do_late_inline() { ShouldNotReachHere(); } @@ -112,11 +118,13 @@ class CallGenerator : public ResourceObj { static CallGenerator* for_virtual_call(ciMethod* m, int vtable_index); // virtual, interface static CallGenerator* for_dynamic_call(ciMethod* m); // invokedynamic - static CallGenerator* for_method_handle_call( JVMState* jvms, ciMethod* caller, ciMethod* callee); - static CallGenerator* for_method_handle_inline(JVMState* jvms, ciMethod* caller, ciMethod* callee); + static CallGenerator* for_method_handle_call( JVMState* jvms, ciMethod* caller, ciMethod* callee, bool delayed_forbidden); + static CallGenerator* for_method_handle_inline(JVMState* jvms, ciMethod* caller, ciMethod* callee, bool& input_not_const); // How to generate a replace a direct call with an inline version static CallGenerator* for_late_inline(ciMethod* m, CallGenerator* inline_cg); + static CallGenerator* for_mh_late_inline(ciMethod* caller, ciMethod* callee, bool input_not_const); + static CallGenerator* for_string_late_inline(ciMethod* m, CallGenerator* inline_cg); // How to make a call but defer the decision whether to inline or not. static CallGenerator* for_warm_call(WarmCallInfo* ci, @@ -147,6 +155,8 @@ class CallGenerator : public ResourceObj { CallGenerator* cg); virtual Node* generate_predicate(JVMState* jvms) { return NULL; }; + virtual void print_inlining_late(const char* msg) { ShouldNotReachHere(); } + static void print_inlining(Compile* C, ciMethod* callee, int inline_level, int bci, const char* msg) { if (PrintInlining) C->print_inlining(callee, inline_level, bci, msg); diff --git a/hotspot/src/share/vm/opto/callnode.cpp b/hotspot/src/share/vm/opto/callnode.cpp index 95f1934c6c1..e8c23b38e33 100644 --- a/hotspot/src/share/vm/opto/callnode.cpp +++ b/hotspot/src/share/vm/opto/callnode.cpp @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "ci/bcEscapeAnalyzer.hpp" #include "compiler/oopMap.hpp" +#include "opto/callGenerator.hpp" #include "opto/callnode.hpp" #include "opto/escape.hpp" #include "opto/locknode.hpp" @@ -775,16 +776,38 @@ void CallNode::extract_projections(CallProjections* projs, bool separate_io_proj // and the exception object may not exist if an exception handler // swallows the exception but all the other must exist and be found. assert(projs->fallthrough_proj != NULL, "must be found"); - assert(projs->fallthrough_catchproj != NULL, "must be found"); - assert(projs->fallthrough_memproj != NULL, "must be found"); - assert(projs->fallthrough_ioproj != NULL, "must be found"); - assert(projs->catchall_catchproj != NULL, "must be found"); + assert(Compile::current()->inlining_incrementally() || projs->fallthrough_catchproj != NULL, "must be found"); + assert(Compile::current()->inlining_incrementally() || projs->fallthrough_memproj != NULL, "must be found"); + assert(Compile::current()->inlining_incrementally() || projs->fallthrough_ioproj != NULL, "must be found"); + assert(Compile::current()->inlining_incrementally() || projs->catchall_catchproj != NULL, "must be found"); if (separate_io_proj) { - assert(projs->catchall_memproj != NULL, "must be found"); - assert(projs->catchall_ioproj != NULL, "must be found"); + assert(Compile::current()->inlining_incrementally() || projs->catchall_memproj != NULL, "must be found"); + assert(Compile::current()->inlining_incrementally() || projs->catchall_ioproj != NULL, "must be found"); } } +Node *CallNode::Ideal(PhaseGVN *phase, bool can_reshape) { + CallGenerator* cg = generator(); + if (can_reshape && cg != NULL && cg->is_mh_late_inline() && !cg->already_attempted()) { + // Check whether this MH handle call becomes a candidate for inlining + ciMethod* callee = cg->method(); + vmIntrinsics::ID iid = callee->intrinsic_id(); + if (iid == vmIntrinsics::_invokeBasic) { + if (in(TypeFunc::Parms)->Opcode() == Op_ConP) { + phase->C->prepend_late_inline(cg); + set_generator(NULL); + } + } else { + assert(callee->has_member_arg(), "wrong type of call?"); + if (in(TypeFunc::Parms + callee->arg_size() - 1)->Opcode() == Op_ConP) { + phase->C->prepend_late_inline(cg); + set_generator(NULL); + } + } + } + return SafePointNode::Ideal(phase, can_reshape); +} + //============================================================================= uint CallJavaNode::size_of() const { return sizeof(*this); } diff --git a/hotspot/src/share/vm/opto/callnode.hpp b/hotspot/src/share/vm/opto/callnode.hpp index f7f4faaa6e3..fee091f798d 100644 --- a/hotspot/src/share/vm/opto/callnode.hpp +++ b/hotspot/src/share/vm/opto/callnode.hpp @@ -507,6 +507,7 @@ public: Node* exobj; }; +class CallGenerator; //------------------------------CallNode--------------------------------------- // Call nodes now subsume the function of debug nodes at callsites, so they @@ -517,26 +518,31 @@ public: const TypeFunc *_tf; // Function type address _entry_point; // Address of method being called float _cnt; // Estimate of number of times called + CallGenerator* _generator; // corresponding CallGenerator for some late inline calls CallNode(const TypeFunc* tf, address addr, const TypePtr* adr_type) : SafePointNode(tf->domain()->cnt(), NULL, adr_type), _tf(tf), _entry_point(addr), - _cnt(COUNT_UNKNOWN) + _cnt(COUNT_UNKNOWN), + _generator(NULL) { init_class_id(Class_Call); } - const TypeFunc* tf() const { return _tf; } - const address entry_point() const { return _entry_point; } - const float cnt() const { return _cnt; } + const TypeFunc* tf() const { return _tf; } + const address entry_point() const { return _entry_point; } + const float cnt() const { return _cnt; } + CallGenerator* generator() const { return _generator; } - void set_tf(const TypeFunc* tf) { _tf = tf; } - void set_entry_point(address p) { _entry_point = p; } - void set_cnt(float c) { _cnt = c; } + void set_tf(const TypeFunc* tf) { _tf = tf; } + void set_entry_point(address p) { _entry_point = p; } + void set_cnt(float c) { _cnt = c; } + void set_generator(CallGenerator* cg) { _generator = cg; } virtual const Type *bottom_type() const; virtual const Type *Value( PhaseTransform *phase ) const; + virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); virtual Node *Identity( PhaseTransform *phase ) { return this; } virtual uint cmp( const Node &n ) const; virtual uint size_of() const = 0; diff --git a/hotspot/src/share/vm/opto/cfgnode.cpp b/hotspot/src/share/vm/opto/cfgnode.cpp index 3ee9fffe04b..12bccd9a538 100644 --- a/hotspot/src/share/vm/opto/cfgnode.cpp +++ b/hotspot/src/share/vm/opto/cfgnode.cpp @@ -363,6 +363,49 @@ bool RegionNode::is_unreachable_region(PhaseGVN *phase) const { return true; // The Region node is unreachable - it is dead. } +bool RegionNode::try_clean_mem_phi(PhaseGVN *phase) { + // Incremental inlining + PhaseStringOpts sometimes produce: + // + // cmpP with 1 top input + // | + // If + // / \ + // IfFalse IfTrue /- Some Node + // \ / / / + // Region / /-MergeMem + // \---Phi + // + // + // It's expected by PhaseStringOpts that the Region goes away and is + // replaced by If's control input but because there's still a Phi, + // the Region stays in the graph. The top input from the cmpP is + // propagated forward and a subgraph that is useful goes away. The + // code below replaces the Phi with the MergeMem so that the Region + // is simplified. + + PhiNode* phi = has_unique_phi(); + if (phi && phi->type() == Type::MEMORY && req() == 3 && phi->is_diamond_phi(true)) { + MergeMemNode* m = NULL; + assert(phi->req() == 3, "same as region"); + for (uint i = 1; i < 3; ++i) { + Node *mem = phi->in(i); + if (mem && mem->is_MergeMem() && in(i)->outcnt() == 1) { + // Nothing is control-dependent on path #i except the region itself. + m = mem->as_MergeMem(); + uint j = 3 - i; + Node* other = phi->in(j); + if (other && other == m->base_memory()) { + // m is a successor memory to other, and is not pinned inside the diamond, so push it out. + // This will allow the diamond to collapse completely. + phase->is_IterGVN()->replace_node(phi, m); + return true; + } + } + } + } + return false; +} + //------------------------------Ideal------------------------------------------ // Return a node which is more "ideal" than the current node. Must preserve // the CFG, but we can still strip out dead paths. @@ -375,6 +418,10 @@ Node *RegionNode::Ideal(PhaseGVN *phase, bool can_reshape) { bool has_phis = false; if (can_reshape) { // Need DU info to check for Phi users has_phis = (has_phi() != NULL); // Cache result + if (has_phis && try_clean_mem_phi(phase)) { + has_phis = false; + } + if (!has_phis) { // No Phi users? Nothing merging? for (uint i = 1; i < req()-1; i++) { Node *if1 = in(i); @@ -1005,7 +1052,9 @@ const Type *PhiNode::Value( PhaseTransform *phase ) const { //------------------------------is_diamond_phi--------------------------------- // Does this Phi represent a simple well-shaped diamond merge? Return the // index of the true path or 0 otherwise. -int PhiNode::is_diamond_phi() const { +// If check_control_only is true, do not inspect the If node at the +// top, and return -1 (not an edge number) on success. +int PhiNode::is_diamond_phi(bool check_control_only) const { // Check for a 2-path merge Node *region = in(0); if( !region ) return 0; @@ -1018,6 +1067,7 @@ int PhiNode::is_diamond_phi() const { Node *iff = ifp1->in(0); if( !iff || !iff->is_If() ) return 0; if( iff != ifp2->in(0) ) return 0; + if (check_control_only) return -1; // Check for a proper bool/cmp const Node *b = iff->in(1); if( !b->is_Bool() ) return 0; diff --git a/hotspot/src/share/vm/opto/cfgnode.hpp b/hotspot/src/share/vm/opto/cfgnode.hpp index a51d78bb385..e795483e3cb 100644 --- a/hotspot/src/share/vm/opto/cfgnode.hpp +++ b/hotspot/src/share/vm/opto/cfgnode.hpp @@ -95,6 +95,7 @@ public: virtual Node *Identity( PhaseTransform *phase ); virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); virtual const RegMask &out_RegMask() const; + bool try_clean_mem_phi(PhaseGVN *phase); }; //------------------------------JProjNode-------------------------------------- @@ -181,7 +182,7 @@ public: LoopSafety simple_data_loop_check(Node *in) const; // Is it unsafe data loop? It becomes a dead loop if this phi node removed. bool is_unsafe_data_reference(Node *in) const; - int is_diamond_phi() const; + int is_diamond_phi(bool check_control_only = false) const; virtual int Opcode() const; virtual bool pinned() const { return in(0) != 0; } virtual const TypePtr *adr_type() const { verify_adr_type(true); return _adr_type; } diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp index 5ea8049c735..f090939186d 100644 --- a/hotspot/src/share/vm/opto/compile.cpp +++ b/hotspot/src/share/vm/opto/compile.cpp @@ -136,7 +136,7 @@ int Compile::intrinsic_insertion_index(ciMethod* m, bool is_virtual) { void Compile::register_intrinsic(CallGenerator* cg) { if (_intrinsics == NULL) { - _intrinsics = new GrowableArray(60); + _intrinsics = new (comp_arena())GrowableArray(comp_arena(), 60, 0, NULL); } // This code is stolen from ciObjectFactory::insert. // Really, GrowableArray should have methods for @@ -365,6 +365,21 @@ void Compile::update_dead_node_list(Unique_Node_List &useful) { } } +void Compile::remove_useless_late_inlines(GrowableArray* inlines, Unique_Node_List &useful) { + int shift = 0; + for (int i = 0; i < inlines->length(); i++) { + CallGenerator* cg = inlines->at(i); + CallNode* call = cg->call_node(); + if (shift > 0) { + inlines->at_put(i-shift, cg); + } + if (!useful.member(call)) { + shift++; + } + } + inlines->trunc_to(inlines->length()-shift); +} + // Disconnect all useless nodes by disconnecting those at the boundary. void Compile::remove_useless_nodes(Unique_Node_List &useful) { uint next = 0; @@ -394,6 +409,9 @@ void Compile::remove_useless_nodes(Unique_Node_List &useful) { remove_macro_node(n); } } + // clean up the late inline lists + remove_useless_late_inlines(&_string_late_inlines, useful); + remove_useless_late_inlines(&_late_inlines, useful); debug_only(verify_graph_edges(true/*check for no_dead_code*/);) } @@ -611,6 +629,12 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr _printer(IdealGraphPrinter::printer()), #endif _congraph(NULL), + _late_inlines(comp_arena(), 2, 0, NULL), + _string_late_inlines(comp_arena(), 2, 0, NULL), + _late_inlines_pos(0), + _number_of_mh_late_inlines(0), + _inlining_progress(false), + _inlining_incrementally(false), _print_inlining_list(NULL), _print_inlining(0) { C = this; @@ -737,29 +761,13 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr rethrow_exceptions(kit.transfer_exceptions_into_jvms()); } - if (!failing() && has_stringbuilder()) { - { - // remove useless nodes to make the usage analysis simpler - ResourceMark rm; - PhaseRemoveUseless pru(initial_gvn(), &for_igvn); - } + assert(IncrementalInline || (_late_inlines.length() == 0 && !has_mh_late_inlines()), "incremental inlining is off"); - { - ResourceMark rm; - print_method("Before StringOpts", 3); - PhaseStringOpts pso(initial_gvn(), &for_igvn); - print_method("After StringOpts", 3); - } - - // now inline anything that we skipped the first time around - while (_late_inlines.length() > 0) { - CallGenerator* cg = _late_inlines.pop(); - cg->do_late_inline(); - if (failing()) return; - } + if (_late_inlines.length() == 0 && !has_mh_late_inlines() && !failing() && has_stringbuilder()) { + inline_string_calls(true); } - assert(_late_inlines.length() == 0, "should have been processed"); - dump_inlining(); + + if (failing()) return; print_method("Before RemoveUseless", 3); @@ -906,6 +914,9 @@ Compile::Compile( ciEnv* ci_env, _dead_node_list(comp_arena()), _dead_node_count(0), _congraph(NULL), + _number_of_mh_late_inlines(0), + _inlining_progress(false), + _inlining_incrementally(false), _print_inlining_list(NULL), _print_inlining(0) { C = this; @@ -1760,6 +1771,124 @@ void Compile::cleanup_loop_predicates(PhaseIterGVN &igvn) { assert(predicate_count()==0, "should be clean!"); } +// StringOpts and late inlining of string methods +void Compile::inline_string_calls(bool parse_time) { + { + // remove useless nodes to make the usage analysis simpler + ResourceMark rm; + PhaseRemoveUseless pru(initial_gvn(), for_igvn()); + } + + { + ResourceMark rm; + print_method("Before StringOpts", 3); + PhaseStringOpts pso(initial_gvn(), for_igvn()); + print_method("After StringOpts", 3); + } + + // now inline anything that we skipped the first time around + if (!parse_time) { + _late_inlines_pos = _late_inlines.length(); + } + + while (_string_late_inlines.length() > 0) { + CallGenerator* cg = _string_late_inlines.pop(); + cg->do_late_inline(); + if (failing()) return; + } + _string_late_inlines.trunc_to(0); +} + +void Compile::inline_incrementally_one(PhaseIterGVN& igvn) { + assert(IncrementalInline, "incremental inlining should be on"); + PhaseGVN* gvn = initial_gvn(); + + set_inlining_progress(false); + for_igvn()->clear(); + gvn->replace_with(&igvn); + + int i = 0; + + for (; i <_late_inlines.length() && !inlining_progress(); i++) { + CallGenerator* cg = _late_inlines.at(i); + _late_inlines_pos = i+1; + cg->do_late_inline(); + if (failing()) return; + } + int j = 0; + for (; i < _late_inlines.length(); i++, j++) { + _late_inlines.at_put(j, _late_inlines.at(i)); + } + _late_inlines.trunc_to(j); + + { + ResourceMark rm; + PhaseRemoveUseless pru(C->initial_gvn(), C->for_igvn()); + } + + igvn = PhaseIterGVN(gvn); +} + +// Perform incremental inlining until bound on number of live nodes is reached +void Compile::inline_incrementally(PhaseIterGVN& igvn) { + PhaseGVN* gvn = initial_gvn(); + + set_inlining_incrementally(true); + set_inlining_progress(true); + uint low_live_nodes = 0; + + while(inlining_progress() && _late_inlines.length() > 0) { + + if (live_nodes() > (uint)LiveNodeCountInliningCutoff) { + if (low_live_nodes < (uint)LiveNodeCountInliningCutoff * 8 / 10) { + // PhaseIdealLoop is expensive so we only try it once we are + // out of loop and we only try it again if the previous helped + // got the number of nodes down significantly + PhaseIdealLoop ideal_loop( igvn, false, true ); + if (failing()) return; + low_live_nodes = live_nodes(); + _major_progress = true; + } + + if (live_nodes() > (uint)LiveNodeCountInliningCutoff) { + break; + } + } + + inline_incrementally_one(igvn); + + if (failing()) return; + + igvn.optimize(); + + if (failing()) return; + } + + assert( igvn._worklist.size() == 0, "should be done with igvn" ); + + if (_string_late_inlines.length() > 0) { + assert(has_stringbuilder(), "inconsistent"); + for_igvn()->clear(); + initial_gvn()->replace_with(&igvn); + + inline_string_calls(false); + + if (failing()) return; + + { + ResourceMark rm; + PhaseRemoveUseless pru(initial_gvn(), for_igvn()); + } + + igvn = PhaseIterGVN(gvn); + + igvn.optimize(); + } + + set_inlining_incrementally(false); +} + + //------------------------------Optimize--------------------------------------- // Given a graph, optimize it. void Compile::Optimize() { @@ -1792,6 +1921,12 @@ void Compile::Optimize() { if (failing()) return; + inline_incrementally(igvn); + + print_method("Incremental Inline", 2); + + if (failing()) return; + // Perform escape analysis if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) { if (has_loops()) { @@ -1914,6 +2049,7 @@ void Compile::Optimize() { } // (End scope of igvn; run destructor if necessary for asserts.) + dump_inlining(); // A method with only infinite loops has no edges entering loops from root { NOT_PRODUCT( TracePhase t2("graphReshape", &_t_graphReshaping, TimeCompiler); ) @@ -3362,6 +3498,28 @@ void Compile::ConstantTable::fill_jump_table(CodeBuffer& cb, MachConstantNode* n void Compile::dump_inlining() { if (PrintInlining) { + // Print inlining message for candidates that we couldn't inline + // for lack of space or non constant receiver + for (int i = 0; i < _late_inlines.length(); i++) { + CallGenerator* cg = _late_inlines.at(i); + cg->print_inlining_late("live nodes > LiveNodeCountInliningCutoff"); + } + Unique_Node_List useful; + useful.push(root()); + for (uint next = 0; next < useful.size(); ++next) { + Node* n = useful.at(next); + if (n->is_Call() && n->as_Call()->generator() != NULL && n->as_Call()->generator()->call_node() == n) { + CallNode* call = n->as_Call(); + CallGenerator* cg = call->generator(); + cg->print_inlining_late("receiver not constant"); + } + uint max = n->len(); + for ( uint i = 0; i < max; ++i ) { + Node *m = n->in(i); + if ( m == NULL ) continue; + useful.push(m); + } + } for (int i = 0; i < _print_inlining_list->length(); i++) { tty->print(_print_inlining_list->at(i).ss()->as_string()); } diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp index 32767e2ddd8..91472ccb006 100644 --- a/hotspot/src/share/vm/opto/compile.hpp +++ b/hotspot/src/share/vm/opto/compile.hpp @@ -280,6 +280,8 @@ class Compile : public Phase { int _orig_pc_slot_offset_in_bytes; int _major_progress; // Count of something big happening + bool _inlining_progress; // progress doing incremental inlining? + bool _inlining_incrementally;// Are we doing incremental inlining (post parse) bool _has_loops; // True if the method _may_ have some loops bool _has_split_ifs; // True if the method _may_ have some split-if bool _has_unsafe_access; // True if the method _may_ produce faults in unsafe loads or stores. @@ -367,8 +369,13 @@ class Compile : public Phase { Unique_Node_List* _for_igvn; // Initial work-list for next round of Iterative GVN WarmCallInfo* _warm_calls; // Sorted work-list for heat-based inlining. - GrowableArray _late_inlines; // List of CallGenerators to be revisited after - // main parsing has finished. + GrowableArray _late_inlines; // List of CallGenerators to be revisited after + // main parsing has finished. + GrowableArray _string_late_inlines; // same but for string operations + + int _late_inlines_pos; // Where in the queue should the next late inlining candidate go (emulate depth first inlining) + uint _number_of_mh_late_inlines; // number of method handle late inlining still pending + // Inlining may not happen in parse order which would make // PrintInlining output confusing. Keep track of PrintInlining @@ -491,6 +498,10 @@ class Compile : public Phase { int fixed_slots() const { assert(_fixed_slots >= 0, ""); return _fixed_slots; } void set_fixed_slots(int n) { _fixed_slots = n; } int major_progress() const { return _major_progress; } + void set_inlining_progress(bool z) { _inlining_progress = z; } + int inlining_progress() const { return _inlining_progress; } + void set_inlining_incrementally(bool z) { _inlining_incrementally = z; } + int inlining_incrementally() const { return _inlining_incrementally; } void set_major_progress() { _major_progress++; } void clear_major_progress() { _major_progress = 0; } int num_loop_opts() const { return _num_loop_opts; } @@ -729,7 +740,7 @@ class Compile : public Phase { // Decide how to build a call. // The profile factor is a discount to apply to this site's interp. profile. - CallGenerator* call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual, JVMState* jvms, bool allow_inline, float profile_factor, bool allow_intrinsics = true); + CallGenerator* call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual, JVMState* jvms, bool allow_inline, float profile_factor, bool allow_intrinsics = true, bool delayed_forbidden = false); bool should_delay_inlining(ciMethod* call_method, JVMState* jvms); // Report if there were too many traps at a current method and bci. @@ -765,10 +776,39 @@ class Compile : public Phase { WarmCallInfo* pop_warm_call(); // Record this CallGenerator for inlining at the end of parsing. - void add_late_inline(CallGenerator* cg) { _late_inlines.push(cg); } + void add_late_inline(CallGenerator* cg) { + _late_inlines.insert_before(_late_inlines_pos, cg); + _late_inlines_pos++; + } + + void prepend_late_inline(CallGenerator* cg) { + _late_inlines.insert_before(0, cg); + } + + void add_string_late_inline(CallGenerator* cg) { + _string_late_inlines.push(cg); + } + + void remove_useless_late_inlines(GrowableArray* inlines, Unique_Node_List &useful); void dump_inlining(); + bool over_inlining_cutoff() const { + if (!inlining_incrementally()) { + return unique() > (uint)NodeCountInliningCutoff; + } else { + return live_nodes() > (uint)LiveNodeCountInliningCutoff; + } + } + + void inc_number_of_mh_late_inlines() { _number_of_mh_late_inlines++; } + void dec_number_of_mh_late_inlines() { assert(_number_of_mh_late_inlines > 0, "_number_of_mh_late_inlines < 0 !"); _number_of_mh_late_inlines--; } + bool has_mh_late_inlines() const { return _number_of_mh_late_inlines > 0; } + + void inline_incrementally_one(PhaseIterGVN& igvn); + void inline_incrementally(PhaseIterGVN& igvn); + void inline_string_calls(bool parse_time); + // Matching, CFG layout, allocation, code generation PhaseCFG* cfg() { return _cfg; } bool select_24_bit_instr() const { return _select_24_bit_instr; } diff --git a/hotspot/src/share/vm/opto/doCall.cpp b/hotspot/src/share/vm/opto/doCall.cpp index 1f21043c32e..099634f0434 100644 --- a/hotspot/src/share/vm/opto/doCall.cpp +++ b/hotspot/src/share/vm/opto/doCall.cpp @@ -63,7 +63,7 @@ void trace_type_profile(Compile* C, ciMethod *method, int depth, int bci, ciMeth CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool call_is_virtual, JVMState* jvms, bool allow_inline, - float prof_factor, bool allow_intrinsics) { + float prof_factor, bool allow_intrinsics, bool delayed_forbidden) { ciMethod* caller = jvms->method(); int bci = jvms->bci(); Bytecodes::Code bytecode = caller->java_code_at_bci(bci); @@ -130,7 +130,9 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool // MethodHandle.invoke* are native methods which obviously don't // have bytecodes and so normal inlining fails. if (callee->is_method_handle_intrinsic()) { - return CallGenerator::for_method_handle_call(jvms, caller, callee); + CallGenerator* cg = CallGenerator::for_method_handle_call(jvms, caller, callee, delayed_forbidden); + assert (cg == NULL || !delayed_forbidden || !cg->is_late_inline() || cg->is_mh_late_inline(), "unexpected CallGenerator"); + return cg; } // Do not inline strict fp into non-strict code, or the reverse @@ -161,20 +163,27 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool WarmCallInfo scratch_ci; if (!UseOldInlining) scratch_ci.init(jvms, callee, profile, prof_factor); - WarmCallInfo* ci = ilt->ok_to_inline(callee, jvms, profile, &scratch_ci); + bool should_delay = false; + WarmCallInfo* ci = ilt->ok_to_inline(callee, jvms, profile, &scratch_ci, should_delay); assert(ci != &scratch_ci, "do not let this pointer escape"); bool allow_inline = (ci != NULL && !ci->is_cold()); bool require_inline = (allow_inline && ci->is_hot()); if (allow_inline) { CallGenerator* cg = CallGenerator::for_inline(callee, expected_uses); - if (require_inline && cg != NULL && should_delay_inlining(callee, jvms)) { + + if (require_inline && cg != NULL) { // Delay the inlining of this method to give us the // opportunity to perform some high level optimizations // first. - return CallGenerator::for_late_inline(callee, cg); + if (should_delay_inlining(callee, jvms)) { + assert(!delayed_forbidden, "strange"); + return CallGenerator::for_string_late_inline(callee, cg); + } else if ((should_delay || AlwaysIncrementalInline) && !delayed_forbidden) { + return CallGenerator::for_late_inline(callee, cg); + } } - if (cg == NULL) { + if (cg == NULL || should_delay) { // Fall through. } else if (require_inline || !InlineWarmCalls) { return cg; diff --git a/hotspot/src/share/vm/opto/graphKit.cpp b/hotspot/src/share/vm/opto/graphKit.cpp index 115952ad65c..cd329a211a9 100644 --- a/hotspot/src/share/vm/opto/graphKit.cpp +++ b/hotspot/src/share/vm/opto/graphKit.cpp @@ -1794,10 +1794,15 @@ void GraphKit::replace_call(CallNode* call, Node* result) { if (ejvms == NULL) { // No exception edges to simply kill off those paths - C->gvn_replace_by(callprojs.catchall_catchproj, C->top()); - C->gvn_replace_by(callprojs.catchall_memproj, C->top()); - C->gvn_replace_by(callprojs.catchall_ioproj, C->top()); - + if (callprojs.catchall_catchproj != NULL) { + C->gvn_replace_by(callprojs.catchall_catchproj, C->top()); + } + if (callprojs.catchall_memproj != NULL) { + C->gvn_replace_by(callprojs.catchall_memproj, C->top()); + } + if (callprojs.catchall_ioproj != NULL) { + C->gvn_replace_by(callprojs.catchall_ioproj, C->top()); + } // Replace the old exception object with top if (callprojs.exobj != NULL) { C->gvn_replace_by(callprojs.exobj, C->top()); @@ -1809,10 +1814,15 @@ void GraphKit::replace_call(CallNode* call, Node* result) { SafePointNode* ex_map = ekit.combine_and_pop_all_exception_states(); Node* ex_oop = ekit.use_exception_state(ex_map); - - C->gvn_replace_by(callprojs.catchall_catchproj, ekit.control()); - C->gvn_replace_by(callprojs.catchall_memproj, ekit.reset_memory()); - C->gvn_replace_by(callprojs.catchall_ioproj, ekit.i_o()); + if (callprojs.catchall_catchproj != NULL) { + C->gvn_replace_by(callprojs.catchall_catchproj, ekit.control()); + } + if (callprojs.catchall_memproj != NULL) { + C->gvn_replace_by(callprojs.catchall_memproj, ekit.reset_memory()); + } + if (callprojs.catchall_ioproj != NULL) { + C->gvn_replace_by(callprojs.catchall_ioproj, ekit.i_o()); + } // Replace the old exception object with the newly created one if (callprojs.exobj != NULL) { diff --git a/hotspot/src/share/vm/opto/parse.hpp b/hotspot/src/share/vm/opto/parse.hpp index 23dd261b9c1..660782ccd7f 100644 --- a/hotspot/src/share/vm/opto/parse.hpp +++ b/hotspot/src/share/vm/opto/parse.hpp @@ -70,7 +70,7 @@ protected: InlineTree *build_inline_tree_for_callee(ciMethod* callee_method, JVMState* caller_jvms, int caller_bci); - const char* try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result); + const char* try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result, bool& should_delay); const char* should_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const; const char* should_not_inline(ciMethod* callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const; void print_inlining(ciMethod *callee_method, int caller_bci, const char *failure_msg) const; @@ -107,7 +107,7 @@ public: // and may be accessed by find_subtree_from_root. // The call_method is the dest_method for a special or static invocation. // The call_method is an optimized virtual method candidate otherwise. - WarmCallInfo* ok_to_inline(ciMethod *call_method, JVMState* caller_jvms, ciCallProfile& profile, WarmCallInfo* wci); + WarmCallInfo* ok_to_inline(ciMethod *call_method, JVMState* caller_jvms, ciCallProfile& profile, WarmCallInfo* wci, bool& should_delay); // Information about inlined method JVMState* caller_jvms() const { return _caller_jvms; } diff --git a/hotspot/src/share/vm/opto/phaseX.cpp b/hotspot/src/share/vm/opto/phaseX.cpp index f2a44f0e7a7..7feb0faee07 100644 --- a/hotspot/src/share/vm/opto/phaseX.cpp +++ b/hotspot/src/share/vm/opto/phaseX.cpp @@ -75,6 +75,13 @@ NodeHash::NodeHash(NodeHash *nh) { // nh->_sentinel must be in the current node space } +void NodeHash::replace_with(NodeHash *nh) { + debug_only(_table = (Node**)badAddress); // interact correctly w/ operator= + // just copy in all the fields + *this = *nh; + // nh->_sentinel must be in the current node space +} + //------------------------------hash_find-------------------------------------- // Find in hash table Node *NodeHash::hash_find( const Node *n ) { diff --git a/hotspot/src/share/vm/opto/phaseX.hpp b/hotspot/src/share/vm/opto/phaseX.hpp index 3fc8a956653..60b1f82fa78 100644 --- a/hotspot/src/share/vm/opto/phaseX.hpp +++ b/hotspot/src/share/vm/opto/phaseX.hpp @@ -92,6 +92,7 @@ public: } void remove_useless_nodes(VectorSet &useful); // replace with sentinel + void replace_with(NodeHash* nh); Node *sentinel() { return _sentinel; } @@ -386,6 +387,11 @@ public: Node *transform( Node *n ); Node *transform_no_reclaim( Node *n ); + void replace_with(PhaseGVN* gvn) { + _table.replace_with(&gvn->_table); + _types = gvn->_types; + } + // Check for a simple dead loop when a data node references itself. DEBUG_ONLY(void dead_loop_check(Node *n);) }; diff --git a/hotspot/src/share/vm/opto/stringopts.cpp b/hotspot/src/share/vm/opto/stringopts.cpp index 4e00945c73a..71abc31bae9 100644 --- a/hotspot/src/share/vm/opto/stringopts.cpp +++ b/hotspot/src/share/vm/opto/stringopts.cpp @@ -265,7 +265,8 @@ void StringConcat::eliminate_unneeded_control() { } else if (n->is_IfTrue()) { Compile* C = _stringopts->C; C->gvn_replace_by(n, n->in(0)->in(0)); - C->gvn_replace_by(n->in(0), C->top()); + // get rid of the other projection + C->gvn_replace_by(n->in(0)->as_If()->proj_out(false), C->top()); } } } @@ -439,7 +440,7 @@ StringConcat* PhaseStringOpts::build_candidate(CallStaticJavaNode* call) { } // Find the constructor call Node* result = alloc->result_cast(); - if (result == NULL || !result->is_CheckCastPP()) { + if (result == NULL || !result->is_CheckCastPP() || alloc->in(TypeFunc::Memory)->is_top()) { // strange looking allocation #ifndef PRODUCT if (PrintOptimizeStringConcat) { @@ -834,6 +835,9 @@ bool StringConcat::validate_control_flow() { ptr->in(1)->in(0) != NULL && ptr->in(1)->in(0)->is_If()) { // Simple diamond. // XXX should check for possibly merging stores. simple data merges are ok. + // The IGVN will make this simple diamond go away when it + // transforms the Region. Make sure it sees it. + Compile::current()->record_for_igvn(ptr); ptr = ptr->in(1)->in(0)->in(0); continue; } diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 21e5cce7b18..a2b4d8b752e 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -3291,6 +3291,18 @@ jint Arguments::parse(const JavaVMInitArgs* args) { if (!EliminateLocks) { EliminateNestedLocks = false; } + if (!Inline) { + IncrementalInline = false; + } +#ifndef PRODUCT + if (!IncrementalInline) { + AlwaysIncrementalInline = false; + } +#endif + if (IncrementalInline && FLAG_IS_DEFAULT(MaxNodeLimit)) { + // incremental inlining: bump MaxNodeLimit + FLAG_SET_DEFAULT(MaxNodeLimit, (intx)75000); + } #endif if (PrintAssembly && FLAG_IS_DEFAULT(DebugNonSafepoints)) { From ce4f8fe85bde94efcd5dc004e281ea22fc363a1c Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Thu, 27 Dec 2012 20:15:22 +0100 Subject: [PATCH 009/204] 8001942: build-infra: General permission problems on Windows/cygwin Added sanity check for file permissions in configure Reviewed-by: tbell, ohair --- common/autoconf/basics.m4 | 14 + common/autoconf/generated-configure.sh | 487 ++++++++++++------------- 2 files changed, 253 insertions(+), 248 deletions(-) diff --git a/common/autoconf/basics.m4 b/common/autoconf/basics.m4 index 0074e8c16b1..8b1dbc899e5 100644 --- a/common/autoconf/basics.m4 +++ b/common/autoconf/basics.m4 @@ -633,6 +633,18 @@ AC_DEFUN([BASIC_CHECK_DIR_ON_LOCAL_DISK], fi ]) +# Check that source files have basic read permissions set. This might +# not be the case in cygwin in certain conditions. +AC_DEFUN_ONCE([BASIC_CHECK_SRC_PERMS], +[ + if test x"$OPENJDK_BUILD_OS" = xwindows; then + file_to_test="$SRC_ROOT/LICENSE" + if test `$STAT -c '%a' "$file_to_test"` -lt 400; then + AC_MSG_ERROR([Bad file permissions on src files. This is usually caused by cloning the repositories with a non cygwin hg in a directory not created in cygwin.]) + fi + fi +]) + AC_DEFUN_ONCE([BASIC_TEST_USABILITY_ISSUES], [ @@ -642,6 +654,8 @@ BASIC_CHECK_DIR_ON_LOCAL_DISK($OUTPUT_ROOT, [OUTPUT_DIR_IS_LOCAL="no"]) AC_MSG_RESULT($OUTPUT_DIR_IS_LOCAL) +BASIC_CHECK_SRC_PERMS + # Check if the user has any old-style ALT_ variables set. FOUND_ALT_VARIABLES=`env | grep ^ALT_` diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index 38370ee3636..ab7360b40c2 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for OpenJDK jdk8. +# Generated by GNU Autoconf 2.67 for OpenJDK jdk8. # # Report bugs to . # @@ -91,7 +91,6 @@ fi IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. -as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -217,18 +216,11 @@ IFS=$as_save_IFS # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. - # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL - case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; - esac - exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : @@ -1439,7 +1431,7 @@ Try \`$0 --help' for more information" $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac @@ -1859,7 +1851,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF OpenJDK configure jdk8 -generated by GNU Autoconf 2.68 +generated by GNU Autoconf 2.67 Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation @@ -1905,7 +1897,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_compile @@ -1943,7 +1935,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile @@ -1981,7 +1973,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_objc_try_compile @@ -2018,7 +2010,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_cpp @@ -2055,7 +2047,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp @@ -2068,10 +2060,10 @@ fi ac_fn_cxx_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval \${$3+:} false; then : + if eval "test \"\${$3+set}\"" = set; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 @@ -2138,7 +2130,7 @@ $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" @@ -2147,7 +2139,7 @@ eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_cxx_check_header_mongrel @@ -2188,7 +2180,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_try_run @@ -2202,7 +2194,7 @@ ac_fn_cxx_check_header_compile () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2220,7 +2212,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_cxx_check_header_compile @@ -2397,7 +2389,7 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ rm -f conftest.val fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_compute_int @@ -2443,7 +2435,7 @@ fi # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_try_link @@ -2456,7 +2448,7 @@ ac_fn_cxx_check_func () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2511,7 +2503,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_cxx_check_func @@ -2524,7 +2516,7 @@ ac_fn_c_check_header_compile () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2542,7 +2534,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_header_compile cat >config.log <<_ACEOF @@ -2550,7 +2542,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by OpenJDK $as_me jdk8, which was -generated by GNU Autoconf 2.68. Invocation command line was +generated by GNU Autoconf 2.67. Invocation command line was $ $0 $@ @@ -2808,7 +2800,7 @@ $as_echo "$as_me: loading site script $ac_site_file" >&6;} || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } fi done @@ -3088,6 +3080,10 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Argument 3: what to do otherwise (remote disk or failure) +# Check that source files have basic read permissions set. This might +# not be the case in cygwin in certain conditions. + + # @@ -3683,7 +3679,7 @@ fi #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1355963953 +DATE_WHEN_GENERATED=1356635654 ############################################################################### # @@ -3721,7 +3717,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_BASENAME+:} false; then : +if test "${ac_cv_path_BASENAME+set}" = set; then : $as_echo_n "(cached) " >&6 else case $BASENAME in @@ -3780,7 +3776,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_BASH+:} false; then : +if test "${ac_cv_path_BASH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $BASH in @@ -3839,7 +3835,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CAT+:} false; then : +if test "${ac_cv_path_CAT+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CAT in @@ -3898,7 +3894,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CHMOD+:} false; then : +if test "${ac_cv_path_CHMOD+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CHMOD in @@ -3957,7 +3953,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CMP+:} false; then : +if test "${ac_cv_path_CMP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CMP in @@ -4016,7 +4012,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CP+:} false; then : +if test "${ac_cv_path_CP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CP in @@ -4075,7 +4071,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CUT+:} false; then : +if test "${ac_cv_path_CUT+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CUT in @@ -4134,7 +4130,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_DATE+:} false; then : +if test "${ac_cv_path_DATE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $DATE in @@ -4193,7 +4189,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_DIFF+:} false; then : +if test "${ac_cv_path_DIFF+set}" = set; then : $as_echo_n "(cached) " >&6 else case $DIFF in @@ -4252,7 +4248,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_DIRNAME+:} false; then : +if test "${ac_cv_path_DIRNAME+set}" = set; then : $as_echo_n "(cached) " >&6 else case $DIRNAME in @@ -4311,7 +4307,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ECHO+:} false; then : +if test "${ac_cv_path_ECHO+set}" = set; then : $as_echo_n "(cached) " >&6 else case $ECHO in @@ -4370,7 +4366,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_EXPR+:} false; then : +if test "${ac_cv_path_EXPR+set}" = set; then : $as_echo_n "(cached) " >&6 else case $EXPR in @@ -4429,7 +4425,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_FILE+:} false; then : +if test "${ac_cv_path_FILE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $FILE in @@ -4488,7 +4484,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_FIND+:} false; then : +if test "${ac_cv_path_FIND+set}" = set; then : $as_echo_n "(cached) " >&6 else case $FIND in @@ -4547,7 +4543,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_HEAD+:} false; then : +if test "${ac_cv_path_HEAD+set}" = set; then : $as_echo_n "(cached) " >&6 else case $HEAD in @@ -4606,7 +4602,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_LN+:} false; then : +if test "${ac_cv_path_LN+set}" = set; then : $as_echo_n "(cached) " >&6 else case $LN in @@ -4665,7 +4661,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_LS+:} false; then : +if test "${ac_cv_path_LS+set}" = set; then : $as_echo_n "(cached) " >&6 else case $LS in @@ -4724,7 +4720,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_MKDIR+:} false; then : +if test "${ac_cv_path_MKDIR+set}" = set; then : $as_echo_n "(cached) " >&6 else case $MKDIR in @@ -4783,7 +4779,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_MKTEMP+:} false; then : +if test "${ac_cv_path_MKTEMP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $MKTEMP in @@ -4842,7 +4838,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_MV+:} false; then : +if test "${ac_cv_path_MV+set}" = set; then : $as_echo_n "(cached) " >&6 else case $MV in @@ -4901,7 +4897,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_PRINTF+:} false; then : +if test "${ac_cv_path_PRINTF+set}" = set; then : $as_echo_n "(cached) " >&6 else case $PRINTF in @@ -4960,7 +4956,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_THEPWDCMD+:} false; then : +if test "${ac_cv_path_THEPWDCMD+set}" = set; then : $as_echo_n "(cached) " >&6 else case $THEPWDCMD in @@ -5019,7 +5015,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_RM+:} false; then : +if test "${ac_cv_path_RM+set}" = set; then : $as_echo_n "(cached) " >&6 else case $RM in @@ -5078,7 +5074,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_SH+:} false; then : +if test "${ac_cv_path_SH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $SH in @@ -5137,7 +5133,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_SORT+:} false; then : +if test "${ac_cv_path_SORT+set}" = set; then : $as_echo_n "(cached) " >&6 else case $SORT in @@ -5196,7 +5192,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_TAIL+:} false; then : +if test "${ac_cv_path_TAIL+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TAIL in @@ -5255,7 +5251,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_TAR+:} false; then : +if test "${ac_cv_path_TAR+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TAR in @@ -5314,7 +5310,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_TEE+:} false; then : +if test "${ac_cv_path_TEE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TEE in @@ -5373,7 +5369,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_TOUCH+:} false; then : +if test "${ac_cv_path_TOUCH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TOUCH in @@ -5432,7 +5428,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_TR+:} false; then : +if test "${ac_cv_path_TR+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TR in @@ -5491,7 +5487,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_UNAME+:} false; then : +if test "${ac_cv_path_UNAME+set}" = set; then : $as_echo_n "(cached) " >&6 else case $UNAME in @@ -5550,7 +5546,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_UNIQ+:} false; then : +if test "${ac_cv_path_UNIQ+set}" = set; then : $as_echo_n "(cached) " >&6 else case $UNIQ in @@ -5609,7 +5605,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_WC+:} false; then : +if test "${ac_cv_path_WC+set}" = set; then : $as_echo_n "(cached) " >&6 else case $WC in @@ -5668,7 +5664,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_WHICH+:} false; then : +if test "${ac_cv_path_WHICH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $WHICH in @@ -5727,7 +5723,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_XARGS+:} false; then : +if test "${ac_cv_path_XARGS+set}" = set; then : $as_echo_n "(cached) " >&6 else case $XARGS in @@ -5787,7 +5783,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AWK+:} false; then : +if test "${ac_cv_prog_AWK+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then @@ -5837,7 +5833,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if ${ac_cv_path_GREP+:} false; then : +if test "${ac_cv_path_GREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then @@ -5912,7 +5908,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } -if ${ac_cv_path_EGREP+:} false; then : +if test "${ac_cv_path_EGREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 @@ -5991,7 +5987,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } -if ${ac_cv_path_FGREP+:} false; then : +if test "${ac_cv_path_FGREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 @@ -6070,7 +6066,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } -if ${ac_cv_path_SED+:} false; then : +if test "${ac_cv_path_SED+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ @@ -6156,7 +6152,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_NAWK+:} false; then : +if test "${ac_cv_path_NAWK+set}" = set; then : $as_echo_n "(cached) " >&6 else case $NAWK in @@ -6216,7 +6212,7 @@ RM="$RM -f" set dummy cygpath; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CYGPATH+:} false; then : +if test "${ac_cv_path_CYGPATH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CYGPATH in @@ -6256,7 +6252,7 @@ fi set dummy readlink; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_READLINK+:} false; then : +if test "${ac_cv_path_READLINK+set}" = set; then : $as_echo_n "(cached) " >&6 else case $READLINK in @@ -6296,7 +6292,7 @@ fi set dummy df; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_DF+:} false; then : +if test "${ac_cv_path_DF+set}" = set; then : $as_echo_n "(cached) " >&6 else case $DF in @@ -6336,7 +6332,7 @@ fi set dummy SetFile; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_SETFILE+:} false; then : +if test "${ac_cv_path_SETFILE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $SETFILE in @@ -6382,7 +6378,7 @@ $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } -if ${ac_cv_build+:} false; then : +if test "${ac_cv_build+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias @@ -6398,7 +6394,7 @@ fi $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; -*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5 ;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' @@ -6416,7 +6412,7 @@ case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } -if ${ac_cv_host+:} false; then : +if test "${ac_cv_host+set}" = set; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then @@ -6431,7 +6427,7 @@ fi $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; -*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5 ;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' @@ -6449,7 +6445,7 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 $as_echo_n "checking target system type... " >&6; } -if ${ac_cv_target+:} false; then : +if test "${ac_cv_target+set}" = set; then : $as_echo_n "(cached) " >&6 else if test "x$target_alias" = x; then @@ -6464,7 +6460,7 @@ fi $as_echo "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; -*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; +*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5 ;; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' @@ -7883,7 +7879,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_PKGHANDLER+:} false; then : +if test "${ac_cv_prog_PKGHANDLER+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$PKGHANDLER"; then @@ -8248,7 +8244,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CHECK_GMAKE+:} false; then : +if test "${ac_cv_path_CHECK_GMAKE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CHECK_GMAKE in @@ -8602,7 +8598,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CHECK_MAKE+:} false; then : +if test "${ac_cv_path_CHECK_MAKE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CHECK_MAKE in @@ -8961,7 +8957,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CHECK_TOOLSDIR_GMAKE+:} false; then : +if test "${ac_cv_path_CHECK_TOOLSDIR_GMAKE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CHECK_TOOLSDIR_GMAKE in @@ -9314,7 +9310,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CHECK_TOOLSDIR_MAKE+:} false; then : +if test "${ac_cv_path_CHECK_TOOLSDIR_MAKE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CHECK_TOOLSDIR_MAKE in @@ -9710,7 +9706,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_UNZIP+:} false; then : +if test "${ac_cv_path_UNZIP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $UNZIP in @@ -9769,7 +9765,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ZIP+:} false; then : +if test "${ac_cv_path_ZIP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $ZIP in @@ -9828,7 +9824,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} set dummy ldd; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_LDD+:} false; then : +if test "${ac_cv_path_LDD+set}" = set; then : $as_echo_n "(cached) " >&6 else case $LDD in @@ -9874,7 +9870,7 @@ fi set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_OTOOL+:} false; then : +if test "${ac_cv_path_OTOOL+set}" = set; then : $as_echo_n "(cached) " >&6 else case $OTOOL in @@ -9919,7 +9915,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_READELF+:} false; then : +if test "${ac_cv_path_READELF+set}" = set; then : $as_echo_n "(cached) " >&6 else case $READELF in @@ -9962,7 +9958,7 @@ done set dummy hg; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_HG+:} false; then : +if test "${ac_cv_path_HG+set}" = set; then : $as_echo_n "(cached) " >&6 else case $HG in @@ -10002,7 +9998,7 @@ fi set dummy stat; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_STAT+:} false; then : +if test "${ac_cv_path_STAT+set}" = set; then : $as_echo_n "(cached) " >&6 else case $STAT in @@ -10042,7 +10038,7 @@ fi set dummy time; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_TIME+:} false; then : +if test "${ac_cv_path_TIME+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TIME in @@ -10087,7 +10083,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_COMM+:} false; then : +if test "${ac_cv_path_COMM+set}" = set; then : $as_echo_n "(cached) " >&6 else case $COMM in @@ -10151,7 +10147,7 @@ if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_PKG_CONFIG+:} false; then : +if test "${ac_cv_path_PKG_CONFIG+set}" = set; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in @@ -10194,7 +10190,7 @@ if test -z "$ac_cv_path_PKG_CONFIG"; then set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : +if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in @@ -10367,7 +10363,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_BDEPS_UNZIP+:} false; then : +if test "${ac_cv_prog_BDEPS_UNZIP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$BDEPS_UNZIP"; then @@ -10413,7 +10409,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_BDEPS_FTP+:} false; then : +if test "${ac_cv_prog_BDEPS_FTP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$BDEPS_FTP"; then @@ -11702,7 +11698,7 @@ $as_echo "$BOOT_JDK_VERSION" >&6; } set dummy javac; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_JAVAC_CHECK+:} false; then : +if test "${ac_cv_path_JAVAC_CHECK+set}" = set; then : $as_echo_n "(cached) " >&6 else case $JAVAC_CHECK in @@ -11742,7 +11738,7 @@ fi set dummy java; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_JAVA_CHECK+:} false; then : +if test "${ac_cv_path_JAVA_CHECK+set}" = set; then : $as_echo_n "(cached) " >&6 else case $JAVA_CHECK in @@ -15801,7 +15797,7 @@ if test "x$OPENJDK_TARGET_OS" = "xwindows"; then set dummy link; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CYGWIN_LINK+:} false; then : +if test "${ac_cv_path_CYGWIN_LINK+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CYGWIN_LINK in @@ -16790,7 +16786,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_BUILD_CC+:} false; then : +if test "${ac_cv_path_BUILD_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else case $BUILD_CC in @@ -17101,7 +17097,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_BUILD_CXX+:} false; then : +if test "${ac_cv_path_BUILD_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else case $BUILD_CXX in @@ -17410,7 +17406,7 @@ $as_echo "$as_me: Rewriting BUILD_CXX to \"$new_complete\"" >&6;} set dummy ld; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_BUILD_LD+:} false; then : +if test "${ac_cv_path_BUILD_LD+set}" = set; then : $as_echo_n "(cached) " >&6 else case $BUILD_LD in @@ -17922,7 +17918,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_TOOLS_DIR_CC+:} false; then : +if test "${ac_cv_path_TOOLS_DIR_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TOOLS_DIR_CC in @@ -17974,7 +17970,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_POTENTIAL_CC+:} false; then : +if test "${ac_cv_path_POTENTIAL_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else case $POTENTIAL_CC in @@ -18387,7 +18383,7 @@ $as_echo "yes, trying to find proper $COMPILER_NAME compiler" >&6; } set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_PROPER_COMPILER_CC+:} false; then : +if test "${ac_cv_prog_PROPER_COMPILER_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$PROPER_COMPILER_CC"; then @@ -18431,7 +18427,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_PROPER_COMPILER_CC+:} false; then : +if test "${ac_cv_prog_ac_ct_PROPER_COMPILER_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_PROPER_COMPILER_CC"; then @@ -18881,7 +18877,7 @@ if test -n "$ac_tool_prefix"; then set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : +if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then @@ -18925,7 +18921,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then @@ -18978,7 +18974,7 @@ fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 @@ -19093,7 +19089,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } @@ -19136,7 +19132,7 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 @@ -19195,7 +19191,7 @@ $as_echo "$ac_try_echo"; } >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } fi fi fi @@ -19206,7 +19202,7 @@ rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } -if ${ac_cv_objext+:} false; then : +if test "${ac_cv_objext+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -19247,7 +19243,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi @@ -19257,7 +19253,7 @@ OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : +if test "${ac_cv_c_compiler_gnu+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -19294,7 +19290,7 @@ ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : +if test "${ac_cv_prog_cc_g+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag @@ -19372,7 +19368,7 @@ else fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : +if test "${ac_cv_prog_cc_c89+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no @@ -19491,7 +19487,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_TOOLS_DIR_CXX+:} false; then : +if test "${ac_cv_path_TOOLS_DIR_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TOOLS_DIR_CXX in @@ -19543,7 +19539,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_POTENTIAL_CXX+:} false; then : +if test "${ac_cv_path_POTENTIAL_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else case $POTENTIAL_CXX in @@ -19956,7 +19952,7 @@ $as_echo "yes, trying to find proper $COMPILER_NAME compiler" >&6; } set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_PROPER_COMPILER_CXX+:} false; then : +if test "${ac_cv_prog_PROPER_COMPILER_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$PROPER_COMPILER_CXX"; then @@ -20000,7 +19996,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_PROPER_COMPILER_CXX+:} false; then : +if test "${ac_cv_prog_ac_ct_PROPER_COMPILER_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_PROPER_COMPILER_CXX"; then @@ -20454,7 +20450,7 @@ if test -z "$CXX"; then set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CXX+:} false; then : +if test "${ac_cv_prog_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then @@ -20498,7 +20494,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CXX+:} false; then : +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then @@ -20576,7 +20572,7 @@ done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } -if ${ac_cv_cxx_compiler_gnu+:} false; then : +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -20613,7 +20609,7 @@ ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } -if ${ac_cv_prog_cxx_g+:} false; then : +if test "${ac_cv_prog_cxx_g+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag @@ -20711,7 +20707,7 @@ if test -n "$ac_tool_prefix"; then set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OBJC+:} false; then : +if test "${ac_cv_prog_OBJC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJC"; then @@ -20755,7 +20751,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OBJC+:} false; then : +if test "${ac_cv_prog_ac_ct_OBJC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJC"; then @@ -20831,7 +20827,7 @@ done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU Objective C compiler" >&5 $as_echo_n "checking whether we are using the GNU Objective C compiler... " >&6; } -if ${ac_cv_objc_compiler_gnu+:} false; then : +if test "${ac_cv_objc_compiler_gnu+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -20868,7 +20864,7 @@ ac_test_OBJCFLAGS=${OBJCFLAGS+set} ac_save_OBJCFLAGS=$OBJCFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $OBJC accepts -g" >&5 $as_echo_n "checking whether $OBJC accepts -g... " >&6; } -if ${ac_cv_prog_objc_g+:} false; then : +if test "${ac_cv_prog_objc_g+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_save_objc_werror_flag=$ac_objc_werror_flag @@ -21244,7 +21240,7 @@ if test "x$OPENJDK_TARGET_OS" != xwindows; then set dummy ${ac_tool_prefix}ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AR+:} false; then : +if test "${ac_cv_prog_AR+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then @@ -21284,7 +21280,7 @@ if test -z "$ac_cv_prog_AR"; then set dummy ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_AR+:} false; then : +if test "${ac_cv_prog_ac_ct_AR+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then @@ -21626,7 +21622,7 @@ if test "x$OPENJDK_TARGET_OS" = xwindows; then : set dummy link; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_WINLD+:} false; then : +if test "${ac_cv_prog_WINLD+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$WINLD"; then @@ -21965,7 +21961,7 @@ $as_echo "yes" >&6; } set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_MT+:} false; then : +if test "${ac_cv_prog_MT+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$MT"; then @@ -22286,7 +22282,7 @@ $as_echo "$as_me: Rewriting MT to \"$new_complete\"" >&6;} set dummy rc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_RC+:} false; then : +if test "${ac_cv_prog_RC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$RC"; then @@ -22677,7 +22673,7 @@ fi set dummy lib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_WINAR+:} false; then : +if test "${ac_cv_prog_WINAR+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$WINAR"; then @@ -22983,7 +22979,7 @@ $as_echo "$as_me: Rewriting WINAR to \"$new_complete\"" >&6;} set dummy dumpbin; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DUMPBIN+:} false; then : +if test "${ac_cv_prog_DUMPBIN+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then @@ -23302,7 +23298,7 @@ if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : + if test "${ac_cv_prog_CPP+set}" = set; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded @@ -23418,7 +23414,7 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } fi ac_ext=cpp @@ -23702,7 +23698,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then - if ${ac_cv_prog_CXXCPP+:} false; then : + if test "${ac_cv_prog_CXXCPP+set}" = set; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded @@ -23818,7 +23814,7 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } fi ac_ext=cpp @@ -24120,7 +24116,7 @@ if test "x$OPENJDK_TARGET_OS" = xsolaris; then set dummy as; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_AS+:} false; then : +if test "${ac_cv_path_AS+set}" = set; then : $as_echo_n "(cached) " >&6 else case $AS in @@ -24434,7 +24430,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_NM+:} false; then : +if test "${ac_cv_path_NM+set}" = set; then : $as_echo_n "(cached) " >&6 else case $NM in @@ -24743,7 +24739,7 @@ $as_echo "$as_me: Rewriting NM to \"$new_complete\"" >&6;} set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_STRIP+:} false; then : +if test "${ac_cv_path_STRIP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $STRIP in @@ -25049,7 +25045,7 @@ $as_echo "$as_me: Rewriting STRIP to \"$new_complete\"" >&6;} set dummy mcs; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_MCS+:} false; then : +if test "${ac_cv_path_MCS+set}" = set; then : $as_echo_n "(cached) " >&6 else case $MCS in @@ -25357,7 +25353,7 @@ elif test "x$OPENJDK_TARGET_OS" != xwindows; then set dummy ${ac_tool_prefix}nm; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_NM+:} false; then : +if test "${ac_cv_prog_NM+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then @@ -25397,7 +25393,7 @@ if test -z "$ac_cv_prog_NM"; then set dummy nm; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_NM+:} false; then : +if test "${ac_cv_prog_ac_ct_NM+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NM"; then @@ -25715,7 +25711,7 @@ $as_echo "$as_me: Rewriting NM to \"$new_complete\"" >&6;} set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_STRIP+:} false; then : +if test "${ac_cv_prog_STRIP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then @@ -25755,7 +25751,7 @@ if test -z "$ac_cv_prog_STRIP"; then set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_STRIP+:} false; then : +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then @@ -26080,7 +26076,7 @@ if test "x$OPENJDK_TARGET_OS" = xsolaris || test "x$OPENJDK_TARGET_OS" = xlinux; set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OBJCOPY+:} false; then : +if test "${ac_cv_prog_OBJCOPY+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJCOPY"; then @@ -26124,7 +26120,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OBJCOPY+:} false; then : +if test "${ac_cv_prog_ac_ct_OBJCOPY+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJCOPY"; then @@ -26451,7 +26447,7 @@ if test -n "$ac_tool_prefix"; then set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OBJDUMP+:} false; then : +if test "${ac_cv_prog_OBJDUMP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then @@ -26495,7 +26491,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : +if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then @@ -26819,7 +26815,7 @@ if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_LIPO+:} false; then : +if test "${ac_cv_path_LIPO+set}" = set; then : $as_echo_n "(cached) " >&6 else case $LIPO in @@ -27134,7 +27130,7 @@ PATH="$OLD_PATH" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : +if test "${ac_cv_header_stdc+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -27310,7 +27306,7 @@ fi for ac_header in stdio.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "stdio.h" "ac_cv_header_stdio_h" "$ac_includes_default" -if test "x$ac_cv_header_stdio_h" = xyes; then : +if test "x$ac_cv_header_stdio_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDIO_H 1 _ACEOF @@ -27339,7 +27335,7 @@ done # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int *" >&5 $as_echo_n "checking size of int *... " >&6; } -if ${ac_cv_sizeof_int_p+:} false; then : +if test "${ac_cv_sizeof_int_p+set}" = set; then : $as_echo_n "(cached) " >&6 else if ac_fn_cxx_compute_int "$LINENO" "(long int) (sizeof (int *))" "ac_cv_sizeof_int_p" "$ac_includes_default"; then : @@ -27349,7 +27345,7 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (int *) -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } else ac_cv_sizeof_int_p=0 fi @@ -27396,7 +27392,7 @@ $as_echo "$OPENJDK_TARGET_CPU_BITS bits" >&6; } # { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 $as_echo_n "checking whether byte ordering is bigendian... " >&6; } -if ${ac_cv_c_bigendian+:} false; then : +if test "${ac_cv_c_bigendian+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_cv_c_bigendian=unknown @@ -28396,8 +28392,8 @@ if test "x$with_x" = xno; then have_x=disabled else case $x_includes,$x_libraries in #( - *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #( - *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then : + *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5 ;; #( + *,NONE | NONE,*) if test "${ac_cv_have_x+set}" = set; then : $as_echo_n "(cached) " >&6 else # One or both of the vars are not set, and there is no cached value. @@ -28674,7 +28670,7 @@ if ac_fn_cxx_try_link "$LINENO"; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet" >&5 $as_echo_n "checking for dnet_ntoa in -ldnet... " >&6; } -if ${ac_cv_lib_dnet_dnet_ntoa+:} false; then : +if test "${ac_cv_lib_dnet_dnet_ntoa+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -28708,14 +28704,14 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_dnet_ntoa" >&5 $as_echo "$ac_cv_lib_dnet_dnet_ntoa" >&6; } -if test "x$ac_cv_lib_dnet_dnet_ntoa" = xyes; then : +if test "x$ac_cv_lib_dnet_dnet_ntoa" = x""yes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" fi if test $ac_cv_lib_dnet_dnet_ntoa = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet_stub" >&5 $as_echo_n "checking for dnet_ntoa in -ldnet_stub... " >&6; } -if ${ac_cv_lib_dnet_stub_dnet_ntoa+:} false; then : +if test "${ac_cv_lib_dnet_stub_dnet_ntoa+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -28749,7 +28745,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5 $as_echo "$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; } -if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = xyes; then : +if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = x""yes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" fi @@ -28768,14 +28764,14 @@ rm -f core conftest.err conftest.$ac_objext \ # The functions gethostbyname, getservbyname, and inet_addr are # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking. ac_fn_cxx_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" -if test "x$ac_cv_func_gethostbyname" = xyes; then : +if test "x$ac_cv_func_gethostbyname" = x""yes; then : fi if test $ac_cv_func_gethostbyname = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 $as_echo_n "checking for gethostbyname in -lnsl... " >&6; } -if ${ac_cv_lib_nsl_gethostbyname+:} false; then : +if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -28809,14 +28805,14 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 $as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } -if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : +if test "x$ac_cv_lib_nsl_gethostbyname" = x""yes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" fi if test $ac_cv_lib_nsl_gethostbyname = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lbsd" >&5 $as_echo_n "checking for gethostbyname in -lbsd... " >&6; } -if ${ac_cv_lib_bsd_gethostbyname+:} false; then : +if test "${ac_cv_lib_bsd_gethostbyname+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -28850,7 +28846,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_gethostbyname" >&5 $as_echo "$ac_cv_lib_bsd_gethostbyname" >&6; } -if test "x$ac_cv_lib_bsd_gethostbyname" = xyes; then : +if test "x$ac_cv_lib_bsd_gethostbyname" = x""yes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd" fi @@ -28865,14 +28861,14 @@ fi # must be given before -lnsl if both are needed. We assume that # if connect needs -lnsl, so does gethostbyname. ac_fn_cxx_check_func "$LINENO" "connect" "ac_cv_func_connect" -if test "x$ac_cv_func_connect" = xyes; then : +if test "x$ac_cv_func_connect" = x""yes; then : fi if test $ac_cv_func_connect = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 $as_echo_n "checking for connect in -lsocket... " >&6; } -if ${ac_cv_lib_socket_connect+:} false; then : +if test "${ac_cv_lib_socket_connect+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -28906,7 +28902,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5 $as_echo "$ac_cv_lib_socket_connect" >&6; } -if test "x$ac_cv_lib_socket_connect" = xyes; then : +if test "x$ac_cv_lib_socket_connect" = x""yes; then : X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" fi @@ -28914,14 +28910,14 @@ fi # Guillermo Gomez says -lposix is necessary on A/UX. ac_fn_cxx_check_func "$LINENO" "remove" "ac_cv_func_remove" -if test "x$ac_cv_func_remove" = xyes; then : +if test "x$ac_cv_func_remove" = x""yes; then : fi if test $ac_cv_func_remove = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for remove in -lposix" >&5 $as_echo_n "checking for remove in -lposix... " >&6; } -if ${ac_cv_lib_posix_remove+:} false; then : +if test "${ac_cv_lib_posix_remove+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -28955,7 +28951,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix_remove" >&5 $as_echo "$ac_cv_lib_posix_remove" >&6; } -if test "x$ac_cv_lib_posix_remove" = xyes; then : +if test "x$ac_cv_lib_posix_remove" = x""yes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" fi @@ -28963,14 +28959,14 @@ fi # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. ac_fn_cxx_check_func "$LINENO" "shmat" "ac_cv_func_shmat" -if test "x$ac_cv_func_shmat" = xyes; then : +if test "x$ac_cv_func_shmat" = x""yes; then : fi if test $ac_cv_func_shmat = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shmat in -lipc" >&5 $as_echo_n "checking for shmat in -lipc... " >&6; } -if ${ac_cv_lib_ipc_shmat+:} false; then : +if test "${ac_cv_lib_ipc_shmat+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29004,7 +29000,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_shmat" >&5 $as_echo "$ac_cv_lib_ipc_shmat" >&6; } -if test "x$ac_cv_lib_ipc_shmat" = xyes; then : +if test "x$ac_cv_lib_ipc_shmat" = x""yes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" fi @@ -29022,7 +29018,7 @@ fi # John Interrante, Karl Berry { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IceConnectionNumber in -lICE" >&5 $as_echo_n "checking for IceConnectionNumber in -lICE... " >&6; } -if ${ac_cv_lib_ICE_IceConnectionNumber+:} false; then : +if test "${ac_cv_lib_ICE_IceConnectionNumber+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29056,7 +29052,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5 $as_echo "$ac_cv_lib_ICE_IceConnectionNumber" >&6; } -if test "x$ac_cv_lib_ICE_IceConnectionNumber" = xyes; then : +if test "x$ac_cv_lib_ICE_IceConnectionNumber" = x""yes; then : X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" fi @@ -30063,7 +30059,7 @@ $as_echo "$FREETYPE2_FOUND" >&6; } LDFLAGS="$FREETYPE2_LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FT_Init_FreeType in -lfreetype" >&5 $as_echo_n "checking for FT_Init_FreeType in -lfreetype... " >&6; } -if ${ac_cv_lib_freetype_FT_Init_FreeType+:} false; then : +if test "${ac_cv_lib_freetype_FT_Init_FreeType+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30097,7 +30093,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_freetype_FT_Init_FreeType" >&5 $as_echo "$ac_cv_lib_freetype_FT_Init_FreeType" >&6; } -if test "x$ac_cv_lib_freetype_FT_Init_FreeType" = xyes; then : +if test "x$ac_cv_lib_freetype_FT_Init_FreeType" = x""yes; then : FREETYPE2_FOUND=true else as_fn_error $? "Could not find freetype2! $HELP_MSG " "$LINENO" 5 @@ -30385,7 +30381,7 @@ fi for ac_header in alsa/asoundlib.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "alsa/asoundlib.h" "ac_cv_header_alsa_asoundlib_h" "$ac_includes_default" -if test "x$ac_cv_header_alsa_asoundlib_h" = xyes; then : +if test "x$ac_cv_header_alsa_asoundlib_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ALSA_ASOUNDLIB_H 1 _ACEOF @@ -30444,7 +30440,7 @@ fi USE_EXTERNAL_LIBJPEG=true { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -ljpeg" >&5 $as_echo_n "checking for main in -ljpeg... " >&6; } -if ${ac_cv_lib_jpeg_main+:} false; then : +if test "${ac_cv_lib_jpeg_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30472,7 +30468,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jpeg_main" >&5 $as_echo "$ac_cv_lib_jpeg_main" >&6; } -if test "x$ac_cv_lib_jpeg_main" = xyes; then : +if test "x$ac_cv_lib_jpeg_main" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBJPEG 1 _ACEOF @@ -30496,7 +30492,7 @@ fi USE_EXTERNAL_LIBJPEG=true { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lgif" >&5 $as_echo_n "checking for main in -lgif... " >&6; } -if ${ac_cv_lib_gif_main+:} false; then : +if test "${ac_cv_lib_gif_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30524,7 +30520,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gif_main" >&5 $as_echo "$ac_cv_lib_gif_main" >&6; } -if test "x$ac_cv_lib_gif_main" = xyes; then : +if test "x$ac_cv_lib_gif_main" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBGIF 1 _ACEOF @@ -30554,7 +30550,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for compress in -lz" >&5 $as_echo_n "checking for compress in -lz... " >&6; } -if ${ac_cv_lib_z_compress+:} false; then : +if test "${ac_cv_lib_z_compress+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30588,7 +30584,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_compress" >&5 $as_echo "$ac_cv_lib_z_compress" >&6; } -if test "x$ac_cv_lib_z_compress" = xyes; then : +if test "x$ac_cv_lib_z_compress" = x""yes; then : ZLIB_FOUND=yes else ZLIB_FOUND=no @@ -30681,7 +30677,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5 $as_echo_n "checking for cos in -lm... " >&6; } -if ${ac_cv_lib_m_cos+:} false; then : +if test "${ac_cv_lib_m_cos+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30715,7 +30711,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5 $as_echo "$ac_cv_lib_m_cos" >&6; } -if test "x$ac_cv_lib_m_cos" = xyes; then : +if test "x$ac_cv_lib_m_cos" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF @@ -30739,7 +30735,7 @@ save_LIBS="$LIBS" LIBS="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : +if test "${ac_cv_lib_dl_dlopen+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30773,7 +30769,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : +if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDL 1 _ACEOF @@ -31417,7 +31413,7 @@ fi set dummy ccache; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CCACHE+:} false; then : +if test "${ac_cv_path_CCACHE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CCACHE in @@ -31546,6 +31542,14 @@ $as_echo "no, disabling ccaching of precompiled headers" >&6; } # Check for some common pitfalls + if test x"$OPENJDK_BUILD_OS" = xwindows; then + file_to_test="$SRC_ROOT/LICENSE" + if test `$STAT -c '%a' "$file_to_test"` -lt 400; then + as_fn_error $? "Bad file permissions on src files. This is usually caused by cloning the repositories with a non cygwin hg in a directory not created in cygwin." "$LINENO" 5 + fi + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if build directory is on local disk" >&5 $as_echo_n "checking if build directory is on local disk... " >&6; } @@ -31576,6 +31580,8 @@ $as_echo_n "checking if build directory is on local disk... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OUTPUT_DIR_IS_LOCAL" >&5 $as_echo "$OUTPUT_DIR_IS_LOCAL" >&6; } + + # Check if the user has any old-style ALT_ variables set. FOUND_ALT_VARIABLES=`env | grep ^ALT_` @@ -31668,21 +31674,10 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then - if test "x$cache_file" != "x/dev/null"; then + test "x$cache_file" != "x/dev/null" && { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} - if test ! -f "$cache_file" || test -h "$cache_file"; then - cat confcache >"$cache_file" - else - case $cache_file in #( - */* | ?:*) - mv -f confcache "$cache_file"$$ && - mv -f "$cache_file"$$ "$cache_file" ;; #( - *) - mv -f confcache "$cache_file" ;; - esac - fi - fi + cat confcache >$cache_file else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} @@ -31714,7 +31709,7 @@ LTLIBOBJS=$ac_ltlibobjs -: "${CONFIG_STATUS=./config.status}" +: ${CONFIG_STATUS=./config.status} ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" @@ -31815,7 +31810,6 @@ fi IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. -as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -32123,7 +32117,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # values after options handling. ac_log=" This file was extended by OpenJDK $as_me jdk8, which was -generated by GNU Autoconf 2.68. Invocation command line was +generated by GNU Autoconf 2.67. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -32186,7 +32180,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ OpenJDK config.status jdk8 -configured by $0, generated by GNU Autoconf 2.68, +configured by $0, generated by GNU Autoconf 2.67, with options \\"\$ac_cs_config\\" Copyright (C) 2010 Free Software Foundation, Inc. @@ -32315,7 +32309,7 @@ do "$OUTPUT_ROOT/spec.sh") CONFIG_FILES="$CONFIG_FILES $OUTPUT_ROOT/spec.sh:$AUTOCONF_DIR/spec.sh.in" ;; "$OUTPUT_ROOT/Makefile") CONFIG_FILES="$CONFIG_FILES $OUTPUT_ROOT/Makefile:$AUTOCONF_DIR/Makefile.in" ;; - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;; esac done @@ -32337,10 +32331,9 @@ fi # after its creation but before its name has been assigned to `$tmp'. $debug || { - tmp= ac_tmp= + tmp= trap 'exit_status=$? - : "${ac_tmp:=$tmp}" - { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } @@ -32348,13 +32341,12 @@ $debug || { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -d "$tmp" + test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 -ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. @@ -32376,7 +32368,7 @@ else ac_cs_awk_cr=$ac_cr fi -echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +echo 'BEGIN {' >"$tmp/subs1.awk" && _ACEOF @@ -32404,7 +32396,7 @@ done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +cat >>"\$tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h @@ -32452,7 +32444,7 @@ t delim rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK -cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && +cat >>"\$tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" @@ -32484,7 +32476,7 @@ if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat -fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ +fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF @@ -32518,7 +32510,7 @@ fi # test -n "$CONFIG_FILES" # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then -cat >"$ac_tmp/defines.awk" <<\_ACAWK || +cat >"$tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF @@ -32530,8 +32522,8 @@ _ACEOF # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do - ac_tt=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_tt"; then + ac_t=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_t"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 @@ -32632,7 +32624,7 @@ do esac case $ac_mode$ac_tag in :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac @@ -32651,7 +32643,7 @@ do for ac_f do case $ac_f in - -) ac_f="$ac_tmp/stdin";; + -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. @@ -32660,7 +32652,7 @@ do [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" @@ -32686,8 +32678,8 @@ $as_echo "$as_me: creating $ac_file" >&6;} esac case $ac_tag in - *:-:* | *:-) cat >"$ac_tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + *:-:* | *:-) cat >"$tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac @@ -32812,22 +32804,21 @@ s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t $ac_datarootdir_hack " -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ - >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ - "$ac_tmp/out"`; test -z "$ac_out"; } && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} - rm -f "$ac_tmp/stdin" + rm -f "$tmp/stdin" case $ac_file in - -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; - *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + -) cat "$tmp/out" && rm -f "$tmp/out";; + *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; @@ -32838,20 +32829,20 @@ which seems to be undefined. Please make sure it is defined" >&2;} if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" - } >"$ac_tmp/config.h" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" + } >"$tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" - mv "$ac_tmp/config.h" "$ac_file" \ + mv "$tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; From 1ac4606dea18f5a1d9877f6f3f1fda4552538458 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Thu, 27 Dec 2012 20:18:21 +0100 Subject: [PATCH 010/204] 8005540: build-infra: Improve incremental build speed on windows by caching find results Reviewed-by: ohair --- common/makefiles/IdlCompilation.gmk | 2 +- common/makefiles/JavaCompilation.gmk | 44 ++++++++++++++------------ common/makefiles/MakeBase.gmk | 42 ++++++++++++++++++++++++ common/makefiles/NativeCompilation.gmk | 2 +- 4 files changed, 68 insertions(+), 22 deletions(-) diff --git a/common/makefiles/IdlCompilation.gmk b/common/makefiles/IdlCompilation.gmk index 11f661a4622..6dc5fee2999 100644 --- a/common/makefiles/IdlCompilation.gmk +++ b/common/makefiles/IdlCompilation.gmk @@ -87,7 +87,7 @@ $(if $(16),$(error Internal makefile error: Too many arguments to SetupIdlCompil $1_SRC := $$(abspath $$($1_SRC)) $1_BIN := $$(abspath $$($1_BIN)) # Find all existing java files and existing class files. -$$(shell $(MKDIR) -p $$($1_SRC) $$($1_BIN)) +$$(eval $$(call MakeDir,$$($1_BIN))) $1_SRCS := $$(shell find $$($1_SRC) -name "*.idl") $1_BINS := $$(shell find $$($1_BIN) -name "*.java") # Prepend the source/bin path to the filter expressions. diff --git a/common/makefiles/JavaCompilation.gmk b/common/makefiles/JavaCompilation.gmk index ab6004452c3..54ce927dd7c 100644 --- a/common/makefiles/JavaCompilation.gmk +++ b/common/makefiles/JavaCompilation.gmk @@ -111,9 +111,9 @@ define SetupArchive ifeq ($$(word 20,$$($1_GREP_INCLUDE_PATTERNS)),) $1_GREP_INCLUDES:=| $(GREP) $$(patsubst %,$(SPACE)-e$(SPACE)$(DQUOTE)%$(DQUOTE),$$($1_GREP_INCLUDE_PATTERNS)) else - $$(shell $(MKDIR) -p $$($1_BIN) && $(RM) $$($1_BIN)/_the.$$($1_JARNAME)_include) - $$(eval $$(call ListPathsSafelyNow,$1_GREP_INCLUDE_PATTERNS,\n, \ - >> $$($1_BIN)/_the.$$($1_JARNAME)_include)) + $1_GREP_INCLUDE_OUTPUT:=$(RM) $$($1_BIN)/_the.$$($1_JARNAME)_include && \ + $$(strip $$(call ListPathsSafely,$1_GREP_INCLUDE_PATTERNS,\n, \ + >> $$($1_BIN)/_the.$$($1_JARNAME)_include)) $1_GREP_INCLUDES:=| $(GREP) -f $$($1_BIN)/_the.$$($1_JARNAME)_include endif endif @@ -124,9 +124,9 @@ define SetupArchive ifeq ($$(word 20,$$($1_GREP_EXCLUDE_PATTERNS)),) $1_GREP_EXCLUDES:=| $(GREP) -v $$(patsubst %,$(SPACE)-e$(SPACE)$(DQUOTE)%$(DQUOTE),$$($1_GREP_EXCLUDE_PATTERNS)) else - $$(shell $(MKDIR) -p $$($1_BIN) && $(RM) $$($1_BIN)/_the.$$($1_JARNAME)_exclude) - $$(eval $$(call ListPathsSafelyNow,$1_GREP_EXCLUDE_PATTERNS,\n, \ - >> $$($1_BIN)/_the.$$($1_JARNAME)_exclude)) + $1_GREP_EXCLUDE_OUTPUT=$(RM) $$($1_BIN)/_the.$$($1_JARNAME)_exclude && \ + $$(strip $$(call ListPathsSafely,$1_GREP_EXCLUDE_PATTERNS,\n, \ + >> $$($1_BIN)/_the.$$($1_JARNAME)_exclude)) $1_GREP_EXCLUDES:=| $(GREP) -v -f $$($1_BIN)/_the.$$($1_JARNAME)_exclude endif endif @@ -137,19 +137,25 @@ define SetupArchive else $1_JARINDEX = true endif - # When this macro is run in the same makefile as the java compilation, dependencies are transfered - # in make variables. When the macro is run in a different makefile than the java compilation, the - # dependencies need to be found in the filesystem. + # When this macro is run in the same makefile as the java compilation, dependencies are + # transfered in make variables. When the macro is run in a different makefile than the + # java compilation, the dependencies need to be found in the filesystem. ifneq (,$2) $1_DEPS:=$2 else + $1_DEPS:=$$(filter $$(addprefix %,$$($1_FIND_PATTERNS)),\ + $$(call CacheFind $$($1_SRCS))) + ifneq (,$$($1_GREP_INCLUDE_PATTERNS)) + $1_DEPS:=$$(filter $$(addsuffix %,$$($1_GREP_INCLUDE_PATTERNS)),$$($1_DEPS)) + endif + ifneq (,$$($1_GREP_EXCLUDE_PATTERNS)) + $1_DEPS:=$$(filter-out $$(addsuffix %,$$($1_GREP_EXCLUDE_PATTERNS)),$$($1_DEPS)) + endif # The subst of \ is needed because $ has to be escaped with \ in EXTRA_FILES for the command # lines, but not here for use in make dependencies. - $1_DEPS:=$$(shell $(FIND) $$($1_SRCS) -type f -a \( $$($1_FIND_PATTERNS) \) \ - $$($1_GREP_INCLUDES) $$($1_GREP_EXCLUDES)) \ - $$(subst \,,$$(foreach src,$$($1_SRCS),$$(addprefix $$(src)/,$$($1_EXTRA_FILES)))) + $1_DEPS+=$$(subst \,,$$(foreach src,$$($1_SRCS),$$(addprefix $$(src)/,$$($1_EXTRA_FILES)))) ifeq (,$$($1_SKIP_METAINF)) - $1_DEPS+=$$(shell $(FIND) $$(addsuffix /META-INF,$$($1_SRCS)) -type f 2> /dev/null) + $1_DEPS+=$$(call CacheFind $$(wildcard $$(addsuffix /META-INF,$$($1_SRCS)))) endif endif @@ -210,6 +216,8 @@ define SetupArchive # Here is the rule that creates/updates the jar file. $$($1_JAR) : $$($1_DEPS) $(MKDIR) -p $$($1_BIN) + $$($1_GREP_INCLUDE_OUTPUT) + $$($1_GREP_EXCLUDE_OUTPUT) $$(if $$($1_MANIFEST),\ $(SED) -e "s#@@RELEASE@@#$(RELEASE)#" \ -e "s#@@COMPANY_NAME@@#$(COMPANY_NAME)#" $$($1_MANIFEST) > $$($1_MANIFEST_FILE) \ @@ -248,8 +256,8 @@ define SetupZipArchive $(if $(16),$(error Internal makefile error: Too many arguments to SetupZipArchive, please update JavaCompilation.gmk)) # Find all files in the source tree. - $1_SUFFIX_FILTER := $$(patsubst %,-o -name $(DQUOTE)*%$(DQUOTE),$$($1_SUFFIXES)) - $1_ALL_SRCS := $$(foreach i,$$($1_SRC), $$(shell $(FIND) $$i -type f -a ! -name "_the.*" \( -name FALSE_DUMMY $$($1_SUFFIX_FILTER) \) )) + $1_ALL_SRCS := $$(call not-containing,_the.,\ + $$(filter $$(addprefix %,$$($1_SUFFIXES)),$$(call CacheFind $$($1_SRC)))) ifneq ($$($1_INCLUDES),) $1_SRC_INCLUDES := $$(foreach i,$$($1_SRC),$$(addprefix $$i/,$$(addsuffix /%,$$($1_INCLUDES)))) @@ -376,7 +384,7 @@ define SetupJavaCompilation $$(foreach d,$$($1_SRC), $$(if $$(wildcard $$d),,$$(error SRC specified to SetupJavaCompilation $1 contains missing directory $$d))) $$(eval $$(call MakeDir,$$($1_BIN))) # Find all files in the source trees. - $1_ALL_SRCS := $$(filter-out $(OVR_SRCS),$$(shell $(FIND) $$($1_SRC) -type f)) + $1_ALL_SRCS += $$(filter-out $(OVR_SRCS),$$(call CacheFind,$$($1_SRC))) # Extract the java files. ifneq ($$($1_EXCLUDE_FILES),) $1_EXCLUDE_FILES_PATTERN:=$$(addprefix %,$$($1_EXCLUDE_FILES)) @@ -408,8 +416,6 @@ define SetupJavaCompilation # Find all files to be copied from source to bin. ifneq (,$$($1_COPY)) - # Rewrite list of patterns into a find statement. - $1_COPY_PATTERN:=$(FALSE_FIND_PATTERN) $$(patsubst %,$(SPACE)-o$(SPACE)-name$(SPACE)$(DQUOTE)*%$(DQUOTE),$$($1_COPY)) # Search for all files to be copied. $1_ALL_COPIES := $$(filter $$(addprefix %,$$($1_COPY)),$$($1_ALL_SRCS)) # Copy these explicitly @@ -436,8 +442,6 @@ define SetupJavaCompilation # Find all property files to be copied and cleaned from source to bin. ifneq (,$$($1_CLEAN)) - # Rewrite list of patterns into a find statement. - $1_CLEAN_PATTERN:=$(FALSE_FIND_PATTERN) $$(patsubst %,$(SPACE)-o$(SPACE)-name$(SPACE)$(DQUOTE)*%$(DQUOTE),$$($1_CLEAN)) # Search for all files to be copied. $1_ALL_CLEANS := $$(filter $$(addprefix %,$$($1_CLEAN)),$$($1_ALL_SRCS)) # Copy and clean must also respect filters. diff --git a/common/makefiles/MakeBase.gmk b/common/makefiles/MakeBase.gmk index 5f334462195..708cbada085 100644 --- a/common/makefiles/MakeBase.gmk +++ b/common/makefiles/MakeBase.gmk @@ -391,4 +391,46 @@ define install-file endef endif +# Convenience functions for working around make's limitations with $(filter ). +containing = $(foreach v,$2,$(if $(findstring $1,$v),$v)) +not-containing = $(foreach v,$2,$(if $(findstring $1,$v),,$v)) + +################################################################################ +# In Cygwin, finds are very costly, both because of expensive forks and because +# of bad file system caching. Find is used extensively in $(shell) commands to +# find source files. This makes rerunning make with no or few changes rather +# expensive. To speed this up, these two macros are used to cache the results +# of simple find commands for reuse. +# +# Runs a find and stores both the directories where it was run and the results. +# This macro can be called multiple times to add to the cache. Only finds files +# with no filters. +# +# Needs to be called with $(eval ) +# +# Param 1 - Dir to find in +ifeq ($(OPENJDK_BUILD_OS),windows) +define FillCacheFind + FIND_CACHE_DIR += $1 + FIND_CACHE := $$(sort $$(FIND_CACHE) $$(shell $(FIND) $1 -type f -o -type l)) +endef +else +define FillCacheFind +endef +endif + +# Mimics find by looking in the cache if all of the directories have been cached. +# Otherwise reverts to shell find. This is safe to call on all platforms, even if +# cache is deactivated. +# +# The extra - is needed when FIND_CACHE_DIR is empty but should be harmless. +# Param 1 - Dirs to find in +define CacheFind + $(if $(filter-out $(addsuffix %,- $(FIND_CACHE_DIR)),$1),\ + $(shell $(FIND) $1 -type f -o -type l),\ + $(filter $(addsuffix %,$1),$(FIND_CACHE))) +endef + +################################################################################ + endif # _MAKEBASE_GMK diff --git a/common/makefiles/NativeCompilation.gmk b/common/makefiles/NativeCompilation.gmk index 7ead10caa09..838a62ce111 100644 --- a/common/makefiles/NativeCompilation.gmk +++ b/common/makefiles/NativeCompilation.gmk @@ -236,7 +236,7 @@ define SetupNativeCompilation $$(foreach d,$$($1_SRC), $$(if $$(wildcard $$d),,$$(error SRC specified to SetupNativeCompilation $1 contains missing directory $$d))) # Find all files in the source trees. Sort to remove duplicates. - $1_ALL_SRCS := $$(sort $$(shell $(FIND) $$($1_SRC) -type f)) + $1_ALL_SRCS := $$(sort $$(call CacheFind,$$($1_SRC))) # Extract the C/C++ files. $1_EXCLUDE_FILES:=$$(foreach i,$$($1_SRC),$$(addprefix $$i/,$$($1_EXCLUDE_FILES))) $1_INCLUDE_FILES:=$$(foreach i,$$($1_SRC),$$(addprefix $$i/,$$($1_INCLUDE_FILES))) From 9268fe1857e3e49546aa960d2d5d1edf0952bb4b Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Thu, 27 Dec 2012 20:55:53 +0100 Subject: [PATCH 011/204] 8005548: build-infra: Fix docs target on windows Fix path sep variable Reviewed-by: tbell --- common/makefiles/javadoc/Javadoc.gmk | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/common/makefiles/javadoc/Javadoc.gmk b/common/makefiles/javadoc/Javadoc.gmk index 84f0b5f8494..cee44b958fe 100644 --- a/common/makefiles/javadoc/Javadoc.gmk +++ b/common/makefiles/javadoc/Javadoc.gmk @@ -32,8 +32,6 @@ include MakeBase.gmk # Definitions for $(DOCSDIR), $(MKDIR), $(BINDIR), etc. # -CLASSPATH_SEPARATOR = : - DOCSDIR=$(OUTPUT_ROOT)/docs TEMPDIR=$(OUTPUT_ROOT)/docstemp @@ -137,7 +135,7 @@ $(FULL_COMPANY_NAME) in the US and other countries. # List of all possible directories for javadoc to look for sources # NOTE: Quotes are required around sourcepath argument only on Windows. # Otherwise, you get "No packages or classes specified." due -# to $(CLASSPATH_SEPARATOR) being interpreted as an end of +# to $(PATH_SEP) being interpreted as an end of # command (newline or shell ; character) ALL_SOURCE_DIRS = $(JDK_SHARE_CLASSES) \ $(JDK_IMPSRC) \ @@ -154,7 +152,7 @@ ALL_EXISTING_SOURCE_DIRS := $(wildcard $(ALL_SOURCE_DIRS)) EMPTY:= SPACE:= $(EMPTY) $(EMPTY) RELEASEDOCS_SOURCEPATH = \ - $(subst $(SPACE),$(CLASSPATH_SEPARATOR),$(strip $(ALL_SOURCE_DIRS))) + $(subst $(SPACE),$(PATH_SEP),$(strip $(ALL_SOURCE_DIRS))) define prep-target $(MKDIR) -p $(@D) From 8ae16060660b7b7e6e730ae2fdcc403bf9f5bb65 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Fri, 28 Dec 2012 09:51:15 +0100 Subject: [PATCH 012/204] 8005549: build-infra: Merge NewMakefile.gmk and common/makefiles/Makefile Reviewed-by: ohair, tbell --- NewMakefile.gmk | 348 +++++++------------------ common/autoconf/Makefile.in | 2 +- common/autoconf/generated-configure.sh | 2 +- common/makefiles/Jprt.gmk | 165 ++++++++++++ common/makefiles/Main.gmk | 12 +- common/makefiles/MakeHelpers.gmk | 9 +- common/makefiles/Makefile | 107 +------- 7 files changed, 267 insertions(+), 378 deletions(-) create mode 100644 common/makefiles/Jprt.gmk diff --git a/NewMakefile.gmk b/NewMakefile.gmk index f38d7396a7d..dcd928718df 100644 --- a/NewMakefile.gmk +++ b/NewMakefile.gmk @@ -23,273 +23,107 @@ # questions. # -# Utilities used in this Makefile -BASENAME=basename -CAT=cat -CD=cd -CMP=cmp -CP=cp -ECHO=echo -MKDIR=mkdir -PRINTF=printf -PWD=pwd -TAR=tar -ifeq ($(PLATFORM),windows) - ZIP=zip +# This must be the first rule +default: + +# Inclusion of this pseudo-target will cause make to execute this file +# serially, regardless of -j. Recursively called makefiles will not be +# affected, however. This is required for correct dependency management. +.NOTPARALLEL: + +# The shell code below will be executed on /usr/ccs/bin/make on Solaris, but not in GNU make. +# /usr/ccs/bin/make lacks basically every other flow control mechanism. +TEST_FOR_NON_GNUMAKE:sh=echo You are not using GNU make/gmake, this is a requirement. Check your path. 1>&2 && exit 1 + +# Assume we have GNU make, but check version. +ifeq (,$(findstring 3.81,$(MAKE_VERSION))) + ifeq (,$(findstring 3.82,$(MAKE_VERSION))) + $(error This version of GNU Make is too low ($(MAKE_VERSION)). Check your path, or upgrade to 3.81 or newer.) + endif +endif + +# Locate this Makefile +ifeq ($(filter /%,$(lastword $(MAKEFILE_LIST))),) + makefile_path:=$(CURDIR)/$(lastword $(MAKEFILE_LIST)) else - # store symbolic links as the link - ZIP=zip -y + makefile_path:=$(lastword $(MAKEFILE_LIST)) endif -# Insure we have a path that looks like it came from pwd -# (This is mostly for Windows sake and drive letters) -define UnixPath # path -$(shell (cd "$1" && $(PWD))) -endef +root_dir:=$(dir $(makefile_path)) -# Current root directory -CURRENT_DIRECTORY := $(shell $(PWD)) +include $(root_dir)/common/makefiles/Jprt.gmk -# Build directory root -BUILD_DIR_ROOT = $(CURRENT_DIRECTORY)/build +# ... and then we can include our helper functions +include $(root_dir)/common/makefiles/MakeHelpers.gmk -# All configured Makefiles to run -ALL_MAKEFILES = $(wildcard $(BUILD_DIR_ROOT)/*-*/Makefile) +$(eval $(call ParseLogLevel)) +$(eval $(call ParseConfAndSpec)) -# All bundles to create -ALL_IMAGE_DIRS = $(wildcard $(BUILD_DIR_ROOT)/*-*/images/*-image) +# Now determine if we have zero, one or several configurations to build. +ifeq ($(SPEC),) + # Since we got past ParseConfAndSpec, we must be building a global target. Do nothing. +else + ifeq ($(words $(SPEC)),1) + # We are building a single configuration. This is the normal case. Execute the Main.gmk file. + include $(root_dir)/common/makefiles/Main.gmk + else + # We are building multiple configurations. + # First, find out the valid targets + # Run the makefile with an arbitraty SPEC using -p -q (quiet dry-run and dump rules) to find + # available PHONY targets. Use this list as valid targets to pass on to the repeated calls. + all_phony_targets=$(filter-out $(global_targets), $(strip $(shell \ + $(MAKE) -p -q -f common/makefiles SPEC=$(firstword $(SPEC)) | \ + grep ^.PHONY: | head -n 1 | cut -d " " -f 2-))) -# Build all the standard 'all', 'images', and 'clean' targets -all images clean: checks - @if [ "$(ALL_MAKEFILES)" = "" ] ; then \ - $(ECHO) "ERROR: No configurations to build"; exit 1; \ - fi - @for bdir in $(dir $(ALL_MAKEFILES)) ; do \ - $(ECHO) "$(CD) $${bdir} && $(MAKE) $@" ; \ - $(CD) $${bdir} && $(MAKE) $@ ; \ - done +$(all_phony_targets): + @$(foreach spec,$(SPEC),($(MAKE) -f NewMakefile.gmk SPEC=$(spec) $(VERBOSE) VERBOSE=$(VERBOSE) $@) &&) true -# TBD: Deploy input -$(BUILD_DIR_ROOT)/.deploy_input: - @if [ "$(ALL_MAKEFILES)" = "" ] ; then \ - $(ECHO) "ERROR: No configurations to build"; exit 1; \ - fi - @for bdir in $(dir $(ALL_MAKEFILES)) ; do \ - if [ deploy/make/Makefile ] ; then \ - echo "Attempting deploy build." ; \ - ( \ - $(RM) -r $${bdir}/deploy_input ; \ - $(MKDIR) -p $${bdir}/deploy_input ; \ - ( $(CD) $${bdir}/images && $(TAR) -cf - j2sdk-image j2re-image ) \ - | ( $(CD) $${bdir}/deploy_input && $(TAR) -xf - ) ; \ - ) ; \ - fi; \ - done - touch $@ - -# TBD: Deploy images -deploy: $(BUILD_DIR_ROOT)/.deploy_input - @if [ "$(ALL_MAKEFILES)" = "" ] ; then \ - $(ECHO) "ERROR: No configurations to build"; exit 1; \ - fi - @for bdir in $(dir $(ALL_MAKEFILES)) ; do \ - if [ deploy/make/Makefile ] ; then \ - echo "Attempting deploy build." ; \ - ( \ - $(CD) deploy/make && \ - $(MAKE) \ - ABS_OUTPUTDIR=$${bdir}/deploy_input \ - OUTPUTDIR=$${bdir}/deploy_input \ - ) ; \ - fi; \ - done - -# TBD: Install bundles -install: - -# Bundle creation -bundles: - @if [ "$(ALL_IMAGE_DIRS)" = "" ] ; then \ - $(ECHO) "ERROR: No images to bundle"; exit 1; \ - fi - @for i in $(ALL_IMAGE_DIRS) ; do \ - $(MKDIR) -p $${i}/../../bundles && \ - $(RM) $${i}/../../bundles/`$(BASENAME) $${i}`.zip && \ - $(ECHO) "$(CD) $${i} && $(ZIP) -q -r ../../bundles/`$(BASENAME) $${i}`.zip ." && \ - $(CD) $${i} && $(ZIP) -q -r ../../bundles/`$(BASENAME) $${i}`.zip . ; \ - done - -# Clobber all the built files -clobber:: - $(RM) -r $(BUILD_DIR_ROOT) - -# Make various checks to insure the build will be successful -# Possibilities: -# * Check that if any closed repo is provided, they all must be. -# * Check that all open repos exist, at least until we are ready for some -# kind of partial build. -checks: - @$(ECHO) "No checks yet" - -# Keep track of user targets -USER_TARGETS += all deploy install images clean clobber checks - -########################################################################### -# To help in adoption of the new configure&&make build process, a bridge -# build will use the old settings to run configure and do the build. - -# Build with the configure bridge -bridgeBuild: bridge2configure images - -# Bridge from old Makefile ALT settings to configure options -bridge2configure: $(BUILD_DIR_ROOT)/.bridge2configureOpts - bash ./configure $(strip $(shell $(CAT) $<)) - -# Create a file with configure options created from old Makefile mechanisms. -$(BUILD_DIR_ROOT)/.bridge2configureOpts: $(BUILD_DIR_ROOT)/.bridge2configureOptsLatest - $(RM) $@ - $(CP) $< $@ - -# Use this file to only change when obvious things have changed -$(BUILD_DIR_ROOT)/.bridge2configureOptsLatest: FRC - $(RM) $@.tmp - $(MKDIR) -p $(BUILD_DIR_ROOT) - @$(ECHO) " --with-debug-level=$(if $(DEBUG_LEVEL),$(DEBUG_LEVEL),release) " >> $@.tmp -ifdef ARCH_DATA_MODEL - @$(ECHO) " --with-target-bits=$(ARCH_DATA_MODEL) " >> $@.tmp -endif -ifdef ALT_PARALLEL_COMPILE_JOBS - @$(ECHO) " --with-num-cores=$(ALT_PARALLEL_COMPILE_JOBS) " >> $@.tmp -endif -ifdef ALT_BOOTDIR - @$(ECHO) " --with-boot-jdk=$(call UnixPath,$(ALT_BOOTDIR)) " >> $@.tmp -endif -ifdef ALT_CUPS_HEADERS_PATH - @$(ECHO) " --with-cups-include=$(call UnixPath,$(ALT_CUPS_HEADERS_PATH)) " >> $@.tmp -endif -ifdef ALT_FREETYPE_HEADERS_PATH - @$(ECHO) " --with-freetype=$(call UnixPath,$(ALT_FREETYPE_HEADERS_PATH)/..) " >> $@.tmp -endif - @if [ -f $@ ] ; then \ - if ! $(CMP) $@ $@.tmp > /dev/null ; then \ - $(CP) $@.tmp $@ ; \ - fi ; \ - else \ - $(CP) $@.tmp $@ ; \ - fi - $(RM) $@.tmp - -# Clobber all the built files -clobber:: bridge2clobber -bridge2clobber:: - $(RM) $(BUILD_DIR_ROOT)/.bridge2* - $(RM) $(BUILD_DIR_ROOT)/.deploy_input - -# Keep track of phony targets -PHONY_LIST += bridge2configure bridgeBuild bridge2clobber - -########################################################################### -# Sanity checks (history target) -# - -sanity: checks - -# Keep track of user targets -USER_TARGETS += sanity - -########################################################################### -# Javadocs -# - -javadocs: - cd common/makefiles && $(MAKE) -f MakefileJavadoc.gmk - -# Keep track of user targets -USER_TARGETS += javadocs - -########################################################################### -# JPRT targets - -ifndef JPRT_ARCHIVE_BUNDLE - JPRT_ARCHIVE_BUNDLE=/tmp/jprt_bundles/j2sdk-image.zip + endif endif -jprt_build_product: DEBUG_LEVEL=release -jprt_build_product: BUILD_DIRNAME=*-release -jprt_build_product: jprt_build_generic - -jprt_build_fastdebug: DEBUG_LEVEL=fastdebug -jprt_build_fastdebug: BUILD_DIRNAME=*-fastdebug -jprt_build_fastdebug: jprt_build_generic - -jprt_build_debug: DEBUG_LEVEL=slowdebug -jprt_build_debug: BUILD_DIRNAME=*-debug -jprt_build_debug: jprt_build_generic - -jprt_build_generic: $(JPRT_ARCHIVE_BUNDLE) - -$(JPRT_ARCHIVE_BUNDLE): bridgeBuild bundles - $(MKDIR) -p $(@D) - $(RM) $@ - $(CP) $(BUILD_DIR_ROOT)/$(BUILD_DIRNAME)/bundles/j2sdk-image.zip $@ - -# Keep track of phony targets -PHONY_LIST += jprt_build_product jprt_build_fastdebug jprt_build_debug \ - jprt_build_generic - -########################################################################### -# Help target - -HELP_FORMAT=%12s%s\n +# Here are "global" targets, i.e. targets that can be executed without specifying a single configuration. +# If you addd more global targets, please update the variable global_targets in MakeHelpers. help: - @$(PRINTF) "# JDK Makefile\n" - @$(PRINTF) "#\n" - @$(PRINTF) "# Usage: make [Target]\n" - @$(PRINTF) "#\n" - @$(PRINTF) "# $(HELP_FORMAT)" "Target " "Description" - @$(PRINTF) "# $(HELP_FORMAT)" "------ " "-----------" - @for i in $(USER_TARGETS) ; do \ - $(MAKE) help_$${i} ; \ - done - @$(PRINTF) "#\n" + $(info ) + $(info OpenJDK Makefile help) + $(info =====================) + $(info ) + $(info Common make targets) + $(info . make [default] # Compile all product in langtools, hotspot, jaxp, jaxws,) + $(info . # corba and jdk) + $(info . make all # Compile everything, all repos and images) + $(info . make images # Create complete j2sdk and j2re images) + $(info . make overlay-images # Create limited images for sparc 64 bit platforms) + $(info . make bootcycle-images # Build images twice, second time with newly build JDK) + $(info . make install # Install the generated images locally) + $(info . make clean # Remove all files generated by make, but not those) + $(info . # generated by configure) + $(info . make dist-clean # Remove all files, including configuration) + $(info . make help # Give some help on using make) + $(info . make test # Run tests, default is all tests (see TEST below)) + $(info ) + $(info Targets for specific components) + $(info (Component is any of langtools, corba, jaxp, jaxws, hotspot, jdk, images or overlay-images)) + $(info . make # Build and everything it depends on. ) + $(info . make -only # Build only, without dependencies. This) + $(info . # is faster but can result in incorrect build results!) + $(info . make clean- # Remove files generated by make for ) + $(info ) + $(info Useful make variables) + $(info . make CONF= # Build all configurations (note, assignment is empty)) + $(info . make CONF= # Build the configuration(s) with a name matching) + $(info . # ) + $(info ) + $(info . make LOG= # Change the log level from warn to ) + $(info . # Available log levels are:) + $(info . # 'warn' (default), 'info', 'debug' and 'trace') + $(info . # To see executed command lines, use LOG=debug) + $(info ) + $(info . make JOBS= # Run parallel make jobs) + $(info . # Note that -jN does not work as expected!) + $(info ) + $(info . make test TEST= # Only run the given test or tests, e.g.) + $(info . # make test TEST="jdk_lang jdk_net") + $(info ) -help_all: - @$(PRINTF) "# $(HELP_FORMAT)" "$(subst help_,,$@) - " \ - "Build the entire jdk but not the images" -help_images: - @$(PRINTF) "# $(HELP_FORMAT)" "$(subst help_,,$@) - " \ - "Create the jdk images for the builds" -help_deploy: - @$(PRINTF) "# $(HELP_FORMAT)" "$(subst help_,,$@) - " \ - "Create the jdk deploy images from the jdk images" -help_install: - @$(PRINTF) "# $(HELP_FORMAT)" "$(subst help_,,$@) - " \ - "Create the jdk install bundles from the deploy images" -help_clean: - @$(PRINTF) "# $(HELP_FORMAT)" "$(subst help_,,$@) - " \ - "Clean and prepare for a fresh build from scratch" -help_clobber: - @$(PRINTF) "# $(HELP_FORMAT)" "$(subst help_,,$@) - " \ - "Clean and also purge any hidden derived data" -help_checks: - @$(PRINTF) "# $(HELP_FORMAT)" "$(subst help_,,$@) - " \ - "Perform various checks to make sure we can build" -help_sanity: - @$(PRINTF) "# $(HELP_FORMAT)" "$(subst help_,,$@) - " \ - "Same as 'make checks'" -help_javadocs: - @$(PRINTF) "# $(HELP_FORMAT)" "$(subst help_,,$@) - " \ - "Build the javadocs" -help_help: - @$(PRINTF) "# $(HELP_FORMAT)" "$(subst help_,,$@) - " \ - "Print out the help messages" - -# Keep track of user targets -USER_TARGETS += help - -########################################################################### -# Phony targets -.PHONY: $(PHONY_LIST) $(USER_TARGETS) - -# Force target -FRC: +.PHONY: help diff --git a/common/autoconf/Makefile.in b/common/autoconf/Makefile.in index d1f148604df..a15b53fb10f 100644 --- a/common/autoconf/Makefile.in +++ b/common/autoconf/Makefile.in @@ -24,4 +24,4 @@ # This Makefile was generated by configure @DATE_WHEN_CONFIGURED@ # GENERATED FILE, DO NOT EDIT SPEC:=@OUTPUT_ROOT@/spec.gmk -include @SRC_ROOT@/common/makefiles/Makefile +include @SRC_ROOT@/NewMakefile.gmk diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index ab7360b40c2..c844fae841a 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -3679,7 +3679,7 @@ fi #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1356635654 +DATE_WHEN_GENERATED=1356638459 ############################################################################### # diff --git a/common/makefiles/Jprt.gmk b/common/makefiles/Jprt.gmk new file mode 100644 index 00000000000..a648bf9191c --- /dev/null +++ b/common/makefiles/Jprt.gmk @@ -0,0 +1,165 @@ +# +# 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# 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. +# + +# This file is included by the root NewerMakefile and contains targets +# and utilities needed by JPRT. + +# Utilities used in this Makefile +CAT=cat +CMP=cmp +CP=cp +ECHO=echo +MKDIR=mkdir +PRINTF=printf +PWD=pwd +# Insure we have a path that looks like it came from pwd +# (This is mostly for Windows sake and drive letters) +define UnixPath # path +$(shell (cd "$1" && $(PWD))) +endef + +BUILD_DIR_ROOT:=$(root_dir)/build + +########################################################################### +# To help in adoption of the new configure&&make build process, a bridge +# build will use the old settings to run configure and do the build. + +# Build with the configure bridge. After running configure, restart make +# to parse the new spec file. +BRIDGE_TARGETS := all +bridgeBuild: bridge2configure + @cd $(root_dir) && $(MAKE) -f NewMakefile.gmk $(BRIDGE_TARGETS) + +# Bridge from old Makefile ALT settings to configure options +bridge2configure: $(BUILD_DIR_ROOT)/.bridge2configureOpts + bash ./configure $(strip $(shell $(CAT) $<)) + +# Create a file with configure options created from old Makefile mechanisms. +$(BUILD_DIR_ROOT)/.bridge2configureOpts: $(BUILD_DIR_ROOT)/.bridge2configureOptsLatest + $(RM) $@ + $(CP) $< $@ + +# Use this file to only change when obvious things have changed +$(BUILD_DIR_ROOT)/.bridge2configureOptsLatest: FRC + $(RM) $@.tmp + $(MKDIR) -p $(BUILD_DIR_ROOT) + @$(ECHO) " --with-debug-level=$(if $(DEBUG_LEVEL),$(DEBUG_LEVEL),release) " >> $@.tmp +ifdef ARCH_DATA_MODEL + @$(ECHO) " --with-target-bits=$(ARCH_DATA_MODEL) " >> $@.tmp +endif +ifeq ($(ARCH_DATA_MODEL),32) + @$(ECHO) " --with-jvm-variants=client,server " >> $@.tmp +endif +ifdef ALT_PARALLEL_COMPILE_JOBS + @$(ECHO) " --with-num-cores=$(ALT_PARALLEL_COMPILE_JOBS) " >> $@.tmp +endif +ifdef ALT_BOOTDIR + @$(ECHO) " --with-boot-jdk=$(call UnixPath,$(ALT_BOOTDIR)) " >> $@.tmp +endif +ifdef ALT_CUPS_HEADERS_PATH + @$(ECHO) " --with-cups-include=$(call UnixPath,$(ALT_CUPS_HEADERS_PATH)) " >> $@.tmp +endif +ifdef ALT_FREETYPE_HEADERS_PATH + @$(ECHO) " --with-freetype=$(call UnixPath,$(ALT_FREETYPE_HEADERS_PATH)/..) " >> $@.tmp +endif +ifdef OPENJDK + @$(ECHO) " --enable-openjdk-only " >> $@.tmp +endif +# Todo: move to closed? +ifdef ALT_MOZILLA_HEADERS_PATH + @$(ECHO) " --with-mozilla-headers=$(call UnixPath,$(ALT_MOZILLA_HEADERS_PATH)) " >> $@.tmp +endif +ifdef ALT_JUNIT_DIR + @$(ECHO) " --with-junit-dir=$(call UnixPath,$(ALT_JUNIT_DIR)) " >> $@.tmp +endif +ifdef ANT_HOME + @$(ECHO) " --with-ant-home=$(call UnixPath,$(ANT_HOME)) " >> $@.tmp +endif +ifdef ALT_SLASH_JAVA + @$(ECHO) " --with-java-devtools=$(call UnixPath,$(ALT_SLASH_JAVA)/devtools) " >> $@.tmp +endif + @if [ -f $@ ] ; then \ + if ! $(CMP) $@ $@.tmp > /dev/null ; then \ + $(CP) $@.tmp $@ ; \ + fi ; \ + else \ + $(CP) $@.tmp $@ ; \ + fi + $(RM) $@.tmp + +PHONY_LIST += bridge2configure bridgeBuild + +########################################################################### +# JPRT targets + +ifndef JPRT_ARCHIVE_BUNDLE + JPRT_ARCHIVE_BUNDLE=/tmp/jprt_bundles/j2sdk-image.zip +endif + +# These targets execute in a SPEC free context, before calling bridgeBuild +# to generate the SPEC. +jprt_build_product: DEBUG_LEVEL=release +jprt_build_product: BUILD_DIRNAME=*-release +jprt_build_product: jprt_build_generic + +jprt_build_fastdebug: DEBUG_LEVEL=fastdebug +jprt_build_fastdebug: BUILD_DIRNAME=*-fastdebug +jprt_build_fastdebug: jprt_build_generic + +jprt_build_debug: DEBUG_LEVEL=slowdebug +jprt_build_debug: BUILD_DIRNAME=*-debug +jprt_build_debug: jprt_build_generic + +jprt_build_generic: BRIDGE_TARGETS+=jprt_bundle +jprt_build_generic: bridgeBuild + +# This target must be called in the context of a SPEC file +jprt_bundle: $(JPRT_ARCHIVE_BUNDLE) + @$(call CheckIfMakeAtEnd) + +# This target must be called in the context of a SPEC file +$(JPRT_ARCHIVE_BUNDLE): bundles + $(MKDIR) -p $(@D) + $(RM) $@ + $(CP) $(BUILD_OUTPUT)/bundles/j2sdk-image.zip $@ + +# This target must be called in the context of a SPEC file +bundles: all + @$(call TargetEnter) + $(MKDIR) -p $(BUILD_OUTPUT)/bundles + $(CD) $(IMAGES_OUTPUTDIR)/j2sdk-image && $(ZIP) -q -r $(BUILD_OUTPUT)/bundles/j2sdk-image.zip . + $(CD) $(IMAGES_OUTPUTDIR)/j2re-image && $(ZIP) -q -r $(BUILD_OUTPUT)/bundles/j2re-image.zip . + @$(call TargetExit) + +# Keep track of phony targets +PHONY_LIST += jprt_build_product jprt_build_fastdebug jprt_build_debug \ + jprt_build_generic bundles jprt_bundle + +########################################################################### +# Phony targets +.PHONY: $(PHONY_LIST) + +# Force target +FRC: diff --git a/common/makefiles/Main.gmk b/common/makefiles/Main.gmk index 33f3cf24952..1bbeecac463 100644 --- a/common/makefiles/Main.gmk +++ b/common/makefiles/Main.gmk @@ -65,7 +65,11 @@ MAKE_ARGS:=$(MAKE_ARGS) -j$(JOBS) ### Main targets -all: jdk +default: jdk + @$(call CheckIfMakeAtEnd) + +all: images docs + @$(call CheckIfMakeAtEnd) start-make: @$(call AtMakeStart) @@ -126,12 +130,6 @@ overlay-images-only: start-make @($(CD) $(JDK_TOPDIR)/makefiles && $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) -f BuildJdk.gmk overlay-images) @$(call TargetExit) -bundles: images bundles-only -bundles-only: start-make - @$(call TargetEnter) - @($(CD) $(JDK_TOPDIR)/makefiles && $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) -f BuildJdk.gmk bundles) - @$(call TargetExit) - install: images install-only install-only: start-make @$(call TargetEnter) diff --git a/common/makefiles/MakeHelpers.gmk b/common/makefiles/MakeHelpers.gmk index f76ad374b2b..81e1d697e11 100644 --- a/common/makefiles/MakeHelpers.gmk +++ b/common/makefiles/MakeHelpers.gmk @@ -50,7 +50,7 @@ BUILDTIMESDIR=$(OUTPUT_ROOT)/tmp/buildtimes # Global targets are possible to run either with or without a SPEC. The prototypical # global target is "help". -global_targets=help configure +global_targets=help jprt% bridgeBuild ############################## # Functions @@ -112,7 +112,7 @@ endef # Do not indent this function, this will add whitespace at the start which the caller won't handle define GetRealTarget -$(strip $(if $(MAKECMDGOALS),$(MAKECMDGOALS),all)) +$(strip $(if $(MAKECMDGOALS),$(MAKECMDGOALS),default)) endef # Do not indent this function, this will add whitespace at the start which the caller won't handle @@ -126,10 +126,7 @@ define CheckIfMakeAtEnd # Check if the current target is the last goal $(if $(filter $@,$(call LastGoal)),$(call AtMakeEnd)) # If the target is 'foo-only', check if our goal was stated as 'foo' - $(if $(filter $(patsubst %-only,%,$@),$(call LastGoal)),$(call AtMakeEnd)) - # If no goal is given, 'all' is default, but the last target executed for all is 'jdk-only'. Check for that, too. - # At most one of the tests can be true. - $(if $(subst all,,$(call LastGoal)),,$(if $(filter $@,jdk-only),$(call AtMakeEnd))) + $(if $(filter $@,$(call LastGoal)-only),$(call AtMakeEnd)) endef # Hook to be called when starting to execute a top-level target diff --git a/common/makefiles/Makefile b/common/makefiles/Makefile index cd5a9bfae34..279106bd58b 100644 --- a/common/makefiles/Makefile +++ b/common/makefiles/Makefile @@ -23,109 +23,4 @@ # questions. # -# This must be the first rule -all: - -# Inclusion of this pseudo-target will cause make to execute this file -# serially, regardless of -j. Recursively called makefiles will not be -# affected, however. This is required for correct dependency management. -.NOTPARALLEL: - -# The shell code below will be executed on /usr/ccs/bin/make on Solaris, but not in GNU make. -# /usr/ccs/bin/make lacks basically every other flow control mechanism. -TEST_FOR_NON_GNUMAKE:sh=echo You are not using GNU make/gmake, this is a requirement. Check your path. 1>&2 && exit 1 - -# Assume we have GNU make, but check version. -ifeq (,$(findstring 3.81,$(MAKE_VERSION))) - ifeq (,$(findstring 3.82,$(MAKE_VERSION))) - $(error This version of GNU Make is too low ($(MAKE_VERSION)). Check your path, or upgrade to 3.81 or newer.) - endif -endif - -# Locate this Makefile -ifeq ($(filter /%,$(lastword $(MAKEFILE_LIST))),) - makefile_path:=$(CURDIR)/$(lastword $(MAKEFILE_LIST)) -else - makefile_path:=$(lastword $(MAKEFILE_LIST)) -endif -root_dir:=$(patsubst %/common/makefiles/Makefile,%,$(makefile_path)) - -# ... and then we can include our helper functions -include $(dir $(makefile_path))/MakeHelpers.gmk - -$(eval $(call ParseLogLevel)) -$(eval $(call ParseConfAndSpec)) - -# Now determine if we have zero, one or several configurations to build. -ifeq ($(SPEC),) - # Since we got past ParseConfAndSpec, we must be building a global target. Do nothing. -else - ifeq ($(words $(SPEC)),1) - # We are building a single configuration. This is the normal case. Execute the Main.gmk file. - include $(dir $(makefile_path))/Main.gmk - else - # We are building multiple configurations. - # First, find out the valid targets - # Run the makefile with an arbitraty SPEC using -p -q (quiet dry-run and dump rules) to find - # available PHONY targets. Use this list as valid targets to pass on to the repeated calls. - all_phony_targets=$(filter-out $(global_targets), $(strip $(shell \ - $(MAKE) -p -q -f $(makefile_path) SPEC=$(firstword $(SPEC)) | \ - grep ^.PHONY: | head -n 1 | cut -d " " -f 2-))) - -$(all_phony_targets): - @$(foreach spec,$(SPEC),($(MAKE) -f $(makefile_path) SPEC=$(spec) $(VERBOSE) VERBOSE=$(VERBOSE) $@) &&) true - - endif -endif - -# Here are "global" targets, i.e. targets that can be executed without specifying a single configuration. -# If you addd more global targets, please update the variable global_targets in MakeHelpers. - -help: - $(info ) - $(info OpenJDK Makefile help) - $(info =====================) - $(info ) - $(info Common make targets) - $(info . make [all] # Compile all code but do not create images) - $(info . make images # Create complete j2sdk and j2re images) - $(info . make overlay-images # Create limited images for sparc 64 bit platforms) - $(info . make bootcycle-images # Build images twice, second time with newly build JDK) - $(info . make install # Install the generated images locally) - $(info . make clean # Remove all files generated by make, but not those) - $(info . # generated by configure) - $(info . make dist-clean # Remove all files, including configuration) - $(info . make help # Give some help on using make) - $(info . make test # Run tests, default is all tests (see TEST below)) - $(info ) - $(info Targets for specific components) - $(info (Component is any of langtools, corba, jaxp, jaxws, hotspot, jdk, images or overlay-images)) - $(info . make # Build and everything it depends on. ) - $(info . make -only # Build only, without dependencies. This) - $(info . # is faster but can result in incorrect build results!) - $(info . make clean- # Remove files generated by make for ) - $(info ) - $(info Useful make variables) - $(info . make CONF= # Build all configurations (note, assignment is empty)) - $(info . make CONF= # Build the configuration(s) with a name matching) - $(info . # ) - $(info ) - $(info . make LOG= # Change the log level from warn to ) - $(info . # Available log levels are:) - $(info . # 'warn' (default), 'info', 'debug' and 'trace') - $(info . # To see executed command lines, use LOG=debug) - $(info ) - $(info . make JOBS= # Run parallel make jobs) - $(info . # Note that -jN does not work as expected!) - $(info ) - $(info . make test TEST= # Only run the given test or tests, e.g.) - $(info . # make test TEST="jdk_lang jdk_net") - $(info ) - -configure: - @$(SHELL) $(root_dir)/configure $(CONFIGURE_ARGS) - @echo ==================================================== - @echo "Note: This is a non-recommended way of running configure." - @echo "Instead, run 'sh configure' in the top-level directory" - -.PHONY: help configure +include ../../NewMakefile.gmk From 15bae865ac61c71667ae644f871d49c144ad0560 Mon Sep 17 00:00:00 2001 From: John Cuthbertson Date: Thu, 3 Jan 2013 16:28:22 -0800 Subject: [PATCH 013/204] 8004816: G1: Kitchensink failures after marking stack changes Reset the marking state, including the mark stack overflow flag, in the event of a marking stack overflow during serial reference processing. Reviewed-by: jmasa --- .../gc_implementation/g1/concurrentMark.cpp | 58 +++++++++---------- .../gc_implementation/g1/concurrentMark.hpp | 15 +++-- .../g1/concurrentMarkThread.cpp | 12 ++-- 3 files changed, 43 insertions(+), 42 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp index e03b2f41cfc..3199cbf5a60 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -192,6 +192,7 @@ bool CMMarkStack::allocate(size_t capacity) { setEmpty(); _capacity = (jint) capacity; _saved_index = -1; + _should_expand = false; NOT_PRODUCT(_max_depth = 0); return true; } @@ -747,8 +748,8 @@ void ConcurrentMark::reset() { assert(_heap_end != NULL, "heap bounds should look ok"); assert(_heap_start < _heap_end, "heap bounds should look ok"); - // reset all the marking data structures and any necessary flags - clear_marking_state(); + // Reset all the marking data structures and any necessary flags + reset_marking_state(); if (verbose_low()) { gclog_or_tty->print_cr("[global] resetting"); @@ -766,6 +767,23 @@ void ConcurrentMark::reset() { set_concurrent_marking_in_progress(); } + +void ConcurrentMark::reset_marking_state(bool clear_overflow) { + _markStack.set_should_expand(); + _markStack.setEmpty(); // Also clears the _markStack overflow flag + if (clear_overflow) { + clear_has_overflown(); + } else { + assert(has_overflown(), "pre-condition"); + } + _finger = _heap_start; + + for (uint i = 0; i < _max_worker_id; ++i) { + CMTaskQueue* queue = _task_queues->queue(i); + queue->set_empty(); + } +} + void ConcurrentMark::set_phase(uint active_tasks, bool concurrent) { assert(active_tasks <= _max_worker_id, "we should not have more"); @@ -796,7 +814,7 @@ void ConcurrentMark::set_phase(uint active_tasks, bool concurrent) { void ConcurrentMark::set_non_marking_state() { // We set the global marking state to some default values when we're // not doing marking. - clear_marking_state(); + reset_marking_state(); _active_tasks = 0; clear_concurrent_marking_in_progress(); } @@ -963,7 +981,7 @@ void ConcurrentMark::enter_first_sync_barrier(uint worker_id) { // not clear the overflow flag since we rely on it being true when // we exit this method to abort the pause and restart concurent // marking. - clear_marking_state(concurrent() /* clear_overflow */); + reset_marking_state(concurrent() /* clear_overflow */); force_overflow()->update(); if (G1Log::fine()) { @@ -1257,8 +1275,9 @@ void ConcurrentMark::checkpointRootsFinal(bool clear_all_soft_refs) { if (has_overflown()) { // Oops. We overflowed. Restart concurrent marking. _restart_for_overflow = true; - // Clear the flag. We do not need it any more. - clear_has_overflown(); + // Clear the marking state because we will be restarting + // marking due to overflowing the global mark stack. + reset_marking_state(); if (G1TraceMarkStackOverflow) { gclog_or_tty->print_cr("\nRemark led to restart for overflow."); } @@ -1282,6 +1301,8 @@ void ConcurrentMark::checkpointRootsFinal(bool clear_all_soft_refs) { /* option */ VerifyOption_G1UseNextMarking); } assert(!restart_for_overflow(), "sanity"); + // Completely reset the marking state since marking completed + set_non_marking_state(); } // Expand the marking stack, if we have to and if we can. @@ -1289,11 +1310,6 @@ void ConcurrentMark::checkpointRootsFinal(bool clear_all_soft_refs) { _markStack.expand(); } - // Reset the marking state if marking completed - if (!restart_for_overflow()) { - set_non_marking_state(); - } - #if VERIFY_OBJS_PROCESSED _scan_obj_cl.objs_processed = 0; ThreadLocalObjQueue::objs_enqueued = 0; @@ -2963,22 +2979,6 @@ void ConcurrentMark::verify_no_cset_oops(bool verify_stacks, } #endif // PRODUCT -void ConcurrentMark::clear_marking_state(bool clear_overflow) { - _markStack.set_should_expand(); - _markStack.setEmpty(); // Also clears the _markStack overflow flag - if (clear_overflow) { - clear_has_overflown(); - } else { - assert(has_overflown(), "pre-condition"); - } - _finger = _heap_start; - - for (uint i = 0; i < _max_worker_id; ++i) { - CMTaskQueue* queue = _task_queues->queue(i); - queue->set_empty(); - } -} - // Aggregate the counting data that was constructed concurrently // with marking. class AggregateCountDataHRClosure: public HeapRegionClosure { @@ -3185,7 +3185,7 @@ void ConcurrentMark::abort() { // Clear the liveness counting data clear_all_count_data(); // Empty mark stack - clear_marking_state(); + reset_marking_state(); for (uint i = 0; i < _max_worker_id; ++i) { _tasks[i]->clear_region_fields(); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp index 8089c98294a..34c5601e050 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -478,15 +478,18 @@ protected: // It resets the global marking data structures, as well as the // task local ones; should be called during initial mark. void reset(); - // It resets all the marking data structures. - void clear_marking_state(bool clear_overflow = true); + + // Resets all the marking data structures. Called when we have to restart + // marking or when marking completes (via set_non_marking_state below). + void reset_marking_state(bool clear_overflow = true); + + // We do this after we're done with marking so that the marking data + // structures are initialised to a sensible and predictable state. + void set_non_marking_state(); // It should be called to indicate which phase we're in (concurrent // mark or remark) and how many threads are currently active. void set_phase(uint active_tasks, bool concurrent); - // We do this after we're done with marking so that the marking data - // structures are initialised to a sensible and predictable state. - void set_non_marking_state(); // prints all gathered CM-related statistics void print_stats(); diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp index 40d2aece12a..3247e87692b 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -159,13 +159,11 @@ void ConcurrentMarkThread::run() { VM_CGC_Operation op(&final_cl, verbose_str, true /* needs_pll */); VMThread::execute(&op); } - if (cm()->restart_for_overflow() && - G1TraceMarkStackOverflow) { - gclog_or_tty->print_cr("Restarting conc marking because of MS overflow " - "in remark (restart #%d).", iter); - } - if (cm()->restart_for_overflow()) { + if (G1TraceMarkStackOverflow) { + gclog_or_tty->print_cr("Restarting conc marking because of MS overflow " + "in remark (restart #%d).", iter); + } if (G1Log::fine()) { gclog_or_tty->date_stamp(PrintGCDateStamps); gclog_or_tty->stamp(PrintGCTimeStamps); From 53cdde9124b28b837bc01e621fc33b3385ed5008 Mon Sep 17 00:00:00 2001 From: Bengt Rutisson Date: Sun, 30 Dec 2012 08:47:52 +0100 Subject: [PATCH 014/204] 8005396: Use ParNew with only one thread instead of DefNew as default for CMS on single CPU machines Reviewed-by: jmasa, jcoomes --- .../cmsCollectorPolicy.cpp | 6 +- .../parNew/parNewGeneration.cpp | 4 -- .../parNew/parNewGeneration.hpp | 2 - .../src/share/vm/memory/collectorPolicy.cpp | 7 +- .../src/share/vm/memory/tenuredGeneration.cpp | 2 +- hotspot/src/share/vm/runtime/arguments.cpp | 69 +++++++++---------- 6 files changed, 39 insertions(+), 51 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp index 5123d460c37..e57d405e5d0 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp @@ -56,7 +56,7 @@ void ConcurrentMarkSweepPolicy::initialize_generations() { if (_generations == NULL) vm_exit_during_initialization("Unable to allocate gen spec"); - if (ParNewGeneration::in_use()) { + if (UseParNewGC) { if (UseAdaptiveSizePolicy) { _generations[0] = new GenerationSpec(Generation::ASParNew, _initial_gen0_size, _max_gen0_size); @@ -96,7 +96,7 @@ void ConcurrentMarkSweepPolicy::initialize_size_policy(size_t init_eden_size, void ConcurrentMarkSweepPolicy::initialize_gc_policy_counters() { // initialize the policy counters - 2 collectors, 3 generations - if (ParNewGeneration::in_use()) { + if (UseParNewGC) { _gc_policy_counters = new GCPolicyCounters("ParNew:CMS", 2, 3); } else { @@ -119,7 +119,7 @@ void ASConcurrentMarkSweepPolicy::initialize_gc_policy_counters() { assert(size_policy() != NULL, "A size policy is required"); // initialize the policy counters - 2 collectors, 3 generations - if (ParNewGeneration::in_use()) { + if (UseParNewGC) { _gc_policy_counters = new CMSGCAdaptivePolicyCounters("ParNew:CMS", 2, 3, size_policy()); } diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp index ea432002a1e..273322436ba 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp @@ -1623,7 +1623,3 @@ void ParNewGeneration::ref_processor_init() const char* ParNewGeneration::name() const { return "par new generation"; } - -bool ParNewGeneration::in_use() { - return UseParNewGC && ParallelGCThreads > 0; -} diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp index b8a2d1ea0bd..bbb6176fd08 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp @@ -361,8 +361,6 @@ class ParNewGeneration: public DefNewGeneration { delete _task_queues; } - static bool in_use(); - virtual void ref_processor_init(); virtual Generation::Name kind() { return Generation::ParNew; } virtual const char* name() const; diff --git a/hotspot/src/share/vm/memory/collectorPolicy.cpp b/hotspot/src/share/vm/memory/collectorPolicy.cpp index 6857181a5be..b13d9761120 100644 --- a/hotspot/src/share/vm/memory/collectorPolicy.cpp +++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp @@ -827,7 +827,7 @@ void MarkSweepPolicy::initialize_generations() { if (_generations == NULL) vm_exit_during_initialization("Unable to allocate gen spec"); - if (UseParNewGC && ParallelGCThreads > 0) { + if (UseParNewGC) { _generations[0] = new GenerationSpec(Generation::ParNew, _initial_gen0_size, _max_gen0_size); } else { _generations[0] = new GenerationSpec(Generation::DefNew, _initial_gen0_size, _max_gen0_size); @@ -840,10 +840,9 @@ void MarkSweepPolicy::initialize_generations() { void MarkSweepPolicy::initialize_gc_policy_counters() { // initialize the policy counters - 2 collectors, 3 generations - if (UseParNewGC && ParallelGCThreads > 0) { + if (UseParNewGC) { _gc_policy_counters = new GCPolicyCounters("ParNew:MSC", 2, 3); - } - else { + } else { _gc_policy_counters = new GCPolicyCounters("Copy:MSC", 2, 3); } } diff --git a/hotspot/src/share/vm/memory/tenuredGeneration.cpp b/hotspot/src/share/vm/memory/tenuredGeneration.cpp index 1d38095f8e5..f47ea307dd8 100644 --- a/hotspot/src/share/vm/memory/tenuredGeneration.cpp +++ b/hotspot/src/share/vm/memory/tenuredGeneration.cpp @@ -62,7 +62,7 @@ TenuredGeneration::TenuredGeneration(ReservedSpace rs, _virtual_space.reserved_size(), _the_space, _gen_counters); #ifndef SERIALGC - if (UseParNewGC && ParallelGCThreads > 0) { + if (UseParNewGC) { typedef ParGCAllocBufferWithBOT* ParGCAllocBufferWithBOTPtr; _alloc_buffers = NEW_C_HEAP_ARRAY(ParGCAllocBufferWithBOTPtr, ParallelGCThreads, mtGC); diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 21e5cce7b18..4d1b9366d07 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1083,10 +1083,6 @@ static void disable_adaptive_size_policy(const char* collector_name) { } } -// If the user has chosen ParallelGCThreads > 0, we set UseParNewGC -// if it's not explictly set or unset. If the user has chosen -// UseParNewGC and not explicitly set ParallelGCThreads we -// set it, unless this is a single cpu machine. void Arguments::set_parnew_gc_flags() { assert(!UseSerialGC && !UseParallelOldGC && !UseParallelGC && !UseG1GC, "control point invariant"); @@ -1095,42 +1091,41 @@ void Arguments::set_parnew_gc_flags() { // Turn off AdaptiveSizePolicy for parnew until it is complete. disable_adaptive_size_policy("UseParNewGC"); - if (ParallelGCThreads == 0) { - FLAG_SET_DEFAULT(ParallelGCThreads, - Abstract_VM_Version::parallel_worker_threads()); - if (ParallelGCThreads == 1) { - FLAG_SET_DEFAULT(UseParNewGC, false); - FLAG_SET_DEFAULT(ParallelGCThreads, 0); - } + if (FLAG_IS_DEFAULT(ParallelGCThreads)) { + FLAG_SET_DEFAULT(ParallelGCThreads, Abstract_VM_Version::parallel_worker_threads()); + assert(ParallelGCThreads > 0, "We should always have at least one thread by default"); + } else if (ParallelGCThreads == 0) { + jio_fprintf(defaultStream::error_stream(), + "The ParNew GC can not be combined with -XX:ParallelGCThreads=0\n"); + vm_exit(1); } - if (UseParNewGC) { - // By default YoungPLABSize and OldPLABSize are set to 4096 and 1024 respectively, - // these settings are default for Parallel Scavenger. For ParNew+Tenured configuration - // we set them to 1024 and 1024. - // See CR 6362902. - if (FLAG_IS_DEFAULT(YoungPLABSize)) { - FLAG_SET_DEFAULT(YoungPLABSize, (intx)1024); - } - if (FLAG_IS_DEFAULT(OldPLABSize)) { - FLAG_SET_DEFAULT(OldPLABSize, (intx)1024); - } - // AlwaysTenure flag should make ParNew promote all at first collection. - // See CR 6362902. - if (AlwaysTenure) { - FLAG_SET_CMDLINE(uintx, MaxTenuringThreshold, 0); - } - // When using compressed oops, we use local overflow stacks, - // rather than using a global overflow list chained through - // the klass word of the object's pre-image. - if (UseCompressedOops && !ParGCUseLocalOverflow) { - if (!FLAG_IS_DEFAULT(ParGCUseLocalOverflow)) { - warning("Forcing +ParGCUseLocalOverflow: needed if using compressed references"); - } - FLAG_SET_DEFAULT(ParGCUseLocalOverflow, true); - } - assert(ParGCUseLocalOverflow || !UseCompressedOops, "Error"); + // By default YoungPLABSize and OldPLABSize are set to 4096 and 1024 respectively, + // these settings are default for Parallel Scavenger. For ParNew+Tenured configuration + // we set them to 1024 and 1024. + // See CR 6362902. + if (FLAG_IS_DEFAULT(YoungPLABSize)) { + FLAG_SET_DEFAULT(YoungPLABSize, (intx)1024); } + if (FLAG_IS_DEFAULT(OldPLABSize)) { + FLAG_SET_DEFAULT(OldPLABSize, (intx)1024); + } + + // AlwaysTenure flag should make ParNew promote all at first collection. + // See CR 6362902. + if (AlwaysTenure) { + FLAG_SET_CMDLINE(uintx, MaxTenuringThreshold, 0); + } + // When using compressed oops, we use local overflow stacks, + // rather than using a global overflow list chained through + // the klass word of the object's pre-image. + if (UseCompressedOops && !ParGCUseLocalOverflow) { + if (!FLAG_IS_DEFAULT(ParGCUseLocalOverflow)) { + warning("Forcing +ParGCUseLocalOverflow: needed if using compressed references"); + } + FLAG_SET_DEFAULT(ParGCUseLocalOverflow, true); + } + assert(ParGCUseLocalOverflow || !UseCompressedOops, "Error"); } // Adjust some sizes to suit CMS and/or ParNew needs; these work well on From 75a99396e7066da6417b8e09f6c2c09f0fefb49d Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Sun, 30 Dec 2012 12:15:02 +0100 Subject: [PATCH 015/204] 8004490: build-infra: mac: hotspot is always built in product, regardless of --with-debug-level setting Reviewed-by: tbell --- common/autoconf/generated-configure.sh | 4 ++-- common/autoconf/jdk-options.m4 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index c844fae841a..4f760356dc0 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -3679,7 +3679,7 @@ fi #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1356638459 +DATE_WHEN_GENERATED=1356865941 ############################################################################### # @@ -7580,7 +7580,7 @@ HOTSPOT_TARGET="$HOTSPOT_TARGET docs export_$HOTSPOT_EXPORT" # from configure, but only server is valid anyway. Fix this # when hotspot makefiles are rewritten. if test "x$MACOSX_UNIVERSAL" = xtrue; then - HOTSPOT_TARGET=universal_product + HOTSPOT_TARGET=universal_${HOTSPOT_EXPORT} fi ##### diff --git a/common/autoconf/jdk-options.m4 b/common/autoconf/jdk-options.m4 index 0a6d10a3fc1..78ee5f1542f 100644 --- a/common/autoconf/jdk-options.m4 +++ b/common/autoconf/jdk-options.m4 @@ -235,7 +235,7 @@ HOTSPOT_TARGET="$HOTSPOT_TARGET docs export_$HOTSPOT_EXPORT" # from configure, but only server is valid anyway. Fix this # when hotspot makefiles are rewritten. if test "x$MACOSX_UNIVERSAL" = xtrue; then - HOTSPOT_TARGET=universal_product + HOTSPOT_TARGET=universal_${HOTSPOT_EXPORT} fi ##### From 8a93671af6c9a872bba45b9d9ad16cd8d71faf4a Mon Sep 17 00:00:00 2001 From: Qi Zuo Date: Mon, 31 Dec 2012 14:52:11 -0500 Subject: [PATCH 016/204] 8005583: Install build(gnumake all) failed preventing RE from doing JDK8 combo builds Reviewed-by: paulk, billyh --- make/install-rules.gmk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/make/install-rules.gmk b/make/install-rules.gmk index 609cc2abd19..2bde487b5ad 100644 --- a/make/install-rules.gmk +++ b/make/install-rules.gmk @@ -96,6 +96,9 @@ endif combo_build: @$(ECHO) $@ installer combo build started: `$(DATE) '+%y-%m-%d %H:%M'` $(CD) $(INSTALL_TOPDIR)/make/installer/bundles/windows/ishield/wrapper/wrapper.jreboth ; $(MAKE) all + $(CD) $(INSTALL_TOPDIR)/make/installer/bundles/windows/ishield/wrapper/wrapper.new64jre ; $(MAKE) all + $(CD) $(INSTALL_TOPDIR)/make/installer/bundles/windows/ishield/jre ; $(MAKE) au_combo + $(CD) $(INSTALL_TOPDIR)/make/installer/bundles/windows/xmlinffile ; $(MAKE) all install-clobber: ifeq ($(BUILD_INSTALL), true) From 36c06a232d85f4b097e02b0dafccb9a0f3bd46c8 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Tue, 1 Jan 2013 14:13:18 +0100 Subject: [PATCH 017/204] 8001895: build-infra: Make JDK_BUILD_NUMBER and MILESTONE customizable Added configure params Reviewed-by: ohair --- common/autoconf/generated-configure.sh | 56 +++++++++++++++++--------- common/autoconf/jdk-options.m4 | 41 +++++++++++-------- common/autoconf/spec.gmk.in | 15 ++++++- common/autoconf/version.numbers | 2 - 4 files changed, 74 insertions(+), 40 deletions(-) diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index 4f760356dc0..88755606939 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -752,8 +752,7 @@ BOOT_RTJAR JAVA_CHECK JAVAC_CHECK COOKED_BUILD_NUMBER -FULL_VERSION -RELEASE +USER_RELEASE_SUFFIX JDK_VERSION RUNTIME_NAME COPYRIGHT_YEAR @@ -969,6 +968,8 @@ enable_headful enable_hotspot_test_in_build with_cacerts_file enable_unlimited_crypto +with_milestone +with_build_number with_boot_jdk with_boot_jdk_jvmargs with_add_source_root @@ -1698,6 +1699,8 @@ Optional Packages: --with-builddeps-group chgrp the downloaded build dependencies to this group --with-cacerts-file specify alternative cacerts file + --with-milestone Set milestone value for build [internal] + --with-build-number Set build number value for build [b00] --with-boot-jdk path to Boot JDK (used to bootstrap build) [probed] --with-boot-jdk-jvmargs specify JVM arguments to be passed to all invocations of the Boot JDK, overriding the default @@ -3679,7 +3682,7 @@ fi #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1356865941 +DATE_WHEN_GENERATED=1357045896 ############################################################################### # @@ -10608,6 +10611,33 @@ COMPRESS_JARS=false if test "x$OPENJDK" = "xfalse"; then . $AUTOCONF_DIR/closed.version.numbers fi + + +# Check whether --with-milestone was given. +if test "${with_milestone+set}" = set; then : + withval=$with_milestone; +fi + +if test "x$with_milestone" = xyes; then + as_fn_error $? "Milestone must have a value" "$LINENO" 5 +elif test "x$with_milestone" != x; then + MILESTONE="$with_milestone" +else + MILESTONE=internal +fi + + +# Check whether --with-build-number was given. +if test "${with_build_number+set}" = set; then : + withval=$with_build_number; +fi + +if test "x$with_build_number" = xyes; then + as_fn_error $? "Build number must have a value" "$LINENO" 5 +elif test "x$with_build_number" != x; then + JDK_BUILD_NUMBER="$with_build_number" +fi + # Now set the JDK version, milestone, build number etc. @@ -10636,24 +10666,12 @@ else fi -if test "x$MILESTONE" != x; then - RELEASE="${JDK_VERSION}-${MILESTONE}${BUILD_VARIANT_RELEASE}" -else - RELEASE="${JDK_VERSION}${BUILD_VARIANT_RELEASE}" -fi +BUILD_DATE=`date '+%Y_%m_%d_%H_%M'` +# Avoid [:alnum:] since it depends on the locale. +CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyz0123456789'` +USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` -if test "x$JDK_BUILD_NUMBER" != x; then - FULL_VERSION="${RELEASE}-${JDK_BUILD_NUMBER}" -else - JDK_BUILD_NUMBER=b00 - BUILD_DATE=`date '+%Y_%m_%d_%H_%M'` - # Avoid [:alnum:] since it depends on the locale. - CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyz0123456789'` - USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FULL_VERSION="${RELEASE}-${USER_RELEASE_SUFFIX}-${JDK_BUILD_NUMBER}" -fi - COOKED_BUILD_NUMBER=`$ECHO $JDK_BUILD_NUMBER | $SED -e 's/^b//' -e 's/^0//'` diff --git a/common/autoconf/jdk-options.m4 b/common/autoconf/jdk-options.m4 index 78ee5f1542f..95cb414baca 100644 --- a/common/autoconf/jdk-options.m4 +++ b/common/autoconf/jdk-options.m4 @@ -376,6 +376,25 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_JDK_VERSION_NUMBERS], if test "x$OPENJDK" = "xfalse"; then . $AUTOCONF_DIR/closed.version.numbers fi + +AC_ARG_WITH(milestone, [AS_HELP_STRING([--with-milestone], + [Set milestone value for build @<:@internal@:>@])]) +if test "x$with_milestone" = xyes; then + AC_MSG_ERROR([Milestone must have a value]) +elif test "x$with_milestone" != x; then + MILESTONE="$with_milestone" +else + MILESTONE=internal +fi + +AC_ARG_WITH(build-number, [AS_HELP_STRING([--with-build-number], + [Set build number value for build @<:@b00@:>@])]) +if test "x$with_build_number" = xyes; then + AC_MSG_ERROR([Build number must have a value]) +elif test "x$with_build_number" != x; then + JDK_BUILD_NUMBER="$with_build_number" +fi + # Now set the JDK version, milestone, build number etc. AC_SUBST(JDK_MAJOR_VERSION) AC_SUBST(JDK_MINOR_VERSION) @@ -404,24 +423,12 @@ else fi AC_SUBST(JDK_VERSION) -if test "x$MILESTONE" != x; then - RELEASE="${JDK_VERSION}-${MILESTONE}${BUILD_VARIANT_RELEASE}" -else - RELEASE="${JDK_VERSION}${BUILD_VARIANT_RELEASE}" -fi -AC_SUBST(RELEASE) +BUILD_DATE=`date '+%Y_%m_%d_%H_%M'` +# Avoid [:alnum:] since it depends on the locale. +CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyz0123456789'` +USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` +AC_SUBST(USER_RELEASE_SUFFIX) -if test "x$JDK_BUILD_NUMBER" != x; then - FULL_VERSION="${RELEASE}-${JDK_BUILD_NUMBER}" -else - JDK_BUILD_NUMBER=b00 - BUILD_DATE=`date '+%Y_%m_%d_%H_%M'` - # Avoid [:alnum:] since it depends on the locale. - CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyz0123456789'` - USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FULL_VERSION="${RELEASE}-${USER_RELEASE_SUFFIX}-${JDK_BUILD_NUMBER}" -fi -AC_SUBST(FULL_VERSION) COOKED_BUILD_NUMBER=`$ECHO $JDK_BUILD_NUMBER | $SED -e 's/^b//' -e 's/^0//'` AC_SUBST(COOKED_BUILD_NUMBER) ]) diff --git a/common/autoconf/spec.gmk.in b/common/autoconf/spec.gmk.in index 5dab096eb03..f16236fc26c 100644 --- a/common/autoconf/spec.gmk.in +++ b/common/autoconf/spec.gmk.in @@ -164,10 +164,21 @@ MACOSX_BUNDLE_ID_BASE=@MACOSX_BUNDLE_ID_BASE@ # Different version strings generated from the above information. JDK_VERSION:=@JDK_VERSION@ RUNTIME_NAME:=@RUNTIME_NAME@ -FULL_VERSION:=@FULL_VERSION@ JRE_RELEASE_VERSION:=@FULL_VERSION@ -RELEASE:=@RELEASE@ COOKED_BUILD_NUMBER:=@COOKED_BUILD_NUMBER@ +# These variables need to be generated here so that MILESTONE and +# JDK_BUILD_NUMBER can be overridden on the make command line. +ifeq ($(MILESTONE),) + RELEASE=$(JDK_VERSION)$(BUILD_VARIANT_RELEASE) +else + RELEASE=$(JDK_VERSION)-$(MILESTONE)$(BUILD_VARIANT_RELEASE) +endif +ifeq ($(JDK_BUILD_NUMBER),b00) + USER_RELEASE_SUFFIX=@USER_RELEASE_SUFFIX@ + FULL_VERSION=$(RELEASE)-$(USER_RELEASE_SUFFIX)-$(JDK_BUILD_NUMBER) +else + FULL_VERSION=$(RELEASE)-$(JDK_BUILD_NUMBER) +endif # How to compile the code: release, fastdebug or slowdebug DEBUG_LEVEL:=@DEBUG_LEVEL@ diff --git a/common/autoconf/version.numbers b/common/autoconf/version.numbers index f174ed4228f..7200e78a2f1 100644 --- a/common/autoconf/version.numbers +++ b/common/autoconf/version.numbers @@ -27,8 +27,6 @@ JDK_MAJOR_VERSION=1 JDK_MINOR_VERSION=8 JDK_MICRO_VERSION=0 JDK_UPDATE_VERSION= -JDK_BUILD_NUMBER= -MILESTONE=internal LAUNCHER_NAME=openjdk PRODUCT_NAME=OpenJDK PRODUCT_SUFFIX="Runtime Environment" From f80cc97adb8546b3dae9a24265e44c9ea3cba6de Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Wed, 2 Jan 2013 11:29:29 +0100 Subject: [PATCH 018/204] 8005347: build-infra: Verify 'gnumake source' at the top level works ok Reviewed-by: tbell, ohair, dholmes --- common/autoconf/basics.m4 | 4 +- common/autoconf/closed.version.numbers | 32 ---- common/autoconf/generated-configure.sh | 144 ++++++++++++++++-- common/autoconf/jdk-options.m4 | 18 ++- common/autoconf/spec.gmk.in | 10 +- .../{version.numbers => version-numbers} | 2 +- 6 files changed, 153 insertions(+), 57 deletions(-) delete mode 100644 common/autoconf/closed.version.numbers rename common/autoconf/{version.numbers => version-numbers} (95%) diff --git a/common/autoconf/basics.m4 b/common/autoconf/basics.m4 index 8b1dbc899e5..c713d22a804 100644 --- a/common/autoconf/basics.m4 +++ b/common/autoconf/basics.m4 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2013, 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 @@ -234,7 +234,9 @@ BASIC_REQUIRE_PROG(BASH, bash) BASIC_REQUIRE_PROG(CAT, cat) BASIC_REQUIRE_PROG(CHMOD, chmod) BASIC_REQUIRE_PROG(CMP, cmp) +BASIC_REQUIRE_PROG(COMM, comm) BASIC_REQUIRE_PROG(CP, cp) +BASIC_REQUIRE_PROG(CPIO, cpio) BASIC_REQUIRE_PROG(CUT, cut) BASIC_REQUIRE_PROG(DATE, date) BASIC_REQUIRE_PROG(DIFF, [gdiff diff]) diff --git a/common/autoconf/closed.version.numbers b/common/autoconf/closed.version.numbers deleted file mode 100644 index b22ad976cbc..00000000000 --- a/common/autoconf/closed.version.numbers +++ /dev/null @@ -1,32 +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. -# - -LAUNCHER_NAME=java -PRODUCT_NAME="Java(TM)" -PRODUCT_SUFFIX="SE Runtime Environment" -JDK_RC_PLATFORM_NAME="Platform SE" -COMPANY_NAME="Oracle Corporation" - -# Might need better names for these -MACOSX_BUNDLE_NAME_BASE="Java SE" -MACOSX_BUNDLE_ID_BASE="com.oracle.java" diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index 88755606939..e8572e653e4 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -754,7 +754,6 @@ JAVAC_CHECK COOKED_BUILD_NUMBER USER_RELEASE_SUFFIX JDK_VERSION -RUNTIME_NAME COPYRIGHT_YEAR MACOSX_BUNDLE_ID_BASE MACOSX_BUNDLE_NAME_BASE @@ -783,7 +782,6 @@ OS_VERSION_MICRO OS_VERSION_MINOR OS_VERSION_MAJOR PKG_CONFIG -COMM TIME STAT HG @@ -899,7 +897,9 @@ DIRNAME DIFF DATE CUT +CPIO CP +COMM CMP CHMOD CAT @@ -2986,7 +2986,7 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Include these first... # -# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2013, 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 @@ -3401,7 +3401,7 @@ pkgadd_help() { # -# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2013, 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 @@ -3433,6 +3433,10 @@ pkgadd_help() { +############################################################################### +# +# Setup version numbers +# @@ -3682,7 +3686,7 @@ fi #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1357045896 +DATE_WHEN_GENERATED=1357120071 ############################################################################### # @@ -4009,6 +4013,65 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} + for ac_prog in comm +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_path_COMM+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $COMM in + [\\/]* | ?:[\\/]*) + ac_cv_path_COMM="$COMM" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_COMM="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +COMM=$ac_cv_path_COMM +if test -n "$COMM"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $COMM" >&5 +$as_echo "$COMM" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$COMM" && break +done + + + if test "x$COMM" = x; then + if test "xcomm" = x; then + PROG_NAME=comm + else + PROG_NAME=comm + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $PROG_NAME!" >&5 +$as_echo "$as_me: Could not find $PROG_NAME!" >&6;} + as_fn_error $? "Cannot continue" "$LINENO" 5 + fi + + + for ac_prog in cp do # Extract the first word of "$ac_prog", so it can be a program name with args. @@ -4068,6 +4131,65 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} + for ac_prog in cpio +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_path_CPIO+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $CPIO in + [\\/]* | ?:[\\/]*) + ac_cv_path_CPIO="$CPIO" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_CPIO="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +CPIO=$ac_cv_path_CPIO +if test -n "$CPIO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPIO" >&5 +$as_echo "$CPIO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CPIO" && break +done + + + if test "x$CPIO" = x; then + if test "xcpio" = x; then + PROG_NAME=cpio + else + PROG_NAME=cpio + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $PROG_NAME!" >&5 +$as_echo "$as_me: Could not find $PROG_NAME!" >&6;} + as_fn_error $? "Cannot continue" "$LINENO" 5 + fi + + + for ac_prog in cut do # Extract the first word of "$ac_prog", so it can be a program name with args. @@ -10607,11 +10729,9 @@ COMPRESS_JARS=false # Source the version numbers -. $AUTOCONF_DIR/version.numbers -if test "x$OPENJDK" = "xfalse"; then - . $AUTOCONF_DIR/closed.version.numbers -fi +. $AUTOCONF_DIR/version-numbers +# Get the settings from parameters # Check whether --with-milestone was given. if test "${with_milestone+set}" = set; then : @@ -10637,6 +10757,9 @@ if test "x$with_build_number" = xyes; then elif test "x$with_build_number" != x; then JDK_BUILD_NUMBER="$with_build_number" fi +if test "x$JDK_BUILD_NUMBER" = x; then + JDK_BUILD_NUMBER=b00 +fi # Now set the JDK version, milestone, build number etc. @@ -10656,9 +10779,6 @@ fi COPYRIGHT_YEAR=`date +'%Y'` -RUNTIME_NAME="$PRODUCT_NAME $PRODUCT_SUFFIX" - - if test "x$JDK_UPDATE_VERSION" != x; then JDK_VERSION="${JDK_MAJOR_VERSION}.${JDK_MINOR_VERSION}.${JDK_MICRO_VERSION}_${JDK_UPDATE_VERSION}" else diff --git a/common/autoconf/jdk-options.m4 b/common/autoconf/jdk-options.m4 index 95cb414baca..254058c8688 100644 --- a/common/autoconf/jdk-options.m4 +++ b/common/autoconf/jdk-options.m4 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2013, 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 @@ -369,14 +369,16 @@ COMPRESS_JARS=false AC_SUBST(COMPRESS_JARS) ]) +############################################################################### +# +# Setup version numbers +# AC_DEFUN_ONCE([JDKOPT_SETUP_JDK_VERSION_NUMBERS], [ # Source the version numbers -. $AUTOCONF_DIR/version.numbers -if test "x$OPENJDK" = "xfalse"; then - . $AUTOCONF_DIR/closed.version.numbers -fi +. $AUTOCONF_DIR/version-numbers +# Get the settings from parameters AC_ARG_WITH(milestone, [AS_HELP_STRING([--with-milestone], [Set milestone value for build @<:@internal@:>@])]) if test "x$with_milestone" = xyes; then @@ -394,6 +396,9 @@ if test "x$with_build_number" = xyes; then elif test "x$with_build_number" != x; then JDK_BUILD_NUMBER="$with_build_number" fi +if test "x$JDK_BUILD_NUMBER" = x; then + JDK_BUILD_NUMBER=b00 +fi # Now set the JDK version, milestone, build number etc. AC_SUBST(JDK_MAJOR_VERSION) @@ -413,9 +418,6 @@ AC_SUBST(MACOSX_BUNDLE_ID_BASE) COPYRIGHT_YEAR=`date +'%Y'` AC_SUBST(COPYRIGHT_YEAR) -RUNTIME_NAME="$PRODUCT_NAME $PRODUCT_SUFFIX" -AC_SUBST(RUNTIME_NAME) - if test "x$JDK_UPDATE_VERSION" != x; then JDK_VERSION="${JDK_MAJOR_VERSION}.${JDK_MINOR_VERSION}.${JDK_MICRO_VERSION}_${JDK_UPDATE_VERSION}" else diff --git a/common/autoconf/spec.gmk.in b/common/autoconf/spec.gmk.in index f16236fc26c..c11e6d2d9bc 100644 --- a/common/autoconf/spec.gmk.in +++ b/common/autoconf/spec.gmk.in @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2013, 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 @@ -163,8 +163,7 @@ MACOSX_BUNDLE_ID_BASE=@MACOSX_BUNDLE_ID_BASE@ # Different version strings generated from the above information. JDK_VERSION:=@JDK_VERSION@ -RUNTIME_NAME:=@RUNTIME_NAME@ -JRE_RELEASE_VERSION:=@FULL_VERSION@ +RUNTIME_NAME=$(PRODUCT_NAME) $(PRODUCT_SUFFIX) COOKED_BUILD_NUMBER:=@COOKED_BUILD_NUMBER@ # These variables need to be generated here so that MILESTONE and # JDK_BUILD_NUMBER can be overridden on the make command line. @@ -179,6 +178,7 @@ ifeq ($(JDK_BUILD_NUMBER),b00) else FULL_VERSION=$(RELEASE)-$(JDK_BUILD_NUMBER) endif +JRE_RELEASE_VERSION:=$(FULL_VERSION) # How to compile the code: release, fastdebug or slowdebug DEBUG_LEVEL:=@DEBUG_LEVEL@ @@ -451,10 +451,13 @@ CCACHE:=@CCACHE@ # CD is going away, but remains to cater for legacy makefiles. CD:=cd CHMOD:=@CHMOD@ +COMM:=@COMM@ CP:=@CP@ +CPIO:=@CPIO@ CUT:=@CUT@ DATE:=@DATE@ DIFF:=@DIFF@ +DIRNAME:=@DIRNAME@ FIND:=@FIND@ FIND_DELETE:=@FIND_DELETE@ ECHO:=@ECHO@ @@ -479,6 +482,7 @@ TEE:=@TEE@ TIME:=@TIME@ TR:=@TR@ TOUCH:=@TOUCH@ +UNIQ:=@UNIQ@ WC:=@WC@ XARGS:=@XARGS@ ZIPEXE:=@ZIP@ diff --git a/common/autoconf/version.numbers b/common/autoconf/version-numbers similarity index 95% rename from common/autoconf/version.numbers rename to common/autoconf/version-numbers index 7200e78a2f1..f567f314a8d 100644 --- a/common/autoconf/version.numbers +++ b/common/autoconf/version-numbers @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2013, 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 From 1d85687c300dbbfee3b811581d13c14d868909ca Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Wed, 2 Jan 2013 15:36:00 +0100 Subject: [PATCH 019/204] 8005355: build-infra: Java security signing (need a top-level make target) Reviewed-by: tbell, ohair --- common/autoconf/spec.gmk.in | 3 +++ common/makefiles/Main.gmk | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/common/autoconf/spec.gmk.in b/common/autoconf/spec.gmk.in index c11e6d2d9bc..ceb92149d43 100644 --- a/common/autoconf/spec.gmk.in +++ b/common/autoconf/spec.gmk.in @@ -231,6 +231,7 @@ JAXWS_OUTPUTDIR=$(BUILD_OUTPUT)/jaxws HOTSPOT_OUTPUTDIR=$(BUILD_OUTPUT)/hotspot JDK_OUTPUTDIR=$(BUILD_OUTPUT)/jdk IMAGES_OUTPUTDIR=$(BUILD_OUTPUT)/images +JCE_OUTPUTDIR=$(BUILD_OUTPUT)/jce-release LANGTOOLS_DIST=$(LANGTOOLS_OUTPUTDIR)/dist CORBA_DIST=$(CORBA_OUTPUTDIR)/dist @@ -431,6 +432,8 @@ RMIC=@FIXPATH@ $(BOOT_JDK)/bin/rmic NATIVE2ASCII=@FIXPATH@ $(BOOT_JDK)/bin/native2ascii +JARSIGNER=@FIXPATH@ $(BOOT_JDK)/bin/jarsigner + # Base flags for RC # Guarding this against resetting value. Legacy make files include spec multiple # times. diff --git a/common/makefiles/Main.gmk b/common/makefiles/Main.gmk index 1bbeecac463..801c986a754 100644 --- a/common/makefiles/Main.gmk +++ b/common/makefiles/Main.gmk @@ -142,6 +142,12 @@ docs-only: start-make @($(CD) $(SRC_ROOT)/common/makefiles/javadoc && $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) -f Javadoc.gmk docs) @$(call TargetExit) +sign-jars: jdk sign-jars-only +sign-jars-only: start-make + @$(call TargetEnter) + @($(CD) $(JDK_TOPDIR)/makefiles && $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) -f BuildJdk.gmk sign-jars) + @$(call TargetExit) + bootcycle-images: @$(ECHO) Boot cycle build step 1: Building the JDK image normally @($(CD) $(SRC_ROOT)/common/makefiles && $(BUILD_LOG_WRAPPER) $(MAKE) SPEC=$(SPEC) images) From 64499d94942de5403c26bd9b20b02bc9ede2b6db Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Wed, 2 Jan 2013 20:28:09 -0500 Subject: [PATCH 020/204] 8005494: SIGSEGV in Rewriter::relocate_and_link() when testing Weblogic with CompressedOops and KlassPtrs Relocate functions with jsr's when rewriting so not repeated after reading shared archive Reviewed-by: twisti, jrose --- hotspot/src/share/vm/interpreter/rewriter.cpp | 59 ++++--------------- hotspot/src/share/vm/interpreter/rewriter.hpp | 8 --- hotspot/src/share/vm/oops/instanceKlass.cpp | 32 ++++++++-- hotspot/src/share/vm/oops/instanceKlass.hpp | 2 +- .../share/vm/prims/jvmtiRedefineClasses.cpp | 2 +- .../src/share/vm/runtime/handles.inline.hpp | 4 ++ 6 files changed, 46 insertions(+), 61 deletions(-) diff --git a/hotspot/src/share/vm/interpreter/rewriter.cpp b/hotspot/src/share/vm/interpreter/rewriter.cpp index b699d4494a4..d906eb0e0ce 100644 --- a/hotspot/src/share/vm/interpreter/rewriter.cpp +++ b/hotspot/src/share/vm/interpreter/rewriter.cpp @@ -27,13 +27,8 @@ #include "interpreter/interpreter.hpp" #include "interpreter/rewriter.hpp" #include "memory/gcLocker.hpp" -#include "memory/metadataFactory.hpp" -#include "memory/oopFactory.hpp" #include "memory/resourceArea.hpp" #include "oops/generateOopMap.hpp" -#include "oops/objArrayOop.hpp" -#include "oops/oop.inline.hpp" -#include "prims/methodComparator.hpp" #include "prims/methodHandles.hpp" // Computes a CPC map (new_index -> original_index) for constant pool entries @@ -402,13 +397,6 @@ void Rewriter::rewrite(instanceKlassHandle klass, TRAPS) { } -void Rewriter::rewrite(instanceKlassHandle klass, constantPoolHandle cpool, Array* methods, TRAPS) { - ResourceMark rm(THREAD); - Rewriter rw(klass, cpool, methods, CHECK); - // (That's all, folks.) -} - - Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Array* methods, TRAPS) : _klass(klass), _pool(cpool), @@ -453,46 +441,25 @@ Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Arraymethods(), THREAD); -} - -void Rewriter::relocate_and_link(instanceKlassHandle this_oop, - Array* methods, TRAPS) { - int len = methods->length(); + // Relocate after everything, but still do this under the is_rewritten flag, + // so methods with jsrs in custom class lists in aren't attempted to be + // rewritten in the RO section of the shared archive. + // Relocated bytecodes don't have to be restored, only the cp cache entries for (int i = len-1; i >= 0; i--) { - methodHandle m(THREAD, methods->at(i)); + methodHandle m(THREAD, _methods->at(i)); if (m->has_jsrs()) { - m = rewrite_jsrs(m, CHECK); + m = rewrite_jsrs(m, THREAD); + // Restore bytecodes to their unrewritten state if there are exceptions + // relocating bytecodes. If some are relocated, that is ok because that + // doesn't affect constant pool to cpCache rewriting. + if (HAS_PENDING_EXCEPTION) { + restore_bytecodes(); + return; + } // Method might have gotten rewritten. methods->at_put(i, m()); } - - // Set up method entry points for compiler and interpreter . - m->link_method(m, CHECK); - - // This is for JVMTI and unrelated to relocator but the last thing we do -#ifdef ASSERT - if (StressMethodComparator) { - static int nmc = 0; - for (int j = i; j >= 0 && j >= i-4; j--) { - if ((++nmc % 1000) == 0) tty->print_cr("Have run MethodComparator %d times...", nmc); - bool z = MethodComparator::methods_EMCP(m(), - methods->at(j)); - if (j == i && !z) { - tty->print("MethodComparator FAIL: "); m->print(); m->print_codes(); - assert(z, "method must compare equal to itself"); - } - } - } -#endif //ASSERT } } diff --git a/hotspot/src/share/vm/interpreter/rewriter.hpp b/hotspot/src/share/vm/interpreter/rewriter.hpp index 78d09a92e23..56067983c84 100644 --- a/hotspot/src/share/vm/interpreter/rewriter.hpp +++ b/hotspot/src/share/vm/interpreter/rewriter.hpp @@ -158,14 +158,6 @@ class Rewriter: public StackObj { public: // Driver routine: static void rewrite(instanceKlassHandle klass, TRAPS); - static void rewrite(instanceKlassHandle klass, constantPoolHandle cpool, Array* methods, TRAPS); - - // Second pass, not gated by is_rewritten flag - static void relocate_and_link(instanceKlassHandle klass, TRAPS); - // JSR292 version to call with it's own methods. - static void relocate_and_link(instanceKlassHandle klass, - Array* methods, TRAPS); - }; #endif // SHARE_VM_INTERPRETER_REWRITER_HPP diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index ce30929f522..de2325d54cf 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -47,6 +47,7 @@ #include "oops/symbol.hpp" #include "prims/jvmtiExport.hpp" #include "prims/jvmtiRedefineClassesTrace.hpp" +#include "prims/methodComparator.hpp" #include "runtime/fieldDescriptor.hpp" #include "runtime/handles.inline.hpp" #include "runtime/javaCalls.hpp" @@ -602,7 +603,7 @@ bool InstanceKlass::link_class_impl( } // relocate jsrs and link methods after they are all rewritten - this_oop->relocate_and_link_methods(CHECK_false); + this_oop->link_methods(CHECK_false); // Initialize the vtable and interface table after // methods have been rewritten since rewrite may @@ -650,10 +651,31 @@ void InstanceKlass::rewrite_class(TRAPS) { // Now relocate and link method entry points after class is rewritten. // This is outside is_rewritten flag. In case of an exception, it can be // executed more than once. -void InstanceKlass::relocate_and_link_methods(TRAPS) { - assert(is_loaded(), "must be loaded"); - instanceKlassHandle this_oop(THREAD, this); - Rewriter::relocate_and_link(this_oop, CHECK); +void InstanceKlass::link_methods(TRAPS) { + int len = methods()->length(); + for (int i = len-1; i >= 0; i--) { + methodHandle m(THREAD, methods()->at(i)); + + // Set up method entry points for compiler and interpreter . + m->link_method(m, CHECK); + + // This is for JVMTI and unrelated to relocator but the last thing we do +#ifdef ASSERT + if (StressMethodComparator) { + ResourceMark rm(THREAD); + static int nmc = 0; + for (int j = i; j >= 0 && j >= i-4; j--) { + if ((++nmc % 1000) == 0) tty->print_cr("Have run MethodComparator %d times...", nmc); + bool z = MethodComparator::methods_EMCP(m(), + methods()->at(j)); + if (j == i && !z) { + tty->print("MethodComparator FAIL: "); m->print(); m->print_codes(); + assert(z, "method must compare equal to itself"); + } + } + } +#endif //ASSERT + } } diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp index 426486dd965..32938dcfbe3 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.hpp +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp @@ -454,7 +454,7 @@ class InstanceKlass: public Klass { bool link_class_or_fail(TRAPS); // returns false on failure void unlink_class(); void rewrite_class(TRAPS); - void relocate_and_link_methods(TRAPS); + void link_methods(TRAPS); Method* class_initializer(); // set the class to initialized if no static initializer is present diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp index 6fb7243a872..a9d3d5f1e39 100644 --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp @@ -1043,7 +1043,7 @@ jvmtiError VM_RedefineClasses::load_new_class_versions(TRAPS) { Rewriter::rewrite(scratch_class, THREAD); if (!HAS_PENDING_EXCEPTION) { - Rewriter::relocate_and_link(scratch_class, THREAD); + scratch_class->link_methods(THREAD); } if (HAS_PENDING_EXCEPTION) { Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); diff --git a/hotspot/src/share/vm/runtime/handles.inline.hpp b/hotspot/src/share/vm/runtime/handles.inline.hpp index 6565b979338..9530b127aea 100644 --- a/hotspot/src/share/vm/runtime/handles.inline.hpp +++ b/hotspot/src/share/vm/runtime/handles.inline.hpp @@ -80,6 +80,8 @@ inline name##Handle::name##Handle(const name##Handle &h) { \ _thread = Thread::current(); \ } \ _thread->metadata_handles()->push((Metadata*)_value); \ + } else { \ + _thread = NULL; \ } \ } \ inline name##Handle& name##Handle::operator=(const name##Handle &s) { \ @@ -94,6 +96,8 @@ inline name##Handle& name##Handle::operator=(const name##Handle &s) { \ _thread = Thread::current(); \ } \ _thread->metadata_handles()->push((Metadata*)_value); \ + } else { \ + _thread = NULL; \ } \ return *this; \ } \ From f2fab621730d34e2ac8fee797de8490efbf5346c Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Thu, 3 Jan 2013 20:54:38 +0100 Subject: [PATCH 021/204] 8005635: build-infra: Support building install in jprt Co-authored-by: Tim Bell Reviewed-by: ohair --- common/autoconf/generated-configure.sh | 2 +- common/autoconf/spec.gmk.in | 16 ++++++++++ common/bin/compare.sh | 41 +++++++++++++++++++------- common/bin/compare_exceptions.sh.incl | 1 + common/makefiles/Jprt.gmk | 9 ++++++ common/src/fixpath.c | 34 +++++++++++++++++---- 6 files changed, 85 insertions(+), 18 deletions(-) diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index e8572e653e4..909206ab8c0 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -3686,7 +3686,7 @@ fi #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1357120071 +DATE_WHEN_GENERATED=1357219413 ############################################################################### # diff --git a/common/autoconf/spec.gmk.in b/common/autoconf/spec.gmk.in index ceb92149d43..5fde9e7cf16 100644 --- a/common/autoconf/spec.gmk.in +++ b/common/autoconf/spec.gmk.in @@ -618,5 +618,21 @@ OS_VERSION_MAJOR:=@OS_VERSION_MAJOR@ OS_VERSION_MINOR:=@OS_VERSION_MINOR@ OS_VERSION_MICRO:=@OS_VERSION_MICRO@ +# Images directory definitions +JDK_IMAGE_SUBDIR:=j2sdk-image +JRE_IMAGE_SUBDIR:=j2re-image +JDK_OVERLAY_IMAGE_SUBDIR:=j2sdk-overlay-image +JRE_OVERLAY_IMAGE_SUBDIR:=j2re-overlay-image +JDK_IMAGE_DIR:=$(IMAGES_OUTPUTDIR)/$(JDK_IMAGE_SUBDIR) +JRE_IMAGE_DIR:=$(IMAGES_OUTPUTDIR)/$(JRE_IMAGE_SUBDIR) +JDK_OVERLAY_IMAGE_DIR:=$(IMAGES_OUTPUTDIR)/$(JDK_OVERLAY_IMAGE_SUBDIR) +JRE_OVERLAY_IMAGE_DIR:=$(IMAGES_OUTPUTDIR)/$(JRE_OVERLAY_IMAGE_SUBDIR) + +# Macosx bundles directory definitions +JDK_BUNDLE_SUBDIR:=j2sdk-bundle/jdk$(JDK_VERSION).jdk/Contents +JRE_BUNDLE_SUBDIR:=j2re-bundle/jre$(JDK_VERSION).jre/Contents +JDK_BUNDLE_DIR:=$(IMAGES_OUTPUTDIR)/$(JDK_BUNDLE_SUBDIR) +JRE_BUNDLE_DIR:=$(IMAGES_OUTPUTDIR)/$(JRE_BUNDLE_SUBDIR) + # Include the custom-spec.gmk file if it exists -include $(dir @SPEC@)/custom-spec.gmk diff --git a/common/bin/compare.sh b/common/bin/compare.sh index afe9ef7cee6..8240c4c423e 100644 --- a/common/bin/compare.sh +++ b/common/bin/compare.sh @@ -98,12 +98,15 @@ diff_text() { if test "x$SUFFIX" = "xclass"; then # To improve performance when large diffs are found, do a rough filtering of classes # elibeble for these exceptions - if $GREP -R -e '[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}' -e thePoint -e aPoint -e setItemsPtr ${THIS_FILE} > /dev/null; then + if $GREP -R -e '[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}' \ + -e '[0-9]\{2\}/[0-9]\{2\}/[0-9]\{4\}' \ + -e thePoint -e aPoint -e setItemsPtr ${THIS_FILE} > /dev/null; then $JAVAP -c -constants -l -p ${OTHER_FILE} > ${OTHER_FILE}.javap $JAVAP -c -constants -l -p ${THIS_FILE} > ${THIS_FILE}.javap TMP=$($DIFF ${OTHER_FILE}.javap ${THIS_FILE}.javap | \ $GREP '^[<>]' | \ $SED -e '/[<>].*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d' \ + -e '/[0-9]\{2\}\/[0-9]\{2\}\/[0-9]\{4\}/d' \ -e '/[<>].*Point Lcom\/apple\/jobjc\/foundation\/NSPoint;/d' \ -e '/[<>].*public com\.apple\.jobjc\.Pointer].*public void setItemsPtr(com\.apple\.jobjc\.Pointer\)/\1(removed)\2/' \ - -e 's/\(Monday\|Tuesday\|Wednesday\|Thursday\|Friday\|Saturday\|Sunday\), [A-Z][a-z]* [0-9][0-9]*, [12][0-9]* [0-9][0-9:]* \(AM\|PM\) [A-Z][A-Z]*/(removed)/' \ + -e 's/[A-Z][a-z]*, [A-Z][a-z]* [0-9][0-9]*, [12][0-9]* [0-9][0-9:]* [AMP]\{2,2\} [A-Z][A-Z]*/(removed)/' \ + -e 's/[A-Z][a-z]* [A-Z][a-z]* [0-9][0-9] [0-9][0-9:]* [A-Z][A-Z]* [12][0-9]*/(removed)/' \ -e 's/^\( from \).*\(\.idl\)$/\1(removed)\2/' \ > $OTHER_FILE $CAT $THIS_DIR/$f | $SED -e 's/\(-- Generated by javadoc \).*\( --\)/\1(removed)\2/' \ -e 's/\(\)/\1(removed)\2/' \ - -e 's/\(Monday\|Tuesday\|Wednesday\|Thursday\|Friday\|Saturday\|Sunday\), [A-Z][a-z]* [0-9][0-9]*, [12][0-9]* [0-9][0-9:]* \(AM\|PM\) [A-Z][A-Z]*/(removed)/' \ + -e 's/[A-Z][a-z]*, [A-Z][a-z]* [0-9][0-9]*, [12][0-9]* [0-9][0-9:]* [AMP]\{2,2\} [A-Z][A-Z]*/(removed)/' \ + -e 's/[A-Z][a-z]* [A-Z][a-z]* [0-9][0-9] [0-9][0-9:]* [A-Z][A-Z]* [12][0-9]*/(removed)/' \ -e 's/^\( from \).*\(\.idl\)$/\1(removed)\2/' \ > $THIS_FILE else @@ -370,14 +376,14 @@ compare_zip_file() { (cd $OTHER_UNZIPDIR && $UNARCHIVE $OTHER_ZIP) # Find all archives inside and unzip them as well to compare the contents rather than - # the archives. - EXCEPTIONS="" - for pack in $($FIND $THIS_UNZIPDIR -name "*.pack" -o -name "*.pack.gz"); do + # the archives. pie.jar.pack.gz i app3.war is corrupt, skip it. + EXCEPTIONS="pie.jar.pack.gz" + for pack in $($FIND $THIS_UNZIPDIR \( -name "*.pack" -o -name "*.pack.gz" \) -a ! -name pie.jar.pack.gz); do ($UNPACK200 $pack $pack.jar) # Filter out the unzipped archives from the diff below. EXCEPTIONS="$EXCEPTIONS $pack $pack.jar" done - for pack in $($FIND $OTHER_UNZIPDIR -name "*.pack" -o -name "*.pack.gz"); do + for pack in $($FIND $OTHER_UNZIPDIR \( -name "*.pack" -o -name "*.pack.gz" \) -a ! -name pie.jar.pack.gz); do ($UNPACK200 $pack $pack.jar) EXCEPTIONS="$EXCEPTIONS $pack $pack.jar" done @@ -1073,7 +1079,11 @@ fi # Figure out the layout of the this build. Which kinds of images have been produced -if [ -d "$THIS/deploy/j2sdk-image" ]; then +if [ -d "$THIS/install/j2sdk-image" ]; then + THIS_J2SDK="$THIS/install/j2sdk-image" + THIS_J2RE="$THIS/install/j2re-image" + echo "Comparing install images" +elif [ -d "$THIS/deploy/j2sdk-image" ]; then THIS_J2SDK="$THIS/deploy/j2sdk-image" THIS_J2RE="$THIS/deploy/j2re-image" echo "Comparing deploy images" @@ -1081,9 +1091,16 @@ elif [ -d "$THIS/images/j2sdk-image" ]; then THIS_J2SDK="$THIS/images/j2sdk-image" THIS_J2RE="$THIS/images/j2re-image" fi + if [ -d "$THIS/images/j2sdk-overlay-image" ]; then - THIS_J2SDK_OVERLAY="$THIS/images/j2sdk-overlay-image" - THIS_J2RE_OVERLAY="$THIS/images/j2re-overlay-image" + if [ -d "$THIS/install/j2sdk-image" ]; then + # If there is an install image, prefer that, it's also overlay + THIS_J2SDK_OVERLAY="$THIS/install/j2sdk-image" + THIS_J2RE_OVERLAY="$THIS/install/j2re-image" + else + THIS_J2SDK_OVERLAY="$THIS/images/j2sdk-overlay-image" + THIS_J2RE_OVERLAY="$THIS/images/j2re-overlay-image" + fi fi if [ -d "$THIS/images/j2sdk-bundle" ]; then @@ -1100,7 +1117,9 @@ if [ -d "$OTHER/j2sdk-image" ]; then OTHER_J2SDK_OVERLAY="$OTHER/j2sdk-image" OTHER_J2RE_OVERLAY="$OTHER/j2re-image" fi - +elif [ -d "$OTHER/images/j2sdk-image" ]; then + OTHER_J2SDK="$OTHER/images/j2sdk-image" + OTHER_J2RE="$OTHER/images/j2re-image" fi if [ -d "$OTHER/j2sdk-bundle" ]; then diff --git a/common/bin/compare_exceptions.sh.incl b/common/bin/compare_exceptions.sh.incl index 0127e9a4eb3..0446dbc150a 100644 --- a/common/bin/compare_exceptions.sh.incl +++ b/common/bin/compare_exceptions.sh.incl @@ -815,6 +815,7 @@ ACCEPTED_SMALL_SIZE_DIFF=" ./jre/bin/attach.dll ./jre/bin/java_crw_demo.dll ./jre/bin/jsoundds.dll +./jre/bin/server/jvm.dll ./bin/appletviewer.exe ./bin/extcheck.exe ./bin/idlj.exe diff --git a/common/makefiles/Jprt.gmk b/common/makefiles/Jprt.gmk index a648bf9191c..91ba6e1a875 100644 --- a/common/makefiles/Jprt.gmk +++ b/common/makefiles/Jprt.gmk @@ -97,6 +97,15 @@ endif ifdef ANT_HOME @$(ECHO) " --with-ant-home=$(call UnixPath,$(ANT_HOME)) " >> $@.tmp endif +ifdef ALT_JAVAFX_ZIP_DIR + @$(ECHO) " --with-javafx-zip-dir=$(call UnixPath,$(ALT_JAVAFX_ZIP_DIR)) " >> $@.tmp +endif +ifdef ALT_WIXDIR + @$(ECHO) " --with-wix=$(call UnixPath,$(ALT_WIXDIR)) " >> $@.tmp +endif +ifdef ALT_CCSS_SIGNING_DIR + @$(ECHO) " --with-ccss-signing=$(call UnixPath,$(ALT_CCSS_SIGNING_DIR)) " >> $@.tmp +endif ifdef ALT_SLASH_JAVA @$(ECHO) " --with-java-devtools=$(call UnixPath,$(ALT_SLASH_JAVA)/devtools) " >> $@.tmp endif diff --git a/common/src/fixpath.c b/common/src/fixpath.c index 835f6b7da6a..a85bf4cc68e 100644 --- a/common/src/fixpath.c +++ b/common/src/fixpath.c @@ -29,6 +29,29 @@ #include #include +void report_error() +{ + LPVOID lpMsgBuf; + DWORD dw = GetLastError(); + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + dw, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &lpMsgBuf, + 0, + NULL); + + fprintf(stderr, + "Could not start process! Failed with error %d: %s\n", + dw, lpMsgBuf); + + LocalFree(lpMsgBuf); +} + /* * Test if pos points to /cygdrive/_/ where _ can * be any character. @@ -256,7 +279,7 @@ int main(int argc, char **argv) DWORD exitCode; if (argc<3 || argv[1][0] != '-' || (argv[1][1] != 'c' && argv[1][1] != 'm')) { - fprintf(stderr, "Usage: fixpath -c|m /cygdrive/c/WINDOWS/notepad.exe /cygdrive/c/x/test.txt"); + fprintf(stderr, "Usage: fixpath -c|m /cygdrive/c/WINDOWS/notepad.exe /cygdrive/c/x/test.txt\n"); exit(0); } @@ -308,11 +331,10 @@ int main(int argc, char **argv) 0, &si, &pi); - if(!rc) - { - //Could not start process; - fprintf(stderr, "Could not start process!\n"); - exit(-1); + if(!rc) { + // Could not start process for some reason. Try to report why: + report_error(); + exit(rc); } WaitForSingleObject(pi.hProcess,INFINITE); From 782ef982f6590f2ea6d0765c06e6bb31eb648618 Mon Sep 17 00:00:00 2001 From: Bill Pittore Date: Thu, 3 Jan 2013 15:08:43 -0500 Subject: [PATCH 022/204] 8004051: assert(_oprs_len[mode] < maxNumberOfOperands) failed: array overflow Assert is triggered when number of register based arguments passed to a java method exceeds 16. Reviewed-by: roland, vladidan --- hotspot/src/share/vm/c1/c1_LIR.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/c1/c1_LIR.hpp b/hotspot/src/share/vm/c1/c1_LIR.hpp index 122ebe8ce1b..cec92f78c27 100644 --- a/hotspot/src/share/vm/c1/c1_LIR.hpp +++ b/hotspot/src/share/vm/c1/c1_LIR.hpp @@ -2259,7 +2259,7 @@ class LIR_OpVisitState: public StackObj { typedef enum { inputMode, firstMode = inputMode, tempMode, outputMode, numModes, invalidMode = -1 } OprMode; enum { - maxNumberOfOperands = 16, + maxNumberOfOperands = 20, maxNumberOfInfos = 4 }; From cfcd28fd9d92a45baf4efa342e71a478ea0cb2dc Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Thu, 3 Jan 2013 15:09:55 -0800 Subject: [PATCH 023/204] 8005522: use fast-string instructions on x86 for zeroing Use 'rep stosb' instead of 'rep stosq' when fast-string operations are available. Reviewed-by: twisti, roland --- hotspot/src/cpu/x86/vm/assembler_x86.cpp | 14 ++++++++--- hotspot/src/cpu/x86/vm/assembler_x86.hpp | 3 ++- hotspot/src/cpu/x86/vm/globals_x86.hpp | 3 +++ hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp | 16 ++++++++++++ hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp | 3 +++ hotspot/src/cpu/x86/vm/vm_version_x86.cpp | 13 +++++++++- hotspot/src/cpu/x86/vm/vm_version_x86.hpp | 11 +++++--- hotspot/src/cpu/x86/vm/x86_32.ad | 25 ++++++++++++++----- hotspot/src/cpu/x86/vm/x86_64.ad | 25 ++++++++++++++++--- hotspot/src/share/vm/opto/memnode.cpp | 4 +-- 10 files changed, 95 insertions(+), 22 deletions(-) diff --git a/hotspot/src/cpu/x86/vm/assembler_x86.cpp b/hotspot/src/cpu/x86/vm/assembler_x86.cpp index 6f97f963084..9fb3645823f 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp @@ -2544,12 +2544,18 @@ void Assembler::rep_mov() { emit_int8((unsigned char)0xA5); } +// sets rcx bytes with rax, value at [edi] +void Assembler::rep_stosb() { + emit_int8((unsigned char)0xF3); // REP + LP64_ONLY(prefix(REX_W)); + emit_int8((unsigned char)0xAA); // STOSB +} + // sets rcx pointer sized words with rax, value at [edi] // generic -void Assembler::rep_set() { // rep_set - emit_int8((unsigned char)0xF3); - // STOSQ - LP64_ONLY(prefix(REX_W)); +void Assembler::rep_stos() { + emit_int8((unsigned char)0xF3); // REP + LP64_ONLY(prefix(REX_W)); // LP64:STOSQ, LP32:STOSD emit_int8((unsigned char)0xAB); } diff --git a/hotspot/src/cpu/x86/vm/assembler_x86.hpp b/hotspot/src/cpu/x86/vm/assembler_x86.hpp index a48aeda8dd3..3d89bfeae94 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp @@ -832,7 +832,8 @@ private: // These do register sized moves/scans void rep_mov(); - void rep_set(); + void rep_stos(); + void rep_stosb(); void repne_scan(); #ifdef _LP64 void repne_scanl(); diff --git a/hotspot/src/cpu/x86/vm/globals_x86.hpp b/hotspot/src/cpu/x86/vm/globals_x86.hpp index 8d1cdfa71b8..fb44e2db52f 100644 --- a/hotspot/src/cpu/x86/vm/globals_x86.hpp +++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp @@ -120,6 +120,9 @@ define_pd_global(intx, CMSYoungGenPerWorker, 64*M); // default max size of CMS product(bool, UseUnalignedLoadStores, false, \ "Use SSE2 MOVDQU instruction for Arraycopy") \ \ + product(bool, UseFastStosb, false, \ + "Use fast-string operation for zeroing: rep stosb") \ + \ /* assembler */ \ product(bool, Use486InstrsOnly, false, \ "Use 80486 Compliant instruction subset") \ diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp index b9d85636cf8..d2549472cd6 100644 --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp @@ -5224,6 +5224,22 @@ void MacroAssembler::verified_entry(int framesize, bool stack_bang, bool fp_mode } +void MacroAssembler::clear_mem(Register base, Register cnt, Register tmp) { + // cnt - number of qwords (8-byte words). + // base - start address, qword aligned. + assert(base==rdi, "base register must be edi for rep stos"); + assert(tmp==rax, "tmp register must be eax for rep stos"); + assert(cnt==rcx, "cnt register must be ecx for rep stos"); + + xorptr(tmp, tmp); + if (UseFastStosb) { + shlptr(cnt,3); // convert to number of bytes + rep_stosb(); + } else { + NOT_LP64(shlptr(cnt,1);) // convert to number of dwords for 32-bit VM + rep_stos(); + } +} // IndexOf for constant substrings with size >= 8 chars // which don't need to be loaded through stack. diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp index 10eab0c8a4f..b77e4e9e200 100644 --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp @@ -1096,6 +1096,9 @@ public: // C2 compiled method's prolog code. void verified_entry(int framesize, bool stack_bang, bool fp_mode_24b); + // clear memory of size 'cnt' qwords, starting at 'base'. + void clear_mem(Register base, Register cnt, Register rtmp); + // IndexOf strings. // Small strings are loaded through stack if they cross page boundary. void string_indexof(Register str1, Register str2, diff --git a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp index fc046676739..75db2903b3e 100644 --- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp +++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp @@ -429,7 +429,7 @@ void VM_Version::get_processor_features() { } char buf[256]; - jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", cores_per_cpu(), threads_per_core(), cpu_family(), _model, _stepping, (supports_cmov() ? ", cmov" : ""), @@ -446,6 +446,7 @@ void VM_Version::get_processor_features() { (supports_avx() ? ", avx" : ""), (supports_avx2() ? ", avx2" : ""), (supports_aes() ? ", aes" : ""), + (supports_erms() ? ", erms" : ""), (supports_mmx_ext() ? ", mmxext" : ""), (supports_3dnow_prefetch() ? ", 3dnowpref" : ""), (supports_lzcnt() ? ", lzcnt": ""), @@ -671,6 +672,16 @@ void VM_Version::get_processor_features() { FLAG_SET_DEFAULT(UsePopCountInstruction, false); } + // Use fast-string operations if available. + if (supports_erms()) { + if (FLAG_IS_DEFAULT(UseFastStosb)) { + UseFastStosb = true; + } + } else if (UseFastStosb) { + warning("fast-string operations are not available on this CPU"); + FLAG_SET_DEFAULT(UseFastStosb, false); + } + #ifdef COMPILER2 if (FLAG_IS_DEFAULT(AlignVector)) { // Modern processors allow misaligned memory operations for vectors. diff --git a/hotspot/src/cpu/x86/vm/vm_version_x86.hpp b/hotspot/src/cpu/x86/vm/vm_version_x86.hpp index 12bd3b770d5..ec8caba23f0 100644 --- a/hotspot/src/cpu/x86/vm/vm_version_x86.hpp +++ b/hotspot/src/cpu/x86/vm/vm_version_x86.hpp @@ -204,7 +204,8 @@ public: avx2 : 1, : 2, bmi2 : 1, - : 23; + erms : 1, + : 22; } bits; }; @@ -247,7 +248,8 @@ protected: CPU_TSCINV = (1 << 16), CPU_AVX = (1 << 17), CPU_AVX2 = (1 << 18), - CPU_AES = (1 << 19) + CPU_AES = (1 << 19), + CPU_ERMS = (1 << 20) // enhanced 'rep movsb/stosb' instructions } cpuFeatureFlags; enum { @@ -425,6 +427,8 @@ protected: result |= CPU_TSCINV; if (_cpuid_info.std_cpuid1_ecx.bits.aes != 0) result |= CPU_AES; + if (_cpuid_info.sef_cpuid7_ebx.bits.erms != 0) + result |= CPU_ERMS; // AMD features. if (is_amd()) { @@ -489,7 +493,7 @@ public: return (_cpuid_info.std_max_function >= 0xB) && // eax[4:0] | ebx[0:15] == 0 indicates invalid topology level. // Some cpus have max cpuid >= 0xB but do not support processor topology. - ((_cpuid_info.tpl_cpuidB0_eax & 0x1f | _cpuid_info.tpl_cpuidB0_ebx.bits.logical_cpus) != 0); + (((_cpuid_info.tpl_cpuidB0_eax & 0x1f) | _cpuid_info.tpl_cpuidB0_ebx.bits.logical_cpus) != 0); } static uint cores_per_cpu() { @@ -550,6 +554,7 @@ public: static bool supports_avx2() { return (_cpuFeatures & CPU_AVX2) != 0; } static bool supports_tsc() { return (_cpuFeatures & CPU_TSC) != 0; } static bool supports_aes() { return (_cpuFeatures & CPU_AES) != 0; } + static bool supports_erms() { return (_cpuFeatures & CPU_ERMS) != 0; } // Intel features static bool is_intel_family_core() { return is_intel() && diff --git a/hotspot/src/cpu/x86/vm/x86_32.ad b/hotspot/src/cpu/x86/vm/x86_32.ad index dafac776c56..462060de119 100644 --- a/hotspot/src/cpu/x86/vm/x86_32.ad +++ b/hotspot/src/cpu/x86/vm/x86_32.ad @@ -11572,15 +11572,28 @@ instruct MoveL2D_reg_reg_sse(regD dst, eRegL src, regD tmp) %{ // ======================================================================= // fast clearing of an array instruct rep_stos(eCXRegI cnt, eDIRegP base, eAXRegI zero, Universe dummy, eFlagsReg cr) %{ + predicate(!UseFastStosb); match(Set dummy (ClearArray cnt base)); effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); - format %{ "SHL ECX,1\t# Convert doublewords to words\n\t" - "XOR EAX,EAX\n\t" + format %{ "XOR EAX,EAX\t# ClearArray:\n\t" + "SHL ECX,1\t# Convert doublewords to words\n\t" "REP STOS\t# store EAX into [EDI++] while ECX--" %} - opcode(0,0x4); - ins_encode( Opcode(0xD1), RegOpc(ECX), - OpcRegReg(0x33,EAX,EAX), - Opcode(0xF3), Opcode(0xAB) ); + ins_encode %{ + __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); + %} + ins_pipe( pipe_slow ); +%} + +instruct rep_fast_stosb(eCXRegI cnt, eDIRegP base, eAXRegI zero, Universe dummy, eFlagsReg cr) %{ + predicate(UseFastStosb); + match(Set dummy (ClearArray cnt base)); + effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); + format %{ "XOR EAX,EAX\t# ClearArray:\n\t" + "SHL ECX,3\t# Convert doublewords to bytes\n\t" + "REP STOSB\t# store EAX into [EDI++] while ECX--" %} + ins_encode %{ + __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); + %} ins_pipe( pipe_slow ); %} diff --git a/hotspot/src/cpu/x86/vm/x86_64.ad b/hotspot/src/cpu/x86/vm/x86_64.ad index 5b05ec22293..b526a6ce27b 100644 --- a/hotspot/src/cpu/x86/vm/x86_64.ad +++ b/hotspot/src/cpu/x86/vm/x86_64.ad @@ -10374,16 +10374,33 @@ instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, rFlagsReg cr) %{ + predicate(!UseFastStosb); match(Set dummy (ClearArray cnt base)); effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); - format %{ "xorl rax, rax\t# ClearArray:\n\t" - "rep stosq\t# Store rax to *rdi++ while rcx--" %} - ins_encode(opc_reg_reg(0x33, RAX, RAX), // xorl %eax, %eax - Opcode(0xF3), Opcode(0x48), Opcode(0xAB)); // rep REX_W stos + format %{ "xorq rax, rax\t# ClearArray:\n\t" + "rep stosq\t# Store rax to *rdi++ while rcx--" %} + ins_encode %{ + __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); + %} ins_pipe(pipe_slow); %} +instruct rep_fast_stosb(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, + rFlagsReg cr) +%{ + predicate(UseFastStosb); + match(Set dummy (ClearArray cnt base)); + effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); + format %{ "xorq rax, rax\t# ClearArray:\n\t" + "shlq rcx,3\t# Convert doublewords to bytes\n\t" + "rep stosb\t# Store rax to *rdi++ while rcx--" %} + ins_encode %{ + __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); + %} + ins_pipe( pipe_slow ); +%} + instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, rax_RegI result, regD tmp1, rFlagsReg cr) %{ diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp index b83e6253b03..bea81f210da 100644 --- a/hotspot/src/share/vm/opto/memnode.cpp +++ b/hotspot/src/share/vm/opto/memnode.cpp @@ -2725,10 +2725,8 @@ Node* ClearArrayNode::clear_memory(Node* ctl, Node* mem, Node* dest, zend = phase->transform( new(C) URShiftXNode(zend, shift) ); } - Node* zsize = phase->transform( new(C) SubXNode(zend, zbase) ); - Node* zinit = phase->zerocon((unit == BytesPerLong) ? T_LONG : T_INT); - // Bulk clear double-words + Node* zsize = phase->transform( new(C) SubXNode(zend, zbase) ); Node* adr = phase->transform( new(C) AddPNode(dest, dest, start_offset) ); mem = new (C) ClearArrayNode(ctl, mem, zsize, adr); return phase->transform(mem); From 7b9133b99c06e28024e2c7cefb5a9ab20ce7cd62 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Thu, 3 Jan 2013 16:30:47 -0800 Subject: [PATCH 024/204] 8005544: Use 256bit YMM registers in arraycopy stubs on x86 Use YMM registers in arraycopy and array_fill stubs. Reviewed-by: roland, twisti --- hotspot/src/cpu/x86/vm/assembler_x86.cpp | 9 + hotspot/src/cpu/x86/vm/assembler_x86.hpp | 3 + hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp | 58 ++++-- .../src/cpu/x86/vm/stubGenerator_x86_32.cpp | 26 ++- .../src/cpu/x86/vm/stubGenerator_x86_64.cpp | 186 ++++++++++++------ 5 files changed, 194 insertions(+), 88 deletions(-) diff --git a/hotspot/src/cpu/x86/vm/assembler_x86.cpp b/hotspot/src/cpu/x86/vm/assembler_x86.cpp index 9fb3645823f..0104292695d 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp @@ -3656,6 +3656,15 @@ void Assembler::vextracti128h(Address dst, XMMRegister src) { emit_int8(0x01); } +// duplicate 4-bytes integer data from src into 8 locations in dest +void Assembler::vpbroadcastd(XMMRegister dst, XMMRegister src) { + assert(VM_Version::supports_avx2(), ""); + bool vector256 = true; + int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, vector256, VEX_OPCODE_0F_38); + emit_int8(0x58); + emit_int8((unsigned char)(0xC0 | encode)); +} + void Assembler::vzeroupper() { assert(VM_Version::supports_avx(), ""); (void)vex_prefix_and_encode(xmm0, xmm0, xmm0, VEX_SIMD_NONE); diff --git a/hotspot/src/cpu/x86/vm/assembler_x86.hpp b/hotspot/src/cpu/x86/vm/assembler_x86.hpp index 3d89bfeae94..569674c2a90 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp @@ -1754,6 +1754,9 @@ private: void vextractf128h(Address dst, XMMRegister src); void vextracti128h(Address dst, XMMRegister src); + // duplicate 4-bytes integer data from src into 8 locations in dest + void vpbroadcastd(XMMRegister dst, XMMRegister src); + // AVX instruction which is used to clear upper 128 bits of YMM registers and // to avoid transaction penalty between AVX and SSE states. There is no // penalty if legacy SSE instructions are encoded using VEX prefix because diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp index d2549472cd6..c75c8d29a6f 100644 --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp @@ -6011,29 +6011,53 @@ void MacroAssembler::generate_fill(BasicType t, bool aligned, { assert( UseSSE >= 2, "supported cpu only" ); Label L_fill_32_bytes_loop, L_check_fill_8_bytes, L_fill_8_bytes_loop, L_fill_8_bytes; - // Fill 32-byte chunks movdl(xtmp, value); - pshufd(xtmp, xtmp, 0); + if (UseAVX >= 2 && UseUnalignedLoadStores) { + // Fill 64-byte chunks + Label L_fill_64_bytes_loop, L_check_fill_32_bytes; + vpbroadcastd(xtmp, xtmp); - subl(count, 8 << shift); - jcc(Assembler::less, L_check_fill_8_bytes); - align(16); + subl(count, 16 << shift); + jcc(Assembler::less, L_check_fill_32_bytes); + align(16); - BIND(L_fill_32_bytes_loop); + BIND(L_fill_64_bytes_loop); + vmovdqu(Address(to, 0), xtmp); + vmovdqu(Address(to, 32), xtmp); + addptr(to, 64); + subl(count, 16 << shift); + jcc(Assembler::greaterEqual, L_fill_64_bytes_loop); - if (UseUnalignedLoadStores) { - movdqu(Address(to, 0), xtmp); - movdqu(Address(to, 16), xtmp); + BIND(L_check_fill_32_bytes); + addl(count, 8 << shift); + jccb(Assembler::less, L_check_fill_8_bytes); + vmovdqu(Address(to, 0), xtmp); + addptr(to, 32); + subl(count, 8 << shift); } else { - movq(Address(to, 0), xtmp); - movq(Address(to, 8), xtmp); - movq(Address(to, 16), xtmp); - movq(Address(to, 24), xtmp); - } + // Fill 32-byte chunks + pshufd(xtmp, xtmp, 0); - addptr(to, 32); - subl(count, 8 << shift); - jcc(Assembler::greaterEqual, L_fill_32_bytes_loop); + subl(count, 8 << shift); + jcc(Assembler::less, L_check_fill_8_bytes); + align(16); + + BIND(L_fill_32_bytes_loop); + + if (UseUnalignedLoadStores) { + movdqu(Address(to, 0), xtmp); + movdqu(Address(to, 16), xtmp); + } else { + movq(Address(to, 0), xtmp); + movq(Address(to, 8), xtmp); + movq(Address(to, 16), xtmp); + movq(Address(to, 24), xtmp); + } + + addptr(to, 32); + subl(count, 8 << shift); + jcc(Assembler::greaterEqual, L_fill_32_bytes_loop); + } BIND(L_check_fill_8_bytes); addl(count, 8 << shift); jccb(Assembler::zero, L_exit); diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp index 3bf5dc5e0fc..e56bb2266d0 100644 --- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp @@ -796,16 +796,22 @@ class StubGenerator: public StubCodeGenerator { __ align(OptoLoopAlignment); __ BIND(L_copy_64_bytes_loop); - if(UseUnalignedLoadStores) { - __ movdqu(xmm0, Address(from, 0)); - __ movdqu(Address(from, to_from, Address::times_1, 0), xmm0); - __ movdqu(xmm1, Address(from, 16)); - __ movdqu(Address(from, to_from, Address::times_1, 16), xmm1); - __ movdqu(xmm2, Address(from, 32)); - __ movdqu(Address(from, to_from, Address::times_1, 32), xmm2); - __ movdqu(xmm3, Address(from, 48)); - __ movdqu(Address(from, to_from, Address::times_1, 48), xmm3); - + if (UseUnalignedLoadStores) { + if (UseAVX >= 2) { + __ vmovdqu(xmm0, Address(from, 0)); + __ vmovdqu(Address(from, to_from, Address::times_1, 0), xmm0); + __ vmovdqu(xmm1, Address(from, 32)); + __ vmovdqu(Address(from, to_from, Address::times_1, 32), xmm1); + } else { + __ movdqu(xmm0, Address(from, 0)); + __ movdqu(Address(from, to_from, Address::times_1, 0), xmm0); + __ movdqu(xmm1, Address(from, 16)); + __ movdqu(Address(from, to_from, Address::times_1, 16), xmm1); + __ movdqu(xmm2, Address(from, 32)); + __ movdqu(Address(from, to_from, Address::times_1, 32), xmm2); + __ movdqu(xmm3, Address(from, 48)); + __ movdqu(Address(from, to_from, Address::times_1, 48), xmm3); + } } else { __ movq(xmm0, Address(from, 0)); __ movq(Address(from, to_from, Address::times_1, 0), xmm0); diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp index 00fa0e9ccc0..c6b94e243bc 100644 --- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp @@ -1286,23 +1286,54 @@ class StubGenerator: public StubCodeGenerator { // end_to - destination array end address // qword_count - 64-bits element count, negative // to - scratch - // L_copy_32_bytes - entry label + // L_copy_bytes - entry label // L_copy_8_bytes - exit label // - void copy_32_bytes_forward(Register end_from, Register end_to, + void copy_bytes_forward(Register end_from, Register end_to, Register qword_count, Register to, - Label& L_copy_32_bytes, Label& L_copy_8_bytes) { + Label& L_copy_bytes, Label& L_copy_8_bytes) { DEBUG_ONLY(__ stop("enter at entry label, not here")); Label L_loop; __ align(OptoLoopAlignment); - __ BIND(L_loop); - if(UseUnalignedLoadStores) { - __ movdqu(xmm0, Address(end_from, qword_count, Address::times_8, -24)); - __ movdqu(Address(end_to, qword_count, Address::times_8, -24), xmm0); - __ movdqu(xmm1, Address(end_from, qword_count, Address::times_8, - 8)); - __ movdqu(Address(end_to, qword_count, Address::times_8, - 8), xmm1); - + if (UseUnalignedLoadStores) { + Label L_end; + // Copy 64-bytes per iteration + __ BIND(L_loop); + if (UseAVX >= 2) { + __ vmovdqu(xmm0, Address(end_from, qword_count, Address::times_8, -56)); + __ vmovdqu(Address(end_to, qword_count, Address::times_8, -56), xmm0); + __ vmovdqu(xmm1, Address(end_from, qword_count, Address::times_8, -24)); + __ vmovdqu(Address(end_to, qword_count, Address::times_8, -24), xmm1); + } else { + __ movdqu(xmm0, Address(end_from, qword_count, Address::times_8, -56)); + __ movdqu(Address(end_to, qword_count, Address::times_8, -56), xmm0); + __ movdqu(xmm1, Address(end_from, qword_count, Address::times_8, -40)); + __ movdqu(Address(end_to, qword_count, Address::times_8, -40), xmm1); + __ movdqu(xmm2, Address(end_from, qword_count, Address::times_8, -24)); + __ movdqu(Address(end_to, qword_count, Address::times_8, -24), xmm2); + __ movdqu(xmm3, Address(end_from, qword_count, Address::times_8, - 8)); + __ movdqu(Address(end_to, qword_count, Address::times_8, - 8), xmm3); + } + __ BIND(L_copy_bytes); + __ addptr(qword_count, 8); + __ jcc(Assembler::lessEqual, L_loop); + __ subptr(qword_count, 4); // sub(8) and add(4) + __ jccb(Assembler::greater, L_end); + // Copy trailing 32 bytes + if (UseAVX >= 2) { + __ vmovdqu(xmm0, Address(end_from, qword_count, Address::times_8, -24)); + __ vmovdqu(Address(end_to, qword_count, Address::times_8, -24), xmm0); + } else { + __ movdqu(xmm0, Address(end_from, qword_count, Address::times_8, -24)); + __ movdqu(Address(end_to, qword_count, Address::times_8, -24), xmm0); + __ movdqu(xmm1, Address(end_from, qword_count, Address::times_8, - 8)); + __ movdqu(Address(end_to, qword_count, Address::times_8, - 8), xmm1); + } + __ addptr(qword_count, 4); + __ BIND(L_end); } else { + // Copy 32-bytes per iteration + __ BIND(L_loop); __ movq(to, Address(end_from, qword_count, Address::times_8, -24)); __ movq(Address(end_to, qword_count, Address::times_8, -24), to); __ movq(to, Address(end_from, qword_count, Address::times_8, -16)); @@ -1311,15 +1342,15 @@ class StubGenerator: public StubCodeGenerator { __ movq(Address(end_to, qword_count, Address::times_8, - 8), to); __ movq(to, Address(end_from, qword_count, Address::times_8, - 0)); __ movq(Address(end_to, qword_count, Address::times_8, - 0), to); + + __ BIND(L_copy_bytes); + __ addptr(qword_count, 4); + __ jcc(Assembler::lessEqual, L_loop); } - __ BIND(L_copy_32_bytes); - __ addptr(qword_count, 4); - __ jcc(Assembler::lessEqual, L_loop); __ subptr(qword_count, 4); __ jcc(Assembler::less, L_copy_8_bytes); // Copy trailing qwords } - // Copy big chunks backward // // Inputs: @@ -1327,23 +1358,55 @@ class StubGenerator: public StubCodeGenerator { // dest - destination array address // qword_count - 64-bits element count // to - scratch - // L_copy_32_bytes - entry label + // L_copy_bytes - entry label // L_copy_8_bytes - exit label // - void copy_32_bytes_backward(Register from, Register dest, + void copy_bytes_backward(Register from, Register dest, Register qword_count, Register to, - Label& L_copy_32_bytes, Label& L_copy_8_bytes) { + Label& L_copy_bytes, Label& L_copy_8_bytes) { DEBUG_ONLY(__ stop("enter at entry label, not here")); Label L_loop; __ align(OptoLoopAlignment); - __ BIND(L_loop); - if(UseUnalignedLoadStores) { - __ movdqu(xmm0, Address(from, qword_count, Address::times_8, 16)); - __ movdqu(Address(dest, qword_count, Address::times_8, 16), xmm0); - __ movdqu(xmm1, Address(from, qword_count, Address::times_8, 0)); - __ movdqu(Address(dest, qword_count, Address::times_8, 0), xmm1); + if (UseUnalignedLoadStores) { + Label L_end; + // Copy 64-bytes per iteration + __ BIND(L_loop); + if (UseAVX >= 2) { + __ vmovdqu(xmm0, Address(from, qword_count, Address::times_8, 32)); + __ vmovdqu(Address(dest, qword_count, Address::times_8, 32), xmm0); + __ vmovdqu(xmm1, Address(from, qword_count, Address::times_8, 0)); + __ vmovdqu(Address(dest, qword_count, Address::times_8, 0), xmm1); + } else { + __ movdqu(xmm0, Address(from, qword_count, Address::times_8, 48)); + __ movdqu(Address(dest, qword_count, Address::times_8, 48), xmm0); + __ movdqu(xmm1, Address(from, qword_count, Address::times_8, 32)); + __ movdqu(Address(dest, qword_count, Address::times_8, 32), xmm1); + __ movdqu(xmm2, Address(from, qword_count, Address::times_8, 16)); + __ movdqu(Address(dest, qword_count, Address::times_8, 16), xmm2); + __ movdqu(xmm3, Address(from, qword_count, Address::times_8, 0)); + __ movdqu(Address(dest, qword_count, Address::times_8, 0), xmm3); + } + __ BIND(L_copy_bytes); + __ subptr(qword_count, 8); + __ jcc(Assembler::greaterEqual, L_loop); + __ addptr(qword_count, 4); // add(8) and sub(4) + __ jccb(Assembler::less, L_end); + // Copy trailing 32 bytes + if (UseAVX >= 2) { + __ vmovdqu(xmm0, Address(from, qword_count, Address::times_8, 0)); + __ vmovdqu(Address(dest, qword_count, Address::times_8, 0), xmm0); + } else { + __ movdqu(xmm0, Address(from, qword_count, Address::times_8, 16)); + __ movdqu(Address(dest, qword_count, Address::times_8, 16), xmm0); + __ movdqu(xmm1, Address(from, qword_count, Address::times_8, 0)); + __ movdqu(Address(dest, qword_count, Address::times_8, 0), xmm1); + } + __ subptr(qword_count, 4); + __ BIND(L_end); } else { + // Copy 32-bytes per iteration + __ BIND(L_loop); __ movq(to, Address(from, qword_count, Address::times_8, 24)); __ movq(Address(dest, qword_count, Address::times_8, 24), to); __ movq(to, Address(from, qword_count, Address::times_8, 16)); @@ -1352,10 +1415,11 @@ class StubGenerator: public StubCodeGenerator { __ movq(Address(dest, qword_count, Address::times_8, 8), to); __ movq(to, Address(from, qword_count, Address::times_8, 0)); __ movq(Address(dest, qword_count, Address::times_8, 0), to); + + __ BIND(L_copy_bytes); + __ subptr(qword_count, 4); + __ jcc(Assembler::greaterEqual, L_loop); } - __ BIND(L_copy_32_bytes); - __ subptr(qword_count, 4); - __ jcc(Assembler::greaterEqual, L_loop); __ addptr(qword_count, 4); __ jcc(Assembler::greater, L_copy_8_bytes); // Copy trailing qwords } @@ -1385,7 +1449,7 @@ class StubGenerator: public StubCodeGenerator { StubCodeMark mark(this, "StubRoutines", name); address start = __ pc(); - Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes, L_copy_2_bytes; + Label L_copy_bytes, L_copy_8_bytes, L_copy_4_bytes, L_copy_2_bytes; Label L_copy_byte, L_exit; const Register from = rdi; // source array address const Register to = rsi; // destination array address @@ -1417,7 +1481,7 @@ class StubGenerator: public StubCodeGenerator { __ lea(end_from, Address(from, qword_count, Address::times_8, -8)); __ lea(end_to, Address(to, qword_count, Address::times_8, -8)); __ negptr(qword_count); // make the count negative - __ jmp(L_copy_32_bytes); + __ jmp(L_copy_bytes); // Copy trailing qwords __ BIND(L_copy_8_bytes); @@ -1460,8 +1524,8 @@ class StubGenerator: public StubCodeGenerator { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); - // Copy in 32-bytes chunks - copy_32_bytes_forward(end_from, end_to, qword_count, rax, L_copy_32_bytes, L_copy_8_bytes); + // Copy in multi-bytes chunks + copy_bytes_forward(end_from, end_to, qword_count, rax, L_copy_bytes, L_copy_8_bytes); __ jmp(L_copy_4_bytes); return start; @@ -1488,7 +1552,7 @@ class StubGenerator: public StubCodeGenerator { StubCodeMark mark(this, "StubRoutines", name); address start = __ pc(); - Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes, L_copy_2_bytes; + Label L_copy_bytes, L_copy_8_bytes, L_copy_4_bytes, L_copy_2_bytes; const Register from = rdi; // source array address const Register to = rsi; // destination array address const Register count = rdx; // elements count @@ -1531,10 +1595,10 @@ class StubGenerator: public StubCodeGenerator { // Check for and copy trailing dword __ BIND(L_copy_4_bytes); __ testl(byte_count, 4); - __ jcc(Assembler::zero, L_copy_32_bytes); + __ jcc(Assembler::zero, L_copy_bytes); __ movl(rax, Address(from, qword_count, Address::times_8)); __ movl(Address(to, qword_count, Address::times_8), rax); - __ jmp(L_copy_32_bytes); + __ jmp(L_copy_bytes); // Copy trailing qwords __ BIND(L_copy_8_bytes); @@ -1549,8 +1613,8 @@ class StubGenerator: public StubCodeGenerator { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); - // Copy in 32-bytes chunks - copy_32_bytes_backward(from, to, qword_count, rax, L_copy_32_bytes, L_copy_8_bytes); + // Copy in multi-bytes chunks + copy_bytes_backward(from, to, qword_count, rax, L_copy_bytes, L_copy_8_bytes); restore_arg_regs(); inc_counter_np(SharedRuntime::_jbyte_array_copy_ctr); // Update counter after rscratch1 is free @@ -1585,7 +1649,7 @@ class StubGenerator: public StubCodeGenerator { StubCodeMark mark(this, "StubRoutines", name); address start = __ pc(); - Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes,L_copy_2_bytes,L_exit; + Label L_copy_bytes, L_copy_8_bytes, L_copy_4_bytes,L_copy_2_bytes,L_exit; const Register from = rdi; // source array address const Register to = rsi; // destination array address const Register count = rdx; // elements count @@ -1616,7 +1680,7 @@ class StubGenerator: public StubCodeGenerator { __ lea(end_from, Address(from, qword_count, Address::times_8, -8)); __ lea(end_to, Address(to, qword_count, Address::times_8, -8)); __ negptr(qword_count); - __ jmp(L_copy_32_bytes); + __ jmp(L_copy_bytes); // Copy trailing qwords __ BIND(L_copy_8_bytes); @@ -1652,8 +1716,8 @@ class StubGenerator: public StubCodeGenerator { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); - // Copy in 32-bytes chunks - copy_32_bytes_forward(end_from, end_to, qword_count, rax, L_copy_32_bytes, L_copy_8_bytes); + // Copy in multi-bytes chunks + copy_bytes_forward(end_from, end_to, qword_count, rax, L_copy_bytes, L_copy_8_bytes); __ jmp(L_copy_4_bytes); return start; @@ -1700,7 +1764,7 @@ class StubGenerator: public StubCodeGenerator { StubCodeMark mark(this, "StubRoutines", name); address start = __ pc(); - Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes; + Label L_copy_bytes, L_copy_8_bytes, L_copy_4_bytes; const Register from = rdi; // source array address const Register to = rsi; // destination array address const Register count = rdx; // elements count @@ -1735,10 +1799,10 @@ class StubGenerator: public StubCodeGenerator { // Check for and copy trailing dword __ BIND(L_copy_4_bytes); __ testl(word_count, 2); - __ jcc(Assembler::zero, L_copy_32_bytes); + __ jcc(Assembler::zero, L_copy_bytes); __ movl(rax, Address(from, qword_count, Address::times_8)); __ movl(Address(to, qword_count, Address::times_8), rax); - __ jmp(L_copy_32_bytes); + __ jmp(L_copy_bytes); // Copy trailing qwords __ BIND(L_copy_8_bytes); @@ -1753,8 +1817,8 @@ class StubGenerator: public StubCodeGenerator { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); - // Copy in 32-bytes chunks - copy_32_bytes_backward(from, to, qword_count, rax, L_copy_32_bytes, L_copy_8_bytes); + // Copy in multi-bytes chunks + copy_bytes_backward(from, to, qword_count, rax, L_copy_bytes, L_copy_8_bytes); restore_arg_regs(); inc_counter_np(SharedRuntime::_jshort_array_copy_ctr); // Update counter after rscratch1 is free @@ -1790,7 +1854,7 @@ class StubGenerator: public StubCodeGenerator { StubCodeMark mark(this, "StubRoutines", name); address start = __ pc(); - Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes, L_exit; + Label L_copy_bytes, L_copy_8_bytes, L_copy_4_bytes, L_exit; const Register from = rdi; // source array address const Register to = rsi; // destination array address const Register count = rdx; // elements count @@ -1826,7 +1890,7 @@ class StubGenerator: public StubCodeGenerator { __ lea(end_from, Address(from, qword_count, Address::times_8, -8)); __ lea(end_to, Address(to, qword_count, Address::times_8, -8)); __ negptr(qword_count); - __ jmp(L_copy_32_bytes); + __ jmp(L_copy_bytes); // Copy trailing qwords __ BIND(L_copy_8_bytes); @@ -1853,8 +1917,8 @@ class StubGenerator: public StubCodeGenerator { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); - // Copy 32-bytes chunks - copy_32_bytes_forward(end_from, end_to, qword_count, rax, L_copy_32_bytes, L_copy_8_bytes); + // Copy in multi-bytes chunks + copy_bytes_forward(end_from, end_to, qword_count, rax, L_copy_bytes, L_copy_8_bytes); __ jmp(L_copy_4_bytes); return start; @@ -1882,7 +1946,7 @@ class StubGenerator: public StubCodeGenerator { StubCodeMark mark(this, "StubRoutines", name); address start = __ pc(); - Label L_copy_32_bytes, L_copy_8_bytes, L_copy_2_bytes, L_exit; + Label L_copy_bytes, L_copy_8_bytes, L_copy_2_bytes, L_exit; const Register from = rdi; // source array address const Register to = rsi; // destination array address const Register count = rdx; // elements count @@ -1916,10 +1980,10 @@ class StubGenerator: public StubCodeGenerator { // Check for and copy trailing dword __ testl(dword_count, 1); - __ jcc(Assembler::zero, L_copy_32_bytes); + __ jcc(Assembler::zero, L_copy_bytes); __ movl(rax, Address(from, dword_count, Address::times_4, -4)); __ movl(Address(to, dword_count, Address::times_4, -4), rax); - __ jmp(L_copy_32_bytes); + __ jmp(L_copy_bytes); // Copy trailing qwords __ BIND(L_copy_8_bytes); @@ -1937,8 +2001,8 @@ class StubGenerator: public StubCodeGenerator { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); - // Copy in 32-bytes chunks - copy_32_bytes_backward(from, to, qword_count, rax, L_copy_32_bytes, L_copy_8_bytes); + // Copy in multi-bytes chunks + copy_bytes_backward(from, to, qword_count, rax, L_copy_bytes, L_copy_8_bytes); __ bind(L_exit); if (is_oop) { @@ -1976,7 +2040,7 @@ class StubGenerator: public StubCodeGenerator { StubCodeMark mark(this, "StubRoutines", name); address start = __ pc(); - Label L_copy_32_bytes, L_copy_8_bytes, L_exit; + Label L_copy_bytes, L_copy_8_bytes, L_exit; const Register from = rdi; // source array address const Register to = rsi; // destination array address const Register qword_count = rdx; // elements count @@ -2008,7 +2072,7 @@ class StubGenerator: public StubCodeGenerator { __ lea(end_from, Address(from, qword_count, Address::times_8, -8)); __ lea(end_to, Address(to, qword_count, Address::times_8, -8)); __ negptr(qword_count); - __ jmp(L_copy_32_bytes); + __ jmp(L_copy_bytes); // Copy trailing qwords __ BIND(L_copy_8_bytes); @@ -2027,8 +2091,8 @@ class StubGenerator: public StubCodeGenerator { __ ret(0); } - // Copy 64-byte chunks - copy_32_bytes_forward(end_from, end_to, qword_count, rax, L_copy_32_bytes, L_copy_8_bytes); + // Copy in multi-bytes chunks + copy_bytes_forward(end_from, end_to, qword_count, rax, L_copy_bytes, L_copy_8_bytes); if (is_oop) { __ BIND(L_exit); @@ -2065,7 +2129,7 @@ class StubGenerator: public StubCodeGenerator { StubCodeMark mark(this, "StubRoutines", name); address start = __ pc(); - Label L_copy_32_bytes, L_copy_8_bytes, L_exit; + Label L_copy_bytes, L_copy_8_bytes, L_exit; const Register from = rdi; // source array address const Register to = rsi; // destination array address const Register qword_count = rdx; // elements count @@ -2091,7 +2155,7 @@ class StubGenerator: public StubCodeGenerator { gen_write_ref_array_pre_barrier(to, saved_count, dest_uninitialized); } - __ jmp(L_copy_32_bytes); + __ jmp(L_copy_bytes); // Copy trailing qwords __ BIND(L_copy_8_bytes); @@ -2110,8 +2174,8 @@ class StubGenerator: public StubCodeGenerator { __ ret(0); } - // Copy in 32-bytes chunks - copy_32_bytes_backward(from, to, qword_count, rax, L_copy_32_bytes, L_copy_8_bytes); + // Copy in multi-bytes chunks + copy_bytes_backward(from, to, qword_count, rax, L_copy_bytes, L_copy_8_bytes); if (is_oop) { __ BIND(L_exit); From 2cd5c87cb9dab3cfaaea5a59b02446f236dbca4d Mon Sep 17 00:00:00 2001 From: Bengt Rutisson Date: Fri, 4 Jan 2013 11:10:17 +0100 Subject: [PATCH 025/204] 8003820: Deprecate untested and rarely used GC combinations Log warning messages for DefNew+CMS and ParNew+SerialOld Reviewed-by: ysr, jwilhelm, jcoomes --- hotspot/src/share/vm/runtime/arguments.cpp | 15 +++++++++++++++ hotspot/src/share/vm/runtime/arguments.hpp | 1 + 2 files changed, 16 insertions(+) diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 4d1b9366d07..c0c0d12a099 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1778,6 +1778,20 @@ bool Arguments::check_gc_consistency() { return status; } +void Arguments::check_deprecated_gcs() { + if (UseConcMarkSweepGC && !UseParNewGC) { + warning("Using the DefNew young collector with the CMS collector is deprecated " + "and will likely be removed in a future release"); + } + + if (UseParNewGC && !UseConcMarkSweepGC) { + // !UseConcMarkSweepGC means that we are using serial old gc. Unfortunately we don't + // set up UseSerialGC properly, so that can't be used in the check here. + warning("Using the ParNew young collector with the Serial old collector is deprecated " + "and will likely be removed in a future release"); + } +} + // Check stack pages settings bool Arguments::check_stack_pages() { @@ -3242,6 +3256,7 @@ jint Arguments::parse(const JavaVMInitArgs* args) { } else if (UseG1GC) { set_g1_gc_flags(); } + check_deprecated_gcs(); #endif // INCLUDE_ALTERNATE_GCS #ifdef SERIALGC diff --git a/hotspot/src/share/vm/runtime/arguments.hpp b/hotspot/src/share/vm/runtime/arguments.hpp index 5e0f0094498..71e6e3001e9 100644 --- a/hotspot/src/share/vm/runtime/arguments.hpp +++ b/hotspot/src/share/vm/runtime/arguments.hpp @@ -413,6 +413,7 @@ class Arguments : AllStatic { static jint adjust_after_os(); // Check for consistency in the selection of the garbage collector. static bool check_gc_consistency(); + static void check_deprecated_gcs(); // Check consistecy or otherwise of VM argument settings static bool check_vm_args_consistency(); // Check stack pages settings From a393578bcc6e26c44f77b6689c81376803abf0b1 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Fri, 4 Jan 2013 11:31:00 +0100 Subject: [PATCH 026/204] 8005575: build-infra: Three JCK tests fails on Solaris with new RE Autoconf-Based build Reviewed-by: ohair --- common/autoconf/compare.sh.in | 3 ++- common/bin/compare.sh | 17 ++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/common/autoconf/compare.sh.in b/common/autoconf/compare.sh.in index 1a1b997da24..b8fa8b85d8a 100644 --- a/common/autoconf/compare.sh.in +++ b/common/autoconf/compare.sh.in @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, 2013 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 @@ -48,6 +48,7 @@ GREP="@GREP@" JAVAP="@FIXPATH@ @BOOT_JDK@/bin/javap" LDD="@LDD@" MKDIR="@MKDIR@" +NAWK="@NAWK@" NM="@NM@" OBJDUMP="@OBJDUMP@" OTOOL="@OTOOL@" diff --git a/common/bin/compare.sh b/common/bin/compare.sh index 8240c4c423e..e2684db956b 100644 --- a/common/bin/compare.sh +++ b/common/bin/compare.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, 2013 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 @@ -113,12 +113,15 @@ diff_text() { fi fi if test "x$SUFFIX" = "xproperties"; then - $CAT $OTHER_FILE | $SED -e 's/\([^\\]\):/\1\\:/g' -e 's/\([^\\]\)=/\1\\=/g' -e 's/#.*/#/g' \ - | $SED -f "$SRC_ROOT/common/makefiles/support/unicode2x.sed" \ - | $SED -e '/^#/d' -e '/^$/d' \ - -e :a -e '/\\$/N; s/\\\n//; ta' \ - -e 's/^[ \t]*//;s/[ \t]*$//' \ - -e 's/\\=/=/' | LANG=C $SORT > $OTHER_FILE.cleaned + # Run through nawk to add possibly missing newline at end of file. + $CAT $OTHER_FILE | $NAWK '{ print }' > $OTHER_FILE.cleaned +# Disable this exception since we aren't changing the properties cleaning method yet. +# $CAT $OTHER_FILE | $SED -e 's/\([^\\]\):/\1\\:/g' -e 's/\([^\\]\)=/\1\\=/g' -e 's/#.*/#/g' \ +# | $SED -f "$SRC_ROOT/common/makefiles/support/unicode2x.sed" \ +# | $SED -e '/^#/d' -e '/^$/d' \ +# -e :a -e '/\\$/N; s/\\\n//; ta' \ +# -e 's/^[ \t]*//;s/[ \t]*$//' \ +# -e 's/\\=/=/' | LANG=C $SORT > $OTHER_FILE.cleaned TMP=$(LANG=C $DIFF $OTHER_FILE.cleaned $THIS_FILE) fi if test -n "$TMP"; then From 24f8d0482874930e4223587a298a3f4ec08c3f16 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Fri, 4 Jan 2013 11:31:16 +0100 Subject: [PATCH 027/204] 8005575: build-infra: Three JCK tests fails on Solaris with new RE Autoconf-Based build Reviewed-by: ohair --- jaxp/makefiles/BuildJaxp.gmk | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/jaxp/makefiles/BuildJaxp.gmk b/jaxp/makefiles/BuildJaxp.gmk index 85649849f2b..e28cdf890c3 100644 --- a/jaxp/makefiles/BuildJaxp.gmk +++ b/jaxp/makefiles/BuildJaxp.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2013, 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 @@ -47,11 +47,23 @@ $(eval $(call SetupJavaCompiler,GENERATE_NEWBYTECODE_DEBUG,\ $(eval $(call SetupJavaCompilation,BUILD_JAXP,\ SETUP:=GENERATE_NEWBYTECODE_DEBUG,\ SRC:=$(JAXP_TOPDIR)/src,\ - CLEAN:=.properties,\ BIN:=$(JAXP_OUTPUTDIR)/classes,\ SRCZIP:=$(JAXP_OUTPUTDIR)/dist/lib/src.zip)) -$(eval $(call SetupArchive,ARCHIVE_JAXP,$(BUILD_JAXP),\ +# Imitate the property cleaning mechanism in the old build. This will likely be replaced +# by the unified functionality in JavaCompilation.gmk, but keep it the same as old build +# for now, even though it actually breaks properties containing # in the value. +# Using nawk to avoid solaris sed. +$(JAXP_OUTPUTDIR)/classes/%.properties: $(JAXP_TOPDIR)/src/%.properties + $(MKDIR) -p $(@D) + $(RM) $@ $@.tmp + $(CAT) $< | LANG=C $(NAWK) '{ sub(/#.*$$/,"#"); print }' > $@.tmp + $(MV) $@.tmp $@ + +SRC_PROP_FILES := $(shell $(FIND) $(JAXP_TOPDIR)/src -name "*.properties") +TARGET_PROP_FILES := $(patsubst $(JAXP_TOPDIR)/src/%,$(JAXP_OUTPUTDIR)/classes/%,$(SRC_PROP_FILES)) + +$(eval $(call SetupArchive,ARCHIVE_JAXP,$(BUILD_JAXP) $(TARGET_PROP_FILES),\ SRCS:=$(JAXP_OUTPUTDIR)/classes,\ SUFFIXES:=.class .properties,\ JAR:=$(JAXP_OUTPUTDIR)/dist/lib/classes.jar)) From c7144600bf1863624d3af755c73cc8aa263fe115 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Fri, 4 Jan 2013 11:31:32 +0100 Subject: [PATCH 028/204] 8005575: build-infra: Three JCK tests fails on Solaris with new RE Autoconf-Based build Reviewed-by: ohair --- jaxws/makefiles/BuildJaxws.gmk | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/jaxws/makefiles/BuildJaxws.gmk b/jaxws/makefiles/BuildJaxws.gmk index a745ec8041e..c1b092d64bc 100644 --- a/jaxws/makefiles/BuildJaxws.gmk +++ b/jaxws/makefiles/BuildJaxws.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2013, 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 @@ -48,14 +48,12 @@ $(eval $(call SetupJavaCompiler,GENERATE_NEWBYTECODE_DEBUG,\ $(eval $(call SetupJavaCompilation,BUILD_JAF,\ SETUP:=GENERATE_NEWBYTECODE_DEBUG,\ SRC:=$(JAXWS_TOPDIR)/src/share/jaf_classes,\ - CLEAN:=.properties,\ COPY:="dummy",\ BIN:=$(JAXWS_OUTPUTDIR)/jaf_classes)) $(eval $(call SetupJavaCompilation,BUILD_JAXWS,\ SETUP:=GENERATE_NEWBYTECODE_DEBUG,\ SRC:=$(JAXWS_TOPDIR)/src/share/jaxws_classes,\ - CLEAN:=.properties,\ BIN:=$(JAXWS_OUTPUTDIR)/jaxws_classes,\ COPY:=.xsd,\ COPY_FILES:=$(JAXWS_TOPDIR)/src/share/jaxws_classes/com/sun/tools/internal/xjc/runtime/JAXBContextFactory.java \ @@ -76,7 +74,31 @@ $(JAXWS_OUTPUTDIR)/jaxws_classes/META-INF/services/com.sun.tools.internal.xjc.Pl BUILD_JAXWS += $(JAXWS_OUTPUTDIR)/jaxws_classes/META-INF/services/com.sun.tools.internal.ws.wscompile.Plugin \ $(JAXWS_OUTPUTDIR)/jaxws_classes/META-INF/services/com.sun.tools.internal.xjc.Plugin -$(eval $(call SetupArchive,ARCHIVE_JAXWS,$(BUILD_JAXWS) $(BUILD_JAF),\ +# Imitate the property cleaning mechanism in the old build. This will likely be replaced +# by the unified functionality in JavaCompilation.gmk, but keep it the same as old build +# for now, even though it actually breaks properties containing # in the value. +# Using nawk to avoid solaris sed. +$(JAXWS_OUTPUTDIR)/jaxws_classes/%.properties: $(JAXWS_TOPDIR)/src/share/jaxws_classes/%.properties + $(MKDIR) -p $(@D) + $(RM) $@ $@.tmp + $(CAT) $< | LANG=C $(NAWK) '{ sub(/#.*$$/,"#"); print }' > $@.tmp + $(MV) $@.tmp $@ + +JAXWS_SRC_PROP_FILES := $(shell $(FIND) $(JAXWS_TOPDIR)/src/share/jaxws_classes -name "*.properties") +TARGET_PROP_FILES := $(patsubst $(JAXWS_TOPDIR)/src/share/jaxws_classes/%,\ + $(JAXWS_OUTPUTDIR)/jaxws_classes/%,$(JAXWS_SRC_PROP_FILES)) + +$(JAXWS_OUTPUTDIR)/jaf_classes/%.properties: $(JAXWS_TOPDIR)/src/share/jaf_classes/%.properties + $(MKDIR) -p $(@D) + $(RM) $@ $@.tmp + $(CAT) $< | LANG=C $(NAWK) '{ sub(/#.*$$/,"#"); print }' > $@.tmp + $(MV) $@.tmp $@ + +JAF_SRC_PROP_FILES := $(shell $(FIND) $(JAXWS_TOPDIR)/src/share/jaf_classes -name "*.properties") +TARGET_PROP_FILES += $(patsubst $(JAXWS_TOPDIR)/src/share/jaf_classes/%,\ + $(JAXWS_OUTPUTDIR)/jaf_classes/%,$(JAF_SRC_PROP_FILES)) + +$(eval $(call SetupArchive,ARCHIVE_JAXWS,$(BUILD_JAXWS) $(BUILD_JAF) $(TARGET_PROP_FILES),\ SRCS:=$(JAXWS_OUTPUTDIR)/jaxws_classes $(JAXWS_OUTPUTDIR)/jaf_classes,\ SUFFIXES:=.class .properties .xsd .java \ com.sun.mirror.apt.AnnotationProcessorFactory \ From 839f973de622bcb8958124b5a05e0a62f84df4b9 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Fri, 4 Jan 2013 16:56:37 +0100 Subject: [PATCH 029/204] 8005692: build-infra: Target "all" should do the right thing Reviewed-by: tbell --- common/makefiles/Main.gmk | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/makefiles/Main.gmk b/common/makefiles/Main.gmk index 801c986a754..c96747f090c 100644 --- a/common/makefiles/Main.gmk +++ b/common/makefiles/Main.gmk @@ -71,6 +71,10 @@ default: jdk all: images docs @$(call CheckIfMakeAtEnd) +ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_BITS),solaris-64) + all: overlay-images +endif + start-make: @$(call AtMakeStart) From 260c554c063f86973b308dddb5d4ca6815682909 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Fri, 4 Jan 2013 17:05:13 +0100 Subject: [PATCH 030/204] 8005597: build-infra: bridgeBuild broken for pure openjdk build Reviewed-by: tbell --- common/makefiles/Jprt.gmk | 51 +++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/common/makefiles/Jprt.gmk b/common/makefiles/Jprt.gmk index 91ba6e1a875..69c7740bd15 100644 --- a/common/makefiles/Jprt.gmk +++ b/common/makefiles/Jprt.gmk @@ -42,6 +42,24 @@ endef BUILD_DIR_ROOT:=$(root_dir)/build +# Appears to be an open build +OPEN_BUILD := \ +$(shell \ + if [ -d $(root_dir)/jdk/src/closed \ + -o -d $(root_dir)/jdk/make/closed \ + -o -d $(root_dir)/jdk/test/closed \ + -o -d $(root_dir)/hotspot/src/closed \ + -o -d $(root_dir)/hotspot/make/closed \ + -o -d $(root_dir)/hotspot/test/closed ] ; then \ + echo "false"; \ + else \ + echo "true"; \ + fi \ + ) +ifdef OPENJDK + OPEN_BUILD=true +endif + ########################################################################### # To help in adoption of the new configure&&make build process, a bridge # build will use the old settings to run configure and do the build. @@ -84,30 +102,31 @@ endif ifdef ALT_FREETYPE_HEADERS_PATH @$(ECHO) " --with-freetype=$(call UnixPath,$(ALT_FREETYPE_HEADERS_PATH)/..) " >> $@.tmp endif -ifdef OPENJDK +ifeq ($(OPEN_BUILD),true) @$(ECHO) " --enable-openjdk-only " >> $@.tmp -endif -# Todo: move to closed? -ifdef ALT_MOZILLA_HEADERS_PATH +else + # Todo: move to closed? + ifdef ALT_MOZILLA_HEADERS_PATH @$(ECHO) " --with-mozilla-headers=$(call UnixPath,$(ALT_MOZILLA_HEADERS_PATH)) " >> $@.tmp -endif -ifdef ALT_JUNIT_DIR + endif + ifdef ALT_JUNIT_DIR @$(ECHO) " --with-junit-dir=$(call UnixPath,$(ALT_JUNIT_DIR)) " >> $@.tmp -endif -ifdef ANT_HOME + endif + ifdef ANT_HOME @$(ECHO) " --with-ant-home=$(call UnixPath,$(ANT_HOME)) " >> $@.tmp -endif -ifdef ALT_JAVAFX_ZIP_DIR + endif + ifdef ALT_JAVAFX_ZIP_DIR @$(ECHO) " --with-javafx-zip-dir=$(call UnixPath,$(ALT_JAVAFX_ZIP_DIR)) " >> $@.tmp -endif -ifdef ALT_WIXDIR + endif + ifdef ALT_WIXDIR @$(ECHO) " --with-wix=$(call UnixPath,$(ALT_WIXDIR)) " >> $@.tmp -endif -ifdef ALT_CCSS_SIGNING_DIR + endif + ifdef ALT_CCSS_SIGNING_DIR @$(ECHO) " --with-ccss-signing=$(call UnixPath,$(ALT_CCSS_SIGNING_DIR)) " >> $@.tmp -endif -ifdef ALT_SLASH_JAVA + endif + ifdef ALT_SLASH_JAVA @$(ECHO) " --with-java-devtools=$(call UnixPath,$(ALT_SLASH_JAVA)/devtools) " >> $@.tmp + endif endif @if [ -f $@ ] ; then \ if ! $(CMP) $@ $@.tmp > /dev/null ; then \ From e92b3e716e535f9452818786192c30cae4c16a54 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Fri, 4 Jan 2013 17:08:33 +0100 Subject: [PATCH 031/204] 8005654: build-infra: Create sec-bin.zip Reviewed-by: tbell --- common/bin/compare.sh | 15 +++++++++++++++ common/makefiles/JavaCompilation.gmk | 8 +++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/common/bin/compare.sh b/common/bin/compare.sh index e2684db956b..aab24421caf 100644 --- a/common/bin/compare.sh +++ b/common/bin/compare.sh @@ -1166,6 +1166,15 @@ if [ -z "$OTHER_DOCS" ]; then echo "WARNING! Other build doesn't contain docs, skipping doc compare." fi +if [ -f "$OTHER/tmp/sec-bin.zip" ]; then + OTHER_SEC_BIN="$OTHER/tmp/sec-bin.zip" +elif [ -f "$OTHER/images/sec-bin.zip" ]; then + OTHER_SEC_BIN="$OTHER/tmp/sec-bin.zip" +else + echo "WARNING! No sec-bin.zip found in other." +fi +THIS_SEC_BIN="$THIS/images/sec-bin.zip" + ########################################################################################## # Do the work @@ -1282,6 +1291,12 @@ if [ "$CMP_ZIPS" = "true" ]; then if [ -n "$THIS_J2SDK" ] && [ -n "$OTHER_J2SDK" ]; then compare_all_zip_files $THIS_J2SDK $OTHER_J2SDK $COMPARE_ROOT/j2sdk fi + if [ -n "$THIS_SEC_BIN" ] && [ -n "$OTHER_SEC_BIN" ]; then + if [ -n "$(echo $THIS_SEC_BIN | $FILTER)" ]; then + echo "sec-bin.zip..." + compare_zip_file $(dirname $THIS_SEC_BIN) $(dirname $OTHER_SEC_BIN) $COMPARE_ROOT/sec-bin sec-bin.zip + fi + fi fi if [ "$CMP_JARS" = "true" ]; then diff --git a/common/makefiles/JavaCompilation.gmk b/common/makefiles/JavaCompilation.gmk index 54ce927dd7c..59adc339779 100644 --- a/common/makefiles/JavaCompilation.gmk +++ b/common/makefiles/JavaCompilation.gmk @@ -250,7 +250,7 @@ endef define SetupZipArchive # param 1 is for example ZIP_MYSOURCE # param 2,3,4,5,6,7,8,9 are named args. - # SRC,ZIP,INCLUDES,EXCLUDES,EXCLUDE_FILES,SUFFIXES,EXTRA_DEPS + # SRC,ZIP,INCLUDES,INCLUDE_FILES,EXCLUDES,EXCLUDE_FILES,SUFFIXES,EXTRA_DEPS $(foreach i,2 3 4 5 6 7 8 9 10 11 12 13 14 15, $(if $($i),$1_$(strip $($i)))$(NEWLINE)) $(call LogSetupMacroEntry,SetupZipArchive($1),$2,$3,$4,$5,$6,$7,$8,$9,$(10),$(11),$(12),$(13),$(14),$(15)) $(if $(16),$(error Internal makefile error: Too many arguments to SetupZipArchive, please update JavaCompilation.gmk)) @@ -267,6 +267,12 @@ define SetupZipArchive else $1_ZIP_INCLUDES := $$(addprefix -i$(SPACE)$(DQUOTE),$$(addsuffix /*$(DQUOTE),$$($1_INCLUDES))) endif + endif + ifneq ($$($1_INCLUDE_FILES),) + $1_SRC_INCLUDES += $$(foreach i,$$($1_SRC),$$(addprefix $$i/,$$($1_INCLUDE_FILES))) + $1_ZIP_INCLUDES += $$(addprefix -i$(SPACE),$$($1_INCLUDE_FILES)) + endif + ifneq ($$($1_SRC_INCLUDES),) $1_ALL_SRCS := $$(filter $$($1_SRC_INCLUDES),$$($1_ALL_SRCS)) endif ifneq ($$($1_EXCLUDES),) From 2574114b01b4f449425f2081a30e181b3fba731c Mon Sep 17 00:00:00 2001 From: Bengt Rutisson Date: Fri, 4 Jan 2013 21:33:22 +0100 Subject: [PATCH 032/204] 8003822: Deprecate the incremental mode of CMS Reviewed-by: johnc, jwilhelm --- hotspot/src/share/vm/runtime/arguments.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index c0c0d12a099..2b5c7af0e67 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1790,6 +1790,10 @@ void Arguments::check_deprecated_gcs() { warning("Using the ParNew young collector with the Serial old collector is deprecated " "and will likely be removed in a future release"); } + + if (CMSIncrementalMode) { + warning("Using incremental CMS is deprecated and will likely be removed in a future release"); + } } // Check stack pages settings From 174782e0222f566e85c12cb77be329a5f8eff59f Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Fri, 4 Jan 2013 22:43:13 +0100 Subject: [PATCH 033/204] 8005723: build-infra: in new infra build, sec-windows-bin-zip and jgss-windows-*-bin.zip are missing Reviewed-by: tbell --- common/bin/compare.sh | 23 +++++++++++++++++------ common/bin/compare_exceptions.sh.incl | 4 ++++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/common/bin/compare.sh b/common/bin/compare.sh index aab24421caf..bcca754cd67 100644 --- a/common/bin/compare.sh +++ b/common/bin/compare.sh @@ -1166,14 +1166,25 @@ if [ -z "$OTHER_DOCS" ]; then echo "WARNING! Other build doesn't contain docs, skipping doc compare." fi -if [ -f "$OTHER/tmp/sec-bin.zip" ]; then - OTHER_SEC_BIN="$OTHER/tmp/sec-bin.zip" -elif [ -f "$OTHER/images/sec-bin.zip" ]; then - OTHER_SEC_BIN="$OTHER/tmp/sec-bin.zip" +if [ -d "$OTHER/images" ]; then + OTHER_SEC_DIR="$OTHER/images" else - echo "WARNING! No sec-bin.zip found in other." + OTHER_SEC_DIR="$OTHER/tmp" +fi +OTHER_SEC_BIN="$OTHER_SEC_DIR/sec-bin.zip" +THIS_SEC_DIR="$THIS/images" +THIS_SEC_BIN="$THIS_SEC_DIR/sec-bin.zip" +if [ "$OPENJDK_TARGET_OS" = "windows" ]; then + if [ "$OPENJDK_TARGET_CPU" = "x86_64" ]; then + JGSS_WINDOWS_BIN="jgss-windows-x64-bin.zip" + else + JGSS_WINDOWS_BIN="jgss-windows-i586-bin.zip" + fi + OTHER_SEC_WINDOWS_BIN="$OTHER_SEC_DIR/sec-windows-bin.zip" + OTHER_JGSS_WINDOWS_BIN="$OTHER_SEC_DIR/$JGSS_WINDOWS_BIN" + THIS_SEC_WINDOWS_BIN="$THIS_SEC_DIR/sec-windows-bin.zip" + THIS_JGSS_WINDOWS_BIN="$THIS_SEC_DIR/$JGSS_WINDOWS_BIN" fi -THIS_SEC_BIN="$THIS/images/sec-bin.zip" ########################################################################################## # Do the work diff --git a/common/bin/compare_exceptions.sh.incl b/common/bin/compare_exceptions.sh.incl index 0446dbc150a..1406010dc34 100644 --- a/common/bin/compare_exceptions.sh.incl +++ b/common/bin/compare_exceptions.sh.incl @@ -807,6 +807,10 @@ fi if [ "$OPENJDK_TARGET_OS" = "windows" ]; then +ACCEPTED_JARZIP_CONTENTS=" +/bin/w2k_lsa_auth.dll +" + # Probably should add all libs here ACCEPTED_SMALL_SIZE_DIFF=" ./demo/jvmti/gctest/lib/gctest.dll From cca092892b5a8bbb5295494c2855e118acb66f18 Mon Sep 17 00:00:00 2001 From: Jon Masamitsu Date: Fri, 4 Jan 2013 17:04:25 -0800 Subject: [PATCH 034/204] 8000325: Change default for CMSClassUnloadingEnabled to true Reviewed-by: stefank, ysr --- hotspot/src/share/vm/runtime/globals.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index c5d4a627b63..05d8de1ff3e 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -1599,7 +1599,7 @@ class CommandLineFlags { develop(bool, CMSTraceThreadState, false, \ "Trace the CMS thread state (enable the trace_state() method)") \ \ - product(bool, CMSClassUnloadingEnabled, false, \ + product(bool, CMSClassUnloadingEnabled, true, \ "Whether class unloading enabled when using CMS GC") \ \ product(uintx, CMSClassUnloadingMaxInterval, 0, \ From 7fb60025eea1d87f9c5f56a1bc2e9b6ec4765b1a Mon Sep 17 00:00:00 2001 From: Jon Masamitsu Date: Fri, 4 Jan 2013 17:04:46 -0800 Subject: [PATCH 035/204] 8005672: Clean up some changes to GC logging with GCCause's Reviewed-by: johnc, ysr --- .../concurrentMarkSweep/concurrentMarkSweepGeneration.cpp | 4 ++-- hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp | 2 +- .../vm/gc_implementation/parallelScavenge/psYoungGen.cpp | 3 ++- hotspot/src/share/vm/gc_interface/gcCause.hpp | 4 ++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp index 475f2b8fee1..25b936fd8a9 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -827,10 +827,10 @@ void ConcurrentMarkSweepGeneration::printOccupancy(const char *s) { GenCollectedHeap* gch = GenCollectedHeap::heap(); if (PrintGCDetails) { if (Verbose) { - gclog_or_tty->print(" [%d %s-%s: "SIZE_FORMAT"("SIZE_FORMAT")]", + gclog_or_tty->print("[%d %s-%s: "SIZE_FORMAT"("SIZE_FORMAT")]", level(), short_name(), s, used(), capacity()); } else { - gclog_or_tty->print(" [%d %s-%s: "SIZE_FORMAT"K("SIZE_FORMAT"K)]", + gclog_or_tty->print("[%d %s-%s: "SIZE_FORMAT"K("SIZE_FORMAT"K)]", level(), short_name(), s, used() / K, capacity() / K); } } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index 448c5707787..cc11754c9a0 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -3668,7 +3668,7 @@ void G1CollectedHeap::log_gc_header() { gclog_or_tty->stamp(PrintGCTimeStamps); GCCauseString gc_cause_str = GCCauseString("GC pause", gc_cause()) - .append(g1_policy()->gcs_are_young() ? " (young)" : " (mixed)") + .append(g1_policy()->gcs_are_young() ? "(young)" : "(mixed)") .append(g1_policy()->during_initial_mark_pause() ? " (initial-mark)" : ""); gclog_or_tty->print("[%s", (const char*)gc_cause_str); diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp index 70c071dfe49..2d8697587ac 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp @@ -808,8 +808,9 @@ void PSYoungGen::print_on(outputStream* st) const { st->print(" to "); to_space()->print_on(st); } +// Note that a space is not printed before the [NAME: void PSYoungGen::print_used_change(size_t prev_used) const { - gclog_or_tty->print(" [%s:", name()); + gclog_or_tty->print("[%s:", name()); gclog_or_tty->print(" " SIZE_FORMAT "K" "->" SIZE_FORMAT "K" "(" SIZE_FORMAT "K)", diff --git a/hotspot/src/share/vm/gc_interface/gcCause.hpp b/hotspot/src/share/vm/gc_interface/gcCause.hpp index c9bfe106c79..58abc2e6f5e 100644 --- a/hotspot/src/share/vm/gc_interface/gcCause.hpp +++ b/hotspot/src/share/vm/gc_interface/gcCause.hpp @@ -99,9 +99,9 @@ class GCCauseString : StackObj { public: GCCauseString(const char* prefix, GCCause::Cause cause) { if (PrintGCCause) { - _position = jio_snprintf(_buffer, _length, "%s (%s)", prefix, GCCause::to_string(cause)); + _position = jio_snprintf(_buffer, _length, "%s (%s) ", prefix, GCCause::to_string(cause)); } else { - _position = jio_snprintf(_buffer, _length, "%s", prefix); + _position = jio_snprintf(_buffer, _length, "%s ", prefix); } assert(_position >= 0 && _position <= _length, err_msg("Need to increase the buffer size in GCCauseString? %d", _position)); From ec348edbe6823cd872a3acda55d3f8b8e2a07a82 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Fri, 4 Jan 2013 21:04:03 -0800 Subject: [PATCH 036/204] 8004229: build-infra: Umbrella for switch of default "make" to new makefiles Reviewed-by: erikj, tbell --- Makefile | 5 +++++ make/jprt.properties | 3 +++ 2 files changed, 8 insertions(+) diff --git a/Makefile b/Makefile index 79c159e9e5c..f9162f0b641 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,11 @@ # If NEWBUILD is defined, use the new build-infra Makefiles and configure. # See NewMakefile.gmk for more information. +# If not specified, select what the default build is +ifndef NEWBUILD + NEWBUILD=true +endif + ifeq ($(NEWBUILD),true) # The new top level Makefile diff --git a/make/jprt.properties b/make/jprt.properties index 603ce5fda94..990c442a164 100644 --- a/make/jprt.properties +++ b/make/jprt.properties @@ -28,6 +28,9 @@ # Locked down to jdk8 jprt.tools.default.release=jdk8 +# Unix toolkit to use for building on windows +jprt.windows.jdk8.build.unix.toolkit=cygwin + # The different build flavors we want, we override here so we just get these 2 jprt.build.flavors=product,fastdebug From 89e575df23b9c0ae82c7037727ace53348715a8c Mon Sep 17 00:00:00 2001 From: Harold Seigel Date: Mon, 7 Jan 2013 15:32:51 -0500 Subject: [PATCH 037/204] 8003705: CDS failed on Windows: can not map in the CDS Map memory only once to prevent 'already mapped' failures. Reviewed-by: acorn, zgu --- hotspot/src/share/vm/memory/filemap.cpp | 14 +++++++++++--- hotspot/src/share/vm/memory/metaspaceShared.cpp | 10 +++++++++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/memory/filemap.cpp b/hotspot/src/share/vm/memory/filemap.cpp index 11b39577667..2069d64a900 100644 --- a/hotspot/src/share/vm/memory/filemap.cpp +++ b/hotspot/src/share/vm/memory/filemap.cpp @@ -211,7 +211,11 @@ void FileMapInfo::open_for_write() { // Remove the existing file in case another process has it open. remove(_full_path); +#ifdef _WINDOWS // if 0444 is used on Windows, then remove() will fail. + int fd = open(_full_path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0744); +#else int fd = open(_full_path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0444); +#endif if (fd < 0) { fail_stop("Unable to create shared archive file %s.", _full_path); } @@ -370,9 +374,8 @@ ReservedSpace FileMapInfo::reserve_shared_memory() { return rs; } // the reserved virtual memory is for mapping class data sharing archive - if (MemTracker::is_on()) { - MemTracker::record_virtual_memory_type((address)rs.base(), mtClassShared); - } + MemTracker::record_virtual_memory_type((address)rs.base(), mtClassShared); + return rs; } @@ -394,6 +397,11 @@ char* FileMapInfo::map_region(int i) { fail_continue(err_msg("Unable to map %s shared space at required address.", shared_region_name[i])); return NULL; } +#ifdef _WINDOWS + // This call is Windows-only because the memory_type gets recorded for the other platforms + // in method FileMapInfo::reserve_shared_memory(), which is not called on Windows. + MemTracker::record_virtual_memory_type((address)base, mtClassShared); +#endif return base; } diff --git a/hotspot/src/share/vm/memory/metaspaceShared.cpp b/hotspot/src/share/vm/memory/metaspaceShared.cpp index 519a766a251..5954e43d05a 100644 --- a/hotspot/src/share/vm/memory/metaspaceShared.cpp +++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp @@ -689,9 +689,15 @@ void MetaspaceShared::print_shared_spaces() { bool MetaspaceShared::map_shared_spaces(FileMapInfo* mapinfo) { size_t image_alignment = mapinfo->alignment(); - // Map in the shared memory and then map the regions on top of it +#ifndef _WINDOWS + // Map in the shared memory and then map the regions on top of it. + // On Windows, don't map the memory here because it will cause the + // mappings of the regions to fail. ReservedSpace shared_rs = mapinfo->reserve_shared_memory(); if (!shared_rs.is_reserved()) return false; +#endif + + assert(!DumpSharedSpaces, "Should not be called with DumpSharedSpaces"); // Map each shared region if ((_ro_base = mapinfo->map_region(ro)) != NULL && @@ -708,8 +714,10 @@ bool MetaspaceShared::map_shared_spaces(FileMapInfo* mapinfo) { if (_rw_base != NULL) mapinfo->unmap_region(rw); if (_md_base != NULL) mapinfo->unmap_region(md); if (_mc_base != NULL) mapinfo->unmap_region(mc); +#ifndef _WINDOWS // Release the entire mapped region shared_rs.release(); +#endif // If -Xshare:on is specified, print out the error message and exit VM, // otherwise, set UseSharedSpaces to false and continue. if (RequireSharedSpaces) { From cd3ceb477155616ada2a5c87ce6d375aaff974fd Mon Sep 17 00:00:00 2001 From: Tim Bell Date: Mon, 7 Jan 2013 14:01:09 -0800 Subject: [PATCH 038/204] 8005442: autogen.sh sets DATE_WHEN_GENERATED to empty string on Solaris version 11 or later Reviewed-by: ohair --- common/autoconf/autogen.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/common/autoconf/autogen.sh b/common/autoconf/autogen.sh index d4da90c77ee..64f11204678 100644 --- a/common/autoconf/autogen.sh +++ b/common/autoconf/autogen.sh @@ -26,9 +26,11 @@ script_dir=`dirname $0` # Create a timestamp as seconds since epoch if test "x`uname -s`" = "xSunOS"; then - # date +%s is not available on Solaris, use this workaround - # from http://solarisjedi.blogspot.co.uk/2006/06/solaris-date-command-and-epoch-time.html - TIMESTAMP=`/usr/bin/truss /usr/bin/date 2>&1 | nawk -F= '/^time\(\)/ {gsub(/ /,"",$2);print $2}'` + TIMESTAMP=`date +%s` + if test "x$TIMESTAMP" = "x%s"; then + # date +%s not available on this Solaris, use workaround from nawk(1): + TIMESTAMP=`nawk 'BEGIN{print srand()}'` + fi else TIMESTAMP=`date +%s` fi From b3fe91a8039a06a283a5e2f6c5ce3109a2bfc4ab Mon Sep 17 00:00:00 2001 From: Morris Meyer Date: Mon, 7 Jan 2013 14:08:28 -0800 Subject: [PATCH 039/204] 8004537: replace AbstractAssembler emit_long with emit_int32 Reviewed-by: jrose, kvn, twisti --- hotspot/src/cpu/sparc/vm/assembler_sparc.hpp | 372 +++++++++--------- .../cpu/sparc/vm/assembler_sparc.inline.hpp | 74 ++-- .../src/cpu/sparc/vm/cppInterpreter_sparc.cpp | 6 +- .../src/cpu/sparc/vm/macroAssembler_sparc.cpp | 4 +- .../sparc/vm/templateInterpreter_sparc.cpp | 2 +- hotspot/src/cpu/x86/vm/assembler_x86.cpp | 50 +-- hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp | 2 +- hotspot/src/share/vm/asm/assembler.hpp | 2 - 8 files changed, 255 insertions(+), 257 deletions(-) diff --git a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp index 6e4812abcd4..5541eb865b2 100644 --- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp +++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp @@ -675,8 +675,8 @@ public: AbstractAssembler::flush(); } - inline void emit_long(int); // shadows AbstractAssembler::emit_long - inline void emit_data(int x) { emit_long(x); } + inline void emit_int32(int); // shadows AbstractAssembler::emit_int32 + inline void emit_data(int x) { emit_int32(x); } inline void emit_data(int, RelocationHolder const&); inline void emit_data(int, relocInfo::relocType rtype); // helper for above fcns @@ -691,12 +691,12 @@ public: inline void add(Register s1, Register s2, Register d ); inline void add(Register s1, int simm13a, Register d ); - void addcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(add_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } - void addcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(add_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void addc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 ) | rs1(s1) | rs2(s2) ); } - void addc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void addccc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } - void addccc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void addcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(add_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } + void addcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(add_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void addc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(addc_op3 ) | rs1(s1) | rs2(s2) ); } + void addc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(addc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void addccc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(addc_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } + void addccc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(addc_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 136 @@ -749,76 +749,76 @@ public: // at address s1 is swapped with the data in d. If the values are not equal, // the the contents of memory at s1 is loaded into d, without the swap. - void casa( Register s1, Register s2, Register d, int ia = -1 ) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(casa_op3 ) | rs1(s1) | (ia == -1 ? immed(true) : imm_asi(ia)) | rs2(s2)); } - void casxa( Register s1, Register s2, Register d, int ia = -1 ) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(casxa_op3) | rs1(s1) | (ia == -1 ? immed(true) : imm_asi(ia)) | rs2(s2)); } + void casa( Register s1, Register s2, Register d, int ia = -1 ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(casa_op3 ) | rs1(s1) | (ia == -1 ? immed(true) : imm_asi(ia)) | rs2(s2)); } + void casxa( Register s1, Register s2, Register d, int ia = -1 ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(casxa_op3) | rs1(s1) | (ia == -1 ? immed(true) : imm_asi(ia)) | rs2(s2)); } // pp 152 - void udiv( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(udiv_op3 ) | rs1(s1) | rs2(s2)); } - void udiv( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(udiv_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void sdiv( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sdiv_op3 ) | rs1(s1) | rs2(s2)); } - void sdiv( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sdiv_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void udivcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(udiv_op3 | cc_bit_op3) | rs1(s1) | rs2(s2)); } - void udivcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(udiv_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void sdivcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sdiv_op3 | cc_bit_op3) | rs1(s1) | rs2(s2)); } - void sdivcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sdiv_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void udiv( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(udiv_op3 ) | rs1(s1) | rs2(s2)); } + void udiv( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(udiv_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void sdiv( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sdiv_op3 ) | rs1(s1) | rs2(s2)); } + void sdiv( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sdiv_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void udivcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(udiv_op3 | cc_bit_op3) | rs1(s1) | rs2(s2)); } + void udivcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(udiv_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void sdivcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sdiv_op3 | cc_bit_op3) | rs1(s1) | rs2(s2)); } + void sdivcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sdiv_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 155 - void done() { v9_only(); cti(); emit_long( op(arith_op) | fcn(0) | op3(done_op3) ); } - void retry() { v9_only(); cti(); emit_long( op(arith_op) | fcn(1) | op3(retry_op3) ); } + void done() { v9_only(); cti(); emit_int32( op(arith_op) | fcn(0) | op3(done_op3) ); } + void retry() { v9_only(); cti(); emit_int32( op(arith_op) | fcn(1) | op3(retry_op3) ); } // pp 156 - void fadd( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | fs1(s1, w) | opf(0x40 + w) | fs2(s2, w)); } - void fsub( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | fs1(s1, w) | opf(0x44 + w) | fs2(s2, w)); } + void fadd( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | fs1(s1, w) | opf(0x40 + w) | fs2(s2, w)); } + void fsub( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | fs1(s1, w) | opf(0x44 + w) | fs2(s2, w)); } // pp 157 - void fcmp( FloatRegisterImpl::Width w, CC cc, FloatRegister s1, FloatRegister s2) { v8_no_cc(cc); emit_long( op(arith_op) | cmpcc(cc) | op3(fpop2_op3) | fs1(s1, w) | opf(0x50 + w) | fs2(s2, w)); } - void fcmpe( FloatRegisterImpl::Width w, CC cc, FloatRegister s1, FloatRegister s2) { v8_no_cc(cc); emit_long( op(arith_op) | cmpcc(cc) | op3(fpop2_op3) | fs1(s1, w) | opf(0x54 + w) | fs2(s2, w)); } + void fcmp( FloatRegisterImpl::Width w, CC cc, FloatRegister s1, FloatRegister s2) { v8_no_cc(cc); emit_int32( op(arith_op) | cmpcc(cc) | op3(fpop2_op3) | fs1(s1, w) | opf(0x50 + w) | fs2(s2, w)); } + void fcmpe( FloatRegisterImpl::Width w, CC cc, FloatRegister s1, FloatRegister s2) { v8_no_cc(cc); emit_int32( op(arith_op) | cmpcc(cc) | op3(fpop2_op3) | fs1(s1, w) | opf(0x54 + w) | fs2(s2, w)); } // pp 159 - void ftox( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v9_only(); emit_long( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(fpop1_op3) | opf(0x80 + w) | fs2(s, w)); } - void ftoi( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_long( op(arith_op) | fd(d, FloatRegisterImpl::S) | op3(fpop1_op3) | opf(0xd0 + w) | fs2(s, w)); } + void ftox( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v9_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(fpop1_op3) | opf(0x80 + w) | fs2(s, w)); } + void ftoi( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::S) | op3(fpop1_op3) | opf(0xd0 + w) | fs2(s, w)); } // pp 160 - void ftof( FloatRegisterImpl::Width sw, FloatRegisterImpl::Width dw, FloatRegister s, FloatRegister d ) { emit_long( op(arith_op) | fd(d, dw) | op3(fpop1_op3) | opf(0xc0 + sw + dw*4) | fs2(s, sw)); } + void ftof( FloatRegisterImpl::Width sw, FloatRegisterImpl::Width dw, FloatRegister s, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, dw) | op3(fpop1_op3) | opf(0xc0 + sw + dw*4) | fs2(s, sw)); } // pp 161 - void fxtof( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v9_only(); emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x80 + w*4) | fs2(s, FloatRegisterImpl::D)); } - void fitof( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0xc0 + w*4) | fs2(s, FloatRegisterImpl::S)); } + void fxtof( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v9_only(); emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x80 + w*4) | fs2(s, FloatRegisterImpl::D)); } + void fitof( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0xc0 + w*4) | fs2(s, FloatRegisterImpl::S)); } // pp 162 - void fmov( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v8_s_only(w); emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x00 + w) | fs2(s, w)); } + void fmov( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v8_s_only(w); emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x00 + w) | fs2(s, w)); } - void fneg( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v8_s_only(w); emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x04 + w) | fs2(s, w)); } + void fneg( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v8_s_only(w); emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x04 + w) | fs2(s, w)); } // page 144 sparc v8 architecture (double prec works on v8 if the source and destination registers are the same). fnegs is the only instruction available // on v8 to do negation of single, double and quad precision floats. - void fneg( FloatRegisterImpl::Width w, FloatRegister sd ) { if (VM_Version::v9_instructions_work()) emit_long( op(arith_op) | fd(sd, w) | op3(fpop1_op3) | opf(0x04 + w) | fs2(sd, w)); else emit_long( op(arith_op) | fd(sd, w) | op3(fpop1_op3) | opf(0x05) | fs2(sd, w)); } + void fneg( FloatRegisterImpl::Width w, FloatRegister sd ) { if (VM_Version::v9_instructions_work()) emit_int32( op(arith_op) | fd(sd, w) | op3(fpop1_op3) | opf(0x04 + w) | fs2(sd, w)); else emit_int32( op(arith_op) | fd(sd, w) | op3(fpop1_op3) | opf(0x05) | fs2(sd, w)); } - void fabs( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v8_s_only(w); emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x08 + w) | fs2(s, w)); } + void fabs( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v8_s_only(w); emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x08 + w) | fs2(s, w)); } // page 144 sparc v8 architecture (double prec works on v8 if the source and destination registers are the same). fabss is the only instruction available // on v8 to do abs operation on single/double/quad precision floats. - void fabs( FloatRegisterImpl::Width w, FloatRegister sd ) { if (VM_Version::v9_instructions_work()) emit_long( op(arith_op) | fd(sd, w) | op3(fpop1_op3) | opf(0x08 + w) | fs2(sd, w)); else emit_long( op(arith_op) | fd(sd, w) | op3(fpop1_op3) | opf(0x09) | fs2(sd, w)); } + void fabs( FloatRegisterImpl::Width w, FloatRegister sd ) { if (VM_Version::v9_instructions_work()) emit_int32( op(arith_op) | fd(sd, w) | op3(fpop1_op3) | opf(0x08 + w) | fs2(sd, w)); else emit_int32( op(arith_op) | fd(sd, w) | op3(fpop1_op3) | opf(0x09) | fs2(sd, w)); } // pp 163 - void fmul( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | fs1(s1, w) | opf(0x48 + w) | fs2(s2, w)); } - void fmul( FloatRegisterImpl::Width sw, FloatRegisterImpl::Width dw, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_long( op(arith_op) | fd(d, dw) | op3(fpop1_op3) | fs1(s1, sw) | opf(0x60 + sw + dw*4) | fs2(s2, sw)); } - void fdiv( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | fs1(s1, w) | opf(0x4c + w) | fs2(s2, w)); } + void fmul( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | fs1(s1, w) | opf(0x48 + w) | fs2(s2, w)); } + void fmul( FloatRegisterImpl::Width sw, FloatRegisterImpl::Width dw, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, dw) | op3(fpop1_op3) | fs1(s1, sw) | opf(0x60 + sw + dw*4) | fs2(s2, sw)); } + void fdiv( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | fs1(s1, w) | opf(0x4c + w) | fs2(s2, w)); } // pp 164 - void fsqrt( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x28 + w) | fs2(s, w)); } + void fsqrt( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x28 + w) | fs2(s, w)); } // pp 165 @@ -827,22 +827,22 @@ public: // pp 167 - void flushw() { v9_only(); emit_long( op(arith_op) | op3(flushw_op3) ); } + void flushw() { v9_only(); emit_int32( op(arith_op) | op3(flushw_op3) ); } // pp 168 - void illtrap( int const22a) { if (const22a != 0) v9_only(); emit_long( op(branch_op) | u_field(const22a, 21, 0) ); } + void illtrap( int const22a) { if (const22a != 0) v9_only(); emit_int32( op(branch_op) | u_field(const22a, 21, 0) ); } // v8 unimp == illtrap(0) // pp 169 - void impdep1( int id1, int const19a ) { v9_only(); emit_long( op(arith_op) | fcn(id1) | op3(impdep1_op3) | u_field(const19a, 18, 0)); } - void impdep2( int id1, int const19a ) { v9_only(); emit_long( op(arith_op) | fcn(id1) | op3(impdep2_op3) | u_field(const19a, 18, 0)); } + void impdep1( int id1, int const19a ) { v9_only(); emit_int32( op(arith_op) | fcn(id1) | op3(impdep1_op3) | u_field(const19a, 18, 0)); } + void impdep2( int id1, int const19a ) { v9_only(); emit_int32( op(arith_op) | fcn(id1) | op3(impdep2_op3) | u_field(const19a, 18, 0)); } // pp 149 (v8) - void cpop1( int opc, int cr1, int cr2, int crd ) { v8_only(); emit_long( op(arith_op) | fcn(crd) | op3(impdep1_op3) | u_field(cr1, 18, 14) | opf(opc) | u_field(cr2, 4, 0)); } - void cpop2( int opc, int cr1, int cr2, int crd ) { v8_only(); emit_long( op(arith_op) | fcn(crd) | op3(impdep2_op3) | u_field(cr1, 18, 14) | opf(opc) | u_field(cr2, 4, 0)); } + void cpop1( int opc, int cr1, int cr2, int crd ) { v8_only(); emit_int32( op(arith_op) | fcn(crd) | op3(impdep1_op3) | u_field(cr1, 18, 14) | opf(opc) | u_field(cr2, 4, 0)); } + void cpop2( int opc, int cr1, int cr2, int crd ) { v8_only(); emit_int32( op(arith_op) | fcn(crd) | op3(impdep2_op3) | u_field(cr1, 18, 14) | opf(opc) | u_field(cr2, 4, 0)); } // pp 170 @@ -872,8 +872,8 @@ public: // 173 - void ldfa( FloatRegisterImpl::Width w, Register s1, Register s2, int ia, FloatRegister d ) { v9_only(); emit_long( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3 | alt_bit_op3, w) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void ldfa( FloatRegisterImpl::Width w, Register s1, int simm13a, FloatRegister d ) { v9_only(); emit_long( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3 | alt_bit_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void ldfa( FloatRegisterImpl::Width w, Register s1, Register s2, int ia, FloatRegister d ) { v9_only(); emit_int32( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3 | alt_bit_op3, w) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void ldfa( FloatRegisterImpl::Width w, Register s1, int simm13a, FloatRegister d ) { v9_only(); emit_int32( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3 | alt_bit_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 175, lduw is ld on v8 @@ -896,22 +896,22 @@ public: // pp 177 - void ldsba( Register s1, Register s2, int ia, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldsb_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void ldsba( Register s1, int simm13a, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldsb_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void ldsha( Register s1, Register s2, int ia, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldsh_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void ldsha( Register s1, int simm13a, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldsh_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void ldswa( Register s1, Register s2, int ia, Register d ) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(ldsw_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void ldswa( Register s1, int simm13a, Register d ) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(ldsw_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void lduba( Register s1, Register s2, int ia, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldub_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void lduba( Register s1, int simm13a, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldub_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void lduha( Register s1, Register s2, int ia, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(lduh_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void lduha( Register s1, int simm13a, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(lduh_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void lduwa( Register s1, Register s2, int ia, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(lduw_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void lduwa( Register s1, int simm13a, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(lduw_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void ldxa( Register s1, Register s2, int ia, Register d ) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(ldx_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void ldxa( Register s1, int simm13a, Register d ) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(ldx_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void ldda( Register s1, Register s2, int ia, Register d ) { v9_dep(); emit_long( op(ldst_op) | rd(d) | op3(ldd_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void ldda( Register s1, int simm13a, Register d ) { v9_dep(); emit_long( op(ldst_op) | rd(d) | op3(ldd_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void ldsba( Register s1, Register s2, int ia, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(ldsb_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void ldsba( Register s1, int simm13a, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(ldsb_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void ldsha( Register s1, Register s2, int ia, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(ldsh_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void ldsha( Register s1, int simm13a, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(ldsh_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void ldswa( Register s1, Register s2, int ia, Register d ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(ldsw_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void ldswa( Register s1, int simm13a, Register d ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(ldsw_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void lduba( Register s1, Register s2, int ia, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(ldub_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void lduba( Register s1, int simm13a, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(ldub_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void lduha( Register s1, Register s2, int ia, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(lduh_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void lduha( Register s1, int simm13a, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(lduh_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void lduwa( Register s1, Register s2, int ia, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(lduw_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void lduwa( Register s1, int simm13a, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(lduw_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void ldxa( Register s1, Register s2, int ia, Register d ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(ldx_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void ldxa( Register s1, int simm13a, Register d ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(ldx_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void ldda( Register s1, Register s2, int ia, Register d ) { v9_dep(); emit_int32( op(ldst_op) | rd(d) | op3(ldd_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void ldda( Register s1, int simm13a, Register d ) { v9_dep(); emit_int32( op(ldst_op) | rd(d) | op3(ldd_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 179 @@ -920,111 +920,111 @@ public: // pp 180 - void ldstuba( Register s1, Register s2, int ia, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldstub_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void ldstuba( Register s1, int simm13a, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldstub_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void ldstuba( Register s1, Register s2, int ia, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(ldstub_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void ldstuba( Register s1, int simm13a, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(ldstub_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 181 - void and3( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(and_op3 ) | rs1(s1) | rs2(s2) ); } - void and3( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(and_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void andcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(and_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } - void andcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(and_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void andn( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(andn_op3 ) | rs1(s1) | rs2(s2) ); } - void andn( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(andn_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void andncc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(andn_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } - void andncc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(andn_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void or3( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(or_op3 ) | rs1(s1) | rs2(s2) ); } - void or3( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(or_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void orcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(or_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } - void orcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(or_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void orn( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(orn_op3) | rs1(s1) | rs2(s2) ); } - void orn( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(orn_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void orncc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(orn_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } - void orncc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(orn_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void xor3( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(xor_op3 ) | rs1(s1) | rs2(s2) ); } - void xor3( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(xor_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void xorcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(xor_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } - void xorcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(xor_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void xnor( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(xnor_op3 ) | rs1(s1) | rs2(s2) ); } - void xnor( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(xnor_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void xnorcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(xnor_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } - void xnorcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(xnor_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void and3( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(and_op3 ) | rs1(s1) | rs2(s2) ); } + void and3( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(and_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void andcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(and_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } + void andcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(and_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void andn( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(andn_op3 ) | rs1(s1) | rs2(s2) ); } + void andn( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(andn_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void andncc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(andn_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } + void andncc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(andn_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void or3( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(or_op3 ) | rs1(s1) | rs2(s2) ); } + void or3( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(or_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void orcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(or_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } + void orcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(or_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void orn( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(orn_op3) | rs1(s1) | rs2(s2) ); } + void orn( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(orn_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void orncc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(orn_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } + void orncc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(orn_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void xor3( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(xor_op3 ) | rs1(s1) | rs2(s2) ); } + void xor3( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(xor_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void xorcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(xor_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } + void xorcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(xor_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void xnor( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(xnor_op3 ) | rs1(s1) | rs2(s2) ); } + void xnor( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(xnor_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void xnorcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(xnor_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } + void xnorcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(xnor_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 183 - void membar( Membar_mask_bits const7a ) { v9_only(); emit_long( op(arith_op) | op3(membar_op3) | rs1(O7) | immed(true) | u_field( int(const7a), 6, 0)); } + void membar( Membar_mask_bits const7a ) { v9_only(); emit_int32( op(arith_op) | op3(membar_op3) | rs1(O7) | immed(true) | u_field( int(const7a), 6, 0)); } // pp 185 - void fmov( FloatRegisterImpl::Width w, Condition c, bool floatCC, CC cca, FloatRegister s2, FloatRegister d ) { v9_only(); emit_long( op(arith_op) | fd(d, w) | op3(fpop2_op3) | cond_mov(c) | opf_cc(cca, floatCC) | opf_low6(w) | fs2(s2, w)); } + void fmov( FloatRegisterImpl::Width w, Condition c, bool floatCC, CC cca, FloatRegister s2, FloatRegister d ) { v9_only(); emit_int32( op(arith_op) | fd(d, w) | op3(fpop2_op3) | cond_mov(c) | opf_cc(cca, floatCC) | opf_low6(w) | fs2(s2, w)); } // pp 189 - void fmov( FloatRegisterImpl::Width w, RCondition c, Register s1, FloatRegister s2, FloatRegister d ) { v9_only(); emit_long( op(arith_op) | fd(d, w) | op3(fpop2_op3) | rs1(s1) | rcond(c) | opf_low5(4 + w) | fs2(s2, w)); } + void fmov( FloatRegisterImpl::Width w, RCondition c, Register s1, FloatRegister s2, FloatRegister d ) { v9_only(); emit_int32( op(arith_op) | fd(d, w) | op3(fpop2_op3) | rs1(s1) | rcond(c) | opf_low5(4 + w) | fs2(s2, w)); } // pp 191 - void movcc( Condition c, bool floatCC, CC cca, Register s2, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(movcc_op3) | mov_cc(cca, floatCC) | cond_mov(c) | rs2(s2) ); } - void movcc( Condition c, bool floatCC, CC cca, int simm11a, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(movcc_op3) | mov_cc(cca, floatCC) | cond_mov(c) | immed(true) | simm(simm11a, 11) ); } + void movcc( Condition c, bool floatCC, CC cca, Register s2, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(movcc_op3) | mov_cc(cca, floatCC) | cond_mov(c) | rs2(s2) ); } + void movcc( Condition c, bool floatCC, CC cca, int simm11a, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(movcc_op3) | mov_cc(cca, floatCC) | cond_mov(c) | immed(true) | simm(simm11a, 11) ); } // pp 195 - void movr( RCondition c, Register s1, Register s2, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(movr_op3) | rs1(s1) | rcond(c) | rs2(s2) ); } - void movr( RCondition c, Register s1, int simm10a, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(movr_op3) | rs1(s1) | rcond(c) | immed(true) | simm(simm10a, 10) ); } + void movr( RCondition c, Register s1, Register s2, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(movr_op3) | rs1(s1) | rcond(c) | rs2(s2) ); } + void movr( RCondition c, Register s1, int simm10a, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(movr_op3) | rs1(s1) | rcond(c) | immed(true) | simm(simm10a, 10) ); } // pp 196 - void mulx( Register s1, Register s2, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(mulx_op3 ) | rs1(s1) | rs2(s2) ); } - void mulx( Register s1, int simm13a, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(mulx_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void sdivx( Register s1, Register s2, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(sdivx_op3) | rs1(s1) | rs2(s2) ); } - void sdivx( Register s1, int simm13a, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(sdivx_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void udivx( Register s1, Register s2, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(udivx_op3) | rs1(s1) | rs2(s2) ); } - void udivx( Register s1, int simm13a, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(udivx_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void mulx( Register s1, Register s2, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(mulx_op3 ) | rs1(s1) | rs2(s2) ); } + void mulx( Register s1, int simm13a, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(mulx_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void sdivx( Register s1, Register s2, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(sdivx_op3) | rs1(s1) | rs2(s2) ); } + void sdivx( Register s1, int simm13a, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(sdivx_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void udivx( Register s1, Register s2, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(udivx_op3) | rs1(s1) | rs2(s2) ); } + void udivx( Register s1, int simm13a, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(udivx_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 197 - void umul( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(umul_op3 ) | rs1(s1) | rs2(s2) ); } - void umul( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(umul_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void smul( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(smul_op3 ) | rs1(s1) | rs2(s2) ); } - void smul( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(smul_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void umulcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(umul_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } - void umulcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(umul_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void smulcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(smul_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } - void smulcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(smul_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void umul( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(umul_op3 ) | rs1(s1) | rs2(s2) ); } + void umul( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(umul_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void smul( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(smul_op3 ) | rs1(s1) | rs2(s2) ); } + void smul( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(smul_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void umulcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(umul_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } + void umulcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(umul_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void smulcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(smul_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } + void smulcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(smul_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 199 - void mulscc( Register s1, Register s2, Register d ) { v9_dep(); emit_long( op(arith_op) | rd(d) | op3(mulscc_op3) | rs1(s1) | rs2(s2) ); } - void mulscc( Register s1, int simm13a, Register d ) { v9_dep(); emit_long( op(arith_op) | rd(d) | op3(mulscc_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void mulscc( Register s1, Register s2, Register d ) { v9_dep(); emit_int32( op(arith_op) | rd(d) | op3(mulscc_op3) | rs1(s1) | rs2(s2) ); } + void mulscc( Register s1, int simm13a, Register d ) { v9_dep(); emit_int32( op(arith_op) | rd(d) | op3(mulscc_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 201 - void nop() { emit_long( op(branch_op) | op2(sethi_op2) ); } + void nop() { emit_int32( op(branch_op) | op2(sethi_op2) ); } // pp 202 - void popc( Register s, Register d) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(popc_op3) | rs2(s)); } - void popc( int simm13a, Register d) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(popc_op3) | immed(true) | simm(simm13a, 13)); } + void popc( Register s, Register d) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(popc_op3) | rs2(s)); } + void popc( int simm13a, Register d) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(popc_op3) | immed(true) | simm(simm13a, 13)); } // pp 203 - void prefetch( Register s1, Register s2, PrefetchFcn f) { v9_only(); emit_long( op(ldst_op) | fcn(f) | op3(prefetch_op3) | rs1(s1) | rs2(s2) ); } + void prefetch( Register s1, Register s2, PrefetchFcn f) { v9_only(); emit_int32( op(ldst_op) | fcn(f) | op3(prefetch_op3) | rs1(s1) | rs2(s2) ); } void prefetch( Register s1, int simm13a, PrefetchFcn f) { v9_only(); emit_data( op(ldst_op) | fcn(f) | op3(prefetch_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } - void prefetcha( Register s1, Register s2, int ia, PrefetchFcn f ) { v9_only(); emit_long( op(ldst_op) | fcn(f) | op3(prefetch_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void prefetcha( Register s1, int simm13a, PrefetchFcn f ) { v9_only(); emit_long( op(ldst_op) | fcn(f) | op3(prefetch_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void prefetcha( Register s1, Register s2, int ia, PrefetchFcn f ) { v9_only(); emit_int32( op(ldst_op) | fcn(f) | op3(prefetch_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void prefetcha( Register s1, int simm13a, PrefetchFcn f ) { v9_only(); emit_int32( op(ldst_op) | fcn(f) | op3(prefetch_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 208 // not implementing read privileged register - inline void rdy( Register d) { v9_dep(); emit_long( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(0, 18, 14)); } - inline void rdccr( Register d) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(2, 18, 14)); } - inline void rdasi( Register d) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(3, 18, 14)); } - inline void rdtick( Register d) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(4, 18, 14)); } // Spoon! - inline void rdpc( Register d) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(5, 18, 14)); } - inline void rdfprs( Register d) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(6, 18, 14)); } + inline void rdy( Register d) { v9_dep(); emit_int32( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(0, 18, 14)); } + inline void rdccr( Register d) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(2, 18, 14)); } + inline void rdasi( Register d) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(3, 18, 14)); } + inline void rdtick( Register d) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(4, 18, 14)); } // Spoon! + inline void rdpc( Register d) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(5, 18, 14)); } + inline void rdfprs( Register d) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(6, 18, 14)); } // pp 213 @@ -1033,47 +1033,47 @@ public: // pp 214 - void save( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(save_op3) | rs1(s1) | rs2(s2) ); } + void save( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(save_op3) | rs1(s1) | rs2(s2) ); } void save( Register s1, int simm13a, Register d ) { // make sure frame is at least large enough for the register save area assert(-simm13a >= 16 * wordSize, "frame too small"); - emit_long( op(arith_op) | rd(d) | op3(save_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); + emit_int32( op(arith_op) | rd(d) | op3(save_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void restore( Register s1 = G0, Register s2 = G0, Register d = G0 ) { emit_long( op(arith_op) | rd(d) | op3(restore_op3) | rs1(s1) | rs2(s2) ); } - void restore( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(restore_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void restore( Register s1 = G0, Register s2 = G0, Register d = G0 ) { emit_int32( op(arith_op) | rd(d) | op3(restore_op3) | rs1(s1) | rs2(s2) ); } + void restore( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(restore_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 216 - void saved() { v9_only(); emit_long( op(arith_op) | fcn(0) | op3(saved_op3)); } - void restored() { v9_only(); emit_long( op(arith_op) | fcn(1) | op3(saved_op3)); } + void saved() { v9_only(); emit_int32( op(arith_op) | fcn(0) | op3(saved_op3)); } + void restored() { v9_only(); emit_int32( op(arith_op) | fcn(1) | op3(saved_op3)); } // pp 217 inline void sethi( int imm22a, Register d, RelocationHolder const& rspec = RelocationHolder() ); // pp 218 - void sll( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sll_op3) | rs1(s1) | sx(0) | rs2(s2) ); } - void sll( Register s1, int imm5a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sll_op3) | rs1(s1) | sx(0) | immed(true) | u_field(imm5a, 4, 0) ); } - void srl( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(srl_op3) | rs1(s1) | sx(0) | rs2(s2) ); } - void srl( Register s1, int imm5a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(srl_op3) | rs1(s1) | sx(0) | immed(true) | u_field(imm5a, 4, 0) ); } - void sra( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sra_op3) | rs1(s1) | sx(0) | rs2(s2) ); } - void sra( Register s1, int imm5a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sra_op3) | rs1(s1) | sx(0) | immed(true) | u_field(imm5a, 4, 0) ); } + void sll( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sll_op3) | rs1(s1) | sx(0) | rs2(s2) ); } + void sll( Register s1, int imm5a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sll_op3) | rs1(s1) | sx(0) | immed(true) | u_field(imm5a, 4, 0) ); } + void srl( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(srl_op3) | rs1(s1) | sx(0) | rs2(s2) ); } + void srl( Register s1, int imm5a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(srl_op3) | rs1(s1) | sx(0) | immed(true) | u_field(imm5a, 4, 0) ); } + void sra( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sra_op3) | rs1(s1) | sx(0) | rs2(s2) ); } + void sra( Register s1, int imm5a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sra_op3) | rs1(s1) | sx(0) | immed(true) | u_field(imm5a, 4, 0) ); } - void sllx( Register s1, Register s2, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(sll_op3) | rs1(s1) | sx(1) | rs2(s2) ); } - void sllx( Register s1, int imm6a, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(sll_op3) | rs1(s1) | sx(1) | immed(true) | u_field(imm6a, 5, 0) ); } - void srlx( Register s1, Register s2, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(srl_op3) | rs1(s1) | sx(1) | rs2(s2) ); } - void srlx( Register s1, int imm6a, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(srl_op3) | rs1(s1) | sx(1) | immed(true) | u_field(imm6a, 5, 0) ); } - void srax( Register s1, Register s2, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(sra_op3) | rs1(s1) | sx(1) | rs2(s2) ); } - void srax( Register s1, int imm6a, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(sra_op3) | rs1(s1) | sx(1) | immed(true) | u_field(imm6a, 5, 0) ); } + void sllx( Register s1, Register s2, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(sll_op3) | rs1(s1) | sx(1) | rs2(s2) ); } + void sllx( Register s1, int imm6a, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(sll_op3) | rs1(s1) | sx(1) | immed(true) | u_field(imm6a, 5, 0) ); } + void srlx( Register s1, Register s2, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(srl_op3) | rs1(s1) | sx(1) | rs2(s2) ); } + void srlx( Register s1, int imm6a, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(srl_op3) | rs1(s1) | sx(1) | immed(true) | u_field(imm6a, 5, 0) ); } + void srax( Register s1, Register s2, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(sra_op3) | rs1(s1) | sx(1) | rs2(s2) ); } + void srax( Register s1, int imm6a, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(sra_op3) | rs1(s1) | sx(1) | immed(true) | u_field(imm6a, 5, 0) ); } // pp 220 - void sir( int simm13a ) { emit_long( op(arith_op) | fcn(15) | op3(sir_op3) | immed(true) | simm(simm13a, 13)); } + void sir( int simm13a ) { emit_int32( op(arith_op) | fcn(15) | op3(sir_op3) | immed(true) | simm(simm13a, 13)); } // pp 221 - void stbar() { emit_long( op(arith_op) | op3(membar_op3) | u_field(15, 18, 14)); } + void stbar() { emit_int32( op(arith_op) | op3(membar_op3) | u_field(15, 18, 14)); } // pp 222 @@ -1087,8 +1087,8 @@ public: // pp 224 - void stfa( FloatRegisterImpl::Width w, FloatRegister d, Register s1, Register s2, int ia ) { v9_only(); emit_long( op(ldst_op) | fd(d, w) | alt_op3(stf_op3 | alt_bit_op3, w) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void stfa( FloatRegisterImpl::Width w, FloatRegister d, Register s1, int simm13a ) { v9_only(); emit_long( op(ldst_op) | fd(d, w) | alt_op3(stf_op3 | alt_bit_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void stfa( FloatRegisterImpl::Width w, FloatRegister d, Register s1, Register s2, int ia ) { v9_only(); emit_int32( op(ldst_op) | fd(d, w) | alt_op3(stf_op3 | alt_bit_op3, w) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void stfa( FloatRegisterImpl::Width w, FloatRegister d, Register s1, int simm13a ) { v9_only(); emit_int32( op(ldst_op) | fd(d, w) | alt_op3(stf_op3 | alt_bit_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // p 226 @@ -1105,16 +1105,16 @@ public: // pp 177 - void stba( Register d, Register s1, Register s2, int ia ) { emit_long( op(ldst_op) | rd(d) | op3(stb_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void stba( Register d, Register s1, int simm13a ) { emit_long( op(ldst_op) | rd(d) | op3(stb_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void stha( Register d, Register s1, Register s2, int ia ) { emit_long( op(ldst_op) | rd(d) | op3(sth_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void stha( Register d, Register s1, int simm13a ) { emit_long( op(ldst_op) | rd(d) | op3(sth_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void stwa( Register d, Register s1, Register s2, int ia ) { emit_long( op(ldst_op) | rd(d) | op3(stw_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void stwa( Register d, Register s1, int simm13a ) { emit_long( op(ldst_op) | rd(d) | op3(stw_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void stxa( Register d, Register s1, Register s2, int ia ) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(stx_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void stxa( Register d, Register s1, int simm13a ) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(stx_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void stda( Register d, Register s1, Register s2, int ia ) { emit_long( op(ldst_op) | rd(d) | op3(std_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void stda( Register d, Register s1, int simm13a ) { emit_long( op(ldst_op) | rd(d) | op3(std_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void stba( Register d, Register s1, Register s2, int ia ) { emit_int32( op(ldst_op) | rd(d) | op3(stb_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void stba( Register d, Register s1, int simm13a ) { emit_int32( op(ldst_op) | rd(d) | op3(stb_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void stha( Register d, Register s1, Register s2, int ia ) { emit_int32( op(ldst_op) | rd(d) | op3(sth_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void stha( Register d, Register s1, int simm13a ) { emit_int32( op(ldst_op) | rd(d) | op3(sth_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void stwa( Register d, Register s1, Register s2, int ia ) { emit_int32( op(ldst_op) | rd(d) | op3(stw_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void stwa( Register d, Register s1, int simm13a ) { emit_int32( op(ldst_op) | rd(d) | op3(stw_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void stxa( Register d, Register s1, Register s2, int ia ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(stx_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void stxa( Register d, Register s1, int simm13a ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(stx_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void stda( Register d, Register s1, Register s2, int ia ) { emit_int32( op(ldst_op) | rd(d) | op3(std_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void stda( Register d, Register s1, int simm13a ) { emit_int32( op(ldst_op) | rd(d) | op3(std_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 97 (v8) @@ -1129,15 +1129,15 @@ public: // pp 230 - void sub( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sub_op3 ) | rs1(s1) | rs2(s2) ); } - void sub( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sub_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void sub( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sub_op3 ) | rs1(s1) | rs2(s2) ); } + void sub( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sub_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void subcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sub_op3 | cc_bit_op3 ) | rs1(s1) | rs2(s2) ); } - void subcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sub_op3 | cc_bit_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void subc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(subc_op3 ) | rs1(s1) | rs2(s2) ); } - void subc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(subc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void subccc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(subc_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } - void subccc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(subc_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void subcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sub_op3 | cc_bit_op3 ) | rs1(s1) | rs2(s2) ); } + void subcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sub_op3 | cc_bit_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void subc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(subc_op3 ) | rs1(s1) | rs2(s2) ); } + void subc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(subc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void subccc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(subc_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } + void subccc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(subc_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 231 @@ -1146,55 +1146,55 @@ public: // pp 232 - void swapa( Register s1, Register s2, int ia, Register d ) { v9_dep(); emit_long( op(ldst_op) | rd(d) | op3(swap_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } - void swapa( Register s1, int simm13a, Register d ) { v9_dep(); emit_long( op(ldst_op) | rd(d) | op3(swap_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void swapa( Register s1, Register s2, int ia, Register d ) { v9_dep(); emit_int32( op(ldst_op) | rd(d) | op3(swap_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } + void swapa( Register s1, int simm13a, Register d ) { v9_dep(); emit_int32( op(ldst_op) | rd(d) | op3(swap_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 234, note op in book is wrong, see pp 268 - void taddcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(taddcc_op3 ) | rs1(s1) | rs2(s2) ); } - void taddcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(taddcc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void taddcctv( Register s1, Register s2, Register d ) { v9_dep(); emit_long( op(arith_op) | rd(d) | op3(taddcctv_op3) | rs1(s1) | rs2(s2) ); } - void taddcctv( Register s1, int simm13a, Register d ) { v9_dep(); emit_long( op(arith_op) | rd(d) | op3(taddcctv_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void taddcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(taddcc_op3 ) | rs1(s1) | rs2(s2) ); } + void taddcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(taddcc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void taddcctv( Register s1, Register s2, Register d ) { v9_dep(); emit_int32( op(arith_op) | rd(d) | op3(taddcctv_op3) | rs1(s1) | rs2(s2) ); } + void taddcctv( Register s1, int simm13a, Register d ) { v9_dep(); emit_int32( op(arith_op) | rd(d) | op3(taddcctv_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 235 - void tsubcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(tsubcc_op3 ) | rs1(s1) | rs2(s2) ); } - void tsubcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(tsubcc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } - void tsubcctv( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(tsubcctv_op3) | rs1(s1) | rs2(s2) ); } - void tsubcctv( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(tsubcctv_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void tsubcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(tsubcc_op3 ) | rs1(s1) | rs2(s2) ); } + void tsubcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(tsubcc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } + void tsubcctv( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(tsubcctv_op3) | rs1(s1) | rs2(s2) ); } + void tsubcctv( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(tsubcctv_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } // pp 237 - void trap( Condition c, CC cc, Register s1, Register s2 ) { v8_no_cc(cc); emit_long( op(arith_op) | cond(c) | op3(trap_op3) | rs1(s1) | trapcc(cc) | rs2(s2)); } - void trap( Condition c, CC cc, Register s1, int trapa ) { v8_no_cc(cc); emit_long( op(arith_op) | cond(c) | op3(trap_op3) | rs1(s1) | trapcc(cc) | immed(true) | u_field(trapa, 6, 0)); } + void trap( Condition c, CC cc, Register s1, Register s2 ) { v8_no_cc(cc); emit_int32( op(arith_op) | cond(c) | op3(trap_op3) | rs1(s1) | trapcc(cc) | rs2(s2)); } + void trap( Condition c, CC cc, Register s1, int trapa ) { v8_no_cc(cc); emit_int32( op(arith_op) | cond(c) | op3(trap_op3) | rs1(s1) | trapcc(cc) | immed(true) | u_field(trapa, 6, 0)); } // simple uncond. trap void trap( int trapa ) { trap( always, icc, G0, trapa ); } // pp 239 omit write priv register for now - inline void wry( Register d) { v9_dep(); emit_long( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(0, 29, 25)); } - inline void wrccr(Register s) { v9_only(); emit_long( op(arith_op) | rs1(s) | op3(wrreg_op3) | u_field(2, 29, 25)); } - inline void wrccr(Register s, int simm13a) { v9_only(); emit_long( op(arith_op) | + inline void wry( Register d) { v9_dep(); emit_int32( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(0, 29, 25)); } + inline void wrccr(Register s) { v9_only(); emit_int32( op(arith_op) | rs1(s) | op3(wrreg_op3) | u_field(2, 29, 25)); } + inline void wrccr(Register s, int simm13a) { v9_only(); emit_int32( op(arith_op) | rs1(s) | op3(wrreg_op3) | u_field(2, 29, 25) | immed(true) | simm(simm13a, 13)); } - inline void wrasi(Register d) { v9_only(); emit_long( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(3, 29, 25)); } + inline void wrasi(Register d) { v9_only(); emit_int32( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(3, 29, 25)); } // wrasi(d, imm) stores (d xor imm) to asi - inline void wrasi(Register d, int simm13a) { v9_only(); emit_long( op(arith_op) | rs1(d) | op3(wrreg_op3) | + inline void wrasi(Register d, int simm13a) { v9_only(); emit_int32( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(3, 29, 25) | immed(true) | simm(simm13a, 13)); } - inline void wrfprs( Register d) { v9_only(); emit_long( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(6, 29, 25)); } + inline void wrfprs( Register d) { v9_only(); emit_int32( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(6, 29, 25)); } // VIS3 instructions - void movstosw( FloatRegister s, Register d ) { vis3_only(); emit_long( op(arith_op) | rd(d) | op3(mftoi_op3) | opf(mstosw_opf) | fs2(s, FloatRegisterImpl::S)); } - void movstouw( FloatRegister s, Register d ) { vis3_only(); emit_long( op(arith_op) | rd(d) | op3(mftoi_op3) | opf(mstouw_opf) | fs2(s, FloatRegisterImpl::S)); } - void movdtox( FloatRegister s, Register d ) { vis3_only(); emit_long( op(arith_op) | rd(d) | op3(mftoi_op3) | opf(mdtox_opf) | fs2(s, FloatRegisterImpl::D)); } + void movstosw( FloatRegister s, Register d ) { vis3_only(); emit_int32( op(arith_op) | rd(d) | op3(mftoi_op3) | opf(mstosw_opf) | fs2(s, FloatRegisterImpl::S)); } + void movstouw( FloatRegister s, Register d ) { vis3_only(); emit_int32( op(arith_op) | rd(d) | op3(mftoi_op3) | opf(mstouw_opf) | fs2(s, FloatRegisterImpl::S)); } + void movdtox( FloatRegister s, Register d ) { vis3_only(); emit_int32( op(arith_op) | rd(d) | op3(mftoi_op3) | opf(mdtox_opf) | fs2(s, FloatRegisterImpl::D)); } - void movwtos( Register s, FloatRegister d ) { vis3_only(); emit_long( op(arith_op) | fd(d, FloatRegisterImpl::S) | op3(mftoi_op3) | opf(mwtos_opf) | rs2(s)); } - void movxtod( Register s, FloatRegister d ) { vis3_only(); emit_long( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(mftoi_op3) | opf(mxtod_opf) | rs2(s)); } + void movwtos( Register s, FloatRegister d ) { vis3_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::S) | op3(mftoi_op3) | opf(mwtos_opf) | rs2(s)); } + void movxtod( Register s, FloatRegister d ) { vis3_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(mftoi_op3) | opf(mxtod_opf) | rs2(s)); } // Creation Assembler(CodeBuffer* code) : AbstractAssembler(code) { diff --git a/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp b/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp index fac53f2cfd7..23904f9e1f2 100644 --- a/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp +++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp @@ -35,24 +35,24 @@ inline void Assembler::check_delay() { # endif } -inline void Assembler::emit_long(int x) { +inline void Assembler::emit_int32(int x) { check_delay(); - AbstractAssembler::emit_long(x); + AbstractAssembler::emit_int32(x); } inline void Assembler::emit_data(int x, relocInfo::relocType rtype) { relocate(rtype); - emit_long(x); + emit_int32(x); } inline void Assembler::emit_data(int x, RelocationHolder const& rspec) { relocate(rspec); - emit_long(x); + emit_int32(x); } -inline void Assembler::add(Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(add_op3) | rs1(s1) | rs2(s2) ); } -inline void Assembler::add(Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(add_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } +inline void Assembler::add(Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(add_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::add(Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(add_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } inline void Assembler::bpr( RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt ) { v9_only(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(bpr_op2) | wdisp16(intptr_t(d), intptr_t(pc())) | predict(p) | rs1(s1), rt); has_delay_slot(); } inline void Assembler::bpr( RCondition c, bool a, Predict p, Register s1, Label& L) { bpr( c, a, p, s1, target(L)); } @@ -79,93 +79,93 @@ inline void Assembler::cbcond(Condition c, CC cc, Register s1, int simm5, Label& inline void Assembler::call( address d, relocInfo::relocType rt ) { cti(); emit_data( op(call_op) | wdisp(intptr_t(d), intptr_t(pc()), 30), rt); has_delay_slot(); assert(rt != relocInfo::virtual_call_type, "must use virtual_call_Relocation::spec"); } inline void Assembler::call( Label& L, relocInfo::relocType rt ) { call( target(L), rt); } -inline void Assembler::flush( Register s1, Register s2) { emit_long( op(arith_op) | op3(flush_op3) | rs1(s1) | rs2(s2)); } +inline void Assembler::flush( Register s1, Register s2) { emit_int32( op(arith_op) | op3(flush_op3) | rs1(s1) | rs2(s2)); } inline void Assembler::flush( Register s1, int simm13a) { emit_data( op(arith_op) | op3(flush_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::jmpl( Register s1, Register s2, Register d ) { cti(); emit_long( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | rs2(s2)); has_delay_slot(); } +inline void Assembler::jmpl( Register s1, Register s2, Register d ) { cti(); emit_int32( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | rs2(s2)); has_delay_slot(); } inline void Assembler::jmpl( Register s1, int simm13a, Register d, RelocationHolder const& rspec ) { cti(); emit_data( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec); has_delay_slot(); } -inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, Register s2, FloatRegister d) { emit_long( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3, w) | rs1(s1) | rs2(s2) ); } +inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, Register s2, FloatRegister d) { emit_int32( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3, w) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, int simm13a, FloatRegister d, RelocationHolder const& rspec) { emit_data( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec); } -inline void Assembler::ldfsr( Register s1, Register s2) { v9_dep(); emit_long( op(ldst_op) | op3(ldfsr_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::ldfsr( Register s1, Register s2) { v9_dep(); emit_int32( op(ldst_op) | op3(ldfsr_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldfsr( Register s1, int simm13a) { v9_dep(); emit_data( op(ldst_op) | op3(ldfsr_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::ldxfsr( Register s1, Register s2) { v9_only(); emit_long( op(ldst_op) | rd(G1) | op3(ldfsr_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::ldxfsr( Register s1, Register s2) { v9_only(); emit_int32( op(ldst_op) | rd(G1) | op3(ldfsr_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldxfsr( Register s1, int simm13a) { v9_only(); emit_data( op(ldst_op) | rd(G1) | op3(ldfsr_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::ldc( Register s1, Register s2, int crd) { v8_only(); emit_long( op(ldst_op) | fcn(crd) | op3(ldc_op3 ) | rs1(s1) | rs2(s2) ); } +inline void Assembler::ldc( Register s1, Register s2, int crd) { v8_only(); emit_int32( op(ldst_op) | fcn(crd) | op3(ldc_op3 ) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldc( Register s1, int simm13a, int crd) { v8_only(); emit_data( op(ldst_op) | fcn(crd) | op3(ldc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::lddc( Register s1, Register s2, int crd) { v8_only(); emit_long( op(ldst_op) | fcn(crd) | op3(lddc_op3 ) | rs1(s1) | rs2(s2) ); } +inline void Assembler::lddc( Register s1, Register s2, int crd) { v8_only(); emit_int32( op(ldst_op) | fcn(crd) | op3(lddc_op3 ) | rs1(s1) | rs2(s2) ); } inline void Assembler::lddc( Register s1, int simm13a, int crd) { v8_only(); emit_data( op(ldst_op) | fcn(crd) | op3(lddc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::ldcsr( Register s1, Register s2, int crd) { v8_only(); emit_long( op(ldst_op) | fcn(crd) | op3(ldcsr_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::ldcsr( Register s1, Register s2, int crd) { v8_only(); emit_int32( op(ldst_op) | fcn(crd) | op3(ldcsr_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldcsr( Register s1, int simm13a, int crd) { v8_only(); emit_data( op(ldst_op) | fcn(crd) | op3(ldcsr_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::ldsb( Register s1, Register s2, Register d) { emit_long( op(ldst_op) | rd(d) | op3(ldsb_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::ldsb( Register s1, Register s2, Register d) { emit_int32( op(ldst_op) | rd(d) | op3(ldsb_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldsb( Register s1, int simm13a, Register d) { emit_data( op(ldst_op) | rd(d) | op3(ldsb_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::ldsh( Register s1, Register s2, Register d) { emit_long( op(ldst_op) | rd(d) | op3(ldsh_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::ldsh( Register s1, Register s2, Register d) { emit_int32( op(ldst_op) | rd(d) | op3(ldsh_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldsh( Register s1, int simm13a, Register d) { emit_data( op(ldst_op) | rd(d) | op3(ldsh_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::ldsw( Register s1, Register s2, Register d) { emit_long( op(ldst_op) | rd(d) | op3(ldsw_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::ldsw( Register s1, Register s2, Register d) { emit_int32( op(ldst_op) | rd(d) | op3(ldsw_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldsw( Register s1, int simm13a, Register d) { emit_data( op(ldst_op) | rd(d) | op3(ldsw_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::ldub( Register s1, Register s2, Register d) { emit_long( op(ldst_op) | rd(d) | op3(ldub_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::ldub( Register s1, Register s2, Register d) { emit_int32( op(ldst_op) | rd(d) | op3(ldub_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldub( Register s1, int simm13a, Register d) { emit_data( op(ldst_op) | rd(d) | op3(ldub_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::lduh( Register s1, Register s2, Register d) { emit_long( op(ldst_op) | rd(d) | op3(lduh_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::lduh( Register s1, Register s2, Register d) { emit_int32( op(ldst_op) | rd(d) | op3(lduh_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::lduh( Register s1, int simm13a, Register d) { emit_data( op(ldst_op) | rd(d) | op3(lduh_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::lduw( Register s1, Register s2, Register d) { emit_long( op(ldst_op) | rd(d) | op3(lduw_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::lduw( Register s1, Register s2, Register d) { emit_int32( op(ldst_op) | rd(d) | op3(lduw_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::lduw( Register s1, int simm13a, Register d) { emit_data( op(ldst_op) | rd(d) | op3(lduw_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::ldx( Register s1, Register s2, Register d) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(ldx_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::ldx( Register s1, Register s2, Register d) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(ldx_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldx( Register s1, int simm13a, Register d) { v9_only(); emit_data( op(ldst_op) | rd(d) | op3(ldx_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::ldd( Register s1, Register s2, Register d) { v9_dep(); assert(d->is_even(), "not even"); emit_long( op(ldst_op) | rd(d) | op3(ldd_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::ldd( Register s1, Register s2, Register d) { v9_dep(); assert(d->is_even(), "not even"); emit_int32( op(ldst_op) | rd(d) | op3(ldd_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldd( Register s1, int simm13a, Register d) { v9_dep(); assert(d->is_even(), "not even"); emit_data( op(ldst_op) | rd(d) | op3(ldd_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::ldstub( Register s1, Register s2, Register d) { emit_long( op(ldst_op) | rd(d) | op3(ldstub_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::ldstub( Register s1, Register s2, Register d) { emit_int32( op(ldst_op) | rd(d) | op3(ldstub_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::ldstub( Register s1, int simm13a, Register d) { emit_data( op(ldst_op) | rd(d) | op3(ldstub_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::rett( Register s1, Register s2 ) { cti(); emit_long( op(arith_op) | op3(rett_op3) | rs1(s1) | rs2(s2)); has_delay_slot(); } +inline void Assembler::rett( Register s1, Register s2 ) { cti(); emit_int32( op(arith_op) | op3(rett_op3) | rs1(s1) | rs2(s2)); has_delay_slot(); } inline void Assembler::rett( Register s1, int simm13a, relocInfo::relocType rt) { cti(); emit_data( op(arith_op) | op3(rett_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rt); has_delay_slot(); } inline void Assembler::sethi( int imm22a, Register d, RelocationHolder const& rspec ) { emit_data( op(branch_op) | rd(d) | op2(sethi_op2) | hi22(imm22a), rspec); } // pp 222 -inline void Assembler::stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, Register s2) { emit_long( op(ldst_op) | fd(d, w) | alt_op3(stf_op3, w) | rs1(s1) | rs2(s2) ); } +inline void Assembler::stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, Register s2) { emit_int32( op(ldst_op) | fd(d, w) | alt_op3(stf_op3, w) | rs1(s1) | rs2(s2) ); } inline void Assembler::stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, int simm13a) { emit_data( op(ldst_op) | fd(d, w) | alt_op3(stf_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::stfsr( Register s1, Register s2) { v9_dep(); emit_long( op(ldst_op) | op3(stfsr_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::stfsr( Register s1, Register s2) { v9_dep(); emit_int32( op(ldst_op) | op3(stfsr_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::stfsr( Register s1, int simm13a) { v9_dep(); emit_data( op(ldst_op) | op3(stfsr_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::stxfsr( Register s1, Register s2) { v9_only(); emit_long( op(ldst_op) | rd(G1) | op3(stfsr_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::stxfsr( Register s1, Register s2) { v9_only(); emit_int32( op(ldst_op) | rd(G1) | op3(stfsr_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::stxfsr( Register s1, int simm13a) { v9_only(); emit_data( op(ldst_op) | rd(G1) | op3(stfsr_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } // p 226 -inline void Assembler::stb( Register d, Register s1, Register s2) { emit_long( op(ldst_op) | rd(d) | op3(stb_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::stb( Register d, Register s1, Register s2) { emit_int32( op(ldst_op) | rd(d) | op3(stb_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::stb( Register d, Register s1, int simm13a) { emit_data( op(ldst_op) | rd(d) | op3(stb_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::sth( Register d, Register s1, Register s2) { emit_long( op(ldst_op) | rd(d) | op3(sth_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::sth( Register d, Register s1, Register s2) { emit_int32( op(ldst_op) | rd(d) | op3(sth_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::sth( Register d, Register s1, int simm13a) { emit_data( op(ldst_op) | rd(d) | op3(sth_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::stw( Register d, Register s1, Register s2) { emit_long( op(ldst_op) | rd(d) | op3(stw_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::stw( Register d, Register s1, Register s2) { emit_int32( op(ldst_op) | rd(d) | op3(stw_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::stw( Register d, Register s1, int simm13a) { emit_data( op(ldst_op) | rd(d) | op3(stw_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::stx( Register d, Register s1, Register s2) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(stx_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::stx( Register d, Register s1, Register s2) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(stx_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::stx( Register d, Register s1, int simm13a) { v9_only(); emit_data( op(ldst_op) | rd(d) | op3(stx_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::std( Register d, Register s1, Register s2) { v9_dep(); assert(d->is_even(), "not even"); emit_long( op(ldst_op) | rd(d) | op3(std_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::std( Register d, Register s1, Register s2) { v9_dep(); assert(d->is_even(), "not even"); emit_int32( op(ldst_op) | rd(d) | op3(std_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::std( Register d, Register s1, int simm13a) { v9_dep(); assert(d->is_even(), "not even"); emit_data( op(ldst_op) | rd(d) | op3(std_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } // v8 p 99 -inline void Assembler::stc( int crd, Register s1, Register s2) { v8_only(); emit_long( op(ldst_op) | fcn(crd) | op3(stc_op3 ) | rs1(s1) | rs2(s2) ); } +inline void Assembler::stc( int crd, Register s1, Register s2) { v8_only(); emit_int32( op(ldst_op) | fcn(crd) | op3(stc_op3 ) | rs1(s1) | rs2(s2) ); } inline void Assembler::stc( int crd, Register s1, int simm13a) { v8_only(); emit_data( op(ldst_op) | fcn(crd) | op3(stc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::stdc( int crd, Register s1, Register s2) { v8_only(); emit_long( op(ldst_op) | fcn(crd) | op3(stdc_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::stdc( int crd, Register s1, Register s2) { v8_only(); emit_int32( op(ldst_op) | fcn(crd) | op3(stdc_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::stdc( int crd, Register s1, int simm13a) { v8_only(); emit_data( op(ldst_op) | fcn(crd) | op3(stdc_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::stcsr( int crd, Register s1, Register s2) { v8_only(); emit_long( op(ldst_op) | fcn(crd) | op3(stcsr_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::stcsr( int crd, Register s1, Register s2) { v8_only(); emit_int32( op(ldst_op) | fcn(crd) | op3(stcsr_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::stcsr( int crd, Register s1, int simm13a) { v8_only(); emit_data( op(ldst_op) | fcn(crd) | op3(stcsr_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::stdcq( int crd, Register s1, Register s2) { v8_only(); emit_long( op(ldst_op) | fcn(crd) | op3(stdcq_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::stdcq( int crd, Register s1, Register s2) { v8_only(); emit_int32( op(ldst_op) | fcn(crd) | op3(stdcq_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::stdcq( int crd, Register s1, int simm13a) { v8_only(); emit_data( op(ldst_op) | fcn(crd) | op3(stdcq_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } // pp 231 -inline void Assembler::swap( Register s1, Register s2, Register d) { v9_dep(); emit_long( op(ldst_op) | rd(d) | op3(swap_op3) | rs1(s1) | rs2(s2) ); } +inline void Assembler::swap( Register s1, Register s2, Register d) { v9_dep(); emit_int32( op(ldst_op) | rd(d) | op3(swap_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::swap( Register s1, int simm13a, Register d) { v9_dep(); emit_data( op(ldst_op) | rd(d) | op3(swap_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } #endif // CPU_SPARC_VM_ASSEMBLER_SPARC_INLINE_HPP diff --git a/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp b/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp index 7031597b6cf..6066c2019d5 100644 --- a/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp @@ -137,7 +137,7 @@ address CppInterpreterGenerator::generate_result_handler_for(BasicType type) { } __ ret(); // return from interpreter activation __ delayed()->restore(I5_savedSP, G0, SP); // remove interpreter frame - NOT_PRODUCT(__ emit_long(0);) // marker for disassembly + NOT_PRODUCT(__ emit_int32(0);) // marker for disassembly return entry; } @@ -232,7 +232,7 @@ address CppInterpreterGenerator::generate_tosca_to_stack_converter(BasicType typ } __ retl(); // return from interpreter activation __ delayed()->nop(); // schedule this better - NOT_PRODUCT(__ emit_long(0);) // marker for disassembly + NOT_PRODUCT(__ emit_int32(0);) // marker for disassembly return entry; } @@ -1473,7 +1473,7 @@ static address interpreter_frame_manager = NULL; __ brx(Assembler::equal, false, Assembler::pt, skip); \ __ delayed()->nop(); \ __ breakpoint_trap(); \ - __ emit_long(marker); \ + __ emit_int32(marker); \ __ bind(skip); \ } #else diff --git a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp index ac56573e766..3690a9272e4 100644 --- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp @@ -1224,7 +1224,7 @@ void MacroAssembler::set_narrow_oop(jobject obj, Register d) { // Relocation with special format (see relocInfo_sparc.hpp). relocate(rspec, 1); // Assembler::sethi(0x3fffff, d); - emit_long( op(branch_op) | rd(d) | op2(sethi_op2) | hi22(0x3fffff) ); + emit_int32( op(branch_op) | rd(d) | op2(sethi_op2) | hi22(0x3fffff) ); // Don't add relocation for 'add'. Do patching during 'sethi' processing. add(d, 0x3ff, d); @@ -1240,7 +1240,7 @@ void MacroAssembler::set_narrow_klass(Klass* k, Register d) { // Relocation with special format (see relocInfo_sparc.hpp). relocate(rspec, 1); // Assembler::sethi(encoded_k, d); - emit_long( op(branch_op) | rd(d) | op2(sethi_op2) | hi22(encoded_k) ); + emit_int32( op(branch_op) | rd(d) | op2(sethi_op2) | hi22(encoded_k) ); // Don't add relocation for 'add'. Do patching during 'sethi' processing. add(d, low10(encoded_k), d); diff --git a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp index 0827c0b1a9c..ed46aa9cdc4 100644 --- a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp @@ -259,7 +259,7 @@ address TemplateInterpreterGenerator::generate_result_handler_for(BasicType type } __ ret(); // return from interpreter activation __ delayed()->restore(I5_savedSP, G0, SP); // remove interpreter frame - NOT_PRODUCT(__ emit_long(0);) // marker for disassembly + NOT_PRODUCT(__ emit_int32(0);) // marker for disassembly return entry; } diff --git a/hotspot/src/cpu/x86/vm/assembler_x86.cpp b/hotspot/src/cpu/x86/vm/assembler_x86.cpp index 0104292695d..5ef4cfcf905 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp @@ -182,7 +182,7 @@ int AbstractAssembler::code_fill_byte() { // make this go away someday void Assembler::emit_data(jint data, relocInfo::relocType rtype, int format) { if (rtype == relocInfo::none) - emit_long(data); + emit_int32(data); else emit_data(data, Relocation::spec_simple(rtype), format); } @@ -202,7 +202,7 @@ void Assembler::emit_data(jint data, RelocationHolder const& rspec, int format) else code_section()->relocate(inst_mark(), rspec, format); } - emit_long(data); + emit_int32(data); } static int encode(Register r) { @@ -243,7 +243,7 @@ void Assembler::emit_arith(int op1, int op2, Register dst, int32_t imm32) { } else { emit_int8(op1); emit_int8(op2 | encode(dst)); - emit_long(imm32); + emit_int32(imm32); } } @@ -254,7 +254,7 @@ void Assembler::emit_arith_imm32(int op1, int op2, Register dst, int32_t imm32) assert((op1 & 0x02) == 0, "sign-extension bit should not be set"); emit_int8(op1); emit_int8(op2 | encode(dst)); - emit_long(imm32); + emit_int32(imm32); } // immediate-to-memory forms @@ -268,7 +268,7 @@ void Assembler::emit_arith_operand(int op1, Register rm, Address adr, int32_t im } else { emit_int8(op1); emit_operand(rm, adr, 4); - emit_long(imm32); + emit_int32(imm32); } } @@ -976,7 +976,7 @@ void Assembler::addr_nop_7() { emit_int8(0x1F); emit_int8((unsigned char)0x80); // emit_rm(cbuf, 0x2, EAX_enc, EAX_enc); - emit_long(0); // 32-bits offset (4 bytes) + emit_int32(0); // 32-bits offset (4 bytes) } void Assembler::addr_nop_8() { @@ -987,7 +987,7 @@ void Assembler::addr_nop_8() { emit_int8((unsigned char)0x84); // emit_rm(cbuf, 0x2, EAX_enc, 0x4); emit_int8(0x00); // emit_rm(cbuf, 0x0, EAX_enc, EAX_enc); - emit_long(0); // 32-bits offset (4 bytes) + emit_int32(0); // 32-bits offset (4 bytes) } void Assembler::addsd(XMMRegister dst, XMMRegister src) { @@ -1076,7 +1076,7 @@ void Assembler::andl(Address dst, int32_t imm32) { prefix(dst); emit_int8((unsigned char)0x81); emit_operand(rsp, dst, 4); - emit_long(imm32); + emit_int32(imm32); } void Assembler::andl(Register dst, int32_t imm32) { @@ -1204,7 +1204,7 @@ void Assembler::cmpl(Address dst, int32_t imm32) { prefix(dst); emit_int8((unsigned char)0x81); emit_operand(rdi, dst, 4); - emit_long(imm32); + emit_int32(imm32); } void Assembler::cmpl(Register dst, int32_t imm32) { @@ -1408,7 +1408,7 @@ void Assembler::imull(Register dst, Register src, int value) { } else { emit_int8(0x69); emit_int8((unsigned char)(0xC0 | encode)); - emit_long(value); + emit_int32(value); } } @@ -1440,7 +1440,7 @@ void Assembler::jcc(Condition cc, Label& L, bool maybe_short) { "must be 32bit offset (call4)"); emit_int8(0x0F); emit_int8((unsigned char)(0x80 | cc)); - emit_long(offs - long_size); + emit_int32(offs - long_size); } } else { // Note: could eliminate cond. jumps to this jump if condition @@ -1450,7 +1450,7 @@ void Assembler::jcc(Condition cc, Label& L, bool maybe_short) { L.add_patch_at(code(), locator()); emit_int8(0x0F); emit_int8((unsigned char)(0x80 | cc)); - emit_long(0); + emit_int32(0); } } @@ -1498,7 +1498,7 @@ void Assembler::jmp(Label& L, bool maybe_short) { emit_int8((offs - short_size) & 0xFF); } else { emit_int8((unsigned char)0xE9); - emit_long(offs - long_size); + emit_int32(offs - long_size); } } else { // By default, forward jumps are always 32-bit displacements, since @@ -1508,7 +1508,7 @@ void Assembler::jmp(Label& L, bool maybe_short) { InstructionMark im(this); L.add_patch_at(code(), locator()); emit_int8((unsigned char)0xE9); - emit_long(0); + emit_int32(0); } } @@ -1732,7 +1732,7 @@ void Assembler::vmovdqu(Address dst, XMMRegister src) { void Assembler::movl(Register dst, int32_t imm32) { int encode = prefix_and_encode(dst->encoding()); emit_int8((unsigned char)(0xB8 | encode)); - emit_long(imm32); + emit_int32(imm32); } void Assembler::movl(Register dst, Register src) { @@ -1753,7 +1753,7 @@ void Assembler::movl(Address dst, int32_t imm32) { prefix(dst); emit_int8((unsigned char)0xC7); emit_operand(rax, dst, 4); - emit_long(imm32); + emit_int32(imm32); } void Assembler::movl(Address dst, Register src) { @@ -2499,7 +2499,7 @@ void Assembler::push(int32_t imm32) { // in 64bits we push 64bits onto the stack but only // take a 32bit immediate emit_int8(0x68); - emit_long(imm32); + emit_int32(imm32); } void Assembler::push(Register src) { @@ -2791,7 +2791,7 @@ void Assembler::testl(Register dst, int32_t imm32) { emit_int8((unsigned char)0xF7); emit_int8((unsigned char)(0xC0 | encode)); } - emit_long(imm32); + emit_int32(imm32); } void Assembler::testl(Register dst, Register src) { @@ -4735,7 +4735,7 @@ void Assembler::andq(Address dst, int32_t imm32) { prefixq(dst); emit_int8((unsigned char)0x81); emit_operand(rsp, dst, 4); - emit_long(imm32); + emit_int32(imm32); } void Assembler::andq(Register dst, int32_t imm32) { @@ -4808,7 +4808,7 @@ void Assembler::cmpq(Address dst, int32_t imm32) { prefixq(dst); emit_int8((unsigned char)0x81); emit_operand(rdi, dst, 4); - emit_long(imm32); + emit_int32(imm32); } void Assembler::cmpq(Register dst, int32_t imm32) { @@ -4947,7 +4947,7 @@ void Assembler::imulq(Register dst, Register src, int value) { } else { emit_int8(0x69); emit_int8((unsigned char)(0xC0 | encode)); - emit_long(value); + emit_int32(value); } } @@ -5100,7 +5100,7 @@ void Assembler::movslq(Register dst, int32_t imm32) { InstructionMark im(this); int encode = prefixq_and_encode(dst->encoding()); emit_int8((unsigned char)(0xC7 | encode)); - emit_long(imm32); + emit_int32(imm32); } void Assembler::movslq(Address dst, int32_t imm32) { @@ -5109,7 +5109,7 @@ void Assembler::movslq(Address dst, int32_t imm32) { prefixq(dst); emit_int8((unsigned char)0xC7); emit_operand(rax, dst, 4); - emit_long(imm32); + emit_int32(imm32); } void Assembler::movslq(Register dst, Address src) { @@ -5187,7 +5187,7 @@ void Assembler::orq(Address dst, int32_t imm32) { prefixq(dst); emit_int8((unsigned char)0x81); emit_operand(rcx, dst, 4); - emit_long(imm32); + emit_int32(imm32); } void Assembler::orq(Register dst, int32_t imm32) { @@ -5422,7 +5422,7 @@ void Assembler::testq(Register dst, int32_t imm32) { emit_int8((unsigned char)0xF7); emit_int8((unsigned char)(0xC0 | encode)); } - emit_long(imm32); + emit_int32(imm32); } void Assembler::testq(Register dst, Register src) { diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp index c75c8d29a6f..7b31fe7b88e 100644 --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp @@ -2540,7 +2540,7 @@ void MacroAssembler::jump_cc(Condition cc, AddressLiteral dst) { // 0000 1111 1000 tttn #32-bit disp emit_int8(0x0F); emit_int8((unsigned char)(0x80 | cc)); - emit_long(offs - long_size); + emit_int32(offs - long_size); } } else { #ifdef ASSERT diff --git a/hotspot/src/share/vm/asm/assembler.hpp b/hotspot/src/share/vm/asm/assembler.hpp index ca26ea5bba9..0a55dc90eb9 100644 --- a/hotspot/src/share/vm/asm/assembler.hpp +++ b/hotspot/src/share/vm/asm/assembler.hpp @@ -216,8 +216,6 @@ class AbstractAssembler : public ResourceObj { bool isByte(int x) const { return 0 <= x && x < 0x100; } bool isShiftCount(int x) const { return 0 <= x && x < 32; } - void emit_long(jint x) { emit_int32(x); } // deprecated - // Instruction boundaries (required when emitting relocatable values). class InstructionMark: public StackObj { private: From 8d91f983e00ac9afc937459e82813477810ae1ac Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Tue, 8 Jan 2013 13:01:19 -0500 Subject: [PATCH 040/204] 8001341: SIGSEGV in methodOopDesc::fast_exception_handler_bci_for(KlassHandle,int,Thread*)+0x3e9 Use methodHandle. Reviewed-by: coleenp, acorn, twisti, sspitsyn --- .../src/share/vm/interpreter/interpreterRuntime.cpp | 2 +- hotspot/src/share/vm/oops/method.cpp | 8 ++++---- hotspot/src/share/vm/oops/method.hpp | 2 +- hotspot/src/share/vm/prims/jvmtiExport.cpp | 13 +++++++++---- hotspot/src/share/vm/runtime/sharedRuntime.cpp | 3 ++- 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp index 682f70032e5..de6b3d12812 100644 --- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp +++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp @@ -417,7 +417,7 @@ IRT_ENTRY(address, InterpreterRuntime::exception_handler_for_exception(JavaThrea // exception handler lookup KlassHandle h_klass(THREAD, h_exception->klass()); - handler_bci = h_method->fast_exception_handler_bci_for(h_klass, current_bci, THREAD); + handler_bci = Method::fast_exception_handler_bci_for(h_method, h_klass, current_bci, THREAD); if (HAS_PENDING_EXCEPTION) { // We threw an exception while trying to find the exception handler. // Transfer the new exception to the exception handle which will diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp index 5818d58c298..b1c9637a0ee 100644 --- a/hotspot/src/share/vm/oops/method.cpp +++ b/hotspot/src/share/vm/oops/method.cpp @@ -192,16 +192,16 @@ char* Method::name_and_sig_as_C_string(Klass* klass, Symbol* method_name, Symbol return buf; } -int Method::fast_exception_handler_bci_for(KlassHandle ex_klass, int throw_bci, TRAPS) { +int Method::fast_exception_handler_bci_for(methodHandle mh, KlassHandle ex_klass, int throw_bci, TRAPS) { // exception table holds quadruple entries of the form (beg_bci, end_bci, handler_bci, klass_index) // access exception table - ExceptionTable table(this); + ExceptionTable table(mh()); int length = table.length(); // iterate through all entries sequentially - constantPoolHandle pool(THREAD, constants()); + constantPoolHandle pool(THREAD, mh->constants()); for (int i = 0; i < length; i ++) { //reacquire the table in case a GC happened - ExceptionTable table(this); + ExceptionTable table(mh()); int beg_bci = table.start_pc(i); int end_bci = table.end_pc(i); assert(beg_bci <= end_bci, "inconsistent exception table"); diff --git a/hotspot/src/share/vm/oops/method.hpp b/hotspot/src/share/vm/oops/method.hpp index 9e5e3b9da6a..7331273e83b 100644 --- a/hotspot/src/share/vm/oops/method.hpp +++ b/hotspot/src/share/vm/oops/method.hpp @@ -343,7 +343,7 @@ class Method : public Metadata { // exception handler which caused the exception to be thrown, which // is needed for proper retries. See, for example, // InterpreterRuntime::exception_handler_for_exception. - int fast_exception_handler_bci_for(KlassHandle ex_klass, int throw_bci, TRAPS); + static int fast_exception_handler_bci_for(methodHandle mh, KlassHandle ex_klass, int throw_bci, TRAPS); // method data access MethodData* method_data() const { diff --git a/hotspot/src/share/vm/prims/jvmtiExport.cpp b/hotspot/src/share/vm/prims/jvmtiExport.cpp index 9674cdce56b..cb5a1f454d9 100644 --- a/hotspot/src/share/vm/prims/jvmtiExport.cpp +++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp @@ -1305,15 +1305,21 @@ void JvmtiExport::post_exception_throw(JavaThread *thread, Method* method, addre vframeStream st(thread); assert(!st.at_end(), "cannot be at end"); Method* current_method = NULL; + // A GC may occur during the Method::fast_exception_handler_bci_for() + // call below if it needs to load the constraint class. Using a + // methodHandle to keep the 'current_method' from being deallocated + // if GC happens. + methodHandle current_mh = methodHandle(thread, current_method); int current_bci = -1; do { current_method = st.method(); + current_mh = methodHandle(thread, current_method); current_bci = st.bci(); do { should_repeat = false; KlassHandle eh_klass(thread, exception_handle()->klass()); - current_bci = current_method->fast_exception_handler_bci_for( - eh_klass, current_bci, THREAD); + current_bci = Method::fast_exception_handler_bci_for( + current_mh, eh_klass, current_bci, THREAD); if (HAS_PENDING_EXCEPTION) { exception_handle = Handle(thread, PENDING_EXCEPTION); CLEAR_PENDING_EXCEPTION; @@ -1328,8 +1334,7 @@ void JvmtiExport::post_exception_throw(JavaThread *thread, Method* method, addre catch_jmethodID = 0; current_bci = 0; } else { - catch_jmethodID = jem.to_jmethodID( - methodHandle(thread, current_method)); + catch_jmethodID = jem.to_jmethodID(current_mh); } JvmtiJavaThreadEventTransition jet(thread); diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp index 539235422d6..7d2b816fe63 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp @@ -643,7 +643,8 @@ address SharedRuntime::compute_compiled_exc_handler(nmethod* nm, address ret_pc, bool skip_scope_increment = false; // exception handler lookup KlassHandle ek (THREAD, exception->klass()); - handler_bci = sd->method()->fast_exception_handler_bci_for(ek, bci, THREAD); + methodHandle mh(THREAD, sd->method()); + handler_bci = Method::fast_exception_handler_bci_for(mh, ek, bci, THREAD); if (HAS_PENDING_EXCEPTION) { recursive_exception = true; // We threw an exception while trying to find the exception handler. From cfea76669a822f5f7b0ae4aaaab28b1c1f7f8759 Mon Sep 17 00:00:00 2001 From: Harold Seigel Date: Tue, 8 Jan 2013 13:38:11 -0500 Subject: [PATCH 041/204] 8005076: Creating a CDS archive with one alignment and running another causes a crash Save the alignment when writing the CDS and compare it when reading the CDS. Reviewed-by: kvn, coleenp --- hotspot/src/share/vm/memory/filemap.cpp | 7 +++++++ hotspot/src/share/vm/memory/filemap.hpp | 1 + hotspot/src/share/vm/runtime/arguments.cpp | 9 ++------- hotspot/src/share/vm/runtime/globals.hpp | 18 +++++++++--------- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/hotspot/src/share/vm/memory/filemap.cpp b/hotspot/src/share/vm/memory/filemap.cpp index 2069d64a900..fe0958073e3 100644 --- a/hotspot/src/share/vm/memory/filemap.cpp +++ b/hotspot/src/share/vm/memory/filemap.cpp @@ -119,6 +119,7 @@ void FileMapInfo::populate_header(size_t alignment) { _header._magic = 0xf00baba2; _header._version = _current_version; _header._alignment = alignment; + _header._obj_alignment = ObjectAlignmentInBytes; // The following fields are for sanity checks for whether this archive // will function correctly with this JVM and the bootclasspath it's @@ -473,6 +474,12 @@ bool FileMapInfo::validate() { " version or build of HotSpot."); return false; } + if (_header._obj_alignment != ObjectAlignmentInBytes) { + fail_continue("The shared archive file's ObjectAlignmentInBytes of %d" + " does not equal the current ObjectAlignmentInBytes of %d.", + _header._obj_alignment, ObjectAlignmentInBytes); + return false; + } // Cannot verify interpreter yet, as it can only be created after the GC // heap has been initialized. diff --git a/hotspot/src/share/vm/memory/filemap.hpp b/hotspot/src/share/vm/memory/filemap.hpp index 7cdd9616cbe..75f01d0510a 100644 --- a/hotspot/src/share/vm/memory/filemap.hpp +++ b/hotspot/src/share/vm/memory/filemap.hpp @@ -63,6 +63,7 @@ private: int _magic; // identify file type. int _version; // (from enum, above.) size_t _alignment; // how shared archive should be aligned + int _obj_alignment; // value of ObjectAlignmentInBytes struct space_info { int _file_offset; // sizeof(this) rounded to vm page size diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index b42f4ce4891..65f6e03b7ff 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1331,14 +1331,14 @@ bool verify_object_alignment() { // then a saved space from compressed oops. if ((int)ObjectAlignmentInBytes > 256) { jio_fprintf(defaultStream::error_stream(), - "error: ObjectAlignmentInBytes=%d must not be greater then 256\n", + "error: ObjectAlignmentInBytes=%d must not be greater than 256\n", (int)ObjectAlignmentInBytes); return false; } // In case page size is very small. if ((int)ObjectAlignmentInBytes >= os::vm_page_size()) { jio_fprintf(defaultStream::error_stream(), - "error: ObjectAlignmentInBytes=%d must be less then page size %d\n", + "error: ObjectAlignmentInBytes=%d must be less than page size %d\n", (int)ObjectAlignmentInBytes, os::vm_page_size()); return false; } @@ -2997,11 +2997,6 @@ void Arguments::set_shared_spaces_flags() { FLAG_SET_DEFAULT(UseLargePages, false); } - // Add 2M to any size for SharedReadOnlySize to get around the JPRT setting - if (DumpSharedSpaces && !FLAG_IS_DEFAULT(SharedReadOnlySize)) { - SharedReadOnlySize = 14*M; - } - if (DumpSharedSpaces) { if (RequireSharedSpaces) { warning("cannot dump shared archive while using shared archive"); diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index dd3750cafb6..abdb42a51e2 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -1830,7 +1830,7 @@ class CommandLineFlags { \ product(intx, CMSIsTooFullPercentage, 98, \ "An absolute ceiling above which CMS will always consider the " \ - "perm gen ripe for collection") \ + "unloading of classes when class unloading is enabled") \ \ develop(bool, CMSTestInFreeList, false, \ "Check if the coalesced range is already in the " \ @@ -1899,13 +1899,13 @@ class CommandLineFlags { "Metadata deallocation alot interval") \ \ develop(bool, TraceMetadataChunkAllocation, false, \ - "Trace humongous metadata allocations") \ + "Trace chunk metadata allocations") \ \ product(bool, TraceMetadataHumongousAllocation, false, \ "Trace humongous metadata allocations") \ \ develop(bool, TraceMetavirtualspaceAllocation, false, \ - "Trace humongous metadata allocations") \ + "Trace virtual space metadata allocations") \ \ notproduct(bool, ExecuteInternalVMTests, false, \ "Enable execution of internal VM tests.") \ @@ -3537,10 +3537,10 @@ class CommandLineFlags { /* Shared spaces */ \ \ product(bool, UseSharedSpaces, true, \ - "Use shared spaces in the permanent generation") \ + "Use shared spaces for metadata") \ \ product(bool, RequireSharedSpaces, false, \ - "Require shared spaces in the permanent generation") \ + "Require shared spaces for metadata") \ \ product(bool, DumpSharedSpaces, false, \ "Special mode: JVM reads a class list, loads classes, builds " \ @@ -3551,16 +3551,16 @@ class CommandLineFlags { "Print usage of shared spaces") \ \ product(uintx, SharedReadWriteSize, NOT_LP64(12*M) LP64_ONLY(16*M), \ - "Size of read-write space in permanent generation (in bytes)") \ + "Size of read-write space for metadata (in bytes)") \ \ product(uintx, SharedReadOnlySize, NOT_LP64(12*M) LP64_ONLY(16*M), \ - "Size of read-only space in permanent generation (in bytes)") \ + "Size of read-only space for metadata (in bytes)") \ \ product(uintx, SharedMiscDataSize, NOT_LP64(2*M) LP64_ONLY(4*M), \ - "Size of the shared data area adjacent to the heap (in bytes)") \ + "Size of the shared miscellaneous data area (in bytes)") \ \ product(uintx, SharedMiscCodeSize, 120*K, \ - "Size of the shared code area adjacent to the heap (in bytes)") \ + "Size of the shared miscellaneous code area (in bytes)") \ \ product(uintx, SharedDummyBlockSize, 0, \ "Size of dummy block used to shift heap addresses (in bytes)") \ From be968245ecee13a29fe1fa84fe282fd7020cfa2a Mon Sep 17 00:00:00 2001 From: Eric Mccorkle Date: Tue, 8 Jan 2013 14:01:36 -0500 Subject: [PATCH 042/204] 8004728: Add hotspot support for parameter reflection Add hotspot support for parameter reflection Reviewed-by: acorn, jrose, coleenp --- hotspot/make/bsd/makefiles/mapfile-vers-debug | 7 +- .../make/bsd/makefiles/mapfile-vers-product | 1 + .../make/linux/makefiles/mapfile-vers-debug | 1 + .../make/linux/makefiles/mapfile-vers-product | 1 + hotspot/make/solaris/makefiles/mapfile-vers | 445 +++++++++--------- .../share/vm/classfile/classFileParser.cpp | 26 +- .../share/vm/classfile/classFileStream.cpp | 7 + .../share/vm/classfile/classFileStream.hpp | 5 + .../src/share/vm/classfile/defaultMethods.cpp | 3 +- .../src/share/vm/classfile/javaClasses.cpp | 66 +++ .../src/share/vm/classfile/javaClasses.hpp | 31 ++ .../share/vm/classfile/systemDictionary.hpp | 2 + hotspot/src/share/vm/classfile/vmSymbols.hpp | 5 + hotspot/src/share/vm/oops/constMethod.cpp | 128 +++-- hotspot/src/share/vm/oops/constMethod.hpp | 41 +- hotspot/src/share/vm/oops/method.cpp | 10 +- hotspot/src/share/vm/oops/method.hpp | 7 + hotspot/src/share/vm/prims/jvm.cpp | 37 +- hotspot/src/share/vm/prims/jvm.h | 2 + hotspot/src/share/vm/runtime/reflection.cpp | 11 + hotspot/src/share/vm/runtime/reflection.hpp | 4 + 21 files changed, 567 insertions(+), 273 deletions(-) diff --git a/hotspot/make/bsd/makefiles/mapfile-vers-debug b/hotspot/make/bsd/makefiles/mapfile-vers-debug index 52e8f435665..00fd1892716 100644 --- a/hotspot/make/bsd/makefiles/mapfile-vers-debug +++ b/hotspot/make/bsd/makefiles/mapfile-vers-debug @@ -1,5 +1,5 @@ # -# @(#)mapfile-vers-debug 1.18 07/10/25 16:47:35 +# @(#)mapfile-vers-debug 1.18 07/10/25 16:47:35 # # @@ -126,7 +126,7 @@ SUNWprivate_1.1 { JVM_GetClassModifiers; JVM_GetClassName; JVM_GetClassNameUTF; - JVM_GetClassSignature; + JVM_GetClassSignature; JVM_GetClassSigners; JVM_GetClassTypeAnnotations; JVM_GetComponentType; @@ -155,6 +155,7 @@ SUNWprivate_1.1 { JVM_GetMethodIxNameUTF; JVM_GetMethodIxSignatureUTF; JVM_GetMethodParameterAnnotations; + JVM_GetMethodParameters; JVM_GetPrimitiveArrayElement; JVM_GetProtectionDomain; JVM_GetSockName; @@ -284,7 +285,7 @@ SUNWprivate_1.1 { # This is for Forte Analyzer profiling support. AsyncGetCallTrace; - # INSERT VTABLE SYMBOLS HERE + # INSERT VTABLE SYMBOLS HERE local: *; diff --git a/hotspot/make/bsd/makefiles/mapfile-vers-product b/hotspot/make/bsd/makefiles/mapfile-vers-product index 05e9a44a1fc..dfa459f0316 100644 --- a/hotspot/make/bsd/makefiles/mapfile-vers-product +++ b/hotspot/make/bsd/makefiles/mapfile-vers-product @@ -155,6 +155,7 @@ SUNWprivate_1.1 { JVM_GetMethodIxNameUTF; JVM_GetMethodIxSignatureUTF; JVM_GetMethodParameterAnnotations; + JVM_GetMethodParameters; JVM_GetPrimitiveArrayElement; JVM_GetProtectionDomain; JVM_GetSockName; diff --git a/hotspot/make/linux/makefiles/mapfile-vers-debug b/hotspot/make/linux/makefiles/mapfile-vers-debug index 93ddc5666a0..d6ebedcb9bd 100644 --- a/hotspot/make/linux/makefiles/mapfile-vers-debug +++ b/hotspot/make/linux/makefiles/mapfile-vers-debug @@ -151,6 +151,7 @@ SUNWprivate_1.1 { JVM_GetMethodIxNameUTF; JVM_GetMethodIxSignatureUTF; JVM_GetMethodParameterAnnotations; + JVM_GetMethodParameters; JVM_GetPrimitiveArrayElement; JVM_GetProtectionDomain; JVM_GetSockName; diff --git a/hotspot/make/linux/makefiles/mapfile-vers-product b/hotspot/make/linux/makefiles/mapfile-vers-product index 029c12c5ff9..733e3af4b11 100644 --- a/hotspot/make/linux/makefiles/mapfile-vers-product +++ b/hotspot/make/linux/makefiles/mapfile-vers-product @@ -151,6 +151,7 @@ SUNWprivate_1.1 { JVM_GetMethodIxNameUTF; JVM_GetMethodIxSignatureUTF; JVM_GetMethodParameterAnnotations; + JVM_GetMethodParameters; JVM_GetPrimitiveArrayElement; JVM_GetProtectionDomain; JVM_GetSockName; diff --git a/hotspot/make/solaris/makefiles/mapfile-vers b/hotspot/make/solaris/makefiles/mapfile-vers index 76af87c0ce5..a10d5c1b4e6 100644 --- a/hotspot/make/solaris/makefiles/mapfile-vers +++ b/hotspot/make/solaris/makefiles/mapfile-vers @@ -26,236 +26,237 @@ SUNWprivate_1.1 { global: - # JNI + # JNI JNI_CreateJavaVM; JNI_GetCreatedJavaVMs; JNI_GetDefaultJavaVMInitArgs; - - # JVM - JVM_Accept; - JVM_ActiveProcessorCount; - JVM_AllocateNewArray; - JVM_AllocateNewObject; - JVM_ArrayCopy; - JVM_AssertionStatusDirectives; - JVM_Available; - JVM_Bind; - JVM_ClassDepth; - JVM_ClassLoaderDepth; - JVM_Clone; - JVM_Close; - JVM_CX8Field; - JVM_CompileClass; - JVM_CompileClasses; - JVM_CompilerCommand; - JVM_Connect; - JVM_ConstantPoolGetClassAt; - JVM_ConstantPoolGetClassAtIfLoaded; - JVM_ConstantPoolGetDoubleAt; - JVM_ConstantPoolGetFieldAt; - JVM_ConstantPoolGetFieldAtIfLoaded; - JVM_ConstantPoolGetFloatAt; - JVM_ConstantPoolGetIntAt; - JVM_ConstantPoolGetLongAt; - JVM_ConstantPoolGetMethodAt; - JVM_ConstantPoolGetMethodAtIfLoaded; - JVM_ConstantPoolGetMemberRefInfoAt; - JVM_ConstantPoolGetSize; - JVM_ConstantPoolGetStringAt; - JVM_ConstantPoolGetUTF8At; - JVM_CountStackFrames; - JVM_CurrentClassLoader; - JVM_CurrentLoadedClass; - JVM_CurrentThread; - JVM_CurrentTimeMillis; - JVM_DefineClass; - JVM_DefineClassWithSource; - JVM_DefineClassWithSourceCond; - JVM_DesiredAssertionStatus; - JVM_DisableCompiler; - JVM_DoPrivileged; - JVM_DTraceGetVersion; - JVM_DTraceActivate; - JVM_DTraceIsProbeEnabled; - JVM_DTraceIsSupported; - JVM_DTraceDispose; - JVM_DumpAllStacks; - JVM_DumpThreads; - JVM_EnableCompiler; - JVM_Exit; - JVM_FillInStackTrace; - JVM_FindClassFromClass; - JVM_FindClassFromClassLoader; - JVM_FindClassFromBootLoader; - JVM_FindLibraryEntry; - JVM_FindLoadedClass; - JVM_FindPrimitiveClass; - JVM_FindSignal; - JVM_FreeMemory; - JVM_GC; - JVM_GetAllThreads; - JVM_GetArrayElement; - JVM_GetArrayLength; - JVM_GetCPClassNameUTF; - JVM_GetCPFieldClassNameUTF; - JVM_GetCPFieldModifiers; - JVM_GetCPFieldNameUTF; - JVM_GetCPFieldSignatureUTF; - JVM_GetCPMethodClassNameUTF; - JVM_GetCPMethodModifiers; - JVM_GetCPMethodNameUTF; - JVM_GetCPMethodSignatureUTF; - JVM_GetCallerClass; - JVM_GetClassAccessFlags; - JVM_GetClassAnnotations; - JVM_GetClassCPEntriesCount; - JVM_GetClassCPTypes; - JVM_GetClassConstantPool; - JVM_GetClassContext; - JVM_GetClassDeclaredConstructors; - JVM_GetClassDeclaredFields; - JVM_GetClassDeclaredMethods; - JVM_GetClassFieldsCount; - JVM_GetClassInterfaces; - JVM_GetClassLoader; - JVM_GetClassMethodsCount; - JVM_GetClassModifiers; - JVM_GetClassName; - JVM_GetClassNameUTF; - JVM_GetClassSignature; - JVM_GetClassSigners; - JVM_GetComponentType; - JVM_GetClassTypeAnnotations; - JVM_GetDeclaredClasses; - JVM_GetDeclaringClass; - JVM_GetEnclosingMethodInfo; - JVM_GetFieldAnnotations; - JVM_GetFieldIxModifiers; - JVM_GetHostName; - JVM_GetInheritedAccessControlContext; - JVM_GetInterfaceVersion; - JVM_GetLastErrorString; - JVM_GetManagement; - JVM_GetMethodAnnotations; - JVM_GetMethodDefaultAnnotationValue; - JVM_GetMethodIxArgsSize; - JVM_GetMethodIxByteCode; - JVM_GetMethodIxByteCodeLength; - JVM_GetMethodIxExceptionIndexes; - JVM_GetMethodIxExceptionTableEntry; - JVM_GetMethodIxExceptionTableLength; - JVM_GetMethodIxExceptionsCount; - JVM_GetMethodIxLocalsCount; - JVM_GetMethodIxMaxStack; - JVM_GetMethodIxModifiers; - JVM_GetMethodIxNameUTF; - JVM_GetMethodIxSignatureUTF; - JVM_GetMethodParameterAnnotations; - JVM_GetPrimitiveArrayElement; - JVM_GetProtectionDomain; - JVM_GetSockName; - JVM_GetSockOpt; - JVM_GetStackAccessControlContext; - JVM_GetStackTraceDepth; - JVM_GetStackTraceElement; - JVM_GetSystemPackage; - JVM_GetSystemPackages; - JVM_GetThreadStateNames; - JVM_GetThreadStateValues; - JVM_GetVersionInfo; - JVM_Halt; - JVM_HoldsLock; - JVM_IHashCode; - JVM_InitAgentProperties; - JVM_InitProperties; - JVM_InitializeCompiler; - JVM_InitializeSocketLibrary; - JVM_InternString; - JVM_Interrupt; - JVM_InvokeMethod; - JVM_IsArrayClass; - JVM_IsConstructorIx; - JVM_IsInterface; - JVM_IsInterrupted; - JVM_IsNaN; - JVM_IsPrimitiveClass; - JVM_IsSameClassPackage; - JVM_IsSilentCompiler; - JVM_IsSupportedJNIVersion; - JVM_IsThreadAlive; - JVM_LatestUserDefinedLoader; - JVM_Listen; - JVM_LoadClass0; - JVM_LoadLibrary; - JVM_Lseek; - JVM_MaxObjectInspectionAge; - JVM_MaxMemory; - JVM_MonitorNotify; - JVM_MonitorNotifyAll; - JVM_MonitorWait; - JVM_NativePath; - JVM_NanoTime; - JVM_NewArray; - JVM_NewInstanceFromConstructor; - JVM_NewMultiArray; - JVM_OnExit; - JVM_Open; - JVM_PrintStackTrace; - JVM_RaiseSignal; - JVM_RawMonitorCreate; - JVM_RawMonitorDestroy; - JVM_RawMonitorEnter; - JVM_RawMonitorExit; - JVM_Read; - JVM_Recv; - JVM_RecvFrom; - JVM_RegisterSignal; - JVM_ReleaseUTF; - JVM_ResolveClass; - JVM_ResumeThread; - JVM_Send; - JVM_SendTo; - JVM_SetArrayElement; - JVM_SetClassSigners; - JVM_SetLength; + + # JVM + JVM_Accept; + JVM_ActiveProcessorCount; + JVM_AllocateNewArray; + JVM_AllocateNewObject; + JVM_ArrayCopy; + JVM_AssertionStatusDirectives; + JVM_Available; + JVM_Bind; + JVM_ClassDepth; + JVM_ClassLoaderDepth; + JVM_Clone; + JVM_Close; + JVM_CX8Field; + JVM_CompileClass; + JVM_CompileClasses; + JVM_CompilerCommand; + JVM_Connect; + JVM_ConstantPoolGetClassAt; + JVM_ConstantPoolGetClassAtIfLoaded; + JVM_ConstantPoolGetDoubleAt; + JVM_ConstantPoolGetFieldAt; + JVM_ConstantPoolGetFieldAtIfLoaded; + JVM_ConstantPoolGetFloatAt; + JVM_ConstantPoolGetIntAt; + JVM_ConstantPoolGetLongAt; + JVM_ConstantPoolGetMethodAt; + JVM_ConstantPoolGetMethodAtIfLoaded; + JVM_ConstantPoolGetMemberRefInfoAt; + JVM_ConstantPoolGetSize; + JVM_ConstantPoolGetStringAt; + JVM_ConstantPoolGetUTF8At; + JVM_CountStackFrames; + JVM_CurrentClassLoader; + JVM_CurrentLoadedClass; + JVM_CurrentThread; + JVM_CurrentTimeMillis; + JVM_DefineClass; + JVM_DefineClassWithSource; + JVM_DefineClassWithSourceCond; + JVM_DesiredAssertionStatus; + JVM_DisableCompiler; + JVM_DoPrivileged; + JVM_DTraceGetVersion; + JVM_DTraceActivate; + JVM_DTraceIsProbeEnabled; + JVM_DTraceIsSupported; + JVM_DTraceDispose; + JVM_DumpAllStacks; + JVM_DumpThreads; + JVM_EnableCompiler; + JVM_Exit; + JVM_FillInStackTrace; + JVM_FindClassFromClass; + JVM_FindClassFromClassLoader; + JVM_FindClassFromBootLoader; + JVM_FindLibraryEntry; + JVM_FindLoadedClass; + JVM_FindPrimitiveClass; + JVM_FindSignal; + JVM_FreeMemory; + JVM_GC; + JVM_GetAllThreads; + JVM_GetArrayElement; + JVM_GetArrayLength; + JVM_GetCPClassNameUTF; + JVM_GetCPFieldClassNameUTF; + JVM_GetCPFieldModifiers; + JVM_GetCPFieldNameUTF; + JVM_GetCPFieldSignatureUTF; + JVM_GetCPMethodClassNameUTF; + JVM_GetCPMethodModifiers; + JVM_GetCPMethodNameUTF; + JVM_GetCPMethodSignatureUTF; + JVM_GetCallerClass; + JVM_GetClassAccessFlags; + JVM_GetClassAnnotations; + JVM_GetClassCPEntriesCount; + JVM_GetClassCPTypes; + JVM_GetClassConstantPool; + JVM_GetClassContext; + JVM_GetClassDeclaredConstructors; + JVM_GetClassDeclaredFields; + JVM_GetClassDeclaredMethods; + JVM_GetClassFieldsCount; + JVM_GetClassInterfaces; + JVM_GetClassLoader; + JVM_GetClassMethodsCount; + JVM_GetClassModifiers; + JVM_GetClassName; + JVM_GetClassNameUTF; + JVM_GetClassSignature; + JVM_GetClassSigners; + JVM_GetComponentType; + JVM_GetClassTypeAnnotations; + JVM_GetDeclaredClasses; + JVM_GetDeclaringClass; + JVM_GetEnclosingMethodInfo; + JVM_GetFieldAnnotations; + JVM_GetFieldIxModifiers; + JVM_GetHostName; + JVM_GetInheritedAccessControlContext; + JVM_GetInterfaceVersion; + JVM_GetLastErrorString; + JVM_GetManagement; + JVM_GetMethodAnnotations; + JVM_GetMethodDefaultAnnotationValue; + JVM_GetMethodIxArgsSize; + JVM_GetMethodIxByteCode; + JVM_GetMethodIxByteCodeLength; + JVM_GetMethodIxExceptionIndexes; + JVM_GetMethodIxExceptionTableEntry; + JVM_GetMethodIxExceptionTableLength; + JVM_GetMethodIxExceptionsCount; + JVM_GetMethodIxLocalsCount; + JVM_GetMethodIxMaxStack; + JVM_GetMethodIxModifiers; + JVM_GetMethodIxNameUTF; + JVM_GetMethodIxSignatureUTF; + JVM_GetMethodParameterAnnotations; + JVM_GetMethodParameters; + JVM_GetPrimitiveArrayElement; + JVM_GetProtectionDomain; + JVM_GetSockName; + JVM_GetSockOpt; + JVM_GetStackAccessControlContext; + JVM_GetStackTraceDepth; + JVM_GetStackTraceElement; + JVM_GetSystemPackage; + JVM_GetSystemPackages; + JVM_GetThreadStateNames; + JVM_GetThreadStateValues; + JVM_GetVersionInfo; + JVM_Halt; + JVM_HoldsLock; + JVM_IHashCode; + JVM_InitAgentProperties; + JVM_InitProperties; + JVM_InitializeCompiler; + JVM_InitializeSocketLibrary; + JVM_InternString; + JVM_Interrupt; + JVM_InvokeMethod; + JVM_IsArrayClass; + JVM_IsConstructorIx; + JVM_IsInterface; + JVM_IsInterrupted; + JVM_IsNaN; + JVM_IsPrimitiveClass; + JVM_IsSameClassPackage; + JVM_IsSilentCompiler; + JVM_IsSupportedJNIVersion; + JVM_IsThreadAlive; + JVM_LatestUserDefinedLoader; + JVM_Listen; + JVM_LoadClass0; + JVM_LoadLibrary; + JVM_Lseek; + JVM_MaxObjectInspectionAge; + JVM_MaxMemory; + JVM_MonitorNotify; + JVM_MonitorNotifyAll; + JVM_MonitorWait; + JVM_NativePath; + JVM_NanoTime; + JVM_NewArray; + JVM_NewInstanceFromConstructor; + JVM_NewMultiArray; + JVM_OnExit; + JVM_Open; + JVM_PrintStackTrace; + JVM_RaiseSignal; + JVM_RawMonitorCreate; + JVM_RawMonitorDestroy; + JVM_RawMonitorEnter; + JVM_RawMonitorExit; + JVM_Read; + JVM_Recv; + JVM_RecvFrom; + JVM_RegisterSignal; + JVM_ReleaseUTF; + JVM_ResolveClass; + JVM_ResumeThread; + JVM_Send; + JVM_SendTo; + JVM_SetArrayElement; + JVM_SetClassSigners; + JVM_SetLength; JVM_SetNativeThreadName; - JVM_SetPrimitiveArrayElement; - JVM_SetProtectionDomain; - JVM_SetSockOpt; - JVM_SetThreadPriority; - JVM_Sleep; - JVM_Socket; - JVM_SocketAvailable; - JVM_SocketClose; - JVM_SocketShutdown; - JVM_StartThread; - JVM_StopThread; - JVM_SuspendThread; - JVM_SupportsCX8; - JVM_Sync; - JVM_Timeout; - JVM_TotalMemory; - JVM_TraceInstructions; - JVM_TraceMethodCalls; - JVM_UnloadLibrary; - JVM_Write; - JVM_Yield; - JVM_handle_solaris_signal; + JVM_SetPrimitiveArrayElement; + JVM_SetProtectionDomain; + JVM_SetSockOpt; + JVM_SetThreadPriority; + JVM_Sleep; + JVM_Socket; + JVM_SocketAvailable; + JVM_SocketClose; + JVM_SocketShutdown; + JVM_StartThread; + JVM_StopThread; + JVM_SuspendThread; + JVM_SupportsCX8; + JVM_Sync; + JVM_Timeout; + JVM_TotalMemory; + JVM_TraceInstructions; + JVM_TraceMethodCalls; + JVM_UnloadLibrary; + JVM_Write; + JVM_Yield; + JVM_handle_solaris_signal; - # miscellaneous functions - jio_fprintf; - jio_printf; - jio_snprintf; - jio_vfprintf; - jio_vsnprintf; + # miscellaneous functions + jio_fprintf; + jio_printf; + jio_snprintf; + jio_vfprintf; + jio_vsnprintf; - # Needed because there is no JVM interface for this. - sysThreadAvailableStackWithSlack; + # Needed because there is no JVM interface for this. + sysThreadAvailableStackWithSlack; - # This is for Forte Analyzer profiling support. - AsyncGetCallTrace; + # This is for Forte Analyzer profiling support. + AsyncGetCallTrace; - # INSERT VTABLE SYMBOLS HERE + # INSERT VTABLE SYMBOLS HERE local: *; diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index 956acea7a25..9dd0640de06 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -1935,6 +1935,8 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data, u2** localvariable_table_start; u2* localvariable_type_table_length; u2** localvariable_type_table_start; + u2 method_parameters_length = 0; + u1* method_parameters_data = NULL; bool parsed_code_attribute = false; bool parsed_checked_exceptions_attribute = false; bool parsed_stackmap_attribute = false; @@ -2144,6 +2146,14 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data, parse_checked_exceptions(&checked_exceptions_length, method_attribute_length, cp, CHECK_(nullHandle)); + } else if (method_attribute_name == vmSymbols::tag_method_parameters()) { + method_parameters_length = cfs->get_u1_fast(); + method_parameters_data = cfs->get_u1_buffer(); + cfs->skip_u2_fast(method_parameters_length); + cfs->skip_u4_fast(method_parameters_length); + // ignore this attribute if it cannot be reflected + if (!SystemDictionary::Parameter_klass_loaded()) + method_parameters_length = 0; } else if (method_attribute_name == vmSymbols::tag_synthetic()) { if (method_attribute_length != 0) { classfile_parse_error( @@ -2231,7 +2241,8 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data, Method* m = Method::allocate( loader_data, code_length, access_flags, linenumber_table_length, total_lvt_length, exception_table_length, checked_exceptions_length, - generic_signature_index, ConstMethod::NORMAL, CHECK_(nullHandle)); + method_parameters_length, generic_signature_index, + ConstMethod::NORMAL, CHECK_(nullHandle)); ClassLoadingService::add_class_method_size(m->size()*HeapWordSize); @@ -2279,6 +2290,18 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data, exception_table_start, size); } + // Copy method parameters + if (method_parameters_length > 0) { + MethodParametersElement* elem = m->constMethod()->method_parameters_start(); + for(int i = 0; i < method_parameters_length; i++) { + elem[i].name_cp_index = + Bytes::get_Java_u2(method_parameters_data); + method_parameters_data += 2; + elem[i].flags = Bytes::get_Java_u4(method_parameters_data); + method_parameters_data += 4; + } + } + // Copy checked exceptions if (checked_exceptions_length > 0) { int size = checked_exceptions_length * sizeof(CheckedExceptionElement) / sizeof(u2); @@ -3042,6 +3065,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, TempNewSymbol& parsed_name, bool verify, TRAPS) { + // When a retransformable agent is attached, JVMTI caches the // class bytes that existed before the first retransformation. // If RedefineClasses() was used before the retransformable diff --git a/hotspot/src/share/vm/classfile/classFileStream.cpp b/hotspot/src/share/vm/classfile/classFileStream.cpp index 19d3e82af42..1c69dfb2ea6 100644 --- a/hotspot/src/share/vm/classfile/classFileStream.cpp +++ b/hotspot/src/share/vm/classfile/classFileStream.cpp @@ -93,3 +93,10 @@ void ClassFileStream::skip_u2(int length, TRAPS) { } _current += length * 2; } + +void ClassFileStream::skip_u4(int length, TRAPS) { + if (_need_verify) { + guarantee_more(length * 4, CHECK); + } + _current += length * 4; +} diff --git a/hotspot/src/share/vm/classfile/classFileStream.hpp b/hotspot/src/share/vm/classfile/classFileStream.hpp index cf6f0e5f3bf..19da924abf2 100644 --- a/hotspot/src/share/vm/classfile/classFileStream.hpp +++ b/hotspot/src/share/vm/classfile/classFileStream.hpp @@ -133,6 +133,11 @@ class ClassFileStream: public ResourceObj { _current += 2 * length; } + void skip_u4(int length, TRAPS); + void skip_u4_fast(int length) { + _current += 4 * length; + } + // Tells whether eos is reached bool at_eos() const { return _current == _buffer_end; } }; diff --git a/hotspot/src/share/vm/classfile/defaultMethods.cpp b/hotspot/src/share/vm/classfile/defaultMethods.cpp index 1f4eefa79f3..ac593a7ef24 100644 --- a/hotspot/src/share/vm/classfile/defaultMethods.cpp +++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp @@ -1148,7 +1148,8 @@ static Method* new_method( int code_length = bytecodes->length(); Method* m = Method::allocate(cp->pool_holder()->class_loader_data(), - code_length, flags, 0, 0, 0, 0, 0, mt, CHECK_NULL); + code_length, flags, 0, 0, 0, 0, 0, 0, + mt, CHECK_NULL); m->set_constants(NULL); // This will get filled in later m->set_name_index(cp->utf8(name)); diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp index 9c2caaa7397..cb30a83d455 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.cpp +++ b/hotspot/src/share/vm/classfile/javaClasses.cpp @@ -2255,6 +2255,66 @@ void sun_reflect_ConstantPool::compute_offsets() { } } +void java_lang_reflect_Parameter::compute_offsets() { + Klass* k = SystemDictionary::reflect_Parameter_klass(); + if(NULL != k) { + compute_offset(name_offset, k, vmSymbols::name_name(), vmSymbols::string_signature()); + compute_offset(modifiers_offset, k, vmSymbols::modifiers_name(), vmSymbols::int_signature()); + compute_offset(index_offset, k, vmSymbols::index_name(), vmSymbols::int_signature()); + compute_offset(executable_offset, k, vmSymbols::executable_name(), vmSymbols::executable_signature()); + } +} + +Handle java_lang_reflect_Parameter::create(TRAPS) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + Symbol* name = vmSymbols::java_lang_reflect_Parameter(); + Klass* k = SystemDictionary::resolve_or_fail(name, true, CHECK_NH); + instanceKlassHandle klass (THREAD, k); + // Ensure it is initialized + klass->initialize(CHECK_NH); + return klass->allocate_instance_handle(CHECK_NH); +} + +oop java_lang_reflect_Parameter::name(oop param) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + return param->obj_field(name_offset); +} + +void java_lang_reflect_Parameter::set_name(oop param, oop value) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + param->obj_field_put(name_offset, value); +} + +int java_lang_reflect_Parameter::modifiers(oop param) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + return param->int_field(modifiers_offset); +} + +void java_lang_reflect_Parameter::set_modifiers(oop param, int value) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + param->int_field_put(modifiers_offset, value); +} + +int java_lang_reflect_Parameter::index(oop param) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + return param->int_field(index_offset); +} + +void java_lang_reflect_Parameter::set_index(oop param, int value) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + param->int_field_put(index_offset, value); +} + +oop java_lang_reflect_Parameter::executable(oop param) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + return param->obj_field(executable_offset); +} + +void java_lang_reflect_Parameter::set_executable(oop param, oop value) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + param->obj_field_put(executable_offset, value); +} + Handle sun_reflect_ConstantPool::create(TRAPS) { assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); @@ -2928,6 +2988,10 @@ int java_lang_reflect_Field::modifiers_offset; int java_lang_reflect_Field::signature_offset; int java_lang_reflect_Field::annotations_offset; int java_lang_reflect_Field::type_annotations_offset; +int java_lang_reflect_Parameter::name_offset; +int java_lang_reflect_Parameter::modifiers_offset; +int java_lang_reflect_Parameter::index_offset; +int java_lang_reflect_Parameter::executable_offset; int java_lang_boxing_object::value_offset; int java_lang_boxing_object::long_value_offset; int java_lang_ref_Reference::referent_offset; @@ -3112,6 +3176,8 @@ void JavaClasses::compute_offsets() { sun_reflect_ConstantPool::compute_offsets(); sun_reflect_UnsafeStaticFieldAccessorImpl::compute_offsets(); } + if (JDK_Version::is_jdk18x_version()) + java_lang_reflect_Parameter::compute_offsets(); // generated interpreter code wants to know about the offsets we just computed: AbstractAssembler::update_delayed_values(); diff --git a/hotspot/src/share/vm/classfile/javaClasses.hpp b/hotspot/src/share/vm/classfile/javaClasses.hpp index 00ce4576499..5ab16251c10 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.hpp +++ b/hotspot/src/share/vm/classfile/javaClasses.hpp @@ -729,6 +729,37 @@ class java_lang_reflect_Field : public java_lang_reflect_AccessibleObject { friend class JavaClasses; }; +class java_lang_reflect_Parameter { + private: + // Note that to reduce dependencies on the JDK we compute these + // offsets at run-time. + static int name_offset; + static int modifiers_offset; + static int index_offset; + static int executable_offset; + + static void compute_offsets(); + + public: + // Allocation + static Handle create(TRAPS); + + // Accessors + static oop name(oop field); + static void set_name(oop field, oop value); + + static int index(oop reflect); + static void set_index(oop reflect, int value); + + static int modifiers(oop reflect); + static void set_modifiers(oop reflect, int value); + + static oop executable(oop constructor); + static void set_executable(oop constructor, oop value); + + friend class JavaClasses; +}; + // Interface to sun.reflect.ConstantPool objects class sun_reflect_ConstantPool { private: diff --git a/hotspot/src/share/vm/classfile/systemDictionary.hpp b/hotspot/src/share/vm/classfile/systemDictionary.hpp index c757d34096c..e2f660ee171 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.hpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp @@ -131,6 +131,7 @@ class SymbolPropertyTable; do_klass(Properties_klass, java_util_Properties, Pre ) \ do_klass(reflect_AccessibleObject_klass, java_lang_reflect_AccessibleObject, Pre ) \ do_klass(reflect_Field_klass, java_lang_reflect_Field, Pre ) \ + do_klass(reflect_Parameter_klass, java_lang_reflect_Parameter, Opt ) \ do_klass(reflect_Method_klass, java_lang_reflect_Method, Pre ) \ do_klass(reflect_Constructor_klass, java_lang_reflect_Constructor, Pre ) \ \ @@ -459,6 +460,7 @@ public: // Tells whether ClassLoader.checkPackageAccess is present static bool has_checkPackageAccess() { return _has_checkPackageAccess; } + static bool Parameter_klass_loaded() { return WK_KLASS(reflect_Parameter_klass) != NULL; } static bool Class_klass_loaded() { return WK_KLASS(Class_klass) != NULL; } static bool Cloneable_klass_loaded() { return WK_KLASS(Cloneable_klass) != NULL; } static bool Object_klass_loaded() { return WK_KLASS(Object_klass) != NULL; } diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp index e5425b4f246..e6168ceba2c 100644 --- a/hotspot/src/share/vm/classfile/vmSymbols.hpp +++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp @@ -86,6 +86,7 @@ template(java_lang_reflect_Method, "java/lang/reflect/Method") \ template(java_lang_reflect_Constructor, "java/lang/reflect/Constructor") \ template(java_lang_reflect_Field, "java/lang/reflect/Field") \ + template(java_lang_reflect_Parameter, "java/lang/reflect/Parameter") \ template(java_lang_reflect_Array, "java/lang/reflect/Array") \ template(java_lang_StringBuffer, "java/lang/StringBuffer") \ template(java_lang_StringBuilder, "java/lang/StringBuilder") \ @@ -126,6 +127,7 @@ template(tag_line_number_table, "LineNumberTable") \ template(tag_local_variable_table, "LocalVariableTable") \ template(tag_local_variable_type_table, "LocalVariableTypeTable") \ + template(tag_method_parameters, "MethodParameters") \ template(tag_stack_map_table, "StackMapTable") \ template(tag_synthetic, "Synthetic") \ template(tag_deprecated, "Deprecated") \ @@ -235,6 +237,8 @@ /* Support for annotations (JDK 1.5 and above) */ \ \ template(annotations_name, "annotations") \ + template(index_name, "index") \ + template(executable_name, "executable") \ template(parameter_annotations_name, "parameterAnnotations") \ template(annotation_default_name, "annotationDefault") \ template(sun_reflect_ConstantPool, "sun/reflect/ConstantPool") \ @@ -475,6 +479,7 @@ template(class_signature, "Ljava/lang/Class;") \ template(string_signature, "Ljava/lang/String;") \ template(reference_signature, "Ljava/lang/ref/Reference;") \ + template(executable_signature, "Ljava/lang/reflect/Executable;") \ template(concurrenthashmap_signature, "Ljava/util/concurrent/ConcurrentHashMap;") \ template(String_StringBuilder_signature, "(Ljava/lang/String;)Ljava/lang/StringBuilder;") \ template(int_StringBuilder_signature, "(I)Ljava/lang/StringBuilder;") \ diff --git a/hotspot/src/share/vm/oops/constMethod.cpp b/hotspot/src/share/vm/oops/constMethod.cpp index 10b057b4f8a..79c10c0e62a 100644 --- a/hotspot/src/share/vm/oops/constMethod.cpp +++ b/hotspot/src/share/vm/oops/constMethod.cpp @@ -39,18 +39,21 @@ ConstMethod* ConstMethod::allocate(ClassLoaderData* loader_data, int localvariable_table_length, int exception_table_length, int checked_exceptions_length, + int method_parameters_length, u2 generic_signature_index, MethodType method_type, TRAPS) { int size = ConstMethod::size(byte_code_size, - compressed_line_number_size, - localvariable_table_length, - exception_table_length, - checked_exceptions_length, - generic_signature_index); + compressed_line_number_size, + localvariable_table_length, + exception_table_length, + checked_exceptions_length, + method_parameters_length, + generic_signature_index); return new (loader_data, size, true, THREAD) ConstMethod( byte_code_size, compressed_line_number_size, localvariable_table_length, - exception_table_length, checked_exceptions_length, generic_signature_index, + exception_table_length, checked_exceptions_length, + method_parameters_length, generic_signature_index, method_type, size); } @@ -59,6 +62,7 @@ ConstMethod::ConstMethod(int byte_code_size, int localvariable_table_length, int exception_table_length, int checked_exceptions_length, + int method_parameters_length, u2 generic_signature_index, MethodType method_type, int size) { @@ -74,7 +78,8 @@ ConstMethod::ConstMethod(int byte_code_size, checked_exceptions_length, compressed_line_number_size, localvariable_table_length, - exception_table_length); + exception_table_length, + method_parameters_length); set_method_type(method_type); assert(this->size() == size, "wrong size for object"); } @@ -92,11 +97,12 @@ void ConstMethod::deallocate_contents(ClassLoaderData* loader_data) { // How big must this constMethodObject be? int ConstMethod::size(int code_size, - int compressed_line_number_size, - int local_variable_table_length, - int exception_table_length, - int checked_exceptions_length, - u2 generic_signature_index) { + int compressed_line_number_size, + int local_variable_table_length, + int exception_table_length, + int checked_exceptions_length, + int method_parameters_length, + u2 generic_signature_index) { int extra_bytes = code_size; if (compressed_line_number_size > 0) { extra_bytes += compressed_line_number_size; @@ -117,6 +123,10 @@ int ConstMethod::size(int code_size, if (generic_signature_index != 0) { extra_bytes += sizeof(u2); } + if (method_parameters_length > 0) { + extra_bytes += sizeof(u2); + extra_bytes += method_parameters_length * sizeof(MethodParametersElement); + } int extra_words = align_size_up(extra_bytes, BytesPerWord) / BytesPerWord; return align_object_size(header_size() + extra_words); } @@ -143,6 +153,18 @@ u2* ConstMethod::generic_signature_index_addr() const { u2* ConstMethod::checked_exceptions_length_addr() const { // Located immediately before the generic signature index. assert(has_checked_exceptions(), "called only if table is present"); + if(has_method_parameters()) { + // If method parameters present, locate immediately before them. + return (u2*)method_parameters_start() - 1; + } else { + // Else, the exception table is at the end of the constMethod. + return has_generic_signature() ? (last_u2_element() - 1) : + last_u2_element(); + } +} + +u2* ConstMethod::method_parameters_length_addr() const { + assert(has_method_parameters(), "called only if table is present"); return has_generic_signature() ? (last_u2_element() - 1) : last_u2_element(); } @@ -153,11 +175,15 @@ u2* ConstMethod::exception_table_length_addr() const { // If checked_exception present, locate immediately before them. return (u2*) checked_exceptions_start() - 1; } else { - // Else, the exception table is at the end of the constMethod or - // immediately before the generic signature index. + if(has_method_parameters()) { + // If method parameters present, locate immediately before them. + return (u2*)method_parameters_start() - 1; + } else { + // Else, the exception table is at the end of the constMethod. return has_generic_signature() ? (last_u2_element() - 1) : last_u2_element(); } + } } u2* ConstMethod::localvariable_table_length_addr() const { @@ -170,12 +196,16 @@ u2* ConstMethod::localvariable_table_length_addr() const { // If checked_exception present, locate immediately before them. return (u2*) checked_exceptions_start() - 1; } else { - // Else, the linenumber table is at the end of the constMethod or - // immediately before the generic signature index. + if(has_method_parameters()) { + // If method parameters present, locate immediately before them. + return (u2*)method_parameters_start() - 1; + } else { + // Else, the exception table is at the end of the constMethod. return has_generic_signature() ? (last_u2_element() - 1) : last_u2_element(); } } + } } // Update the flags to indicate the presence of these optional fields. @@ -183,29 +213,57 @@ void ConstMethod::set_inlined_tables_length(u2 generic_signature_index, int checked_exceptions_len, int compressed_line_number_size, int localvariable_table_len, - int exception_table_len) { - // Must be done in the order below, otherwise length_addr accessors - // will not work. Only set bit in header if length is positive. + int exception_table_len, + int method_parameters_len) { assert(_flags == 0, "Error"); - if (compressed_line_number_size > 0) { + if (compressed_line_number_size > 0) _flags |= _has_linenumber_table; - } - if (generic_signature_index != 0) { + if (generic_signature_index != 0) _flags |= _has_generic_signature; - *(generic_signature_index_addr()) = generic_signature_index; - } - if (checked_exceptions_len > 0) { + if (method_parameters_len > 0) + _flags |= _has_method_parameters; + if (checked_exceptions_len > 0) _flags |= _has_checked_exceptions; - *(checked_exceptions_length_addr()) = checked_exceptions_len; - } - if (exception_table_len > 0) { + if (exception_table_len > 0) _flags |= _has_exception_table; - *(exception_table_length_addr()) = exception_table_len; - } - if (localvariable_table_len > 0) { + if (localvariable_table_len > 0) _flags |= _has_localvariable_table; + + // This code is extremely brittle and should possibly be revised. + // The *_length_addr functions walk backwards through the + // constMethod data, using each of the length indexes ahead of them, + // as well as the flags variable. Therefore, the indexes must be + // initialized in reverse order, or else they will compute the wrong + // offsets. Moving the initialization of _flags into a separate + // block solves *half* of the problem, but the following part will + // still break if the order is not exactly right. + // + // Also, the servicability agent needs to be informed anytime + // anything is added here. It might be advisable to have some sort + // of indication of this inline. + if (generic_signature_index != 0) + *(generic_signature_index_addr()) = generic_signature_index; + // New data should probably go here. + if (method_parameters_len > 0) + *(method_parameters_length_addr()) = method_parameters_len; + if (checked_exceptions_len > 0) + *(checked_exceptions_length_addr()) = checked_exceptions_len; + if (exception_table_len > 0) + *(exception_table_length_addr()) = exception_table_len; + if (localvariable_table_len > 0) *(localvariable_table_length_addr()) = localvariable_table_len; - } +} + +int ConstMethod::method_parameters_length() const { + return has_method_parameters() ? *(method_parameters_length_addr()) : 0; +} + +MethodParametersElement* ConstMethod::method_parameters_start() const { + u2* addr = method_parameters_length_addr(); + u2 length = *addr; + assert(length > 0, "should only be called if table is present"); + addr -= length * sizeof(MethodParametersElement) / sizeof(u2); + return (MethodParametersElement*) addr; } @@ -298,6 +356,10 @@ void ConstMethod::verify_on(outputStream* st) { } guarantee(compressed_table_end <= m_end, "invalid method layout"); // Verify checked exceptions, exception table and local variable tables + if (has_method_parameters()) { + u2* addr = method_parameters_length_addr(); + guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout"); + } if (has_checked_exceptions()) { u2* addr = checked_exceptions_length_addr(); guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout"); @@ -318,6 +380,8 @@ void ConstMethod::verify_on(outputStream* st) { uncompressed_table_start = (u2*) exception_table_start(); } else if (has_checked_exceptions()) { uncompressed_table_start = (u2*) checked_exceptions_start(); + } else if (has_method_parameters()) { + uncompressed_table_start = (u2*) method_parameters_start(); } else { uncompressed_table_start = (u2*) m_end; } diff --git a/hotspot/src/share/vm/oops/constMethod.hpp b/hotspot/src/share/vm/oops/constMethod.hpp index 2819b3e7756..08c650278e6 100644 --- a/hotspot/src/share/vm/oops/constMethod.hpp +++ b/hotspot/src/share/vm/oops/constMethod.hpp @@ -77,9 +77,18 @@ // | (access flags bit tells whether table is present) | // | (indexed from end of ConstMethod*) | // |------------------------------------------------------| +// | method parameters elements + length (length last) | +// | (length is u2, elements are u2, u4 structures) | +// | (see class MethodParametersElement) | +// | (access flags bit tells whether table is present) | +// | (indexed from end of ConstMethod*) | +// |------------------------------------------------------| // | generic signature index (u2) | // | (indexed from start of constMethodOop) | // |------------------------------------------------------| +// +// IMPORTANT: If anything gets added here, there need to be changes to +// ensure that ServicabilityAgent doesn't get broken as a result! // Utitily class decribing elements in checked exceptions table inlined in Method*. @@ -109,6 +118,13 @@ class ExceptionTableElement VALUE_OBJ_CLASS_SPEC { u2 catch_type_index; }; +// Utility class describing elements in method parameters +class MethodParametersElement VALUE_OBJ_CLASS_SPEC { + public: + u2 name_cp_index; + u4 flags; +}; + class ConstMethod : public MetaspaceObj { friend class VMStructs; @@ -123,7 +139,8 @@ private: _has_localvariable_table = 4, _has_exception_table = 8, _has_generic_signature = 16, - _is_overpass = 32 + _has_method_parameters = 32, + _is_overpass = 64 }; // Bit vector of signature @@ -160,6 +177,7 @@ private: int localvariable_table_length, int exception_table_length, int checked_exceptions_length, + int method_parameters_length, u2 generic_signature_index, MethodType is_overpass, int size); @@ -171,6 +189,7 @@ public: int localvariable_table_length, int exception_table_length, int checked_exceptions_length, + int method_parameters_length, u2 generic_signature_index, MethodType mt, TRAPS); @@ -182,7 +201,8 @@ public: int checked_exceptions_len, int compressed_line_number_size, int localvariable_table_len, - int exception_table_len); + int exception_table_len, + int method_parameters_length); bool has_generic_signature() const { return (_flags & _has_generic_signature) != 0; } @@ -199,6 +219,9 @@ public: bool has_exception_handler() const { return (_flags & _has_exception_table) != 0; } + bool has_method_parameters() const + { return (_flags & _has_method_parameters) != 0; } + MethodType method_type() const { return ((_flags & _is_overpass) == 0) ? NORMAL : OVERPASS; } @@ -284,10 +307,11 @@ public: // Size needed static int size(int code_size, int compressed_line_number_size, - int local_variable_table_length, - int exception_table_length, - int checked_exceptions_length, - u2 generic_signature_index); + int local_variable_table_length, + int exception_table_length, + int checked_exceptions_length, + int method_parameters_length, + u2 generic_signature_index); int size() const { return _constMethod_size;} void set_constMethod_size(int size) { _constMethod_size = size; } @@ -308,6 +332,7 @@ public: u2* checked_exceptions_length_addr() const; u2* localvariable_table_length_addr() const; u2* exception_table_length_addr() const; + u2* method_parameters_length_addr() const; // checked exceptions int checked_exceptions_length() const; @@ -321,6 +346,10 @@ public: int exception_table_length() const; ExceptionTableElement* exception_table_start() const; + // method parameters table + int method_parameters_length() const; + MethodParametersElement* method_parameters_start() const; + // byte codes void set_code(address code) { if (code_size() > 0) { diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp index c8aff7f36fd..81251f91720 100644 --- a/hotspot/src/share/vm/oops/method.cpp +++ b/hotspot/src/share/vm/oops/method.cpp @@ -64,6 +64,7 @@ Method* Method::allocate(ClassLoaderData* loader_data, int localvariable_table_length, int exception_table_length, int checked_exceptions_length, + int method_parameters_length, u2 generic_signature_index, ConstMethod::MethodType method_type, TRAPS) { @@ -75,6 +76,7 @@ Method* Method::allocate(ClassLoaderData* loader_data, localvariable_table_length, exception_table_length, checked_exceptions_length, + method_parameters_length, generic_signature_index, method_type, CHECK_NULL); @@ -1035,8 +1037,10 @@ methodHandle Method::make_method_handle_intrinsic(vmIntrinsics::ID iid, methodHandle m; { - Method* m_oop = Method::allocate(loader_data, 0, accessFlags_from(flags_bits), - 0, 0, 0, 0, 0, ConstMethod::NORMAL, CHECK_(empty)); + Method* m_oop = Method::allocate(loader_data, 0, + accessFlags_from(flags_bits), + 0, 0, 0, 0, 0, 0, + ConstMethod::NORMAL, CHECK_(empty)); m = methodHandle(THREAD, m_oop); } m->set_constants(cp()); @@ -1088,6 +1092,7 @@ methodHandle Method::clone_with_new_data(methodHandle m, u_char* new_code, int n int checked_exceptions_len = m->checked_exceptions_length(); int localvariable_len = m->localvariable_table_length(); int exception_table_len = m->exception_table_length(); + int method_parameters_len = m->method_parameters_length(); ClassLoaderData* loader_data = m->method_holder()->class_loader_data(); Method* newm_oop = Method::allocate(loader_data, @@ -1097,6 +1102,7 @@ methodHandle Method::clone_with_new_data(methodHandle m, u_char* new_code, int n localvariable_len, exception_table_len, checked_exceptions_len, + method_parameters_len, generic_signature_index, m->method_type(), CHECK_(methodHandle())); diff --git a/hotspot/src/share/vm/oops/method.hpp b/hotspot/src/share/vm/oops/method.hpp index 50305294ec9..1385671ead4 100644 --- a/hotspot/src/share/vm/oops/method.hpp +++ b/hotspot/src/share/vm/oops/method.hpp @@ -160,6 +160,7 @@ class Method : public Metadata { int localvariable_table_length, int exception_table_length, int checked_exceptions_length, + int method_parameters_length, u2 generic_signature_index, ConstMethod::MethodType method_type, TRAPS); @@ -480,6 +481,12 @@ class Method : public Metadata { void print_codes_on(outputStream* st) const PRODUCT_RETURN; void print_codes_on(int from, int to, outputStream* st) const PRODUCT_RETURN; + // method parameters + int method_parameters_length() const + { return constMethod()->method_parameters_length(); } + MethodParametersElement* method_parameters_start() const + { return constMethod()->method_parameters_start(); } + // checked exceptions int checked_exceptions_length() const { return constMethod()->checked_exceptions_length(); } diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp index 51d4a1d6e25..f899aac02e7 100644 --- a/hotspot/src/share/vm/prims/jvm.cpp +++ b/hotspot/src/share/vm/prims/jvm.cpp @@ -1515,7 +1515,7 @@ JVM_ENTRY(jbyteArray, JVM_GetFieldAnnotations(JNIEnv *env, jobject field)) JVM_END -static Method* jvm_get_method_common(jobject method, TRAPS) { +static Method* jvm_get_method_common(jobject method) { // some of this code was adapted from from jni_FromReflectedMethod oop reflected = JNIHandles::resolve_non_null(method); @@ -1533,8 +1533,7 @@ static Method* jvm_get_method_common(jobject method, TRAPS) { } Klass* k = java_lang_Class::as_Klass(mirror); - KlassHandle kh(THREAD, k); - Method* m = InstanceKlass::cast(kh())->method_with_idnum(slot); + Method* m = InstanceKlass::cast(k)->method_with_idnum(slot); if (m == NULL) { assert(false, "cannot find method"); return NULL; // robustness @@ -1548,7 +1547,7 @@ JVM_ENTRY(jbyteArray, JVM_GetMethodAnnotations(JNIEnv *env, jobject method)) JVMWrapper("JVM_GetMethodAnnotations"); // method is a handle to a java.lang.reflect.Method object - Method* m = jvm_get_method_common(method, CHECK_NULL); + Method* m = jvm_get_method_common(method); return (jbyteArray) JNIHandles::make_local(env, Annotations::make_java_array(m->annotations(), THREAD)); JVM_END @@ -1558,7 +1557,7 @@ JVM_ENTRY(jbyteArray, JVM_GetMethodDefaultAnnotationValue(JNIEnv *env, jobject m JVMWrapper("JVM_GetMethodDefaultAnnotationValue"); // method is a handle to a java.lang.reflect.Method object - Method* m = jvm_get_method_common(method, CHECK_NULL); + Method* m = jvm_get_method_common(method); return (jbyteArray) JNIHandles::make_local(env, Annotations::make_java_array(m->annotation_default(), THREAD)); JVM_END @@ -1568,7 +1567,7 @@ JVM_ENTRY(jbyteArray, JVM_GetMethodParameterAnnotations(JNIEnv *env, jobject met JVMWrapper("JVM_GetMethodParameterAnnotations"); // method is a handle to a java.lang.reflect.Method object - Method* m = jvm_get_method_common(method, CHECK_NULL); + Method* m = jvm_get_method_common(method); return (jbyteArray) JNIHandles::make_local(env, Annotations::make_java_array(m->parameter_annotations(), THREAD)); JVM_END @@ -1590,6 +1589,32 @@ JVM_ENTRY(jbyteArray, JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls)) return NULL; JVM_END +JVM_ENTRY(jobjectArray, JVM_GetMethodParameters(JNIEnv *env, jobject method)) +{ + JVMWrapper("JVM_GetMethodParameters"); + // method is a handle to a java.lang.reflect.Method object + Method* method_ptr = jvm_get_method_common(method); + methodHandle mh (THREAD, method_ptr); + Handle reflected_method (THREAD, JNIHandles::resolve_non_null(method)); + const int num_params = mh->method_parameters_length(); + + if(0 != num_params) { + objArrayOop result_oop = oopFactory::new_objArray(SystemDictionary::reflect_Parameter_klass(), num_params, CHECK_NULL); + objArrayHandle result (THREAD, result_oop); + + for(int i = 0; i < num_params; i++) { + MethodParametersElement* params = mh->method_parameters_start(); + Symbol* const sym = mh->constants()->symbol_at(params[i].name_cp_index); + oop param = Reflection::new_parameter(reflected_method, i, sym, + params[i].flags, CHECK_NULL); + result->obj_at_put(i, param); + } + return (jobjectArray)JNIHandles::make_local(env, result()); + } else { + return (jobjectArray)NULL; + } +} +JVM_END // New (JDK 1.4) reflection implementation ///////////////////////////////////// diff --git a/hotspot/src/share/vm/prims/jvm.h b/hotspot/src/share/vm/prims/jvm.h index 8dde7e90050..899138ede9e 100644 --- a/hotspot/src/share/vm/prims/jvm.h +++ b/hotspot/src/share/vm/prims/jvm.h @@ -86,6 +86,8 @@ extern "C" { #define JVM_INTERFACE_VERSION 4 +JNIEXPORT jobjectArray JNICALL +JVM_GetMethodParameters(JNIEnv *env, jobject method); JNIEXPORT jint JNICALL JVM_GetInterfaceVersion(void); diff --git a/hotspot/src/share/vm/runtime/reflection.cpp b/hotspot/src/share/vm/runtime/reflection.cpp index 7099d6c9396..76a72e4e9b7 100644 --- a/hotspot/src/share/vm/runtime/reflection.cpp +++ b/hotspot/src/share/vm/runtime/reflection.cpp @@ -860,6 +860,17 @@ oop Reflection::new_field(fieldDescriptor* fd, bool intern_name, TRAPS) { return rh(); } +oop Reflection::new_parameter(Handle method, int index, Symbol* sym, + int flags, TRAPS) { + Handle name = java_lang_String::create_from_symbol(sym, CHECK_NULL); + Handle rh = java_lang_reflect_Parameter::create(CHECK_NULL); + java_lang_reflect_Parameter::set_name(rh(), name()); + java_lang_reflect_Parameter::set_modifiers(rh(), flags); + java_lang_reflect_Parameter::set_executable(rh(), method()); + java_lang_reflect_Parameter::set_index(rh(), index); + return rh(); +} + methodHandle Reflection::resolve_interface_call(instanceKlassHandle klass, methodHandle method, KlassHandle recv_klass, Handle receiver, TRAPS) { diff --git a/hotspot/src/share/vm/runtime/reflection.hpp b/hotspot/src/share/vm/runtime/reflection.hpp index dbc57ef3cfc..df84831cc7c 100644 --- a/hotspot/src/share/vm/runtime/reflection.hpp +++ b/hotspot/src/share/vm/runtime/reflection.hpp @@ -118,6 +118,10 @@ class Reflection: public AllStatic { static oop new_constructor(methodHandle method, TRAPS); // Create a java.lang.reflect.Field object based on a field descriptor static oop new_field(fieldDescriptor* fd, bool intern_name, TRAPS); + // Create a java.lang.reflect.Parameter object based on a + // MethodParameterElement + static oop new_parameter(Handle method, int index, Symbol* sym, + int flags, TRAPS); private: // method resolution for invoke From 5c6318e816370f2bea4f6c2aed7b5beeb6a1b48f Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Tue, 8 Jan 2013 14:04:25 -0500 Subject: [PATCH 043/204] 8005048: NMT: #loaded classes needs to just show the # defined classes Count number of instance classes so that it matches class metadata size Reviewed-by: coleenp, acorn --- hotspot/src/share/vm/oops/instanceKlass.cpp | 6 ++ hotspot/src/share/vm/oops/instanceKlass.hpp | 6 ++ hotspot/src/share/vm/services/memBaseline.cpp | 3 +- hotspot/src/share/vm/services/memRecorder.cpp | 9 ++- hotspot/src/share/vm/services/memRecorder.hpp | 1 + hotspot/src/share/vm/services/memSnapshot.cpp | 4 +- hotspot/src/share/vm/services/memSnapshot.hpp | 6 +- .../src/share/vm/services/memTrackWorker.cpp | 58 +++++++++---------- .../src/share/vm/services/memTrackWorker.hpp | 55 +++++++++++++++--- hotspot/src/share/vm/services/memTracker.cpp | 3 +- hotspot/src/share/vm/services/memTracker.hpp | 1 + 11 files changed, 107 insertions(+), 45 deletions(-) diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index 69d1910f2b1..4d2567effcb 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -160,6 +160,8 @@ HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__end, #endif // ndef DTRACE_ENABLED +volatile int InstanceKlass::_total_instanceKlass_count = 0; + Klass* InstanceKlass::allocate_instance_klass(ClassLoaderData* loader_data, int vtable_len, int itable_len, @@ -203,6 +205,7 @@ Klass* InstanceKlass::allocate_instance_klass(ClassLoaderData* loader_data, access_flags, !host_klass.is_null()); } + Atomic::inc(&_total_instanceKlass_count); return ik; } @@ -2306,6 +2309,9 @@ void InstanceKlass::release_C_heap_structures() { if (_array_name != NULL) _array_name->decrement_refcount(); if (_source_file_name != NULL) _source_file_name->decrement_refcount(); if (_source_debug_extension != NULL) FREE_C_HEAP_ARRAY(char, _source_debug_extension, mtClass); + + assert(_total_instanceKlass_count >= 1, "Sanity check"); + Atomic::dec(&_total_instanceKlass_count); } void InstanceKlass::set_source_file_name(Symbol* n) { diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp index ad59ab0632f..9cdeb989087 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.hpp +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp @@ -31,6 +31,7 @@ #include "oops/fieldInfo.hpp" #include "oops/instanceOop.hpp" #include "oops/klassVtable.hpp" +#include "runtime/atomic.hpp" #include "runtime/handles.hpp" #include "runtime/os.hpp" #include "utilities/accessFlags.hpp" @@ -170,6 +171,11 @@ class InstanceKlass: public Klass { initialization_error // error happened during initialization }; + static int number_of_instance_classes() { return _total_instanceKlass_count; } + + private: + static volatile int _total_instanceKlass_count; + protected: // Protection domain. oop _protection_domain; diff --git a/hotspot/src/share/vm/services/memBaseline.cpp b/hotspot/src/share/vm/services/memBaseline.cpp index 9127e00f981..9d9832e8601 100644 --- a/hotspot/src/share/vm/services/memBaseline.cpp +++ b/hotspot/src/share/vm/services/memBaseline.cpp @@ -22,7 +22,6 @@ * */ #include "precompiled.hpp" -#include "classfile/systemDictionary.hpp" #include "memory/allocation.hpp" #include "services/memBaseline.hpp" #include "services/memTracker.hpp" @@ -349,7 +348,7 @@ bool MemBaseline::baseline(MemSnapshot& snapshot, bool summary_only) { reset(); _baselined = baseline_malloc_summary(snapshot._alloc_ptrs) && baseline_vm_summary(snapshot._vm_ptrs); - _number_of_classes = SystemDictionary::number_of_classes(); + _number_of_classes = snapshot.number_of_classes(); if (!summary_only && MemTracker::track_callsite() && _baselined) { _baselined = baseline_malloc_details(snapshot._alloc_ptrs) && diff --git a/hotspot/src/share/vm/services/memRecorder.cpp b/hotspot/src/share/vm/services/memRecorder.cpp index 5ec865af323..93703269ede 100644 --- a/hotspot/src/share/vm/services/memRecorder.cpp +++ b/hotspot/src/share/vm/services/memRecorder.cpp @@ -84,10 +84,13 @@ MemRecorder::~MemRecorder() { } delete _pointer_records; } - if (_next != NULL) { - delete _next; + // delete all linked recorders + while (_next != NULL) { + MemRecorder* tmp = _next; + _next = _next->next(); + tmp->set_next(NULL); + delete tmp; } - Atomic::dec(&_instance_count); } diff --git a/hotspot/src/share/vm/services/memRecorder.hpp b/hotspot/src/share/vm/services/memRecorder.hpp index 2afeeb09b52..e4c322d65ad 100644 --- a/hotspot/src/share/vm/services/memRecorder.hpp +++ b/hotspot/src/share/vm/services/memRecorder.hpp @@ -203,6 +203,7 @@ class MemRecorder : public CHeapObj { friend class MemSnapshot; friend class MemTracker; friend class MemTrackWorker; + friend class GenerationData; protected: // the array that holds memory records diff --git a/hotspot/src/share/vm/services/memSnapshot.cpp b/hotspot/src/share/vm/services/memSnapshot.cpp index c293542f7e8..dbc0bbb4f18 100644 --- a/hotspot/src/share/vm/services/memSnapshot.cpp +++ b/hotspot/src/share/vm/services/memSnapshot.cpp @@ -384,6 +384,7 @@ MemSnapshot::MemSnapshot() { _staging_area.init(); _lock = new (std::nothrow) Mutex(Monitor::max_nonleaf - 1, "memSnapshotLock"); NOT_PRODUCT(_untracked_count = 0;) + _number_of_classes = 0; } MemSnapshot::~MemSnapshot() { @@ -479,7 +480,7 @@ bool MemSnapshot::merge(MemRecorder* rec) { // promote data to next generation -bool MemSnapshot::promote() { +bool MemSnapshot::promote(int number_of_classes) { assert(_alloc_ptrs != NULL && _vm_ptrs != NULL, "Just check"); assert(_staging_area.malloc_data() != NULL && _staging_area.vm_data() != NULL, "Just check"); @@ -496,6 +497,7 @@ bool MemSnapshot::promote() { NOT_PRODUCT(check_malloc_pointers();) _staging_area.clear(); + _number_of_classes = number_of_classes; return promoted; } diff --git a/hotspot/src/share/vm/services/memSnapshot.hpp b/hotspot/src/share/vm/services/memSnapshot.hpp index 5755108c013..7d31c7386fe 100644 --- a/hotspot/src/share/vm/services/memSnapshot.hpp +++ b/hotspot/src/share/vm/services/memSnapshot.hpp @@ -355,6 +355,9 @@ class MemSnapshot : public CHeapObj { // the lock to protect this snapshot Monitor* _lock; + // the number of instance classes + int _number_of_classes; + NOT_PRODUCT(size_t _untracked_count;) friend class MemBaseline; @@ -375,8 +378,9 @@ class MemSnapshot : public CHeapObj { // merge a per-thread memory recorder into staging area bool merge(MemRecorder* rec); // promote staged data to snapshot - bool promote(); + bool promote(int number_of_classes); + int number_of_classes() const { return _number_of_classes; } void wait(long timeout) { assert(_lock != NULL, "Just check"); diff --git a/hotspot/src/share/vm/services/memTrackWorker.cpp b/hotspot/src/share/vm/services/memTrackWorker.cpp index 9f0577af0fa..19b375d4085 100644 --- a/hotspot/src/share/vm/services/memTrackWorker.cpp +++ b/hotspot/src/share/vm/services/memTrackWorker.cpp @@ -29,6 +29,16 @@ #include "utilities/decoder.hpp" #include "utilities/vmError.hpp" + +void GenerationData::reset() { + _number_of_classes = 0; + while (_recorder_list != NULL) { + MemRecorder* tmp = _recorder_list; + _recorder_list = _recorder_list->next(); + MemTracker::release_thread_recorder(tmp); + } +} + MemTrackWorker::MemTrackWorker() { // create thread uses cgc thread type for now. We should revisit // the option, or create new thread type. @@ -39,7 +49,7 @@ MemTrackWorker::MemTrackWorker() { if (!has_error()) { _head = _tail = 0; for(int index = 0; index < MAX_GENERATIONS; index ++) { - _gen[index] = NULL; + ::new ((void*)&_gen[index]) GenerationData(); } } NOT_PRODUCT(_sync_point_count = 0;) @@ -49,10 +59,7 @@ MemTrackWorker::MemTrackWorker() { MemTrackWorker::~MemTrackWorker() { for (int index = 0; index < MAX_GENERATIONS; index ++) { - MemRecorder* rc = _gen[index]; - if (rc != NULL) { - delete rc; - } + _gen[index].reset(); } } @@ -90,12 +97,7 @@ void MemTrackWorker::run() { { // take a recorder from earliest generation in buffer ThreadCritical tc; - rec = _gen[_head]; - if (rec != NULL) { - _gen[_head] = rec->next(); - } - assert(count_recorder(_gen[_head]) <= MemRecorder::_instance_count, - "infinite loop after dequeue"); + rec = _gen[_head].next_recorder(); } if (rec != NULL) { // merge the recorder into staging area @@ -109,16 +111,20 @@ void MemTrackWorker::run() { // no more recorder to merge, promote staging area // to snapshot if (_head != _tail) { + long number_of_classes; { ThreadCritical tc; - if (_gen[_head] != NULL || _head == _tail) { + if (_gen[_head].has_more_recorder() || _head == _tail) { continue; } + number_of_classes = _gen[_head].number_of_classes(); + _gen[_head].reset(); + // done with this generation, increment _head pointer _head = (_head + 1) % MAX_GENERATIONS; } // promote this generation data to snapshot - if (!snapshot->promote()) { + if (!snapshot->promote(number_of_classes)) { // failed to promote, means out of memory MemTracker::shutdown(MemTracker::NMT_out_of_memory); } @@ -126,8 +132,8 @@ void MemTrackWorker::run() { snapshot->wait(1000); ThreadCritical tc; // check if more data arrived - if (_gen[_head] == NULL) { - _gen[_head] = MemTracker::get_pending_recorders(); + if (!_gen[_head].has_more_recorder()) { + _gen[_head].add_recorders(MemTracker::get_pending_recorders()); } } } @@ -147,7 +153,7 @@ void MemTrackWorker::run() { // 1. add all recorders in pending queue to current generation // 2. increase generation -void MemTrackWorker::at_sync_point(MemRecorder* rec) { +void MemTrackWorker::at_sync_point(MemRecorder* rec, int number_of_classes) { NOT_PRODUCT(_sync_point_count ++;) assert(count_recorder(rec) <= MemRecorder::_instance_count, "pending queue has infinite loop"); @@ -155,23 +161,15 @@ void MemTrackWorker::at_sync_point(MemRecorder* rec) { bool out_of_generation_buffer = false; // check shutdown state inside ThreadCritical if (MemTracker::shutdown_in_progress()) return; + + _gen[_tail].set_number_of_classes(number_of_classes); // append the recorders to the end of the generation - if( rec != NULL) { - MemRecorder* cur_head = _gen[_tail]; - if (cur_head == NULL) { - _gen[_tail] = rec; - } else { - while (cur_head->next() != NULL) { - cur_head = cur_head->next(); - } - cur_head->set_next(rec); - } - } - assert(count_recorder(rec) <= MemRecorder::_instance_count, + _gen[_tail].add_recorders(rec); + assert(count_recorder(_gen[_tail].peek()) <= MemRecorder::_instance_count, "after add to current generation has infinite loop"); // we have collected all recorders for this generation. If there is data, // we need to increment _tail to start a new generation. - if (_gen[_tail] != NULL || _head == _tail) { + if (_gen[_tail].has_more_recorder() || _head == _tail) { _tail = (_tail + 1) % MAX_GENERATIONS; out_of_generation_buffer = (_tail == _head); } @@ -194,7 +192,7 @@ int MemTrackWorker::count_recorder(const MemRecorder* head) { int MemTrackWorker::count_pending_recorders() const { int count = 0; for (int index = 0; index < MAX_GENERATIONS; index ++) { - MemRecorder* head = _gen[index]; + MemRecorder* head = _gen[index].peek(); if (head != NULL) { count += count_recorder(head); } diff --git a/hotspot/src/share/vm/services/memTrackWorker.hpp b/hotspot/src/share/vm/services/memTrackWorker.hpp index 969828cabee..9a2d52802e2 100644 --- a/hotspot/src/share/vm/services/memTrackWorker.hpp +++ b/hotspot/src/share/vm/services/memTrackWorker.hpp @@ -32,17 +32,58 @@ // Maximum MAX_GENERATIONS generation data can be tracked. #define MAX_GENERATIONS 512 +class GenerationData : public _ValueObj { + private: + int _number_of_classes; + MemRecorder* _recorder_list; + + public: + GenerationData(): _number_of_classes(0), _recorder_list(NULL) { } + + inline int number_of_classes() const { return _number_of_classes; } + inline void set_number_of_classes(long num) { _number_of_classes = num; } + + inline MemRecorder* next_recorder() { + if (_recorder_list == NULL) { + return NULL; + } else { + MemRecorder* tmp = _recorder_list; + _recorder_list = _recorder_list->next(); + return tmp; + } + } + + inline bool has_more_recorder() const { + return (_recorder_list != NULL); + } + + // add recorders to this generation + void add_recorders(MemRecorder* head) { + if (head != NULL) { + if (_recorder_list == NULL) { + _recorder_list = head; + } else { + MemRecorder* tmp = _recorder_list; + for (; tmp->next() != NULL; tmp = tmp->next()); + tmp->set_next(head); + } + } + } + + void reset(); + + NOT_PRODUCT(MemRecorder* peek() const { return _recorder_list; }) +}; class MemTrackWorker : public NamedThread { private: - // circular buffer. This buffer contains recorders to be merged into global + // circular buffer. This buffer contains generation data to be merged into global // snaphsot. - // Each slot holds a linked list of memory recorders, that contains one - // generation of memory data. - MemRecorder* _gen[MAX_GENERATIONS]; - int _head, _tail; // head and tail pointers to above circular buffer + // Each slot holds a generation + GenerationData _gen[MAX_GENERATIONS]; + int _head, _tail; // head and tail pointers to above circular buffer - bool _has_error; + bool _has_error; public: MemTrackWorker(); @@ -56,7 +97,7 @@ class MemTrackWorker : public NamedThread { inline bool has_error() const { return _has_error; } // task at synchronization point - void at_sync_point(MemRecorder* pending_recorders); + void at_sync_point(MemRecorder* pending_recorders, int number_of_classes); // for debugging purpose, they are not thread safe. NOT_PRODUCT(static int count_recorder(const MemRecorder* head);) diff --git a/hotspot/src/share/vm/services/memTracker.cpp b/hotspot/src/share/vm/services/memTracker.cpp index ebb690a1b9d..c8032d8fd1a 100644 --- a/hotspot/src/share/vm/services/memTracker.cpp +++ b/hotspot/src/share/vm/services/memTracker.cpp @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "oops/instanceKlass.hpp" #include "runtime/atomic.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/mutexLocker.hpp" @@ -485,7 +486,7 @@ void MemTracker::sync() { } // check _worker_thread with lock to avoid racing condition if (_worker_thread != NULL) { - _worker_thread->at_sync_point(pending_recorders); + _worker_thread->at_sync_point(pending_recorders, InstanceKlass::number_of_instance_classes()); } assert(SequenceGenerator::peek() == 1, "Should not have memory activities during sync-point"); diff --git a/hotspot/src/share/vm/services/memTracker.hpp b/hotspot/src/share/vm/services/memTracker.hpp index bd149efb3f4..538195c0c75 100644 --- a/hotspot/src/share/vm/services/memTracker.hpp +++ b/hotspot/src/share/vm/services/memTracker.hpp @@ -142,6 +142,7 @@ class Thread; * MemTracker is the 'gate' class to native memory tracking runtime. */ class MemTracker : AllStatic { + friend class GenerationData; friend class MemTrackWorker; friend class MemSnapshot; friend class SyncThreadRecorderClosure; From 38c81fb4113ed8c82c95c47c409f0e5e416c5a06 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Tue, 8 Jan 2013 11:30:51 -0800 Subject: [PATCH 044/204] 8005419: Improve intrinsics code performance on x86 by using AVX2 Use 256bit vpxor,vptest instructions in String.compareTo() and equals() intrinsics. Reviewed-by: twisti --- hotspot/src/cpu/x86/vm/assembler_x86.cpp | 20 ++ hotspot/src/cpu/x86/vm/assembler_x86.hpp | 5 +- hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp | 176 ++++++++++++++---- hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp | 4 + .../test/compiler/8005419/Test8005419.java | 120 ++++++++++++ 5 files changed, 290 insertions(+), 35 deletions(-) create mode 100644 hotspot/test/compiler/8005419/Test8005419.java diff --git a/hotspot/src/cpu/x86/vm/assembler_x86.cpp b/hotspot/src/cpu/x86/vm/assembler_x86.cpp index 5ef4cfcf905..8b474ba2409 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp @@ -2468,6 +2468,26 @@ void Assembler::ptest(XMMRegister dst, XMMRegister src) { emit_int8((unsigned char)(0xC0 | encode)); } +void Assembler::vptest(XMMRegister dst, Address src) { + assert(VM_Version::supports_avx(), ""); + InstructionMark im(this); + bool vector256 = true; + assert(dst != xnoreg, "sanity"); + int dst_enc = dst->encoding(); + // swap src<->dst for encoding + vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector256); + emit_int8(0x17); + emit_operand(dst, src); +} + +void Assembler::vptest(XMMRegister dst, XMMRegister src) { + assert(VM_Version::supports_avx(), ""); + bool vector256 = true; + int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, vector256, VEX_OPCODE_0F_38); + emit_int8(0x17); + emit_int8((unsigned char)(0xC0 | encode)); +} + void Assembler::punpcklbw(XMMRegister dst, Address src) { NOT_LP64(assert(VM_Version::supports_sse2(), "")); assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes"); diff --git a/hotspot/src/cpu/x86/vm/assembler_x86.hpp b/hotspot/src/cpu/x86/vm/assembler_x86.hpp index 569674c2a90..bcef330e4cf 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp @@ -1444,9 +1444,12 @@ private: // Shift Right by bytes Logical DoubleQuadword Immediate void psrldq(XMMRegister dst, int shift); - // Logical Compare Double Quadword + // Logical Compare 128bit void ptest(XMMRegister dst, XMMRegister src); void ptest(XMMRegister dst, Address src); + // Logical Compare 256bit + void vptest(XMMRegister dst, XMMRegister src); + void vptest(XMMRegister dst, Address src); // Interleave Low Bytes void punpcklbw(XMMRegister dst, XMMRegister src); diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp index 7b31fe7b88e..e9e414077f5 100644 --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp @@ -5675,42 +5675,114 @@ void MacroAssembler::string_compare(Register str1, Register str2, testl(cnt2, cnt2); jcc(Assembler::zero, LENGTH_DIFF_LABEL); - // Load first characters + // Compare first characters load_unsigned_short(result, Address(str1, 0)); load_unsigned_short(cnt1, Address(str2, 0)); - - // Compare first characters subl(result, cnt1); jcc(Assembler::notZero, POP_LABEL); - decrementl(cnt2); - jcc(Assembler::zero, LENGTH_DIFF_LABEL); + cmpl(cnt2, 1); + jcc(Assembler::equal, LENGTH_DIFF_LABEL); - { - // Check after comparing first character to see if strings are equivalent - Label LSkip2; - // Check if the strings start at same location - cmpptr(str1, str2); - jccb(Assembler::notEqual, LSkip2); - - // Check if the length difference is zero (from stack) - cmpl(Address(rsp, 0), 0x0); - jcc(Assembler::equal, LENGTH_DIFF_LABEL); - - // Strings might not be equivalent - bind(LSkip2); - } + // Check if the strings start at the same location. + cmpptr(str1, str2); + jcc(Assembler::equal, LENGTH_DIFF_LABEL); Address::ScaleFactor scale = Address::times_2; int stride = 8; - // Advance to next element - addptr(str1, 16/stride); - addptr(str2, 16/stride); + if (UseAVX >= 2) { + Label COMPARE_WIDE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_WIDE_TAIL, COMPARE_SMALL_STR; + Label COMPARE_WIDE_VECTORS_LOOP, COMPARE_16_CHARS, COMPARE_INDEX_CHAR; + Label COMPARE_TAIL_LONG; + int pcmpmask = 0x19; - if (UseSSE42Intrinsics) { + // Setup to compare 16-chars (32-bytes) vectors, + // start from first character again because it has aligned address. + int stride2 = 16; + int adr_stride = stride << scale; + int adr_stride2 = stride2 << scale; + + assert(result == rax && cnt2 == rdx && cnt1 == rcx, "pcmpestri"); + // rax and rdx are used by pcmpestri as elements counters + movl(result, cnt2); + andl(cnt2, ~(stride2-1)); // cnt2 holds the vector count + jcc(Assembler::zero, COMPARE_TAIL_LONG); + + // fast path : compare first 2 8-char vectors. + bind(COMPARE_16_CHARS); + movdqu(vec1, Address(str1, 0)); + pcmpestri(vec1, Address(str2, 0), pcmpmask); + jccb(Assembler::below, COMPARE_INDEX_CHAR); + + movdqu(vec1, Address(str1, adr_stride)); + pcmpestri(vec1, Address(str2, adr_stride), pcmpmask); + jccb(Assembler::aboveEqual, COMPARE_WIDE_VECTORS); + addl(cnt1, stride); + + // Compare the characters at index in cnt1 + bind(COMPARE_INDEX_CHAR); //cnt1 has the offset of the mismatching character + load_unsigned_short(result, Address(str1, cnt1, scale)); + load_unsigned_short(cnt2, Address(str2, cnt1, scale)); + subl(result, cnt2); + jmp(POP_LABEL); + + // Setup the registers to start vector comparison loop + bind(COMPARE_WIDE_VECTORS); + lea(str1, Address(str1, result, scale)); + lea(str2, Address(str2, result, scale)); + subl(result, stride2); + subl(cnt2, stride2); + jccb(Assembler::zero, COMPARE_WIDE_TAIL); + negptr(result); + + // In a loop, compare 16-chars (32-bytes) at once using (vpxor+vptest) + bind(COMPARE_WIDE_VECTORS_LOOP); + vmovdqu(vec1, Address(str1, result, scale)); + vpxor(vec1, Address(str2, result, scale)); + vptest(vec1, vec1); + jccb(Assembler::notZero, VECTOR_NOT_EQUAL); + addptr(result, stride2); + subl(cnt2, stride2); + jccb(Assembler::notZero, COMPARE_WIDE_VECTORS_LOOP); + + // compare wide vectors tail + bind(COMPARE_WIDE_TAIL); + testptr(result, result); + jccb(Assembler::zero, LENGTH_DIFF_LABEL); + + movl(result, stride2); + movl(cnt2, result); + negptr(result); + jmpb(COMPARE_WIDE_VECTORS_LOOP); + + // Identifies the mismatching (higher or lower)16-bytes in the 32-byte vectors. + bind(VECTOR_NOT_EQUAL); + lea(str1, Address(str1, result, scale)); + lea(str2, Address(str2, result, scale)); + jmp(COMPARE_16_CHARS); + + // Compare tail chars, length between 1 to 15 chars + bind(COMPARE_TAIL_LONG); + movl(cnt2, result); + cmpl(cnt2, stride); + jccb(Assembler::less, COMPARE_SMALL_STR); + + movdqu(vec1, Address(str1, 0)); + pcmpestri(vec1, Address(str2, 0), pcmpmask); + jcc(Assembler::below, COMPARE_INDEX_CHAR); + subptr(cnt2, stride); + jccb(Assembler::zero, LENGTH_DIFF_LABEL); + lea(str1, Address(str1, result, scale)); + lea(str2, Address(str2, result, scale)); + negptr(cnt2); + jmpb(WHILE_HEAD_LABEL); + + bind(COMPARE_SMALL_STR); + } else if (UseSSE42Intrinsics) { Label COMPARE_WIDE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_TAIL; int pcmpmask = 0x19; - // Setup to compare 16-byte vectors + // Setup to compare 8-char (16-byte) vectors, + // start from first character again because it has aligned address. movl(result, cnt2); andl(cnt2, ~(stride - 1)); // cnt2 holds the vector count jccb(Assembler::zero, COMPARE_TAIL); @@ -5742,7 +5814,7 @@ void MacroAssembler::string_compare(Register str1, Register str2, jccb(Assembler::notZero, COMPARE_WIDE_VECTORS); // compare wide vectors tail - testl(result, result); + testptr(result, result); jccb(Assembler::zero, LENGTH_DIFF_LABEL); movl(cnt2, stride); @@ -5754,21 +5826,20 @@ void MacroAssembler::string_compare(Register str1, Register str2, // Mismatched characters in the vectors bind(VECTOR_NOT_EQUAL); - addptr(result, cnt1); - movptr(cnt2, result); - load_unsigned_short(result, Address(str1, cnt2, scale)); - load_unsigned_short(cnt1, Address(str2, cnt2, scale)); - subl(result, cnt1); + addptr(cnt1, result); + load_unsigned_short(result, Address(str1, cnt1, scale)); + load_unsigned_short(cnt2, Address(str2, cnt1, scale)); + subl(result, cnt2); jmpb(POP_LABEL); bind(COMPARE_TAIL); // limit is zero movl(cnt2, result); // Fallthru to tail compare } - // Shift str2 and str1 to the end of the arrays, negate min - lea(str1, Address(str1, cnt2, scale, 0)); - lea(str2, Address(str2, cnt2, scale, 0)); + lea(str1, Address(str1, cnt2, scale)); + lea(str2, Address(str2, cnt2, scale)); + decrementl(cnt2); // first character was compared already negptr(cnt2); // Compare the rest of the elements @@ -5833,7 +5904,44 @@ void MacroAssembler::char_arrays_equals(bool is_array_equ, Register ary1, Regist shll(limit, 1); // byte count != 0 movl(result, limit); // copy - if (UseSSE42Intrinsics) { + if (UseAVX >= 2) { + // With AVX2, use 32-byte vector compare + Label COMPARE_WIDE_VECTORS, COMPARE_TAIL; + + // Compare 32-byte vectors + andl(result, 0x0000001e); // tail count (in bytes) + andl(limit, 0xffffffe0); // vector count (in bytes) + jccb(Assembler::zero, COMPARE_TAIL); + + lea(ary1, Address(ary1, limit, Address::times_1)); + lea(ary2, Address(ary2, limit, Address::times_1)); + negptr(limit); + + bind(COMPARE_WIDE_VECTORS); + vmovdqu(vec1, Address(ary1, limit, Address::times_1)); + vmovdqu(vec2, Address(ary2, limit, Address::times_1)); + vpxor(vec1, vec2); + + vptest(vec1, vec1); + jccb(Assembler::notZero, FALSE_LABEL); + addptr(limit, 32); + jcc(Assembler::notZero, COMPARE_WIDE_VECTORS); + + testl(result, result); + jccb(Assembler::zero, TRUE_LABEL); + + vmovdqu(vec1, Address(ary1, result, Address::times_1, -32)); + vmovdqu(vec2, Address(ary2, result, Address::times_1, -32)); + vpxor(vec1, vec2); + + vptest(vec1, vec1); + jccb(Assembler::notZero, FALSE_LABEL); + jmpb(TRUE_LABEL); + + bind(COMPARE_TAIL); // limit is zero + movl(limit, result); + // Fallthru to tail compare + } else if (UseSSE42Intrinsics) { // With SSE4.2, use double quad vector compare Label COMPARE_WIDE_VECTORS, COMPARE_TAIL; diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp index b77e4e9e200..3afcf23ebae 100644 --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp @@ -1011,6 +1011,10 @@ public: Assembler::vxorpd(dst, nds, src, vector256); } + // Simple version for AVX2 256bit vectors + void vpxor(XMMRegister dst, XMMRegister src) { Assembler::vpxor(dst, dst, src, true); } + void vpxor(XMMRegister dst, Address src) { Assembler::vpxor(dst, dst, src, true); } + // Move packed integer values from low 128 bit to hign 128 bit in 256 bit vector. void vinserti128h(XMMRegister dst, XMMRegister nds, XMMRegister src) { if (UseAVX > 1) // vinserti128h is available only in AVX2 diff --git a/hotspot/test/compiler/8005419/Test8005419.java b/hotspot/test/compiler/8005419/Test8005419.java new file mode 100644 index 00000000000..80b4e0fc037 --- /dev/null +++ b/hotspot/test/compiler/8005419/Test8005419.java @@ -0,0 +1,120 @@ +/* + * 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. + */ + +/* + * @test + * @bug 8005419 + * @summary Improve intrinsics code performance on x86 by using AVX2 + * @run main/othervm -Xbatch -Xmx64m Test8005419 + * + */ + +public class Test8005419 { + public static int SIZE = 64; + + public static void main(String[] args) { + char[] a = new char[SIZE]; + char[] b = new char[SIZE]; + + for (int i = 16; i < SIZE; i++) { + a[i] = (char)i; + b[i] = (char)i; + } + String s1 = new String(a); + String s2 = new String(b); + + // Warm up + boolean failed = false; + int result = 0; + for (int i = 0; i < 10000; i++) { + result += test(s1, s2); + } + for (int i = 0; i < 10000; i++) { + result += test(s1, s2); + } + for (int i = 0; i < 10000; i++) { + result += test(s1, s2); + } + if (result != 0) failed = true; + + System.out.println("Start testing"); + // Compare same string + result = test(s1, s1); + if (result != 0) { + failed = true; + System.out.println("Failed same: result = " + result + ", expected 0"); + } + // Compare equal strings + for (int i = 1; i <= SIZE; i++) { + s1 = new String(a, 0, i); + s2 = new String(b, 0, i); + result = test(s1, s2); + if (result != 0) { + failed = true; + System.out.println("Failed equals s1[" + i + "], s2[" + i + "]: result = " + result + ", expected 0"); + } + } + // Compare equal strings but different sizes + for (int i = 1; i <= SIZE; i++) { + s1 = new String(a, 0, i); + for (int j = 1; j <= SIZE; j++) { + s2 = new String(b, 0, j); + result = test(s1, s2); + if (result != (i-j)) { + failed = true; + System.out.println("Failed diff size s1[" + i + "], s2[" + j + "]: result = " + result + ", expected " + (i-j)); + } + } + } + // Compare strings with one char different and different sizes + for (int i = 1; i <= SIZE; i++) { + s1 = new String(a, 0, i); + for (int j = 0; j < i; j++) { + b[j] -= 3; // change char + s2 = new String(b, 0, i); + result = test(s1, s2); + int chdiff = a[j] - b[j]; + if (result != chdiff) { + failed = true; + System.out.println("Failed diff char s1[" + i + "], s2[" + i + "]: result = " + result + ", expected " + chdiff); + } + result = test(s2, s1); + chdiff = b[j] - a[j]; + if (result != chdiff) { + failed = true; + System.out.println("Failed diff char s2[" + i + "], s1[" + i + "]: result = " + result + ", expected " + chdiff); + } + b[j] += 3; // restore + } + } + if (failed) { + System.out.println("FAILED"); + System.exit(97); + } + System.out.println("PASSED"); + } + + private static int test(String str1, String str2) { + return str1.compareTo(str2); + } +} From 3c8b65b820be21a99c506f24624c801f60e6befc Mon Sep 17 00:00:00 2001 From: Tim Bell Date: Tue, 8 Jan 2013 16:23:45 -0800 Subject: [PATCH 045/204] 8005794: in new infra, how do we change java -version? Added configure parameter --with-user-release-suffix Reviewed-by: ohair, tbell --- common/autoconf/generated-configure.sh | 523 +++++++++++++------------ common/autoconf/jdk-options.m4 | 36 +- 2 files changed, 303 insertions(+), 256 deletions(-) diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index 909206ab8c0..6a8d834abae 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.67 for OpenJDK jdk8. +# Generated by GNU Autoconf 2.68 for OpenJDK jdk8. # # Report bugs to . # @@ -91,6 +91,7 @@ fi IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. +as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -216,11 +217,18 @@ IFS=$as_save_IFS # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. + # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL - exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} + case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; + esac + exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : @@ -752,7 +760,6 @@ BOOT_RTJAR JAVA_CHECK JAVAC_CHECK COOKED_BUILD_NUMBER -USER_RELEASE_SUFFIX JDK_VERSION COPYRIGHT_YEAR MACOSX_BUNDLE_ID_BASE @@ -768,6 +775,7 @@ JDK_UPDATE_VERSION JDK_MICRO_VERSION JDK_MINOR_VERSION JDK_MAJOR_VERSION +USER_RELEASE_SUFFIX COMPRESS_JARS UNLIMITED_CRYPTO CACERTS_FILE @@ -970,6 +978,7 @@ with_cacerts_file enable_unlimited_crypto with_milestone with_build_number +with_user_release_suffix with_boot_jdk with_boot_jdk_jvmargs with_add_source_root @@ -1432,7 +1441,7 @@ Try \`$0 --help' for more information" $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac @@ -1701,6 +1710,9 @@ Optional Packages: --with-cacerts-file specify alternative cacerts file --with-milestone Set milestone value for build [internal] --with-build-number Set build number value for build [b00] + --with-user-release-suffix + Add a custom string to the version string if build + number isn't set.[username_builddateb00] --with-boot-jdk path to Boot JDK (used to bootstrap build) [probed] --with-boot-jdk-jvmargs specify JVM arguments to be passed to all invocations of the Boot JDK, overriding the default @@ -1854,7 +1866,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF OpenJDK configure jdk8 -generated by GNU Autoconf 2.67 +generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation @@ -1900,7 +1912,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile @@ -1938,7 +1950,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile @@ -1976,7 +1988,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_objc_try_compile @@ -2013,7 +2025,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp @@ -2050,7 +2062,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp @@ -2063,10 +2075,10 @@ fi ac_fn_cxx_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval "test \"\${$3+set}\"" = set; then : + if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 @@ -2133,7 +2145,7 @@ $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" @@ -2142,7 +2154,7 @@ eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_mongrel @@ -2183,7 +2195,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_run @@ -2197,7 +2209,7 @@ ac_fn_cxx_check_header_compile () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2215,7 +2227,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_compile @@ -2392,7 +2404,7 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ rm -f conftest.val fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_compute_int @@ -2438,7 +2450,7 @@ fi # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_link @@ -2451,7 +2463,7 @@ ac_fn_cxx_check_func () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2506,7 +2518,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_func @@ -2519,7 +2531,7 @@ ac_fn_c_check_header_compile () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2537,7 +2549,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile cat >config.log <<_ACEOF @@ -2545,7 +2557,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by OpenJDK $as_me jdk8, which was -generated by GNU Autoconf 2.67. Invocation command line was +generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2803,7 +2815,7 @@ $as_echo "$as_me: loading site script $ac_site_file" >&6;} || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } fi done @@ -3686,7 +3698,7 @@ fi #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1357219413 +DATE_WHEN_GENERATED=1357690920 ############################################################################### # @@ -3724,7 +3736,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_BASENAME+set}" = set; then : +if ${ac_cv_path_BASENAME+:} false; then : $as_echo_n "(cached) " >&6 else case $BASENAME in @@ -3783,7 +3795,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_BASH+set}" = set; then : +if ${ac_cv_path_BASH+:} false; then : $as_echo_n "(cached) " >&6 else case $BASH in @@ -3842,7 +3854,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CAT+set}" = set; then : +if ${ac_cv_path_CAT+:} false; then : $as_echo_n "(cached) " >&6 else case $CAT in @@ -3901,7 +3913,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CHMOD+set}" = set; then : +if ${ac_cv_path_CHMOD+:} false; then : $as_echo_n "(cached) " >&6 else case $CHMOD in @@ -3960,7 +3972,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CMP+set}" = set; then : +if ${ac_cv_path_CMP+:} false; then : $as_echo_n "(cached) " >&6 else case $CMP in @@ -4019,7 +4031,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_COMM+set}" = set; then : +if ${ac_cv_path_COMM+:} false; then : $as_echo_n "(cached) " >&6 else case $COMM in @@ -4078,7 +4090,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CP+set}" = set; then : +if ${ac_cv_path_CP+:} false; then : $as_echo_n "(cached) " >&6 else case $CP in @@ -4137,7 +4149,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CPIO+set}" = set; then : +if ${ac_cv_path_CPIO+:} false; then : $as_echo_n "(cached) " >&6 else case $CPIO in @@ -4196,7 +4208,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CUT+set}" = set; then : +if ${ac_cv_path_CUT+:} false; then : $as_echo_n "(cached) " >&6 else case $CUT in @@ -4255,7 +4267,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_DATE+set}" = set; then : +if ${ac_cv_path_DATE+:} false; then : $as_echo_n "(cached) " >&6 else case $DATE in @@ -4314,7 +4326,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_DIFF+set}" = set; then : +if ${ac_cv_path_DIFF+:} false; then : $as_echo_n "(cached) " >&6 else case $DIFF in @@ -4373,7 +4385,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_DIRNAME+set}" = set; then : +if ${ac_cv_path_DIRNAME+:} false; then : $as_echo_n "(cached) " >&6 else case $DIRNAME in @@ -4432,7 +4444,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_ECHO+set}" = set; then : +if ${ac_cv_path_ECHO+:} false; then : $as_echo_n "(cached) " >&6 else case $ECHO in @@ -4491,7 +4503,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_EXPR+set}" = set; then : +if ${ac_cv_path_EXPR+:} false; then : $as_echo_n "(cached) " >&6 else case $EXPR in @@ -4550,7 +4562,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_FILE+set}" = set; then : +if ${ac_cv_path_FILE+:} false; then : $as_echo_n "(cached) " >&6 else case $FILE in @@ -4609,7 +4621,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_FIND+set}" = set; then : +if ${ac_cv_path_FIND+:} false; then : $as_echo_n "(cached) " >&6 else case $FIND in @@ -4668,7 +4680,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_HEAD+set}" = set; then : +if ${ac_cv_path_HEAD+:} false; then : $as_echo_n "(cached) " >&6 else case $HEAD in @@ -4727,7 +4739,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_LN+set}" = set; then : +if ${ac_cv_path_LN+:} false; then : $as_echo_n "(cached) " >&6 else case $LN in @@ -4786,7 +4798,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_LS+set}" = set; then : +if ${ac_cv_path_LS+:} false; then : $as_echo_n "(cached) " >&6 else case $LS in @@ -4845,7 +4857,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_MKDIR+set}" = set; then : +if ${ac_cv_path_MKDIR+:} false; then : $as_echo_n "(cached) " >&6 else case $MKDIR in @@ -4904,7 +4916,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_MKTEMP+set}" = set; then : +if ${ac_cv_path_MKTEMP+:} false; then : $as_echo_n "(cached) " >&6 else case $MKTEMP in @@ -4963,7 +4975,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_MV+set}" = set; then : +if ${ac_cv_path_MV+:} false; then : $as_echo_n "(cached) " >&6 else case $MV in @@ -5022,7 +5034,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_PRINTF+set}" = set; then : +if ${ac_cv_path_PRINTF+:} false; then : $as_echo_n "(cached) " >&6 else case $PRINTF in @@ -5081,7 +5093,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_THEPWDCMD+set}" = set; then : +if ${ac_cv_path_THEPWDCMD+:} false; then : $as_echo_n "(cached) " >&6 else case $THEPWDCMD in @@ -5140,7 +5152,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_RM+set}" = set; then : +if ${ac_cv_path_RM+:} false; then : $as_echo_n "(cached) " >&6 else case $RM in @@ -5199,7 +5211,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_SH+set}" = set; then : +if ${ac_cv_path_SH+:} false; then : $as_echo_n "(cached) " >&6 else case $SH in @@ -5258,7 +5270,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_SORT+set}" = set; then : +if ${ac_cv_path_SORT+:} false; then : $as_echo_n "(cached) " >&6 else case $SORT in @@ -5317,7 +5329,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_TAIL+set}" = set; then : +if ${ac_cv_path_TAIL+:} false; then : $as_echo_n "(cached) " >&6 else case $TAIL in @@ -5376,7 +5388,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_TAR+set}" = set; then : +if ${ac_cv_path_TAR+:} false; then : $as_echo_n "(cached) " >&6 else case $TAR in @@ -5435,7 +5447,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_TEE+set}" = set; then : +if ${ac_cv_path_TEE+:} false; then : $as_echo_n "(cached) " >&6 else case $TEE in @@ -5494,7 +5506,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_TOUCH+set}" = set; then : +if ${ac_cv_path_TOUCH+:} false; then : $as_echo_n "(cached) " >&6 else case $TOUCH in @@ -5553,7 +5565,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_TR+set}" = set; then : +if ${ac_cv_path_TR+:} false; then : $as_echo_n "(cached) " >&6 else case $TR in @@ -5612,7 +5624,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_UNAME+set}" = set; then : +if ${ac_cv_path_UNAME+:} false; then : $as_echo_n "(cached) " >&6 else case $UNAME in @@ -5671,7 +5683,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_UNIQ+set}" = set; then : +if ${ac_cv_path_UNIQ+:} false; then : $as_echo_n "(cached) " >&6 else case $UNIQ in @@ -5730,7 +5742,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_WC+set}" = set; then : +if ${ac_cv_path_WC+:} false; then : $as_echo_n "(cached) " >&6 else case $WC in @@ -5789,7 +5801,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_WHICH+set}" = set; then : +if ${ac_cv_path_WHICH+:} false; then : $as_echo_n "(cached) " >&6 else case $WHICH in @@ -5848,7 +5860,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_XARGS+set}" = set; then : +if ${ac_cv_path_XARGS+:} false; then : $as_echo_n "(cached) " >&6 else case $XARGS in @@ -5908,7 +5920,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_AWK+set}" = set; then : +if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then @@ -5958,7 +5970,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if test "${ac_cv_path_GREP+set}" = set; then : +if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then @@ -6033,7 +6045,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } -if test "${ac_cv_path_EGREP+set}" = set; then : +if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 @@ -6112,7 +6124,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } -if test "${ac_cv_path_FGREP+set}" = set; then : +if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 @@ -6191,7 +6203,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } -if test "${ac_cv_path_SED+set}" = set; then : +if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ @@ -6277,7 +6289,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_NAWK+set}" = set; then : +if ${ac_cv_path_NAWK+:} false; then : $as_echo_n "(cached) " >&6 else case $NAWK in @@ -6337,7 +6349,7 @@ RM="$RM -f" set dummy cygpath; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CYGPATH+set}" = set; then : +if ${ac_cv_path_CYGPATH+:} false; then : $as_echo_n "(cached) " >&6 else case $CYGPATH in @@ -6377,7 +6389,7 @@ fi set dummy readlink; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_READLINK+set}" = set; then : +if ${ac_cv_path_READLINK+:} false; then : $as_echo_n "(cached) " >&6 else case $READLINK in @@ -6417,7 +6429,7 @@ fi set dummy df; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_DF+set}" = set; then : +if ${ac_cv_path_DF+:} false; then : $as_echo_n "(cached) " >&6 else case $DF in @@ -6457,7 +6469,7 @@ fi set dummy SetFile; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_SETFILE+set}" = set; then : +if ${ac_cv_path_SETFILE+:} false; then : $as_echo_n "(cached) " >&6 else case $SETFILE in @@ -6503,7 +6515,7 @@ $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } -if test "${ac_cv_build+set}" = set; then : +if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias @@ -6519,7 +6531,7 @@ fi $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; -*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5 ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' @@ -6537,7 +6549,7 @@ case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } -if test "${ac_cv_host+set}" = set; then : +if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then @@ -6552,7 +6564,7 @@ fi $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; -*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5 ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' @@ -6570,7 +6582,7 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 $as_echo_n "checking target system type... " >&6; } -if test "${ac_cv_target+set}" = set; then : +if ${ac_cv_target+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$target_alias" = x; then @@ -6585,7 +6597,7 @@ fi $as_echo "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; -*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5 ;; +*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' @@ -8004,7 +8016,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_PKGHANDLER+set}" = set; then : +if ${ac_cv_prog_PKGHANDLER+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PKGHANDLER"; then @@ -8369,7 +8381,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CHECK_GMAKE+set}" = set; then : +if ${ac_cv_path_CHECK_GMAKE+:} false; then : $as_echo_n "(cached) " >&6 else case $CHECK_GMAKE in @@ -8723,7 +8735,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CHECK_MAKE+set}" = set; then : +if ${ac_cv_path_CHECK_MAKE+:} false; then : $as_echo_n "(cached) " >&6 else case $CHECK_MAKE in @@ -9082,7 +9094,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CHECK_TOOLSDIR_GMAKE+set}" = set; then : +if ${ac_cv_path_CHECK_TOOLSDIR_GMAKE+:} false; then : $as_echo_n "(cached) " >&6 else case $CHECK_TOOLSDIR_GMAKE in @@ -9435,7 +9447,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CHECK_TOOLSDIR_MAKE+set}" = set; then : +if ${ac_cv_path_CHECK_TOOLSDIR_MAKE+:} false; then : $as_echo_n "(cached) " >&6 else case $CHECK_TOOLSDIR_MAKE in @@ -9831,7 +9843,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_UNZIP+set}" = set; then : +if ${ac_cv_path_UNZIP+:} false; then : $as_echo_n "(cached) " >&6 else case $UNZIP in @@ -9890,7 +9902,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_ZIP+set}" = set; then : +if ${ac_cv_path_ZIP+:} false; then : $as_echo_n "(cached) " >&6 else case $ZIP in @@ -9949,7 +9961,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} set dummy ldd; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_LDD+set}" = set; then : +if ${ac_cv_path_LDD+:} false; then : $as_echo_n "(cached) " >&6 else case $LDD in @@ -9995,7 +10007,7 @@ fi set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_OTOOL+set}" = set; then : +if ${ac_cv_path_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else case $OTOOL in @@ -10040,7 +10052,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_READELF+set}" = set; then : +if ${ac_cv_path_READELF+:} false; then : $as_echo_n "(cached) " >&6 else case $READELF in @@ -10083,7 +10095,7 @@ done set dummy hg; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_HG+set}" = set; then : +if ${ac_cv_path_HG+:} false; then : $as_echo_n "(cached) " >&6 else case $HG in @@ -10123,7 +10135,7 @@ fi set dummy stat; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_STAT+set}" = set; then : +if ${ac_cv_path_STAT+:} false; then : $as_echo_n "(cached) " >&6 else case $STAT in @@ -10163,7 +10175,7 @@ fi set dummy time; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_TIME+set}" = set; then : +if ${ac_cv_path_TIME+:} false; then : $as_echo_n "(cached) " >&6 else case $TIME in @@ -10208,7 +10220,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_COMM+set}" = set; then : +if ${ac_cv_path_COMM+:} false; then : $as_echo_n "(cached) " >&6 else case $COMM in @@ -10272,7 +10284,7 @@ if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_PKG_CONFIG+set}" = set; then : +if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in @@ -10315,7 +10327,7 @@ if test -z "$ac_cv_path_PKG_CONFIG"; then set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then : +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in @@ -10488,7 +10500,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_BDEPS_UNZIP+set}" = set; then : +if ${ac_cv_prog_BDEPS_UNZIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$BDEPS_UNZIP"; then @@ -10534,7 +10546,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_BDEPS_FTP+set}" = set; then : +if ${ac_cv_prog_BDEPS_FTP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$BDEPS_FTP"; then @@ -10739,11 +10751,11 @@ if test "${with_milestone+set}" = set; then : fi if test "x$with_milestone" = xyes; then - as_fn_error $? "Milestone must have a value" "$LINENO" 5 + as_fn_error $? "Milestone must have a value" "$LINENO" 5 elif test "x$with_milestone" != x; then MILESTONE="$with_milestone" else - MILESTONE=internal + MILESTONE=internal fi @@ -10753,14 +10765,32 @@ if test "${with_build_number+set}" = set; then : fi if test "x$with_build_number" = xyes; then - as_fn_error $? "Build number must have a value" "$LINENO" 5 + as_fn_error $? "Build number must have a value" "$LINENO" 5 elif test "x$with_build_number" != x; then - JDK_BUILD_NUMBER="$with_build_number" + JDK_BUILD_NUMBER="$with_build_number" fi if test "x$JDK_BUILD_NUMBER" = x; then - JDK_BUILD_NUMBER=b00 + JDK_BUILD_NUMBER=b00 fi + +# Check whether --with-user-release-suffix was given. +if test "${with_user_release_suffix+set}" = set; then : + withval=$with_user_release_suffix; +fi + +if test "x$with_user_release_suffix" = xyes; then + as_fn_error $? "Release suffix must have a value" "$LINENO" 5 +elif test "x$with_user_release_suffix" != x; then + USER_RELEASE_SUFFIX="$with_user_release_suffix" +else + BUILD_DATE=`date '+%Y_%m_%d_%H_%M'` + # Avoid [:alnum:] since it depends on the locale. + CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyz0123456789'` + USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` +fi + + # Now set the JDK version, milestone, build number etc. @@ -10780,18 +10810,12 @@ COPYRIGHT_YEAR=`date +'%Y'` if test "x$JDK_UPDATE_VERSION" != x; then - JDK_VERSION="${JDK_MAJOR_VERSION}.${JDK_MINOR_VERSION}.${JDK_MICRO_VERSION}_${JDK_UPDATE_VERSION}" + JDK_VERSION="${JDK_MAJOR_VERSION}.${JDK_MINOR_VERSION}.${JDK_MICRO_VERSION}_${JDK_UPDATE_VERSION}" else - JDK_VERSION="${JDK_MAJOR_VERSION}.${JDK_MINOR_VERSION}.${JDK_MICRO_VERSION}" + JDK_VERSION="${JDK_MAJOR_VERSION}.${JDK_MINOR_VERSION}.${JDK_MICRO_VERSION}" fi -BUILD_DATE=`date '+%Y_%m_%d_%H_%M'` -# Avoid [:alnum:] since it depends on the locale. -CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyz0123456789'` -USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - - COOKED_BUILD_NUMBER=`$ECHO $JDK_BUILD_NUMBER | $SED -e 's/^b//' -e 's/^0//'` @@ -11836,7 +11860,7 @@ $as_echo "$BOOT_JDK_VERSION" >&6; } set dummy javac; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_JAVAC_CHECK+set}" = set; then : +if ${ac_cv_path_JAVAC_CHECK+:} false; then : $as_echo_n "(cached) " >&6 else case $JAVAC_CHECK in @@ -11876,7 +11900,7 @@ fi set dummy java; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_JAVA_CHECK+set}" = set; then : +if ${ac_cv_path_JAVA_CHECK+:} false; then : $as_echo_n "(cached) " >&6 else case $JAVA_CHECK in @@ -15935,7 +15959,7 @@ if test "x$OPENJDK_TARGET_OS" = "xwindows"; then set dummy link; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CYGWIN_LINK+set}" = set; then : +if ${ac_cv_path_CYGWIN_LINK+:} false; then : $as_echo_n "(cached) " >&6 else case $CYGWIN_LINK in @@ -16924,7 +16948,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_BUILD_CC+set}" = set; then : +if ${ac_cv_path_BUILD_CC+:} false; then : $as_echo_n "(cached) " >&6 else case $BUILD_CC in @@ -17235,7 +17259,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_BUILD_CXX+set}" = set; then : +if ${ac_cv_path_BUILD_CXX+:} false; then : $as_echo_n "(cached) " >&6 else case $BUILD_CXX in @@ -17544,7 +17568,7 @@ $as_echo "$as_me: Rewriting BUILD_CXX to \"$new_complete\"" >&6;} set dummy ld; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_BUILD_LD+set}" = set; then : +if ${ac_cv_path_BUILD_LD+:} false; then : $as_echo_n "(cached) " >&6 else case $BUILD_LD in @@ -18056,7 +18080,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_TOOLS_DIR_CC+set}" = set; then : +if ${ac_cv_path_TOOLS_DIR_CC+:} false; then : $as_echo_n "(cached) " >&6 else case $TOOLS_DIR_CC in @@ -18108,7 +18132,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_POTENTIAL_CC+set}" = set; then : +if ${ac_cv_path_POTENTIAL_CC+:} false; then : $as_echo_n "(cached) " >&6 else case $POTENTIAL_CC in @@ -18521,7 +18545,7 @@ $as_echo "yes, trying to find proper $COMPILER_NAME compiler" >&6; } set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_PROPER_COMPILER_CC+set}" = set; then : +if ${ac_cv_prog_PROPER_COMPILER_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PROPER_COMPILER_CC"; then @@ -18565,7 +18589,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_PROPER_COMPILER_CC+set}" = set; then : +if ${ac_cv_prog_ac_ct_PROPER_COMPILER_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_PROPER_COMPILER_CC"; then @@ -19015,7 +19039,7 @@ if test -n "$ac_tool_prefix"; then set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : +if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then @@ -19059,7 +19083,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : +if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then @@ -19112,7 +19136,7 @@ fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 @@ -19227,7 +19251,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } @@ -19270,7 +19294,7 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 @@ -19329,7 +19353,7 @@ $as_echo "$ac_try_echo"; } >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } fi fi fi @@ -19340,7 +19364,7 @@ rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } -if test "${ac_cv_objext+set}" = set; then : +if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -19381,7 +19405,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi @@ -19391,7 +19415,7 @@ OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if test "${ac_cv_c_compiler_gnu+set}" = set; then : +if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -19428,7 +19452,7 @@ ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } -if test "${ac_cv_prog_cc_g+set}" = set; then : +if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag @@ -19506,7 +19530,7 @@ else fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if test "${ac_cv_prog_cc_c89+set}" = set; then : +if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no @@ -19625,7 +19649,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_TOOLS_DIR_CXX+set}" = set; then : +if ${ac_cv_path_TOOLS_DIR_CXX+:} false; then : $as_echo_n "(cached) " >&6 else case $TOOLS_DIR_CXX in @@ -19677,7 +19701,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_POTENTIAL_CXX+set}" = set; then : +if ${ac_cv_path_POTENTIAL_CXX+:} false; then : $as_echo_n "(cached) " >&6 else case $POTENTIAL_CXX in @@ -20090,7 +20114,7 @@ $as_echo "yes, trying to find proper $COMPILER_NAME compiler" >&6; } set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_PROPER_COMPILER_CXX+set}" = set; then : +if ${ac_cv_prog_PROPER_COMPILER_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PROPER_COMPILER_CXX"; then @@ -20134,7 +20158,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_PROPER_COMPILER_CXX+set}" = set; then : +if ${ac_cv_prog_ac_ct_PROPER_COMPILER_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_PROPER_COMPILER_CXX"; then @@ -20588,7 +20612,7 @@ if test -z "$CXX"; then set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CXX+set}" = set; then : +if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then @@ -20632,7 +20656,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then : +if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then @@ -20710,7 +20734,7 @@ done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } -if test "${ac_cv_cxx_compiler_gnu+set}" = set; then : +if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -20747,7 +20771,7 @@ ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } -if test "${ac_cv_prog_cxx_g+set}" = set; then : +if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag @@ -20845,7 +20869,7 @@ if test -n "$ac_tool_prefix"; then set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_OBJC+set}" = set; then : +if ${ac_cv_prog_OBJC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJC"; then @@ -20889,7 +20913,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_OBJC+set}" = set; then : +if ${ac_cv_prog_ac_ct_OBJC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJC"; then @@ -20965,7 +20989,7 @@ done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU Objective C compiler" >&5 $as_echo_n "checking whether we are using the GNU Objective C compiler... " >&6; } -if test "${ac_cv_objc_compiler_gnu+set}" = set; then : +if ${ac_cv_objc_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -21002,7 +21026,7 @@ ac_test_OBJCFLAGS=${OBJCFLAGS+set} ac_save_OBJCFLAGS=$OBJCFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $OBJC accepts -g" >&5 $as_echo_n "checking whether $OBJC accepts -g... " >&6; } -if test "${ac_cv_prog_objc_g+set}" = set; then : +if ${ac_cv_prog_objc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_objc_werror_flag=$ac_objc_werror_flag @@ -21378,7 +21402,7 @@ if test "x$OPENJDK_TARGET_OS" != xwindows; then set dummy ${ac_tool_prefix}ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_AR+set}" = set; then : +if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then @@ -21418,7 +21442,7 @@ if test -z "$ac_cv_prog_AR"; then set dummy ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_AR+set}" = set; then : +if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then @@ -21760,7 +21784,7 @@ if test "x$OPENJDK_TARGET_OS" = xwindows; then : set dummy link; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_WINLD+set}" = set; then : +if ${ac_cv_prog_WINLD+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$WINLD"; then @@ -22099,7 +22123,7 @@ $as_echo "yes" >&6; } set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_MT+set}" = set; then : +if ${ac_cv_prog_MT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MT"; then @@ -22420,7 +22444,7 @@ $as_echo "$as_me: Rewriting MT to \"$new_complete\"" >&6;} set dummy rc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_RC+set}" = set; then : +if ${ac_cv_prog_RC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RC"; then @@ -22811,7 +22835,7 @@ fi set dummy lib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_WINAR+set}" = set; then : +if ${ac_cv_prog_WINAR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$WINAR"; then @@ -23117,7 +23141,7 @@ $as_echo "$as_me: Rewriting WINAR to \"$new_complete\"" >&6;} set dummy dumpbin; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_DUMPBIN+set}" = set; then : +if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then @@ -23436,7 +23460,7 @@ if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then - if test "${ac_cv_prog_CPP+set}" = set; then : + if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded @@ -23552,7 +23576,7 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=cpp @@ -23836,7 +23860,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then - if test "${ac_cv_prog_CXXCPP+set}" = set; then : + if ${ac_cv_prog_CXXCPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded @@ -23952,7 +23976,7 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=cpp @@ -24254,7 +24278,7 @@ if test "x$OPENJDK_TARGET_OS" = xsolaris; then set dummy as; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_AS+set}" = set; then : +if ${ac_cv_path_AS+:} false; then : $as_echo_n "(cached) " >&6 else case $AS in @@ -24568,7 +24592,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_NM+set}" = set; then : +if ${ac_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else case $NM in @@ -24877,7 +24901,7 @@ $as_echo "$as_me: Rewriting NM to \"$new_complete\"" >&6;} set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_STRIP+set}" = set; then : +if ${ac_cv_path_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else case $STRIP in @@ -25183,7 +25207,7 @@ $as_echo "$as_me: Rewriting STRIP to \"$new_complete\"" >&6;} set dummy mcs; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_MCS+set}" = set; then : +if ${ac_cv_path_MCS+:} false; then : $as_echo_n "(cached) " >&6 else case $MCS in @@ -25491,7 +25515,7 @@ elif test "x$OPENJDK_TARGET_OS" != xwindows; then set dummy ${ac_tool_prefix}nm; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_NM+set}" = set; then : +if ${ac_cv_prog_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then @@ -25531,7 +25555,7 @@ if test -z "$ac_cv_prog_NM"; then set dummy nm; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_NM+set}" = set; then : +if ${ac_cv_prog_ac_ct_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NM"; then @@ -25849,7 +25873,7 @@ $as_echo "$as_me: Rewriting NM to \"$new_complete\"" >&6;} set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_STRIP+set}" = set; then : +if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then @@ -25889,7 +25913,7 @@ if test -z "$ac_cv_prog_STRIP"; then set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then @@ -26214,7 +26238,7 @@ if test "x$OPENJDK_TARGET_OS" = xsolaris || test "x$OPENJDK_TARGET_OS" = xlinux; set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_OBJCOPY+set}" = set; then : +if ${ac_cv_prog_OBJCOPY+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJCOPY"; then @@ -26258,7 +26282,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_OBJCOPY+set}" = set; then : +if ${ac_cv_prog_ac_ct_OBJCOPY+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJCOPY"; then @@ -26585,7 +26609,7 @@ if test -n "$ac_tool_prefix"; then set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_OBJDUMP+set}" = set; then : +if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then @@ -26629,7 +26653,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then : +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then @@ -26953,7 +26977,7 @@ if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_LIPO+set}" = set; then : +if ${ac_cv_path_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else case $LIPO in @@ -27268,7 +27292,7 @@ PATH="$OLD_PATH" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } -if test "${ac_cv_header_stdc+set}" = set; then : +if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -27444,7 +27468,7 @@ fi for ac_header in stdio.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "stdio.h" "ac_cv_header_stdio_h" "$ac_includes_default" -if test "x$ac_cv_header_stdio_h" = x""yes; then : +if test "x$ac_cv_header_stdio_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDIO_H 1 _ACEOF @@ -27473,7 +27497,7 @@ done # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int *" >&5 $as_echo_n "checking size of int *... " >&6; } -if test "${ac_cv_sizeof_int_p+set}" = set; then : +if ${ac_cv_sizeof_int_p+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_cxx_compute_int "$LINENO" "(long int) (sizeof (int *))" "ac_cv_sizeof_int_p" "$ac_includes_default"; then : @@ -27483,7 +27507,7 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (int *) -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_int_p=0 fi @@ -27530,7 +27554,7 @@ $as_echo "$OPENJDK_TARGET_CPU_BITS bits" >&6; } # { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 $as_echo_n "checking whether byte ordering is bigendian... " >&6; } -if test "${ac_cv_c_bigendian+set}" = set; then : +if ${ac_cv_c_bigendian+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_bigendian=unknown @@ -28530,8 +28554,8 @@ if test "x$with_x" = xno; then have_x=disabled else case $x_includes,$x_libraries in #( - *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5 ;; #( - *,NONE | NONE,*) if test "${ac_cv_have_x+set}" = set; then : + *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #( + *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then : $as_echo_n "(cached) " >&6 else # One or both of the vars are not set, and there is no cached value. @@ -28808,7 +28832,7 @@ if ac_fn_cxx_try_link "$LINENO"; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet" >&5 $as_echo_n "checking for dnet_ntoa in -ldnet... " >&6; } -if test "${ac_cv_lib_dnet_dnet_ntoa+set}" = set; then : +if ${ac_cv_lib_dnet_dnet_ntoa+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -28842,14 +28866,14 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_dnet_ntoa" >&5 $as_echo "$ac_cv_lib_dnet_dnet_ntoa" >&6; } -if test "x$ac_cv_lib_dnet_dnet_ntoa" = x""yes; then : +if test "x$ac_cv_lib_dnet_dnet_ntoa" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" fi if test $ac_cv_lib_dnet_dnet_ntoa = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet_stub" >&5 $as_echo_n "checking for dnet_ntoa in -ldnet_stub... " >&6; } -if test "${ac_cv_lib_dnet_stub_dnet_ntoa+set}" = set; then : +if ${ac_cv_lib_dnet_stub_dnet_ntoa+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -28883,7 +28907,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5 $as_echo "$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; } -if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = x""yes; then : +if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" fi @@ -28902,14 +28926,14 @@ rm -f core conftest.err conftest.$ac_objext \ # The functions gethostbyname, getservbyname, and inet_addr are # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking. ac_fn_cxx_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" -if test "x$ac_cv_func_gethostbyname" = x""yes; then : +if test "x$ac_cv_func_gethostbyname" = xyes; then : fi if test $ac_cv_func_gethostbyname = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 $as_echo_n "checking for gethostbyname in -lnsl... " >&6; } -if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then : +if ${ac_cv_lib_nsl_gethostbyname+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -28943,14 +28967,14 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 $as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } -if test "x$ac_cv_lib_nsl_gethostbyname" = x""yes; then : +if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" fi if test $ac_cv_lib_nsl_gethostbyname = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lbsd" >&5 $as_echo_n "checking for gethostbyname in -lbsd... " >&6; } -if test "${ac_cv_lib_bsd_gethostbyname+set}" = set; then : +if ${ac_cv_lib_bsd_gethostbyname+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -28984,7 +29008,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_gethostbyname" >&5 $as_echo "$ac_cv_lib_bsd_gethostbyname" >&6; } -if test "x$ac_cv_lib_bsd_gethostbyname" = x""yes; then : +if test "x$ac_cv_lib_bsd_gethostbyname" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd" fi @@ -28999,14 +29023,14 @@ fi # must be given before -lnsl if both are needed. We assume that # if connect needs -lnsl, so does gethostbyname. ac_fn_cxx_check_func "$LINENO" "connect" "ac_cv_func_connect" -if test "x$ac_cv_func_connect" = x""yes; then : +if test "x$ac_cv_func_connect" = xyes; then : fi if test $ac_cv_func_connect = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 $as_echo_n "checking for connect in -lsocket... " >&6; } -if test "${ac_cv_lib_socket_connect+set}" = set; then : +if ${ac_cv_lib_socket_connect+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29040,7 +29064,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5 $as_echo "$ac_cv_lib_socket_connect" >&6; } -if test "x$ac_cv_lib_socket_connect" = x""yes; then : +if test "x$ac_cv_lib_socket_connect" = xyes; then : X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" fi @@ -29048,14 +29072,14 @@ fi # Guillermo Gomez says -lposix is necessary on A/UX. ac_fn_cxx_check_func "$LINENO" "remove" "ac_cv_func_remove" -if test "x$ac_cv_func_remove" = x""yes; then : +if test "x$ac_cv_func_remove" = xyes; then : fi if test $ac_cv_func_remove = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for remove in -lposix" >&5 $as_echo_n "checking for remove in -lposix... " >&6; } -if test "${ac_cv_lib_posix_remove+set}" = set; then : +if ${ac_cv_lib_posix_remove+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29089,7 +29113,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix_remove" >&5 $as_echo "$ac_cv_lib_posix_remove" >&6; } -if test "x$ac_cv_lib_posix_remove" = x""yes; then : +if test "x$ac_cv_lib_posix_remove" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" fi @@ -29097,14 +29121,14 @@ fi # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. ac_fn_cxx_check_func "$LINENO" "shmat" "ac_cv_func_shmat" -if test "x$ac_cv_func_shmat" = x""yes; then : +if test "x$ac_cv_func_shmat" = xyes; then : fi if test $ac_cv_func_shmat = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shmat in -lipc" >&5 $as_echo_n "checking for shmat in -lipc... " >&6; } -if test "${ac_cv_lib_ipc_shmat+set}" = set; then : +if ${ac_cv_lib_ipc_shmat+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29138,7 +29162,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_shmat" >&5 $as_echo "$ac_cv_lib_ipc_shmat" >&6; } -if test "x$ac_cv_lib_ipc_shmat" = x""yes; then : +if test "x$ac_cv_lib_ipc_shmat" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" fi @@ -29156,7 +29180,7 @@ fi # John Interrante, Karl Berry { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IceConnectionNumber in -lICE" >&5 $as_echo_n "checking for IceConnectionNumber in -lICE... " >&6; } -if test "${ac_cv_lib_ICE_IceConnectionNumber+set}" = set; then : +if ${ac_cv_lib_ICE_IceConnectionNumber+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29190,7 +29214,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5 $as_echo "$ac_cv_lib_ICE_IceConnectionNumber" >&6; } -if test "x$ac_cv_lib_ICE_IceConnectionNumber" = x""yes; then : +if test "x$ac_cv_lib_ICE_IceConnectionNumber" = xyes; then : X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" fi @@ -30197,7 +30221,7 @@ $as_echo "$FREETYPE2_FOUND" >&6; } LDFLAGS="$FREETYPE2_LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FT_Init_FreeType in -lfreetype" >&5 $as_echo_n "checking for FT_Init_FreeType in -lfreetype... " >&6; } -if test "${ac_cv_lib_freetype_FT_Init_FreeType+set}" = set; then : +if ${ac_cv_lib_freetype_FT_Init_FreeType+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30231,7 +30255,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_freetype_FT_Init_FreeType" >&5 $as_echo "$ac_cv_lib_freetype_FT_Init_FreeType" >&6; } -if test "x$ac_cv_lib_freetype_FT_Init_FreeType" = x""yes; then : +if test "x$ac_cv_lib_freetype_FT_Init_FreeType" = xyes; then : FREETYPE2_FOUND=true else as_fn_error $? "Could not find freetype2! $HELP_MSG " "$LINENO" 5 @@ -30519,7 +30543,7 @@ fi for ac_header in alsa/asoundlib.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "alsa/asoundlib.h" "ac_cv_header_alsa_asoundlib_h" "$ac_includes_default" -if test "x$ac_cv_header_alsa_asoundlib_h" = x""yes; then : +if test "x$ac_cv_header_alsa_asoundlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ALSA_ASOUNDLIB_H 1 _ACEOF @@ -30578,7 +30602,7 @@ fi USE_EXTERNAL_LIBJPEG=true { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -ljpeg" >&5 $as_echo_n "checking for main in -ljpeg... " >&6; } -if test "${ac_cv_lib_jpeg_main+set}" = set; then : +if ${ac_cv_lib_jpeg_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30606,7 +30630,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jpeg_main" >&5 $as_echo "$ac_cv_lib_jpeg_main" >&6; } -if test "x$ac_cv_lib_jpeg_main" = x""yes; then : +if test "x$ac_cv_lib_jpeg_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBJPEG 1 _ACEOF @@ -30630,7 +30654,7 @@ fi USE_EXTERNAL_LIBJPEG=true { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lgif" >&5 $as_echo_n "checking for main in -lgif... " >&6; } -if test "${ac_cv_lib_gif_main+set}" = set; then : +if ${ac_cv_lib_gif_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30658,7 +30682,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gif_main" >&5 $as_echo "$ac_cv_lib_gif_main" >&6; } -if test "x$ac_cv_lib_gif_main" = x""yes; then : +if test "x$ac_cv_lib_gif_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBGIF 1 _ACEOF @@ -30688,7 +30712,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for compress in -lz" >&5 $as_echo_n "checking for compress in -lz... " >&6; } -if test "${ac_cv_lib_z_compress+set}" = set; then : +if ${ac_cv_lib_z_compress+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30722,7 +30746,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_compress" >&5 $as_echo "$ac_cv_lib_z_compress" >&6; } -if test "x$ac_cv_lib_z_compress" = x""yes; then : +if test "x$ac_cv_lib_z_compress" = xyes; then : ZLIB_FOUND=yes else ZLIB_FOUND=no @@ -30815,7 +30839,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5 $as_echo_n "checking for cos in -lm... " >&6; } -if test "${ac_cv_lib_m_cos+set}" = set; then : +if ${ac_cv_lib_m_cos+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30849,7 +30873,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5 $as_echo "$ac_cv_lib_m_cos" >&6; } -if test "x$ac_cv_lib_m_cos" = x""yes; then : +if test "x$ac_cv_lib_m_cos" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF @@ -30873,7 +30897,7 @@ save_LIBS="$LIBS" LIBS="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } -if test "${ac_cv_lib_dl_dlopen+set}" = set; then : +if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30907,7 +30931,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDL 1 _ACEOF @@ -31144,7 +31168,7 @@ HOTSPOT_MAKE_ARGS="$HOTSPOT_TARGET" # The name of the Service Agent jar. SALIB_NAME="${LIBRARY_PREFIX}saproc${SHARED_LIBRARY_SUFFIX}" if test "x$OPENJDK_TARGET_OS" = "xwindows"; then - SALIB_NAME="${LIBRARY_PREFIX}sawindbg${SHARED_LIBRARY_SUFFIX}" + SALIB_NAME="${LIBRARY_PREFIX}sawindbg${SHARED_LIBRARY_SUFFIX}" fi @@ -31551,7 +31575,7 @@ fi set dummy ccache; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CCACHE+set}" = set; then : +if ${ac_cv_path_CCACHE+:} false; then : $as_echo_n "(cached) " >&6 else case $CCACHE in @@ -31812,10 +31836,21 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then - test "x$cache_file" != "x/dev/null" && + if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} - cat confcache >$cache_file + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} @@ -31847,7 +31882,7 @@ LTLIBOBJS=$ac_ltlibobjs -: ${CONFIG_STATUS=./config.status} +: "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" @@ -31948,6 +31983,7 @@ fi IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. +as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -32255,7 +32291,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # values after options handling. ac_log=" This file was extended by OpenJDK $as_me jdk8, which was -generated by GNU Autoconf 2.67. Invocation command line was +generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -32318,7 +32354,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ OpenJDK config.status jdk8 -configured by $0, generated by GNU Autoconf 2.67, +configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" Copyright (C) 2010 Free Software Foundation, Inc. @@ -32447,7 +32483,7 @@ do "$OUTPUT_ROOT/spec.sh") CONFIG_FILES="$CONFIG_FILES $OUTPUT_ROOT/spec.sh:$AUTOCONF_DIR/spec.sh.in" ;; "$OUTPUT_ROOT/Makefile") CONFIG_FILES="$CONFIG_FILES $OUTPUT_ROOT/Makefile:$AUTOCONF_DIR/Makefile.in" ;; - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;; + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done @@ -32469,9 +32505,10 @@ fi # after its creation but before its name has been assigned to `$tmp'. $debug || { - tmp= + tmp= ac_tmp= trap 'exit_status=$? - { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } @@ -32479,12 +32516,13 @@ $debug || { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" + test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. @@ -32506,7 +32544,7 @@ else ac_cs_awk_cr=$ac_cr fi -echo 'BEGIN {' >"$tmp/subs1.awk" && +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF @@ -32534,7 +32572,7 @@ done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$tmp/subs1.awk" <<\\_ACAWK && +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h @@ -32582,7 +32620,7 @@ t delim rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK -cat >>"\$tmp/subs1.awk" <<_ACAWK && +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" @@ -32614,7 +32652,7 @@ if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat -fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF @@ -32648,7 +32686,7 @@ fi # test -n "$CONFIG_FILES" # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then -cat >"$tmp/defines.awk" <<\_ACAWK || +cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF @@ -32660,8 +32698,8 @@ _ACEOF # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do - ac_t=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_t"; then + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 @@ -32762,7 +32800,7 @@ do esac case $ac_mode$ac_tag in :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac @@ -32781,7 +32819,7 @@ do for ac_f do case $ac_f in - -) ac_f="$tmp/stdin";; + -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. @@ -32790,7 +32828,7 @@ do [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;; + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" @@ -32816,8 +32854,8 @@ $as_echo "$as_me: creating $ac_file" >&6;} esac case $ac_tag in - *:-:* | *:-) cat >"$tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac @@ -32942,21 +32980,22 @@ s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t $ac_datarootdir_hack " -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} - rm -f "$tmp/stdin" + rm -f "$ac_tmp/stdin" case $ac_file in - -) cat "$tmp/out" && rm -f "$tmp/out";; - *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; @@ -32967,20 +33006,20 @@ which seems to be undefined. Please make sure it is defined" >&2;} if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" - } >"$tmp/config.h" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" - mv "$tmp/config.h" "$ac_file" \ + mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; diff --git a/common/autoconf/jdk-options.m4 b/common/autoconf/jdk-options.m4 index 254058c8688..7e216b0a617 100644 --- a/common/autoconf/jdk-options.m4 +++ b/common/autoconf/jdk-options.m4 @@ -382,24 +382,38 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_JDK_VERSION_NUMBERS], AC_ARG_WITH(milestone, [AS_HELP_STRING([--with-milestone], [Set milestone value for build @<:@internal@:>@])]) if test "x$with_milestone" = xyes; then - AC_MSG_ERROR([Milestone must have a value]) + AC_MSG_ERROR([Milestone must have a value]) elif test "x$with_milestone" != x; then MILESTONE="$with_milestone" else - MILESTONE=internal + MILESTONE=internal fi AC_ARG_WITH(build-number, [AS_HELP_STRING([--with-build-number], [Set build number value for build @<:@b00@:>@])]) if test "x$with_build_number" = xyes; then - AC_MSG_ERROR([Build number must have a value]) + AC_MSG_ERROR([Build number must have a value]) elif test "x$with_build_number" != x; then - JDK_BUILD_NUMBER="$with_build_number" + JDK_BUILD_NUMBER="$with_build_number" fi if test "x$JDK_BUILD_NUMBER" = x; then - JDK_BUILD_NUMBER=b00 + JDK_BUILD_NUMBER=b00 fi +AC_ARG_WITH(user-release-suffix, [AS_HELP_STRING([--with-user-release-suffix], + [Add a custom string to the version string if build number isn't set.@<:@username_builddateb00@:>@])]) +if test "x$with_user_release_suffix" = xyes; then + AC_MSG_ERROR([Release suffix must have a value]) +elif test "x$with_user_release_suffix" != x; then + USER_RELEASE_SUFFIX="$with_user_release_suffix" +else + BUILD_DATE=`date '+%Y_%m_%d_%H_%M'` + # Avoid [:alnum:] since it depends on the locale. + CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyz0123456789'` + USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` +fi +AC_SUBST(USER_RELEASE_SUFFIX) + # Now set the JDK version, milestone, build number etc. AC_SUBST(JDK_MAJOR_VERSION) AC_SUBST(JDK_MINOR_VERSION) @@ -419,18 +433,12 @@ COPYRIGHT_YEAR=`date +'%Y'` AC_SUBST(COPYRIGHT_YEAR) if test "x$JDK_UPDATE_VERSION" != x; then - JDK_VERSION="${JDK_MAJOR_VERSION}.${JDK_MINOR_VERSION}.${JDK_MICRO_VERSION}_${JDK_UPDATE_VERSION}" + JDK_VERSION="${JDK_MAJOR_VERSION}.${JDK_MINOR_VERSION}.${JDK_MICRO_VERSION}_${JDK_UPDATE_VERSION}" else - JDK_VERSION="${JDK_MAJOR_VERSION}.${JDK_MINOR_VERSION}.${JDK_MICRO_VERSION}" + JDK_VERSION="${JDK_MAJOR_VERSION}.${JDK_MINOR_VERSION}.${JDK_MICRO_VERSION}" fi AC_SUBST(JDK_VERSION) -BUILD_DATE=`date '+%Y_%m_%d_%H_%M'` -# Avoid [:alnum:] since it depends on the locale. -CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyz0123456789'` -USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` -AC_SUBST(USER_RELEASE_SUFFIX) - COOKED_BUILD_NUMBER=`$ECHO $JDK_BUILD_NUMBER | $SED -e 's/^b//' -e 's/^0//'` AC_SUBST(COOKED_BUILD_NUMBER) ]) @@ -443,7 +451,7 @@ AC_SUBST(HOTSPOT_MAKE_ARGS) # The name of the Service Agent jar. SALIB_NAME="${LIBRARY_PREFIX}saproc${SHARED_LIBRARY_SUFFIX}" if test "x$OPENJDK_TARGET_OS" = "xwindows"; then - SALIB_NAME="${LIBRARY_PREFIX}sawindbg${SHARED_LIBRARY_SUFFIX}" + SALIB_NAME="${LIBRARY_PREFIX}sawindbg${SHARED_LIBRARY_SUFFIX}" fi AC_SUBST(SALIB_NAME) From 0f2c37ea4a7c5a92eade5f8a02b0d2d18192f74a Mon Sep 17 00:00:00 2001 From: Bengt Rutisson Date: Wed, 9 Jan 2013 09:48:58 +0100 Subject: [PATCH 046/204] 8005489: VM hangs during GC with ParallelGC and ParallelGCThreads=0 Print an error message and exit the VM if UseParallalGC is combined with ParllelGCThreads==0. Also reviewed by vitalyd@gmail.com. Reviewed-by: stefank, ehelin --- hotspot/src/share/vm/runtime/arguments.cpp | 46 ++++++++++++---------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 2b5c7af0e67..6a041805a63 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1454,30 +1454,34 @@ void Arguments::set_parallel_gc_flags() { // If no heap maximum was requested explicitly, use some reasonable fraction // of the physical memory, up to a maximum of 1GB. - if (UseParallelGC) { - FLAG_SET_DEFAULT(ParallelGCThreads, - Abstract_VM_Version::parallel_worker_threads()); + FLAG_SET_DEFAULT(ParallelGCThreads, + Abstract_VM_Version::parallel_worker_threads()); + if (ParallelGCThreads == 0) { + jio_fprintf(defaultStream::error_stream(), + "The Parallel GC can not be combined with -XX:ParallelGCThreads=0\n"); + vm_exit(1); + } - // If InitialSurvivorRatio or MinSurvivorRatio were not specified, but the - // SurvivorRatio has been set, reset their default values to SurvivorRatio + - // 2. By doing this we make SurvivorRatio also work for Parallel Scavenger. - // See CR 6362902 for details. - if (!FLAG_IS_DEFAULT(SurvivorRatio)) { - if (FLAG_IS_DEFAULT(InitialSurvivorRatio)) { - FLAG_SET_DEFAULT(InitialSurvivorRatio, SurvivorRatio + 2); - } - if (FLAG_IS_DEFAULT(MinSurvivorRatio)) { - FLAG_SET_DEFAULT(MinSurvivorRatio, SurvivorRatio + 2); - } + + // If InitialSurvivorRatio or MinSurvivorRatio were not specified, but the + // SurvivorRatio has been set, reset their default values to SurvivorRatio + + // 2. By doing this we make SurvivorRatio also work for Parallel Scavenger. + // See CR 6362902 for details. + if (!FLAG_IS_DEFAULT(SurvivorRatio)) { + if (FLAG_IS_DEFAULT(InitialSurvivorRatio)) { + FLAG_SET_DEFAULT(InitialSurvivorRatio, SurvivorRatio + 2); } + if (FLAG_IS_DEFAULT(MinSurvivorRatio)) { + FLAG_SET_DEFAULT(MinSurvivorRatio, SurvivorRatio + 2); + } + } - if (UseParallelOldGC) { - // Par compact uses lower default values since they are treated as - // minimums. These are different defaults because of the different - // interpretation and are not ergonomically set. - if (FLAG_IS_DEFAULT(MarkSweepDeadRatio)) { - FLAG_SET_DEFAULT(MarkSweepDeadRatio, 1); - } + if (UseParallelOldGC) { + // Par compact uses lower default values since they are treated as + // minimums. These are different defaults because of the different + // interpretation and are not ergonomically set. + if (FLAG_IS_DEFAULT(MarkSweepDeadRatio)) { + FLAG_SET_DEFAULT(MarkSweepDeadRatio, 1); } } } From 8762d54e63d2f6c3609a254e44be070f8c612903 Mon Sep 17 00:00:00 2001 From: Bharadwaj Yadavalli Date: Wed, 9 Jan 2013 11:39:30 -0500 Subject: [PATCH 047/204] 8005689: InterfaceAccessFlagsTest failures in Lambda-JDK tests Fix verifier for new interface access flags Reviewed-by: acorn, kvn --- .../share/vm/classfile/classFileParser.cpp | 40 +++++++++++++++---- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index 9dd0640de06..efb6138e583 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -3912,7 +3912,10 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, // check that if this class is an interface then it doesn't have static methods if (this_klass->is_interface()) { - check_illegal_static_method(this_klass, CHECK_(nullHandle)); + /* An interface in a JAVA 8 classfile can be static */ + if (_major_version < JAVA_8_VERSION) { + check_illegal_static_method(this_klass, CHECK_(nullHandle)); + } } @@ -4466,6 +4469,7 @@ void ClassFileParser::verify_legal_method_modifiers( const bool is_bridge = (flags & JVM_ACC_BRIDGE) != 0; const bool is_strict = (flags & JVM_ACC_STRICT) != 0; const bool is_synchronized = (flags & JVM_ACC_SYNCHRONIZED) != 0; + const bool is_protected = (flags & JVM_ACC_PROTECTED) != 0; const bool major_gte_15 = _major_version >= JAVA_1_5_VERSION; const bool major_gte_8 = _major_version >= JAVA_8_VERSION; const bool is_initializer = (name == vmSymbols::object_initializer_name()); @@ -4473,11 +4477,33 @@ void ClassFileParser::verify_legal_method_modifiers( bool is_illegal = false; if (is_interface) { - if (!is_public || is_static || is_final || is_native || - ((is_synchronized || is_strict) && major_gte_15 && - (!major_gte_8 || is_abstract)) || - (!major_gte_8 && !is_abstract)) { - is_illegal = true; + if (major_gte_8) { + // Class file version is JAVA_8_VERSION or later Methods of + // interfaces may set any of the flags except ACC_PROTECTED, + // ACC_FINAL, ACC_NATIVE, and ACC_SYNCHRONIZED; they must + // have exactly one of the ACC_PUBLIC or ACC_PRIVATE flags set. + if ((is_public == is_private) || /* Only one of private and public should be true - XNOR */ + (is_native || is_protected || is_final || is_synchronized) || + // If a specific method of a class or interface has its + // ACC_ABSTRACT flag set, it must not have any of its + // ACC_FINAL, ACC_NATIVE, ACC_PRIVATE, ACC_STATIC, + // ACC_STRICT, or ACC_SYNCHRONIZED flags set. No need to + // check for ACC_FINAL, ACC_NATIVE or ACC_SYNCHRONIZED as + // those flags are illegal irrespective of ACC_ABSTRACT being set or not. + (is_abstract && (is_private || is_static || is_strict))) { + is_illegal = true; + } + } else if (major_gte_15) { + // Class file version in the interval [JAVA_1_5_VERSION, JAVA_8_VERSION) + if (!is_public || is_static || is_final || is_synchronized || + is_native || !is_abstract || is_strict) { + is_illegal = true; + } + } else { + // Class file version is pre-JAVA_1_5_VERSION + if (!is_public || is_static || is_final || is_native || !is_abstract) { + is_illegal = true; + } } } else { // not interface if (is_initializer) { From 030fa5107d44b37dce7a61306b186bd9eb6ceb28 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Wed, 9 Jan 2013 14:46:55 -0500 Subject: [PATCH 048/204] 7152671: RFE: Windows decoder should add some std dirs to the symbol search path Added JRE/JDK bin directories to decoder's symbol search path Reviewed-by: dcubed, sla --- hotspot/src/os/windows/vm/decoder_windows.cpp | 78 ++++++++++++++++++- hotspot/src/os/windows/vm/decoder_windows.hpp | 2 + 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/hotspot/src/os/windows/vm/decoder_windows.cpp b/hotspot/src/os/windows/vm/decoder_windows.cpp index 82ba909bc5c..2b4682728a2 100644 --- a/hotspot/src/os/windows/vm/decoder_windows.cpp +++ b/hotspot/src/os/windows/vm/decoder_windows.cpp @@ -49,7 +49,7 @@ void WindowsDecoder::initialize() { pfn_SymSetOptions _pfnSymSetOptions = (pfn_SymSetOptions)::GetProcAddress(handle, "SymSetOptions"); pfn_SymInitialize _pfnSymInitialize = (pfn_SymInitialize)::GetProcAddress(handle, "SymInitialize"); _pfnSymGetSymFromAddr64 = (pfn_SymGetSymFromAddr64)::GetProcAddress(handle, "SymGetSymFromAddr64"); - _pfnUndecorateSymbolName = (pfn_UndecorateSymbolName)GetProcAddress(handle, "UnDecorateSymbolName"); + _pfnUndecorateSymbolName = (pfn_UndecorateSymbolName)::GetProcAddress(handle, "UnDecorateSymbolName"); if (_pfnSymSetOptions == NULL || _pfnSymInitialize == NULL || _pfnSymGetSymFromAddr64 == NULL) { _pfnSymGetSymFromAddr64 = NULL; @@ -60,8 +60,9 @@ void WindowsDecoder::initialize() { return; } - _pfnSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS); - if (!_pfnSymInitialize(GetCurrentProcess(), NULL, TRUE)) { + HANDLE hProcess = ::GetCurrentProcess(); + _pfnSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_EXACT_SYMBOLS); + if (!_pfnSymInitialize(hProcess, NULL, TRUE)) { _pfnSymGetSymFromAddr64 = NULL; _pfnUndecorateSymbolName = NULL; ::FreeLibrary(handle); @@ -70,6 +71,77 @@ void WindowsDecoder::initialize() { return; } + // set pdb search paths + pfn_SymSetSearchPath _pfn_SymSetSearchPath = + (pfn_SymSetSearchPath)::GetProcAddress(handle, "SymSetSearchPath"); + pfn_SymGetSearchPath _pfn_SymGetSearchPath = + (pfn_SymGetSearchPath)::GetProcAddress(handle, "SymGetSearchPath"); + if (_pfn_SymSetSearchPath != NULL && _pfn_SymGetSearchPath != NULL) { + char paths[MAX_PATH]; + int len = sizeof(paths); + if (!_pfn_SymGetSearchPath(hProcess, paths, len)) { + paths[0] = '\0'; + } else { + // available spaces in path buffer + len -= (int)strlen(paths); + } + + char tmp_path[MAX_PATH]; + DWORD dwSize; + HMODULE hJVM = ::GetModuleHandle("jvm.dll"); + tmp_path[0] = '\0'; + // append the path where jvm.dll is located + if (hJVM != NULL && (dwSize = ::GetModuleFileName(hJVM, tmp_path, sizeof(tmp_path))) > 0) { + while (dwSize > 0 && tmp_path[dwSize] != '\\') { + dwSize --; + } + + tmp_path[dwSize] = '\0'; + + if (dwSize > 0 && len > (int)dwSize + 1) { + strncat(paths, os::path_separator(), 1); + strncat(paths, tmp_path, dwSize); + len -= dwSize + 1; + } + } + + // append $JRE/bin. Arguments::get_java_home actually returns $JRE + // path + char *p = Arguments::get_java_home(); + assert(p != NULL, "empty java home"); + size_t java_home_len = strlen(p); + if (len > (int)java_home_len + 5) { + strncat(paths, os::path_separator(), 1); + strncat(paths, p, java_home_len); + strncat(paths, "\\bin", 4); + len -= (int)(java_home_len + 5); + } + + // append $JDK/bin path if it exists + assert(java_home_len < MAX_PATH, "Invalid path length"); + // assume $JRE is under $JDK, construct $JDK/bin path and + // see if it exists or not + if (strncmp(&p[java_home_len - 3], "jre", 3) == 0) { + strncpy(tmp_path, p, java_home_len - 3); + tmp_path[java_home_len - 3] = '\0'; + strncat(tmp_path, "bin", 3); + + // if the directory exists + DWORD dwAttrib = GetFileAttributes(tmp_path); + if (dwAttrib != INVALID_FILE_ATTRIBUTES && + (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) { + // tmp_path should have the same length as java_home_len, since we only + // replaced 'jre' with 'bin' + if (len > (int)java_home_len + 1) { + strncat(paths, os::path_separator(), 1); + strncat(paths, tmp_path, java_home_len); + } + } + } + + _pfn_SymSetSearchPath(hProcess, paths); + } + // find out if jvm.dll contains private symbols, by decoding // current function and comparing the result address addr = (address)Decoder::demangle; diff --git a/hotspot/src/os/windows/vm/decoder_windows.hpp b/hotspot/src/os/windows/vm/decoder_windows.hpp index b2c2638d8ab..3008ee79136 100644 --- a/hotspot/src/os/windows/vm/decoder_windows.hpp +++ b/hotspot/src/os/windows/vm/decoder_windows.hpp @@ -35,6 +35,8 @@ typedef DWORD (WINAPI *pfn_SymSetOptions)(DWORD); typedef BOOL (WINAPI *pfn_SymInitialize)(HANDLE, PCTSTR, BOOL); typedef BOOL (WINAPI *pfn_SymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64); typedef DWORD (WINAPI *pfn_UndecorateSymbolName)(const char*, char*, DWORD, DWORD); +typedef BOOL (WINAPI *pfn_SymSetSearchPath)(HANDLE, PCTSTR); +typedef BOOL (WINAPI *pfn_SymGetSearchPath)(HANDLE, PTSTR, int); class WindowsDecoder : public AbstractDecoder { From a55305503e8760946e81ab452b34e8ea5fecea43 Mon Sep 17 00:00:00 2001 From: Christian Thalinger Date: Wed, 9 Jan 2013 15:37:23 -0800 Subject: [PATCH 049/204] 8005418: JSR 292: virtual dispatch bug in 292 impl Reviewed-by: jrose, kvn --- hotspot/src/share/vm/opto/callGenerator.cpp | 26 +++- hotspot/src/share/vm/opto/compile.hpp | 11 +- hotspot/src/share/vm/opto/doCall.cpp | 133 ++++++++++---------- hotspot/src/share/vm/opto/parse.hpp | 4 - hotspot/src/share/vm/opto/parse1.cpp | 3 +- 5 files changed, 102 insertions(+), 75 deletions(-) diff --git a/hotspot/src/share/vm/opto/callGenerator.cpp b/hotspot/src/share/vm/opto/callGenerator.cpp index d82495f4a16..89a7c46f6ed 100644 --- a/hotspot/src/share/vm/opto/callGenerator.cpp +++ b/hotspot/src/share/vm/opto/callGenerator.cpp @@ -717,6 +717,7 @@ CallGenerator* CallGenerator::for_method_handle_call(JVMState* jvms, ciMethod* c (input_not_const || !C->inlining_incrementally() || C->over_inlining_cutoff())) { return CallGenerator::for_mh_late_inline(caller, callee, input_not_const); } else { + // Out-of-line call. return CallGenerator::for_direct_call(callee); } } @@ -739,7 +740,7 @@ CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* guarantee(!target->is_method_handle_intrinsic(), "should not happen"); // XXX remove const int vtable_index = Method::invalid_vtable_index; CallGenerator* cg = C->call_generator(target, vtable_index, false, jvms, true, PROB_ALWAYS, true, true); - assert (!cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here"); + assert(!cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here"); if (cg != NULL && cg->is_inline()) return cg; } @@ -787,10 +788,25 @@ CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* } } } - const int vtable_index = Method::invalid_vtable_index; - const bool call_is_virtual = target->is_abstract(); // FIXME workaround - CallGenerator* cg = C->call_generator(target, vtable_index, call_is_virtual, jvms, true, PROB_ALWAYS, true, true); - assert (!cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here"); + + // Try to get the most accurate receiver type + const bool is_virtual = (iid == vmIntrinsics::_linkToVirtual); + const bool is_virtual_or_interface = (is_virtual || iid == vmIntrinsics::_linkToInterface); + int vtable_index = Method::invalid_vtable_index; + bool call_does_dispatch = false; + + if (is_virtual_or_interface) { + ciInstanceKlass* klass = target->holder(); + Node* receiver_node = kit.argument(0); + const TypeOopPtr* receiver_type = gvn.type(receiver_node)->isa_oopptr(); + // call_does_dispatch and vtable_index are out-parameters. They might be changed. + target = C->optimize_virtual_call(caller, jvms->bci(), klass, target, receiver_type, + is_virtual, + call_does_dispatch, vtable_index); // out-parameters + } + + CallGenerator* cg = C->call_generator(target, vtable_index, call_does_dispatch, jvms, true, PROB_ALWAYS, true, true); + assert(!cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here"); if (cg != NULL && cg->is_inline()) return cg; } diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp index 91472ccb006..58482956a8c 100644 --- a/hotspot/src/share/vm/opto/compile.hpp +++ b/hotspot/src/share/vm/opto/compile.hpp @@ -72,6 +72,7 @@ class SafePointNode; class JVMState; class TypeData; class TypePtr; +class TypeOopPtr; class TypeFunc; class Unique_Node_List; class nmethod; @@ -740,9 +741,17 @@ class Compile : public Phase { // Decide how to build a call. // The profile factor is a discount to apply to this site's interp. profile. - CallGenerator* call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual, JVMState* jvms, bool allow_inline, float profile_factor, bool allow_intrinsics = true, bool delayed_forbidden = false); + CallGenerator* call_generator(ciMethod* call_method, int vtable_index, bool call_does_dispatch, JVMState* jvms, bool allow_inline, float profile_factor, bool allow_intrinsics = true, bool delayed_forbidden = false); bool should_delay_inlining(ciMethod* call_method, JVMState* jvms); + // Helper functions to identify inlining potential at call-site + ciMethod* optimize_virtual_call(ciMethod* caller, int bci, ciInstanceKlass* klass, + ciMethod* callee, const TypeOopPtr* receiver_type, + bool is_virtual, + bool &call_does_dispatch, int &vtable_index); + ciMethod* optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* klass, + ciMethod* callee, const TypeOopPtr* receiver_type); + // Report if there were too many traps at a current method and bci. // Report if a trap was recorded, and/or PerMethodTrapLimit was exceeded. // If there is no MDO at all, report no trap unless told to assume it. diff --git a/hotspot/src/share/vm/opto/doCall.cpp b/hotspot/src/share/vm/opto/doCall.cpp index 099634f0434..5d094c99afc 100644 --- a/hotspot/src/share/vm/opto/doCall.cpp +++ b/hotspot/src/share/vm/opto/doCall.cpp @@ -61,7 +61,7 @@ void trace_type_profile(Compile* C, ciMethod *method, int depth, int bci, ciMeth } } -CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool call_is_virtual, +CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool call_does_dispatch, JVMState* jvms, bool allow_inline, float prof_factor, bool allow_intrinsics, bool delayed_forbidden) { ciMethod* caller = jvms->method(); @@ -82,7 +82,7 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool // See how many times this site has been invoked. int site_count = profile.count(); int receiver_count = -1; - if (call_is_virtual && UseTypeProfile && profile.has_receiver(0)) { + if (call_does_dispatch && UseTypeProfile && profile.has_receiver(0)) { // Receivers in the profile structure are ordered by call counts // so that the most called (major) receiver is profile.receiver(0). receiver_count = profile.receiver_count(0); @@ -94,7 +94,7 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool int r2id = (rid != -1 && profile.has_receiver(1))? log->identify(profile.receiver(1)):-1; log->begin_elem("call method='%d' count='%d' prof_factor='%g'", log->identify(callee), site_count, prof_factor); - if (call_is_virtual) log->print(" virtual='1'"); + if (call_does_dispatch) log->print(" virtual='1'"); if (allow_inline) log->print(" inline='1'"); if (receiver_count >= 0) { log->print(" receiver='%d' receiver_count='%d'", rid, receiver_count); @@ -111,12 +111,12 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool // We do this before the strict f.p. check below because the // intrinsics handle strict f.p. correctly. if (allow_inline && allow_intrinsics) { - CallGenerator* cg = find_intrinsic(callee, call_is_virtual); + CallGenerator* cg = find_intrinsic(callee, call_does_dispatch); if (cg != NULL) { if (cg->is_predicted()) { // Code without intrinsic but, hopefully, inlined. CallGenerator* inline_cg = this->call_generator(callee, - vtable_index, call_is_virtual, jvms, allow_inline, prof_factor, false); + vtable_index, call_does_dispatch, jvms, allow_inline, prof_factor, false); if (inline_cg != NULL) { cg = CallGenerator::for_predicted_intrinsic(cg, inline_cg); } @@ -131,7 +131,7 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool // have bytecodes and so normal inlining fails. if (callee->is_method_handle_intrinsic()) { CallGenerator* cg = CallGenerator::for_method_handle_call(jvms, caller, callee, delayed_forbidden); - assert (cg == NULL || !delayed_forbidden || !cg->is_late_inline() || cg->is_mh_late_inline(), "unexpected CallGenerator"); + assert(cg == NULL || !delayed_forbidden || !cg->is_late_inline() || cg->is_mh_late_inline(), "unexpected CallGenerator"); return cg; } @@ -149,7 +149,7 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool float expected_uses = past_uses; // Try inlining a bytecoded method: - if (!call_is_virtual) { + if (!call_does_dispatch) { InlineTree* ilt; if (UseOldInlining) { ilt = InlineTree::find_subtree_from_root(this->ilt(), jvms->caller(), jvms->method()); @@ -188,14 +188,14 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool } else if (require_inline || !InlineWarmCalls) { return cg; } else { - CallGenerator* cold_cg = call_generator(callee, vtable_index, call_is_virtual, jvms, false, prof_factor); + CallGenerator* cold_cg = call_generator(callee, vtable_index, call_does_dispatch, jvms, false, prof_factor); return CallGenerator::for_warm_call(ci, cold_cg, cg); } } } // Try using the type profile. - if (call_is_virtual && site_count > 0 && receiver_count > 0) { + if (call_does_dispatch && site_count > 0 && receiver_count > 0) { // The major receiver's count >= TypeProfileMajorReceiverPercent of site_count. bool have_major_receiver = (100.*profile.receiver_prob(0) >= (float)TypeProfileMajorReceiverPercent); ciMethod* receiver_method = NULL; @@ -209,7 +209,7 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool if (receiver_method != NULL) { // The single majority receiver sufficiently outweighs the minority. CallGenerator* hit_cg = this->call_generator(receiver_method, - vtable_index, !call_is_virtual, jvms, allow_inline, prof_factor); + vtable_index, !call_does_dispatch, jvms, allow_inline, prof_factor); if (hit_cg != NULL) { // Look up second receiver. CallGenerator* next_hit_cg = NULL; @@ -219,7 +219,7 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool profile.receiver(1)); if (next_receiver_method != NULL) { next_hit_cg = this->call_generator(next_receiver_method, - vtable_index, !call_is_virtual, jvms, + vtable_index, !call_does_dispatch, jvms, allow_inline, prof_factor); if (next_hit_cg != NULL && !next_hit_cg->is_inline() && have_major_receiver && UseOnlyInlinedBimorphic) { @@ -265,7 +265,7 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool // There was no special inlining tactic, or it bailed out. // Use a more generic tactic, like a simple call. - if (call_is_virtual) { + if (call_does_dispatch) { return CallGenerator::for_virtual_call(callee, vtable_index); } else { // Class Hierarchy Analysis or Type Profile reveals a unique target, @@ -397,6 +397,7 @@ void Parse::do_call() { // orig_callee is the resolved callee which's signature includes the // appendix argument. const int nargs = orig_callee->arg_size(); + const bool is_signature_polymorphic = MethodHandles::is_signature_polymorphic(orig_callee->intrinsic_id()); // Push appendix argument (MethodType, CallSite, etc.), if one. if (iter().has_appendix()) { @@ -413,25 +414,18 @@ void Parse::do_call() { // Then we may introduce a run-time check and inline on the path where it succeeds. // The other path may uncommon_trap, check for another receiver, or do a v-call. - // Choose call strategy. - bool call_is_virtual = is_virtual_or_interface; - int vtable_index = Method::invalid_vtable_index; - ciMethod* callee = orig_callee; - // Try to get the most accurate receiver type + ciMethod* callee = orig_callee; + int vtable_index = Method::invalid_vtable_index; + bool call_does_dispatch = false; + if (is_virtual_or_interface) { Node* receiver_node = stack(sp() - nargs); const TypeOopPtr* receiver_type = _gvn.type(receiver_node)->isa_oopptr(); - ciMethod* optimized_virtual_method = optimize_inlining(method(), bci(), klass, orig_callee, receiver_type); - - // Have the call been sufficiently improved such that it is no longer a virtual? - if (optimized_virtual_method != NULL) { - callee = optimized_virtual_method; - call_is_virtual = false; - } else if (!UseInlineCaches && is_virtual && callee->is_loaded()) { - // We can make a vtable call at this site - vtable_index = callee->resolve_vtable_index(method()->holder(), klass); - } + // call_does_dispatch and vtable_index are out-parameters. They might be changed. + callee = C->optimize_virtual_call(method(), bci(), klass, orig_callee, receiver_type, + is_virtual, + call_does_dispatch, vtable_index); // out-parameters } // Note: It's OK to try to inline a virtual call. @@ -447,7 +441,7 @@ void Parse::do_call() { // Decide call tactic. // This call checks with CHA, the interpreter profile, intrinsics table, etc. // It decides whether inlining is desirable or not. - CallGenerator* cg = C->call_generator(callee, vtable_index, call_is_virtual, jvms, try_inline, prof_factor()); + CallGenerator* cg = C->call_generator(callee, vtable_index, call_does_dispatch, jvms, try_inline, prof_factor()); // NOTE: Don't use orig_callee and callee after this point! Use cg->method() instead. orig_callee = callee = NULL; @@ -487,7 +481,7 @@ void Parse::do_call() { // the call site, perhaps because it did not match a pattern the // intrinsic was expecting to optimize. Should always be possible to // get a normal java call that may inline in that case - cg = C->call_generator(cg->method(), vtable_index, call_is_virtual, jvms, try_inline, prof_factor(), /* allow_intrinsics= */ false); + cg = C->call_generator(cg->method(), vtable_index, call_does_dispatch, jvms, try_inline, prof_factor(), /* allow_intrinsics= */ false); if ((new_jvms = cg->generate(jvms)) == NULL) { guarantee(failing(), "call failed to generate: calls should work"); return; @@ -522,55 +516,44 @@ void Parse::do_call() { round_double_result(cg->method()); ciType* rtype = cg->method()->return_type(); - if (Bytecodes::has_optional_appendix(iter().cur_bc_raw())) { + ciType* ctype = declared_signature->return_type(); + + if (Bytecodes::has_optional_appendix(iter().cur_bc_raw()) || is_signature_polymorphic) { // Be careful here with return types. - ciType* ctype = declared_signature->return_type(); if (ctype != rtype) { BasicType rt = rtype->basic_type(); BasicType ct = ctype->basic_type(); - Node* retnode = peek(); if (ct == T_VOID) { // It's OK for a method to return a value that is discarded. // The discarding does not require any special action from the caller. // The Java code knows this, at VerifyType.isNullConversion. pop_node(rt); // whatever it was, pop it - retnode = top(); } else if (rt == T_INT || is_subword_type(rt)) { - // FIXME: This logic should be factored out. - if (ct == T_BOOLEAN) { - retnode = _gvn.transform( new (C) AndINode(retnode, intcon(0x1)) ); - } else if (ct == T_CHAR) { - retnode = _gvn.transform( new (C) AndINode(retnode, intcon(0xFFFF)) ); - } else if (ct == T_BYTE) { - retnode = _gvn.transform( new (C) LShiftINode(retnode, intcon(24)) ); - retnode = _gvn.transform( new (C) RShiftINode(retnode, intcon(24)) ); - } else if (ct == T_SHORT) { - retnode = _gvn.transform( new (C) LShiftINode(retnode, intcon(16)) ); - retnode = _gvn.transform( new (C) RShiftINode(retnode, intcon(16)) ); - } else { - assert(ct == T_INT, err_msg_res("rt=%s, ct=%s", type2name(rt), type2name(ct))); - } + // Nothing. These cases are handled in lambda form bytecode. + assert(ct == T_INT || is_subword_type(ct), err_msg_res("must match: rt=%s, ct=%s", type2name(rt), type2name(ct))); } else if (rt == T_OBJECT || rt == T_ARRAY) { assert(ct == T_OBJECT || ct == T_ARRAY, err_msg_res("rt=%s, ct=%s", type2name(rt), type2name(ct))); if (ctype->is_loaded()) { const TypeOopPtr* arg_type = TypeOopPtr::make_from_klass(rtype->as_klass()); const Type* sig_type = TypeOopPtr::make_from_klass(ctype->as_klass()); if (arg_type != NULL && !arg_type->higher_equal(sig_type)) { + Node* retnode = pop(); Node* cast_obj = _gvn.transform(new (C) CheckCastPPNode(control(), retnode, sig_type)); - pop(); push(cast_obj); } } } else { - assert(ct == rt, err_msg("unexpected mismatch rt=%d, ct=%d", rt, ct)); + assert(rt == ct, err_msg_res("unexpected mismatch: rt=%s, ct=%s", type2name(rt), type2name(ct))); // push a zero; it's better than getting an oop/int mismatch - retnode = pop_node(rt); - retnode = zerocon(ct); + pop_node(rt); + Node* retnode = zerocon(ct); push_node(ct, retnode); } // Now that the value is well-behaved, continue with the call-site type. rtype = ctype; } + } else { + assert(rtype == ctype, "mismatched return types"); // symbolic resolution enforces this } // If the return type of the method is not loaded, assert that the @@ -888,17 +871,39 @@ void Parse::count_compiled_calls(bool at_method_entry, bool is_inline) { #endif //PRODUCT +ciMethod* Compile::optimize_virtual_call(ciMethod* caller, int bci, ciInstanceKlass* klass, + ciMethod* callee, const TypeOopPtr* receiver_type, + bool is_virtual, + bool& call_does_dispatch, int& vtable_index) { + // Set default values for out-parameters. + call_does_dispatch = true; + vtable_index = Method::invalid_vtable_index; + + // Choose call strategy. + ciMethod* optimized_virtual_method = optimize_inlining(caller, bci, klass, callee, receiver_type); + + // Have the call been sufficiently improved such that it is no longer a virtual? + if (optimized_virtual_method != NULL) { + callee = optimized_virtual_method; + call_does_dispatch = false; + } else if (!UseInlineCaches && is_virtual && callee->is_loaded()) { + // We can make a vtable call at this site + vtable_index = callee->resolve_vtable_index(caller->holder(), klass); + } + return callee; +} + // Identify possible target method and inlining style -ciMethod* Parse::optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* klass, - ciMethod *dest_method, const TypeOopPtr* receiver_type) { +ciMethod* Compile::optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* klass, + ciMethod* callee, const TypeOopPtr* receiver_type) { // only use for virtual or interface calls // If it is obviously final, do not bother to call find_monomorphic_target, // because the class hierarchy checks are not needed, and may fail due to // incompletely loaded classes. Since we do our own class loading checks // in this module, we may confidently bind to any method. - if (dest_method->can_be_statically_bound()) { - return dest_method; + if (callee->can_be_statically_bound()) { + return callee; } // Attempt to improve the receiver @@ -907,8 +912,8 @@ ciMethod* Parse::optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* k if (receiver_type != NULL) { // Array methods are all inherited from Object, and are monomorphic. if (receiver_type->isa_aryptr() && - dest_method->holder() == env()->Object_klass()) { - return dest_method; + callee->holder() == env()->Object_klass()) { + return callee; } // All other interesting cases are instance klasses. @@ -928,7 +933,7 @@ ciMethod* Parse::optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* k } ciInstanceKlass* calling_klass = caller->holder(); - ciMethod* cha_monomorphic_target = dest_method->find_monomorphic_target(calling_klass, klass, actual_receiver); + ciMethod* cha_monomorphic_target = callee->find_monomorphic_target(calling_klass, klass, actual_receiver); if (cha_monomorphic_target != NULL) { assert(!cha_monomorphic_target->is_abstract(), ""); // Look at the method-receiver type. Does it add "too much information"? @@ -946,10 +951,10 @@ ciMethod* Parse::optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* k cha_monomorphic_target->print(); tty->cr(); } - if (C->log() != NULL) { - C->log()->elem("missed_CHA_opportunity klass='%d' method='%d'", - C->log()->identify(klass), - C->log()->identify(cha_monomorphic_target)); + if (log() != NULL) { + log()->elem("missed_CHA_opportunity klass='%d' method='%d'", + log()->identify(klass), + log()->identify(cha_monomorphic_target)); } cha_monomorphic_target = NULL; } @@ -961,7 +966,7 @@ ciMethod* Parse::optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* k // by dynamic class loading. Be sure to test the "static" receiver // dest_method here, as opposed to the actual receiver, which may // falsely lead us to believe that the receiver is final or private. - C->dependencies()->assert_unique_concrete_method(actual_receiver, cha_monomorphic_target); + dependencies()->assert_unique_concrete_method(actual_receiver, cha_monomorphic_target); return cha_monomorphic_target; } @@ -970,7 +975,7 @@ ciMethod* Parse::optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* k if (actual_receiver_is_exact) { // In case of evolution, there is a dependence on every inlined method, since each // such method can be changed when its class is redefined. - ciMethod* exact_method = dest_method->resolve_invoke(calling_klass, actual_receiver); + ciMethod* exact_method = callee->resolve_invoke(calling_klass, actual_receiver); if (exact_method != NULL) { #ifndef PRODUCT if (PrintOpto) { diff --git a/hotspot/src/share/vm/opto/parse.hpp b/hotspot/src/share/vm/opto/parse.hpp index 660782ccd7f..c880832a446 100644 --- a/hotspot/src/share/vm/opto/parse.hpp +++ b/hotspot/src/share/vm/opto/parse.hpp @@ -469,10 +469,6 @@ class Parse : public GraphKit { // Helper function to uncommon-trap or bailout for non-compilable call-sites bool can_not_compile_call_site(ciMethod *dest_method, ciInstanceKlass *klass); - // Helper function to identify inlining potential at call-site - ciMethod* optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* klass, - ciMethod *dest_method, const TypeOopPtr* receiver_type); - // Helper function to setup for type-profile based inlining bool prepare_type_profile_inline(ciInstanceKlass* prof_klass, ciMethod* prof_method); diff --git a/hotspot/src/share/vm/opto/parse1.cpp b/hotspot/src/share/vm/opto/parse1.cpp index 7009352917f..f0f7c8b0a9c 100644 --- a/hotspot/src/share/vm/opto/parse1.cpp +++ b/hotspot/src/share/vm/opto/parse1.cpp @@ -1404,7 +1404,8 @@ void Parse::do_one_block() { do_one_bytecode(); - assert(!have_se || stopped() || failing() || (sp() - pre_bc_sp) == depth, "correct depth prediction"); + assert(!have_se || stopped() || failing() || (sp() - pre_bc_sp) == depth, + err_msg_res("incorrect depth prediction: sp=%d, pre_bc_sp=%d, depth=%d", sp(), pre_bc_sp, depth)); do_exceptions(); From 4ed6eedb665b8bca5602d34c12c72cd6a625aec7 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Thu, 10 Jan 2013 12:20:16 +0100 Subject: [PATCH 050/204] 8005858: build-infra: Add missed comparison of sec-windows-bin.zip and friends to compare.sh Reviewed-by: tbell, ohair --- common/bin/compare.sh | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/common/bin/compare.sh b/common/bin/compare.sh index bcca754cd67..1e1ceb08ae6 100644 --- a/common/bin/compare.sh +++ b/common/bin/compare.sh @@ -1305,7 +1305,19 @@ if [ "$CMP_ZIPS" = "true" ]; then if [ -n "$THIS_SEC_BIN" ] && [ -n "$OTHER_SEC_BIN" ]; then if [ -n "$(echo $THIS_SEC_BIN | $FILTER)" ]; then echo "sec-bin.zip..." - compare_zip_file $(dirname $THIS_SEC_BIN) $(dirname $OTHER_SEC_BIN) $COMPARE_ROOT/sec-bin sec-bin.zip + compare_zip_file $THIS_SEC_DIR $OTHER_SEC_DIR $COMPARE_ROOT/sec-bin sec-bin.zip + fi + fi + if [ -n "$THIS_SEC_WINDOWS_BIN" ] && [ -n "$OTHER_SEC_WINDOWS_BIN" ]; then + if [ -n "$(echo $THIS_SEC_WINDOWS_BIN | $FILTER)" ]; then + echo "sec-windows-bin.zip..." + compare_zip_file $THIS_SEC_DIR $OTHER_SEC_DIR $COMPARE_ROOT/sec-bin sec-windows-bin.zip + fi + fi + if [ -n "$THIS_JGSS_WINDOWS_BIN" ] && [ -n "$OTHER_JGSS_WINDOWS_BIN" ]; then + if [ -n "$(echo $THIS_JGSS_WINDOWS_BIN | $FILTER)" ]; then + echo "$JGSS_WINDOWS_BIN..." + compare_zip_file $THIS_SEC_DIR $OTHER_SEC_DIR $COMPARE_ROOT/sec-bin $JGSS_WINDOWS_BIN fi fi fi From 472004ca58f6c7189b23d1298adec5550e991fad Mon Sep 17 00:00:00 2001 From: Karen Kinnear Date: Thu, 10 Jan 2013 17:38:20 -0500 Subject: [PATCH 051/204] 7199207: NPG: Crash in PlaceholderTable::verify after StackOverflow Reduce scope of placeholder table entries to improve cleanup Reviewed-by: dholmes, coleenp --- .../src/share/vm/classfile/placeholders.cpp | 12 +- .../src/share/vm/classfile/placeholders.hpp | 10 +- .../share/vm/classfile/systemDictionary.cpp | 174 ++++++------------ hotspot/src/share/vm/utilities/exceptions.hpp | 3 +- 4 files changed, 72 insertions(+), 127 deletions(-) diff --git a/hotspot/src/share/vm/classfile/placeholders.cpp b/hotspot/src/share/vm/classfile/placeholders.cpp index 1babaaf978c..10d7650db58 100644 --- a/hotspot/src/share/vm/classfile/placeholders.cpp +++ b/hotspot/src/share/vm/classfile/placeholders.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -142,7 +142,7 @@ PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash, } -// placeholder used to track class loading internal states +// placeholder is used to track class loading internal states // placeholder existence now for loading superclass/superinterface // superthreadQ tracks class circularity, while loading superclass/superinterface // loadInstanceThreadQ tracks load_instance_class calls @@ -153,15 +153,17 @@ PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash, // All claimants remove SeenThread after completing action // On removal: if definer and all queues empty, remove entry // Note: you can be in both placeholders and systemDictionary -// see parse_stream for redefine classes // Therefore - must always check SD first // Ignores the case where entry is not found void PlaceholderTable::find_and_remove(int index, unsigned int hash, - Symbol* name, ClassLoaderData* loader_data, Thread* thread) { + Symbol* name, ClassLoaderData* loader_data, + classloadAction action, + Thread* thread) { assert_locked_or_safepoint(SystemDictionary_lock); PlaceholderEntry *probe = get_entry(index, hash, name, loader_data); if (probe != NULL) { - // No other threads using this entry + probe->remove_seen_thread(thread, action); + // If no other threads using this entry, and this thread is not using this entry for other states if ((probe->superThreadQ() == NULL) && (probe->loadInstanceThreadQ() == NULL) && (probe->defineThreadQ() == NULL) && (probe->definer() == NULL)) { remove_entry(index, hash, name, loader_data); diff --git a/hotspot/src/share/vm/classfile/placeholders.hpp b/hotspot/src/share/vm/classfile/placeholders.hpp index af4518a462f..ca0d85af0fb 100644 --- a/hotspot/src/share/vm/classfile/placeholders.hpp +++ b/hotspot/src/share/vm/classfile/placeholders.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -82,7 +82,7 @@ public: }; // find_and_add returns probe pointer - old or new - // If no entry exists, add a placeholder entry and push SeenThread + // If no entry exists, add a placeholder entry and push SeenThread for classloadAction // If entry exists, reuse entry and push SeenThread for classloadAction PlaceholderEntry* find_and_add(int index, unsigned int hash, Symbol* name, ClassLoaderData* loader_data, @@ -92,9 +92,11 @@ public: void remove_entry(int index, unsigned int hash, Symbol* name, ClassLoaderData* loader_data); -// Remove placeholder information + // find_and_remove first removes SeenThread for classloadAction + // If all queues are empty and definer is null, remove the PlacheholderEntry completely void find_and_remove(int index, unsigned int hash, - Symbol* name, ClassLoaderData* loader_data, Thread* thread); + Symbol* name, ClassLoaderData* loader_data, + classloadAction action, Thread* thread); // GC support. void classes_do(KlassClosure* f); diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp index a493e73d84d..54601625056 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -172,7 +172,7 @@ Klass* SystemDictionary::handle_resolution_exception(Symbol* class_name, Handle assert(klass_h() == NULL, "Should not have result with exception pending"); Handle e(THREAD, PENDING_EXCEPTION); CLEAR_PENDING_EXCEPTION; - THROW_MSG_CAUSE_0(vmSymbols::java_lang_NoClassDefFoundError(), class_name->as_C_string(), e); + THROW_MSG_CAUSE_NULL(vmSymbols::java_lang_NoClassDefFoundError(), class_name->as_C_string(), e); } else { return NULL; } @@ -181,9 +181,9 @@ Klass* SystemDictionary::handle_resolution_exception(Symbol* class_name, Handle if (klass_h() == NULL) { ResourceMark rm(THREAD); if (throw_error) { - THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), class_name->as_C_string()); + THROW_MSG_NULL(vmSymbols::java_lang_NoClassDefFoundError(), class_name->as_C_string()); } else { - THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), class_name->as_C_string()); + THROW_MSG_NULL(vmSymbols::java_lang_ClassNotFoundException(), class_name->as_C_string()); } } return (Klass*)klass_h(); @@ -343,29 +343,29 @@ Klass* SystemDictionary::resolve_super_or_fail(Symbol* child_name, } if (throw_circularity_error) { ResourceMark rm(THREAD); - THROW_MSG_0(vmSymbols::java_lang_ClassCircularityError(), child_name->as_C_string()); + THROW_MSG_NULL(vmSymbols::java_lang_ClassCircularityError(), child_name->as_C_string()); } // java.lang.Object should have been found above assert(class_name != NULL, "null super class for resolving"); // Resolve the super class or interface, check results on return - Klass* superk = NULL; - superk = SystemDictionary::resolve_or_null(class_name, + Klass* superk = SystemDictionary::resolve_or_null(class_name, class_loader, protection_domain, THREAD); KlassHandle superk_h(THREAD, superk); - // Note: clean up of placeholders currently in callers of - // resolve_super_or_fail - either at update_dictionary time - // or on error + // Clean up of placeholders moved so that each classloadAction registrar self-cleans up + // It is no longer necessary to keep the placeholder table alive until update_dictionary + // or error. GC used to walk the placeholder table as strong roots. + // The instanceKlass is kept alive because the class loader is on the stack, + // which keeps the loader_data alive, as well as all instanceKlasses in + // the loader_data. parseClassFile adds the instanceKlass to loader_data. { - MutexLocker mu(SystemDictionary_lock, THREAD); - PlaceholderEntry* probe = placeholders()->get_entry(p_index, p_hash, child_name, loader_data); - if (probe != NULL) { - probe->remove_seen_thread(THREAD, PlaceholderTable::LOAD_SUPER); - } + MutexLocker mu(SystemDictionary_lock, THREAD); + placeholders()->find_and_remove(p_index, p_hash, child_name, loader_data, PlaceholderTable::LOAD_SUPER, THREAD); + SystemDictionary_lock->notify_all(); } if (HAS_PENDING_EXCEPTION || superk_h() == NULL) { // can null superk @@ -430,8 +430,8 @@ void SystemDictionary::validate_protection_domain(instanceKlassHandle klass, // We're using a No_Safepoint_Verifier to catch any place where we // might potentially do a GC at all. - // SystemDictionary::do_unloading() asserts that classes are only - // unloaded at a safepoint. + // Dictionary::do_unloading() asserts that classes in SD are only + // unloaded at a safepoint. Anonymous classes are not in SD. No_Safepoint_Verifier nosafepoint; dictionary()->add_protection_domain(d_index, d_hash, klass, loader_data, protection_domain, THREAD); @@ -486,7 +486,6 @@ void SystemDictionary::double_lock_wait(Handle lockObject, TRAPS) { // super class loading here. // This also is critical in cases where the original thread gets stalled // even in non-circularity situations. -// Note: only one thread can define the class, but multiple can resolve // Note: must call resolve_super_or_fail even if null super - // to force placeholder entry creation for this class for circularity detection // Caller must check for pending exception @@ -518,14 +517,6 @@ instanceKlassHandle SystemDictionary::handle_parallel_super_load( protection_domain, true, CHECK_(nh)); - // We don't redefine the class, so we just need to clean up if there - // was not an error (don't want to modify any system dictionary - // data structures). - { - MutexLocker mu(SystemDictionary_lock, THREAD); - placeholders()->find_and_remove(p_index, p_hash, name, loader_data, THREAD); - SystemDictionary_lock->notify_all(); - } // parallelCapable class loaders do NOT wait for parallel superclass loads to complete // Serial class loaders and bootstrap classloader do wait for superclass loads @@ -595,6 +586,10 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla // Do lookup to see if class already exist and the protection domain // has the right access + // This call uses find which checks protection domain already matches + // All subsequent calls use find_class, and set has_loaded_class so that + // before we return a result we call out to java to check for valid protection domain + // to allow returning the Klass* and add it to the pd_set if it is valid unsigned int d_hash = dictionary()->compute_hash(name, loader_data); int d_index = dictionary()->hash_to_index(d_hash); Klass* probe = dictionary()->find(d_index, d_hash, name, loader_data, @@ -652,7 +647,7 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla } } - // If the class in is in the placeholder table, class loading is in progress + // If the class is in the placeholder table, class loading is in progress if (super_load_in_progress && havesupername==true) { k = SystemDictionary::handle_parallel_super_load(name, superclassname, class_loader, protection_domain, lockObject, THREAD); @@ -664,7 +659,9 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla } } + bool throw_circularity_error = false; if (!class_has_been_loaded) { + bool load_instance_added = false; // add placeholder entry to record loading instance class // Five cases: @@ -690,7 +687,7 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla // No performance benefit and no deadlock issues. // case 5. parallelCapable user level classloaders - without objectLocker // Allow parallel classloading of a class/classloader pair - bool throw_circularity_error = false; + { MutexLocker mu(SystemDictionary_lock, THREAD); if (class_loader.is_null() || !is_parallelCapable(class_loader)) { @@ -726,12 +723,13 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla } } } - // All cases: add LOAD_INSTANCE + // All cases: add LOAD_INSTANCE holding SystemDictionary_lock // case 3: UnsyncloadClass || case 5: parallelCapable: allow competing threads to try // LOAD_INSTANCE in parallel - // add placeholder entry even if error - callers will remove on error + if (!throw_circularity_error && !class_has_been_loaded) { PlaceholderEntry* newprobe = placeholders()->find_and_add(p_index, p_hash, name, loader_data, PlaceholderTable::LOAD_INSTANCE, NULL, THREAD); + load_instance_added = true; // For class loaders that do not acquire the classloader object lock, // if they did not catch another thread holding LOAD_INSTANCE, // need a check analogous to the acquire ObjectLocker/find_class @@ -740,19 +738,18 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla // class loaders holding the ObjectLock shouldn't find the class here Klass* check = find_class(d_index, d_hash, name, loader_data); if (check != NULL) { - // Klass is already loaded, so just return it + // Klass is already loaded, so return it after checking/adding protection domain k = instanceKlassHandle(THREAD, check); class_has_been_loaded = true; - newprobe->remove_seen_thread(THREAD, PlaceholderTable::LOAD_INSTANCE); - placeholders()->find_and_remove(p_index, p_hash, name, loader_data, THREAD); - SystemDictionary_lock->notify_all(); } } } + // must throw error outside of owning lock if (throw_circularity_error) { + assert(!HAS_PENDING_EXCEPTION && load_instance_added == false,"circularity error cleanup"); ResourceMark rm(THREAD); - THROW_MSG_0(vmSymbols::java_lang_ClassCircularityError(), name->as_C_string()); + THROW_MSG_NULL(vmSymbols::java_lang_ClassCircularityError(), name->as_C_string()); } if (!class_has_been_loaded) { @@ -782,20 +779,6 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla } } - // clean up placeholder entries for success or error - // This cleans up LOAD_INSTANCE entries - // It also cleans up LOAD_SUPER entries on errors from - // calling load_instance_class - { - MutexLocker mu(SystemDictionary_lock, THREAD); - PlaceholderEntry* probe = placeholders()->get_entry(p_index, p_hash, name, loader_data); - if (probe != NULL) { - probe->remove_seen_thread(THREAD, PlaceholderTable::LOAD_INSTANCE); - placeholders()->find_and_remove(p_index, p_hash, name, loader_data, THREAD); - SystemDictionary_lock->notify_all(); - } - } - // If everything was OK (no exceptions, no null return value), and // class_loader is NOT the defining loader, do a little more bookkeeping. if (!HAS_PENDING_EXCEPTION && !k.is_null() && @@ -819,18 +802,22 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla } } } - if (HAS_PENDING_EXCEPTION || k.is_null()) { - // On error, clean up placeholders - { - MutexLocker mu(SystemDictionary_lock, THREAD); - placeholders()->find_and_remove(p_index, p_hash, name, loader_data, THREAD); - SystemDictionary_lock->notify_all(); - } - return NULL; - } + } // load_instance_class loop + + if (load_instance_added == true) { + // clean up placeholder entries for LOAD_INSTANCE success or error + // This brackets the SystemDictionary updates for both defining + // and initiating loaders + MutexLocker mu(SystemDictionary_lock, THREAD); + placeholders()->find_and_remove(p_index, p_hash, name, loader_data, PlaceholderTable::LOAD_INSTANCE, THREAD); + SystemDictionary_lock->notify_all(); } } + if (HAS_PENDING_EXCEPTION || k.is_null()) { + return NULL; + } + #ifdef ASSERT { ClassLoaderData* loader_data = k->class_loader_data(); @@ -850,8 +837,8 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla // so we cannot allow GC to occur while we're holding this entry. // We're using a No_Safepoint_Verifier to catch any place where we // might potentially do a GC at all. - // SystemDictionary::do_unloading() asserts that classes are only - // unloaded at a safepoint. + // Dictionary::do_unloading() asserts that classes in SD are only + // unloaded at a safepoint. Anonymous classes are not in SD. No_Safepoint_Verifier nosafepoint; if (dictionary()->is_valid_protection_domain(d_index, d_hash, name, loader_data, @@ -898,8 +885,8 @@ Klass* SystemDictionary::find(Symbol* class_name, // so we cannot allow GC to occur while we're holding this entry. // We're using a No_Safepoint_Verifier to catch any place where we // might potentially do a GC at all. - // SystemDictionary::do_unloading() asserts that classes are only - // unloaded at a safepoint. + // Dictionary::do_unloading() asserts that classes in SD are only + // unloaded at a safepoint. Anonymous classes are not in SD. No_Safepoint_Verifier nosafepoint; return dictionary()->find(d_index, d_hash, class_name, loader_data, protection_domain, THREAD); @@ -965,10 +952,6 @@ Klass* SystemDictionary::parse_stream(Symbol* class_name, // throw potential ClassFormatErrors. // // Note: "name" is updated. - // Further note: a placeholder will be added for this class when - // super classes are loaded (resolve_super_or_fail). We expect this - // to be called for all classes but java.lang.Object; and we preload - // java.lang.Object through resolve_or_fail, not this path. instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name, loader_data, @@ -979,21 +962,6 @@ Klass* SystemDictionary::parse_stream(Symbol* class_name, true, THREAD); - // We don't redefine the class, so we just need to clean up whether there - // was an error or not (don't want to modify any system dictionary - // data structures). - // Parsed name could be null if we threw an error before we got far - // enough along to parse it -- in that case, there is nothing to clean up. - if (parsed_name != NULL) { - unsigned int p_hash = placeholders()->compute_hash(parsed_name, - loader_data); - int p_index = placeholders()->hash_to_index(p_hash); - { - MutexLocker mu(SystemDictionary_lock, THREAD); - placeholders()->find_and_remove(p_index, p_hash, parsed_name, loader_data, THREAD); - SystemDictionary_lock->notify_all(); - } - } if (host_klass.not_null() && k.not_null()) { assert(EnableInvokeDynamic, ""); @@ -1062,10 +1030,6 @@ Klass* SystemDictionary::resolve_from_stream(Symbol* class_name, // throw potential ClassFormatErrors. // // Note: "name" is updated. - // Further note: a placeholder will be added for this class when - // super classes are loaded (resolve_super_or_fail). We expect this - // to be called for all classes but java.lang.Object; and we preload - // java.lang.Object through resolve_or_fail, not this path. instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name, loader_data, @@ -1114,25 +1078,7 @@ Klass* SystemDictionary::resolve_from_stream(Symbol* class_name, } } - // If parsing the class file or define_instance_class failed, we - // need to remove the placeholder added on our behalf. But we - // must make sure parsed_name is valid first (it won't be if we had - // a format error before the class was parsed far enough to - // find the name). - if (HAS_PENDING_EXCEPTION && parsed_name != NULL) { - unsigned int p_hash = placeholders()->compute_hash(parsed_name, - loader_data); - int p_index = placeholders()->hash_to_index(p_hash); - { - MutexLocker mu(SystemDictionary_lock, THREAD); - placeholders()->find_and_remove(p_index, p_hash, parsed_name, loader_data, THREAD); - SystemDictionary_lock->notify_all(); - } - return NULL; - } - - // Make sure that we didn't leave a place holder in the - // SystemDictionary; this is only done on success + // Make sure we have an entry in the SystemDictionary on success debug_only( { if (!HAS_PENDING_EXCEPTION) { assert(parsed_name != NULL, "parsed_name is still null?"); @@ -1547,8 +1493,7 @@ instanceKlassHandle SystemDictionary::find_or_define_instance_class(Symbol* clas // Other cases fall through, and may run into duplicate defines // caught by finding an entry in the SystemDictionary if ((UnsyncloadClass || is_parallelDefine(class_loader)) && (probe->instance_klass() != NULL)) { - probe->remove_seen_thread(THREAD, PlaceholderTable::DEFINE_CLASS); - placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, THREAD); + placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, THREAD); SystemDictionary_lock->notify_all(); #ifdef ASSERT Klass* check = find_class(d_index, d_hash, name_h, loader_data); @@ -1578,8 +1523,7 @@ instanceKlassHandle SystemDictionary::find_or_define_instance_class(Symbol* clas probe->set_instance_klass(k()); } probe->set_definer(NULL); - probe->remove_seen_thread(THREAD, PlaceholderTable::DEFINE_CLASS); - placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, THREAD); + placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, THREAD); SystemDictionary_lock->notify_all(); } } @@ -1736,6 +1680,8 @@ int SystemDictionary::calculate_systemdictionary_size(int classcount) { } return newsize; } +// Assumes classes in the SystemDictionary are only unloaded at a safepoint +// Note: anonymous classes are not in the SD. bool SystemDictionary::do_unloading(BoolObjectClosure* is_alive) { // First, mark for unload all ClassLoaderData referencing a dead class loader. bool has_dead_loaders = ClassLoaderDataGraph::do_unloading(is_alive); @@ -2105,9 +2051,7 @@ void SystemDictionary::update_dictionary(int d_index, unsigned int d_hash, // All loaded classes get a unique ID. TRACE_INIT_ID(k); - // Check for a placeholder. If there, remove it and make a - // new system dictionary entry. - placeholders()->find_and_remove(p_index, p_hash, name, loader_data, THREAD); + // Make a new system dictionary entry. Klass* sd_check = find_class(d_index, d_hash, name, loader_data); if (sd_check == NULL) { dictionary()->add_klass(name, loader_data, k); @@ -2116,12 +2060,8 @@ void SystemDictionary::update_dictionary(int d_index, unsigned int d_hash, #ifdef ASSERT sd_check = find_class(d_index, d_hash, name, loader_data); assert (sd_check != NULL, "should have entry in system dictionary"); -// Changed to allow PH to remain to complete class circularity checking -// while only one thread can define a class at one time, multiple -// classes can resolve the superclass for a class at one time, -// and the placeholder is used to track that -// Symbol* ph_check = find_placeholder(name, class_loader); -// assert (ph_check == NULL, "should not have a placeholder entry"); + // Note: there may be a placeholder entry: for circularity testing + // or for parallel defines #endif SystemDictionary_lock->notify_all(); } diff --git a/hotspot/src/share/vm/utilities/exceptions.hpp b/hotspot/src/share/vm/utilities/exceptions.hpp index 740912d3909..089cd3e0811 100644 --- a/hotspot/src/share/vm/utilities/exceptions.hpp +++ b/hotspot/src/share/vm/utilities/exceptions.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, 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 @@ -267,6 +267,7 @@ class Exceptions { #define THROW_WRAPPED_0(name, oop_to_wrap) THROW_WRAPPED_(name, oop_to_wrap, 0) #define THROW_ARG_0(name, signature, arg) THROW_ARG_(name, signature, arg, 0) #define THROW_MSG_CAUSE_0(name, message, cause) THROW_MSG_CAUSE_(name, message, cause, 0) +#define THROW_MSG_CAUSE_NULL(name, message, cause) THROW_MSG_CAUSE_(name, message, cause, NULL) #define THROW_NULL(name) THROW_(name, NULL) #define THROW_MSG_NULL(name, message) THROW_MSG_(name, message, NULL) From e7e6443c6d3c1e98d289306b38c5d2a101cc8e51 Mon Sep 17 00:00:00 2001 From: Mikael Vidstedt Date: Thu, 10 Jan 2013 17:06:26 -0800 Subject: [PATCH 052/204] 8004747: Remove last_entry from VM_STRUCT macros Instead of passing in last_entry to all the VM_ macros just expand it in the main vmStructs.cpp file. Reviewed-by: dholmes, sspitsyn, minqi --- hotspot/src/cpu/sparc/vm/vmStructs_sparc.hpp | 29 +- hotspot/src/cpu/x86/vm/vmStructs_x86.hpp | 27 +- hotspot/src/cpu/zero/vm/vmStructs_zero.hpp | 24 +- .../os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp | 23 +- .../os_cpu/bsd_zero/vm/vmStructs_bsd_zero.hpp | 16 +- .../linux_sparc/vm/vmStructs_linux_sparc.hpp | 25 +- .../linux_x86/vm/vmStructs_linux_x86.hpp | 23 +- .../linux_zero/vm/vmStructs_linux_zero.hpp | 17 +- .../vm/vmStructs_solaris_sparc.hpp | 26 +- .../solaris_x86/vm/vmStructs_solaris_x86.hpp | 24 +- .../windows_x86/vm/vmStructs_windows_x86.hpp | 23 +- hotspot/src/share/vm/runtime/vmStructs.cpp | 248 +++++++++--------- 12 files changed, 179 insertions(+), 326 deletions(-) diff --git a/hotspot/src/cpu/sparc/vm/vmStructs_sparc.hpp b/hotspot/src/cpu/sparc/vm/vmStructs_sparc.hpp index 8103a6395b7..11f829385b8 100644 --- a/hotspot/src/cpu/sparc/vm/vmStructs_sparc.hpp +++ b/hotspot/src/cpu/sparc/vm/vmStructs_sparc.hpp @@ -29,7 +29,7 @@ // constants required by the Serviceability Agent. This file is // referenced by vmStructs.cpp. -#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \ +#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \ \ /******************************/ \ /* JavaCallWrapper */ \ @@ -37,22 +37,12 @@ /******************************/ \ /* JavaFrameAnchor */ \ /******************************/ \ - volatile_nonstatic_field(JavaFrameAnchor, _flags, int) \ - \ + volatile_nonstatic_field(JavaFrameAnchor, _flags, int) - /* NOTE that we do not use the last_entry() macro here; it is used */ - /* in vmStructs__.hpp's VM_STRUCTS_OS_CPU macro (and must */ - /* be present there) */ +#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) -#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \ - - /* NOTE that we do not use the last_entry() macro here; it is used */ - /* in vmStructs__.hpp's VM_TYPES_OS_CPU macro (and must */ - /* be present there) */ - - -#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ +#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \ /******************************/ \ /* Register numbers (C2 only) */ \ /******************************/ \ @@ -90,15 +80,6 @@ declare_c2_constant(R_G6_num) \ declare_c2_constant(R_G7_num) - - /* NOTE that we do not use the last_entry() macro here; it is used */ - /* in vmStructs__.hpp's VM_INT_CONSTANTS_OS_CPU macro (and must */ - /* be present there) */ - -#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ - - /* NOTE that we do not use the last_entry() macro here; it is used */ - /* in vmStructs__.hpp's VM_LONG_CONSTANTS_OS_CPU macro (and must */ - /* be present there) */ +#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) #endif // CPU_SPARC_VM_VMSTRUCTS_SPARC_HPP diff --git a/hotspot/src/cpu/x86/vm/vmStructs_x86.hpp b/hotspot/src/cpu/x86/vm/vmStructs_x86.hpp index 8dddc9c3e1d..847d08ed207 100644 --- a/hotspot/src/cpu/x86/vm/vmStructs_x86.hpp +++ b/hotspot/src/cpu/x86/vm/vmStructs_x86.hpp @@ -29,7 +29,7 @@ // constants required by the Serviceability Agent. This file is // referenced by vmStructs.cpp. -#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \ +#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \ \ /******************************/ \ /* JavaCallWrapper */ \ @@ -37,31 +37,14 @@ /******************************/ \ /* JavaFrameAnchor */ \ /******************************/ \ - volatile_nonstatic_field(JavaFrameAnchor, _last_Java_fp, intptr_t*) \ - \ - - /* NOTE that we do not use the last_entry() macro here; it is used */ - /* in vmStructs__.hpp's VM_STRUCTS_OS_CPU macro (and must */ - /* be present there) */ + volatile_nonstatic_field(JavaFrameAnchor, _last_Java_fp, intptr_t*) -#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \ - /* NOTE that we do not use the last_entry() macro here; it is used */ - /* in vmStructs__.hpp's VM_TYPES_OS_CPU macro (and must */ - /* be present there) */ +#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) +#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) -#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ - - /* NOTE that we do not use the last_entry() macro here; it is used */ - /* in vmStructs__.hpp's VM_INT_CONSTANTS_OS_CPU macro (and must */ - /* be present there) */ - -#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ - - /* NOTE that we do not use the last_entry() macro here; it is used */ - /* in vmStructs__.hpp's VM_LONG_CONSTANTS_OS_CPU macro (and must */ - /* be present there) */ +#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) #endif // CPU_X86_VM_VMSTRUCTS_X86_HPP diff --git a/hotspot/src/cpu/zero/vm/vmStructs_zero.hpp b/hotspot/src/cpu/zero/vm/vmStructs_zero.hpp index 1b3815a0a2c..0bbc1f40f45 100644 --- a/hotspot/src/cpu/zero/vm/vmStructs_zero.hpp +++ b/hotspot/src/cpu/zero/vm/vmStructs_zero.hpp @@ -30,28 +30,12 @@ // constants required by the Serviceability Agent. This file is // referenced by vmStructs.cpp. -#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \ +#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) - /* NOTE that we do not use the last_entry() macro here; it is used */ - /* in vmStructs__.hpp's VM_STRUCTS_OS_CPU macro (and must */ - /* be present there) */ +#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) -#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \ +#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) - /* NOTE that we do not use the last_entry() macro here; it is used */ - /* in vmStructs__.hpp's VM_TYPES_OS_CPU macro (and must */ - /* be present there) */ - -#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ - - /* NOTE that we do not use the last_entry() macro here; it is used */ - /* in vmStructs__.hpp's VM_INT_CONSTANTS_OS_CPU macro (and must */ - /* be present there) */ - -#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ - - /* NOTE that we do not use the last_entry() macro here; it is used */ - /* in vmStructs__.hpp's VM_LONG_CONSTANTS_OS_CPU macro (and must */ - /* be present there) */ +#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) #endif // CPU_ZERO_VM_VMSTRUCTS_ZERO_HPP diff --git a/hotspot/src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp b/hotspot/src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp index b98d975408a..edfbcfa9a54 100644 --- a/hotspot/src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp +++ b/hotspot/src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp @@ -29,37 +29,26 @@ // constants required by the Serviceability Agent. This file is // referenced by vmStructs.cpp. -#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \ +#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \ \ /******************************/ \ /* Threads (NOTE: incomplete) */ \ /******************************/ \ nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \ - nonstatic_field(OSThread, _pthread_id, pthread_t) \ - /* This must be the last entry, and must be present */ \ - last_entry() + nonstatic_field(OSThread, _pthread_id, pthread_t) -#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \ +#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \ \ /**********************/ \ /* Posix Thread IDs */ \ /**********************/ \ \ declare_unsigned_integer_type(OSThread::thread_id_t) \ - declare_unsigned_integer_type(pthread_t) \ - \ - /* This must be the last entry, and must be present */ \ - last_entry() + declare_unsigned_integer_type(pthread_t) -#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ - \ - /* This must be the last entry, and must be present */ \ - last_entry() +#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) -#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ - \ - /* This must be the last entry, and must be present */ \ - last_entry() +#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) #endif // OS_CPU_BSD_X86_VM_VMSTRUCTS_BSD_X86_HPP diff --git a/hotspot/src/os_cpu/bsd_zero/vm/vmStructs_bsd_zero.hpp b/hotspot/src/os_cpu/bsd_zero/vm/vmStructs_bsd_zero.hpp index 17165cc9d13..6673f448f81 100644 --- a/hotspot/src/os_cpu/bsd_zero/vm/vmStructs_bsd_zero.hpp +++ b/hotspot/src/os_cpu/bsd_zero/vm/vmStructs_bsd_zero.hpp @@ -30,21 +30,13 @@ // constants required by the Serviceability Agent. This file is // referenced by vmStructs.cpp. -#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \ - /* This must be the last entry, and must be present */ \ - last_entry() +#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) -#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \ - /* This must be the last entry, and must be present */ \ - last_entry() +#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) -#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ - /* This must be the last entry, and must be present */ \ - last_entry() +#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) -#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ - /* This must be the last entry, and must be present */ \ - last_entry() +#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) #endif // OS_CPU_BSD_ZERO_VM_VMSTRUCTS_BSD_ZERO_HPP diff --git a/hotspot/src/os_cpu/linux_sparc/vm/vmStructs_linux_sparc.hpp b/hotspot/src/os_cpu/linux_sparc/vm/vmStructs_linux_sparc.hpp index 58fc94bbc38..38bc63e6496 100644 --- a/hotspot/src/os_cpu/linux_sparc/vm/vmStructs_linux_sparc.hpp +++ b/hotspot/src/os_cpu/linux_sparc/vm/vmStructs_linux_sparc.hpp @@ -29,7 +29,7 @@ // constants required by the Serviceability Agent. This file is // referenced by vmStructs.cpp. -#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \ +#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \ \ /******************************/ \ /* Threads (NOTE: incomplete) */ \ @@ -37,38 +37,27 @@ \ nonstatic_field(JavaThread, _base_of_stack_pointer, intptr_t*) \ nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \ - nonstatic_field(OSThread, _pthread_id, pthread_t) \ - /* This must be the last entry, and must be present */ \ - last_entry() + nonstatic_field(OSThread, _pthread_id, pthread_t) -#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \ +#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \ \ /**********************/ \ /* POSIX Thread IDs */ \ /**********************/ \ \ declare_integer_type(OSThread::thread_id_t) \ - declare_unsigned_integer_type(pthread_t) \ - \ - /* This must be the last entry, and must be present */ \ - last_entry() + declare_unsigned_integer_type(pthread_t) -#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ +#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \ \ /************************/ \ /* JavaThread constants */ \ /************************/ \ \ - declare_constant(JavaFrameAnchor::flushed) \ - \ - /* This must be the last entry, and must be present */ \ - last_entry() + declare_constant(JavaFrameAnchor::flushed) -#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ - \ - /* This must be the last entry, and must be present */ \ - last_entry() +#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) #endif // OS_CPU_LINUX_SPARC_VM_VMSTRUCTS_LINUX_SPARC_HPP diff --git a/hotspot/src/os_cpu/linux_x86/vm/vmStructs_linux_x86.hpp b/hotspot/src/os_cpu/linux_x86/vm/vmStructs_linux_x86.hpp index c01e6c91c2a..828f992d8ba 100644 --- a/hotspot/src/os_cpu/linux_x86/vm/vmStructs_linux_x86.hpp +++ b/hotspot/src/os_cpu/linux_x86/vm/vmStructs_linux_x86.hpp @@ -29,37 +29,26 @@ // constants required by the Serviceability Agent. This file is // referenced by vmStructs.cpp. -#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \ +#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \ \ /******************************/ \ /* Threads (NOTE: incomplete) */ \ /******************************/ \ nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \ - nonstatic_field(OSThread, _pthread_id, pthread_t) \ - /* This must be the last entry, and must be present */ \ - last_entry() + nonstatic_field(OSThread, _pthread_id, pthread_t) -#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \ +#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \ \ /**********************/ \ /* Posix Thread IDs */ \ /**********************/ \ \ declare_integer_type(OSThread::thread_id_t) \ - declare_unsigned_integer_type(pthread_t) \ - \ - /* This must be the last entry, and must be present */ \ - last_entry() + declare_unsigned_integer_type(pthread_t) -#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ - \ - /* This must be the last entry, and must be present */ \ - last_entry() +#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) -#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ - \ - /* This must be the last entry, and must be present */ \ - last_entry() +#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) #endif // OS_CPU_LINUX_X86_VM_VMSTRUCTS_LINUX_X86_HPP diff --git a/hotspot/src/os_cpu/linux_zero/vm/vmStructs_linux_zero.hpp b/hotspot/src/os_cpu/linux_zero/vm/vmStructs_linux_zero.hpp index 46c7912c372..34b82a96d79 100644 --- a/hotspot/src/os_cpu/linux_zero/vm/vmStructs_linux_zero.hpp +++ b/hotspot/src/os_cpu/linux_zero/vm/vmStructs_linux_zero.hpp @@ -30,21 +30,12 @@ // constants required by the Serviceability Agent. This file is // referenced by vmStructs.cpp. -#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \ - /* This must be the last entry, and must be present */ \ - last_entry() +#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) +#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) -#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \ - /* This must be the last entry, and must be present */ \ - last_entry() +#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) -#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ - /* This must be the last entry, and must be present */ \ - last_entry() - -#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ - /* This must be the last entry, and must be present */ \ - last_entry() +#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) #endif // OS_CPU_LINUX_ZERO_VM_VMSTRUCTS_LINUX_ZERO_HPP diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/vmStructs_solaris_sparc.hpp b/hotspot/src/os_cpu/solaris_sparc/vm/vmStructs_solaris_sparc.hpp index 58113a9ea49..40d6ae735aa 100644 --- a/hotspot/src/os_cpu/solaris_sparc/vm/vmStructs_solaris_sparc.hpp +++ b/hotspot/src/os_cpu/solaris_sparc/vm/vmStructs_solaris_sparc.hpp @@ -29,44 +29,32 @@ // constants required by the Serviceability Agent. This file is // referenced by vmStructs.cpp. -#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \ +#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \ \ /******************************/ \ /* Threads (NOTE: incomplete) */ \ /******************************/ \ \ nonstatic_field(JavaThread, _base_of_stack_pointer, intptr_t*) \ - nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \ - /* This must be the last entry, and must be present */ \ - last_entry() + nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) - -#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \ +#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \ \ /**********************/ \ /* Solaris Thread IDs */ \ /**********************/ \ \ - declare_unsigned_integer_type(OSThread::thread_id_t) \ - \ - /* This must be the last entry, and must be present */ \ - last_entry() + declare_unsigned_integer_type(OSThread::thread_id_t) -#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ +#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \ \ /************************/ \ /* JavaThread constants */ \ /************************/ \ \ - declare_constant(JavaFrameAnchor::flushed) \ - \ - /* This must be the last entry, and must be present */ \ - last_entry() + declare_constant(JavaFrameAnchor::flushed) -#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ - \ - /* This must be the last entry, and must be present */ \ - last_entry() +#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) #endif // OS_CPU_SOLARIS_SPARC_VM_VMSTRUCTS_SOLARIS_SPARC_HPP diff --git a/hotspot/src/os_cpu/solaris_x86/vm/vmStructs_solaris_x86.hpp b/hotspot/src/os_cpu/solaris_x86/vm/vmStructs_solaris_x86.hpp index a2a4f7c60b7..523fdc7cc42 100644 --- a/hotspot/src/os_cpu/solaris_x86/vm/vmStructs_solaris_x86.hpp +++ b/hotspot/src/os_cpu/solaris_x86/vm/vmStructs_solaris_x86.hpp @@ -29,36 +29,24 @@ // constants required by the Serviceability Agent. This file is // referenced by vmStructs.cpp. -#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \ +#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \ \ /******************************/ \ /* Threads (NOTE: incomplete) */ \ /******************************/ \ \ - nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \ - \ - /* This must be the last entry, and must be present */ \ - last_entry() + nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) -#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \ +#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \ \ /**********************/ \ /* Solaris Thread IDs */ \ /**********************/ \ \ - declare_unsigned_integer_type(OSThread::thread_id_t) \ - \ - /* This must be the last entry, and must be present */ \ - last_entry() + declare_unsigned_integer_type(OSThread::thread_id_t) -#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ - \ - /* This must be the last entry, and must be present */ \ - last_entry() +#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) -#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ - \ - /* This must be the last entry, and must be present */ \ - last_entry() +#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) #endif // OS_CPU_SOLARIS_X86_VM_VMSTRUCTS_SOLARIS_X86_HPP diff --git a/hotspot/src/os_cpu/windows_x86/vm/vmStructs_windows_x86.hpp b/hotspot/src/os_cpu/windows_x86/vm/vmStructs_windows_x86.hpp index 69d25c93186..a392b63632c 100644 --- a/hotspot/src/os_cpu/windows_x86/vm/vmStructs_windows_x86.hpp +++ b/hotspot/src/os_cpu/windows_x86/vm/vmStructs_windows_x86.hpp @@ -29,32 +29,21 @@ // constants required by the Serviceability Agent. This file is // referenced by vmStructs.cpp. -#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \ +#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \ \ /******************************/ \ /* Threads (NOTE: incomplete) */ \ /******************************/ \ \ nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \ - unchecked_nonstatic_field(OSThread, _thread_handle, sizeof(HANDLE)) /* NOTE: no type */ \ - \ - /* This must be the last entry, and must be present */ \ - last_entry() + unchecked_nonstatic_field(OSThread, _thread_handle, sizeof(HANDLE)) /* NOTE: no type */ -#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \ +#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \ \ - declare_unsigned_integer_type(OSThread::thread_id_t) \ - /* This must be the last entry, and must be present */ \ - last_entry() + declare_unsigned_integer_type(OSThread::thread_id_t) -#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ - \ - /* This must be the last entry, and must be present */ \ - last_entry() +#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) -#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ - \ - /* This must be the last entry, and must be present */ \ - last_entry() +#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) #endif // OS_CPU_WINDOWS_X86_VM_VMSTRUCTS_WINDOWS_X86_HPP diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index 9ac10e26d4c..958298bf994 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -257,8 +257,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; c1_nonstatic_field, \ c2_nonstatic_field, \ unchecked_c1_static_field, \ - unchecked_c2_static_field, \ - last_entry) \ + unchecked_c2_static_field) \ \ /******************************************************************/ \ /* OopDesc and Klass hierarchies (NOTE: MethodData* incomplete) */ \ @@ -1238,9 +1237,6 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; nonstatic_field(FreeList, _count, ssize_t) \ nonstatic_field(MetablockTreeDictionary, _total_size, size_t) - /* NOTE that we do not use the last_entry() macro here; it is used */ - /* in vmStructs__.hpp's VM_STRUCTS_OS_CPU macro (and must */ - /* be present there) */ //-------------------------------------------------------------------------------- // VM_TYPES @@ -1280,8 +1276,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_unsigned_integer_type, \ declare_c1_toplevel_type, \ declare_c2_type, \ - declare_c2_toplevel_type, \ - last_entry) \ + declare_c2_toplevel_type) \ \ /*************************************************************/ \ /* Java primitive types -- required by the SA implementation */ \ @@ -2098,10 +2093,6 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_type(MetablockTreeDictionary, FreeBlockDictionary) - /* NOTE that we do not use the last_entry() macro here; it is used */ - /* in vmStructs__.hpp's VM_TYPES_OS_CPU macro (and must be */ - /* present there) */ - //-------------------------------------------------------------------------------- // VM_INT_CONSTANTS // @@ -2114,8 +2105,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_preprocessor_constant, \ declare_c1_constant, \ declare_c2_constant, \ - declare_c2_preprocessor_constant, \ - last_entry) \ + declare_c2_preprocessor_constant) \ \ /******************/ \ /* Useful globals */ \ @@ -2483,9 +2473,6 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_c2_preprocessor_constant("SAVED_ON_ENTRY_REG_COUNT", SAVED_ON_ENTRY_REG_COUNT) \ declare_c2_preprocessor_constant("C_SAVED_ON_ENTRY_REG_COUNT", C_SAVED_ON_ENTRY_REG_COUNT) - /* NOTE that we do not use the last_entry() macro here; it is used */ - /* in vmStructs__.hpp's VM_INT_CONSTANTS_OS_CPU macro (and */ - /* must be present there) */ //-------------------------------------------------------------------------------- // VM_LONG_CONSTANTS @@ -2495,7 +2482,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; // enums, etc., while "declare_preprocessor_constant" must be used for // all #defined constants. -#define VM_LONG_CONSTANTS(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \ +#define VM_LONG_CONSTANTS(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \ \ /*********************/ \ /* MarkOop constants */ \ @@ -2541,11 +2528,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; /* Constants in markOop used by CMS. */ \ declare_constant(markOopDesc::cms_shift) \ declare_constant(markOopDesc::cms_mask) \ - declare_constant(markOopDesc::size_shift) \ - - /* NOTE that we do not use the last_entry() macro here; it is used */ - /* in vmStructs__.hpp's VM_LONG_CONSTANTS_OS_CPU macro (and */ - /* must be present there) */ + declare_constant(markOopDesc::size_shift) //-------------------------------------------------------------------------------- @@ -2608,9 +2591,6 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; // This is a no-op macro for unchecked fields #define CHECK_NO_OP(a, b, c) -// This is a no-op macro for the sentinel value -#define CHECK_SENTINEL() - // // Build-specific macros: // @@ -2789,48 +2769,47 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; // as long as class VMStructs is a friend VMStructEntry VMStructs::localHotSpotVMStructs[] = { - VM_STRUCTS(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \ - GENERATE_STATIC_VM_STRUCT_ENTRY, \ - GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY, \ - GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \ - GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY, \ - GENERATE_C1_NONSTATIC_VM_STRUCT_ENTRY, \ - GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY, \ - GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY, \ - GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY, \ - GENERATE_VM_STRUCT_LAST_ENTRY) + VM_STRUCTS(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, + GENERATE_STATIC_VM_STRUCT_ENTRY, + GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY, + GENERATE_NONSTATIC_VM_STRUCT_ENTRY, + GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY, + GENERATE_C1_NONSTATIC_VM_STRUCT_ENTRY, + GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY, + GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY, + GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY) #ifndef SERIALGC - VM_STRUCTS_PARALLELGC(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \ + VM_STRUCTS_PARALLELGC(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, GENERATE_STATIC_VM_STRUCT_ENTRY) - VM_STRUCTS_CMS(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \ - GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \ + VM_STRUCTS_CMS(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, + GENERATE_NONSTATIC_VM_STRUCT_ENTRY, GENERATE_STATIC_VM_STRUCT_ENTRY) - VM_STRUCTS_G1(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \ + VM_STRUCTS_G1(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, GENERATE_STATIC_VM_STRUCT_ENTRY) #endif // SERIALGC - VM_STRUCTS_CPU(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \ - GENERATE_STATIC_VM_STRUCT_ENTRY, \ - GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY, \ - GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \ - GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY, \ - GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY, \ - GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY, \ - GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY, \ - GENERATE_VM_STRUCT_LAST_ENTRY) + VM_STRUCTS_CPU(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, + GENERATE_STATIC_VM_STRUCT_ENTRY, + GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY, + GENERATE_NONSTATIC_VM_STRUCT_ENTRY, + GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY, + GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY, + GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY, + GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY) - VM_STRUCTS_OS_CPU(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \ - GENERATE_STATIC_VM_STRUCT_ENTRY, \ - GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY, \ - GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \ - GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY, \ - GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY, \ - GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY, \ - GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY, \ - GENERATE_VM_STRUCT_LAST_ENTRY) + VM_STRUCTS_OS_CPU(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, + GENERATE_STATIC_VM_STRUCT_ENTRY, + GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY, + GENERATE_NONSTATIC_VM_STRUCT_ENTRY, + GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY, + GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY, + GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY, + GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY) + + GENERATE_VM_STRUCT_LAST_ENTRY() }; VMTypeEntry VMStructs::localHotSpotVMTypes[] = { @@ -2842,8 +2821,7 @@ VMTypeEntry VMStructs::localHotSpotVMTypes[] = { GENERATE_UNSIGNED_INTEGER_VM_TYPE_ENTRY, GENERATE_C1_TOPLEVEL_VM_TYPE_ENTRY, GENERATE_C2_VM_TYPE_ENTRY, - GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY, - GENERATE_VM_TYPE_LAST_ENTRY) + GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY) #ifndef SERIALGC VM_TYPES_PARALLELGC(GENERATE_VM_TYPE_ENTRY, @@ -2865,8 +2843,7 @@ VMTypeEntry VMStructs::localHotSpotVMTypes[] = { GENERATE_UNSIGNED_INTEGER_VM_TYPE_ENTRY, GENERATE_C1_TOPLEVEL_VM_TYPE_ENTRY, GENERATE_C2_VM_TYPE_ENTRY, - GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY, - GENERATE_VM_TYPE_LAST_ENTRY) + GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY) VM_TYPES_OS_CPU(GENERATE_VM_TYPE_ENTRY, GENERATE_TOPLEVEL_VM_TYPE_ENTRY, @@ -2875,8 +2852,9 @@ VMTypeEntry VMStructs::localHotSpotVMTypes[] = { GENERATE_UNSIGNED_INTEGER_VM_TYPE_ENTRY, GENERATE_C1_TOPLEVEL_VM_TYPE_ENTRY, GENERATE_C2_VM_TYPE_ENTRY, - GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY, - GENERATE_VM_TYPE_LAST_ENTRY) + GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY) + + GENERATE_VM_TYPE_LAST_ENTRY() }; VMIntConstantEntry VMStructs::localHotSpotVMIntConstants[] = { @@ -2885,8 +2863,7 @@ VMIntConstantEntry VMStructs::localHotSpotVMIntConstants[] = { GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY, GENERATE_C1_VM_INT_CONSTANT_ENTRY, GENERATE_C2_VM_INT_CONSTANT_ENTRY, - GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY, - GENERATE_VM_INT_CONSTANT_LAST_ENTRY) + GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY) #ifndef SERIALGC VM_INT_CONSTANTS_CMS(GENERATE_VM_INT_CONSTANT_ENTRY) @@ -2898,15 +2875,15 @@ VMIntConstantEntry VMStructs::localHotSpotVMIntConstants[] = { GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY, GENERATE_C1_VM_INT_CONSTANT_ENTRY, GENERATE_C2_VM_INT_CONSTANT_ENTRY, - GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY, - GENERATE_VM_INT_CONSTANT_LAST_ENTRY) + GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY) VM_INT_CONSTANTS_OS_CPU(GENERATE_VM_INT_CONSTANT_ENTRY, GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY, GENERATE_C1_VM_INT_CONSTANT_ENTRY, GENERATE_C2_VM_INT_CONSTANT_ENTRY, - GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY, - GENERATE_VM_INT_CONSTANT_LAST_ENTRY) + GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY) + + GENERATE_VM_INT_CONSTANT_LAST_ENTRY() }; VMLongConstantEntry VMStructs::localHotSpotVMLongConstants[] = { @@ -2915,22 +2892,21 @@ VMLongConstantEntry VMStructs::localHotSpotVMLongConstants[] = { GENERATE_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY, GENERATE_C1_VM_LONG_CONSTANT_ENTRY, GENERATE_C2_VM_LONG_CONSTANT_ENTRY, - GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY, - GENERATE_VM_LONG_CONSTANT_LAST_ENTRY) + GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY) VM_LONG_CONSTANTS_CPU(GENERATE_VM_LONG_CONSTANT_ENTRY, GENERATE_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY, GENERATE_C1_VM_LONG_CONSTANT_ENTRY, GENERATE_C2_VM_LONG_CONSTANT_ENTRY, - GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY, - GENERATE_VM_LONG_CONSTANT_LAST_ENTRY) + GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY) VM_LONG_CONSTANTS_OS_CPU(GENERATE_VM_LONG_CONSTANT_ENTRY, GENERATE_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY, GENERATE_C1_VM_LONG_CONSTANT_ENTRY, GENERATE_C2_VM_LONG_CONSTANT_ENTRY, - GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY, - GENERATE_VM_LONG_CONSTANT_LAST_ENTRY) + GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY) + + GENERATE_VM_LONG_CONSTANT_LAST_ENTRY() }; // This is used both to check the types of referenced fields and, in @@ -2945,8 +2921,7 @@ VMStructs::init() { CHECK_C1_NONSTATIC_VM_STRUCT_ENTRY, CHECK_C2_NONSTATIC_VM_STRUCT_ENTRY, CHECK_NO_OP, - CHECK_NO_OP, - CHECK_SENTINEL); + CHECK_NO_OP); #ifndef SERIALGC VM_STRUCTS_PARALLELGC(CHECK_NONSTATIC_VM_STRUCT_ENTRY, @@ -2967,8 +2942,7 @@ VMStructs::init() { CHECK_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY, CHECK_C2_NONSTATIC_VM_STRUCT_ENTRY, CHECK_NO_OP, - CHECK_NO_OP, - CHECK_SENTINEL); + CHECK_NO_OP); VM_STRUCTS_OS_CPU(CHECK_NONSTATIC_VM_STRUCT_ENTRY, CHECK_STATIC_VM_STRUCT_ENTRY, @@ -2977,8 +2951,7 @@ VMStructs::init() { CHECK_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY, CHECK_C2_NONSTATIC_VM_STRUCT_ENTRY, CHECK_NO_OP, - CHECK_NO_OP, - CHECK_SENTINEL); + CHECK_NO_OP); VM_TYPES(CHECK_VM_TYPE_ENTRY, CHECK_SINGLE_ARG_VM_TYPE_NO_OP, @@ -2987,8 +2960,7 @@ VMStructs::init() { CHECK_SINGLE_ARG_VM_TYPE_NO_OP, CHECK_C1_TOPLEVEL_VM_TYPE_ENTRY, CHECK_C2_VM_TYPE_ENTRY, - CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY, - CHECK_SENTINEL); + CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY); #ifndef SERIALGC VM_TYPES_PARALLELGC(CHECK_VM_TYPE_ENTRY, @@ -3010,8 +2982,7 @@ VMStructs::init() { CHECK_SINGLE_ARG_VM_TYPE_NO_OP, CHECK_C1_TOPLEVEL_VM_TYPE_ENTRY, CHECK_C2_VM_TYPE_ENTRY, - CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY, - CHECK_SENTINEL); + CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY); VM_TYPES_OS_CPU(CHECK_VM_TYPE_ENTRY, CHECK_SINGLE_ARG_VM_TYPE_NO_OP, @@ -3020,8 +2991,7 @@ VMStructs::init() { CHECK_SINGLE_ARG_VM_TYPE_NO_OP, CHECK_C1_TOPLEVEL_VM_TYPE_ENTRY, CHECK_C2_VM_TYPE_ENTRY, - CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY, - CHECK_SENTINEL); + CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY); // // Split VM_STRUCTS() invocation into two parts to allow MS VC++ 6.0 @@ -3040,53 +3010,49 @@ VMStructs::init() { // Solstice NFS setup. If everyone switches to local workspaces on // Win32, we can put this back in. #ifndef _WINDOWS - debug_only(VM_STRUCTS(ENSURE_FIELD_TYPE_PRESENT, \ - CHECK_NO_OP, \ - CHECK_NO_OP, \ - CHECK_NO_OP, \ - CHECK_NO_OP, \ - CHECK_NO_OP, \ - CHECK_NO_OP, \ - CHECK_NO_OP, \ - CHECK_NO_OP, \ - CHECK_SENTINEL)); - debug_only(VM_STRUCTS(CHECK_NO_OP, \ - ENSURE_FIELD_TYPE_PRESENT, \ - CHECK_NO_OP, \ - ENSURE_FIELD_TYPE_PRESENT, \ - ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT, \ - ENSURE_C1_FIELD_TYPE_PRESENT, \ - ENSURE_C2_FIELD_TYPE_PRESENT, \ - CHECK_NO_OP, \ - CHECK_NO_OP, \ - CHECK_SENTINEL)); + debug_only(VM_STRUCTS(ENSURE_FIELD_TYPE_PRESENT, + CHECK_NO_OP, + CHECK_NO_OP, + CHECK_NO_OP, + CHECK_NO_OP, + CHECK_NO_OP, + CHECK_NO_OP, + CHECK_NO_OP, + CHECK_NO_OP)); + debug_only(VM_STRUCTS(CHECK_NO_OP, + ENSURE_FIELD_TYPE_PRESENT, + CHECK_NO_OP, + ENSURE_FIELD_TYPE_PRESENT, + ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT, + ENSURE_C1_FIELD_TYPE_PRESENT, + ENSURE_C2_FIELD_TYPE_PRESENT, + CHECK_NO_OP, + CHECK_NO_OP)); #ifndef SERIALGC - debug_only(VM_STRUCTS_PARALLELGC(ENSURE_FIELD_TYPE_PRESENT, \ + debug_only(VM_STRUCTS_PARALLELGC(ENSURE_FIELD_TYPE_PRESENT, ENSURE_FIELD_TYPE_PRESENT)); - debug_only(VM_STRUCTS_CMS(ENSURE_FIELD_TYPE_PRESENT, \ - ENSURE_FIELD_TYPE_PRESENT, \ + debug_only(VM_STRUCTS_CMS(ENSURE_FIELD_TYPE_PRESENT, + ENSURE_FIELD_TYPE_PRESENT, ENSURE_FIELD_TYPE_PRESENT)); - debug_only(VM_STRUCTS_G1(ENSURE_FIELD_TYPE_PRESENT, \ + debug_only(VM_STRUCTS_G1(ENSURE_FIELD_TYPE_PRESENT, ENSURE_FIELD_TYPE_PRESENT)); #endif // SERIALGC - debug_only(VM_STRUCTS_CPU(ENSURE_FIELD_TYPE_PRESENT, \ - ENSURE_FIELD_TYPE_PRESENT, \ - CHECK_NO_OP, \ - ENSURE_FIELD_TYPE_PRESENT, \ - ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT, \ - ENSURE_C2_FIELD_TYPE_PRESENT, \ - CHECK_NO_OP, \ - CHECK_NO_OP, \ - CHECK_SENTINEL)); - debug_only(VM_STRUCTS_OS_CPU(ENSURE_FIELD_TYPE_PRESENT, \ - ENSURE_FIELD_TYPE_PRESENT, \ - CHECK_NO_OP, \ - ENSURE_FIELD_TYPE_PRESENT, \ - ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT, \ - ENSURE_C2_FIELD_TYPE_PRESENT, \ - CHECK_NO_OP, \ - CHECK_NO_OP, \ - CHECK_SENTINEL)); + debug_only(VM_STRUCTS_CPU(ENSURE_FIELD_TYPE_PRESENT, + ENSURE_FIELD_TYPE_PRESENT, + CHECK_NO_OP, + ENSURE_FIELD_TYPE_PRESENT, + ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT, + ENSURE_C2_FIELD_TYPE_PRESENT, + CHECK_NO_OP, + CHECK_NO_OP)); + debug_only(VM_STRUCTS_OS_CPU(ENSURE_FIELD_TYPE_PRESENT, + ENSURE_FIELD_TYPE_PRESENT, + CHECK_NO_OP, + ENSURE_FIELD_TYPE_PRESENT, + ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT, + ENSURE_C2_FIELD_TYPE_PRESENT, + CHECK_NO_OP, + CHECK_NO_OP)); #endif } @@ -3206,6 +3172,30 @@ void vmStructs_init() { #ifndef PRODUCT void VMStructs::test() { + // Make sure last entry in the each array is indeed the correct end marker. + // The reason why these are static is to make sure they are zero initialized. + // Putting them on the stack will leave some garbage in the padding of some fields. + static VMStructEntry struct_last_entry = GENERATE_VM_STRUCT_LAST_ENTRY(); + assert(memcmp(&localHotSpotVMStructs[(sizeof(localHotSpotVMStructs) / sizeof(VMStructEntry)) - 1], + &struct_last_entry, + sizeof(VMStructEntry)) == 0, "Incorrect last entry in localHotSpotVMStructs"); + + static VMTypeEntry type_last_entry = GENERATE_VM_TYPE_LAST_ENTRY(); + assert(memcmp(&localHotSpotVMTypes[sizeof(localHotSpotVMTypes) / sizeof(VMTypeEntry) - 1], + &type_last_entry, + sizeof(VMTypeEntry)) == 0, "Incorrect last entry in localHotSpotVMTypes"); + + static VMIntConstantEntry int_last_entry = GENERATE_VM_INT_CONSTANT_LAST_ENTRY(); + assert(memcmp(&localHotSpotVMIntConstants[sizeof(localHotSpotVMIntConstants) / sizeof(VMIntConstantEntry) - 1], + &int_last_entry, + sizeof(VMIntConstantEntry)) == 0, "Incorrect last entry in localHotSpotVMIntConstants"); + + static VMLongConstantEntry long_last_entry = GENERATE_VM_LONG_CONSTANT_LAST_ENTRY(); + assert(memcmp(&localHotSpotVMLongConstants[sizeof(localHotSpotVMLongConstants) / sizeof(VMLongConstantEntry) - 1], + &long_last_entry, + sizeof(VMLongConstantEntry)) == 0, "Incorrect last entry in localHotSpotVMLongConstants"); + + // Check for duplicate entries in type array for (int i = 0; localHotSpotVMTypes[i].typeName != NULL; i++) { for (int j = i + 1; localHotSpotVMTypes[j].typeName != NULL; j++) { From cac8a55fb2a9eb6c53253cd0daf0223977371f17 Mon Sep 17 00:00:00 2001 From: Jeremy Manson Date: Thu, 10 Jan 2013 21:00:11 -0500 Subject: [PATCH 053/204] 8005921: Memory leaks in vmStructs.cpp Reviewed-by: dholmes, mikael, rasbold --- hotspot/src/share/vm/runtime/vmStructs.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index 958298bf994..09d557cdbf9 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -3112,10 +3112,10 @@ static int recursiveFindType(VMTypeEntry* origtypes, const char* typeName, bool s[len-1] = '\0'; // tty->print_cr("checking \"%s\" for \"%s\"", s, typeName); if (recursiveFindType(origtypes, s, true) == 1) { - delete s; + delete [] s; return 1; } - delete s; + delete [] s; } const char* start = NULL; if (strstr(typeName, "GrowableArray<") == typeName) { @@ -3131,10 +3131,10 @@ static int recursiveFindType(VMTypeEntry* origtypes, const char* typeName, bool s[len-1] = '\0'; // tty->print_cr("checking \"%s\" for \"%s\"", s, typeName); if (recursiveFindType(origtypes, s, true) == 1) { - delete s; + delete [] s; return 1; } - delete s; + delete [] s; } if (strstr(typeName, "const ") == typeName) { const char * s = typeName + strlen("const "); @@ -3148,8 +3148,10 @@ static int recursiveFindType(VMTypeEntry* origtypes, const char* typeName, bool s[len - 6] = '\0'; // tty->print_cr("checking \"%s\" for \"%s\"", s, typeName); if (recursiveFindType(origtypes, s, true) == 1) { + free(s); return 1; } + free(s); } if (!isRecurse) { tty->print_cr("type \"%s\" not found", typeName); From ce51b6ebee9ab3b0051243e8cb9be689b99f65a8 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Thu, 10 Jan 2013 19:36:13 -0800 Subject: [PATCH 054/204] 8004834: Add doclint support into javadoc Reviewed-by: erikj, tbell --- common/makefiles/javadoc/Javadoc.gmk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/makefiles/javadoc/Javadoc.gmk b/common/makefiles/javadoc/Javadoc.gmk index 84f0b5f8494..2d919c05462 100644 --- a/common/makefiles/javadoc/Javadoc.gmk +++ b/common/makefiles/javadoc/Javadoc.gmk @@ -1,4 +1,4 @@ -# Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1997, 2013, 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 @@ -271,6 +271,7 @@ COMMON_JAVADOCFLAGS = \ -quiet \ -use \ -keywords \ + -Xdoclint:none \ $(ADDITIONAL_JAVADOCFLAGS) ifdef OPENJDK From 7518dede81f02eeff80f686d7e5784935b5bc3fd Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Thu, 10 Jan 2013 19:38:57 -0800 Subject: [PATCH 055/204] 8004834: Add doclint support into javadoc Reviewed-by: darcy --- .../formats/html/ConfigurationImpl.java | 47 +++- .../internal/toolkit/Configuration.java | 4 +- .../toolkit/resources/doclets.properties | 2 + .../toolkit/util/MessageRetriever.java | 11 +- .../com/sun/tools/javac/comp/Enter.java | 8 +- .../classes/com/sun/tools/javadoc/DocEnv.java | 43 ++- .../com/sun/tools/javadoc/DocImpl.java | 10 +- .../sun/tools/javadoc/JavadocMemberEnter.java | 6 +- .../com/sun/tools/javadoc/RootDocImpl.java | 13 +- .../com/sun/javadoc/5093723/T5093723.java | 2 +- .../testBadSourceFile/TestBadSourceFile.java | 4 +- .../TestHtmlDefinitionListTag.java | 10 +- .../TestNewLanguageFeatures.java | 4 +- .../javadoc/testReturnTag/TestReturnTag.java | 4 +- .../TestTagInheritence.java | 4 +- .../javadoc/testTagMisuse/TestTagMisuse.java | 4 +- .../javadoc/testValueTag/TestValueTag.java | 3 +- .../TestWarnBadParamNames.java | 4 +- .../javadoc/testWarnings/TestWarnings.java | 6 +- .../test/tools/javadoc/6958836/Test.java | 3 +- .../test/tools/javadoc/6964914/Test.java | 3 +- .../tools/javadoc/6964914/TestStdDoclet.java | 3 +- langtools/test/tools/javadoc/MaxWarns.java | 2 +- langtools/test/tools/javadoc/T6551367.java | 4 +- .../tools/javadoc/doclint/DocLintTest.java | 251 ++++++++++++++++++ 25 files changed, 401 insertions(+), 54 deletions(-) create mode 100644 langtools/test/tools/javadoc/doclint/DocLintTest.java diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java index a6244a0335f..e74c73835d9 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, 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 @@ -33,8 +33,10 @@ import javax.tools.JavaFileManager; import com.sun.javadoc.*; import com.sun.tools.doclets.internal.toolkit.*; import com.sun.tools.doclets.internal.toolkit.util.*; +import com.sun.tools.doclint.DocLint; import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.util.Context; +import com.sun.tools.javadoc.RootDocImpl; /** * Configure the output based on the command line options. @@ -171,6 +173,11 @@ public class ConfigurationImpl extends Configuration { */ public boolean createoverview = false; + /** + * Collected set of doclint options + */ + public Set doclintOpts = new LinkedHashSet(); + /** * Unique Resource Handler for this package. */ @@ -255,6 +262,10 @@ public class ConfigurationImpl extends Configuration { nooverview = true; } else if (opt.equals("-overview")) { overview = true; + } else if (opt.equals("-xdoclint")) { + doclintOpts.add(null); + } else if (opt.startsWith("-xdoclint:")) { + doclintOpts.add(opt.substring(opt.indexOf(":") + 1)); } } if (root.specifiedClasses().length > 0) { @@ -270,6 +281,10 @@ public class ConfigurationImpl extends Configuration { } setCreateOverview(); setTopFile(root); + + if (root instanceof RootDocImpl) { + ((RootDocImpl) root).initDocLint(doclintOpts); + } } /** @@ -303,7 +318,9 @@ public class ConfigurationImpl extends Configuration { option.equals("-serialwarn") || option.equals("-use") || option.equals("-nonavbar") || - option.equals("-nooverview")) { + option.equals("-nooverview") || + option.equals("-xdoclint") || + option.startsWith("-xdoclint:")) { return 1; } else if (option.equals("-help")) { System.out.println(getText("doclet.usage")); @@ -410,6 +427,16 @@ public class ConfigurationImpl extends Configuration { return false; } noindex = true; + } else if (opt.startsWith("-xdoclint:")) { + if (opt.contains("/")) { + reporter.printError(getText("doclet.Option_doclint_no_qualifiers")); + return false; + } + if (!DocLint.isValidOption( + opt.replace("-xdoclint:", DocLint.XMSGS_CUSTOM_PREFIX))) { + reporter.printError(getText("doclet.Option_doclint_invalid_arg")); + return false; + } } } return true; @@ -506,8 +533,8 @@ public class ConfigurationImpl extends Configuration { */ @Override public Locale getLocale() { - if (root instanceof com.sun.tools.javadoc.RootDocImpl) - return ((com.sun.tools.javadoc.RootDocImpl)root).getLocale(); + if (root instanceof RootDocImpl) + return ((RootDocImpl)root).getLocale(); else return Locale.getDefault(); } @@ -518,8 +545,8 @@ public class ConfigurationImpl extends Configuration { @Override public JavaFileManager getFileManager() { if (fileManager == null) { - if (root instanceof com.sun.tools.javadoc.RootDocImpl) - fileManager = ((com.sun.tools.javadoc.RootDocImpl)root).getFileManager(); + if (root instanceof RootDocImpl) + fileManager = ((RootDocImpl) root).getFileManager(); else fileManager = new JavacFileManager(new Context(), false, null); } @@ -527,4 +554,12 @@ public class ConfigurationImpl extends Configuration { } private JavaFileManager fileManager; + + @Override + public boolean showMessage(SourcePosition pos, String key) { + if (root instanceof RootDocImpl) { + return pos == null || ((RootDocImpl) root).showTagMessages(); + } + return true; + } } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java index 13099d24be9..2d869df9556 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -781,4 +781,6 @@ public abstract class Configuration { sourcetab = n; tabSpaces = String.format("%" + n + "s", ""); } + + public abstract boolean showMessage(SourcePosition pos, String key); } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties index f476b1b861f..93223311754 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties @@ -11,6 +11,8 @@ doclet.Class_0_implements_serializable=Class {0} implements Serializable doclet.Class_0_extends_implements_serializable=Class {0} extends {1} implements Serializable doclet.Option_conflict=Option {0} conflicts with {1} doclet.Option_reuse=Option reused: {0} +doclet.Option_doclint_no_qualifiers=Access qualifiers not permitted for -Xdoclint arguments +doclet.Option_doclint_invalid_arg=Invalid argument for -Xdoclint option doclet.exception_encountered= {0} encountered \n\ \twhile attempting to create file: {1} doclet.perform_copy_exception_encountered= {0} encountered while \n\ diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MessageRetriever.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MessageRetriever.java index d761cfebc69..75129c20a3e 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MessageRetriever.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MessageRetriever.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, 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 @@ -60,9 +60,9 @@ public class MessageRetriever { private ResourceBundle messageRB; /** - * Initilize the ResourceBundle with the given resource. + * Initialize the ResourceBundle with the given resource. * - * @param rb the esource bundle to read. + * @param rb the resource bundle to read. */ public MessageRetriever(ResourceBundle rb) { this.configuration = null; @@ -71,7 +71,7 @@ public class MessageRetriever { } /** - * Initilize the ResourceBundle with the given resource. + * Initialize the ResourceBundle with the given resource. * * @param configuration the configuration * @param resourcelocation Resource. @@ -189,7 +189,8 @@ public class MessageRetriever { * @param args arguments to be replaced in the message. */ public void warning(SourcePosition pos, String key, Object... args) { - printWarning(pos, getText(key, args)); + if (configuration.showMessage(pos, key)) + printWarning(pos, getText(key, args)); } /** diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java index ccf7a82badd..1165a151aa2 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -131,7 +131,11 @@ public class Enter extends JCTree.Visitor { predefClassDef = make.ClassDef( make.Modifiers(PUBLIC), - syms.predefClass.name, null, null, null, null); + syms.predefClass.name, + List.nil(), + null, + List.nil(), + List.nil()); predefClassDef.sym = syms.predefClass; todo = Todo.instance(context); fileManager = context.get(JavaFileManager.class); diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java index ba08ae47eaa..0cac65c422a 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, 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 @@ -31,8 +31,10 @@ import java.util.*; import javax.tools.JavaFileManager; import com.sun.javadoc.*; +import com.sun.source.util.JavacTask; import com.sun.source.util.TreePath; -import com.sun.tools.javac.api.JavacTrees; +import com.sun.tools.doclint.DocLint; +import com.sun.tools.javac.api.BasicJavacTask; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Type.ClassType; @@ -105,6 +107,7 @@ public class DocEnv { Types types; JavaFileManager fileManager; Context context; + DocLint doclint; WeakHashMap treePaths = new WeakHashMap(); @@ -400,6 +403,9 @@ public class DocEnv { public void warning(DocImpl doc, String key, String a1) { if (silent) return; + // suppress messages that have (probably) been covered by doclint + if (doclint != null && doc != null && key.startsWith("tag")) + return; messager.warning(doc==null ? null : doc.position(), key, a1); } @@ -732,9 +738,15 @@ public class DocEnv { return p; } - TreePath getTreePath(JCCompilationUnit toplevel, JCTree tree) { - // don't bother to cache paths for classes and members - return new TreePath(getTreePath(toplevel), tree); + TreePath getTreePath(JCCompilationUnit toplevel, JCClassDecl tree) { + TreePath p = treePaths.get(tree); + if (p == null) + treePaths.put(tree, p = new TreePath(getTreePath(toplevel), tree)); + return p; + } + + TreePath getTreePath(JCCompilationUnit toplevel, JCClassDecl cdecl, JCTree tree) { + return new TreePath(getTreePath(toplevel, cdecl), tree); } /** @@ -781,4 +793,25 @@ public class DocEnv { result |= Modifier.VOLATILE; return result; } + + void initDoclint(Collection opts) { + ArrayList doclintOpts = new ArrayList(); + + for (String opt: opts) { + doclintOpts.add(opt == null ? DocLint.XMSGS_OPTION : DocLint.XMSGS_CUSTOM_PREFIX + opt); + } + + if (doclintOpts.size() == 1 + && doclintOpts.get(0).equals(DocLint.XMSGS_CUSTOM_PREFIX + "none")) { + return; + } + + JavacTask t = BasicJavacTask.instance(context); + doclint = new DocLint(); + doclint.init(t, doclintOpts.toArray(new String[doclintOpts.size()]), false); + } + + boolean showTagMessages() { + return (doclint == null); + } } diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/DocImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/DocImpl.java index 12451293c9a..e5b3f6c9980 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/DocImpl.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -126,7 +126,13 @@ public abstract class DocImpl implements Doc, Comparable { */ Comment comment() { if (comment == null) { - comment = new Comment(this, documentation()); + String d = documentation(); + if (env.doclint != null + && treePath != null + && d.equals(getCommentText(treePath))) { + env.doclint.scan(treePath); + } + comment = new Comment(this, d); } return comment; } diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java index 76e93a34367..058d173ebe7 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -72,7 +72,7 @@ public class JavadocMemberEnter extends MemberEnter { super.visitMethodDef(tree); MethodSymbol meth = tree.sym; if (meth == null || meth.kind != Kinds.MTH) return; - TreePath treePath = docenv.getTreePath(env.toplevel, tree); + TreePath treePath = docenv.getTreePath(env.toplevel, env.enclClass, tree); if (meth.isConstructor()) docenv.makeConstructorDoc(meth, treePath); else if (isAnnotationTypeElement(meth)) @@ -90,7 +90,7 @@ public class JavadocMemberEnter extends MemberEnter { if (tree.sym != null && tree.sym.kind == Kinds.VAR && !isParameter(tree.sym)) { - docenv.makeFieldDoc(tree.sym, docenv.getTreePath(env.toplevel, tree)); + docenv.makeFieldDoc(tree.sym, docenv.getTreePath(env.toplevel, env.enclClass, tree)); } } diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/RootDocImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/RootDocImpl.java index f662dd749db..89a086aa8f8 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/RootDocImpl.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/RootDocImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -26,13 +26,14 @@ package com.sun.tools.javadoc; import java.io.IOException; +import java.util.Collection; import java.util.Locale; + import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; import javax.tools.StandardJavaFileManager; import com.sun.javadoc.*; - import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; @@ -375,4 +376,12 @@ public class RootDocImpl extends DocImpl implements RootDoc { public JavaFileManager getFileManager() { return env.fileManager; } + + public void initDocLint(Collection opts) { + env.initDoclint(opts); + } + + public boolean showTagMessages() { + return env.showTagMessages(); + } } diff --git a/langtools/test/com/sun/javadoc/5093723/T5093723.java b/langtools/test/com/sun/javadoc/5093723/T5093723.java index cab8c1d53d6..4fb3f90a821 100644 --- a/langtools/test/com/sun/javadoc/5093723/T5093723.java +++ b/langtools/test/com/sun/javadoc/5093723/T5093723.java @@ -36,7 +36,7 @@ public class T5093723 extends JavadocTester { private static final String BUG_ID = "5093723"; private static final String[] ARGS = new String[] { - "-d", BUG_ID + ".out", "-source", "5", + "-d", BUG_ID + ".out", "-source", "5", "-Xdoclint:none", SRC_DIR + "/DocumentedClass.java", SRC_DIR + "/UndocumentedClass.java" }; diff --git a/langtools/test/com/sun/javadoc/testBadSourceFile/TestBadSourceFile.java b/langtools/test/com/sun/javadoc/testBadSourceFile/TestBadSourceFile.java index 9f928543957..266aafdde1f 100644 --- a/langtools/test/com/sun/javadoc/testBadSourceFile/TestBadSourceFile.java +++ b/langtools/test/com/sun/javadoc/testBadSourceFile/TestBadSourceFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -40,7 +40,7 @@ public class TestBadSourceFile extends JavadocTester { //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, SRC_DIR + FS + "C2.java" + "-Xdoclint:none", "-d", BUG_ID, SRC_DIR + FS + "C2.java" }; //Input for string search tests. diff --git a/langtools/test/com/sun/javadoc/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java b/langtools/test/com/sun/javadoc/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java index 508175a1949..7c403e5b5b0 100644 --- a/langtools/test/com/sun/javadoc/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java +++ b/langtools/test/com/sun/javadoc/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2013, 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 @@ -222,19 +222,19 @@ public class TestHtmlDefinitionListTag extends JavadocTester { private static final String[] ARGS1 = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1"}; + "-Xdoclint:none", "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1"}; private static final String[] ARGS2 = new String[] { - "-d", BUG_ID, "-nocomment", "-sourcepath", SRC_DIR, "pkg1"}; + "-Xdoclint:none", "-d", BUG_ID, "-nocomment", "-sourcepath", SRC_DIR, "pkg1"}; private static final String[] ARGS3 = new String[] { - "-d", BUG_ID, "-nodeprecated", "-sourcepath", SRC_DIR, "pkg1"}; + "-Xdoclint:none", "-d", BUG_ID, "-nodeprecated", "-sourcepath", SRC_DIR, "pkg1"}; private static final String[] ARGS4 = new String[] { - "-d", BUG_ID, "-nocomment", "-nodeprecated", "-sourcepath", SRC_DIR, "pkg1"}; + "-Xdoclint:none", "-d", BUG_ID, "-nocomment", "-nodeprecated", "-sourcepath", SRC_DIR, "pkg1"}; /** * The entry point of the test. diff --git a/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java b/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java index 0ad0d86e84e..cc6694594e4 100644 --- a/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java +++ b/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -40,7 +40,7 @@ public class TestNewLanguageFeatures extends JavadocTester { //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-use", "-source", "1.5", "-sourcepath", SRC_DIR, "pkg", "pkg1", "pkg2" + "-Xdoclint:none", "-d", BUG_ID, "-use", "-source", "1.5", "-sourcepath", SRC_DIR, "pkg", "pkg1", "pkg2" }; //Input for string search tests. diff --git a/langtools/test/com/sun/javadoc/testReturnTag/TestReturnTag.java b/langtools/test/com/sun/javadoc/testReturnTag/TestReturnTag.java index eab8f02acd6..b7319746af3 100644 --- a/langtools/test/com/sun/javadoc/testReturnTag/TestReturnTag.java +++ b/langtools/test/com/sun/javadoc/testReturnTag/TestReturnTag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -39,7 +39,7 @@ public class TestReturnTag extends JavadocTester { //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, SRC_DIR + FS + "TestReturnTag.java" + "-Xdoclint:none", "-d", BUG_ID, "-sourcepath", SRC_DIR, SRC_DIR + FS + "TestReturnTag.java" }; //Input for string search tests. diff --git a/langtools/test/com/sun/javadoc/testTagInheritence/TestTagInheritence.java b/langtools/test/com/sun/javadoc/testTagInheritence/TestTagInheritence.java index ca6f4c0f108..194d10ef118 100644 --- a/langtools/test/com/sun/javadoc/testTagInheritence/TestTagInheritence.java +++ b/langtools/test/com/sun/javadoc/testTagInheritence/TestTagInheritence.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2013, 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 @@ -36,7 +36,7 @@ public class TestTagInheritence extends JavadocTester { private static final String BUG_ID = "4496223-4496270-4618686-4720974-4812240-6253614-6253604"; private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg", "firstSentence", "firstSentence2" + "-Xdoclint:none", "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg", "firstSentence", "firstSentence2" }; /** diff --git a/langtools/test/com/sun/javadoc/testTagMisuse/TestTagMisuse.java b/langtools/test/com/sun/javadoc/testTagMisuse/TestTagMisuse.java index b80c4ca3141..d5f67301b60 100644 --- a/langtools/test/com/sun/javadoc/testTagMisuse/TestTagMisuse.java +++ b/langtools/test/com/sun/javadoc/testTagMisuse/TestTagMisuse.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -42,7 +42,7 @@ public class TestTagMisuse extends JavadocTester { }; private static final String[][] NEGATED_TEST = NO_TEST; private static final String[] ARGS = new String[] { - "-d", BUG_ID, SRC_DIR + FS + "TestTagMisuse.java" + "-Xdoclint:none", "-d", BUG_ID, SRC_DIR + FS + "TestTagMisuse.java" }; /** diff --git a/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java b/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java index 08780aa6acb..f53e6f4f1a5 100644 --- a/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java +++ b/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -41,6 +41,7 @@ public class TestValueTag extends JavadocTester { //Javadoc arguments. private static final String[] ARGS = new String[] { + "-Xdoclint:none", "-d", BUG_ID, "-sourcepath", SRC_DIR, "-tag", "todo", "pkg1", "pkg2" }; diff --git a/langtools/test/com/sun/javadoc/testWarnBadParamNames/TestWarnBadParamNames.java b/langtools/test/com/sun/javadoc/testWarnBadParamNames/TestWarnBadParamNames.java index de23e99862f..1d58351cff0 100644 --- a/langtools/test/com/sun/javadoc/testWarnBadParamNames/TestWarnBadParamNames.java +++ b/langtools/test/com/sun/javadoc/testWarnBadParamNames/TestWarnBadParamNames.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2013, 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 @@ -43,7 +43,7 @@ public class TestWarnBadParamNames extends JavadocTester { }; private static final String[][] NEGATED_TEST = NO_TEST; private static final String[] ARGS = new String[] { - "-d", BUG_ID, SRC_DIR + FS + "C.java" + "-Xdoclint:none", "-d", BUG_ID, SRC_DIR + FS + "C.java" }; /** diff --git a/langtools/test/com/sun/javadoc/testWarnings/TestWarnings.java b/langtools/test/com/sun/javadoc/testWarnings/TestWarnings.java index bf21f3f0d8f..d5f697a213e 100644 --- a/langtools/test/com/sun/javadoc/testWarnings/TestWarnings.java +++ b/langtools/test/com/sun/javadoc/testWarnings/TestWarnings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2013, 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 @@ -43,11 +43,11 @@ public class TestWarnings extends JavadocTester { //Javadoc arguments. private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg" + "-Xdoclint:none", "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg" }; private static final String[] ARGS2 = new String[] { - "-d", BUG_ID, "-private", "-sourcepath", SRC_DIR, "pkg" + "-Xdoclint:none", "-d", BUG_ID, "-private", "-sourcepath", SRC_DIR, "pkg" }; //Input for string search tests. diff --git a/langtools/test/tools/javadoc/6958836/Test.java b/langtools/test/tools/javadoc/6958836/Test.java index 75222700a98..41746f71347 100644 --- a/langtools/test/tools/javadoc/6958836/Test.java +++ b/langtools/test/tools/javadoc/6958836/Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, 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 @@ -61,6 +61,7 @@ public class Test { // Force en_US locale in lieu of something like -XDrawDiagnostics. // For some reason, this must be the first option when used. opts.addAll(list("-locale", "en_US")); + opts.add("-Xdoclint:none"); opts.addAll(list("-classpath", System.getProperty("test.src"))); opts.addAll(list("-d", testOutDir.getPath())); opts.addAll(testOpts); diff --git a/langtools/test/tools/javadoc/6964914/Test.java b/langtools/test/tools/javadoc/6964914/Test.java index 92362afc1f7..751f29572e9 100644 --- a/langtools/test/tools/javadoc/6964914/Test.java +++ b/langtools/test/tools/javadoc/6964914/Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, 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 @@ -45,6 +45,7 @@ public class Test { void javadoc(String path, String expect) { File testSrc = new File(System.getProperty("test.src")); String[] args = { + "-Xdoclint:none", "-source", "1.4", // enables certain Parser warnings "-bootclasspath", System.getProperty("sun.boot.class.path"), "-classpath", ".", diff --git a/langtools/test/tools/javadoc/6964914/TestStdDoclet.java b/langtools/test/tools/javadoc/6964914/TestStdDoclet.java index 9714557571c..ce6a39f77c9 100644 --- a/langtools/test/tools/javadoc/6964914/TestStdDoclet.java +++ b/langtools/test/tools/javadoc/6964914/TestStdDoclet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, 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 @@ -57,6 +57,7 @@ public class TestStdDoclet { Process p = new ProcessBuilder() .command(javadoc.getPath(), "-J-Xbootclasspath:" + System.getProperty("sun.boot.class.path"), + "-Xdoclint:none", "-package", new File(testSrc, thisClassName + ".java").getPath()) .redirectErrorStream(true) diff --git a/langtools/test/tools/javadoc/MaxWarns.java b/langtools/test/tools/javadoc/MaxWarns.java index 9cd3b381c01..93b870f62d3 100644 --- a/langtools/test/tools/javadoc/MaxWarns.java +++ b/langtools/test/tools/javadoc/MaxWarns.java @@ -74,7 +74,7 @@ public class MaxWarns { String javadoc(File f) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); - String[] args = { "-d", "api", f.getPath() }; + String[] args = { "-Xdoclint:none", "-d", "api", f.getPath() }; int rc = com.sun.tools.javadoc.Main.execute("javadoc", pw, pw, pw, com.sun.tools.doclets.standard.Standard.class.getName(), args); pw.flush(); diff --git a/langtools/test/tools/javadoc/T6551367.java b/langtools/test/tools/javadoc/T6551367.java index 04e6bdc1bde..f82e7caa633 100644 --- a/langtools/test/tools/javadoc/T6551367.java +++ b/langtools/test/tools/javadoc/T6551367.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, 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 @@ -46,7 +46,7 @@ public class T6551367 extends com.sun.tools.doclets.standard.Standard { File source = new File(testSrc, file); int rc = execute("javadoc", "T6551367", T6551367.class.getClassLoader(), - new String[]{source.getPath(), "-d", destDir.getAbsolutePath()}); + new String[]{"-Xdoclint:none", source.getPath(), "-d", destDir.getAbsolutePath()}); if (rc != 0) throw new Error("unexpected exit from javadoc: " + rc); } diff --git a/langtools/test/tools/javadoc/doclint/DocLintTest.java b/langtools/test/tools/javadoc/doclint/DocLintTest.java new file mode 100644 index 00000000000..22557fa1f1f --- /dev/null +++ b/langtools/test/tools/javadoc/doclint/DocLintTest.java @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2012, 2013, 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. + */ + +/* + * @test + * @bug 8004834 + * @summary Add doclint support into javadoc + */ + +import java.io.File; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.net.URI; +import java.util.Arrays; +import java.util.Collections; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.tools.Diagnostic; +import javax.tools.DocumentationTool; +import javax.tools.DocumentationTool.DocumentationTask; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.StandardLocation; +import javax.tools.ToolProvider; +import static javax.tools.Diagnostic.Kind.*; + +import com.sun.tools.javac.main.Main; + +public class DocLintTest { + public static void main(String... args) throws Exception { + new DocLintTest().run(); + } + + DocumentationTool javadoc; + StandardJavaFileManager fm; + JavaFileObject file; + + final String code = + /* 01 */ "/** Class comment. */\n" + + /* 02 */ "public class Test {\n" + + /* 03 */ " /** Method comment. */\n" + + /* 04 */ " public void method() { }\n" + + /* 05 */ "\n" + + /* 06 */ " /** Syntax < error. */\n" + + /* 07 */ " private void syntaxError() { }\n" + + /* 08 */ "\n" + + /* 09 */ " /** @see DoesNotExist */\n" + + /* 10 */ " protected void referenceError() { }\n" + + /* 11 */ "\n" + + /* 12 */ " /** @return */\n" + + /* 13 */ " public int emptyReturn() { return 0; }\n" + + /* 14 */ "}\n"; + + private final String rawDiags = "-XDrawDiagnostics"; + + private enum Message { + // doclint messages + DL_ERR6(ERROR, "Test.java:6:16: compiler.err.proc.messager: malformed HTML"), + DL_ERR9(ERROR, "Test.java:9:14: compiler.err.proc.messager: reference not found"), + DL_WRN12(WARNING, "Test.java:12:9: compiler.warn.proc.messager: no description for @return"), + + // doclint messages when -XDrawDiagnostics is not in effect + DL_ERR9A(ERROR, "Test.java:9: error: reference not found"), + DL_WRN12A(WARNING, "Test.java:12: warning: no description for @return"), + + // javadoc messages about bad content: these should only appear when doclint is disabled + JD_WRN10(WARNING, "Test.java:10: warning - Tag @see: reference not found: DoesNotExist"), + JD_WRN13(WARNING, "Test.java:13: warning - @return tag has no arguments."), + + // javadoc messages for bad options + OPT_BADARG(ERROR, "javadoc: error - Invalid argument for -Xdoclint option"), + OPT_BADQUAL(ERROR, "javadoc: error - Access qualifiers not permitted for -Xdoclint arguments"); + + final Diagnostic.Kind kind; + final String text; + + static Message get(String text) { + for (Message m: values()) { + if (m.text.equals(text)) + return m; + } + return null; + } + + Message(Diagnostic.Kind kind, String text) { + this.kind = kind; + this.text = text; + } + + @Override + public String toString() { + return "[" + kind + ",\"" + text + "\"]"; + } + } + + void run() throws Exception { + javadoc = ToolProvider.getSystemDocumentationTool(); + fm = javadoc.getStandardFileManager(null, null, null); + fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File("."))); + file = new SimpleJavaFileObject(URI.create("Test.java"), JavaFileObject.Kind.SOURCE) { + @Override + public CharSequence getCharContent(boolean ignoreEncoding) { + return code; + } + }; + + test(Collections.emptyList(), + Main.Result.ERROR, + EnumSet.of(Message.DL_ERR9A, Message.DL_WRN12A)); + + test(Arrays.asList(rawDiags), + Main.Result.ERROR, + EnumSet.of(Message.DL_ERR9, Message.DL_WRN12)); + + test(Arrays.asList("-Xdoclint:none"), + Main.Result.OK, + EnumSet.of(Message.JD_WRN10, Message.JD_WRN13)); + + test(Arrays.asList(rawDiags, "-Xdoclint"), + Main.Result.ERROR, + EnumSet.of(Message.DL_ERR9, Message.DL_WRN12)); + + test(Arrays.asList(rawDiags, "-Xdoclint:all/public"), + Main.Result.ERROR, + EnumSet.of(Message.OPT_BADQUAL)); + + test(Arrays.asList(rawDiags, "-Xdoclint:all", "-public"), + Main.Result.OK, + EnumSet.of(Message.DL_WRN12)); + + test(Arrays.asList(rawDiags, "-Xdoclint:syntax"), + Main.Result.OK, + EnumSet.of(Message.DL_WRN12)); + + test(Arrays.asList(rawDiags, "-Xdoclint:syntax", "-private"), + Main.Result.ERROR, + EnumSet.of(Message.DL_ERR6, Message.DL_WRN12)); + + test(Arrays.asList(rawDiags, "-Xdoclint:reference"), + Main.Result.ERROR, + EnumSet.of(Message.DL_ERR9)); + + test(Arrays.asList(rawDiags, "-Xdoclint:badarg"), + Main.Result.ERROR, + EnumSet.of(Message.OPT_BADARG)); + + if (errors > 0) + throw new Exception(errors + " errors occurred"); + } + + void test(List opts, Main.Result expectResult, Set expectMessages) { + System.err.println("test: " + opts); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + List files = Arrays.asList(file); + try { + DocumentationTask t = javadoc.getTask(pw, fm, null, null, opts, files); + boolean ok = t.call(); + pw.close(); + String out = sw.toString().replaceAll("[\r\n]+", "\n"); + if (!out.isEmpty()) + System.err.println(out); + if (ok && expectResult != Main.Result.OK) { + error("Compilation succeeded unexpectedly"); + } else if (!ok && expectResult != Main.Result.ERROR) { + error("Compilation failed unexpectedly"); + } else + check(out, expectMessages); + } catch (IllegalArgumentException e) { + System.err.println(e); + String expectOut = expectMessages.iterator().next().text; + if (expectResult != Main.Result.CMDERR) + error("unexpected exception caught"); + else if (!e.getMessage().equals(expectOut)) { + error("unexpected exception message: " + + e.getMessage() + + " expected: " + expectOut); + } + } + +// if (errors > 0) +// throw new Error("stop"); + } + + private void check(String out, Set expect) { + Pattern ignore = Pattern.compile("^(Building|Constructing|Generating|Loading|Standard|Starting| ) .*"); + Pattern stats = Pattern.compile("^([1-9]+) (error|warning)(s?)"); + Set found = EnumSet.noneOf(Message.class); + int e = 0, w = 0; + for (String line: out.split("[\r\n]+")) { + if (ignore.matcher(line).matches()) + continue; + + Matcher s = stats.matcher(line); + if (s.matches()) { + int i = Integer.valueOf(s.group(1)); + if (s.group(2).equals("error")) + e++; + else + w++; + continue; + } + + Message m = Message.get(line); + if (m == null) + error("Unexpected line: " + line); + else + found.add(m); + } + for (Message m: expect) { + if (!found.contains(m)) + error("expected message not found: " + m.text); + } + for (Message m: found) { + if (!expect.contains(m)) + error("unexpected message found: " + m.text); + } + } + + void error(String msg) { + System.err.println("Error: " + msg); + errors++; + } + + int errors; +} From 8f7055008085deffd407ec4d004097498cc1ca52 Mon Sep 17 00:00:00 2001 From: David Buck Date: Thu, 10 Jan 2013 20:26:00 -0800 Subject: [PATCH 056/204] 8003147: port fix for BCEL bug 39695 Added support for Local Variable Type Table so that BCEL library can be used to modify methods with generics-related debug data without violating class file format Reviewed-by: lancea --- .../org/apache/bcel/internal/Constants.java | 32 ++-- .../bcel/internal/classfile/Attribute.java | 3 + .../internal/classfile/DescendingVisitor.java | 6 + .../bcel/internal/classfile/EmptyVisitor.java | 1 + .../classfile/LocalVariableTypeTable.java | 146 ++++++++++++++++++ .../bcel/internal/classfile/Visitor.java | 1 + .../bcel/internal/generic/MethodGen.java | 17 ++ 7 files changed, 191 insertions(+), 15 deletions(-) create mode 100644 jaxp/src/com/sun/org/apache/bcel/internal/classfile/LocalVariableTypeTable.java diff --git a/jaxp/src/com/sun/org/apache/bcel/internal/Constants.java b/jaxp/src/com/sun/org/apache/bcel/internal/Constants.java index ac4ae3e3e37..d7fc6bcedf0 100644 --- a/jaxp/src/com/sun/org/apache/bcel/internal/Constants.java +++ b/jaxp/src/com/sun/org/apache/bcel/internal/Constants.java @@ -746,27 +746,29 @@ public interface Constants { /** Attributes and their corresponding names. */ - public static final byte ATTR_UNKNOWN = -1; - public static final byte ATTR_SOURCE_FILE = 0; - public static final byte ATTR_CONSTANT_VALUE = 1; - public static final byte ATTR_CODE = 2; - public static final byte ATTR_EXCEPTIONS = 3; - public static final byte ATTR_LINE_NUMBER_TABLE = 4; - public static final byte ATTR_LOCAL_VARIABLE_TABLE = 5; - public static final byte ATTR_INNER_CLASSES = 6; - public static final byte ATTR_SYNTHETIC = 7; - public static final byte ATTR_DEPRECATED = 8; - public static final byte ATTR_PMG = 9; - public static final byte ATTR_SIGNATURE = 10; - public static final byte ATTR_STACK_MAP = 11; + public static final byte ATTR_UNKNOWN = -1; + public static final byte ATTR_SOURCE_FILE = 0; + public static final byte ATTR_CONSTANT_VALUE = 1; + public static final byte ATTR_CODE = 2; + public static final byte ATTR_EXCEPTIONS = 3; + public static final byte ATTR_LINE_NUMBER_TABLE = 4; + public static final byte ATTR_LOCAL_VARIABLE_TABLE = 5; + public static final byte ATTR_INNER_CLASSES = 6; + public static final byte ATTR_SYNTHETIC = 7; + public static final byte ATTR_DEPRECATED = 8; + public static final byte ATTR_PMG = 9; + public static final byte ATTR_SIGNATURE = 10; + public static final byte ATTR_STACK_MAP = 11; + public static final byte ATTR_LOCAL_VARIABLE_TYPE_TABLE = 12; - public static final short KNOWN_ATTRIBUTES = 12; + public static final short KNOWN_ATTRIBUTES = 13; public static final String[] ATTRIBUTE_NAMES = { "SourceFile", "ConstantValue", "Code", "Exceptions", "LineNumberTable", "LocalVariableTable", "InnerClasses", "Synthetic", "Deprecated", - "PMGClass", "Signature", "StackMap" + "PMGClass", "Signature", "StackMap", + "LocalVariableTypeTable" }; /** Constants used in the StackMap attribute. diff --git a/jaxp/src/com/sun/org/apache/bcel/internal/classfile/Attribute.java b/jaxp/src/com/sun/org/apache/bcel/internal/classfile/Attribute.java index a391d4d639a..204bb2506bb 100644 --- a/jaxp/src/com/sun/org/apache/bcel/internal/classfile/Attribute.java +++ b/jaxp/src/com/sun/org/apache/bcel/internal/classfile/Attribute.java @@ -206,6 +206,9 @@ public abstract class Attribute implements Cloneable, Node, Serializable { case Constants.ATTR_LOCAL_VARIABLE_TABLE: return new LocalVariableTable(name_index, length, file, constant_pool); + case Constants.ATTR_LOCAL_VARIABLE_TYPE_TABLE: + return new LocalVariableTypeTable(name_index, length, file, constant_pool); + case Constants.ATTR_INNER_CLASSES: return new InnerClasses(name_index, length, file, constant_pool); diff --git a/jaxp/src/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java b/jaxp/src/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java index c25cce0555b..fe35197652d 100644 --- a/jaxp/src/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java +++ b/jaxp/src/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java @@ -210,6 +210,12 @@ public class DescendingVisitor implements Visitor { stack.pop(); } + public void visitLocalVariableTypeTable(LocalVariableTypeTable obj) { + stack.push(obj); + obj.accept(visitor); + stack.pop(); + } + public void visitStackMap(StackMap table) { stack.push(table); table.accept(visitor); diff --git a/jaxp/src/com/sun/org/apache/bcel/internal/classfile/EmptyVisitor.java b/jaxp/src/com/sun/org/apache/bcel/internal/classfile/EmptyVisitor.java index 88fe11e6a8a..32a1cc144cf 100644 --- a/jaxp/src/com/sun/org/apache/bcel/internal/classfile/EmptyVisitor.java +++ b/jaxp/src/com/sun/org/apache/bcel/internal/classfile/EmptyVisitor.java @@ -98,6 +98,7 @@ public class EmptyVisitor implements Visitor { public void visitLineNumberTable(LineNumberTable obj) {} public void visitLocalVariable(LocalVariable obj) {} public void visitLocalVariableTable(LocalVariableTable obj) {} + public void visitLocalVariableTypeTable(LocalVariableTypeTable obj) {} public void visitMethod(Method obj) {} public void visitSignature(Signature obj) {} public void visitSourceFile(SourceFile obj) {} diff --git a/jaxp/src/com/sun/org/apache/bcel/internal/classfile/LocalVariableTypeTable.java b/jaxp/src/com/sun/org/apache/bcel/internal/classfile/LocalVariableTypeTable.java new file mode 100644 index 00000000000..472f53a2b6f --- /dev/null +++ b/jaxp/src/com/sun/org/apache/bcel/internal/classfile/LocalVariableTypeTable.java @@ -0,0 +1,146 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +// The new table is used when generic types are about... + +//LocalVariableTable_attribute { +// u2 attribute_name_index; +// u4 attribute_length; +// u2 local_variable_table_length; +// { u2 start_pc; +// u2 length; +// u2 name_index; +// u2 descriptor_index; +// u2 index; +// } local_variable_table[local_variable_table_length]; +// } + +//LocalVariableTypeTable_attribute { +// u2 attribute_name_index; +// u4 attribute_length; +// u2 local_variable_type_table_length; +// { +// u2 start_pc; +// u2 length; +// u2 name_index; +// u2 signature_index; +// u2 index; +// } local_variable_type_table[local_variable_type_table_length]; +// } +// J5TODO: Needs some testing ! +public class LocalVariableTypeTable extends Attribute { + private static final long serialVersionUID = -1082157891095177114L; +private int local_variable_type_table_length; // Table of local + private LocalVariable[] local_variable_type_table; // variables + + public LocalVariableTypeTable(LocalVariableTypeTable c) { + this(c.getNameIndex(), c.getLength(), c.getLocalVariableTypeTable(), + c.getConstantPool()); + } + + public LocalVariableTypeTable(int name_index, int length, + LocalVariable[] local_variable_table, + ConstantPool constant_pool) + { + super(Constants.ATTR_LOCAL_VARIABLE_TYPE_TABLE, name_index, length, constant_pool); + setLocalVariableTable(local_variable_table); + } + + LocalVariableTypeTable(int nameIdx, int len, DataInputStream dis,ConstantPool cpool) throws IOException { + this(nameIdx, len, (LocalVariable[])null, cpool); + + local_variable_type_table_length = (dis.readUnsignedShort()); + local_variable_type_table = new LocalVariable[local_variable_type_table_length]; + + for(int i=0; i < local_variable_type_table_length; i++) + local_variable_type_table[i] = new LocalVariable(dis, cpool); + } + + @Override +public void accept(Visitor v) { + v.visitLocalVariableTypeTable(this); + } + + @Override +public final void dump(DataOutputStream file) throws IOException + { + super.dump(file); + file.writeShort(local_variable_type_table_length); + for(int i=0; i < local_variable_type_table_length; i++) + local_variable_type_table[i].dump(file); + } + + public final LocalVariable[] getLocalVariableTypeTable() { + return local_variable_type_table; + } + + public final LocalVariable getLocalVariable(int index) { + for(int i=0; i < local_variable_type_table_length; i++) + if(local_variable_type_table[i].getIndex() == index) + return local_variable_type_table[i]; + + return null; + } + + public final void setLocalVariableTable(LocalVariable[] local_variable_table) + { + this.local_variable_type_table = local_variable_table; + local_variable_type_table_length = (local_variable_table == null)? 0 : + local_variable_table.length; + } + + /** + * @return String representation. + */ + @Override +public final String toString() { + StringBuilder buf = new StringBuilder(); + + for(int i=0; i < local_variable_type_table_length; i++) { + buf.append(local_variable_type_table[i].toString()); + + if(i < local_variable_type_table_length - 1) buf.append('\n'); + } + + return buf.toString(); + } + + /** + * @return deep copy of this attribute + */ + @Override +public Attribute copy(ConstantPool constant_pool) { + LocalVariableTypeTable c = (LocalVariableTypeTable)clone(); + + c.local_variable_type_table = new LocalVariable[local_variable_type_table_length]; + for(int i=0; i < local_variable_type_table_length; i++) + c.local_variable_type_table[i] = local_variable_type_table[i].copy(); + + c.constant_pool = constant_pool; + return c; + } + + public final int getTableLength() { return local_variable_type_table_length; } +} diff --git a/jaxp/src/com/sun/org/apache/bcel/internal/classfile/Visitor.java b/jaxp/src/com/sun/org/apache/bcel/internal/classfile/Visitor.java index a66c7ad2927..a076768700c 100644 --- a/jaxp/src/com/sun/org/apache/bcel/internal/classfile/Visitor.java +++ b/jaxp/src/com/sun/org/apache/bcel/internal/classfile/Visitor.java @@ -94,6 +94,7 @@ public interface Visitor { public void visitLineNumberTable(LineNumberTable obj); public void visitLocalVariable(LocalVariable obj); public void visitLocalVariableTable(LocalVariableTable obj); + public void visitLocalVariableTypeTable(LocalVariableTypeTable obj); public void visitMethod(Method obj); public void visitSignature(Signature obj); public void visitSourceFile(SourceFile obj); diff --git a/jaxp/src/com/sun/org/apache/bcel/internal/generic/MethodGen.java b/jaxp/src/com/sun/org/apache/bcel/internal/generic/MethodGen.java index a58172a9114..34da00768cd 100644 --- a/jaxp/src/com/sun/org/apache/bcel/internal/generic/MethodGen.java +++ b/jaxp/src/com/sun/org/apache/bcel/internal/generic/MethodGen.java @@ -258,6 +258,23 @@ public class MethodGen extends FieldGenOrMethodGen { addLocalVariable(l.getName(), Type.getType(l.getSignature()), l.getIndex(), start, end); } + } else if (a instanceof LocalVariableTypeTable) { + LocalVariable[] lv = ((LocalVariableTypeTable) a).getLocalVariableTypeTable(); + removeLocalVariables(); + for (int k = 0; k < lv.length; k++) { + LocalVariable l = lv[k]; + InstructionHandle start = il.findHandle(l.getStartPC()); + InstructionHandle end = il.findHandle(l.getStartPC() + l.getLength()); + // Repair malformed handles + if (null == start) { + start = il.getStart(); + } + if (null == end) { + end = il.getEnd(); + } + addLocalVariable(l.getName(), Type.getType(l.getSignature()), l + .getIndex(), start, end); + } } else addCodeAttribute(a); } From 95d6d393e96f4cd2a14b45237c7a13d17aa8d5b6 Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Fri, 11 Jan 2013 01:43:10 -0800 Subject: [PATCH 057/204] Added tag hs25-b15 for changeset 8bac833614e0 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 13706d68127..8f3ec3572e1 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -306,3 +306,4 @@ cb8a4e04bc8c104de8a2f67463c7e31232bf8d68 jdk8-b69 e94068d4ff52849c8aa0786a53a59b63d1312a39 jdk8-b70 0847210f85480bf3848dc90bc2ab23c0a4791b55 jdk8-b71 d5cb5830f570d1304ea4b196dde672a291b55f29 jdk8-b72 +1e129851479e4f5df439109fca2c7be1f1613522 hs25-b15 From ad4210a395d66812abeb68f067fc38df5abb0a0a Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Fri, 11 Jan 2013 10:46:59 +0100 Subject: [PATCH 058/204] 8005850: build-infra: Make --enable-openjdk-only really disable custom Reviewed-by: ohair, dholmes --- common/autoconf/configure.ac | 3 + common/autoconf/generated-configure.sh | 587 ++++++++++++------------- common/autoconf/jdk-options.m4 | 60 +-- 3 files changed, 320 insertions(+), 330 deletions(-) diff --git a/common/autoconf/configure.ac b/common/autoconf/configure.ac index 0dc235535ea..0bb0faf0d2f 100644 --- a/common/autoconf/configure.ac +++ b/common/autoconf/configure.ac @@ -83,6 +83,9 @@ PLATFORM_SETUP_OPENJDK_BUILD_AND_TARGET BASIC_SETUP_PATHS BASIC_SETUP_LOGGING +# Check if it's a pure open build or if custom sources are to be used. +JDKOPT_SETUP_OPEN_OR_CUSTOM + # These are needed to be able to create a configuration name (and thus the output directory) JDKOPT_SETUP_JDK_VARIANT JDKOPT_SETUP_JVM_VARIANTS diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index 6a8d834abae..d210623a4a0 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for OpenJDK jdk8. +# Generated by GNU Autoconf 2.67 for OpenJDK jdk8. # # Report bugs to . # @@ -91,7 +91,6 @@ fi IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. -as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -217,18 +216,11 @@ IFS=$as_save_IFS # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. - # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL - case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; - esac - exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : @@ -783,7 +775,6 @@ TEST_IN_BUILD BUILD_HEADLESS SUPPORT_HEADFUL SUPPORT_HEADLESS -SET_OPENJDK BDEPS_FTP BDEPS_UNZIP OS_VERSION_MICRO @@ -822,6 +813,7 @@ JVM_VARIANT_CLIENT JVM_VARIANT_SERVER JVM_VARIANTS JDK_VARIANT +SET_OPENJDK BUILD_LOG_WRAPPER BUILD_LOG_PREVIOUS BUILD_LOG @@ -962,6 +954,7 @@ with_target_bits with_sys_root with_tools_dir with_devkit +enable_openjdk_only with_jdk_variant with_jvm_variants enable_debug @@ -971,7 +964,6 @@ with_builddeps_conf with_builddeps_server with_builddeps_dir with_builddeps_group -enable_openjdk_only enable_headful enable_hotspot_test_in_build with_cacerts_file @@ -1441,7 +1433,7 @@ Try \`$0 --help' for more information" $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac @@ -1657,10 +1649,10 @@ Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-openjdk-only suppress building custom source even if present + [disabled] --enable-debug set the debug level to fastdebug (shorthand for --with-debug-level=fastdebug) [disabled] - --enable-openjdk-only supress building closed source even if present - [disabled] --disable-headful disable building headful support (graphical UI support) [enabled] --enable-hotspot-test-in-build @@ -1866,7 +1858,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF OpenJDK configure jdk8 -generated by GNU Autoconf 2.68 +generated by GNU Autoconf 2.67 Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation @@ -1912,7 +1904,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_compile @@ -1950,7 +1942,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile @@ -1988,7 +1980,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_objc_try_compile @@ -2025,7 +2017,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_cpp @@ -2062,7 +2054,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp @@ -2075,10 +2067,10 @@ fi ac_fn_cxx_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval \${$3+:} false; then : + if eval "test \"\${$3+set}\"" = set; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 @@ -2145,7 +2137,7 @@ $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" @@ -2154,7 +2146,7 @@ eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_cxx_check_header_mongrel @@ -2195,7 +2187,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_try_run @@ -2209,7 +2201,7 @@ ac_fn_cxx_check_header_compile () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2227,7 +2219,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_cxx_check_header_compile @@ -2404,7 +2396,7 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ rm -f conftest.val fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_compute_int @@ -2450,7 +2442,7 @@ fi # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_try_link @@ -2463,7 +2455,7 @@ ac_fn_cxx_check_func () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2518,7 +2510,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_cxx_check_func @@ -2531,7 +2523,7 @@ ac_fn_c_check_header_compile () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2549,7 +2541,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_header_compile cat >config.log <<_ACEOF @@ -2557,7 +2549,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by OpenJDK $as_me jdk8, which was -generated by GNU Autoconf 2.68. Invocation command line was +generated by GNU Autoconf 2.67. Invocation command line was $ $0 $@ @@ -2815,7 +2807,7 @@ $as_echo "$as_me: loading site script $ac_site_file" >&6;} || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } fi done @@ -3444,6 +3436,13 @@ pkgadd_help() { +############################################################################### +# +# Should we build only OpenJDK even if closed sources are present? +# + + + ############################################################################### # @@ -3698,7 +3697,7 @@ fi #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1357690920 +DATE_WHEN_GENERATED=1357897535 ############################################################################### # @@ -3736,7 +3735,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_BASENAME+:} false; then : +if test "${ac_cv_path_BASENAME+set}" = set; then : $as_echo_n "(cached) " >&6 else case $BASENAME in @@ -3795,7 +3794,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_BASH+:} false; then : +if test "${ac_cv_path_BASH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $BASH in @@ -3854,7 +3853,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CAT+:} false; then : +if test "${ac_cv_path_CAT+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CAT in @@ -3913,7 +3912,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CHMOD+:} false; then : +if test "${ac_cv_path_CHMOD+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CHMOD in @@ -3972,7 +3971,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CMP+:} false; then : +if test "${ac_cv_path_CMP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CMP in @@ -4031,7 +4030,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_COMM+:} false; then : +if test "${ac_cv_path_COMM+set}" = set; then : $as_echo_n "(cached) " >&6 else case $COMM in @@ -4090,7 +4089,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CP+:} false; then : +if test "${ac_cv_path_CP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CP in @@ -4149,7 +4148,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CPIO+:} false; then : +if test "${ac_cv_path_CPIO+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CPIO in @@ -4208,7 +4207,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CUT+:} false; then : +if test "${ac_cv_path_CUT+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CUT in @@ -4267,7 +4266,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_DATE+:} false; then : +if test "${ac_cv_path_DATE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $DATE in @@ -4326,7 +4325,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_DIFF+:} false; then : +if test "${ac_cv_path_DIFF+set}" = set; then : $as_echo_n "(cached) " >&6 else case $DIFF in @@ -4385,7 +4384,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_DIRNAME+:} false; then : +if test "${ac_cv_path_DIRNAME+set}" = set; then : $as_echo_n "(cached) " >&6 else case $DIRNAME in @@ -4444,7 +4443,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ECHO+:} false; then : +if test "${ac_cv_path_ECHO+set}" = set; then : $as_echo_n "(cached) " >&6 else case $ECHO in @@ -4503,7 +4502,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_EXPR+:} false; then : +if test "${ac_cv_path_EXPR+set}" = set; then : $as_echo_n "(cached) " >&6 else case $EXPR in @@ -4562,7 +4561,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_FILE+:} false; then : +if test "${ac_cv_path_FILE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $FILE in @@ -4621,7 +4620,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_FIND+:} false; then : +if test "${ac_cv_path_FIND+set}" = set; then : $as_echo_n "(cached) " >&6 else case $FIND in @@ -4680,7 +4679,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_HEAD+:} false; then : +if test "${ac_cv_path_HEAD+set}" = set; then : $as_echo_n "(cached) " >&6 else case $HEAD in @@ -4739,7 +4738,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_LN+:} false; then : +if test "${ac_cv_path_LN+set}" = set; then : $as_echo_n "(cached) " >&6 else case $LN in @@ -4798,7 +4797,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_LS+:} false; then : +if test "${ac_cv_path_LS+set}" = set; then : $as_echo_n "(cached) " >&6 else case $LS in @@ -4857,7 +4856,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_MKDIR+:} false; then : +if test "${ac_cv_path_MKDIR+set}" = set; then : $as_echo_n "(cached) " >&6 else case $MKDIR in @@ -4916,7 +4915,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_MKTEMP+:} false; then : +if test "${ac_cv_path_MKTEMP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $MKTEMP in @@ -4975,7 +4974,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_MV+:} false; then : +if test "${ac_cv_path_MV+set}" = set; then : $as_echo_n "(cached) " >&6 else case $MV in @@ -5034,7 +5033,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_PRINTF+:} false; then : +if test "${ac_cv_path_PRINTF+set}" = set; then : $as_echo_n "(cached) " >&6 else case $PRINTF in @@ -5093,7 +5092,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_THEPWDCMD+:} false; then : +if test "${ac_cv_path_THEPWDCMD+set}" = set; then : $as_echo_n "(cached) " >&6 else case $THEPWDCMD in @@ -5152,7 +5151,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_RM+:} false; then : +if test "${ac_cv_path_RM+set}" = set; then : $as_echo_n "(cached) " >&6 else case $RM in @@ -5211,7 +5210,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_SH+:} false; then : +if test "${ac_cv_path_SH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $SH in @@ -5270,7 +5269,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_SORT+:} false; then : +if test "${ac_cv_path_SORT+set}" = set; then : $as_echo_n "(cached) " >&6 else case $SORT in @@ -5329,7 +5328,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_TAIL+:} false; then : +if test "${ac_cv_path_TAIL+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TAIL in @@ -5388,7 +5387,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_TAR+:} false; then : +if test "${ac_cv_path_TAR+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TAR in @@ -5447,7 +5446,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_TEE+:} false; then : +if test "${ac_cv_path_TEE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TEE in @@ -5506,7 +5505,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_TOUCH+:} false; then : +if test "${ac_cv_path_TOUCH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TOUCH in @@ -5565,7 +5564,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_TR+:} false; then : +if test "${ac_cv_path_TR+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TR in @@ -5624,7 +5623,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_UNAME+:} false; then : +if test "${ac_cv_path_UNAME+set}" = set; then : $as_echo_n "(cached) " >&6 else case $UNAME in @@ -5683,7 +5682,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_UNIQ+:} false; then : +if test "${ac_cv_path_UNIQ+set}" = set; then : $as_echo_n "(cached) " >&6 else case $UNIQ in @@ -5742,7 +5741,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_WC+:} false; then : +if test "${ac_cv_path_WC+set}" = set; then : $as_echo_n "(cached) " >&6 else case $WC in @@ -5801,7 +5800,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_WHICH+:} false; then : +if test "${ac_cv_path_WHICH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $WHICH in @@ -5860,7 +5859,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_XARGS+:} false; then : +if test "${ac_cv_path_XARGS+set}" = set; then : $as_echo_n "(cached) " >&6 else case $XARGS in @@ -5920,7 +5919,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AWK+:} false; then : +if test "${ac_cv_prog_AWK+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then @@ -5970,7 +5969,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if ${ac_cv_path_GREP+:} false; then : +if test "${ac_cv_path_GREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then @@ -6045,7 +6044,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } -if ${ac_cv_path_EGREP+:} false; then : +if test "${ac_cv_path_EGREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 @@ -6124,7 +6123,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } -if ${ac_cv_path_FGREP+:} false; then : +if test "${ac_cv_path_FGREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 @@ -6203,7 +6202,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } -if ${ac_cv_path_SED+:} false; then : +if test "${ac_cv_path_SED+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ @@ -6289,7 +6288,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_NAWK+:} false; then : +if test "${ac_cv_path_NAWK+set}" = set; then : $as_echo_n "(cached) " >&6 else case $NAWK in @@ -6349,7 +6348,7 @@ RM="$RM -f" set dummy cygpath; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CYGPATH+:} false; then : +if test "${ac_cv_path_CYGPATH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CYGPATH in @@ -6389,7 +6388,7 @@ fi set dummy readlink; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_READLINK+:} false; then : +if test "${ac_cv_path_READLINK+set}" = set; then : $as_echo_n "(cached) " >&6 else case $READLINK in @@ -6429,7 +6428,7 @@ fi set dummy df; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_DF+:} false; then : +if test "${ac_cv_path_DF+set}" = set; then : $as_echo_n "(cached) " >&6 else case $DF in @@ -6469,7 +6468,7 @@ fi set dummy SetFile; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_SETFILE+:} false; then : +if test "${ac_cv_path_SETFILE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $SETFILE in @@ -6515,7 +6514,7 @@ $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } -if ${ac_cv_build+:} false; then : +if test "${ac_cv_build+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias @@ -6531,7 +6530,7 @@ fi $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; -*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5 ;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' @@ -6549,7 +6548,7 @@ case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } -if ${ac_cv_host+:} false; then : +if test "${ac_cv_host+set}" = set; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then @@ -6564,7 +6563,7 @@ fi $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; -*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5 ;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' @@ -6582,7 +6581,7 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 $as_echo_n "checking target system type... " >&6; } -if ${ac_cv_target+:} false; then : +if test "${ac_cv_target+set}" = set; then : $as_echo_n "(cached) " >&6 else if test "x$target_alias" = x; then @@ -6597,7 +6596,7 @@ fi $as_echo "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; -*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; +*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5 ;; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' @@ -7488,6 +7487,53 @@ BUILD_LOG_WRAPPER='$(BASH) $(SRC_ROOT)/common/bin/logger.sh $(BUILD_LOG)' +# Check if it's a pure open build or if custom sources are to be used. + + # Check whether --enable-openjdk-only was given. +if test "${enable_openjdk_only+set}" = set; then : + enableval=$enable_openjdk_only; +else + enable_openjdk_only="no" +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for presence of closed sources" >&5 +$as_echo_n "checking for presence of closed sources... " >&6; } + if test -d "$SRC_ROOT/jdk/src/closed"; then + CLOSED_SOURCE_PRESENT=yes + else + CLOSED_SOURCE_PRESENT=no + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CLOSED_SOURCE_PRESENT" >&5 +$as_echo "$CLOSED_SOURCE_PRESENT" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if closed source is suppressed (openjdk-only)" >&5 +$as_echo_n "checking if closed source is suppressed (openjdk-only)... " >&6; } + SUPPRESS_CLOSED_SOURCE="$enable_openjdk_only" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SUPPRESS_CLOSED_SOURCE" >&5 +$as_echo "$SUPPRESS_CLOSED_SOURCE" >&6; } + + if test "x$CLOSED_SOURCE_PRESENT" = xno; then + OPENJDK=true + if test "x$SUPPRESS_CLOSED_SOURCE" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No closed source present, --enable-openjdk-only makes no sense" >&5 +$as_echo "$as_me: WARNING: No closed source present, --enable-openjdk-only makes no sense" >&2;} + fi + else + if test "x$SUPPRESS_CLOSED_SOURCE" = "xyes"; then + OPENJDK=true + else + OPENJDK=false + fi + fi + + if test "x$OPENJDK" = "xtrue"; then + SET_OPENJDK="OPENJDK=true" + fi + + + + # These are needed to be able to create a configuration name (and thus the output directory) ############################################################################### @@ -8016,7 +8062,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_PKGHANDLER+:} false; then : +if test "${ac_cv_prog_PKGHANDLER+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$PKGHANDLER"; then @@ -8381,7 +8427,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CHECK_GMAKE+:} false; then : +if test "${ac_cv_path_CHECK_GMAKE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CHECK_GMAKE in @@ -8735,7 +8781,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CHECK_MAKE+:} false; then : +if test "${ac_cv_path_CHECK_MAKE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CHECK_MAKE in @@ -9094,7 +9140,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CHECK_TOOLSDIR_GMAKE+:} false; then : +if test "${ac_cv_path_CHECK_TOOLSDIR_GMAKE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CHECK_TOOLSDIR_GMAKE in @@ -9447,7 +9493,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CHECK_TOOLSDIR_MAKE+:} false; then : +if test "${ac_cv_path_CHECK_TOOLSDIR_MAKE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CHECK_TOOLSDIR_MAKE in @@ -9843,7 +9889,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_UNZIP+:} false; then : +if test "${ac_cv_path_UNZIP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $UNZIP in @@ -9902,7 +9948,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ZIP+:} false; then : +if test "${ac_cv_path_ZIP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $ZIP in @@ -9961,7 +10007,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} set dummy ldd; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_LDD+:} false; then : +if test "${ac_cv_path_LDD+set}" = set; then : $as_echo_n "(cached) " >&6 else case $LDD in @@ -10007,7 +10053,7 @@ fi set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_OTOOL+:} false; then : +if test "${ac_cv_path_OTOOL+set}" = set; then : $as_echo_n "(cached) " >&6 else case $OTOOL in @@ -10052,7 +10098,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_READELF+:} false; then : +if test "${ac_cv_path_READELF+set}" = set; then : $as_echo_n "(cached) " >&6 else case $READELF in @@ -10095,7 +10141,7 @@ done set dummy hg; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_HG+:} false; then : +if test "${ac_cv_path_HG+set}" = set; then : $as_echo_n "(cached) " >&6 else case $HG in @@ -10135,7 +10181,7 @@ fi set dummy stat; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_STAT+:} false; then : +if test "${ac_cv_path_STAT+set}" = set; then : $as_echo_n "(cached) " >&6 else case $STAT in @@ -10175,7 +10221,7 @@ fi set dummy time; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_TIME+:} false; then : +if test "${ac_cv_path_TIME+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TIME in @@ -10220,7 +10266,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_COMM+:} false; then : +if test "${ac_cv_path_COMM+set}" = set; then : $as_echo_n "(cached) " >&6 else case $COMM in @@ -10284,7 +10330,7 @@ if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_PKG_CONFIG+:} false; then : +if test "${ac_cv_path_PKG_CONFIG+set}" = set; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in @@ -10327,7 +10373,7 @@ if test -z "$ac_cv_path_PKG_CONFIG"; then set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : +if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in @@ -10500,7 +10546,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_BDEPS_UNZIP+:} false; then : +if test "${ac_cv_prog_BDEPS_UNZIP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$BDEPS_UNZIP"; then @@ -10546,7 +10592,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_BDEPS_FTP+:} false; then : +if test "${ac_cv_prog_BDEPS_FTP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$BDEPS_FTP"; then @@ -10593,54 +10639,6 @@ done # We need build & target for this. -############################################################################### -# -# Should we build only OpenJDK even if closed sources are present? -# -# Check whether --enable-openjdk-only was given. -if test "${enable_openjdk_only+set}" = set; then : - enableval=$enable_openjdk_only; -else - enable_openjdk_only="no" -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for presence of closed sources" >&5 -$as_echo_n "checking for presence of closed sources... " >&6; } -if test -d "$SRC_ROOT/jdk/src/closed"; then - CLOSED_SOURCE_PRESENT=yes -else - CLOSED_SOURCE_PRESENT=no -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CLOSED_SOURCE_PRESENT" >&5 -$as_echo "$CLOSED_SOURCE_PRESENT" >&6; } - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if closed source is supressed (openjdk-only)" >&5 -$as_echo_n "checking if closed source is supressed (openjdk-only)... " >&6; } -SUPRESS_CLOSED_SOURCE="$enable_openjdk_only" -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SUPRESS_CLOSED_SOURCE" >&5 -$as_echo "$SUPRESS_CLOSED_SOURCE" >&6; } - -if test "x$CLOSED_SOURCE_PRESENT" = xno; then - OPENJDK=true - if test "x$SUPRESS_CLOSED_SOURCE" = "xyes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No closed source present, --enable-openjdk-only makes no sense" >&5 -$as_echo "$as_me: WARNING: No closed source present, --enable-openjdk-only makes no sense" >&2;} - fi -else - if test "x$SUPRESS_CLOSED_SOURCE" = "xyes"; then - OPENJDK=true - else - OPENJDK=false - fi -fi - -if test "x$OPENJDK" = "xtrue"; then - SET_OPENJDK="OPENJDK=true" -fi - - - ############################################################################### # # Should we build a JDK/JVM with headful support (ie a graphical ui)? @@ -11860,7 +11858,7 @@ $as_echo "$BOOT_JDK_VERSION" >&6; } set dummy javac; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_JAVAC_CHECK+:} false; then : +if test "${ac_cv_path_JAVAC_CHECK+set}" = set; then : $as_echo_n "(cached) " >&6 else case $JAVAC_CHECK in @@ -11900,7 +11898,7 @@ fi set dummy java; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_JAVA_CHECK+:} false; then : +if test "${ac_cv_path_JAVA_CHECK+set}" = set; then : $as_echo_n "(cached) " >&6 else case $JAVA_CHECK in @@ -15959,7 +15957,7 @@ if test "x$OPENJDK_TARGET_OS" = "xwindows"; then set dummy link; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CYGWIN_LINK+:} false; then : +if test "${ac_cv_path_CYGWIN_LINK+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CYGWIN_LINK in @@ -16948,7 +16946,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_BUILD_CC+:} false; then : +if test "${ac_cv_path_BUILD_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else case $BUILD_CC in @@ -17259,7 +17257,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_BUILD_CXX+:} false; then : +if test "${ac_cv_path_BUILD_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else case $BUILD_CXX in @@ -17568,7 +17566,7 @@ $as_echo "$as_me: Rewriting BUILD_CXX to \"$new_complete\"" >&6;} set dummy ld; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_BUILD_LD+:} false; then : +if test "${ac_cv_path_BUILD_LD+set}" = set; then : $as_echo_n "(cached) " >&6 else case $BUILD_LD in @@ -18080,7 +18078,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_TOOLS_DIR_CC+:} false; then : +if test "${ac_cv_path_TOOLS_DIR_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TOOLS_DIR_CC in @@ -18132,7 +18130,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_POTENTIAL_CC+:} false; then : +if test "${ac_cv_path_POTENTIAL_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else case $POTENTIAL_CC in @@ -18545,7 +18543,7 @@ $as_echo "yes, trying to find proper $COMPILER_NAME compiler" >&6; } set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_PROPER_COMPILER_CC+:} false; then : +if test "${ac_cv_prog_PROPER_COMPILER_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$PROPER_COMPILER_CC"; then @@ -18589,7 +18587,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_PROPER_COMPILER_CC+:} false; then : +if test "${ac_cv_prog_ac_ct_PROPER_COMPILER_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_PROPER_COMPILER_CC"; then @@ -19039,7 +19037,7 @@ if test -n "$ac_tool_prefix"; then set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : +if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then @@ -19083,7 +19081,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then @@ -19136,7 +19134,7 @@ fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 @@ -19251,7 +19249,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } @@ -19294,7 +19292,7 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 @@ -19353,7 +19351,7 @@ $as_echo "$ac_try_echo"; } >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } fi fi fi @@ -19364,7 +19362,7 @@ rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } -if ${ac_cv_objext+:} false; then : +if test "${ac_cv_objext+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -19405,7 +19403,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi @@ -19415,7 +19413,7 @@ OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : +if test "${ac_cv_c_compiler_gnu+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -19452,7 +19450,7 @@ ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : +if test "${ac_cv_prog_cc_g+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag @@ -19530,7 +19528,7 @@ else fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : +if test "${ac_cv_prog_cc_c89+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no @@ -19649,7 +19647,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_TOOLS_DIR_CXX+:} false; then : +if test "${ac_cv_path_TOOLS_DIR_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TOOLS_DIR_CXX in @@ -19701,7 +19699,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_POTENTIAL_CXX+:} false; then : +if test "${ac_cv_path_POTENTIAL_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else case $POTENTIAL_CXX in @@ -20114,7 +20112,7 @@ $as_echo "yes, trying to find proper $COMPILER_NAME compiler" >&6; } set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_PROPER_COMPILER_CXX+:} false; then : +if test "${ac_cv_prog_PROPER_COMPILER_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$PROPER_COMPILER_CXX"; then @@ -20158,7 +20156,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_PROPER_COMPILER_CXX+:} false; then : +if test "${ac_cv_prog_ac_ct_PROPER_COMPILER_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_PROPER_COMPILER_CXX"; then @@ -20612,7 +20610,7 @@ if test -z "$CXX"; then set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CXX+:} false; then : +if test "${ac_cv_prog_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then @@ -20656,7 +20654,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CXX+:} false; then : +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then @@ -20734,7 +20732,7 @@ done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } -if ${ac_cv_cxx_compiler_gnu+:} false; then : +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -20771,7 +20769,7 @@ ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } -if ${ac_cv_prog_cxx_g+:} false; then : +if test "${ac_cv_prog_cxx_g+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag @@ -20869,7 +20867,7 @@ if test -n "$ac_tool_prefix"; then set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OBJC+:} false; then : +if test "${ac_cv_prog_OBJC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJC"; then @@ -20913,7 +20911,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OBJC+:} false; then : +if test "${ac_cv_prog_ac_ct_OBJC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJC"; then @@ -20989,7 +20987,7 @@ done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU Objective C compiler" >&5 $as_echo_n "checking whether we are using the GNU Objective C compiler... " >&6; } -if ${ac_cv_objc_compiler_gnu+:} false; then : +if test "${ac_cv_objc_compiler_gnu+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -21026,7 +21024,7 @@ ac_test_OBJCFLAGS=${OBJCFLAGS+set} ac_save_OBJCFLAGS=$OBJCFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $OBJC accepts -g" >&5 $as_echo_n "checking whether $OBJC accepts -g... " >&6; } -if ${ac_cv_prog_objc_g+:} false; then : +if test "${ac_cv_prog_objc_g+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_save_objc_werror_flag=$ac_objc_werror_flag @@ -21402,7 +21400,7 @@ if test "x$OPENJDK_TARGET_OS" != xwindows; then set dummy ${ac_tool_prefix}ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AR+:} false; then : +if test "${ac_cv_prog_AR+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then @@ -21442,7 +21440,7 @@ if test -z "$ac_cv_prog_AR"; then set dummy ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_AR+:} false; then : +if test "${ac_cv_prog_ac_ct_AR+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then @@ -21784,7 +21782,7 @@ if test "x$OPENJDK_TARGET_OS" = xwindows; then : set dummy link; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_WINLD+:} false; then : +if test "${ac_cv_prog_WINLD+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$WINLD"; then @@ -22123,7 +22121,7 @@ $as_echo "yes" >&6; } set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_MT+:} false; then : +if test "${ac_cv_prog_MT+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$MT"; then @@ -22444,7 +22442,7 @@ $as_echo "$as_me: Rewriting MT to \"$new_complete\"" >&6;} set dummy rc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_RC+:} false; then : +if test "${ac_cv_prog_RC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$RC"; then @@ -22835,7 +22833,7 @@ fi set dummy lib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_WINAR+:} false; then : +if test "${ac_cv_prog_WINAR+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$WINAR"; then @@ -23141,7 +23139,7 @@ $as_echo "$as_me: Rewriting WINAR to \"$new_complete\"" >&6;} set dummy dumpbin; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DUMPBIN+:} false; then : +if test "${ac_cv_prog_DUMPBIN+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then @@ -23460,7 +23458,7 @@ if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : + if test "${ac_cv_prog_CPP+set}" = set; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded @@ -23576,7 +23574,7 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } fi ac_ext=cpp @@ -23860,7 +23858,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then - if ${ac_cv_prog_CXXCPP+:} false; then : + if test "${ac_cv_prog_CXXCPP+set}" = set; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded @@ -23976,7 +23974,7 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } fi ac_ext=cpp @@ -24278,7 +24276,7 @@ if test "x$OPENJDK_TARGET_OS" = xsolaris; then set dummy as; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_AS+:} false; then : +if test "${ac_cv_path_AS+set}" = set; then : $as_echo_n "(cached) " >&6 else case $AS in @@ -24592,7 +24590,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_NM+:} false; then : +if test "${ac_cv_path_NM+set}" = set; then : $as_echo_n "(cached) " >&6 else case $NM in @@ -24901,7 +24899,7 @@ $as_echo "$as_me: Rewriting NM to \"$new_complete\"" >&6;} set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_STRIP+:} false; then : +if test "${ac_cv_path_STRIP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $STRIP in @@ -25207,7 +25205,7 @@ $as_echo "$as_me: Rewriting STRIP to \"$new_complete\"" >&6;} set dummy mcs; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_MCS+:} false; then : +if test "${ac_cv_path_MCS+set}" = set; then : $as_echo_n "(cached) " >&6 else case $MCS in @@ -25515,7 +25513,7 @@ elif test "x$OPENJDK_TARGET_OS" != xwindows; then set dummy ${ac_tool_prefix}nm; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_NM+:} false; then : +if test "${ac_cv_prog_NM+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then @@ -25555,7 +25553,7 @@ if test -z "$ac_cv_prog_NM"; then set dummy nm; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_NM+:} false; then : +if test "${ac_cv_prog_ac_ct_NM+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NM"; then @@ -25873,7 +25871,7 @@ $as_echo "$as_me: Rewriting NM to \"$new_complete\"" >&6;} set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_STRIP+:} false; then : +if test "${ac_cv_prog_STRIP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then @@ -25913,7 +25911,7 @@ if test -z "$ac_cv_prog_STRIP"; then set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_STRIP+:} false; then : +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then @@ -26238,7 +26236,7 @@ if test "x$OPENJDK_TARGET_OS" = xsolaris || test "x$OPENJDK_TARGET_OS" = xlinux; set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OBJCOPY+:} false; then : +if test "${ac_cv_prog_OBJCOPY+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJCOPY"; then @@ -26282,7 +26280,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OBJCOPY+:} false; then : +if test "${ac_cv_prog_ac_ct_OBJCOPY+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJCOPY"; then @@ -26609,7 +26607,7 @@ if test -n "$ac_tool_prefix"; then set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OBJDUMP+:} false; then : +if test "${ac_cv_prog_OBJDUMP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then @@ -26653,7 +26651,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : +if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then @@ -26977,7 +26975,7 @@ if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_LIPO+:} false; then : +if test "${ac_cv_path_LIPO+set}" = set; then : $as_echo_n "(cached) " >&6 else case $LIPO in @@ -27292,7 +27290,7 @@ PATH="$OLD_PATH" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : +if test "${ac_cv_header_stdc+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -27468,7 +27466,7 @@ fi for ac_header in stdio.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "stdio.h" "ac_cv_header_stdio_h" "$ac_includes_default" -if test "x$ac_cv_header_stdio_h" = xyes; then : +if test "x$ac_cv_header_stdio_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDIO_H 1 _ACEOF @@ -27497,7 +27495,7 @@ done # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int *" >&5 $as_echo_n "checking size of int *... " >&6; } -if ${ac_cv_sizeof_int_p+:} false; then : +if test "${ac_cv_sizeof_int_p+set}" = set; then : $as_echo_n "(cached) " >&6 else if ac_fn_cxx_compute_int "$LINENO" "(long int) (sizeof (int *))" "ac_cv_sizeof_int_p" "$ac_includes_default"; then : @@ -27507,7 +27505,7 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (int *) -See \`config.log' for more details" "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } else ac_cv_sizeof_int_p=0 fi @@ -27554,7 +27552,7 @@ $as_echo "$OPENJDK_TARGET_CPU_BITS bits" >&6; } # { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 $as_echo_n "checking whether byte ordering is bigendian... " >&6; } -if ${ac_cv_c_bigendian+:} false; then : +if test "${ac_cv_c_bigendian+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_cv_c_bigendian=unknown @@ -28554,8 +28552,8 @@ if test "x$with_x" = xno; then have_x=disabled else case $x_includes,$x_libraries in #( - *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #( - *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then : + *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5 ;; #( + *,NONE | NONE,*) if test "${ac_cv_have_x+set}" = set; then : $as_echo_n "(cached) " >&6 else # One or both of the vars are not set, and there is no cached value. @@ -28832,7 +28830,7 @@ if ac_fn_cxx_try_link "$LINENO"; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet" >&5 $as_echo_n "checking for dnet_ntoa in -ldnet... " >&6; } -if ${ac_cv_lib_dnet_dnet_ntoa+:} false; then : +if test "${ac_cv_lib_dnet_dnet_ntoa+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -28866,14 +28864,14 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_dnet_ntoa" >&5 $as_echo "$ac_cv_lib_dnet_dnet_ntoa" >&6; } -if test "x$ac_cv_lib_dnet_dnet_ntoa" = xyes; then : +if test "x$ac_cv_lib_dnet_dnet_ntoa" = x""yes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" fi if test $ac_cv_lib_dnet_dnet_ntoa = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet_stub" >&5 $as_echo_n "checking for dnet_ntoa in -ldnet_stub... " >&6; } -if ${ac_cv_lib_dnet_stub_dnet_ntoa+:} false; then : +if test "${ac_cv_lib_dnet_stub_dnet_ntoa+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -28907,7 +28905,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5 $as_echo "$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; } -if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = xyes; then : +if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = x""yes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" fi @@ -28926,14 +28924,14 @@ rm -f core conftest.err conftest.$ac_objext \ # The functions gethostbyname, getservbyname, and inet_addr are # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking. ac_fn_cxx_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" -if test "x$ac_cv_func_gethostbyname" = xyes; then : +if test "x$ac_cv_func_gethostbyname" = x""yes; then : fi if test $ac_cv_func_gethostbyname = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 $as_echo_n "checking for gethostbyname in -lnsl... " >&6; } -if ${ac_cv_lib_nsl_gethostbyname+:} false; then : +if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -28967,14 +28965,14 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 $as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } -if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : +if test "x$ac_cv_lib_nsl_gethostbyname" = x""yes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" fi if test $ac_cv_lib_nsl_gethostbyname = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lbsd" >&5 $as_echo_n "checking for gethostbyname in -lbsd... " >&6; } -if ${ac_cv_lib_bsd_gethostbyname+:} false; then : +if test "${ac_cv_lib_bsd_gethostbyname+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29008,7 +29006,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_gethostbyname" >&5 $as_echo "$ac_cv_lib_bsd_gethostbyname" >&6; } -if test "x$ac_cv_lib_bsd_gethostbyname" = xyes; then : +if test "x$ac_cv_lib_bsd_gethostbyname" = x""yes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd" fi @@ -29023,14 +29021,14 @@ fi # must be given before -lnsl if both are needed. We assume that # if connect needs -lnsl, so does gethostbyname. ac_fn_cxx_check_func "$LINENO" "connect" "ac_cv_func_connect" -if test "x$ac_cv_func_connect" = xyes; then : +if test "x$ac_cv_func_connect" = x""yes; then : fi if test $ac_cv_func_connect = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 $as_echo_n "checking for connect in -lsocket... " >&6; } -if ${ac_cv_lib_socket_connect+:} false; then : +if test "${ac_cv_lib_socket_connect+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29064,7 +29062,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5 $as_echo "$ac_cv_lib_socket_connect" >&6; } -if test "x$ac_cv_lib_socket_connect" = xyes; then : +if test "x$ac_cv_lib_socket_connect" = x""yes; then : X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" fi @@ -29072,14 +29070,14 @@ fi # Guillermo Gomez says -lposix is necessary on A/UX. ac_fn_cxx_check_func "$LINENO" "remove" "ac_cv_func_remove" -if test "x$ac_cv_func_remove" = xyes; then : +if test "x$ac_cv_func_remove" = x""yes; then : fi if test $ac_cv_func_remove = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for remove in -lposix" >&5 $as_echo_n "checking for remove in -lposix... " >&6; } -if ${ac_cv_lib_posix_remove+:} false; then : +if test "${ac_cv_lib_posix_remove+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29113,7 +29111,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix_remove" >&5 $as_echo "$ac_cv_lib_posix_remove" >&6; } -if test "x$ac_cv_lib_posix_remove" = xyes; then : +if test "x$ac_cv_lib_posix_remove" = x""yes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" fi @@ -29121,14 +29119,14 @@ fi # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. ac_fn_cxx_check_func "$LINENO" "shmat" "ac_cv_func_shmat" -if test "x$ac_cv_func_shmat" = xyes; then : +if test "x$ac_cv_func_shmat" = x""yes; then : fi if test $ac_cv_func_shmat = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shmat in -lipc" >&5 $as_echo_n "checking for shmat in -lipc... " >&6; } -if ${ac_cv_lib_ipc_shmat+:} false; then : +if test "${ac_cv_lib_ipc_shmat+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29162,7 +29160,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_shmat" >&5 $as_echo "$ac_cv_lib_ipc_shmat" >&6; } -if test "x$ac_cv_lib_ipc_shmat" = xyes; then : +if test "x$ac_cv_lib_ipc_shmat" = x""yes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" fi @@ -29180,7 +29178,7 @@ fi # John Interrante, Karl Berry { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IceConnectionNumber in -lICE" >&5 $as_echo_n "checking for IceConnectionNumber in -lICE... " >&6; } -if ${ac_cv_lib_ICE_IceConnectionNumber+:} false; then : +if test "${ac_cv_lib_ICE_IceConnectionNumber+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29214,7 +29212,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5 $as_echo "$ac_cv_lib_ICE_IceConnectionNumber" >&6; } -if test "x$ac_cv_lib_ICE_IceConnectionNumber" = xyes; then : +if test "x$ac_cv_lib_ICE_IceConnectionNumber" = x""yes; then : X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" fi @@ -30221,7 +30219,7 @@ $as_echo "$FREETYPE2_FOUND" >&6; } LDFLAGS="$FREETYPE2_LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FT_Init_FreeType in -lfreetype" >&5 $as_echo_n "checking for FT_Init_FreeType in -lfreetype... " >&6; } -if ${ac_cv_lib_freetype_FT_Init_FreeType+:} false; then : +if test "${ac_cv_lib_freetype_FT_Init_FreeType+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30255,7 +30253,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_freetype_FT_Init_FreeType" >&5 $as_echo "$ac_cv_lib_freetype_FT_Init_FreeType" >&6; } -if test "x$ac_cv_lib_freetype_FT_Init_FreeType" = xyes; then : +if test "x$ac_cv_lib_freetype_FT_Init_FreeType" = x""yes; then : FREETYPE2_FOUND=true else as_fn_error $? "Could not find freetype2! $HELP_MSG " "$LINENO" 5 @@ -30543,7 +30541,7 @@ fi for ac_header in alsa/asoundlib.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "alsa/asoundlib.h" "ac_cv_header_alsa_asoundlib_h" "$ac_includes_default" -if test "x$ac_cv_header_alsa_asoundlib_h" = xyes; then : +if test "x$ac_cv_header_alsa_asoundlib_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ALSA_ASOUNDLIB_H 1 _ACEOF @@ -30602,7 +30600,7 @@ fi USE_EXTERNAL_LIBJPEG=true { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -ljpeg" >&5 $as_echo_n "checking for main in -ljpeg... " >&6; } -if ${ac_cv_lib_jpeg_main+:} false; then : +if test "${ac_cv_lib_jpeg_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30630,7 +30628,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jpeg_main" >&5 $as_echo "$ac_cv_lib_jpeg_main" >&6; } -if test "x$ac_cv_lib_jpeg_main" = xyes; then : +if test "x$ac_cv_lib_jpeg_main" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBJPEG 1 _ACEOF @@ -30654,7 +30652,7 @@ fi USE_EXTERNAL_LIBJPEG=true { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lgif" >&5 $as_echo_n "checking for main in -lgif... " >&6; } -if ${ac_cv_lib_gif_main+:} false; then : +if test "${ac_cv_lib_gif_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30682,7 +30680,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gif_main" >&5 $as_echo "$ac_cv_lib_gif_main" >&6; } -if test "x$ac_cv_lib_gif_main" = xyes; then : +if test "x$ac_cv_lib_gif_main" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBGIF 1 _ACEOF @@ -30712,7 +30710,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for compress in -lz" >&5 $as_echo_n "checking for compress in -lz... " >&6; } -if ${ac_cv_lib_z_compress+:} false; then : +if test "${ac_cv_lib_z_compress+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30746,7 +30744,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_compress" >&5 $as_echo "$ac_cv_lib_z_compress" >&6; } -if test "x$ac_cv_lib_z_compress" = xyes; then : +if test "x$ac_cv_lib_z_compress" = x""yes; then : ZLIB_FOUND=yes else ZLIB_FOUND=no @@ -30839,7 +30837,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5 $as_echo_n "checking for cos in -lm... " >&6; } -if ${ac_cv_lib_m_cos+:} false; then : +if test "${ac_cv_lib_m_cos+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30873,7 +30871,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5 $as_echo "$ac_cv_lib_m_cos" >&6; } -if test "x$ac_cv_lib_m_cos" = xyes; then : +if test "x$ac_cv_lib_m_cos" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF @@ -30897,7 +30895,7 @@ save_LIBS="$LIBS" LIBS="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : +if test "${ac_cv_lib_dl_dlopen+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30931,7 +30929,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : +if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDL 1 _ACEOF @@ -31575,7 +31573,7 @@ fi set dummy ccache; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CCACHE+:} false; then : +if test "${ac_cv_path_CCACHE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CCACHE in @@ -31836,21 +31834,10 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then - if test "x$cache_file" != "x/dev/null"; then + test "x$cache_file" != "x/dev/null" && { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} - if test ! -f "$cache_file" || test -h "$cache_file"; then - cat confcache >"$cache_file" - else - case $cache_file in #( - */* | ?:*) - mv -f confcache "$cache_file"$$ && - mv -f "$cache_file"$$ "$cache_file" ;; #( - *) - mv -f confcache "$cache_file" ;; - esac - fi - fi + cat confcache >$cache_file else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} @@ -31882,7 +31869,7 @@ LTLIBOBJS=$ac_ltlibobjs -: "${CONFIG_STATUS=./config.status}" +: ${CONFIG_STATUS=./config.status} ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" @@ -31983,7 +31970,6 @@ fi IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. -as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -32291,7 +32277,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # values after options handling. ac_log=" This file was extended by OpenJDK $as_me jdk8, which was -generated by GNU Autoconf 2.68. Invocation command line was +generated by GNU Autoconf 2.67. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -32354,7 +32340,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ OpenJDK config.status jdk8 -configured by $0, generated by GNU Autoconf 2.68, +configured by $0, generated by GNU Autoconf 2.67, with options \\"\$ac_cs_config\\" Copyright (C) 2010 Free Software Foundation, Inc. @@ -32483,7 +32469,7 @@ do "$OUTPUT_ROOT/spec.sh") CONFIG_FILES="$CONFIG_FILES $OUTPUT_ROOT/spec.sh:$AUTOCONF_DIR/spec.sh.in" ;; "$OUTPUT_ROOT/Makefile") CONFIG_FILES="$CONFIG_FILES $OUTPUT_ROOT/Makefile:$AUTOCONF_DIR/Makefile.in" ;; - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;; esac done @@ -32505,10 +32491,9 @@ fi # after its creation but before its name has been assigned to `$tmp'. $debug || { - tmp= ac_tmp= + tmp= trap 'exit_status=$? - : "${ac_tmp:=$tmp}" - { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } @@ -32516,13 +32501,12 @@ $debug || { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -d "$tmp" + test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 -ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. @@ -32544,7 +32528,7 @@ else ac_cs_awk_cr=$ac_cr fi -echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +echo 'BEGIN {' >"$tmp/subs1.awk" && _ACEOF @@ -32572,7 +32556,7 @@ done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +cat >>"\$tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h @@ -32620,7 +32604,7 @@ t delim rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK -cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && +cat >>"\$tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" @@ -32652,7 +32636,7 @@ if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat -fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ +fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF @@ -32686,7 +32670,7 @@ fi # test -n "$CONFIG_FILES" # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then -cat >"$ac_tmp/defines.awk" <<\_ACAWK || +cat >"$tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF @@ -32698,8 +32682,8 @@ _ACEOF # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do - ac_tt=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_tt"; then + ac_t=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_t"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 @@ -32800,7 +32784,7 @@ do esac case $ac_mode$ac_tag in :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac @@ -32819,7 +32803,7 @@ do for ac_f do case $ac_f in - -) ac_f="$ac_tmp/stdin";; + -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. @@ -32828,7 +32812,7 @@ do [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" @@ -32854,8 +32838,8 @@ $as_echo "$as_me: creating $ac_file" >&6;} esac case $ac_tag in - *:-:* | *:-) cat >"$ac_tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + *:-:* | *:-) cat >"$tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac @@ -32980,22 +32964,21 @@ s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t $ac_datarootdir_hack " -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ - >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ - "$ac_tmp/out"`; test -z "$ac_out"; } && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} - rm -f "$ac_tmp/stdin" + rm -f "$tmp/stdin" case $ac_file in - -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; - *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + -) cat "$tmp/out" && rm -f "$tmp/out";; + *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; @@ -33006,20 +32989,20 @@ which seems to be undefined. Please make sure it is defined" >&2;} if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" - } >"$ac_tmp/config.h" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" + } >"$tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" - mv "$ac_tmp/config.h" "$ac_file" \ + mv "$tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; diff --git a/common/autoconf/jdk-options.m4 b/common/autoconf/jdk-options.m4 index 7e216b0a617..d9f188d65d8 100644 --- a/common/autoconf/jdk-options.m4 +++ b/common/autoconf/jdk-options.m4 @@ -247,46 +247,50 @@ AC_SUBST(DEBUG_CLASSFILES) AC_SUBST(BUILD_VARIANT_RELEASE) ]) -AC_DEFUN_ONCE([JDKOPT_SETUP_JDK_OPTIONS], -[ ############################################################################### # # Should we build only OpenJDK even if closed sources are present? # -AC_ARG_ENABLE([openjdk-only], [AS_HELP_STRING([--enable-openjdk-only], - [supress building closed source even if present @<:@disabled@:>@])],,[enable_openjdk_only="no"]) +AC_DEFUN_ONCE([JDKOPT_SETUP_OPEN_OR_CUSTOM], +[ + AC_ARG_ENABLE([openjdk-only], [AS_HELP_STRING([--enable-openjdk-only], + [suppress building custom source even if present @<:@disabled@:>@])],,[enable_openjdk_only="no"]) -AC_MSG_CHECKING([for presence of closed sources]) -if test -d "$SRC_ROOT/jdk/src/closed"; then + AC_MSG_CHECKING([for presence of closed sources]) + if test -d "$SRC_ROOT/jdk/src/closed"; then CLOSED_SOURCE_PRESENT=yes -else - CLOSED_SOURCE_PRESENT=no -fi -AC_MSG_RESULT([$CLOSED_SOURCE_PRESENT]) - -AC_MSG_CHECKING([if closed source is supressed (openjdk-only)]) -SUPRESS_CLOSED_SOURCE="$enable_openjdk_only" -AC_MSG_RESULT([$SUPRESS_CLOSED_SOURCE]) - -if test "x$CLOSED_SOURCE_PRESENT" = xno; then - OPENJDK=true - if test "x$SUPRESS_CLOSED_SOURCE" = "xyes"; then - AC_MSG_WARN([No closed source present, --enable-openjdk-only makes no sense]) - fi -else - if test "x$SUPRESS_CLOSED_SOURCE" = "xyes"; then - OPENJDK=true else - OPENJDK=false + CLOSED_SOURCE_PRESENT=no fi -fi + AC_MSG_RESULT([$CLOSED_SOURCE_PRESENT]) -if test "x$OPENJDK" = "xtrue"; then + AC_MSG_CHECKING([if closed source is suppressed (openjdk-only)]) + SUPPRESS_CLOSED_SOURCE="$enable_openjdk_only" + AC_MSG_RESULT([$SUPPRESS_CLOSED_SOURCE]) + + if test "x$CLOSED_SOURCE_PRESENT" = xno; then + OPENJDK=true + if test "x$SUPPRESS_CLOSED_SOURCE" = "xyes"; then + AC_MSG_WARN([No closed source present, --enable-openjdk-only makes no sense]) + fi + else + if test "x$SUPPRESS_CLOSED_SOURCE" = "xyes"; then + OPENJDK=true + else + OPENJDK=false + fi + fi + + if test "x$OPENJDK" = "xtrue"; then SET_OPENJDK="OPENJDK=true" -fi + fi -AC_SUBST(SET_OPENJDK) + AC_SUBST(SET_OPENJDK) +]) + +AC_DEFUN_ONCE([JDKOPT_SETUP_JDK_OPTIONS], +[ ############################################################################### # From d06c06026ac94ec811ac7b1d4825f9be5a0a9c0b Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Fri, 11 Jan 2013 02:02:51 -0800 Subject: [PATCH 059/204] 8006034: new hotspot build - hs25-b16 Reviewed-by: jcoomes --- hotspot/make/hotspot_version | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version index d6959b3b86c..946cb5c1aa8 100644 --- a/hotspot/make/hotspot_version +++ b/hotspot/make/hotspot_version @@ -1,5 +1,5 @@ # -# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2013, 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 @@ -31,11 +31,11 @@ # # Don't put quotes (fail windows build). -HOTSPOT_VM_COPYRIGHT=Copyright 2012 +HOTSPOT_VM_COPYRIGHT=Copyright 2013 HS_MAJOR_VER=25 HS_MINOR_VER=0 -HS_BUILD_NUMBER=15 +HS_BUILD_NUMBER=16 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 From 93d2366337fae6b1607a4c6368bc3fa9e872dfca Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Fri, 11 Jan 2013 12:30:54 -0500 Subject: [PATCH 060/204] 8005936: PrintNMTStatistics doesn't work for normal JVM exit Moved NMT shutdown code to JVM exit handler to ensure NMT statistics is printed when PrintNMTStatistics is enabled Reviewed-by: acorn, dholmes, coleenp --- hotspot/src/share/vm/runtime/java.cpp | 4 ++++ hotspot/src/share/vm/runtime/thread.cpp | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/runtime/java.cpp b/hotspot/src/share/vm/runtime/java.cpp index ad6399495b0..fb26ad9ddfc 100644 --- a/hotspot/src/share/vm/runtime/java.cpp +++ b/hotspot/src/share/vm/runtime/java.cpp @@ -542,6 +542,10 @@ void before_exit(JavaThread * thread) { BeforeExit_lock->notify_all(); } + // Shutdown NMT before exit. Otherwise, + // it will run into trouble when system destroys static variables. + MemTracker::shutdown(MemTracker::NMT_normal); + #undef BEFORE_EXIT_NOT_RUN #undef BEFORE_EXIT_RUNNING #undef BEFORE_EXIT_DONE diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index db3cace3d64..971f4f8dad1 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -4011,10 +4011,6 @@ bool Threads::destroy_vm() { Mutex::_as_suspend_equivalent_flag); } - // Shutdown NMT before exit. Otherwise, - // it will run into trouble when system destroys static variables. - MemTracker::shutdown(MemTracker::NMT_normal); - // Hang forever on exit if we are reporting an error. if (ShowMessageBoxOnError && is_error_reported()) { os::infinite_sleep(); From 2cbabcea4a6e675bd498173a64f1f061c3ac5199 Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Fri, 11 Jan 2013 16:55:07 -0500 Subject: [PATCH 061/204] 8005895: Inefficient InstanceKlass field packing wasts memory Pack _misc_has_default_methods into the _misc_flags, move _idnum_allocated_count. Reviewed-by: coleenp, shade --- hotspot/src/share/vm/oops/instanceKlass.hpp | 24 +++++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp index 0d173faa510..9793dd77d82 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.hpp +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp @@ -225,12 +225,16 @@ class InstanceKlass: public Klass { u2 _java_fields_count; // The number of declared Java fields int _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks + // _is_marked_dependent can be set concurrently, thus cannot be part of the + // _misc_flags. bool _is_marked_dependent; // used for marking during flushing and deoptimization + enum { _misc_rewritten = 1 << 0, // methods rewritten. _misc_has_nonstatic_fields = 1 << 1, // for sizing with UseCompressedOops _misc_should_verify_class = 1 << 2, // allow caching of preverification - _misc_is_anonymous = 1 << 3 // has embedded _inner_classes field + _misc_is_anonymous = 1 << 3, // has embedded _inner_classes field + _misc_has_default_methods = 1 << 4 // class/superclass/implemented interfaces has default methods }; u2 _misc_flags; u2 _minor_version; // minor version number of class file @@ -253,10 +257,6 @@ class InstanceKlass: public Klass { jint _cached_class_file_len; // JVMTI: length of above JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map; // JVMTI: used during heap iteration - // true if class, superclass, or implemented interfaces have default methods - bool _has_default_methods; - - volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change // Method array. Array* _methods; // Interface (Klass*s) this class declares locally to implement. @@ -280,6 +280,8 @@ class InstanceKlass: public Klass { // ... Array* _fields; + volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change + // Class states are defined as ClassState (see above). // Place the _init_state here to utilize the unused 2-byte after // _idnum_allocated_count. @@ -616,8 +618,16 @@ class InstanceKlass: public Klass { return _jvmti_cached_class_field_map; } - bool has_default_methods() const { return _has_default_methods; } - void set_has_default_methods(bool b) { _has_default_methods = b; } + bool has_default_methods() const { + return (_misc_flags & _misc_has_default_methods) != 0; + } + void set_has_default_methods(bool b) { + if (b) { + _misc_flags |= _misc_has_default_methods; + } else { + _misc_flags &= ~_misc_has_default_methods; + } + } // for adding methods, ConstMethod::UNSET_IDNUM means no more ids available inline u2 next_method_idnum(); From 6c57a4b9f8978dfa88f586d7dc109d95f6a62f96 Mon Sep 17 00:00:00 2001 From: Christian Thalinger Date: Fri, 11 Jan 2013 14:07:09 -0800 Subject: [PATCH 062/204] 8006031: LibraryCallKit::inline_array_copyOf disabled unintentionally with 7172640 Reviewed-by: kvn --- hotspot/src/share/vm/opto/library_call.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index 313339edfde..b2138abe931 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -3559,7 +3559,7 @@ bool LibraryCallKit::inline_native_getLength() { // public static T[] java.util.Arrays.copyOf( U[] original, int newLength, Class newType); // public static T[] java.util.Arrays.copyOfRange(U[] original, int from, int to, Class newType); bool LibraryCallKit::inline_array_copyOf(bool is_copyOfRange) { - return false; + tty->print_cr("LibraryCallKit::inline_array_copyOf: %d", is_copyOfRange); if (too_many_traps(Deoptimization::Reason_intrinsic)) return false; // Get the arguments. From a42478ecf417902fbb5dd100ffbe44d5dc38c1d6 Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Fri, 11 Jan 2013 16:47:23 -0800 Subject: [PATCH 063/204] 8005816: Shark: fix volatile float field access Reviewed-by: twisti --- hotspot/src/share/vm/shark/sharkBlock.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/shark/sharkBlock.cpp b/hotspot/src/share/vm/shark/sharkBlock.cpp index b4e98365efc..723b2d1dbc6 100644 --- a/hotspot/src/share/vm/shark/sharkBlock.cpp +++ b/hotspot/src/share/vm/shark/sharkBlock.cpp @@ -1044,10 +1044,17 @@ void SharkBlock::do_field_access(bool is_get, bool is_field) { BasicType basic_type = field->type()->basic_type(); Type *stack_type = SharkType::to_stackType(basic_type); Type *field_type = SharkType::to_arrayType(basic_type); - + Type *type = field_type; + if (field->is_volatile()) { + if (field_type == SharkType::jfloat_type()) { + type = SharkType::jint_type(); + } else if (field_type == SharkType::jdouble_type()) { + type = SharkType::jlong_type(); + } + } Value *addr = builder()->CreateAddressOfStructEntry( object, in_ByteSize(field->offset_in_bytes()), - PointerType::getUnqual(field_type), + PointerType::getUnqual(type), "addr"); // Do the access @@ -1055,6 +1062,7 @@ void SharkBlock::do_field_access(bool is_get, bool is_field) { Value* field_value; if (field->is_volatile()) { field_value = builder()->CreateAtomicLoad(addr); + field_value = builder()->CreateBitCast(field_value, field_type); } else { field_value = builder()->CreateLoad(addr); } @@ -1074,6 +1082,7 @@ void SharkBlock::do_field_access(bool is_get, bool is_field) { } if (field->is_volatile()) { + field_value = builder()->CreateBitCast(field_value, type); builder()->CreateAtomicStore(field_value, addr); } else { builder()->CreateStore(field_value, addr); From a0a0d0b65ef0dc2a055fac34fbad0b44e0a4067a Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Fri, 11 Jan 2013 16:47:23 -0800 Subject: [PATCH 064/204] 8005817: Shark: implement deoptimization support Reviewed-by: twisti --- hotspot/src/cpu/zero/vm/frame_zero.cpp | 18 ++++++++++++++---- hotspot/src/cpu/zero/vm/frame_zero.inline.hpp | 15 ++++++++++++--- hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp | 4 ++++ hotspot/src/share/vm/shark/sharkInvariants.hpp | 8 +++++--- .../src/share/vm/shark/sharkTopLevelBlock.cpp | 7 ++++--- 5 files changed, 39 insertions(+), 13 deletions(-) diff --git a/hotspot/src/cpu/zero/vm/frame_zero.cpp b/hotspot/src/cpu/zero/vm/frame_zero.cpp index 8643af5953f..56f2a7a1c71 100644 --- a/hotspot/src/cpu/zero/vm/frame_zero.cpp +++ b/hotspot/src/cpu/zero/vm/frame_zero.cpp @@ -98,10 +98,20 @@ BasicObjectLock* frame::interpreter_frame_monitor_end() const { #endif // CC_INTERP void frame::patch_pc(Thread* thread, address pc) { - // We borrow this call to set the thread pointer in the interpreter - // state; the hook to set up deoptimized frames isn't supplied it. - assert(pc == NULL, "should be"); - get_interpreterState()->set_thread((JavaThread *) thread); + + if (pc != NULL) { + _cb = CodeCache::find_blob(pc); + SharkFrame* sharkframe = zeroframe()->as_shark_frame(); + sharkframe->set_pc(pc); + _pc = pc; + _deopt_state = is_deoptimized; + + } else { + // We borrow this call to set the thread pointer in the interpreter + // state; the hook to set up deoptimized frames isn't supplied it. + assert(pc == NULL, "should be"); + get_interpreterState()->set_thread((JavaThread *) thread); + } } bool frame::safe_for_sender(JavaThread *thread) { diff --git a/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp b/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp index 2bc703ae032..f6bd6d3c6be 100644 --- a/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp +++ b/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp @@ -45,27 +45,36 @@ inline frame::frame(ZeroFrame* zf, intptr_t* sp) { case ZeroFrame::ENTRY_FRAME: _pc = StubRoutines::call_stub_return_pc(); _cb = NULL; + _deopt_state = not_deoptimized; break; case ZeroFrame::INTERPRETER_FRAME: _pc = NULL; _cb = NULL; + _deopt_state = not_deoptimized; break; - case ZeroFrame::SHARK_FRAME: + case ZeroFrame::SHARK_FRAME: { _pc = zero_sharkframe()->pc(); _cb = CodeCache::find_blob_unsafe(pc()); + address original_pc = nmethod::get_deopt_original_pc(this); + if (original_pc != NULL) { + _pc = original_pc; + _deopt_state = is_deoptimized; + } else { + _deopt_state = not_deoptimized; + } break; - + } case ZeroFrame::FAKE_STUB_FRAME: _pc = NULL; _cb = NULL; + _deopt_state = not_deoptimized; break; default: ShouldNotReachHere(); } - _deopt_state = not_deoptimized; } // Accessors diff --git a/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp b/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp index 6c67d0eb1d8..505241b147f 100644 --- a/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp +++ b/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp @@ -68,6 +68,10 @@ class SharkFrame : public ZeroFrame { return (address) value_of_word(pc_off); } + void set_pc(address pc) const { + *((address*) addr_of_word(pc_off)) = pc; + } + intptr_t* unextended_sp() const { return (intptr_t *) value_of_word(unextended_sp_off); } diff --git a/hotspot/src/share/vm/shark/sharkInvariants.hpp b/hotspot/src/share/vm/shark/sharkInvariants.hpp index 50e1be8ea6d..8e9d0aec062 100644 --- a/hotspot/src/share/vm/shark/sharkInvariants.hpp +++ b/hotspot/src/share/vm/shark/sharkInvariants.hpp @@ -99,13 +99,15 @@ class SharkCompileInvariants : public ResourceObj { DebugInformationRecorder* debug_info() const { return env()->debug_info(); } - Dependencies* dependencies() const { - return env()->dependencies(); - } SharkCodeBuffer* code_buffer() const { return builder()->code_buffer(); } + public: + Dependencies* dependencies() const { + return env()->dependencies(); + } + // Commonly used classes protected: ciInstanceKlass* java_lang_Object_klass() const { diff --git a/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp b/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp index fcd6906caad..a3f90b058bf 100644 --- a/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp +++ b/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp @@ -1030,7 +1030,6 @@ ciMethod* SharkTopLevelBlock::improve_virtual_call(ciMethod* caller, dest_method->holder() == java_lang_Object_klass()) return dest_method; -#ifdef SHARK_CAN_DEOPTIMIZE_ANYWHERE // This code can replace a virtual call with a direct call if this // class is the only one in the entire set of loaded classes that // implements this method. This makes the compiled code dependent @@ -1064,6 +1063,8 @@ ciMethod* SharkTopLevelBlock::improve_virtual_call(ciMethod* caller, if (monomorphic_target != NULL) { assert(!monomorphic_target->is_abstract(), "shouldn't be"); + function()->dependencies()->assert_unique_concrete_method(actual_receiver, monomorphic_target); + // Opto has a bunch of type checking here that I don't // understand. It's to inhibit casting in one direction, // possibly because objects in Opto can have inexact @@ -1097,7 +1098,6 @@ ciMethod* SharkTopLevelBlock::improve_virtual_call(ciMethod* caller, // with non-monomorphic targets if the receiver has an exact // type. We don't mark types this way, so we can't do this. -#endif // SHARK_CAN_DEOPTIMIZE_ANYWHERE return NULL; } @@ -1298,8 +1298,9 @@ void SharkTopLevelBlock::do_call() { // Try to inline the call if (!call_is_virtual) { - if (SharkInliner::attempt_inline(call_method, current_state())) + if (SharkInliner::attempt_inline(call_method, current_state())) { return; + } } // Find the method we are calling From ba649f4203f5d53ce5f0475156c87dc741a7869d Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Fri, 11 Jan 2013 16:47:23 -0800 Subject: [PATCH 065/204] 8005818: Shark: fix OSR for non-empty incoming stack Reviewed-by: twisti --- hotspot/src/share/vm/shark/sharkCompiler.cpp | 3 +++ hotspot/src/share/vm/shark/sharkFunction.cpp | 4 ++++ hotspot/src/share/vm/shark/sharkInvariants.hpp | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/shark/sharkCompiler.cpp b/hotspot/src/share/vm/shark/sharkCompiler.cpp index 3438240ad00..cde6bc23e76 100644 --- a/hotspot/src/share/vm/shark/sharkCompiler.cpp +++ b/hotspot/src/share/vm/shark/sharkCompiler.cpp @@ -185,6 +185,9 @@ void SharkCompiler::compile_method(ciEnv* env, // Build the LLVM IR for the method Function *function = SharkFunction::build(env, &builder, flow, name); + if (env->failing()) { + return; + } // Generate native code. It's unpleasant that we have to drop into // the VM to do this -- it blocks safepoints -- but I can't see any diff --git a/hotspot/src/share/vm/shark/sharkFunction.cpp b/hotspot/src/share/vm/shark/sharkFunction.cpp index 917ed0109ac..1ec7a371fb4 100644 --- a/hotspot/src/share/vm/shark/sharkFunction.cpp +++ b/hotspot/src/share/vm/shark/sharkFunction.cpp @@ -77,6 +77,10 @@ void SharkFunction::initialize(const char *name) { // Walk the tree from the start block to determine which // blocks are entered and which blocks require phis SharkTopLevelBlock *start_block = block(flow()->start_block_num()); + if (is_osr() && start_block->stack_depth_at_entry() != 0) { + env()->record_method_not_compilable("can't compile OSR block with incoming stack-depth > 0"); + return; + } assert(start_block->start() == flow()->start_bci(), "blocks out of order"); start_block->enter(); diff --git a/hotspot/src/share/vm/shark/sharkInvariants.hpp b/hotspot/src/share/vm/shark/sharkInvariants.hpp index 8e9d0aec062..e6b6399fe26 100644 --- a/hotspot/src/share/vm/shark/sharkInvariants.hpp +++ b/hotspot/src/share/vm/shark/sharkInvariants.hpp @@ -68,7 +68,7 @@ class SharkCompileInvariants : public ResourceObj { // // Accessing this directly is kind of ugly, so it's private. Add // new accessors below if you need something from it. - private: + protected: ciEnv* env() const { assert(_env != NULL, "env not available"); return _env; From b17ebac5b54b3e1be6199cd71c63843c771836dc Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Fri, 11 Jan 2013 16:47:23 -0800 Subject: [PATCH 066/204] 8005820: Shark: enable JSR292 support Reviewed-by: twisti --- .../share/vm/compiler/abstractCompiler.hpp | 1 + .../src/share/vm/compiler/compileBroker.cpp | 2 +- hotspot/src/share/vm/shark/sharkBlock.cpp | 2 +- hotspot/src/share/vm/shark/sharkCompiler.hpp | 3 +++ hotspot/src/share/vm/shark/sharkConstant.cpp | 7 +++++- hotspot/src/share/vm/shark/sharkInliner.cpp | 2 +- .../src/share/vm/shark/sharkTopLevelBlock.cpp | 24 ++++++++++++++++++- 7 files changed, 36 insertions(+), 5 deletions(-) diff --git a/hotspot/src/share/vm/compiler/abstractCompiler.hpp b/hotspot/src/share/vm/compiler/abstractCompiler.hpp index 9007a82fc49..96453e7d9ba 100644 --- a/hotspot/src/share/vm/compiler/abstractCompiler.hpp +++ b/hotspot/src/share/vm/compiler/abstractCompiler.hpp @@ -50,6 +50,7 @@ class AbstractCompiler : public CHeapObj { // Missing feature tests virtual bool supports_native() { return true; } virtual bool supports_osr () { return true; } + virtual bool can_compile_method(methodHandle method) { return true; } #if defined(TIERED) || ( !defined(COMPILER1) && !defined(COMPILER2) && !defined(SHARK)) virtual bool is_c1 () { return false; } virtual bool is_c2 () { return false; } diff --git a/hotspot/src/share/vm/compiler/compileBroker.cpp b/hotspot/src/share/vm/compiler/compileBroker.cpp index 73ab865dc74..57389701d82 100644 --- a/hotspot/src/share/vm/compiler/compileBroker.cpp +++ b/hotspot/src/share/vm/compiler/compileBroker.cpp @@ -1218,7 +1218,7 @@ nmethod* CompileBroker::compile_method(methodHandle method, int osr_bci, // lock, make sure that the compilation // isn't prohibited in a straightforward way. - if (compiler(comp_level) == NULL || compilation_is_prohibited(method, osr_bci, comp_level)) { + if (compiler(comp_level) == NULL || !compiler(comp_level)->can_compile_method(method) || compilation_is_prohibited(method, osr_bci, comp_level)) { return NULL; } diff --git a/hotspot/src/share/vm/shark/sharkBlock.cpp b/hotspot/src/share/vm/shark/sharkBlock.cpp index 723b2d1dbc6..6b1b5fbe89c 100644 --- a/hotspot/src/share/vm/shark/sharkBlock.cpp +++ b/hotspot/src/share/vm/shark/sharkBlock.cpp @@ -1032,7 +1032,7 @@ void SharkBlock::do_field_access(bool is_get, bool is_field) { check_null(value); object = value->generic_value(); } - if (is_get && field->is_constant()) { + if (is_get && field->is_constant() && field->is_static()) { SharkConstant *constant = SharkConstant::for_field(iter()); if (constant->is_loaded()) value = constant->value(builder()); diff --git a/hotspot/src/share/vm/shark/sharkCompiler.hpp b/hotspot/src/share/vm/shark/sharkCompiler.hpp index 828a783a80d..7e530c142aa 100644 --- a/hotspot/src/share/vm/shark/sharkCompiler.hpp +++ b/hotspot/src/share/vm/shark/sharkCompiler.hpp @@ -46,6 +46,9 @@ class SharkCompiler : public AbstractCompiler { // Missing feature tests bool supports_native() { return true; } bool supports_osr() { return true; } + bool can_compile_method(methodHandle method) { + return ! (method->is_method_handle_intrinsic() || method->is_compiled_lambda_form()); + } // Customization bool needs_adapters() { return false; } diff --git a/hotspot/src/share/vm/shark/sharkConstant.cpp b/hotspot/src/share/vm/shark/sharkConstant.cpp index b45ec136e77..cd6e1152d0f 100644 --- a/hotspot/src/share/vm/shark/sharkConstant.cpp +++ b/hotspot/src/share/vm/shark/sharkConstant.cpp @@ -37,7 +37,12 @@ SharkConstant* SharkConstant::for_ldc(ciBytecodeStream *iter) { ciType *type = NULL; if (constant.basic_type() == T_OBJECT) { ciEnv *env = ciEnv::current(); - assert(constant.as_object()->klass() == env->String_klass() || constant.as_object()->klass() == env->Class_klass(), "should be"); + + assert(constant.as_object()->klass() == env->String_klass() + || constant.as_object()->klass() == env->Class_klass() + || constant.as_object()->klass()->is_subtype_of(env->MethodType_klass()) + || constant.as_object()->klass()->is_subtype_of(env->MethodHandle_klass()), "should be"); + type = constant.as_object()->klass(); } return new SharkConstant(constant, type); diff --git a/hotspot/src/share/vm/shark/sharkInliner.cpp b/hotspot/src/share/vm/shark/sharkInliner.cpp index c9e895a9c9b..1f4ea829fb3 100644 --- a/hotspot/src/share/vm/shark/sharkInliner.cpp +++ b/hotspot/src/share/vm/shark/sharkInliner.cpp @@ -725,7 +725,7 @@ bool SharkInlinerHelper::do_field_access(bool is_get, bool is_field) { // Push the result if necessary if (is_get) { bool result_pushed = false; - if (field->is_constant()) { + if (field->is_constant() && field->is_static()) { SharkConstant *sc = SharkConstant::for_field(iter()); if (sc->is_loaded()) { push(sc->is_nonzero()); diff --git a/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp b/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp index a3f90b058bf..6614146bb42 100644 --- a/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp +++ b/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp @@ -113,7 +113,19 @@ void SharkTopLevelBlock::scan_for_traps() { ciSignature* sig; method = iter()->get_method(will_link, &sig); assert(will_link, "typeflow responsibility"); - + // We can't compile calls to method handle intrinsics, because we use + // the interpreter entry points and they expect the top frame to be an + // interpreter frame. We need to implement the intrinsics for Shark. + if (method->is_method_handle_intrinsic() || method->is_compiled_lambda_form()) { + if (SharkPerformanceWarnings) { + warning("JSR292 optimization not yet implemented in Shark"); + } + set_trap( + Deoptimization::make_trap_request( + Deoptimization::Reason_unhandled, + Deoptimization::Action_make_not_compilable), bci()); + return; + } if (!method->holder()->is_linked()) { set_trap( Deoptimization::make_trap_request( @@ -158,6 +170,16 @@ void SharkTopLevelBlock::scan_for_traps() { return; } break; + case Bytecodes::_invokedynamic: + case Bytecodes::_invokehandle: + if (SharkPerformanceWarnings) { + warning("JSR292 optimization not yet implemented in Shark"); + } + set_trap( + Deoptimization::make_trap_request( + Deoptimization::Reason_unhandled, + Deoptimization::Action_make_not_compilable), bci()); + return; } } From fb60d01e3632b5f81633db04881c64bcea809c19 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Fri, 11 Jan 2013 16:50:34 -0800 Subject: [PATCH 067/204] 8006123: Support @Contended Annotation - JEP 142 (jdk part) Jdk changes for 8003895. Reviewed-by: darcy, jrose, coleenp, dholmes, kvn --- jdk/src/share/classes/sun/misc/Contended.java | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 jdk/src/share/classes/sun/misc/Contended.java diff --git a/jdk/src/share/classes/sun/misc/Contended.java b/jdk/src/share/classes/sun/misc/Contended.java new file mode 100644 index 00000000000..6925b4242d6 --- /dev/null +++ b/jdk/src/share/classes/sun/misc/Contended.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package sun.misc; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation marks classes and fields as considered to be contended. + * @since 1.8 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD, ElementType.TYPE}) +public @interface Contended { + + /** + Defines the contention group tag. + */ + String value() default ""; +} From 827930b510dd8ae13b0dd42f97f499c4772384f6 Mon Sep 17 00:00:00 2001 From: Christian Thalinger Date: Fri, 11 Jan 2013 20:01:16 -0800 Subject: [PATCH 068/204] 8006127: remove printing code added with 8006031 Reviewed-by: kvn --- hotspot/src/share/vm/opto/library_call.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index b2138abe931..406f605853d 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -3559,7 +3559,6 @@ bool LibraryCallKit::inline_native_getLength() { // public static T[] java.util.Arrays.copyOf( U[] original, int newLength, Class newType); // public static T[] java.util.Arrays.copyOfRange(U[] original, int from, int to, Class newType); bool LibraryCallKit::inline_array_copyOf(bool is_copyOfRange) { - tty->print_cr("LibraryCallKit::inline_array_copyOf: %d", is_copyOfRange); if (too_many_traps(Deoptimization::Reason_intrinsic)) return false; // Get the arguments. From 48aff5a2675eb4615fcba3ca665b4dc1f8e29d96 Mon Sep 17 00:00:00 2001 From: Yong Jeffrey Huang Date: Sun, 13 Jan 2013 18:45:43 -0800 Subject: [PATCH 069/204] 7114053: [sq] Inproper tanslation for iso lanugage of Albanian Reviewed-by: naoto --- .../classes/sun/util/resources/sq/LocaleNames_sq.properties | 4 ++-- jdk/test/sun/text/resources/LocaleData | 3 +++ jdk/test/sun/text/resources/LocaleDataTest.java | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/classes/sun/util/resources/sq/LocaleNames_sq.properties b/jdk/src/share/classes/sun/util/resources/sq/LocaleNames_sq.properties index e66c0e1d22b..903dcea5317 100644 --- a/jdk/src/share/classes/sun/util/resources/sq/LocaleNames_sq.properties +++ b/jdk/src/share/classes/sun/util/resources/sq/LocaleNames_sq.properties @@ -1,4 +1,4 @@ -# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2013, 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 @@ -38,7 +38,7 @@ # language names # key is ISO 639 language code -sq=shqipe +sq=shqip # country names # key is ISO 3166 country code diff --git a/jdk/test/sun/text/resources/LocaleData b/jdk/test/sun/text/resources/LocaleData index 59dc0ebeffb..87b9d44cb27 100644 --- a/jdk/test/sun/text/resources/LocaleData +++ b/jdk/test/sun/text/resources/LocaleData @@ -7660,3 +7660,6 @@ FormatData/zh/DayNarrows/6=\u516d # bug 7195759 CurrencyNames//ZMW=ZMW + +# bug 7114053 +LocaleNames/sq/sq=shqip diff --git a/jdk/test/sun/text/resources/LocaleDataTest.java b/jdk/test/sun/text/resources/LocaleDataTest.java index bd1932209cf..50b8caef993 100644 --- a/jdk/test/sun/text/resources/LocaleDataTest.java +++ b/jdk/test/sun/text/resources/LocaleDataTest.java @@ -34,7 +34,7 @@ * 6509039 6609737 6610748 6645271 6507067 6873931 6450945 6645268 6646611 * 6645405 6650730 6910489 6573250 6870908 6585666 6716626 6914413 6916787 * 6919624 6998391 7019267 7020960 7025837 7020583 7036905 7066203 7101495 - * 7003124 7085757 7028073 7171028 7189611 8000983 7195759 + * 7003124 7085757 7028073 7171028 7189611 8000983 7195759 7114053 * @summary Verify locale data * */ From a3639fdea176da5d87615a58ef294d5f5cb0bc5c Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Mon, 14 Jan 2013 09:58:52 +0100 Subject: [PATCH 070/204] 8004018: Remove old initialization flags Reviewed-by: dholmes, stefank --- hotspot/src/share/vm/runtime/globals.hpp | 12 ---- hotspot/src/share/vm/runtime/thread.cpp | 77 +++++++++--------------- 2 files changed, 29 insertions(+), 60 deletions(-) diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 7ea96627e82..61aee4a9060 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -969,18 +969,6 @@ class CommandLineFlags { notproduct(uintx, WarnOnStalledSpinLock, 0, \ "Prints warnings for stalled SpinLocks") \ \ - develop(bool, InitializeJavaLangSystem, true, \ - "Initialize java.lang.System - turn off for individual " \ - "method debugging") \ - \ - develop(bool, InitializeJavaLangString, true, \ - "Initialize java.lang.String - turn off for individual " \ - "method debugging") \ - \ - develop(bool, InitializeJavaLangExceptionsErrors, true, \ - "Initialize various error and exception classes - turn off for " \ - "individual method debugging") \ - \ product(bool, RegisterFinalizersAtInit, true, \ "Register finalizable objects at end of Object. or " \ "after allocation") \ diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index db3cace3d64..5be1615e1be 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -1716,7 +1716,6 @@ static void ensure_join(JavaThread* thread) { // cleanup_failed_attach_current_thread as well. void JavaThread::exit(bool destroy_vm, ExitType exit_type) { assert(this == JavaThread::current(), "thread consistency check"); - if (!InitializeJavaLangSystem) return; HandleMark hm(this); Handle uncaught_exception(this, this->pending_exception()); @@ -3469,11 +3468,7 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { create_vm_init_libraries(); } - if (InitializeJavaLangString) { - initialize_class(vmSymbols::java_lang_String(), CHECK_0); - } else { - warning("java.lang.String not initialized"); - } + initialize_class(vmSymbols::java_lang_String(), CHECK_0); if (AggressiveOpts) { { @@ -3514,53 +3509,39 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { } // Initialize java_lang.System (needed before creating the thread) - if (InitializeJavaLangSystem) { - initialize_class(vmSymbols::java_lang_System(), CHECK_0); - initialize_class(vmSymbols::java_lang_ThreadGroup(), CHECK_0); - Handle thread_group = create_initial_thread_group(CHECK_0); - Universe::set_main_thread_group(thread_group()); - initialize_class(vmSymbols::java_lang_Thread(), CHECK_0); - oop thread_object = create_initial_thread(thread_group, main_thread, CHECK_0); - main_thread->set_threadObj(thread_object); - // Set thread status to running since main thread has - // been started and running. - java_lang_Thread::set_thread_status(thread_object, - java_lang_Thread::RUNNABLE); + initialize_class(vmSymbols::java_lang_System(), CHECK_0); + initialize_class(vmSymbols::java_lang_ThreadGroup(), CHECK_0); + Handle thread_group = create_initial_thread_group(CHECK_0); + Universe::set_main_thread_group(thread_group()); + initialize_class(vmSymbols::java_lang_Thread(), CHECK_0); + oop thread_object = create_initial_thread(thread_group, main_thread, CHECK_0); + main_thread->set_threadObj(thread_object); + // Set thread status to running since main thread has + // been started and running. + java_lang_Thread::set_thread_status(thread_object, + java_lang_Thread::RUNNABLE); - // The VM creates & returns objects of this class. Make sure it's initialized. - initialize_class(vmSymbols::java_lang_Class(), CHECK_0); + // The VM creates & returns objects of this class. Make sure it's initialized. + initialize_class(vmSymbols::java_lang_Class(), CHECK_0); - // The VM preresolves methods to these classes. Make sure that they get initialized - initialize_class(vmSymbols::java_lang_reflect_Method(), CHECK_0); - initialize_class(vmSymbols::java_lang_ref_Finalizer(), CHECK_0); - call_initializeSystemClass(CHECK_0); + // The VM preresolves methods to these classes. Make sure that they get initialized + initialize_class(vmSymbols::java_lang_reflect_Method(), CHECK_0); + initialize_class(vmSymbols::java_lang_ref_Finalizer(), CHECK_0); + call_initializeSystemClass(CHECK_0); - // get the Java runtime name after java.lang.System is initialized - JDK_Version::set_runtime_name(get_java_runtime_name(THREAD)); - JDK_Version::set_runtime_version(get_java_runtime_version(THREAD)); - } else { - warning("java.lang.System not initialized"); - } + // get the Java runtime name after java.lang.System is initialized + JDK_Version::set_runtime_name(get_java_runtime_name(THREAD)); + JDK_Version::set_runtime_version(get_java_runtime_version(THREAD)); // an instance of OutOfMemory exception has been allocated earlier - if (InitializeJavaLangExceptionsErrors) { - initialize_class(vmSymbols::java_lang_OutOfMemoryError(), CHECK_0); - initialize_class(vmSymbols::java_lang_NullPointerException(), CHECK_0); - initialize_class(vmSymbols::java_lang_ClassCastException(), CHECK_0); - initialize_class(vmSymbols::java_lang_ArrayStoreException(), CHECK_0); - initialize_class(vmSymbols::java_lang_ArithmeticException(), CHECK_0); - initialize_class(vmSymbols::java_lang_StackOverflowError(), CHECK_0); - initialize_class(vmSymbols::java_lang_IllegalMonitorStateException(), CHECK_0); - initialize_class(vmSymbols::java_lang_IllegalArgumentException(), CHECK_0); - } else { - warning("java.lang.OutOfMemoryError has not been initialized"); - warning("java.lang.NullPointerException has not been initialized"); - warning("java.lang.ClassCastException has not been initialized"); - warning("java.lang.ArrayStoreException has not been initialized"); - warning("java.lang.ArithmeticException has not been initialized"); - warning("java.lang.StackOverflowError has not been initialized"); - warning("java.lang.IllegalArgumentException has not been initialized"); - } + initialize_class(vmSymbols::java_lang_OutOfMemoryError(), CHECK_0); + initialize_class(vmSymbols::java_lang_NullPointerException(), CHECK_0); + initialize_class(vmSymbols::java_lang_ClassCastException(), CHECK_0); + initialize_class(vmSymbols::java_lang_ArrayStoreException(), CHECK_0); + initialize_class(vmSymbols::java_lang_ArithmeticException(), CHECK_0); + initialize_class(vmSymbols::java_lang_StackOverflowError(), CHECK_0); + initialize_class(vmSymbols::java_lang_IllegalMonitorStateException(), CHECK_0); + initialize_class(vmSymbols::java_lang_IllegalArgumentException(), CHECK_0); } // See : bugid 4211085. From 7510da3514997ef6e9fa46f91635dcc2ade43d9e Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Mon, 14 Jan 2013 13:09:59 +0100 Subject: [PATCH 071/204] 8006074: build-infra: Configure fails to find SetEnv.Cmd in microsoft sdk Reviewed-by: tbell, ohair --- common/autoconf/basics_windows.m4 | 4 +- common/autoconf/generated-configure.sh | 126 ++++++++++++------------- 2 files changed, 65 insertions(+), 65 deletions(-) diff --git a/common/autoconf/basics_windows.m4 b/common/autoconf/basics_windows.m4 index c7f3d5213ee..d0c48ae7c25 100644 --- a/common/autoconf/basics_windows.m4 +++ b/common/autoconf/basics_windows.m4 @@ -175,7 +175,7 @@ AC_DEFUN([BASIC_FIXUP_EXECUTABLE_CYGWIN], # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -191,7 +191,7 @@ AC_DEFUN([BASIC_FIXUP_EXECUTABLE_CYGWIN], # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index d210623a4a0..ff6a41fc001 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -3697,7 +3697,7 @@ fi #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1357897535 +DATE_WHEN_GENERATED=1358165331 ############################################################################### # @@ -8164,7 +8164,7 @@ $as_echo "$as_me: Found GNU make version $MAKE_VERSION_STRING at $MAKE_CANDIDATE # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -8180,7 +8180,7 @@ $as_echo "$as_me: Found GNU make version $MAKE_VERSION_STRING at $MAKE_CANDIDATE # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -8521,7 +8521,7 @@ $as_echo "$as_me: Found GNU make version $MAKE_VERSION_STRING at $MAKE_CANDIDATE # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -8537,7 +8537,7 @@ $as_echo "$as_me: Found GNU make version $MAKE_VERSION_STRING at $MAKE_CANDIDATE # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -8875,7 +8875,7 @@ $as_echo "$as_me: Found GNU make version $MAKE_VERSION_STRING at $MAKE_CANDIDATE # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -8891,7 +8891,7 @@ $as_echo "$as_me: Found GNU make version $MAKE_VERSION_STRING at $MAKE_CANDIDATE # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -9234,7 +9234,7 @@ $as_echo "$as_me: Found GNU make version $MAKE_VERSION_STRING at $MAKE_CANDIDATE # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -9250,7 +9250,7 @@ $as_echo "$as_me: Found GNU make version $MAKE_VERSION_STRING at $MAKE_CANDIDATE # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -9587,7 +9587,7 @@ $as_echo "$as_me: Found GNU make version $MAKE_VERSION_STRING at $MAKE_CANDIDATE # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -9603,7 +9603,7 @@ $as_echo "$as_me: Found GNU make version $MAKE_VERSION_STRING at $MAKE_CANDIDATE # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -16404,7 +16404,7 @@ $as_echo "$as_me: Warning: $VCVARSFILE is missing, this is probably Visual Studi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -16420,7 +16420,7 @@ $as_echo "$as_me: Warning: $VCVARSFILE is missing, this is probably Visual Studi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -17004,7 +17004,7 @@ done # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -17020,7 +17020,7 @@ done # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -17315,7 +17315,7 @@ done # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -17331,7 +17331,7 @@ done # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -17621,7 +17621,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -17637,7 +17637,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -18219,7 +18219,7 @@ done # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -18235,7 +18235,7 @@ done # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -18655,7 +18655,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -18671,7 +18671,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -19788,7 +19788,7 @@ done # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -19804,7 +19804,7 @@ done # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -20224,7 +20224,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -20240,7 +20240,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -21125,7 +21125,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -21141,7 +21141,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -21506,7 +21506,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -21522,7 +21522,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -21853,7 +21853,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -21869,7 +21869,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -22190,7 +22190,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -22206,7 +22206,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -22511,7 +22511,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -22527,7 +22527,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -22885,7 +22885,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -22901,7 +22901,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -23191,7 +23191,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -23207,7 +23207,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -23602,7 +23602,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -23618,7 +23618,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -24002,7 +24002,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -24018,7 +24018,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -24331,7 +24331,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -24347,7 +24347,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -24648,7 +24648,7 @@ done # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -24664,7 +24664,7 @@ done # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -24954,7 +24954,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -24970,7 +24970,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -25260,7 +25260,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -25276,7 +25276,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -25619,7 +25619,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -25635,7 +25635,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -25977,7 +25977,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -25993,7 +25993,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -26350,7 +26350,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -26366,7 +26366,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -26721,7 +26721,7 @@ if test "x$OBJDUMP" != x; then # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -26737,7 +26737,7 @@ if test "x$OBJDUMP" != x; then # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -27030,7 +27030,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi @@ -27046,7 +27046,7 @@ fi # bat and cmd files are not always considered executable in cygwin causing which # to not find them if test "x$new_path" = x \ - && test "x`$ECHO \"$path\" | $GREP -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ + && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \ && test "x`$LS \"$path\" 2>/dev/null`" != x; then new_path=`$CYGPATH -u "$path"` fi From 73b452e94143914226bafc2ac86f16c276aa1dae Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy Date: Mon, 14 Jan 2013 08:32:29 -0500 Subject: [PATCH 072/204] 7166409: bug4331515.java fail with NullPointerException on ubuntu10.04-x86 for JDK8 Reviewed-by: serb --- .../com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java index 7d5e237948c..6213ac1e0c0 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java @@ -2619,13 +2619,15 @@ public class WindowsLookAndFeel extends BasicLookAndFeel private static class FocusColorProperty extends DesktopProperty { public FocusColorProperty () { - // Fallback value is never used bacause of the configureValue method doesn't return null + // Fallback value is never used because of the configureValue method doesn't return null super("win.3d.backgroundColor", Color.BLACK); } @Override protected Object configureValue(Object value) { - if (! ((Boolean)Toolkit.getDefaultToolkit().getDesktopProperty("win.highContrast.on")).booleanValue()){ + Object highContrastOn = Toolkit.getDefaultToolkit(). + getDesktopProperty("win.highContrast.on"); + if (highContrastOn == null || !((Boolean) highContrastOn).booleanValue()) { return Color.BLACK; } return Color.BLACK.equals(value) ? Color.WHITE : Color.BLACK; From 0614ed6542613326b7f46121e3ef1be8e7a01c59 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 14 Jan 2013 15:17:47 +0100 Subject: [PATCH 073/204] 8003985: Support @Contended Annotation - JEP 142 HotSpot changes to support @Contended annotation. Reviewed-by: coleenp, kvn, jrose --- .../sun/jvm/hotspot/oops/InstanceKlass.java | 17 +- hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp | 7 + hotspot/src/cpu/x86/vm/vm_version_x86.cpp | 7 + .../share/vm/classfile/classFileParser.cpp | 451 +++++++++++++++--- .../share/vm/classfile/classFileParser.hpp | 22 +- hotspot/src/share/vm/classfile/vmSymbols.hpp | 5 +- hotspot/src/share/vm/oops/fieldInfo.hpp | 144 +++++- hotspot/src/share/vm/oops/fieldStreams.hpp | 17 + hotspot/src/share/vm/oops/instanceKlass.hpp | 14 +- hotspot/src/share/vm/runtime/globals.hpp | 14 +- hotspot/src/share/vm/runtime/vmStructs.cpp | 11 +- 11 files changed, 617 insertions(+), 92 deletions(-) diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java index ba07fa34800..7052f8a2d18 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java @@ -52,6 +52,8 @@ public class InstanceKlass extends Klass { private static int LOW_OFFSET; private static int HIGH_OFFSET; private static int FIELD_SLOTS; + private static short FIELDINFO_TAG_SIZE; + private static short FIELDINFO_TAG_OFFSET; // ClassState constants private static int CLASS_STATE_ALLOCATED; @@ -96,9 +98,12 @@ public class InstanceKlass extends Klass { NAME_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::name_index_offset").intValue(); SIGNATURE_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::signature_index_offset").intValue(); INITVAL_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::initval_index_offset").intValue(); - LOW_OFFSET = db.lookupIntConstant("FieldInfo::low_offset").intValue(); - HIGH_OFFSET = db.lookupIntConstant("FieldInfo::high_offset").intValue(); + LOW_OFFSET = db.lookupIntConstant("FieldInfo::low_packed_offset").intValue(); + HIGH_OFFSET = db.lookupIntConstant("FieldInfo::high_packed_offset").intValue(); FIELD_SLOTS = db.lookupIntConstant("FieldInfo::field_slots").intValue(); + FIELDINFO_TAG_SIZE = db.lookupIntConstant("FIELDINFO_TAG_SIZE").shortValue(); + FIELDINFO_TAG_OFFSET = db.lookupIntConstant("FIELDINFO_TAG_OFFSET").shortValue(); + // read ClassState constants CLASS_STATE_ALLOCATED = db.lookupIntConstant("InstanceKlass::allocated").intValue(); CLASS_STATE_LOADED = db.lookupIntConstant("InstanceKlass::loaded").intValue(); @@ -314,8 +319,12 @@ public class InstanceKlass extends Klass { public int getFieldOffset(int index) { U2Array fields = getFields(); - return VM.getVM().buildIntFromShorts(fields.at(index * FIELD_SLOTS + LOW_OFFSET), - fields.at(index * FIELD_SLOTS + HIGH_OFFSET)); + short lo = fields.at(index * FIELD_SLOTS + LOW_OFFSET); + short hi = fields.at(index * FIELD_SLOTS + HIGH_OFFSET); + if ((lo & FIELDINFO_TAG_SIZE) == FIELDINFO_TAG_OFFSET) { + return VM.getVM().buildIntFromShorts(lo, hi) >> FIELDINFO_TAG_SIZE; + } + throw new RuntimeException("should not reach here"); } // Accessors for declared fields diff --git a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp index 7d3becef336..03670106924 100644 --- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp @@ -259,6 +259,10 @@ void VM_Version::initialize() { if (!has_vis1()) // Drop to 0 if no VIS1 support UseVIS = 0; + if (FLAG_IS_DEFAULT(ContendedPaddingWidth) && + (cache_line_size > ContendedPaddingWidth)) + ContendedPaddingWidth = cache_line_size; + #ifndef PRODUCT if (PrintMiscellaneous && Verbose) { tty->print("Allocation"); @@ -286,6 +290,9 @@ void VM_Version::initialize() { if (PrefetchFieldsAhead > 0) { tty->print_cr("PrefetchFieldsAhead %d", PrefetchFieldsAhead); } + if (ContendedPaddingWidth > 0) { + tty->print_cr("ContendedPaddingWidth %d", ContendedPaddingWidth); + } } #endif // PRODUCT } diff --git a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp index fc046676739..41f5ec2cdc7 100644 --- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp +++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp @@ -734,6 +734,10 @@ void VM_Version::get_processor_features() { PrefetchFieldsAhead = prefetch_fields_ahead(); #endif + if (FLAG_IS_DEFAULT(ContendedPaddingWidth) && + (cache_line_size > ContendedPaddingWidth)) + ContendedPaddingWidth = cache_line_size; + #ifndef PRODUCT if (PrintMiscellaneous && Verbose) { tty->print_cr("Logical CPUs per core: %u", @@ -780,6 +784,9 @@ void VM_Version::get_processor_features() { if (PrefetchFieldsAhead > 0) { tty->print_cr("PrefetchFieldsAhead %d", PrefetchFieldsAhead); } + if (ContendedPaddingWidth > 0) { + tty->print_cr("ContendedPaddingWidth %d", ContendedPaddingWidth); + } } #endif // !PRODUCT } diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index efb6138e583..af9700f25cb 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -970,6 +970,12 @@ void ClassFileParser::parse_field_attributes(ClassLoaderData* loader_data, runtime_visible_annotations_length = attribute_length; runtime_visible_annotations = cfs->get_u1_buffer(); assert(runtime_visible_annotations != NULL, "null visible annotations"); + parse_annotations(loader_data, + runtime_visible_annotations, + runtime_visible_annotations_length, + cp, + parsed_annotations, + CHECK); cfs->skip_u1(runtime_visible_annotations_length, CHECK); } else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { runtime_invisible_annotations_length = attribute_length; @@ -1216,19 +1222,16 @@ Array* ClassFileParser::parse_fields(ClassLoaderData* loader_data, field->initialize(access_flags.as_short(), name_index, signature_index, - constantvalue_index, - 0); - if (parsed_annotations.has_any_annotations()) - parsed_annotations.apply_to(field); - + constantvalue_index); BasicType type = cp->basic_type_for_signature_at(signature_index); // Remember how many oops we encountered and compute allocation type FieldAllocationType atype = fac->update(is_static, type); + field->set_allocation_type(atype); - // The correct offset is computed later (all oop fields will be located together) - // We temporarily store the allocation type in the offset field - field->set_offset(atype); + // After field is initialized with type, we can augment it with aux info + if (parsed_annotations.has_any_annotations()) + parsed_annotations.apply_to(field); } int index = length; @@ -1259,17 +1262,13 @@ Array* ClassFileParser::parse_fields(ClassLoaderData* loader_data, field->initialize(JVM_ACC_FIELD_INTERNAL, injected[n].name_index, injected[n].signature_index, - 0, 0); BasicType type = FieldType::basic_type(injected[n].signature()); // Remember how many oops we encountered and compute allocation type FieldAllocationType atype = fac->update(false, type); - - // The correct offset is computed later (all oop fields will be located together) - // We temporarily store the allocation type in the offset field - field->set_offset(atype); + field->set_allocation_type(atype); index++; } } @@ -1735,7 +1734,8 @@ int ClassFileParser::skip_annotation_value(u1* buffer, int limit, int index) { } // Sift through annotations, looking for those significant to the VM: -void ClassFileParser::parse_annotations(u1* buffer, int limit, +void ClassFileParser::parse_annotations(ClassLoaderData* loader_data, + u1* buffer, int limit, constantPoolHandle cp, ClassFileParser::AnnotationCollector* coll, TRAPS) { @@ -1752,9 +1752,12 @@ void ClassFileParser::parse_annotations(u1* buffer, int limit, e_type_off = 7, // utf8 such as 'Ljava/lang/annotation/RetentionPolicy;' e_con_off = 9, // utf8 payload, such as 'SOURCE', 'CLASS', 'RUNTIME' e_size = 11, // end of 'e' annotation - c_tag_val = 'c', - c_con_off = 7, // utf8 payload, such as 'I' or 'Ljava/lang/String;' + c_tag_val = 'c', // payload is type + c_con_off = 7, // utf8 payload, such as 'I' c_size = 9, // end of 'c' annotation + s_tag_val = 's', // payload is String + s_con_off = 7, // utf8 payload, such as 'Ljava/lang/String;' + s_size = 9, min_size = 6 // smallest possible size (zero members) }; while ((--nann) >= 0 && (index-2 + min_size <= limit)) { @@ -1773,57 +1776,65 @@ void ClassFileParser::parse_annotations(u1* buffer, int limit, } // Here is where parsing particular annotations will take place. - AnnotationCollector::ID id = coll->annotation_index(aname); + AnnotationCollector::ID id = coll->annotation_index(loader_data, aname); if (id == AnnotationCollector::_unknown) continue; coll->set_annotation(id); - // If there are no values, just set the bit and move on: - if (count == 0) continue; - // For the record, here is how annotation payloads can be collected. - // Suppose we want to capture @Retention.value. Here is how: - //if (id == AnnotationCollector::_class_Retention) { - // Symbol* payload = NULL; - // if (count == 1 - // && e_size == (index0 - index) // match size - // && e_tag_val == *(abase + tag_off) - // && (check_symbol_at(cp, Bytes::get_Java_u2(abase + e_type_off)) - // == vmSymbols::RetentionPolicy_signature()) - // && member == vmSymbols::value_name()) { - // payload = check_symbol_at(cp, Bytes::get_Java_u2(abase + e_con_off)); - // } - // check_property(payload != NULL, - // "Invalid @Retention annotation at offset %u in class file %s", - // index0, CHECK); - // if (payload != NULL) { - // payload->increment_refcount(); - // coll->_class_RetentionPolicy = payload; - // } - //} + if (id == AnnotationCollector::_sun_misc_Contended) { + if (count == 1 + && s_size == (index - index0) // match size + && s_tag_val == *(abase + tag_off) + && member == vmSymbols::value_name()) { + u2 group_index = Bytes::get_Java_u2(abase + s_con_off); + coll->set_contended_group(group_index); + } else { + coll->set_contended_group(0); // default contended group + } + coll->set_contended(true); + } else { + coll->set_contended(false); + } } } -ClassFileParser::AnnotationCollector::ID ClassFileParser::AnnotationCollector::annotation_index(Symbol* name) { +ClassFileParser::AnnotationCollector::ID +ClassFileParser::AnnotationCollector::annotation_index(ClassLoaderData* loader_data, + Symbol* name) { vmSymbols::SID sid = vmSymbols::find_sid(name); + bool privileged = false; + if (loader_data->is_the_null_class_loader_data()) { + // Privileged code can use all annotations. Other code silently drops some. + privileged = true; + } switch (sid) { case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_ForceInline_signature): if (_location != _in_method) break; // only allow for methods + if (!privileged) break; // only allow in privileged code return _method_ForceInline; case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_DontInline_signature): if (_location != _in_method) break; // only allow for methods + if (!privileged) break; // only allow in privileged code return _method_DontInline; case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Compiled_signature): if (_location != _in_method) break; // only allow for methods + if (!privileged) break; // only allow in privileged code return _method_LambdaForm_Compiled; case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Hidden_signature): if (_location != _in_method) break; // only allow for methods + if (!privileged) break; // only allow in privileged code return _method_LambdaForm_Hidden; + case vmSymbols::VM_SYMBOL_ENUM_NAME(sun_misc_Contended_signature): + if (_location != _in_field && _location != _in_class) break; // only allow for fields and classes + if (!EnableContended || (RestrictContended && !privileged)) break; // honor privileges + return _sun_misc_Contended; default: break; } return AnnotationCollector::_unknown; } void ClassFileParser::FieldAnnotationCollector::apply_to(FieldInfo* f) { - fatal("no field annotations yet"); + if (is_contended()) + f->set_contended_group(contended_group()); } void ClassFileParser::MethodAnnotationCollector::apply_to(methodHandle m) { @@ -1838,7 +1849,7 @@ void ClassFileParser::MethodAnnotationCollector::apply_to(methodHandle m) { } void ClassFileParser::ClassAnnotationCollector::apply_to(instanceKlassHandle k) { - fatal("no class annotations yet"); + k->set_is_contended(is_contended()); } @@ -2181,7 +2192,8 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data, runtime_visible_annotations_length = method_attribute_length; runtime_visible_annotations = cfs->get_u1_buffer(); assert(runtime_visible_annotations != NULL, "null visible annotations"); - parse_annotations(runtime_visible_annotations, + parse_annotations(loader_data, + runtime_visible_annotations, runtime_visible_annotations_length, cp, &parsed_annotations, CHECK_(nullHandle)); cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle)); @@ -2886,7 +2898,8 @@ void ClassFileParser::parse_classfile_attributes(ClassLoaderData* loader_data, runtime_visible_annotations_length = attribute_length; runtime_visible_annotations = cfs->get_u1_buffer(); assert(runtime_visible_annotations != NULL, "null visible annotations"); - parse_annotations(runtime_visible_annotations, + parse_annotations(loader_data, + runtime_visible_annotations, runtime_visible_annotations_length, cp, parsed_annotations, @@ -3405,18 +3418,21 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, // Size of Java itable (in words) itable_size = access_flags.is_interface() ? 0 : klassItable::compute_itable_size(transitive_interfaces); + // get the padding width from the option + // TODO: Ask VM about specific CPU we are running on + int pad_size = ContendedPaddingWidth; + // Field size and offset computation int nonstatic_field_size = super_klass() == NULL ? 0 : super_klass->nonstatic_field_size(); #ifndef PRODUCT int orig_nonstatic_field_size = 0; #endif - int static_field_size = 0; int next_static_oop_offset; int next_static_double_offset; int next_static_word_offset; int next_static_short_offset; int next_static_byte_offset; - int next_static_type_offset; + int next_static_padded_offset; int next_nonstatic_oop_offset; int next_nonstatic_double_offset; int next_nonstatic_word_offset; @@ -3426,11 +3442,36 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, int first_nonstatic_oop_offset; int first_nonstatic_field_offset; int next_nonstatic_field_offset; + int next_nonstatic_padded_offset; + + // Count the contended fields by type. + int static_contended_count = 0; + int nonstatic_contended_count = 0; + FieldAllocationCount fac_contended; + for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) { + FieldAllocationType atype = (FieldAllocationType) fs.allocation_type(); + if (fs.is_contended()) { + fac_contended.count[atype]++; + if (fs.access_flags().is_static()) { + static_contended_count++; + } else { + nonstatic_contended_count++; + } + } + } + int contended_count = static_contended_count + nonstatic_contended_count; + // Calculate the starting byte offsets next_static_oop_offset = InstanceMirrorKlass::offset_of_static_fields(); + + // class is contended, pad before all the fields + if (parsed_annotations.is_contended()) { + next_static_oop_offset += pad_size; + } + next_static_double_offset = next_static_oop_offset + - (fac.count[STATIC_OOP] * heapOopSize); + ((fac.count[STATIC_OOP] - fac_contended.count[STATIC_OOP]) * heapOopSize); if ( fac.count[STATIC_DOUBLE] && (Universe::field_type_should_be_aligned(T_DOUBLE) || Universe::field_type_should_be_aligned(T_LONG)) ) { @@ -3438,25 +3479,29 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, } next_static_word_offset = next_static_double_offset + - (fac.count[STATIC_DOUBLE] * BytesPerLong); + ((fac.count[STATIC_DOUBLE] - fac_contended.count[STATIC_DOUBLE]) * BytesPerLong); next_static_short_offset = next_static_word_offset + - (fac.count[STATIC_WORD] * BytesPerInt); + ((fac.count[STATIC_WORD] - fac_contended.count[STATIC_WORD]) * BytesPerInt); next_static_byte_offset = next_static_short_offset + - (fac.count[STATIC_SHORT] * BytesPerShort); - next_static_type_offset = align_size_up((next_static_byte_offset + - fac.count[STATIC_BYTE] ), wordSize ); - static_field_size = (next_static_type_offset - - next_static_oop_offset) / wordSize; + ((fac.count[STATIC_SHORT] - fac_contended.count[STATIC_SHORT]) * BytesPerShort); + next_static_padded_offset = next_static_byte_offset + + ((fac.count[STATIC_BYTE] - fac_contended.count[STATIC_BYTE]) * 1); first_nonstatic_field_offset = instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size * heapOopSize; + + // class is contended, pad before all the fields + if (parsed_annotations.is_contended()) { + first_nonstatic_field_offset += pad_size; + } + next_nonstatic_field_offset = first_nonstatic_field_offset; - unsigned int nonstatic_double_count = fac.count[NONSTATIC_DOUBLE]; - unsigned int nonstatic_word_count = fac.count[NONSTATIC_WORD]; - unsigned int nonstatic_short_count = fac.count[NONSTATIC_SHORT]; - unsigned int nonstatic_byte_count = fac.count[NONSTATIC_BYTE]; - unsigned int nonstatic_oop_count = fac.count[NONSTATIC_OOP]; + unsigned int nonstatic_double_count = fac.count[NONSTATIC_DOUBLE] - fac_contended.count[NONSTATIC_DOUBLE]; + unsigned int nonstatic_word_count = fac.count[NONSTATIC_WORD] - fac_contended.count[NONSTATIC_WORD]; + unsigned int nonstatic_short_count = fac.count[NONSTATIC_SHORT] - fac_contended.count[NONSTATIC_SHORT]; + unsigned int nonstatic_byte_count = fac.count[NONSTATIC_BYTE] - fac_contended.count[NONSTATIC_BYTE]; + unsigned int nonstatic_oop_count = fac.count[NONSTATIC_OOP] - fac_contended.count[NONSTATIC_OOP]; bool super_has_nonstatic_fields = (super_klass() != NULL && super_klass->has_nonstatic_fields()); @@ -3529,12 +3574,12 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, } if( allocation_style == 0 ) { - // Fields order: oops, longs/doubles, ints, shorts/chars, bytes + // Fields order: oops, longs/doubles, ints, shorts/chars, bytes, padded fields next_nonstatic_oop_offset = next_nonstatic_field_offset; next_nonstatic_double_offset = next_nonstatic_oop_offset + (nonstatic_oop_count * heapOopSize); } else if( allocation_style == 1 ) { - // Fields order: longs/doubles, ints, shorts/chars, bytes, oops + // Fields order: longs/doubles, ints, shorts/chars, bytes, oops, padded fields next_nonstatic_double_offset = next_nonstatic_field_offset; } else if( allocation_style == 2 ) { // Fields allocation: oops fields in super and sub classes are together. @@ -3613,27 +3658,33 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, (nonstatic_word_count * BytesPerInt); next_nonstatic_byte_offset = next_nonstatic_short_offset + (nonstatic_short_count * BytesPerShort); + next_nonstatic_padded_offset = next_nonstatic_byte_offset + + nonstatic_byte_count; - int notaligned_offset; - if( allocation_style == 0 ) { - notaligned_offset = next_nonstatic_byte_offset + nonstatic_byte_count; - } else { // allocation_style == 1 - next_nonstatic_oop_offset = next_nonstatic_byte_offset + nonstatic_byte_count; + // let oops jump before padding with this allocation style + if( allocation_style == 1 ) { + next_nonstatic_oop_offset = next_nonstatic_padded_offset; if( nonstatic_oop_count > 0 ) { next_nonstatic_oop_offset = align_size_up(next_nonstatic_oop_offset, heapOopSize); } - notaligned_offset = next_nonstatic_oop_offset + (nonstatic_oop_count * heapOopSize); + next_nonstatic_padded_offset = next_nonstatic_oop_offset + (nonstatic_oop_count * heapOopSize); } - next_nonstatic_type_offset = align_size_up(notaligned_offset, heapOopSize ); - nonstatic_field_size = nonstatic_field_size + ((next_nonstatic_type_offset - - first_nonstatic_field_offset)/heapOopSize); // Iterate over fields again and compute correct offsets. // The field allocation type was temporarily stored in the offset slot. // oop fields are located before non-oop fields (static and non-static). for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) { + + // skip already laid out fields + if (fs.is_offset_set()) continue; + + // contended fields are handled below + if (fs.is_contended()) continue; + int real_offset; - FieldAllocationType atype = (FieldAllocationType) fs.offset(); + FieldAllocationType atype = (FieldAllocationType) fs.allocation_type(); + + // pack the rest of the fields switch (atype) { case STATIC_OOP: real_offset = next_static_oop_offset; @@ -3722,13 +3773,225 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, fs.set_offset(real_offset); } + + // Handle the contended cases. + // + // Each contended field should not intersect the cache line with another contended field. + // In the absence of alignment information, we end up with pessimistically separating + // the fields with full-width padding. + // + // Additionally, this should not break alignment for the fields, so we round the alignment up + // for each field. + if (contended_count > 0) { + + // if there is at least one contended field, we need to have pre-padding for them + if (nonstatic_contended_count > 0) { + next_nonstatic_padded_offset += pad_size; + } + + // collect all contended groups + BitMap bm(cp->size()); + for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) { + // skip already laid out fields + if (fs.is_offset_set()) continue; + + if (fs.is_contended()) { + bm.set_bit(fs.contended_group()); + } + } + + int current_group = -1; + while ((current_group = (int)bm.get_next_one_offset(current_group + 1)) != (int)bm.size()) { + + for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) { + + // skip already laid out fields + if (fs.is_offset_set()) continue; + + // skip non-contended fields and fields from different group + if (!fs.is_contended() || (fs.contended_group() != current_group)) continue; + + // handle statics below + if (fs.access_flags().is_static()) continue; + + int real_offset; + FieldAllocationType atype = (FieldAllocationType) fs.allocation_type(); + + switch (atype) { + case NONSTATIC_BYTE: + next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, 1); + real_offset = next_nonstatic_padded_offset; + next_nonstatic_padded_offset += 1; + break; + + case NONSTATIC_SHORT: + next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, BytesPerShort); + real_offset = next_nonstatic_padded_offset; + next_nonstatic_padded_offset += BytesPerShort; + break; + + case NONSTATIC_WORD: + next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, BytesPerInt); + real_offset = next_nonstatic_padded_offset; + next_nonstatic_padded_offset += BytesPerInt; + break; + + case NONSTATIC_DOUBLE: + next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, BytesPerLong); + real_offset = next_nonstatic_padded_offset; + next_nonstatic_padded_offset += BytesPerLong; + break; + + case NONSTATIC_OOP: + next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, heapOopSize); + real_offset = next_nonstatic_padded_offset; + next_nonstatic_padded_offset += heapOopSize; + + // Create new oop map + nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset; + nonstatic_oop_counts [nonstatic_oop_map_count] = 1; + nonstatic_oop_map_count += 1; + if( first_nonstatic_oop_offset == 0 ) { // Undefined + first_nonstatic_oop_offset = real_offset; + } + break; + + default: + ShouldNotReachHere(); + } + + if (fs.contended_group() == 0) { + // Contended group defines the equivalence class over the fields: + // the fields within the same contended group are not inter-padded. + // The only exception is default group, which does not incur the + // equivalence, and so requires intra-padding. + next_nonstatic_padded_offset += pad_size; + } + + fs.set_offset(real_offset); + } // for + + // Start laying out the next group. + // Note that this will effectively pad the last group in the back; + // this is expected to alleviate memory contention effects for + // subclass fields and/or adjacent object. + // If this was the default group, the padding is already in place. + if (current_group != 0) { + next_nonstatic_padded_offset += pad_size; + } + } + + // handle static fields + + // if there is at least one contended field, we need to have pre-padding for them + if (static_contended_count > 0) { + next_static_padded_offset += pad_size; + } + + current_group = -1; + while ((current_group = (int)bm.get_next_one_offset(current_group + 1)) != (int)bm.size()) { + + for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) { + + // skip already laid out fields + if (fs.is_offset_set()) continue; + + // skip non-contended fields and fields from different group + if (!fs.is_contended() || (fs.contended_group() != current_group)) continue; + + // non-statics already handled above + if (!fs.access_flags().is_static()) continue; + + int real_offset; + FieldAllocationType atype = (FieldAllocationType) fs.allocation_type(); + + switch (atype) { + + case STATIC_BYTE: + next_static_padded_offset = align_size_up(next_static_padded_offset, 1); + real_offset = next_static_padded_offset; + next_static_padded_offset += 1; + break; + + case STATIC_SHORT: + next_static_padded_offset = align_size_up(next_static_padded_offset, BytesPerShort); + real_offset = next_static_padded_offset; + next_static_padded_offset += BytesPerShort; + break; + + case STATIC_WORD: + next_static_padded_offset = align_size_up(next_static_padded_offset, BytesPerInt); + real_offset = next_static_padded_offset; + next_static_padded_offset += BytesPerInt; + break; + + case STATIC_DOUBLE: + next_static_padded_offset = align_size_up(next_static_padded_offset, BytesPerLong); + real_offset = next_static_padded_offset; + next_static_padded_offset += BytesPerLong; + break; + + case STATIC_OOP: + next_static_padded_offset = align_size_up(next_static_padded_offset, heapOopSize); + real_offset = next_static_padded_offset; + next_static_padded_offset += heapOopSize; + break; + + default: + ShouldNotReachHere(); + } + + if (fs.contended_group() == 0) { + // Contended group defines the equivalence class over the fields: + // the fields within the same contended group are not inter-padded. + // The only exception is default group, which does not incur the + // equivalence, and so requires intra-padding. + next_static_padded_offset += pad_size; + } + + fs.set_offset(real_offset); + } // for + + // Start laying out the next group. + // Note that this will effectively pad the last group in the back; + // this is expected to alleviate memory contention effects for + // subclass fields and/or adjacent object. + // If this was the default group, the padding is already in place. + if (current_group != 0) { + next_static_padded_offset += pad_size; + } + + } + + } // handle contended + // Size of instances int instance_size; + int notaligned_offset = next_nonstatic_padded_offset; + + // Entire class is contended, pad in the back. + // This helps to alleviate memory contention effects for subclass fields + // and/or adjacent object. + if (parsed_annotations.is_contended()) { + notaligned_offset += pad_size; + next_static_padded_offset += pad_size; + } + + int next_static_type_offset = align_size_up(next_static_padded_offset, wordSize); + int static_field_size = (next_static_type_offset - + InstanceMirrorKlass::offset_of_static_fields()) / wordSize; + + next_nonstatic_type_offset = align_size_up(notaligned_offset, heapOopSize ); + nonstatic_field_size = nonstatic_field_size + ((next_nonstatic_type_offset + - first_nonstatic_field_offset)/heapOopSize); + next_nonstatic_type_offset = align_size_up(notaligned_offset, wordSize ); instance_size = align_object_size(next_nonstatic_type_offset / wordSize); - assert(instance_size == align_object_size(align_size_up((instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize), wordSize) / wordSize), "consistent layout helper value"); + assert(instance_size == align_object_size(align_size_up( + (instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize + ((parsed_annotations.is_contended()) ? pad_size : 0)), + wordSize) / wordSize), "consistent layout helper value"); // Number of non-static oop map blocks allocated at end of klass. const unsigned int total_oop_map_count = @@ -4008,6 +4271,18 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, } #endif +#ifndef PRODUCT + if (PrintFieldLayout) { + print_field_layout(name, + fields, + cp, + instance_size, + first_nonstatic_field_offset, + next_nonstatic_field_offset, + next_static_type_offset); + } +#endif + // preserve result across HandleMark preserve_this_klass = this_klass(); } @@ -4020,6 +4295,38 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, return this_klass; } +void ClassFileParser::print_field_layout(Symbol* name, + Array* fields, + constantPoolHandle cp, + int instance_size, + int instance_fields_start, + int instance_fields_end, + int static_fields_end) { + tty->print("%s: field layout\n", name->as_klass_external_name()); + tty->print(" @%3d %s\n", instance_fields_start, "--- instance fields start ---"); + for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) { + if (!fs.access_flags().is_static()) { + tty->print(" @%3d \"%s\" %s\n", + fs.offset(), + fs.name()->as_klass_external_name(), + fs.signature()->as_klass_external_name()); + } + } + tty->print(" @%3d %s\n", instance_fields_end, "--- instance fields end ---"); + tty->print(" @%3d %s\n", instance_size * wordSize, "--- instance ends ---"); + tty->print(" @%3d %s\n", InstanceMirrorKlass::offset_of_static_fields(), "--- static fields start ---"); + for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) { + if (fs.access_flags().is_static()) { + tty->print(" @%3d \"%s\" %s\n", + fs.offset(), + fs.name()->as_klass_external_name(), + fs.signature()->as_klass_external_name()); + } + } + tty->print(" @%3d %s\n", static_fields_end, "--- static fields end ---"); + tty->print("\n"); +} + unsigned int ClassFileParser::compute_oop_map_count(instanceKlassHandle super, unsigned int nonstatic_oop_map_count, diff --git a/hotspot/src/share/vm/classfile/classFileParser.hpp b/hotspot/src/share/vm/classfile/classFileParser.hpp index 5a5d3fc397a..cc0193a15f5 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.hpp +++ b/hotspot/src/share/vm/classfile/classFileParser.hpp @@ -95,17 +95,20 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC { _method_DontInline, _method_LambdaForm_Compiled, _method_LambdaForm_Hidden, + _sun_misc_Contended, _annotation_LIMIT }; const Location _location; int _annotations_present; + u2 _contended_group; + AnnotationCollector(Location location) : _location(location), _annotations_present(0) { assert((int)_annotation_LIMIT <= (int)sizeof(_annotations_present) * BitsPerByte, ""); } // If this annotation name has an ID, report it (or _none). - ID annotation_index(Symbol* name); + ID annotation_index(ClassLoaderData* loader_data, Symbol* name); // Set the annotation name: void set_annotation(ID id) { assert((int)id >= 0 && (int)id < (int)_annotation_LIMIT, "oob"); @@ -114,6 +117,12 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC { // Report if the annotation is present. bool has_any_annotations() { return _annotations_present != 0; } bool has_annotation(ID id) { return (nth_bit((int)id) & _annotations_present) != 0; } + + void set_contended_group(u2 group) { _contended_group = group; } + u2 contended_group() { return _contended_group; } + + void set_contended(bool contended) { set_annotation(_sun_misc_Contended); } + bool is_contended() { return has_annotation(_sun_misc_Contended); } }; class FieldAnnotationCollector: public AnnotationCollector { public: @@ -177,6 +186,14 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC { Array** fields_type_annotations, u2* java_fields_count_ptr, TRAPS); + void print_field_layout(Symbol* name, + Array* fields, + constantPoolHandle cp, + int instance_size, + int instance_fields_start, + int instance_fields_end, + int static_fields_end); + // Method parsing methodHandle parse_method(ClassLoaderData* loader_data, constantPoolHandle cp, @@ -247,7 +264,8 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC { int runtime_invisible_annotations_length, TRAPS); int skip_annotation(u1* buffer, int limit, int index); int skip_annotation_value(u1* buffer, int limit, int index); - void parse_annotations(u1* buffer, int limit, constantPoolHandle cp, + void parse_annotations(ClassLoaderData* loader_data, + u1* buffer, int limit, constantPoolHandle cp, /* Results (currently, only one result is supported): */ AnnotationCollector* result, TRAPS); diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp index e6168ceba2c..e77e5cea2db 100644 --- a/hotspot/src/share/vm/classfile/vmSymbols.hpp +++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp @@ -194,7 +194,10 @@ template(java_lang_VirtualMachineError, "java/lang/VirtualMachineError") \ template(java_lang_StackOverflowError, "java/lang/StackOverflowError") \ template(java_lang_StackTraceElement, "java/lang/StackTraceElement") \ + \ + /* Concurrency support */ \ template(java_util_concurrent_locks_AbstractOwnableSynchronizer, "java/util/concurrent/locks/AbstractOwnableSynchronizer") \ + template(sun_misc_Contended_signature, "Lsun/misc/Contended;") \ \ /* class symbols needed by intrinsics */ \ VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, template, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE) \ @@ -284,7 +287,7 @@ NOT_LP64( do_alias(intptr_signature, int_signature) ) \ LP64_ONLY( do_alias(intptr_signature, long_signature) ) \ template(selectAlternative_signature, "(ZLjava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;") \ - \ + \ /* common method and field names */ \ template(object_initializer_name, "") \ template(class_initializer_name, "") \ diff --git a/hotspot/src/share/vm/oops/fieldInfo.hpp b/hotspot/src/share/vm/oops/fieldInfo.hpp index ee4af47204d..331dc05f37c 100644 --- a/hotspot/src/share/vm/oops/fieldInfo.hpp +++ b/hotspot/src/share/vm/oops/fieldInfo.hpp @@ -43,14 +43,29 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC { public: // fields // Field info extracted from the class file and stored - // as an array of 7 shorts + // as an array of 6 shorts. + +#define FIELDINFO_TAG_SIZE 2 +#define FIELDINFO_TAG_BLANK 0 +#define FIELDINFO_TAG_OFFSET 1 +#define FIELDINFO_TAG_TYPE_PLAIN 2 +#define FIELDINFO_TAG_TYPE_CONTENDED 3 +#define FIELDINFO_TAG_MASK 3 + + // Packed field has the tag, and can be either of: + // hi bits <--------------------------- lo bits + // |---------high---------|---------low---------| + // ..........................................00 - blank + // [------------------offset----------------]01 - real field offset + // ......................[-------type-------]10 - plain field with type + // [--contention_group--][-------type-------]11 - contended field with type and contention group enum FieldOffset { access_flags_offset = 0, name_index_offset = 1, signature_index_offset = 2, initval_index_offset = 3, - low_offset = 4, - high_offset = 5, + low_packed_offset = 4, + high_packed_offset = 5, field_slots = 6 }; @@ -76,17 +91,90 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC { void initialize(u2 access_flags, u2 name_index, u2 signature_index, - u2 initval_index, - u4 offset) { + u2 initval_index) { _shorts[access_flags_offset] = access_flags; _shorts[name_index_offset] = name_index; _shorts[signature_index_offset] = signature_index; _shorts[initval_index_offset] = initval_index; - set_offset(offset); + _shorts[low_packed_offset] = 0; + _shorts[high_packed_offset] = 0; } u2 access_flags() const { return _shorts[access_flags_offset]; } - u4 offset() const { return build_int_from_shorts(_shorts[low_offset], _shorts[high_offset]); } + u4 offset() const { + u2 lo = _shorts[low_packed_offset]; + switch(lo & FIELDINFO_TAG_MASK) { + case FIELDINFO_TAG_OFFSET: + return build_int_from_shorts(_shorts[low_packed_offset], _shorts[high_packed_offset]) >> FIELDINFO_TAG_SIZE; +#ifndef PRODUCT + case FIELDINFO_TAG_TYPE_PLAIN: + ShouldNotReachHere2("Asking offset for the plain type field"); + case FIELDINFO_TAG_TYPE_CONTENDED: + ShouldNotReachHere2("Asking offset for the contended type field"); + case FIELDINFO_TAG_BLANK: + ShouldNotReachHere2("Asking offset for the blank field"); +#endif + } + ShouldNotReachHere(); + return 0; + } + + bool is_contended() const { + u2 lo = _shorts[low_packed_offset]; + switch(lo & FIELDINFO_TAG_MASK) { + case FIELDINFO_TAG_TYPE_PLAIN: + return false; + case FIELDINFO_TAG_TYPE_CONTENDED: + return true; +#ifndef PRODUCT + case FIELDINFO_TAG_OFFSET: + ShouldNotReachHere2("Asking contended flag for the field with offset"); + case FIELDINFO_TAG_BLANK: + ShouldNotReachHere2("Asking contended flag for the blank field"); +#endif + } + ShouldNotReachHere(); + return false; + } + + u2 contended_group() const { + u2 lo = _shorts[low_packed_offset]; + switch(lo & FIELDINFO_TAG_MASK) { + case FIELDINFO_TAG_TYPE_PLAIN: + return 0; + case FIELDINFO_TAG_TYPE_CONTENDED: + return _shorts[high_packed_offset]; +#ifndef PRODUCT + case FIELDINFO_TAG_OFFSET: + ShouldNotReachHere2("Asking the contended group for the field with offset"); + case FIELDINFO_TAG_BLANK: + ShouldNotReachHere2("Asking the contended group for the blank field"); +#endif + } + ShouldNotReachHere(); + return 0; + } + + u2 allocation_type() const { + u2 lo = _shorts[low_packed_offset]; + switch(lo & FIELDINFO_TAG_MASK) { + case FIELDINFO_TAG_TYPE_PLAIN: + case FIELDINFO_TAG_TYPE_CONTENDED: + return (lo >> FIELDINFO_TAG_SIZE); +#ifndef PRODUCT + case FIELDINFO_TAG_OFFSET: + ShouldNotReachHere2("Asking the field type for field with offset"); + case FIELDINFO_TAG_BLANK: + ShouldNotReachHere2("Asking the field type for the blank field"); +#endif + } + ShouldNotReachHere(); + return 0; + } + + bool is_offset_set() const { + return (_shorts[low_packed_offset] & FIELDINFO_TAG_MASK) == FIELDINFO_TAG_OFFSET; + } Symbol* name(constantPoolHandle cp) const { int index = name_index(); @@ -106,8 +194,46 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC { void set_access_flags(u2 val) { _shorts[access_flags_offset] = val; } void set_offset(u4 val) { - _shorts[low_offset] = extract_low_short_from_int(val); - _shorts[high_offset] = extract_high_short_from_int(val); + val = val << FIELDINFO_TAG_SIZE; // make room for tag + _shorts[low_packed_offset] = extract_low_short_from_int(val) | FIELDINFO_TAG_OFFSET; + _shorts[high_packed_offset] = extract_high_short_from_int(val); + } + + void set_allocation_type(int type) { + u2 lo = _shorts[low_packed_offset]; + switch(lo & FIELDINFO_TAG_MASK) { + case FIELDINFO_TAG_BLANK: + _shorts[low_packed_offset] = ((type << FIELDINFO_TAG_SIZE)) & 0xFFFF; + _shorts[low_packed_offset] &= ~FIELDINFO_TAG_MASK; + _shorts[low_packed_offset] |= FIELDINFO_TAG_TYPE_PLAIN; + return; +#ifndef PRODUCT + case FIELDINFO_TAG_TYPE_PLAIN: + case FIELDINFO_TAG_TYPE_CONTENDED: + case FIELDINFO_TAG_OFFSET: + ShouldNotReachHere2("Setting the field type with overwriting"); +#endif + } + ShouldNotReachHere(); + } + + void set_contended_group(u2 val) { + u2 lo = _shorts[low_packed_offset]; + switch(lo & FIELDINFO_TAG_MASK) { + case FIELDINFO_TAG_TYPE_PLAIN: + _shorts[low_packed_offset] |= FIELDINFO_TAG_TYPE_CONTENDED; + _shorts[high_packed_offset] = val; + return; +#ifndef PRODUCT + case FIELDINFO_TAG_TYPE_CONTENDED: + ShouldNotReachHere2("Overwriting contended group"); + case FIELDINFO_TAG_BLANK: + ShouldNotReachHere2("Setting contended group for the blank field"); + case FIELDINFO_TAG_OFFSET: + ShouldNotReachHere2("Setting contended group for field with offset"); +#endif + } + ShouldNotReachHere(); } bool is_internal() const { diff --git a/hotspot/src/share/vm/oops/fieldStreams.hpp b/hotspot/src/share/vm/oops/fieldStreams.hpp index adde764127b..acc590c970c 100644 --- a/hotspot/src/share/vm/oops/fieldStreams.hpp +++ b/hotspot/src/share/vm/oops/fieldStreams.hpp @@ -160,9 +160,26 @@ class FieldStreamBase : public StackObj { return field()->offset(); } + int allocation_type() const { + return field()->allocation_type(); + } + void set_offset(int offset) { field()->set_offset(offset); } + + bool is_offset_set() const { + return field()->is_offset_set(); + } + + bool is_contended() const { + return field()->is_contended(); + } + + int contended_group() const { + return field()->contended_group(); + } + }; // Iterate over only the internal fields diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp index 0d173faa510..31ba745c19d 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.hpp +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp @@ -230,7 +230,8 @@ class InstanceKlass: public Klass { _misc_rewritten = 1 << 0, // methods rewritten. _misc_has_nonstatic_fields = 1 << 1, // for sizing with UseCompressedOops _misc_should_verify_class = 1 << 2, // allow caching of preverification - _misc_is_anonymous = 1 << 3 // has embedded _inner_classes field + _misc_is_anonymous = 1 << 3, // has embedded _inner_classes field + _misc_is_contended = 1 << 4 // marked with contended annotation }; u2 _misc_flags; u2 _minor_version; // minor version number of class file @@ -550,6 +551,17 @@ class InstanceKlass: public Klass { return is_anonymous() ? java_mirror() : class_loader(); } + bool is_contended() const { + return (_misc_flags & _misc_is_contended) != 0; + } + void set_is_contended(bool value) { + if (value) { + _misc_flags |= _misc_is_contended; + } else { + _misc_flags &= ~_misc_is_contended; + } + } + // signers objArrayOop signers() const { return _signers; } void set_signers(objArrayOop s) { klass_oop_store((oop*)&_signers, s); } diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index abdb42a51e2..52c9e7afad5 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -1075,7 +1075,7 @@ class CommandLineFlags { \ product(intx, ClearFPUAtPark, 0, "(Unsafe,Unstable)" ) \ \ - product(intx, hashCode, 0, \ + product(intx, hashCode, 5, \ "(Unstable) select hashCode generation algorithm" ) \ \ product(intx, WorkAroundNPTLTimedWaitHang, 1, \ @@ -1173,6 +1173,18 @@ class CommandLineFlags { notproduct(bool, PrintCompactFieldsSavings, false, \ "Print how many words were saved with CompactFields") \ \ + notproduct(bool, PrintFieldLayout, false, \ + "Print field layout for each class") \ + \ + product(intx, ContendedPaddingWidth, 128, \ + "How many bytes to pad the fields/classes marked @Contended with")\ + \ + product(bool, EnableContended, true, \ + "Enable @Contended annotation support") \ + \ + product(bool, RestrictContended, true, \ + "Restrict @Contended to trusted classes") \ + \ product(bool, UseBiasedLocking, true, \ "Enable biased locking in JVM") \ \ diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index 09d557cdbf9..e4f9cbb3ee0 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -2284,10 +2284,17 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_constant(FieldInfo::name_index_offset) \ declare_constant(FieldInfo::signature_index_offset) \ declare_constant(FieldInfo::initval_index_offset) \ - declare_constant(FieldInfo::low_offset) \ - declare_constant(FieldInfo::high_offset) \ + declare_constant(FieldInfo::low_packed_offset) \ + declare_constant(FieldInfo::high_packed_offset) \ declare_constant(FieldInfo::field_slots) \ \ + /*************************************/ \ + /* FieldInfo tag constants */ \ + /*************************************/ \ + \ + declare_preprocessor_constant("FIELDINFO_TAG_SIZE", FIELDINFO_TAG_SIZE) \ + declare_preprocessor_constant("FIELDINFO_TAG_OFFSET", FIELDINFO_TAG_OFFSET) \ + \ /************************************************/ \ /* InstanceKlass InnerClassAttributeOffset enum */ \ /************************************************/ \ From efc2bb8cee582e87bca24abbf6cd908581965f65 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Mon, 14 Jan 2013 15:30:22 +0100 Subject: [PATCH 074/204] 8006100: build-infra: Bundle up the correct images in jprt Reviewed-by: tbell --- NewMakefile.gmk | 6 ++++-- common/makefiles/Jprt.gmk | 12 +++++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/NewMakefile.gmk b/NewMakefile.gmk index dcd928718df..ce711a80b74 100644 --- a/NewMakefile.gmk +++ b/NewMakefile.gmk @@ -50,8 +50,6 @@ else endif root_dir:=$(dir $(makefile_path)) -include $(root_dir)/common/makefiles/Jprt.gmk - # ... and then we can include our helper functions include $(root_dir)/common/makefiles/MakeHelpers.gmk @@ -80,6 +78,10 @@ $(all_phony_targets): endif endif +# Include this after a potential spec file has been included so that the bundles target +# has access to the spec variables. +include $(root_dir)/common/makefiles/Jprt.gmk + # Here are "global" targets, i.e. targets that can be executed without specifying a single configuration. # If you addd more global targets, please update the variable global_targets in MakeHelpers. diff --git a/common/makefiles/Jprt.gmk b/common/makefiles/Jprt.gmk index 69c7740bd15..78e2096e5df 100644 --- a/common/makefiles/Jprt.gmk +++ b/common/makefiles/Jprt.gmk @@ -26,7 +26,8 @@ # This file is included by the root NewerMakefile and contains targets # and utilities needed by JPRT. -# Utilities used in this Makefile +# Utilities used in this Makefile. Most of this makefile executes without +# the context of a spec file from configure. CAT=cat CMP=cmp CP=cp @@ -177,8 +178,13 @@ $(JPRT_ARCHIVE_BUNDLE): bundles bundles: all @$(call TargetEnter) $(MKDIR) -p $(BUILD_OUTPUT)/bundles - $(CD) $(IMAGES_OUTPUTDIR)/j2sdk-image && $(ZIP) -q -r $(BUILD_OUTPUT)/bundles/j2sdk-image.zip . - $(CD) $(IMAGES_OUTPUTDIR)/j2re-image && $(ZIP) -q -r $(BUILD_OUTPUT)/bundles/j2re-image.zip . +ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_BITS),solaris-64) + $(CD) $(JDK_OVERLAY_IMAGE_DIR) && $(ZIP) -q -r $(BUILD_OUTPUT)/bundles/j2sdk-image.zip . + $(CD) $(JRE_OVERLAY_IMAGE_DIR) && $(ZIP) -q -r $(BUILD_OUTPUT)/bundles/j2re-image.zip . +else + $(CD) $(JDK_IMAGE_DIR) && $(ZIP) -q -r $(BUILD_OUTPUT)/bundles/j2sdk-image.zip . + $(CD) $(JRE_IMAGE_DIR) && $(ZIP) -q -r $(BUILD_OUTPUT)/bundles/j2re-image.zip . +endif @$(call TargetExit) # Keep track of phony targets From be0c8e9f08c42bcd5543214f5c2868bf036d469b Mon Sep 17 00:00:00 2001 From: Eric Mccorkle Date: Mon, 14 Jan 2013 11:01:39 -0500 Subject: [PATCH 075/204] 8006005: Fix constant pool index validation and alignment trap for method parameter reflection This patch addresses an alignment trap due to the storage format of method parameters data in constMethod. It also adds code to validate constant pool indexes for method parameters data. Reviewed-by: jrose, dholmes --- .../share/vm/classfile/classFileParser.cpp | 18 ++++++++- hotspot/src/share/vm/oops/constMethod.hpp | 7 +++- hotspot/src/share/vm/prims/jvm.cpp | 38 +++++++++++++------ hotspot/src/share/vm/runtime/reflection.cpp | 10 ++++- 4 files changed, 58 insertions(+), 15 deletions(-) diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index efb6138e583..a2fec400d94 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -59,6 +59,7 @@ #include "services/classLoadingService.hpp" #include "services/threadService.hpp" #include "utilities/array.hpp" +#include "utilities/globalDefinitions.hpp" // We generally try to create the oops directly when parsing, rather than // allocating temporary data structures and copying the bytes twice. A @@ -2148,9 +2149,21 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data, cp, CHECK_(nullHandle)); } else if (method_attribute_name == vmSymbols::tag_method_parameters()) { method_parameters_length = cfs->get_u1_fast(); + // Track the actual size (note: this is written for clarity; a + // decent compiler will CSE and constant-fold this into a single + // expression) + u2 actual_size = 1; method_parameters_data = cfs->get_u1_buffer(); + actual_size += 2 * method_parameters_length; cfs->skip_u2_fast(method_parameters_length); + actual_size += 4 * method_parameters_length; cfs->skip_u4_fast(method_parameters_length); + // Enforce attribute length + if (method_attribute_length != actual_size) { + classfile_parse_error( + "Invalid MethodParameters method attribute length %u in class file %s", + method_attribute_length, CHECK_(nullHandle)); + } // ignore this attribute if it cannot be reflected if (!SystemDictionary::Parameter_klass_loaded()) method_parameters_length = 0; @@ -2297,7 +2310,10 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data, elem[i].name_cp_index = Bytes::get_Java_u2(method_parameters_data); method_parameters_data += 2; - elem[i].flags = Bytes::get_Java_u4(method_parameters_data); + u4 flags = Bytes::get_Java_u4(method_parameters_data); + // This caused an alignment fault on Sparc, if flags was a u4 + elem[i].flags_lo = extract_low_short_from_int(flags); + elem[i].flags_hi = extract_high_short_from_int(flags); method_parameters_data += 4; } } diff --git a/hotspot/src/share/vm/oops/constMethod.hpp b/hotspot/src/share/vm/oops/constMethod.hpp index 08c650278e6..8b593982140 100644 --- a/hotspot/src/share/vm/oops/constMethod.hpp +++ b/hotspot/src/share/vm/oops/constMethod.hpp @@ -122,7 +122,12 @@ class ExceptionTableElement VALUE_OBJ_CLASS_SPEC { class MethodParametersElement VALUE_OBJ_CLASS_SPEC { public: u2 name_cp_index; - u4 flags; + // This has to happen, otherwise it will cause SIGBUS from a + // misaligned u4 on some architectures (ie SPARC) + // because MethodParametersElements are only aligned mod 2 + // within the ConstMethod container u2 flags_hi; + u2 flags_hi; + u2 flags_lo; }; diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp index f899aac02e7..8b7b2583c5f 100644 --- a/hotspot/src/share/vm/prims/jvm.cpp +++ b/hotspot/src/share/vm/prims/jvm.cpp @@ -1589,6 +1589,12 @@ JVM_ENTRY(jbyteArray, JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls)) return NULL; JVM_END +static void bounds_check(constantPoolHandle cp, jint index, TRAPS) { + if (!cp->is_within_bounds(index)) { + THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Constant pool index out of bounds"); + } +} + JVM_ENTRY(jobjectArray, JVM_GetMethodParameters(JNIEnv *env, jobject method)) { JVMWrapper("JVM_GetMethodParameters"); @@ -1598,15 +1604,31 @@ JVM_ENTRY(jobjectArray, JVM_GetMethodParameters(JNIEnv *env, jobject method)) Handle reflected_method (THREAD, JNIHandles::resolve_non_null(method)); const int num_params = mh->method_parameters_length(); - if(0 != num_params) { + if (0 != num_params) { + // make sure all the symbols are properly formatted + for (int i = 0; i < num_params; i++) { + MethodParametersElement* params = mh->method_parameters_start(); + int index = params[i].name_cp_index; + bounds_check(mh->constants(), index, CHECK_NULL); + + if (0 != index && !mh->constants()->tag_at(index).is_utf8()) { + THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), + "Wrong type at constant pool index"); + } + + } + objArrayOop result_oop = oopFactory::new_objArray(SystemDictionary::reflect_Parameter_klass(), num_params, CHECK_NULL); objArrayHandle result (THREAD, result_oop); - for(int i = 0; i < num_params; i++) { + for (int i = 0; i < num_params; i++) { MethodParametersElement* params = mh->method_parameters_start(); - Symbol* const sym = mh->constants()->symbol_at(params[i].name_cp_index); + // For a 0 index, give a NULL symbol + Symbol* const sym = 0 != params[i].name_cp_index ? + mh->constants()->symbol_at(params[i].name_cp_index) : NULL; + int flags = build_int_from_shorts(params[i].flags_lo, params[i].flags_hi); oop param = Reflection::new_parameter(reflected_method, i, sym, - params[i].flags, CHECK_NULL); + flags, CHECK_NULL); result->obj_at_put(i, param); } return (jobjectArray)JNIHandles::make_local(env, result()); @@ -1830,13 +1852,6 @@ JVM_ENTRY(jint, JVM_ConstantPoolGetSize(JNIEnv *env, jobject obj, jobject unused JVM_END -static void bounds_check(constantPoolHandle cp, jint index, TRAPS) { - if (!cp->is_within_bounds(index)) { - THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Constant pool index out of bounds"); - } -} - - JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAt(JNIEnv *env, jobject obj, jobject unused, jint index)) { JVMWrapper("JVM_ConstantPoolGetClassAt"); @@ -1851,7 +1866,6 @@ JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAt(JNIEnv *env, jobject obj, jobject u } JVM_END - JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAtIfLoaded(JNIEnv *env, jobject obj, jobject unused, jint index)) { JVMWrapper("JVM_ConstantPoolGetClassAtIfLoaded"); diff --git a/hotspot/src/share/vm/runtime/reflection.cpp b/hotspot/src/share/vm/runtime/reflection.cpp index 76a72e4e9b7..8d0cab2a441 100644 --- a/hotspot/src/share/vm/runtime/reflection.cpp +++ b/hotspot/src/share/vm/runtime/reflection.cpp @@ -862,7 +862,15 @@ oop Reflection::new_field(fieldDescriptor* fd, bool intern_name, TRAPS) { oop Reflection::new_parameter(Handle method, int index, Symbol* sym, int flags, TRAPS) { - Handle name = java_lang_String::create_from_symbol(sym, CHECK_NULL); + Handle name; + + // A null symbol here translates to the empty string + if(NULL != sym) { + name = java_lang_String::create_from_symbol(sym, CHECK_NULL); + } else { + name = java_lang_String::create_from_str("", CHECK_NULL); + } + Handle rh = java_lang_reflect_Parameter::create(CHECK_NULL); java_lang_reflect_Parameter::set_name(rh(), name()); java_lang_reflect_Parameter::set_modifiers(rh(), flags); From f8b9f3900cadebd35e5fc1082c069cd94e6436c0 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Mon, 14 Jan 2013 08:22:32 -0800 Subject: [PATCH 076/204] 8006095: C1: SIGSEGV w/ -XX:+LogCompilation Avoid printing inlining decision when compilation fails Reviewed-by: kvn, roland --- hotspot/src/share/vm/c1/c1_GraphBuilder.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp index 85c3aa1c9a9..cbaf83b8fea 100644 --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp @@ -3223,7 +3223,12 @@ bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known, Bytecodes::Co } if (try_inline_full(callee, holder_known, bc, receiver)) return true; - print_inlining(callee, _inline_bailout_msg, /*success*/ false); + + // Entire compilation could fail during try_inline_full call. + // In that case printing inlining decision info is useless. + if (!bailed_out()) + print_inlining(callee, _inline_bailout_msg, /*success*/ false); + return false; } @@ -3753,7 +3758,8 @@ bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, Bytecode push_scope(callee, cont); // the BlockListBuilder for the callee could have bailed out - CHECK_BAILOUT_(false); + if (bailed_out()) + return false; // Temporarily set up bytecode stream so we can append instructions // (only using the bci of this stream) @@ -3819,7 +3825,8 @@ bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, Bytecode iterate_all_blocks(callee_start_block == NULL); // If we bailed out during parsing, return immediately (this is bad news) - if (bailed_out()) return false; + if (bailed_out()) + return false; // iterate_all_blocks theoretically traverses in random order; in // practice, we have only traversed the continuation if we are @@ -3828,9 +3835,6 @@ bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, Bytecode !continuation()->is_set(BlockBegin::was_visited_flag), "continuation should not have been parsed yet if we created it"); - // If we bailed out during parsing, return immediately (this is bad news) - CHECK_BAILOUT_(false); - // At this point we are almost ready to return and resume parsing of // the caller back in the GraphBuilder. The only thing we want to do // first is an optimization: during parsing of the callee we @@ -4171,7 +4175,10 @@ void GraphBuilder::print_inlining(ciMethod* callee, const char* msg, bool succes else log->inline_success("receiver is statically known"); } else { - log->inline_fail(msg); + if (msg != NULL) + log->inline_fail(msg); + else + log->inline_fail("reason unknown"); } } From 561384762672523b6d9757401803dacbbffef2dc Mon Sep 17 00:00:00 2001 From: Alexander Harlap Date: Mon, 14 Jan 2013 13:44:49 -0500 Subject: [PATCH 077/204] 8005639: Move InlineSynchronizedMethods flag from develop to product Move InlineSynchronizedMethods flag from develop to product Reviewed-by: kvn, vladidan --- hotspot/src/share/vm/c1/c1_globals.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/c1/c1_globals.hpp b/hotspot/src/share/vm/c1/c1_globals.hpp index e81636c524a..16451f6d526 100644 --- a/hotspot/src/share/vm/c1/c1_globals.hpp +++ b/hotspot/src/share/vm/c1/c1_globals.hpp @@ -147,7 +147,7 @@ "Inline methods containing exception handlers " \ "(NOTE: does not work with current backend)") \ \ - develop(bool, InlineSynchronizedMethods, true, \ + product(bool, InlineSynchronizedMethods, true, \ "Inline synchronized methods") \ \ develop(bool, InlineNIOCheckIndex, true, \ From 95cbed6639bff77ca7b1b5c8233e4e5fa87f0909 Mon Sep 17 00:00:00 2001 From: Alexander Harlap Date: Mon, 14 Jan 2013 13:52:08 -0500 Subject: [PATCH 078/204] 8005204: Code Cache Reduction: command line options implementation Adding more detailed output on CodeCache usage Reviewed-by: kvn, vladidan --- hotspot/src/share/vm/code/codeCache.cpp | 47 ++++++++++++++----- hotspot/src/share/vm/code/codeCache.hpp | 4 +- .../src/share/vm/compiler/compileBroker.cpp | 21 ++++++++- hotspot/src/share/vm/runtime/globals.hpp | 9 ++-- hotspot/src/share/vm/runtime/java.cpp | 6 +++ hotspot/src/share/vm/utilities/vmError.cpp | 2 +- 6 files changed, 70 insertions(+), 19 deletions(-) diff --git a/hotspot/src/share/vm/code/codeCache.cpp b/hotspot/src/share/vm/code/codeCache.cpp index c40a377ebb3..d5b8f8f9a78 100644 --- a/hotspot/src/share/vm/code/codeCache.cpp +++ b/hotspot/src/share/vm/code/codeCache.cpp @@ -30,6 +30,7 @@ #include "code/icBuffer.hpp" #include "code/nmethod.hpp" #include "code/pcDesc.hpp" +#include "compiler/compileBroker.hpp" #include "gc_implementation/shared/markSweep.hpp" #include "memory/allocation.inline.hpp" #include "memory/gcLocker.hpp" @@ -39,6 +40,7 @@ #include "oops/objArrayOop.hpp" #include "oops/oop.inline.hpp" #include "runtime/handles.inline.hpp" +#include "runtime/arguments.hpp" #include "runtime/icache.hpp" #include "runtime/java.hpp" #include "runtime/mutexLocker.hpp" @@ -168,6 +170,8 @@ nmethod* CodeCache::next_nmethod (CodeBlob* cb) { return (nmethod*)cb; } +static size_t maxCodeCacheUsed = 0; + CodeBlob* CodeCache::allocate(int size) { // Do not seize the CodeCache lock here--if the caller has not // already done so, we are going to lose bigtime, since the code @@ -192,6 +196,8 @@ CodeBlob* CodeCache::allocate(int size) { (address)_heap->end() - (address)_heap->begin()); } } + maxCodeCacheUsed = MAX2(maxCodeCacheUsed, ((address)_heap->high_boundary() - + (address)_heap->low_boundary()) - unallocated_capacity()); verify_if_often(); print_trace("allocation", cb, size); return cb; @@ -928,7 +934,14 @@ void CodeCache::print_internals() { FREE_C_HEAP_ARRAY(int, buckets, mtCode); } +#endif // !PRODUCT + void CodeCache::print() { + print_summary(tty); + +#ifndef PRODUCT + if (!Verbose) return; + CodeBlob_sizes live; CodeBlob_sizes dead; @@ -953,7 +966,7 @@ void CodeCache::print() { } - if (Verbose) { + if (WizardMode) { // print the oop_map usage int code_size = 0; int number_of_blobs = 0; @@ -977,20 +990,30 @@ void CodeCache::print() { tty->print_cr(" map size = %d", map_size); } +#endif // !PRODUCT } -#endif // PRODUCT +void CodeCache::print_summary(outputStream* st, bool detailed) { + size_t total = (_heap->high_boundary() - _heap->low_boundary()); + st->print_cr("CodeCache: size=" SIZE_FORMAT "Kb used=" SIZE_FORMAT + "Kb max_used=" SIZE_FORMAT "Kb free=" SIZE_FORMAT + "Kb max_free_chunk=" SIZE_FORMAT "Kb", + total/K, (total - unallocated_capacity())/K, + maxCodeCacheUsed/K, unallocated_capacity()/K, largest_free_block()/K); -void CodeCache::print_bounds(outputStream* st) { - st->print_cr("Code Cache [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT ")", - _heap->low_boundary(), - _heap->high(), - _heap->high_boundary()); - st->print_cr(" total_blobs=" UINT32_FORMAT " nmethods=" UINT32_FORMAT - " adapters=" UINT32_FORMAT " free_code_cache=" SIZE_FORMAT "Kb" - " largest_free_block=" SIZE_FORMAT, - nof_blobs(), nof_nmethods(), nof_adapters(), - unallocated_capacity()/K, largest_free_block()); + if (detailed) { + st->print_cr(" bounds [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT "]", + _heap->low_boundary(), + _heap->high(), + _heap->high_boundary()); + st->print_cr(" total_blobs=" UINT32_FORMAT " nmethods=" UINT32_FORMAT + " adapters=" UINT32_FORMAT, + nof_blobs(), nof_nmethods(), nof_adapters()); + st->print_cr(" compilation: %s", CompileBroker::should_compile_new_jobs() ? + "enabled" : Arguments::mode() == Arguments::_int ? + "disabled (interpreter mode)" : + "disabled (not enough contiguous free space left)"); + } } void CodeCache::log_state(outputStream* st) { diff --git a/hotspot/src/share/vm/code/codeCache.hpp b/hotspot/src/share/vm/code/codeCache.hpp index 6187ba9a2a7..92ce241b938 100644 --- a/hotspot/src/share/vm/code/codeCache.hpp +++ b/hotspot/src/share/vm/code/codeCache.hpp @@ -145,11 +145,11 @@ class CodeCache : AllStatic { static void prune_scavenge_root_nmethods(); // Printing/debugging - static void print() PRODUCT_RETURN; // prints summary + static void print(); // prints summary static void print_internals(); static void verify(); // verifies the code cache static void print_trace(const char* event, CodeBlob* cb, int size = 0) PRODUCT_RETURN; - static void print_bounds(outputStream* st); // Prints a summary of the bounds of the code cache + static void print_summary(outputStream* st, bool detailed = true); // Prints a summary of the code cache usage static void log_state(outputStream* st); // The full limits of the codeCache diff --git a/hotspot/src/share/vm/compiler/compileBroker.cpp b/hotspot/src/share/vm/compiler/compileBroker.cpp index 73ab865dc74..94c042d32e3 100644 --- a/hotspot/src/share/vm/compiler/compileBroker.cpp +++ b/hotspot/src/share/vm/compiler/compileBroker.cpp @@ -1714,6 +1714,20 @@ void CompileBroker::maybe_block() { } } +// wrapper for CodeCache::print_summary() +static void codecache_print(bool detailed) +{ + ResourceMark rm; + stringStream s; + // Dump code cache into a buffer before locking the tty, + { + MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + CodeCache::print_summary(&s, detailed); + } + ttyLocker ttyl; + tty->print_cr(s.as_string()); +} + // ------------------------------------------------------------------ // CompileBroker::invoke_compiler_on_method // @@ -1841,6 +1855,9 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) { tty->print_cr("size: %d time: %d inlined: %d bytes", code_size, (int)time.milliseconds(), task->num_inlined_bytecodes()); } + if (PrintCodeCacheOnCompilation) + codecache_print(/* detailed= */ false); + // Disable compilation, if required. switch (compilable) { case ciEnv::MethodCompilable_never: @@ -1885,6 +1902,7 @@ void CompileBroker::handle_full_code_cache() { UseInterpreter = true; if (UseCompiler || AlwaysCompileLoopMethods ) { if (xtty != NULL) { + ResourceMark rm; stringStream s; // Dump code cache state into a buffer before locking the tty, // because log_state() will use locks causing lock conflicts. @@ -1898,9 +1916,9 @@ void CompileBroker::handle_full_code_cache() { } warning("CodeCache is full. Compiler has been disabled."); warning("Try increasing the code cache size using -XX:ReservedCodeCacheSize="); - CodeCache::print_bounds(tty); #ifndef PRODUCT if (CompileTheWorld || ExitOnFullCodeCache) { + codecache_print(/* detailed= */ true); before_exit(JavaThread::current()); exit_globals(); // will delete tty vm_direct_exit(CompileTheWorld ? 0 : 1); @@ -1913,6 +1931,7 @@ void CompileBroker::handle_full_code_cache() { AlwaysCompileLoopMethods = false; } } + codecache_print(/* detailed= */ true); } // ------------------------------------------------------------------ diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 7ea96627e82..0856bd30367 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -929,11 +929,14 @@ class CommandLineFlags { "Starts debugger when an implicit OS (e.g., NULL) " \ "exception happens") \ \ - notproduct(bool, PrintCodeCache, false, \ - "Print the compiled_code cache when exiting") \ + product(bool, PrintCodeCache, false, \ + "Print the code cache memory usage when exiting") \ \ develop(bool, PrintCodeCache2, false, \ - "Print detailed info on the compiled_code cache when exiting") \ + "Print detailed usage info on the code cache when exiting") \ + \ + product(bool, PrintCodeCacheOnCompilation, false, \ + "Print the code cache memory usage each time a method is compiled") \ \ diagnostic(bool, PrintStubCode, false, \ "Print generated stub code") \ diff --git a/hotspot/src/share/vm/runtime/java.cpp b/hotspot/src/share/vm/runtime/java.cpp index ad6399495b0..61ad935018c 100644 --- a/hotspot/src/share/vm/runtime/java.cpp +++ b/hotspot/src/share/vm/runtime/java.cpp @@ -368,6 +368,12 @@ void print_statistics() { if (CITime) { CompileBroker::print_times(); } + + if (PrintCodeCache) { + MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + CodeCache::print(); + } + #ifdef COMPILER2 if (PrintPreciseBiasedLockingStatistics) { OptoRuntime::print_named_counters(); diff --git a/hotspot/src/share/vm/utilities/vmError.cpp b/hotspot/src/share/vm/utilities/vmError.cpp index ddb6e1cf882..d8fe93b64f3 100644 --- a/hotspot/src/share/vm/utilities/vmError.cpp +++ b/hotspot/src/share/vm/utilities/vmError.cpp @@ -702,7 +702,7 @@ void VMError::report(outputStream* st) { if (_verbose && Universe::is_fully_initialized()) { // print code cache information before vm abort - CodeCache::print_bounds(st); + CodeCache::print_summary(st); st->cr(); } From 9e3a1213576a299b599b884b0821b80799659d6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Borggr=C3=A9n-Franck?= Date: Mon, 14 Jan 2013 19:52:36 +0100 Subject: [PATCH 079/204] 7193719: Support repeating annotations in javax.lang.model Reviewed-by: jjg --- .../com/sun/tools/javac/code/Symbol.java | 9 +- .../sun/tools/javac/model/JavacElements.java | 242 ++++++++++++++++-- .../javax/lang/model/element/Element.java | 52 +++- 3 files changed, 276 insertions(+), 27 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java index 6f2e19985a4..134b0c1e890 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -450,7 +450,7 @@ public abstract class Symbol implements Element { * This is the implementation for {@code * javax.lang.model.element.Element.getAnnotationMirrors()}. */ - public final List getAnnotationMirrors() { + public final List getAnnotationMirrors() { return getRawAttributes(); } @@ -462,6 +462,11 @@ public abstract class Symbol implements Element { return JavacElements.getAnnotation(this, annoType); } + // This method is part of the javax.lang.model API, do not use this in javac code. + public A[] getAnnotations(Class annoType) { + return JavacElements.getAnnotations(this, annoType); + } + // TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList public java.util.List getEnclosedElements() { return List.nil(); diff --git a/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java b/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java index 168cef93e72..517ec5b4703 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java +++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -27,6 +27,8 @@ package com.sun.tools.javac.model; import java.lang.annotation.Annotation; import java.lang.annotation.Inherited; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.Map; import javax.lang.model.SourceVersion; @@ -96,32 +98,43 @@ public class JavacElements implements Elements { enter = Enter.instance(context); } - /** - * An internal-use utility that creates a reified annotation. + * An internal-use utility that creates a runtime view of an + * annotation. This is the implementation of + * Element.getAnnotation(Class). */ public static A getAnnotation(Symbol annotated, Class annoType) { if (!annoType.isAnnotation()) throw new IllegalArgumentException("Not an annotation type: " + annoType); - String name = annoType.getName(); - for (Attribute.Compound anno : annotated.getAnnotationMirrors()) - if (name.equals(anno.type.tsym.flatName().toString())) - return AnnotationProxyMaker.generateAnnotation(anno, annoType); - return null; + Attribute.Compound c; + if (annotated.kind == Kinds.TYP && annotated instanceof ClassSymbol) { + c = getAttributeOnClass((ClassSymbol)annotated, annoType); + } else { + c = getAttribute(annotated, annoType); + } + return c == null ? null : AnnotationProxyMaker.generateAnnotation(c, annoType); } - /** - * An internal-use utility that creates a reified annotation. - * This overloaded version take annotation inheritance into account. - */ - public static A getAnnotation(ClassSymbol annotated, - Class annoType) { + // Helper to getAnnotation[s] + private static Attribute.Compound getAttribute(Symbol annotated, + Class annoType) { + String name = annoType.getName(); + + for (Attribute.Compound anno : annotated.getRawAttributes()) + if (name.equals(anno.type.tsym.flatName().toString())) + return anno; + + return null; + } + // Helper to getAnnotation[s] + private static Attribute.Compound getAttributeOnClass(ClassSymbol annotated, + Class annoType) { boolean inherited = annoType.isAnnotationPresent(Inherited.class); - A result = null; + Attribute.Compound result = null; while (annotated.name != annotated.name.table.names.java_lang_Object) { - result = getAnnotation((Symbol)annotated, annoType); + result = getAttribute(annotated, annoType); if (result != null || !inherited) break; Type sup = annotated.getSuperclass(); @@ -132,6 +145,188 @@ public class JavacElements implements Elements { return result; } + /** + * An internal-use utility that creates a runtime view of + * annotations. This is the implementation of + * Element.getAnnotations(Class). + */ + public static A[] getAnnotations(Symbol annotated, + Class annoType) { + if (!annoType.isAnnotation()) + throw new IllegalArgumentException("Not an annotation type: " + + annoType); + // If annoType does not declare a container this is equivalent to wrapping + // getAnnotation(...) in an array. + Class containerType = getContainer(annoType); + if (containerType == null) { + A res = getAnnotation(annotated, annoType); + int size; + if (res == null) { + size = 0; + } else { + size = 1; + } + @SuppressWarnings("unchecked") // annoType is the Class for A + A[] arr = (A[])java.lang.reflect.Array.newInstance(annoType, size); + if (res != null) + arr[0] = res; + return arr; + } + + // So we have a containing type + String name = annoType.getName(); + String annoTypeName = annoType.getSimpleName(); + String containerTypeName = containerType.getSimpleName(); + int directIndex = -1, containerIndex = -1; + Attribute.Compound direct = null, container = null; + Attribute.Compound[] rawAttributes = annotated.getRawAttributes().toArray(new Attribute.Compound[0]); + + // Find directly present annotations + for (int i = 0; i < rawAttributes.length; i++) { + if (annoTypeName.equals(rawAttributes[i].type.tsym.flatName().toString())) { + directIndex = i; + direct = rawAttributes[i]; + } else if(containerTypeName != null && + containerTypeName.equals(rawAttributes[i].type.tsym.flatName().toString())) { + containerIndex = i; + container = rawAttributes[i]; + } + } + // Deal with inherited annotations + if (annotated.kind == Kinds.TYP && + (annotated instanceof ClassSymbol)) { + ClassSymbol s = (ClassSymbol)annotated; + if (direct == null && container == null) { + direct = getAttributeOnClass(s, annoType); + container = getAttributeOnClass(s, containerType); + + // both are inherited and found, put container last + if (direct != null && container != null) { + directIndex = 0; + containerIndex = 1; + } else if (direct != null) { + directIndex = 0; + } else { + containerIndex = 0; + } + } else if (direct == null) { + direct = getAttributeOnClass(s, annoType); + if (direct != null) + directIndex = containerIndex + 1; + } else if (container == null) { + container = getAttributeOnClass(s, containerType); + if (container != null) + containerIndex = directIndex + 1; + } + } + + // Pack them in an array + Attribute[] contained0 = new Attribute[0]; + if (container != null) + contained0 = unpackAttributes(container); + ListBuffer compounds = ListBuffer.lb(); + for (Attribute a : contained0) + if (a instanceof Attribute.Compound) + compounds = compounds.append((Attribute.Compound)a); + Attribute.Compound[] contained = compounds.toArray(new Attribute.Compound[0]); + + int size = (direct == null ? 0 : 1) + contained.length; + @SuppressWarnings("unchecked") // annoType is the Class for A + A[] arr = (A[])java.lang.reflect.Array.newInstance(annoType, size); + + // if direct && container, which is first? + int insert = -1; + int length = arr.length; + if (directIndex >= 0 && containerIndex >= 0) { + if (directIndex < containerIndex) { + arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType); + insert = 1; + } else { + arr[arr.length - 1] = AnnotationProxyMaker.generateAnnotation(direct, annoType); + insert = 0; + length--; + } + } else if (directIndex >= 0) { + arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType); + return arr; + } else { + // Only container + insert = 0; + } + + for (int i = 0; i + insert < length; i++) + arr[insert + i] = AnnotationProxyMaker.generateAnnotation(contained[i], annoType); + + return arr; + } + + // Needed to unpack the runtime view of containing annotations + private static final Class CONTAINED_BY_CLASS = initContainedBy(); + private static final Method VALUE_ELEMENT_METHOD = initValueElementMethod(); + + private static Class initContainedBy() { + try { + @SuppressWarnings("unchecked") // java.lang.annotation.ContainedBy extends Annotation by being an annotation type + Class c = (Class)Class.forName("java.lang.annotation.ContainedBy"); + return c; + } catch (ClassNotFoundException e) { + return null; + } catch (SecurityException e) { + return null; + } + } + private static Method initValueElementMethod() { + if (CONTAINED_BY_CLASS == null) + return null; + + Method m = null; + try { + m = CONTAINED_BY_CLASS.getMethod("value"); + if (m != null) + m.setAccessible(true); + return m; + } catch (NoSuchMethodException e) { + return null; + } + } + + // Helper to getAnnotations + private static Class getContainer(Class annoType) { + // Since we can not refer to java.lang.annotation.ContainedBy until we are + // bootstrapping with java 8 we need to get the ContainedBy annotation using + // reflective invocations instead of just using its type and element method. + if (CONTAINED_BY_CLASS != null && + VALUE_ELEMENT_METHOD != null) { + // Get the ContainedBy instance on the annotations declaration + Annotation containedBy = (Annotation)annoType.getAnnotation(CONTAINED_BY_CLASS); + if (containedBy != null) { + try { + // Get the value element, it should be a class + // indicating the containing annotation type + @SuppressWarnings("unchecked") + Class containerType = (Class)VALUE_ELEMENT_METHOD.invoke(containedBy); + if (containerType == null) + return null; + + return containerType; + } catch (ClassCastException e) { + return null; + } catch (IllegalAccessException e) { + return null; + } catch (InvocationTargetException e ) { + return null; + } + } + } + return null; + } + // Helper to getAnnotations + private static Attribute[] unpackAttributes(Attribute.Compound container) { + // We now have an instance of the container, + // unpack it returning an instance of the + // contained type or null + return ((Attribute.Array)container.member(container.type.tsym.name.table.names.value)).values; + } public PackageSymbol getPackageElement(CharSequence name) { String strName = name.toString(); @@ -238,8 +433,10 @@ public class JavacElements implements Elements { tree.accept(vis); if (vis.result == null) return null; + + List annos = sym.getRawAttributes(); return matchAnnoToTree(cast(Attribute.Compound.class, findme), - sym.getAnnotationMirrors(), + annos, vis.result); } @@ -442,7 +639,7 @@ public class JavacElements implements Elements { */ public List getAllAnnotationMirrors(Element e) { Symbol sym = cast(Symbol.class, e); - List annos = sym.getAnnotationMirrors(); + List annos = sym.getRawAttributes(); while (sym.getKind() == ElementKind.CLASS) { Type sup = ((ClassSymbol) sym).getSuperclass(); if (!sup.hasTag(CLASS) || sup.isErroneous() || @@ -451,7 +648,8 @@ public class JavacElements implements Elements { } sym = sup.tsym; List oldAnnos = annos; - for (Attribute.Compound anno : sym.getAnnotationMirrors()) { + List newAnnos = sym.getRawAttributes(); + for (Attribute.Compound anno : newAnnos) { if (isInherited(anno.type) && !containsAnnoOfType(oldAnnos, anno.type)) { annos = annos.prepend(anno); @@ -465,11 +663,7 @@ public class JavacElements implements Elements { * Tests whether an annotation type is @Inherited. */ private boolean isInherited(Type annotype) { - for (Attribute.Compound anno : annotype.tsym.getAnnotationMirrors()) { - if (anno.type.tsym == syms.inheritedType.tsym) - return true; - } - return false; + return annotype.tsym.attribute(syms.inheritedType.tsym) != null; } /** diff --git a/langtools/src/share/classes/javax/lang/model/element/Element.java b/langtools/src/share/classes/javax/lang/model/element/Element.java index 505525865c5..b0b463df13f 100644 --- a/langtools/src/share/classes/javax/lang/model/element/Element.java +++ b/langtools/src/share/classes/javax/lang/model/element/Element.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -148,6 +148,56 @@ public interface Element { */ A getAnnotation(Class annotationType); + /** + * Returns an array of all of this element's annotation for the + * specified type if such annotations are present, else an empty + * array. The annotation may be either inherited or directly + * present on this element. This method will look through a container + * annotation (if present) if the supplied annotation type is + * repeatable. + * + *

The annotations returned by this method could contain an element + * whose value is of type {@code Class}. + * This value cannot be returned directly: information necessary to + * locate and load a class (such as the class loader to use) is + * not available, and the class might not be loadable at all. + * Attempting to read a {@code Class} object by invoking the relevant + * method on the returned annotation + * will result in a {@link MirroredTypeException}, + * from which the corresponding {@link TypeMirror} may be extracted. + * Similarly, attempting to read a {@code Class[]}-valued element + * will result in a {@link MirroredTypesException}. + * + *

+ * Note: This method is unlike others in this and related + * interfaces. It operates on runtime reflective information — + * representations of annotation types currently loaded into the + * VM — rather than on the representations defined by and used + * throughout these interfaces. Consequently, calling methods on + * the returned annotation object can throw many of the exceptions + * that can be thrown when calling methods on an annotation object + * returned by core reflection. This method is intended for + * callers that are written to operate on a known, fixed set of + * annotation types. + *
+ * + * @param
the annotation type + * @param annotationType the {@code Class} object corresponding to + * the annotation type + * @return this element's annotations for the specified annotation + * type if present on this element, else an empty array + * + * @see #getAnnotationMirrors() + * @see #getAnnotation() + * @see java.lang.reflect.AnnotatedElement#getAnnotations + * @see EnumConstantNotPresentException + * @see AnnotationTypeMismatchException + * @see IncompleteAnnotationException + * @see MirroredTypeException + * @see MirroredTypesException + */ + A[] getAnnotations(Class annotationType); + /** * Returns the modifiers of this element, excluding annotations. * Implicit modifiers, such as the {@code public} and {@code static} From b4546eb428eeecd4c764029150a24b2edea7e429 Mon Sep 17 00:00:00 2001 From: Mikael Vidstedt Date: Mon, 14 Jan 2013 11:00:56 -0800 Subject: [PATCH 080/204] 8005592: ClassLoaderDataGraph::_unloading incorrectly defined as nonstatic in vmStructs Added assertion to catch problem earlier and removed the unused field Reviewed-by: dholmes, acorn --- hotspot/src/share/vm/runtime/vmStructs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index e4f9cbb3ee0..8d454992cf8 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -717,7 +717,6 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; nonstatic_field(ClassLoaderData, _next, ClassLoaderData*) \ \ static_field(ClassLoaderDataGraph, _head, ClassLoaderData*) \ - nonstatic_field(ClassLoaderDataGraph, _unloading, ClassLoaderData*) \ \ /*******************/ \ /* GrowableArrays */ \ @@ -2575,7 +2574,8 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; // This macro checks the type of a VMStructEntry by comparing pointer types #define CHECK_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \ - {typeName *dummyObj = NULL; type* dummy = &dummyObj->fieldName; } + {typeName *dummyObj = NULL; type* dummy = &dummyObj->fieldName; \ + assert(offset_of(typeName, fieldName) < sizeof(typeName), "Illegal nonstatic struct entry, field offset too large"); } // This macro checks the type of a volatile VMStructEntry by comparing pointer types #define CHECK_VOLATILE_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \ From 33b7cd7cae2d7a22bf107e1e746d3be133bedcdb Mon Sep 17 00:00:00 2001 From: Bengt Rutisson Date: Mon, 14 Jan 2013 21:30:45 +0100 Subject: [PATCH 081/204] 8005972: ParNew should not update the tenuring threshold when promotion failed has occurred Reviewed-by: ysr, johnc, jwilhelm --- .../vm/gc_implementation/parNew/parNewGeneration.cpp | 9 ++------- .../vm/gc_implementation/parNew/parNewGeneration.hpp | 4 ---- hotspot/src/share/vm/memory/defNewGeneration.cpp | 9 ++++++--- hotspot/src/share/vm/memory/defNewGeneration.hpp | 4 +++- 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp index 273322436ba..e868d870990 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp @@ -878,12 +878,6 @@ void EvacuateFollowersClosureGeneral::do_void() { bool ParNewGeneration::_avoid_promotion_undo = false; -void ParNewGeneration::adjust_desired_tenuring_threshold() { - // Set the desired survivor size to half the real survivor space - _tenuring_threshold = - age_table()->compute_tenuring_threshold(to()->capacity()/HeapWordSize); -} - // A Generation that does parallel young-gen collection. void ParNewGeneration::collect(bool full, @@ -1013,6 +1007,8 @@ void ParNewGeneration::collect(bool full, size_policy->reset_gc_overhead_limit_count(); assert(to()->is_empty(), "to space should be empty now"); + + adjust_desired_tenuring_threshold(); } else { assert(_promo_failure_scan_stack.is_empty(), "post condition"); _promo_failure_scan_stack.clear(true); // Clear cached segments. @@ -1035,7 +1031,6 @@ void ParNewGeneration::collect(bool full, from()->set_concurrent_iteration_safe_limit(from()->top()); to()->set_concurrent_iteration_safe_limit(to()->top()); - adjust_desired_tenuring_threshold(); if (ResizePLAB) { plab_stats()->adjust_desired_plab_sz(n_workers); } diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp index bbb6176fd08..487552bfba9 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp @@ -347,10 +347,6 @@ class ParNewGeneration: public DefNewGeneration { bool survivor_overflow() { return _survivor_overflow; } void set_survivor_overflow(bool v) { _survivor_overflow = v; } - // Adjust the tenuring threshold. See the implementation for - // the details of the policy. - virtual void adjust_desired_tenuring_threshold(); - public: ParNewGeneration(ReservedSpace rs, size_t initial_byte_size, int level); diff --git a/hotspot/src/share/vm/memory/defNewGeneration.cpp b/hotspot/src/share/vm/memory/defNewGeneration.cpp index cca7cd0e704..689ce7b8bbf 100644 --- a/hotspot/src/share/vm/memory/defNewGeneration.cpp +++ b/hotspot/src/share/vm/memory/defNewGeneration.cpp @@ -550,6 +550,11 @@ HeapWord* DefNewGeneration::expand_and_allocate(size_t size, return allocate(size, is_tlab); } +void DefNewGeneration::adjust_desired_tenuring_threshold() { + // Set the desired survivor size to half the real survivor space + _tenuring_threshold = + age_table()->compute_tenuring_threshold(to()->capacity()/HeapWordSize); +} void DefNewGeneration::collect(bool full, bool clear_all_soft_refs, @@ -649,9 +654,7 @@ void DefNewGeneration::collect(bool full, assert(to()->is_empty(), "to space should be empty now"); - // Set the desired survivor size to half the real survivor space - _tenuring_threshold = - age_table()->compute_tenuring_threshold(to()->capacity()/HeapWordSize); + adjust_desired_tenuring_threshold(); // A successful scavenge should restart the GC time limit count which is // for full GC's. diff --git a/hotspot/src/share/vm/memory/defNewGeneration.hpp b/hotspot/src/share/vm/memory/defNewGeneration.hpp index b7c794d86c2..38ea742b38a 100644 --- a/hotspot/src/share/vm/memory/defNewGeneration.hpp +++ b/hotspot/src/share/vm/memory/defNewGeneration.hpp @@ -124,7 +124,9 @@ protected: _should_allocate_from_space = true; } - protected: + // Tenuring + void adjust_desired_tenuring_threshold(); + // Spaces EdenSpace* _eden_space; ContiguousSpace* _from_space; From a2f594bf745112b1662d7aaf732f23a69cc29215 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 14 Jan 2013 13:50:01 -0800 Subject: [PATCH 082/204] 8006119: update javac to follow latest spec for repeatable annotations Reviewed-by: darcy --- .../com/sun/tools/javac/code/Annotations.java | 8 +- .../com/sun/tools/javac/code/Symtab.java | 8 +- .../com/sun/tools/javac/comp/Annotate.java | 35 +++--- .../com/sun/tools/javac/comp/Attr.java | 24 ++-- .../com/sun/tools/javac/comp/Check.java | 113 ++++-------------- .../sun/tools/javac/model/JavacElements.java | 26 ++-- .../tools/javac/resources/compiler.properties | 50 +++----- .../pkg/ContaineeSynthDoc.java | 4 +- .../pkg/ContainerSynthDoc.java | 3 +- .../pkg1/ContaineeSynthDoc.java | 4 +- .../pkg1/ContainerSynthNotDoc.java | 3 +- .../BaseAnnoAsContainerAnno.java | 6 +- .../BaseAnnoAsContainerAnno.out | 2 +- .../BasicRepeatingAnnotations.java | 5 +- .../repeatingAnnotations/CheckTargets.java | 11 +- .../ClassReaderDefault.java | 8 +- .../ContainerHasRepeatedContained.java | 8 +- .../CyclicAnnotation.java | 9 +- .../repeatingAnnotations/CyclicAnnotation.out | 8 +- .../DefaultCasePresent.java | 8 +- .../DelayRepeatedContainer.java | 5 +- .../DocumentedContainerAnno.java | 6 +- .../DocumentedContainerAnno.out | 2 +- .../InheritedContainerAnno.java | 6 +- .../InheritedContainerAnno.out | 2 +- .../repeatingAnnotations/InvalidTarget.java | 5 +- .../MissingContainer.java | 6 +- .../repeatingAnnotations/MissingContainer.out | 9 +- .../MissingContainerFor.java | 38 ------ .../MissingDefaultCase1.java | 6 +- .../MissingDefaultCase1.out | 4 +- .../MissingDefaultCase2.java | 6 +- .../MissingDefaultCase2.out | 4 +- .../MissingValueMethod.java | 6 +- .../MissingValueMethod.out | 6 +- .../MultiLevelRepeatableAnno.java | 11 +- .../MultipleAnnoMixedOrder.java | 11 +- .../NestedContainers.java | 8 +- .../repeatingAnnotations/NoRepeatableAnno.out | 4 +- .../repeatingAnnotations/RepMemberAnno.java | 8 +- .../RepSelfMemberAnno.java | 8 +- .../RepeatingAndContainerPresent.java | 4 +- .../RepeatingTargetNotAllowed.java | 5 +- .../RepeatingTargetNotAllowed.out | 2 +- .../SelfRepeatingAnnotations.java | 5 +- .../SingleRepeatingAndContainer.java | 5 +- .../UseWrongContainedBy.java | 42 ------- .../UseWrongContainerFor.java | 42 ------- ...ntainedBy.java => UseWrongRepeatable.java} | 14 ++- .../WrongContainedBy.java | 39 ------ .../WrongContainerFor.java | 39 ------ .../WrongReturnTypeForValue.java | 6 +- .../WrongReturnTypeForValue.out | 7 +- .../combo/BasicSyntaxCombo.java | 5 +- .../combo/DeprecatedAnnoCombo.java | 13 +- .../combo/DocumentedAnnoCombo.java | 8 +- .../repeatingAnnotations/combo/Helper.java | 8 +- .../combo/InheritedAnnoCombo.java | 8 +- .../combo/RetentionAnnoCombo.java | 7 +- .../tools/javac/diags/examples.not-yet.txt | 6 +- .../examples/InvalidDuplicateAnnotation.java | 9 +- ...java => RepeatableDocumentedMismatch.java} | 9 +- ....java => RepeatableInheritedMismatch.java} | 9 +- ...dByNoValue.java => RepeatableNoValue.java} | 9 +- ...Default.java => RepeatableNonDefault.java} | 9 +- ....java => RepeatableRetentionMismatch.java} | 9 +- ...tch.java => RepeatableTargetMismatch.java} | 9 +- ...ype.java => RepeatableWrongValueType.java} | 9 +- .../RepeatingAnnotationAndContainer.java | 7 +- .../diags/examples/WrongContainedBy.java | 35 ------ .../diags/examples/WrongContainerFor.java | 35 ------ 71 files changed, 243 insertions(+), 675 deletions(-) delete mode 100644 langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainerFor.java delete mode 100644 langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainedBy.java delete mode 100644 langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainerFor.java rename langtools/test/tools/javac/annotations/repeatingAnnotations/{MissingContainedBy.java => UseWrongRepeatable.java} (79%) delete mode 100644 langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainedBy.java delete mode 100644 langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainerFor.java rename langtools/test/tools/javac/diags/examples/{ContainedByDocumentedMismatch.java => RepeatableDocumentedMismatch.java} (82%) rename langtools/test/tools/javac/diags/examples/{ContainedByInheritedMismatch.java => RepeatableInheritedMismatch.java} (82%) rename langtools/test/tools/javac/diags/examples/{ContainedByNoValue.java => RepeatableNoValue.java} (83%) rename langtools/test/tools/javac/diags/examples/{ContainedByNonDefault.java => RepeatableNonDefault.java} (82%) rename langtools/test/tools/javac/diags/examples/{ContainedByRetentionMismatch.java => RepeatableRetentionMismatch.java} (83%) rename langtools/test/tools/javac/diags/examples/{ContainedByTargetMismatch.java => RepeatableTargetMismatch.java} (82%) rename langtools/test/tools/javac/diags/examples/{ContainedByWrongValueType.java => RepeatableWrongValueType.java} (82%) delete mode 100644 langtools/test/tools/javac/diags/examples/WrongContainedBy.java delete mode 100644 langtools/test/tools/javac/diags/examples/WrongContainerFor.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java b/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java index 29c88c9d90e..f9c3e76ae74 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -126,12 +126,12 @@ public class Annotations { // // We need to do this in two passes because when creating // a container for a repeating annotation we must - // guarantee that the @ContainedBy on the + // guarantee that the @Repeatable on the // contained annotation is fully annotated // // The way we force this order is to do all repeating // annotations in a pass after all non-repeating are - // finished. This will work because @ContainedBy + // finished. This will work because @Repeatable // is non-repeating and therefore will be annotated in the // fist pass. @@ -261,7 +261,7 @@ public class Annotations { // its contained annotation. ListBuffer manualContainer = ctx.annotated.get(validRepeated.type.tsym); if (manualContainer != null) { - log.error(ctx.pos.get(manualContainer.first()), "invalid.containedby.annotation.repeated.and.container.present", + log.error(ctx.pos.get(manualContainer.first()), "invalid.repeatable.annotation.repeated.and.container.present", manualContainer.first().type.tsym); } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java index 00d6b69db94..17535be2053 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -161,8 +161,7 @@ public class Symtab { public final Type autoCloseableType; public final Type trustMeType; public final Type lambdaMetafactory; - public final Type containedByType; - public final Type containerForType; + public final Type repeatableType; public final Type documentedType; public final Type elementTypeType; @@ -494,8 +493,7 @@ public class Symtab { deprecatedType = enterClass("java.lang.Deprecated"); suppressWarningsType = enterClass("java.lang.SuppressWarnings"); inheritedType = enterClass("java.lang.annotation.Inherited"); - containedByType = enterClass("java.lang.annotation.ContainedBy"); - containerForType = enterClass("java.lang.annotation.ContainerFor"); + repeatableType = enterClass("java.lang.annotation.Repeatable"); documentedType = enterClass("java.lang.annotation.Documented"); elementTypeType = enterClass("java.lang.annotation.ElementType"); systemType = enterClass("java.lang.System"); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java index b9807d9180c..a2cd3851742 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -392,7 +392,7 @@ public class Annotate { List.of(p))); if (!chk.annotationApplicable(annoTree, on)) - log.error(annoTree.pos(), "invalid.containedby.annotation.incompatible.target", targetContainerType, origAnnoType); + log.error(annoTree.pos(), "invalid.repeatable.annotation.incompatible.target", targetContainerType, origAnnoType); if (!chk.validateAnnotationDeferErrors(annoTree)) log.error(annoTree.pos(), "duplicate.annotation.invalid.repeated", origAnnoType); @@ -414,11 +414,11 @@ public class Annotate { Type origAnnoType = currentAnno.type; TypeSymbol origAnnoDecl = origAnnoType.tsym; - // Fetch the ContainedBy annotation from the current + // Fetch the Repeatable annotation from the current // annotation's declaration, or null if it has none - Attribute.Compound ca = origAnnoDecl.attribute(syms.containedByType.tsym); - if (ca == null) { // has no ContainedBy annotation - log.error(pos, "duplicate.annotation.missing.container", origAnnoType, syms.containedByType); + Attribute.Compound ca = origAnnoDecl.attribute(syms.repeatableType.tsym); + if (ca == null) { // has no Repeatable annotation + log.error(pos, "duplicate.annotation.missing.container", origAnnoType, syms.repeatableType); return null; } @@ -440,23 +440,23 @@ public class Annotate { DiagnosticPosition pos, TypeSymbol annoDecl) { - // The next three checks check that the ContainedBy annotation + // The next three checks check that the Repeatable annotation // on the declaration of the annotation type that is repeating is // valid. - // ContainedBy must have at least one element + // Repeatable must have at least one element if (ca.values.isEmpty()) { - log.error(pos, "invalid.containedby.annotation", annoDecl); + log.error(pos, "invalid.repeatable.annotation", annoDecl); return null; } Pair p = ca.values.head; Name name = p.fst.name; if (name != names.value) { // should contain only one element, named "value" - log.error(pos, "invalid.containedby.annotation", annoDecl); + log.error(pos, "invalid.repeatable.annotation", annoDecl); return null; } if (!(p.snd instanceof Attribute.Class)) { // check that the value of "value" is an Attribute.Class - log.error(pos, "invalid.containedby.annotation", annoDecl); + log.error(pos, "invalid.repeatable.annotation", annoDecl); return null; } @@ -491,13 +491,13 @@ public class Annotate { } if (error) { log.error(pos, - "invalid.containedby.annotation.multiple.values", + "invalid.repeatable.annotation.multiple.values", targetContainerType, nr_value_elems); return null; } else if (nr_value_elems == 0) { log.error(pos, - "invalid.containedby.annotation.no.value", + "invalid.repeatable.annotation.no.value", targetContainerType); return null; } @@ -506,7 +506,7 @@ public class Annotate { // probably "impossible" to fail this if (containerValueSymbol.kind != Kinds.MTH) { log.error(pos, - "invalid.containedby.annotation.invalid.value", + "invalid.repeatable.annotation.invalid.value", targetContainerType); fatalError = true; } @@ -518,7 +518,7 @@ public class Annotate { if (!(types.isArray(valueRetType) && types.isSameType(expectedType, valueRetType))) { log.error(pos, - "invalid.containedby.annotation.value.return", + "invalid.repeatable.annotation.value.return", targetContainerType, valueRetType, expectedType); @@ -528,10 +528,7 @@ public class Annotate { fatalError = true; } - // Explicitly no check for/validity of @ContainerFor. That is - // done on declaration of the container, and at reflect time. - - // The rest of the conditions for a valid containing annotation are made + // The conditions for a valid containing annotation are made // in Check.validateRepeatedAnnotaton(); return fatalError ? null : containerValueSymbol; diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index da982534deb..a787b4845a1 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -3844,24 +3844,14 @@ public class Attr extends JCTree.Visitor { log.error(tree.typarams.head.pos(), "intf.annotation.cant.have.type.params"); - // If this annotation has a @ContainedBy, validate - Attribute.Compound containedBy = c.attribute(syms.containedByType.tsym); - if (containedBy != null) { - // get diagnositc position for error reporting - DiagnosticPosition cbPos = getDiagnosticPosition(tree, containedBy.type); + // If this annotation has a @Repeatable, validate + Attribute.Compound repeatable = c.attribute(syms.repeatableType.tsym); + if (repeatable != null) { + // get diagnostic position for error reporting + DiagnosticPosition cbPos = getDiagnosticPosition(tree, repeatable.type); Assert.checkNonNull(cbPos); - chk.validateContainedBy(c, containedBy, cbPos); - } - - // If this annotation has a @ContainerFor, validate - Attribute.Compound containerFor = c.attribute(syms.containerForType.tsym); - if (containerFor != null) { - // get diagnositc position for error reporting - DiagnosticPosition cfPos = getDiagnosticPosition(tree, containerFor.type); - Assert.checkNonNull(cfPos); - - chk.validateContainerFor(c, containerFor, cfPos); + chk.validateRepeatable(c, repeatable, cbPos); } } else { // Check that all extended classes and interfaces diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index 7db55b62c02..bcc9aa32bcb 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -2592,30 +2592,30 @@ public class Check { } /** - * Validate the proposed container 'containedBy' on the + * Validate the proposed container 'repeatable' on the * annotation type symbol 's'. Report errors at position * 'pos'. * - * @param s The (annotation)type declaration annotated with a @ContainedBy - * @param containedBy the @ContainedBy on 's' + * @param s The (annotation)type declaration annotated with a @Repeatable + * @param repeatable the @Repeatable on 's' * @param pos where to report errors */ - public void validateContainedBy(TypeSymbol s, Attribute.Compound containedBy, DiagnosticPosition pos) { - Assert.check(types.isSameType(containedBy.type, syms.containedByType)); + public void validateRepeatable(TypeSymbol s, Attribute.Compound repeatable, DiagnosticPosition pos) { + Assert.check(types.isSameType(repeatable.type, syms.repeatableType)); Type t = null; - List> l = containedBy.values; + List> l = repeatable.values; if (!l.isEmpty()) { Assert.check(l.head.fst.name == names.value); t = ((Attribute.Class)l.head.snd).getValue(); } if (t == null) { - log.error(pos, "invalid.container.wrong.containedby", s, containedBy); + // errors should already have been reported during Annotate return; } - validateHasContainerFor(t.tsym, s, pos); + validateValue(t.tsym, s, pos); validateRetention(t.tsym, s, pos); validateDocumented(t.tsym, s, pos); validateInherited(t.tsym, s, pos); @@ -2623,79 +2623,18 @@ public class Check { validateDefault(t.tsym, s, pos); } - /** - * Validate the proposed container 'containerFor' on the - * annotation type symbol 's'. Report errors at position - * 'pos'. - * - * @param s The (annotation)type declaration annotated with a @ContainerFor - * @param containerFor the @ContainedFor on 's' - * @param pos where to report errors - */ - public void validateContainerFor(TypeSymbol s, Attribute.Compound containerFor, DiagnosticPosition pos) { - Assert.check(types.isSameType(containerFor.type, syms.containerForType)); - - Type t = null; - List> l = containerFor.values; - if (!l.isEmpty()) { - Assert.check(l.head.fst.name == names.value); - t = ((Attribute.Class)l.head.snd).getValue(); + private void validateValue(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) { + Scope.Entry e = container.members().lookup(names.value); + if (e.scope != null && e.sym.kind == MTH) { + MethodSymbol m = (MethodSymbol) e.sym; + Type ret = m.getReturnType(); + if (!(ret.hasTag(ARRAY) && types.isSameType(((ArrayType)ret).elemtype, contained.type))) { + log.error(pos, "invalid.repeatable.annotation.value.return", + container, ret, types.makeArrayType(contained.type)); + } + } else { + log.error(pos, "invalid.repeatable.annotation.no.value", container); } - - if (t == null) { - log.error(pos, "invalid.container.wrong.containerfor", s, containerFor); - return; - } - - validateHasContainedBy(t.tsym, s, pos); - } - - private void validateHasContainedBy(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) { - Attribute.Compound containedBy = container.attribute(syms.containedByType.tsym); - - if (containedBy == null) { - log.error(pos, "invalid.container.no.containedby", container, syms.containedByType.tsym); - return; - } - - Type t = null; - List> l = containedBy.values; - if (!l.isEmpty()) { - Assert.check(l.head.fst.name == names.value); - t = ((Attribute.Class)l.head.snd).getValue(); - } - - if (t == null) { - log.error(pos, "invalid.container.wrong.containedby", container, contained); - return; - } - - if (!types.isSameType(t, contained.type)) - log.error(pos, "invalid.container.wrong.containedby", t.tsym, contained); - } - - private void validateHasContainerFor(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) { - Attribute.Compound containerFor = container.attribute(syms.containerForType.tsym); - - if (containerFor == null) { - log.error(pos, "invalid.container.no.containerfor", container, syms.containerForType.tsym); - return; - } - - Type t = null; - List> l = containerFor.values; - if (!l.isEmpty()) { - Assert.check(l.head.fst.name == names.value); - t = ((Attribute.Class)l.head.snd).getValue(); - } - - if (t == null) { - log.error(pos, "invalid.container.wrong.containerfor", container, contained); - return; - } - - if (!types.isSameType(t, contained.type)) - log.error(pos, "invalid.container.wrong.containerfor", t.tsym, contained); } private void validateRetention(Symbol container, Symbol contained, DiagnosticPosition pos) { @@ -2715,7 +2654,7 @@ public class Check { } } if (error ) { - log.error(pos, "invalid.containedby.annotation.retention", + log.error(pos, "invalid.repeatable.annotation.retention", container, containerRetention, contained, containedRetention); } @@ -2724,7 +2663,7 @@ public class Check { private void validateDocumented(Symbol container, Symbol contained, DiagnosticPosition pos) { if (contained.attribute(syms.documentedType.tsym) != null) { if (container.attribute(syms.documentedType.tsym) == null) { - log.error(pos, "invalid.containedby.annotation.not.documented", container, contained); + log.error(pos, "invalid.repeatable.annotation.not.documented", container, contained); } } } @@ -2732,7 +2671,7 @@ public class Check { private void validateInherited(Symbol container, Symbol contained, DiagnosticPosition pos) { if (contained.attribute(syms.inheritedType.tsym) != null) { if (container.attribute(syms.inheritedType.tsym) == null) { - log.error(pos, "invalid.containedby.annotation.not.inherited", container, contained); + log.error(pos, "invalid.repeatable.annotation.not.inherited", container, contained); } } } @@ -2752,7 +2691,7 @@ public class Check { // contained has target, but container has not, error Attribute.Array containerTarget = getAttributeTargetAttribute(container); if (containerTarget == null) { - log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained); + log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained); return; } @@ -2775,7 +2714,7 @@ public class Check { } if (!isTargetSubset(containedTargets, containerTargets)) { - log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained); + log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained); } } @@ -2809,7 +2748,7 @@ public class Check { elm.kind == Kinds.MTH && ((MethodSymbol)elm).defaultValue == null) { log.error(pos, - "invalid.containedby.annotation.elem.nondefault", + "invalid.repeatable.annotation.elem.nondefault", container, elm); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java b/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java index 517ec5b4703..14f6e366ddb 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java +++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java @@ -261,13 +261,13 @@ public class JavacElements implements Elements { } // Needed to unpack the runtime view of containing annotations - private static final Class CONTAINED_BY_CLASS = initContainedBy(); + private static final Class REPEATABLE_CLASS = initRepeatable(); private static final Method VALUE_ELEMENT_METHOD = initValueElementMethod(); - private static Class initContainedBy() { + private static Class initRepeatable() { try { - @SuppressWarnings("unchecked") // java.lang.annotation.ContainedBy extends Annotation by being an annotation type - Class c = (Class)Class.forName("java.lang.annotation.ContainedBy"); + @SuppressWarnings("unchecked") // java.lang.annotation.Repeatable extends Annotation by being an annotation type + Class c = (Class)Class.forName("java.lang.annotation.Repeatable"); return c; } catch (ClassNotFoundException e) { return null; @@ -276,12 +276,12 @@ public class JavacElements implements Elements { } } private static Method initValueElementMethod() { - if (CONTAINED_BY_CLASS == null) + if (REPEATABLE_CLASS == null) return null; Method m = null; try { - m = CONTAINED_BY_CLASS.getMethod("value"); + m = REPEATABLE_CLASS.getMethod("value"); if (m != null) m.setAccessible(true); return m; @@ -292,19 +292,19 @@ public class JavacElements implements Elements { // Helper to getAnnotations private static Class getContainer(Class annoType) { - // Since we can not refer to java.lang.annotation.ContainedBy until we are - // bootstrapping with java 8 we need to get the ContainedBy annotation using + // Since we can not refer to java.lang.annotation.Repeatable until we are + // bootstrapping with java 8 we need to get the Repeatable annotation using // reflective invocations instead of just using its type and element method. - if (CONTAINED_BY_CLASS != null && + if (REPEATABLE_CLASS != null && VALUE_ELEMENT_METHOD != null) { - // Get the ContainedBy instance on the annotations declaration - Annotation containedBy = (Annotation)annoType.getAnnotation(CONTAINED_BY_CLASS); - if (containedBy != null) { + // Get the Repeatable instance on the annotations declaration + Annotation repeatable = (Annotation)annoType.getAnnotation(REPEATABLE_CLASS); + if (repeatable != null) { try { // Get the value element, it should be a class // indicating the containing annotation type @SuppressWarnings("unchecked") - Class containerType = (Class)VALUE_ELEMENT_METHOD.invoke(containedBy); + Class containerType = (Class)VALUE_ELEMENT_METHOD.invoke(repeatable); if (containerType == null) return null; diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties index 1f36e636ccc..41c89491c63 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2013, 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 @@ -319,64 +319,48 @@ compiler.err.duplicate.annotation.member.value=\ compiler.err.duplicate.annotation.missing.container=\ duplicate annotation, the declaration of {0} does not have a valid {1} annotation -# 0: type, 1: type -compiler.err.invalid.container.no.containedby=\ - invalid contained repeatable annotation, {0} is not annotated with {1} - -# 0: type, 1: type -compiler.err.invalid.container.wrong.containedby=\ - invalid contained repeatable annotation, {0} does not match {1} - -# 0: type, 1: type -compiler.err.invalid.container.no.containerfor=\ - invalid container for repeating annotations, {0} is not annotated with {1} - -# 0: type, 1: type -compiler.err.invalid.container.wrong.containerfor=\ - invalid container for repeating annotations, {0} does not match {1} +# 0: type +compiler.err.invalid.repeatable.annotation=\ + duplicate annotation, {0} is annotated with an invalid Repeatable annotation # 0: type -compiler.err.invalid.containedby.annotation=\ - duplicate annotation, {0} is annotated with an invalid ContainedBy annotation - -# 0: type -compiler.err.invalid.containedby.annotation.no.value=\ - duplicate annotation, {0} is not a valid ContainedBy, no value element method declared +compiler.err.invalid.repeatable.annotation.no.value=\ + duplicate annotation, {0} is not a valid Repeatable, no value element method declared # 0: type, 1: number -compiler.err.invalid.containedby.annotation.multiple.values=\ - duplicate annotation, {0} is not a valid ContainedBy, {1} value element methods declared +compiler.err.invalid.repeatable.annotation.multiple.values=\ + duplicate annotation, {0} is not a valid Repeatable, {1} value element methods declared # 0: type -compiler.err.invalid.containedby.annotation.invalid.value=\ - duplicate annotation, {0} is not a valid ContainedBy, invalid value element, need a method +compiler.err.invalid.repeatable.annotation.invalid.value=\ + duplicate annotation, {0} is not a valid Repeatable, invalid value element, need a method # 0: type, 1: type, 2: type -compiler.err.invalid.containedby.annotation.value.return=\ +compiler.err.invalid.repeatable.annotation.value.return=\ duplicate annotation, value element of containing annotation {0} should have type {2}, found {1} # 0: type, 1: symbol -compiler.err.invalid.containedby.annotation.elem.nondefault=\ +compiler.err.invalid.repeatable.annotation.elem.nondefault=\ containing annotation {0} does not have a default value for element {1} # 0: symbol, 1: type, 2: symbol, 3: type -compiler.err.invalid.containedby.annotation.retention=\ +compiler.err.invalid.repeatable.annotation.retention=\ containing annotation {0} has shorter retention ({1}) than the contained annotation {2} with retention {3} # 0: symbol, 1: symbol -compiler.err.invalid.containedby.annotation.not.documented=\ +compiler.err.invalid.repeatable.annotation.not.documented=\ containing annotation type, {0}, is not @Documented while repeated annotation type, {1}, is # 0: symbol, 1: symbol -compiler.err.invalid.containedby.annotation.not.inherited=\ +compiler.err.invalid.repeatable.annotation.not.inherited=\ containing annotation type, {0}, is not @Inherited while repeated annotation type, {1}, is # 0: symbol, 1: symbol -compiler.err.invalid.containedby.annotation.incompatible.target=\ +compiler.err.invalid.repeatable.annotation.incompatible.target=\ target of container annotation {0} is not a subset of target of repeated annotation {1} # 0: symbol -compiler.err.invalid.containedby.annotation.repeated.and.container.present=\ +compiler.err.invalid.repeatable.annotation.repeated.and.container.present=\ container {0} must not be present at the same time as the element it contains # 0: name diff --git a/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContaineeSynthDoc.java b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContaineeSynthDoc.java index 8499ffb5e8b..a0208e201b3 100644 --- a/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContaineeSynthDoc.java +++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContaineeSynthDoc.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -32,6 +32,6 @@ import java.lang.annotation.*; * @author Bhavesh Patel */ @Documented -@ContainedBy(ContainerSynthDoc.class) +@Repeatable(ContainerSynthDoc.class) public @interface ContaineeSynthDoc { } diff --git a/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContainerSynthDoc.java b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContainerSynthDoc.java index 950b923d357..bdf86ee8537 100644 --- a/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContainerSynthDoc.java +++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContainerSynthDoc.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -32,7 +32,6 @@ import java.lang.annotation.*; * @author Bhavesh Patel */ @Documented -@ContainerFor(ContaineeSynthDoc.class) public @interface ContainerSynthDoc { ContaineeSynthDoc[] value(); diff --git a/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContaineeSynthDoc.java b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContaineeSynthDoc.java index 15722e3324e..a3211095282 100644 --- a/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContaineeSynthDoc.java +++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContaineeSynthDoc.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -32,6 +32,6 @@ import java.lang.annotation.*; * @author Bhavesh Patel */ @Documented -@ContainedBy(ContainerSynthNotDoc.class) +@Repeatable(ContainerSynthNotDoc.class) public @interface ContaineeSynthDoc { } diff --git a/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContainerSynthNotDoc.java b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContainerSynthNotDoc.java index fbdfc272b18..247dd1edd2e 100644 --- a/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContainerSynthNotDoc.java +++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContainerSynthNotDoc.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -31,7 +31,6 @@ import java.lang.annotation.*; * * @author Bhavesh Patel */ -@ContainerFor(ContaineeSynthDoc.class) public @interface ContainerSynthNotDoc { ContaineeSynthDoc[] value(); diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/BaseAnnoAsContainerAnno.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/BaseAnnoAsContainerAnno.java index d508fea04c7..baf8b14363a 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/BaseAnnoAsContainerAnno.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/BaseAnnoAsContainerAnno.java @@ -6,11 +6,9 @@ * @compile/fail/ref=BaseAnnoAsContainerAnno.out -XDrawDiagnostics BaseAnnoAsContainerAnno.java */ -import java.lang.annotation.ContainedBy; -import java.lang.annotation.ContainerFor; +import java.lang.annotation.Repeatable; -@ContainedBy(Foo.class) -@ContainerFor(Foo.class) +@Repeatable(Foo.class) @interface Foo { Foo[] value() default {}; } diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/BaseAnnoAsContainerAnno.out b/langtools/test/tools/javac/annotations/repeatingAnnotations/BaseAnnoAsContainerAnno.out index 8f2419f297b..0d6975ac424 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/BaseAnnoAsContainerAnno.out +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/BaseAnnoAsContainerAnno.out @@ -1,2 +1,2 @@ -BaseAnnoAsContainerAnno.java:15:11: compiler.err.cyclic.annotation.element +BaseAnnoAsContainerAnno.java:13:11: compiler.err.cyclic.annotation.element 1 error diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/BasicRepeatingAnnotations.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/BasicRepeatingAnnotations.java index 9d9e59c1fc4..848cd18cc39 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/BasicRepeatingAnnotations.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/BasicRepeatingAnnotations.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -34,10 +34,9 @@ import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) -@ContainedBy(Foos.class) +@Repeatable(Foos.class) @interface Foo {} -@ContainerFor(Foo.class) @Retention(RetentionPolicy.RUNTIME) @interface Foos { Foo[] value(); diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/CheckTargets.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/CheckTargets.java index 1489cea562d..bdcfb1e51dc 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/CheckTargets.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/CheckTargets.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -32,32 +32,29 @@ import java.lang.annotation.*; -@ContainedBy(Foos.class) +@Repeatable(Foos.class) @Target(ElementType.TYPE) @interface Foo {} -@ContainerFor(Foo.class) @Target(ElementType.ANNOTATION_TYPE) @interface Foos { Foo[] value(); } -@ContainedBy(Bars.class) +@Repeatable(Bars.class) @Target(ElementType.TYPE) @interface Bar {} -@ContainerFor(Bar.class) @Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE }) @interface Bars { Bar[] value(); } -@ContainedBy(Bazs.class) +@Repeatable(Bazs.class) @Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE }) @interface Baz {} -@ContainerFor(Baz.class) @Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE }) @interface Bazs { Baz[] value(); diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/ClassReaderDefault.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/ClassReaderDefault.java index 18d9d7c6a41..f441f5b046c 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/ClassReaderDefault.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/ClassReaderDefault.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -30,17 +30,15 @@ * @compile ClassReaderDefault.java * @compile SeparateCompile.java */ -import java.lang.annotation.ContainedBy; -import java.lang.annotation.ContainerFor; +import java.lang.annotation.Repeatable; public class ClassReaderDefault { } -@ContainerFor(Foo.class) @interface FooContainer { Foo[] value(); int f() default 0; } -@ContainedBy(FooContainer.class) +@Repeatable(FooContainer.class) @interface Foo {} diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/ContainerHasRepeatedContained.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/ContainerHasRepeatedContained.java index ca2345d6b16..86cb6a071bd 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/ContainerHasRepeatedContained.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/ContainerHasRepeatedContained.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -30,15 +30,13 @@ * @run compile ContainerHasRepeatedContained.java */ -import java.lang.annotation.ContainedBy; -import java.lang.annotation.ContainerFor; +import java.lang.annotation.Repeatable; -@ContainedBy(BarContainer.class) +@Repeatable(BarContainer.class) @interface Bar {} @Bar @Bar -@ContainerFor(Bar.class) @interface BarContainer { Bar[] value(); } diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/CyclicAnnotation.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/CyclicAnnotation.java index 7549d464d5f..82d52700459 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/CyclicAnnotation.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/CyclicAnnotation.java @@ -6,17 +6,14 @@ * @compile/fail/ref=CyclicAnnotation.out -XDrawDiagnostics CyclicAnnotation.java */ -import java.lang.annotation.ContainedBy; -import java.lang.annotation.ContainerFor; +import java.lang.annotation.Repeatable; -@ContainedBy(Foo.class) -@ContainerFor(Baz.class) +@Repeatable(Foo.class) @interface Baz { Foo[] value() default {}; } -@ContainedBy(Baz.class) -@ContainerFor(Foo.class) +@Repeatable(Baz.class) @interface Foo{ Baz[] value() default {}; } diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/CyclicAnnotation.out b/langtools/test/tools/javac/annotations/repeatingAnnotations/CyclicAnnotation.out index 070b8ca0883..84079dd77b4 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/CyclicAnnotation.out +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/CyclicAnnotation.out @@ -1,6 +1,2 @@ -CyclicAnnotation.java:12:1: compiler.err.invalid.container.wrong.containerfor: Foo, Baz -CyclicAnnotation.java:13:1: compiler.err.invalid.container.wrong.containedby: Foo, Baz -CyclicAnnotation.java:15:11: compiler.err.cyclic.annotation.element -CyclicAnnotation.java:18:1: compiler.err.invalid.container.wrong.containerfor: Baz, Foo -CyclicAnnotation.java:19:1: compiler.err.invalid.container.wrong.containedby: Baz, Foo -5 errors +CyclicAnnotation.java:13:11: compiler.err.cyclic.annotation.element +1 error diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/DefaultCasePresent.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/DefaultCasePresent.java index 7352a622119..4f8778d4488 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/DefaultCasePresent.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DefaultCasePresent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -29,13 +29,11 @@ * @compile DefaultCasePresent.java */ -import java.lang.annotation.ContainedBy; -import java.lang.annotation.ContainerFor; +import java.lang.annotation.Repeatable; -@ContainedBy(FooContainer.class) +@Repeatable(FooContainer.class) @interface Foo {} -@ContainerFor(Foo.class) @interface FooContainer { Foo[] value(); String other() default "other-method"; diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/DelayRepeatedContainer.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/DelayRepeatedContainer.java index ffceb9c3707..939ce4a3266 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/DelayRepeatedContainer.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DelayRepeatedContainer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -39,12 +39,11 @@ public class DelayRepeatedContainer { @Bar("katt") @Bar("lol") -@ContainedBy(BarContainer.class) +@Repeatable(BarContainer.class) @interface Bar { String value(); } -@ContainerFor(Bar.class) @interface BarContainer { Bar[] value(); } diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/DocumentedContainerAnno.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/DocumentedContainerAnno.java index 96d86f7a368..95fd96ceda2 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/DocumentedContainerAnno.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DocumentedContainerAnno.java @@ -6,15 +6,13 @@ * @compile/fail/ref=DocumentedContainerAnno.out -XDrawDiagnostics DocumentedContainerAnno.java */ -import java.lang.annotation.ContainedBy; -import java.lang.annotation.ContainerFor; +import java.lang.annotation.Repeatable; import java.lang.annotation.Documented; @Documented -@ContainedBy(FooContainer.class) +@Repeatable(FooContainer.class) @interface Foo {} -@ContainerFor(Foo.class) @interface FooContainer{ Foo[] value(); } diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/DocumentedContainerAnno.out b/langtools/test/tools/javac/annotations/repeatingAnnotations/DocumentedContainerAnno.out index 409d0414e77..bb267c47af3 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/DocumentedContainerAnno.out +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DocumentedContainerAnno.out @@ -1,2 +1,2 @@ -DocumentedContainerAnno.java:14:1: compiler.err.invalid.containedby.annotation.not.documented: FooContainer, Foo +DocumentedContainerAnno.java:13:1: compiler.err.invalid.repeatable.annotation.not.documented: FooContainer, Foo 1 error diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/InheritedContainerAnno.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/InheritedContainerAnno.java index 2d2a9c63894..20f8ad25224 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/InheritedContainerAnno.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/InheritedContainerAnno.java @@ -6,15 +6,13 @@ * @compile/fail/ref=InheritedContainerAnno.out -XDrawDiagnostics InheritedContainerAnno.java */ -import java.lang.annotation.ContainedBy; -import java.lang.annotation.ContainerFor; +import java.lang.annotation.Repeatable; import java.lang.annotation.Inherited; @Inherited -@ContainedBy(FooContainer.class) +@Repeatable(FooContainer.class) @interface Foo {} -@ContainerFor(Foo.class) @interface FooContainer{ Foo[] value(); } diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/InheritedContainerAnno.out b/langtools/test/tools/javac/annotations/repeatingAnnotations/InheritedContainerAnno.out index 10fcc772581..43736227f0d 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/InheritedContainerAnno.out +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/InheritedContainerAnno.out @@ -1,2 +1,2 @@ -InheritedContainerAnno.java:14:1: compiler.err.invalid.containedby.annotation.not.inherited: FooContainer, Foo +InheritedContainerAnno.java:13:1: compiler.err.invalid.repeatable.annotation.not.inherited: FooContainer, Foo 1 error diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/InvalidTarget.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/InvalidTarget.java index 24c23386033..f85924a5d4c 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/InvalidTarget.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/InvalidTarget.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -32,11 +32,10 @@ import java.lang.annotation.*; -@ContainedBy(Foos.class) +@Repeatable(Foos.class) @Target(ElementType.ANNOTATION_TYPE) @interface Foo {} -@ContainerFor(Foo.class) @Target(ElementType.TYPE) @interface Foos { Foo[] value(); diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainer.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainer.java index 8e5650442dc..e35273e0f4a 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainer.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainer.java @@ -6,13 +6,11 @@ * @compile/fail/ref=MissingContainer.out -XDrawDiagnostics MissingContainer.java */ -import java.lang.annotation.ContainedBy; -import java.lang.annotation.ContainerFor; +import java.lang.annotation.Repeatable; -@ContainedBy() +@Repeatable() @interface Foo {} -@ContainerFor(Foo.class) @interface FooContainer { Foo[] value(); } diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainer.out b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainer.out index 76986a76769..5a0e89df1ee 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainer.out +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainer.out @@ -1,5 +1,4 @@ -MissingContainer.java:20:1: compiler.err.invalid.containedby.annotation: Foo -MissingContainer.java:20:6: compiler.err.invalid.containedby.annotation: Foo -MissingContainer.java:12:1: compiler.err.annotation.missing.default.value: java.lang.annotation.ContainedBy, value -MissingContainer.java:15:1: compiler.err.invalid.container.wrong.containedby: Foo, FooContainer -4 errors +MissingContainer.java:18:1: compiler.err.invalid.repeatable.annotation: Foo +MissingContainer.java:18:6: compiler.err.invalid.repeatable.annotation: Foo +MissingContainer.java:11:1: compiler.err.annotation.missing.default.value: java.lang.annotation.Repeatable, value +3 errors diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainerFor.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainerFor.java deleted file mode 100644 index 7d22aebf9b3..00000000000 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainerFor.java +++ /dev/null @@ -1,38 +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. - */ - -/** - * @test - * @summary Smoke test for repeating annotations - * @compile/fail MissingContainerFor.java - * @bug 7151010 - */ - -import java.lang.annotation.*; - -@interface Foos { - MissingContainerFor[] value(); -} - -@ContainedBy(Foos.class) -public @interface MissingContainerFor {} diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase1.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase1.java index c29d0e8afa7..478154738c6 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase1.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase1.java @@ -6,13 +6,11 @@ * @compile/fail/ref=MissingDefaultCase1.out -XDrawDiagnostics MissingDefaultCase1.java */ -import java.lang.annotation.ContainedBy; -import java.lang.annotation.ContainerFor; +import java.lang.annotation.Repeatable; -@ContainedBy(FooContainer.class) +@Repeatable(FooContainer.class) @interface Foo {} -@ContainerFor(Foo.class) @interface FooContainer { Foo[] value(); String other(); // missing default clause diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase1.out b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase1.out index ae188503866..474b6c16451 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase1.out +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase1.out @@ -1,3 +1,3 @@ -MissingDefaultCase1.java:21:1: compiler.err.duplicate.annotation.invalid.repeated: Foo -MissingDefaultCase1.java:12:1: compiler.err.invalid.containedby.annotation.elem.nondefault: FooContainer, other() +MissingDefaultCase1.java:19:1: compiler.err.duplicate.annotation.invalid.repeated: Foo +MissingDefaultCase1.java:11:1: compiler.err.invalid.repeatable.annotation.elem.nondefault: FooContainer, other() 2 errors diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase2.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase2.java index b0b42b40cfc..73f2cfe6500 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase2.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase2.java @@ -6,13 +6,11 @@ * @compile/fail/ref=MissingDefaultCase2.out -XDrawDiagnostics MissingDefaultCase2.java */ -import java.lang.annotation.ContainedBy; -import java.lang.annotation.ContainerFor; +import java.lang.annotation.Repeatable; -@ContainedBy(FooContainer.class) +@Repeatable(FooContainer.class) @interface Foo {} -@ContainerFor(Foo.class) @interface FooContainer { Foo[] value(); Foo other(); // missing default clause and return type is an annotation diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase2.out b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase2.out index 7e3a4229587..de467107770 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase2.out +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase2.out @@ -1,3 +1,3 @@ -MissingDefaultCase2.java:21:1: compiler.err.duplicate.annotation.invalid.repeated: Foo -MissingDefaultCase2.java:12:1: compiler.err.invalid.containedby.annotation.elem.nondefault: FooContainer, other() +MissingDefaultCase2.java:19:1: compiler.err.duplicate.annotation.invalid.repeated: Foo +MissingDefaultCase2.java:11:1: compiler.err.invalid.repeatable.annotation.elem.nondefault: FooContainer, other() 2 errors diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingValueMethod.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingValueMethod.java index 36333b75cb2..a539a94c59a 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingValueMethod.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingValueMethod.java @@ -6,13 +6,11 @@ * @compile/fail/ref=MissingValueMethod.out -XDrawDiagnostics MissingValueMethod.java */ -import java.lang.annotation.ContainedBy; -import java.lang.annotation.ContainerFor; +import java.lang.annotation.Repeatable; -@ContainedBy(FooContainer.class) +@Repeatable(FooContainer.class) @interface Foo {} -@ContainerFor(Foo.class) @interface FooContainer{ Foo[] values(); // wrong method name } diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingValueMethod.out b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingValueMethod.out index a712b5fa798..bb1e8888d61 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingValueMethod.out +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingValueMethod.out @@ -1,4 +1,4 @@ -MissingValueMethod.java:20:1: compiler.err.invalid.containedby.annotation.no.value: FooContainer -MissingValueMethod.java:20:6: compiler.err.invalid.containedby.annotation.no.value: FooContainer -MissingValueMethod.java:12:1: compiler.err.invalid.containedby.annotation.elem.nondefault: FooContainer, values() +MissingValueMethod.java:18:1: compiler.err.invalid.repeatable.annotation.no.value: FooContainer +MissingValueMethod.java:18:6: compiler.err.invalid.repeatable.annotation.no.value: FooContainer +MissingValueMethod.java:11:1: compiler.err.invalid.repeatable.annotation.no.value: FooContainer 3 errors diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/MultiLevelRepeatableAnno.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/MultiLevelRepeatableAnno.java index 62b0089e0a4..8459f863329 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MultiLevelRepeatableAnno.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MultiLevelRepeatableAnno.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -29,19 +29,16 @@ * @compile MultiLevelRepeatableAnno.java */ -import java.lang.annotation.ContainedBy; -import java.lang.annotation.ContainerFor; +import java.lang.annotation.Repeatable; -@ContainedBy(FooContainer.class) +@Repeatable(FooContainer.class) @interface Foo {} -@ContainedBy(FooContainerContainer.class) -@ContainerFor(Foo.class) +@Repeatable(FooContainerContainer.class) @interface FooContainer { Foo[] value(); } -@ContainerFor(FooContainer.class) @interface FooContainerContainer { FooContainer[] value(); } diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/MultipleAnnoMixedOrder.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/MultipleAnnoMixedOrder.java index 0de0c3221a0..5992dfc8ee7 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MultipleAnnoMixedOrder.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MultipleAnnoMixedOrder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -29,25 +29,22 @@ * @compile MultipleAnnoMixedOrder.java */ -import java.lang.annotation.ContainedBy; -import java.lang.annotation.ContainerFor; +import java.lang.annotation.Repeatable; -@ContainedBy(FooContainer.class) +@Repeatable(FooContainer.class) @interface Foo { int getNumbers(); } -@ContainerFor(Foo.class) @interface FooContainer { Foo[] value(); } -@ContainedBy(BazContainer.class) +@Repeatable(BazContainer.class) @interface Baz { String getStr(); } -@ContainerFor(Baz.class) @interface BazContainer { Baz[] value(); } diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/NestedContainers.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/NestedContainers.java index c492258801a..4694989e821 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/NestedContainers.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/NestedContainers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -34,17 +34,15 @@ import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) -@ContainedBy(Foos.class) +@Repeatable(Foos.class) @interface Foo {} @Retention(RetentionPolicy.RUNTIME) -@ContainedBy(FoosFoos.class) -@ContainerFor(Foo.class) +@Repeatable(FoosFoos.class) @interface Foos { Foo[] value(); } -@ContainerFor(Foos.class) @Retention(RetentionPolicy.RUNTIME) @interface FoosFoos { Foos[] value(); diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/NoRepeatableAnno.out b/langtools/test/tools/javac/annotations/repeatingAnnotations/NoRepeatableAnno.out index 42a8105b79d..1af160338c3 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/NoRepeatableAnno.out +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/NoRepeatableAnno.out @@ -1,3 +1,3 @@ -NoRepeatableAnno.java:11:1: compiler.err.duplicate.annotation.missing.container: Foo, java.lang.annotation.ContainedBy -NoRepeatableAnno.java:11:6: compiler.err.duplicate.annotation.missing.container: Foo, java.lang.annotation.ContainedBy +NoRepeatableAnno.java:11:1: compiler.err.duplicate.annotation.missing.container: Foo, java.lang.annotation.Repeatable +NoRepeatableAnno.java:11:6: compiler.err.duplicate.annotation.missing.container: Foo, java.lang.annotation.Repeatable 2 errors diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepMemberAnno.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepMemberAnno.java index bb67c91cee0..2a6fc880f3f 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepMemberAnno.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepMemberAnno.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -30,20 +30,18 @@ * @run compile RepMemberAnno.java */ -import java.lang.annotation.ContainedBy; -import java.lang.annotation.ContainerFor; +import java.lang.annotation.Repeatable; public class RepMemberAnno { @Bar("Apa") @Bar("Banan") public void meh() {} } -@ContainedBy(BarContainer.class) +@Repeatable(BarContainer.class) @interface Bar { String value(); } -@ContainerFor(Bar.class) @interface BarContainer { Bar[] value(); } diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepSelfMemberAnno.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepSelfMemberAnno.java index bc11c69c1f0..79fdf213863 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepSelfMemberAnno.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepSelfMemberAnno.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -34,21 +34,19 @@ import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) -@ContainedBy(BarContainer.class) +@Repeatable(BarContainer.class) public @interface RepSelfMemberAnno { @RepSelfMemberAnno @RepSelfMemberAnno String meh() default "banan"; } -@ContainedBy(BarContainerContainer.class) +@Repeatable(BarContainerContainer.class) @Retention(RetentionPolicy.RUNTIME) -@ContainerFor(RepSelfMemberAnno.class) @interface BarContainer { RepSelfMemberAnno[] value(); } -@ContainerFor(BarContainer.class) @Retention(RetentionPolicy.RUNTIME) @interface BarContainerContainer { BarContainer[] value(); diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.java index 26d98513502..62bc29f10bc 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -30,7 +30,7 @@ import java.lang.annotation.*; -@ContainedBy(Foos.class) +@Repeatable(Foos.class) @interface Foo {} @interface Foos { diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingTargetNotAllowed.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingTargetNotAllowed.java index 7210b3f573b..7d2ba5e7673 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingTargetNotAllowed.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingTargetNotAllowed.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -31,10 +31,9 @@ import java.lang.annotation.*; -@ContainedBy(Foos.class) +@Repeatable(Foos.class) @interface Foo {} -@ContainerFor(Foo.class) @Target(ElementType.ANNOTATION_TYPE) @interface Foos { Foo[] value(); diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingTargetNotAllowed.out b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingTargetNotAllowed.out index fd4b6acc4cc..7979c8213b9 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingTargetNotAllowed.out +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingTargetNotAllowed.out @@ -1,2 +1,2 @@ -RepeatingTargetNotAllowed.java:44:5: compiler.err.invalid.containedby.annotation.incompatible.target: Foos, Foo +RepeatingTargetNotAllowed.java:43:5: compiler.err.invalid.repeatable.annotation.incompatible.target: Foos, Foo 1 error diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/SelfRepeatingAnnotations.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/SelfRepeatingAnnotations.java index b0eb87d876b..7a70c90562d 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/SelfRepeatingAnnotations.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/SelfRepeatingAnnotations.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -33,7 +33,6 @@ import java.lang.annotation.*; -@ContainerFor(SelfRepeatingAnno.class) @Retention(RetentionPolicy.RUNTIME) @interface Foos { SelfRepeatingAnno[] value(); @@ -42,7 +41,7 @@ import java.lang.annotation.*; @SelfRepeatingAnno @Retention(RetentionPolicy.RUNTIME) @SelfRepeatingAnno -@ContainedBy(Foos.class) +@Repeatable(Foos.class) @interface SelfRepeatingAnno {} public class SelfRepeatingAnnotations { diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/SingleRepeatingAndContainer.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/SingleRepeatingAndContainer.java index b18d259670f..56cc83ca5d6 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/SingleRepeatingAndContainer.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/SingleRepeatingAndContainer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -30,10 +30,9 @@ import java.lang.annotation.*; -@ContainedBy(Foos.class) +@Repeatable(Foos.class) @interface Foo {} -@ContainerFor(Foo.class) @interface Foos { Foo[] value(); } diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainedBy.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainedBy.java deleted file mode 100644 index a8a8a633d6b..00000000000 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainedBy.java +++ /dev/null @@ -1,42 +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. - */ - -/** - * @test - * @summary Smoke test for repeating annotations - * @compile/fail UseWrongContainedBy.java - * @bug 7151010 - */ - -import java.lang.annotation.*; - -@ContainerFor(UseWrongContainedBy.class) -@interface Foos { - UseWrongContainedBy[] value(); -} - -@ContainedBy(Target.class) -public @interface UseWrongContainedBy {} - -@UseWrongContainedBy @UseWrongContainedBy -@interface Foo {} diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainerFor.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainerFor.java deleted file mode 100644 index 5067ef20625..00000000000 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainerFor.java +++ /dev/null @@ -1,42 +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. - */ - -/** - * @test - * @summary Smoke test for repeating annotations - * @compile/fail UseWrongContainerFor.java - * @bug 7151010 - */ - -import java.lang.annotation.*; - -@ContainerFor(Retention.class) -@interface Foos { - UseWrongContainerFor[] value(); -} - -@ContainedBy(Foos.class) -public @interface UseWrongContainerFor {} - -@UseWrongContainerFor @UseWrongContainerFor -@interface Foo {} diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainedBy.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongRepeatable.java similarity index 79% rename from langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainedBy.java rename to langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongRepeatable.java index 0a141a9e129..8d4b37f4c31 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainedBy.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongRepeatable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -24,16 +24,18 @@ /** * @test * @summary Smoke test for repeating annotations - * @compile/fail MissingContainedBy.java + * @compile/fail UseWrongRepeatable.java * @bug 7151010 */ import java.lang.annotation.*; - -@ContainerFor(MissingContainedBy.class) @interface Foos { - MissingContainedBy[] value(); + UseWrongRepeatable[] value(); } -public @interface MissingContainedBy {} +@Repeatable(Target.class) +public @interface UseWrongRepeatable {} + +@UseWrongRepeatable @UseWrongRepeatable +@interface Foo {} diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainedBy.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainedBy.java deleted file mode 100644 index 182acf0534d..00000000000 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainedBy.java +++ /dev/null @@ -1,39 +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. - */ - -/** - * @test - * @summary Smoke test for repeating annotations - * @compile/fail WrongContainedBy.java - * @bug 7151010 - */ - -import java.lang.annotation.*; - -@ContainerFor(WrongContainedBy.class) -@interface Foos { - WrongContainedBy[] value(); -} - -@ContainedBy(Target.class) -public @interface WrongContainedBy {} diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainerFor.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainerFor.java deleted file mode 100644 index c87bdbcc40b..00000000000 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainerFor.java +++ /dev/null @@ -1,39 +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. - */ - -/** - * @test - * @summary Smoke test for repeating annotations - * @compile/fail WrongContainerFor.java - * @bug 7151010 - */ - -import java.lang.annotation.*; - -@ContainerFor(Retention.class) -@interface Foos { - WrongContainerFor[] value(); -} - -@ContainedBy(Foos.class) -public @interface WrongContainerFor {} diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongReturnTypeForValue.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongReturnTypeForValue.java index 6573f2f86e7..69f25b6985a 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongReturnTypeForValue.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongReturnTypeForValue.java @@ -6,15 +6,13 @@ * @compile/fail/ref=WrongReturnTypeForValue.out -XDrawDiagnostics WrongReturnTypeForValue.java */ -import java.lang.annotation.ContainedBy; -import java.lang.annotation.ContainerFor; +import java.lang.annotation.Repeatable; -@ContainedBy(FooContainer.class) +@Repeatable(FooContainer.class) @interface Foo { int getNumbers(); } -@ContainerFor(Foo.class) @interface FooContainer{ Foo value(); // wrong return type } diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongReturnTypeForValue.out b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongReturnTypeForValue.out index aa2c6384851..add7bbaa3ae 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongReturnTypeForValue.out +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongReturnTypeForValue.out @@ -1,3 +1,4 @@ -WrongReturnTypeForValue.java:22:1: compiler.err.invalid.containedby.annotation.value.return: FooContainer, Foo, Foo[] -WrongReturnTypeForValue.java:22:6: compiler.err.invalid.containedby.annotation.value.return: FooContainer, Foo, Foo[] -2 errors +WrongReturnTypeForValue.java:20:1: compiler.err.invalid.repeatable.annotation.value.return: FooContainer, Foo, Foo[] +WrongReturnTypeForValue.java:20:6: compiler.err.invalid.repeatable.annotation.value.return: FooContainer, Foo, Foo[] +WrongReturnTypeForValue.java:11:1: compiler.err.invalid.repeatable.annotation.value.return: FooContainer, Foo, Foo[] +3 errors diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/BasicSyntaxCombo.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/BasicSyntaxCombo.java index 802f631f5b1..03e9dbe8e37 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/BasicSyntaxCombo.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/BasicSyntaxCombo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -163,9 +163,8 @@ public class BasicSyntaxCombo extends Helper{ String replaceStr = "/*"+type+"*/"; StringBuilder annoData = new StringBuilder(); annoData.append(Helper.ContentVars.IMPORTCONTAINERSTMTS.getVal()) - .append(Helper.ContentVars.CONTAINERFOR.getVal()) .append(Helper.ContentVars.CONTAINER.getVal()) - .append(Helper.ContentVars.CONTAINEDBY.getVal()) + .append(Helper.ContentVars.REPEATABLE.getVal()) .append(Helper.ContentVars.BASE.getVal()); JavaFileObject pkgInfoFile = null; diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DeprecatedAnnoCombo.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DeprecatedAnnoCombo.java index ba4e1652a03..8a2bcca1f30 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DeprecatedAnnoCombo.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DeprecatedAnnoCombo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -115,24 +115,21 @@ public class DeprecatedAnnoCombo extends Helper { switch(className) { case "DeprecatedonBoth": annoData.append(Helper.ContentVars.DEPRECATED.getVal()) - .append(Helper.ContentVars.CONTAINERFOR.getVal()) .append(Helper.ContentVars.CONTAINER.getVal()) .append(Helper.ContentVars.DEPRECATED.getVal()) - .append(Helper.ContentVars.CONTAINEDBY.getVal()) + .append(Helper.ContentVars.REPEATABLE.getVal()) .append(Helper.ContentVars.BASE.getVal()); break; case "DeprecatedonBase": - annoData.append(Helper.ContentVars.CONTAINERFOR.getVal()) - .append(Helper.ContentVars.CONTAINER.getVal()) + annoData.append(Helper.ContentVars.CONTAINER.getVal()) .append(Helper.ContentVars.DEPRECATED.getVal()) - .append(Helper.ContentVars.CONTAINEDBY.getVal()) + .append(Helper.ContentVars.REPEATABLE.getVal()) .append(Helper.ContentVars.BASE.getVal()); break; case "DeprecatedonContainer": annoData.append(Helper.ContentVars.DEPRECATED.getVal()) - .append(Helper.ContentVars.CONTAINERFOR.getVal()) .append(Helper.ContentVars.CONTAINER.getVal()) - .append(Helper.ContentVars.CONTAINEDBY.getVal()) + .append(Helper.ContentVars.REPEATABLE.getVal()) .append(Helper.ContentVars.BASE.getVal()); break; } diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DocumentedAnnoCombo.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DocumentedAnnoCombo.java index dbe38afd768..4bb3728dda0 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DocumentedAnnoCombo.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DocumentedAnnoCombo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -93,17 +93,15 @@ public class DocumentedAnnoCombo extends Helper { switch(className) { case "DocumentedonBothAnno": annoData.append(Helper.ContentVars.DOCUMENTED.getVal()) - .append(Helper.ContentVars.CONTAINERFOR.getVal()) .append(Helper.ContentVars.CONTAINER.getVal()) .append(Helper.ContentVars.DOCUMENTED.getVal()) - .append(Helper.ContentVars.CONTAINEDBY.getVal()) + .append(Helper.ContentVars.REPEATABLE.getVal()) .append(Helper.ContentVars.BASE.getVal()); break; case "DocumentedonContainer": annoData.append(Helper.ContentVars.DOCUMENTED.getVal()) - .append(Helper.ContentVars.CONTAINERFOR.getVal()) .append(Helper.ContentVars.CONTAINER.getVal()) - .append(Helper.ContentVars.CONTAINEDBY.getVal()) + .append(Helper.ContentVars.REPEATABLE.getVal()) .append(Helper.ContentVars.BASE.getVal()); break; } diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java index 653c2f5ce0a..8a0109578c1 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -34,15 +34,13 @@ import javax.tools.JavaCompiler.CompilationTask; public class Helper { enum ContentVars { - IMPORTCONTAINERSTMTS("\nimport java.lang.annotation.ContainedBy;\n" + - "\nimport java.lang.annotation.ContainerFor;\n"), + IMPORTCONTAINERSTMTS("\nimport java.lang.annotation.Repeatable;\n"), IMPORTDEPRECATED("import java.lang.Deprecated;\n"), IMPORTDOCUMENTED("import java.lang.annotation.Documented;\n"), IMPORTINHERITED("import java.lang.annotation.Inherited;\n"), IMPORTRETENTION("import java.lang.annotation.Retention;\n" + "\nimport java.lang.annotation.RetentionPolicy;\n"), - CONTAINEDBY("\n@ContainedBy(FooContainer.class)\n"), - CONTAINERFOR("@ContainerFor(Foo.class)\n"), + REPEATABLE("\n@Repeatable(FooContainer.class)\n"), CONTAINER("@interface FooContainer {\n" +" Foo[] value();\n}\n"), BASE("@interface Foo {}\n"), REPEATABLEANNO("\n@Foo() @Foo()"), diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/InheritedAnnoCombo.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/InheritedAnnoCombo.java index b0b019f065d..cb49350f6fd 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/InheritedAnnoCombo.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/InheritedAnnoCombo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -94,17 +94,15 @@ public class InheritedAnnoCombo extends Helper { switch(className) { case "InheritedonBothAnno": annoData.append(Helper.ContentVars.INHERITED.getVal()) - .append(Helper.ContentVars.CONTAINERFOR.getVal()) .append(Helper.ContentVars.CONTAINER.getVal()) .append(Helper.ContentVars.INHERITED.getVal()) - .append(Helper.ContentVars.CONTAINEDBY.getVal()) + .append(Helper.ContentVars.REPEATABLE.getVal()) .append(Helper.ContentVars.BASE.getVal()); break; case "InheritedonBase": annoData.append(Helper.ContentVars.INHERITED.getVal()) - .append(Helper.ContentVars.CONTAINERFOR.getVal()) .append(Helper.ContentVars.CONTAINER.getVal()) - .append(Helper.ContentVars.CONTAINEDBY.getVal()) + .append(Helper.ContentVars.REPEATABLE.getVal()) .append(Helper.ContentVars.BASE.getVal()); break; } diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/RetentionAnnoCombo.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/RetentionAnnoCombo.java index 99c5c5eb0ce..3a5ebaf142b 100644 --- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/RetentionAnnoCombo.java +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/RetentionAnnoCombo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -120,7 +120,7 @@ public class RetentionAnnoCombo extends Helper { new DiagnosticCollector(); boolean ok = compileCode(className, contents, diagnostics); - String expectedErrKey = "compiler.err.invalid.containedby" + + String expectedErrKey = "compiler.err.invalid.repeatable" + ".annotation.retention"; if (!shouldCompile && !ok) { for (Diagnostic d : diagnostics.getDiagnostics()) { @@ -175,10 +175,9 @@ public class RetentionAnnoCombo extends Helper { StringBuilder annoData = new StringBuilder(); annoData.append(Helper.ContentVars.IMPORTCONTAINERSTMTS.getVal()) .append(Helper.ContentVars.IMPORTRETENTION.getVal()) - .append(Helper.ContentVars.CONTAINERFOR.getVal()) .append(replacedRetCAVal) .append(Helper.ContentVars.CONTAINER.getVal()) - .append(Helper.ContentVars.CONTAINEDBY.getVal()) + .append(Helper.ContentVars.REPEATABLE.getVal()) .append(replacedRetBaseVal) .append(Helper.ContentVars.BASE.getVal()); diff --git a/langtools/test/tools/javac/diags/examples.not-yet.txt b/langtools/test/tools/javac/diags/examples.not-yet.txt index 061825ac0d2..ef2b5c84e5a 100644 --- a/langtools/test/tools/javac/diags/examples.not-yet.txt +++ b/langtools/test/tools/javac/diags/examples.not-yet.txt @@ -5,9 +5,9 @@ compiler.err.cant.read.file # (apt.JavaCompiler?) compiler.err.cant.select.static.class.from.param.type compiler.err.dc.unterminated.string # cannot happen compiler.err.illegal.char.for.encoding -compiler.err.invalid.containedby.annotation # should not happen -compiler.err.invalid.containedby.annotation.invalid.value # "can't" happen -compiler.err.invalid.containedby.annotation.multiple.values # can't happen +compiler.err.invalid.repeatable.annotation # should not happen +compiler.err.invalid.repeatable.annotation.invalid.value # "can't" happen +compiler.err.invalid.repeatable.annotation.multiple.values # can't happen compiler.err.io.exception # (javah.JavahTask?) compiler.err.limit.code # Code compiler.err.limit.code.too.large.for.try.stmt # Gen diff --git a/langtools/test/tools/javac/diags/examples/InvalidDuplicateAnnotation.java b/langtools/test/tools/javac/diags/examples/InvalidDuplicateAnnotation.java index 1dcc0997961..4d2cf299b00 100644 --- a/langtools/test/tools/javac/diags/examples/InvalidDuplicateAnnotation.java +++ b/langtools/test/tools/javac/diags/examples/InvalidDuplicateAnnotation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -22,17 +22,16 @@ */ // key: compiler.err.duplicate.annotation.invalid.repeated -// key: compiler.err.invalid.containedby.annotation.elem.nondefault -// +// key: compiler.err.invalid.repeatable.annotation.elem.nondefault + // We need an almost valid containing annotation. The easiest way to get // one close enough to valid is by forgetting a default. import java.lang.annotation.*; -@ContainedBy(Annos.class) +@Repeatable(Annos.class) @interface Anno { } -@ContainerFor(Anno.class) @interface Annos { Anno[] value(); String foo(); } @Anno diff --git a/langtools/test/tools/javac/diags/examples/ContainedByDocumentedMismatch.java b/langtools/test/tools/javac/diags/examples/RepeatableDocumentedMismatch.java similarity index 82% rename from langtools/test/tools/javac/diags/examples/ContainedByDocumentedMismatch.java rename to langtools/test/tools/javac/diags/examples/RepeatableDocumentedMismatch.java index a5077c7b825..0329acfc476 100644 --- a/langtools/test/tools/javac/diags/examples/ContainedByDocumentedMismatch.java +++ b/langtools/test/tools/javac/diags/examples/RepeatableDocumentedMismatch.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -21,17 +21,16 @@ * questions. */ -// key: compiler.err.invalid.containedby.annotation.not.documented +// key: compiler.err.invalid.repeatable.annotation.not.documented import java.lang.annotation.*; @Documented -@ContainedBy(Annos.class) +@Repeatable(Annos.class) @interface Anno { } -@ContainerFor(Anno.class) @interface Annos { Anno[] value(); } @Anno @Anno -class ContainedByDocumentedMismatch { } +class RepeatableDocumentedMismatch { } diff --git a/langtools/test/tools/javac/diags/examples/ContainedByInheritedMismatch.java b/langtools/test/tools/javac/diags/examples/RepeatableInheritedMismatch.java similarity index 82% rename from langtools/test/tools/javac/diags/examples/ContainedByInheritedMismatch.java rename to langtools/test/tools/javac/diags/examples/RepeatableInheritedMismatch.java index d7723bad61c..57ad1705859 100644 --- a/langtools/test/tools/javac/diags/examples/ContainedByInheritedMismatch.java +++ b/langtools/test/tools/javac/diags/examples/RepeatableInheritedMismatch.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -21,17 +21,16 @@ * questions. */ -// key: compiler.err.invalid.containedby.annotation.not.inherited +// key: compiler.err.invalid.repeatable.annotation.not.inherited import java.lang.annotation.*; @Inherited -@ContainedBy(Annos.class) +@Repeatable(Annos.class) @interface Anno { } -@ContainerFor(Anno.class) @interface Annos { Anno[] value(); } @Anno @Anno -class ContainedByInheritedMismatch { } +class RepeatableInheritedMismatch { } diff --git a/langtools/test/tools/javac/diags/examples/ContainedByNoValue.java b/langtools/test/tools/javac/diags/examples/RepeatableNoValue.java similarity index 83% rename from langtools/test/tools/javac/diags/examples/ContainedByNoValue.java rename to langtools/test/tools/javac/diags/examples/RepeatableNoValue.java index 8cb612808f9..01f88717bca 100644 --- a/langtools/test/tools/javac/diags/examples/ContainedByNoValue.java +++ b/langtools/test/tools/javac/diags/examples/RepeatableNoValue.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -21,16 +21,15 @@ * questions. */ -// key: compiler.err.invalid.containedby.annotation.no.value +// key: compiler.err.invalid.repeatable.annotation.no.value import java.lang.annotation.*; -@ContainedBy(Annos.class) +@Repeatable(Annos.class) @interface Anno { } -@ContainerFor(Anno.class) @interface Annos {} @Anno @Anno -class ContainedByNoValue { } +class RepeatableNoValue { } diff --git a/langtools/test/tools/javac/diags/examples/ContainedByNonDefault.java b/langtools/test/tools/javac/diags/examples/RepeatableNonDefault.java similarity index 82% rename from langtools/test/tools/javac/diags/examples/ContainedByNonDefault.java rename to langtools/test/tools/javac/diags/examples/RepeatableNonDefault.java index d6006dedfe3..bbf2ce57211 100644 --- a/langtools/test/tools/javac/diags/examples/ContainedByNonDefault.java +++ b/langtools/test/tools/javac/diags/examples/RepeatableNonDefault.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -21,14 +21,13 @@ * questions. */ -// key: compiler.err.invalid.containedby.annotation.elem.nondefault +// key: compiler.err.invalid.repeatable.annotation.elem.nondefault import java.lang.annotation.*; -@ContainedBy(Annos.class) +@Repeatable(Annos.class) @interface Anno { } -@ContainerFor(Anno.class) @interface Annos { Anno[] value(); String foo(); } -class ContainedByNonDefault { } +class RepeatableNonDefault { } diff --git a/langtools/test/tools/javac/diags/examples/ContainedByRetentionMismatch.java b/langtools/test/tools/javac/diags/examples/RepeatableRetentionMismatch.java similarity index 83% rename from langtools/test/tools/javac/diags/examples/ContainedByRetentionMismatch.java rename to langtools/test/tools/javac/diags/examples/RepeatableRetentionMismatch.java index 22680f5b644..47a19e2696f 100644 --- a/langtools/test/tools/javac/diags/examples/ContainedByRetentionMismatch.java +++ b/langtools/test/tools/javac/diags/examples/RepeatableRetentionMismatch.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -21,17 +21,16 @@ * questions. */ -// key: compiler.err.invalid.containedby.annotation.retention +// key: compiler.err.invalid.repeatable.annotation.retention import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) -@ContainedBy(Annos.class) +@Repeatable(Annos.class) @interface Anno { } -@ContainerFor(Anno.class) @interface Annos { Anno[] value(); } @Anno @Anno -class ContainedByRetentionMismatch { } +class RepeatableRetentionMismatch { } diff --git a/langtools/test/tools/javac/diags/examples/ContainedByTargetMismatch.java b/langtools/test/tools/javac/diags/examples/RepeatableTargetMismatch.java similarity index 82% rename from langtools/test/tools/javac/diags/examples/ContainedByTargetMismatch.java rename to langtools/test/tools/javac/diags/examples/RepeatableTargetMismatch.java index 3fcd4fb3f5d..d16cad28f70 100644 --- a/langtools/test/tools/javac/diags/examples/ContainedByTargetMismatch.java +++ b/langtools/test/tools/javac/diags/examples/RepeatableTargetMismatch.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -21,15 +21,14 @@ * questions. */ -// key: compiler.err.invalid.containedby.annotation.incompatible.target +// key: compiler.err.invalid.repeatable.annotation.incompatible.target import java.lang.annotation.*; -@ContainedBy(Annos.class) +@Repeatable(Annos.class) @Target(ElementType.METHOD) @interface Anno { } -@ContainerFor(Anno.class) @interface Annos { Anno[] value(); } -class ContainedByTargetMismatch { } +class RepeatableTargetMismatch { } diff --git a/langtools/test/tools/javac/diags/examples/ContainedByWrongValueType.java b/langtools/test/tools/javac/diags/examples/RepeatableWrongValueType.java similarity index 82% rename from langtools/test/tools/javac/diags/examples/ContainedByWrongValueType.java rename to langtools/test/tools/javac/diags/examples/RepeatableWrongValueType.java index 9b963bd3f6e..583e01532b1 100644 --- a/langtools/test/tools/javac/diags/examples/ContainedByWrongValueType.java +++ b/langtools/test/tools/javac/diags/examples/RepeatableWrongValueType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -21,16 +21,15 @@ * questions. */ -// key: compiler.err.invalid.containedby.annotation.value.return +// key: compiler.err.invalid.repeatable.annotation.value.return import java.lang.annotation.*; -@ContainedBy(Annos.class) +@Repeatable(Annos.class) @interface Anno { } -@ContainerFor(Anno.class) @interface Annos { String value(); } @Anno @Anno -class ContainedByWrongValueType { } +class RepeatableWrongValueType { } diff --git a/langtools/test/tools/javac/diags/examples/RepeatingAnnotationAndContainer.java b/langtools/test/tools/javac/diags/examples/RepeatingAnnotationAndContainer.java index 07a9bfddefb..dec4b59649a 100644 --- a/langtools/test/tools/javac/diags/examples/RepeatingAnnotationAndContainer.java +++ b/langtools/test/tools/javac/diags/examples/RepeatingAnnotationAndContainer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -21,14 +21,13 @@ * questions. */ -// key: compiler.err.invalid.containedby.annotation.repeated.and.container.present +// key: compiler.err.invalid.repeatable.annotation.repeated.and.container.present import java.lang.annotation.*; -@ContainedBy(Annos.class) +@Repeatable(Annos.class) @interface Anno { } -@ContainerFor(Anno.class) @interface Annos { Anno[] value(); } @Anno diff --git a/langtools/test/tools/javac/diags/examples/WrongContainedBy.java b/langtools/test/tools/javac/diags/examples/WrongContainedBy.java deleted file mode 100644 index 6914c4bd64e..00000000000 --- a/langtools/test/tools/javac/diags/examples/WrongContainedBy.java +++ /dev/null @@ -1,35 +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. - */ - -// key: compiler.err.invalid.container.no.containerfor -// key: compiler.err.invalid.container.wrong.containedby - -import java.lang.annotation.*; - -@ContainerFor(WrongContainedBy.class) -@interface Foos { - WrongContainedBy[] value(); -} - -@ContainedBy(Target.class) -public @interface WrongContainedBy {} diff --git a/langtools/test/tools/javac/diags/examples/WrongContainerFor.java b/langtools/test/tools/javac/diags/examples/WrongContainerFor.java deleted file mode 100644 index e439b780fbe..00000000000 --- a/langtools/test/tools/javac/diags/examples/WrongContainerFor.java +++ /dev/null @@ -1,35 +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. - */ - -// key: compiler.err.invalid.container.wrong.containerfor -// key: compiler.err.invalid.container.no.containedby - -import java.lang.annotation.*; - -@ContainerFor(Retention.class) -@interface Foos { - WrongContainerFor[] value(); -} - -@ContainedBy(Foos.class) -public @interface WrongContainerFor {} From f92bbd33111f87b51ffb94f6e677300a7aa4281b Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 14 Jan 2013 14:17:25 -0800 Subject: [PATCH 083/204] 8006241: Test DocRootSlash.java fails Reviewed-by: darcy --- langtools/test/com/sun/javadoc/DocRootSlash/DocRootSlash.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/langtools/test/com/sun/javadoc/DocRootSlash/DocRootSlash.java b/langtools/test/com/sun/javadoc/DocRootSlash/DocRootSlash.java index 032481764d8..75562bdee08 100644 --- a/langtools/test/com/sun/javadoc/DocRootSlash/DocRootSlash.java +++ b/langtools/test/com/sun/javadoc/DocRootSlash/DocRootSlash.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2013, 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 @@ -60,6 +60,7 @@ public class DocRootSlash String srcdir = System.getProperty("test.src", "."); runJavadoc(new String[] {"-d", TMPDIR_STRING1, + "-Xdoclint:none", "-overview", (srcdir + FS + "overview.html"), "-header", "{@docroot} {@docRoot}", "-sourcepath", srcdir, From c79f62bb7dccf1c20ac3d87fe98adb21f93d6458 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Mon, 14 Jan 2013 16:38:25 -0800 Subject: [PATCH 084/204] 8005284: build-infra: nonstandard copyright headers under common/autoconf/build-aux Reviewed-by: katleman --- .../autoconf/build-aux/autoconf-config.guess | 25 ++++++++++++++++++ common/autoconf/build-aux/config.sub | 26 +++++++++++++++++++ common/autoconf/build-aux/pkg.m4 | 26 +++++++++++++++++++ 3 files changed, 77 insertions(+) diff --git a/common/autoconf/build-aux/autoconf-config.guess b/common/autoconf/build-aux/autoconf-config.guess index e69905d5201..3aa7f690629 100644 --- a/common/autoconf/build-aux/autoconf-config.guess +++ b/common/autoconf/build-aux/autoconf-config.guess @@ -1,4 +1,29 @@ #! /bin/sh +# +# Copyright (c) 2012, 2013, 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# 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. +# + # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 diff --git a/common/autoconf/build-aux/config.sub b/common/autoconf/build-aux/config.sub index 6759825a5b7..1aab2b303e3 100644 --- a/common/autoconf/build-aux/config.sub +++ b/common/autoconf/build-aux/config.sub @@ -1,4 +1,30 @@ #! /bin/sh + +# +# Copyright (c) 2012, 2013, 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# 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. +# + # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 diff --git a/common/autoconf/build-aux/pkg.m4 b/common/autoconf/build-aux/pkg.m4 index a0b9cd45dfc..5f4b22bb27f 100644 --- a/common/autoconf/build-aux/pkg.m4 +++ b/common/autoconf/build-aux/pkg.m4 @@ -1,4 +1,30 @@ # pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- + +# +# Copyright (c) 2012, 2013, 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# 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. +# + # # Copyright © 2004 Scott James Remnant . # From 97013ba02828f3025f3bb019c826bad332b1ee17 Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy Date: Tue, 15 Jan 2013 12:49:03 +0400 Subject: [PATCH 085/204] 8003978: closed/javax/swing/JRootPane/bug4670486.java fails since jdk7u12b01 on macosx Reviewed-by: serb, leonidr --- .../com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java | 1 - .../sun/java/swing/plaf/motif/MotifLookAndFeel.java | 6 ++++-- .../javax/swing/plaf/basic/BasicLookAndFeel.java | 4 +++- jdk/src/share/classes/sun/swing/SwingUtilities2.java | 8 ++++++++ .../TypeAhead/SubMenuShowTest/SubMenuShowTest.java | 10 ++++++++++ 5 files changed, 25 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java index 6fb52a4cd4a..1fe26b09f31 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java @@ -787,7 +787,6 @@ public class GTKLookAndFeel extends SynthLookAndFeel { "List.font", new FontLazyValue(Region.LIST), "List.rendererUseUIBorder", Boolean.FALSE, - "Menu.shortcutKeys", new int[] {KeyEvent.ALT_MASK}, "Menu.arrowIcon", new GTKStyle.GTKLazyValue( "com.sun.java.swing.plaf.gtk.GTKIconFactory", "getMenuArrowIcon"), diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifLookAndFeel.java b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifLookAndFeel.java index 923cd9d18b9..fdc6fa6210a 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifLookAndFeel.java +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifLookAndFeel.java @@ -630,8 +630,10 @@ public class MotifLookAndFeel extends BasicLookAndFeel "Menu.menuPopupOffsetY", new Integer(0), "Menu.submenuPopupOffsetX", new Integer(-2), "Menu.submenuPopupOffsetY", new Integer(3), - "Menu.shortcutKeys", new int[] {KeyEvent.ALT_MASK, - KeyEvent.META_MASK}, + "Menu.shortcutKeys", new int[]{ + SwingUtilities2.getSystemMnemonicKeyMask(), + KeyEvent.META_MASK + }, "Menu.cancelMode", "hideMenuTree", "MenuBar.border", menuBarBorder, diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java index 437704ad4e7..5a9135844bc 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java @@ -1153,7 +1153,9 @@ public abstract class BasicLookAndFeel extends LookAndFeel implements Serializab "Menu.menuPopupOffsetY", new Integer(0), "Menu.submenuPopupOffsetX", new Integer(0), "Menu.submenuPopupOffsetY", new Integer(0), - "Menu.shortcutKeys", new int[] {KeyEvent.ALT_MASK}, + "Menu.shortcutKeys", new int[]{ + SwingUtilities2.getSystemMnemonicKeyMask() + }, "Menu.crossMenuMnemonic", Boolean.TRUE, // Menu.cancelMode affects the cancel menu action behaviour; // currently supports: diff --git a/jdk/src/share/classes/sun/swing/SwingUtilities2.java b/jdk/src/share/classes/sun/swing/SwingUtilities2.java index 2094ec0c11d..c6134885adf 100644 --- a/jdk/src/share/classes/sun/swing/SwingUtilities2.java +++ b/jdk/src/share/classes/sun/swing/SwingUtilities2.java @@ -1879,4 +1879,12 @@ public class SwingUtilities2 { } return -1; } + + public static int getSystemMnemonicKeyMask() { + Toolkit toolkit = Toolkit.getDefaultToolkit(); + if (toolkit instanceof SunToolkit) { + return ((SunToolkit) toolkit).getFocusAcceleratorKeyMask(); + } + return InputEvent.ALT_MASK; + } } diff --git a/jdk/test/java/awt/KeyboardFocusmanager/TypeAhead/SubMenuShowTest/SubMenuShowTest.java b/jdk/test/java/awt/KeyboardFocusmanager/TypeAhead/SubMenuShowTest/SubMenuShowTest.java index f01b8856f0f..d95441ba1bc 100644 --- a/jdk/test/java/awt/KeyboardFocusmanager/TypeAhead/SubMenuShowTest/SubMenuShowTest.java +++ b/jdk/test/java/awt/KeyboardFocusmanager/TypeAhead/SubMenuShowTest/SubMenuShowTest.java @@ -36,6 +36,7 @@ import java.applet.Applet; import java.util.concurrent.atomic.AtomicBoolean; import java.lang.reflect.InvocationTargetException; import test.java.awt.regtesthelpers.Util; +import sun.awt.OSInfo; public class SubMenuShowTest extends Applet { Robot robot; @@ -86,6 +87,11 @@ public class SubMenuShowTest extends Applet { frame.setVisible(true); Util.waitForIdle(robot); + boolean isMacOSX = (OSInfo.getOSType() == OSInfo.OSType.MACOSX); + if (isMacOSX) { + robot.keyPress(KeyEvent.VK_CONTROL); + robot.delay(20); + } robot.keyPress(KeyEvent.VK_ALT); robot.delay(20); robot.keyPress(KeyEvent.VK_F); @@ -93,6 +99,10 @@ public class SubMenuShowTest extends Applet { robot.keyRelease(KeyEvent.VK_F); robot.delay(20); robot.keyRelease(KeyEvent.VK_ALT); + if (isMacOSX) { + robot.keyRelease(KeyEvent.VK_CONTROL); + robot.delay(20); + } Util.waitForIdle(robot); robot.keyPress(KeyEvent.VK_M); From 67fc68ea7f815c3c6b23fc29ce3f60998e9ad0a7 Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Tue, 15 Jan 2013 13:32:13 +0100 Subject: [PATCH 086/204] 8005590: java_lang_Class injected field resolved_constructor appears unused Reviewed-by: coleenp, dholmes --- hotspot/src/share/vm/classfile/javaClasses.cpp | 15 --------------- hotspot/src/share/vm/classfile/javaClasses.hpp | 6 ------ hotspot/src/share/vm/classfile/vmSymbols.hpp | 1 - hotspot/src/share/vm/oops/instanceKlass.cpp | 4 ---- hotspot/src/share/vm/runtime/vmStructs.cpp | 1 - 5 files changed, 27 deletions(-) diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp index cb30a83d455..1c46188b728 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.cpp +++ b/hotspot/src/share/vm/classfile/javaClasses.cpp @@ -687,19 +687,6 @@ void java_lang_Class::set_array_klass(oop java_class, Klass* klass) { } -Method* java_lang_Class::resolved_constructor(oop java_class) { - Metadata* constructor = java_class->metadata_field(_resolved_constructor_offset); - assert(constructor == NULL || constructor->is_method(), "should be method"); - return ((Method*)constructor); -} - - -void java_lang_Class::set_resolved_constructor(oop java_class, Method* constructor) { - assert(constructor->is_method(), "should be method"); - java_class->metadata_field_put(_resolved_constructor_offset, constructor); -} - - bool java_lang_Class::is_primitive(oop java_class) { // should assert: //assert(java_lang_Class::is_instance(java_class), "must be a Class object"); @@ -2949,7 +2936,6 @@ int java_lang_System::err_offset_in_bytes() { int java_lang_Class::_klass_offset; int java_lang_Class::_array_klass_offset; -int java_lang_Class::_resolved_constructor_offset; int java_lang_Class::_oop_size_offset; int java_lang_Class::_static_oop_field_count_offset; GrowableArray* java_lang_Class::_fixup_mirror_list = NULL; @@ -3303,7 +3289,6 @@ void JavaClasses::check_offsets() { // Fake fields // CHECK_OFFSET("java/lang/Class", java_lang_Class, klass); // %%% this needs to be checked // CHECK_OFFSET("java/lang/Class", java_lang_Class, array_klass); // %%% this needs to be checked - // CHECK_OFFSET("java/lang/Class", java_lang_Class, resolved_constructor); // %%% this needs to be checked // java.lang.Throwable diff --git a/hotspot/src/share/vm/classfile/javaClasses.hpp b/hotspot/src/share/vm/classfile/javaClasses.hpp index 5ab16251c10..fe48e0f614d 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.hpp +++ b/hotspot/src/share/vm/classfile/javaClasses.hpp @@ -206,7 +206,6 @@ class java_lang_String : AllStatic { #define CLASS_INJECTED_FIELDS(macro) \ macro(java_lang_Class, klass, intptr_signature, false) \ - macro(java_lang_Class, resolved_constructor, intptr_signature, false) \ macro(java_lang_Class, array_klass, intptr_signature, false) \ macro(java_lang_Class, oop_size, int_signature, false) \ macro(java_lang_Class, static_oop_field_count, int_signature, false) @@ -218,7 +217,6 @@ class java_lang_Class : AllStatic { // The fake offsets are added by the class loader when java.lang.Class is loaded static int _klass_offset; - static int _resolved_constructor_offset; static int _array_klass_offset; static int _oop_size_offset; @@ -254,15 +252,11 @@ class java_lang_Class : AllStatic { static bool is_primitive(oop java_class); static BasicType primitive_type(oop java_class); static oop primitive_mirror(BasicType t); - // JVM_NewInstance support - static Method* resolved_constructor(oop java_class); - static void set_resolved_constructor(oop java_class, Method* constructor); // JVM_NewArray support static Klass* array_klass(oop java_class); static void set_array_klass(oop java_class, Klass* klass); // compiler support for class operations static int klass_offset_in_bytes() { return _klass_offset; } - static int resolved_constructor_offset_in_bytes() { return _resolved_constructor_offset; } static int array_klass_offset_in_bytes() { return _array_klass_offset; } // Support for classRedefinedCount field static int classRedefinedCount(oop the_class_mirror); diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp index e6168ceba2c..9829e834875 100644 --- a/hotspot/src/share/vm/classfile/vmSymbols.hpp +++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp @@ -383,7 +383,6 @@ template(basicType_name, "basicType") \ template(append_name, "append") \ template(klass_name, "klass") \ - template(resolved_constructor_name, "resolved_constructor") \ template(array_klass_name, "array_klass") \ template(oop_size_name, "oop_size") \ template(static_oop_field_count_name, "static_oop_field_count") \ diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index d123641a0c7..b0b7038e35b 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -2890,11 +2890,7 @@ void InstanceKlass::oop_print_on(oop obj, outputStream* st) { st->print(BULLET"fake entry for mirror: "); mirrored_klass->print_value_on_maybe_null(st); st->cr(); - st->print(BULLET"fake entry resolved_constructor: "); - Method* ctor = java_lang_Class::resolved_constructor(obj); - ctor->print_value_on_maybe_null(st); Klass* array_klass = java_lang_Class::array_klass(obj); - st->cr(); st->print(BULLET"fake entry for array: "); array_klass->print_value_on_maybe_null(st); st->cr(); diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index 9ac10e26d4c..c4172c18212 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -1200,7 +1200,6 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; /*********************************/ \ \ static_field(java_lang_Class, _klass_offset, int) \ - static_field(java_lang_Class, _resolved_constructor_offset, int) \ static_field(java_lang_Class, _array_klass_offset, int) \ static_field(java_lang_Class, _oop_size_offset, int) \ static_field(java_lang_Class, _static_oop_field_count_offset, int) \ From 9d65c6d24f2326b52541e9ae6820d8a6ad2e8448 Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Tue, 15 Jan 2013 10:09:45 +0100 Subject: [PATCH 087/204] 8005994: Method annotations are allocated unnecessarily during class file parsing Also reviewed by: vitalyd@gmail.com Reviewed-by: coleenp, acorn --- .../share/vm/classfile/classFileParser.cpp | 47 ++++++++++++------- hotspot/src/share/vm/prims/jvm.cpp | 7 ++- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index 9dd0640de06..102d551f00b 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -2475,26 +2475,38 @@ Array* ClassFileParser::parse_methods(ClassLoaderData* loader_data, *has_default_methods = true; } methods->at_put(index, method()); - if (*methods_annotations == NULL) { - *methods_annotations = - MetadataFactory::new_array(loader_data, length, NULL, CHECK_NULL); + + if (method_annotations != NULL) { + if (*methods_annotations == NULL) { + *methods_annotations = + MetadataFactory::new_array(loader_data, length, NULL, CHECK_NULL); + } + (*methods_annotations)->at_put(index, method_annotations); } - (*methods_annotations)->at_put(index, method_annotations); - if (*methods_parameter_annotations == NULL) { - *methods_parameter_annotations = - MetadataFactory::new_array(loader_data, length, NULL, CHECK_NULL); + + if (method_parameter_annotations != NULL) { + if (*methods_parameter_annotations == NULL) { + *methods_parameter_annotations = + MetadataFactory::new_array(loader_data, length, NULL, CHECK_NULL); + } + (*methods_parameter_annotations)->at_put(index, method_parameter_annotations); } - (*methods_parameter_annotations)->at_put(index, method_parameter_annotations); - if (*methods_default_annotations == NULL) { - *methods_default_annotations = - MetadataFactory::new_array(loader_data, length, NULL, CHECK_NULL); + + if (method_default_annotations != NULL) { + if (*methods_default_annotations == NULL) { + *methods_default_annotations = + MetadataFactory::new_array(loader_data, length, NULL, CHECK_NULL); + } + (*methods_default_annotations)->at_put(index, method_default_annotations); } - (*methods_default_annotations)->at_put(index, method_default_annotations); - if (*methods_type_annotations == NULL) { - *methods_type_annotations = - MetadataFactory::new_array(loader_data, length, NULL, CHECK_NULL); + + if (method_type_annotations != NULL) { + if (*methods_type_annotations == NULL) { + *methods_type_annotations = + MetadataFactory::new_array(loader_data, length, NULL, CHECK_NULL); + } + (*methods_type_annotations)->at_put(index, method_type_annotations); } - (*methods_type_annotations)->at_put(index, method_type_annotations); } if (_need_verify && length > 1) { @@ -3309,8 +3321,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, bool has_final_method = false; AccessFlags promoted_flags; promoted_flags.set_flags(0); - // These need to be oop pointers because they are allocated lazily - // inside parse_methods inside a nested HandleMark + Array* methods_annotations = NULL; Array* methods_parameter_annotations = NULL; Array* methods_default_annotations = NULL; diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp index f899aac02e7..0bf74c44bb7 100644 --- a/hotspot/src/share/vm/prims/jvm.cpp +++ b/hotspot/src/share/vm/prims/jvm.cpp @@ -1582,8 +1582,11 @@ JVM_ENTRY(jbyteArray, JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls)) if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) { Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls)); if (k->oop_is_instance()) { - typeArrayOop a = Annotations::make_java_array(InstanceKlass::cast(k)->type_annotations()->class_annotations(), CHECK_NULL); - return (jbyteArray) JNIHandles::make_local(env, a); + Annotations* type_annotations = InstanceKlass::cast(k)->type_annotations(); + if (type_annotations != NULL) { + typeArrayOop a = Annotations::make_java_array(type_annotations->class_annotations(), CHECK_NULL); + return (jbyteArray) JNIHandles::make_local(env, a); + } } } return NULL; From 08f29b04df596c4c082b01ad96bec5a943b8cc1a Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Tue, 15 Jan 2013 21:57:47 +0400 Subject: [PATCH 088/204] 7124525: [macosx] No animation on certain Swing components in Aqua LaF Reviewed-by: alexsch, swingler --- .../classes/com/apple/laf/AquaPainter.java | 44 ++++++++----------- .../classes/com/apple/laf/ImageCache.java | 22 ++++++---- 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/jdk/src/macosx/classes/com/apple/laf/AquaPainter.java b/jdk/src/macosx/classes/com/apple/laf/AquaPainter.java index cfafa43d9de..303938d5988 100644 --- a/jdk/src/macosx/classes/com/apple/laf/AquaPainter.java +++ b/jdk/src/macosx/classes/com/apple/laf/AquaPainter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -37,7 +37,6 @@ import sun.awt.image.*; import sun.java2d.*; import sun.print.*; import apple.laf.*; -import apple.laf.JRSUIConstants.Widget; import apple.laf.JRSUIUtils.NineSliceMetricsProvider; abstract class AquaPainter { @@ -63,7 +62,7 @@ abstract class AquaPainter { } static AquaPainter create(final T state, final NineSliceMetricsProvider metricsProvider) { - return new AquaNineSlicingImagePainter(state, metricsProvider); + return new AquaNineSlicingImagePainter<>(state, metricsProvider); } abstract void paint(final Graphics2D g, final T stateToPaint, final Component c); @@ -71,7 +70,7 @@ abstract class AquaPainter { final Rectangle boundsRect = new Rectangle(); final JRSUIControl control; T state; - public AquaPainter(final JRSUIControl control, final T state) { + AquaPainter(final JRSUIControl control, final T state) { this.control = control; this.state = state; } @@ -94,14 +93,14 @@ abstract class AquaPainter { protected final HashMap slicedControlImages; protected final NineSliceMetricsProvider metricsProvider; - public AquaNineSlicingImagePainter(final T state) { + AquaNineSlicingImagePainter(final T state) { this(state, null); } - public AquaNineSlicingImagePainter(final T state, final NineSliceMetricsProvider metricsProvider) { + AquaNineSlicingImagePainter(final T state, final NineSliceMetricsProvider metricsProvider) { super(new JRSUIControl(false), state); this.metricsProvider = metricsProvider; - slicedControlImages = new HashMap(); + slicedControlImages = new HashMap<>(); } @Override @@ -127,7 +126,7 @@ abstract class AquaPainter { } static class AquaSingleImagePainter extends AquaPainter { - public AquaSingleImagePainter(final T state) { + AquaSingleImagePainter(final T state) { super(new JRSUIControl(false), state); } @@ -137,12 +136,12 @@ abstract class AquaPainter { } static void paintFromSingleCachedImage(final Graphics2D g, final JRSUIControl control, final JRSUIState controlState, final Component c, final Rectangle boundsRect) { - Rectangle clipRect = g.getClipBounds(); - Rectangle intersection = boundsRect.intersection(clipRect); + final Rectangle clipRect = g.getClipBounds(); + final Rectangle intersection = boundsRect.intersection(clipRect); if (intersection.width <= 0 || intersection.height <= 0) return; - int imgX1 = intersection.x - boundsRect.x; - int imgY1 = intersection.y - boundsRect.y; + final int imgX1 = intersection.x - boundsRect.x; + final int imgY1 = intersection.y - boundsRect.y; final GraphicsConfiguration config = g.getDeviceConfiguration(); final ImageCache cache = ImageCache.getInstance(); @@ -150,20 +149,15 @@ abstract class AquaPainter { if (image == null) { image = new BufferedImage(boundsRect.width, boundsRect.height, BufferedImage.TYPE_INT_ARGB_PRE); cache.setImage(image, config, boundsRect.width, boundsRect.height, controlState); - } else { - g.drawImage(image, intersection.x, intersection.y, intersection.x + intersection.width, intersection.y + intersection.height, - imgX1, imgY1, imgX1 + intersection.width, imgY1 + intersection.height, null); - return; + final WritableRaster raster = image.getRaster(); + final DataBufferInt buffer = (DataBufferInt)raster.getDataBuffer(); + + control.set(controlState); + control.paint(SunWritableRaster.stealData(buffer, 0), + image.getWidth(), image.getHeight(), 0, 0, boundsRect.width, boundsRect.height); + SunWritableRaster.markDirty(buffer); } - final WritableRaster raster = image.getRaster(); - final DataBufferInt buffer = (DataBufferInt)raster.getDataBuffer(); - - control.set(controlState); - control.paint(SunWritableRaster.stealData(buffer, 0), - image.getWidth(), image.getHeight(), 0, 0, boundsRect.width, boundsRect.height); - SunWritableRaster.markDirty(buffer); - g.drawImage(image, intersection.x, intersection.y, intersection.x + intersection.width, intersection.y + intersection.height, imgX1, imgY1, imgX1 + intersection.width, imgY1 + intersection.height, null); } @@ -173,7 +167,7 @@ abstract class AquaPainter { final JRSUIControl control; final JRSUIState state; - public RecyclableJRSUISlicedImageControl(final JRSUIControl control, final JRSUIState state, final NineSliceMetrics metrics) { + RecyclableJRSUISlicedImageControl(final JRSUIControl control, final JRSUIState state, final NineSliceMetrics metrics) { super(metrics); this.control = control; this.state = state; diff --git a/jdk/src/macosx/classes/com/apple/laf/ImageCache.java b/jdk/src/macosx/classes/com/apple/laf/ImageCache.java index 7ed83ae961c..f9af5c06161 100644 --- a/jdk/src/macosx/classes/com/apple/laf/ImageCache.java +++ b/jdk/src/macosx/classes/com/apple/laf/ImageCache.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -30,6 +30,7 @@ import java.lang.ref.*; import java.util.*; import java.util.concurrent.locks.*; +import apple.laf.JRSUIConstants; import apple.laf.JRSUIState; import com.apple.laf.AquaUtils.RecyclableSingleton; @@ -38,9 +39,9 @@ import com.apple.laf.AquaUtils.RecyclableSingleton; * SoftReferences so they will be dropped by the GC if heap memory gets tight. When our size hits max pixel count least * recently requested images are removed first. */ -class ImageCache { +final class ImageCache { // Ordered Map keyed by args hash, ordered by most recent accessed entry. - private final LinkedHashMap map = new LinkedHashMap(16, 0.75f, true); + private final LinkedHashMap map = new LinkedHashMap<>(16, 0.75f, true); // Maximum number of pixels to cache, this is used if maxCount private final int maxPixelCount; @@ -50,7 +51,7 @@ class ImageCache { // Lock for concurrent access to map private final ReadWriteLock lock = new ReentrantReadWriteLock(); // Reference queue for tracking lost softreferences to images in the cache - private final ReferenceQueue referenceQueue = new ReferenceQueue(); + private final ReferenceQueue referenceQueue = new ReferenceQueue<>(); // Singleton Instance private static final RecyclableSingleton instance = new RecyclableSingleton() { @@ -63,11 +64,11 @@ class ImageCache { return instance.get(); } - public ImageCache(final int maxPixelCount) { + ImageCache(final int maxPixelCount) { this.maxPixelCount = maxPixelCount; } - public ImageCache() { + ImageCache() { this((8 * 1024 * 1024) / 4); // 8Mb of pixels } @@ -99,10 +100,13 @@ class ImageCache { * @param config The graphics configuration, needed if cached image is a Volatile Image. Used as part of cache key * @param w The image width, used as part of cache key * @param h The image height, used as part of cache key - * @param args Other arguments to use as part of the cache key - * @return true if the image could be cached or false if the image is too big + * @return true if the image could be cached, false otherwise. */ public boolean setImage(final Image image, final GraphicsConfiguration config, final int w, final int h, final JRSUIState state) { + if (state.is(JRSUIConstants.Animating.YES)) { + return false; + } + final int hash = hash(config, w, h, state); lock.writeLock().lock(); @@ -167,7 +171,7 @@ class ImageCache { private final int h; private final JRSUIState state; - public PixelCountSoftReference(final Image referent, final ReferenceQueue q, final int pixelCount, final int hash, final GraphicsConfiguration config, final int w, final int h, final JRSUIState state) { + PixelCountSoftReference(final Image referent, final ReferenceQueue q, final int pixelCount, final int hash, final GraphicsConfiguration config, final int w, final int h, final JRSUIState state) { super(referent, q); this.pixelCount = pixelCount; this.hash = hash; From 5dda34f79842cfe079f94fcd169517a71621d87b Mon Sep 17 00:00:00 2001 From: Christian Thalinger Date: Tue, 15 Jan 2013 12:06:18 -0800 Subject: [PATCH 089/204] 8006109: test/java/util/AbstractSequentialList/AddAll.java fails: assert(rtype == ctype) failed: mismatched return types Reviewed-by: kvn --- hotspot/src/share/vm/ci/ciType.cpp | 16 +++++++++++++++- hotspot/src/share/vm/ci/ciType.hpp | 1 + hotspot/src/share/vm/opto/doCall.cpp | 8 +++++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/ci/ciType.cpp b/hotspot/src/share/vm/ci/ciType.cpp index 47412130f04..e74dd921804 100644 --- a/hotspot/src/share/vm/ci/ciType.cpp +++ b/hotspot/src/share/vm/ci/ciType.cpp @@ -59,6 +59,19 @@ bool ciType::is_subtype_of(ciType* type) { return false; } +// ------------------------------------------------------------------ +// ciType::name +// +// Return the name of this type +const char* ciType::name() { + if (is_primitive_type()) { + return type2name(basic_type()); + } else { + assert(is_klass(), "must be"); + return as_klass()->name()->as_utf8(); + } +} + // ------------------------------------------------------------------ // ciType::print_impl // @@ -73,7 +86,8 @@ void ciType::print_impl(outputStream* st) { // // Print the name of this type void ciType::print_name_on(outputStream* st) { - st->print(type2name(basic_type())); + ResourceMark rm; + st->print(name()); } diff --git a/hotspot/src/share/vm/ci/ciType.hpp b/hotspot/src/share/vm/ci/ciType.hpp index 807ae1bec92..25f79e01263 100644 --- a/hotspot/src/share/vm/ci/ciType.hpp +++ b/hotspot/src/share/vm/ci/ciType.hpp @@ -77,6 +77,7 @@ public: bool is_type() const { return true; } bool is_classless() const { return is_primitive_type(); } + const char* name(); virtual void print_name_on(outputStream* st); void print_name() { print_name_on(tty); diff --git a/hotspot/src/share/vm/opto/doCall.cpp b/hotspot/src/share/vm/opto/doCall.cpp index 5d094c99afc..9a7562d01fb 100644 --- a/hotspot/src/share/vm/opto/doCall.cpp +++ b/hotspot/src/share/vm/opto/doCall.cpp @@ -553,7 +553,13 @@ void Parse::do_call() { rtype = ctype; } } else { - assert(rtype == ctype, "mismatched return types"); // symbolic resolution enforces this + // Symbolic resolution enforces the types to be the same. + // NOTE: We must relax the assert for unloaded types because two + // different ciType instances of the same unloaded class type + // can appear to be "loaded" by different loaders (depending on + // the accessing class). + assert(!rtype->is_loaded() || !ctype->is_loaded() || rtype == ctype, + err_msg_res("mismatched return types: rtype=%s, ctype=%s", rtype->name(), ctype->name())); } // If the return type of the method is not loaded, assert that the From b3b1b412b1e94f437b9b5bcda4d5cbb2713470f4 Mon Sep 17 00:00:00 2001 From: John Cuthbertson Date: Tue, 15 Jan 2013 12:32:26 -0800 Subject: [PATCH 090/204] 8001425: G1: Change the default values for certain G1 specific flags Changes to default and ergonomic flag values recommended by performance team. Changes were also reviewed by Monica Beckwith . Reviewed-by: brutisso, huntch --- .../src/share/vm/gc_implementation/g1/g1_globals.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp index 92b1cb3fc49..d362956ea80 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -287,24 +287,24 @@ "The number of times we'll force an overflow during " \ "concurrent marking") \ \ - experimental(uintx, G1NewSizePercent, 20, \ + experimental(uintx, G1NewSizePercent, 5, \ "Percentage (0-100) of the heap size to use as default " \ "minimum young gen size.") \ \ - experimental(uintx, G1MaxNewSizePercent, 80, \ + experimental(uintx, G1MaxNewSizePercent, 60, \ "Percentage (0-100) of the heap size to use as default " \ " maximum young gen size.") \ \ - experimental(uintx, G1MixedGCLiveThresholdPercent, 90, \ + experimental(uintx, G1MixedGCLiveThresholdPercent, 65, \ "Threshold for regions to be considered for inclusion in the " \ "collection set of mixed GCs. " \ "Regions with live bytes exceeding this will not be collected.") \ \ - product(uintx, G1HeapWastePercent, 5, \ + product(uintx, G1HeapWastePercent, 10, \ "Amount of space, expressed as a percentage of the heap size, " \ "that G1 is willing not to collect to avoid expensive GCs.") \ \ - product(uintx, G1MixedGCCountTarget, 4, \ + product(uintx, G1MixedGCCountTarget, 8, \ "The target number of mixed GCs after a marking cycle.") \ \ experimental(uintx, G1OldCSetRegionThresholdPercent, 10, \ From b60eabe8132255357077d228e597ca5d57681b02 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Tue, 15 Jan 2013 20:38:39 +0000 Subject: [PATCH 091/204] 8006344: Broken javadoc link in javax.lang.model.element.Element Reviewed-by: lancea, alanb, jfranck --- .../src/share/classes/javax/lang/model/element/Element.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langtools/src/share/classes/javax/lang/model/element/Element.java b/langtools/src/share/classes/javax/lang/model/element/Element.java index b0b463df13f..a95cbe0ca95 100644 --- a/langtools/src/share/classes/javax/lang/model/element/Element.java +++ b/langtools/src/share/classes/javax/lang/model/element/Element.java @@ -188,7 +188,7 @@ public interface Element { * type if present on this element, else an empty array * * @see #getAnnotationMirrors() - * @see #getAnnotation() + * @see #getAnnotation(java.lang.Class) * @see java.lang.reflect.AnnotatedElement#getAnnotations * @see EnumConstantNotPresentException * @see AnnotationTypeMismatchException From f8b61f9b0cf65849167dda0c12c89fb5c251f5d2 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Tue, 15 Jan 2013 13:03:11 -0800 Subject: [PATCH 092/204] 8006224: Doclint NPE for attribute with no value Reviewed-by: darcy --- .../com/sun/tools/doclint/Checker.java | 18 ++-- .../doclint/resources/doclint.properties | 3 +- langtools/test/tools/doclint/AnchorTest.java | 93 +++++++++++++++++++ langtools/test/tools/doclint/AnchorTest.out | 37 ++++++++ 4 files changed, 143 insertions(+), 8 deletions(-) create mode 100644 langtools/test/tools/doclint/AnchorTest.java create mode 100644 langtools/test/tools/doclint/AnchorTest.out diff --git a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java index 26a9cf1904d..0664838936d 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java +++ b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -447,14 +447,18 @@ public class Checker extends DocTreeScanner { if (currTag != HtmlTag.A) { break; } - // fallthrough + // fallthrough case ID: String value = getAttrValue(tree); - if (!validName.matcher(value).matches()) { - env.messages.error(HTML, tree, "dc.invalid.anchor", value); - } - if (!foundAnchors.add(value)) { - env.messages.error(HTML, tree, "dc.anchor.already.defined", value); + if (value == null) { + env.messages.error(HTML, tree, "dc.anchor.value.missing"); + } else { + if (!validName.matcher(value).matches()) { + env.messages.error(HTML, tree, "dc.invalid.anchor", value); + } + if (!foundAnchors.add(value)) { + env.messages.error(HTML, tree, "dc.anchor.already.defined", value); + } } break; diff --git a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties index e85afc92d7c..33b0d7d1151 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties +++ b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, 2013, 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 @@ -24,6 +24,7 @@ # dc.anchor.already.defined = anchor already defined: {0} +dc.anchor.value.missing = no value given for anchor dc.attr.lacks.value = attribute lacks value dc.attr.obsolete = attribute obsolete: {0} dc.attr.obsolete.use.css = attribute obsolete, use CSS instead: {0} diff --git a/langtools/test/tools/doclint/AnchorTest.java b/langtools/test/tools/doclint/AnchorTest.java new file mode 100644 index 00000000000..08e19031b4a --- /dev/null +++ b/langtools/test/tools/doclint/AnchorTest.java @@ -0,0 +1,93 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8004832 + * @summary Add new doclint package + * @build DocLintTester + * @run main DocLintTester -ref AnchorTest.out AnchorTest.java + */ + +/** */ +public class AnchorTest { + // tests for + + /** + * + */ + public void a_name_foo() { } + + /** + * + */ + public void a_name_already_defined() { } + + /** + * + */ + public void a_name_empty() { } + + /** + * + */ + public void a_name_invalid() { } + + /** + * + */ + public void a_name_missing() { } + + // tests for + + /** + * + */ + public void a_id_foo() { } + + /** + * + */ + public void a_id_already_defined() { } + + /** + * + */ + public void a_id_empty() { } + + /** + * + */ + public void a_id_invalid() { } + + /** + * + */ + public void a_id_missing() { } + + // tests for id=value on non- tags + + /** + *

text

+ */ + public void p_id_foo() { } + + /** + *

text

+ */ + public void p_id_already_defined() { } + + /** + *

text

+ */ + public void p_id_empty() { } + + /** + *

text

+ */ + public void p_id_invalid() { } + + /** + *

text

+ */ + public void p_id_missing() { } + + +} diff --git a/langtools/test/tools/doclint/AnchorTest.out b/langtools/test/tools/doclint/AnchorTest.out new file mode 100644 index 00000000000..562be5ba96c --- /dev/null +++ b/langtools/test/tools/doclint/AnchorTest.out @@ -0,0 +1,37 @@ +AnchorTest.java:19: error: anchor already defined: foo + *
+ ^ +AnchorTest.java:24: error: invalid name for anchor: "" + * + ^ +AnchorTest.java:29: error: invalid name for anchor: "123" + * + ^ +AnchorTest.java:34: error: no value given for anchor + * + ^ +AnchorTest.java:46: error: anchor already defined: foo + * + ^ +AnchorTest.java:51: error: invalid name for anchor: "" + * + ^ +AnchorTest.java:56: error: invalid name for anchor: "123" + * + ^ +AnchorTest.java:61: error: no value given for anchor + * + ^ +AnchorTest.java:73: error: anchor already defined: foo + *

text

+ ^ +AnchorTest.java:78: error: invalid name for anchor: "" + *

text

+ ^ +AnchorTest.java:83: error: invalid name for anchor: "123" + *

text

+ ^ +AnchorTest.java:88: error: no value given for anchor + *

text

+ ^ +12 errors From 84fce989ddf522c4b558064b9e6afa9aad404951 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Tue, 15 Jan 2013 17:05:53 -0500 Subject: [PATCH 093/204] 8005467: CDS size information is incorrect and unfriendly Changed words to bytes, and added usage percentage information Reviewed-by: coleenp, twisti --- .../src/share/vm/memory/metaspaceShared.cpp | 47 +++++++++++++++---- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspaceShared.cpp b/hotspot/src/share/vm/memory/metaspaceShared.cpp index 5954e43d05a..4f53114c6cd 100644 --- a/hotspot/src/share/vm/memory/metaspaceShared.cpp +++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -373,17 +373,44 @@ void VM_PopulateDumpSharedSpace::doit() { md_top = wc.get_top(); // Print shared spaces all the time - const char* fmt = "%s space: " PTR_FORMAT " out of " PTR_FORMAT " words allocated at " PTR_FORMAT "."; + const char* fmt = "%s space: %9d [ %4.1f%% of total] out of %9d bytes [%4.1f%% used] at " PTR_FORMAT; Metaspace* ro_space = _loader_data->ro_metaspace(); Metaspace* rw_space = _loader_data->rw_metaspace(); - tty->print_cr(fmt, "ro", ro_space->used_words(Metaspace::NonClassType), - ro_space->capacity_words(Metaspace::NonClassType), - ro_space->bottom()); - tty->print_cr(fmt, "rw", rw_space->used_words(Metaspace::NonClassType), - rw_space->capacity_words(Metaspace::NonClassType), - rw_space->bottom()); - tty->print_cr(fmt, "md", md_top - md_low, md_end-md_low, md_low); - tty->print_cr(fmt, "mc", mc_top - mc_low, mc_end-mc_low, mc_low); + const size_t BPW = BytesPerWord; + + // Allocated size of each space (may not be all occupied) + const size_t ro_alloced = ro_space->capacity_words(Metaspace::NonClassType) * BPW; + const size_t rw_alloced = rw_space->capacity_words(Metaspace::NonClassType) * BPW; + const size_t md_alloced = md_end-md_low; + const size_t mc_alloced = mc_end-mc_low; + const size_t total_alloced = ro_alloced + rw_alloced + md_alloced + mc_alloced; + + // Occupied size of each space. + const size_t ro_bytes = ro_space->used_words(Metaspace::NonClassType) * BPW; + const size_t rw_bytes = rw_space->used_words(Metaspace::NonClassType) * BPW; + const size_t md_bytes = size_t(md_top - md_low); + const size_t mc_bytes = size_t(mc_top - mc_low); + + // Percent of total size + const size_t total_bytes = ro_bytes + rw_bytes + md_bytes + mc_bytes; + const double ro_t_perc = ro_bytes / double(total_bytes) * 100.0; + const double rw_t_perc = rw_bytes / double(total_bytes) * 100.0; + const double md_t_perc = md_bytes / double(total_bytes) * 100.0; + const double mc_t_perc = mc_bytes / double(total_bytes) * 100.0; + + // Percent of fullness of each space + const double ro_u_perc = ro_bytes / double(ro_alloced) * 100.0; + const double rw_u_perc = rw_bytes / double(rw_alloced) * 100.0; + const double md_u_perc = md_bytes / double(md_alloced) * 100.0; + const double mc_u_perc = mc_bytes / double(mc_alloced) * 100.0; + const double total_u_perc = total_bytes / double(total_alloced) * 100.0; + + tty->print_cr(fmt, "ro", ro_bytes, ro_t_perc, ro_alloced, ro_u_perc, ro_space->bottom()); + tty->print_cr(fmt, "rw", rw_bytes, rw_t_perc, rw_alloced, rw_u_perc, rw_space->bottom()); + tty->print_cr(fmt, "md", md_bytes, md_t_perc, md_alloced, md_u_perc, md_low); + tty->print_cr(fmt, "mc", mc_bytes, mc_t_perc, mc_alloced, mc_u_perc, mc_low); + tty->print_cr("total : %9d [100.0%% of total] out of %9d bytes [%4.1f%% used]", + total_bytes, total_alloced, total_u_perc); // Update the vtable pointers in all of the Klass objects in the // heap. They should point to newly generated vtable. From cc15237ca514c501a2e9ffff0386d4d890634d83 Mon Sep 17 00:00:00 2001 From: David Chase Date: Tue, 15 Jan 2013 14:45:12 -0800 Subject: [PATCH 094/204] 8005821: C2: -XX:+PrintIntrinsics is broken Check all print inlining flags when processing inlining list. Reviewed-by: kvn, twisti --- hotspot/src/share/vm/opto/compile.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp index f090939186d..ae9d6996a9c 100644 --- a/hotspot/src/share/vm/opto/compile.cpp +++ b/hotspot/src/share/vm/opto/compile.cpp @@ -692,7 +692,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr PhaseGVN gvn(node_arena(), estimated_size); set_initial_gvn(&gvn); - if (PrintInlining) { + if (PrintInlining || PrintIntrinsics NOT_PRODUCT( || PrintOptoInlining)) { _print_inlining_list = new (comp_arena())GrowableArray(comp_arena(), 1, 1, PrintInliningBuffer()); } { // Scope for timing the parser @@ -2049,7 +2049,7 @@ void Compile::Optimize() { } // (End scope of igvn; run destructor if necessary for asserts.) - dump_inlining(); + dump_inlining(); // A method with only infinite loops has no edges entering loops from root { NOT_PRODUCT( TracePhase t2("graphReshape", &_t_graphReshaping, TimeCompiler); ) @@ -3497,7 +3497,7 @@ void Compile::ConstantTable::fill_jump_table(CodeBuffer& cb, MachConstantNode* n } void Compile::dump_inlining() { - if (PrintInlining) { + if (PrintInlining || PrintIntrinsics NOT_PRODUCT( || PrintOptoInlining)) { // Print inlining message for candidates that we couldn't inline // for lack of space or non constant receiver for (int i = 0; i < _late_inlines.length(); i++) { From 38f6de7a0c6a19c03261545c3bdd8875632310de Mon Sep 17 00:00:00 2001 From: Bengt Rutisson Date: Wed, 16 Jan 2013 12:46:27 +0100 Subject: [PATCH 095/204] 8006242: G1: WorkerDataArray::verify() too strict for double calculations Also reviewed by vitalyd@gmail.com. Reviewed-by: johnc, mgerdin --- .../gc_implementation/g1/g1GCPhaseTimes.cpp | 34 +++++++++++-------- .../gc_implementation/g1/g1GCPhaseTimes.hpp | 2 ++ 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp index 7a102cf43d7..9782b67c007 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp @@ -131,17 +131,23 @@ void WorkerDataArray::print(int level, const char* title) { #ifndef PRODUCT +template <> const int WorkerDataArray::_uninitialized = -1; +template <> const double WorkerDataArray::_uninitialized = -1.0; +template <> const size_t WorkerDataArray::_uninitialized = (size_t)-1; + template void WorkerDataArray::reset() { for (uint i = 0; i < _length; i++) { - _data[i] = (T)-1; + _data[i] = (T)_uninitialized; } } template void WorkerDataArray::verify() { for (uint i = 0; i < _length; i++) { - assert(_data[i] >= (T)0, err_msg("Invalid data for worker %d", i)); + assert(_data[i] != _uninitialized, + err_msg("Invalid data for worker " UINT32_FORMAT ", data: %lf, uninitialized: %lf", + i, (double)_data[i], (double)_uninitialized)); } } @@ -201,20 +207,20 @@ void G1GCPhaseTimes::note_gc_end() { _last_termination_attempts.verify(); _last_gc_worker_end_times_ms.verify(); - for (uint i = 0; i < _active_gc_threads; i++) { - double worker_time = _last_gc_worker_end_times_ms.get(i) - _last_gc_worker_start_times_ms.get(i); - _last_gc_worker_times_ms.set(i, worker_time); + for (uint i = 0; i < _active_gc_threads; i++) { + double worker_time = _last_gc_worker_end_times_ms.get(i) - _last_gc_worker_start_times_ms.get(i); + _last_gc_worker_times_ms.set(i, worker_time); - double worker_known_time = _last_ext_root_scan_times_ms.get(i) + - _last_satb_filtering_times_ms.get(i) + - _last_update_rs_times_ms.get(i) + - _last_scan_rs_times_ms.get(i) + - _last_obj_copy_times_ms.get(i) + - _last_termination_times_ms.get(i); + double worker_known_time = _last_ext_root_scan_times_ms.get(i) + + _last_satb_filtering_times_ms.get(i) + + _last_update_rs_times_ms.get(i) + + _last_scan_rs_times_ms.get(i) + + _last_obj_copy_times_ms.get(i) + + _last_termination_times_ms.get(i); - double worker_other_time = worker_time - worker_known_time; - _last_gc_worker_other_times_ms.set(i, worker_other_time); - } + double worker_other_time = worker_time - worker_known_time; + _last_gc_worker_other_times_ms.set(i, worker_other_time); + } _last_gc_worker_times_ms.verify(); _last_gc_worker_other_times_ms.verify(); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp index 99e35c63d43..b6e289ed22a 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp @@ -35,6 +35,8 @@ class WorkerDataArray : public CHeapObj { const char* _print_format; bool _print_sum; + NOT_PRODUCT(static const T _uninitialized;) + // We are caching the sum and average to only have to calculate them once. // This is not done in an MT-safe way. It is intetened to allow single // threaded code to call sum() and average() multiple times in any order From 9a4e15eaf6278b1659c51c9277948fbb9da2efbb Mon Sep 17 00:00:00 2001 From: Mikhail Cherkasov Date: Wed, 16 Jan 2013 17:26:41 +0400 Subject: [PATCH 096/204] 8005492: Reduce number of warnings in sun/awt/* classes Reviewed-by: art, anthony --- jdk/src/share/classes/java/awt/Button.java | 2 +- jdk/src/share/classes/java/awt/Checkbox.java | 2 +- jdk/src/share/classes/java/awt/Choice.java | 8 +++---- jdk/src/share/classes/java/awt/Component.java | 1 + jdk/src/share/classes/java/awt/Container.java | 22 ++++++++--------- jdk/src/share/classes/java/awt/Dialog.java | 12 +++++----- jdk/src/share/classes/java/awt/Frame.java | 4 ++-- .../java/awt/KeyboardFocusManager.java | 2 +- jdk/src/share/classes/java/awt/Scrollbar.java | 2 +- jdk/src/share/classes/java/awt/TextArea.java | 6 ++--- .../share/classes/java/awt/TextComponent.java | 2 +- jdk/src/share/classes/java/awt/TextField.java | 2 +- jdk/src/share/classes/java/awt/Toolkit.java | 2 +- jdk/src/share/classes/java/awt/Window.java | 24 +++++++++++-------- .../classes/sun/awt/image/SurfaceManager.java | 6 ++--- 15 files changed, 51 insertions(+), 46 deletions(-) diff --git a/jdk/src/share/classes/java/awt/Button.java b/jdk/src/share/classes/java/awt/Button.java index f0bad87430b..9fe42d41cbc 100644 --- a/jdk/src/share/classes/java/awt/Button.java +++ b/jdk/src/share/classes/java/awt/Button.java @@ -300,7 +300,7 @@ public class Button extends Component implements Accessible { * @since 1.4 */ public synchronized ActionListener[] getActionListeners() { - return (ActionListener[]) (getListeners(ActionListener.class)); + return getListeners(ActionListener.class); } /** diff --git a/jdk/src/share/classes/java/awt/Checkbox.java b/jdk/src/share/classes/java/awt/Checkbox.java index 5c8e65f8aac..f0486f35e45 100644 --- a/jdk/src/share/classes/java/awt/Checkbox.java +++ b/jdk/src/share/classes/java/awt/Checkbox.java @@ -470,7 +470,7 @@ public class Checkbox extends Component implements ItemSelectable, Accessible { * @since 1.4 */ public synchronized ItemListener[] getItemListeners() { - return (ItemListener[]) (getListeners(ItemListener.class)); + return getListeners(ItemListener.class); } /** diff --git a/jdk/src/share/classes/java/awt/Choice.java b/jdk/src/share/classes/java/awt/Choice.java index 895be89a615..9ef765818dc 100644 --- a/jdk/src/share/classes/java/awt/Choice.java +++ b/jdk/src/share/classes/java/awt/Choice.java @@ -85,7 +85,7 @@ public class Choice extends Component implements ItemSelectable, Accessible { * @see #insert(String, int) * @see #remove(String) */ - Vector pItems; + Vector pItems; /** * The index of the current choice for this Choice @@ -129,7 +129,7 @@ public class Choice extends Component implements ItemSelectable, Accessible { */ public Choice() throws HeadlessException { GraphicsEnvironment.checkHeadless(); - pItems = new Vector(); + pItems = new Vector<>(); } /** @@ -191,7 +191,7 @@ public class Choice extends Component implements ItemSelectable, Accessible { * be called on the toolkit thread. */ final String getItemImpl(int index) { - return (String)pItems.elementAt(index); + return pItems.elementAt(index); } /** @@ -524,7 +524,7 @@ public class Choice extends Component implements ItemSelectable, Accessible { * @since 1.4 */ public synchronized ItemListener[] getItemListeners() { - return (ItemListener[])(getListeners(ItemListener.class)); + return getListeners(ItemListener.class); } /** diff --git a/jdk/src/share/classes/java/awt/Component.java b/jdk/src/share/classes/java/awt/Component.java index e4f25f0da2b..42e422d3e93 100644 --- a/jdk/src/share/classes/java/awt/Component.java +++ b/jdk/src/share/classes/java/awt/Component.java @@ -7287,6 +7287,7 @@ public abstract class Component implements ImageObserver, MenuContainer, } final Set getFocusTraversalKeys_NoIDCheck(int id) { // Okay to return Set directly because it is an unmodifiable view + @SuppressWarnings("unchecked") Set keystrokes = (focusTraversalKeys != null) ? focusTraversalKeys[id] : null; diff --git a/jdk/src/share/classes/java/awt/Container.java b/jdk/src/share/classes/java/awt/Container.java index ce2a19138b1..78af6b10c62 100644 --- a/jdk/src/share/classes/java/awt/Container.java +++ b/jdk/src/share/classes/java/awt/Container.java @@ -161,7 +161,7 @@ public class Container extends Component { private boolean focusTraversalPolicyProvider; // keeps track of the threads that are printing this component - private transient Set printingThreads; + private transient Set printingThreads; // True if there is at least one thread that's printing this component private transient boolean printing = false; @@ -275,7 +275,7 @@ public class Container extends Component { */ public Container() { } - + @SuppressWarnings({"unchecked","rawtypes"}) void initializeFocusTraversalKeys() { focusTraversalKeys = new Set[4]; } @@ -2006,7 +2006,7 @@ public class Container extends Component { try { synchronized (getObjectLock()) { if (printingThreads == null) { - printingThreads = new HashSet(); + printingThreads = new HashSet<>(); } printingThreads.add(t); printing = true; @@ -2148,7 +2148,7 @@ public class Container extends Component { * @since 1.4 */ public synchronized ContainerListener[] getContainerListeners() { - return (ContainerListener[]) (getListeners(ContainerListener.class)); + return getListeners(ContainerListener.class); } /** @@ -2599,9 +2599,9 @@ public class Container extends Component { if (GraphicsEnvironment.isHeadless()) { throw new HeadlessException(); } - PointerInfo pi = (PointerInfo)java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + PointerInfo pi = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public PointerInfo run() { return MouseInfo.getPointerInfo(); } } @@ -2682,7 +2682,7 @@ public class Container extends Component { y - comp.y, ignoreEnabled); } else { - comp = comp.locate(x - comp.x, y - comp.y); + comp = comp.getComponentAt(x - comp.x, y - comp.y); } if (comp != null && comp.visible && (ignoreEnabled || comp.enabled)) @@ -2700,7 +2700,7 @@ public class Container extends Component { y - comp.y, ignoreEnabled); } else { - comp = comp.locate(x - comp.x, y - comp.y); + comp = comp.getComponentAt(x - comp.x, y - comp.y); } if (comp != null && comp.visible && (ignoreEnabled || comp.enabled)) @@ -4637,7 +4637,7 @@ class LightweightDispatcher implements java.io.Serializable, AWTEventListener { private void startListeningForOtherDrags() { //System.out.println("Adding AWTEventListener"); java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { + new java.security.PrivilegedAction() { public Object run() { nativeContainer.getToolkit().addAWTEventListener( LightweightDispatcher.this, @@ -4652,7 +4652,7 @@ class LightweightDispatcher implements java.io.Serializable, AWTEventListener { private void stopListeningForOtherDrags() { //System.out.println("Removing AWTEventListener"); java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { + new java.security.PrivilegedAction() { public Object run() { nativeContainer.getToolkit().removeAWTEventListener(LightweightDispatcher.this); return null; diff --git a/jdk/src/share/classes/java/awt/Dialog.java b/jdk/src/share/classes/java/awt/Dialog.java index 800d19c0200..622a4531d3a 100644 --- a/jdk/src/share/classes/java/awt/Dialog.java +++ b/jdk/src/share/classes/java/awt/Dialog.java @@ -1047,9 +1047,9 @@ public class Dialog extends Window { // if this dialog is toolkit-modal, the filter should be added // to all EDTs (for all AppContexts) if (modalityType == ModalityType.TOOLKIT_MODAL) { - Iterator it = AppContext.getAppContexts().iterator(); + Iterator it = AppContext.getAppContexts().iterator(); while (it.hasNext()) { - AppContext appContext = (AppContext)it.next(); + AppContext appContext = it.next(); if (appContext == showAppContext) { continue; } @@ -1084,9 +1084,9 @@ public class Dialog extends Window { // if this dialog is toolkit-modal, its filter must be removed // from all EDTs (for all AppContexts) if (modalityType == ModalityType.TOOLKIT_MODAL) { - Iterator it = AppContext.getAppContexts().iterator(); + Iterator it = AppContext.getAppContexts().iterator(); while (it.hasNext()) { - AppContext appContext = (AppContext)it.next(); + AppContext appContext = it.next(); if (appContext == showAppContext) { continue; } @@ -1396,7 +1396,7 @@ public class Dialog extends Window { if (d.shouldBlock(this)) { Window w = d; while ((w != null) && (w != this)) { - w = (Window)(w.getOwner_NoClientCode()); + w = w.getOwner_NoClientCode(); } if ((w == this) || !shouldBlock(d) || (modalityType.compareTo(d.getModalityType()) < 0)) { blockers.add(d); @@ -1611,7 +1611,7 @@ public class Dialog extends Window { setModal(modal); } - blockedWindows = new IdentityArrayList(); + blockedWindows = new IdentityArrayList<>(); } /* diff --git a/jdk/src/share/classes/java/awt/Frame.java b/jdk/src/share/classes/java/awt/Frame.java index 1a3173730e5..2513ddb75ef 100644 --- a/jdk/src/share/classes/java/awt/Frame.java +++ b/jdk/src/share/classes/java/awt/Frame.java @@ -353,7 +353,7 @@ public class Frame extends Window implements MenuContainer { * @serial * @see java.awt.Window#ownedWindowList */ - Vector ownedWindows; + Vector ownedWindows; private static final String base = "frame"; private static int nameCounter = 0; @@ -1242,7 +1242,7 @@ public class Frame extends Window implements MenuContainer { // if (ownedWindows != null) { for (int i = 0; i < ownedWindows.size(); i++) { - connectOwnedWindow((Window) ownedWindows.elementAt(i)); + connectOwnedWindow(ownedWindows.elementAt(i)); } ownedWindows = null; } diff --git a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java index 36a5b9b7fae..af9dcb1b2c2 100644 --- a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java +++ b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java @@ -416,7 +416,7 @@ public abstract class KeyboardFocusManager } } - static Set initFocusTraversalKeysSet(String value, Set targetSet) { + static Set initFocusTraversalKeysSet(String value, Set targetSet) { StringTokenizer tokens = new StringTokenizer(value, ","); while (tokens.hasMoreTokens()) { targetSet.add(AWTKeyStroke.getAWTKeyStroke(tokens.nextToken())); diff --git a/jdk/src/share/classes/java/awt/Scrollbar.java b/jdk/src/share/classes/java/awt/Scrollbar.java index fb033305e51..b6a581d96a8 100644 --- a/jdk/src/share/classes/java/awt/Scrollbar.java +++ b/jdk/src/share/classes/java/awt/Scrollbar.java @@ -1012,7 +1012,7 @@ public class Scrollbar extends Component implements Adjustable, Accessible { * @since 1.4 */ public synchronized AdjustmentListener[] getAdjustmentListeners() { - return (AdjustmentListener[])(getListeners(AdjustmentListener.class)); + return getListeners(AdjustmentListener.class); } /** diff --git a/jdk/src/share/classes/java/awt/TextArea.java b/jdk/src/share/classes/java/awt/TextArea.java index af76af8cbfa..8b16d9ec61d 100644 --- a/jdk/src/share/classes/java/awt/TextArea.java +++ b/jdk/src/share/classes/java/awt/TextArea.java @@ -123,7 +123,7 @@ public class TextArea extends TextComponent { * Cache the Sets of forward and backward traversal keys so we need not * look them up each time. */ - private static Set forwardTraversalKeys, backwardTraversalKeys; + private static Set forwardTraversalKeys, backwardTraversalKeys; /* * JDK 1.1 serialVersionUID @@ -143,10 +143,10 @@ public class TextArea extends TextComponent { } forwardTraversalKeys = KeyboardFocusManager.initFocusTraversalKeysSet( "ctrl TAB", - new HashSet()); + new HashSet()); backwardTraversalKeys = KeyboardFocusManager.initFocusTraversalKeysSet( "ctrl shift TAB", - new HashSet()); + new HashSet()); } /** diff --git a/jdk/src/share/classes/java/awt/TextComponent.java b/jdk/src/share/classes/java/awt/TextComponent.java index c99cae403a4..ecc9b3fd47c 100644 --- a/jdk/src/share/classes/java/awt/TextComponent.java +++ b/jdk/src/share/classes/java/awt/TextComponent.java @@ -606,7 +606,7 @@ public class TextComponent extends Component implements Accessible { * @since 1.4 */ public synchronized TextListener[] getTextListeners() { - return (TextListener[])(getListeners(TextListener.class)); + return getListeners(TextListener.class); } /** diff --git a/jdk/src/share/classes/java/awt/TextField.java b/jdk/src/share/classes/java/awt/TextField.java index 268661c15f3..7c0e528f5f7 100644 --- a/jdk/src/share/classes/java/awt/TextField.java +++ b/jdk/src/share/classes/java/awt/TextField.java @@ -507,7 +507,7 @@ public class TextField extends TextComponent { * @since 1.4 */ public synchronized ActionListener[] getActionListeners() { - return (ActionListener[])(getListeners(ActionListener.class)); + return getListeners(ActionListener.class); } /** diff --git a/jdk/src/share/classes/java/awt/Toolkit.java b/jdk/src/share/classes/java/awt/Toolkit.java index 8509534734c..783706a72b4 100644 --- a/jdk/src/share/classes/java/awt/Toolkit.java +++ b/jdk/src/share/classes/java/awt/Toolkit.java @@ -863,7 +863,7 @@ public abstract class Toolkit { new java.security.PrivilegedAction() { public Void run() { String nm = null; - Class cls = null; + Class cls = null; try { nm = System.getProperty("awt.toolkit"); try { diff --git a/jdk/src/share/classes/java/awt/Window.java b/jdk/src/share/classes/java/awt/Window.java index 984e287bd50..4b9765443eb 100644 --- a/jdk/src/share/classes/java/awt/Window.java +++ b/jdk/src/share/classes/java/awt/Window.java @@ -441,7 +441,7 @@ public class Window extends Container implements Accessible { transient Object anchor = new Object(); static class WindowDisposerRecord implements sun.java2d.DisposerRecord { final WeakReference owner; - final WeakReference weakThis; + final WeakReference weakThis; final WeakReference context; WindowDisposerRecord(AppContext context, Window victim) { owner = new WeakReference(victim.getOwner()); @@ -1542,6 +1542,7 @@ public class Window extends Container implements Accessible { private static Window[] getWindows(AppContext appContext) { synchronized (Window.class) { Window realCopy[]; + @SuppressWarnings("unchecked") Vector> windowList = (Vector>)appContext.get(Window.class); if (windowList != null) { @@ -1866,7 +1867,7 @@ public class Window extends Container implements Accessible { * @since 1.4 */ public synchronized WindowListener[] getWindowListeners() { - return (WindowListener[])(getListeners(WindowListener.class)); + return getListeners(WindowListener.class); } /** @@ -1882,7 +1883,7 @@ public class Window extends Container implements Accessible { * @since 1.4 */ public synchronized WindowFocusListener[] getWindowFocusListeners() { - return (WindowFocusListener[])(getListeners(WindowFocusListener.class)); + return getListeners(WindowFocusListener.class); } /** @@ -1898,7 +1899,7 @@ public class Window extends Container implements Accessible { * @since 1.4 */ public synchronized WindowStateListener[] getWindowStateListeners() { - return (WindowStateListener[])(getListeners(WindowStateListener.class)); + return getListeners(WindowStateListener.class); } @@ -2014,7 +2015,6 @@ public class Window extends Container implements Accessible { break; case WindowEvent.WINDOW_STATE_CHANGED: processWindowStateEvent((WindowEvent)e); - default: break; } return; @@ -2382,12 +2382,14 @@ public class Window extends Container implements Accessible { * KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS * @since 1.4 */ + @SuppressWarnings("unchecked") public Set getFocusTraversalKeys(int id) { if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH) { throw new IllegalArgumentException("invalid focus traversal key identifier"); } // Okay to return Set directly because it is an unmodifiable view + @SuppressWarnings("rawtypes") Set keystrokes = (focusTraversalKeys != null) ? focusTraversalKeys[id] : null; @@ -2765,7 +2767,7 @@ public class Window extends Container implements Accessible { /* * Support for tracking all windows owned by this window */ - void addOwnedWindow(WeakReference weakWindow) { + void addOwnedWindow(WeakReference weakWindow) { if (weakWindow != null) { synchronized(ownedWindowList) { // this if statement should really be an assert, but we don't @@ -2777,7 +2779,7 @@ public class Window extends Container implements Accessible { } } - void removeOwnedWindow(WeakReference weakWindow) { + void removeOwnedWindow(WeakReference weakWindow) { if (weakWindow != null) { // synchronized block not required since removeElement is // already synchronized @@ -2792,6 +2794,7 @@ public class Window extends Container implements Accessible { private void addToWindowList() { synchronized (Window.class) { + @SuppressWarnings("unchecked") Vector> windowList = (Vector>)appContext.get(Window.class); if (windowList == null) { windowList = new Vector>(); @@ -2801,8 +2804,9 @@ public class Window extends Container implements Accessible { } } - private static void removeFromWindowList(AppContext context, WeakReference weakThis) { + private static void removeFromWindowList(AppContext context, WeakReference weakThis) { synchronized (Window.class) { + @SuppressWarnings("unchecked") Vector> windowList = (Vector>)context.get(Window.class); if (windowList != null) { windowList.remove(weakThis); @@ -2945,7 +2949,7 @@ public class Window extends Container implements Accessible { // Deserialized Windows are not yet visible. visible = false; - weakThis = new WeakReference(this); + weakThis = new WeakReference<>(this); anchor = new Object(); sun.java2d.Disposer.addRecord(anchor, new WindowDisposerRecord(appContext, this)); @@ -2956,7 +2960,7 @@ public class Window extends Container implements Accessible { private void deserializeResources(ObjectInputStream s) throws ClassNotFoundException, IOException, HeadlessException { - ownedWindowList = new Vector(); + ownedWindowList = new Vector<>(); if (windowSerializedDataVersion < 2) { // Translate old-style focus tracking to new model. For 1.4 and diff --git a/jdk/src/share/classes/sun/awt/image/SurfaceManager.java b/jdk/src/share/classes/sun/awt/image/SurfaceManager.java index 9451f91e323..f10673a9423 100644 --- a/jdk/src/share/classes/sun/awt/image/SurfaceManager.java +++ b/jdk/src/share/classes/sun/awt/image/SurfaceManager.java @@ -88,7 +88,7 @@ public abstract class SurfaceManager { imgaccessor.setSurfaceManager(img, mgr); } - private ConcurrentHashMap cacheMap; + private ConcurrentHashMap cacheMap; /** * Return an arbitrary cached object for an arbitrary cache key. @@ -123,7 +123,7 @@ public abstract class SurfaceManager { if (cacheMap == null) { synchronized (this) { if (cacheMap == null) { - cacheMap = new ConcurrentHashMap(2); + cacheMap = new ConcurrentHashMap<>(2); } } } @@ -245,7 +245,7 @@ public abstract class SurfaceManager { synchronized void flush(boolean deaccelerate) { if (cacheMap != null) { - Iterator i = cacheMap.values().iterator(); + Iterator i = cacheMap.values().iterator(); while (i.hasNext()) { Object o = i.next(); if (o instanceof FlushableCacheData) { From 07e2e8803a15230e63049d07beaa1c639a86cb70 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Wed, 16 Jan 2013 16:30:04 +0100 Subject: [PATCH 097/204] 8006403: Regression: jstack failed due to the FieldInfo regression in SA Reviewed-by: sla, dholmes --- .../src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java | 4 +++- hotspot/src/share/vm/runtime/vmStructs.cpp | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java index 7052f8a2d18..cfa26eacdbd 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java @@ -53,6 +53,7 @@ public class InstanceKlass extends Klass { private static int HIGH_OFFSET; private static int FIELD_SLOTS; private static short FIELDINFO_TAG_SIZE; + private static short FIELDINFO_TAG_MASK; private static short FIELDINFO_TAG_OFFSET; // ClassState constants @@ -102,6 +103,7 @@ public class InstanceKlass extends Klass { HIGH_OFFSET = db.lookupIntConstant("FieldInfo::high_packed_offset").intValue(); FIELD_SLOTS = db.lookupIntConstant("FieldInfo::field_slots").intValue(); FIELDINFO_TAG_SIZE = db.lookupIntConstant("FIELDINFO_TAG_SIZE").shortValue(); + FIELDINFO_TAG_MASK = db.lookupIntConstant("FIELDINFO_TAG_MASK").shortValue(); FIELDINFO_TAG_OFFSET = db.lookupIntConstant("FIELDINFO_TAG_OFFSET").shortValue(); // read ClassState constants @@ -321,7 +323,7 @@ public class InstanceKlass extends Klass { U2Array fields = getFields(); short lo = fields.at(index * FIELD_SLOTS + LOW_OFFSET); short hi = fields.at(index * FIELD_SLOTS + HIGH_OFFSET); - if ((lo & FIELDINFO_TAG_SIZE) == FIELDINFO_TAG_OFFSET) { + if ((lo & FIELDINFO_TAG_MASK) == FIELDINFO_TAG_OFFSET) { return VM.getVM().buildIntFromShorts(lo, hi) >> FIELDINFO_TAG_SIZE; } throw new RuntimeException("should not reach here"); diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index 8d454992cf8..791a317af17 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -2292,6 +2292,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; /*************************************/ \ \ declare_preprocessor_constant("FIELDINFO_TAG_SIZE", FIELDINFO_TAG_SIZE) \ + declare_preprocessor_constant("FIELDINFO_TAG_MASK", FIELDINFO_TAG_MASK) \ declare_preprocessor_constant("FIELDINFO_TAG_OFFSET", FIELDINFO_TAG_OFFSET) \ \ /************************************************/ \ From d19bc80ca1d894550267d873414eb382bebb4bc4 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Wed, 16 Jan 2013 16:27:01 +0000 Subject: [PATCH 098/204] 8005854: Add support for array constructor references Support constructor references of the kind int[]::new Reviewed-by: jjg --- .../com/sun/tools/javac/comp/Check.java | 34 ++++++++---- .../sun/tools/javac/comp/LambdaToMethod.java | 44 +++++++++------ .../com/sun/tools/javac/comp/Resolve.java | 46 +++++++++++++++- .../com/sun/tools/javac/tree/JCTree.java | 4 +- .../tools/javac/lambda/MethodReference59.java | 52 ++++++++++++++++++ .../tools/javac/lambda/MethodReference60.java | 55 +++++++++++++++++++ .../tools/javac/lambda/MethodReference60.out | 6 ++ 7 files changed, 209 insertions(+), 32 deletions(-) create mode 100644 langtools/test/tools/javac/lambda/MethodReference59.java create mode 100644 langtools/test/tools/javac/lambda/MethodReference60.java create mode 100644 langtools/test/tools/javac/lambda/MethodReference60.out diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index bcc9aa32bcb..16bf5e43cfa 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -634,25 +634,40 @@ public class Check { } } + Type checkClassOrArrayType(DiagnosticPosition pos, Type t) { + if (!t.hasTag(CLASS) && !t.hasTag(ARRAY) && !t.hasTag(ERROR)) { + return typeTagError(pos, + diags.fragment("type.req.class.array"), + asTypeParam(t)); + } else { + return t; + } + } + /** Check that type is a class or interface type. * @param pos Position to be used for error reporting. * @param t The type to be checked. */ Type checkClassType(DiagnosticPosition pos, Type t) { - if (!t.hasTag(CLASS) && !t.hasTag(ERROR)) + if (!t.hasTag(CLASS) && !t.hasTag(ERROR)) { return typeTagError(pos, diags.fragment("type.req.class"), - (t.hasTag(TYPEVAR)) - ? diags.fragment("type.parameter", t) - : t); - else + asTypeParam(t)); + } else { return t; + } } + //where + private Object asTypeParam(Type t) { + return (t.hasTag(TYPEVAR)) + ? diags.fragment("type.parameter", t) + : t; + } /** Check that type is a valid qualifier for a constructor reference expression */ Type checkConstructorRefType(DiagnosticPosition pos, Type t) { - t = checkClassType(pos, t); + t = checkClassOrArrayType(pos, t); if (t.hasTag(CLASS)) { if ((t.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) { log.error(pos, "abstract.cant.be.instantiated"); @@ -690,11 +705,8 @@ public class Check { * @param t The type to be checked. */ Type checkReifiableReferenceType(DiagnosticPosition pos, Type t) { - if (!t.hasTag(CLASS) && !t.hasTag(ARRAY) && !t.hasTag(ERROR)) { - return typeTagError(pos, - diags.fragment("type.req.class.array"), - t); - } else if (!types.isReifiable(t)) { + t = checkClassOrArrayType(pos, t); + if (!t.isErroneous() && !types.isReifiable(t)) { log.error(pos, "illegal.generic.type.for.instof"); return types.createErrorType(t); } else { diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java index 6ad3da8ddae..f7af35aaed3 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java @@ -302,6 +302,7 @@ public class LambdaToMethod extends TreeTranslator { case UNBOUND: /** Type :: instMethod */ case STATIC: /** Type :: staticMethod */ case TOPLEVEL: /** Top level :: new */ + case ARRAY_CTOR: /** ArrayType :: new */ init = null; break; @@ -645,24 +646,33 @@ public class LambdaToMethod extends TreeTranslator { * to the first bridge synthetic parameter */ private JCExpression bridgeExpressionNew() { - JCExpression encl = null; - switch (tree.kind) { - case UNBOUND: - case IMPLICIT_INNER: - encl = make.Ident(params.first()); - } + if (tree.kind == ReferenceKind.ARRAY_CTOR) { + //create the array creation expression + JCNewArray newArr = make.NewArray(make.Type(types.elemtype(tree.getQualifierExpression().type)), + List.of(make.Ident(params.first())), + null); + newArr.type = tree.getQualifierExpression().type; + return newArr; + } else { + JCExpression encl = null; + switch (tree.kind) { + case UNBOUND: + case IMPLICIT_INNER: + encl = make.Ident(params.first()); + } - //create the instance creation expression - JCNewClass newClass = make.NewClass(encl, - List.nil(), - make.Type(tree.getQualifierExpression().type), - convertArgs(tree.sym, args.toList(), tree.varargsElement), - null); - newClass.constructor = tree.sym; - newClass.constructorType = tree.sym.erasure(types); - newClass.type = tree.getQualifierExpression().type; - setVarargsIfNeeded(newClass, tree.varargsElement); - return newClass; + //create the instance creation expression + JCNewClass newClass = make.NewClass(encl, + List.nil(), + make.Type(tree.getQualifierExpression().type), + convertArgs(tree.sym, args.toList(), tree.varargsElement), + null); + newClass.constructor = tree.sym; + newClass.constructorType = tree.sym.erasure(types); + newClass.type = tree.getQualifierExpression().type; + setVarargsIfNeeded(newClass, tree.varargsElement); + return newClass; + } } private VarSymbol addParameter(String name, Type p, boolean genArg) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java index 4b6cab1bf0e..d5adb408242 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -2386,10 +2386,23 @@ public class Resolve { List typeargtypes, boolean boxingAllowed) { MethodResolutionPhase maxPhase = boxingAllowed ? VARARITY : BASIC; + + ReferenceLookupHelper boundLookupHelper; + if (!name.equals(names.init)) { + //method reference + boundLookupHelper = + new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase); + } else if (site.hasTag(ARRAY)) { + //array constructor reference + boundLookupHelper = + new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase); + } else { + //class constructor reference + boundLookupHelper = + new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase); + } + //step 1 - bound lookup - ReferenceLookupHelper boundLookupHelper = name.equals(names.init) ? - new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase) : - new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase); Env boundEnv = env.dup(env.tree, env.info.dup()); Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, boundLookupHelper); @@ -2626,6 +2639,33 @@ public class Resolve { } } + /** + * Helper class for array constructor lookup; an array constructor lookup + * is simulated by looking up a method that returns the array type specified + * as qualifier, and that accepts a single int parameter (size of the array). + */ + class ArrayConstructorReferenceLookupHelper extends ReferenceLookupHelper { + + ArrayConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List argtypes, + List typeargtypes, MethodResolutionPhase maxPhase) { + super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase); + } + + @Override + protected Symbol lookup(Env env, MethodResolutionPhase phase) { + Scope sc = new Scope(syms.arrayClass); + MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym); + arrayConstr.type = new MethodType(List.of(syms.intType), site, List.nil(), syms.methodClass); + sc.enter(arrayConstr); + return findMethodInScope(env, site, name, argtypes, typeargtypes, sc, methodNotFound, phase.isBoxingRequired(), phase.isVarargsRequired(), false, false); + } + + @Override + ReferenceKind referenceKind(Symbol sym) { + return ReferenceKind.ARRAY_CTOR; + } + } + /** * Helper class for constructor reference lookup. The lookup logic is based * upon either Resolve.findMethod or Resolve.findDiamond - depending on diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java index 269890eeb2b..f28a8cf4a52 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java @@ -1838,7 +1838,9 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { /** Inner # new */ IMPLICIT_INNER(ReferenceMode.NEW, false), /** Toplevel # new */ - TOPLEVEL(ReferenceMode.NEW, false); + TOPLEVEL(ReferenceMode.NEW, false), + /** ArrayType # new */ + ARRAY_CTOR(ReferenceMode.NEW, false); final ReferenceMode mode; final boolean unbound; diff --git a/langtools/test/tools/javac/lambda/MethodReference59.java b/langtools/test/tools/javac/lambda/MethodReference59.java new file mode 100644 index 00000000000..76b6669e313 --- /dev/null +++ b/langtools/test/tools/javac/lambda/MethodReference59.java @@ -0,0 +1,52 @@ +/* + * 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. + */ + +/* + * @test + * @bug 8004102 + * @summary Add support for array constructor references + */ +public class MethodReference59 { + + static int assertionCount = 0; + + static void assertTrue(boolean cond) { + assertionCount++; + if (!cond) + throw new AssertionError(); + } + + interface ArrayFactory { + X make(int size); + } + + public static void main(String[] args) { + ArrayFactory factory1 = int[]::new; + int[] i1 = factory1.make(5); + assertTrue(i1.length == 5); + ArrayFactory factory2 = int[][]::new; + int[][] i2 = factory2.make(5); + assertTrue(i2.length == 5); + assertTrue(assertionCount == 2); + } +} diff --git a/langtools/test/tools/javac/lambda/MethodReference60.java b/langtools/test/tools/javac/lambda/MethodReference60.java new file mode 100644 index 00000000000..f8317af36e2 --- /dev/null +++ b/langtools/test/tools/javac/lambda/MethodReference60.java @@ -0,0 +1,55 @@ +/* + * 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. + */ + +/* + * @test + * @bug 8004102 + * @summary Add support for array constructor references + * @compile/fail/ref=MethodReference60.out -XDrawDiagnostics MethodReference60.java + */ +public class MethodReference60 { + + interface ArrayFactory { + X make(int size); + } + + interface BadArrayFactory1 { + X make(); + } + + interface BadArrayFactory2 { + X make(int i1, int i2); + } + + interface BadArrayFactory3 { + X make(String s); + } + + public static void main(String[] args) { + BadArrayFactory1 factory1 = int[]::new; //param mismatch + BadArrayFactory2 factory2 = int[]::new; //param mismatch + BadArrayFactory3 factory3 = int[]::new; //param mismatch + ArrayFactory factory4 = int[]::new; //return type mismatch + ArrayFactory factory5 = int[]::new; //return type mismatch + } +} diff --git a/langtools/test/tools/javac/lambda/MethodReference60.out b/langtools/test/tools/javac/lambda/MethodReference60.out new file mode 100644 index 00000000000..5aa973cf2ad --- /dev/null +++ b/langtools/test/tools/javac/lambda/MethodReference60.out @@ -0,0 +1,6 @@ +MethodReference60.java:49:44: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Array, int, compiler.misc.no.args, kindname.class, Array, (compiler.misc.arg.length.mismatch))) +MethodReference60.java:50:44: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Array, int, int,int, kindname.class, Array, (compiler.misc.arg.length.mismatch))) +MethodReference60.java:51:44: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Array, int, java.lang.String, kindname.class, Array, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.String, int)))) +MethodReference60.java:52:42: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.mref: (compiler.misc.inconvertible.types: int[], java.lang.Integer)) +MethodReference60.java:53:44: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.mref: (compiler.misc.inconvertible.types: int[], java.lang.Integer[])) +5 errors From 3b3feb3853f5bc44a5c3b62049a2d4c9789ccf41 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Wed, 16 Jan 2013 16:30:11 +0000 Subject: [PATCH 099/204] 8005299: Add FunctionalInterface checking to javac Javac should check that types annotated with @FunctionalInterface are indeed functional interfaces Reviewed-by: jjg --- .../com/sun/tools/javac/code/Symtab.java | 2 ++ .../com/sun/tools/javac/code/Types.java | 8 ++--- .../com/sun/tools/javac/comp/Check.java | 12 +++++++ .../tools/javac/resources/compiler.properties | 17 +++++++--- .../javac/util/RichDiagnosticFormatter.java | 2 +- .../tools/javac/diags/examples.not-yet.txt | 1 + .../diags/examples/BadFunctionalIntfAnno.java | 28 ++++++++++++++++ .../test/tools/javac/lambda/BadConv03.out | 2 +- .../test/tools/javac/lambda/BadLambdaPos.out | 4 +-- .../test/tools/javac/lambda/BadTargetType.out | 8 ++--- .../javac/lambda/FunctionalInterfaceAnno.java | 33 +++++++++++++++++++ .../javac/lambda/FunctionalInterfaceAnno.out | 9 +++++ .../tools/javac/lambda/Intersection01.out | 4 +-- .../test/tools/javac/lambda/LambdaConv09.out | 8 ++--- .../test/tools/javac/lambda/LambdaExpr10.out | 12 +++---- .../tools/javac/lambda/MethodReference04.out | 2 +- .../test/tools/javac/lambda/TargetType17.out | 16 ++++----- .../test/tools/javac/lambda/TargetType43.out | 4 +-- .../funcInterfaces/LambdaTest2_neg1.out | 2 +- .../javac/lambda/funcInterfaces/NonSAM1.out | 2 +- .../javac/lambda/funcInterfaces/NonSAM3.out | 16 ++++----- .../lambdaExpression/AbstractClass_neg.out | 2 +- .../lambdaExpression/InvalidExpression5.out | 2 +- 23 files changed, 145 insertions(+), 51 deletions(-) create mode 100644 langtools/test/tools/javac/diags/examples/BadFunctionalIntfAnno.java create mode 100644 langtools/test/tools/javac/lambda/FunctionalInterfaceAnno.java create mode 100644 langtools/test/tools/javac/lambda/FunctionalInterfaceAnno.out diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java index 17535be2053..2ec60dbf432 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java @@ -164,6 +164,7 @@ public class Symtab { public final Type repeatableType; public final Type documentedType; public final Type elementTypeType; + public final Type functionalInterfaceType; /** The symbol representing the length field of an array. */ @@ -507,6 +508,7 @@ public class Symtab { nativeHeaderType = enterClass("java.lang.annotation.Native"); nativeHeaderType_old = enterClass("javax.tools.annotation.GenerateNativeHeader"); lambdaMetafactory = enterClass("java.lang.invoke.LambdaMetafactory"); + functionalInterfaceType = enterClass("java.lang.FunctionalInterface"); synthesizeEmptyInterfaceIfMissing(autoCloseableType); synthesizeEmptyInterfaceIfMissing(cloneableType); diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java index a7378f8acfe..2a3946716d4 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java @@ -392,9 +392,9 @@ public class Types { * Compute the function descriptor associated with a given functional interface */ public FunctionDescriptor findDescriptorInternal(TypeSymbol origin, CompoundScope membersCache) throws FunctionDescriptorLookupError { - if (!origin.isInterface()) { + if (!origin.isInterface() || (origin.flags() & ANNOTATION) != 0) { //t must be an interface - throw failure("not.a.functional.intf"); + throw failure("not.a.functional.intf", origin); } final ListBuffer abstracts = ListBuffer.lb(); @@ -406,13 +406,13 @@ public class Types { abstracts.append(sym); } else { //the target method(s) should be the only abstract members of t - throw failure("not.a.functional.intf.1", + throw failure("not.a.functional.intf.1", origin, diags.fragment("incompatible.abstracts", Kinds.kindName(origin), origin)); } } if (abstracts.isEmpty()) { //t must define a suitable non-generic method - throw failure("not.a.functional.intf.1", + throw failure("not.a.functional.intf.1", origin, diags.fragment("no.abstracts", Kinds.kindName(origin), origin)); } else if (abstracts.size() == 1) { return new FunctionDescriptor(abstracts.first()); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index 16bf5e43cfa..0ad9c099199 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -2601,6 +2601,18 @@ public class Check { if (!isOverrider(s)) log.error(a.pos(), "method.does.not.override.superclass"); } + + if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) { + if (s.kind != TYP) { + log.error(a.pos(), "bad.functional.intf.anno"); + } else { + try { + types.findDescriptorSymbol((TypeSymbol)s); + } catch (Types.FunctionDescriptorLookupError ex) { + log.error(a.pos(), "bad.functional.intf.anno.1", ex.getDiagnostic()); + } + } + } } /** diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties index 41c89491c63..f04abc7c42a 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -178,14 +178,23 @@ compiler.misc.no.abstracts=\ compiler.misc.incompatible.abstracts=\ multiple non-overriding abstract methods found in {0} {1} -compiler.misc.not.a.functional.intf=\ - the target type must be a functional interface +compiler.err.bad.functional.intf.anno=\ + Unexpected @FunctionalInterface annotation # 0: message segment -compiler.misc.not.a.functional.intf.1=\ - the target type must be a functional interface\n\ +compiler.err.bad.functional.intf.anno.1=\ + Unexpected @FunctionalInterface annotation\n\ {0} +# 0: symbol +compiler.misc.not.a.functional.intf=\ + {0} is not a functional interface + +# 0: symbol, 1: message segment +compiler.misc.not.a.functional.intf.1=\ + {0} is not a functional interface\n\ + {1} + # 0: symbol, 1: symbol kind, 2: symbol compiler.misc.invalid.generic.lambda.target=\ invalid functional descriptor for lambda expression\n\ diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java b/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java index 46867d5fa75..7c5849d2758 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java @@ -288,7 +288,7 @@ public class RichDiagnosticFormatter extends public String simplify(Symbol s) { String name = s.getQualifiedName().toString(); - if (!s.type.isCompound()) { + if (!s.type.isCompound() && !s.type.isPrimitive()) { List conflicts = nameClashes.get(s.getSimpleName()); if (conflicts == null || (conflicts.size() == 1 && diff --git a/langtools/test/tools/javac/diags/examples.not-yet.txt b/langtools/test/tools/javac/diags/examples.not-yet.txt index ef2b5c84e5a..1cc337e69fa 100644 --- a/langtools/test/tools/javac/diags/examples.not-yet.txt +++ b/langtools/test/tools/javac/diags/examples.not-yet.txt @@ -1,6 +1,7 @@ compiler.err.already.annotated # internal compiler error? compiler.err.already.defined.this.unit # seems to be masked by compiler.err.duplicate.class compiler.err.annotation.value.not.allowable.type # cannot happen: precluded by complete type-specific tests +compiler.err.bad.functional.intf.anno # seems to be masked by compiler.err.annotation.type.not.applicable compiler.err.cant.read.file # (apt.JavaCompiler?) compiler.err.cant.select.static.class.from.param.type compiler.err.dc.unterminated.string # cannot happen diff --git a/langtools/test/tools/javac/diags/examples/BadFunctionalIntfAnno.java b/langtools/test/tools/javac/diags/examples/BadFunctionalIntfAnno.java new file mode 100644 index 00000000000..87090505bd2 --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/BadFunctionalIntfAnno.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2013, 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. + */ + +// key: compiler.err.bad.functional.intf.anno.1 +// key: compiler.misc.not.a.functional.intf + +@FunctionalInterface +class BadFunctionalIntfAnno { } diff --git a/langtools/test/tools/javac/lambda/BadConv03.out b/langtools/test/tools/javac/lambda/BadConv03.out index 078f304f413..210148069a8 100644 --- a/langtools/test/tools/javac/lambda/BadConv03.out +++ b/langtools/test/tools/javac/lambda/BadConv03.out @@ -1,2 +1,2 @@ -BadConv03.java:19:11: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, BadConv03.B)) +BadConv03.java:19:11: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: BadConv03.B, (compiler.misc.incompatible.abstracts: kindname.interface, BadConv03.B)) 1 error diff --git a/langtools/test/tools/javac/lambda/BadLambdaPos.out b/langtools/test/tools/javac/lambda/BadLambdaPos.out index b2436d9ca1a..d192495c9c6 100644 --- a/langtools/test/tools/javac/lambda/BadLambdaPos.out +++ b/langtools/test/tools/javac/lambda/BadLambdaPos.out @@ -4,6 +4,6 @@ BadLambdaPos.java:19:14: compiler.err.unexpected.lambda BadLambdaPos.java:23:18: compiler.err.unexpected.lambda BadLambdaPos.java:23:34: compiler.err.unexpected.lambda BadLambdaPos.java:24:21: compiler.err.unexpected.lambda -BadLambdaPos.java:28:22: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf) -BadLambdaPos.java:29:28: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf) +BadLambdaPos.java:28:22: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object) +BadLambdaPos.java:29:28: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object) 8 errors diff --git a/langtools/test/tools/javac/lambda/BadTargetType.out b/langtools/test/tools/javac/lambda/BadTargetType.out index 8979631251b..122b4c833e4 100644 --- a/langtools/test/tools/javac/lambda/BadTargetType.out +++ b/langtools/test/tools/javac/lambda/BadTargetType.out @@ -1,5 +1,5 @@ -BadTargetType.java:16:24: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf) -BadTargetType.java:17:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf) -BadTargetType.java:20:9: compiler.err.cant.apply.symbol: kindname.method, m1, java.lang.Object, @460, kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf)) -BadTargetType.java:21:9: compiler.err.cant.apply.symbol: kindname.method, m2, java.lang.Object, @489, kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf)) +BadTargetType.java:16:24: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object) +BadTargetType.java:17:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object) +BadTargetType.java:20:9: compiler.err.cant.apply.symbol: kindname.method, m1, java.lang.Object, @460, kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf: java.lang.Object)) +BadTargetType.java:21:9: compiler.err.cant.apply.symbol: kindname.method, m2, java.lang.Object, @489, kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf: java.lang.Object)) 4 errors diff --git a/langtools/test/tools/javac/lambda/FunctionalInterfaceAnno.java b/langtools/test/tools/javac/lambda/FunctionalInterfaceAnno.java new file mode 100644 index 00000000000..49248a0e378 --- /dev/null +++ b/langtools/test/tools/javac/lambda/FunctionalInterfaceAnno.java @@ -0,0 +1,33 @@ +/* + * @test /nodynamiccopyright/ + * @summary smoke test for functional interface annotation + * @compile/fail/ref=FunctionalInterfaceAnno.out -XDrawDiagnostics FunctionalInterfaceAnno.java + */ +class FunctionalInterfaceAnno { + @FunctionalInterface + static class A { } //not an interface + + @FunctionalInterface + static abstract class B { } //not an interface + + @FunctionalInterface + enum C { } //not an interface + + @FunctionalInterface + @interface D { } //not an interface + + @FunctionalInterface + interface E { } //no abstracts + + @FunctionalInterface + interface F { default void m() { } } //no abstracts + + @FunctionalInterface + interface G { String toString(); } //no abstracts + + @FunctionalInterface + interface H { void m(); void n(); } //incompatible abstracts + + @FunctionalInterface + interface I { void m(); } //ok +} diff --git a/langtools/test/tools/javac/lambda/FunctionalInterfaceAnno.out b/langtools/test/tools/javac/lambda/FunctionalInterfaceAnno.out new file mode 100644 index 00000000000..d6b8c398bc6 --- /dev/null +++ b/langtools/test/tools/javac/lambda/FunctionalInterfaceAnno.out @@ -0,0 +1,9 @@ +FunctionalInterfaceAnno.java:7:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf: FunctionalInterfaceAnno.A) +FunctionalInterfaceAnno.java:10:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf: FunctionalInterfaceAnno.B) +FunctionalInterfaceAnno.java:13:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf: FunctionalInterfaceAnno.C) +FunctionalInterfaceAnno.java:16:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf: FunctionalInterfaceAnno.D) +FunctionalInterfaceAnno.java:19:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf.1: FunctionalInterfaceAnno.E, (compiler.misc.no.abstracts: kindname.interface, FunctionalInterfaceAnno.E)) +FunctionalInterfaceAnno.java:22:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf.1: FunctionalInterfaceAnno.F, (compiler.misc.no.abstracts: kindname.interface, FunctionalInterfaceAnno.F)) +FunctionalInterfaceAnno.java:25:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf.1: FunctionalInterfaceAnno.G, (compiler.misc.no.abstracts: kindname.interface, FunctionalInterfaceAnno.G)) +FunctionalInterfaceAnno.java:28:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf.1: FunctionalInterfaceAnno.H, (compiler.misc.incompatible.abstracts: kindname.interface, FunctionalInterfaceAnno.H)) +8 errors diff --git a/langtools/test/tools/javac/lambda/Intersection01.out b/langtools/test/tools/javac/lambda/Intersection01.out index 122935b0913..75debb49693 100644 --- a/langtools/test/tools/javac/lambda/Intersection01.out +++ b/langtools/test/tools/javac/lambda/Intersection01.out @@ -1,3 +1,3 @@ -Intersection01.java:36:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable)) -Intersection01.java:38:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable)) +Intersection01.java:36:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: java.io.Serializable, (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable)) +Intersection01.java:38:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: java.io.Serializable, (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable)) 2 errors diff --git a/langtools/test/tools/javac/lambda/LambdaConv09.out b/langtools/test/tools/javac/lambda/LambdaConv09.out index 1f99986794c..5265879d881 100644 --- a/langtools/test/tools/javac/lambda/LambdaConv09.out +++ b/langtools/test/tools/javac/lambda/LambdaConv09.out @@ -1,5 +1,5 @@ -LambdaConv09.java:42:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo1)) -LambdaConv09.java:43:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo2)) -LambdaConv09.java:44:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo3)) -LambdaConv09.java:46:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo5)) +LambdaConv09.java:42:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: LambdaConv09.Foo1, (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo1)) +LambdaConv09.java:43:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: LambdaConv09.Foo2, (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo2)) +LambdaConv09.java:44:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: LambdaConv09.Foo3, (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo3)) +LambdaConv09.java:46:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: LambdaConv09.Foo5, (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo5)) 4 errors diff --git a/langtools/test/tools/javac/lambda/LambdaExpr10.out b/langtools/test/tools/javac/lambda/LambdaExpr10.out index adcba0ad43e..9270b144671 100644 --- a/langtools/test/tools/javac/lambda/LambdaExpr10.out +++ b/langtools/test/tools/javac/lambda/LambdaExpr10.out @@ -1,9 +1,9 @@ -LambdaExpr10.java:18:28: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf) -LambdaExpr10.java:19:32: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf) -LambdaExpr10.java:23:40: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf) -LambdaExpr10.java:24:46: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf) -LambdaExpr10.java:28:29: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf) -LambdaExpr10.java:29:33: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf) +LambdaExpr10.java:18:28: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object) +LambdaExpr10.java:19:32: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object) +LambdaExpr10.java:23:40: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object) +LambdaExpr10.java:24:46: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object) +LambdaExpr10.java:28:29: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object) +LambdaExpr10.java:29:33: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object) LambdaExpr10.java:33:35: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Object, void)) LambdaExpr10.java:34:49: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Object, void)) 8 errors diff --git a/langtools/test/tools/javac/lambda/MethodReference04.out b/langtools/test/tools/javac/lambda/MethodReference04.out index 789804b78d5..46c933a12c2 100644 --- a/langtools/test/tools/javac/lambda/MethodReference04.out +++ b/langtools/test/tools/javac/lambda/MethodReference04.out @@ -1,2 +1,2 @@ -MethodReference04.java:13:16: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf) +MethodReference04.java:13:16: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object) 1 error diff --git a/langtools/test/tools/javac/lambda/TargetType17.out b/langtools/test/tools/javac/lambda/TargetType17.out index 0bb985f699b..2bdf33ce266 100644 --- a/langtools/test/tools/javac/lambda/TargetType17.out +++ b/langtools/test/tools/javac/lambda/TargetType17.out @@ -1,9 +1,9 @@ -TargetType17.java:14:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf) -TargetType17.java:15:23: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf) -TargetType17.java:16:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf) -TargetType17.java:17:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf) -TargetType17.java:18:23: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf) -TargetType17.java:19:25: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf) -TargetType17.java:20:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf) -TargetType17.java:21:27: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf) +TargetType17.java:14:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: byte) +TargetType17.java:15:23: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: short) +TargetType17.java:16:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: int) +TargetType17.java:17:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: long) +TargetType17.java:18:23: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: float) +TargetType17.java:19:25: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: double) +TargetType17.java:20:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: char) +TargetType17.java:21:27: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: boolean) 8 errors diff --git a/langtools/test/tools/javac/lambda/TargetType43.out b/langtools/test/tools/javac/lambda/TargetType43.out index b7b8766c516..7d50949d9a0 100644 --- a/langtools/test/tools/javac/lambda/TargetType43.out +++ b/langtools/test/tools/javac/lambda/TargetType43.out @@ -1,5 +1,5 @@ -TargetType43.java:13:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf) +TargetType43.java:13:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object) TargetType43.java:13:30: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, TargetType43, null) -TargetType43.java:14:9: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.Object, @359, kindname.class, TargetType43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf)) +TargetType43.java:14:9: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.Object, @359, kindname.class, TargetType43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf: java.lang.Object)) TargetType43.java:14:21: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, TargetType43, null) 4 errors diff --git a/langtools/test/tools/javac/lambda/funcInterfaces/LambdaTest2_neg1.out b/langtools/test/tools/javac/lambda/funcInterfaces/LambdaTest2_neg1.out index 4780e80fec6..0a96b7ded8d 100644 --- a/langtools/test/tools/javac/lambda/funcInterfaces/LambdaTest2_neg1.out +++ b/langtools/test/tools/javac/lambda/funcInterfaces/LambdaTest2_neg1.out @@ -1,2 +1,2 @@ -LambdaTest2_neg1.java:15:13: compiler.err.cant.apply.symbol: kindname.method, methodQooRoo, QooRoo, @531, kindname.class, LambdaTest2_neg1, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, QooRoo))) +LambdaTest2_neg1.java:15:13: compiler.err.cant.apply.symbol: kindname.method, methodQooRoo, QooRoo, @531, kindname.class, LambdaTest2_neg1, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf.1: QooRoo, (compiler.misc.incompatible.abstracts: kindname.interface, QooRoo))) 1 error diff --git a/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM1.out b/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM1.out index c2472263c0a..abfaf967caa 100644 --- a/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM1.out +++ b/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM1.out @@ -1,2 +1,2 @@ -NonSAM1.java:11:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, Planet)) +NonSAM1.java:11:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: Planet, (compiler.misc.no.abstracts: kindname.interface, Planet)) 1 error diff --git a/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM3.out b/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM3.out index 8c9ff08b5ae..9f52ba5f767 100644 --- a/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM3.out +++ b/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM3.out @@ -1,9 +1,9 @@ -NonSAM3.java:15:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, FooBar)) -NonSAM3.java:16:22: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, FooBar)) -NonSAM3.java:17:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE)) -NonSAM3.java:18:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE)) -NonSAM3.java:19:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE)) -NonSAM3.java:20:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE)) -NonSAM3.java:21:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE)) -NonSAM3.java:22:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE)) +NonSAM3.java:15:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: FooBar, (compiler.misc.incompatible.abstracts: kindname.interface, FooBar)) +NonSAM3.java:16:22: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: FooBar, (compiler.misc.incompatible.abstracts: kindname.interface, FooBar)) +NonSAM3.java:17:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: DE, (compiler.misc.incompatible.abstracts: kindname.interface, DE)) +NonSAM3.java:18:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: DE, (compiler.misc.incompatible.abstracts: kindname.interface, DE)) +NonSAM3.java:19:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: DE, (compiler.misc.incompatible.abstracts: kindname.interface, DE)) +NonSAM3.java:20:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: DE, (compiler.misc.incompatible.abstracts: kindname.interface, DE)) +NonSAM3.java:21:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: DE, (compiler.misc.incompatible.abstracts: kindname.interface, DE)) +NonSAM3.java:22:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: DE, (compiler.misc.incompatible.abstracts: kindname.interface, DE)) 8 errors diff --git a/langtools/test/tools/javac/lambda/lambdaExpression/AbstractClass_neg.out b/langtools/test/tools/javac/lambda/lambdaExpression/AbstractClass_neg.out index 2fc5555b1e6..cfe68383937 100644 --- a/langtools/test/tools/javac/lambda/lambdaExpression/AbstractClass_neg.out +++ b/langtools/test/tools/javac/lambda/lambdaExpression/AbstractClass_neg.out @@ -1,2 +1,2 @@ -AbstractClass_neg.java:16:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf) +AbstractClass_neg.java:16:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: AbstractClass_neg.SAM) 1 error diff --git a/langtools/test/tools/javac/lambda/lambdaExpression/InvalidExpression5.out b/langtools/test/tools/javac/lambda/lambdaExpression/InvalidExpression5.out index 251425e6675..f9c70cddcb8 100644 --- a/langtools/test/tools/javac/lambda/lambdaExpression/InvalidExpression5.out +++ b/langtools/test/tools/javac/lambda/lambdaExpression/InvalidExpression5.out @@ -1,2 +1,2 @@ -InvalidExpression5.java:12:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf) +InvalidExpression5.java:12:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object) 1 error From 5a60f56dbe32ba268524d68a7ce8df2c40cf9e53 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Wed, 16 Jan 2013 17:40:28 +0000 Subject: [PATCH 100/204] 8005964: Regression: difference in error recovery after ambiguity causes JCK test failure Wrong implementation of ResolveError.access in AmbiguityError Reviewed-by: jjh --- .../src/share/classes/com/sun/tools/javac/comp/Resolve.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java index d5adb408242..2847ff1bfe8 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -3421,7 +3421,10 @@ public class Resolve { @Override protected Symbol access(Name name, TypeSymbol location) { - return ambiguousSyms.last(); + Symbol firstAmbiguity = ambiguousSyms.last(); + return firstAmbiguity.kind == TYP ? + types.createErrorType(name, location, firstAmbiguity.type).tsym : + firstAmbiguity; } } From 17ebfc350d1c0fea959a96bda36778c8f78a5bf2 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Wed, 16 Jan 2013 10:29:52 -0800 Subject: [PATCH 101/204] 8006236: doclint: structural issue hidden Reviewed-by: darcy --- .../com/sun/tools/doclint/Checker.java | 23 ++++++++++- langtools/test/tools/doclint/EndTagsTest.java | 39 +++++++++++++++++++ langtools/test/tools/doclint/EndTagsTest.out | 25 ++++++++++++ 3 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 langtools/test/tools/doclint/EndTagsTest.java create mode 100644 langtools/test/tools/doclint/EndTagsTest.out diff --git a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java index 0664838936d..b0d8d06f127 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java +++ b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java @@ -25,6 +25,7 @@ package com.sun.tools.doclint; +import com.sun.source.doctree.LiteralTree; import java.util.regex.Matcher; import com.sun.source.doctree.LinkTree; import java.net.URI; @@ -359,9 +360,8 @@ public class Checker extends DocTreeScanner { env.messages.error(HTML, tree, "dc.tag.unknown", treeName); } else if (t.endKind == HtmlTag.EndKind.NONE) { env.messages.error(HTML, tree, "dc.tag.end.not.permitted", treeName); - } else if (tagStack.isEmpty()) { - env.messages.error(HTML, tree, "dc.tag.end.unexpected", treeName); } else { + boolean done = false; while (!tagStack.isEmpty()) { TagStackItem top = tagStack.peek(); if (t == top.tag) { @@ -383,6 +383,7 @@ public class Checker extends DocTreeScanner { env.messages.error(HTML, tree, "dc.text.not.allowed", treeName); } tagStack.pop(); + done = true; break; } else if (top.tag == null || top.tag.endKind != HtmlTag.EndKind.REQUIRED) { tagStack.pop(); @@ -400,10 +401,15 @@ public class Checker extends DocTreeScanner { tagStack.pop(); } else { env.messages.error(HTML, tree, "dc.tag.end.unexpected", treeName); + done = true; break; } } } + + if (!done && tagStack.isEmpty()) { + env.messages.error(HTML, tree, "dc.tag.end.unexpected", treeName); + } } return super.visitEndElement(tree, ignore); @@ -545,6 +551,19 @@ public class Checker extends DocTreeScanner { } } + @Override + public Void visitLiteral(LiteralTree tree, Void ignore) { + if (tree.getKind() == DocTree.Kind.CODE) { + for (TagStackItem tsi: tagStack) { + if (tsi.tag == HtmlTag.CODE) { + env.messages.warning(HTML, tree, "dc.tag.nested.not.allowed", "code"); + break; + } + } + } + return super.visitLiteral(tree, ignore); + } + @Override public Void visitParam(ParamTree tree, Void ignore) { boolean typaram = tree.isTypeParameter(); diff --git a/langtools/test/tools/doclint/EndTagsTest.java b/langtools/test/tools/doclint/EndTagsTest.java new file mode 100644 index 00000000000..154f516324a --- /dev/null +++ b/langtools/test/tools/doclint/EndTagsTest.java @@ -0,0 +1,39 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8006236 + * @summary doclint: structural issue hidden + * @build DocLintTester + * @run main DocLintTester -Xmsgs:-html EndTagsTest.java + * @run main DocLintTester -ref EndTagsTest.out EndTagsTest.java + */ + +/** */ +public class EndTagsTest { + /**

text image

*/ + public void valid_all() { } + + /**

text image */ + public void valid_omit_optional_close() { } + + /** */ + public void invalid_missing_start() { } + + /**

*/ + public void invalid_missing_start_2() { } + + /**

text

*/ + public void invalid_missing_start_3() { } + + /** image */ + public void invalid_end() { } + + /** */ + public void unknown_start_end() { } + + /** */ + public void unknown_start() { } + + /** */ + public void unknown_end() { } +} + diff --git a/langtools/test/tools/doclint/EndTagsTest.out b/langtools/test/tools/doclint/EndTagsTest.out new file mode 100644 index 00000000000..61af632535c --- /dev/null +++ b/langtools/test/tools/doclint/EndTagsTest.out @@ -0,0 +1,25 @@ +EndTagsTest.java:18: error: unexpected end tag: + /** */ + ^ +EndTagsTest.java:21: error: unexpected end tag: + /**

*/ + ^ +EndTagsTest.java:24: error: unexpected end tag: + /**

text

*/ + ^ +EndTagsTest.java:27: error: invalid end tag: + /** image */ + ^ +EndTagsTest.java:30: error: unknown tag: invalid + /** */ + ^ +EndTagsTest.java:30: error: unknown tag: invalid + /** */ + ^ +EndTagsTest.java:33: error: unknown tag: invalid + /** */ + ^ +EndTagsTest.java:36: error: unknown tag: invalid + /** */ + ^ +8 errors From 15750269ce04ebb20ce854500e2854c8b1fd044b Mon Sep 17 00:00:00 2001 From: David Katleman Date: Wed, 16 Jan 2013 11:59:37 -0800 Subject: [PATCH 102/204] Added tag jdk8-b73 for changeset e6f9cd2122f9 --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 85a42f862f4..8555b3366ec 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -194,3 +194,4 @@ cdb401a60cea6ad5ef3f498725ed1decf8dda1ea jdk8-b68 105a25ffa4a4f0af70188d4371b4a0385009b7ce jdk8-b70 51ad2a34342055333eb5f36e2fb514b027895708 jdk8-b71 c1be681d80a1f1c848dc671d664fccb19e046a12 jdk8-b72 +93b9664f97eeb6f89397a8842318ebacaac9feb9 jdk8-b73 From 7716c3be5eda0675fc8ac58da77b66f95f2127a9 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Wed, 16 Jan 2013 11:59:38 -0800 Subject: [PATCH 103/204] Added tag jdk8-b73 for changeset 8268581591da --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index 47a378ec418..1a3ee17d1bb 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -194,3 +194,4 @@ d54dc53e223ed9ce7d5f4d2cd02ad9d5def3c2db jdk8-b59 603cceb495c8133d47b26a7502d51c7d8a67d76b jdk8-b70 8171d23e914d758836527b80b06debcfdb718f2d jdk8-b71 cb40427f47145b01b7e53c3e02b38ff7625efbda jdk8-b72 +191afde59e7be0e1a1d76d06f2a32ff17444f0ec jdk8-b73 From c5c2fe5f1403d7bf197f7c61701716513741d9c0 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Wed, 16 Jan 2013 11:59:44 -0800 Subject: [PATCH 104/204] Added tag jdk8-b73 for changeset b63b5628ae56 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 13706d68127..906453c8eda 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -306,3 +306,4 @@ cb8a4e04bc8c104de8a2f67463c7e31232bf8d68 jdk8-b69 e94068d4ff52849c8aa0786a53a59b63d1312a39 jdk8-b70 0847210f85480bf3848dc90bc2ab23c0a4791b55 jdk8-b71 d5cb5830f570d1304ea4b196dde672a291b55f29 jdk8-b72 +11619f33cd683c2f1d6ef72f1c6ff3dacf5a9f1c jdk8-b73 From 41ec1cb0656343fe1c69e63caa3dfc32e3e66db5 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Wed, 16 Jan 2013 11:59:54 -0800 Subject: [PATCH 105/204] Added tag jdk8-b73 for changeset 4c46a5207766 --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index 95842b77d83..4d8f24840a0 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -194,3 +194,4 @@ b854e70084214e9dcf1b37373f6e4b1a68760e03 jdk8-b68 6ec9edffc286c9c9ac96c9cd2050b01cb5d514a8 jdk8-b70 499be952a291cec1dc774a84a238941d6faf772d jdk8-b71 bdf2af722a6b54fca47d8c51d17a1b8f41dd7a3e jdk8-b72 +84946404d1e1de003ed2bf218ef8d48906a90e37 jdk8-b73 From 4598fecb7c19f8293ca23b42dbeff2b57359502f Mon Sep 17 00:00:00 2001 From: David Katleman Date: Wed, 16 Jan 2013 11:59:59 -0800 Subject: [PATCH 106/204] Added tag jdk8-b73 for changeset a7dead2f55ef --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index fbab4113f1f..f4bf9b21b81 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -194,3 +194,4 @@ d3fe408f3a9ad250bc9a4e9365bdfc3f28c1d3f4 jdk8-b68 3b1c2733d47ee9f8c530925df4041c59f9ee5a31 jdk8-b70 f577a39c9fb3d5820248c13c2cc74a192a9313e0 jdk8-b71 d9707230294d54e695e745a90de6112909100f12 jdk8-b72 +c606f644a5d9118c14b5822738bf23c300f14f24 jdk8-b73 From 2062fc003c1f496c870b4a45394d1d8694a3b212 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Wed, 16 Jan 2013 12:00:21 -0800 Subject: [PATCH 107/204] Added tag jdk8-b73 for changeset b568005e66bd --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index dc9480c104e..cd611eef514 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -194,3 +194,4 @@ d7360bf35ee1f40ff78c2e83a22b5446ee464346 jdk8-b69 47f71d7c124f24c2fe2dfc49865b332345b458ed jdk8-b70 467e4d9281bcf119eaec42af1423c96bd401871c jdk8-b71 6f0986ed9b7e11d6eb06618f27e20b18f19fb797 jdk8-b72 +8d0baee36c7184d55c80354b45704c37d6b7ac79 jdk8-b73 From e942cdde819b76892eb060c6b25f10f0cf7b29bb Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Wed, 16 Jan 2013 13:22:09 -0800 Subject: [PATCH 108/204] 8006283: Change to Class.cast() in javax.lang.model implementation for repeating annotations Reviewed-by: jjg --- .../classes/com/sun/tools/javac/model/JavacElements.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java b/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java index 14f6e366ddb..5861e70f7f3 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java +++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java @@ -266,9 +266,10 @@ public class JavacElements implements Elements { private static Class initRepeatable() { try { - @SuppressWarnings("unchecked") // java.lang.annotation.Repeatable extends Annotation by being an annotation type - Class c = (Class)Class.forName("java.lang.annotation.Repeatable"); - return c; + // Repeatable will not be available when bootstrapping on + // JDK 7 so use a reflective lookup instead of a class + // literal for Repeatable.class. + return Class.forName("java.lang.annotation.Repeatable").asSubclass(Annotation.class); } catch (ClassNotFoundException e) { return null; } catch (SecurityException e) { From c803a77fa8f02c256f2436c31f9b9352d9cacaa5 Mon Sep 17 00:00:00 2001 From: David Chase Date: Wed, 16 Jan 2013 14:55:18 -0800 Subject: [PATCH 109/204] 8006204: please JTREGify test/compiler/7190310/Test7190310.java Add proper jtreg annotations in the preceding comment, including an explicit timeout. Reviewed-by: kvn, twisti --- hotspot/test/compiler/7190310/Test7190310.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/hotspot/test/compiler/7190310/Test7190310.java b/hotspot/test/compiler/7190310/Test7190310.java index 57a89b93b39..b45c60bf196 100644 --- a/hotspot/test/compiler/7190310/Test7190310.java +++ b/hotspot/test/compiler/7190310/Test7190310.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -23,7 +23,16 @@ */ /* - * Manual test + * @test + * @bug 7190310 + * @summary Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops + * @run main/othervm/timeout=600 -Xbatch Test7190310 + */ + +/* + * Note bug exhibits as infinite loop, timeout is helpful. + * It should normally finish pretty quickly, but on some especially slow machines + * it may not. The companion _unsafe test lacks a timeout, but that is okay. */ import java.lang.ref.*; From 7b493a180e406771500a247a01a07f0cbc656de7 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Wed, 16 Jan 2013 20:41:14 -0800 Subject: [PATCH 110/204] 8006228: Doclint doesn't detect {@code nested inline} Reviewed-by: darcy --- .../classes/com/sun/tools/doclint/Checker.java | 2 +- .../tools/doclint/resources/doclint.properties | 1 + langtools/test/tools/doclint/LiteralTest.java | 16 ++++++++++++++++ langtools/test/tools/doclint/LiteralTest.out | 4 ++++ 4 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 langtools/test/tools/doclint/LiteralTest.java create mode 100644 langtools/test/tools/doclint/LiteralTest.out diff --git a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java index b0d8d06f127..8b4697c8e49 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java +++ b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java @@ -556,7 +556,7 @@ public class Checker extends DocTreeScanner { if (tree.getKind() == DocTree.Kind.CODE) { for (TagStackItem tsi: tagStack) { if (tsi.tag == HtmlTag.CODE) { - env.messages.warning(HTML, tree, "dc.tag.nested.not.allowed", "code"); + env.messages.warning(HTML, tree, "dc.tag.code.within.code"); break; } } diff --git a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties index 33b0d7d1151..a1a3a02c7bb 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties +++ b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties @@ -48,6 +48,7 @@ dc.no.alt.attr.for.image = no "alt" attribute for image dc.no.summary.or.caption.for.table=no summary or caption for table dc.param.name.not.found = @param name not found dc.ref.not.found = reference not found +dc.tag.code.within.code = '{@code'} within dc.tag.empty = empty <{0}> tag dc.tag.end.not.permitted = invalid end tag: dc.tag.end.unexpected = unexpected end tag: diff --git a/langtools/test/tools/doclint/LiteralTest.java b/langtools/test/tools/doclint/LiteralTest.java new file mode 100644 index 00000000000..008246edee6 --- /dev/null +++ b/langtools/test/tools/doclint/LiteralTest.java @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8006228 + * @summary Doclint doesn't detect {@code nested inline} + * @build DocLintTester + * @run main DocLintTester -ref LiteralTest.out LiteralTest.java + */ + +/** */ +public class LiteralTest { + /** abc {@literal < & > } def */ + public void ok_literal_in_code() { } + + /** abc {@code < & > } def */ + public void bad_code_in_code() { } +} diff --git a/langtools/test/tools/doclint/LiteralTest.out b/langtools/test/tools/doclint/LiteralTest.out new file mode 100644 index 00000000000..4cb41d9d7bb --- /dev/null +++ b/langtools/test/tools/doclint/LiteralTest.out @@ -0,0 +1,4 @@ +LiteralTest.java:14: warning: {@code} within + /** abc {@code < & > } def */ + ^ +1 warning From 6799149f7d1bc04933b07466043f471892808a7b Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Thu, 17 Jan 2013 11:39:48 +0100 Subject: [PATCH 111/204] 8006513: Null pointer in DefaultMethods::generate_default_methods when merging annotations Reviewed-by: brutisso, jfranck --- .../src/share/vm/classfile/defaultMethods.cpp | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/hotspot/src/share/vm/classfile/defaultMethods.cpp b/hotspot/src/share/vm/classfile/defaultMethods.cpp index ac593a7ef24..ce516b84bc1 100644 --- a/hotspot/src/share/vm/classfile/defaultMethods.cpp +++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp @@ -1285,13 +1285,15 @@ static void merge_in_new_methods(InstanceKlass* klass, enum { ANNOTATIONS, PARAMETERS, DEFAULTS, NUM_ARRAYS }; - Array* original_annots[NUM_ARRAYS]; + Array* original_annots[NUM_ARRAYS] = { NULL }; Array* original_methods = klass->methods(); Annotations* annots = klass->annotations(); - original_annots[ANNOTATIONS] = annots->methods_annotations(); - original_annots[PARAMETERS] = annots->methods_parameter_annotations(); - original_annots[DEFAULTS] = annots->methods_default_annotations(); + if (annots != NULL) { + original_annots[ANNOTATIONS] = annots->methods_annotations(); + original_annots[PARAMETERS] = annots->methods_parameter_annotations(); + original_annots[DEFAULTS] = annots->methods_default_annotations(); + } Array* original_ordering = klass->method_ordering(); Array* merged_ordering = Universe::the_empty_int_array(); @@ -1370,9 +1372,15 @@ static void merge_in_new_methods(InstanceKlass* klass, // Replace klass methods with new merged lists klass->set_methods(merged_methods); - annots->set_methods_annotations(merged_annots[ANNOTATIONS]); - annots->set_methods_parameter_annotations(merged_annots[PARAMETERS]); - annots->set_methods_default_annotations(merged_annots[DEFAULTS]); + if (annots != NULL) { + annots->set_methods_annotations(merged_annots[ANNOTATIONS]); + annots->set_methods_parameter_annotations(merged_annots[PARAMETERS]); + annots->set_methods_default_annotations(merged_annots[DEFAULTS]); + } else { + assert(merged_annots[ANNOTATIONS] == NULL, "Must be"); + assert(merged_annots[PARAMETERS] == NULL, "Must be"); + assert(merged_annots[DEFAULTS] == NULL, "Must be"); + } ClassLoaderData* cld = klass->class_loader_data(); MetadataFactory::free_array(cld, original_methods); From b7bcfe73b19eb6bcf7532f0c39b2506bc7c48c66 Mon Sep 17 00:00:00 2001 From: Konstantin Shefov Date: Thu, 17 Jan 2013 15:08:08 +0000 Subject: [PATCH 112/204] 7124209: [macosx] SpringLayout issue. BASELINE is not in the range: [NORTH, SOUTH] Reviewed-by: serb, alexsch --- .../SpringLayout/4726194/bug4726194.java | 161 ++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 jdk/test/javax/swing/SpringLayout/4726194/bug4726194.java diff --git a/jdk/test/javax/swing/SpringLayout/4726194/bug4726194.java b/jdk/test/javax/swing/SpringLayout/4726194/bug4726194.java new file mode 100644 index 00000000000..2516910e07c --- /dev/null +++ b/jdk/test/javax/swing/SpringLayout/4726194/bug4726194.java @@ -0,0 +1,161 @@ +/* + * 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. + */ + +/* + * @test + * @bug 4726194 7124209 + * @summary Tests for 4726194 + * @author Phil Milne + */ +import java.awt.*; +import java.lang.reflect.InvocationTargetException; +import java.util.*; +import java.util.List; +import javax.swing.*; + +public class bug4726194 { + + private static String[] hConstraints = {SpringLayout.WEST, "Width", SpringLayout.EAST, SpringLayout.HORIZONTAL_CENTER}; + private static String[] vConstraints = {SpringLayout.NORTH, "Height", SpringLayout.SOUTH, SpringLayout.VERTICAL_CENTER, SpringLayout.BASELINE}; + private static int[] FAIL = new int[3]; + private static boolean TEST_DUPLICATES = false; + + public static void main(String[] args) { + try { + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + int minLevel = 2; + int maxLevel = 2; + for (int i = minLevel; i <= maxLevel; i++) { + test(i, true); + test(i, false); + } + } + }); + } catch (InterruptedException | InvocationTargetException ex) { + ex.printStackTrace(); + throw new RuntimeException("FAILED: SwingUtilities.invokeAndWait method failed!"); + } + } + + public static void test(int level, boolean horizontal) { + List result = new ArrayList(); + String[] constraints = horizontal ? hConstraints : vConstraints; + test(level, constraints, result, Arrays.asList(new Object[level])); + JTextField tf = new JTextField(""); + tf.setFont(new Font("Dialog", Font.PLAIN, 6)); + System.out.print("\t\t"); + for (int j = 0; j < constraints.length; j++) { + String constraint = constraints[j]; + System.out.print(constraint + " ".substring(constraint.length())); + } + System.out.println(""); + for (int i = 0; i < result.size(); i++) { + SpringLayout.Constraints c = new SpringLayout.Constraints(tf); + List cc = (List) result.get(i); + for (int j = 0; j < cc.size(); j++) { + String constraint = (String) cc.get(j); + c.setConstraint(constraint, Spring.constant((j + 1) * 10)); + } + System.out.print(" Input:\t\t"); + for (int j = 0; j < constraints.length; j++) { + String constraint = constraints[j]; + int jj = cc.indexOf(constraint); + String val = cc.contains(constraint) ? Integer.toString((jj + 1) * 10) : "?"; + System.out.print(val + "\t\t"); + } + System.out.println(""); + System.out.print("Output:\t\t"); + for (int j = 0; j < constraints.length; j++) { + String constraint = constraints[j]; + Spring spring = c.getConstraint(constraint); + String springVal = (spring == null) ? "?" : Integer.toString(spring.getValue()); + System.out.print(springVal); + System.out.print("\t\t"); + } + for (int j = 0; j < cc.size(); j++) { + String constraint = (String) cc.get(j); + Spring con = c.getConstraint(constraint); + if (con == null || con.getValue() != (j + 1) * 10) { + throw new RuntimeException("Values are wrong!!! "); + } + } + if (horizontal) { + int[] a1 = getValues(c, new String[]{SpringLayout.WEST, SpringLayout.WIDTH, SpringLayout.EAST}); + if (a1[0] + a1[1] != a1[2]) { + throw new RuntimeException("WEST + WIDTH != EAST!!! "); + } + int[] a2 = getValues(c, new String[]{SpringLayout.WEST, SpringLayout.WIDTH, SpringLayout.HORIZONTAL_CENTER}); + if (a2[0] + a2[1] / 2 != a2[2]) { + throw new RuntimeException("WEST + WIDTH/2 != HORIZONTAL_CENTER!!! "); + } + } else { + int[] a3 = getValues(c, new String[]{SpringLayout.NORTH, SpringLayout.HEIGHT, SpringLayout.SOUTH}); + if (a3[0] + a3[1] != a3[2]) { + throw new RuntimeException("NORTH + HEIGHT != SOUTH!!! "); + } + int[] a4 = getValues(c, new String[]{SpringLayout.NORTH, SpringLayout.HEIGHT, SpringLayout.VERTICAL_CENTER}); + int vcDiff = Math.abs(a4[0] + a4[1] / 2 - a4[2]); + if (vcDiff > 1) { + throw new RuntimeException("NORTH + HEIGHT/2 != VERTICAL_CENTER!!! "); + } + int[] a5 = getValues(c, new String[]{SpringLayout.NORTH, SpringLayout.BASELINE, SpringLayout.SOUTH}); + if (a5[0] > a5[1] != a5[1] > a5[2]) { + throw new RuntimeException("BASELINE is not in the range: [NORTH, SOUTH]!!!"); + } + } + System.out.println(""); + } + System.out.println(""); + } + + private static int[] getValues(SpringLayout.Constraints con, String[] cNames) { + int[] result = new int[cNames.length]; + for (int i = 0; i < cNames.length; i++) { + String name = cNames[i]; + Spring s = con.getConstraint(name); + if (s == null) { + System.out.print("Warning: " + name + " is undefined. "); + return FAIL; + } + result[i] = s.getValue(); + } + return result; + } + + public static void test(int level, String[] constraints, List result, List soFar) { + if (level == 0) { + result.add(soFar); + return; + } + for (int i = 0; i < constraints.length; i++) { + if (soFar.contains(constraints[i]) && !TEST_DUPLICATES) { + continue; + } + List child = new ArrayList(soFar); + child.set(level - 1, constraints[i]); + test(level - 1, constraints, result, child); + } + } +} From 68f3dd76c92ce3b0219ac2cc346718dd865645d9 Mon Sep 17 00:00:00 2001 From: Harold Seigel Date: Thu, 17 Jan 2013 10:25:16 -0500 Subject: [PATCH 113/204] 7102489: RFE: cleanup jlong typedef on __APPLE__and _LLP64 systems Define jlong as long on all LP64 platforms and add JLONG_FORMAT macro. Reviewed-by: dholmes, coleenp, mikael, kvn --- hotspot/src/cpu/x86/vm/jni_x86.h | 9 ++------- hotspot/src/os/bsd/vm/os_bsd.inline.hpp | 10 +--------- hotspot/src/os/linux/vm/os_linux.inline.hpp | 10 +--------- hotspot/src/os/posix/launcher/java_md.c | 7 +------ hotspot/src/os/posix/launcher/java_md.h | 8 +++++++- hotspot/src/os/solaris/vm/os_solaris.inline.hpp | 5 +---- hotspot/src/os/windows/launcher/java_md.c | 7 +------ hotspot/src/os/windows/launcher/java_md.h | 4 +++- hotspot/src/os/windows/vm/os_windows.cpp | 8 ++++---- hotspot/src/os/windows/vm/os_windows.inline.hpp | 5 +---- hotspot/src/share/tools/launcher/java.c | 4 ++-- hotspot/src/share/tools/launcher/java.h | 3 +-- hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp | 4 ++-- hotspot/src/share/vm/c1/c1_LIR.cpp | 4 ++-- hotspot/src/share/vm/ci/ciReplay.cpp | 4 ++-- .../concurrentMarkSweep/compactibleFreeListSpace.cpp | 4 ++-- .../concurrentMarkSweepGeneration.cpp | 6 +++--- .../parallelScavenge/psScavenge.cpp | 4 ++-- .../share/vm/gc_implementation/shared/ageTable.cpp | 4 ++-- hotspot/src/share/vm/memory/universe.cpp | 4 ++-- hotspot/src/share/vm/opto/idealGraphPrinter.cpp | 4 ++-- hotspot/src/share/vm/opto/type.cpp | 12 ++++++------ hotspot/src/share/vm/runtime/aprofiler.cpp | 4 ++-- hotspot/src/share/vm/runtime/arguments.cpp | 4 ++-- hotspot/src/share/vm/runtime/os.hpp | 6 +----- hotspot/src/share/vm/runtime/perfData.cpp | 4 ++-- hotspot/src/share/vm/runtime/virtualspace.cpp | 6 +++--- hotspot/src/share/vm/services/diagnosticArgument.cpp | 6 +++--- hotspot/src/share/vm/services/heapDumper.cpp | 4 ++-- hotspot/src/share/vm/services/lowMemoryDetector.cpp | 4 ++-- hotspot/src/share/vm/utilities/globalDefinitions.hpp | 10 +++++++++- .../src/share/vm/utilities/globalDefinitions_gcc.hpp | 6 +++++- hotspot/src/share/vm/utilities/ostream.cpp | 8 +++----- hotspot/src/share/vm/utilities/taskqueue.cpp | 6 +++--- 34 files changed, 87 insertions(+), 111 deletions(-) diff --git a/hotspot/src/cpu/x86/vm/jni_x86.h b/hotspot/src/cpu/x86/vm/jni_x86.h index d724c86007a..2cd7abd304e 100644 --- a/hotspot/src/cpu/x86/vm/jni_x86.h +++ b/hotspot/src/cpu/x86/vm/jni_x86.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -38,14 +38,9 @@ #define JNICALL typedef int jint; -#if defined(_LP64) && !defined(__APPLE__) +#if defined(_LP64) typedef long jlong; #else - /* - * On _LP64 __APPLE__ "long" and "long long" are both 64 bits, - * but we use the "long long" typedef to avoid complaints from - * the __APPLE__ compiler about fprintf formats. - */ typedef long long jlong; #endif diff --git a/hotspot/src/os/bsd/vm/os_bsd.inline.hpp b/hotspot/src/os/bsd/vm/os_bsd.inline.hpp index 6a7cdc08b5f..8fc3c2b0878 100644 --- a/hotspot/src/os/bsd/vm/os_bsd.inline.hpp +++ b/hotspot/src/os/bsd/vm/os_bsd.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -59,14 +59,6 @@ inline const char* os::path_separator() { return ":"; } -inline const char* os::jlong_format_specifier() { - return "%lld"; -} - -inline const char* os::julong_format_specifier() { - return "%llu"; -} - // File names are case-sensitive on windows only inline int os::file_name_strcmp(const char* s1, const char* s2) { return strcmp(s1, s2); diff --git a/hotspot/src/os/linux/vm/os_linux.inline.hpp b/hotspot/src/os/linux/vm/os_linux.inline.hpp index c779f8a6aa5..3a8d8d97d9b 100644 --- a/hotspot/src/os/linux/vm/os_linux.inline.hpp +++ b/hotspot/src/os/linux/vm/os_linux.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -68,14 +68,6 @@ inline const char* os::path_separator() { return ":"; } -inline const char* os::jlong_format_specifier() { - return "%lld"; -} - -inline const char* os::julong_format_specifier() { - return "%llu"; -} - // File names are case-sensitive on windows only inline int os::file_name_strcmp(const char* s1, const char* s2) { return strcmp(s1, s2); diff --git a/hotspot/src/os/posix/launcher/java_md.c b/hotspot/src/os/posix/launcher/java_md.c index 970222c4fd3..b5fc949813c 100644 --- a/hotspot/src/os/posix/launcher/java_md.c +++ b/hotspot/src/os/posix/launcher/java_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -1876,11 +1876,6 @@ void SplashFreeLibrary() { } } -const char * -jlong_format_specifier() { - return "%lld"; -} - /* * Block current thread and continue execution in a new thread */ diff --git a/hotspot/src/os/posix/launcher/java_md.h b/hotspot/src/os/posix/launcher/java_md.h index ed36fd1af67..63c449a2926 100644 --- a/hotspot/src/os/posix/launcher/java_md.h +++ b/hotspot/src/os/posix/launcher/java_md.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -64,6 +64,12 @@ #define Counter2Micros(counts) (1) #endif /* HAVE_GETHRTIME */ +#ifdef _LP64 +#define JLONG_FORMAT "%ld" +#else +#define JLONG_FORMAT "%lld" +#endif + /* * Function prototypes. */ diff --git a/hotspot/src/os/solaris/vm/os_solaris.inline.hpp b/hotspot/src/os/solaris/vm/os_solaris.inline.hpp index a3f09d01d32..61691fd384a 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.inline.hpp +++ b/hotspot/src/os/solaris/vm/os_solaris.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -50,9 +50,6 @@ inline const char* os::file_separator() { return "/"; } inline const char* os::line_separator() { return "\n"; } inline const char* os::path_separator() { return ":"; } -inline const char* os::jlong_format_specifier() { return "%lld"; } -inline const char* os::julong_format_specifier() { return "%llu"; } - // File names are case-sensitive on windows only inline int os::file_name_strcmp(const char* s1, const char* s2) { return strcmp(s1, s2); diff --git a/hotspot/src/os/windows/launcher/java_md.c b/hotspot/src/os/windows/launcher/java_md.c index 2fde40ad205..3e28755009c 100644 --- a/hotspot/src/os/windows/launcher/java_md.c +++ b/hotspot/src/os/windows/launcher/java_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -1323,11 +1323,6 @@ void SplashFreeLibrary() { } } -const char * -jlong_format_specifier() { - return "%I64d"; -} - /* * Block current thread and continue execution in a new thread */ diff --git a/hotspot/src/os/windows/launcher/java_md.h b/hotspot/src/os/windows/launcher/java_md.h index 111be1ee13a..763e2457644 100644 --- a/hotspot/src/os/windows/launcher/java_md.h +++ b/hotspot/src/os/windows/launcher/java_md.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -69,6 +69,8 @@ extern jlong Counter2Micros(jlong counts); extern int _main(int argc, char **argv); #endif +#define JLONG_FORMAT "%I64d" + /* * Function prototypes. */ diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index b8498d5a1e2..a10b83f8940 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -2946,7 +2946,7 @@ char* os::pd_reserve_memory(size_t bytes, char* addr, size_t alignment_hint) { } if( Verbose && PrintMiscellaneous ) { reserveTimer.stop(); - tty->print_cr("reserve_memory of %Ix bytes took %ld ms (%ld ticks)", bytes, + tty->print_cr("reserve_memory of %Ix bytes took " JLONG_FORMAT " ms (" JLONG_FORMAT " ticks)", bytes, reserveTimer.milliseconds(), reserveTimer.ticks()); } } @@ -4305,7 +4305,7 @@ char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset, if (hFile == NULL) { if (PrintMiscellaneous && Verbose) { DWORD err = GetLastError(); - tty->print_cr("CreateFile() failed: GetLastError->%ld."); + tty->print_cr("CreateFile() failed: GetLastError->%ld.", err); } return NULL; } @@ -4355,7 +4355,7 @@ char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset, if (hMap == NULL) { if (PrintMiscellaneous && Verbose) { DWORD err = GetLastError(); - tty->print_cr("CreateFileMapping() failed: GetLastError->%ld."); + tty->print_cr("CreateFileMapping() failed: GetLastError->%ld.", err); } CloseHandle(hFile); return NULL; diff --git a/hotspot/src/os/windows/vm/os_windows.inline.hpp b/hotspot/src/os/windows/vm/os_windows.inline.hpp index 8f8c3c72fd2..1df8694d9dd 100644 --- a/hotspot/src/os/windows/vm/os_windows.inline.hpp +++ b/hotspot/src/os/windows/vm/os_windows.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -38,9 +38,6 @@ inline const char* os::line_separator() { return "\r\n"; } inline const char* os::path_separator() { return ";"; } inline const char* os::dll_file_extension() { return ".dll"; } -inline const char* os::jlong_format_specifier() { return "%I64d"; } -inline const char* os::julong_format_specifier() { return "%I64u"; } - inline const int os::default_file_open_flags() { return O_BINARY | O_NOINHERIT;} // File names are case-insensitive on windows only diff --git a/hotspot/src/share/tools/launcher/java.c b/hotspot/src/share/tools/launcher/java.c index 5ebfb9a8dc3..63f11d77c86 100644 --- a/hotspot/src/share/tools/launcher/java.c +++ b/hotspot/src/share/tools/launcher/java.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -808,7 +808,7 @@ CheckJvmType(int *pargc, char ***argv, jboolean speculative) { static int parse_stack_size(const char *s, jlong *result) { jlong n = 0; - int args_read = sscanf(s, jlong_format_specifier(), &n); + int args_read = sscanf(s, JLONG_FORMAT, &n); if (args_read != 1) { return 0; } diff --git a/hotspot/src/share/tools/launcher/java.h b/hotspot/src/share/tools/launcher/java.h index 97fba2184f7..1dd79618c84 100644 --- a/hotspot/src/share/tools/launcher/java.h +++ b/hotspot/src/share/tools/launcher/java.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -86,7 +86,6 @@ void ReportExceptionDescription(JNIEnv * env); jboolean RemovableMachineDependentOption(char * option); void PrintMachineDependentOptions(); -const char *jlong_format_specifier(); /* * Block current thread and continue execution in new thread */ diff --git a/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp b/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp index a2f6f86fd85..68e0feb5b83 100644 --- a/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp +++ b/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -360,7 +360,7 @@ void InstructionPrinter::do_Constant(Constant* x) { ValueType* t = x->type(); switch (t->tag()) { case intTag : output()->print("%d" , t->as_IntConstant ()->value()); break; - case longTag : output()->print(os::jlong_format_specifier(), t->as_LongConstant()->value()); output()->print("L"); break; + case longTag : output()->print(JLONG_FORMAT, t->as_LongConstant()->value()); output()->print("L"); break; case floatTag : output()->print("%g" , t->as_FloatConstant ()->value()); break; case doubleTag : output()->print("%gD" , t->as_DoubleConstant()->value()); break; case objectTag : print_object(x); break; diff --git a/hotspot/src/share/vm/c1/c1_LIR.cpp b/hotspot/src/share/vm/c1/c1_LIR.cpp index 178d1867179..7a0563c6a20 100644 --- a/hotspot/src/share/vm/c1/c1_LIR.cpp +++ b/hotspot/src/share/vm/c1/c1_LIR.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, 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 @@ -1563,7 +1563,7 @@ void LIR_Const::print_value_on(outputStream* out) const { switch (type()) { case T_ADDRESS:out->print("address:%d",as_jint()); break; case T_INT: out->print("int:%d", as_jint()); break; - case T_LONG: out->print("lng:%lld", as_jlong()); break; + case T_LONG: out->print("lng:" JLONG_FORMAT, as_jlong()); break; case T_FLOAT: out->print("flt:%f", as_jfloat()); break; case T_DOUBLE: out->print("dbl:%f", as_jdouble()); break; case T_OBJECT: out->print("obj:0x%x", as_jobject()); break; diff --git a/hotspot/src/share/vm/ci/ciReplay.cpp b/hotspot/src/share/vm/ci/ciReplay.cpp index f2e77241960..9b532b8e26b 100644 --- a/hotspot/src/share/vm/ci/ciReplay.cpp +++ b/hotspot/src/share/vm/ci/ciReplay.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2013, 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 @@ -645,7 +645,7 @@ class CompileReplay : public StackObj { java_mirror->bool_field_put(fd.offset(), value); } else if (strcmp(field_signature, "J") == 0) { jlong value; - if (sscanf(string_value, INT64_FORMAT, &value) != 1) { + if (sscanf(string_value, JLONG_FORMAT, &value) != 1) { fprintf(stderr, "Error parsing long: %s\n", string_value); return; } diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp index 2f43c987669..9fb347a05c5 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -555,7 +555,7 @@ void CompactibleFreeListSpace::reportFreeListStatistics() const { reportIndexedFreeListStatistics(); size_t total_size = totalSizeInIndexedFreeLists() + _dictionary->total_chunk_size(DEBUG_ONLY(freelistLock())); - gclog_or_tty->print(" free=%ld frag=%1.4f\n", total_size, flsFrag()); + gclog_or_tty->print(" free=" SIZE_FORMAT " frag=%1.4f\n", total_size, flsFrag()); } } diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp index 475f2b8fee1..2ed7e465ad0 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -3338,7 +3338,7 @@ bool ConcurrentMarkSweepGeneration::grow_by(size_t bytes) { if (Verbose && PrintGC) { size_t new_mem_size = _virtual_space.committed_size(); size_t old_mem_size = new_mem_size - bytes; - gclog_or_tty->print_cr("Expanding %s from %ldK by %ldK to %ldK", + gclog_or_tty->print_cr("Expanding %s from " SIZE_FORMAT "K by " SIZE_FORMAT "K to " SIZE_FORMAT "K", name(), old_mem_size/K, bytes/K, new_mem_size/K); } } @@ -9203,7 +9203,7 @@ void ASConcurrentMarkSweepGeneration::shrink_by(size_t desired_bytes) { if (Verbose && PrintGCDetails) { size_t new_mem_size = _virtual_space.committed_size(); size_t old_mem_size = new_mem_size + bytes; - gclog_or_tty->print_cr("Shrinking %s from %ldK by %ldK to %ldK", + gclog_or_tty->print_cr("Shrinking %s from " SIZE_FORMAT "K by " SIZE_FORMAT "K to " SIZE_FORMAT "K", name(), old_mem_size/K, bytes/K, new_mem_size/K); } } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp index f68b1b5a446..078bd62aff7 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2013, 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 @@ -529,7 +529,7 @@ bool PSScavenge::invoke_no_policy() { if (PrintTenuringDistribution) { gclog_or_tty->cr(); - gclog_or_tty->print_cr("Desired survivor size %ld bytes, new threshold %u (max %u)", + gclog_or_tty->print_cr("Desired survivor size " SIZE_FORMAT " bytes, new threshold %u (max %u)", size_policy->calculated_survivor_size_in_bytes(), _tenuring_threshold, MaxTenuringThreshold); } diff --git a/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp b/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp index 50162a0adb1..311fd7771dd 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -96,7 +96,7 @@ uint ageTable::compute_tenuring_threshold(size_t survivor_capacity) { if (PrintTenuringDistribution) { gclog_or_tty->cr(); - gclog_or_tty->print_cr("Desired survivor size %ld bytes, new threshold %u (max %u)", + gclog_or_tty->print_cr("Desired survivor size " SIZE_FORMAT " bytes, new threshold %u (max %u)", desired_survivor_size*oopSize, result, MaxTenuringThreshold); } diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp index c528d270c64..c9199228cb9 100644 --- a/hotspot/src/share/vm/memory/universe.cpp +++ b/hotspot/src/share/vm/memory/universe.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -228,7 +228,7 @@ void Universe::check_alignment(uintx size, uintx alignment, const char* name) { if (size < alignment || size % alignment != 0) { ResourceMark rm; stringStream st; - st.print("Size of %s (%ld bytes) must be aligned to %ld bytes", name, size, alignment); + st.print("Size of %s (" UINTX_FORMAT " bytes) must be aligned to " UINTX_FORMAT " bytes", name, size, alignment); char* error = st.as_string(); vm_exit_during_initialization(error); } diff --git a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp index 0928704d9cb..1f811b8f4b8 100644 --- a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp +++ b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2013, 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 @@ -547,7 +547,7 @@ void IdealGraphPrinter::visit_node(Node *n, bool edges, VectorSet* temp_set) { // max. 2 chars allowed if (value >= -9 && value <= 99) { - sprintf(buffer, INT64_FORMAT, value); + sprintf(buffer, JLONG_FORMAT, value); print_prop(short_name, buffer); } else { print_prop(short_name, "L"); diff --git a/hotspot/src/share/vm/opto/type.cpp b/hotspot/src/share/vm/opto/type.cpp index 1a8ee2597dd..3928c23aff3 100644 --- a/hotspot/src/share/vm/opto/type.cpp +++ b/hotspot/src/share/vm/opto/type.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -1542,10 +1542,10 @@ bool TypeLong::is_finite() const { static const char* longnamenear(jlong x, const char* xname, char* buf, jlong n) { if (n > x) { if (n >= x + 10000) return NULL; - sprintf(buf, "%s+" INT64_FORMAT, xname, n - x); + sprintf(buf, "%s+" JLONG_FORMAT, xname, n - x); } else if (n < x) { if (n <= x - 10000) return NULL; - sprintf(buf, "%s-" INT64_FORMAT, xname, x - n); + sprintf(buf, "%s-" JLONG_FORMAT, xname, x - n); } else { return xname; } @@ -1557,11 +1557,11 @@ static const char* longname(char* buf, jlong n) { if (n == min_jlong) return "min"; else if (n < min_jlong + 10000) - sprintf(buf, "min+" INT64_FORMAT, n - min_jlong); + sprintf(buf, "min+" JLONG_FORMAT, n - min_jlong); else if (n == max_jlong) return "max"; else if (n > max_jlong - 10000) - sprintf(buf, "max-" INT64_FORMAT, max_jlong - n); + sprintf(buf, "max-" JLONG_FORMAT, max_jlong - n); else if ((str = longnamenear(max_juint, "maxuint", buf, n)) != NULL) return str; else if ((str = longnamenear(max_jint, "maxint", buf, n)) != NULL) @@ -1569,7 +1569,7 @@ static const char* longname(char* buf, jlong n) { else if ((str = longnamenear(min_jint, "minint", buf, n)) != NULL) return str; else - sprintf(buf, INT64_FORMAT, n); + sprintf(buf, JLONG_FORMAT, n); return buf; } diff --git a/hotspot/src/share/vm/runtime/aprofiler.cpp b/hotspot/src/share/vm/runtime/aprofiler.cpp index 6c4e9cc428d..e71bfb587ef 100644 --- a/hotspot/src/share/vm/runtime/aprofiler.cpp +++ b/hotspot/src/share/vm/runtime/aprofiler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -129,7 +129,7 @@ void AllocationProfiler::print(size_t cutoff) { assert(!is_active(), "AllocationProfiler cannot be active while printing profile"); tty->cr(); - tty->print_cr("Allocation profile (sizes in bytes, cutoff = %ld bytes):", cutoff * BytesPerWord); + tty->print_cr("Allocation profile (sizes in bytes, cutoff = " SIZE_FORMAT " bytes):", cutoff * BytesPerWord); tty->cr(); // Print regular instance klasses and basic type array klasses diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 65f6e03b7ff..d5d700441df 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -532,7 +532,7 @@ char* SysClassPath::add_jars_to_path(char* path, const char* directory) { // Parses a memory size specification string. static bool atomull(const char *s, julong* result) { julong n = 0; - int args_read = sscanf(s, os::julong_format_specifier(), &n); + int args_read = sscanf(s, JULONG_FORMAT, &n); if (args_read != 1) { return false; } diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp index 235005f9890..d061a0848c6 100644 --- a/hotspot/src/share/vm/runtime/os.hpp +++ b/hotspot/src/share/vm/runtime/os.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -641,10 +641,6 @@ class os: AllStatic { static struct hostent* get_host_by_name(char* name); - // Printing 64 bit integers - static const char* jlong_format_specifier(); - static const char* julong_format_specifier(); - // Support for signals (see JVM_RaiseSignal, JVM_RegisterSignal) static void signal_init(); static void signal_init_pd(); diff --git a/hotspot/src/share/vm/runtime/perfData.cpp b/hotspot/src/share/vm/runtime/perfData.cpp index ddb565b074c..777ea27f906 100644 --- a/hotspot/src/share/vm/runtime/perfData.cpp +++ b/hotspot/src/share/vm/runtime/perfData.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -192,7 +192,7 @@ PerfLong::PerfLong(CounterNS ns, const char* namep, Units u, Variability v) } int PerfLong::format(char* buffer, int length) { - return jio_snprintf(buffer, length,"%lld", *(jlong*)_valuep); + return jio_snprintf(buffer, length, JLONG_FORMAT, *(jlong*)_valuep); } PerfLongVariant::PerfLongVariant(CounterNS ns, const char* namep, Units u, diff --git a/hotspot/src/share/vm/runtime/virtualspace.cpp b/hotspot/src/share/vm/runtime/virtualspace.cpp index f33c1995e34..dffb588dbae 100644 --- a/hotspot/src/share/vm/runtime/virtualspace.cpp +++ b/hotspot/src/share/vm/runtime/virtualspace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -868,8 +868,8 @@ void VirtualSpace::print() { tty->print ("Virtual space:"); if (special()) tty->print(" (pinned in memory)"); tty->cr(); - tty->print_cr(" - committed: %ld", committed_size()); - tty->print_cr(" - reserved: %ld", reserved_size()); + tty->print_cr(" - committed: " SIZE_FORMAT, committed_size()); + tty->print_cr(" - reserved: " SIZE_FORMAT, reserved_size()); tty->print_cr(" - [low, high]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low(), high()); tty->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low_boundary(), high_boundary()); } diff --git a/hotspot/src/share/vm/services/diagnosticArgument.cpp b/hotspot/src/share/vm/services/diagnosticArgument.cpp index 23267fae520..5d0eb756b28 100644 --- a/hotspot/src/share/vm/services/diagnosticArgument.cpp +++ b/hotspot/src/share/vm/services/diagnosticArgument.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013 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 @@ -86,7 +86,7 @@ void GenDCmdArgument::to_string(StringArrayArgument* f, char* buf, size_t len) { template <> void DCmdArgument::parse_value(const char* str, size_t len, TRAPS) { - if (str == NULL || sscanf(str, INT64_FORMAT, &_value) != 1) { + if (str == NULL || sscanf(str, JLONG_FORMAT, &_value) != 1) { THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Integer parsing error in diagnostic command arguments\n"); } @@ -171,7 +171,7 @@ template <> void DCmdArgument::parse_value(const char* str, "Integer parsing error nanotime value: syntax error"); } - int argc = sscanf(str, INT64_FORMAT , &_value._time); + int argc = sscanf(str, JLONG_FORMAT, &_value._time); if (argc != 1) { THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Integer parsing error nanotime value: syntax error"); diff --git a/hotspot/src/share/vm/services/heapDumper.cpp b/hotspot/src/share/vm/services/heapDumper.cpp index 0dbe2e86589..65ee27f457a 100644 --- a/hotspot/src/share/vm/services/heapDumper.cpp +++ b/hotspot/src/share/vm/services/heapDumper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -1866,7 +1866,7 @@ int HeapDumper::dump(const char* path) { if (error() == NULL) { char msg[256]; sprintf(msg, "Heap dump file created [%s bytes in %3.3f secs]", - os::jlong_format_specifier(), timer()->seconds()); + JLONG_FORMAT, timer()->seconds()); tty->print_cr(msg, writer.bytes_written()); } else { tty->print_cr("Dump file is incomplete: %s", writer.error()); diff --git a/hotspot/src/share/vm/services/lowMemoryDetector.cpp b/hotspot/src/share/vm/services/lowMemoryDetector.cpp index babd93ac85b..199a342dd77 100644 --- a/hotspot/src/share/vm/services/lowMemoryDetector.cpp +++ b/hotspot/src/share/vm/services/lowMemoryDetector.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -353,7 +353,7 @@ void SensorInfo::clear(int count, TRAPS) { #ifndef PRODUCT void SensorInfo::print() { - tty->print_cr("%s count = %ld pending_triggers = %ld pending_clears = %ld", + tty->print_cr("%s count = " SIZE_FORMAT " pending_triggers = %ld pending_clears = %ld", (_sensor_on ? "on" : "off"), _sensor_count, _pending_trigger_count, _pending_clear_count); } diff --git a/hotspot/src/share/vm/utilities/globalDefinitions.hpp b/hotspot/src/share/vm/utilities/globalDefinitions.hpp index e00be90320e..5c10cf018be 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp +++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -1250,6 +1250,14 @@ inline int build_int_from_shorts( jushort low, jushort high ) { #define PTR64_FORMAT "0x%016" PRIx64 +// Format jlong, if necessary +#ifndef JLONG_FORMAT +#define JLONG_FORMAT INT64_FORMAT +#endif +#ifndef JULONG_FORMAT +#define JULONG_FORMAT UINT64_FORMAT +#endif + // Format pointers which change size between 32- and 64-bit. #ifdef _LP64 #define INTPTR_FORMAT "0x%016" PRIxPTR diff --git a/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp b/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp index e103816de93..a69708f8c8f 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp +++ b/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, 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 @@ -306,4 +306,8 @@ inline int wcslen(const jchar* x) { return wcslen((const wchar_t*)x); } #endif #define offsetof(klass,field) offset_of(klass,field) +#if defined(_LP64) && defined(__APPLE__) +#define JLONG_FORMAT "%ld" +#endif // _LP64 && __APPLE__ + #endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_GCC_HPP diff --git a/hotspot/src/share/vm/utilities/ostream.cpp b/hotspot/src/share/vm/utilities/ostream.cpp index 2b6e2eeb853..ea0a0c25bec 100644 --- a/hotspot/src/share/vm/utilities/ostream.cpp +++ b/hotspot/src/share/vm/utilities/ostream.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -243,13 +243,11 @@ outputStream& outputStream::indent() { } void outputStream::print_jlong(jlong value) { - // N.B. Same as INT64_FORMAT - print(os::jlong_format_specifier(), value); + print(JLONG_FORMAT, value); } void outputStream::print_julong(julong value) { - // N.B. Same as UINT64_FORMAT - print(os::julong_format_specifier(), value); + print(JULONG_FORMAT, value); } /** diff --git a/hotspot/src/share/vm/utilities/taskqueue.cpp b/hotspot/src/share/vm/utilities/taskqueue.cpp index fbb035adf0c..862c9b304fb 100644 --- a/hotspot/src/share/vm/utilities/taskqueue.cpp +++ b/hotspot/src/share/vm/utilities/taskqueue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -239,8 +239,8 @@ ParallelTaskTerminator::offer_termination(TerminatorTerminator* terminator) { #ifdef TRACESPINNING void ParallelTaskTerminator::print_termination_counts() { - gclog_or_tty->print_cr("ParallelTaskTerminator Total yields: %lld " - "Total spins: %lld Total peeks: %lld", + gclog_or_tty->print_cr("ParallelTaskTerminator Total yields: " UINT32_FORMAT + " Total spins: " UINT32_FORMAT " Total peeks: " UINT32_FORMAT, total_yields(), total_spins(), total_peeks()); From 0a95b1d28c920504ef3323e356a6338e388575b2 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Thu, 17 Jan 2013 18:15:20 +0000 Subject: [PATCH 114/204] 8005852: Treatment of '_' as identifier Warn when '_' is found in an identifier position Reviewed-by: jjg --- .../sun/tools/javac/parser/JavacParser.java | 137 ++++++++++-------- .../com/sun/tools/javac/parser/Tokens.java | 10 +- .../tools/javac/resources/compiler.properties | 4 + .../tools/javac/lambda/LambdaParserTest.java | 78 ++++++---- 4 files changed, 137 insertions(+), 92 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java index 28f6d8a29eb..a44f9c310bf 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java @@ -245,40 +245,42 @@ public class JavacParser implements Parser { token = S.token(); } - protected boolean peekToken(TokenKind tk) { + protected boolean peekToken(Filter tk) { return peekToken(0, tk); } - protected boolean peekToken(int lookahead, TokenKind tk) { - return S.token(lookahead + 1).kind == tk; + protected boolean peekToken(int lookahead, Filter tk) { + return tk.accepts(S.token(lookahead + 1).kind); } - protected boolean peekToken(TokenKind tk1, TokenKind tk2) { + protected boolean peekToken(Filter tk1, Filter tk2) { return peekToken(0, tk1, tk2); } - protected boolean peekToken(int lookahead, TokenKind tk1, TokenKind tk2) { - return S.token(lookahead + 1).kind == tk1 && - S.token(lookahead + 2).kind == tk2; + protected boolean peekToken(int lookahead, Filter tk1, Filter tk2) { + return tk1.accepts(S.token(lookahead + 1).kind) && + tk2.accepts(S.token(lookahead + 2).kind); } - protected boolean peekToken(TokenKind tk1, TokenKind tk2, TokenKind tk3) { + protected boolean peekToken(Filter tk1, Filter tk2, Filter tk3) { return peekToken(0, tk1, tk2, tk3); } - protected boolean peekToken(int lookahead, TokenKind tk1, TokenKind tk2, TokenKind tk3) { - return S.token(lookahead + 1).kind == tk1 && - S.token(lookahead + 2).kind == tk2 && - S.token(lookahead + 3).kind == tk3; + protected boolean peekToken(int lookahead, Filter tk1, Filter tk2, Filter tk3) { + return tk1.accepts(S.token(lookahead + 1).kind) && + tk2.accepts(S.token(lookahead + 2).kind) && + tk3.accepts(S.token(lookahead + 3).kind); } - protected boolean peekToken(TokenKind... kinds) { + @SuppressWarnings("unchecked") + protected boolean peekToken(Filter... kinds) { return peekToken(0, kinds); } - protected boolean peekToken(int lookahead, TokenKind... kinds) { + @SuppressWarnings("unchecked") + protected boolean peekToken(int lookahead, Filter... kinds) { for (; lookahead < kinds.length ; lookahead++) { - if (S.token(lookahead + 1).kind != kinds[lookahead]) { + if (!kinds[lookahead].accepts(S.token(lookahead + 1).kind)) { return false; } } @@ -333,6 +335,7 @@ public class JavacParser implements Parser { if (stopAtMemberDecl) return; break; + case UNDERSCORE: case IDENTIFIER: if (stopAtIdentifier) return; @@ -552,11 +555,16 @@ public class JavacParser implements Parser { nextToken(); return name; } + } else if (token.kind == UNDERSCORE) { + warning(token.pos, "underscore.as.identifier"); + Name name = token.name(); + nextToken(); + return name; } else { accept(IDENTIFIER); return names.error; } -} + } /** * Qualident = Ident { DOT Ident } @@ -1056,7 +1064,7 @@ public class JavacParser implements Parser { typeArgs = null; } else return illegal(); break; - case IDENTIFIER: case ASSERT: case ENUM: + case UNDERSCORE: case IDENTIFIER: case ASSERT: case ENUM: if (typeArgs != null) return illegal(); if ((mode & EXPR) != 0 && peekToken(ARROW)) { t = lambdaExpressionOrStatement(false, false, pos); @@ -1274,7 +1282,7 @@ public class JavacParser implements Parser { int pos = 0, depth = 0; for (Token t = S.token(pos) ; ; t = S.token(++pos)) { switch (t.kind) { - case IDENTIFIER: case QUES: case EXTENDS: case SUPER: + case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER: case DOT: case RBRACKET: case LBRACKET: case COMMA: case BYTE: case SHORT: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case CHAR: @@ -1323,8 +1331,8 @@ public class JavacParser implements Parser { if (peekToken(lookahead, RPAREN)) { //Type, ')' -> cast return ParensResult.CAST; - } else if (peekToken(lookahead, IDENTIFIER)) { - //Type, 'Identifier -> explicit lambda + } else if (peekToken(lookahead, LAX_IDENTIFIER)) { + //Type, Identifier/'_'/'assert'/'enum' -> explicit lambda return ParensResult.EXPLICIT_LAMBDA; } break; @@ -1350,16 +1358,19 @@ public class JavacParser implements Parser { case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL: case TRUE: case FALSE: case NULL: - case NEW: case IDENTIFIER: case ASSERT: case ENUM: + case NEW: case IDENTIFIER: case ASSERT: case ENUM: case UNDERSCORE: case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID: return ParensResult.CAST; default: return ParensResult.PARENS; } + case UNDERSCORE: + case ASSERT: + case ENUM: case IDENTIFIER: - if (peekToken(lookahead, IDENTIFIER)) { - // Identifier, Identifier -> explicit lambda + if (peekToken(lookahead, LAX_IDENTIFIER)) { + // Identifier, Identifier/'_'/'assert'/'enum' -> explicit lambda return ParensResult.EXPLICIT_LAMBDA; } else if (peekToken(lookahead, RPAREN, ARROW)) { // Identifier, ')' '->' -> implicit lambda @@ -1372,8 +1383,8 @@ public class JavacParser implements Parser { //those can only appear in explicit lambdas return ParensResult.EXPLICIT_LAMBDA; case LBRACKET: - if (peekToken(lookahead, RBRACKET, IDENTIFIER)) { - // '[', ']', Identifier -> explicit lambda + if (peekToken(lookahead, RBRACKET, LAX_IDENTIFIER)) { + // '[', ']', Identifier/'_'/'assert'/'enum' -> explicit lambda return ParensResult.EXPLICIT_LAMBDA; } else if (peekToken(lookahead, RBRACKET, RPAREN) || peekToken(lookahead, RBRACKET, AMP)) { @@ -1402,11 +1413,11 @@ public class JavacParser implements Parser { // '>', ')' -> cast // '>', '&' -> cast return ParensResult.CAST; - } else if (peekToken(lookahead, IDENTIFIER, COMMA) || - peekToken(lookahead, IDENTIFIER, RPAREN, ARROW) || + } else if (peekToken(lookahead, LAX_IDENTIFIER, COMMA) || + peekToken(lookahead, LAX_IDENTIFIER, RPAREN, ARROW) || peekToken(lookahead, ELLIPSIS)) { - // '>', Identifier, ',' -> explicit lambda - // '>', Identifier, ')', '->' -> explicit lambda + // '>', Identifier/'_'/'assert'/'enum', ',' -> explicit lambda + // '>', Identifier/'_'/'assert'/'enum', ')', '->' -> explicit lambda // '>', '...' -> explicit lambda return ParensResult.EXPLICIT_LAMBDA; } @@ -1426,6 +1437,13 @@ public class JavacParser implements Parser { } } + /** Accepts all identifier-like tokens */ + Filter LAX_IDENTIFIER = new Filter() { + public boolean accepts(TokenKind t) { + return t == IDENTIFIER || t == UNDERSCORE || t == ASSERT || t == ENUM; + } + }; + enum ParensResult { CAST, EXPLICIT_LAMBDA, @@ -1433,21 +1451,9 @@ public class JavacParser implements Parser { PARENS; } - JCExpression lambdaExpressionOrStatement(JCVariableDecl firstParam, int pos) { - ListBuffer params = new ListBuffer(); - params.append(firstParam); - JCVariableDecl lastParam = firstParam; - while ((lastParam.mods.flags & Flags.VARARGS) == 0 && token.kind == COMMA) { - nextToken(); - params.append(lastParam = formalParameter()); - } - accept(RPAREN); - return lambdaExpressionOrStatementRest(params.toList(), pos); - } - JCExpression lambdaExpressionOrStatement(boolean hasParens, boolean explicitParams, int pos) { List params = explicitParams ? - formalParameters() : + formalParameters(true) : implicitParameters(hasParens); return lambdaExpressionOrStatementRest(params, pos); @@ -1628,7 +1634,7 @@ public class JavacParser implements Parser { nextToken(); JCExpression bound = parseType(); return F.at(pos).Wildcard(t, bound); - } else if (token.kind == IDENTIFIER) { + } else if (LAX_IDENTIFIER.accepts(token.kind)) { //error recovery TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND); JCExpression wc = toP(F.at(pos).Wildcard(t, null)); @@ -1678,7 +1684,7 @@ public class JavacParser implements Parser { if (token.pos == endPosTable.errorEndPos) { // error recovery Name name = null; - if (token.kind == IDENTIFIER) { + if (LAX_IDENTIFIER.accepts(token.kind)) { name = token.name(); nextToken(); } else { @@ -2026,10 +2032,7 @@ public class JavacParser implements Parser { nextToken(); JCStatement stat = parseStatement(); return List.of(F.at(pos).Labelled(prevToken.name(), stat)); - } else if ((lastmode & TYPE) != 0 && - (token.kind == IDENTIFIER || - token.kind == ASSERT || - token.kind == ENUM)) { + } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) { pos = token.pos; JCModifiers mods = F.at(Position.NOPOS).Modifiers(0); F.at(pos); @@ -2183,14 +2186,14 @@ public class JavacParser implements Parser { } case BREAK: { nextToken(); - Name label = (token.kind == IDENTIFIER || token.kind == ASSERT || token.kind == ENUM) ? ident() : null; + Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null; JCBreak t = to(F.at(pos).Break(label)); accept(SEMI); return t; } case CONTINUE: { nextToken(); - Name label = (token.kind == IDENTIFIER || token.kind == ASSERT || token.kind == ENUM) ? ident() : null; + Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null; JCContinue t = to(F.at(pos).Continue(label)); accept(SEMI); return t; @@ -2351,9 +2354,7 @@ public class JavacParser implements Parser { return variableDeclarators(optFinal(0), parseType(), stats).toList(); } else { JCExpression t = term(EXPR | TYPE); - if ((lastmode & TYPE) != 0 && - (token.kind == IDENTIFIER || token.kind == ASSERT || - token.kind == ENUM)) { + if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) { return variableDeclarators(modifiersOpt(), t, stats).toList(); } else if ((lastmode & TYPE) != 0 && token.kind == COLON) { error(pos, "bad.initializer", "for-loop"); @@ -2609,8 +2610,18 @@ public class JavacParser implements Parser { /** VariableDeclaratorId = Ident BracketsOpt */ JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) { + return variableDeclaratorId(mods, type, false); + } + //where + JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean lambdaParameter) { int pos = token.pos; - Name name = ident(); + Name name; + if (lambdaParameter && token.kind == UNDERSCORE) { + syntaxError(pos, "expected", IDENTIFIER); + name = token.name(); + } else { + name = ident(); + } if ((mods.flags & Flags.VARARGS) != 0 && token.kind == LBRACKET) { log.error(token.pos, "varargs.and.old.array.syntax"); @@ -2770,7 +2781,7 @@ public class JavacParser implements Parser { } else { int pos = token.pos; List errs; - if (token.kind == IDENTIFIER) { + if (LAX_IDENTIFIER.accepts(token.kind)) { errs = List.of(mods, toP(F.at(pos).Ident(ident()))); setErrorEndPos(token.pos); } else { @@ -2787,7 +2798,7 @@ public class JavacParser implements Parser { } int pos = token.pos; List errs; - if (token.kind == IDENTIFIER) { + if (LAX_IDENTIFIER.accepts(token.kind)) { errs = List.of(mods, toP(F.at(pos).Ident(ident()))); setErrorEndPos(token.pos); } else { @@ -3182,14 +3193,17 @@ public class JavacParser implements Parser { * FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter */ List formalParameters() { + return formalParameters(false); + } + List formalParameters(boolean lambdaParameters) { ListBuffer params = new ListBuffer(); JCVariableDecl lastParam = null; accept(LPAREN); if (token.kind != RPAREN) { - params.append(lastParam = formalParameter()); + params.append(lastParam = formalParameter(lambdaParameters)); while ((lastParam.mods.flags & Flags.VARARGS) == 0 && token.kind == COMMA) { nextToken(); - params.append(lastParam = formalParameter()); + params.append(lastParam = formalParameter(lambdaParameters)); } } accept(RPAREN); @@ -3225,6 +3239,9 @@ public class JavacParser implements Parser { * LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter */ protected JCVariableDecl formalParameter() { + return formalParameter(false); + } + protected JCVariableDecl formalParameter(boolean lambdaParameter) { JCModifiers mods = optFinal(Flags.PARAMETER); JCExpression type = parseType(); if (token.kind == ELLIPSIS) { @@ -3233,12 +3250,12 @@ public class JavacParser implements Parser { type = to(F.at(token.pos).TypeArray(type)); nextToken(); } - return variableDeclaratorId(mods, type); + return variableDeclaratorId(mods, type, lambdaParameter); } protected JCVariableDecl implicitParameter() { JCModifiers mods = F.at(token.pos).Modifiers(Flags.PARAMETER); - return variableDeclaratorId(mods, null); + return variableDeclaratorId(mods, null, true); } /* ---------- auxiliary methods -------------- */ diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/Tokens.java b/langtools/src/share/classes/com/sun/tools/javac/parser/Tokens.java index 3e6362aa8e3..d55defedf73 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/Tokens.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/Tokens.java @@ -33,6 +33,7 @@ import com.sun.tools.javac.parser.Tokens.Token.Tag; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.Name; import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.Filter; import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Names; @@ -74,7 +75,6 @@ public class Tokens { protected Tokens(Context context) { context.put(tokensKey, this); names = Names.instance(context); - for (TokenKind t : TokenKind.values()) { if (t.name != null) enterKeyword(t.name, t); @@ -113,7 +113,7 @@ public class Tokens { * This enum defines all tokens used by the javac scanner. A token is * optionally associated with a name. */ - public enum TokenKind implements Formattable { + public enum TokenKind implements Formattable, Filter { EOF(), ERROR(), IDENTIFIER(Tag.NAMED), @@ -176,6 +176,7 @@ public class Tokens { TRUE("true", Tag.NAMED), FALSE("false", Tag.NAMED), NULL("null", Tag.NAMED), + UNDERSCORE("_", Tag.NAMED), ARROW("->"), COLCOL("::"), LPAREN("("), @@ -283,6 +284,11 @@ public class Tokens { public String toString(Locale locale, Messages messages) { return name != null ? toString() : messages.getLocalizedString(locale, "compiler.misc." + toString()); } + + @Override + public boolean accepts(TokenKind that) { + return this == that; + } } public interface Comment { diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties index f04abc7c42a..c9febb4a215 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -2132,6 +2132,10 @@ compiler.warn.assert.as.identifier=\ as of release 1.4, ''assert'' is a keyword, and may not be used as an identifier\n\ (use -source 1.4 or higher to use ''assert'' as a keyword) +compiler.warn.underscore.as.identifier=\ + ''_'' used as an identifier\n\ + (use of ''_'' as an identifier might not be supported in future releases) + compiler.err.enum.as.identifier=\ as of release 5, ''enum'' is a keyword, and may not be used as an identifier\n\ (use -source 1.4 or lower to use ''enum'' as an identifier) diff --git a/langtools/test/tools/javac/lambda/LambdaParserTest.java b/langtools/test/tools/javac/lambda/LambdaParserTest.java index c4fb4f548a2..0574e47df62 100644 --- a/langtools/test/tools/javac/lambda/LambdaParserTest.java +++ b/langtools/test/tools/javac/lambda/LambdaParserTest.java @@ -23,8 +23,7 @@ /* * @test - * @bug 7115050 - * @bug 8003280 + * @bug 7115050 8003280 8005852 * @summary Add lambda tests * Add parser support for lambda expressions * @library ../lib @@ -46,12 +45,12 @@ public class LambdaParserTest enum LambdaKind { NILARY_EXPR("()->x"), NILARY_STMT("()->{ return x; }"), - ONEARY_SHORT_EXPR("x->x"), - ONEARY_SHORT_STMT("x->{ return x; }"), - ONEARY_EXPR("(#M1 #T1 x)->x"), - ONEARY_STMT("(#M1 #T1 x)->{ return x; }"), - TWOARY_EXPR("(#M1 #T1 x, #M2 #T2 y)->x"), - TWOARY_STMT("(#M1 #T1 x, #M2 #T2 y)->{ return x; }"); + ONEARY_SHORT_EXPR("#PN->x"), + ONEARY_SHORT_STMT("#PN->{ return x; }"), + ONEARY_EXPR("(#M1 #T1 #PN)->x"), + ONEARY_STMT("(#M1 #T1 #PN)->{ return x; }"), + TWOARY_EXPR("(#M1 #T1 #PN, #M2 #T2 y)->x"), + TWOARY_STMT("(#M1 #T1 #PN, #M2 #T2 y)->{ return x; }"); String lambdaTemplate; @@ -60,11 +59,12 @@ public class LambdaParserTest } String getLambdaString(LambdaParameterKind pk1, LambdaParameterKind pk2, - ModifierKind mk1, ModifierKind mk2) { + ModifierKind mk1, ModifierKind mk2, LambdaParameterName pn) { return lambdaTemplate.replaceAll("#M1", mk1.modifier) .replaceAll("#M2", mk2.modifier) .replaceAll("#T1", pk1.parameterType) - .replaceAll("#T2", pk2.parameterType); + .replaceAll("#T2", pk2.parameterType) + .replaceAll("#PN", pn.nameStr); } int arity() { @@ -87,6 +87,17 @@ public class LambdaParserTest } } + enum LambdaParameterName { + IDENT("x"), + UNDERSCORE("_"); + + String nameStr; + + LambdaParameterName(String nameStr) { + this.nameStr = nameStr; + } + } + enum LambdaParameterKind { IMPLICIT(""), EXPLIICT_SIMPLE("A"), @@ -151,8 +162,8 @@ public class LambdaParserTest } String expressionString(LambdaParameterKind pk1, LambdaParameterKind pk2, - ModifierKind mk1, ModifierKind mk2, LambdaKind lk, SubExprKind sk) { - return expressionTemplate.replaceAll("#L", lk.getLambdaString(pk1, pk2, mk1, mk2)) + ModifierKind mk1, ModifierKind mk2, LambdaKind lk, LambdaParameterName pn, SubExprKind sk) { + return expressionTemplate.replaceAll("#L", lk.getLambdaString(pk1, pk2, mk1, mk2, pn)) .replaceAll("#S", sk.subExpression); } } @@ -174,25 +185,27 @@ public class LambdaParserTest public static void main(String... args) throws Exception { for (LambdaKind lk : LambdaKind.values()) { - for (LambdaParameterKind pk1 : LambdaParameterKind.values()) { - if (lk.arity() < 1 && pk1 != LambdaParameterKind.IMPLICIT) - continue; - for (LambdaParameterKind pk2 : LambdaParameterKind.values()) { - if (lk.arity() < 2 && pk2 != LambdaParameterKind.IMPLICIT) + for (LambdaParameterName pn : LambdaParameterName.values()) { + for (LambdaParameterKind pk1 : LambdaParameterKind.values()) { + if (lk.arity() < 1 && pk1 != LambdaParameterKind.IMPLICIT) continue; - for (ModifierKind mk1 : ModifierKind.values()) { - if (mk1 != ModifierKind.NONE && lk.isShort()) + for (LambdaParameterKind pk2 : LambdaParameterKind.values()) { + if (lk.arity() < 2 && pk2 != LambdaParameterKind.IMPLICIT) continue; - if (lk.arity() < 1 && mk1 != ModifierKind.NONE) - continue; - for (ModifierKind mk2 : ModifierKind.values()) { - if (lk.arity() < 2 && mk2 != ModifierKind.NONE) + for (ModifierKind mk1 : ModifierKind.values()) { + if (mk1 != ModifierKind.NONE && lk.isShort()) continue; - for (SubExprKind sk : SubExprKind.values()) { - for (ExprKind ek : ExprKind.values()) { - pool.execute( - new LambdaParserTest(pk1, pk2, mk1, - mk2, lk, sk, ek)); + if (lk.arity() < 1 && mk1 != ModifierKind.NONE) + continue; + for (ModifierKind mk2 : ModifierKind.values()) { + if (lk.arity() < 2 && mk2 != ModifierKind.NONE) + continue; + for (SubExprKind sk : SubExprKind.values()) { + for (ExprKind ek : ExprKind.values()) { + pool.execute( + new LambdaParserTest(pk1, pk2, mk1, + mk2, lk, sk, ek, pn)); + } } } } @@ -209,6 +222,7 @@ public class LambdaParserTest ModifierKind mk1; ModifierKind mk2; LambdaKind lk; + LambdaParameterName pn; SubExprKind sk; ExprKind ek; JavaSource source; @@ -216,12 +230,13 @@ public class LambdaParserTest LambdaParserTest(LambdaParameterKind pk1, LambdaParameterKind pk2, ModifierKind mk1, ModifierKind mk2, LambdaKind lk, - SubExprKind sk, ExprKind ek) { + SubExprKind sk, ExprKind ek, LambdaParameterName pn) { this.pk1 = pk1; this.pk2 = pk2; this.mk1 = mk1; this.mk2 = mk2; this.lk = lk; + this.pn = pn; this.sk = sk; this.ek = ek; this.source = new JavaSource(); @@ -239,7 +254,7 @@ public class LambdaParserTest public JavaSource() { super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); source = template.replaceAll("#E", - ek.expressionString(pk1, pk2, mk1, mk2, lk, sk)); + ek.expressionString(pk1, pk2, mk1, mk2, lk, pn, sk)); } @Override @@ -272,6 +287,9 @@ public class LambdaParserTest errorExpected = true; } + errorExpected |= pn == LambdaParameterName.UNDERSCORE && + lk.arity() > 0; + if (errorExpected != diagChecker.errorFound) { throw new Error("invalid diagnostics for source:\n" + source.getCharContent(true) + From e508ba9b0bd7553f7cf5e65858efafe26b56a956 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Thu, 17 Jan 2013 13:40:31 -0500 Subject: [PATCH 115/204] 7174978: NPG: Fix bactrace builder for class redefinition Remove Method* from backtrace but save version so redefine classes doesn't give inaccurate line numbers. Removed old Merlin API with duplicate code. Reviewed-by: dholmes, sspitsyn --- hotspot/make/bsd/makefiles/mapfile-vers-debug | 3 +- .../make/bsd/makefiles/mapfile-vers-product | 3 +- .../make/linux/makefiles/mapfile-vers-debug | 3 +- .../make/linux/makefiles/mapfile-vers-product | 3 +- hotspot/make/solaris/makefiles/mapfile-vers | 3 +- .../src/share/vm/classfile/javaClasses.cpp | 530 +++++++++--------- .../src/share/vm/classfile/javaClasses.hpp | 17 +- hotspot/src/share/vm/oops/constantPool.cpp | 4 +- hotspot/src/share/vm/oops/constantPool.hpp | 13 +- hotspot/src/share/vm/prims/jvm.cpp | 11 +- hotspot/src/share/vm/prims/jvm.h | 5 +- .../share/vm/prims/jvmtiRedefineClasses.cpp | 43 +- 12 files changed, 297 insertions(+), 341 deletions(-) diff --git a/hotspot/make/bsd/makefiles/mapfile-vers-debug b/hotspot/make/bsd/makefiles/mapfile-vers-debug index 00fd1892716..ef827302c54 100644 --- a/hotspot/make/bsd/makefiles/mapfile-vers-debug +++ b/hotspot/make/bsd/makefiles/mapfile-vers-debug @@ -3,7 +3,7 @@ # # -# Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 2013, 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 @@ -205,7 +205,6 @@ SUNWprivate_1.1 { JVM_NewMultiArray; JVM_OnExit; JVM_Open; - JVM_PrintStackTrace; JVM_RaiseSignal; JVM_RawMonitorCreate; JVM_RawMonitorDestroy; diff --git a/hotspot/make/bsd/makefiles/mapfile-vers-product b/hotspot/make/bsd/makefiles/mapfile-vers-product index dfa459f0316..0d2b04ca774 100644 --- a/hotspot/make/bsd/makefiles/mapfile-vers-product +++ b/hotspot/make/bsd/makefiles/mapfile-vers-product @@ -3,7 +3,7 @@ # # -# Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 2013, 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 @@ -205,7 +205,6 @@ SUNWprivate_1.1 { JVM_NewMultiArray; JVM_OnExit; JVM_Open; - JVM_PrintStackTrace; JVM_RaiseSignal; JVM_RawMonitorCreate; JVM_RawMonitorDestroy; diff --git a/hotspot/make/linux/makefiles/mapfile-vers-debug b/hotspot/make/linux/makefiles/mapfile-vers-debug index d6ebedcb9bd..ae4e2f9bcc3 100644 --- a/hotspot/make/linux/makefiles/mapfile-vers-debug +++ b/hotspot/make/linux/makefiles/mapfile-vers-debug @@ -1,5 +1,5 @@ # -# Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 2013, 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 @@ -201,7 +201,6 @@ SUNWprivate_1.1 { JVM_NewMultiArray; JVM_OnExit; JVM_Open; - JVM_PrintStackTrace; JVM_RaiseSignal; JVM_RawMonitorCreate; JVM_RawMonitorDestroy; diff --git a/hotspot/make/linux/makefiles/mapfile-vers-product b/hotspot/make/linux/makefiles/mapfile-vers-product index 733e3af4b11..9a3028d2a09 100644 --- a/hotspot/make/linux/makefiles/mapfile-vers-product +++ b/hotspot/make/linux/makefiles/mapfile-vers-product @@ -1,5 +1,5 @@ # -# Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 2013, 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 @@ -201,7 +201,6 @@ SUNWprivate_1.1 { JVM_NewMultiArray; JVM_OnExit; JVM_Open; - JVM_PrintStackTrace; JVM_RaiseSignal; JVM_RawMonitorCreate; JVM_RawMonitorDestroy; diff --git a/hotspot/make/solaris/makefiles/mapfile-vers b/hotspot/make/solaris/makefiles/mapfile-vers index a10d5c1b4e6..bf21253062e 100644 --- a/hotspot/make/solaris/makefiles/mapfile-vers +++ b/hotspot/make/solaris/makefiles/mapfile-vers @@ -1,5 +1,5 @@ # -# Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2013, 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 @@ -201,7 +201,6 @@ SUNWprivate_1.1 { JVM_NewMultiArray; JVM_OnExit; JVM_Open; - JVM_PrintStackTrace; JVM_RaiseSignal; JVM_RawMonitorCreate; JVM_RawMonitorDestroy; diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp index cb30a83d455..d63659fb867 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.cpp +++ b/hotspot/src/share/vm/classfile/javaClasses.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -1158,179 +1158,43 @@ void java_lang_Throwable::print(Handle throwable, outputStream* st) { } } -// Print stack trace element to resource allocated buffer -char* java_lang_Throwable::print_stack_element_to_buffer(Method* method, int bci) { - // Get strings and string lengths - InstanceKlass* klass = method->method_holder(); - const char* klass_name = klass->external_name(); - int buf_len = (int)strlen(klass_name); - char* source_file_name; - if (klass->source_file_name() == NULL) { - source_file_name = NULL; - } else { - source_file_name = klass->source_file_name()->as_C_string(); - buf_len += (int)strlen(source_file_name); - } - char* method_name = method->name()->as_C_string(); - buf_len += (int)strlen(method_name); +// After this many redefines, the stack trace is unreliable. +const int MAX_VERSION = USHRT_MAX; - // Allocate temporary buffer with extra space for formatting and line number - char* buf = NEW_RESOURCE_ARRAY(char, buf_len + 64); +// Helper backtrace functions to store bci|version together. +static inline int merge_bci_and_version(int bci, int version) { + // only store u2 for version, checking for overflow. + if (version > USHRT_MAX || version < 0) version = MAX_VERSION; + assert((jushort)bci == bci, "bci should be short"); + return build_int_from_shorts(version, bci); +} - // Print stack trace line in buffer - sprintf(buf, "\tat %s.%s", klass_name, method_name); +static inline int bci_at(unsigned int merged) { + return extract_high_short_from_int(merged); +} +static inline int version_at(unsigned int merged) { + return extract_low_short_from_int(merged); +} + +static inline bool version_matches(Method* method, int version) { + return (method->constants()->version() == version && version < MAX_VERSION); +} + +static inline int get_line_number(Method* method, int bci) { + int line_number = 0; if (method->is_native()) { - strcat(buf, "(Native Method)"); + // Negative value different from -1 below, enabling Java code in + // class java.lang.StackTraceElement to distinguish "native" from + // "no LineNumberTable". JDK tests for -2. + line_number = -2; } else { - int line_number = method->line_number_from_bci(bci); - if (source_file_name != NULL && (line_number != -1)) { - // Sourcename and linenumber - sprintf(buf + (int)strlen(buf), "(%s:%d)", source_file_name, line_number); - } else if (source_file_name != NULL) { - // Just sourcename - sprintf(buf + (int)strlen(buf), "(%s)", source_file_name); - } else { - // Neither soucename and linenumber - sprintf(buf + (int)strlen(buf), "(Unknown Source)"); - } - nmethod* nm = method->code(); - if (WizardMode && nm != NULL) { - sprintf(buf + (int)strlen(buf), "(nmethod " INTPTR_FORMAT ")", (intptr_t)nm); + // Returns -1 if no LineNumberTable, and otherwise actual line number + line_number = method->line_number_from_bci(bci); + if (line_number == -1 && ShowHiddenFrames) { + line_number = bci + 1000000; } } - - return buf; -} - - -void java_lang_Throwable::print_stack_element(Handle stream, Method* method, int bci) { - ResourceMark rm; - char* buf = print_stack_element_to_buffer(method, bci); - print_to_stream(stream, buf); -} - -void java_lang_Throwable::print_stack_element(outputStream *st, Method* method, int bci) { - ResourceMark rm; - char* buf = print_stack_element_to_buffer(method, bci); - st->print_cr("%s", buf); -} - -void java_lang_Throwable::print_to_stream(Handle stream, const char* str) { - if (stream.is_null()) { - tty->print_cr("%s", str); - } else { - EXCEPTION_MARK; - JavaValue result(T_VOID); - Handle arg (THREAD, oopFactory::new_charArray(str, THREAD)); - if (!HAS_PENDING_EXCEPTION) { - JavaCalls::call_virtual(&result, - stream, - KlassHandle(THREAD, stream->klass()), - vmSymbols::println_name(), - vmSymbols::char_array_void_signature(), - arg, - THREAD); - } - // Ignore any exceptions. we are in the middle of exception handling. Same as classic VM. - if (HAS_PENDING_EXCEPTION) CLEAR_PENDING_EXCEPTION; - } - -} - - -const char* java_lang_Throwable::no_stack_trace_message() { - return "\t<>"; -} - - -// Currently used only for exceptions occurring during startup -void java_lang_Throwable::print_stack_trace(oop throwable, outputStream* st) { - Thread *THREAD = Thread::current(); - Handle h_throwable(THREAD, throwable); - while (h_throwable.not_null()) { - objArrayHandle result (THREAD, objArrayOop(backtrace(h_throwable()))); - if (result.is_null()) { - st->print_cr(no_stack_trace_message()); - return; - } - - while (result.not_null()) { - typeArrayHandle methods (THREAD, - typeArrayOop(result->obj_at(trace_methods_offset))); - typeArrayHandle bcis (THREAD, - typeArrayOop(result->obj_at(trace_bcis_offset))); - - if (methods.is_null() || bcis.is_null()) { - st->print_cr(no_stack_trace_message()); - return; - } - - int length = methods()->length(); - for (int index = 0; index < length; index++) { - Method* method = ((Method*)methods()->metadata_at(index)); - if (method == NULL) goto handle_cause; - int bci = bcis->ushort_at(index); - print_stack_element(st, method, bci); - } - result = objArrayHandle(THREAD, objArrayOop(result->obj_at(trace_next_offset))); - } - handle_cause: - { - EXCEPTION_MARK; - JavaValue result(T_OBJECT); - JavaCalls::call_virtual(&result, - h_throwable, - KlassHandle(THREAD, h_throwable->klass()), - vmSymbols::getCause_name(), - vmSymbols::void_throwable_signature(), - THREAD); - // Ignore any exceptions. we are in the middle of exception handling. Same as classic VM. - if (HAS_PENDING_EXCEPTION) { - CLEAR_PENDING_EXCEPTION; - h_throwable = Handle(); - } else { - h_throwable = Handle(THREAD, (oop) result.get_jobject()); - if (h_throwable.not_null()) { - st->print("Caused by: "); - print(h_throwable, st); - st->cr(); - } - } - } - } -} - - -void java_lang_Throwable::print_stack_trace(oop throwable, oop print_stream) { - // Note: this is no longer used in Merlin, but we support it for compatibility. - Thread *thread = Thread::current(); - Handle stream(thread, print_stream); - objArrayHandle result (thread, objArrayOop(backtrace(throwable))); - if (result.is_null()) { - print_to_stream(stream, no_stack_trace_message()); - return; - } - - while (result.not_null()) { - typeArrayHandle methods(thread, - typeArrayOop(result->obj_at(trace_methods_offset))); - typeArrayHandle bcis (thread, - typeArrayOop(result->obj_at(trace_bcis_offset))); - - if (methods.is_null() || bcis.is_null()) { - print_to_stream(stream, no_stack_trace_message()); - return; - } - - int length = methods()->length(); - for (int index = 0; index < length; index++) { - Method* method = ((Method*)methods()->metadata_at(index)); - if (method == NULL) return; - int bci = bcis->ushort_at(index); - print_stack_element(stream, method, bci); - } - result = objArrayHandle(thread, objArrayOop(result->obj_at(trace_next_offset))); - } + return line_number; } // This class provides a simple wrapper over the internal structure of @@ -1350,13 +1214,30 @@ class BacktraceBuilder: public StackObj { enum { trace_methods_offset = java_lang_Throwable::trace_methods_offset, - trace_bcis_offset = java_lang_Throwable::trace_bcis_offset, + trace_bcis_offset = java_lang_Throwable::trace_bcis_offset, trace_mirrors_offset = java_lang_Throwable::trace_mirrors_offset, trace_next_offset = java_lang_Throwable::trace_next_offset, trace_size = java_lang_Throwable::trace_size, trace_chunk_size = java_lang_Throwable::trace_chunk_size }; + // get info out of chunks + static typeArrayOop get_methods(objArrayHandle chunk) { + typeArrayOop methods = typeArrayOop(chunk->obj_at(trace_methods_offset)); + assert(methods != NULL, "method array should be initialized in backtrace"); + return methods; + } + static typeArrayOop get_bcis(objArrayHandle chunk) { + typeArrayOop bcis = typeArrayOop(chunk->obj_at(trace_bcis_offset)); + assert(bcis != NULL, "bci array should be initialized in backtrace"); + return bcis; + } + static objArrayOop get_mirrors(objArrayHandle chunk) { + objArrayOop mirrors = objArrayOop(chunk->obj_at(trace_mirrors_offset)); + assert(mirrors != NULL, "mirror array should be initialized in backtrace"); + return mirrors; + } + // constructor for new backtrace BacktraceBuilder(TRAPS): _methods(NULL), _bcis(NULL), _head(NULL), _mirrors(NULL) { expand(CHECK); @@ -1364,6 +1245,19 @@ class BacktraceBuilder: public StackObj { _index = 0; } + BacktraceBuilder(objArrayHandle backtrace) { + _methods = get_methods(backtrace); + _bcis = get_bcis(backtrace); + _mirrors = get_mirrors(backtrace); + assert(_methods->length() == _bcis->length() && + _methods->length() == _mirrors->length(), + "method and source information arrays should match"); + + // head is the preallocated backtrace + _backtrace = _head = backtrace(); + _index = 0; + } + void expand(TRAPS) { objArrayHandle old_head(THREAD, _head); Pause_No_Safepoint_Verifier pnsv(&_nsv); @@ -1371,10 +1265,10 @@ class BacktraceBuilder: public StackObj { objArrayOop head = oopFactory::new_objectArray(trace_size, CHECK); objArrayHandle new_head(THREAD, head); - typeArrayOop methods = oopFactory::new_metaDataArray(trace_chunk_size, CHECK); + typeArrayOop methods = oopFactory::new_shortArray(trace_chunk_size, CHECK); typeArrayHandle new_methods(THREAD, methods); - typeArrayOop bcis = oopFactory::new_shortArray(trace_chunk_size, CHECK); + typeArrayOop bcis = oopFactory::new_intArray(trace_chunk_size, CHECK); typeArrayHandle new_bcis(THREAD, bcis); objArrayOop mirrors = oopFactory::new_objectArray(trace_chunk_size, CHECK); @@ -1389,7 +1283,7 @@ class BacktraceBuilder: public StackObj { _head = new_head(); _methods = new_methods(); - _bcis = new_bcis(); + _bcis = new_bcis(); _mirrors = new_mirrors(); _index = 0; } @@ -1403,7 +1297,6 @@ class BacktraceBuilder: public StackObj { // shorts. The later line number lookup would just smear the -1 // to a 0 even if it could be recorded. if (bci == SynchronizationEntryBCI) bci = 0; - assert(bci == (jushort)bci, "doesn't fit"); if (_index >= trace_chunk_size) { methodHandle mhandle(THREAD, method); @@ -1411,26 +1304,148 @@ class BacktraceBuilder: public StackObj { method = mhandle(); } - _methods->metadata_at_put(_index, method); - _bcis->ushort_at_put(_index, bci); - // we need to save the mirrors in the backtrace to keep the methods from - // being unloaded if their class loader is unloaded while we still have - // this stack trace. + _methods->short_at_put(_index, method->method_idnum()); + _bcis->int_at_put(_index, merge_bci_and_version(bci, method->constants()->version())); + + // We need to save the mirrors in the backtrace to keep the class + // from being unloaded while we still have this stack trace. + assert(method->method_holder()->java_mirror() != NULL, "never push null for mirror"); _mirrors->obj_at_put(_index, method->method_holder()->java_mirror()); _index++; } - Method* current_method() { - assert(_index >= 0 && _index < trace_chunk_size, "out of range"); - return ((Method*)_methods->metadata_at(_index)); - } - - jushort current_bci() { - assert(_index >= 0 && _index < trace_chunk_size, "out of range"); - return _bcis->ushort_at(_index); - } }; +// Print stack trace element to resource allocated buffer +char* java_lang_Throwable::print_stack_element_to_buffer(Handle mirror, + int method_id, int version, int bci) { + + // Get strings and string lengths + InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror())); + const char* klass_name = holder->external_name(); + int buf_len = (int)strlen(klass_name); + + // pushing to the stack trace added one. + Method* method = holder->method_with_idnum(method_id); + char* method_name = method->name()->as_C_string(); + buf_len += (int)strlen(method_name); + + char* source_file_name = NULL; + if (version_matches(method, version)) { + Symbol* source = holder->source_file_name(); + if (source != NULL) { + source_file_name = source->as_C_string(); + buf_len += (int)strlen(source_file_name); + } + } + + // Allocate temporary buffer with extra space for formatting and line number + char* buf = NEW_RESOURCE_ARRAY(char, buf_len + 64); + + // Print stack trace line in buffer + sprintf(buf, "\tat %s.%s", klass_name, method_name); + + if (!version_matches(method, version)) { + strcat(buf, "(Redefined)"); + } else { + int line_number = get_line_number(method, bci); + if (line_number == -2) { + strcat(buf, "(Native Method)"); + } else { + if (source_file_name != NULL && (line_number != -1)) { + // Sourcename and linenumber + sprintf(buf + (int)strlen(buf), "(%s:%d)", source_file_name, line_number); + } else if (source_file_name != NULL) { + // Just sourcename + sprintf(buf + (int)strlen(buf), "(%s)", source_file_name); + } else { + // Neither sourcename nor linenumber + sprintf(buf + (int)strlen(buf), "(Unknown Source)"); + } + nmethod* nm = method->code(); + if (WizardMode && nm != NULL) { + sprintf(buf + (int)strlen(buf), "(nmethod " INTPTR_FORMAT ")", (intptr_t)nm); + } + } + } + + return buf; +} + +void java_lang_Throwable::print_stack_element(outputStream *st, Handle mirror, + int method_id, int version, int bci) { + ResourceMark rm; + char* buf = print_stack_element_to_buffer(mirror, method_id, version, bci); + st->print_cr("%s", buf); +} + +void java_lang_Throwable::print_stack_element(outputStream *st, methodHandle method, int bci) { + Handle mirror = method->method_holder()->java_mirror(); + int method_id = method->method_idnum(); + int version = method->constants()->version(); + print_stack_element(st, mirror, method_id, version, bci); +} + +const char* java_lang_Throwable::no_stack_trace_message() { + return "\t<>"; +} + + +// Currently used only for exceptions occurring during startup +void java_lang_Throwable::print_stack_trace(oop throwable, outputStream* st) { + Thread *THREAD = Thread::current(); + Handle h_throwable(THREAD, throwable); + while (h_throwable.not_null()) { + objArrayHandle result (THREAD, objArrayOop(backtrace(h_throwable()))); + if (result.is_null()) { + st->print_cr(no_stack_trace_message()); + return; + } + + while (result.not_null()) { + + // Get method id, bci, version and mirror from chunk + typeArrayHandle methods (THREAD, BacktraceBuilder::get_methods(result)); + typeArrayHandle bcis (THREAD, BacktraceBuilder::get_bcis(result)); + objArrayHandle mirrors (THREAD, BacktraceBuilder::get_mirrors(result)); + + int length = methods()->length(); + for (int index = 0; index < length; index++) { + Handle mirror(THREAD, mirrors->obj_at(index)); + // NULL mirror means end of stack trace + if (mirror.is_null()) goto handle_cause; + int method = methods->short_at(index); + int version = version_at(bcis->int_at(index)); + int bci = bci_at(bcis->int_at(index)); + print_stack_element(st, mirror, method, version, bci); + } + result = objArrayHandle(THREAD, objArrayOop(result->obj_at(trace_next_offset))); + } + handle_cause: + { + EXCEPTION_MARK; + JavaValue cause(T_OBJECT); + JavaCalls::call_virtual(&cause, + h_throwable, + KlassHandle(THREAD, h_throwable->klass()), + vmSymbols::getCause_name(), + vmSymbols::void_throwable_signature(), + THREAD); + // Ignore any exceptions. we are in the middle of exception handling. Same as classic VM. + if (HAS_PENDING_EXCEPTION) { + CLEAR_PENDING_EXCEPTION; + h_throwable = Handle(); + } else { + h_throwable = Handle(THREAD, (oop) cause.get_jobject()); + if (h_throwable.not_null()) { + st->print("Caused by: "); + print(h_throwable, st); + st->cr(); + } + } + } + } +} void java_lang_Throwable::fill_in_stack_trace(Handle throwable, methodHandle method, TRAPS) { if (!StackTraceInThrowable) return; @@ -1591,21 +1606,8 @@ void java_lang_Throwable::allocate_backtrace(Handle throwable, TRAPS) { // No-op if stack trace is disabled if (!StackTraceInThrowable) return; - - objArrayOop h_oop = oopFactory::new_objectArray(trace_size, CHECK); - objArrayHandle backtrace (THREAD, h_oop); - typeArrayOop m_oop = oopFactory::new_metaDataArray(trace_chunk_size, CHECK); - typeArrayHandle methods (THREAD, m_oop); - typeArrayOop b = oopFactory::new_shortArray(trace_chunk_size, CHECK); - typeArrayHandle bcis(THREAD, b); - objArrayOop mirror_oop = oopFactory::new_objectArray(trace_chunk_size, CHECK); - objArrayHandle mirrors (THREAD, mirror_oop); - - // backtrace has space for one chunk (next is NULL) - backtrace->obj_at_put(trace_methods_offset, methods()); - backtrace->obj_at_put(trace_bcis_offset, bcis()); - backtrace->obj_at_put(trace_mirrors_offset, mirrors()); - set_backtrace(throwable(), backtrace()); + BacktraceBuilder bt(CHECK); // creates a backtrace + set_backtrace(throwable(), bt.backtrace()); } @@ -1617,48 +1619,26 @@ void java_lang_Throwable::fill_in_stack_trace_of_preallocated_backtrace(Handle t assert(throwable->is_a(SystemDictionary::Throwable_klass()), "sanity check"); - objArrayOop backtrace = (objArrayOop)java_lang_Throwable::backtrace(throwable()); - assert(backtrace != NULL, "backtrace not preallocated"); + JavaThread* THREAD = JavaThread::current(); - oop m = backtrace->obj_at(trace_methods_offset); - typeArrayOop methods = typeArrayOop(m); - assert(methods != NULL && methods->length() > 0, "method array not preallocated"); + objArrayHandle backtrace (THREAD, (objArrayOop)java_lang_Throwable::backtrace(throwable())); + assert(backtrace.not_null(), "backtrace should have been preallocated"); - oop b = backtrace->obj_at(trace_bcis_offset); - typeArrayOop bcis = typeArrayOop(b); - assert(bcis != NULL, "bci array not preallocated"); + ResourceMark rm(THREAD); + vframeStream st(THREAD); - oop mr = backtrace->obj_at(trace_mirrors_offset); - objArrayOop mirrors = objArrayOop(mr); - assert(mirrors != NULL, "bci array not preallocated"); - - assert(methods->length() == bcis->length() && - methods->length() == mirrors->length(), - "method and bci arrays should match"); - - JavaThread* thread = JavaThread::current(); - ResourceMark rm(thread); - vframeStream st(thread); + BacktraceBuilder bt(backtrace); // Unlike fill_in_stack_trace we do not skip fillInStackTrace or throwable init // methods as preallocated errors aren't created by "java" code. // fill in as much stack trace as possible + typeArrayOop methods = BacktraceBuilder::get_methods(backtrace); int max_chunks = MIN2(methods->length(), (int)MaxJavaStackTraceDepth); int chunk_count = 0; for (;!st.at_end(); st.next()) { - // Add entry and smear the -1 bci to 0 since the array only holds - // unsigned shorts. The later line number lookup would just smear - // the -1 to a 0 even if it could be recorded. - int bci = st.bci(); - if (bci == SynchronizationEntryBCI) bci = 0; - assert(bci == (jushort)bci, "doesn't fit"); - bcis->ushort_at_put(chunk_count, bci); - methods->metadata_at_put(chunk_count, st.method()); - mirrors->obj_at_put(chunk_count, - st.method()->method_holder()->java_mirror()); - + bt.push(st.method(), st.bci(), CHECK); chunk_count++; // Bail-out for deep stacks @@ -1672,7 +1652,6 @@ void java_lang_Throwable::fill_in_stack_trace_of_preallocated_backtrace(Handle t java_lang_Throwable::set_stacktrace(throwable(), java_lang_Throwable::unassigned_stacktrace()); assert(java_lang_Throwable::unassigned_stacktrace() != NULL, "not initialized"); } - } @@ -1691,12 +1670,12 @@ int java_lang_Throwable::get_stack_trace_depth(oop throwable, TRAPS) { chunk = next; } assert(chunk != NULL && chunk->obj_at(trace_next_offset) == NULL, "sanity check"); - // Count element in remaining partial chunk - typeArrayOop methods = typeArrayOop(chunk->obj_at(trace_methods_offset)); - typeArrayOop bcis = typeArrayOop(chunk->obj_at(trace_bcis_offset)); - assert(methods != NULL && bcis != NULL, "sanity check"); - for (int i = 0; i < methods->length(); i++) { - if (methods->metadata_at(i) == NULL) break; + // Count element in remaining partial chunk. NULL value for mirror + // marks the end of the stack trace elements that are saved. + objArrayOop mirrors = BacktraceBuilder::get_mirrors(chunk); + assert(mirrors != NULL, "sanity check"); + for (int i = 0; i < mirrors->length(); i++) { + if (mirrors->obj_at(i) == NULL) break; depth++; } } @@ -1722,25 +1701,28 @@ oop java_lang_Throwable::get_stack_trace_element(oop throwable, int index, TRAPS if (chunk == NULL) { THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL); } - // Get method,bci from chunk - typeArrayOop methods = typeArrayOop(chunk->obj_at(trace_methods_offset)); - typeArrayOop bcis = typeArrayOop(chunk->obj_at(trace_bcis_offset)); - assert(methods != NULL && bcis != NULL, "sanity check"); - methodHandle method(THREAD, ((Method*)methods->metadata_at(chunk_index))); - int bci = bcis->ushort_at(chunk_index); + // Get method id, bci, version and mirror from chunk + typeArrayOop methods = BacktraceBuilder::get_methods(chunk); + typeArrayOop bcis = BacktraceBuilder::get_bcis(chunk); + objArrayOop mirrors = BacktraceBuilder::get_mirrors(chunk); + + assert(methods != NULL && bcis != NULL && mirrors != NULL, "sanity check"); + + int method = methods->short_at(chunk_index); + int version = version_at(bcis->int_at(chunk_index)); + int bci = bci_at(bcis->int_at(chunk_index)); + Handle mirror(THREAD, mirrors->obj_at(chunk_index)); + // Chunk can be partial full - if (method.is_null()) { + if (mirror.is_null()) { THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL); } - oop element = java_lang_StackTraceElement::create(method, bci, CHECK_0); + oop element = java_lang_StackTraceElement::create(mirror, method, version, bci, CHECK_0); return element; } -oop java_lang_StackTraceElement::create(methodHandle method, int bci, TRAPS) { - // SystemDictionary::stackTraceElement_klass() will be null for pre-1.4 JDKs - assert(JDK_Version::is_gte_jdk14x_version(), "should only be called in >= 1.4"); - +oop java_lang_StackTraceElement::create(Handle mirror, int method_id, int version, int bci, TRAPS) { // Allocate java.lang.StackTraceElement instance Klass* k = SystemDictionary::StackTraceElement_klass(); assert(k != NULL, "must be loaded in 1.4+"); @@ -1752,37 +1734,39 @@ oop java_lang_StackTraceElement::create(methodHandle method, int bci, TRAPS) { Handle element = ik->allocate_instance_handle(CHECK_0); // Fill in class name ResourceMark rm(THREAD); - const char* str = method->method_holder()->external_name(); + InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror())); + const char* str = holder->external_name(); oop classname = StringTable::intern((char*) str, CHECK_0); java_lang_StackTraceElement::set_declaringClass(element(), classname); + // Fill in method name + Method* method = holder->method_with_idnum(method_id); oop methodname = StringTable::intern(method->name(), CHECK_0); java_lang_StackTraceElement::set_methodName(element(), methodname); - // Fill in source file name - Symbol* source = method->method_holder()->source_file_name(); - if (ShowHiddenFrames && source == NULL) - source = vmSymbols::unknown_class_name(); - oop filename = StringTable::intern(source, CHECK_0); - java_lang_StackTraceElement::set_fileName(element(), filename); - // File in source line number - int line_number; - if (method->is_native()) { - // Negative value different from -1 below, enabling Java code in - // class java.lang.StackTraceElement to distinguish "native" from - // "no LineNumberTable". - line_number = -2; - } else { - // Returns -1 if no LineNumberTable, and otherwise actual line number - line_number = method->line_number_from_bci(bci); - if (line_number == -1 && ShowHiddenFrames) { - line_number = bci + 1000000; - } - } - java_lang_StackTraceElement::set_lineNumber(element(), line_number); + if (!version_matches(method, version)) { + // The method was redefined, accurate line number information isn't available + java_lang_StackTraceElement::set_fileName(element(), NULL); + java_lang_StackTraceElement::set_lineNumber(element(), -1); + } else { + // Fill in source file name and line number. + Symbol* source = holder->source_file_name(); + if (ShowHiddenFrames && source == NULL) + source = vmSymbols::unknown_class_name(); + oop filename = StringTable::intern(source, CHECK_0); + java_lang_StackTraceElement::set_fileName(element(), filename); + + int line_number = get_line_number(method, bci); + java_lang_StackTraceElement::set_lineNumber(element(), line_number); + } return element(); } +oop java_lang_StackTraceElement::create(methodHandle method, int bci, TRAPS) { + Handle mirror (THREAD, method->method_holder()->java_mirror()); + int method_id = method->method_idnum(); + return create(mirror, method_id, method->constants()->version(), bci, THREAD); +} void java_lang_reflect_AccessibleObject::compute_offsets() { Klass* k = SystemDictionary::reflect_AccessibleObject_klass(); diff --git a/hotspot/src/share/vm/classfile/javaClasses.hpp b/hotspot/src/share/vm/classfile/javaClasses.hpp index 5ab16251c10..51ee95da145 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.hpp +++ b/hotspot/src/share/vm/classfile/javaClasses.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -469,8 +469,7 @@ class java_lang_Throwable: AllStatic { static int static_unassigned_stacktrace_offset; // Printing - static char* print_stack_element_to_buffer(Method* method, int bci); - static void print_to_stream(Handle stream, const char* str); + static char* print_stack_element_to_buffer(Handle mirror, int method, int version, int bci); // StackTrace (programmatic access, new since 1.4) static void clear_stacktrace(oop throwable); // No stack trace available @@ -490,12 +489,9 @@ class java_lang_Throwable: AllStatic { static oop message(oop throwable); static oop message(Handle throwable); static void set_message(oop throwable, oop value); - // Print stack trace stored in exception by call-back to Java - // Note: this is no longer used in Merlin, but we still suppport - // it for compatibility. - static void print_stack_trace(oop throwable, oop print_stream); - static void print_stack_element(Handle stream, Method* method, int bci); - static void print_stack_element(outputStream *st, Method* method, int bci); + static void print_stack_element(outputStream *st, Handle mirror, int method, + int version, int bci); + static void print_stack_element(outputStream *st, methodHandle method, int bci); static void print_stack_usage(Handle stream); // Allocate space for backtrace (created but stack trace not filled in) @@ -1263,7 +1259,8 @@ class java_lang_StackTraceElement: AllStatic { static void set_lineNumber(oop element, int value); // Create an instance of StackTraceElement - static oop create(methodHandle m, int bci, TRAPS); + static oop create(Handle mirror, int method, int version, int bci, TRAPS); + static oop create(methodHandle method, int bci, TRAPS); // Debugging friend class JavaClasses; diff --git a/hotspot/src/share/vm/oops/constantPool.cpp b/hotspot/src/share/vm/oops/constantPool.cpp index ff8472d3d79..770510c7880 100644 --- a/hotspot/src/share/vm/oops/constantPool.cpp +++ b/hotspot/src/share/vm/oops/constantPool.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -66,7 +66,7 @@ ConstantPool::ConstantPool(Array* tags) { set_pool_holder(NULL); set_flags(0); // only set to non-zero if constant pool is merged by RedefineClasses - set_orig_length(0); + set_version(0); set_lock(new Monitor(Monitor::nonleaf + 2, "A constant pool lock")); // all fields are initialized; needed for GC set_on_stack(false); diff --git a/hotspot/src/share/vm/oops/constantPool.hpp b/hotspot/src/share/vm/oops/constantPool.hpp index 768cd39a65c..3872dfb81e3 100644 --- a/hotspot/src/share/vm/oops/constantPool.hpp +++ b/hotspot/src/share/vm/oops/constantPool.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -103,8 +103,8 @@ class ConstantPool : public Metadata { union { // set for CDS to restore resolved references int _resolved_reference_length; - // only set to non-zero if constant pool is merged by RedefineClasses - int _orig_length; + // keeps version number for redefined classes (used in backtrace) + int _version; } _saved; Monitor* _lock; @@ -784,8 +784,11 @@ class ConstantPool : public Metadata { static void copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int end_i, constantPoolHandle to_cp, int to_i, TRAPS); static void copy_entry_to(constantPoolHandle from_cp, int from_i, constantPoolHandle to_cp, int to_i, TRAPS); int find_matching_entry(int pattern_i, constantPoolHandle search_cp, TRAPS); - int orig_length() const { return _saved._orig_length; } - void set_orig_length(int orig_length) { _saved._orig_length = orig_length; } + int version() const { return _saved._version; } + void set_version(int version) { _saved._version = version; } + void increment_and_save_version(int version) { + _saved._version = version >= 0 ? version++ : version; // keep overflow + } void set_resolved_reference_length(int length) { _saved._resolved_reference_length = length; } int resolved_reference_length() const { return _saved._resolved_reference_length; } diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp index 8b7b2583c5f..9b15947a7f1 100644 --- a/hotspot/src/share/vm/prims/jvm.cpp +++ b/hotspot/src/share/vm/prims/jvm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -484,15 +484,6 @@ JVM_ENTRY(void, JVM_FillInStackTrace(JNIEnv *env, jobject receiver)) JVM_END -JVM_ENTRY(void, JVM_PrintStackTrace(JNIEnv *env, jobject receiver, jobject printable)) - JVMWrapper("JVM_PrintStackTrace"); - // Note: This is no longer used in Merlin, but we still support it for compatibility. - oop exception = JNIHandles::resolve_non_null(receiver); - oop stream = JNIHandles::resolve_non_null(printable); - java_lang_Throwable::print_stack_trace(exception, stream); -JVM_END - - JVM_ENTRY(jint, JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable)) JVMWrapper("JVM_GetStackTraceDepth"); oop exception = JNIHandles::resolve(throwable); diff --git a/hotspot/src/share/vm/prims/jvm.h b/hotspot/src/share/vm/prims/jvm.h index 899138ede9e..c081f872afa 100644 --- a/hotspot/src/share/vm/prims/jvm.h +++ b/hotspot/src/share/vm/prims/jvm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -212,9 +212,6 @@ JVM_IsNaN(jdouble d); JNIEXPORT void JNICALL JVM_FillInStackTrace(JNIEnv *env, jobject throwable); -JNIEXPORT void JNICALL -JVM_PrintStackTrace(JNIEnv *env, jobject throwable, jobject printable); - JNIEXPORT jint JNICALL JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable); diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp index a9d3d5f1e39..7e68f2b1059 100644 --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -1334,20 +1334,8 @@ jvmtiError VM_RedefineClasses::merge_cp_and_rewrite( return JVMTI_ERROR_INTERNAL; } - int orig_length = old_cp->orig_length(); - if (orig_length == 0) { - // This old_cp is an actual original constant pool. We save - // the original length in the merged constant pool so that - // merge_constant_pools() can be more efficient. If a constant - // pool has a non-zero orig_length() value, then that constant - // pool was created by a merge operation in RedefineClasses. - merge_cp->set_orig_length(old_cp->length()); - } else { - // This old_cp is a merged constant pool from a previous - // RedefineClasses() calls so just copy the orig_length() - // value. - merge_cp->set_orig_length(old_cp->orig_length()); - } + // Update the version number of the constant pool + merge_cp->increment_and_save_version(old_cp->version()); ResourceMark rm(THREAD); _index_map_count = 0; @@ -2417,18 +2405,19 @@ void VM_RedefineClasses::set_new_constant_pool( int scratch_cp_length, TRAPS) { assert(scratch_cp->length() >= scratch_cp_length, "sanity check"); - // scratch_cp is a merged constant pool and has enough space for a - // worst case merge situation. We want to associate the minimum - // sized constant pool with the klass to save space. - constantPoolHandle smaller_cp(THREAD, - ConstantPool::allocate(loader_data, scratch_cp_length, - THREAD)); - // preserve orig_length() value in the smaller copy - int orig_length = scratch_cp->orig_length(); - assert(orig_length != 0, "sanity check"); - smaller_cp->set_orig_length(orig_length); - scratch_cp->copy_cp_to(1, scratch_cp_length - 1, smaller_cp, 1, THREAD); - scratch_cp = smaller_cp; + // scratch_cp is a merged constant pool and has enough space for a + // worst case merge situation. We want to associate the minimum + // sized constant pool with the klass to save space. + constantPoolHandle smaller_cp(THREAD, + ConstantPool::allocate(loader_data, scratch_cp_length, THREAD)); + + // preserve version() value in the smaller copy + int version = scratch_cp->version(); + assert(version != 0, "sanity check"); + smaller_cp->set_version(version); + + scratch_cp->copy_cp_to(1, scratch_cp_length - 1, smaller_cp, 1, THREAD); + scratch_cp = smaller_cp; // attach new constant pool to klass scratch_cp->set_pool_holder(scratch_class()); From 3d5f55b8512d649e68ee685058b9a6d7354c6cd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20=C3=96hrstr=C3=B6m?= Date: Fri, 18 Jan 2013 00:16:21 +0100 Subject: [PATCH 116/204] 8004658: Add internal smart javac wrapper to solve JEP 139 Reviewed-by: jjg --- langtools/make/build.properties | 16 +- langtools/make/build.xml | 40 +- .../com/sun/tools/sjavac/BuildState.java | 275 +++++ .../com/sun/tools/sjavac/CleanProperties.java | 148 +++ .../com/sun/tools/sjavac/CompileChunk.java | 57 ++ .../sun/tools/sjavac/CompileJavaPackages.java | 344 +++++++ .../sun/tools/sjavac/CompileProperties.java | 221 ++++ .../com/sun/tools/sjavac/CopyFile.java | 116 +++ .../com/sun/tools/sjavac/JavacState.java | 857 ++++++++++++++++ .../classes/com/sun/tools/sjavac/Log.java | 92 ++ .../classes/com/sun/tools/sjavac/Main.java | 969 ++++++++++++++++++ .../classes/com/sun/tools/sjavac/Module.java | 141 +++ .../classes/com/sun/tools/sjavac/Package.java | 307 ++++++ .../sun/tools/sjavac/ProblemException.java | 41 + .../classes/com/sun/tools/sjavac/Source.java | 400 ++++++++ .../com/sun/tools/sjavac/Transformer.java | 99 ++ .../classes/com/sun/tools/sjavac/Util.java | 160 +++ .../sun/tools/sjavac/comp/Dependencies.java | 188 ++++ .../sjavac/comp/JavaCompilerWithDeps.java | 109 ++ .../sun/tools/sjavac/comp/PubapiVisitor.java | 157 +++ .../tools/sjavac/comp/ResolveWithDeps.java | 67 ++ .../tools/sjavac/comp/SmartFileManager.java | 221 ++++ .../tools/sjavac/comp/SmartFileObject.java | 126 +++ .../sun/tools/sjavac/comp/SmartWriter.java | 78 ++ .../sun/tools/sjavac/server/CompilerPool.java | 163 +++ .../tools/sjavac/server/CompilerThread.java | 419 ++++++++ .../sun/tools/sjavac/server/JavacServer.java | 751 ++++++++++++++ .../com/sun/tools/sjavac/server/PortFile.java | 259 +++++ .../com/sun/tools/sjavac/server/SysInfo.java | 45 + langtools/test/tools/sjavac/SJavac.java | 590 +++++++++++ 30 files changed, 7449 insertions(+), 7 deletions(-) create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/BuildState.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/CleanProperties.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/CompileChunk.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/CompileProperties.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/CopyFile.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/Log.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/Main.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/Module.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/Package.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/ProblemException.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/Source.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/Transformer.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/Util.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/comp/Dependencies.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/comp/JavaCompilerWithDeps.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/comp/PubapiVisitor.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/comp/ResolveWithDeps.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/comp/SmartFileManager.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/comp/SmartFileObject.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/comp/SmartWriter.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/server/CompilerPool.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/server/CompilerThread.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/server/PortFile.java create mode 100644 langtools/src/share/classes/com/sun/tools/sjavac/server/SysInfo.java create mode 100644 langtools/test/tools/sjavac/SJavac.java diff --git a/langtools/make/build.properties b/langtools/make/build.properties index 3470a69d868..72ae8793c24 100644 --- a/langtools/make/build.properties +++ b/langtools/make/build.properties @@ -29,18 +29,18 @@ # Override this path as needed, either on the command line or in # one of the standard user build.properties files (see build.xml) -# boot.java.home = /opt/jdk/1.6.0 +# boot.java.home = /opt/jdk/1.7.0 boot.java = ${boot.java.home}/bin/java boot.javac = ${boot.java.home}/bin/javac -boot.javac.source = 6 -boot.javac.target = 6 +boot.javac.source = 7 +boot.javac.target = 7 # This is the JDK used to run the product version of the tools, # for example, for testing. If you're building a complete JDK, specify that. # Override this path as needed, either on the command line or in # one of the standard user build.properties files (see build.xml) -# target.java.home = /opt/jdk/1.7.0 +# target.java.home = /opt/jdk/1.8.0 target.java = ${target.java.home}/bin/java # Version info -- override as needed @@ -161,6 +161,14 @@ javap.tests = \ # +sjavac.includes = \ + com/sun/tools/sjavac/ + +sjavac.tests = \ + tools/sjavac + +# + # The following files require the latest JDK to be available. # The API can be provided by using a suitable boot.java.home # or by setting import.jdk diff --git a/langtools/make/build.xml b/langtools/make/build.xml index be1c357852c..9292ee3f392 100644 --- a/langtools/make/build.xml +++ b/langtools/make/build.xml @@ -241,15 +241,15 @@ - + @@ -656,6 +656,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + * @@ -1486,6 +1665,7 @@ public class Type implements PrimitiveType { R visitForAll(ForAll t, S s); R visitUndetVar(UndetVar t, S s); R visitErrorType(ErrorType t, S s); + R visitAnnotatedType(AnnotatedType t, S s); R visitType(Type t, S s); } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java index c3fba38ff85..32a6ffdc8f4 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -25,6 +25,8 @@ package com.sun.tools.javac.code; +import java.util.Iterator; + import com.sun.tools.javac.util.*; /** A type annotation position. @@ -34,12 +36,92 @@ import com.sun.tools.javac.util.*; * This code and its internal interfaces are subject to change or * deletion without notice. */ +// Code duplicated in com.sun.tools.classfile.TypeAnnotation.Position public class TypeAnnotationPosition { + public enum TypePathEntryKind { + ARRAY(0), + INNER_TYPE(1), + WILDCARD(2), + TYPE_ARGUMENT(3); + + public final int tag; + + private TypePathEntryKind(int tag) { + this.tag = tag; + } + } + + public static class TypePathEntry { + /** The fixed number of bytes per TypePathEntry. */ + public static final int bytesPerEntry = 2; + + public final TypePathEntryKind tag; + public final int arg; + + public static final TypePathEntry ARRAY = new TypePathEntry(TypePathEntryKind.ARRAY); + public static final TypePathEntry INNER_TYPE = new TypePathEntry(TypePathEntryKind.INNER_TYPE); + public static final TypePathEntry WILDCARD = new TypePathEntry(TypePathEntryKind.WILDCARD); + + private TypePathEntry(TypePathEntryKind tag) { + Assert.check(tag == TypePathEntryKind.ARRAY || + tag == TypePathEntryKind.INNER_TYPE || + tag == TypePathEntryKind.WILDCARD, + "Invalid TypePathEntryKind: " + tag); + this.tag = tag; + this.arg = 0; + } + + public TypePathEntry(TypePathEntryKind tag, int arg) { + Assert.check(tag == TypePathEntryKind.TYPE_ARGUMENT, + "Invalid TypePathEntryKind: " + tag); + this.tag = tag; + this.arg = arg; + } + + public static TypePathEntry fromBinary(int tag, int arg) { + Assert.check(arg == 0 || tag == TypePathEntryKind.TYPE_ARGUMENT.tag, + "Invalid TypePathEntry tag/arg: " + tag + "/" + arg); + switch (tag) { + case 0: + return ARRAY; + case 1: + return INNER_TYPE; + case 2: + return WILDCARD; + case 3: + return new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, arg); + default: + Assert.error("Invalid TypePathEntryKind tag: " + tag); + return null; + } + } + + @Override + public String toString() { + return tag.toString() + + (tag == TypePathEntryKind.TYPE_ARGUMENT ? ("(" + arg + ")") : ""); + } + + @Override + public boolean equals(Object other) { + if (! (other instanceof TypePathEntry)) { + return false; + } + TypePathEntry tpe = (TypePathEntry) other; + return this.tag == tpe.tag && this.arg == tpe.arg; + } + + @Override + public int hashCode() { + return this.tag.hashCode() * 17 + this.arg; + } + } + public TargetType type = TargetType.UNKNOWN; // For generic/array types. - public List location = List.nil(); + public List location = List.nil(); // Tree position. public int pos = -1; @@ -59,11 +141,13 @@ public class TypeAnnotationPosition { // For type parameter and method parameter public int parameter_index = Integer.MIN_VALUE; - // For class extends, implements, and throws classes + // For class extends, implements, and throws clauses public int type_index = Integer.MIN_VALUE; - // For wildcards - public TypeAnnotationPosition wildcard_position = null; + // For exception parameters, index into exception table + public int exception_index = Integer.MIN_VALUE; + + public TypeAnnotationPosition() {} @Override public String toString() { @@ -72,27 +156,27 @@ public class TypeAnnotationPosition { sb.append(type); switch (type) { - // type case - case TYPECAST: - case TYPECAST_GENERIC_OR_ARRAY: - // object creation + // type cast + case CAST: + // instanceof case INSTANCEOF: - case INSTANCEOF_GENERIC_OR_ARRAY: - // new expression + // new expression case NEW: - case NEW_GENERIC_OR_ARRAY: - case NEW_TYPE_ARGUMENT: - case NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY: sb.append(", offset = "); sb.append(offset); break; - // local variable + // local variable case LOCAL_VARIABLE: - case LOCAL_VARIABLE_GENERIC_OR_ARRAY: + // resource variable + case RESOURCE_VARIABLE: + if (lvarOffset == null) { + sb.append(", lvarOffset is null!"); + break; + } sb.append(", {"); for (int i = 0; i < lvarOffset.length; ++i) { if (i != 0) sb.append("; "); - sb.append(", start_pc = "); + sb.append("start_pc = "); sb.append(lvarOffset[i]); sb.append(", length = "); sb.append(lvarLength[i]); @@ -101,73 +185,72 @@ public class TypeAnnotationPosition { } sb.append("}"); break; - // method receiver + // method receiver case METHOD_RECEIVER: // Do nothing break; - // type parameters + // type parameter case CLASS_TYPE_PARAMETER: case METHOD_TYPE_PARAMETER: sb.append(", param_index = "); sb.append(parameter_index); break; - // type parameters bound + // type parameter bound case CLASS_TYPE_PARAMETER_BOUND: - case CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY: case METHOD_TYPE_PARAMETER_BOUND: - case METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY: sb.append(", param_index = "); sb.append(parameter_index); sb.append(", bound_index = "); sb.append(bound_index); break; - // wildcard - case WILDCARD_BOUND: - case WILDCARD_BOUND_GENERIC_OR_ARRAY: - sb.append(", wild_card = "); - sb.append(wildcard_position); - break; - // Class extends and implements clauses + // class extends or implements clause case CLASS_EXTENDS: - case CLASS_EXTENDS_GENERIC_OR_ARRAY: sb.append(", type_index = "); sb.append(type_index); break; - // throws + // throws case THROWS: sb.append(", type_index = "); sb.append(type_index); break; - case CLASS_LITERAL: - case CLASS_LITERAL_GENERIC_OR_ARRAY: - sb.append(", offset = "); - sb.append(offset); + // exception parameter + case EXCEPTION_PARAMETER: + sb.append(", exception_index = "); + sb.append(exception_index); break; - // method parameter: not specified - case METHOD_PARAMETER_GENERIC_OR_ARRAY: + // method parameter + case METHOD_FORMAL_PARAMETER: sb.append(", param_index = "); sb.append(parameter_index); break; - // method type argument: wasn't specified - case METHOD_TYPE_ARGUMENT: - case METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY: + // method/constructor/reference type argument + case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: + case METHOD_INVOCATION_TYPE_ARGUMENT: + case METHOD_REFERENCE_TYPE_ARGUMENT: sb.append(", offset = "); sb.append(offset); sb.append(", type_index = "); sb.append(type_index); break; - // We don't need to worry abut these - case METHOD_RETURN_GENERIC_OR_ARRAY: - case FIELD_GENERIC_OR_ARRAY: + // We don't need to worry about these + case METHOD_RETURN: + case FIELD: + break; + // lambda formal parameter + case LAMBDA_FORMAL_PARAMETER: + // TODO: also needs an offset? + sb.append(", param_index = "); + sb.append(parameter_index); break; case UNKNOWN: + sb.append(", position UNKNOWN!"); break; default: - // throw new AssertionError("unknown type: " + type); + Assert.error("Unknown target type: " + type); } // Append location data for generics/arrays. - if (type.hasLocation()) { + if (!location.isEmpty()) { sb.append(", location = ("); sb.append(location); sb.append(")"); @@ -186,10 +269,33 @@ public class TypeAnnotationPosition { * @return true if the target has not been optimized away */ public boolean emitToClassfile() { - if (type == TargetType.WILDCARD_BOUND - || type == TargetType.WILDCARD_BOUND_GENERIC_OR_ARRAY) - return wildcard_position.isValidOffset; - else - return !type.isLocal() || isValidOffset; + return !type.isLocal() || isValidOffset; + } + + /** + * Decode the binary representation for a type path and set + * the {@code location} field. + * + * @param list The bytecode representation of the type path. + */ + public static List getTypePathFromBinary(java.util.List list) { + ListBuffer loc = ListBuffer.lb(); + Iterator iter = list.iterator(); + while (iter.hasNext()) { + Integer fst = iter.next(); + Assert.check(iter.hasNext(), "Could not decode type path: " + list); + Integer snd = iter.next(); + loc = loc.append(TypePathEntry.fromBinary(fst, snd)); + } + return loc.toList(); + } + + public static List getBinaryFromTypePath(java.util.List locs) { + ListBuffer loc = ListBuffer.lb(); + for (TypePathEntry tpe : locs) { + loc = loc.append(tpe.tag.tag); + loc = loc.append(tpe.arg); + } + return loc.toList(); } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java new file mode 100644 index 00000000000..b438b2f1e93 --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java @@ -0,0 +1,1037 @@ +/* + * Copyright (c) 2009, 2013, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package com.sun.tools.javac.code; + +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.type.TypeKind; + +import com.sun.tools.javac.code.Attribute; +import com.sun.tools.javac.code.Attribute.TypeCompound; +import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.code.Kinds; +import com.sun.tools.javac.code.Type.AnnotatedType; +import com.sun.tools.javac.code.Type.ArrayType; +import com.sun.tools.javac.code.Type.CapturedType; +import com.sun.tools.javac.code.Type.ClassType; +import com.sun.tools.javac.code.Type.ErrorType; +import com.sun.tools.javac.code.Type.ForAll; +import com.sun.tools.javac.code.Type.MethodType; +import com.sun.tools.javac.code.Type.PackageType; +import com.sun.tools.javac.code.Type.TypeVar; +import com.sun.tools.javac.code.Type.UndetVar; +import com.sun.tools.javac.code.Type.Visitor; +import com.sun.tools.javac.code.Type.WildcardType; +import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntry; +import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntryKind; +import com.sun.tools.javac.code.TypeTag; +import com.sun.tools.javac.code.Symbol.VarSymbol; +import com.sun.tools.javac.comp.Annotate.Annotator; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.JCTree.JCBlock; +import com.sun.tools.javac.tree.JCTree.JCClassDecl; +import com.sun.tools.javac.tree.JCTree.JCExpression; +import com.sun.tools.javac.tree.JCTree.JCMethodDecl; +import com.sun.tools.javac.tree.JCTree.JCTypeApply; +import com.sun.tools.javac.tree.JCTree.JCVariableDecl; +import com.sun.tools.javac.tree.TreeScanner; +import com.sun.tools.javac.tree.JCTree.*; +import com.sun.tools.javac.util.Assert; +import com.sun.tools.javac.util.List; +import com.sun.tools.javac.util.ListBuffer; +import com.sun.tools.javac.util.Log; +import com.sun.tools.javac.util.Names; + +/** + * Contains operations specific to processing type annotations. + * This class has two functions: + * separate declaration from type annotations and insert the type + * annotations to their types; + * and determine the TypeAnnotationPositions for all type annotations. + */ +public class TypeAnnotations { + // Class cannot be instantiated. + private TypeAnnotations() {} + + /** + * Separate type annotations from declaration annotations and + * determine the correct positions for type annotations. + * This version only visits types in signatures and should be + * called from MemberEnter. + * The method returns the Annotator object that should be added + * to the correct Annotate queue for later processing. + */ + public static Annotator organizeTypeAnnotationsSignatures(final Symtab syms, final Names names, + final Log log, final JCClassDecl tree) { + return new Annotator() { + @Override + public void enterAnnotation() { + new TypeAnnotationPositions(syms, names, log, true).scan(tree); + } + }; + } + + /** + * This version only visits types in bodies, that is, field initializers, + * top-level blocks, and method bodies, and should be called from Attr. + */ + public static void organizeTypeAnnotationsBodies(Symtab syms, Names names, Log log, JCClassDecl tree) { + new TypeAnnotationPositions(syms, names, log, false).scan(tree); + } + + private static class TypeAnnotationPositions extends TreeScanner { + + private enum AnnotationType { DECLARATION, TYPE, BOTH }; + + private final Symtab syms; + private final Names names; + private final Log log; + private final boolean sigOnly; + + private TypeAnnotationPositions(Symtab syms, Names names, Log log, boolean sigOnly) { + this.syms = syms; + this.names = names; + this.log = log; + this.sigOnly = sigOnly; + } + + /* + * When traversing the AST we keep the "frames" of visited + * trees in order to determine the position of annotations. + */ + private ListBuffer frames = ListBuffer.lb(); + + protected void push(JCTree t) { frames = frames.prepend(t); } + protected JCTree pop() { return frames.next(); } + // could this be frames.elems.tail.head? + private JCTree peek2() { return frames.toList().tail.head; } + + @Override + public void scan(JCTree tree) { + push(tree); + super.scan(tree); + pop(); + } + + /** + * Separates type annotations from declaration annotations. + * This step is needed because in certain locations (where declaration + * and type annotations can be mixed, e.g. the type of a field) + * we never build an JCAnnotatedType. This step finds these + * annotations and marks them as if they were part of the type. + */ + private void separateAnnotationsKinds(JCTree typetree, Type type, Symbol sym, + TypeAnnotationPosition pos) { + /* + System.out.printf("separateAnnotationsKinds(typetree: %s, type: %s, symbol: %s, pos: %s%n", + typetree, type, sym, pos); + */ + List annotations = sym.getRawAttributes(); + ListBuffer declAnnos = new ListBuffer(); + ListBuffer typeAnnos = new ListBuffer(); + + for (Attribute.Compound a : annotations) { + switch (annotationType(a, sym)) { + case DECLARATION: + declAnnos.append(a); + break; + case BOTH: { + declAnnos.append(a); + Attribute.TypeCompound ta = toTypeCompound(a, pos); + typeAnnos.append(ta); + break; + } + case TYPE: { + Attribute.TypeCompound ta = toTypeCompound(a, pos); + typeAnnos.append(ta); + break; + } + } + } + + sym.annotations.reset(); + sym.annotations.setDeclarationAttributes(declAnnos.toList()); + + List typeAnnotations = typeAnnos.toList(); + + if (type == null) { + // When type is null, put the type annotations to the symbol. + // This is used for constructor return annotations, for which + // no appropriate type exists. + sym.annotations.appendUniqueTypes(typeAnnotations); + return; + } + + // type is non-null and annotations are added to that type + type = typeWithAnnotations(typetree, type, typeAnnotations, log); + + if (sym.getKind() == ElementKind.METHOD) { + sym.type.asMethodType().restype = type; + } else { + sym.type = type; + } + + sym.annotations.appendUniqueTypes(typeAnnotations); + if (sym.getKind() == ElementKind.PARAMETER && + sym.getQualifiedName().equals(names._this)) { + sym.owner.type.asMethodType().recvtype = type; + // note that the typeAnnotations will also be added to the owner below. + } + if (sym.getKind() == ElementKind.PARAMETER || + sym.getKind() == ElementKind.LOCAL_VARIABLE || + sym.getKind() == ElementKind.RESOURCE_VARIABLE || + sym.getKind() == ElementKind.EXCEPTION_PARAMETER) { + // Make sure all type annotations from the symbol are also + // on the owner. + sym.owner.annotations.appendUniqueTypes(sym.getTypeAnnotationMirrors()); + } + } + + // This method has a similar purpose as + // {@link com.sun.tools.javac.parser.JavacParser.insertAnnotationsToMostInner(JCExpression, List, boolean)} + // We found a type annotation in a declaration annotation position, + // for example, on the return type. + // Such an annotation is _not_ part of an JCAnnotatedType tree and we therefore + // need to set its position explicitly. + // The method returns a copy of type that contains these annotations. + private static Type typeWithAnnotations(final JCTree typetree, final Type type, + final List annotations, Log log) { + // System.out.printf("typeWithAnnotations(typetree: %s, type: %s, annotations: %s)%n", + // typetree, type, annotations); + if (annotations.isEmpty()) { + return type; + } + if (type.hasTag(TypeTag.ARRAY)) { + Type toreturn; + Type.ArrayType tomodify; + Type.ArrayType arType; + { + Type touse = type; + if (type.getKind() == TypeKind.ANNOTATED) { + Type.AnnotatedType atype = (Type.AnnotatedType)type; + toreturn = new Type.AnnotatedType(atype.underlyingType); + ((Type.AnnotatedType)toreturn).typeAnnotations = atype.typeAnnotations; + touse = atype.underlyingType; + arType = (Type.ArrayType) touse; + tomodify = new Type.ArrayType(null, arType.tsym); + ((Type.AnnotatedType)toreturn).underlyingType = tomodify; + } else { + arType = (Type.ArrayType) touse; + tomodify = new Type.ArrayType(null, arType.tsym); + toreturn = tomodify; + } + } + JCArrayTypeTree arTree = arrayTypeTree(typetree); + + ListBuffer depth = ListBuffer.lb(); + depth = depth.append(TypePathEntry.ARRAY); + while (arType.elemtype.hasTag(TypeTag.ARRAY)) { + if (arType.elemtype.getKind() == TypeKind.ANNOTATED) { + Type.AnnotatedType aelemtype = (Type.AnnotatedType) arType.elemtype; + Type.AnnotatedType newAT = new Type.AnnotatedType(aelemtype.underlyingType); + tomodify.elemtype = newAT; + newAT.typeAnnotations = aelemtype.typeAnnotations; + arType = (Type.ArrayType) aelemtype.underlyingType; + tomodify = new Type.ArrayType(null, arType.tsym); + newAT.underlyingType = tomodify; + } else { + arType = (Type.ArrayType) arType.elemtype; + tomodify.elemtype = new Type.ArrayType(null, arType.tsym); + tomodify = (Type.ArrayType) tomodify.elemtype; + } + arTree = arrayTypeTree(arTree.elemtype); + depth = depth.append(TypePathEntry.ARRAY); + } + Type arelemType = typeWithAnnotations(arTree.elemtype, arType.elemtype, annotations, log); + tomodify.elemtype = arelemType; + for (Attribute.TypeCompound a : annotations) { + TypeAnnotationPosition p = a.position; + p.location = p.location.prependList(depth.toList()); + } + return toreturn; + } else if (type.hasTag(TypeTag.TYPEVAR)) { + // Nothing to do for type variables. + return type; + } else { + Type enclTy = type; + Element enclEl = type.asElement(); + JCTree enclTr = typetree; + + while (enclEl != null && + enclEl.getKind() != ElementKind.PACKAGE && + enclTy != null && + enclTy.getKind() != TypeKind.NONE && + enclTy.getKind() != TypeKind.ERROR && + (enclTr.getKind() == JCTree.Kind.MEMBER_SELECT || + enclTr.getKind() == JCTree.Kind.PARAMETERIZED_TYPE || + enclTr.getKind() == JCTree.Kind.ANNOTATED_TYPE)) { + // Iterate also over the type tree, not just the type: the type is already + // completely resolved and we cannot distinguish where the annotation + // belongs for a nested type. + if (enclTr.getKind() == JCTree.Kind.MEMBER_SELECT) { + // only change encl in this case. + enclTy = enclTy.getEnclosingType(); + enclEl = enclEl.getEnclosingElement(); + enclTr = ((JCFieldAccess)enclTr).getExpression(); + } else if (enclTr.getKind() == JCTree.Kind.PARAMETERIZED_TYPE) { + enclTr = ((JCTypeApply)enclTr).getType(); + } else { + // only other option because of while condition + enclTr = ((JCAnnotatedType)enclTr).getUnderlyingType(); + } + } + + /** We are trying to annotate some enclosing type, + * but nothing more exists. + */ + if (enclTy != null && + enclTy.getKind() == TypeKind.NONE && + (enclTr.getKind() == JCTree.Kind.IDENTIFIER || + enclTr.getKind() == JCTree.Kind.MEMBER_SELECT || + enclTr.getKind() == JCTree.Kind.PARAMETERIZED_TYPE || + enclTr.getKind() == JCTree.Kind.ANNOTATED_TYPE)) { + // TODO: also if it's "java. @A lang.Object", that is, + // if it's on a package? + log.error(enclTr.pos(), "cant.annotate.nested.type", enclTr.toString()); + return type; + } + + // At this point we have visited the part of the nested + // type that is written in the source code. + // Now count from here to the actual top-level class to determine + // the correct nesting. + + // The genericLocation for the annotation. + ListBuffer depth = ListBuffer.lb(); + + Type topTy = enclTy; + while (enclEl != null && + enclEl.getKind() != ElementKind.PACKAGE && + topTy != null && + topTy.getKind() != TypeKind.NONE && + topTy.getKind() != TypeKind.ERROR) { + topTy = topTy.getEnclosingType(); + enclEl = enclEl.getEnclosingElement(); + + if (topTy != null && topTy.getKind() != TypeKind.NONE) { + // Only count enclosing types. + depth = depth.append(TypePathEntry.INNER_TYPE); + } + } + + if (depth.nonEmpty()) { + // Only need to change the annotation positions + // if they are on an enclosed type. + for (Attribute.TypeCompound a : annotations) { + TypeAnnotationPosition p = a.position; + p.location = p.location.appendList(depth.toList()); + } + } + + Type ret = typeWithAnnotations(type, enclTy, annotations); + return ret; + } + } + + private static JCArrayTypeTree arrayTypeTree(JCTree typetree) { + if (typetree.getKind() == JCTree.Kind.ARRAY_TYPE) { + return (JCArrayTypeTree) typetree; + } else if (typetree.getKind() == JCTree.Kind.ANNOTATED_TYPE) { + return (JCArrayTypeTree) ((JCAnnotatedType)typetree).underlyingType; + } else { + Assert.error("Could not determine array type from type tree: " + typetree); + return null; + } + } + + /** Return a copy of the first type that only differs by + * inserting the annotations to the left-most/inner-most type + * or the type given by stopAt. + * + * We need the stopAt parameter to know where on a type to + * put the annotations. + * If we have nested classes Outer > Middle > Inner, and we + * have the source type "@A Middle.Inner", we will invoke + * this method with type = Outer.Middle.Inner, + * stopAt = Middle.Inner, and annotations = @A. + * + * @param type The type to copy. + * @param stopAt The type to stop at. + * @param annotations The annotations to insert. + * @return A copy of type that contains the annotations. + */ + private static Type typeWithAnnotations(final Type type, + final Type stopAt, + final List annotations) { + Visitor> visitor = + new Type.Visitor>() { + @Override + public Type visitClassType(ClassType t, List s) { + // assert that t.constValue() == null? + if (t == stopAt || + t.getEnclosingType() == Type.noType) { + return new AnnotatedType(s, t); + } else { + ClassType ret = new ClassType(t.getEnclosingType().accept(this, s), + t.typarams_field, t.tsym); + ret.all_interfaces_field = t.all_interfaces_field; + ret.allparams_field = t.allparams_field; + ret.interfaces_field = t.interfaces_field; + ret.rank_field = t.rank_field; + ret.supertype_field = t.supertype_field; + return ret; + } + } + + @Override + public Type visitAnnotatedType(AnnotatedType t, List s) { + return new AnnotatedType(t.typeAnnotations, t.underlyingType.accept(this, s)); + } + + @Override + public Type visitWildcardType(WildcardType t, List s) { + return new AnnotatedType(s, t); + } + + @Override + public Type visitArrayType(ArrayType t, List s) { + ArrayType ret = new ArrayType(t.elemtype.accept(this, s), t.tsym); + return ret; + } + + @Override + public Type visitMethodType(MethodType t, List s) { + // Impossible? + return t; + } + + @Override + public Type visitPackageType(PackageType t, List s) { + // Impossible? + return t; + } + + @Override + public Type visitTypeVar(TypeVar t, List s) { + return new AnnotatedType(s, t); + } + + @Override + public Type visitCapturedType(CapturedType t, List s) { + return new AnnotatedType(s, t); + } + + @Override + public Type visitForAll(ForAll t, List s) { + // Impossible? + return t; + } + + @Override + public Type visitUndetVar(UndetVar t, List s) { + // Impossible? + return t; + } + + @Override + public Type visitErrorType(ErrorType t, List s) { + return new AnnotatedType(s, t); + } + + @Override + public Type visitType(Type t, List s) { + // Error? + return t; + } + }; + + return type.accept(visitor, annotations); + } + + private static Attribute.TypeCompound toTypeCompound(Attribute.Compound a, TypeAnnotationPosition p) { + // It is safe to alias the position. + return new Attribute.TypeCompound(a, p); + } + + private AnnotationType annotationType(Attribute.Compound a, Symbol s) { + Attribute.Compound atTarget = + a.type.tsym.attribute(syms.annotationTargetType.tsym); + if (atTarget == null) { + return inferTargetMetaInfo(a, s); + } + Attribute atValue = atTarget.member(names.value); + if (!(atValue instanceof Attribute.Array)) { + Assert.error("annotationType(): bad @Target argument " + atValue + + " (" + atValue.getClass() + ")"); + return AnnotationType.DECLARATION; // error recovery + } + Attribute.Array arr = (Attribute.Array) atValue; + boolean isDecl = false, isType = false; + for (Attribute app : arr.values) { + if (!(app instanceof Attribute.Enum)) { + Assert.error("annotationType(): unrecognized Attribute kind " + app + + " (" + app.getClass() + ")"); + isDecl = true; + continue; + } + Attribute.Enum e = (Attribute.Enum) app; + if (e.value.name == names.TYPE) { + if (s.kind == Kinds.TYP) + isDecl = true; + } else if (e.value.name == names.FIELD) { + if (s.kind == Kinds.VAR && + s.owner.kind != Kinds.MTH) + isDecl = true; + } else if (e.value.name == names.METHOD) { + if (s.kind == Kinds.MTH && + !s.isConstructor()) + isDecl = true; + } else if (e.value.name == names.PARAMETER) { + if (s.kind == Kinds.VAR && + s.owner.kind == Kinds.MTH && + (s.flags() & Flags.PARAMETER) != 0) + isDecl = true; + } else if (e.value.name == names.CONSTRUCTOR) { + if (s.kind == Kinds.MTH && + s.isConstructor()) + isDecl = true; + } else if (e.value.name == names.LOCAL_VARIABLE) { + if (s.kind == Kinds.VAR && + s.owner.kind == Kinds.MTH && + (s.flags() & Flags.PARAMETER) == 0) + isDecl = true; + } else if (e.value.name == names.ANNOTATION_TYPE) { + if (s.kind == Kinds.TYP && + (s.flags() & Flags.ANNOTATION) != 0) + isDecl = true; + } else if (e.value.name == names.PACKAGE) { + if (s.kind == Kinds.PCK) + isDecl = true; + } else if (e.value.name == names.TYPE_USE) { + if (s.kind == Kinds.TYP || + s.kind == Kinds.VAR || + (s.kind == Kinds.MTH && !s.isConstructor() && + !s.type.getReturnType().hasTag(TypeTag.VOID)) || + (s.kind == Kinds.MTH && s.isConstructor())) + isType = true; + } else if (e.value.name == names.TYPE_PARAMETER) { + /* Irrelevant in this case */ + // TYPE_PARAMETER doesn't aid in distinguishing between + // Type annotations and declaration annotations on an + // Element + } else { + Assert.error("annotationType(): unrecognized Attribute name " + e.value.name + + " (" + e.value.name.getClass() + ")"); + isDecl = true; + } + } + if (isDecl && isType) { + return AnnotationType.BOTH; + } else if (isType) { + return AnnotationType.TYPE; + } else { + return AnnotationType.DECLARATION; + } + } + + /** Infer the target annotation kind, if none is give. + * We only infer declaration annotations. + */ + private static AnnotationType inferTargetMetaInfo(Attribute.Compound a, Symbol s) { + return AnnotationType.DECLARATION; + } + + + /* This is the beginning of the second part of organizing + * type annotations: determine the type annotation positions. + */ + + private void resolveFrame(JCTree tree, JCTree frame, + List path, TypeAnnotationPosition p) { + /* + System.out.println("Resolving tree: " + tree + " kind: " + tree.getKind()); + System.out.println(" Framing tree: " + frame + " kind: " + frame.getKind()); + */ + switch (frame.getKind()) { + case TYPE_CAST: + p.type = TargetType.CAST; + p.pos = frame.pos; + return; + + case INSTANCE_OF: + p.type = TargetType.INSTANCEOF; + p.pos = frame.pos; + return; + + case NEW_CLASS: + JCNewClass frameNewClass = (JCNewClass)frame; + if (frameNewClass.typeargs.contains(tree)) { + p.type = TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT; + p.type_index = frameNewClass.typeargs.indexOf(tree); + } else { + p.type = TargetType.NEW; + } + p.pos = frame.pos; + return; + + case NEW_ARRAY: + p.type = TargetType.NEW; + p.pos = frame.pos; + return; + + case ANNOTATION_TYPE: + case CLASS: + case ENUM: + case INTERFACE: + p.pos = frame.pos; + if (((JCClassDecl)frame).extending == tree) { + p.type = TargetType.CLASS_EXTENDS; + p.type_index = -1; + } else if (((JCClassDecl)frame).implementing.contains(tree)) { + p.type = TargetType.CLASS_EXTENDS; + p.type_index = ((JCClassDecl)frame).implementing.indexOf(tree); + } else if (((JCClassDecl)frame).typarams.contains(tree)) { + p.type = TargetType.CLASS_TYPE_PARAMETER; + p.parameter_index = ((JCClassDecl)frame).typarams.indexOf(tree); + } else { + Assert.error("Could not determine position of tree " + tree + + " within frame " + frame); + } + return; + + case METHOD: { + JCMethodDecl frameMethod = (JCMethodDecl) frame; + p.pos = frame.pos; + if (frameMethod.thrown.contains(tree)) { + p.type = TargetType.THROWS; + p.type_index = frameMethod.thrown.indexOf(tree); + } else if (frameMethod.restype == tree) { + p.type = TargetType.METHOD_RETURN; + } else if (frameMethod.typarams.contains(tree)) { + p.type = TargetType.METHOD_TYPE_PARAMETER; + p.parameter_index = frameMethod.typarams.indexOf(tree); + } else { + Assert.error("Could not determine position of tree " + tree + + " within frame " + frame); + } + return; + } + + case PARAMETERIZED_TYPE: { + if (((JCTypeApply)frame).clazz == tree) { + // generic: RAW; noop + } else if (((JCTypeApply)frame).arguments.contains(tree)) { + JCTypeApply taframe = (JCTypeApply) frame; + int arg = taframe.arguments.indexOf(tree); + p.location = p.location.prepend(new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, arg)); + + locateNestedTypes(taframe.type, p); + } else { + Assert.error("Could not determine type argument position of tree " + tree + + " within frame " + frame); + } + + List newPath = path.tail; + resolveFrame(newPath.head, newPath.tail.head, newPath, p); + return; + } + + case ARRAY_TYPE: { + ListBuffer index = ListBuffer.lb(); + index = index.append(TypePathEntry.ARRAY); + List newPath = path.tail; + while (true) { + JCTree npHead = newPath.tail.head; + if (npHead.hasTag(JCTree.Tag.TYPEARRAY)) { + newPath = newPath.tail; + index = index.append(TypePathEntry.ARRAY); + } else if (npHead.hasTag(JCTree.Tag.ANNOTATED_TYPE)) { + newPath = newPath.tail; + } else { + break; + } + } + p.location = p.location.prependList(index.toList()); + resolveFrame(newPath.head, newPath.tail.head, newPath, p); + return; + } + + case TYPE_PARAMETER: + if (path.tail.tail.head.hasTag(JCTree.Tag.CLASSDEF)) { + JCClassDecl clazz = (JCClassDecl)path.tail.tail.head; + p.type = TargetType.CLASS_TYPE_PARAMETER_BOUND; + p.parameter_index = clazz.typarams.indexOf(path.tail.head); + p.bound_index = ((JCTypeParameter)frame).bounds.indexOf(tree); + if (((JCTypeParameter)frame).bounds.get(0).type.isInterface()) { + // Account for an implicit Object as bound 0 + p.bound_index += 1; + } + } else if (path.tail.tail.head.hasTag(JCTree.Tag.METHODDEF)) { + JCMethodDecl method = (JCMethodDecl)path.tail.tail.head; + p.type = TargetType.METHOD_TYPE_PARAMETER_BOUND; + p.parameter_index = method.typarams.indexOf(path.tail.head); + p.bound_index = ((JCTypeParameter)frame).bounds.indexOf(tree); + if (((JCTypeParameter)frame).bounds.get(0).type.isInterface()) { + // Account for an implicit Object as bound 0 + p.bound_index += 1; + } + } else { + Assert.error("Could not determine position of tree " + tree + + " within frame " + frame); + } + p.pos = frame.pos; + return; + + case VARIABLE: + VarSymbol v = ((JCVariableDecl)frame).sym; + p.pos = frame.pos; + switch (v.getKind()) { + case LOCAL_VARIABLE: + p.type = TargetType.LOCAL_VARIABLE; + break; + case FIELD: + p.type = TargetType.FIELD; + break; + case PARAMETER: + if (v.getQualifiedName().equals(names._this)) { + // TODO: Intro a separate ElementKind? + p.type = TargetType.METHOD_RECEIVER; + } else { + p.type = TargetType.METHOD_FORMAL_PARAMETER; + p.parameter_index = methodParamIndex(path, frame); + } + break; + case EXCEPTION_PARAMETER: + p.type = TargetType.EXCEPTION_PARAMETER; + break; + case RESOURCE_VARIABLE: + p.type = TargetType.RESOURCE_VARIABLE; + break; + default: + Assert.error("Found unexpected type annotation for variable: " + v + " with kind: " + v.getKind()); + } + return; + + case ANNOTATED_TYPE: { + if (frame == tree) { + // This is only true for the first annotated type we see. + // For any other annotated types along the path, we do + // not care about inner types. + JCAnnotatedType atypetree = (JCAnnotatedType) frame; + final Type utype = atypetree.underlyingType.type; + Symbol tsym = utype.tsym; + if (tsym.getKind().equals(ElementKind.TYPE_PARAMETER) || + utype.getKind().equals(TypeKind.WILDCARD) || + utype.getKind().equals(TypeKind.ARRAY)) { + // Type parameters, wildcards, and arrays have the declaring + // class/method as enclosing elements. + // There is actually nothing to do for them. + } else { + locateNestedTypes(utype, p); + } + } + List newPath = path.tail; + resolveFrame(newPath.head, newPath.tail.head, newPath, p); + return; + } + + case UNION_TYPE: { + // TODO: can we store any information here to help in + // determining the final position? + List newPath = path.tail; + resolveFrame(newPath.head, newPath.tail.head, newPath, p); + return; + } + + case METHOD_INVOCATION: { + JCMethodInvocation invocation = (JCMethodInvocation)frame; + if (!invocation.typeargs.contains(tree)) { + Assert.error("{" + tree + "} is not an argument in the invocation: " + invocation); + } + p.type = TargetType.METHOD_INVOCATION_TYPE_ARGUMENT; + p.pos = invocation.pos; + p.type_index = invocation.typeargs.indexOf(tree); + return; + } + + case EXTENDS_WILDCARD: + case SUPER_WILDCARD: { + // Annotations in wildcard bounds + p.location = p.location.prepend(TypePathEntry.WILDCARD); + List newPath = path.tail; + resolveFrame(newPath.head, newPath.tail.head, newPath, p); + return; + } + + case MEMBER_SELECT: { + List newPath = path.tail; + resolveFrame(newPath.head, newPath.tail.head, newPath, p); + return; + } + + default: + Assert.error("Unresolved frame: " + frame + " of kind: " + frame.getKind() + + "\n Looking for tree: " + tree); + return; + } + } + + private static void locateNestedTypes(Type type, TypeAnnotationPosition p) { + // The number of "steps" to get from the full type to the + // left-most outer type. + ListBuffer depth = ListBuffer.lb(); + + Type encl = type.getEnclosingType(); + while (encl != null && + encl.getKind() != TypeKind.NONE && + encl.getKind() != TypeKind.ERROR) { + depth = depth.append(TypePathEntry.INNER_TYPE); + encl = encl.getEnclosingType(); + } + if (depth.nonEmpty()) { + p.location = p.location.prependList(depth.toList()); + } + } + + private static int methodParamIndex(List path, JCTree param) { + List curr = path; + while (curr.head.getTag() != Tag.METHODDEF) { + curr = curr.tail; + } + JCMethodDecl method = (JCMethodDecl)curr.head; + return method.params.indexOf(param); + } + + // Each class (including enclosed inner classes) is visited separately. + // This flag is used to prevent from visiting inner classes. + private boolean isInClass = false; + + @Override + public void visitClassDef(JCClassDecl tree) { + if (isInClass) + return; + isInClass = true; + if (sigOnly) { + scan(tree.mods); + scan(tree.typarams); + scan(tree.extending); + scan(tree.implementing); + } + scan(tree.defs); + } + + /** + * Resolve declaration vs. type annotations in methods and + * then determine the positions. + */ + @Override + public void visitMethodDef(final JCMethodDecl tree) { + if (tree.sym == null) { + // Something most be wrong, e.g. a class not found. + // Quietly ignore. (See test FailOver15.java) + return; + } + if (sigOnly) { + { + TypeAnnotationPosition pos = new TypeAnnotationPosition(); + pos.type = TargetType.METHOD_RETURN; + if (tree.sym.isConstructor()) { + pos.pos = tree.pos; + // Use null to mark that the annotations go with the symbol. + separateAnnotationsKinds(tree, null, tree.sym, pos); + } else { + pos.pos = tree.restype.pos; + separateAnnotationsKinds(tree.restype, tree.sym.type.getReturnType(), + tree.sym, pos); + } + } + if (tree.recvparam != null && tree.recvparam.sym != null) { + // TODO: make sure there are no declaration annotations. + TypeAnnotationPosition pos = new TypeAnnotationPosition(); + pos.type = TargetType.METHOD_RECEIVER; + pos.pos = tree.recvparam.vartype.pos; + separateAnnotationsKinds(tree.recvparam.vartype, tree.recvparam.sym.type, + tree.recvparam.sym, pos); + } + int i = 0; + for (JCVariableDecl param : tree.params) { + TypeAnnotationPosition pos = new TypeAnnotationPosition(); + pos.type = TargetType.METHOD_FORMAL_PARAMETER; + pos.parameter_index = i; + pos.pos = param.vartype.pos; + separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos); + ++i; + } + } + + push(tree); + // super.visitMethodDef(tree); + if (sigOnly) { + scan(tree.mods); + scan(tree.restype); + scan(tree.typarams); + scan(tree.recvparam); + scan(tree.params); + scan(tree.thrown); + } else { + scan(tree.defaultValue); + scan(tree.body); + } + pop(); + } + + /** + * Resolve declaration vs. type annotations in variable declarations and + * then determine the positions. + */ + @Override + public void visitVarDef(final JCVariableDecl tree) { + if (tree.sym == null) { + // Something is wrong already. Quietly ignore. + } else if (tree.sym.getKind() == ElementKind.FIELD) { + if (sigOnly) { + TypeAnnotationPosition pos = new TypeAnnotationPosition(); + pos.type = TargetType.FIELD; + pos.pos = tree.pos; + separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos); + } + } else if (tree.sym.getKind() == ElementKind.LOCAL_VARIABLE) { + TypeAnnotationPosition pos = new TypeAnnotationPosition(); + pos.type = TargetType.LOCAL_VARIABLE; + pos.pos = tree.pos; + separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos); + } else if (tree.sym.getKind() == ElementKind.EXCEPTION_PARAMETER) { + // System.out.println("Found exception param: " + tree); + TypeAnnotationPosition pos = new TypeAnnotationPosition(); + pos.type = TargetType.EXCEPTION_PARAMETER; + pos.pos = tree.pos; + separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos); + } else if (tree.sym.getKind() == ElementKind.RESOURCE_VARIABLE) { + TypeAnnotationPosition pos = new TypeAnnotationPosition(); + pos.type = TargetType.RESOURCE_VARIABLE; + pos.pos = tree.pos; + separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos); + } else { + // There is nothing else in a variable declaration that needs separation. + // System.out.println("We found a: " + tree); + } + + push(tree); + // super.visitVarDef(tree); + scan(tree.mods); + scan(tree.vartype); + if (!sigOnly) { + scan(tree.init); + } + pop(); + } + + @Override + public void visitBlock(JCBlock tree) { + // Do not descend into top-level blocks when only interested + // in the signature. + if (!sigOnly) { + scan(tree.stats); + } + } + + @Override + public void visitAnnotatedType(JCAnnotatedType tree) { + push(tree); + findPosition(tree, tree, tree.annotations); + pop(); + super.visitAnnotatedType(tree); + } + + @Override + public void visitTypeParameter(JCTypeParameter tree) { + findPosition(tree, peek2(), tree.annotations); + super.visitTypeParameter(tree); + } + + @Override + public void visitNewArray(JCNewArray tree) { + findPosition(tree, tree, tree.annotations); + int dimAnnosCount = tree.dimAnnotations.size(); + ListBuffer depth = ListBuffer.lb(); + + // handle annotations associated with dimensions + for (int i = 0; i < dimAnnosCount; ++i) { + TypeAnnotationPosition p = new TypeAnnotationPosition(); + p.pos = tree.pos; + p.type = TargetType.NEW; + if (i != 0) { + depth = depth.append(TypePathEntry.ARRAY); + p.location = p.location.appendList(depth.toList()); + } + + setTypeAnnotationPos(tree.dimAnnotations.get(i), p); + } + + // handle "free" annotations + // int i = dimAnnosCount == 0 ? 0 : dimAnnosCount - 1; + // TODO: is depth.size == i here? + JCExpression elemType = tree.elemtype; + while (elemType != null) { + if (elemType.hasTag(JCTree.Tag.ANNOTATED_TYPE)) { + JCAnnotatedType at = (JCAnnotatedType)elemType; + TypeAnnotationPosition p = new TypeAnnotationPosition(); + p.type = TargetType.NEW; + p.pos = tree.pos; + p.location = p.location.appendList(depth.toList()); + setTypeAnnotationPos(at.annotations, p); + elemType = at.underlyingType; + } else if (elemType.hasTag(JCTree.Tag.TYPEARRAY)) { + depth = depth.append(TypePathEntry.ARRAY); + elemType = ((JCArrayTypeTree)elemType).elemtype; + } else { + break; + } + } + scan(tree.elems); + } + + private void findPosition(JCTree tree, JCTree frame, List annotations) { + if (!annotations.isEmpty()) { + /* + System.out.println("Finding pos for: " + annotations); + System.out.println(" tree: " + tree); + System.out.println(" frame: " + frame); + */ + TypeAnnotationPosition p = new TypeAnnotationPosition(); + resolveFrame(tree, frame, frames.toList(), p); + setTypeAnnotationPos(annotations, p); + } + } + + private static void setTypeAnnotationPos(List annotations, + TypeAnnotationPosition position) { + for (JCAnnotation anno : annotations) { + ((Attribute.TypeCompound) anno.attribute).position = position; + } + } + } +} diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java index 23a25738e2d..f7fa66625ef 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -34,13 +34,14 @@ import java.util.Map; import java.util.Set; import java.util.WeakHashMap; +import javax.lang.model.type.TypeKind; + import com.sun.tools.javac.code.Attribute.RetentionPolicy; import com.sun.tools.javac.code.Lint.LintCategory; import com.sun.tools.javac.code.Type.UndetVar.InferenceBound; import com.sun.tools.javac.comp.Check; import com.sun.tools.javac.jvm.ClassReader; import com.sun.tools.javac.util.*; -import com.sun.tools.javac.util.List; import static com.sun.tools.javac.code.BoundKind.*; import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Scope.*; @@ -684,6 +685,8 @@ public class Types { //where private boolean isSubtypeUncheckedInternal(Type t, Type s, Warner warn) { if (t.hasTag(ARRAY) && s.hasTag(ARRAY)) { + t = t.unannotatedType(); + s = s.unannotatedType(); if (((ArrayType)t).elemtype.isPrimitive()) { return isSameType(elemtype(t), elemtype(s)); } else { @@ -709,7 +712,10 @@ public class Types { } private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) { - if (t.tag != ARRAY || isReifiable(t)) return; + if (t.tag != ARRAY || isReifiable(t)) + return; + t = t.unannotatedType(); + s = s.unannotatedType(); ArrayType from = (ArrayType)t; boolean shouldWarn = false; switch (s.tag) { @@ -739,6 +745,12 @@ public class Types { return isSubtype(t, s, false); } public boolean isSubtype(Type t, Type s, boolean capture) { + if (t == s) + return true; + + t = t.unannotatedType(); + s = s.unannotatedType(); + if (t == s) return true; @@ -1683,6 +1695,7 @@ public class Types { case WILDCARD: return elemtype(upperBound(t)); case ARRAY: + t = t.unannotatedType(); return ((ArrayType)t).elemtype; case FORALL: return elemtype(((ForAll)t).qtype); @@ -2011,6 +2024,11 @@ public class Types { public Type visitErrorType(ErrorType t, Boolean recurse) { return t; } + + @Override + public Type visitAnnotatedType(AnnotatedType t, Boolean recurse) { + return new AnnotatedType(t.typeAnnotations, erasure(t.underlyingType, recurse)); + } }; private Mapping erasureFun = new Mapping ("erasure") { @@ -2953,6 +2971,7 @@ public class Types { * graph. Undefined for all but reference types. */ public int rank(Type t) { + t = t.unannotatedType(); switch(t.tag) { case CLASS: { ClassType cls = (ClassType)t; @@ -3654,6 +3673,7 @@ public class Types { t = subst(type1, t.tsym.type.getTypeArguments(), t.getTypeArguments()); } } + t = t.unannotatedType(); ClassType cls = (ClassType)t; if (cls.isRaw() || !cls.isParameterized()) return cls; @@ -4172,6 +4192,8 @@ public class Types { public R visitForAll(ForAll t, S s) { return visitType(t, s); } public R visitUndetVar(UndetVar t, S s) { return visitType(t, s); } public R visitErrorType(ErrorType t, S s) { return visitType(t, s); } + // Pretend annotations don't exist + public R visitAnnotatedType(AnnotatedType t, S s) { return visit(t.underlyingType, s); } } /** diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java index a2cd3851742..678d2c2bb6a 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java @@ -26,6 +26,7 @@ package com.sun.tools.javac.comp; import java.util.Map; + import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.code.*; @@ -87,20 +88,30 @@ public class Annotate { private int enterCount = 0; ListBuffer q = new ListBuffer(); + ListBuffer typesQ = new ListBuffer(); ListBuffer repeatedQ = new ListBuffer(); - - public void normal(Annotator a) { - q.append(a); - } + ListBuffer afterRepeatedQ = new ListBuffer(); public void earlier(Annotator a) { q.prepend(a); } + public void normal(Annotator a) { + q.append(a); + } + + public void typeAnnotation(Annotator a) { + typesQ.append(a); + } + public void repeated(Annotator a) { repeatedQ.append(a); } + public void afterRepeated(Annotator a) { + afterRepeatedQ.append(a); + } + /** Called when the Enter phase starts. */ public void enterStart() { enterCount++; @@ -116,12 +127,18 @@ public class Annotate { if (enterCount != 0) return; enterCount++; try { - while (q.nonEmpty()) + while (q.nonEmpty()) { q.next().enterAnnotation(); - + } + while (typesQ.nonEmpty()) { + typesQ.next().enterAnnotation(); + } while (repeatedQ.nonEmpty()) { repeatedQ.next().enterAnnotation(); } + while (afterRepeatedQ.nonEmpty()) { + afterRepeatedQ.next().enterAnnotation(); + } } finally { enterCount--; } @@ -141,16 +158,18 @@ public class Annotate { * This context contains all the information needed to synthesize new * annotations trees by the completer for repeating annotations. */ - public class AnnotateRepeatedContext { + public class AnnotateRepeatedContext { public final Env env; - public final Map> annotated; - public final Map pos; + public final Map> annotated; + public final Map pos; public final Log log; + public final boolean isTypeCompound; public AnnotateRepeatedContext(Env env, - Map> annotated, - Map pos, - Log log) { + Map> annotated, + Map pos, + Log log, + boolean isTypeCompound) { Assert.checkNonNull(env); Assert.checkNonNull(annotated); Assert.checkNonNull(pos); @@ -160,6 +179,7 @@ public class Annotate { this.annotated = annotated; this.pos = pos; this.log = log; + this.isTypeCompound = isTypeCompound; } /** @@ -170,7 +190,7 @@ public class Annotate { * @param repeatingAnnotations a List of repeating annotations * @return a new Attribute.Compound that is the container for the repeatingAnnotations */ - public Attribute.Compound processRepeatedAnnotations(List repeatingAnnotations, Symbol sym) { + public T processRepeatedAnnotations(List repeatingAnnotations, Symbol sym) { return Annotate.this.processRepeatedAnnotations(repeatingAnnotations, this, sym); } @@ -246,7 +266,12 @@ public class Annotate { ((MethodSymbol)method, value)); t.type = result; } - return new Attribute.Compound(a.type, buf.toList()); + // TODO: this should be a TypeCompound if "a" is a JCTypeAnnotation. + // However, how do we find the correct position? + Attribute.Compound ac = new Attribute.Compound(a.type, buf.toList()); + // TODO: is this something we want? Who would use it? + // a.attribute = ac; + return ac; } Attribute enterAttributeValue(Type expected, @@ -329,6 +354,15 @@ public class Annotate { return new Attribute.Error(attr.attribExpr(tree, env, expected)); } + Attribute.TypeCompound enterTypeAnnotation(JCAnnotation a, + Type expected, + Env env) { + Attribute.Compound c = enterAnnotation(a, expected, env); + Attribute.TypeCompound tc = new Attribute.TypeCompound(c.type, c.values, new TypeAnnotationPosition()); + a.attribute = tc; + return tc; + } + /* ********************************* * Support for repeating annotations ***********************************/ @@ -337,10 +371,10 @@ public class Annotate { * synthesized container annotation or null IFF all repeating * annotation are invalid. This method reports errors/warnings. */ - private Attribute.Compound processRepeatedAnnotations(List annotations, - AnnotateRepeatedContext ctx, - Symbol on) { - Attribute.Compound firstOccurrence = annotations.head; + private T processRepeatedAnnotations(List annotations, + AnnotateRepeatedContext ctx, + Symbol on) { + T firstOccurrence = annotations.head; List repeated = List.nil(); Type origAnnoType = null; Type arrayOfOrigAnnoType = null; @@ -350,16 +384,16 @@ public class Annotate { Assert.check(!annotations.isEmpty() && !annotations.tail.isEmpty()); // i.e. size() > 1 - for (List al = annotations; + for (List al = annotations; !al.isEmpty(); al = al.tail) { - Attribute.Compound currentAnno = al.head; + T currentAnno = al.head; origAnnoType = currentAnno.type; if (arrayOfOrigAnnoType == null) { arrayOfOrigAnnoType = types.makeArrayType(origAnnoType); -} + } Type currentContainerType = getContainingType(currentAnno, ctx.pos.get(currentAnno)); if (currentContainerType == null) { @@ -383,25 +417,46 @@ public class Annotate { if (!repeated.isEmpty()) { repeated = repeated.reverse(); - JCAnnotation annoTree; TreeMaker m = make.at(ctx.pos.get(firstOccurrence)); Pair p = new Pair(containerValueSymbol, new Attribute.Array(arrayOfOrigAnnoType, repeated)); - annoTree = m.Annotation(new Attribute.Compound(targetContainerType, - List.of(p))); + if (ctx.isTypeCompound) { + /* TODO: the following code would be cleaner: + Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p), + ((Attribute.TypeCompound)annotations.head).position); + JCTypeAnnotation annoTree = m.TypeAnnotation(at); + at = enterTypeAnnotation(annoTree, targetContainerType, ctx.env); + */ + // However, we directly construct the TypeCompound to keep the + // direct relation to the contained TypeCompounds. + Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p), + ((Attribute.TypeCompound)annotations.head).position); - if (!chk.annotationApplicable(annoTree, on)) - log.error(annoTree.pos(), "invalid.repeatable.annotation.incompatible.target", targetContainerType, origAnnoType); + // TODO: annotation applicability checks from below? - if (!chk.validateAnnotationDeferErrors(annoTree)) - log.error(annoTree.pos(), "duplicate.annotation.invalid.repeated", origAnnoType); + at.setSynthesized(true); - Attribute.Compound c = enterAnnotation(annoTree, - targetContainerType, - ctx.env); - c.setSynthesized(true); - return c; + @SuppressWarnings("unchecked") + T x = (T) at; + return x; + } else { + Attribute.Compound c = new Attribute.Compound(targetContainerType, List.of(p)); + JCAnnotation annoTree = m.Annotation(c); + + if (!chk.annotationApplicable(annoTree, on)) + log.error(annoTree.pos(), "invalid.repeatable.annotation.incompatible.target", targetContainerType, origAnnoType); + + if (!chk.validateAnnotationDeferErrors(annoTree)) + log.error(annoTree.pos(), "duplicate.annotation.invalid.repeated", origAnnoType); + + c = enterAnnotation(annoTree, targetContainerType, ctx.env); + c.setSynthesized(true); + + @SuppressWarnings("unchecked") + T x = (T) c; + return x; + } } else { return null; // errors should have been reported elsewhere } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index 20ddc1c09f5..db09cf5ed9b 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -26,9 +26,9 @@ package com.sun.tools.javac.comp; import java.util.*; -import java.util.Set; import javax.lang.model.element.ElementKind; +import javax.lang.model.type.TypeKind; import javax.tools.JavaFileObject; import com.sun.source.tree.IdentifierTree; @@ -45,7 +45,6 @@ import com.sun.tools.javac.comp.DeferredAttr.AttrMode; import com.sun.tools.javac.comp.Infer.InferenceContext; import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener; import com.sun.tools.javac.jvm.*; -import com.sun.tools.javac.jvm.Target; import com.sun.tools.javac.tree.*; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*; @@ -880,6 +879,7 @@ public class Attr extends JCTree.Visitor { deferredLintHandler.flush(tree.pos()); chk.checkDeprecatedAnnotation(tree.pos(), m); + // Create a new environment with local scope // for attributing the method. Env localEnv = memberEnter.methodEnv(tree, env); @@ -923,6 +923,21 @@ public class Attr extends JCTree.Visitor { // Check that result type is well-formed. chk.validate(tree.restype, localEnv); + // Check that receiver type is well-formed. + if (tree.recvparam != null) { + // Use a new environment to check the receiver parameter. + // Otherwise I get "might not have been initialized" errors. + // Is there a better way? + Env newEnv = memberEnter.methodEnv(tree, env); + attribType(tree.recvparam, newEnv); + chk.validate(tree.recvparam, newEnv); + if (!(tree.recvparam.type == m.owner.type || types.isSameType(tree.recvparam.type, m.owner.type))) { + // The == covers the common non-generic case, but for generic classes we need isSameType; + // note that equals didn't work. + log.error(tree.recvparam.pos(), "incorrect.receiver.type"); + } + } + // annotation method checks if ((owner.flags() & ANNOTATION) != 0) { // annotation method cannot have throws clause @@ -996,9 +1011,14 @@ public class Attr extends JCTree.Visitor { } } + // Attribute all type annotations in the body + memberEnter.typeAnnotate(tree.body, localEnv, m); + annotate.flush(); + // Attribute method body. attribStat(tree.body, localEnv); } + localEnv.info.scope.leave(); result = tree.type = m.type; chk.validateAnnotations(tree.mods.annotations, m); @@ -1019,6 +1039,12 @@ public class Attr extends JCTree.Visitor { memberEnter.memberEnter(tree, env); annotate.flush(); } + } else { + if (tree.init != null) { + // Field initializer expression need to be entered. + memberEnter.typeAnnotate(tree.init, env, tree.sym); + annotate.flush(); + } } VarSymbol v = tree.sym; @@ -1076,6 +1102,11 @@ public class Attr extends JCTree.Visitor { new MethodSymbol(tree.flags | BLOCK, names.empty, null, env.info.scope.owner); if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++; + + // Attribute all type annotations in the block + memberEnter.typeAnnotate(tree, localEnv, localEnv.info.scope.owner); + annotate.flush(); + attribStats(tree.stats, localEnv); } else { // Create a new local environment with a local scope. @@ -1847,10 +1878,24 @@ public class Attr extends JCTree.Visitor { // If enclosing class is given, attribute it, and // complete class name to be fully qualified JCExpression clazz = tree.clazz; // Class field following new - JCExpression clazzid = // Identifier in class field - (clazz.hasTag(TYPEAPPLY)) - ? ((JCTypeApply) clazz).clazz - : clazz; + JCExpression clazzid; // Identifier in class field + JCAnnotatedType annoclazzid; // Annotated type enclosing clazzid + annoclazzid = null; + + if (clazz.hasTag(TYPEAPPLY)) { + clazzid = ((JCTypeApply) clazz).clazz; + if (clazzid.hasTag(ANNOTATED_TYPE)) { + annoclazzid = (JCAnnotatedType) clazzid; + clazzid = annoclazzid.underlyingType; + } + } else { + if (clazz.hasTag(ANNOTATED_TYPE)) { + annoclazzid = (JCAnnotatedType) clazz; + clazzid = annoclazzid.underlyingType; + } else { + clazzid = clazz; + } + } JCExpression clazzid1 = clazzid; // The same in fully qualified form @@ -1865,14 +1910,30 @@ public class Attr extends JCTree.Visitor { // yields a clazz T.C. Type encltype = chk.checkRefType(tree.encl.pos(), attribExpr(tree.encl, env)); + // TODO 308: in .new C, do we also want to add the type annotations + // from expr to the combined type, or not? Yes, do this. clazzid1 = make.at(clazz.pos).Select(make.Type(encltype), ((JCIdent) clazzid).name); - if (clazz.hasTag(TYPEAPPLY)) - clazz = make.at(tree.pos). + + if (clazz.hasTag(ANNOTATED_TYPE)) { + JCAnnotatedType annoType = (JCAnnotatedType) clazz; + List annos = annoType.annotations; + + if (annoType.underlyingType.hasTag(TYPEAPPLY)) { + clazzid1 = make.at(tree.pos). + TypeApply(clazzid1, + ((JCTypeApply) clazz).arguments); + } + + clazzid1 = make.at(tree.pos). + AnnotatedType(annos, clazzid1); + } else if (clazz.hasTag(TYPEAPPLY)) { + clazzid1 = make.at(tree.pos). TypeApply(clazzid1, ((JCTypeApply) clazz).arguments); - else - clazz = clazzid1; + } + + clazz = clazzid1; } // Attribute clazz expression and store @@ -1889,6 +1950,9 @@ public class Attr extends JCTree.Visitor { tree.clazz.type = clazztype; TreeInfo.setSymbol(clazzid, TreeInfo.symbol(clazzid1)); clazzid.type = ((JCIdent) clazzid).sym.type; + if (annoclazzid != null) { + annoclazzid.type = clazzid.type; + } if (!clazztype.isErroneous()) { if (cdef != null && clazztype.tsym.isInterface()) { log.error(tree.encl.pos(), "anon.class.impl.intf.no.qual.for.new"); @@ -3255,8 +3319,18 @@ public class Attr extends JCTree.Visitor { // Tree.Visitor. else if (ownOuter.hasTag(CLASS) && site != ownOuter) { Type normOuter = site; - if (normOuter.hasTag(CLASS)) + if (normOuter.hasTag(CLASS)) { normOuter = types.asEnclosingSuper(site, ownOuter.tsym); + if (site.getKind() == TypeKind.ANNOTATED) { + // Propagate any type annotations. + // TODO: should asEnclosingSuper do this? + // Note that the type annotations in site will be updated + // by annotateType. Therefore, modify site instead + // of creating a new AnnotatedType. + ((AnnotatedType)site).underlyingType = normOuter; + normOuter = site; + } + } if (normOuter == null) // perhaps from an import normOuter = types.erasure(ownOuter); if (normOuter != ownOuter) @@ -3644,8 +3718,15 @@ public class Attr extends JCTree.Visitor { tree.type = result = checkIntersection(tree, tree.bounds); } - public void visitTypeParameter(JCTypeParameter tree) { - TypeVar typeVar = (TypeVar)tree.type; + public void visitTypeParameter(JCTypeParameter tree) { + TypeVar typeVar = (TypeVar) tree.type; + + if (tree.annotations != null && tree.annotations.nonEmpty()) { + AnnotatedType antype = new AnnotatedType(typeVar); + annotateType(antype, tree.annotations); + tree.type = antype; + } + if (!typeVar.bound.isErroneous()) { //fixup type-parameter bound computed in 'attribTypeVariables' typeVar.bound = checkIntersection(tree, tree.bounds); @@ -3741,6 +3822,44 @@ public class Attr extends JCTree.Visitor { result = tree.type = syms.errType; } + public void visitAnnotatedType(JCAnnotatedType tree) { + Type underlyingType = attribType(tree.getUnderlyingType(), env); + this.attribAnnotationTypes(tree.annotations, env); + AnnotatedType antype = new AnnotatedType(underlyingType); + annotateType(antype, tree.annotations); + result = tree.type = antype; + } + + /** + * Apply the annotations to the particular type. + */ + public void annotateType(final AnnotatedType type, final List annotations) { + if (annotations.isEmpty()) + return; + annotate.typeAnnotation(new Annotate.Annotator() { + @Override + public String toString() { + return "annotate " + annotations + " onto " + type; + } + @Override + public void enterAnnotation() { + List compounds = fromAnnotations(annotations); + type.typeAnnotations = compounds; + } + }); + } + + private static List fromAnnotations(List annotations) { + if (annotations.isEmpty()) + return List.nil(); + + ListBuffer buf = ListBuffer.lb(); + for (JCAnnotation anno : annotations) { + buf.append((Attribute.TypeCompound) anno.attribute); + } + return buf.toList(); + } + public void visitErroneous(JCErroneous tree) { if (tree.errs != null) for (JCTree err : tree.errs) @@ -3972,6 +4091,12 @@ public class Attr extends JCTree.Visitor { (c.flags() & ABSTRACT) == 0) { checkSerialVersionUID(tree, c); } + + // Correctly organize the postions of the type annotations + TypeAnnotations.organizeTypeAnnotationsBodies(this.syms, this.names, this.log, tree); + + // Check type annotations applicability rules + validateTypeAnnotations(tree); } // where /** get a diagnostic position for an attribute of Type t, or null if attribute missing */ @@ -4029,6 +4154,94 @@ public class Attr extends JCTree.Visitor { return types.capture(type); } + private void validateTypeAnnotations(JCTree tree) { + tree.accept(typeAnnotationsValidator); + } + //where + private final JCTree.Visitor typeAnnotationsValidator = + new TreeScanner() { + public void visitAnnotation(JCAnnotation tree) { + if (tree.hasTag(TYPE_ANNOTATION)) { + // TODO: It seems to WMD as if the annotation in + // parameters, in particular also the recvparam, are never + // of type JCTypeAnnotation and therefore never checked! + // Luckily this check doesn't really do anything that isn't + // also done elsewhere. + chk.validateTypeAnnotation(tree, false); + } + super.visitAnnotation(tree); + } + public void visitTypeParameter(JCTypeParameter tree) { + chk.validateTypeAnnotations(tree.annotations, true); + scan(tree.bounds); + // Don't call super. + // This is needed because above we call validateTypeAnnotation with + // false, which would forbid annotations on type parameters. + // super.visitTypeParameter(tree); + } + public void visitMethodDef(JCMethodDecl tree) { + // Static methods cannot have receiver type annotations. + // In test case FailOver15.java, the nested method getString has + // a null sym, because an unknown class is instantiated. + // I would say it's safe to skip. + if (tree.sym != null && (tree.sym.flags() & Flags.STATIC) != 0) { + if (tree.recvparam != null) { + // TODO: better error message. Is the pos good? + log.error(tree.recvparam.pos(), "annotation.type.not.applicable"); + } + } + if (tree.restype != null && tree.restype.type != null) { + validateAnnotatedType(tree.restype, tree.restype.type); + } + super.visitMethodDef(tree); + } + public void visitVarDef(final JCVariableDecl tree) { + if (tree.sym != null && tree.sym.type != null) + validateAnnotatedType(tree, tree.sym.type); + super.visitVarDef(tree); + } + public void visitTypeCast(JCTypeCast tree) { + if (tree.clazz != null && tree.clazz.type != null) + validateAnnotatedType(tree.clazz, tree.clazz.type); + super.visitTypeCast(tree); + } + public void visitTypeTest(JCInstanceOf tree) { + if (tree.clazz != null && tree.clazz.type != null) + validateAnnotatedType(tree.clazz, tree.clazz.type); + super.visitTypeTest(tree); + } + // TODO: what else do we need? + // public void visitNewClass(JCNewClass tree) { + // public void visitNewArray(JCNewArray tree) { + + /* I would want to model this after + * com.sun.tools.javac.comp.Check.Validator.visitSelectInternal(JCFieldAccess) + * and override visitSelect and visitTypeApply. + * However, we only set the annotated type in the top-level type + * of the symbol. + * Therefore, we need to override each individual location where a type + * can occur. + */ + private void validateAnnotatedType(final JCTree errtree, final Type type) { + if (type.getEnclosingType() != null && + type != type.getEnclosingType()) { + validateEnclosingAnnotatedType(errtree, type.getEnclosingType()); + } + for (Type targ : type.getTypeArguments()) { + validateAnnotatedType(errtree, targ); + } + } + private void validateEnclosingAnnotatedType(final JCTree errtree, final Type type) { + validateAnnotatedType(errtree, type); + if (type.tsym != null && + type.tsym.isStatic() && + type.getAnnotations().nonEmpty()) { + // Enclosing static classes cannot have type annotations. + log.error(errtree.pos(), "cant.annotate.static.class"); + } + } + }; + // /** diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index ed38ae7042c..43283c8154f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -26,7 +26,7 @@ package com.sun.tools.javac.comp; import java.util.*; -import java.util.Set; + import javax.tools.JavaFileManager; import com.sun.tools.javac.code.*; @@ -101,6 +101,9 @@ public class Check { context.put(checkKey, this); names = Names.instance(context); + dfltTargetMeta = new Name[] { names.PACKAGE, names.TYPE, + names.FIELD, names.METHOD, names.CONSTRUCTOR, + names.ANNOTATION_TYPE, names.LOCAL_VARIABLE, names.PARAMETER}; log = Log.instance(context); rs = Resolve.instance(context); syms = Symtab.instance(context); @@ -572,35 +575,28 @@ public class Check { if (!tree.type.isErroneous() && (env.info.lint == null || env.info.lint.isEnabled(Lint.LintCategory.CAST)) && types.isSameType(tree.expr.type, tree.clazz.type) + && !(ignoreAnnotatedCasts && TreeInfo.containsTypeAnnotation(tree.clazz)) && !is292targetTypeCast(tree)) { log.warning(Lint.LintCategory.CAST, tree.pos(), "redundant.cast", tree.expr.type); } } //where - private boolean is292targetTypeCast(JCTypeCast tree) { - boolean is292targetTypeCast = false; - JCExpression expr = TreeInfo.skipParens(tree.expr); - if (expr.hasTag(APPLY)) { - JCMethodInvocation apply = (JCMethodInvocation)expr; - Symbol sym = TreeInfo.symbol(apply.meth); - is292targetTypeCast = sym != null && - sym.kind == MTH && - (sym.flags() & HYPOTHETICAL) != 0; - } - return is292targetTypeCast; + private boolean is292targetTypeCast(JCTypeCast tree) { + boolean is292targetTypeCast = false; + JCExpression expr = TreeInfo.skipParens(tree.expr); + if (expr.hasTag(APPLY)) { + JCMethodInvocation apply = (JCMethodInvocation)expr; + Symbol sym = TreeInfo.symbol(apply.meth); + is292targetTypeCast = sym != null && + sym.kind == MTH && + (sym.flags() & HYPOTHETICAL) != 0; } - - - -//where - /** Is type a type variable, or a (possibly multi-dimensional) array of - * type variables? - */ - boolean isTypeVar(Type t) { - return t.hasTag(TYPEVAR) || t.hasTag(ARRAY) && isTypeVar(types.elemtype(t)); + return is292targetTypeCast; } + private static final boolean ignoreAnnotatedCasts = true; + /** Check that a type is within some bounds. * * Used in TypeApply to verify that, e.g., X in {@code V} is a valid @@ -853,7 +849,7 @@ public class Check { // System.out.println("actuals: " + argtypes); List formals = owntype.getParameterTypes(); Type last = useVarargs ? formals.last() : null; - if (sym.name==names.init && + if (sym.name == names.init && sym.owner == syms.enumSym) formals = formals.tail.tail; List args = argtrees; @@ -1326,6 +1322,11 @@ public class Check { } } + @Override + public void visitAnnotatedType(JCAnnotatedType tree) { + tree.underlyingType.accept(this); + } + /** Default visitor method: do nothing. */ @Override @@ -2246,7 +2247,7 @@ public class Check { void checkImplementations(JCClassDecl tree) { checkImplementations(tree, tree.sym, tree.sym); } -//where + //where /** Check that all methods which implement some * method in `ic' conform to the method they implement. */ @@ -2587,6 +2588,13 @@ public class Check { validateAnnotation(a, s); } + /** Check the type annotations. + */ + public void validateTypeAnnotations(List annotations, boolean isTypeParameter) { + for (JCAnnotation a : annotations) + validateTypeAnnotation(a, isTypeParameter); + } + /** Check an annotation of a symbol. */ private void validateAnnotation(JCAnnotation a, Symbol s) { @@ -2613,6 +2621,14 @@ public class Check { } } + public void validateTypeAnnotation(JCAnnotation a, boolean isTypeParameter) { + Assert.checkNonNull(a.type, "annotation tree hasn't been attributed yet: " + a); + validateAnnotationTree(a); + + if (!isTypeAnnotation(a, isTypeParameter)) + log.error(a.pos(), "annotation.type.not.applicable"); + } + /** * Validate the proposed container 'repeatable' on the * annotation type symbol 's'. Report errors at position @@ -2795,45 +2811,90 @@ public class Check { return false; } + /** Is the annotation applicable to type annotations? */ + protected boolean isTypeAnnotation(JCAnnotation a, boolean isTypeParameter) { + Attribute.Compound atTarget = + a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym); + if (atTarget == null) { + // An annotation without @Target is not a type annotation. + return false; + } + + Attribute atValue = atTarget.member(names.value); + if (!(atValue instanceof Attribute.Array)) { + return false; // error recovery + } + + Attribute.Array arr = (Attribute.Array) atValue; + for (Attribute app : arr.values) { + if (!(app instanceof Attribute.Enum)) { + return false; // recovery + } + Attribute.Enum e = (Attribute.Enum) app; + + if (e.value.name == names.TYPE_USE) + return true; + else if (isTypeParameter && e.value.name == names.TYPE_PARAMETER) + return true; + } + return false; + } + /** Is the annotation applicable to the symbol? */ boolean annotationApplicable(JCAnnotation a, Symbol s) { Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym); + Name[] targets; + if (arr == null) { - return true; + targets = defaultTargetMetaInfo(a, s); + } else { + // TODO: can we optimize this? + targets = new Name[arr.values.length]; + for (int i=0; i typarams, List params, JCTree res, + JCVariableDecl recvparam, List thrown, Env env) { @@ -368,6 +375,15 @@ public class MemberEnter extends JCTree.Visitor implements Completer { // Attribute result type, if one is given. Type restype = res == null ? syms.voidType : attr.attribType(res, env); + // Attribute receiver type, if one is given. + Type recvtype; + if (recvparam!=null) { + memberEnter(recvparam, env); + recvtype = recvparam.vartype.type; + } else { + recvtype = null; + } + // Attribute thrown exceptions. ListBuffer thrownbuf = new ListBuffer(); for (List l = thrown; l.nonEmpty(); l = l.tail) { @@ -376,10 +392,12 @@ public class MemberEnter extends JCTree.Visitor implements Completer { exc = chk.checkClassType(l.head.pos(), exc); thrownbuf.append(exc); } - Type mtype = new MethodType(argbuf.toList(), + MethodType mtype = new MethodType(argbuf.toList(), restype, thrownbuf.toList(), syms.methodClass); + mtype.recvtype = recvtype; + return tvars.isEmpty() ? mtype : new ForAll(tvars, mtype); } @@ -573,7 +591,8 @@ public class MemberEnter extends JCTree.Visitor implements Completer { try { // Compute the method type m.type = signature(tree.typarams, tree.params, - tree.restype, tree.thrown, + tree.restype, tree.recvparam, + tree.thrown, localEnv); } finally { chk.setDeferredLintHandler(prevLintHandler); @@ -597,6 +616,10 @@ public class MemberEnter extends JCTree.Visitor implements Completer { enclScope.enter(m); } annotateLater(tree.mods.annotations, localEnv, m); + // Visit the signature of the method. Note that + // TypeAnnotate doesn't descend into the body. + typeAnnotate(tree, localEnv, m); + if (tree.defaultValue != null) annotateDefaultValueLater(tree.defaultValue, localEnv, m); } @@ -642,7 +665,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { //(a plain array type) with the more precise VarargsType --- we need //to do it this way because varargs is represented in the tree as a modifier //on the parameter declaration, and not as a distinct type of array node. - ArrayType atype = (ArrayType)tree.vartype.type; + ArrayType atype = (ArrayType)tree.vartype.type.unannotatedType(); tree.vartype.type = atype.makeVarargs(); } Scope enclScope = enter.enterScope(env); @@ -665,6 +688,8 @@ public class MemberEnter extends JCTree.Visitor implements Completer { enclScope.enter(v); } annotateLater(tree.mods.annotations, localEnv, v); + typeAnnotate(tree.vartype, env, tree.sym); + annotate.flush(); v.pos = tree.pos; } @@ -759,7 +784,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { log.error(annotations.head.pos, "already.annotated", kindName(s), s); - enterAnnotations(annotations, localEnv, s); + actualEnterAnnotations(annotations, localEnv, s); } finally { log.useSource(prev); } @@ -781,7 +806,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { } /** Enter a set of annotations. */ - private void enterAnnotations(List annotations, + private void actualEnterAnnotations(List annotations, Env env, Symbol s) { Map> annotated = @@ -817,11 +842,11 @@ public class MemberEnter extends JCTree.Visitor implements Completer { && s.owner.kind != MTH && types.isSameType(c.type, syms.deprecatedType)) { s.flags_field |= Flags.DEPRECATED; - } + } } - s.annotations.setAttributesWithCompletion( - annotate.new AnnotateRepeatedContext(env, annotated, pos, log)); + s.annotations.setDeclarationAttributesWithCompletion( + annotate.new AnnotateRepeatedContext(env, annotated, pos, log, false)); } /** Queue processing of an attribute default value. */ @@ -900,6 +925,12 @@ public class MemberEnter extends JCTree.Visitor implements Completer { // create an environment for evaluating the base clauses Env baseEnv = baseEnv(tree, env); + if (tree.extending != null) + typeAnnotate(tree.extending, baseEnv, sym); + for (JCExpression impl : tree.implementing) + typeAnnotate(impl, baseEnv, sym); + annotate.flush(); + // Determine supertype. Type supertype = (tree.extending != null) @@ -969,10 +1000,15 @@ public class MemberEnter extends JCTree.Visitor implements Completer { if (hasDeprecatedAnnotation(tree.mods.annotations)) c.flags_field |= DEPRECATED; annotateLater(tree.mods.annotations, baseEnv, c); + // class type parameters use baseEnv but everything uses env chk.checkNonCyclicDecl(tree); attr.attribTypeVariables(tree.typarams, baseEnv); + // Do this here, where we have the symbol. + for (JCTypeParameter tp : tree.typarams) + typeAnnotate(tp, baseEnv, sym); + annotate.flush(); // Add default constructor if needed. if ((c.flags() & INTERFACE) == 0 && @@ -1050,12 +1086,120 @@ public class MemberEnter extends JCTree.Visitor implements Completer { } finally { isFirst = true; } + } + annotate.afterRepeated(TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, tree)); + } - // commit pending annotations - annotate.flush(); + private void actualEnterTypeAnnotations(final List annotations, + final Env env, + final Symbol s) { + Map> annotated = + new LinkedHashMap>(); + Map pos = + new HashMap(); + + for (List al = annotations; !al.isEmpty(); al = al.tail) { + JCAnnotation a = al.head; + Attribute.TypeCompound tc = annotate.enterTypeAnnotation(a, + syms.annotationType, + env); + if (tc == null) { + continue; + } + + if (annotated.containsKey(a.type.tsym)) { + if (source.allowRepeatedAnnotations()) { + ListBuffer l = annotated.get(a.type.tsym); + l = l.append(tc); + annotated.put(a.type.tsym, l); + pos.put(tc, a.pos()); + } else { + log.error(a.pos(), "duplicate.annotation"); + } + } else { + annotated.put(a.type.tsym, ListBuffer.of(tc)); + pos.put(tc, a.pos()); + } + } + + s.annotations.appendTypeAttributesWithCompletion( + annotate.new AnnotateRepeatedContext(env, annotated, pos, log, true)); + } + + public void typeAnnotate(final JCTree tree, final Env env, final Symbol sym) { + tree.accept(new TypeAnnotate(env, sym)); + } + + /** + * We need to use a TreeScanner, because it is not enough to visit the top-level + * annotations. We also need to visit type arguments, etc. + */ + private class TypeAnnotate extends TreeScanner { + private Env env; + private Symbol sym; + + public TypeAnnotate(final Env env, final Symbol sym) { + this.env = env; + this.sym = sym; + } + + void annotateTypeLater(final List annotations) { + if (annotations.isEmpty()) { + return; + } + + annotate.normal(new Annotate.Annotator() { + @Override + public String toString() { + return "type annotate " + annotations + " onto " + sym + " in " + sym.owner; + } + @Override + public void enterAnnotation() { + JavaFileObject prev = log.useSource(env.toplevel.sourcefile); + try { + actualEnterTypeAnnotations(annotations, env, sym); + } finally { + log.useSource(prev); + } + } + }); + } + + @Override + public void visitAnnotatedType(final JCAnnotatedType tree) { + annotateTypeLater(tree.annotations); + super.visitAnnotatedType(tree); + } + + @Override + public void visitTypeParameter(final JCTypeParameter tree) { + annotateTypeLater(tree.annotations); + super.visitTypeParameter(tree); + } + + @Override + public void visitNewArray(final JCNewArray tree) { + annotateTypeLater(tree.annotations); + for (List dimAnnos : tree.dimAnnotations) + annotateTypeLater(dimAnnos); + super.visitNewArray(tree); + } + + @Override + public void visitMethodDef(final JCMethodDecl tree) { + scan(tree.mods); + scan(tree.restype); + scan(tree.typarams); + scan(tree.recvparam); + scan(tree.params); + scan(tree.thrown); + scan(tree.defaultValue); + // Do not annotate the body, just the signature. + // scan(tree.body); } } + private Env baseEnv(JCClassDecl tree, Env env) { Scope baseScope = new Scope(tree.sym); //import already entered local classes into base scope diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java index c058d34de1e..08cc94f372f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -55,7 +55,6 @@ import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Map; -import java.util.Set; import javax.lang.model.element.ElementVisitor; @@ -696,7 +695,7 @@ public class Resolve { if (varargsFormal == null && argtypes.size() != formals.size()) { - report(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args + reportMC(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args } while (argtypes.nonEmpty() && formals.head != varargsFormal) { @@ -707,7 +706,7 @@ public class Resolve { } if (formals.head != varargsFormal) { - report(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args + reportMC(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args } if (useVarargs) { @@ -724,7 +723,7 @@ public class Resolve { } } - private void report(MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) { + private void reportMC(MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) { boolean inferDiag = inferenceContext != infer.emptyContext; InapplicableMethodException ex = inferDiag ? infer.inferenceException : inapplicableMethodException; @@ -748,7 +747,7 @@ public class Resolve { } else { if (!isAccessible(env, t)) { Symbol location = env.enclClass.sym; - report(MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location); + reportMC(MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location); } } } @@ -761,7 +760,7 @@ public class Resolve { @Override public void report(DiagnosticPosition pos, JCDiagnostic details) { - report(methodDiag, deferredAttrContext.inferenceContext, details); + reportMC(methodDiag, deferredAttrContext.inferenceContext, details); } }; return new MethodResultInfo(to, checkContext); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java index 899e0c110b3..0b191293db7 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -483,6 +483,7 @@ public class TransTypes extends TreeTranslator { tree.restype = translate(tree.restype, null); tree.typarams = List.nil(); tree.params = translateVarDefs(tree.params); + tree.recvparam = translate(tree.recvparam, null); tree.thrown = translate(tree.thrown, null); tree.body = translate(tree.body, tree.sym.erasure(types).getReturnType()); tree.type = erasure(tree.type); diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java index 33ee5a780fb..4061471be55 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -351,8 +351,8 @@ public class ClassReader implements Completer { /** Read a byte. */ - byte nextByte() { - return buf[bp++]; + int nextByte() { + return buf[bp++] & 0xFF; } /** Read an integer. @@ -1172,6 +1172,19 @@ public class ClassReader implements Completer { } }, + new AttributeReader(names.RuntimeVisibleTypeAnnotations, V52, CLASS_OR_MEMBER_ATTRIBUTE) { + protected void read(Symbol sym, int attrLen) { + attachTypeAnnotations(sym); + } + }, + + new AttributeReader(names.RuntimeInvisibleTypeAnnotations, V52, CLASS_OR_MEMBER_ATTRIBUTE) { + protected void read(Symbol sym, int attrLen) { + attachTypeAnnotations(sym); + } + }, + + // The following attributes for a Code attribute are not currently handled // StackMapTable // SourceDebugExtension @@ -1381,6 +1394,17 @@ public class ClassReader implements Completer { } } + void attachTypeAnnotations(final Symbol sym) { + int numAttributes = nextChar(); + if (numAttributes != 0) { + ListBuffer proxies = + ListBuffer.lb(); + for (int i = 0; i < numAttributes; i++) + proxies.append(readTypeAnnotation()); + annotate.normal(new TypeAnnotationCompleter(sym, proxies.toList())); + } + } + /** Attach the default value for an annotation element. */ void attachAnnotationDefault(final Symbol sym) { @@ -1427,6 +1451,111 @@ public class ClassReader implements Completer { return new CompoundAnnotationProxy(t, pairs.toList()); } + TypeAnnotationProxy readTypeAnnotation() { + TypeAnnotationPosition position = readPosition(); + CompoundAnnotationProxy proxy = readCompoundAnnotation(); + + return new TypeAnnotationProxy(proxy, position); + } + + TypeAnnotationPosition readPosition() { + int tag = nextByte(); // TargetType tag is a byte + + if (!TargetType.isValidTargetTypeValue(tag)) + throw this.badClassFile("bad.type.annotation.value", String.format("0x%02X", tag)); + + TypeAnnotationPosition position = new TypeAnnotationPosition(); + TargetType type = TargetType.fromTargetTypeValue(tag); + + position.type = type; + + switch (type) { + // type cast + case CAST: + // instanceof + case INSTANCEOF: + // new expression + case NEW: + position.offset = nextChar(); + break; + // local variable + case LOCAL_VARIABLE: + // resource variable + case RESOURCE_VARIABLE: + int table_length = nextChar(); + position.lvarOffset = new int[table_length]; + position.lvarLength = new int[table_length]; + position.lvarIndex = new int[table_length]; + + for (int i = 0; i < table_length; ++i) { + position.lvarOffset[i] = nextChar(); + position.lvarLength[i] = nextChar(); + position.lvarIndex[i] = nextChar(); + } + break; + // exception parameter + case EXCEPTION_PARAMETER: + position.exception_index = nextByte(); + break; + // method receiver + case METHOD_RECEIVER: + // Do nothing + break; + // type parameter + case CLASS_TYPE_PARAMETER: + case METHOD_TYPE_PARAMETER: + position.parameter_index = nextByte(); + break; + // type parameter bound + case CLASS_TYPE_PARAMETER_BOUND: + case METHOD_TYPE_PARAMETER_BOUND: + position.parameter_index = nextByte(); + position.bound_index = nextByte(); + break; + // class extends or implements clause + case CLASS_EXTENDS: + position.type_index = nextChar(); + break; + // throws + case THROWS: + position.type_index = nextChar(); + break; + // method parameter + case METHOD_FORMAL_PARAMETER: + position.parameter_index = nextByte(); + break; + // method/constructor/reference type argument + case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: + case METHOD_INVOCATION_TYPE_ARGUMENT: + case METHOD_REFERENCE_TYPE_ARGUMENT: + position.offset = nextChar(); + position.type_index = nextByte(); + break; + // We don't need to worry about these + case METHOD_RETURN: + case FIELD: + break; + // lambda formal parameter + case LAMBDA_FORMAL_PARAMETER: + position.parameter_index = nextByte(); + break; + case UNKNOWN: + throw new AssertionError("jvm.ClassReader: UNKNOWN target type should never occur!"); + default: + throw new AssertionError("jvm.ClassReader: Unknown target type for position: " + position); + } + + { // See whether there is location info and read it + int len = nextByte(); + ListBuffer loc = ListBuffer.lb(); + for (int i = 0; i < len * TypeAnnotationPosition.TypePathEntry.bytesPerEntry; ++i) + loc = loc.append(nextByte()); + position.location = TypeAnnotationPosition.getTypePathFromBinary(loc.toList()); + } + + return position; + } + Attribute readAttributeValue() { char c = (char) buf[bp++]; switch (c) { @@ -1748,7 +1877,7 @@ public class ClassReader implements Completer { Annotations annotations = sym.annotations; List newList = deproxyCompoundList(l); if (annotations.pendingCompletion()) { - annotations.setAttributes(newList); + annotations.setDeclarationAttributes(newList); } else { annotations.append(newList); } @@ -1758,6 +1887,39 @@ public class ClassReader implements Completer { } } + class TypeAnnotationCompleter extends AnnotationCompleter { + + List proxies; + + TypeAnnotationCompleter(Symbol sym, + List proxies) { + super(sym, List.nil()); + this.proxies = proxies; + } + + List deproxyTypeCompoundList(List proxies) { + ListBuffer buf = ListBuffer.lb(); + for (TypeAnnotationProxy proxy: proxies) { + Attribute.Compound compound = deproxyCompound(proxy.compound); + Attribute.TypeCompound typeCompound = new Attribute.TypeCompound(compound, proxy.position); + buf.add(typeCompound); + } + return buf.toList(); + } + + @Override + public void enterAnnotation() { + JavaFileObject previousClassFile = currentClassFile; + try { + currentClassFile = classFile; + List newList = deproxyTypeCompoundList(proxies); + sym.annotations.setTypeAttributes(newList.prependList(sym.getRawTypeAttributes())); + } finally { + currentClassFile = previousClassFile; + } + } + } + /************************************************************************ * Reading Symbols diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java index 329000d3e4f..b48701ee37c 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -31,12 +31,14 @@ import java.util.Map; import java.util.Set; import java.util.HashSet; +import javax.lang.model.type.TypeKind; import javax.tools.JavaFileManager; import javax.tools.FileObject; import javax.tools.JavaFileObject; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Attribute.RetentionPolicy; +import com.sun.tools.javac.code.Attribute.TypeCompound; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.Types.UniqueType; @@ -47,7 +49,6 @@ import com.sun.tools.javac.jvm.Pool.MethodHandle; import com.sun.tools.javac.jvm.Pool.Variable; import com.sun.tools.javac.util.*; -import static com.sun.tools.javac.code.BoundKind.*; import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.TypeTag.*; @@ -68,19 +69,17 @@ public class ClassWriter extends ClassFile { protected static final Context.Key classWriterKey = new Context.Key(); - private final Symtab syms; - private final Options options; /** Switch: verbose output. */ private boolean verbose; - /** Switch: scramble private names. + /** Switch: scramble private field names. */ private boolean scramble; - /** Switch: scramble private names. + /** Switch: scramble all field names. */ private boolean scrambleAll; @@ -96,7 +95,7 @@ public class ClassWriter extends ClassFile { */ private boolean genCrt; - /** Switch: describe the generated stackmap + /** Switch: describe the generated stackmap. */ boolean debugstackmap; @@ -114,7 +113,7 @@ public class ClassWriter extends ClassFile { private Types types; /** The initial sizes of the data and constant pool buffers. - * sizes are increased when buffers get full. + * Sizes are increased when buffers get full. */ static final int DATA_BUF_SIZE = 0x0fff0; static final int POOL_BUF_SIZE = 0x1fff0; @@ -181,7 +180,6 @@ public class ClassWriter extends ClassFile { log = Log.instance(context); names = Names.instance(context); - syms = Symtab.instance(context); options = Options.instance(context); target = Target.instance(context); source = Source.instance(context); @@ -279,6 +277,7 @@ public class ClassWriter extends ClassFile { /** Assemble signature of given type in string buffer. */ void assembleSig(Type type) { + type = type.unannotatedType(); switch (type.getTag()) { case BYTE: sigbuf.appendByte('B'); @@ -379,6 +378,7 @@ public class ClassWriter extends ClassFile { } void assembleClassSig(Type type) { + type = type.unannotatedType(); ClassType ct = (ClassType)type; ClassSymbol c = (ClassSymbol)ct.tsym; enterInner(c); @@ -722,6 +722,7 @@ public class ClassWriter extends ClassFile { acount++; } acount += writeJavaAnnotations(sym.getRawAttributes()); + acount += writeTypeAnnotations(sym.getRawTypeAttributes()); return acount; } @@ -838,6 +839,76 @@ public class ClassWriter extends ClassFile { return attrCount; } + int writeTypeAnnotations(List typeAnnos) { + if (typeAnnos.isEmpty()) return 0; + + ListBuffer visibles = ListBuffer.lb(); + ListBuffer invisibles = ListBuffer.lb(); + + for (Attribute.TypeCompound tc : typeAnnos) { + if (tc.position == null || tc.position.type == TargetType.UNKNOWN) { + boolean found = false; + // TODO: the position for the container annotation of a + // repeating type annotation has to be set. + // This cannot be done when the container is created, because + // then the position is not determined yet. + // How can we link these pieces better together? + if (tc.values.size() == 1) { + Pair val = tc.values.get(0); + if (val.fst.getSimpleName().contentEquals("value") && + val.snd instanceof Attribute.Array) { + Attribute.Array arr = (Attribute.Array) val.snd; + if (arr.values.length != 0 && + arr.values[0] instanceof Attribute.TypeCompound) { + TypeCompound atycomp = (Attribute.TypeCompound) arr.values[0]; + if (atycomp.position.type != TargetType.UNKNOWN) { + tc.position = atycomp.position; + found = true; + } + } + } + } + if (!found) { + // This happens for nested types like @A Outer. @B Inner. + // For method parameters we get the annotation twice! Once with + // a valid position, once unknown. + // TODO: find a cleaner solution. + // System.err.println("ClassWriter: Position UNKNOWN in type annotation: " + tc); + continue; + } + } + if (!tc.position.emitToClassfile()) + continue; + switch (types.getRetention(tc)) { + case SOURCE: break; + case CLASS: invisibles.append(tc); break; + case RUNTIME: visibles.append(tc); break; + default: ;// /* fail soft */ throw new AssertionError(vis); + } + } + + int attrCount = 0; + if (visibles.length() != 0) { + int attrIndex = writeAttr(names.RuntimeVisibleTypeAnnotations); + databuf.appendChar(visibles.length()); + for (Attribute.TypeCompound p : visibles) + writeTypeAnnotation(p); + endAttr(attrIndex); + attrCount++; + } + + if (invisibles.length() != 0) { + int attrIndex = writeAttr(names.RuntimeInvisibleTypeAnnotations); + databuf.appendChar(invisibles.length()); + for (Attribute.TypeCompound p : invisibles) + writeTypeAnnotation(p); + endAttr(attrIndex); + attrCount++; + } + + return attrCount; + } + /** A visitor to write an attribute including its leading * single-character marker. */ @@ -914,6 +985,94 @@ public class ClassWriter extends ClassFile { p.snd.accept(awriter); } } + + void writeTypeAnnotation(Attribute.TypeCompound c) { + writePosition(c.position); + writeCompoundAttribute(c); + } + + void writePosition(TypeAnnotationPosition p) { + databuf.appendByte(p.type.targetTypeValue()); // TargetType tag is a byte + switch (p.type) { + // type cast + case CAST: + // instanceof + case INSTANCEOF: + // new expression + case NEW: + databuf.appendChar(p.offset); + break; + // local variable + case LOCAL_VARIABLE: + // resource variable + case RESOURCE_VARIABLE: + databuf.appendChar(p.lvarOffset.length); // for table length + for (int i = 0; i < p.lvarOffset.length; ++i) { + databuf.appendChar(p.lvarOffset[i]); + databuf.appendChar(p.lvarLength[i]); + databuf.appendChar(p.lvarIndex[i]); + } + break; + // exception parameter + case EXCEPTION_PARAMETER: + databuf.appendByte(p.exception_index); + break; + // method receiver + case METHOD_RECEIVER: + // Do nothing + break; + // type parameter + case CLASS_TYPE_PARAMETER: + case METHOD_TYPE_PARAMETER: + databuf.appendByte(p.parameter_index); + break; + // type parameter bound + case CLASS_TYPE_PARAMETER_BOUND: + case METHOD_TYPE_PARAMETER_BOUND: + databuf.appendByte(p.parameter_index); + databuf.appendByte(p.bound_index); + break; + // class extends or implements clause + case CLASS_EXTENDS: + databuf.appendChar(p.type_index); + break; + // throws + case THROWS: + databuf.appendChar(p.type_index); + break; + // method parameter + case METHOD_FORMAL_PARAMETER: + databuf.appendByte(p.parameter_index); + break; + // method/constructor/reference type argument + case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: + case METHOD_INVOCATION_TYPE_ARGUMENT: + case METHOD_REFERENCE_TYPE_ARGUMENT: + databuf.appendChar(p.offset); + databuf.appendByte(p.type_index); + break; + // We don't need to worry about these + case METHOD_RETURN: + case FIELD: + break; + // lambda formal parameter + case LAMBDA_FORMAL_PARAMETER: + databuf.appendByte(p.parameter_index); + break; + case UNKNOWN: + throw new AssertionError("jvm.ClassWriter: UNKNOWN target type should never occur!"); + default: + throw new AssertionError("jvm.ClassWriter: Unknown target type for position: " + p); + } + + { // Append location data for generics/arrays. + databuf.appendByte(p.location.size()); + java.util.List loc = TypeAnnotationPosition.getBinaryFromTypePath(p.location); + for (int i : loc) + databuf.appendByte((byte)i); + } + } + /********************************************************************** * Writing Objects **********************************************************************/ @@ -1661,6 +1820,7 @@ public class ClassWriter extends ClassFile { acount += writeFlagAttrs(c.flags()); acount += writeJavaAnnotations(c.getRawAttributes()); + acount += writeTypeAnnotations(c.getRawTypeAttributes()); acount += writeEnclosingMethodAttribute(c); acount += writeExtraClassAttributes(c); diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java index 87e1d6aea76..f5f37ef0435 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -1924,17 +1924,70 @@ public class Code { if (length < Character.MAX_VALUE) { v.length = length; putVar(v); + fillLocalVarPosition(v); } } } state.defined.excl(adr); } + private void fillLocalVarPosition(LocalVar lv) { + if (lv == null || lv.sym == null + || lv.sym.annotations.isTypesEmpty()) + return; + for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) { + TypeAnnotationPosition p = ta.position; + p.lvarOffset = new int[] { (int)lv.start_pc }; + p.lvarLength = new int[] { (int)lv.length }; + p.lvarIndex = new int[] { (int)lv.reg }; + p.isValidOffset = true; + } + } + + // Method to be called after compressCatchTable to + // fill in the exception table index for type + // annotations on exception parameters. + public void fillExceptionParameterPositions() { + for (int i = 0; i < varBufferSize; ++i) { + LocalVar lv = varBuffer[i]; + if (lv == null || lv.sym == null + || lv.sym.annotations.isTypesEmpty() + || !lv.sym.isExceptionParameter()) + return; + + int exidx = findExceptionIndex(lv); + + for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) { + TypeAnnotationPosition p = ta.position; + p.exception_index = exidx; + } + } + } + + private int findExceptionIndex(LocalVar lv) { + List iter = catchInfo.toList(); + int len = catchInfo.length(); + for (int i = 0; i < len; ++i) { + char[] catchEntry = iter.head; + iter = iter.tail; + char handlerpc = catchEntry[2]; + if (lv.start_pc == handlerpc + 1) { + return i; + } + } + return -1; + } + /** Put a live variable range into the buffer to be output to the * class file. */ void putVar(LocalVar var) { - if (!varDebugInfo) return; + // Keep local variables if + // 1) we need them for debug information + // 2) it is an exception type and it contains type annotations + if (!varDebugInfo && + (!var.sym.isExceptionParameter() || + var.sym.annotations.isTypesEmpty())) return; if ((var.sym.flags() & Flags.SYNTHETIC) != 0) return; if (varBuffer == null) varBuffer = new LocalVar[20]; diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java index f99c48b258c..b450fdcf43e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -1016,8 +1016,11 @@ public class Gen extends JCTree.Visitor { code.frameBeforeLast = null; } - //compress exception table + // Compress exception table code.compressCatchTable(); + + // Fill in type annotation positions for exception parameters + code.fillExceptionParameterPositions(); } } @@ -1738,6 +1741,7 @@ public class Gen extends JCTree.Visitor { *************************************************************************/ public void visitApply(JCMethodInvocation tree) { + setTypeAnnotationPositions(tree.pos); // Generate code for method. Item m = genExpr(tree.meth, methodType); // Generate code for all arguments, where the expected types are @@ -1775,10 +1779,48 @@ public class Gen extends JCTree.Visitor { result = items.makeStackItem(pt); } + private void setTypeAnnotationPositions(int treePos) { + MethodSymbol meth = code.meth; + + for (Attribute.TypeCompound ta : meth.getRawTypeAttributes()) { + if (ta.position.pos == treePos) { + ta.position.offset = code.cp; + ta.position.lvarOffset = new int[] { code.cp }; + ta.position.isValidOffset = true; + } + } + + if (code.meth.getKind() != javax.lang.model.element.ElementKind.CONSTRUCTOR + && code.meth.getKind() != javax.lang.model.element.ElementKind.STATIC_INIT) + return; + + for (Attribute.TypeCompound ta : meth.owner.getRawTypeAttributes()) { + if (ta.position.pos == treePos) { + ta.position.offset = code.cp; + ta.position.lvarOffset = new int[] { code.cp }; + ta.position.isValidOffset = true; + } + } + + ClassSymbol clazz = meth.enclClass(); + for (Symbol s : new com.sun.tools.javac.model.FilteredMemberList(clazz.members())) { + if (!s.getKind().isField()) + continue; + for (Attribute.TypeCompound ta : s.getRawTypeAttributes()) { + if (ta.position.pos == treePos) { + ta.position.offset = code.cp; + ta.position.lvarOffset = new int[] { code.cp }; + ta.position.isValidOffset = true; + } + } + } + } + public void visitNewClass(JCNewClass tree) { // Enclosing instances or anonymous classes should have been eliminated // by now. Assert.check(tree.encl == null && tree.def == null); + setTypeAnnotationPositions(tree.pos); code.emitop2(new_, makeRef(tree.pos(), tree.type)); code.emitop0(dup); @@ -1793,6 +1835,7 @@ public class Gen extends JCTree.Visitor { } public void visitNewArray(JCNewArray tree) { + setTypeAnnotationPositions(tree.pos); if (tree.elems != null) { Type elemtype = types.elemtype(tree.type); @@ -2122,6 +2165,7 @@ public class Gen extends JCTree.Visitor { } public void visitTypeCast(JCTypeCast tree) { + setTypeAnnotationPositions(tree.pos); result = genExpr(tree.expr, tree.clazz.type).load(); // Additional code is only needed if we cast to a reference type // which is not statically a supertype of the expression's type. @@ -2138,6 +2182,7 @@ public class Gen extends JCTree.Visitor { } public void visitTypeTest(JCInstanceOf tree) { + setTypeAnnotationPositions(tree.pos); genExpr(tree.expr, tree.expr.type).load(); code.emitop2(instanceof_, makeRef(tree.pos(), tree.clazz.type)); result = items.makeStackItem(syms.booleanType); @@ -2184,7 +2229,7 @@ public class Gen extends JCTree.Visitor { code.emitop2(ldc2, makeRef(tree.pos(), tree.selected.type)); result = items.makeStackItem(pt); return; - } + } Symbol ssym = TreeInfo.symbol(tree.selected); diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java index b1b8444bd6f..139ba519a9f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -158,7 +158,7 @@ public class JNIWriter { return false; /* temporary code for backwards compatibility */ - for (Attribute.Compound a: c.annotations.getAttributes()) { + for (Attribute.Compound a: c.annotations.getDeclarationAttributes()) { if (a.type.tsym == syms.nativeHeaderType_old.tsym) return true; } @@ -167,7 +167,7 @@ public class JNIWriter { for (Scope.Entry i = c.members_field.elems; i != null; i = i.sibling) { if (i.sym.kind == Kinds.MTH && (i.sym.flags() & Flags.NATIVE) != 0) return true; - for (Attribute.Compound a: i.sym.annotations.getAttributes()) { + for (Attribute.Compound a: i.sym.annotations.getDeclarationAttributes()) { if (a.type.tsym == syms.nativeHeaderType.tsym) return true; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java index 40fbd22bd25..5bf9d276872 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java +++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -513,7 +513,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter { */ public CompileState shouldStopPolicyIfNoError; - /** A queue of all as yet unattributed classes.oLo + /** A queue of all as yet unattributed classes. */ public Todo todo; diff --git a/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java b/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java index 83ce128cd35..9d8933daa5c 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java +++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -25,9 +25,9 @@ package com.sun.tools.javac.model; +import java.lang.annotation.Annotation; import java.util.Collections; import java.util.EnumSet; -import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -333,4 +333,28 @@ public class JavacTypes implements javax.lang.model.util.Types { return results; } + + public List typeAnnotationsOf(TypeMirror type) { + // TODO: these methods can be removed. + return null; // ((Type)type).typeAnnotations; + } + + public A typeAnnotationOf(TypeMirror type, + Class annotationType) { + // TODO: these methods can be removed. + return null; // JavacElements.getAnnotation(((Type)type).typeAnnotations, annotationType); + } + + public TypeMirror receiverTypeOf(ExecutableType type) { + return ((Type)type).asMethodType().recvtype; + } + + /* + public A receiverTypeAnnotationOf( + ExecutableType type, Class annotationType) { + return JavacElements.getAnnotation( + ((Type)type).asMethodType().receiverTypeAnnotations, + annotationType); + }*/ + } diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java index 95de4c1756c..52e8e087aa9 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -88,6 +88,41 @@ public class JavacParser implements Parser { /** End position mappings container */ private final AbstractEndPosTable endPosTable; + // Because of javac's limited lookahead, some contexts are ambiguous in + // the presence of type annotations even though they are not ambiguous + // in the absence of type annotations. Consider this code: + // void m(String [] m) { } + // void m(String ... m) { } + // After parsing "String", javac calls bracketsOpt which immediately + // returns if the next character is not '['. Similarly, javac can see + // if the next token is ... and in that case parse an ellipsis. But in + // the presence of type annotations: + // void m(String @A [] m) { } + // void m(String @A ... m) { } + // no finite lookahead is enough to determine whether to read array + // levels or an ellipsis. Furthermore, if you call bracketsOpt, then + // bracketsOpt first reads all the leading annotations and only then + // discovers that it needs to fail. bracketsOpt needs a way to push + // back the extra annotations that it read. (But, bracketsOpt should + // not *always* be allowed to push back extra annotations that it finds + // -- in most contexts, any such extra annotation is an error. + // + // The following two variables permit type annotations that have + // already been read to be stored for later use. Alternate + // implementations are possible but would cause much larger changes to + // the parser. + + /** Type annotations that have already been read but have not yet been used. **/ + private List typeAnnotationsPushedBack = List.nil(); + + /** + * If the parser notices extra annotations, then it either immediately + * issues an error (if this variable is false) or places the extra + * annotations in variable typeAnnotationsPushedBack (if this variable + * is true). + */ + private boolean permitTypeAnnotationsPushBack = false; + interface ErrorRecoveryAction { JCTree doRecover(JavacParser parser); } @@ -126,6 +161,7 @@ public class JavacParser implements Parser { this.allowDefaultMethods = source.allowDefaultMethods(); this.allowStaticInterfaceMethods = source.allowStaticInterfaceMethods(); this.allowIntersectionTypesInCast = source.allowIntersectionTypesInCast(); + this.allowTypeAnnotations = source.allowTypeAnnotations(); this.keepDocComments = keepDocComments; docComments = newDocCommentTable(keepDocComments, fac); this.keepLineMap = keepLineMap; @@ -215,6 +251,20 @@ public class JavacParser implements Parser { */ boolean keepLineMap; + /** Switch: should we recognize type annotations? + */ + boolean allowTypeAnnotations; + + /** Switch: is "this" allowed as an identifier? + * This is needed to parse receiver types. + */ + boolean allowThisIdent; + + /** The type of the method receiver, as specified by a first "this" parameter. + */ + JCVariableDecl receiverParam; + + /** When terms are parsed, the mode determines which is expected: * mode = EXPR : an expression * mode = TYPE : a type @@ -558,6 +608,18 @@ public class JavacParser implements Parser { nextToken(); return name; } + } else if (token.kind == THIS) { + if (allowThisIdent) { + // Make sure we're using a supported source version. + checkTypeAnnotations(); + Name name = token.name(); + nextToken(); + return name; + } else { + error(token.pos, "this.as.identifier"); + nextToken(); + return names.error; + } } else if (token.kind == UNDERSCORE) { warning(token.pos, "underscore.as.identifier"); Name name = token.name(); @@ -570,14 +632,21 @@ public class JavacParser implements Parser { } /** - * Qualident = Ident { DOT Ident } + * Qualident = Ident { DOT [Annotations] Ident } */ - public JCExpression qualident() { + public JCExpression qualident(boolean allowAnnos) { JCExpression t = toP(F.at(token.pos).Ident(ident())); while (token.kind == DOT) { int pos = token.pos; nextToken(); + List tyannos = null; + if (allowAnnos) { + tyannos = typeAnnotationsOpt(); + } t = toP(F.at(pos).Select(t, ident())); + if (tyannos != null && tyannos.nonEmpty()) { + t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t)); + } } return t; } @@ -686,7 +755,7 @@ public class JavacParser implements Parser { nextToken(); return t; } -//where + //where boolean isZero(String s) { char[] cs = s.toCharArray(); int base = ((cs.length > 1 && Character.toLowerCase(cs[1]) == 'x') ? 16 : 10); @@ -706,7 +775,34 @@ public class JavacParser implements Parser { return term(EXPR); } + /** + * parses (optional) type annotations followed by a type. If the + * annotations are present before the type and are not consumed during array + * parsing, this method returns a {@link JCAnnotatedType} consisting of + * these annotations and the underlying type. Otherwise, it returns the + * underlying type. + * + *

+ * + * Note that this method sets {@code mode} to {@code TYPE} first, before + * parsing annotations. + */ public JCExpression parseType() { + List annotations = typeAnnotationsOpt(); + return parseType(annotations); + } + + public JCExpression parseType(List annotations) { + JCExpression result = unannotatedType(); + + if (annotations.nonEmpty()) { + result = insertAnnotationsToMostInner(result, annotations, false); + } + + return result; + } + + public JCExpression unannotatedType() { return term(TYPE); } @@ -864,7 +960,7 @@ public class JavacParser implements Parser { opStackSupply.add(opStack); return t; } -//where + //where /** Construct a binary or type test node. */ private JCExpression makeOp(int pos, @@ -943,9 +1039,9 @@ public class JavacParser implements Parser { * | NEW [TypeArguments] Creator * | "(" Arguments ")" "->" ( Expression | Block ) * | Ident "->" ( Expression | Block ) - * | Ident { "." Ident } + * | [Annotations] Ident { "." [Annotations] Ident } * | Expression3 MemberReferenceSuffix - * [ "[" ( "]" BracketsOpt "." CLASS | Expression "]" ) + * [ [Annotations] "[" ( "]" BracketsOpt "." CLASS | Expression "]" ) * | Arguments * | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator ) * ] @@ -1067,6 +1163,34 @@ public class JavacParser implements Parser { typeArgs = null; } else return illegal(); break; + case MONKEYS_AT: + // Only annotated cast types are valid + List typeAnnos = typeAnnotationsOpt(); + if (typeAnnos.isEmpty()) { + // else there would be no '@' + throw new AssertionError("Expected type annotations, but found none!"); + } + + JCExpression expr = term3(); + + if ((mode & TYPE) == 0) { + // Type annotations on class literals no longer legal + if (!expr.hasTag(Tag.SELECT)) { + return illegal(typeAnnos.head.pos); + } + JCFieldAccess sel = (JCFieldAccess)expr; + + if (sel.name != names._class) { + return illegal(); + } else { + log.error(token.pos, "no.annotations.on.dot.class"); + return expr; + } + } else { + // Type annotations targeting a cast + t = insertAnnotationsToMostInner(expr, typeAnnos, false); + } + break; case UNDERSCORE: case IDENTIFIER: case ASSERT: case ENUM: if (typeArgs != null) return illegal(); if ((mode & EXPR) != 0 && peekToken(ARROW)) { @@ -1075,6 +1199,13 @@ public class JavacParser implements Parser { t = toP(F.at(token.pos).Ident(ident())); loop: while (true) { pos = token.pos; + final List annos = typeAnnotationsOpt(); + + // need to report an error later if LBRACKET is for array + // index access rather than array creation level + if (!annos.isEmpty() && token.kind != LBRACKET && token.kind != ELLIPSIS) + return illegal(annos.head.pos); + switch (token.kind) { case LBRACKET: nextToken(); @@ -1082,11 +1213,23 @@ public class JavacParser implements Parser { nextToken(); t = bracketsOpt(t); t = toP(F.at(pos).TypeArray(t)); - t = bracketsSuffix(t); + if (annos.nonEmpty()) { + t = toP(F.at(pos).AnnotatedType(annos, t)); + } + // .class is only allowed if there were no annotations + JCExpression nt = bracketsSuffix(t); + if (nt != t && (annos.nonEmpty() || TreeInfo.containsTypeAnnotation(t))) { + // t and nt are different if bracketsSuffix parsed a .class. + // The check for nonEmpty covers the case when the whole array is annotated. + // Helper method isAnnotated looks for annos deeply within t. + syntaxError("no.annotations.on.dot.class"); + } + t = nt; } else { if ((mode & EXPR) != 0) { mode = EXPR; JCExpression t1 = term(); + if (!annos.isEmpty()) t = illegal(annos.head.pos); t = to(F.at(pos).Indexed(t, t1)); } accept(RBRACKET); @@ -1096,6 +1239,7 @@ public class JavacParser implements Parser { if ((mode & EXPR) != 0) { mode = EXPR; t = arguments(typeArgs, t); + if (!annos.isEmpty()) t = illegal(annos.head.pos); typeArgs = null; } break loop; @@ -1136,9 +1280,25 @@ public class JavacParser implements Parser { break loop; } } + + List tyannos = null; + if ((mode & TYPE) != 0 && token.kind == MONKEYS_AT) { + tyannos = typeAnnotationsOpt(); + } // typeArgs saved for next loop iteration. t = toP(F.at(pos).Select(t, ident())); + if (tyannos != null && tyannos.nonEmpty()) { + t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t)); + } break; + case ELLIPSIS: + if (this.permitTypeAnnotationsPushBack) { + this.typeAnnotationsPushedBack = annos; + } else if (annos.nonEmpty()) { + // Don't return here -- error recovery attempt + illegal(annos.head.pos); + } + break loop; case LT: if ((mode & TYPE) == 0 && isUnboundMemberRef()) { //this is an unbound method reference whose qualifier @@ -1212,6 +1372,8 @@ public class JavacParser implements Parser { if (typeArgs != null) illegal(); while (true) { int pos1 = token.pos; + final List annos = typeAnnotationsOpt(); + if (token.kind == LBRACKET) { nextToken(); if ((mode & TYPE) != 0) { @@ -1225,6 +1387,9 @@ public class JavacParser implements Parser { mode = EXPR; continue; } + if (annos.nonEmpty()) { + t = toP(F.at(pos1).AnnotatedType(annos, t)); + } return t; } mode = oldmode; @@ -1253,7 +1418,15 @@ public class JavacParser implements Parser { t = innerCreator(pos2, typeArgs, t); typeArgs = null; } else { + List tyannos = null; + if ((mode & TYPE) != 0 && token.kind == MONKEYS_AT) { + // is the mode check needed? + tyannos = typeAnnotationsOpt(); + } t = toP(F.at(pos1).Select(t, ident())); + if (tyannos != null && tyannos.nonEmpty()) { + t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t)); + } t = argumentsOpt(typeArgs, typeArgumentsOpt(t)); typeArgs = null; } @@ -1263,6 +1436,12 @@ public class JavacParser implements Parser { accept(COLCOL); t = memberReferenceSuffix(pos1, t); } else { + if (!annos.isEmpty()) { + if (permitTypeAnnotationsPushBack) + typeAnnotationsPushedBack = annos; + else + return illegal(annos.head.pos); + } break; } } @@ -1321,7 +1500,7 @@ public class JavacParser implements Parser { ParensResult analyzeParens() { int depth = 0; boolean type = false; - for (int lookahead = 0 ; ; lookahead++) { + outer: for (int lookahead = 0 ; ; lookahead++) { TokenKind tk = S.token(lookahead).kind; switch (tk) { case EXTENDS: case SUPER: case COMMA: @@ -1382,9 +1561,36 @@ public class JavacParser implements Parser { break; case FINAL: case ELLIPSIS: - case MONKEYS_AT: //those can only appear in explicit lambdas return ParensResult.EXPLICIT_LAMBDA; + case MONKEYS_AT: + type = true; + lookahead += 1; //skip '@' + while (peekToken(lookahead, DOT)) { + lookahead += 2; + } + if (peekToken(lookahead, LPAREN)) { + lookahead++; + //skip annotation values + int nesting = 0; + for (; ; lookahead++) { + TokenKind tk2 = S.token(lookahead).kind; + switch (tk2) { + case EOF: + return ParensResult.PARENS; + case LPAREN: + nesting++; + break; + case RPAREN: + nesting--; + if (nesting == 0) { + continue outer; + } + break; + } + } + } + break; case LBRACKET: if (peekToken(lookahead, RBRACKET, LAX_IDENTIFIER)) { // '[', ']', Identifier/'_'/'assert'/'enum' -> explicit lambda @@ -1618,25 +1824,27 @@ public class JavacParser implements Parser { /** * {@literal * TypeArgument = Type - * | "?" - * | "?" EXTENDS Type {"&" Type} - * | "?" SUPER Type + * | [Annotations] "?" + * | [Annotations] "?" EXTENDS Type {"&" Type} + * | [Annotations] "?" SUPER Type * } */ JCExpression typeArgument() { - if (token.kind != QUES) return parseType(); + List annotations = typeAnnotationsOpt(); + if (token.kind != QUES) return parseType(annotations); int pos = token.pos; nextToken(); + JCExpression result; if (token.kind == EXTENDS) { TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.EXTENDS)); nextToken(); JCExpression bound = parseType(); - return F.at(pos).Wildcard(t, bound); + result = F.at(pos).Wildcard(t, bound); } else if (token.kind == SUPER) { TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.SUPER)); nextToken(); JCExpression bound = parseType(); - return F.at(pos).Wildcard(t, bound); + result = F.at(pos).Wildcard(t, bound); } else if (LAX_IDENTIFIER.accepts(token.kind)) { //error recovery TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND); @@ -1644,11 +1852,15 @@ public class JavacParser implements Parser { JCIdent id = toP(F.at(token.pos).Ident(ident())); JCErroneous err = F.at(pos).Erroneous(List.of(wc, id)); reportSyntaxError(err, "expected3", GT, EXTENDS, SUPER); - return err; + result = err; } else { TypeBoundKind t = toP(F.at(pos).TypeBoundKind(BoundKind.UNBOUND)); - return toP(F.at(pos).Wildcard(t, null)); + result = toP(F.at(pos).Wildcard(t, null)); } + if (!annotations.isEmpty()) { + result = toP(F.at(annotations.head.pos).AnnotatedType(annotations,result)); + } + return result; } JCTypeApply typeArguments(JCExpression t, boolean diamondAllowed) { @@ -1657,22 +1869,51 @@ public class JavacParser implements Parser { return toP(F.at(pos).TypeApply(t, args)); } - /** BracketsOpt = {"[" "]"} + /** + * BracketsOpt = { [Annotations] "[" "]" }* + * + *

+ * + * annotations is the list of annotations targeting + * the expression t. */ - private JCExpression bracketsOpt(JCExpression t) { + private JCExpression bracketsOpt(JCExpression t, + List annotations) { + List nextLevelAnnotations = typeAnnotationsOpt(); + if (token.kind == LBRACKET) { int pos = token.pos; nextToken(); - t = bracketsOptCont(t, pos); - F.at(pos); + t = bracketsOptCont(t, pos, nextLevelAnnotations); + } else if (!nextLevelAnnotations.isEmpty()) { + if (permitTypeAnnotationsPushBack) { + this.typeAnnotationsPushedBack = nextLevelAnnotations; + } else { + return illegal(nextLevelAnnotations.head.pos); + } + } + + if (!annotations.isEmpty()) { + t = toP(F.at(token.pos).AnnotatedType(annotations, t)); } return t; } - private JCArrayTypeTree bracketsOptCont(JCExpression t, int pos) { + /** BracketsOpt = [ "[" "]" { [Annotations] "[" "]"} ] + */ + private JCExpression bracketsOpt(JCExpression t) { + return bracketsOpt(t, List.nil()); + } + + private JCExpression bracketsOptCont(JCExpression t, int pos, + List annotations) { accept(RBRACKET); t = bracketsOpt(t); - return toP(F.at(pos).TypeArray(t)); + t = toP(F.at(pos).TypeArray(t)); + if (annotations.nonEmpty()) { + t = toP(F.at(pos).AnnotatedType(annotations, t)); + } + return t; } /** BracketsSuffixExpr = "." CLASS @@ -1686,7 +1927,7 @@ public class JavacParser implements Parser { accept(CLASS); if (token.pos == endPosTable.errorEndPos) { // error recovery - Name name = null; + Name name; if (LAX_IDENTIFIER.accepts(token.kind)) { name = token.name(); nextToken(); @@ -1724,8 +1965,8 @@ public class JavacParser implements Parser { if (token.kind == LT) { typeArgs = typeArguments(false); } - Name refName = null; - ReferenceMode refMode = null; + Name refName; + ReferenceMode refMode; if (token.kind == NEW) { refMode = ReferenceMode.NEW; refName = names.init; @@ -1737,18 +1978,31 @@ public class JavacParser implements Parser { return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs)); } - /** Creator = Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest ) + /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest ) */ JCExpression creator(int newpos, List typeArgs) { + List newAnnotations = typeAnnotationsOpt(); + switch (token.kind) { case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: - if (typeArgs == null) - return arrayCreatorRest(newpos, basicType()); + if (typeArgs == null) { + if (newAnnotations.isEmpty()) { + return arrayCreatorRest(newpos, basicType()); + } else { + return arrayCreatorRest(newpos, toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, basicType()))); + } + } break; default: } - JCExpression t = qualident(); + JCExpression t = qualident(true); + + // handle type annotations for non primitive arrays + if (newAnnotations.nonEmpty()) { + t = insertAnnotationsToMostInner(t, newAnnotations, false); + } + int oldmode = mode; mode = TYPE; boolean diamondFound = false; @@ -1766,7 +2020,13 @@ public class JavacParser implements Parser { } int pos = token.pos; nextToken(); + List tyannos = typeAnnotationsOpt(); t = toP(F.at(pos).Select(t, ident())); + + if (tyannos != null && tyannos.nonEmpty()) { + t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t)); + } + if (token.kind == LT) { lastTypeargsPos = token.pos; checkGenerics(); @@ -1775,7 +2035,7 @@ public class JavacParser implements Parser { } } mode = oldmode; - if (token.kind == LBRACKET) { + if (token.kind == LBRACKET || token.kind == MONKEYS_AT) { JCExpression e = arrayCreatorRest(newpos, t); if (diamondFound) { reportSyntaxError(lastTypeargsPos, "cannot.create.array.with.diamond"); @@ -1796,7 +2056,15 @@ public class JavacParser implements Parser { } return e; } else if (token.kind == LPAREN) { - return classCreatorRest(newpos, null, typeArgs, t); + JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t); + if (newClass.def != null) { + assert newClass.def.mods.annotations.isEmpty(); + if (newAnnotations.nonEmpty()) { + newClass.def.mods.pos = earlier(newClass.def.mods.pos, newAnnotations.head.pos); + newClass.def.mods.annotations = List.convert(JCAnnotation.class, newAnnotations); + } + } + return newClass; } else { setErrorEndPos(token.pos); reportSyntaxError(token.pos, "expected2", LPAREN, LBRACKET); @@ -1805,10 +2073,17 @@ public class JavacParser implements Parser { } } - /** InnerCreator = Ident [TypeArguments] ClassCreatorRest + /** InnerCreator = [Annotations] Ident [TypeArguments] ClassCreatorRest */ JCExpression innerCreator(int newpos, List typeArgs, JCExpression encl) { + List newAnnotations = typeAnnotationsOpt(); + JCExpression t = toP(F.at(token.pos).Ident(ident())); + + if (newAnnotations.nonEmpty()) { + t = toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, t)); + } + if (token.kind == LT) { int oldmode = mode; checkGenerics(); @@ -1818,35 +2093,65 @@ public class JavacParser implements Parser { return classCreatorRest(newpos, encl, typeArgs, t); } - /** ArrayCreatorRest = "[" ( "]" BracketsOpt ArrayInitializer - * | Expression "]" {"[" Expression "]"} BracketsOpt ) + /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer + * | Expression "]" {[Annotations] "[" Expression "]"} BracketsOpt ) */ JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) { + List annos = typeAnnotationsOpt(); + accept(LBRACKET); if (token.kind == RBRACKET) { accept(RBRACKET); - elemtype = bracketsOpt(elemtype); + elemtype = bracketsOpt(elemtype, annos); if (token.kind == LBRACE) { - return arrayInitializer(newpos, elemtype); + JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype); + if (annos.nonEmpty()) { + // when an array initializer is present then + // the parsed annotations should target the + // new array tree + // bracketsOpt inserts the annotation in + // elemtype, and it needs to be corrected + // + JCAnnotatedType annotated = (JCAnnotatedType)elemtype; + assert annotated.annotations == annos; + na.annotations = annotated.annotations; + na.elemtype = annotated.underlyingType; + } + return na; } else { JCExpression t = toP(F.at(newpos).NewArray(elemtype, List.nil(), null)); return syntaxError(token.pos, List.of(t), "array.dimension.missing"); } } else { ListBuffer dims = new ListBuffer(); + + // maintain array dimension type annotations + ListBuffer> dimAnnotations = ListBuffer.lb(); + dimAnnotations.append(annos); + dims.append(parseExpression()); accept(RBRACKET); - while (token.kind == LBRACKET) { + while (token.kind == LBRACKET + || token.kind == MONKEYS_AT) { + List maybeDimAnnos = typeAnnotationsOpt(); int pos = token.pos; nextToken(); if (token.kind == RBRACKET) { - elemtype = bracketsOptCont(elemtype, pos); + elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos); } else { - dims.append(parseExpression()); - accept(RBRACKET); + if (token.kind == RBRACKET) { // no dimension + elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos); + } else { + dimAnnotations.append(maybeDimAnnos); + dims.append(parseExpression()); + accept(RBRACKET); + } } } - return toP(F.at(newpos).NewArray(elemtype, dims.toList(), null)); + + JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), null)); + na.dimAnnotations = dimAnnotations.toList(); + return na; } } @@ -2254,6 +2559,7 @@ public class JavacParser implements Parser { } /** CatchClause = CATCH "(" FormalParameter ")" Block + * TODO: the "FormalParameter" is not correct, it uses the special "catchTypes" rule below. */ protected JCCatch catchClause() { int pos = token.pos; @@ -2276,7 +2582,9 @@ public class JavacParser implements Parser { while (token.kind == BAR) { checkMulticatch(); nextToken(); - catchTypes.add(qualident()); + // Instead of qualident this is now parseType. + // But would that allow too much, e.g. arrays or generics? + catchTypes.add(parseType()); } return catchTypes.toList(); } @@ -2377,16 +2685,28 @@ public class JavacParser implements Parser { } /** AnnotationsOpt = { '@' Annotation } + * + * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION */ - List annotationsOpt() { + List annotationsOpt(Tag kind) { if (token.kind != MONKEYS_AT) return List.nil(); // optimization ListBuffer buf = new ListBuffer(); + int prevmode = mode; while (token.kind == MONKEYS_AT) { int pos = token.pos; nextToken(); - buf.append(annotation(pos)); + buf.append(annotation(pos, kind)); } - return buf.toList(); + lastmode = mode; + mode = prevmode; + List annotations = buf.toList(); + + return annotations; + } + + List typeAnnotationsOpt() { + List annotations = annotationsOpt(Tag.TYPE_ANNOTATION); + return annotations; } /** ModifiersOpt = { Modifier } @@ -2412,7 +2732,7 @@ public class JavacParser implements Parser { if (token.deprecatedFlag()) { flags |= Flags.DEPRECATED; } - int lastPos = Position.NOPOS; + int lastPos; loop: while (true) { long flag; @@ -2439,12 +2759,11 @@ public class JavacParser implements Parser { if (flag == Flags.ANNOTATION) { checkAnnotations(); if (token.kind != INTERFACE) { - JCAnnotation ann = annotation(lastPos); + JCAnnotation ann = annotation(lastPos, Tag.ANNOTATION); // if first modifier is an annotation, set pos to annotation's. if (flags == 0 && annotations.isEmpty()) pos = ann.pos; annotations.append(ann); - lastPos = ann.pos; flag = 0; } } @@ -2468,14 +2787,27 @@ public class JavacParser implements Parser { } /** Annotation = "@" Qualident [ "(" AnnotationFieldValues ")" ] + * * @param pos position of "@" token + * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION */ - JCAnnotation annotation(int pos) { + JCAnnotation annotation(int pos, Tag kind) { // accept(AT); // AT consumed by caller checkAnnotations(); - JCTree ident = qualident(); + if (kind == Tag.TYPE_ANNOTATION) { + checkTypeAnnotations(); + } + JCTree ident = qualident(false); List fieldValues = annotationFieldValuesOpt(); - JCAnnotation ann = F.at(pos).Annotation(ident, fieldValues); + JCAnnotation ann; + if (kind == Tag.ANNOTATION) { + ann = F.at(pos).Annotation(ident, fieldValues); + } else if (kind == Tag.TYPE_ANNOTATION) { + ann = F.at(pos).TypeAnnotation(ident, fieldValues); + } else { + throw new AssertionError("Unhandled annotation kind: " + kind); + } + storeEnd(ann, S.prevToken().endPos); return ann; } @@ -2528,7 +2860,7 @@ public class JavacParser implements Parser { case MONKEYS_AT: pos = token.pos; nextToken(); - return annotation(pos); + return annotation(pos, Tag.ANNOTATION); case LBRACE: pos = token.pos; accept(LBRACE); @@ -2683,7 +3015,7 @@ public class JavacParser implements Parser { mods = null; } nextToken(); - pid = qualident(); + pid = qualident(false); accept(SEMI); } ListBuffer defs = new ListBuffer(); @@ -2934,7 +3266,7 @@ public class JavacParser implements Parser { flags |= Flags.DEPRECATED; } int pos = token.pos; - List annotations = annotationsOpt(); + List annotations = annotationsOpt(Tag.ANNOTATION); JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations); List typeArgs = typeArgumentsOpt(); int identPos = token.pos; @@ -3037,15 +3369,25 @@ public class JavacParser implements Parser { mods.pos = pos; storeEnd(mods, pos); } + List annosAfterParams = annotationsOpt(Tag.ANNOTATION); + Token tk = token; pos = token.pos; JCExpression type; boolean isVoid = token.kind == VOID; if (isVoid) { + if (annosAfterParams.nonEmpty()) + illegal(annosAfterParams.head.pos); type = to(F.at(pos).TypeIdent(TypeTag.VOID)); nextToken(); } else { - type = parseType(); + if (annosAfterParams.nonEmpty()) { + mods.annotations = mods.annotations.appendList(annosAfterParams); + if (mods.pos == Position.NOPOS) + mods.pos = mods.annotations.head.pos; + } + // method returns types are un-annotated types + type = unannotatedType(); } if (token.kind == LPAREN && !isInterface && type.hasTag(IDENT)) { if (isInterface || tk.name() != className) @@ -3101,51 +3443,68 @@ public class JavacParser implements Parser { if (isInterface && (mods.flags & Flags.STATIC) != 0) { checkStaticInterfaceMethods(); } - List params = formalParameters(); - if (!isVoid) type = bracketsOpt(type); - List thrown = List.nil(); - if (token.kind == THROWS) { - nextToken(); - thrown = qualidentList(); - } - JCBlock body = null; - JCExpression defaultValue; - if (token.kind == LBRACE) { - body = block(); - defaultValue = null; - } else { - if (token.kind == DEFAULT) { - accept(DEFAULT); - defaultValue = annotationValue(); - } else { - defaultValue = null; + JCVariableDecl prevReceiverParam = this.receiverParam; + try { + this.receiverParam = null; + // Parsing formalParameters sets the receiverParam, if present + List params = formalParameters(); + if (!isVoid) type = bracketsOpt(type); + List thrown = List.nil(); + if (token.kind == THROWS) { + nextToken(); + thrown = qualidentList(); } - accept(SEMI); - if (token.pos <= endPosTable.errorEndPos) { - // error recovery - skip(false, true, false, false); - if (token.kind == LBRACE) { - body = block(); + JCBlock body = null; + JCExpression defaultValue; + if (token.kind == LBRACE) { + body = block(); + defaultValue = null; + } else { + if (token.kind == DEFAULT) { + accept(DEFAULT); + defaultValue = annotationValue(); + } else { + defaultValue = null; + } + accept(SEMI); + if (token.pos <= endPosTable.errorEndPos) { + // error recovery + skip(false, true, false, false); + if (token.kind == LBRACE) { + body = block(); + } } } - } - JCMethodDecl result = - toP(F.at(pos).MethodDef(mods, name, type, typarams, - params, thrown, - body, defaultValue)); - attach(result, dc); - return result; + JCMethodDecl result = + toP(F.at(pos).MethodDef(mods, name, type, typarams, + receiverParam, params, thrown, + body, defaultValue)); + attach(result, dc); + return result; + } finally { + this.receiverParam = prevReceiverParam; + } } - /** QualidentList = Qualident {"," Qualident} + /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident} */ List qualidentList() { ListBuffer ts = new ListBuffer(); - ts.append(qualident()); + + List typeAnnos = typeAnnotationsOpt(); + if (!typeAnnos.isEmpty()) + ts.append(toP(F.at(typeAnnos.head.pos).AnnotatedType(typeAnnos, qualident(true)))); + else + ts.append(qualident(true)); while (token.kind == COMMA) { nextToken(); - ts.append(qualident()); + + typeAnnos = typeAnnotationsOpt(); + if (!typeAnnos.isEmpty()) + ts.append(toP(F.at(typeAnnos.head.pos).AnnotatedType(typeAnnos, qualident(true)))); + else + ts.append(qualident(true)); } return ts.toList(); } @@ -3174,13 +3533,14 @@ public class JavacParser implements Parser { /** * {@literal - * TypeParameter = TypeVariable [TypeParameterBound] + * TypeParameter = [Annotations] TypeVariable [TypeParameterBound] * TypeParameterBound = EXTENDS Type {"&" Type} * TypeVariable = Ident * } */ JCTypeParameter typeParameter() { int pos = token.pos; + List annos = typeAnnotationsOpt(); Name name = ident(); ListBuffer bounds = new ListBuffer(); if (token.kind == EXTENDS) { @@ -3191,7 +3551,7 @@ public class JavacParser implements Parser { bounds.append(parseType()); } } - return toP(F.at(pos).TypeParameter(name, bounds.toList())); + return toP(F.at(pos).TypeParameter(name, bounds.toList(), annos)); } /** FormalParameters = "(" [ FormalParameterList ] ")" @@ -3203,10 +3563,17 @@ public class JavacParser implements Parser { } List formalParameters(boolean lambdaParameters) { ListBuffer params = new ListBuffer(); - JCVariableDecl lastParam = null; + JCVariableDecl lastParam; accept(LPAREN); if (token.kind != RPAREN) { - params.append(lastParam = formalParameter(lambdaParameters)); + this.allowThisIdent = true; + lastParam = formalParameter(lambdaParameters); + if (lastParam.name.contentEquals(TokenKind.THIS.name)) { + this.receiverParam = lastParam; + } else { + params.append(lastParam); + } + this.allowThisIdent = false; while ((lastParam.mods.flags & Flags.VARARGS) == 0 && token.kind == COMMA) { nextToken(); params.append(lastParam = formalParameter(lambdaParameters)); @@ -3241,6 +3608,77 @@ public class JavacParser implements Parser { return mods; } + /** + * Inserts the annotations (and possibly a new array level) + * to the left-most type in an array or nested type. + * + * When parsing a type like {@code @B Outer.Inner @A []}, the + * {@code @A} annotation should target the array itself, while + * {@code @B} targets the nested type {@code Outer}. + * + * Currently the parser parses the annotation first, then + * the array, and then inserts the annotation to the left-most + * nested type. + * + * When {@code createNewLevel} is true, then a new array + * level is inserted as the most inner type, and have the + * annotations target it. This is useful in the case of + * varargs, e.g. {@code String @A [] @B ...}, as the parser + * first parses the type {@code String @A []} then inserts + * a new array level with {@code @B} annotation. + */ + private JCExpression insertAnnotationsToMostInner( + JCExpression type, List annos, + boolean createNewLevel) { + int origEndPos = getEndPos(type); + JCExpression mostInnerType = type; + JCArrayTypeTree mostInnerArrayType = null; + while (TreeInfo.typeIn(mostInnerType).hasTag(TYPEARRAY)) { + mostInnerArrayType = (JCArrayTypeTree) TreeInfo.typeIn(mostInnerType); + mostInnerType = mostInnerArrayType.elemtype; + } + + if (createNewLevel) { + mostInnerType = to(F.at(token.pos).TypeArray(mostInnerType)); + } + + JCExpression mostInnerTypeToReturn = mostInnerType; + if (annos.nonEmpty()) { + JCExpression lastToModify = mostInnerType; + + while (TreeInfo.typeIn(mostInnerType).hasTag(SELECT) || + TreeInfo.typeIn(mostInnerType).hasTag(TYPEAPPLY)) { + while (TreeInfo.typeIn(mostInnerType).hasTag(SELECT)) { + lastToModify = mostInnerType; + mostInnerType = ((JCFieldAccess) TreeInfo.typeIn(mostInnerType)).getExpression(); + } + while (TreeInfo.typeIn(mostInnerType).hasTag(TYPEAPPLY)) { + lastToModify = mostInnerType; + mostInnerType = ((JCTypeApply) TreeInfo.typeIn(mostInnerType)).clazz; + } + } + + mostInnerType = F.at(annos.head.pos).AnnotatedType(annos, mostInnerType); + + if (TreeInfo.typeIn(lastToModify).hasTag(TYPEAPPLY)) { + ((JCTypeApply) TreeInfo.typeIn(lastToModify)).clazz = mostInnerType; + } else if (TreeInfo.typeIn(lastToModify).hasTag(SELECT)) { + ((JCFieldAccess) TreeInfo.typeIn(lastToModify)).selected = mostInnerType; + } else { + // We never saw a SELECT or TYPEAPPLY, return the annotated type. + mostInnerTypeToReturn = mostInnerType; + } + } + + if (mostInnerArrayType == null) { + return mostInnerTypeToReturn; + } else { + mostInnerArrayType.elemtype = mostInnerTypeToReturn; + storeEnd(type, origEndPos); + return type; + } + } + /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId * LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter */ @@ -3249,12 +3687,27 @@ public class JavacParser implements Parser { } protected JCVariableDecl formalParameter(boolean lambdaParameter) { JCModifiers mods = optFinal(Flags.PARAMETER); + // need to distinguish between vararg annos and array annos + // look at typeAnnotationsPushedBack comment + this.permitTypeAnnotationsPushBack = true; JCExpression type = parseType(); + this.permitTypeAnnotationsPushBack = false; + if (token.kind == ELLIPSIS) { + List varargsAnnos = typeAnnotationsPushedBack; + typeAnnotationsPushedBack = List.nil(); checkVarargs(); mods.flags |= Flags.VARARGS; - type = to(F.at(token.pos).TypeArray(type)); + // insert var arg type annotations + type = insertAnnotationsToMostInner(type, varargsAnnos, true); nextToken(); + } else { + // if not a var arg, then typeAnnotationsPushedBack should be null + if (typeAnnotationsPushedBack.nonEmpty()) { + reportSyntaxError(typeAnnotationsPushedBack.head.pos, + "illegal.start.of.type"); + } + typeAnnotationsPushedBack = List.nil(); } return variableDeclaratorId(mods, type, lambdaParameter); } @@ -3508,6 +3961,12 @@ public class JavacParser implements Parser { allowStaticInterfaceMethods = true; } } + void checkTypeAnnotations() { + if (!allowTypeAnnotations) { + log.error(token.pos, "type.annotations.not.supported.in.source", source.name); + allowTypeAnnotations = true; + } + } /* * a functional source tree and end position mappings diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java b/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java index 20c49e6cfc2..8a813f0e9de 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -59,6 +59,7 @@ public class Scanner implements Lexer { private List savedTokens = new ArrayList(); private JavaTokenizer tokenizer; + /** * Create a scanner from the input array. This method might * modify the array. To avoid copying the input array, ensure diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/UnicodeReader.java b/langtools/src/share/classes/com/sun/tools/javac/parser/UnicodeReader.java index 84e6792cdd1..8b308c5834a 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/UnicodeReader.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/UnicodeReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, 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 @@ -38,7 +38,7 @@ import static com.sun.tools.javac.util.LayoutCharacters.*; /** The char reader used by the javac lexer/tokenizer. Returns the sequence of * characters contained in the input stream, handling unicode escape accordingly. - * Additionally, it provide features for saving chars into a buffer and to retrieve + * Additionally, it provides features for saving chars into a buffer and to retrieve * them at a later stage. * *

This is NOT part of any supported API. diff --git a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java index 498ca34b415..d71184d5157 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java +++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -817,9 +817,6 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea /** The set of package-info files to be processed this round. */ List packageInfoFiles; - /** The number of Messager errors generated in this round. */ - int nMessagerErrors; - /** Create a round (common code). */ private Round(Context context, int number, int priorErrors, int priorWarnings, Log.DeferredDiagnosticHandler deferredDiagnosticHandler) { @@ -829,7 +826,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea compiler = JavaCompiler.instance(context); log = Log.instance(context); log.nerrors = priorErrors; - log.nwarnings += priorWarnings; + log.nwarnings = priorWarnings; if (number == 1) { Assert.checkNonNull(deferredDiagnosticHandler); this.deferredDiagnosticHandler = deferredDiagnosticHandler; @@ -870,7 +867,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea Set newSourceFiles, Map newClassFiles) { this(prev.nextContext(), prev.number+1, - prev.nMessagerErrors, + prev.compiler.log.nerrors, prev.compiler.log.nwarnings, null); this.genClassFiles = prev.genClassFiles; @@ -911,15 +908,12 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea } /** Create the compiler to be used for the final compilation. */ - JavaCompiler finalCompiler(boolean errorStatus) { + JavaCompiler finalCompiler() { try { Context nextCtx = nextContext(); JavacProcessingEnvironment.this.context = nextCtx; JavaCompiler c = JavaCompiler.instance(nextCtx); - c.log.nwarnings += compiler.log.nwarnings; - if (errorStatus) { - c.log.nerrors += compiler.log.nerrors; - } + c.log.initRound(compiler.log); return c; } finally { compiler.close(false); @@ -1027,8 +1021,6 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea if (!taskListener.isEmpty()) taskListener.finished(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND)); } - - nMessagerErrors = messager.errorCount(); } void showDiagnostics(boolean showAll) { @@ -1107,9 +1099,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea next.put(Tokens.tokensKey, tokens); Log nextLog = Log.instance(next); - // propogate the log's writers directly, instead of going through context - nextLog.setWriters(log); - nextLog.setSourceMap(log); + nextLog.initRound(log); JavaCompiler oldCompiler = JavaCompiler.instance(context); JavaCompiler nextCompiler = JavaCompiler.instance(next); @@ -1206,7 +1196,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea new LinkedHashSet(filer.getGeneratedSourceFileObjects()); roots = cleanTrees(round.roots); - JavaCompiler compiler = round.finalCompiler(errorStatus); + JavaCompiler compiler = round.finalCompiler(); if (newSourceFiles.size() > 0) roots = roots.appendList(compiler.parseFiles(newSourceFiles)); @@ -1311,7 +1301,6 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea if (procNames != null) return true; - String procPath; URL[] urls = new URL[1]; for(File pathElement : workingpath) { try { @@ -1382,6 +1371,10 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea node.sym = null; super.visitIdent(node); } + public void visitAnnotation(JCAnnotation node) { + node.attribute = null; + super.visitAnnotation(node); + } }; diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties index ec60b811201..5161bedb3b4 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -1666,6 +1666,9 @@ compiler.misc.bad.const.pool.tag.at=\ compiler.misc.bad.signature=\ bad signature: {0} +compiler.misc.bad.type.annotation.value=\ + bad type annotation target type value: {0} + compiler.misc.class.file.wrong.class=\ class file contains wrong class: {0} @@ -2149,6 +2152,23 @@ compiler.err.assert.as.identifier=\ as of release 1.4, ''assert'' is a keyword, and may not be used as an identifier\n\ (use -source 1.3 or lower to use ''assert'' as an identifier) +# TODO 308: make a better error message +compiler.err.this.as.identifier=\ + as of release 8, ''this'' is allowed as the parameter name for the receiver type only, which has to be the first parameter + +# TODO 308: make a better error message +compiler.err.cant.annotate.static.class=\ + enclosing static nested class cannot be annotated +# TODO 308: make a better error message +compiler.err.cant.annotate.nested.type=\ + nested type cannot be annotated + +compiler.err.incorrect.receiver.type=\ + the receiver type does not match the enclosing class type + +compiler.err.no.annotations.on.dot.class=\ + no annotations are allowed in the type of a class literal + # 0: string compiler.err.generics.not.supported.in.source=\ generics are not supported in -source {0}\n\ @@ -2164,9 +2184,10 @@ compiler.err.annotations.not.supported.in.source=\ annotations are not supported in -source {0}\n\ (use -source 5 or higher to enable annotations) -#308 compiler.err.type.annotations.not.supported.in.source=\ -#308 type annotations are not supported in -source {0}\n\ -#308 (use -source 7 or higher to enable type annotations) +# 0: string +compiler.err.type.annotations.not.supported.in.source=\ + type annotations are not supported in -source {0}\n\ +(use -source 8 or higher to enable type annotations) # 0: string compiler.err.foreach.not.supported.in.source=\ diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_ja.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_ja.properties index 890ae3f9597..6f1096aeab2 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_ja.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_ja.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2013, 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 @@ -1340,6 +1340,10 @@ compiler.err.enum.as.identifier=\u30EA\u30EA\u30FC\u30B95\u304B\u3089''enum''\u3 compiler.err.assert.as.identifier=\u30EA\u30EA\u30FC\u30B91.4\u304B\u3089''assert''\u306F\u30AD\u30FC\u30EF\u30FC\u30C9\u306A\u306E\u3067\u3001\u8B58\u5225\u5B50\u3068\u3057\u3066\u4F7F\u7528\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093\n(''assert''\u3092\u8B58\u5225\u5B50\u3068\u3057\u3066\u4F7F\u7528\u3059\u308B\u306B\u306F\u3001-source 1.3\u4EE5\u524D\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044) +# TODO 308: make a better error message +# compiler.err.this.as.identifier=\ +# as of release 8, ''this'' is allowed as the parameter name for the receiver type only, which has to be the first parameter + # 0: string compiler.err.generics.not.supported.in.source=\u7DCF\u79F0\u578B\u306F-source {0}\u3067\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\n(\u7DCF\u79F0\u578B\u3092\u4F7F\u7528\u53EF\u80FD\u306B\u3059\u308B\u306B\u306F\u3001-source 5\u4EE5\u964D\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044) @@ -1351,7 +1355,7 @@ compiler.err.annotations.not.supported.in.source=\u6CE8\u91C8\u306F-source {0}\u #308 compiler.err.type.annotations.not.supported.in.source=\ #308 type annotations are not supported in -source {0}\n\ -#308 (use -source 7 or higher to enable type annotations) +#308 (use -source 8 or higher to enable type annotations) # 0: string compiler.err.foreach.not.supported.in.source=for-each\u30EB\u30FC\u30D7\u306F-source {0}\u3067\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\n(for-each\u30EB\u30FC\u30D7\u3092\u4F7F\u7528\u53EF\u80FD\u306B\u3059\u308B\u306B\u306F\u3001-source 5\u4EE5\u964D\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044) diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties index 9ede9a363ba..005bc3b3e69 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2013, 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 @@ -1340,6 +1340,10 @@ compiler.err.enum.as.identifier=\u4ECE\u53D1\u884C\u7248 5 \u5F00\u59CB, ''enum' compiler.err.assert.as.identifier=\u4ECE\u53D1\u884C\u7248 1.4 \u5F00\u59CB, ''assert'' \u662F\u4E00\u4E2A\u5173\u952E\u5B57, \u4F46\u4E0D\u80FD\u7528\u4F5C\u6807\u8BC6\u7B26\n(\u8BF7\u4F7F\u7528 -source 1.3 \u6216\u66F4\u4F4E\u7248\u672C\u4EE5\u5C06 ''assert'' \u7528\u4F5C\u6807\u8BC6\u7B26) +# TODO 308: make a better error message +# compiler.err.this.as.identifier=\ +# as of release 8, ''this'' is allowed as the parameter name for the receiver type only, which has to be the first parameter + # 0: string compiler.err.generics.not.supported.in.source=-source {0} \u4E2D\u4E0D\u652F\u6301\u6CDB\u578B\n(\u8BF7\u4F7F\u7528 -source 5 \u6216\u66F4\u9AD8\u7248\u672C\u4EE5\u542F\u7528\u6CDB\u578B) @@ -1351,7 +1355,7 @@ compiler.err.annotations.not.supported.in.source=-source {0} \u4E2D\u4E0D\u652F\ #308 compiler.err.type.annotations.not.supported.in.source=\ #308 type annotations are not supported in -source {0}\n\ -#308 (use -source 7 or higher to enable type annotations) +#308 (use -source 8 or higher to enable type annotations) # 0: string compiler.err.foreach.not.supported.in.source=-source {0} \u4E2D\u4E0D\u652F\u6301 for-each \u5FAA\u73AF\n(\u8BF7\u4F7F\u7528 -source 5 \u6216\u66F4\u9AD8\u7248\u672C\u4EE5\u542F\u7528 for-each \u5FAA\u73AF) diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java index b6ca54757c5..97a31131440 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -250,11 +250,11 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { */ TYPEAPPLY, - /** Union types, of type TypeUnion + /** Union types, of type TypeUnion. */ TYPEUNION, - /** Intersection types, of type TypeIntersection + /** Intersection types, of type TypeIntersection. */ TYPEINTERSECTION, @@ -274,10 +274,16 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { */ ANNOTATION, + /** metadata: Type annotation. + */ + TYPE_ANNOTATION, + /** metadata: Modifiers */ MODIFIERS, + /** An annotated type tree. + */ ANNOTATED_TYPE, /** Error trees, of type Erroneous. @@ -725,6 +731,8 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { public JCExpression restype; /** type parameters */ public List typarams; + /** receiver parameter */ + public JCVariableDecl recvparam; /** value parameters */ public List params; /** exceptions thrown by this method */ @@ -739,6 +747,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { Name name, JCExpression restype, List typarams, + JCVariableDecl recvparam, List params, List thrown, JCBlock body, @@ -750,6 +759,9 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { this.restype = restype; this.typarams = typarams; this.params = params; + this.recvparam = recvparam; + // TODO: do something special if the given type is null? + // receiver != null ? receiver : List.nil()); this.thrown = thrown; this.body = body; this.defaultValue = defaultValue; @@ -768,6 +780,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { public List getParameters() { return params; } + public JCVariableDecl getReceiverParameter() { return recvparam; } public List getThrows() { return thrown; } @@ -1505,6 +1518,10 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { public static class JCNewArray extends JCExpression implements NewArrayTree { public JCExpression elemtype; public List dims; + // type annotations on inner-most component + public List annotations; + // type annotations on dimensions + public List> dimAnnotations; public List elems; protected JCNewArray(JCExpression elemtype, List dims, @@ -1512,6 +1529,8 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { { this.elemtype = elemtype; this.dims = dims; + this.annotations = List.nil(); + this.dimAnnotations = List.nil(); this.elems = elems; } @Override @@ -2152,9 +2171,12 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { public Name name; /** bounds */ public List bounds; - protected JCTypeParameter(Name name, List bounds) { + /** type annotations on type parameter */ + public List annotations; + protected JCTypeParameter(Name name, List bounds, List annotations) { this.name = name; this.bounds = bounds; + this.annotations = annotations; } @Override public void accept(Visitor v) { v.visitTypeParameter(this); } @@ -2164,6 +2186,9 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { public List getBounds() { return bounds; } + public List getAnnotations() { + return annotations; + } @Override public R accept(TreeVisitor v, D d) { return v.visitTypeParameter(this, d); @@ -2230,16 +2255,27 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { } public static class JCAnnotation extends JCExpression implements AnnotationTree { + // Either Tag.ANNOTATION or Tag.TYPE_ANNOTATION + private Tag tag; + public JCTree annotationType; public List args; - protected JCAnnotation(JCTree annotationType, List args) { + + // Attribute.Compound if tag is ANNOTATION + // Attribute.TypeCompound if tag is TYPE_ANNOTATION + public Attribute.Compound attribute; + + protected JCAnnotation(Tag tag, JCTree annotationType, List args) { + this.tag = tag; this.annotationType = annotationType; this.args = args; } + @Override public void accept(Visitor v) { v.visitAnnotation(this); } - public Kind getKind() { return Kind.ANNOTATION; } + public Kind getKind() { return TreeInfo.tagToKind(getTag()); } + public JCTree getAnnotationType() { return annotationType; } public List getArguments() { return args; @@ -2250,7 +2286,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { } @Override public Tag getTag() { - return ANNOTATION; + return tag; } } @@ -2281,6 +2317,35 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { } } + public static class JCAnnotatedType extends JCExpression implements com.sun.source.tree.AnnotatedTypeTree { + // type annotations + public List annotations; + public JCExpression underlyingType; + + protected JCAnnotatedType(List annotations, JCExpression underlyingType) { + this.annotations = annotations; + this.underlyingType = underlyingType; + } + @Override + public void accept(Visitor v) { v.visitAnnotatedType(this); } + + public Kind getKind() { return Kind.ANNOTATED_TYPE; } + public List getAnnotations() { + return annotations; + } + public JCExpression getUnderlyingType() { + return underlyingType; + } + @Override + public R accept(TreeVisitor v, D d) { + return v.visitAnnotatedType(this, d); + } + @Override + public Tag getTag() { + return ANNOTATED_TYPE; + } + } + public static class JCErroneous extends JCExpression implements com.sun.source.tree.ErroneousTree { public List errs; @@ -2347,6 +2412,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { Name name, JCExpression restype, List typarams, + JCVariableDecl recvparam, List params, List thrown, JCBlock body, @@ -2472,6 +2538,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { public void visitTypeBoundKind(TypeBoundKind that) { visitTree(that); } public void visitAnnotation(JCAnnotation that) { visitTree(that); } public void visitModifiers(JCModifiers that) { visitTree(that); } + public void visitAnnotatedType(JCAnnotatedType that) { visitTree(that); } public void visitErroneous(JCErroneous that) { visitTree(that); } public void visitLetExpr(LetExpr that) { visitTree(that); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java index 094b8610c0b..3e6c149fbbc 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java @@ -29,7 +29,6 @@ import java.io.*; import com.sun.source.tree.MemberReferenceTree.ReferenceMode; import com.sun.tools.javac.code.*; -import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.List; @@ -261,6 +260,15 @@ public class Pretty extends JCTree.Visitor { } } + public void printTypeAnnotations(List trees) throws IOException { + if (trees.nonEmpty()) + print(" "); + for (List l = trees; l.nonEmpty(); l = l.tail) { + printExpr(l.head); + print(" "); + } + } + /** Print documentation comment, if it exists * @param tree The tree for which a documentation comment should be printed. */ @@ -491,6 +499,12 @@ public class Pretty extends JCTree.Visitor { print(" " + tree.name); } print("("); + if (tree.recvparam!=null) { + printExpr(tree.recvparam); + if (tree.params.size() > 0) { + print(", "); + } + } printExprs(tree.params); print(")"); if (tree.thrown.nonEmpty()) { @@ -543,7 +557,15 @@ public class Pretty extends JCTree.Visitor { } else { printExpr(tree.mods); if ((tree.mods.flags & VARARGS) != 0) { - printExpr(((JCArrayTypeTree) tree.vartype).elemtype); + JCTree vartype = tree.vartype; + List tas = null; + if (vartype instanceof JCAnnotatedType) { + tas = ((JCAnnotatedType)vartype).annotations; + vartype = ((JCAnnotatedType)vartype).underlyingType; + } + printExpr(((JCArrayTypeTree) vartype).elemtype); + if (tas != null) + printTypeAnnotations(tas); print("... " + tree.name); } else { printExpr(tree.vartype); @@ -919,16 +941,29 @@ public class Pretty extends JCTree.Visitor { try { if (tree.elemtype != null) { print("new "); + printTypeAnnotations(tree.annotations); JCTree elem = tree.elemtype; - if (elem.hasTag(TYPEARRAY)) - printBaseElementType((JCArrayTypeTree) elem); - else - printExpr(elem); + printBaseElementType(elem); + boolean isElemAnnoType = elem instanceof JCAnnotatedType; + int i = 0; + List> da = tree.dimAnnotations; for (List l = tree.dims; l.nonEmpty(); l = l.tail) { + if (da.size() > i) { + printTypeAnnotations(da.get(i)); + } print("["); + i++; printExpr(l.head); print("]"); } + if (tree.elems != null) { + if (isElemAnnoType) { + printTypeAnnotations(((JCAnnotatedType)tree.elemtype).annotations); + } + print("[]"); + } + if (isElemAnnoType) + elem = ((JCAnnotatedType)elem).underlyingType; if (elem instanceof JCArrayTypeTree) printBrackets((JCArrayTypeTree) elem); } @@ -1225,6 +1260,12 @@ public class Pretty extends JCTree.Visitor { JCTree elem; while (true) { elem = tree.elemtype; + if (elem.hasTag(ANNOTATED_TYPE)) { + JCAnnotatedType atype = (JCAnnotatedType) elem; + elem = atype.underlyingType; + if (!elem.hasTag(TYPEARRAY)) break; + printTypeAnnotations(atype.annotations); + } print("[]"); if (!elem.hasTag(TYPEARRAY)) break; tree = (JCArrayTypeTree) elem; @@ -1327,6 +1368,32 @@ public class Pretty extends JCTree.Visitor { } } + public void visitAnnotatedType(JCAnnotatedType tree) { + try { + if (tree.underlyingType.getKind() == JCTree.Kind.MEMBER_SELECT) { + JCFieldAccess access = (JCFieldAccess) tree.underlyingType; + printExpr(access.selected, TreeInfo.postfixPrec); + print("."); + printTypeAnnotations(tree.annotations); + print(access.name); + } else if (tree.underlyingType.getKind() == JCTree.Kind.ARRAY_TYPE) { + JCArrayTypeTree array = (JCArrayTypeTree) tree.underlyingType; + printBaseElementType(tree); + printTypeAnnotations(tree.annotations); + print("[]"); + JCExpression elem = array.elemtype; + if (elem.hasTag(TYPEARRAY)) { + printBrackets((JCArrayTypeTree) elem); + } + } else { + printTypeAnnotations(tree.annotations); + printExpr(tree.underlyingType); + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + public void visitTree(JCTree tree) { try { print("(UNKNOWN: " + tree + ")"); diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java index c2e2ef92290..49f988d8b6d 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2013, 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 @@ -71,11 +71,26 @@ public class TreeCopier

implements TreeVisitor { return lb.toList(); } + public JCTree visitAnnotatedType(AnnotatedTypeTree node, P p) { + JCAnnotatedType t = (JCAnnotatedType) node; + List annotations = copy(t.annotations, p); + JCExpression underlyingType = copy(t.underlyingType, p); + return M.at(t.pos).AnnotatedType(annotations, underlyingType); + } + public JCTree visitAnnotation(AnnotationTree node, P p) { JCAnnotation t = (JCAnnotation) node; JCTree annotationType = copy(t.annotationType, p); List args = copy(t.args, p); - return M.at(t.pos).Annotation(annotationType, args); + if (t.getKind() == Tree.Kind.TYPE_ANNOTATION) { + JCAnnotation newTA = M.at(t.pos).TypeAnnotation(annotationType, args); + newTA.attribute = t.attribute; + return newTA; + } else { + JCAnnotation newT = M.at(t.pos).Annotation(annotationType, args); + newT.attribute = t.attribute; + return newT; + } } public JCTree visitAssert(AssertTree node, P p) { @@ -233,10 +248,11 @@ public class TreeCopier

implements TreeVisitor { JCExpression restype = copy(t.restype, p); List typarams = copy(t.typarams, p); List params = copy(t.params, p); + JCVariableDecl recvparam = copy(t.recvparam, p); List thrown = copy(t.thrown, p); JCBlock body = copy(t.body, p); JCExpression defaultValue = copy(t.defaultValue, p); - return M.at(t.pos).MethodDef(mods, t.name, restype, typarams, params, thrown, body, defaultValue); + return M.at(t.pos).MethodDef(mods, t.name, restype, typarams, recvparam, params, thrown, body, defaultValue); } public JCTree visitMethodInvocation(MethodInvocationTree node, P p) { @@ -384,8 +400,9 @@ public class TreeCopier

implements TreeVisitor { public JCTree visitTypeParameter(TypeParameterTree node, P p) { JCTypeParameter t = (JCTypeParameter) node; + List annos = copy(t.annotations, p); List bounds = copy(t.bounds, p); - return M.at(t.pos).TypeParameter(t.name, bounds); + return M.at(t.pos).TypeParameter(t.name, bounds, annos); } public JCTree visitInstanceOf(InstanceOfTree node, P p) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java index deed8352494..36e3a100729 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -453,6 +453,19 @@ public class TreeInfo { case POSTINC: case POSTDEC: return getStartPos(((JCUnary) tree).arg); + case ANNOTATED_TYPE: { + JCAnnotatedType node = (JCAnnotatedType) tree; + if (node.annotations.nonEmpty()) { + if (node.underlyingType.hasTag(TYPEARRAY) || + node.underlyingType.hasTag(SELECT)) { + return getStartPos(node.underlyingType); + } else { + return getStartPos(node.annotations.head); + } + } else { + return getStartPos(node.underlyingType); + } + } case NEWCLASS: { JCNewClass node = (JCNewClass)tree; if (node.encl != null) @@ -560,6 +573,8 @@ public class TreeInfo { return getEndPos(((JCUnary) tree).arg, endPosTable); case WHILELOOP: return getEndPos(((JCWhileLoop) tree).body, endPosTable); + case ANNOTATED_TYPE: + return getEndPos(((JCAnnotatedType) tree).underlyingType, endPosTable); case ERRONEOUS: { JCErroneous node = (JCErroneous)tree; if (node.errs != null && node.errs.nonEmpty()) @@ -799,6 +814,8 @@ public class TreeInfo { return ((JCFieldAccess) tree).sym; case TYPEAPPLY: return symbol(((JCTypeApply) tree).clazz); + case ANNOTATED_TYPE: + return symbol(((JCAnnotatedType) tree).underlyingType); default: return null; } @@ -1036,17 +1053,24 @@ public class TreeInfo { case NULLCHK: return Tree.Kind.OTHER; + case ANNOTATION: + return Tree.Kind.ANNOTATION; + case TYPE_ANNOTATION: + return Tree.Kind.TYPE_ANNOTATION; + default: return null; } } /** - * Returns the underlying type of the tree if it is annotated type, - * or the tree itself otherwise + * Returns the underlying type of the tree if it is an annotated type, + * or the tree itself otherwise. */ public static JCExpression typeIn(JCExpression tree) { switch (tree.getTag()) { + case ANNOTATED_TYPE: + return ((JCAnnotatedType)tree).underlyingType; case IDENT: /* simple names */ case TYPEIDENT: /* primitive name */ case SELECT: /* qualified name */ @@ -1054,20 +1078,55 @@ public class TreeInfo { case WILDCARD: /* wild cards */ case TYPEPARAMETER: /* type parameters */ case TYPEAPPLY: /* parameterized types */ + case ERRONEOUS: /* error tree TODO: needed for BadCast JSR308 test case. Better way? */ return tree; default: throw new AssertionError("Unexpected type tree: " + tree); } } + /* Return the inner-most type of a type tree. + * For an array that contains an annotated type, return that annotated type. + * TODO: currently only used by Pretty. Describe behavior better. + */ public static JCTree innermostType(JCTree type) { - switch (type.getTag()) { - case TYPEARRAY: - return innermostType(((JCArrayTypeTree)type).elemtype); - case WILDCARD: - return innermostType(((JCWildcard)type).inner); - default: - return type; + JCTree lastAnnotatedType = null; + JCTree cur = type; + loop: while (true) { + switch (cur.getTag()) { + case TYPEARRAY: + lastAnnotatedType = null; + cur = ((JCArrayTypeTree)cur).elemtype; + break; + case WILDCARD: + lastAnnotatedType = null; + cur = ((JCWildcard)cur).inner; + break; + case ANNOTATED_TYPE: + lastAnnotatedType = cur; + cur = ((JCAnnotatedType)cur).underlyingType; + break; + default: + break loop; + } + } + if (lastAnnotatedType!=null) { + return lastAnnotatedType; + } else { + return cur; } } + + private static class TypeAnnotationFinder extends TreeScanner { + public boolean foundTypeAnno = false; + public void visitAnnotation(JCAnnotation tree) { + foundTypeAnno = foundTypeAnno || tree.hasTag(TYPE_ANNOTATION); + } + } + + public static boolean containsTypeAnnotation(JCTree e) { + TypeAnnotationFinder finder = new TypeAnnotationFinder(); + finder.scan(e); + return finder.foundTypeAnno; + } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java index 27a2d74feda..cc6405e22d9 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -169,10 +169,26 @@ public class TreeMaker implements JCTree.Factory { List thrown, JCBlock body, JCExpression defaultValue) { + return MethodDef( + mods, name, restype, typarams, null, params, + thrown, body, defaultValue); + } + + public JCMethodDecl MethodDef(JCModifiers mods, + Name name, + JCExpression restype, + List typarams, + JCVariableDecl recvparam, + List params, + List thrown, + JCBlock body, + JCExpression defaultValue) + { JCMethodDecl tree = new JCMethodDecl(mods, name, restype, typarams, + recvparam, params, thrown, body, @@ -463,7 +479,11 @@ public class TreeMaker implements JCTree.Factory { } public JCTypeParameter TypeParameter(Name name, List bounds) { - JCTypeParameter tree = new JCTypeParameter(name, bounds); + return TypeParameter(name, bounds, List.nil()); + } + + public JCTypeParameter TypeParameter(Name name, List bounds, List annos) { + JCTypeParameter tree = new JCTypeParameter(name, bounds, annos); tree.pos = pos; return tree; } @@ -481,7 +501,13 @@ public class TreeMaker implements JCTree.Factory { } public JCAnnotation Annotation(JCTree annotationType, List args) { - JCAnnotation tree = new JCAnnotation(annotationType, args); + JCAnnotation tree = new JCAnnotation(Tag.ANNOTATION, annotationType, args); + tree.pos = pos; + return tree; + } + + public JCAnnotation TypeAnnotation(JCTree annotationType, List args) { + JCAnnotation tree = new JCAnnotation(Tag.TYPE_ANNOTATION, annotationType, args); tree.pos = pos; return tree; } @@ -497,6 +523,12 @@ public class TreeMaker implements JCTree.Factory { return Modifiers(flags, List.nil()); } + public JCAnnotatedType AnnotatedType(List annotations, JCExpression underlyingType) { + JCAnnotatedType tree = new JCAnnotatedType(annotations, underlyingType); + tree.pos = pos; + return tree; + } + public JCErroneous Erroneous() { return Erroneous(List.nil()); } @@ -755,7 +787,11 @@ public class TreeMaker implements JCTree.Factory { result = Erroneous(); } public void visitCompound(Attribute.Compound compound) { - result = visitCompoundInternal(compound); + if (compound instanceof Attribute.TypeCompound) { + result = visitTypeCompoundInternal((Attribute.TypeCompound) compound); + } else { + result = visitCompoundInternal(compound); + } } public JCAnnotation visitCompoundInternal(Attribute.Compound compound) { ListBuffer args = new ListBuffer(); @@ -766,6 +802,15 @@ public class TreeMaker implements JCTree.Factory { } return Annotation(Type(compound.type), args.toList()); } + public JCAnnotation visitTypeCompoundInternal(Attribute.TypeCompound compound) { + ListBuffer args = new ListBuffer(); + for (List> values = compound.values; values.nonEmpty(); values=values.tail) { + Pair pair = values.head; + JCExpression valueTree = translate(pair.snd); + args.append(Assign(Ident(pair.fst), valueTree).setType(valueTree.type)); + } + return TypeAnnotation(Type(compound.type), args.toList()); + } public void visitArray(Attribute.Array array) { ListBuffer elems = new ListBuffer(); for (int i = 0; i < array.values.length; i++) @@ -779,7 +824,11 @@ public class TreeMaker implements JCTree.Factory { JCAnnotation translate(Attribute.Compound a) { return visitCompoundInternal(a); } + JCAnnotation translate(Attribute.TypeCompound a) { + return visitTypeCompoundInternal(a); + } } + AnnotationBuilder annotationBuilder = new AnnotationBuilder(); /** Create an annotation tree from an attribute. @@ -788,6 +837,10 @@ public class TreeMaker implements JCTree.Factory { return annotationBuilder.translate((Attribute.Compound)a); } + public JCAnnotation TypeAnnotation(Attribute a) { + return annotationBuilder.translate((Attribute.TypeCompound) a); + } + /** Create a method definition from a method symbol and a method body. */ public JCMethodDecl MethodDef(MethodSymbol m, JCBlock body) { @@ -804,6 +857,7 @@ public class TreeMaker implements JCTree.Factory { m.name, Type(mtype.getReturnType()), TypeParams(mtype.getTypeArguments()), + null, // receiver type Params(mtype.getParameterTypes(), m), Types(mtype.getThrownTypes()), body, @@ -822,7 +876,6 @@ public class TreeMaker implements JCTree.Factory { */ public List TypeParams(List typarams) { ListBuffer tparams = new ListBuffer(); - int i = 0; for (List l = typarams; l.nonEmpty(); l = l.tail) tparams.append(TypeParam(l.head.tsym.name, (TypeVar)l.head)); return tparams.toList(); diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java index eff0fe2c617..57724d34292 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -84,6 +84,7 @@ public class TreeScanner extends Visitor { scan(tree.mods); scan(tree.restype); scan(tree.typarams); + scan(tree.recvparam); scan(tree.params); scan(tree.thrown); scan(tree.defaultValue); @@ -200,15 +201,18 @@ public class TreeScanner extends Visitor { public void visitNewClass(JCNewClass tree) { scan(tree.encl); - scan(tree.clazz); scan(tree.typeargs); + scan(tree.clazz); scan(tree.args); scan(tree.def); } public void visitNewArray(JCNewArray tree) { + scan(tree.annotations); scan(tree.elemtype); scan(tree.dims); + for (List annos : tree.dimAnnotations) + scan(annos); scan(tree.elems); } @@ -291,6 +295,7 @@ public class TreeScanner extends Visitor { } public void visitTypeParameter(JCTypeParameter tree) { + scan(tree.annotations); scan(tree.bounds); } @@ -314,6 +319,11 @@ public class TreeScanner extends Visitor { scan(tree.args); } + public void visitAnnotatedType(JCAnnotatedType tree) { + scan(tree.annotations); + scan(tree.underlyingType); + } + public void visitErroneous(JCErroneous tree) { } diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java index daf456fa90d..42e97deee11 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -139,6 +139,7 @@ public class TreeTranslator extends JCTree.Visitor { tree.mods = translate(tree.mods); tree.restype = translate(tree.restype); tree.typarams = translateTypeParams(tree.typarams); + tree.recvparam = translate(tree.recvparam); tree.params = translateVarDefs(tree.params); tree.thrown = translate(tree.thrown); tree.body = translate(tree.body); @@ -289,6 +290,11 @@ public class TreeTranslator extends JCTree.Visitor { } public void visitNewArray(JCNewArray tree) { + tree.annotations = translate(tree.annotations); + List> dimAnnos = List.nil(); + for (List origDimAnnos : tree.dimAnnotations) + dimAnnos = dimAnnos.append(translate(origDimAnnos)); + tree.dimAnnotations = dimAnnos; tree.elemtype = translate(tree.elemtype); tree.dims = translate(tree.dims); tree.elems = translate(tree.elems); @@ -385,6 +391,7 @@ public class TreeTranslator extends JCTree.Visitor { } public void visitTypeParameter(JCTypeParameter tree) { + tree.annotations = translate(tree.annotations); tree.bounds = translate(tree.bounds); result = tree; } @@ -422,6 +429,12 @@ public class TreeTranslator extends JCTree.Visitor { result = tree; } + public void visitAnnotatedType(JCAnnotatedType tree) { + tree.annotations = translate(tree.annotations); + tree.underlyingType = translate(tree.underlyingType); + result = tree; + } + public void visitTree(JCTree tree) { throw new AssertionError(tree); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java b/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java index 17ce2319dc1..be531e0ef03 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -388,7 +388,7 @@ public class JCDiagnostic implements Diagnostic { this.source = source; this.position = pos; this.key = key; - this.args = args; + this.args = args; int n = (pos == null ? Position.NOPOS : pos.getPreferredPosition()); if (n == Position.NOPOS || source == null) diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java index 70267f7097c..4ed16c1eb6d 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -217,7 +217,7 @@ public class Log extends AbstractLog { private JavacMessages messages; /** -+ * Handler for initial dispatch of diagnostics. + * Handler for initial dispatch of diagnostics. */ private DiagnosticHandler diagnosticHandler; @@ -385,14 +385,17 @@ public class Log extends AbstractLog { noticeWriter = warnWriter = errWriter = pw; } - public void setWriters(Log other) { + /** + * Propagate the previous log's information. + */ + public void initRound(Log other) { this.noticeWriter = other.noticeWriter; this.warnWriter = other.warnWriter; this.errWriter = other.errWriter; - } - - public void setSourceMap(Log other) { this.sourceMap = other.sourceMap; + this.recorded = other.recorded; + this.nerrors = other.nerrors; + this.nwarnings = other.nwarnings; } /** diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/AbstractTypeImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/AbstractTypeImpl.java index e589bfa8678..6adcb43f90b 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/AbstractTypeImpl.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/AbstractTypeImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -104,4 +104,8 @@ abstract class AbstractTypeImpl implements com.sun.javadoc.Type { public AnnotationTypeDoc asAnnotationTypeDoc() { return null; } + + public AnnotatedType asAnnotatedType() { + return null; + } } diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotatedTypeImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotatedTypeImpl.java new file mode 100644 index 00000000000..a49dc8a3134 --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotatedTypeImpl.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2003, 2013, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package com.sun.tools.javadoc; + +import com.sun.javadoc.*; +import com.sun.tools.javac.code.Attribute; +import com.sun.tools.javac.code.Attribute.TypeCompound; +import com.sun.tools.javac.util.List; + +/** + * Implementation of AnnotatedType, which + * represents an annotated type. + * + * @author Mahmood Ali + * @since 1.8 + */ +public class AnnotatedTypeImpl + extends AbstractTypeImpl implements AnnotatedType { + + AnnotatedTypeImpl(DocEnv env, com.sun.tools.javac.code.Type.AnnotatedType type) { + super(env, type); + } + + /** + * Get the annotations of this program element. + * Return an empty array if there are none. + */ + @Override + public AnnotationDesc[] annotations() { + List tas = ((com.sun.tools.javac.code.Type.AnnotatedType)type).typeAnnotations; + if (tas == null || + tas.isEmpty()) { + return new AnnotationDesc[0]; + } + AnnotationDesc res[] = new AnnotationDesc[tas.length()]; + int i = 0; + for (Attribute.Compound a : tas) { + res[i++] = new AnnotationDescImpl(env, a); + } + return res; + } + + @Override + public com.sun.javadoc.Type underlyingType() { + return TypeMaker.getType(env, ((com.sun.tools.javac.code.Type.AnnotatedType)type).underlyingType, true, false); + } + + @Override + public AnnotatedType asAnnotatedType() { + return this; + } + + @Override + public String toString() { + return typeName(); + } + + @Override + public String typeName() { + return this.underlyingType().typeName(); + } + + @Override + public String qualifiedTypeName() { + return this.underlyingType().qualifiedTypeName(); + } + + @Override + public String simpleTypeName() { + return this.underlyingType().simpleTypeName(); + } + + @Override + public String dimension() { + return this.underlyingType().dimension(); + } + + @Override + public boolean isPrimitive() { + return this.underlyingType().isPrimitive(); + } + + @Override + public ClassDoc asClassDoc() { + return this.underlyingType().asClassDoc(); + } + + @Override + public TypeVariable asTypeVariable() { + return this.underlyingType().asTypeVariable(); + } + + @Override + public WildcardType asWildcardType() { + return this.underlyingType().asWildcardType(); + } + + @Override + public ParameterizedType asParameterizedType() { + return this.underlyingType().asParameterizedType(); + } +} diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java index ffcc5e7853f..3d1ac353cc0 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -1185,6 +1185,13 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc { return null; } + /** + * Returns null, as this is not an annotated type. + */ + public AnnotatedType asAnnotatedType() { + return null; + } + /** * Return false, as this is not a primitive type. */ diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/ExecutableMemberDocImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/ExecutableMemberDocImpl.java index 72a666d27a7..a1a741d10ff 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/ExecutableMemberDocImpl.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/ExecutableMemberDocImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -28,10 +28,14 @@ package com.sun.tools.javadoc; import java.lang.reflect.Modifier; import java.text.CollationKey; +import javax.lang.model.type.TypeKind; + import com.sun.javadoc.*; import com.sun.source.util.TreePath; +import com.sun.tools.javac.code.Attribute; import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.code.Attribute.Compound; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Type; import com.sun.tools.javac.util.List; @@ -195,6 +199,24 @@ public abstract class ExecutableMemberDocImpl return result; } + public AnnotationDesc[] receiverAnnotations() { + // TODO: change how receiver annotations are output! + Type recvtype = sym.type.asMethodType().recvtype; + if (recvtype == null) { + return new AnnotationDesc[0]; + } + if (recvtype.getKind() != TypeKind.ANNOTATED) { + return new AnnotationDesc[0]; + } + List typeAnnos = ((com.sun.tools.javac.code.Type.AnnotatedType)recvtype).typeAnnotations; + AnnotationDesc result[] = new AnnotationDesc[typeAnnos.length()]; + int i = 0; + for (Attribute.Compound a : typeAnnos) { + result[i++] = new AnnotationDescImpl(env, a); + } + return result; + } + /** * Return the formal type parameters of this method or constructor. * Return an empty array if there are none. diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/PrimitiveType.java b/langtools/src/share/classes/com/sun/tools/javadoc/PrimitiveType.java index 15679a79f46..9f6345f98b0 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/PrimitiveType.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/PrimitiveType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -121,12 +121,19 @@ class PrimitiveType implements com.sun.javadoc.Type { } /** - * Return null, as this is not a wildcard type; + * Return null, as this is not a wildcard type. */ public WildcardType asWildcardType() { return null; } + /** + * Return null, as this is not an annotated type. + */ + public AnnotatedType asAnnotatedType() { + return null; + } + /** * Returns a string representation of the type. * diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java b/langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java index dd0f355fa24..4a24e9406a5 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/TypeMaker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -25,6 +25,8 @@ package com.sun.tools.javadoc; +import javax.lang.model.type.TypeKind; + import com.sun.javadoc.*; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol.ClassSymbol; @@ -51,12 +53,27 @@ public class TypeMaker { * @param errToClassDoc if true, ERROR type results in a ClassDoc; * false preserves legacy behavior */ + public static com.sun.javadoc.Type getType(DocEnv env, Type t, + boolean errorToClassDoc) { + return getType(env, t, errorToClassDoc, true); + } + @SuppressWarnings("fallthrough") public static com.sun.javadoc.Type getType(DocEnv env, Type t, - boolean errToClassDoc) { + boolean errToClassDoc, boolean considerAnnotations) { if (env.legacyDoclet) { t = env.types.erasure(t); } + if (considerAnnotations + && t.getKind() == TypeKind.ANNOTATED) { + return new AnnotatedTypeImpl(env, (com.sun.tools.javac.code.Type.AnnotatedType) t); + } + + if (t.getKind() == TypeKind.ANNOTATED) { + Type.AnnotatedType at = (Type.AnnotatedType) t; + return new AnnotatedTypeImpl(env, at); + } + switch (t.getTag()) { case CLASS: if (ClassDocImpl.isGeneric((ClassSymbol)t.tsym)) { @@ -129,6 +146,11 @@ public class TypeMaker { * Class names are qualified if "full" is true. */ static String getTypeString(DocEnv env, Type t, boolean full) { + // TODO: should annotations be included here? + if (t.getKind() == TypeKind.ANNOTATED) { + Type.AnnotatedType at = (Type.AnnotatedType)t; + t = at.underlyingType; + } switch (t.getTag()) { case ARRAY: StringBuilder s = new StringBuilder(); @@ -281,6 +303,13 @@ public class TypeMaker { return null; } + /** + * Return null, as there are no annotations of the type + */ + public AnnotatedType asAnnotatedType() { + return null; + } + /** * Return this type as an AnnotationTypeDoc if it * represents an annotation type. Array dimensions are ignored. diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java index 85f946c6bf9..19a5bb9fab4 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java +++ b/langtools/src/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -25,8 +25,12 @@ package com.sun.tools.javadoc; +import javax.lang.model.type.TypeKind; + import com.sun.javadoc.*; +import com.sun.tools.javac.code.Attribute; +import com.sun.tools.javac.code.Attribute.TypeCompound; import com.sun.tools.javac.code.Kinds; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol.ClassSymbol; @@ -120,11 +124,30 @@ public class TypeVariableImpl extends AbstractTypeImpl implements TypeVariable { * Get the bounds of a type variable as listed in the "extends" clause. */ private static List getBounds(TypeVar v, DocEnv env) { - Name boundname = v.getUpperBound().tsym.getQualifiedName(); - if (boundname == boundname.table.names.java_lang_Object) { + final Type upperBound = v.getUpperBound(); + Name boundname = upperBound.tsym.getQualifiedName(); + if (boundname == boundname.table.names.java_lang_Object + && upperBound.getKind() != TypeKind.ANNOTATED) { return List.nil(); } else { return env.types.getBounds(v); } } + + /** + * Get the annotations of this program element. + * Return an empty array if there are none. + */ + public AnnotationDesc[] annotations() { + if (type.getKind() != TypeKind.ANNOTATED) { + return new AnnotationDesc[0]; + } + List tas = ((com.sun.tools.javac.code.Type.AnnotatedType) type).typeAnnotations; + AnnotationDesc res[] = new AnnotationDesc[tas.length()]; + int i = 0; + for (Attribute.Compound a : tas) { + res[i++] = new AnnotationDescImpl(env, a); + } + return res; + } } diff --git a/langtools/src/share/classes/com/sun/tools/javap/AnnotationWriter.java b/langtools/src/share/classes/com/sun/tools/javap/AnnotationWriter.java index 37ec6b291e4..6f894e7cb62 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/AnnotationWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javap/AnnotationWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2013, 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 @@ -26,6 +26,7 @@ package com.sun.tools.javap; import com.sun.tools.classfile.Annotation; +import com.sun.tools.classfile.TypeAnnotation; import com.sun.tools.classfile.Annotation.Annotation_element_value; import com.sun.tools.classfile.Annotation.Array_element_value; import com.sun.tools.classfile.Annotation.Class_element_value; @@ -76,6 +77,124 @@ public class AnnotationWriter extends BasicWriter { print(")"); } + public void write(TypeAnnotation annot) { + write(annot, true, false); + } + + public void write(TypeAnnotation annot, boolean showOffsets, boolean resolveIndices) { + write(annot.annotation, resolveIndices); + print(": "); + write(annot.position, showOffsets); + } + + public void write(TypeAnnotation.Position pos, boolean showOffsets) { + print(pos.type); + + switch (pos.type) { + // type cast + case CAST: + // instanceof + case INSTANCEOF: + // new expression + case NEW: + if (showOffsets) { + print(", offset="); + print(pos.offset); + } + break; + // local variable + case LOCAL_VARIABLE: + // resource variable + case RESOURCE_VARIABLE: + if (pos.lvarOffset == null) { + print(", lvarOffset is Null!"); + break; + } + print(", {"); + for (int i = 0; i < pos.lvarOffset.length; ++i) { + if (i != 0) print("; "); + if (showOffsets) { + print("start_pc="); + print(pos.lvarOffset[i]); + } + print(", length="); + print(pos.lvarLength[i]); + print(", index="); + print(pos.lvarIndex[i]); + } + print("}"); + break; + // exception parameter + case EXCEPTION_PARAMETER: + print(", exception_index="); + print(pos.exception_index); + break; + // method receiver + case METHOD_RECEIVER: + // Do nothing + break; + // type parameter + case CLASS_TYPE_PARAMETER: + case METHOD_TYPE_PARAMETER: + print(", param_index="); + print(pos.parameter_index); + break; + // type parameter bound + case CLASS_TYPE_PARAMETER_BOUND: + case METHOD_TYPE_PARAMETER_BOUND: + print(", param_index="); + print(pos.parameter_index); + print(", bound_index="); + print(pos.bound_index); + break; + // class extends or implements clause + case CLASS_EXTENDS: + print(", type_index="); + print(pos.type_index); + break; + // throws + case THROWS: + print(", type_index="); + print(pos.type_index); + break; + // method parameter + case METHOD_FORMAL_PARAMETER: + print(", param_index="); + print(pos.parameter_index); + break; + // method/constructor/reference type argument + case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: + case METHOD_INVOCATION_TYPE_ARGUMENT: + case METHOD_REFERENCE_TYPE_ARGUMENT: + if (showOffsets) { + print(", offset="); + print(pos.offset); + } + print(", type_index="); + print(pos.type_index); + break; + // We don't need to worry about these + case METHOD_RETURN: + case FIELD: + break; + // lambda formal parameter + case LAMBDA_FORMAL_PARAMETER: + print(", param_index="); + print(pos.parameter_index); + break; + case UNKNOWN: + throw new AssertionError("AnnotationWriter: UNKNOWN target type should never occur!"); + default: + throw new AssertionError("AnnotationWriter: Unknown target type for position: " + pos); + } + + // Append location data for generics/arrays. + if (!pos.location.isEmpty()) { + print(", location="); + print(pos.location); + } + } + public void write(Annotation.element_value_pair pair) { write(pair, false); } diff --git a/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java b/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java index 329dccb2f87..d25477b237e 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2013, 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 @@ -49,8 +49,10 @@ import com.sun.tools.classfile.LocalVariableTypeTable_attribute; import com.sun.tools.classfile.MethodParameters_attribute; import com.sun.tools.classfile.RuntimeInvisibleAnnotations_attribute; import com.sun.tools.classfile.RuntimeInvisibleParameterAnnotations_attribute; +import com.sun.tools.classfile.RuntimeInvisibleTypeAnnotations_attribute; import com.sun.tools.classfile.RuntimeVisibleAnnotations_attribute; import com.sun.tools.classfile.RuntimeVisibleParameterAnnotations_attribute; +import com.sun.tools.classfile.RuntimeVisibleTypeAnnotations_attribute; import com.sun.tools.classfile.Signature_attribute; import com.sun.tools.classfile.SourceDebugExtension_attribute; import com.sun.tools.classfile.SourceFile_attribute; @@ -433,6 +435,30 @@ public class AttributeWriter extends BasicWriter return null; } + public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, Void ignore) { + println("RuntimeVisibleTypeAnnotations:"); + indent(+1); + for (int i = 0; i < attr.annotations.length; i++) { + print(i + ": "); + annotationWriter.write(attr.annotations[i]); + println(); + } + indent(-1); + return null; + } + + public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, Void ignore) { + println("RuntimeInvisibleTypeAnnotations:"); + indent(+1); + for (int i = 0; i < attr.annotations.length; i++) { + print(i + ": "); + annotationWriter.write(attr.annotations[i]); + println(); + } + indent(-1); + return null; + } + public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, Void ignore) { println("RuntimeVisibleParameterAnnotations:"); indent(+1); diff --git a/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java b/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java index 50ce27dcbdf..657194d19c6 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2013, 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 @@ -64,6 +64,7 @@ public class CodeWriter extends BasicWriter { stackMapWriter = StackMapWriter.instance(context); localVariableTableWriter = LocalVariableTableWriter.instance(context); localVariableTypeTableWriter = LocalVariableTypeTableWriter.instance(context); + typeAnnotationWriter = TypeAnnotationWriter.instance(context); options = Options.instance(context); } @@ -265,6 +266,11 @@ public class CodeWriter extends BasicWriter { detailWriters.add(tryBlockWriter); } + if (options.details.contains(InstructionDetailWriter.Kind.TYPE_ANNOS)) { + typeAnnotationWriter.reset(attr); + detailWriters.add(typeAnnotationWriter); + } + return detailWriters; } @@ -273,6 +279,7 @@ public class CodeWriter extends BasicWriter { private ConstantWriter constantWriter; private LocalVariableTableWriter localVariableTableWriter; private LocalVariableTypeTableWriter localVariableTypeTableWriter; + private TypeAnnotationWriter typeAnnotationWriter; private SourceWriter sourceWriter; private StackMapWriter stackMapWriter; private TryBlockWriter tryBlockWriter; diff --git a/langtools/src/share/classes/com/sun/tools/javap/InstructionDetailWriter.java b/langtools/src/share/classes/com/sun/tools/javap/InstructionDetailWriter.java index 7459d6c0d11..8a828b8f2b3 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/InstructionDetailWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javap/InstructionDetailWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2013, 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 @@ -42,10 +42,13 @@ public abstract class InstructionDetailWriter extends BasicWriter { LOCAL_VAR_TYPES("localVariableTypes"), SOURCE("source"), STACKMAPS("stackMaps"), - TRY_BLOCKS("tryBlocks"); + TRY_BLOCKS("tryBlocks"), + TYPE_ANNOS("typeAnnotations"); + Kind(String option) { this.option = option; } + final String option; } diff --git a/langtools/src/share/classes/com/sun/tools/javap/TypeAnnotationWriter.java b/langtools/src/share/classes/com/sun/tools/javap/TypeAnnotationWriter.java new file mode 100644 index 00000000000..e5a3a68f1a3 --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/javap/TypeAnnotationWriter.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2009, 2013, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ +package com.sun.tools.javap; + +import com.sun.tools.classfile.Attribute; +import com.sun.tools.classfile.Code_attribute; +import com.sun.tools.classfile.TypeAnnotation; +import com.sun.tools.classfile.TypeAnnotation.Position; +import com.sun.tools.classfile.Instruction; +import com.sun.tools.classfile.Method; +import com.sun.tools.classfile.RuntimeInvisibleTypeAnnotations_attribute; +import com.sun.tools.classfile.RuntimeTypeAnnotations_attribute; +import com.sun.tools.classfile.RuntimeVisibleTypeAnnotations_attribute; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Annotate instructions with details about type annotations. + * + *

This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + */ +public class TypeAnnotationWriter extends InstructionDetailWriter { + public enum NoteKind { VISIBLE, INVISIBLE }; + public static class Note { + Note(NoteKind kind, TypeAnnotation anno) { + this.kind = kind; + this.anno = anno; + } + public final NoteKind kind; + public final TypeAnnotation anno; + } + + static TypeAnnotationWriter instance(Context context) { + TypeAnnotationWriter instance = context.get(TypeAnnotationWriter.class); + if (instance == null) + instance = new TypeAnnotationWriter(context); + return instance; + } + + protected TypeAnnotationWriter(Context context) { + super(context); + context.put(TypeAnnotationWriter.class, this); + annotationWriter = AnnotationWriter.instance(context); + classWriter = ClassWriter.instance(context); + } + + public void reset(Code_attribute attr) { + Method m = classWriter.getMethod(); + pcMap = new HashMap>(); + check(NoteKind.VISIBLE, (RuntimeVisibleTypeAnnotations_attribute) m.attributes.get(Attribute.RuntimeVisibleTypeAnnotations)); + check(NoteKind.INVISIBLE, (RuntimeInvisibleTypeAnnotations_attribute) m.attributes.get(Attribute.RuntimeInvisibleTypeAnnotations)); + } + + private void check(NoteKind kind, RuntimeTypeAnnotations_attribute attr) { + if (attr == null) + return; + + for (TypeAnnotation anno: attr.annotations) { + Position p = anno.position; + Note note = null; + if (p.offset != -1) + addNote(p.offset, note = new Note(kind, anno)); + if (p.lvarOffset != null) { + for (int i = 0; i < p.lvarOffset.length; i++) { + if (note == null) + note = new Note(kind, anno); + addNote(p.lvarOffset[i], note); + } + } + } + } + + private void addNote(int pc, Note note) { + List list = pcMap.get(pc); + if (list == null) + pcMap.put(pc, list = new ArrayList()); + list.add(note); + } + + @Override + void writeDetails(Instruction instr) { + String indent = space(2); // get from Options? + int pc = instr.getPC(); + List notes = pcMap.get(pc); + if (notes != null) { + for (Note n: notes) { + print(indent); + print("@"); + annotationWriter.write(n.anno, false, true); + print(", "); + println(n.kind.toString().toLowerCase()); + } + } + } + + private AnnotationWriter annotationWriter; + private ClassWriter classWriter; + private Map> pcMap; +} diff --git a/langtools/src/share/classes/javax/lang/model/SourceVersion.java b/langtools/src/share/classes/javax/lang/model/SourceVersion.java index c810c9e6013..e2f3bfd538f 100644 --- a/langtools/src/share/classes/javax/lang/model/SourceVersion.java +++ b/langtools/src/share/classes/javax/lang/model/SourceVersion.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -46,7 +46,7 @@ import java.util.HashSet; */ public enum SourceVersion { /* - * Summary of language evoluation + * Summary of language evolution * 1.1: nested classes * 1.2: strictfp * 1.3: no changes diff --git a/langtools/src/share/classes/javax/lang/model/type/AnnotatedType.java b/langtools/src/share/classes/javax/lang/model/type/AnnotatedType.java new file mode 100644 index 00000000000..c2a27dc6e1a --- /dev/null +++ b/langtools/src/share/classes/javax/lang/model/type/AnnotatedType.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2012, 2013, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package javax.lang.model.type; + +import java.util.List; + +import javax.lang.model.element.AnnotationMirror; + +/** + * Represents an annotated type. + * + * As of the {@link javax.lang.model.SourceVersion#RELEASE_8 + * RELEASE_8} source version, annotated types can appear for all + * type uses. + * + * @author Werner Dietl + * @since 1.8 + */ +public interface AnnotatedType extends TypeMirror, + DeclaredType, TypeVariable, WildcardType, + PrimitiveType, ArrayType { + + List getAnnotations(); + TypeMirror getUnderlyingType(); +} diff --git a/langtools/src/share/classes/javax/lang/model/type/ExecutableType.java b/langtools/src/share/classes/javax/lang/model/type/ExecutableType.java index 7b2e63adc93..9bdccaaefb3 100644 --- a/langtools/src/share/classes/javax/lang/model/type/ExecutableType.java +++ b/langtools/src/share/classes/javax/lang/model/type/ExecutableType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -77,6 +77,14 @@ public interface ExecutableType extends TypeMirror { */ List getParameterTypes(); + /** + * Returns the type of this executable's receiver parameter. + * + * @return the type of this executable's receiver parameter + * TODO: null if none specified or always a valid value? + */ + TypeMirror getReceiverType(); + /** * Returns the exceptions and other throwables listed in this * executable's {@code throws} clause. diff --git a/langtools/src/share/classes/javax/lang/model/type/TypeKind.java b/langtools/src/share/classes/javax/lang/model/type/TypeKind.java index 0f67a3ba7b6..1a9f11d895e 100644 --- a/langtools/src/share/classes/javax/lang/model/type/TypeKind.java +++ b/langtools/src/share/classes/javax/lang/model/type/TypeKind.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -151,7 +151,14 @@ public enum TypeKind { * * @since 1.8 */ - INTERSECTION; + INTERSECTION, + + /** + * An annotated type. + * + * @since 1.8 + */ + ANNOTATED; /** * Returns {@code true} if this kind corresponds to a primitive diff --git a/langtools/src/share/classes/javax/lang/model/type/TypeVisitor.java b/langtools/src/share/classes/javax/lang/model/type/TypeVisitor.java index f95af6c87d9..b59cce20b74 100644 --- a/langtools/src/share/classes/javax/lang/model/type/TypeVisitor.java +++ b/langtools/src/share/classes/javax/lang/model/type/TypeVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -182,4 +182,14 @@ public interface TypeVisitor { * @since 1.8 */ R visitIntersection(IntersectionType t, P p); + + /** + * Visits an annotated type. + * + * @param t the type to visit + * @param p a visitor-specified parameter + * @return a visitor-specified result + * @since 1.8 + */ + R visitAnnotated(AnnotatedType t, P p); } diff --git a/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java b/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java index c36fda3dec9..aa07280c91a 100644 --- a/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java +++ b/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -124,6 +124,23 @@ public abstract class AbstractTypeVisitor6 implements TypeVisitor { return visitUnknown(t, p); } + /** + * Visits an {@code AnnotatedType} element by calling {@code + * visit} on the underlying type. + + * @param t {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of calling {@code visit} on the underlying type + * + * @since 1.8 + * + * TODO: should xxxVisitor8 subclasses override this and call + * the defaultAction? + */ + public R visitAnnotated(AnnotatedType t, P p) { + return visit(t.getUnderlyingType(), p); + } + /** * {@inheritDoc} * diff --git a/langtools/src/share/classes/javax/lang/model/util/Types.java b/langtools/src/share/classes/javax/lang/model/util/Types.java index a53e66a53f2..7e41ddf70cd 100644 --- a/langtools/src/share/classes/javax/lang/model/util/Types.java +++ b/langtools/src/share/classes/javax/lang/model/util/Types.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -25,6 +25,9 @@ package javax.lang.model.util; +import java.lang.annotation.Annotation; +import java.lang.annotation.AnnotationTypeMismatchException; +import java.lang.annotation.IncompleteAnnotationException; import java.util.List; import javax.lang.model.element.*; import javax.lang.model.type.*; @@ -298,4 +301,116 @@ public interface Types { * for the given type */ TypeMirror asMemberOf(DeclaredType containing, Element element); + + /** + * Returns the annotations targeting the type. + * + * @param type the targeted type + * @return the type annotations targeting the type + */ + List typeAnnotationsOf(TypeMirror type); + + /** + * Returns the type's annotation for the specified type if + * such an annotation is present, else {@code null}. The + * annotation has to be directly present on this + * element. + * + *

The annotation returned by this method could contain an element + * whose value is of type {@code Class}. + * This value cannot be returned directly: information necessary to + * locate and load a class (such as the class loader to use) is + * not available, and the class might not be loadable at all. + * Attempting to read a {@code Class} object by invoking the relevant + * method on the returned annotation + * will result in a {@link MirroredTypeException}, + * from which the corresponding {@link TypeMirror} may be extracted. + * Similarly, attempting to read a {@code Class[]}-valued element + * will result in a {@link MirroredTypesException}. + * + *

+ * Note: This method is unlike others in this and related + * interfaces. It operates on runtime reflective information — + * representations of annotation types currently loaded into the + * VM — rather than on the representations defined by and used + * throughout these interfaces. Consequently, calling methods on + * the returned annotation object can throw many of the exceptions + * that can be thrown when calling methods on an annotation object + * returned by core reflection. This method is intended for + * callers that are written to operate on a known, fixed set of + * annotation types. + *
+ * + * @param
the annotation type + * @param type the targeted type + * @param annotationType the {@code Class} object corresponding to + * the annotation type + * @return the type's annotation for the specified annotation + * type if present on the type, else {@code null} + * + * @see Element#getAnnotationMirrors() + * @see EnumConstantNotPresentException + * @see AnnotationTypeMismatchException + * @see IncompleteAnnotationException + * @see MirroredTypeException + * @see MirroredTypesException + */ + A typeAnnotationOf(TypeMirror type, Class annotationType); + + /** + * Returns the annotations targeting the method receiver type. + * + * @param type the targeted type + * @return the receiver type of the executable type + */ + TypeMirror receiverTypeOf(ExecutableType type); + + /** + * Returns the type's annotation for the specified executable type + * receiver if such an annotation is present, else {@code null}. The + * annotation has to be directly present on this + * element. + * + *

The annotation returned by this method could contain an element + * whose value is of type {@code Class}. + * This value cannot be returned directly: information necessary to + * locate and load a class (such as the class loader to use) is + * not available, and the class might not be loadable at all. + * Attempting to read a {@code Class} object by invoking the relevant + * method on the returned annotation + * will result in a {@link MirroredTypeException}, + * from which the corresponding {@link TypeMirror} may be extracted. + * Similarly, attempting to read a {@code Class[]}-valued element + * will result in a {@link MirroredTypesException}. + * + *

+ * Note: This method is unlike others in this and related + * interfaces. It operates on runtime reflective information — + * representations of annotation types currently loaded into the + * VM — rather than on the representations defined by and used + * throughout these interfaces. Consequently, calling methods on + * the returned annotation object can throw many of the exceptions + * that can be thrown when calling methods on an annotation object + * returned by core reflection. This method is intended for + * callers that are written to operate on a known, fixed set of + * annotation types. + *
+ * + * @param
the annotation type + * @param type the method type + * @param annotationType the {@code Class} object corresponding to + * the annotation type + * @return the type's annotation for the specified annotation + * type if present on the type, else {@code null} + * + * @see Element#getAnnotationMirrors() + * @see EnumConstantNotPresentException + * @see AnnotationTypeMismatchException + * @see IncompleteAnnotationException + * @see MirroredTypeException + * @see MirroredTypesException + */ + // TODO: no longer needed? + // A receiverTypeAnnotationOf(ExecutableType type, Class annotationType); + } diff --git a/langtools/test/com/sun/javadoc/testAnnotationOptional/TestAnnotationOptional.java b/langtools/test/com/sun/javadoc/testAnnotationOptional/TestAnnotationOptional.java new file mode 100644 index 00000000000..ecd96852281 --- /dev/null +++ b/langtools/test/com/sun/javadoc/testAnnotationOptional/TestAnnotationOptional.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2009 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. + */ + +/* + * @test + * @summary Make sure that annotations types with optional elements has + * element headers + * @author Mahmood Ali + * @library ../lib/ + * @build JavadocTester + * @build TestAnnotationOptional + * @run main TestAnnotationOptional + */ + +public class TestAnnotationOptional extends JavadocTester { + + //Test information. + private static final String BUG_ID = "NO_BUG_ID_YET"; + + //Javadoc arguments. + private static final String[] ARGS = new String[] { + "-d", BUG_ID, "-sourcepath", SRC_DIR, "-source", "1.5", "pkg" + }; + + //Input for string search tests. + private static final String[][] TEST = { + {BUG_ID + FS + "pkg" + FS + "AnnotationOptional.html", + "" + } + }; + + private static final String[][] NEGATED_TEST = NO_TEST; + + /** + * The entry point of the test. + * @param args the array of command line arguments. + */ + public static void main(String[] args) { + TestAnnotationOptional tester = new TestAnnotationOptional(); + run(tester, ARGS, TEST, NEGATED_TEST); + tester.printSummary(); + } + + /** + * {@inheritDoc} + */ + public String getBugId() { + return BUG_ID; + } + + /** + * {@inheritDoc} + */ + public String getBugName() { + return getClass().getName(); + } +} diff --git a/langtools/test/com/sun/javadoc/testAnnotationOptional/pkg/AnnotationOptional.java b/langtools/test/com/sun/javadoc/testAnnotationOptional/pkg/AnnotationOptional.java new file mode 100644 index 00000000000..7004c1d4344 --- /dev/null +++ b/langtools/test/com/sun/javadoc/testAnnotationOptional/pkg/AnnotationOptional.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2009 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. + */ + +package pkg; + +import java.lang.annotation.*; + +/** + * This is just a test annotation type with optional value element. + * + * @author Mahmood Ali + * @since 1.5 + */ +@Documented public @interface AnnotationOptional { + String value() default ""; +} diff --git a/langtools/test/com/sun/javadoc/typeAnnotations/smoke/TestSmoke.java b/langtools/test/com/sun/javadoc/typeAnnotations/smoke/TestSmoke.java new file mode 100644 index 00000000000..dc8d10b1146 --- /dev/null +++ b/langtools/test/com/sun/javadoc/typeAnnotations/smoke/TestSmoke.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2010 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. + */ + +/* + * @test + * @bug 8006735 + * @ignore + * @summary Smoke test for ensuring that annotations are emited to javadoc + * + * @author Mahmood Ali + * @library ../../lib/ + * @build JavadocTester + * @build TestSmoke + * @run main TestSmoke + */ + +public class TestSmoke extends JavadocTester { + + //Test information. + private static final String BUG_ID = "NOT_SPECIFIED_YET"; + + //Javadoc arguments. + private static final String[] ARGS = new String[] { + "-d", BUG_ID, "-private", "-sourcepath", SRC_DIR, "pkg" + }; + + //Input for string search tests. + private static final String[][] TEST = { + {BUG_ID + FS + "pkg" + FS + "T0x1C.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x1D.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x0D.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x06.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x0B.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x0F.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x20.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x22.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x10.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x10A.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x12.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x11.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x13.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x15.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x14.html", "@DA"}, + {BUG_ID + FS + "pkg" + FS + "T0x16.html", "@DA"} + }; + + private static final String[][] NEGATED_TEST = { + {BUG_ID + FS + "pkg" + FS + "T0x1C.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x1D.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x00.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x01.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x02.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x04.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x08.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x0D.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x06.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x0B.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x0F.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x20.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x22.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x10.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x10A.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x12.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x11.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x13.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x15.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x14.html", "@A"}, + {BUG_ID + FS + "pkg" + FS + "T0x16.html", "@A"} + }; + + /** + * The entry point of the test. + * @param args the array of command line arguments. + */ + public static void main(String[] args) { + TestSmoke tester = new TestSmoke(); + run(tester, ARGS, TEST, NEGATED_TEST); + tester.printSummary(); + } + + /** + * {@inheritDoc} + */ + public String getBugId() { + return BUG_ID; + } + + /** + * {@inheritDoc} + */ + public String getBugName() { + return getClass().getName(); + } +} diff --git a/langtools/test/com/sun/javadoc/typeAnnotations/smoke/pkg/TargetTypes.java b/langtools/test/com/sun/javadoc/typeAnnotations/smoke/pkg/TargetTypes.java new file mode 100644 index 00000000000..24c93e3ba08 --- /dev/null +++ b/langtools/test/com/sun/javadoc/typeAnnotations/smoke/pkg/TargetTypes.java @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2010 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. + */ + +package pkg; + +import java.lang.annotation.*; +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.*; + +import java.util.*; +import java.io.*; + +/* + * @summary compiler accepts all values + * @author Mahmood Ali + * @author Yuri Gaevsky + */ + +@Target({TYPE_USE}) +@Retention(RetentionPolicy.RUNTIME) +@interface A {} + +@Target({TYPE_USE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@interface DA {} + +/** wildcard bound */ +class T0x1C { + void m0x1C(List lst) {} +} + +/** wildcard bound generic/array */ +class T0x1D { + void m0x1D(List> lst) {} +} + +/** typecast */ +class T0x00 { + void m0x00(Long l1) { + Object l2 = (@A @DA Long) l1; + } +} + +/** typecast generic/array */ +class T0x01 { + void m0x01(List list) { + List l = (List<@A @DA T>) list; + } +} + +/** instanceof */ +class T0x02 { + boolean m0x02(String s) { + return (s instanceof @A @DA String); + } +} + +/** object creation (new) */ +class T0x04 { + void m0x04() { + new @A @DA ArrayList(); + } +} + +/** local variable */ +class T0x08 { + void m0x08() { + @A @DA String s = null; + } +} + +/** method parameter generic/array */ +class T0x0D { + void m0x0D(HashMap<@A @DA Object, List<@A @DA List<@A @DA Class>>> s1) {} +} + +/** method receiver */ +class T0x06 { + void m0x06(@A @DA T0x06 this) {} +} + +/** method return type generic/array */ +class T0x0B { + Class<@A @DA Object> m0x0B() { return null; } +} + +/** field generic/array */ +class T0x0F { + HashMap<@A @DA Object, @A @DA Object> c1; +} + +/** method type parameter */ +class T0x20 { + <@A @DA T, @A @DA U> void m0x20() {} +} + +/** class type parameter */ +class T0x22<@A @DA T, @A @DA U> { +} + +/** class type parameter bound */ +class T0x10 { +} + +class T0x10A { +} + +/** method type parameter bound */ +class T0x12 { + void m0x12() {} +} + +/** class type parameter bound generic/array */ +class T0x11> { +} + +/** method type parameter bound generic/array */ +class T0x13 { + static > T m0x13() { + return null; + } +} + +/** class extends/implements generic/array */ +class T0x15 extends ArrayList<@A @DA T> { +} + +/** type test (instanceof) generic/array */ +class T0x03 { + void m0x03(T typeObj, Object obj) { + boolean ok = obj instanceof String @A @DA []; + } +} + +/** object creation (new) generic/array */ +class T0x05 { + void m0x05() { + new ArrayList<@A @DA T>(); + } +} + +/** local variable generic/array */ +class T0x09 { + void g() { + List<@A @DA String> l = null; + } + + void a() { + String @A @DA [] as = null; + } +} + +/** type argument in constructor call generic/array */ +class T0x19 { + T0x19() {} + + void g() { + new > T0x19(); + } +} + +/** type argument in method call generic/array */ +class T0x1B { + void m0x1B() { + Collections.emptyList(); + } +} + +/** type argument in constructor call */ +class T0x18 { + T0x18() {} + + void m() { + new <@A @DA Integer> T0x18(); + } +} + +/** type argument in method call */ +class T0x1A { + public static T m() { return null; } + static void m0x1A() { + T0x1A.<@A @DA Integer, @A @DA Short>m(); + } +} + +/** class extends/implements */ +class T0x14 extends @A @DA Thread implements @A @DA Serializable, @A @DA Cloneable { +} + +/** exception type in throws */ +class T0x16 { + void m0x16() throws @A @DA Exception {} +} diff --git a/langtools/test/tools/javac/7129225/TestImportStar.java b/langtools/test/tools/javac/7129225/TestImportStar.java index c22e5b9d4ec..eaca9ed23c3 100644 --- a/langtools/test/tools/javac/7129225/TestImportStar.java +++ b/langtools/test/tools/javac/7129225/TestImportStar.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -30,7 +30,7 @@ * @build JavacTestingAbstractProcessor * @compile/fail/ref=NegTest.ref -XDrawDiagnostics TestImportStar.java * @compile Anno.java AnnoProcessor.java - * @compile/ref=TestImportStar.ref -XDrawDiagnostics -processor AnnoProcessor -proc:only TestImportStar.java + * @compile/fail/ref=TestImportStar.ref -XDrawDiagnostics -processor AnnoProcessor -proc:only TestImportStar.java */ //The @compile/fail... verifies that the fix doesn't break the normal compilation of import xxx.* diff --git a/langtools/test/tools/javac/7129225/TestImportStar.ref b/langtools/test/tools/javac/7129225/TestImportStar.ref index 6248faddde8..5b3c75d7d89 100644 --- a/langtools/test/tools/javac/7129225/TestImportStar.ref +++ b/langtools/test/tools/javac/7129225/TestImportStar.ref @@ -1,3 +1,4 @@ - compiler.note.proc.messager: RUNNING - lastRound = false TestImportStar.java:39:1: compiler.err.doesnt.exist: xxx - compiler.note.proc.messager: RUNNING - lastRound = true +1 error \ No newline at end of file diff --git a/langtools/test/tools/javac/T6873845.java b/langtools/test/tools/javac/T6873845.java index ff84028326f..b1cfea6d203 100644 --- a/langtools/test/tools/javac/T6873845.java +++ b/langtools/test/tools/javac/T6873845.java @@ -19,8 +19,8 @@ public class T6873845 { if (out.contains("sunapi")) throw new Exception("unexpected output for -X"); - String warn1 = "T6873845.java:72:9: compiler.warn.sun.proprietary: sun.misc.Unsafe" + newline; - String warn2 = "T6873845.java:77:9: compiler.warn.sun.proprietary: sun.misc.Unsafe" + newline; + String warn1 = "T6873845.java:73:9: compiler.warn.sun.proprietary: sun.misc.Unsafe" + newline; + String warn2 = "T6873845.java:78:9: compiler.warn.sun.proprietary: sun.misc.Unsafe" + newline; String note1 = "- compiler.note.sunapi.filename: T6873845.java" + newline; String note2 = "- compiler.note.sunapi.recompile" + newline; @@ -52,7 +52,8 @@ public class T6873845 { args.add(0, "-XDrawDiagnostics"); String out = compile(args); if (!out.equals(expect)) - throw new Exception("unexpected output from compiler"); + throw new Exception("unexpected output from compiler; expected: " + expect + + "\n found: " + out); } String compile(List args) throws Exception{ diff --git a/langtools/test/tools/javac/T6985181.java b/langtools/test/tools/javac/T6985181.java new file mode 100644 index 00000000000..2211ff45fc2 --- /dev/null +++ b/langtools/test/tools/javac/T6985181.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/* + * @test + * @bug 6985181 + * @summary Annotations lost from classfile + */ + +import java.io.*; +import java.util.*; + +public class T6985181 { + public static void main(String... args) throws Exception{ + new T6985181().run(); + } + + public void run() throws Exception { + String code = "@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE_PARAMETER)\n" + + "@interface Simple { }\n" + + "interface Test<@Simple T> { }"; + + File srcFile = writeFile("Test.java", code); + File classesDir = new File("classes"); + classesDir.mkdirs(); + compile("-d", classesDir.getPath(), srcFile.getPath()); + String out = javap(new File(classesDir, srcFile.getName().replace(".java", ".class"))); + if (!out.contains("RuntimeInvisibleTypeAnnotations")) + throw new Exception("RuntimeInvisibleTypeAnnotations not found"); + } + + void compile(String... args) throws Exception { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + int rc = com.sun.tools.javac.Main.compile(args, pw); + pw.close(); + String out = sw.toString(); + if (out.length() > 0) + System.err.println(out); + if (rc != 0) + throw new Exception("Compilation failed: rc=" + rc); + } + + String javap(File classFile) throws Exception { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + String[] args = { "-v", classFile.getPath() }; + int rc = com.sun.tools.javap.Main.run(args, pw); + pw.close(); + String out = sw.toString(); + if (out.length() > 0) + System.err.println(out); + if (rc != 0) + throw new Exception("javap failed: rc=" + rc); + return out; + } + + File writeFile(String path, String body) throws IOException { + File f = new File(path); + FileWriter out = new FileWriter(f); + try { + out.write(body); + } finally { + out.close(); + } + return f; + } +} diff --git a/langtools/test/tools/javac/annotations/6881115/T6881115.java b/langtools/test/tools/javac/annotations/6881115/T6881115.java index 2f779c4ac46..0c917f15c64 100644 --- a/langtools/test/tools/javac/annotations/6881115/T6881115.java +++ b/langtools/test/tools/javac/annotations/6881115/T6881115.java @@ -1,3 +1,6 @@ +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + /* * @test /nodynamiccopyright/ * @bug 6881115 6976649 @@ -6,15 +9,18 @@ * @compile/fail/ref=T6881115.out -XDrawDiagnostics T6881115.java */ +@Target({ElementType.TYPE, ElementType.TYPE_PARAMETER, ElementType.ANNOTATION_TYPE}) @interface A { B b() default @B(b2 = 1, b2 = 2); B[] b_arr() default {@B(), @B(b2 = 1, b2 = 2)}; } + @interface B { String b1(); int b2(); } + @A(b = @B(b2 = 1, b2 = 2), b_arr = {@B(), @B(b2 = 1, b2 = 2)}) -class T6881115 {} +class T6881115<@A(b = @B(b2 = 1, b2 = 2), + b_arr = {@B(), @B(b2 = 1, b2 = 2)}) X> {} diff --git a/langtools/test/tools/javac/annotations/6881115/T6881115.out b/langtools/test/tools/javac/annotations/6881115/T6881115.out index 93b90cff473..a924a311590 100644 --- a/langtools/test/tools/javac/annotations/6881115/T6881115.out +++ b/langtools/test/tools/javac/annotations/6881115/T6881115.out @@ -1,11 +1,16 @@ -T6881115.java:10:30: compiler.err.duplicate.annotation.member.value: b2, B -T6881115.java:10:19: compiler.err.annotation.missing.default.value: B, b1 -T6881115.java:11:26: compiler.err.annotation.missing.default.value.1: B, b1,b2 -T6881115.java:11:43: compiler.err.duplicate.annotation.member.value: b2, B -T6881115.java:11:32: compiler.err.annotation.missing.default.value: B, b1 -T6881115.java:17:19: compiler.err.duplicate.annotation.member.value: b2, B -T6881115.java:17:8: compiler.err.annotation.missing.default.value: B, b1 -T6881115.java:18:13: compiler.err.annotation.missing.default.value.1: B, b1,b2 -T6881115.java:18:30: compiler.err.duplicate.annotation.member.value: b2, B -T6881115.java:18:19: compiler.err.annotation.missing.default.value: B, b1 -10 errors +T6881115.java:14:30: compiler.err.duplicate.annotation.member.value: b2, B +T6881115.java:14:19: compiler.err.annotation.missing.default.value: B, b1 +T6881115.java:15:26: compiler.err.annotation.missing.default.value.1: B, b1,b2 +T6881115.java:15:43: compiler.err.duplicate.annotation.member.value: b2, B +T6881115.java:15:32: compiler.err.annotation.missing.default.value: B, b1 +T6881115.java:23:19: compiler.err.duplicate.annotation.member.value: b2, B +T6881115.java:23:8: compiler.err.annotation.missing.default.value: B, b1 +T6881115.java:24:13: compiler.err.annotation.missing.default.value.1: B, b1,b2 +T6881115.java:24:30: compiler.err.duplicate.annotation.member.value: b2, B +T6881115.java:24:19: compiler.err.annotation.missing.default.value: B, b1 +T6881115.java:25:34: compiler.err.duplicate.annotation.member.value: b2, B +T6881115.java:25:23: compiler.err.annotation.missing.default.value: B, b1 +T6881115.java:26:28: compiler.err.annotation.missing.default.value.1: B, b1,b2 +T6881115.java:26:45: compiler.err.duplicate.annotation.member.value: b2, B +T6881115.java:26:34: compiler.err.annotation.missing.default.value: B, b1 +15 errors diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/6967002/T6967002.java b/langtools/test/tools/javac/annotations/typeAnnotations/6967002/T6967002.java new file mode 100644 index 00000000000..a0cbc78c690 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/6967002/T6967002.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/* + * @test + * @bug 6967002 8006775 + * @summary JDK7 b99 javac compilation error (java.lang.AssertionError) + * @author Maurizio Cimadamore + * @compile/fail/ref=T6967002.out -XDrawDiagnostics T6967002.java + */ +class Test { + private static void m(byte[] octets) { + return m(octets..., ?); + } +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/6967002/T6967002.out b/langtools/test/tools/javac/annotations/typeAnnotations/6967002/T6967002.out new file mode 100644 index 00000000000..18b75307f04 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/6967002/T6967002.out @@ -0,0 +1,8 @@ +T6967002.java:33:22: compiler.err.expected: ')' +T6967002.java:33:25: compiler.err.illegal.start.of.expr +T6967002.java:33:28: compiler.err.illegal.start.of.expr +T6967002.java:33:29: compiler.err.illegal.start.of.expr +T6967002.java:33:27: compiler.err.not.stmt +T6967002.java:33:30: compiler.err.expected: ';' +T6967002.java:35:2: compiler.err.premature.eof +7 errors diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/InnerClass.java b/langtools/test/tools/javac/annotations/typeAnnotations/InnerClass.java new file mode 100644 index 00000000000..53cab9fa589 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/InnerClass.java @@ -0,0 +1,65 @@ +import java.lang.annotation.ElementType; + +/* + * Copyright (c) 2009, 2013, 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. + */ + +/* + * @test + * @bug 6843077 8006775 + * @summary compiler crashes when visiting inner classes + * @author Mahmood Ali + * @compile InnerClass.java + */ + +import java.lang.annotation.*; + +class InnerClass { + + InnerClass() {} + InnerClass(Object o) {} + + private void a() { + new Object() { + public void method() { } + }; + } + + Object f1 = new InnerClass() { + void method() { } + }; + + Object f2 = new InnerClass() { + <@A R> void method() { } + }; + + Object f3 = new InnerClass(null) { + void method() { } + }; + + Object f4 = new InnerClass(null) { + <@A R> void method() { } + }; + + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface A { } +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/MultipleTargets.java b/langtools/test/tools/javac/annotations/typeAnnotations/MultipleTargets.java new file mode 100644 index 00000000000..041366cd701 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/MultipleTargets.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +/* + * @test + * @bug 6843077 8006775 + * @summary check that type annotations may appear on void method if it is a + * method annotation too. + * @author Mahmood Ali + * @compile MultipleTargets.java + */ + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +class TypeUseTarget { + @A void voidMethod() { } +} + +@Target({ElementType.TYPE_USE, ElementType.METHOD}) +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/TargetTypes.java b/langtools/test/tools/javac/annotations/typeAnnotations/TargetTypes.java new file mode 100644 index 00000000000..f808a8d4cda --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/TargetTypes.java @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2009 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. + */ +import java.lang.annotation.*; +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.*; + +import java.util.*; +import java.io.*; + +/* + * @test + * @summary compiler accepts all values + * @author Mahmood Ali + * @author Yuri Gaevsky + * @compile TargetTypes.java + */ + +@Target({TYPE_USE, TYPE_PARAMETER, TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@interface A {} + +/** wildcard bound */ +class T0x1C { + void m0x1C(List lst) {} +} + +/** wildcard bound generic/array */ +class T0x1D { + void m0x1D(List> lst) {} +} + +/** typecast */ +class T0x00 { + void m0x00(Long l1) { + Object l2 = (@A Long) l1; + } +} + +/** typecast generic/array */ +class T0x01 { + void m0x01(List list) { + List l = (List<@A T>) list; + } +} + +/** instanceof */ +class T0x02 { + boolean m0x02(String s) { + return (s instanceof @A String); + } +} + +/** object creation (new) */ +class T0x04 { + void m0x04() { + new @A ArrayList(); + } +} + +/** local variable */ +class T0x08 { + void m0x08() { + @A String s = null; + } +} + +/** method parameter generic/array */ +class T0x0D { + void m0x0D(HashMap<@A Object, List<@A List<@A Class>>> s1) {} +} + +/** method receiver */ +class T0x06 { + void m0x06(@A T0x06 this) {} +} + +/** method return type generic/array */ +class T0x0B { + Class<@A Object> m0x0B() { return null; } +} + +/** field generic/array */ +class T0x0F { + HashMap<@A Object, @A Object> c1; +} + +/** method type parameter */ +class T0x20 { + <@A T, @A U> void m0x20() {} +} + +/** class type parameter */ +class T0x22<@A T, @A U> { +} + +/** class type parameter bound */ +class T0x10 { +} + +/** method type parameter bound */ +class T0x12 { + void m0x12() {} +} + +/** class type parameter bound generic/array */ +class T0x11> { +} + + +/** method type parameter bound generic/array */ +class T0x13 { + static > T m0x13() { + return null; + } +} + +/** class extends/implements generic/array */ +class T0x15 extends ArrayList<@A T> { +} + +/** type test (instanceof) generic/array */ +class T0x03 { + void m0x03(T typeObj, Object obj) { + boolean ok = obj instanceof String @A []; + } +} + +/** object creation (new) generic/array */ +class T0x05 { + void m0x05() { + new ArrayList<@A T>(); + } +} + +/** local variable generic/array */ +class T0x09 { + void g() { + List<@A String> l = null; + } + + void a() { + String @A [] as = null; + } +} + +/** type argument in constructor call generic/array */ +class T0x19 { + T0x19() {} + + void g() { + new > T0x19(); + } +} + +/** type argument in method call generic/array */ +class T0x1B { + void m0x1B() { + Collections.emptyList(); + } +} + +/** type argument in constructor call */ +class T0x18 { + T0x18() {} + + void m() { + new <@A Integer> T0x18(); + } +} + +/** type argument in method call */ +class T0x1A { + public static T m() { return null; } + static void m0x1A() { + T0x1A.<@A Integer, @A Short>m(); + } +} + +/** class extends/implements */ +class T0x14 extends @A Object implements @A Serializable, @A Cloneable { +} + +/** exception type in throws */ +class T0x16 { + void m0x16() throws @A Exception {} +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/TypeParameterTarget.java b/langtools/test/tools/javac/annotations/typeAnnotations/TypeParameterTarget.java new file mode 100644 index 00000000000..100331c1090 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/TypeParameterTarget.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +/* + * @test + * @bug 6843077 8006775 + * @summary check that type annotations may appear on all type parameter + * @author Mahmood Ali + * @compile TypeParameterTarget.java + */ + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +class TypeUseTarget<@A K extends Object> { + String[] field; + + <@A K, @A V> String genericMethod(K k) { return null; } +} + +interface MyInterface { } + +@interface MyAnnotation { } + +@Target(ElementType.TYPE_PARAMETER) +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/TypeProcOnly.java b/langtools/test/tools/javac/annotations/typeAnnotations/TypeProcOnly.java new file mode 100644 index 00000000000..73d28971ee0 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/TypeProcOnly.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2009 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. + */ +import java.io.*; +import java.util.Set; +import java.util.HashSet; + +import javax.annotation.processing.*; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.*; +import javax.lang.model.util.ElementFilter; + +import com.sun.source.util.JavacTask; +import com.sun.source.util.TaskEvent; +import com.sun.source.util.TaskListener; +import com.sun.source.util.TreePath; +import com.sun.tools.javac.main.JavaCompiler; +import com.sun.tools.javac.main.JavaCompiler.CompileState; +import com.sun.tools.javac.processing.JavacProcessingEnvironment; +import com.sun.tools.javac.util.Context; + +/* + * @test + * @summary test that type processors are run when -proc:only is passed. + * This class implements the functionality of a type processor, as previously + * embodied by the AbstractTypeProcessor class. + * + * @author Mahmood Ali + * @author Werner Dietl + */ +@SupportedAnnotationTypes("*") +public class TypeProcOnly extends AbstractProcessor { + private static final String INDICATOR = "INDICATOR"; + + private final AttributionTaskListener listener = new AttributionTaskListener(); + private final Set elements = new HashSet(); + + @Override + public final void init(ProcessingEnvironment env) { + super.init(env); + JavacTask.instance(env).addTaskListener(listener); + Context ctx = ((JavacProcessingEnvironment)processingEnv).getContext(); + JavaCompiler compiler = JavaCompiler.instance(ctx); + compiler.shouldStopPolicyIfNoError = CompileState.max( + compiler.shouldStopPolicyIfNoError, + CompileState.FLOW); + } + + @Override + public final boolean process(Set annotations, + RoundEnvironment roundEnv) { + for (TypeElement elem : ElementFilter.typesIn(roundEnv.getRootElements())) { + elements.add(elem.getQualifiedName()); + } + return false; + } + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + private final class AttributionTaskListener implements TaskListener { + @Override + public void started(TaskEvent e) { } + + @Override + public void finished(TaskEvent e) { + if (e.getKind() != TaskEvent.Kind.ANALYZE) + return; + + if (!elements.remove(e.getTypeElement().getQualifiedName())) + return; + + System.out.println(INDICATOR); + } + } + + + private static File writeTestFile() throws IOException { + File f = new File("Test.java"); + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); + out.println("class Test { }"); + out.close(); + return f; + } + + public static void main(String[] args) throws Exception { + PrintStream prevOut = System.out; + + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + PrintStream out = new PrintStream(bytes); + System.setOut(out); + + try { + File f = writeTestFile(); + com.sun.tools.javac.Main.compile(new String[] {"-proc:only", "-processor", "TypeProcOnly", f.getAbsolutePath()}); + } finally { + System.setOut(prevOut); + } + + if (bytes.toString().trim().equals(INDICATOR)) { + System.out.println("PASSED"); + } else { + throw new Exception("Processor did not run correctly. Output: " + bytes); + } + } +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/TypeUseTarget.java b/langtools/test/tools/javac/annotations/typeAnnotations/TypeUseTarget.java new file mode 100644 index 00000000000..4ec21c0ef2a --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/TypeUseTarget.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +/* + * @test + * @bug 6843077 8006775 + * @summary check that type annotations may appear on all type declarations + * @author Mahmood Ali + * @compile TypeUseTarget.java + */ + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +@A +class TypeUseTarget { + @A String @A [] field; + + @A String test(@A TypeUseTarget this, @A String param, @A String @A ... vararg) { + @A Object o = new @A String @A [3]; + TypeUseTarget<@A String> target; + return (@A String) null; + } + + @A String genericMethod(K k) { return null; } + @Decl @A String genericMethod1(K k) { return null; } + @A @Decl String genericMethod2(K k) { return null; } + @Decl @A String genericMethod3(K k) { return null; } + @Decl String genericMethod4(K k) { return null; } + @A @Decl String genericMethod5(K k) { return null; } +} + +@A +interface MyInterface { } + +@A +@interface MyAnnotation { } + +@Target(ElementType.TYPE_USE) +@interface A { } + +@interface Decl { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/api/AnnotatedArrayOrder.java b/langtools/test/tools/javac/annotations/typeAnnotations/api/AnnotatedArrayOrder.java new file mode 100644 index 00000000000..947b46536cc --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/api/AnnotatedArrayOrder.java @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2010 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. + */ + +/* + * @test + * @summary Checks the annotation types targeting array types + */ + +import com.sun.tools.javac.api.JavacTool; +import java.io.File; +import java.io.PrintWriter; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.lang.annotation.*; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import com.sun.source.tree.*; +import com.sun.source.util.JavacTask; +import com.sun.source.util.TreeScanner; +import javax.tools.StandardJavaFileManager; + + +public class AnnotatedArrayOrder { + public static void main(String[] args) throws Exception { + PrintWriter out = new PrintWriter(System.out, true); + JavacTool tool = JavacTool.create(); + StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + File testSrc = new File(System.getProperty("test.src")); + Iterable f = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "AnnotatedArrayOrder.java"))); + JavacTask task = tool.getTask(out, fm, null, null, null, f); + Iterable trees = task.parse(); + out.flush(); + + Scanner s = new Scanner(); + for (CompilationUnitTree t: trees) + s.scan(t, null); + + } + + private static class Scanner extends TreeScanner { + public Void visitCompilationUnit(CompilationUnitTree node, Void ignore) { + super.visitCompilationUnit(node, ignore); + if (!expectedLocations.isEmpty()) { + throw new AssertionError("Didn't found all annotations: " + expectedLocations); + } + return null; + } + + private void testAnnotations(List annos, int found) { + String annotation = annos.get(0).toString(); + + if (!expectedLocations.containsKey(annotation)) + throw new AssertionError("Found unexpected annotation: " + annotation + expectedLocations); + + int expected = expectedLocations.get(annotation); + if (found != expected) + throw new AssertionError("The expected array length for this error doesn't match"); + + expectedLocations.remove(annotation); + } + + public Void visitAnnotatedType(AnnotatedTypeTree node, Void ignore) { + testAnnotations(node.getAnnotations(), arrayLength(node)); + return super.visitAnnotatedType(node, ignore); + } + + private int arrayLength(Tree tree) { + switch (tree.getKind()) { + case ARRAY_TYPE: + return 1 + arrayLength(((ArrayTypeTree)tree).getType()); + case ANNOTATED_TYPE: + return arrayLength(((AnnotatedTypeTree)tree).getUnderlyingType()); + default: + return 0; + } + } + } + + // expectedLocations values: + static Map expectedLocations = new HashMap(); + + // visited code + @A String @C [] @B [] field; + static { + // Shouldn't find @A(), as it is field annotation + expectedLocations.put("@B()", 1); + expectedLocations.put("@C()", 2); + } + + List<@D String @F [] @E []> typearg; + static { + expectedLocations.put("@D()", 0); + expectedLocations.put("@E()", 1); + expectedLocations.put("@F()", 2); + } + + void varargSimple(@G String @H ... vararg1) { } + static { + // Shouldn't find @G(), as it is a parameter annotation + expectedLocations.put("@H()", 1); + } + + void varargLong(@I String @L [] @K [] @J ... vararg2) { } + static { + // Shouldn't find @I(), as it is a parameter annotation + expectedLocations.put("@J()", 1); + expectedLocations.put("@K()", 2); + expectedLocations.put("@L()", 3); + } + + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface A {} + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface B {} + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface C {} + + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface D {} + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface E {} + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface F {} + + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface G {} + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface H {} + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface I {} + + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface J {} + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface K {} + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface L {} +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/api/ArrayCreationTree.java b/langtools/test/tools/javac/annotations/typeAnnotations/api/ArrayCreationTree.java new file mode 100644 index 00000000000..55f81eb7cf6 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/api/ArrayCreationTree.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2010 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. + */ + +/* + * @test + * @summary Checks that the interaction between annotated and unannotated + * array levels in array creation trees + */ + +import com.sun.tools.javac.api.JavacTool; +import com.sun.tools.javac.tree.JCTree.JCNewArray; +import java.lang.annotation.*; +import java.io.File; +import java.io.PrintWriter; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import com.sun.source.tree.*; +import com.sun.source.util.JavacTask; +import com.sun.source.util.TreeScanner; +import javax.tools.StandardJavaFileManager; + + +public class ArrayCreationTree { + public static void main(String[] args) throws Exception { + PrintWriter out = new PrintWriter(System.out, true); + JavacTool tool = JavacTool.create(); + StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + File testSrc = new File(System.getProperty("test.src")); + Iterable f = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "ArrayCreationTree.java"))); + JavacTask task = tool.getTask(out, fm, null, null, null, f); + Iterable trees = task.parse(); + out.flush(); + + Scanner s = new Scanner(); + for (CompilationUnitTree t: trees) + s.scan(t, null); + + } + + private static class Scanner extends TreeScanner { + int foundAnnotations = 0; + public Void visitCompilationUnit(CompilationUnitTree node, Void ignore) { + super.visitCompilationUnit(node, ignore); + if (foundAnnotations != expectedAnnotations) { + throw new AssertionError("Expected " + expectedAnnotations + + " annotations but found: " + foundAnnotations); + } + return null; + } + + private void testAnnotations(List annos, int found) { + if (annos.isEmpty()) return; + + String annotation = annos.get(0).toString(); + foundAnnotations++; + + int expected = -1; + if (annotation.equals("@A()")) + expected = 0; + else if (annotation.equals("@B()")) + expected = 1; + else if (annotation.equals("@C()")) + expected = 2; + else + throw new AssertionError("found an unexpected annotation: " + annotation); + if (found != expected) { + throw new AssertionError("Unexpected found length" + + ", found " + found + " but expected " + expected); + } + } + + public Void visitAnnotatedType(AnnotatedTypeTree node, Void ignore) { + testAnnotations(node.getAnnotations(), arrayLength(node)); + return super.visitAnnotatedType(node, ignore); + } + + public Void visitNewArray(NewArrayTree node, Void ignore) { + // the Tree API hasn't been updated to expose annotations yet + JCNewArray newArray = (JCNewArray)node; + int totalLength = node.getDimensions().size() + + arrayLength(node.getType()) + + ((newArray.getInitializers() != null) ? 1 : 0); + testAnnotations(newArray.annotations, totalLength); + int count = 0; + for (List annos : newArray.dimAnnotations) { + testAnnotations(annos, totalLength - count); + count++; + } + return super.visitNewArray(node, ignore); + } + + private int arrayLength(Tree tree) { + // TODO: the tree is null when called with node.getType(). Why? + if (tree==null) return -1; + switch (tree.getKind()) { + case ARRAY_TYPE: + return 1 + arrayLength(((ArrayTypeTree)tree).getType()); + case ANNOTATED_TYPE: + return arrayLength(((AnnotatedTypeTree)tree).getUnderlyingType()); + default: + return 0; + } + } + } + + static int expectedAnnotations = 21; + + Object a1 = new @A Object @C [2] @B [1]; + Object b1 = new @A Object @C [2] @B [ ]; + Object c1 = new @A Object @C [ ] @B [ ] { }; + + Object a2 = new @A Object @C [2] [1]; + Object b2 = new @A Object @C [2] [ ]; + Object c2 = new @A Object @C [ ] [ ] { }; + + Object a3 = new @A Object [2] @B [1]; + Object b3 = new @A Object [2] @B [ ]; + Object c3 = new @A Object [ ] @B [ ] { }; + + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface A {} + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface B {} + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface C {} + +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/api/ArrayPositionConsistency.java b/langtools/test/tools/javac/annotations/typeAnnotations/api/ArrayPositionConsistency.java new file mode 100644 index 00000000000..7d00ef3aa19 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/api/ArrayPositionConsistency.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2010 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. + */ + +/* + * @test + * @summary Checks that the interaction between annotated and unannotated + * array levels + */ + +import com.sun.tools.javac.api.JavacTool; +import java.lang.annotation.*; +import java.io.File; +import java.io.PrintWriter; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import com.sun.source.tree.*; +import com.sun.source.util.JavacTask; +import com.sun.source.util.TreeScanner; +import javax.tools.StandardJavaFileManager; + + +public class ArrayPositionConsistency { + public static void main(String[] args) throws Exception { + PrintWriter out = new PrintWriter(System.out, true); + JavacTool tool = JavacTool.create(); + StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + File testSrc = new File(System.getProperty("test.src")); + Iterable f = + fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "ArrayPositionConsistency.java"))); + JavacTask task = tool.getTask(out, fm, null, null, null, f); + Iterable trees = task.parse(); + out.flush(); + + Scanner s = new Scanner(); + for (CompilationUnitTree t: trees) + s.scan(t, null); + + } + + private static class Scanner extends TreeScanner { + int foundAnnotations = 0; + public Void visitCompilationUnit(CompilationUnitTree node, Void ignore) { + super.visitCompilationUnit(node, ignore); + if (foundAnnotations != expectedAnnotations) { + throw new AssertionError("Expected " + expectedAnnotations + + " annotations but found: " + foundAnnotations); + } + return null; + } + + private void testAnnotations(List annos, int found) { + String annotation = annos.get(0).toString(); + foundAnnotations++; + + int expected = -1; + if (annotation.equals("@A()")) + expected = 0; + else if (annotation.equals("@B()")) + expected = 1; + else if (annotation.equals("@C()")) + expected = 2; + else + throw new AssertionError("found an unexpected annotation: " + annotation); + if (found != expected) { + throw new AssertionError("Unexpected found length" + + ", found " + found + " but expected " + expected); + } + } + + public Void visitAnnotatedType(AnnotatedTypeTree node, Void ignore) { + testAnnotations(node.getAnnotations(), arrayLength(node)); + return super.visitAnnotatedType(node, ignore); + } + + private int arrayLength(Tree tree) { + switch (tree.getKind()) { + case ARRAY_TYPE: + return 1 + arrayLength(((ArrayTypeTree)tree).getType()); + case ANNOTATED_TYPE: + return arrayLength(((AnnotatedTypeTree)tree).getUnderlyingType()); + default: + return 0; + } + } + } + + static int expectedAnnotations = 23; + + // visited code + @A String @C [] @B [] field1; + @A String @C [] [] field2; + @A String [] @B [] field3; + String [] @B [] field4; + + @A List @C [] @B [] genfield1; + @A List @C [] [] genfield2; + @A List [] @B [] genfield3; + List [] @B [] genfield4; + + List<@A String @C [] @B []> typearg1; + List<@A String @C [] []> typearg2; + List<@A String [] @B []> typearg3; + List< String [] @B []> typearg4; + + void vararg1(@A String @C [] @B ... arg) {} + void vararg2(@A String @C [] ... arg) {} + void vararg3(@A String [] @B ... arg) {} + void vararg4( String [] @B ... arg) {} + + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface A {} + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface B {} + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface C {} + +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/attribution/Scopes.java b/langtools/test/tools/javac/annotations/typeAnnotations/attribution/Scopes.java new file mode 100644 index 00000000000..da01c38d096 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/attribution/Scopes.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +/* + * @test + * @bug 6843077 8006775 + * @summary test scopes of attribution + * @author Mahmood Ali + * @compile Scopes.java + */ +class Scopes { + + void test(@A(VALUE) Scopes this) { } + void test1(@A(value=VALUE) Scopes this) { } + + private static final int VALUE = 1; + @interface A { int value(); } +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/ClassfileTestHelper.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/ClassfileTestHelper.java new file mode 100644 index 00000000000..a06407e0144 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/ClassfileTestHelper.java @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2012, 2013 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. + */ + +import java.lang.annotation.*; +import java.io.*; +import java.net.URL; +import java.util.List; + +import com.sun.tools.classfile.*; + +public class ClassfileTestHelper { + int expected_tinvisibles = 0; + int expected_tvisibles = 0; + int expected_invisibles = 0; + int expected_visibles = 0; + + //Makes debugging much easier. Set to 'false' for less output. + public Boolean verbose = true; + void println(String msg) { if(verbose) System.out.println(msg); } + + File writeTestFile(String fname, String source) throws IOException { + File f = new File(fname); + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); + out.println(source); + out.close(); + return f; + } + + File compile(File f) { + int rc = com.sun.tools.javac.Main.compile(new String[] { + "-source", "1.8", "-g", f.getPath() }); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + String path = f.getPath(); + return new File(path.substring(0, path.length() - 5) + ".class"); + } + + ClassFile getClassFile(String name) throws IOException, ConstantPoolException { + URL url = getClass().getResource(name); + InputStream in = url.openStream(); + try { + return ClassFile.read(in); + } finally { + in.close(); + } + } + + ClassFile getClassFile(URL url) throws IOException, ConstantPoolException { + InputStream in = url.openStream(); + try { + return ClassFile.read(in); + } finally { + in.close(); + } + } + + /************ Helper annotations counting methods ******************/ + void test(ClassFile cf) { + test("CLASS",cf, null, null, Attribute.RuntimeVisibleTypeAnnotations, true); + test("CLASS",cf, null, null, Attribute.RuntimeInvisibleTypeAnnotations, false); + //RuntimeAnnotations since one annotation can result in two attributes. + test("CLASS",cf, null, null, Attribute.RuntimeVisibleAnnotations, true); + test("CLASS",cf, null, null, Attribute.RuntimeInvisibleAnnotations, false); + } + + void test(ClassFile cf, Method m) { + test("METHOD",cf, null, m, Attribute.RuntimeVisibleTypeAnnotations, true); + test("METHOD",cf, null, m, Attribute.RuntimeInvisibleTypeAnnotations, false); + test("METHOD",cf, null, m, Attribute.RuntimeVisibleAnnotations, true); + test("METHOD",cf, null, m, Attribute.RuntimeInvisibleAnnotations, false); + } + + void test(ClassFile cf, Field f) { + test("FIELD",cf, f, null, Attribute.RuntimeVisibleTypeAnnotations, true); + test("FIELD",cf, f, null, Attribute.RuntimeInvisibleTypeAnnotations, false); + test("FIELD",cf, f, null, Attribute.RuntimeVisibleAnnotations, true); + test("FIELD",cf, f, null, Attribute.RuntimeInvisibleAnnotations, false); + } + + + // Test the result of Attributes.getIndex according to expectations + // encoded in the class/field/method name; increment annotations counts. + void test(String ttype, ClassFile cf, Field f, Method m, String annName, boolean visible) { + String testtype = ttype; + String name = null; + int index = -1; + Attribute attr = null; + boolean isTAattr = annName.contains("TypeAnnotations"); + try { + switch(testtype) { + case "FIELD": + name = f.getName(cf.constant_pool); + index = f.attributes.getIndex(cf.constant_pool, annName); + if(index!= -1) attr = f.attributes.get(index); + break; + case "METHOD": + name = m.getName(cf.constant_pool); + index = m.attributes.getIndex(cf.constant_pool, annName); + if(index!= -1) attr = m.attributes.get(index); + break; + default: + name = cf.getName(); + index = cf.attributes.getIndex(cf.constant_pool, annName); + if(index!= -1) attr = cf.attributes.get(index); + } + } catch(ConstantPoolException cpe) { cpe.printStackTrace(); } + + if (index != -1) { + assert attr instanceof RuntimeTypeAnnotations_attribute; + if(isTAattr) { //count RuntimeTypeAnnotations + RuntimeTypeAnnotations_attribute tAttr = + (RuntimeTypeAnnotations_attribute)attr; + println(testtype + ": " + name + ", " + annName + ": " + + tAttr.annotations.length ); + allt += tAttr.annotations.length; + if (visible) + tvisibles += tAttr.annotations.length; + else + tinvisibles += tAttr.annotations.length; + } else { + RuntimeAnnotations_attribute tAttr = + (RuntimeAnnotations_attribute)attr; + println(testtype + ": " + name + ", " + annName + ": " + + tAttr.annotations.length ); + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + } + } + } + + void countAnnotations() { + errors=0; + int expected_allt = expected_tvisibles + expected_tinvisibles; + int expected_all = expected_visibles + expected_invisibles; + + if (expected_allt != allt) { + errors++; + System.err.println("Failure: expected " + expected_allt + + " type annotations but found " + allt); + } + if (expected_all != all) { + errors++; + System.err.println("Failure: expected " + expected_all + + " annotations but found " + all); + } + if (expected_tvisibles != tvisibles) { + errors++; + System.err.println("Failure: expected " + expected_tvisibles + + " typevisible annotations but found " + tvisibles); + } + + if (expected_tinvisibles != tinvisibles) { + errors++; + System.err.println("Failure: expected " + expected_tinvisibles + + " typeinvisible annotations but found " + tinvisibles); + } + allt=0; + tvisibles=0; + tinvisibles=0; + all=0; + visibles=0; + invisibles=0; + } + + int errors; + int allt; + int tvisibles; + int tinvisibles; + int all; + int visibles; + int invisibles; +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest1.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest1.java new file mode 100644 index 00000000000..0041dd35f61 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest1.java @@ -0,0 +1,369 @@ +/* + * Copyright (c) 2013 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. + */ + +/* + * @test + * @bug 8005085 8005877 8004829 8005681 8006734 8006775 + * @ignore + * @summary Combinations of Target ElementTypes on (repeated)type annotations. + */ + +import com.sun.tools.classfile.*; +import java.io.File; + +public class CombinationsTargetTest1 extends ClassfileTestHelper { + // Helps identify test case in event of failure. + int testcount = 0; + int src1 = 1, src2 = 2, src4 = 4, + src5 = 5, src6 = 6, src7 = 7; + + String[] ETypes={"TYPE", "FIELD", "METHOD", "PARAMETER", "CONSTRUCTOR", + "LOCAL_VARIABLE", "ANNOTATION_TYPE", "PACKAGE"}; + + // local class tests will have an inner class. + Boolean hasInnerClass=false; + String innerClassname=""; + + public static void main(String[] args) throws Exception { + new CombinationsTargetTest1().run(); + } + + void run() throws Exception { + // Determines which repeat and order in source(ABMix). + Boolean As= false, BDs=true, ABMix=false; + int testrun=0; + // A repeats and/or B/D repeats, ABMix for order of As and Bs. + Boolean [][] bRepeat = new Boolean[][]{{false,false,false},//no repeats + {true,false,false}, //repeat @A + {false,true,false}, //repeat @B + {true,true,false}, //repeat both + {false,false,true} //repeat mix + }; + for(Boolean[] bCombo : bRepeat) { + As=bCombo[0]; BDs=bCombo[1]; ABMix=bCombo[2]; + for(String et : ETypes) { + switch(et) { + case "METHOD": + test( 8, 0, 2, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src1); + test(10, 0, 2, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src2); + test( 8, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src4); + test(10, 0, 2, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src6); + test( 0, 8, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, src1); + test( 0, 10, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, src2); + test( 0, 8, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, src4); + test( 0, 10, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, src6); + break; + case "CONSTRUCTOR": + case "FIELD": + test( 8, 0, 4, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src1); + test( 6, 0, 3, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src5); + test( 9, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src7); + test( 0, 8, 0, 4, As, BDs, ABMix, "RUNTIME", et, ++testrun, src1); + test( 0, 6, 0, 3, As, BDs, ABMix, "RUNTIME", et, ++testrun, src5); + test( 0, 9, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, src7); + break; + default:/*TYPE,PARAMETER,LOCAL_VARIABLE,ANNOTATION_TYPE,PACKAGE*/ + test( 8, 0, 2, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src1); + test( 6, 0, 3, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src5); + test( 0, 8, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, src1); + test( 0, 6, 0, 3, As, BDs, ABMix, "RUNTIME", et, ++testrun, src5); + } + } + } + } + + public void test(int tinv, int tvis, int inv, int vis, Boolean Arepeats, + Boolean BDrepeats, Boolean ABmix, String rtn, String et2, + Integer N, int source) throws Exception { + ++testcount; + expected_tvisibles = tvis; + expected_tinvisibles = tinv; + expected_visibles = vis; + expected_invisibles = inv; + File testFile = null; + String tname="Test" + N.toString(); + hasInnerClass=false; + String testDef = "Test " + testcount + " parameters: tinv=" + tinv + + ", tvis=" + tvis + ", inv=" + inv + ", vis=" + vis + + ", Arepeats=" + Arepeats + ", BDrepeats=" + BDrepeats + + ", ABmix=" + ABmix + ", retention: " + rtn + ", anno2: " + + et2 + ", src=" + source; + + println(testDef); + // Create test source and File. + String sourceString = sourceString(tname, rtn, et2, Arepeats, + BDrepeats, ABmix, source); + testFile = writeTestFile(tname+".java", sourceString); + // Compile test source and read classfile. + File classFile = null; + try { + classFile = compile(testFile); + } catch (Error err) { + System.err.println("Failed compile. Source:\n" + sourceString); + throw err; + } + //if sourcString() set hasInnerClass it also set innerClassname. + if(hasInnerClass) { + StringBuffer sb = new StringBuffer(classFile.getAbsolutePath()); + classFile=new File(sb.insert(sb.lastIndexOf(".class"),innerClassname).toString()); + } + ClassFile cf = ClassFile.read(classFile); + + //Test class,fields and method counts. + test(cf); + + for (Field f : cf.fields) { + test(cf, f); + } + for (Method m: cf.methods) { + test(cf, m); + } + countAnnotations(); + if (errors > 0) { + System.err.println( testDef ); + System.err.println( "Source:\n" + sourceString ); + throw new Exception( errors + " errors found" ); + } + println("Pass"); + } + + // + // Source for test cases + // + String sourceString(String testname, String retentn, String annot2, + Boolean Arepeats, Boolean BDrepeats, Boolean ABmix, + int src) { + + String As = "@A", Bs = "@B", Ds = "@D"; + if(Arepeats) As = "@A @A"; + if(BDrepeats) { + Bs = "@B @B"; + Ds = "@D @D"; + } + if(ABmix) { As = "@A @B"; Bs = "@A @B"; Ds = "@D @D"; } + + // Source to check for TYPE_USE and TYPE_PARAMETER annotations. + // Source base (annotations) is same for all test cases. + String source = new String(); + String imports = new String("import java.lang.annotation.*; \n" + + "import static java.lang.annotation.RetentionPolicy.*; \n" + + "import static java.lang.annotation.ElementType.*; \n" + + "import java.util.List; \n" + + "import java.util.HashMap; \n" + + "import java.util.Map; \n\n"); + + String sourceBase = new String("@Retention("+retentn+")\n" + + "@Target({TYPE_USE,_OTHER_})\n" + + "@ContainedBy( AC.class )\n" + + "@interface A { }\n\n" + + + "@Retention("+retentn+")\n" + + "@Target({TYPE_USE,_OTHER_})\n" + + "@ContainerFor(A.class)\n" + + "@interface AC { A[] value(); }\n\n" + + + "@Retention("+retentn+")\n" + + "@Target({TYPE_USE,_OTHER_})\n" + + "@ContainedBy( BC.class )\n" + + "@interface B { }\n\n" + + + "@Retention("+retentn+")\n" + + "@Target({TYPE_USE,_OTHER_})\n" + + "@ContainerFor(B.class)\n" + + "@interface BC { B[] value(); } \n\n" + + + "@Retention("+retentn+")\n" + + "@Target({TYPE_PARAMETER,_OTHER_})\n" + + "@interface C { }\n\n" + + + "@Retention("+retentn+")\n" + + "@Target({TYPE_USE,TYPE_PARAMETER,_OTHER_})\n" + + "@ContainedBy(DC.class)\n" + + "@interface D { }\n\n" + + + "@Retention("+retentn+")\n" + + "@Target({TYPE_USE,TYPE_PARAMETER,_OTHER_})\n" + + "@ContainerFor(D.class) \n" + + "@interface DC { D[] value(); }\n\n"); + + // Test case sources with sample generated source. + switch(src) { + case 1: // repeating type annotations at class level + /* + * @A @B class Test1 { + * @A @B Test1(){} + * @A @B Integer i1 = 0; + * String @A @B [] @A @B [] sa = null; + * // type usage in method body + * String test(Test1 this, String param, String ... vararg) { + * Object o = new String [3]; + * return (String) null; + * }} + */ + source = new String( + "// (repeating) type annotations at class level. \n" + + "_As_ _Bs_ class " + testname + " {\n" + + "_As_ _Bs_ " + testname +"(){} \n" + + "_As_ _Bs_ Integer i1 = 0; \n" + + "String _As_ _Bs_ [] _As_ _Bs_ [] sa = null; \n" + + "// type usage in method body \n" + + "String test("+testname+" this, " + + "String param, String ... vararg) { \n" + + " Object o = new String [3]; \n" + + " return (String) null; \n" + + "} \n" + + "} \n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) + + "\n\n"; + break; + case 2: // (repeating) type annotations on method. + /* + * class Test12 { + * Test12(){} + * // type usage on method + * @A @B String test(@A @B Test12 this, @A @B String param, @A @B String @A @B ... vararg) { + * Object o = new String [3]; + * return (String) null; + * }} + */ + source = new String( + "// (repeating) type annotations on method. \n" + + "class " + testname + " {\n" + + testname +"(){} \n" + + "// type usage on method \n" + + "_As_ _Bs_ String test(_As_ _Bs_ "+testname+" this, " + + "_As_ _Bs_ String param, _As_ _Bs_ String _As_ _Bs_ ... vararg) { \n" + + " Object o = new String [3]; \n" + + " return (String) null; \n" + + "} \n" + + "} \n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) + + "\n\n"; + break; + case 4: //(repeating) annotations on wildcard, type arguments in anonymous class. + /* + * class Test13 { + * public T data = null; + * T getData() { return data;} + * String mtest( Test13 t){ return t.getData(); } + * public void test() { + * mtest( new Test13<@A @B String>() { + * void m1(List<@A @B ? extends @A @B Object> lst) {} + * void m2() throws@A @B Exception { } + * }); + * } + * } + */ + source = new String( source + + "// (repeating) annotations on wildcard, type arguments in anonymous class. \n" + + "class " + testname + " {\n" + + " public T data = null;\n" + + " T getData() { return data;}\n" + + " String mtest( " + testname + " t){ return t.getData(); }\n" + + " public void test() {\n" + + " mtest( new " + testname + "<_As_ _Bs_ String>() {\n" + + " void m1(List<_As_ _Bs_ ? extends _As_ _Bs_ Object> lst) {}\n" + + " void m2() throws_As_ _Bs_ Exception { }\n" + + " });\n" + + " }\n" + + "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) + "\n\n"; + hasInnerClass=true; + innerClassname="$1"; + break; + case 5: // (repeating)annotations on type parameters, bounds and type arguments on class decl. + /* + * @A @B @D + * class Test2<@A @B @C @D T extends @A @B Object> { + * Map, Integer> map = + * new HashMap, Integer>(); + * Map,Integer> map2 = new HashMap<>(); + * String test(Test2 this) { return null;} + * String genericMethod(T t) { return null; } + * } + */ + source = new String( source + + "// (repeating)annotations on type parameters, bounds and type arguments on class decl. \n" + + "_As_ _Bs_ _Ds_\n" + //8004829: A and B on type parameter below. + "class " + testname + "<_As_ _Bs_ @C _Ds_ T extends _As_ _Bs_ Object> {\n" + + " Map, Integer> map =\n" + + " new HashMap, Integer>();\n" + + " Map,Integer> map2 = new HashMap<>();\n" + + " String test(" + testname + " this) { return null;}\n" + + " String genericMethod(T t) { return null; }\n" + + "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) + + "\n\n"; + break; + case 6: // (repeating) annotations on type parameters, bounds and type arguments on method. + /* + * class Test14 { + * Map, Integer> map = + * new HashMap, Integer>(); + * Map, Integer> map2 = new HashMap<>(); + * String test(@A @B Test14<@D T> this) { return null;} + * <@C @D T> @A @B String genericMethod(@A @B @D T t) { return null; } + * } + */ + source = new String( source + + "// (repeating) annotations on type parameters, bounds and type arguments on method. \n" + + "class " + testname + " {\n" + + " Map, Integer> map =\n" + + " new HashMap, Integer>();\n" + + " Map, Integer> map2 = new HashMap<>();\n" + + " String test(_As_ _Bs_ " + testname + "<_Ds_ T> this) { return null;}\n" + + " <@C _Ds_ T> _As_ _Bs_ String genericMethod(_As_ _Bs_ _Ds_ T t) { return null; }\n" + + "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) + + "\n\n"; + break; + case 7: // repeating annotations on type parameters, bounds and type arguments in method. + /* + * class Test7{ + * Map, E > foo(E e) { + * class maptest <@A @B @D E> { + * Map,@A @B @D E> getMap() { + * return new HashMap,E>(); + * } + * } + * return new maptest().getMap(); + * } + * Map,String> shm = foo(new String("hello")); + * } + */ + source = new String( source + + "// (repeating)annotations on type parameters of class, method return value in method. \n" + + "class "+ testname + "{\n" + + " Map, E > foo(E e) {\n" + + " class maptest <_As_ _Bs_ _Ds_ E> {\n" + // inner class $1maptest + " Map,_As_ _Bs_ _Ds_ E> getMap() { \n" + + " return new HashMap,E>();\n" + + " }\n" + + " }\n" + + " return new maptest().getMap();\n" + + " }\n" + + " Map,String> shm = foo(new String(\"hello\"));\n" + + "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) + + "\n\n"; + hasInnerClass=true; + innerClassname="$1maptest"; + break; + } + return imports + source; + } +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java new file mode 100644 index 00000000000..a0308a38975 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2013 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. + */ + +/* + * @test + * @bug 8005085 8005877 8004829 8005681 8006734 8006775 + * @ignore + * @summary Combinations of Target ElementTypes on (repeated)type annotations. + */ + +import com.sun.tools.classfile.*; +import java.io.File; + +public class CombinationsTargetTest2 extends ClassfileTestHelper { + // Helps identify test case in event of failure. + int testcount = 0; + int src3 = 3, src8 = 8, src9 = 9; + + String[] ETypes={"TYPE", "FIELD", "METHOD", "PARAMETER", "CONSTRUCTOR", + "LOCAL_VARIABLE", "ANNOTATION_TYPE", "PACKAGE"}; + + // local class tests will have an inner class. + Boolean hasInnerClass=false; + String innerClassname=""; + + public static void main(String[] args) throws Exception { + new CombinationsTargetTest2().run(); + } + + void run() throws Exception { + // Determines which repeat and order in source(ABMix). + Boolean As= false, BDs=true, ABMix=false; + int testrun=0; + // A repeats and/or B/D repeats, ABMix for order of As and Bs. + Boolean [][] bRepeat = new Boolean[][]{{false,false,false},//no repeats + {true,false,false}, //repeat @A + {false,true,false}, //repeat @B + {true,true,false}, //repeat both + {false,false,true} //repeat mix + }; + for(Boolean[] bCombo : bRepeat) { + As=bCombo[0]; BDs=bCombo[1]; ABMix=bCombo[2]; + for(String et : ETypes) { + switch(et) { + case "METHOD": + test( 8, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src3); + test( 0, 8, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, src3); + break; + case "CONSTRUCTOR": + case "FIELD": + test( 8, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src3); + test( 8, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src8); + test( 6, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, src9); + test( 0, 8, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, src3); + test( 0, 8, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, src8); + test( 0, 6, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, src9); + break; + default:/*TYPE,PARAMETER,LOCAL_VARIABLE,ANNOTATION_TYPE,PACKAGE*/ + break; + } + } + } + } + + public void test(int tinv, int tvis, int inv, int vis, Boolean Arepeats, + Boolean BDrepeats, Boolean ABmix, String rtn, String et2, + Integer N, int source) throws Exception { + ++testcount; + expected_tvisibles = tvis; + expected_tinvisibles = tinv; + expected_visibles = vis; + expected_invisibles = inv; + File testFile = null; + String tname="Test" + N.toString(); + hasInnerClass=false; + String testDef = "Test " + testcount + " parameters: tinv=" + tinv + + ", tvis=" + tvis + ", inv=" + inv + ", vis=" + vis + + ", Arepeats=" + Arepeats + ", BDrepeats=" + BDrepeats + + ", ABmix=" + ABmix + ", retention: " + rtn + ", anno2: " + + et2 + ", src=" + source; + +// Uncomment this block to run the tests but skip failing scenarios. +// // 8005681 - skip cases with repeated annotations on new, array, cast. +// if((source==3 || source==8 || source==9) && (ABmix || (Arepeats && BDrepeats))) { +// System.out.println(testDef+"\n8005681-skip repeated annotations on new,array,cast"); +// return; +// } + + println(testDef); + // Create test source and File. + String sourceString = sourceString(tname, rtn, et2, Arepeats, + BDrepeats, ABmix, source); + testFile = writeTestFile(tname+".java", sourceString); + // Compile test source and read classfile. + File classFile = null; + try { + classFile = compile(testFile); + } catch (Error err) { + System.err.println("Failed compile. Source:\n" + sourceString); + throw err; + } + //if sourcString() set hasInnerClass it also set innerClassname. + if(hasInnerClass) { + StringBuffer sb = new StringBuffer(classFile.getAbsolutePath()); + classFile=new File(sb.insert(sb.lastIndexOf(".class"),innerClassname).toString()); + } + ClassFile cf = ClassFile.read(classFile); + + //Test class,fields and method counts. + test(cf); + + for (Field f : cf.fields) { + test(cf, f); + } + for (Method m: cf.methods) { + test(cf, m); + } + countAnnotations(); + if (errors > 0) { + System.err.println( testDef ); + System.err.println( "Source:\n" + sourceString ); + throw new Exception( errors + " errors found" ); + } + println("Pass"); + } + + // + // Source for test cases + // + String sourceString(String testname, String retentn, String annot2, + Boolean Arepeats, Boolean BDrepeats, Boolean ABmix, + int src) { + + String As = "@A", Bs = "@B", Ds = "@D"; + if(Arepeats) As = "@A @A"; + if(BDrepeats) { + Bs = "@B @B"; + Ds = "@D @D"; + } + if(ABmix) { As = "@A @B"; Bs = "@A @B"; Ds = "@D @D"; } + + // Source to check for TYPE_USE and TYPE_PARAMETER annotations. + // Source base (annotations) is same for all test cases. + String source = new String(); + String imports = new String("import java.lang.annotation.*; \n" + + "import static java.lang.annotation.RetentionPolicy.*; \n" + + "import static java.lang.annotation.ElementType.*; \n" + + "import java.util.List; \n" + + "import java.util.HashMap; \n" + + "import java.util.Map; \n\n"); + + String sourceBase = new String("@Retention("+retentn+")\n" + + "@Target({TYPE_USE,_OTHER_})\n" + + "@ContainedBy( AC.class )\n" + + "@interface A { }\n\n" + + + "@Retention("+retentn+")\n" + + "@Target({TYPE_USE,_OTHER_})\n" + + "@ContainerFor(A.class)\n" + + "@interface AC { A[] value(); }\n\n" + + + "@Retention("+retentn+")\n" + + "@Target({TYPE_USE,_OTHER_})\n" + + "@ContainedBy( BC.class )\n" + + "@interface B { }\n\n" + + + "@Retention("+retentn+")\n" + + "@Target({TYPE_USE,_OTHER_})\n" + + "@ContainerFor(B.class)\n" + + "@interface BC { B[] value(); } \n\n" + + + "@Retention("+retentn+")\n" + + "@Target({TYPE_USE,TYPE_PARAMETER,_OTHER_})\n" + + "@ContainedBy(DC.class)\n" + + "@interface D { }\n\n" + + + "@Retention("+retentn+")\n" + + "@Target({TYPE_USE,TYPE_PARAMETER,_OTHER_})\n" + + "@ContainerFor(D.class) \n" + + "@interface DC { D[] value(); }\n\n"); + + // Test case sources with sample generated source + switch(src) { + case 3: // (repeating) type annotations on field in method body + /* + * class Test1 { + * Test1(){} + * // type usage in method body + * String test(Test1 this, String param, String ... vararg) { + * @A @B + * Object o = new @A @B String @A @B [3]; + * return (@A @B String) null; + * }} + */ + source = new String( + "class " + testname + " {\n" + + "" + testname +"(){} \n" + + "// type usage in method body \n" + + "String test("+testname+" this, " + + "String param, String ... vararg) { \n" + + " _As_ _Bs_\n Object o = new _As_ _Bs_ String _As_ _Bs_ [3]; \n" + + " return (_As_ _Bs_ String) null; \n" + + "} \n" + + "} \n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) + + "\n\n"; + break; + case 8: // (repeating) annotations on type parameters, bounds and type arguments in new statement. + /* + * class Test2 { + * Map, Integer> map = + * new HashMap<@A @B List<@A @B String>, @A @B Integer>(); + * Map, Integer> map2 = new @A @B HashMap<>(); + * String test(Test2 this) { return null;} + * String genericMethod(T t) { return null; } + * } + */ + source = new String( source + + "// (repeating) annotations on type parameters, bounds and type arguments. \n" + + "class " + testname + " {\n" + + " Map, Integer> map =\n" + + " new HashMap<_As_ _Bs_ List<_As_ _Bs_ String>, _As_ _Bs_ Integer>();\n" + + " Map, Integer> map2 = new _As_ _Bs_ HashMap<>();\n" + + " String test(" + testname + " this) { return null;}\n" + + " String genericMethod(T t) { return null; }\n" + + "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) + + "\n\n"; + break; + case 9: // (repeating)annotations on type parameters of class, method return value in method. + /* + * class Test3{ + * Map, E > foo(E e) { + * class maptest { + * Map,E> getMap() { + * Map,E> Em = new HashMap,@A @B @D E>(); + * return Em; + * } + * } + * return new maptest().getMap(); + * } + * Map,String> shm = foo(new String("hello")); + * } + */ + source = new String( source + + "// (repeating)annotations on type parameters of class, method return value in method. \n" + + "class "+ testname + "{\n" + + " Map, E > foo(E e) {\n" + + " class maptest {\n" + // inner class $1maptest + " Map,E> getMap() { \n" + + " Map,E> Em = new HashMap,_As_ _Bs_ _Ds_ E>();\n" + + " return Em;\n" + + " }\n" + + " }\n" + + " return new maptest().getMap();\n" + + " }\n" + + " Map,String> shm = foo(new String(\"hello\"));\n" + + "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) + + "\n\n"; + hasInnerClass=true; + innerClassname="$1maptest"; + break; + + } + return imports + source; + } +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/DeadCode.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/DeadCode.java new file mode 100644 index 00000000000..6d00bcc2ce6 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/DeadCode.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2009, 2013, 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. + */ + +import java.lang.annotation.*; +import java.io.*; +import java.net.URL; +import java.util.List; + +import com.sun.tools.classfile.*; + +/* + * @test + * @bug 6917130 8006775 + * @summary test that optimized away annotations are not emited to classfile + */ + +public class DeadCode extends ClassfileTestHelper { + public static void main(String[] args) throws Exception { + new DeadCode().run(); + } + + public void run() throws Exception { + expected_tinvisibles = 1; + expected_tvisibles = 0; + + ClassFile cf = getClassFile("DeadCode$Test.class"); + test(cf); + for (Field f : cf.fields) { + test(cf, f); + } + for (Method m: cf.methods) { + test(cf, m); + } + + countAnnotations(); + + if (errors > 0) + throw new Exception(errors + " errors found"); + System.out.println("PASSED"); + } + + /*********************** Test class *************************/ + static class Test { + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface A {} + + void test() { + List o = null; + o.toString(); + + @A String m; + if (false) { + @A String a; + @A String b = "m"; + b.toString(); + List c = null; + c.toString(); + } + } + } + +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/NewTypeArguments.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/NewTypeArguments.java new file mode 100644 index 00000000000..84b9a85b3ae --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/NewTypeArguments.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2009 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. + */ + +import java.lang.annotation.*; +import java.io.*; +import java.net.URL; +import java.util.List; + +import com.sun.tools.classfile.*; + +/* + * @test ClassLiterals + * @summary test that new type arguments are emitted to classfile + */ + +public class NewTypeArguments extends ClassfileTestHelper{ + public static void main(String[] args) throws Exception { + new NewTypeArguments().run(); + } + + public void run() throws Exception { + expected_tinvisibles = 3; + expected_tvisibles = 0; + + ClassFile cf = getClassFile("NewTypeArguments$Test.class"); + test(cf); + for (Field f : cf.fields) { + test(cf, f); + } + for (Method m: cf.methods) { + test(cf, m); + } + + countAnnotations(); + + if (errors > 0) + throw new Exception(errors + " errors found"); + System.out.println("PASSED"); + } + + /*********************** Test class *************************/ + static class Test { + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface A {} + Test(E e) {} + + void test() { + new <@A String> Test(null); + new <@A List<@A String>> Test(null); + } + } +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/NoTargetAnnotations.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/NoTargetAnnotations.java new file mode 100644 index 00000000000..6458d54234b --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/NoTargetAnnotations.java @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2008 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. + */ + +import java.io.*; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.net.URL; +import java.util.List; + +import com.sun.tools.classfile.*; + +/* + * @test NoTargetAnnotations + * @summary test that annotations with no Target meta type is emitted + * only once as declaration annotation + */ +public class NoTargetAnnotations { + + public static void main(String[] args) throws Exception { + new NoTargetAnnotations().run(); + } + + public void run() throws Exception { + ClassFile cf = getClassFile("NoTargetAnnotations$Test.class"); + for (Field f : cf.fields) { + test(cf, f); + testDeclaration(cf, f); + } + for (Method m: cf.methods) { + test(cf, m); + testDeclaration(cf, m); + } + + countAnnotations(); + + if (errors > 0) + throw new Exception(errors + " errors found"); + System.out.println("PASSED"); + } + + ClassFile getClassFile(String name) throws IOException, ConstantPoolException { + URL url = getClass().getResource(name); + InputStream in = url.openStream(); + try { + return ClassFile.read(in); + } finally { + in.close(); + } + } + + /************ Helper annotations counting methods ******************/ + void test(ClassFile cf, Method m) { + test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); + test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); + } + + void test(ClassFile cf, Field m) { + test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); + test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); + } + + void testDeclaration(ClassFile cf, Method m) { + testDecl(cf, m, Attribute.RuntimeVisibleAnnotations, true); + testDecl(cf, m, Attribute.RuntimeInvisibleAnnotations, false); + } + + void testDeclaration(ClassFile cf, Field m) { + testDecl(cf, m, Attribute.RuntimeVisibleAnnotations, true); + testDecl(cf, m, Attribute.RuntimeInvisibleAnnotations, false); + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void test(ClassFile cf, Method m, String name, boolean visible) { + int index = m.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = m.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + } + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void test(ClassFile cf, Field m, String name, boolean visible) { + int index = m.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = m.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + } + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void testDecl(ClassFile cf, Method m, String name, boolean visible) { + int index = m.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = m.attributes.get(index); + assert attr instanceof RuntimeAnnotations_attribute; + RuntimeAnnotations_attribute tAttr = (RuntimeAnnotations_attribute)attr; + this.declAnnotations += tAttr.annotations.length; + } + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void testDecl(ClassFile cf, Field m, String name, boolean visible) { + int index = m.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = m.attributes.get(index); + assert attr instanceof RuntimeAnnotations_attribute; + RuntimeAnnotations_attribute tAttr = (RuntimeAnnotations_attribute)attr; + this.declAnnotations += tAttr.annotations.length; + } + } + + File compileTestFile(File f) { + int rc = com.sun.tools.javac.Main.compile(new String[] { "-XDTA:writer", "-source", "1.8", "-g", f.getPath() }); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + String path = f.getPath(); + return new File(path.substring(0, path.length() - 5) + ".class"); + } + + void countAnnotations() { + int expected_all = expected_visibles + expected_invisibles; + + if (expected_all != all) { + errors++; + System.err.println("expected " + expected_all + + " annotations but found " + all); + } + + if (expected_visibles != visibles) { + errors++; + System.err.println("expected " + expected_visibles + + " visibles annotations but found " + visibles); + } + + if (expected_invisibles != invisibles) { + errors++; + System.err.println("expected " + expected_invisibles + + " invisibles annotations but found " + invisibles); + } + + if (expected_decl != declAnnotations) { + errors++; + System.err.println("expected " + expected_decl + + " declaration annotations but found " + declAnnotations); + } + } + + int errors; + int all; + int visibles; + int invisibles; + + int declAnnotations; + + /*********************** Test class *************************/ + static int expected_invisibles = 0; + static int expected_visibles = 0; + static int expected_decl = 1; + + static class Test { + @Retention(RetentionPolicy.RUNTIME) + @interface A {} + + @A String method() { + return null; + } + } +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/TypeCasts.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/TypeCasts.java new file mode 100644 index 00000000000..18f8e3b36bd --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/TypeCasts.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2009 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. + */ + +import java.lang.annotation.*; +import java.io.*; +import java.net.URL; +import java.util.List; + +import com.sun.tools.classfile.*; + +/* + * @test + * @bug 6843077 8006775 + * @summary test that typecasts annotation are emitted if only the cast + * expression is optimized away + */ + +public class TypeCasts extends ClassfileTestHelper{ + public static void main(String[] args) throws Exception { + new TypeCasts().run(); + } + + public void run() throws Exception { + expected_tinvisibles = 4; + expected_tvisibles = 0; + + ClassFile cf = getClassFile("TypeCasts$Test.class"); + test(cf); + for (Field f : cf.fields) { + test(cf, f); + } + for (Method m: cf.methods) { + test(cf, m); + } + + countAnnotations(); + + if (errors > 0) + throw new Exception(errors + " errors found"); + System.out.println("PASSED"); + } + + /*********************** Test class *************************/ + static class Test { + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface A {} + + void emit() { + Object o = null; + String s = null; + + String a0 = (@A String)o; + Object a1 = (@A Object)o; + + String b0 = (@A String)s; + Object b1 = (@A Object)s; + } + + void alldeadcode() { + Object o = null; + + if (false) { + String a0 = (@A String)o; + } + } + } +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/Wildcards.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/Wildcards.java new file mode 100644 index 00000000000..d4621047ac5 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/Wildcards.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2009 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. + */ + +import java.lang.annotation.*; +import java.io.*; +import java.net.URL; +import java.util.List; + +import com.sun.tools.classfile.*; + +/* + * @test Wildcards + * @bug 6843077 8006775 + * @summary test that annotations target wildcards get emitted to classfile + */ +public class Wildcards extends ClassfileTestHelper { + public static void main(String[] args) throws Exception { + new Wildcards().run(); + } + + public void run() throws Exception { + expected_tinvisibles = 3; + expected_tvisibles = 0; + + ClassFile cf = getClassFile("Wildcards$Test.class"); + test(cf); + for (Field f : cf.fields) { + test(cf, f); + } + for (Method m: cf.methods) { + test(cf, m); + } + + countAnnotations(); + + if (errors > 0) + throw new Exception(errors + " errors found"); + System.out.println("PASSED"); + } + + /*********************** Test class *************************/ + static class Test { + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface A {} + + List f; + + List test(List p) { + List l; // not counted... gets optimized away + return null; + } + } +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedImport.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedImport.java new file mode 100644 index 00000000000..db14aefee15 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedImport.java @@ -0,0 +1,15 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8006775 + * @summary Import clauses cannot use annotations. + * @author Werner Dietl + * @compile/fail/ref=AnnotatedImport.out -XDrawDiagnostics AnnotatedImport.java + */ + +import java.@A util.List; +import @A java.util.Map; +import java.util.@A HashMap; + +class AnnotatedImport { } + +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedImport.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedImport.out new file mode 100644 index 00000000000..dbd0d42c1e3 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedImport.out @@ -0,0 +1,7 @@ +AnnotatedImport.java:9:13: compiler.err.expected: token.identifier +AnnotatedImport.java:9:14: compiler.err.expected3: class, interface, enum +AnnotatedImport.java:10:7: compiler.err.expected: token.identifier +AnnotatedImport.java:10:10: compiler.err.expected: ';' +AnnotatedImport.java:11:18: compiler.err.expected: token.identifier +AnnotatedImport.java:11:19: compiler.err.expected3: class, interface, enum +6 errors diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage1.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage1.java new file mode 100644 index 00000000000..6b8b64a656f --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage1.java @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8006775 + * @summary Package declarations cannot use annotations. + * @author Werner Dietl + * @compile/fail/ref=AnnotatedPackage1.out -XDrawDiagnostics AnnotatedPackage1.java + */ + +package name.@A p1.p2; + +class AnnotatedPackage1 { } + +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage1.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage1.out new file mode 100644 index 00000000000..66ae60f72f2 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage1.out @@ -0,0 +1,3 @@ +AnnotatedPackage1.java:9:14: compiler.err.expected: token.identifier +AnnotatedPackage1.java:9:15: compiler.err.expected3: class, interface, enum +2 errors diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage2.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage2.java new file mode 100644 index 00000000000..53eb5b142f3 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage2.java @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8006775 + * @summary Package declarations cannot use annotations. + * @author Werner Dietl + * @compile/fail/ref=AnnotatedPackage2.out -XDrawDiagnostics AnnotatedPackage2.java + */ + +package @A p1.p2; + +class AnnotatedPackage2 { } + +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage2.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage2.out new file mode 100644 index 00000000000..2ab804500f8 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage2.out @@ -0,0 +1,3 @@ +AnnotatedPackage2.java:9:8: compiler.err.expected: token.identifier +AnnotatedPackage2.java:9:10: compiler.err.expected3: class, interface, enum +2 errors diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.java new file mode 100644 index 00000000000..9f80b2e9f28 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.java @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary test that only Java 8 allows type annotations + * @author Mahmood Ali + * @compile/fail/ref=AnnotationVersion.out -XDrawDiagnostics -Xlint:-options -source 1.6 AnnotationVersion.java + * @compile/fail/ref=AnnotationVersion7.out -XDrawDiagnostics -Xlint:-options -source 1.7 AnnotationVersion.java + */ +class AnnotationVersion { + public void method(@A AnnotationVersion this) { } +} + +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.out new file mode 100644 index 00000000000..d836ff3532a --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.out @@ -0,0 +1,2 @@ +AnnotationVersion.java:10:43: compiler.err.type.annotations.not.supported.in.source: 1.6 +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion7.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion7.out new file mode 100644 index 00000000000..cb2fca3edce --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion7.out @@ -0,0 +1,2 @@ +AnnotationVersion.java:10:43: compiler.err.type.annotations.not.supported.in.source: 1.7 +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/BadCast.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/BadCast.java new file mode 100644 index 00000000000..a24c323d746 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/BadCast.java @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8006775 + * @summary A cast cannot consist of only an annotation. + * @author Werner Dietl + * @compile/fail/ref=BadCast.out -XDrawDiagnostics BadCast.java + */ +class BadCast { + static void main() { + Object o = (@A) ""; + } +} + +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/BadCast.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/BadCast.out new file mode 100644 index 00000000000..f1b8bf04ca6 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/BadCast.out @@ -0,0 +1,2 @@ +BadCast.java:10:19: compiler.err.illegal.start.of.type +1 error \ No newline at end of file diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.java new file mode 100644 index 00000000000..8cd7d6aa155 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.java @@ -0,0 +1,41 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8006733 8006775 + * @ignore + * @summary A static outer class cannot be annotated. + * @author Werner Dietl + * @compile/fail/ref=CantAnnotateStaticClass.out -XDrawDiagnostics CantAnnotateStaticClass.java + */ + +import java.util.List; +import java.lang.annotation.*; + +class CantAnnotateStaticClass { + @Target(ElementType.TYPE_USE) + @interface A {} + + static class Outer { + class Inner {} + } + + // 8 errors: + @A Outer.Inner f1; + @A Outer.Inner f1r() { return null; } + void f1p(@A Outer.Inner p) { } + void f1c(Object o) { + Object l = (@A Outer.Inner) o; + } + + List<@A Outer.Inner> f2; + List<@A Outer.Inner> f2r() { return null; } + void f2p(List<@A Outer.Inner> p) { } + void f2c(Object o) { + Object l = (List<@A Outer.Inner>) o; + } + + // OK: + @A Outer g1; + List<@A Outer> g2; + Outer. @A Inner g3; + List g4; +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.out new file mode 100644 index 00000000000..2995a4d0e74 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/CantAnnotateStaticClass.out @@ -0,0 +1 @@ +dummy \ No newline at end of file diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteArray.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteArray.java new file mode 100644 index 00000000000..c414a5f807e --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteArray.java @@ -0,0 +1,12 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary test incomplete array declaration + * @author Mahmood Ali + * @compile/fail/ref=IncompleteArray.out -XDrawDiagnostics IncompleteArray.java + */ +class IncompleteArray { + int @A [] @A var; +} + +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteArray.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteArray.out new file mode 100644 index 00000000000..a03a09283ee --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteArray.out @@ -0,0 +1,2 @@ +IncompleteArray.java:9:13: compiler.err.illegal.start.of.type +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteVararg.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteVararg.java new file mode 100644 index 00000000000..1bb05a43aec --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteVararg.java @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary test incomplete vararg declaration + * @author Mahmood Ali + * @compile/fail/ref=IncompleteVararg.out -XDrawDiagnostics IncompleteVararg.java + */ +class IncompleteArray { + // the last variable may be vararg + void method(int @A test) { } +} + +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteVararg.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteVararg.out new file mode 100644 index 00000000000..7cec6c9ee78 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IncompleteVararg.out @@ -0,0 +1,2 @@ +IncompleteVararg.java:10:19: compiler.err.illegal.start.of.type +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/IndexArray.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IndexArray.java new file mode 100644 index 00000000000..7098b93ee81 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IndexArray.java @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary test indexing of an array + * @author Mahmood Ali + * @compile/fail/ref=IndexArray.out -XDrawDiagnostics IndexArray.java + */ +class IndexArray { + int[] var; + int a = var @A [1]; +} + +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/IndexArray.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IndexArray.out new file mode 100644 index 00000000000..762f38b15a8 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/IndexArray.out @@ -0,0 +1,2 @@ +IndexArray.java:10:15: compiler.err.illegal.start.of.expr +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/LintCast.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/LintCast.java new file mode 100644 index 00000000000..fdb31832ae5 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/LintCast.java @@ -0,0 +1,69 @@ +import java.lang.annotation.*; +import java.util.List; + +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary test that compiler doesn't warn about annotated redundant casts + * @author Mahmood Ali + * @author Werner Dietl + * @compile/ref=LintCast.out -Xlint:cast -XDrawDiagnostics LintCast.java + */ +class LintCast { + void unparameterized() { + String s = "m"; + String s1 = (String)s; + String s2 = (@A String)s; + } + + void parameterized() { + List l = null; + List l1 = (List)l; + List l2 = (List<@A String>)l; + } + + void array() { + int @A [] a = null; + int[] a1 = (int[])a; + int[] a2 = (int @A [])a; + } + + void sameAnnotations() { + @A String annotated = null; + String unannotated = null; + + // compiler ignore annotated casts even if redundant + @A String anno1 = (@A String)annotated; + + // warn if redundant without an annotation + String anno2 = (String)annotated; + String unanno2 = (String)unannotated; + } + + void more() { + Object @A [] a = null; + Object[] a1 = (Object[])a; + Object[] a2 = (Object @A [])a; + + @A List l3 = null; + List l4 = (List)l3; + List l5 = (@A List)l3; + + List<@A String> l6 = null; + List l7 = (List)l6; + List l8 = (List<@A String>)l6; + + @A Object o = null; + Object o1 = (Object)o; + Object o2 = (@A Object)o; + + Outer. @A Inner oi = null; + Outer.Inner oi1 = (Outer.Inner)oi; + Outer.Inner oi2 = (Outer. @A Inner)oi; + } + + class Outer { class Inner {} } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/LintCast.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/LintCast.out new file mode 100644 index 00000000000..212423e8895 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/LintCast.out @@ -0,0 +1,11 @@ +LintCast.java:15:21: compiler.warn.redundant.cast: java.lang.String +LintCast.java:21:27: compiler.warn.redundant.cast: java.util.List +LintCast.java:27:20: compiler.warn.redundant.cast: (@A :: int[]) +LintCast.java:39:24: compiler.warn.redundant.cast: java.lang.String +LintCast.java:40:26: compiler.warn.redundant.cast: java.lang.String +LintCast.java:45:23: compiler.warn.redundant.cast: (@A :: java.lang.Object[]) +LintCast.java:49:27: compiler.warn.redundant.cast: java.util.List +LintCast.java:53:27: compiler.warn.redundant.cast: java.util.List +LintCast.java:57:21: compiler.warn.redundant.cast: java.lang.Object +LintCast.java:61:27: compiler.warn.redundant.cast: LintCast.Outer.Inner +10 warnings \ No newline at end of file diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/OldArray.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/OldArray.java new file mode 100644 index 00000000000..4ed4e87aec1 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/OldArray.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +/* + * @test + * @bug 6843077 8006775 + * @summary test old array syntax + * @author Mahmood Ali + * @compile/fail -XDrawDiagnostics OldArray.java + */ +class OldArray { + String [@A] s() { return null; } +} + +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/Scopes.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/Scopes.java new file mode 100644 index 00000000000..aab3c55832c --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/Scopes.java @@ -0,0 +1,17 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check that A is accessible in the class type parameters + * @author Mahmood Ali + * @compile/fail/ref=Scopes.out -XDrawDiagnostics Scopes.java + */ +class Scopes { + // UniqueInner is not visible in the type parameters. + // One has to use Scopes.UniqueInner. + // Annotations with the default @Target are not allowed there, + // so we also get the second error about the invalid location. + // Adding the target here doesn't matter, as we don't resolve + // the annotation type. + // @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface UniqueInner { }; +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/Scopes.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/Scopes.out new file mode 100644 index 00000000000..cf7eeceb9d8 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/Scopes.out @@ -0,0 +1,3 @@ +Scopes.java:8:25: compiler.err.cant.resolve: kindname.class, UniqueInner, , +Scopes.java:8:24: compiler.err.annotation.type.not.applicable +2 errors diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticFields.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticFields.java new file mode 100644 index 00000000000..f75583f9688 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticFields.java @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary static field access isn't a valid location + * @author Mahmood Ali + * @compile/fail/ref=StaticFields.out -XDrawDiagnostics StaticFields.java + */ +class C { + int f; + int a = @A C.f; +} + +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticFields.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticFields.out new file mode 100644 index 00000000000..3364c661fdb --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticFields.out @@ -0,0 +1,2 @@ +StaticFields.java:10:17: compiler.err.illegal.start.of.expr +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.java new file mode 100644 index 00000000000..cb386d1abab --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.java @@ -0,0 +1,12 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary static methods don't have receivers + * @author Mahmood Ali + * @compile/fail/ref=StaticMethods.out -XDrawDiagnostics StaticMethods.java + */ +class StaticMethods { + static void main(@A StaticMethods this) { } +} + +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.out new file mode 100644 index 00000000000..d75a02bffe3 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.out @@ -0,0 +1,2 @@ +StaticMethods.java:9:37: compiler.err.annotation.type.not.applicable +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeAndField.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeAndField.java new file mode 100644 index 00000000000..4f600f44abc --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeAndField.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2013, 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. + */ + +/* + * @test + * @bug 8006703 8006775 + * @summary Ensure that TYPE_USE and FIELD work together. + * @author Werner Dietl + * @compile TypeAndField.java + */ +import java.lang.annotation.*; + +class TypeAndField { + @TA Integer i; + @TA int j; +} + +@Retention(RetentionPolicy.CLASS) +@Target({ElementType.TYPE_USE, ElementType.FIELD}) +@interface TA { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/VoidGenericMethod.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/VoidGenericMethod.java new file mode 100644 index 00000000000..38a0395ffab --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/VoidGenericMethod.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +/* + * @test + * @bug 6843077 8006775 + * @summary test type annotation on void generic methods + * @author Mahmood Ali + * @compile/fail VoidGenericMethod.java + */ +class VoidGenericMethod { + public @A void method() { } +} + +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DuplicateAnnotationValue.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DuplicateAnnotationValue.java new file mode 100644 index 00000000000..cc0b2d96db9 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DuplicateAnnotationValue.java @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 6919944 8006775 + * @summary check for duplicate annotation values + * @author Mahmood Ali + * @compile/fail/ref=DuplicateAnnotationValue.out -XDrawDiagnostics DuplicateAnnotationValue.java + */ +import java.lang.annotation.*; +class DuplicateAnnotationValue { + void test() { + String @A(value = 2, value = 1) [] s; + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { int value(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DuplicateAnnotationValue.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DuplicateAnnotationValue.out new file mode 100644 index 00000000000..566321c05db --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DuplicateAnnotationValue.out @@ -0,0 +1,2 @@ +DuplicateAnnotationValue.java:11:26: compiler.err.duplicate.annotation.member.value: value, A +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DuplicateTypeAnnotation.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DuplicateTypeAnnotation.java new file mode 100644 index 00000000000..da0438eda17 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DuplicateTypeAnnotation.java @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for duplicate annotations + * @author Mahmood Ali + * @compile/fail/ref=DuplicateTypeAnnotation.out -XDrawDiagnostics DuplicateTypeAnnotation.java + */ +import java.lang.annotation.*; +class DuplicateTypeAnnotation { + void test() { + String @A @A [] s; + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DuplicateTypeAnnotation.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DuplicateTypeAnnotation.out new file mode 100644 index 00000000000..3c5f6ea1c68 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DuplicateTypeAnnotation.out @@ -0,0 +1,3 @@ +DuplicateTypeAnnotation.java:11:12: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +DuplicateTypeAnnotation.java:11:15: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +2 errors diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/InvalidLocation.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/InvalidLocation.java new file mode 100644 index 00000000000..da44d219383 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/InvalidLocation.java @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for invalid annotatins given the target + * @author Mahmood Ali + * @compile/fail/ref=InvalidLocation.out -XDrawDiagnostics InvalidLocation.java + */ + +class InvalidLocation { + void test() { + String @A [] s; + } +} + +@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/InvalidLocation.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/InvalidLocation.out new file mode 100644 index 00000000000..868ab979837 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/InvalidLocation.out @@ -0,0 +1,2 @@ +InvalidLocation.java:11:12: compiler.err.annotation.type.not.applicable +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/MissingAnnotationValue.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/MissingAnnotationValue.java new file mode 100644 index 00000000000..4f099e03156 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/MissingAnnotationValue.java @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for missing annotation value + * @author Mahmood Ali + * @compile/fail/ref=MissingAnnotationValue.out -XDrawDiagnostics MissingAnnotationValue.java + */ +class MissingAnnotationValue { + void test() { + String @A [] s; + } +} + +@interface A { int field(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/MissingAnnotationValue.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/MissingAnnotationValue.out new file mode 100644 index 00000000000..74a7ef7340b --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/MissingAnnotationValue.out @@ -0,0 +1,2 @@ +MissingAnnotationValue.java:10:12: compiler.err.annotation.missing.default.value: A, field +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/DuplicateAnnotationValue.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/DuplicateAnnotationValue.java new file mode 100644 index 00000000000..2230767d300 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/DuplicateAnnotationValue.java @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 6919944 8006775 + * @summary check for duplicate annotation values for type parameter + * @author Mahmood Ali + * @compile/fail/ref=DuplicateAnnotationValue.out -XDrawDiagnostics DuplicateAnnotationValue.java + */ +import java.lang.annotation.*; +class DuplicateAnnotationValue { + void method() { + class Inner<@A(value = 2, value = 1) K> {} + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { int value(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/DuplicateAnnotationValue.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/DuplicateAnnotationValue.out new file mode 100644 index 00000000000..12248c81a87 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/DuplicateAnnotationValue.out @@ -0,0 +1,2 @@ +DuplicateAnnotationValue.java:11:31: compiler.err.duplicate.annotation.member.value: value, A +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/DuplicateTypeAnnotation.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/DuplicateTypeAnnotation.java new file mode 100644 index 00000000000..3438dd2a9fc --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/DuplicateTypeAnnotation.java @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for duplicate annotations + * @author Mahmood Ali + * @compile/fail/ref=DuplicateTypeAnnotation.out -XDrawDiagnostics DuplicateTypeAnnotation.java + */ +import java.lang.annotation.*; +class DuplicateTypeAnno { + void innermethod() { + class Inner<@A @A K> { } + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/DuplicateTypeAnnotation.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/DuplicateTypeAnnotation.out new file mode 100644 index 00000000000..7eb43efa3ed --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/DuplicateTypeAnnotation.out @@ -0,0 +1,3 @@ +DuplicateTypeAnnotation.java:11:17: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +DuplicateTypeAnnotation.java:11:20: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +2 errors diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/InvalidLocation.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/InvalidLocation.java new file mode 100644 index 00000000000..46d65a8daef --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/InvalidLocation.java @@ -0,0 +1,15 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for invalid annotatins given the target + * @author Mahmood Ali + * @compile/fail/ref=InvalidLocation.out -XDrawDiagnostics InvalidLocation.java + */ +class InvalidLocation { + void innermethod() { + class Inner<@A K> {} + } +} + +@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/InvalidLocation.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/InvalidLocation.out new file mode 100644 index 00000000000..b74ad54ba94 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/InvalidLocation.out @@ -0,0 +1,2 @@ +InvalidLocation.java:10:17: compiler.err.annotation.type.not.applicable +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/MissingAnnotationValue.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/MissingAnnotationValue.java new file mode 100644 index 00000000000..5a5c8b69587 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/MissingAnnotationValue.java @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for missing annotation value + * @author Mahmood Ali + * @compile/fail/ref=MissingAnnotationValue.out -XDrawDiagnostics MissingAnnotationValue.java + */ +class MissingAnnotationValue { + void innermethod() { + class Inner<@A K> { } + } +} + +@interface A { int field(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/MissingAnnotationValue.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/MissingAnnotationValue.out new file mode 100644 index 00000000000..637ff4acc0a --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/innertypeparams/MissingAnnotationValue.out @@ -0,0 +1,2 @@ +MissingAnnotationValue.java:10:17: compiler.err.annotation.missing.default.value: A, field +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/DuplicateAnnotationValue.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/DuplicateAnnotationValue.java new file mode 100644 index 00000000000..f3f36165b64 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/DuplicateAnnotationValue.java @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 6919944 8006775 + * @summary check for duplicate annotation values + * @author Mahmood Ali + * @compile/fail/ref=DuplicateAnnotationValue.out -XDrawDiagnostics DuplicateAnnotationValue.java + */ +import java.lang.annotation.*; +class DuplicateAnnotationValue { + void test() { + String[] a = new String @A(value = 2, value = 1) [5] ; + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { int value(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/DuplicateAnnotationValue.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/DuplicateAnnotationValue.out new file mode 100644 index 00000000000..cb7b69d86f9 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/DuplicateAnnotationValue.out @@ -0,0 +1,2 @@ +DuplicateAnnotationValue.java:11:43: compiler.err.duplicate.annotation.member.value: value, A +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/DuplicateTypeAnnotation.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/DuplicateTypeAnnotation.java new file mode 100644 index 00000000000..be8f479fedf --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/DuplicateTypeAnnotation.java @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for duplicate annotations + * @author Mahmood Ali + * @compile/fail/ref=DuplicateTypeAnnotation.out -XDrawDiagnostics DuplicateTypeAnnotation.java + */ +import java.lang.annotation.*; +class DuplicateTypeAnnotation { + void test() { + String[] a = new String @A @A [5] ; + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/DuplicateTypeAnnotation.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/DuplicateTypeAnnotation.out new file mode 100644 index 00000000000..537e6156ef3 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/DuplicateTypeAnnotation.out @@ -0,0 +1,3 @@ +DuplicateTypeAnnotation.java:11:29: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +DuplicateTypeAnnotation.java:11:32: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +2 errors diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/InvalidLocation.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/InvalidLocation.java new file mode 100644 index 00000000000..a43e2e7b070 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/InvalidLocation.java @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for invalid annotatins given the target + * @author Mahmood Ali + * @compile/fail/ref=InvalidLocation.out -XDrawDiagnostics InvalidLocation.java + */ + +class InvalidLocation { + void test() { + String[] s = new String @A [5] ; + } +} + +@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/InvalidLocation.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/InvalidLocation.out new file mode 100644 index 00000000000..1d98d174319 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/InvalidLocation.out @@ -0,0 +1,2 @@ +InvalidLocation.java:11:29: compiler.err.annotation.type.not.applicable +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/MissingAnnotationValue.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/MissingAnnotationValue.java new file mode 100644 index 00000000000..15cf6e91496 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/MissingAnnotationValue.java @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for missing annotation value + * @author Mahmood Ali + * @compile/fail/ref=MissingAnnotationValue.out -XDrawDiagnostics MissingAnnotationValue.java + */ +class MissingAnnotationValue { + void test() { + String[] a = new String @A [5]; + } +} + +@interface A { int field(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/MissingAnnotationValue.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/MissingAnnotationValue.out new file mode 100644 index 00000000000..6865348250b --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/newarray/MissingAnnotationValue.out @@ -0,0 +1,2 @@ +MissingAnnotationValue.java:10:29: compiler.err.annotation.missing.default.value: A, field +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/BrokenAnnotation.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/BrokenAnnotation.java new file mode 100644 index 00000000000..7e4581851e5 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/BrokenAnnotation.java @@ -0,0 +1,99 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8006775 + * @summary Ensure unresolved upper bound annotation is handled correctly + * @author Werner Dietl + * @compile/fail/ref=BrokenAnnotation.out -XDrawDiagnostics BrokenAnnotation.java + */ + +// No import, making the annotation @A invalid. +// import java.lang.annotation.*; + +// Works: @Broke.A class... +// Works: class Broke<@Broke.A T> { +// Used to fail: +class BrokenAnnotation { + @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) + @interface A { } +} + +// If the Annotation is e.g. on the top-level class, we +// get something like this: +// +// Broke.java:6: cannot find symbol +// symbol : class Target +// location: class Broke +// @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +// ^ +// 1 error +// +// When the annotation is in the upper bound, one used to get +// the following stack trace: +// +// An exception has occurred in the compiler (1.7.0-jsr308-1.2.7). Please report this bug so we can fix it. For instructions, see http://types.cs.washington.edu/checker-framework/current/README-jsr308.html#reporting-bugs . Thank you. +// java.lang.NullPointerException +// at com.sun.tools.javac.code.Type.isCompound(Type.java:346) +// at com.sun.tools.javac.code.Types.getBounds(Types.java:1940) +// at com.sun.tools.javac.util.RichDiagnosticFormatter$1.visitTypeVar(RichDiagnosticFormatter.java:534) +// at com.sun.tools.javac.util.RichDiagnosticFormatter$1.visitTypeVar(RichDiagnosticFormatter.java:1) +// at com.sun.tools.javac.code.Type$TypeVar.accept(Type.java:1049) +// at com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:3809) +// at com.sun.tools.javac.util.RichDiagnosticFormatter$1.visit(RichDiagnosticFormatter.java:450) +// at com.sun.tools.javac.util.RichDiagnosticFormatter$1.visitClassType(RichDiagnosticFormatter.java:518) +// at com.sun.tools.javac.util.RichDiagnosticFormatter$1.visitClassType(RichDiagnosticFormatter.java:1) +// at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:596) +// at com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:3809) +// at com.sun.tools.javac.util.RichDiagnosticFormatter.preprocessType(RichDiagnosticFormatter.java:442) +// at com.sun.tools.javac.util.RichDiagnosticFormatter.preprocessArgument(RichDiagnosticFormatter.java:172) +// at com.sun.tools.javac.util.RichDiagnosticFormatter.preprocessDiagnostic(RichDiagnosticFormatter.java:155) +// at com.sun.tools.javac.util.RichDiagnosticFormatter.preprocessArgument(RichDiagnosticFormatter.java:178) +// at com.sun.tools.javac.util.RichDiagnosticFormatter.preprocessDiagnostic(RichDiagnosticFormatter.java:155) +// at com.sun.tools.javac.util.RichDiagnosticFormatter.format(RichDiagnosticFormatter.java:111) +// at com.sun.tools.javac.util.RichDiagnosticFormatter.format(RichDiagnosticFormatter.java:1) +// at com.sun.tools.javac.util.Log.writeDiagnostic(Log.java:514) +// at com.sun.tools.javac.util.Log.report(Log.java:496) +// at com.sun.tools.javac.comp.Resolve.logResolveError(Resolve.java:2160) +// at com.sun.tools.javac.comp.Resolve.access(Resolve.java:1553) +// at com.sun.tools.javac.comp.Resolve.access(Resolve.java:1580) +// at com.sun.tools.javac.comp.Resolve.access(Resolve.java:1592) +// at com.sun.tools.javac.comp.Resolve.resolveIdent(Resolve.java:1653) +// at com.sun.tools.javac.comp.Attr.visitIdent(Attr.java:2191) +// at com.sun.tools.javac.tree.JCTree$JCIdent.accept(JCTree.java:1873) +// at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:467) +// at com.sun.tools.javac.comp.Attr.attribType(Attr.java:503) +// at com.sun.tools.javac.comp.Attr.attribType(Attr.java:496) +// at com.sun.tools.javac.comp.Attr.attribAnnotationTypes(Attr.java:605) +// at com.sun.tools.javac.comp.MemberEnter.complete(MemberEnter.java:944) +// at com.sun.tools.javac.code.Symbol.complete(Symbol.java:432) +// at com.sun.tools.javac.code.Symbol$ClassSymbol.complete(Symbol.java:832) +// at com.sun.tools.javac.code.Symbol$ClassSymbol.flags(Symbol.java:775) +// at com.sun.tools.javac.comp.Resolve.isAccessible(Resolve.java:350) +// at com.sun.tools.javac.comp.Resolve.isAccessible(Resolve.java:346) +// at com.sun.tools.javac.comp.Resolve.findMemberType(Resolve.java:1346) +// at com.sun.tools.javac.comp.Resolve.findIdentInType(Resolve.java:1512) +// at com.sun.tools.javac.comp.Attr.selectSym(Attr.java:2434) +// at com.sun.tools.javac.comp.Attr.visitSelect(Attr.java:2312) +// at com.sun.tools.javac.tree.JCTree$JCFieldAccess.accept(JCTree.java:1805) +// at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:467) +// at com.sun.tools.javac.comp.Attr.attribType(Attr.java:503) +// at com.sun.tools.javac.comp.Attr.attribType(Attr.java:496) +// at com.sun.tools.javac.comp.Attr.attribAnnotationTypes(Attr.java:605) +// at com.sun.tools.javac.comp.Attr.visitAnnotatedType(Attr.java:3016) +// at com.sun.tools.javac.tree.JCTree$JCAnnotatedType.accept(JCTree.java:2253) +// at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:467) +// at com.sun.tools.javac.comp.Attr.attribType(Attr.java:503) +// at com.sun.tools.javac.comp.Attr.attribType(Attr.java:496) +// at com.sun.tools.javac.comp.Attr.attribTypeVariables(Attr.java:569) +// at com.sun.tools.javac.comp.MemberEnter.complete(MemberEnter.java:955) +// at com.sun.tools.javac.code.Symbol.complete(Symbol.java:432) +// at com.sun.tools.javac.code.Symbol$ClassSymbol.complete(Symbol.java:832) +// at com.sun.tools.javac.comp.Enter.complete(Enter.java:500) +// at com.sun.tools.javac.comp.Enter.main(Enter.java:478) +// at com.sun.tools.javac.main.JavaCompiler.enterTrees(JavaCompiler.java:950) +// at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:841) +// at com.sun.tools.javac.main.Main.compile(Main.java:441) +// at com.sun.tools.javac.main.Main.compile(Main.java:358) +// at com.sun.tools.javac.main.Main.compile(Main.java:347) +// at com.sun.tools.javac.main.Main.compile(Main.java:338) +// at com.sun.tools.javac.Main.compile(Main.java:76) +// at com.sun.tools.javac.Main.main(Main.java:61) diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/BrokenAnnotation.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/BrokenAnnotation.out new file mode 100644 index 00000000000..caeb4bb158d --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/BrokenAnnotation.out @@ -0,0 +1,3 @@ +BrokenAnnotation.java:16:6: compiler.err.cant.resolve.location: kindname.class, Target, , , (compiler.misc.location: kindname.class, BrokenAnnotation, null) +BrokenAnnotation.java:15:34: compiler.err.annotation.type.not.applicable +2 errors \ No newline at end of file diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/DuplicateAnnotationValue.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/DuplicateAnnotationValue.java new file mode 100644 index 00000000000..ae1a043495f --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/DuplicateAnnotationValue.java @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 6919944 8006775 + * @summary check for duplicate annotation values for type parameter + * @author Mahmood Ali + * @compile/fail/ref=DuplicateAnnotationValue.out -XDrawDiagnostics DuplicateAnnotationValue.java + */ +import java.lang.annotation.*; +class DuplicateAnnotationValue { +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { int value(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/DuplicateAnnotationValue.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/DuplicateAnnotationValue.out new file mode 100644 index 00000000000..5badf2cc240 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/DuplicateAnnotationValue.out @@ -0,0 +1,2 @@ +DuplicateAnnotationValue.java:9:56: compiler.err.duplicate.annotation.member.value: value, A +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/DuplicateTypeAnnotation.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/DuplicateTypeAnnotation.java new file mode 100644 index 00000000000..0e64a844f57 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/DuplicateTypeAnnotation.java @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for duplicate annotations + * @author Mahmood Ali + * @compile/fail/ref=DuplicateTypeAnnotation.out -XDrawDiagnostics DuplicateTypeAnnotation.java + */ +import java.lang.annotation.*; +class DuplicateTypeAnno { +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/DuplicateTypeAnnotation.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/DuplicateTypeAnnotation.out new file mode 100644 index 00000000000..09b7843aaf3 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/DuplicateTypeAnnotation.out @@ -0,0 +1,3 @@ +DuplicateTypeAnnotation.java:9:35: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +DuplicateTypeAnnotation.java:9:38: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +2 errors \ No newline at end of file diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/InvalidLocation.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/InvalidLocation.java new file mode 100644 index 00000000000..374a143d26a --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/InvalidLocation.java @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for invalid annotatins given the target + * @author Mahmood Ali + * @compile/fail/ref=InvalidLocation.out -XDrawDiagnostics InvalidLocation.java + */ + +class InvalidLocation { +} + +@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/InvalidLocation.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/InvalidLocation.out new file mode 100644 index 00000000000..d474f174346 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/InvalidLocation.out @@ -0,0 +1,2 @@ +InvalidLocation.java:9:33: compiler.err.annotation.type.not.applicable +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/MissingAnnotationValue.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/MissingAnnotationValue.java new file mode 100644 index 00000000000..58cb921c925 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/MissingAnnotationValue.java @@ -0,0 +1,14 @@ +import java.lang.annotation.*; + +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for missing annotation value + * @author Mahmood Ali + * @compile/fail/ref=MissingAnnotationValue.out -XDrawDiagnostics MissingAnnotationValue.java + */ +class MissingAnnotationValue { +} + +@Target(ElementType.TYPE_USE) +@interface A { int field(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/MissingAnnotationValue.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/MissingAnnotationValue.out new file mode 100644 index 00000000000..89f3ef0de98 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/parambounds/MissingAnnotationValue.out @@ -0,0 +1,2 @@ +MissingAnnotationValue.java:10:40: compiler.err.annotation.missing.default.value: A, field +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DuplicateAnnotationValue.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DuplicateAnnotationValue.java new file mode 100644 index 00000000000..aa0dd5c1eb6 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DuplicateAnnotationValue.java @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 6919944 8006775 + * @summary check for duplicate annotation values in receiver + * @author Mahmood Ali + * @compile/fail/ref=DuplicateAnnotationValue.out -XDrawDiagnostics DuplicateAnnotationValue.java + */ +import java.lang.annotation.*; +class DuplicateAnnotationValue { + void test(@A(value = 2, value = 1) DuplicateAnnotationValue this) { } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { int value(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DuplicateAnnotationValue.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DuplicateAnnotationValue.out new file mode 100644 index 00000000000..73cff02fa91 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DuplicateAnnotationValue.out @@ -0,0 +1,2 @@ +DuplicateAnnotationValue.java:10:27: compiler.err.duplicate.annotation.member.value: value, A +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DuplicateTypeAnnotation.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DuplicateTypeAnnotation.java new file mode 100644 index 00000000000..1ba2846c42d --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DuplicateTypeAnnotation.java @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for duplicate annotations in receiver + * @author Mahmood Ali + * @compile/fail/ref=DuplicateTypeAnnotation.out -XDrawDiagnostics DuplicateTypeAnnotation.java + */ +import java.lang.annotation.*; +class DuplicateTypeAnnotation { + void test(@A @A DuplicateTypeAnnotation this) { } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DuplicateTypeAnnotation.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DuplicateTypeAnnotation.out new file mode 100644 index 00000000000..a2f6dba28c3 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DuplicateTypeAnnotation.out @@ -0,0 +1,3 @@ +DuplicateTypeAnnotation.java:10:13: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +DuplicateTypeAnnotation.java:10:16: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +2 errors diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/InvalidLocation.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/InvalidLocation.java new file mode 100644 index 00000000000..a0f03434387 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/InvalidLocation.java @@ -0,0 +1,15 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for invalid annotatins given the target + * @author Mahmood Ali + * @compile/fail/ref=InvalidLocation.out -XDrawDiagnostics InvalidLocation.java + */ + +class InvalidLocation { + void test(@A InvalidLocation this) { + } +} + +@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/InvalidLocation.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/InvalidLocation.out new file mode 100644 index 00000000000..96a01cec454 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/InvalidLocation.out @@ -0,0 +1,2 @@ +InvalidLocation.java:10:13: compiler.err.annotation.type.not.applicable +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/MissingAnnotationValue.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/MissingAnnotationValue.java new file mode 100644 index 00000000000..4043ed6bc50 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/MissingAnnotationValue.java @@ -0,0 +1,12 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for missing annotation value + * @author Mahmood Ali + * @compile/fail/ref=MissingAnnotationValue.out -XDrawDiagnostics MissingAnnotationValue.java + */ +class MissingAnnotationValue { + void test(@A MissingAnnotationValue this) { } +} + +@interface A { int field(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/MissingAnnotationValue.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/MissingAnnotationValue.out new file mode 100644 index 00000000000..c83391029bf --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/MissingAnnotationValue.out @@ -0,0 +1,2 @@ +MissingAnnotationValue.java:9:13: compiler.err.annotation.missing.default.value: A, field +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/Nesting.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/Nesting.java new file mode 100644 index 00000000000..6b5d7fc3a9f --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/Nesting.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +/* + * @test + * @bug 8006775 + * @summary Ensure that nested classes/methods work + * @author Werner Dietl + * @compile Nesting.java + */ +@interface A { } + +class Nesting { + void top(@A Nesting this) {} + + class B { + void inB(@A B this) {} + } + + void meth(@A Nesting this) { + class C { + void inMethod(@A C this) {} + } + } +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/StaticThings.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/StaticThings.java new file mode 100644 index 00000000000..35ee8432812 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/StaticThings.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +/* + * @test + * @bug 8006775 + * @summary the receiver parameter and static methods/classes + * @author Werner Dietl + * @compile/fail/ref=StaticThings.out -XDrawDiagnostics StaticThings.java + */ +class Test { + // bad + static void test1(Test this) {} + + // bad + static Object test2(Test this) { return null; } + + class Nested1 { + // good + void test3a(Nested1 this) {} + // good + void test3b(Test.Nested1 this) {} + // No static methods + // static void test3c(Nested1 this) {} + } + static class Nested2 { + // good + void test4a(Nested2 this) {} + // good + void test4b(Test.Nested2 this) {} + // bad + static void test4c(Nested2 this) {} + // bad + static void test4d(Test.Nested2 this) {} + } +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/StaticThings.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/StaticThings.out new file mode 100644 index 00000000000..fc50011c1b8 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/StaticThings.out @@ -0,0 +1,5 @@ +StaticThings.java:52:32: compiler.err.annotation.type.not.applicable +StaticThings.java:54:37: compiler.err.annotation.type.not.applicable +StaticThings.java:33:26: compiler.err.annotation.type.not.applicable +StaticThings.java:36:28: compiler.err.annotation.type.not.applicable +4 errors \ No newline at end of file diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.java new file mode 100644 index 00000000000..63277109f30 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +/* + * @test + * @bug 8006775 + * @summary the receiver parameter has the type of the surrounding class + * @author Werner Dietl + * @compile/fail/ref=WrongType.out -XDrawDiagnostics WrongType.java + */ + +@interface A {} + +class WrongType { + Object f; + + void good1(@A WrongType this) {} + + void good2(@A WrongType this) { + this.f = null; + Object o = this.f; + } + + void bad1(@A Object this) {} + + void bad2(@A Object this) { + this.f = null; + Object o = this.f; + } + + void wow(@A XYZ this) { + this.f = null; + } + + class Inner { + void good1(@A Inner this) {} + void good2(@A WrongType.Inner this) {} + + void outerOnly(@A WrongType this) {} + void wrongInner(@A Object this) {} + void badOuter(@A Outer.Inner this) {} + void badInner(@A WrongType.XY this) {} + } + + class Generics { + void m(Generics this) {} + } +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.out new file mode 100644 index 00000000000..804425aaf76 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.out @@ -0,0 +1,9 @@ +WrongType.java:51:15: compiler.err.cant.resolve.location: kindname.class, XYZ, , , (compiler.misc.location: kindname.class, WrongType, null) +WrongType.java:61:27: compiler.err.doesnt.exist: Outer +WrongType.java:62:31: compiler.err.cant.resolve.location: kindname.class, XY, , , (compiler.misc.location: kindname.class, WrongType, null) +WrongType.java:44:23: compiler.err.incorrect.receiver.type +WrongType.java:46:23: compiler.err.incorrect.receiver.type +WrongType.java:59:33: compiler.err.incorrect.receiver.type +WrongType.java:60:31: compiler.err.incorrect.receiver.type +WrongType.java:66:28: compiler.err.incorrect.receiver.type +8 errors \ No newline at end of file diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/DuplicateAnnotationValue.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/DuplicateAnnotationValue.java new file mode 100644 index 00000000000..5f399fa276f --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/DuplicateAnnotationValue.java @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for Duplicate annotation value + * @author Mahmood Ali + * @compile/fail/ref=DuplicateAnnotationValue.out -XDrawDiagnostics DuplicateAnnotationValue.java + */ +import java.lang.annotation.*; +class DuplicateAnnotationValue { + void test() { + new @A String(); + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { int field(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/DuplicateAnnotationValue.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/DuplicateAnnotationValue.out new file mode 100644 index 00000000000..dd7e50bbade --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/DuplicateAnnotationValue.out @@ -0,0 +1,2 @@ +DuplicateAnnotationValue.java:11:9: compiler.err.annotation.missing.default.value: A, field +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/DuplicateTypeAnnotation.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/DuplicateTypeAnnotation.java new file mode 100644 index 00000000000..014490f6104 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/DuplicateTypeAnnotation.java @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for duplicate annotations + * @author Mahmood Ali + * @compile/fail/ref=DuplicateTypeAnnotation.out -XDrawDiagnostics DuplicateTypeAnnotation.java + */ +import java.lang.annotation.*; +class DuplicateTypeAnnotation { + void test() { + new @A @A String(); + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/DuplicateTypeAnnotation.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/DuplicateTypeAnnotation.out new file mode 100644 index 00000000000..04b67141421 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/DuplicateTypeAnnotation.out @@ -0,0 +1,3 @@ +DuplicateTypeAnnotation.java:11:9: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +DuplicateTypeAnnotation.java:11:12: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +2 errors \ No newline at end of file diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/InvalidLocation.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/InvalidLocation.java new file mode 100644 index 00000000000..c3622976c75 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/InvalidLocation.java @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for invalid annotatins given the target + * @author Mahmood Ali + * @compile/fail/ref=InvalidLocation.out -XDrawDiagnostics InvalidLocation.java + */ + +class InvalidLocation { + void test() { + new @A String(); + } +} + +@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/InvalidLocation.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/InvalidLocation.out new file mode 100644 index 00000000000..ad9861c2f6f --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/InvalidLocation.out @@ -0,0 +1,2 @@ +InvalidLocation.java:11:9: compiler.err.annotation.type.not.applicable +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.java new file mode 100644 index 00000000000..5a6bb4299b8 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.java @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for missing annotation value + * @author Mahmood Ali + * @compile/fail/ref=MissingAnnotationValue.out -XDrawDiagnostics MissingAnnotationValue.java + */ +class MissingAnnotationValue { + void test() { + new @A String(); + } +} + +@interface A { int field(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.out new file mode 100644 index 00000000000..f83f6dfa58a --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.out @@ -0,0 +1,2 @@ +MissingAnnotationValue.java:10:9: compiler.err.annotation.missing.default.value: A, field +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/DuplicateAnnotationValue.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/DuplicateAnnotationValue.java new file mode 100644 index 00000000000..a1f432e5563 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/DuplicateAnnotationValue.java @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 6919944 8006775 + * @summary check for duplicate annotation values for type parameter + * @author Mahmood Ali + * @compile/fail/ref=DuplicateAnnotationValue.out -XDrawDiagnostics DuplicateAnnotationValue.java + */ +import java.lang.annotation.*; +class DuplicateAnnotationValue { + DuplicateAnnotationValue<@A(value = 2, value = 1) String> l; +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { int value(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/DuplicateAnnotationValue.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/DuplicateAnnotationValue.out new file mode 100644 index 00000000000..c8e21def939 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/DuplicateAnnotationValue.out @@ -0,0 +1,2 @@ +DuplicateAnnotationValue.java:10:42: compiler.err.duplicate.annotation.member.value: value, A +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/DuplicateTypeAnnotation.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/DuplicateTypeAnnotation.java new file mode 100644 index 00000000000..c25afb5c412 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/DuplicateTypeAnnotation.java @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for duplicate annotations + * @author Mahmood Ali + * @compile/fail/ref=DuplicateTypeAnnotation.out -XDrawDiagnostics DuplicateTypeAnnotation.java + */ +import java.lang.annotation.*; +class DuplicateTypeAnno { + DuplicateTypeAnno<@A @A String> l; +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/DuplicateTypeAnnotation.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/DuplicateTypeAnnotation.out new file mode 100644 index 00000000000..3b6802d9038 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/DuplicateTypeAnnotation.out @@ -0,0 +1,3 @@ +DuplicateTypeAnnotation.java:10:21: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +DuplicateTypeAnnotation.java:10:24: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +2 errors \ No newline at end of file diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/InvalidLocation.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/InvalidLocation.java new file mode 100644 index 00000000000..4b12e79df24 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/InvalidLocation.java @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for invalid annotatins given the target + * @author Mahmood Ali + * @compile/fail/ref=InvalidLocation.out -XDrawDiagnostics InvalidLocation.java + */ + +class InvalidLocation { + InvalidLocation<@A String> l; +} + +@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/InvalidLocation.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/InvalidLocation.out new file mode 100644 index 00000000000..30841b78f0f --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/InvalidLocation.out @@ -0,0 +1,2 @@ +InvalidLocation.java:10:19: compiler.err.annotation.type.not.applicable +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/MissingAnnotationValue.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/MissingAnnotationValue.java new file mode 100644 index 00000000000..a6e00304fa1 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/MissingAnnotationValue.java @@ -0,0 +1,12 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for missing annotation value + * @author Mahmood Ali + * @compile/fail/ref=MissingAnnotationValue.out -XDrawDiagnostics MissingAnnotationValue.java + */ +class MissingAnnotationValue { + MissingAnnotationValue<@A String> l; +} + +@interface A { int field(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/MissingAnnotationValue.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/MissingAnnotationValue.out new file mode 100644 index 00000000000..749442f45b6 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeArgs/MissingAnnotationValue.out @@ -0,0 +1,2 @@ +MissingAnnotationValue.java:9:26: compiler.err.annotation.missing.default.value: A, field +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/DuplicateAnnotationValue.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/DuplicateAnnotationValue.java new file mode 100644 index 00000000000..22ab06ef225 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/DuplicateAnnotationValue.java @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 6919944 8006775 + * @summary check for duplicate annotation values for type parameter + * @author Mahmood Ali + * @compile/fail/ref=DuplicateAnnotationValue.out -XDrawDiagnostics DuplicateAnnotationValue.java + */ +import java.lang.annotation.*; +class DuplicateAnnotationValue<@A(value = 2, value = 1) K> { +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { int value(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/DuplicateAnnotationValue.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/DuplicateAnnotationValue.out new file mode 100644 index 00000000000..b3485b2332b --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/DuplicateAnnotationValue.out @@ -0,0 +1,2 @@ +DuplicateAnnotationValue.java:9:46: compiler.err.duplicate.annotation.member.value: value, A +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/DuplicateTypeAnnotation.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/DuplicateTypeAnnotation.java new file mode 100644 index 00000000000..20883a0ba85 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/DuplicateTypeAnnotation.java @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for duplicate annotations + * @author Mahmood Ali + * @compile/fail/ref=DuplicateTypeAnnotation.out -XDrawDiagnostics DuplicateTypeAnnotation.java + */ +import java.lang.annotation.*; +class DuplicateTypeAnno<@A @A K> { +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/DuplicateTypeAnnotation.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/DuplicateTypeAnnotation.out new file mode 100644 index 00000000000..6fd3ba6e32b --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/DuplicateTypeAnnotation.out @@ -0,0 +1,3 @@ +DuplicateTypeAnnotation.java:9:25: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +DuplicateTypeAnnotation.java:9:28: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +2 errors \ No newline at end of file diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/InvalidLocation.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/InvalidLocation.java new file mode 100644 index 00000000000..094a76ccab1 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/InvalidLocation.java @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for invalid annotatins given the target + * @author Mahmood Ali + * @compile/fail/ref=InvalidLocation.out -XDrawDiagnostics InvalidLocation.java + */ + +class InvalidLocation<@A K> { +} + +@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/InvalidLocation.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/InvalidLocation.out new file mode 100644 index 00000000000..87d42a278c4 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/InvalidLocation.out @@ -0,0 +1,2 @@ +InvalidLocation.java:9:23: compiler.err.annotation.type.not.applicable +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/MissingAnnotationValue.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/MissingAnnotationValue.java new file mode 100644 index 00000000000..39f8bee930f --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/MissingAnnotationValue.java @@ -0,0 +1,11 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for missing annotation value + * @author Mahmood Ali + * @compile/fail/ref=MissingAnnotationValue.out -XDrawDiagnostics MissingAnnotationValue.java + */ +class MissingAnnotationValue<@A K> { +} + +@interface A { int field(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/MissingAnnotationValue.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/MissingAnnotationValue.out new file mode 100644 index 00000000000..acac021869b --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/typeparams/MissingAnnotationValue.out @@ -0,0 +1,2 @@ +MissingAnnotationValue.java:8:30: compiler.err.annotation.missing.default.value: A, field +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DuplicateAnnotationValue.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DuplicateAnnotationValue.java new file mode 100644 index 00000000000..7355719f607 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DuplicateAnnotationValue.java @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 6919944 8006775 + * @summary check for duplicate annotation values for type parameter + * @author Mahmood Ali + * @compile/fail/ref=DuplicateAnnotationValue.out -XDrawDiagnostics DuplicateAnnotationValue.java + */ +import java.lang.annotation.*; +class DuplicateAnnotationValue { + DuplicateAnnotationValue<@A(value = 2, value = 1) ?> l; +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { int value(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DuplicateAnnotationValue.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DuplicateAnnotationValue.out new file mode 100644 index 00000000000..c8e21def939 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DuplicateAnnotationValue.out @@ -0,0 +1,2 @@ +DuplicateAnnotationValue.java:10:42: compiler.err.duplicate.annotation.member.value: value, A +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DuplicateTypeAnnotation.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DuplicateTypeAnnotation.java new file mode 100644 index 00000000000..17ac7a98cbe --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DuplicateTypeAnnotation.java @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for duplicate annotations + * @author Mahmood Ali + * @compile/fail/ref=DuplicateTypeAnnotation.out -XDrawDiagnostics DuplicateTypeAnnotation.java + */ +import java.lang.annotation.*; +class DuplicateTypeAnno { + DuplicateTypeAnno<@A @A ?> l; +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DuplicateTypeAnnotation.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DuplicateTypeAnnotation.out new file mode 100644 index 00000000000..3b6802d9038 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DuplicateTypeAnnotation.out @@ -0,0 +1,3 @@ +DuplicateTypeAnnotation.java:10:21: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +DuplicateTypeAnnotation.java:10:24: compiler.err.duplicate.annotation.missing.container: A, java.lang.annotation.Repeatable +2 errors \ No newline at end of file diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/InvalidLocation.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/InvalidLocation.java new file mode 100644 index 00000000000..eee6ed28b73 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/InvalidLocation.java @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for invalid annotatins given the target + * @author Mahmood Ali + * @compile/fail/ref=InvalidLocation.out -XDrawDiagnostics InvalidLocation.java + */ + +class InvalidLocation { + InvalidLocation<@A ?> l; +} + +@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/InvalidLocation.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/InvalidLocation.out new file mode 100644 index 00000000000..30841b78f0f --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/InvalidLocation.out @@ -0,0 +1,2 @@ +InvalidLocation.java:10:19: compiler.err.annotation.type.not.applicable +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/MissingAnnotationValue.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/MissingAnnotationValue.java new file mode 100644 index 00000000000..c111c895c7d --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/MissingAnnotationValue.java @@ -0,0 +1,12 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary check for missing annotation value + * @author Mahmood Ali + * @compile/fail/ref=MissingAnnotationValue.out -XDrawDiagnostics MissingAnnotationValue.java + */ +class MissingAnnotationValue { + MissingAnnotationValue<@A ?> l; +} + +@interface A { int field(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/MissingAnnotationValue.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/MissingAnnotationValue.out new file mode 100644 index 00000000000..749442f45b6 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/MissingAnnotationValue.out @@ -0,0 +1,2 @@ +MissingAnnotationValue.java:9:26: compiler.err.annotation.missing.default.value: A, field +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/Constructor.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/Constructor.java new file mode 100644 index 00000000000..bbba6345611 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/Constructor.java @@ -0,0 +1,37 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary test invalid location of TypeUse + * @author Mahmood Ali + * @compile/fail/ref=Constructor.out -XDrawDiagnostics Constructor.java + */ + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +class Constructor { + // Constructor result type use annotation + @A Constructor() { } + + // Not type parameter annotation + @B Constructor(int x) { } + + // TODO add err: no "this" receiver parameter for constructors + // Constructor(@A Constructor this, Object o) { } + + // TODO: support Outer.this. +} + +class Constructor2 { + class Inner { + // OK + @A Inner() { } + } +} + +@Target(ElementType.TYPE_USE) +@interface A { } + +@Target(ElementType.TYPE_PARAMETER) +@interface B { } + diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/Constructor.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/Constructor.out new file mode 100644 index 00000000000..05689245d5f --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/Constructor.out @@ -0,0 +1,2 @@ +Constructor.java:17:3: compiler.err.annotation.type.not.applicable +1 error \ No newline at end of file diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/DotClass.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/DotClass.java new file mode 100644 index 00000000000..9aaa99e7e99 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/DotClass.java @@ -0,0 +1,74 @@ +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.ElementType.TYPE_PARAMETER; +import static java.lang.annotation.ElementType.TYPE_USE; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/* + * Copyright (c) 2009 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. + */ + +/* + * @test + * @summary Class literals are not type uses and cannot be annotated + * @author Werner Dietl + * @compile/fail/ref=DotClass.out -XDrawDiagnostics DotClass.java + */ + +@Target({TYPE_USE, TYPE_PARAMETER, TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@interface A {} + +@interface B { int value(); } + +class T0x1E { + void m0x1E() { + Class c = @A Object.class; + } + + Class c = @A String.class; + + Class as = @A String.class; +} + +class ClassLiterals { + public static void main(String[] args) { + if (String.class != @A String.class) throw new Error(); + if (@A int.class != int.class) throw new Error(); + if (@A int.class != Integer.TYPE) throw new Error(); + if (@A int @B(0) [].class != int[].class) throw new Error(); + + if (String[].class != @A String[].class) throw new Error(); + if (String[].class != String @A [].class) throw new Error(); + if (@A int[].class != int[].class) throw new Error(); + if (@A int @B(0) [].class != int[].class) throw new Error(); + } + + Object classLit1 = @A String @C [] @B(0) [].class; + Object classLit2 = @A String @C [] [].class; + Object classLit3 = @A String [] @B(0) [].class; + Object classLit4 = String [] @B(0) [].class; + Object classLit5 = String @C [] [].class; + Object classLit6 = String [] [].class; +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/DotClass.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/DotClass.out new file mode 100644 index 00000000000..c40f3d7cd74 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/DotClass.out @@ -0,0 +1,17 @@ +DotClass.java:47:42: compiler.err.no.annotations.on.dot.class +DotClass.java:50:33: compiler.err.no.annotations.on.dot.class +DotClass.java:52:52: compiler.err.no.annotations.on.dot.class +DotClass.java:57:44: compiler.err.no.annotations.on.dot.class +DotClass.java:58:26: compiler.err.no.annotations.on.dot.class +DotClass.java:59:26: compiler.err.no.annotations.on.dot.class +DotClass.java:60:35: compiler.err.no.annotations.on.dot.class +DotClass.java:62:48: compiler.err.no.annotations.on.dot.class +DotClass.java:63:49: compiler.err.no.annotations.on.dot.class +DotClass.java:64:28: compiler.err.no.annotations.on.dot.class +DotClass.java:65:35: compiler.err.no.annotations.on.dot.class +DotClass.java:68:54: compiler.err.no.annotations.on.dot.class +DotClass.java:69:54: compiler.err.no.annotations.on.dot.class +DotClass.java:70:54: compiler.err.no.annotations.on.dot.class +DotClass.java:71:54: compiler.err.no.annotations.on.dot.class +DotClass.java:72:54: compiler.err.no.annotations.on.dot.class +16 errors \ No newline at end of file diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/IncompleteArray.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/IncompleteArray.java new file mode 100644 index 00000000000..c414a5f807e --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/IncompleteArray.java @@ -0,0 +1,12 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary test incomplete array declaration + * @author Mahmood Ali + * @compile/fail/ref=IncompleteArray.out -XDrawDiagnostics IncompleteArray.java + */ +class IncompleteArray { + int @A [] @A var; +} + +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/IncompleteArray.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/IncompleteArray.out new file mode 100644 index 00000000000..a03a09283ee --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/IncompleteArray.out @@ -0,0 +1,2 @@ +IncompleteArray.java:9:13: compiler.err.illegal.start.of.type +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/NotTypeParameter.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/NotTypeParameter.java new file mode 100644 index 00000000000..49ba85f344d --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/NotTypeParameter.java @@ -0,0 +1,25 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary test invalid location of TypeUse and TypeParameter + * @author Mahmood Ali + * @compile/fail/ref=NotTypeParameter.out -XDrawDiagnostics NotTypeParameter.java + */ + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +class VoidMethod<@A K> { + @A void test() { } +} + +@Target(ElementType.TYPE_USE) +@interface A { } + +class TypeVariable<@B T> { + @B T test1() { return null; } + void test2(@B T p) {} +} + +@Target(ElementType.TYPE_PARAMETER) +@interface B { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/NotTypeParameter.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/NotTypeParameter.out new file mode 100644 index 00000000000..40e4ebc7068 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/NotTypeParameter.out @@ -0,0 +1,4 @@ +NotTypeParameter.java:13:3: compiler.err.annotation.type.not.applicable +NotTypeParameter.java:20:3: compiler.err.annotation.type.not.applicable +NotTypeParameter.java:21:14: compiler.err.annotation.type.not.applicable +3 errors diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/NotTypeUse.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/NotTypeUse.java new file mode 100644 index 00000000000..6c8bfeee3b6 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/NotTypeUse.java @@ -0,0 +1,17 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary test invalid location of TypeUse + * @author Mahmood Ali + * @compile/fail/ref=NotTypeUse.out -XDrawDiagnostics NotTypeUse.java + */ + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +class VoidMethod { + @A void test() { } +} + +@Target(ElementType.TYPE) +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/NotTypeUse.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/NotTypeUse.out new file mode 100644 index 00000000000..9728d3589ec --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/NotTypeUse.out @@ -0,0 +1,2 @@ +NotTypeUse.java:13:3: compiler.err.annotation.type.not.applicable +1 error diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/VoidMethod.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/VoidMethod.java new file mode 100644 index 00000000000..a82768ce76b --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/VoidMethod.java @@ -0,0 +1,33 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6843077 8006775 + * @summary test invalid location of TypeUse and TypeParameter + * @author Mahmood Ali + * @compile/fail/ref=VoidMethod.out -XDrawDiagnostics VoidMethod.java + */ + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +class VoidMethod { + // Invalid + @A void test1() { } + // The following is legal: + @B void test2() { } + // Invalid + @C void test3() { } + // The following is legal: + @D void test4() { } +} + +@Target(ElementType.TYPE_USE) +@interface A { } + +@Target({ElementType.TYPE_USE, ElementType.METHOD}) +@interface B { } + +@Target(ElementType.TYPE_PARAMETER) +@interface C { } + +@Target({ElementType.TYPE_PARAMETER, ElementType.METHOD}) +@interface D { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/VoidMethod.out b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/VoidMethod.out new file mode 100644 index 00000000000..7cbba4aa163 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/target/VoidMethod.out @@ -0,0 +1,3 @@ +VoidMethod.java:14:3: compiler.err.annotation.type.not.applicable +VoidMethod.java:18:3: compiler.err.annotation.type.not.applicable +2 errors diff --git a/langtools/test/tools/javac/typeAnnotations/newlocations/BasicTest.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/BasicTest.java similarity index 73% rename from langtools/test/tools/javac/typeAnnotations/newlocations/BasicTest.java rename to langtools/test/tools/javac/annotations/typeAnnotations/newlocations/BasicTest.java index a5de45959cb..8c7fb83a3f1 100644 --- a/langtools/test/tools/javac/typeAnnotations/newlocations/BasicTest.java +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/BasicTest.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2013, 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 @@ -24,22 +24,25 @@ /* * @test - * @bug 6843077 + * @bug 6843077 8006775 * @summary random tests for new locations * @author Matt Papi - * @compile/fail/ref=BasicTest.out -XDrawDiagnostics BasicTest.java + * @compile BasicTest.java */ +import java.lang.annotation.*; import java.util.*; import java.io.*; +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface A {} +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface B {} +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface C {} +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface D {} -//308: Test inverted to verify that type annotations can not be parsed yet. - /** * Tests basic JSR 308 parser functionality. We don't really care about what * the parse tree looks like, just that these annotations can be parsed. @@ -48,8 +51,7 @@ class BasicTest extends @B LinkedList implements @C List void test() { - // Handle annotated class literals/cast types - Class c = @A String.class; + // Handle annotated cast types Object o = (@A Object) "foo"; // Handle annotated "new" expressions (except arrays; see ArrayTest) @@ -57,21 +59,23 @@ class BasicTest extends @B LinkedList implements @C List boolean b = o instanceof @A Object; - @A Map<@B List<@C String>, @D String> map = new @A HashMap<@B List<@C String>, @D String>(); - Class c2 = @A String.class; + Class c2 = null; } // Handle receiver annotations // Handle annotations on a qualified identifier list - void test2() @C @D throws @A IllegalArgumentException, @B IOException { + void test2(@C @D BasicTest this) throws @A IllegalArgumentException, @B IOException { } // Handle annotations on a varargs element type - void test3(Object @A... objs) { + void test3(@B Object @A... objs) { } - } + void test4(@B Class<@C ?> @A ... clz) { } + + + // TODO: add more tests... nested classes, etc. } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ClassExtends.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ClassExtends.java new file mode 100644 index 00000000000..24df0774fa4 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ClassExtends.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +import java.lang.annotation.*; + +/* + * @test + * @bug 6843077 8006775 + * @summary new type annotation location: class extends/implements + * @author Mahmood Ali + * @compile ClassExtends.java + */ +abstract class MyClass extends @A ParameterizedClass<@B String> + implements @B CharSequence, @A ParameterizedInterface<@B String> { } + +interface MyInterface extends @A ParameterizedInterface<@A String>, + @B CharSequence { } + +class ParameterizedClass {} +interface ParameterizedInterface {} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A {} +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B {} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ClassParameters.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ClassParameters.java new file mode 100644 index 00000000000..9b2fbbe8045 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ClassParameters.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +import java.lang.annotation.*; + +/* + * @test + * @bug 6843077 8006775 + * @summary new type annotation location: class type parameter bounds + * @author Mahmood Ali + * @compile ClassParameters.java + */ +class Unannotated { } + +class ExtendsBound { } +class ExtendsGeneric> { } +class TwoBounds { } + +class Complex1 { } +class Complex2 { } +class ComplexBoth { } + +class Outer { + void inner() { + class Unannotated { } + + class ExtendsBound { } + class ExtendsGeneric> { } + class TwoBounds { } + + class Complex1 { } + class Complex2 { } + class ComplexBoth { } + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ConstructorTypeArgs.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ConstructorTypeArgs.java new file mode 100644 index 00000000000..6db9804fdee --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ConstructorTypeArgs.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +import java.lang.annotation.*; + +/* + * @test + * @bug 6843077 8006775 + * @summary new type annotation location: constructor type args + * @author Mahmood Ali + * @compile ConstructorTypeArgs.java + */ + +class ConstructorTypeArgs { + void oneArg() { + new @A MyList<@A String>(); + new MyList<@A MyList<@B(0) String>>(); + } + + void twoArg() { + new MyMap(); + new MyMap<@A String, @B(0) MyList<@A String>>(); + } + + void withArraysIn() { + new MyList(); + new MyList<@A String @B(0) [] @A []>(); + + new MyMap<@A String[], @B(0) MyList<@A String> @A []>(); + } +} + +class MyList { } +class MyMap { } + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { int value(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ExceptionParameters.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ExceptionParameters.java new file mode 100644 index 00000000000..81b327c5c04 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ExceptionParameters.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013, 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. + */ + +import java.lang.annotation.*; + +import java.io.*; + +/* + * @test + * @bug 6843077 8006775 + * @summary new type annotation location: exception parameters + * @author Werner Dietl + * @compile ExceptionParameters.java + */ + +class ExceptionParameters { + + void exception() { + try { + foobar(); + } catch (@A Exception e) { + e.toString(); + } + } + + void finalException() { + try { + foobar(); + } catch (final @B Exception e) { + e.toString(); + } + } + + void multiException1() { + try { + foobar(); + } catch (@A NullPointerException | @B IndexOutOfBoundsException e) { + e.toString(); + } + } + + void multiException2() { + try { + foobar(); + } catch (java.lang.@A NullPointerException | java.lang.@B IndexOutOfBoundsException e) { + e.toString(); + } + } + + void foobar() {} +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Expressions.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Expressions.java new file mode 100644 index 00000000000..bd4acc9c895 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Expressions.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +import java.lang.annotation.*; + +/* + * @test + * @bug 6843077 8006775 + * @summary new type annotation location: expressions + * @author Mahmood Ali + * @compile Expressions.java + */ +class Expressions { + void instanceOf() { + Object o = null; + boolean a = o instanceof @A String; + boolean b = o instanceof @B(0) String; + } + + void instanceOfArray() { + Object o = null; + boolean a1 = o instanceof @A String []; + boolean a2 = o instanceof @B(0) String []; + + boolean b1 = o instanceof String @A []; + boolean b2 = o instanceof String @B(0) []; + } + + void objectCreation() { + new @A String(); + new @B(0) String(); + } + + void objectCreationArray() { + Object a1 = new @A String [] [] { }; + Object a2 = new @A String [1] []; + Object a3 = new @A String [1] [2]; + + Object b1 = new @A String @B(0) [] [] { }; + Object b2 = new @A String @B(0) [1] []; + Object b3 = new @A String @B(0) [1] [2]; + + Object c1 = new @A String [] @B(0) [] { }; + Object c2 = new @A String [1] @B(0) []; + Object c3 = new @A String [1] @B(0) [2]; + + Object d1 = new @A String @B(0) [] @B(0) [] { }; + Object d2 = new @A String @B(0) [1] @B(0) []; + Object d3 = new @A String @B(0) [1] @B(0) [2]; + + Object rand = new @A String @B(value = 0) [1] @B(value = 0) [2]; + + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { int value(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Fields.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Fields.java new file mode 100644 index 00000000000..04fb39f021e --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Fields.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +import java.lang.annotation.*; + +/* + * @test + * @bug 6843077 8006775 + * @summary new type annotation location: field type array/generics + * @author Mahmood Ali + * @compile Fields.java + */ + +class DefaultScope { + Parameterized unannotated; + Parameterized<@A String, String> firstTypeArg; + Parameterized secondTypeArg; + Parameterized<@A String, @B String> bothTypeArgs; + + Parameterized<@A Parameterized<@A String, @B String>, @B String> + nestedParameterized; + + @A String [] array1; + @A String @B [] array1Deep; + @A String [] [] array2; + @A String @A [] @B [] array2Deep; + String @A [] [] array2First; + String [] @B [] array2Second; + + // Old-style array syntax + String array2FirstOld @A []; + String array2SecondOld [] @B []; +} + +class ModifiedScoped { + public final Parameterized unannotated = null; + public final Parameterized<@A String, String> firstTypeArg = null; + public final Parameterized secondTypeArg = null; + public final Parameterized<@A String, @B String> bothTypeArgs = null; + + public final Parameterized<@A Parameterized<@A String, @B String>, @B String> + nestedParameterized = null; + + public final @A String [] array1 = null; + public final @A String @B [] array1Deep = null; + public final @A String [] [] array2 = null; + public final @A String @A [] @B [] array2Deep = null; + public final String @A [] [] array2First = null; + public final String [] @B [] array2Second = null; +} + +class Parameterized { } + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/LocalVariables.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/LocalVariables.java new file mode 100644 index 00000000000..9f057f5807a --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/LocalVariables.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +import java.lang.annotation.*; + +/* + * @test + * @bug 6843077 8006775 + * @summary new type annotation location: local variables array/generics + * @author Mahmood Ali + * @compile LocalVariables.java + */ + +class DefaultScope { + void parameterized() { + Parameterized unannotated; + Parameterized<@A String, String> firstTypeArg; + Parameterized secondTypeArg; + Parameterized<@A String, @B String> bothTypeArgs; + + Parameterized<@A Parameterized<@A String, @B String>, @B String> + nestedParameterized; + } + + void arrays() { + @A String [] array1; + @A String @B [] array1Deep; + @A String [] [] array2; + @A String @A [] @B [] array2Deep; + String @A [] [] array2First; + String [] @B [] array2Second; + } +} + +class ModifiedVars { + void parameterized() { + final Parameterized unannotated = null; + final Parameterized<@A String, String> firstTypeArg = null; + final Parameterized secondTypeArg = null; + final Parameterized<@A String, @B String> bothTypeArgs = null; + + final Parameterized<@A Parameterized<@A String, @B String>, @B String> + nestedParameterized = null; + } + + void arrays() { + final @A String [] array1 = null; + final @A String @B [] array1Deep = null; + final @A String [] [] array2 = null; + final @A String @A [] @B [] array2Deep = null; + final String @A [] [] array2First = null; + final String [] @B [] array2Second = null; + } +} + +class Parameterized { } + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MethodReturnType.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MethodReturnType.java new file mode 100644 index 00000000000..1a3b4905155 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MethodReturnType.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +import java.lang.annotation.*; + +/* + * @test + * @bug 6843077 8006775 + * @summary new type annotation location: method return type array/generics + * @author Mahmood Ali + * @compile MethodReturnType.java + */ + +class DefaultScope { + Parameterized unannotated() { return null; } + Parameterized<@A String, String> firstTypeArg() { return null; } + Parameterized secondTypeArg() { return null; } + Parameterized<@A String, @B String> bothTypeArgs() { return null; } + + Parameterized<@A Parameterized<@A String, @B String>, @B String> + nestedParameterized() { return null; } + + public @A String method() { return null; } + + @A String [] array1() { return null; } + @A String @B [] array1Deep() { return null; } + @A String [] [] array2() { return null; } + @A String @A [] @B [] array2Deep() { return null; } + String @A [] [] array2First() { return null; } + String [] @B [] array2Second() { return null; } + + // Old-style array syntax + String array2FirstOld() @A [] { return null; } + String array2SecondOld() [] @B [] { return null; } +} + +class ModifiedScoped { + public final Parameterized unannotated() { return null; } + public final Parameterized<@A String, String> firstTypeArg() { return null; } + public final Parameterized secondTypeArg() { return null; } + public final Parameterized<@A String, @B String> bothTypeArgs() { return null; } + + public final Parameterized<@A Parameterized<@A String, @B String>, @B String> + nestedParameterized() { return null; } + + public final @A String [] array1() { return null; } + public final @A String @B [] array1Deep() { return null; } + public final @A String [] [] array2() { return null; } + public final @A String @A [] @B [] array2Deep() { return null; } + public final String @A [] [] array2First() { return null; } + public final String [] @B [] array2Second() { return null; } +} + +class Parameterized { } + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MethodTypeArgs.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MethodTypeArgs.java new file mode 100644 index 00000000000..1da62766208 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MethodTypeArgs.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +import java.lang.annotation.*; + +/* + * @test + * @bug 6843077 8006775 + * @summary new type annotation location: method type args + * @author Mahmood Ali + * @compile MethodTypeArgs.java + */ + +class MethodTypeArgs { + void oneArg() { + this.<@A String>newList(); + this.<@A MyList<@B(0) String>>newList(); + + MethodTypeArgs.<@A String>newList(); + MethodTypeArgs.<@A MyList<@B(0) String>>newList(); + } + + void twoArg() { + this.newMap(); + this.<@A String, @B(0) MyList<@A String>>newMap(); + + MethodTypeArgs.newMap(); + MethodTypeArgs.<@A String, @B(0) MyList<@A String>>newMap(); + } + + void withArraysIn() { + this.newList(); + this.<@A String @B(0) [] @A []>newList(); + + this.<@A String[], @B(0) MyList<@A String> @A []>newMap(); + } + + static void newList() { } + static void newMap() { } +} + +class MyList { } + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { int value(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MethodTypeParameters.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MethodTypeParameters.java new file mode 100644 index 00000000000..4363af11364 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MethodTypeParameters.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +import java.lang.annotation.*; + +/* + * @test + * @bug 6843077 8006775 + * @summary new type annotation location: method type parameter bounds + * @author Mahmood Ali + * @compile MethodTypeParameters.java + */ + +class UnscopedUnmodified { + void methodExtends() {} + > void nestedExtends() {} + > void dual() {} + > void dualOneAnno() {} +} + +class PublicModifiedMethods { + public final void methodExtends() {} + public final > void nestedExtends() {} + public final > void dual() {} + public final > void dualOneAnno() {} +} + +class Parameterized { } + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MultiCatch.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MultiCatch.java new file mode 100644 index 00000000000..1745e61ae6b --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/MultiCatch.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +import java.lang.annotation.*; + +/* + * @test + * @ignore // syntax not sure yet. + * @bug 8006775 + * @summary new type annotation location: multicatch + * @author Werner Dietl + * @compile MultiCatch.java + */ + +class DefaultScope { + void exception01() { + try { + System.out.println("Hello 1!"); + } catch (@B NullPointerException | @C IllegalArgumentException e) { + e.toString(); + } + } + void exception02() { + try { + System.out.println("Hello 2!"); + } catch @A (@B NullPointerException | @C IllegalArgumentException e) { + e.toString(); + } + } +} + +class ModifiedVars { + /* + void exception() { + try { + arrays(); + } catch (final @A Exception e) { + e.toString(); + } + } + */ +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface C { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface D { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/NestedTypes.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/NestedTypes.java new file mode 100644 index 00000000000..7572b4fefb2 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/NestedTypes.java @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +import java.lang.annotation.*; +import java.util.Map; + +/* + * @test + * @bug 8006775 + * @summary new type annotation location: nested types + * @author Werner Dietl + * @compile NestedTypes.java + */ +class Outer { + class Inner { + class Inner2 { + // m1a-c all have the same parameter type. + void m1a(@A Inner2 p1a) {} + void m1b(Inner.@A Inner2 p1b) {} + void m1c(Outer.Inner.@A Inner2 p1c) {} + // notice the difference to m1d + void m1d(@A Outer.Inner.Inner2 p1d) {} + + // m2a-b both have the same parameter type. + void m2a(@A Inner.Inner2 p2a) {} + void m2b(Outer.@A Inner.Inner2 p2b) {} + + // The location for @A is the same in m3a-c + void m3a(@A Outer p3a) {} + void m3b(@A Outer.Inner p3b) {} + void m3c(@A Outer.Inner.Inner2 p3c) {} + + // Test combinations + void m4a(@A Outer p3a) {} + void m4b(@A Outer. @B Inner p3b) {} + void m4c(@A Outer. @B Inner. @C Inner2 p3c) {} + } + } + + void m4a(@A Map p4a) {} + void m4b(Map.@B Entry p4c) {} + // Illegal: + // void m4b(@A Map.Entry p4b) {} + // void m4c(@A Map.@B Entry p4c) {} + + void m4c(Map.@B Entry p4d) {} + // Illegal: + // void m4d(@A Map.@B Entry p4d) {} + + void m4e(MyList p4e) {} + void m4f(MyList p4f) {} + // Illegal: + // void m4g(MyList<@A Map.Entry> p4e) {} + // void m4h(MyList<@A Map.@B Entry> p4f) {} + + class GInner { + class GInner2 {} + } + + static class Static {} + static class GStatic { + static class GStatic2 {} + } +} + +class Test1 { + // Outer.GStatic.GStatic2 gs; + Outer.GStatic.@A GStatic2 gsgood; + // TODO: add failing test + // Outer.@A GStatic.GStatic2 gsbad; + + MyList<@A Outer . @B Inner. @C Inner2> f; + @A Outer .GInner.GInner2 g; + + // TODO: Make sure that something like this fails gracefully: + // MyList pkg; + + @A Outer f1; + @A Outer . @B Inner f2 = f1.new @B Inner(); + // TODO: ensure type annos on new are stored. + @A Outer . @B GInner<@C Object> f3 = f1.new @B GInner<@C Object>(); + + MyList<@A Outer . @B GInner<@C MyList<@D Object>>. @E GInner2<@F Integer, @G Object>> f4; + // MyList.GInner2> f4clean; + + @A Outer . @B GInner<@C MyList<@D Object>>. @E GInner2<@F Integer, @G Object> f4top; + + MyList<@A Outer . @B GInner<@C MyList<@D Object @E[] @F[]>>. @G GInner2<@H Integer, @I Object> @J[] @K[]> f4arr; + + @A Outer . @B GInner<@C MyList<@D Object @E[] @F[]>>. @G GInner2<@H Integer, @I Object> @J[] @K[] f4arrtop; + + MyList f5; + // Illegal: + // MyList<@A Outer . @B Static> f5; + + Outer . @B Static f6; + // Illegal: + // @A Outer . @B Static f6; + + Outer . @Bv("B") GStatic<@Cv("C") String, @Dv("D") Object> f7; + // Illegal: + // @Av("A") Outer . @Bv("B") GStatic<@Cv("C") String, @Dv("D") Object> f7; + + Outer . @Cv("Data") Static f8; + // Illegal: + // @A Outer . @Cv("Data") Static f8; + + MyList f9; + // Illegal: + // MyList<@A Outer . @Cv("Data") Static> f9; +} + +class Test2 { + void m() { + @A Outer f1 = null; + @A Outer.@B Inner f2 = null; + Outer.@B Static f3 = null; + // Illegal: + // @A Outer.@B Static f3 = null; + @A Outer.@C Inner f4 = null; + + Outer . @B Static f5 = null; + Outer . @Cv("Data") Static f6 = null; + MyList f7 = null; + } +} + +class Test3 { + void monster(@A Outer p1, + @A Outer.@B Inner p2, + Outer.@B Static p3, + @A Outer.@Cv("Test") Inner p4, + Outer . @B Static p5, + Outer . @Cv("Data") Static p6, + MyList p7) { + } +} + +class Test4 { + void m() { + @A Outer p1 = new @A Outer(); + @A Outer.@B Inner p2 = p1.new @B Inner(); + // Illegal: + // @A Outer.@B Static p3 = new @A Outer.@B Static(); + // Object o3 = new @A Outer.@B Static(); + + @A Outer.@Cv("Test") Inner p4 = p1.new @Cv("Test") Inner(); + Outer . @B Static p5 = new Outer . @B Static(); + Outer . @Cv("Data") Static p6 = new Outer . @Cv("Data") Static(); + MyList p7 = new MyList(); + } +} + +class MyList { } + + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface C { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface D { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface E { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface F { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface G { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface H { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface I { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface J { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface K { } + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface Av { String value(); } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface Bv { String value(); } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface Cv { String value(); } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface Dv { String value(); } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface Ev { String value(); } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface Fv { String value(); } + diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Parameters.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Parameters.java new file mode 100644 index 00000000000..4952986d347 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Parameters.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +import java.lang.annotation.*; + +/* + * @test + * @bug 6843077 8006775 + * @summary new type annotation location: parameter type array/generics + * @author Mahmood Ali + * @compile Parameters.java + */ + +class Parameters { + void unannotated(Parameterized a) {} + void firstTypeArg(Parameterized<@A String, String> a) {} + void secondTypeArg(Parameterized a) {} + void bothTypeArgs(Parameterized<@A String, @B String> both) {} + + void nestedParameterized(Parameterized<@A Parameterized<@A String, @B String>, @B String> a) {} + + void array1(@A String [] a) {} + void array1Deep(@A String @B [] a) {} + void array2(@A String [] [] a) {} + void array2Deep(@A String @A [] @B [] a) {} + void array2First(String @A [] [] a) {} + void array2Second(String [] @B [] a) {} +} + +class Parameterized { } + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Receivers.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Receivers.java new file mode 100644 index 00000000000..95103ff1670 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Receivers.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +import java.lang.annotation.*; + +/* + * @test + * @bug 6843077 8006775 + * @summary new type annotation location: receivers + * @author Mahmood Ali, Werner Dietl + * @compile Receivers.java + */ +class DefaultUnmodified { + void plain(@A DefaultUnmodified this) { } + void generic(@A DefaultUnmodified this) { } + void withException(@A DefaultUnmodified this) throws Exception { } + String nonVoid(@A DefaultUnmodified this) { return null; } + void accept(@A DefaultUnmodified this, T r) throws Exception { } +} + +class PublicModified { + public final void plain(@A PublicModified this) { } + public final void generic(@A PublicModified this) { } + public final void withException(@A PublicModified this) throws Exception { } + public final String nonVoid(@A PublicModified this) { return null; } + public final void accept(@A PublicModified this, T r) throws Exception { } +} + +class WithValue { + void plain(@B("m") WithValue this) { } + void generic(@B("m") WithValue this) { } + void withException(@B("m") WithValue this) throws Exception { } + String nonVoid(@B("m") WithValue this) { return null; } + void accept(@B("m") WithValue this, T r) throws Exception { } +} + +class WithFinal { + void plain(final @B("m") WithFinal this) { } + void generic(final @B("m") WithFinal this) { } + void withException(final @B("m") WithFinal this) throws Exception { } + String nonVoid(final @B("m") WithFinal this) { return null; } + void accept(final @B("m") WithFinal this, T r) throws Exception { } +} + +class WithBody { + Object f; + + void field(@A WithBody this) { + this.f = null; + } + void meth(@A WithBody this) { + this.toString(); + } +} + +class Generic1 { + void test1(Generic1 this) {} + void test2(@A Generic1 this) {} + void test3(Generic1<@A X> this) {} + void test4(@A Generic1<@A X> this) {} +} + +class Generic2<@A X> { + void test1(Generic2 this) {} + void test2(@A Generic2 this) {} + void test3(Generic2<@A X> this) {} + void test4(@A Generic2<@A X> this) {} +} + +class Generic3 { + void test1(Generic3 this) {} + void test2(@A Generic3 this) {} + void test3(Generic3<@A X> this) {} + void test4(@A Generic3<@A X> this) {} +} + +class Generic4 { + void test1(Generic4 this) {} + void test2(@A Generic4 this) {} + void test3(Generic4<@A X> this) {} + void test4(@A Generic4<@A X> this) {} +} + +class Outer { + class Inner { + void none(Outer.Inner this) {} + void outer(@A Outer.Inner this) {} + void inner(Outer. @B("i") Inner this) {} + void both(@A Outer.@B("i") Inner this) {} + + void innerOnlyNone(Inner this) {} + void innerOnly(@A Inner this) {} + } +} + +class GenericOuter { + class GenericInner { + void none(GenericOuter.GenericInner this) {} + void outer(@A GenericOuter.GenericInner this) {} + void inner(GenericOuter. @B("i") GenericInner this) {} + void both(@A GenericOuter.@B("i") GenericInner this) {} + + void innerOnlyNone(GenericInner this) {} + void innerOnly(@A GenericInner this) {} + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A {} +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { String value(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/RepeatingTypeAnnotations.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/RepeatingTypeAnnotations.java new file mode 100644 index 00000000000..db227cb56f6 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/RepeatingTypeAnnotations.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2012, 2013, 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. + */ + +import java.lang.annotation.*; + +/* + * @test + * @bug 8006775 + * @summary repeating type annotations are possible + * @author Werner Dietl + * @compile/fail/ref=RepeatingTypeAnnotations.out -XDrawDiagnostics RepeatingTypeAnnotations.java + */ + +class RepeatingTypeAnnotations { + // Fields + @RTA @RTA Object fr1 = null; + Object fr2 = new @RTA @RTA Object(); + // error + Object fs = new @TA @TA Object(); + // error + Object ft = new @TA @TA Object(); + Object fe = new @TA @TA Object(); + + // Local variables + Object foo() { + Object o = new @RTA @RTA Object(); + o = new @TA @RTA @RTA Object(); + o = new @RTA @TA @RTA Object(); + // error + o = new @RTA @TA @RTA @TA Object(); + // error + return new @TA @TA Object(); + } + + // Instance creation + Object bar() { + Object o = new @RTA @RTA MyList<@RTA @RTA Object>(); + o = new @TA @RTA MyList<@TA @RTA Object>(); + o = new @TA @RTA @RTA MyList<@RTA @TA @RTA Object>(); + // error + o = new @TA @TA MyList<@RTA @RTA Object>(); + // error + o = new @RTA @RTA MyList<@TA @TA Object>(); + // error + return new @TA @TA MyList<@RTA @RTA Object>(); + } + + // More tests + void oneArg() { + Object o = new @RTA @RTA Object(); + // error + o = new @TA @TA Object(); + o = new @RTA @TA @RTA Object(); + + o = new MyList<@RTA @RTA Object>(); + // error + o = new MyList<@TA @TA Object>(); + // error + o = new @TA @TA MyList<@TA @TA Object>(); + // error + this.<@TA @TA String>newList(); + + this.<@RTA @RTA MyList<@RTA @RTA String>>newList(); + // error + this.<@TA @TA MyList<@TA @TA String>>newList(); + + o = (@RTA @RTA MyList<@RTA @RTA Object>) o; + // error + o = (@TA @TA MyList<@TA @TA Object>) o; + + this.<@RTA @RTA String, @RTA @RTA Object>newMap(); + // error + this.<@TA @TA String, @TA @TA Object>newMap(); + + this.<@RTA @RTA String @RTA @RTA []>newList(); + // error + this.<@TA @TA String @TA @TA []>newList(); + + this.<@RTA @RTA String @RTA @RTA [] @RTA @RTA [], MyList<@RTA @RTA String> @RTA @RTA []>newMap(); + // error + this. @TA @TA []>newMap(); + } + + static void newList() { } + static void newMap() { } +} + +class MyList { } + + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TA { } + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TAs { + TA[] value(); +} + +@Repeatable(RTAs.class) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface RTA { } + +@ContainerFor(RTA.class) +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface RTAs { + RTA[] value(); +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/RepeatingTypeAnnotations.out b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/RepeatingTypeAnnotations.out new file mode 100644 index 00000000000..4866c6ef697 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/RepeatingTypeAnnotations.out @@ -0,0 +1,53 @@ +RepeatingTypeAnnotations.java:39:21: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:39:25: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:41:21: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:41:25: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:42:21: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:42:25: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:50:22: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:50:31: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:52:20: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:52:24: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:61:17: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:61:21: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:63:34: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:63:38: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:65:20: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:65:24: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:72:17: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:72:21: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:77:24: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:77:28: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:79:17: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:79:21: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:79:32: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:79:36: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:81:15: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:81:19: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:85:15: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:85:19: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:85:30: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:85:34: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:89:14: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:89:18: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:89:29: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:89:33: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:93:15: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:93:19: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:93:31: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:93:35: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:97:30: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:97:34: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:97:15: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:97:19: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:101:22: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:101:26: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:101:33: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:101:37: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:101:68: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:101:72: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:101:52: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +RepeatingTypeAnnotations.java:101:56: compiler.err.duplicate.annotation.missing.container: TA, java.lang.annotation.Repeatable +- compiler.note.unchecked.filename: RepeatingTypeAnnotations.java +- compiler.note.unchecked.recompile +50 errors \ No newline at end of file diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ResourceVariables.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ResourceVariables.java new file mode 100644 index 00000000000..7482e043f51 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/ResourceVariables.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2013, 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. + */ + +import java.lang.annotation.*; + +import java.io.*; + +/* + * @test + * @bug 6843077 8006775 + * @summary new type annotation location: resource variables + * @author Werner Dietl + * @compile ResourceVariables.java + */ + +class ResourceVariables { + void m() throws Exception { + try (@A InputStream is = new @B FileInputStream("xxx")) { + } + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Throws.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Throws.java new file mode 100644 index 00000000000..147325a0214 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Throws.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +import java.lang.annotation.*; + +/* + * @test + * @bug 6843077 8006775 + * @summary new type annotation location: throw clauses + * @author Mahmood Ali + * @compile Throws.java + */ +class DefaultUnmodified { + void oneException() throws @A Exception {} + void twoExceptions() throws @A RuntimeException, @A Exception {} +} + +class PublicModified { + public final void oneException(String a) throws @A Exception {} + public final void twoExceptions(String a) throws @A RuntimeException, @A Exception {} +} + +class WithValue { + void oneException() throws @B("m") Exception {} + void twoExceptions() throws @B(value="m") RuntimeException, @A Exception {} +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A {} +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { String value(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/TopLevelBlocks.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/TopLevelBlocks.java new file mode 100644 index 00000000000..ee2a6710ca6 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/TopLevelBlocks.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2012, 2013, 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. + */ + +import java.lang.annotation.*; +import java.util.Map; + +/* + * @test + * @bug 8006775 + * @summary type annotation location: top level blocks + * @author Werner Dietl + * @compile TopLevelBlocks.java + */ + +class TopLevelBlocks { + static Object f; + + { + f = new @A Object(); + } + + static final Object sf; + + static { + sf = new @A Object(); + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/TypeCasts.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/TypeCasts.java new file mode 100644 index 00000000000..c7508e25451 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/TypeCasts.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +import java.lang.annotation.*; + +/* + * @test + * @bug 6843077 8006775 + * @summary new type annotation location: type casts + * @author Mahmood Ali + * @compile TypeCasts.java + */ +class TypeCasts { + void methodA() { + String s = (@A String) null; + Object o = (@A Class<@A String>) null; + } + + void methodB() { + String s = (@B("m") String) null; + Object o = (@B("m") Class<@B("m") String>) null; + } +} + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { String value(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/TypeParameters.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/TypeParameters.java new file mode 100644 index 00000000000..1e93ba54639 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/TypeParameters.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +import java.lang.annotation.*; + +/* + * @test + * @bug 6843077 8006775 + * @summary new type annotation location: class and method type parameters + * @author Mahmood Ali + * @compile TypeParameters.java + */ + +class Unannotated { } +class OneAnnotated<@A K> { } +class TwoAnnotated<@A K, @A V> { } +class SecondAnnotated { } + +class TestMethods { + void unannotated() { } + <@A K> void oneAnnotated() { } + <@A K, @B("m") V> void twoAnnotated() { } + void secondAnnotated() { } +} + +class UnannotatedB { } +class OneAnnotatedB<@B("m") K> { } +class TwoAnnotatedB<@B("m") K, @B("m") V> { } +class SecondAnnotatedB { } + +class OneAnnotatedC<@C K> { } +class TwoAnnotatedC<@C K, @C V> { } +class SecondAnnotatedC { } + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { String value(); } +@Target(ElementType.TYPE_USE) +@interface C { } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Varargs.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Varargs.java new file mode 100644 index 00000000000..d28c108a6c6 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Varargs.java @@ -0,0 +1,46 @@ + +/* + * Copyright (c) 2008 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. + */ + +import java.lang.annotation.*; + +/* + * @test + * @summary test acceptance of varargs annotations + * @author Mahmood Ali + * @compile Varargs.java + */ + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A {} + +class Varargs { + + // Handle annotations on a varargs element type + void varargPlain(Object @A... objs) { + + } + + void varargGeneric(Class @A ... clz) { + } +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Wildcards.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Wildcards.java new file mode 100644 index 00000000000..38de895a767 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/Wildcards.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +import java.lang.annotation.*; + +/* + * @test + * @bug 6843077 8006775 + * @summary new type annotation location: wildcard bound + * @author Mahmood Ali + * @compile Wildcards.java + */ +class BoundTest { + void wcExtends(MyList l) { } + void wcSuper(MyList l) { } + + MyList returnWcExtends() { return null; } + MyList returnWcSuper() { return null; } + MyList> complex() { return null; } +} + +class BoundWithValue { + void wcExtends(MyList l) { } + void wcSuper(MyList l) { } + + MyList returnWcExtends() { return null; } + MyList returnWcSuper() { return null; } + MyList> complex() { return null; } +} + +class SelfTest { + void wcExtends(MyList<@A ?> l) { } + void wcSuper(MyList<@A ?> l) { } + + MyList<@A ?> returnWcExtends() { return null; } + MyList<@A ?> returnWcSuper() { return null; } + MyList<@A ? extends @A MyList<@B("m") ?>> complex() { return null; } +} + +class SelfWithValue { + void wcExtends(MyList<@B("m") ?> l) { } + void wcSuper(MyList<@B(value="m") ?> l) { } + + MyList<@B("m") ?> returnWcExtends() { return null; } + MyList<@B(value="m") ?> returnWcSuper() { return null; } + MyList<@B("m") ? extends MyList<@B("m") ? super String>> complex() { return null; } +} + +class MyList { } + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface A { } +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface B { String value(); } diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/packageanno/PackageProcessor.java b/langtools/test/tools/javac/annotations/typeAnnotations/packageanno/PackageProcessor.java new file mode 100644 index 00000000000..4f0d56522f9 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/packageanno/PackageProcessor.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2009 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. + */ +import java.util.HashSet; +import java.util.Set; + +import javax.annotation.processing.*; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.*; +import javax.lang.model.util.ElementFilter; + +import com.sun.source.util.JavacTask; +import com.sun.source.util.TaskEvent; +import com.sun.source.util.TaskListener; +import com.sun.source.util.TreePath; +import com.sun.tools.javac.main.JavaCompiler; +import com.sun.tools.javac.main.JavaCompiler.CompileState; +import com.sun.tools.javac.processing.JavacProcessingEnvironment; +import com.sun.tools.javac.util.Context; + +/* + * @test + * @summary test that package annotations are available to type processors. + * This class implements the functionality of a type processor, as previously + * embodied by the AbstractTypeProcessor class. + * + * @author Mahmood Ali + * @author Werner Dietl + * + * @compile PackageProcessor.java + * @compile -cp . -processor PackageProcessor mypackage/Anno.java mypackage/MyClass.java mypackage/package-info.java + */ + +@SupportedAnnotationTypes("*") +public class PackageProcessor extends AbstractProcessor { + + private final AttributionTaskListener listener = new AttributionTaskListener(); + private final Set elements = new HashSet(); + + @Override + public final void init(ProcessingEnvironment env) { + super.init(env); + JavacTask.instance(env).addTaskListener(listener); + Context ctx = ((JavacProcessingEnvironment)processingEnv).getContext(); + JavaCompiler compiler = JavaCompiler.instance(ctx); + compiler.shouldStopPolicyIfNoError = CompileState.max(compiler.shouldStopPolicyIfNoError, + CompileState.FLOW); + } + + @Override + public final boolean process(Set annotations, + RoundEnvironment roundEnv) { + for (TypeElement elem : ElementFilter.typesIn(roundEnv.getRootElements())) { + elements.add(elem.getQualifiedName()); + } + return false; + } + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + private final class AttributionTaskListener implements TaskListener { + @Override + public void started(TaskEvent e) { } + + @Override + public void finished(TaskEvent e) { + if (e.getKind() != TaskEvent.Kind.ANALYZE) + return; + + if (!elements.remove(e.getTypeElement().getQualifiedName())) + return; + + if (e.getTypeElement().getSimpleName().contentEquals("MyClass")) { + Element owner = e.getTypeElement().getEnclosingElement(); + if (owner.getKind() != ElementKind.PACKAGE) + throw new RuntimeException("class owner should be a package: " + owner); + if (owner.getAnnotationMirrors().size() != 1) + throw new RuntimeException("the owner package should have one annotation: " + owner); + } + } + } + +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/packageanno/mypackage/Anno.java b/langtools/test/tools/javac/annotations/typeAnnotations/packageanno/mypackage/Anno.java new file mode 100644 index 00000000000..25f05341fbc --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/packageanno/mypackage/Anno.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2009 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. + */ +package mypackage; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Retention; + +@Retention(RetentionPolicy.RUNTIME) +public @interface Anno {} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/packageanno/mypackage/MyClass.java b/langtools/test/tools/javac/annotations/typeAnnotations/packageanno/mypackage/MyClass.java new file mode 100644 index 00000000000..e955ffc825e --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/packageanno/mypackage/MyClass.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2009 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. + */ +package mypackage; + +public class MyClass {} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/packageanno/mypackage/package-info.java b/langtools/test/tools/javac/annotations/typeAnnotations/packageanno/mypackage/package-info.java new file mode 100644 index 00000000000..f80bd8afa53 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/packageanno/mypackage/package-info.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2009 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. + */ + +@mypackage.Anno +package mypackage; diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ClassExtends.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ClassExtends.java new file mode 100644 index 00000000000..5fd9751879a --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ClassExtends.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2009 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. + */ + +import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; + +/* + * @test + * @summary Test population of reference info for class extends clauses + * @compile -g Driver.java ReferenceInfoUtil.java ClassExtends.java + * @run main Driver ClassExtends + */ +public class ClassExtends { + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_EXTENDS, typeIndex = -1), + @TADescription(annotation = "TB", type = CLASS_EXTENDS, typeIndex = 1) + }) + public String regularClass() { + return "class Test extends @TA Object implements Cloneable, @TB Runnable {" + + " public void run() { } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_EXTENDS, typeIndex = -1, + genericLocation = { 3, 0 }), + @TADescription(annotation = "TB", type = CLASS_EXTENDS, typeIndex = 1, + genericLocation = { 3, 1 }) + }) + public String regularClassExtendsParametrized() { + return "class Test extends HashMap<@TA String, String> implements Cloneable, Map{ } "; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_EXTENDS, typeIndex = -1), + @TADescription(annotation = "TB", type = CLASS_EXTENDS, typeIndex = 1) + }) + public String abstractClass() { + return "abstract class Test extends @TA Date implements Cloneable, @TB Runnable {" + + " public void run() { } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_EXTENDS, typeIndex = -1, + genericLocation = { 3, 0 }), + @TADescription(annotation = "TB", type = CLASS_EXTENDS, typeIndex = 1, + genericLocation = { 3, 1 }) + }) + public String abstractClassExtendsParametrized() { + return "abstract class Test extends HashMap<@TA String, String> implements Cloneable, Map{ } "; + } + + @TADescription(annotation = "TB", type = CLASS_EXTENDS, typeIndex = 1) + public String regularInterface() { + return "interface Test extends Cloneable, @TB Runnable { }"; + } + + @TADescription(annotation = "TB", type = CLASS_EXTENDS, typeIndex = 1, + genericLocation = { 3, 1 }) + public String regularInterfaceExtendsParametrized() { + return "interface Test extends Cloneable, Map{ } "; + } + + @TADescription(annotation = "TB", type = CLASS_EXTENDS, typeIndex = 1) + public String regularEnum() { + return "enum Test implements Cloneable, @TB Runnable { TEST; public void run() { } }"; + } + + @TADescription(annotation = "TB", type = CLASS_EXTENDS, typeIndex = 1, + genericLocation = { 3, 0 }) + public String regularEnumExtendsParametrized() { + return + "enum Test implements Cloneable, Comparator<@TB String> { TEST; " + + "public int compare(String a, String b) { return 0; }}"; + } + +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ClassTypeParam.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ClassTypeParam.java new file mode 100644 index 00000000000..0d82706984f --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ClassTypeParam.java @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2009 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. + */ + +import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; + +/* + * @test + * @summary Test population of reference info for class type parameters + * @compile -g Driver.java ReferenceInfoUtil.java ClassTypeParam.java + * @run main Driver ClassTypeParam + */ +public class ClassTypeParam { + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_TYPE_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TC", type = CLASS_TYPE_PARAMETER, paramIndex = 1), + @TADescription(annotation = "TD", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 0), + @TADescription(annotation = "TE", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1) + }) + public String regularClass() { + return "class Test<@TA K extends @TB Date, @TC V extends @TD Object & @TE Cloneable> { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_TYPE_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TC", type = CLASS_TYPE_PARAMETER, paramIndex = 1), + @TADescription(annotation = "TE", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1) + }) + public String regularClass2() { + return "class Test<@TA K extends @TB Date, @TC V extends @TE Cloneable> { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1, genericLocation = {3, 1}), + @TADescription(annotation = "TC", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1), + @TADescription(annotation = "TD", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0}), + @TADescription(annotation = "TE", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0, 3, 0}) + }) + public String regularClassParameterized() { + return "class Test, V extends @TC List<@TD List<@TE Object>>> { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1, genericLocation = {3, 1}), + @TADescription(annotation = "TC", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1), + @TADescription(annotation = "TD", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0}), + @TADescription(annotation = "TE", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0, 3, 0}), + @TADescription(annotation = "TF", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 0), + @TADescription(annotation = "TG", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0) + }) + public String regularClassParameterized2() { + return "class Test, V extends @TF Object & @TC List<@TD List<@TE Object>>> { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_TYPE_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TC", type = CLASS_TYPE_PARAMETER, paramIndex = 1), + @TADescription(annotation = "TD", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 0), + @TADescription(annotation = "TE", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1) + }) + public String abstractClass() { + return "abstract class Test<@TA K extends @TB Date, @TC V extends @TD Object & @TE Cloneable> { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1, genericLocation = {3, 1}), + @TADescription(annotation = "TC", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1), + @TADescription(annotation = "TD", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0}), + @TADescription(annotation = "TE", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0, 3, 0}), + @TADescription(annotation = "TF", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 0) + }) + public String abstractClassParameterized() { + return "abstract class Test, V extends @TF Object & @TC List<@TD List<@TE Object>>> { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_TYPE_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TC", type = CLASS_TYPE_PARAMETER, paramIndex = 1), + @TADescription(annotation = "TD", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 0), + @TADescription(annotation = "TE", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1) + }) + public String regularInterface() { + return "interface Test<@TA K extends @TB Date, @TC V extends @TD Object & @TE Cloneable> { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1, genericLocation = {3, 1}), + @TADescription(annotation = "TC", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1), + @TADescription(annotation = "TD", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0}), + @TADescription(annotation = "TE", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0, 3, 0}) + }) + public String regularInterfaceParameterized() { + return "interface Test, V extends @TC List<@TD List<@TE Object>>> { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1, genericLocation = {3, 1}), + @TADescription(annotation = "TC", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1), + @TADescription(annotation = "TD", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0}), + @TADescription(annotation = "TE", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0, 3, 0}), + @TADescription(annotation = "TF", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 0), + @TADescription(annotation = "TG", type = CLASS_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0) + }) + public String regularInterfaceParameterized2() { + return "interface Test, V extends @TF Object & @TC List<@TD List<@TE Object>>> { }"; + } + + @TADescription(annotation = "TA", type = METHOD_RETURN) + public String useInReturn1() { + return "class Test { @TA T m() { throw new RuntimeException(); } }"; + } + + @TADescription(annotation = "TA", type = METHOD_RETURN, genericLocation = {3, 0}) + public String useInReturn2() { + return "class Test { Class<@TA T> m() { throw new RuntimeException(); } }"; + } + + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + paramIndex = 0, genericLocation = {3, 0}) + public String useInParam1() { + return "class Test { void m(Class<@TA T> p) { throw new RuntimeException(); } }"; + } + + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + paramIndex = 0, genericLocation = {3, 0}) + public String useInParam2() { + return "class Test { void m(Class<@TA Object> p) { throw new RuntimeException(); } }"; + } +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java new file mode 100644 index 00000000000..2ad8b31badc --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java @@ -0,0 +1,73 @@ +/* + * 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. + */ + +import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; + +/* + * @test + * @summary Test population of reference info for constructor results + * @compile -g Driver.java ReferenceInfoUtil.java Constructors.java + * @run main Driver Constructors + */ +public class Constructors { + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN), + @TADescription(annotation = "TB", type = METHOD_RETURN), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, paramIndex = 0) + }) + public String regularClass() { + return "class Test { @TA Test() {}" + + " @TB Test(@TC int b) {} }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN), + @TADescription(annotation = "TB", type = METHOD_RETURN), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, paramIndex = 0) + }) + @TestClass("Test$Inner") + public String innerClass() { + return "class Test { class Inner {" + + " @TA Inner() {}" + + " @TB Inner(@TC int b) {}" + + " } }"; + } + + /* TODO: Outer.this annotation support. + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RECEIVER), + @TADescription(annotation = "TB", type = METHOD_RETURN), + @TADescription(annotation = "TC", type = METHOD_RECEIVER), + @TADescription(annotation = "TD", type = METHOD_RETURN), + @TADescription(annotation = "TE", type = METHOD_FORMAL_PARAMETER, paramIndex = 0) + }) + @TestClass("Test$Inner") + public String innerClass2() { + return "class Test { class Inner {" + + " @TB Inner(@TA Test Test.this) {}" + + " @TD Inner(@TC Test Test.this, @TE int b) {}" + + " } }"; + } + */ +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Driver.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Driver.java new file mode 100644 index 00000000000..5986fa95de8 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Driver.java @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2009 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. + */ + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.lang.annotation.*; +import java.lang.reflect.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.TypeAnnotation; +import com.sun.tools.classfile.TypeAnnotation.TargetType; + +public class Driver { + + private static final PrintStream out = System.out; + + public static void main(String[] args) throws Exception { + if (args.length == 0 || args.length > 1) + throw new IllegalArgumentException("Usage: java Driver "); + String name = args[0]; + Class clazz = Class.forName(name); + new Driver().runDriver(clazz.newInstance()); + } + + protected void runDriver(Object object) throws Exception { + int passed = 0, failed = 0; + Class clazz = object.getClass(); + out.println("Tests for " + clazz.getName()); + + // Find methods + for (Method method : clazz.getMethods()) { + Map expected = expectedOf(method); + if (expected == null) + continue; + if (method.getReturnType() != String.class) + throw new IllegalArgumentException("Test method needs to return a string: " + method); + String testClass = testClassOf(method); + + try { + String compact = (String)method.invoke(object); + String fullFile = wrap(compact); + ClassFile cf = compileAndReturn(fullFile, testClass); + List actual = ReferenceInfoUtil.extendedAnnotationsOf(cf); + ReferenceInfoUtil.compare(expected, actual, cf); + out.println("PASSED: " + method.getName()); + ++passed; + } catch (Throwable e) { + out.println("FAILED: " + method.getName()); + out.println(" " + e.toString()); + ++failed; + } + } + + out.println(); + int total = passed + failed; + out.println(total + " total tests: " + passed + " PASSED, " + failed + " FAILED"); + + out.flush(); + + if (failed != 0) + throw new RuntimeException(failed + " tests failed"); + } + + private Map expectedOf(Method m) { + TADescription ta = m.getAnnotation(TADescription.class); + TADescriptions tas = m.getAnnotation(TADescriptions.class); + + if (ta == null && tas == null) + return null; + + Map result = + new HashMap(); + + if (ta != null) + result.putAll(expectedOf(ta)); + + if (tas != null) { + for (TADescription a : tas.value()) { + result.putAll(expectedOf(a)); + } + } + + return result; + } + + private Map expectedOf(TADescription d) { + String annoName = d.annotation(); + + TypeAnnotation.Position p = new TypeAnnotation.Position(); + p.type = d.type(); + if (d.offset() != NOT_SET) + p.offset = d.offset(); + if (d.lvarOffset().length != 0) + p.lvarOffset = d.lvarOffset(); + if (d.lvarLength().length != 0) + p.lvarLength = d.lvarLength(); + if (d.lvarIndex().length != 0) + p.lvarIndex = d.lvarIndex(); + if (d.boundIndex() != NOT_SET) + p.bound_index = d.boundIndex(); + if (d.paramIndex() != NOT_SET) + p.parameter_index = d.paramIndex(); + if (d.typeIndex() != NOT_SET) + p.type_index = d.typeIndex(); + if (d.exceptionIndex() != NOT_SET) + p.exception_index = d.exceptionIndex(); + if (d.genericLocation().length != 0) { + p.location = TypeAnnotation.Position.getTypePathFromBinary(wrapIntArray(d.genericLocation())); + } + + return Collections.singletonMap(annoName, p); + } + + private List wrapIntArray(int[] ints) { + List list = new ArrayList(ints.length); + for (int i : ints) + list.add(i); + return list; + } + + private String testClassOf(Method m) { + TestClass tc = m.getAnnotation(TestClass.class); + if (tc != null) { + return tc.value(); + } else { + return "Test"; + } + } + + private ClassFile compileAndReturn(String fullFile, String testClass) throws Exception { + File source = writeTestFile(fullFile); + File clazzFile = compileTestFile(source, testClass); + return ClassFile.read(clazzFile); + } + + protected File writeTestFile(String fullFile) throws IOException { + File f = new File("Test.java"); + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); + out.println(fullFile); + out.close(); + return f; + } + + protected File compileTestFile(File f, String testClass) { + int rc = com.sun.tools.javac.Main.compile(new String[] { "-source", "1.8", "-g", f.getPath() }); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + String path; + if (f.getParent() != null) { + path = f.getParent(); + } else { + path = ""; + } + + return new File(path + testClass + ".class"); + } + + private String wrap(String compact) { + StringBuilder sb = new StringBuilder(); + + // Automatically import java.util + sb.append("\nimport java.util.*;"); + sb.append("\nimport java.lang.annotation.*;"); + + sb.append("\n\n"); + boolean isSnippet = !(compact.startsWith("class") + || compact.contains(" class")) + && !compact.contains("interface") + && !compact.contains("enum"); + if (isSnippet) + sb.append("class Test {\n"); + + sb.append(compact); + sb.append("\n"); + + if (isSnippet) + sb.append("}\n\n"); + + if (isSnippet) { + // Have a few common nested types for testing + sb.append("class Outer { class Inner {} }"); + sb.append("class SOuter { static class SInner {} }"); + sb.append("class GOuter { class GInner {} }"); + } + + // create A ... F annotation declarations + sb.append("\n@interface A {}"); + sb.append("\n@interface B {}"); + sb.append("\n@interface C {}"); + sb.append("\n@interface D {}"); + sb.append("\n@interface E {}"); + sb.append("\n@interface F {}"); + + // create TA ... TF proper type annotations + sb.append("\n"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA {}"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TB {}"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TC {}"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TD {}"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TE {}"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TF {}"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TG {}"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TH {}"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TI {}"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TJ {}"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TK {}"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TL {}"); + sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TM {}"); + + // create RTA, RTAs, RTB, RTBs for repeating type annotations + sb.append("\n"); + sb.append("\n@Repeatable(RTAs.class) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTA {}"); + sb.append("\n@Repeatable(RTBs.class) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTB {}"); + + sb.append("\n@ContainerFor(RTA.class) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTAs { RTA[] value(); }"); + sb.append("\n@ContainerFor(RTB.class) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTBs { RTB[] value(); }"); + + sb.append("\n@Target(value={ElementType.TYPE,ElementType.FIELD,ElementType.METHOD,ElementType.PARAMETER,ElementType.CONSTRUCTOR,ElementType.LOCAL_VARIABLE})"); + sb.append("\n@interface Decl {}"); + + return sb.toString(); + } + + public static final int NOT_SET = -888; + +} + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@interface TADescription { + String annotation(); + + TargetType type(); + int offset() default Driver.NOT_SET; + int[] lvarOffset() default { }; + int[] lvarLength() default { }; + int[] lvarIndex() default { }; + int boundIndex() default Driver.NOT_SET; + int paramIndex() default Driver.NOT_SET; + int typeIndex() default Driver.NOT_SET; + int exceptionIndex() default Driver.NOT_SET; + + int[] genericLocation() default {}; +} + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@interface TADescriptions { + TADescription[] value() default {}; +} + +/** + * The name of the class that should be analyzed. + * Should only need to be provided when analyzing inner classes. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@interface TestClass { + String value() default "Test"; +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ExceptionParameters.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ExceptionParameters.java new file mode 100644 index 00000000000..70ca77aa560 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ExceptionParameters.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013 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. + */ + +import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; + +/* + * @test + * @summary Test population of reference info for exception parameters + * @author Werner Dietl + * @compile -g Driver.java ReferenceInfoUtil.java ExceptionParameters.java + * @run main Driver ExceptionParameters + */ +public class ExceptionParameters { + + @TADescription(annotation = "TA", type = EXCEPTION_PARAMETER, exceptionIndex = 0) + public String exception() { + return "void exception() { try { new Object(); } catch(@TA Exception e) { } }"; + } + + @TADescription(annotation = "TA", type = EXCEPTION_PARAMETER, exceptionIndex = 0) + public String finalException() { + return "void finalException() { try { new Object(); } catch(final @TA Exception e) { } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = EXCEPTION_PARAMETER, exceptionIndex = 0), + @TADescription(annotation = "TB", type = EXCEPTION_PARAMETER, exceptionIndex = 1), + @TADescription(annotation = "TC", type = EXCEPTION_PARAMETER, exceptionIndex = 2) + }) + public String multipleExceptions() { + return "void multipleExceptions() { " + + "try { new Object(); } catch(@TA Exception e) { }" + + "try { new Object(); } catch(@TB Exception e) { }" + + "try { new Object(); } catch(@TC Exception e) { }" + + " }"; + } +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Fields.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Fields.java new file mode 100644 index 00000000000..d352fa79b23 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Fields.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2009 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. + */ + +import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; + +/* + * @test + * @summary Test population of reference info for field + * @compile -g Driver.java ReferenceInfoUtil.java Fields.java + * @run main Driver Fields + */ +public class Fields { + + // field types + @TADescription(annotation = "TA", type = FIELD) + public String fieldAsPrimitive() { + return "@TA int test;"; + } + + @TADescription(annotation = "TA", type = FIELD) + public String fieldAsObject() { + return "@TA Object test;"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = FIELD), + @TADescription(annotation = "TB", type = FIELD, + genericLocation = { 3, 0 }), + @TADescription(annotation = "TC", type = FIELD, + genericLocation = { 3, 1 }), + @TADescription(annotation = "TD", type = FIELD, + genericLocation = { 3, 1, 3, 0 }) + }) + public String fieldAsParametrized() { + return "@TA Map<@TB String, @TC List<@TD String>> test;"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = FIELD), + @TADescription(annotation = "TB", type = FIELD, + genericLocation = { 0, 0 }), + @TADescription(annotation = "TC", type = FIELD, + genericLocation = { 0, 0, 0, 0 }) + }) + public String fieldAsArray() { + return "@TC String @TA [] @TB [] test;"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = FIELD), + @TADescription(annotation = "TB", type = FIELD, + genericLocation = { 0, 0 }), + @TADescription(annotation = "TC", type = FIELD, + genericLocation = { 0, 0, 0, 0 }) + }) + public String fieldAsArrayOld() { + return "@TC String test @TA [] @TB [];"; + } + + @TADescriptions({}) + public String fieldWithDeclarationAnnotatin() { + return "@Decl String test;"; + } + + @TADescriptions({}) + public String fieldWithNoTargetAnno() { + return "@A String test;"; + } + + // Smoke tests + @TADescription(annotation = "TA", type = FIELD) + public String interfacefieldAsObject() { + return "interface Test { @TA String test = null; }"; + } + + @TADescription(annotation = "TA", type = FIELD) + public String abstractfieldAsObject() { + return "abstract class Test { @TA String test; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = FIELD), + @TADescription(annotation = "TB", type = FIELD, + genericLocation = { 3, 0 }), + @TADescription(annotation = "TC", type = FIELD, + genericLocation = { 3, 1 }), + @TADescription(annotation = "TD", type = FIELD, + genericLocation = { 3, 1, 3, 0 }) + }) + public String interfacefieldAsParametrized() { + return "interface Test { @TA Map<@TB String, @TC List<@TD String>> test = null; }"; + } + + + @TADescriptions({ + @TADescription(annotation = "TA", type = FIELD), + @TADescription(annotation = "TB", type = FIELD, + genericLocation = { 3, 0 }), + @TADescription(annotation = "TC", type = FIELD, + genericLocation = { 3, 1 }), + @TADescription(annotation = "TD", type = FIELD, + genericLocation = { 3, 1, 3, 0 }) + }) + public String staticFieldAsParametrized() { + return "static @TA Map<@TB String, @TC List<@TD String>> test;"; + } + +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/FromSpecification.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/FromSpecification.java new file mode 100644 index 00000000000..e8e111d8c30 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/FromSpecification.java @@ -0,0 +1,122 @@ +/* + * 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. + */ + +import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; + +/* + * @test + * @summary Test that the examples from the manual are stored as expected + * @compile -g Driver.java ReferenceInfoUtil.java FromSpecification.java + * @run main Driver FromSpecification + */ +public class FromSpecification { + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0}, paramIndex = 0), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 2, 0}, paramIndex = 0), + @TADescription(annotation = "TD", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 1}, paramIndex = 0), + @TADescription(annotation = "TE", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 1, 3, 0}, paramIndex = 0) + }) + public String testSpec1() { + return "void test(@TA Map<@TB ? extends @TC String, @TD List<@TE Object>> a) { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TF", type = METHOD_FORMAL_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TG", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0}, paramIndex = 0), + @TADescription(annotation = "TH", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0, 0, 0}, paramIndex = 0), + @TADescription(annotation = "TI", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0, 0, 0, 0, 0}, paramIndex = 0) + }) + public String testSpec2() { + return "void test(@TI String @TF [] @TG [] @TH [] a) { }"; + } + + // Note first "1, 0" for top-level class Test. + @TADescriptions({ + @TADescription(annotation = "TJ", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0, 1, 0, 1, 0, 1, 0}, paramIndex = 0), + @TADescription(annotation = "TK", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0, 1, 0, 1, 0}, paramIndex = 0), + @TADescription(annotation = "TL", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0, 1, 0}, paramIndex = 0), + @TADescription(annotation = "TM", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0}, paramIndex = 0) + }) + public String testSpec3() { + return "class Test { class O1 { class O2 { class O3 { class NestedStatic {} } } }" + + "void test(@TM O1.@TL O2.@TK O3.@TJ NestedStatic a) { } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0}, paramIndex = 0), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 3, 0}, paramIndex = 0), + @TADescription(annotation = "TD", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 3, 0, 0, 0}, paramIndex = 0), + @TADescription(annotation = "TE", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 3, 0, 0, 0, 0, 0}, paramIndex = 0), + @TADescription(annotation = "TF", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 3, 0, 0, 0, 0, 0, 0, 0}, paramIndex = 0), + @TADescription(annotation = "TG", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 1}, paramIndex = 0), + @TADescription(annotation = "TH", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 1, 3, 0}, paramIndex = 0) + }) + public String testSpec4() { + return "void test(@TA Map<@TB Comparable<@TF Object @TC [] @TD [] @TE []>, @TG List<@TH String>> a) { }"; + } + + // Note first "1, 0" for top-level class Test. + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0, 1, 0, 1, 0, 1, 0}, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0, 1, 0, 1, 0, 1, 0, 3, 0}, paramIndex = 0), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0, 1, 0, 1, 0, 1, 0, 3, 1}, paramIndex = 0), + @TADescription(annotation = "TD", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0, 1, 0, 1, 0}, paramIndex = 0), + @TADescription(annotation = "TE", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0, 1, 0}, paramIndex = 0), + @TADescription(annotation = "TF", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0, 1, 0, 3, 0}, paramIndex = 0), + @TADescription(annotation = "TG", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0, 1, 0, 3, 1}, paramIndex = 0), + @TADescription(annotation = "TH", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0}, paramIndex = 0) + }) + public String testSpec5() { + return "class Test { class O1 { class O2 { class O3 { class Nested {} } } }" + + "void test(@TH O1.@TE O2<@TF String, @TG String>.@TD O3.@TA Nested<@TB String, @TC String> a) { } }"; + } +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodParameters.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodParameters.java new file mode 100644 index 00000000000..cfe36ed9ae2 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodParameters.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2009 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. + */ + +import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; + +/* + * @test + * @summary Test population of reference info for method parameters + * @compile -g Driver.java ReferenceInfoUtil.java MethodParameters.java + * @run main Driver MethodParameters + */ +public class MethodParameters { + + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 0) + public String methodParamAsPrimitive() { + return "void test(@TA int a) { }"; + } + + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 1) + public String methodParamAsObject() { + return "void test(Object b, @TA Object a) { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 0 }, paramIndex = 0), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 1 }, paramIndex = 0), + @TADescription(annotation = "TD", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 1, 3, 0 }, paramIndex = 0) + }) + public String methodParamAsParametrized() { + return "void test(@TA Map<@TB String, @TC List<@TD String>> a) { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 0 }, paramIndex = 0), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 0, 2, 0 }, paramIndex = 0), + @TADescription(annotation = "TD", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 1 }, paramIndex = 0), + @TADescription(annotation = "TE", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 1, 3, 0 }, paramIndex = 0), + @TADescription(annotation = "TF", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 1, 3, 0, 2, 0 }, paramIndex = 0), + @TADescription(annotation = "TG", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 1, 3, 0, 2, 0, 3, 0 }, paramIndex = 0), + @TADescription(annotation = "TH", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 1, 3, 0, 2, 0, 3, 0, 2, 0 }, paramIndex = 0), + @TADescription(annotation = "TI", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 1, 3, 0, 2, 0, 3, 1 }, paramIndex = 0), + @TADescription(annotation = "TJ", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 1, 3, 0, 2, 0, 3, 1, 2, 0 }, paramIndex = 0) + }) + public String methodParamAsWildcard() { + return "void test(@TA Map<@TB ? extends @TC String," + + " @TD List<@TE ? extends @TF Map<@TG ? super @TH String," + + " @TI ? extends @TJ Object>>> a) { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 1), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 0, 0 }, paramIndex = 1), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 0, 0, 0, 0 }, paramIndex = 1) + }) + public String methodParamAsArray() { + return "void test(Object b, @TC String @TA [] @TB [] a) { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 1), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 0, 0 }, paramIndex = 1), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 0, 0, 0, 0 }, paramIndex = 1) + }) + public String methodParamAsVararg() { + return "void test(Object b, @TC String @TA [] @TB ... a) { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 1), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 0, 0 }, paramIndex = 1), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 0, 0, 0, 0 }, paramIndex = 1) + }) + public String methodParamAsFQVararg() { + return "void test(Object b, java.lang.@TC String @TA [] @TB ... a) { }"; + } + + @TADescriptions({}) + public String methodWithDeclarationAnnotatin() { + return "void test(@Decl String a) { }"; + } + + @TADescriptions({}) + public String methodWithNoTargetAnno() { + return "void test(@A String a) { }"; + } + + // Smoke tests + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 0) + public String interfacemethodParamAsObject() { + return "interface Test { void test(@TA Object a); }"; + } + + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 2) + public String abstractmethodParamAsObject() { + return "abstract class Test { abstract void test(Object b, Object c, @TA Object a); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 0 }, paramIndex = 0), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 1 }, paramIndex = 0), + @TADescription(annotation = "TD", type = METHOD_FORMAL_PARAMETER, + genericLocation = { 3, 1, 3, 0 }, paramIndex = 0) + }) + public String interfacemethodParamAsParametrized() { + return "interface Test { void test(@TA Map<@TB String, @TC List<@TD String>> a); }"; + } + +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodReceivers.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodReceivers.java new file mode 100644 index 00000000000..c834d0cef56 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodReceivers.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2009 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. + */ + +import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; + +/* + * @test + * @summary Test population of reference info for method receivers + * @compile -g Driver.java ReferenceInfoUtil.java MethodReceivers.java + * @run main Driver MethodReceivers + */ +public class MethodReceivers { + + @TADescription(annotation = "TA", type = METHOD_RECEIVER) + public String regularMethod() { + return "class Test { void test(@TA Test this) { } }"; + } + + @TADescription(annotation = "TA", type = METHOD_RECEIVER) + public String abstractMethod() { + return "abstract class Test { abstract void test(@TA Test this); }"; + } + + @TADescription(annotation = "TA", type = METHOD_RECEIVER) + public String interfaceMethod() { + return "interface Test { void test(@TA Test this); }"; + } + + @TADescription(annotation = "TA", type = METHOD_RECEIVER) + public String regularWithThrows() { + return "class Test { void test(@TA Test this) throws Exception { } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RECEIVER, + genericLocation = {}), + @TADescription(annotation = "TB", type = METHOD_RECEIVER, + genericLocation = {1, 0}) + }) + @TestClass("TestOuter$TestInner") + public String nestedtypes1() { + return "class TestOuter { class TestInner { void test(@TA TestOuter. @TB TestInner this) { } } }"; + } + + @TADescription(annotation = "TA", type = METHOD_RECEIVER, + genericLocation = {}) + @TestClass("TestOuter$TestInner") + public String nestedtypes2() { + return "class TestOuter { class TestInner { void test(@TA TestOuter.TestInner this) { } } }"; + } + + @TADescription(annotation = "TB", type = METHOD_RECEIVER, + genericLocation = {1, 0}) + @TestClass("TestOuter$TestInner") + public String nestedtypes3() { + return "class TestOuter { class TestInner { void test(TestOuter. @TB TestInner this) { } } }"; + } + +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodReturns.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodReturns.java new file mode 100644 index 00000000000..07fc9f23742 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodReturns.java @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2009 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. + */ + +import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; + +/* + * @test + * @summary Test population of reference info for method return + * @compile -g Driver.java ReferenceInfoUtil.java MethodReturns.java + * @run main Driver MethodReturns + */ +public class MethodReturns { + + // Method returns + @TADescription(annotation = "TA", type = METHOD_RETURN) + public String methodReturnAsPrimitive() { + return "@TA int test() { return 0; }"; + } + + @TADescription(annotation = "TA", type = METHOD_RETURN) + public String methodReturnAsObject() { + return "@TA Object test() { return null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN), + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = { 3, 0 }), + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = { 3, 1 }), + @TADescription(annotation = "TD", type = METHOD_RETURN, + genericLocation = { 3, 1, 3, 0 }) + }) + public String methodReturnAsParametrized() { + return "@TA Map<@TB String, @TC List<@TD String>> test() { return null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN), + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = { 0, 0 }), + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = { 0, 0, 0, 0 }) + }) + public String methodReturnAsArray() { + return "@TC String @TA [] @TB [] test() { return null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN), + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = { 0, 0 }), + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = { 0, 0, 0, 0 }) + }) + public String methodReturnAsArrayOld() { + return "@TC String test() @TA [] @TB [] { return null; }"; + } + + @TADescriptions({}) + public String methodWithDeclarationAnnotation() { + return "@Decl String test() { return null; }"; + } + + @TADescriptions({}) + public String methodWithNoTargetAnno() { + return "@A String test() { return null; }"; + } + + // Smoke tests + @TADescription(annotation = "TA", type = METHOD_RETURN) + public String interfaceMethodReturnAsObject() { + return "interface Test { @TA Object test(); }"; + } + + @TADescription(annotation = "TA", type = METHOD_RETURN) + public String abstractMethodReturnAsObject() { + return "abstract class Test { abstract @TA Object test(); }"; + } + + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN), + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = { 3, 0 }), + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = { 3, 1 }), + @TADescription(annotation = "TD", type = METHOD_RETURN, + genericLocation = { 3, 1, 3, 0 }) + }) + public String interfaceMethodReturnAsParametrized() { + return "interface Test { @TA Map<@TB String, @TC List<@TD String>> test(); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN, + genericLocation = { 3, 0 }), + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0 }), + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0, 1, 0 }), + @TADescription(annotation = "TD", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0, 1, 0, 3, 0 }), + @TADescription(annotation = "TE", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0, 1, 0, 3, 1 }), + @TADescription(annotation = "TF", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0, 1, 0, 3, 1, 2, 0 }) + }) + public String methodReturnAsNestedWildcard() { + return "Set<@TA ? extends @TB GOuter. @TC GInner<@TD String, @TE ? super @TF Object>> entrySet() { return null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN, + genericLocation = { 3, 0, 1, 0, 3, 0 }), + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = { 3, 0, 1, 0, 3, 1 }), + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = { 3, 0, 1, 0, 3, 1, 2, 0 }) + }) + public String methodReturnAsNestedWildcard2() { + return "class GOuter { class GInner {} } " + + "class Test { Set.GInner<@TA K, @TB ? extends @TC Object>> entrySet() { return null; } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0 }), + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0, 1, 0 }), + }) + public String methodReturnAsNestedWildcard3() { + return "Set. @TC GInner> entrySet() { return null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0, 1, 0 }), + }) + public String methodReturnAsNestedWildcard4() { + return "Set. @TC GInner> entrySet() { return null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0 }), + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0, 1, 0 }), + }) + public String methodReturnAsNestedWildcard5() { + return "Set entrySet() { return null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0, 1, 0, 3, 0 }), + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0, 1, 0, 3, 1 }), + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = { 3, 0, 2, 0, 1, 0 }), + }) + public String methodReturnAsNestedWildcard6() { + return "Set. @TC GInner<@TA String, @TB Object>> entrySet() { return null; }"; + } + +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodThrows.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodThrows.java new file mode 100644 index 00000000000..155e4bbfb71 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodThrows.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2009 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. + */ + +import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; + +/* + * @test + * @summary Test population of reference info for method exception clauses + * @compile -g Driver.java ReferenceInfoUtil.java MethodThrows.java + * @run main Driver MethodThrows + */ +public class MethodThrows { + + @TADescriptions({ + @TADescription(annotation = "TA", type = THROWS, typeIndex = 0), + @TADescription(annotation = "TB", type = THROWS, typeIndex = 2) + }) + public String regularMethod() { + return "class Test { void test() throws @TA RuntimeException, IllegalArgumentException, @TB Exception { } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = THROWS, typeIndex = 0), + @TADescription(annotation = "TB", type = THROWS, typeIndex = 2) + }) + public String abstractMethod() { + return "abstract class Test { abstract void test() throws @TA RuntimeException, IllegalArgumentException, @TB Exception; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = THROWS, typeIndex = 0), + @TADescription(annotation = "TB", type = THROWS, typeIndex = 2) + }) + public String interfaceMethod() { + return "interface Test { void test() throws @TA RuntimeException, IllegalArgumentException, @TB Exception; }"; + } +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodTypeParam.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodTypeParam.java new file mode 100644 index 00000000000..4b7b521904f --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodTypeParam.java @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2009 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. + */ + +import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; + +/* + * @test + * @summary Test population of reference info for method type parameters + * @compile -g Driver.java ReferenceInfoUtil.java MethodTypeParam.java + * @run main Driver MethodTypeParam + */ +public class MethodTypeParam { + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER, paramIndex = 1), + @TADescription(annotation = "TD", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 0), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1) + }) + public String regularClass() { + return "<@TA K extends @TB Date, @TC V extends @TD Object & @TE Cloneable> void test() { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER, paramIndex = 1), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1) + }) + public String regularClass2() { + return "<@TA K extends @TB Date, @TC V extends @TE Cloneable> void test() { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1, genericLocation = {3, 1}), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1), + @TADescription(annotation = "TD", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0}), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0, 3, 0}), + @TADescription(annotation = "TF", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 0) + }) + public String regularClassParameterized() { + return ", V extends @TF Object & @TC List<@TD List<@TE Object>>> void test() { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER, paramIndex = 1), + @TADescription(annotation = "TD", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 0), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1) + }) + public String abstractClass() { + return "abstract class Test { abstract <@TA K extends @TB Date, @TC V extends @TD Object & @TE Cloneable> void test(); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1, genericLocation = {3, 1}), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1), + @TADescription(annotation = "TD", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0}), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0, 3, 0}), + @TADescription(annotation = "TF", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 0), + @TADescription(annotation = "TG", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0) + }) + public String abstractClassParameterized() { + return "abstract class Test { abstract , V extends @TF Object & @TC List<@TD List<@TE Object>>> void test(); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1, genericLocation = {3, 1}), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1), + @TADescription(annotation = "TD", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0}), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0, 3, 0}) + }) + public String abstractClassParameterized2() { + return "abstract class Test { abstract , V extends @TC List<@TD List<@TE Object>>> void test(); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1) + }) + public String abstractClassParameterized3() { + return "abstract class Test { abstract , V extends @TB List> void test(); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER, paramIndex = 1), + @TADescription(annotation = "TD", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 0), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1) + }) + public String regularInterface() { + return "interface Test { <@TA K extends @TB Date, @TC V extends @TD Object & @TE Cloneable> void test(); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1, genericLocation = {3, 1}), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1), + @TADescription(annotation = "TD", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0}), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0, 3, 0}), + @TADescription(annotation = "TF", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 0), + @TADescription(annotation = "TG", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TH", type = METHOD_TYPE_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TI", type = METHOD_TYPE_PARAMETER, paramIndex = 1) + }) + public String regularInterfaceParameterized() { + return "interface Test { <@TH K extends @TG Object & @TA Map, @TI V extends @TF Object & @TC List<@TD List<@TE Object>>> void test(); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1, genericLocation = {3, 1}), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1), + @TADescription(annotation = "TD", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0}), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 1, boundIndex = 1, genericLocation = {3, 0, 3, 0}), + @TADescription(annotation = "TF", type = METHOD_TYPE_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TG", type = METHOD_TYPE_PARAMETER, paramIndex = 1) + }) + public String regularInterfaceParameterized2() { + return "interface Test { <@TF K extends @TA Map, @TG V extends @TC List<@TD List<@TE Object>>> void test(); }"; + } + + @TADescription(annotation = "TA", type = METHOD_RETURN) + public String useInReturn1() { + return "class Test { @TA T m() { throw new RuntimeException(); } }"; + } + + @TADescription(annotation = "TA", type = METHOD_RETURN, genericLocation = {3, 0}) + public String useInReturn2() { + return "class Test { Class<@TA T> m() { throw new RuntimeException(); } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TB", type = METHOD_RETURN) + }) + public String useInReturn3() { + return "class Test { @TB T m() { throw new RuntimeException(); } }"; + } + + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + paramIndex = 0, genericLocation = {3, 0}) + public String useInParam1() { + return "class Test { void m(Class<@TA T> p) { throw new RuntimeException(); } }"; + } + + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + paramIndex = 0, genericLocation = {3, 0}) + public String useInParam2() { + return "class Test { void m(Class<@TA Object> p) { throw new RuntimeException(); } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, paramIndex = 0, boundIndex = 2), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, paramIndex = 0) + }) + public String useInParam3() { + return "interface IA {} " + + "interface IB {} " + + "interface IC {} " + + "class Test { & @TB IC> void m(@TC T p) { throw new RuntimeException(); } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, + paramIndex = 0, boundIndex = 1, + genericLocation = {}), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, + paramIndex = 0, boundIndex = 2, + genericLocation = {}), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, + paramIndex = 0) + }) + public String useInParam4() { + return "class Test {" + + " interface IA {} " + + " interface IB {} " + + " interface IC {} " + + " & @TB IC> void m(@TC T p) { throw new RuntimeException(); } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, + paramIndex = 0, boundIndex = 0, + genericLocation = {}), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, + paramIndex = 0, boundIndex = 0, + genericLocation = {1, 0}), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER_BOUND, + paramIndex = 0, boundIndex = 0, + genericLocation = {1, 0, 3, 0}), + }) + public String useInParam5() { + return "class Test {" + + " interface IA {} " + + " class CB {} " + + " > void m(T p) { throw new RuntimeException(); } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER, + paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, + paramIndex = 0, boundIndex = 0, + genericLocation = {}), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER_BOUND, + paramIndex = 0, boundIndex = 0, + genericLocation = {1, 0, 3, 0}), + @TADescription(annotation = "TD", type = METHOD_TYPE_PARAMETER_BOUND, + paramIndex = 0, boundIndex = 1, + genericLocation = {}), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, + paramIndex = 0, boundIndex = 1, + genericLocation = {3, 0}) + }) + public String useInParam6() { + return "class Test {" + + " interface IA {} " + + " interface IB {} " + + " class CC {} " + + " interface ID {} " + + " <@TA T extends @TB Test.CC<@TC IA> & Test. @TD ID<@TE IA>> void m(T p) { throw new RuntimeException(); } }"; + } +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java new file mode 100644 index 00000000000..d62d52ff158 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013 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. + */ + +import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; + +/* + * @test + * @bug 8006732 8006775 + * @ignore + * @summary Test population of reference info for multicatch exception parameters + * @author Werner Dietl + * @compile -g Driver.java ReferenceInfoUtil.java MultiCatch.java + * @run main Driver MultiCatch + */ +public class MultiCatch { + + @TADescriptions({ + @TADescription(annotation = "TA", type = EXCEPTION_PARAMETER, exceptionIndex = 0), + @TADescription(annotation = "TB", type = EXCEPTION_PARAMETER, exceptionIndex = 1) + }) + public String multiCatch1() { + return "void multiCatch1() { " + + "try { new Object(); } catch (@TA NullPointerException | @TB IndexOutOfBoundsException e) { e.toString(); } }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = EXCEPTION_PARAMETER, exceptionIndex = 0), + @TADescription(annotation = "TB", type = EXCEPTION_PARAMETER, exceptionIndex = 1), + @TADescription(annotation = "TC", type = EXCEPTION_PARAMETER, exceptionIndex = 2), + }) + public String multiCatch2() { + return "void multiCatch2() { " + + "try { new Object(); } catch (@TA NullPointerException | @TB IndexOutOfBoundsException | @TC IllegalArgumentException e) { e.toString(); } }"; + } + +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java new file mode 100644 index 00000000000..476e23f05ce --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java @@ -0,0 +1,834 @@ +/* + * 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. + */ + +import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; + +/* + * @test + * @summary Test population of reference info for nested types + * @compile -g Driver.java ReferenceInfoUtil.java NestedTypes.java + * @run main Driver NestedTypes + */ +public class NestedTypes { + + // method parameters + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + genericLocation = {}, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0}, paramIndex = 0) + }) + public String testParam1() { + return "void test(@TA Outer.@TB Inner a) { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0}, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 1, 0}, paramIndex = 0) + }) + public String testParam1b() { + return "void test(List<@TA Outer.@TB Inner> a) { }"; + } + + // TODO: the tests that use @TA Map.Entry should fail, as + // Map cannot be annotated. + // We need some tests for the fully qualified name syntax. + /* + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + genericLocation = {}, paramIndex = 0) + public String testParam1c() { + return "void test(java.util.@TA Map.Entry a) { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + genericLocation = {}, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0}, paramIndex = 0) + }) + public String testParam1d() { + return "void test(java.util.@TA Map.@TB Entry a) { }"; + } + + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0}, paramIndex = 0) + public String testParam1e() { + return "void test(List a) { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0}, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 1, 0}, paramIndex = 0) + }) + public String testParam1f() { + return "void test(List a) { }"; + } + */ + + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0}, paramIndex = 0) + public String testParam1g() { + return "void test(List a) { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + genericLocation = {}, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = {1, 0}, paramIndex = 0) + }) + public String testParam2() { + return "void test(@TA GOuter.@TB GInner a) { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0}, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 1, 0}, paramIndex = 0) + }) + public String testParam2b() { + return "void test(List<@TA GOuter.@TB GInner> a) { }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0, 0, 0}, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0, 0, 0, 1, 0}, paramIndex = 0), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0}, paramIndex = 0), + @TADescription(annotation = "TD", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0}, paramIndex = 0), + @TADescription(annotation = "TE", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0, 3, 0}, paramIndex = 0), + @TADescription(annotation = "TF", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0}, paramIndex = 0), + @TADescription(annotation = "TG", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0, 0, 0, 1, 0, 1, 0}, paramIndex = 0), + @TADescription(annotation = "TH", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0, 0, 0, 1, 0, 1, 0, 3, 0}, paramIndex = 0), + @TADescription(annotation = "TI", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0, 0, 0, 1, 0, 1, 0, 3, 1}, paramIndex = 0), + @TADescription(annotation = "TJ", type = METHOD_FORMAL_PARAMETER, paramIndex = 0), + @TADescription(annotation = "TK", type = METHOD_FORMAL_PARAMETER, + genericLocation = {0, 0}, paramIndex = 0) + }) + public String testParam3() { + return "class Outer {\n" + + " class GInner {\n" + + " class GInner2 {}\n" + + "}}\n\n" + + "class Test {\n" + + " void test(@TA Outer . @TB GInner<@TC List<@TD Object @TE[] @TF[]>>. @TG GInner2<@TH Integer, @TI Object> @TJ[] @TK[] a) { }\n" + + "}"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 0, 0, 0, 0}, paramIndex = 0), + @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0}, paramIndex = 0), + @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0}, paramIndex = 0), + @TADescription(annotation = "TD", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0}, paramIndex = 0), + @TADescription(annotation = "TE", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0}, paramIndex = 0), + @TADescription(annotation = "TF", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0}, paramIndex = 0), + @TADescription(annotation = "TG", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0}, paramIndex = 0), + @TADescription(annotation = "TH", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0, 3, 0}, paramIndex = 0), + @TADescription(annotation = "TI", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0, 3, 1}, paramIndex = 0), + @TADescription(annotation = "TJ", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0}, paramIndex = 0), + @TADescription(annotation = "TK", type = METHOD_FORMAL_PARAMETER, + genericLocation = {3, 0, 0, 0}, paramIndex = 0) + }) + public String testParam4() { + return "class Outer {\n" + + " class GInner {\n" + + " class GInner2 {}\n" + + "}}\n\n" + + "class Test {\n" + + " void test(List<@TA Outer . @TB GInner<@TC List<@TD Object @TE[] @TF[]>>. @TG GInner2<@TH Integer, @TI Object> @TJ[] @TK[]> a) { }\n" + + "}"; + } + + + // Local variables + + @TADescriptions({ + @TADescription(annotation = "TA", type = LOCAL_VARIABLE, + genericLocation = {}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TB", type = LOCAL_VARIABLE, + genericLocation = {1, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}) + }) + public String testLocal1a() { + return "void test() { @TA Outer.@TB Inner a = null; }"; + } + + @TADescription(annotation = "TA", type = LOCAL_VARIABLE, + genericLocation = {}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}) + public String testLocal1b() { + return "void test() { @TA Outer.Inner a = null; }"; + } + + @TADescription(annotation = "TB", type = LOCAL_VARIABLE, + genericLocation = {1, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}) + public String testLocal1c() { + return "void test() { Outer.@TB Inner a = null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = LOCAL_VARIABLE, + genericLocation = {}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TB", type = LOCAL_VARIABLE, + genericLocation = {1, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}) + }) + public String testLocal2() { + return "void test() { @TA GOuter.@TB GInner a = null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = LOCAL_VARIABLE, + genericLocation = {0, 0, 0, 0}, + lvarOffset = {5}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TB", type = LOCAL_VARIABLE, + genericLocation = {0, 0, 0, 0, 1, 0}, + lvarOffset = {5}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TC", type = LOCAL_VARIABLE, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0}, + lvarOffset = {5}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TD", type = LOCAL_VARIABLE, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0}, + lvarOffset = {5}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TE", type = LOCAL_VARIABLE, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0, 3, 0}, + lvarOffset = {5}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TF", type = LOCAL_VARIABLE, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0}, + lvarOffset = {5}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TG", type = LOCAL_VARIABLE, + genericLocation = {0, 0, 0, 0, 1, 0, 1, 0}, + lvarOffset = {5}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TH", type = LOCAL_VARIABLE, + genericLocation = {0, 0, 0, 0, 1, 0, 1, 0, 3, 0}, + lvarOffset = {5}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TI", type = LOCAL_VARIABLE, + genericLocation = {0, 0, 0, 0, 1, 0, 1, 0, 3, 1}, + lvarOffset = {5}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TJ", type = LOCAL_VARIABLE, + genericLocation = {}, + lvarOffset = {5}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TK", type = LOCAL_VARIABLE, + genericLocation = {0, 0}, + lvarOffset = {5}, lvarLength = {1}, lvarIndex = {1}) + }) + public String testLocal3() { + return "class Outer {\n" + + " class GInner {\n" + + " class GInner2 {}\n" + + "}}\n\n" + + "class Test {\n" + + " void test() { @TA Outer . @TB GInner<@TC List<@TD Object @TE[] @TF[]>>. @TG GInner2<@TH Integer, @TI Object> @TJ[] @TK[] a = null; }\n" + + "}"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = LOCAL_VARIABLE, + genericLocation = {3, 0, 0, 0, 0, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TB", type = LOCAL_VARIABLE, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TC", type = LOCAL_VARIABLE, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TD", type = LOCAL_VARIABLE, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TE", type = LOCAL_VARIABLE, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TF", type = LOCAL_VARIABLE, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TG", type = LOCAL_VARIABLE, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TH", type = LOCAL_VARIABLE, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0, 3, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TI", type = LOCAL_VARIABLE, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0, 3, 1}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TJ", type = LOCAL_VARIABLE, + genericLocation = {3, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}), + @TADescription(annotation = "TK", type = LOCAL_VARIABLE, + genericLocation = {3, 0, 0, 0}, + lvarOffset = {2}, lvarLength = {1}, lvarIndex = {1}) + }) + public String testLocal4() { + return "class Outer {\n" + + " class GInner {\n" + + " class GInner2 {}\n" + + "}}\n\n" + + "class Test {\n" + + " void test() { List<@TA Outer . @TB GInner<@TC List<@TD Object @TE[] @TF[]>>. @TG GInner2<@TH Integer, @TI Object> @TJ[] @TK[]> a = null; }\n" + + "}"; + } + + + // fields + + @TADescriptions({ + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {}), + @TADescription(annotation = "TB", type = FIELD, + genericLocation = {1, 0}) + }) + public String testField1a() { + return "@TA Outer.@TB Inner a;"; + } + + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {}) + public String testField1b() { + return "@TA Outer.Inner a;"; + } + + @TADescription(annotation = "TB", type = FIELD, + genericLocation = {1, 0}) + public String testField1c() { + return "Outer.@TB Inner a;"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {}), + @TADescription(annotation = "TB", type = FIELD, + genericLocation = {1, 0}) + }) + public String testField2() { + return "@TA GOuter.@TB GInner a;"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {0, 0, 0, 0}), + @TADescription(annotation = "TB", type = FIELD, + genericLocation = {0, 0, 0, 0, 1, 0}), + @TADescription(annotation = "TC", type = FIELD, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0}), + @TADescription(annotation = "TD", type = FIELD, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0}), + @TADescription(annotation = "TE", type = FIELD, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0, 3, 0}), + @TADescription(annotation = "TF", type = FIELD, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0}), + @TADescription(annotation = "TG", type = FIELD, + genericLocation = {0, 0, 0, 0, 1, 0, 1, 0}), + @TADescription(annotation = "TH", type = FIELD, + genericLocation = {0, 0, 0, 0, 1, 0, 1, 0, 3, 0}), + @TADescription(annotation = "TI", type = FIELD, + genericLocation = {0, 0, 0, 0, 1, 0, 1, 0, 3, 1}), + @TADescription(annotation = "TJ", type = FIELD), + @TADescription(annotation = "TK", type = FIELD, + genericLocation = {0, 0}) + }) + public String testField3() { + return "class Outer {\n" + + " class GInner {\n" + + " class GInner2 {}\n" + + "}}\n\n" + + "class Test {\n" + + " @TA Outer . @TB GInner<@TC List<@TD Object @TE[] @TF[]>>. @TG GInner2<@TH Integer, @TI Object> @TJ[] @TK[] a;\n" + + "}"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {3, 0, 0, 0, 0, 0}), + @TADescription(annotation = "TB", type = FIELD, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0}), + @TADescription(annotation = "TC", type = FIELD, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0}), + @TADescription(annotation = "TD", type = FIELD, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0}), + @TADescription(annotation = "TE", type = FIELD, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0}), + @TADescription(annotation = "TF", type = FIELD, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0}), + @TADescription(annotation = "TG", type = FIELD, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0}), + @TADescription(annotation = "TH", type = FIELD, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0, 3, 0}), + @TADescription(annotation = "TI", type = FIELD, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0, 3, 1}), + @TADescription(annotation = "TJ", type = FIELD, + genericLocation = {3, 0}), + @TADescription(annotation = "TK", type = FIELD, + genericLocation = {3, 0, 0, 0}) + }) + public String testField4() { + return "class Outer {\n" + + " class GInner {\n" + + " class GInner2 {}\n" + + "}}\n\n" + + "class Test {\n" + + " List<@TA Outer . @TB GInner<@TC List<@TD Object @TE[] @TF[]>>. @TG GInner2<@TH Integer, @TI Object> @TJ[] @TK[]> a;\n" + + "}"; + } + + + // return types + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN, + genericLocation = {}), + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = {1, 0}) + }) + public String testReturn1() { + return "@TA Outer.@TB Inner test() { return null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN, + genericLocation = {}), + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = {1, 0}) + }) + public String testReturn2() { + return "@TA GOuter.@TB GInner test() { return null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN, + genericLocation = {0, 0, 0, 0}), + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = {0, 0, 0, 0, 1, 0}), + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0}), + @TADescription(annotation = "TD", type = METHOD_RETURN, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0}), + @TADescription(annotation = "TE", type = METHOD_RETURN, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0, 3, 0}), + @TADescription(annotation = "TF", type = METHOD_RETURN, + genericLocation = {0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0}), + @TADescription(annotation = "TG", type = METHOD_RETURN, + genericLocation = {0, 0, 0, 0, 1, 0, 1, 0}), + @TADescription(annotation = "TH", type = METHOD_RETURN, + genericLocation = {0, 0, 0, 0, 1, 0, 1, 0, 3, 0}), + @TADescription(annotation = "TI", type = METHOD_RETURN, + genericLocation = {0, 0, 0, 0, 1, 0, 1, 0, 3, 1}), + @TADescription(annotation = "TJ", type = METHOD_RETURN), + @TADescription(annotation = "TK", type = METHOD_RETURN, + genericLocation = {0, 0}) + }) + public String testReturn3() { + return "class Outer {\n" + + " class GInner {\n" + + " class GInner2 {}\n" + + "}}\n\n" + + "class Test {\n" + + " @TA Outer . @TB GInner<@TC List<@TD Object @TE[] @TF[]>>. @TG GInner2<@TH Integer, @TI Object> @TJ[] @TK[] test() { return null; }\n" + + "}"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN, + genericLocation = {3, 0, 0, 0, 0, 0}), + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0}), + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0}), + @TADescription(annotation = "TD", type = METHOD_RETURN, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0}), + @TADescription(annotation = "TE", type = METHOD_RETURN, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0}), + @TADescription(annotation = "TF", type = METHOD_RETURN, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0}), + @TADescription(annotation = "TG", type = METHOD_RETURN, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0}), + @TADescription(annotation = "TH", type = METHOD_RETURN, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0, 3, 0}), + @TADescription(annotation = "TI", type = METHOD_RETURN, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0, 3, 1}), + @TADescription(annotation = "TJ", type = METHOD_RETURN, + genericLocation = {3, 0}), + @TADescription(annotation = "TK", type = METHOD_RETURN, + genericLocation = {3, 0, 0, 0}) + }) + public String testReturn4() { + return "class Outer {\n" + + " class GInner {\n" + + " class GInner2 {}\n" + + "}}\n\n" + + "class Test {\n" + + " List<@TA Outer . @TB GInner<@TC List<@TD Object @TE[] @TF[]>>. @TG GInner2<@TH Integer, @TI Object> @TJ[] @TK[]> test() { return null; }\n" + + "}"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_RETURN, + genericLocation = {3, 0}), + @TADescription(annotation = "TB", type = METHOD_RETURN, + genericLocation = {3, 0, 3, 0}), + @TADescription(annotation = "TC", type = METHOD_RETURN, + genericLocation = {3, 0, 3, 1}), + @TADescription(annotation = "TD", type = METHOD_RETURN, + genericLocation = {3, 0, 3, 1, 3, 0}), + @TADescription(annotation = "TE", type = METHOD_RETURN, + genericLocation = {3, 0, 1, 0}), + @TADescription(annotation = "TF", type = METHOD_RETURN, + genericLocation = {3, 0, 1, 0, 3, 0}), + @TADescription(annotation = "TG", type = METHOD_RETURN, + genericLocation = {3, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0}), + @TADescription(annotation = "TH", type = METHOD_RETURN, + genericLocation = {3, 0, 1, 0, 3, 0, 3, 0}), + @TADescription(annotation = "TI", type = METHOD_RETURN, + genericLocation = {3, 0, 1, 0, 3, 0, 3, 0, 0, 0}), + @TADescription(annotation = "TJ", type = METHOD_RETURN, + genericLocation = {3, 0, 1, 0, 1, 0}), + }) + public String testReturn5() { + return "class GOuter {\n" + + " class GInner {\n" + + " class GInner2 {}\n" + + "}}\n\n" + + "class Test {\n" + + " List<@TA GOuter<@TB String, @TC List<@TD Object>> . @TE GInner<@TF List<@TG Object @TH[] @TI[]>>. @TJ GInner2> test() { return null; }\n" + + "}"; + } + + + // type parameters + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {}, paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {1, 0}, paramIndex = 0, boundIndex = 0) + }) + public String testTypeparam1() { + return " X test() { return null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {}, paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {1, 0}, paramIndex = 0, boundIndex = 0) + }) + public String testTypeparam2() { + return ".@TB GInner> X test() { return null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {}, + paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {1, 0}, + paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {1, 0, 3, 0}, + paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TD", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {1, 0, 3, 0, 3, 0, 0, 0, 0, 0}, + paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {1, 0, 3, 0, 3, 0}, + paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TF", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {1, 0, 3, 0, 3, 0, 0, 0}, + paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TG", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {1, 0, 1, 0}, + paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TH", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {1, 0, 1, 0, 3, 0}, + paramIndex = 0, boundIndex = 0), + @TADescription(annotation = "TI", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {1, 0, 1, 0, 3, 1}, + paramIndex = 0, boundIndex = 0), + }) + public String testTypeparam3() { + return "class Outer {\n" + + " class GInner {\n" + + " class GInner2 {}\n" + + "}}\n\n" + + "class Test {\n" + + " >. @TG GInner2<@TH Integer, @TI Object>> X test() { return null; }\n" + + "}"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 0, 0, 0, 0}, + paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0}, + paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0}, + paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TD", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0}, + paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0}, + paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TF", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 3, 0, 3, 0, 0, 0}, + paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TG", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0}, + paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TH", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0, 3, 0}, + paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TI", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 0, 0, 0, 0, 1, 0, 1, 0, 3, 1}, + paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TJ", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0}, + paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TK", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 0, 0}, + paramIndex = 0, boundIndex = 1) + }) + public String testTypeparam4() { + return "class Outer {\n" + + " class GInner {\n" + + " class GInner2 {}\n" + + "}}\n\n" + + "class Test {\n" + + " >. @TG GInner2<@TH Integer, @TI Object> @TJ[] @TK[]>> X test() { return null; }\n" + + "}"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0}, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TB", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 3, 0}, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TC", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 3, 1}, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TD", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 3, 1, 3, 0}, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TE", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 1, 0}, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TF", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 1, 0, 3, 0}, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TG", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 1, 0, 3, 0, 3, 0, 0, 0, 0, 0}, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TH", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 1, 0, 3, 0, 3, 0}, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TI", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 1, 0, 3, 0, 3, 0, 0, 0}, paramIndex = 0, boundIndex = 1), + @TADescription(annotation = "TJ", type = METHOD_TYPE_PARAMETER_BOUND, + genericLocation = {3, 0, 1, 0, 1, 0}, paramIndex = 0, boundIndex = 1), + }) + public String testTypeparam5() { + return "class GOuter {\n" + + " class GInner {\n" + + " class GInner2 {}\n" + + "}}\n\n" + + "class Test {\n" + + " > . @TE GInner<@TF List<@TG Object @TH[] @TI[]>>. @TJ GInner2>> X test() { return null; }\n" + + "}"; + } + + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {3, 0, 1, 0}) + public String testUses1a() { + return "class Test { class Inner {} List<@TA Inner> f; }"; + } + + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {3, 0}) + public String testUses1b() { + return "class Test { class Inner {} List<@TA Test.Inner> f; }"; + } + + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {3, 0, 1, 0, 1, 0}) + @TestClass("Test$Inner") + public String testUses2a() { + return "class Test { class Inner { class Inner2{} List<@TA Inner2> f; }}"; + } + + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {3, 0, 1, 0}) + @TestClass("Test$Inner") + public String testUses2b() { + return "class Test { class Inner { class Inner2{} List<@TA Inner.Inner2> f; }}"; + } + + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {3, 0, 1, 0, 1, 0}) + @TestClass("Test$Inner") + public String testUses2c() { + return "class Test { class Inner { class Inner2{} List f; }}"; + } + + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {3, 0}) + @TestClass("Test$Inner") + public String testUses2d() { + return "class Test{ class Inner { class Inner2{} List<@TA Test.Inner.Inner2> f; }}"; + } + + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {3, 0, 1, 0}) + @TestClass("Test$Inner") + public String testUses2e() { + return "class Test { class Inner { class Inner2{} List f; }}"; + } + + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {3, 0, 1, 0, 1, 0}) + @TestClass("Test$Inner") + public String testUses2f() { + return "class Test { class Inner { class Inner2{} List f; }}"; + } + + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {3, 0, 1, 0, 1, 0}) + @TestClass("Test$Inner") + public String testUses3a() { + return "class Test { class Inner { class Inner2{}\n" + + " List f; }}"; + } + + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {3, 0, 1, 0}) + @TestClass("Test$Inner") + public String testUses3b() { + return "class Test { class Inner { class Inner2{}\n" + + " List f; }}"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {}), + @TADescription(annotation = "TB", type = FIELD, + genericLocation = {3, 0}) + }) + public String testUses4() { + return "class Test { static class TInner {}\n" + + " @TA TInner f; \n" + + " List<@TB TInner> g; }"; + } + + @TADescription(annotation = "TA", type = FIELD, + genericLocation = {3, 0, 1, 0, 3, 1}) + @TestClass("Test$Inner") + public String testUses3c() { + return "class Test { class Inner { class Inner2{}\n" + + " List.Inner2> f; }}"; + } + + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex=0) + public String testFullyQualified1() { + return "void testme(java.security.@TA ProtectionDomain protectionDomain) {}"; + } + + @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex=0, + genericLocation = {3, 0}) + public String testFullyQualified2() { + return "void testme(List protectionDomain) {}"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = LOCAL_VARIABLE, + genericLocation = {}, + lvarOffset = ReferenceInfoUtil.IGNORE_VALUE, + lvarLength = ReferenceInfoUtil.IGNORE_VALUE, + lvarIndex = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = LOCAL_VARIABLE, + genericLocation = {1, 0}, + lvarOffset = ReferenceInfoUtil.IGNORE_VALUE, + lvarLength = ReferenceInfoUtil.IGNORE_VALUE, + lvarIndex = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TC", type = LOCAL_VARIABLE, + // Only classes count, not methods. + genericLocation = {1, 0, 1, 0}, + lvarOffset = ReferenceInfoUtil.IGNORE_VALUE, + lvarLength = ReferenceInfoUtil.IGNORE_VALUE, + lvarIndex = ReferenceInfoUtil.IGNORE_VALUE), + }) + @TestClass("Outer$Inner") + public String testMethodNesting1() { + return "class Outer {\n" + + " class Inner {\n" + + " void foo() {\n" + + " class MInner {}\n" + + " @TA Outer . @TB Inner l1 = null;\n" + + " @TC MInner l2 = null;\n" + + " }\n" + + "}}\n"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = NEW, + genericLocation = {}, + offset = 0), + @TADescription(annotation = "TB", type = NEW, + genericLocation = {1, 0}, + offset = 0), + @TADescription(annotation = "TC", type = NEW, + // Only classes count, not methods. + genericLocation = {1, 0, 1, 0}, + offset = 12), + }) + @TestClass("Outer$Inner") + public String testMethodNesting2() { + return "class Outer {\n" + + " class Inner {\n" + + " void foo() {\n" + + " class MInner {}\n" + + " Object o1 = new @TA Outer . @TB Inner();" + + " Object o2 = new @TC MInner();\n" + + " }\n" + + "}}\n"; + } +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NewObjects.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NewObjects.java new file mode 100644 index 00000000000..b56dbb74d23 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/NewObjects.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2009 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. + */ + +import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; + +/* + * @test + * @summary Test population of reference info for new object creations + * @compile -g Driver.java ReferenceInfoUtil.java NewObjects.java + * @run main Driver NewObjects + */ +public class NewObjects { + + @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE) + public String returnObject() { + return "Object returnObject() { return new @TA String(); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = NEW, + genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String returnObjectGeneric() { + return "Object returnObjectGeneric() { return new @TA ArrayList<@TB String>(); }"; + } + + @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE) + public String initObject() { + return "void initObject() { Object a = new @TA String(); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = NEW, + genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TC", type = NEW, + genericLocation = { 3, 1 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String initObjectGeneric() { + return "void initObjectGeneric() { Object a = new @TA HashMap<@TB String, @TC String>(); }"; + } + + @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE) + public String eqtestObject() { + return "void eqtestObject() { if (null == new @TA String()); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = NEW, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = NEW, + genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String eqtestObjectGeneric() { + return "void eqtestObjectGeneric() { if (null == new @TA ArrayList<@TB String >()); }"; + } + +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ReferenceInfoUtil.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ReferenceInfoUtil.java new file mode 100644 index 00000000000..0a94ee07de3 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/ReferenceInfoUtil.java @@ -0,0 +1,332 @@ +/* + * Copyright (c) 2009 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. + */ + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import com.sun.tools.classfile.Attribute; +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.TypeAnnotation; +import com.sun.tools.classfile.Field; +import com.sun.tools.classfile.Method; +import com.sun.tools.classfile.RuntimeTypeAnnotations_attribute; +import com.sun.tools.classfile.ConstantPool.InvalidIndex; +import com.sun.tools.classfile.ConstantPool.UnexpectedEntry; + +public class ReferenceInfoUtil { + + public static final int IGNORE_VALUE = -321; + + public static List extendedAnnotationsOf(ClassFile cf) { + List annos = new ArrayList(); + findAnnotations(cf, annos); + return annos; + } + + /////////////////// Extract type annotations ////////////////// + private static void findAnnotations(ClassFile cf, List annos) { + findAnnotations(cf, Attribute.RuntimeVisibleTypeAnnotations, annos); + findAnnotations(cf, Attribute.RuntimeInvisibleTypeAnnotations, annos); + + for (Field f : cf.fields) { + findAnnotations(cf, f, annos); + } + for (Method m: cf.methods) { + findAnnotations(cf, m, annos); + } + } + + private static void findAnnotations(ClassFile cf, Method m, List annos) { + findAnnotations(cf, m, Attribute.RuntimeVisibleTypeAnnotations, annos); + findAnnotations(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, annos); + } + + private static void findAnnotations(ClassFile cf, Field m, List annos) { + findAnnotations(cf, m, Attribute.RuntimeVisibleTypeAnnotations, annos); + findAnnotations(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, annos); + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + private static void findAnnotations(ClassFile cf, String name, List annos) { + int index = cf.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = cf.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + annos.addAll(Arrays.asList(tAttr.annotations)); + } + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + private static void findAnnotations(ClassFile cf, Method m, String name, List annos) { + int index = m.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = m.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + annos.addAll(Arrays.asList(tAttr.annotations)); + } + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + private static void findAnnotations(ClassFile cf, Field m, String name, List annos) { + int index = m.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = m.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + annos.addAll(Arrays.asList(tAttr.annotations)); + } + } + + /////////////////// TA Position Builder /////////////////////// + /* TODO: comment out this dead code. Was this unfinished code that was + * supposed to be used somewhere? The tests pass without this. + private static class TAPositionBuilder { + private TypeAnnotation.Position pos = new TypeAnnotation.Position(); + + private TAPositionBuilder() { } + + public TypeAnnotation.Position build() { return pos; } + + public static TAPositionBuilder ofType(TypeAnnotation.TargetType type) { + TAPositionBuilder builder = new TAPositionBuilder(); + builder.pos.type = type; + return builder; + } + + public TAPositionBuilder atOffset(int offset) { + switch (pos.type) { + // type cast + case TYPECAST: + // instanceof + case INSTANCEOF: + // new expression + case NEW: + pos.offset = offset; + break; + default: + throw new IllegalArgumentException("invalid field for given type: " + pos.type); + } + return this; + } + + public TAPositionBuilder atLocalPosition(int offset, int length, int index) { + switch (pos.type) { + // local variable + case LOCAL_VARIABLE: + pos.lvarOffset = new int[] { offset }; + pos.lvarLength = new int[] { length }; + pos.lvarIndex = new int[] { index }; + break; + default: + throw new IllegalArgumentException("invalid field for given type: " + pos.type); + } + return this; + } + + public TAPositionBuilder atParameterIndex(int index) { + switch (pos.type) { + // type parameters + case CLASS_TYPE_PARAMETER: + case METHOD_TYPE_PARAMETER: + // method parameter + case METHOD_FORMAL_PARAMETER: + pos.parameter_index = index; + break; + default: + throw new IllegalArgumentException("invalid field for given type: " + pos.type); + } + return this; + } + + public TAPositionBuilder atParamBound(int param, int bound) { + switch (pos.type) { + // type parameters bounds + case CLASS_TYPE_PARAMETER_BOUND: + case METHOD_TYPE_PARAMETER_BOUND: + pos.parameter_index = param; + pos.bound_index = bound; + break; + default: + throw new IllegalArgumentException("invalid field for given type: " + pos.type); + } + return this; + } + + public TAPositionBuilder atWildcardPosition(TypeAnnotation.Position pos) { + switch (pos.type) { + // wildcards + case WILDCARD_BOUND: + pos.wildcard_position = pos; + break; + default: + throw new IllegalArgumentException("invalid field for given type: " + pos.type); + } + return this; + } + + public TAPositionBuilder atTypeIndex(int index) { + switch (pos.type) { + // class extends or implements clauses + case CLASS_EXTENDS: + // throws + case THROWS: + pos.type_index = index; + break; + default: + throw new IllegalArgumentException("invalid field for given type: " + pos.type); + } + return this; + } + + public TAPositionBuilder atOffsetWithIndex(int offset, int index) { + switch (pos.type) { + // method type argument: wasn't specified + case NEW_TYPE_ARGUMENT: + case METHOD_TYPE_ARGUMENT: + pos.offset = offset; + pos.type_index = index; + break; + default: + throw new IllegalArgumentException("invalid field for given type: " + pos.type); + } + return this; + } + + public TAPositionBuilder atGenericLocation(Integer ...loc) { + pos.location = Arrays.asList(loc); + pos.type = pos.type.getGenericComplement(); + return this; + } + }*/ + + /////////////////////// Equality testing ///////////////////// + private static boolean areEquals(int a, int b) { + return a == b || a == IGNORE_VALUE || b == IGNORE_VALUE; + } + + private static boolean areEquals(int[] a, int[] a2) { + if (a==a2) + return true; + if (a==null || a2==null) + return false; + + int length = a.length; + if (a2.length != length) + return false; + + for (int i=0; i annotations, ClassFile cf) throws InvalidIndex, UnexpectedEntry { + String properName = "L" + name + ";"; + for (TypeAnnotation anno : annotations) { + String actualName = cf.constant_pool.getUTF8Value(anno.annotation.type_index); + if (properName.equals(actualName)) + return anno; + } + return null; + } + + public static boolean compare(Map expectedAnnos, + List actualAnnos, ClassFile cf) throws InvalidIndex, UnexpectedEntry { + if (actualAnnos.size() != expectedAnnos.size()) { + throw new ComparisionException("Wrong number of annotations", + expectedAnnos, + actualAnnos); + } + + for (Map.Entry e : expectedAnnos.entrySet()) { + String aName = e.getKey(); + TypeAnnotation.Position expected = e.getValue(); + TypeAnnotation actual = findAnnotation(aName, actualAnnos, cf); + if (actual == null) + throw new ComparisionException("Expected annotation not found: " + aName); + + // TODO: you currently get an exception if the test case does not use all necessary + // annotation attributes, e.g. forgetting the offset for a local variable. + // It would be nicer to give an understandable warning instead. + if (!areEquals(expected, actual.position)) { + throw new ComparisionException("Unexpected position for annotation : " + aName + + "\n Expected: " + expected.toString() + + "\n Found: " + actual.position.toString()); + } + } + return true; + } +} + +class ComparisionException extends RuntimeException { + private static final long serialVersionUID = -3930499712333815821L; + + public final Map expected; + public final List found; + + public ComparisionException(String message) { + this(message, null, null); + } + + public ComparisionException(String message, Map expected, List found) { + super(message); + this.expected = expected; + this.found = found; + } + + public String toString() { + String str = super.toString(); + if (expected != null && found != null) { + str += "\n\tExpected: " + expected.size() + " annotations; but found: " + found.size() + " annotations\n" + + " Expected: " + expected + + "\n Found: " + found; + } + return str; + } +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/RepeatingTypeAnnotations.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/RepeatingTypeAnnotations.java new file mode 100644 index 00000000000..2755b4871c7 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/RepeatingTypeAnnotations.java @@ -0,0 +1,75 @@ +/* + * 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. + */ + +import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; + +/* + * @test + * @summary Test population of reference info for repeating type annotations + * @compile -g Driver.java ReferenceInfoUtil.java RepeatingTypeAnnotations.java + * @run main Driver RepeatingTypeAnnotations + * @author Werner Dietl + */ +public class RepeatingTypeAnnotations { + // Field types + @TADescription(annotation = "RTAs", type = FIELD) + public String fieldAsPrimitive() { + return "@RTA @RTA int test;"; + } + + // Method returns + @TADescription(annotation = "RTAs", type = METHOD_RETURN) + public String methodReturn1() { + return "@RTA @RTA int test() { return 0; }"; + } + + @TADescription(annotation = "RTAs", type = METHOD_RETURN) + public String methodReturn2() { + return "@RTAs({@RTA, @RTA}) int test() { return 0; }"; + } + + // Method parameters + @TADescriptions({ + @TADescription(annotation = "RTAs", type = METHOD_FORMAL_PARAMETER, + paramIndex = 0), + @TADescription(annotation = "RTBs", type = METHOD_FORMAL_PARAMETER, + paramIndex = 0, + genericLocation = { 3, 0 }) + }) + public String methodParam1() { + return "void m(@RTA @RTA List<@RTB @RTB String> p) {}"; + } + + @TADescriptions({ + @TADescription(annotation = "RTAs", type = METHOD_FORMAL_PARAMETER, + paramIndex = 0), + @TADescription(annotation = "RTBs", type = METHOD_FORMAL_PARAMETER, + paramIndex = 0, + genericLocation = { 3, 0 }) + }) + public String methodParam2() { + return "void m(@RTAs({@RTA, @RTA}) List<@RTBs({@RTB, @RTB}) String> p) {}"; + } + + // TODO: test that all other locations work with repeated type annotations. +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/TypeCasts.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/TypeCasts.java new file mode 100644 index 00000000000..c77dcdc5857 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/TypeCasts.java @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2009 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. + */ + +import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; + +/* + * @test + * @summary Test population of reference info for type casts + * @compile -g Driver.java ReferenceInfoUtil.java TypeCasts.java + * @run main Driver TypeCasts + */ +public class TypeCasts { + + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE) + public String returnObject() { + return "Object returnObject() { return (@TA String)null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = CAST, + genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TC", type = CAST, + genericLocation = { 0, 0, 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String returnObjectArray() { + return "Object returnObjectArray() { return (@TC String @TA [] @TB [])null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = CAST, + genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String returnObjectGeneric() { + return "Object returnObjectGeneric() { return (@TA List<@TB String>)null; }"; + } + + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE) + public String returnPrim() { + return "Object returnPrim() { return (@TA int)0; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = CAST, + genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String returnPrimArray() { + return "Object returnPrimArray() { return (@TB int @TA [])null; }"; + } + + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE) + public String initObject() { + return "void initObject() { Object a = (@TA String)null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = CAST, + genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String initObjectArray() { + return "void initObjectArray() { Object a = (@TB String @TA [])null; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = CAST, + genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String initObjectGeneric() { + return "void initObjectGeneric() { Object a = (@TA List<@TB String>)null; }"; + } + + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE) + public String initPrim() { + return "void initPrim() { Object a = (@TA int)0; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = CAST, + genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String initPrimArray() { + return "void initPrimArray() { Object a = (@TB int @TA [])null; }"; + } + + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE) + public String eqtestObject() { + return "void eqtestObject() { if (null == (@TA String)null); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = CAST, + genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String eqtestObjectArray() { + return "void eqtestObjectArray() { if (null == (@TB String @TA [])null); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = CAST, + genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String eqtestObjectGeneric() { + return "void eqtestObjectGeneric() { if (null == (@TA List<@TB String >)null); }"; + } + + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE) + // compiler optimizes away compile time constants casts + public String eqtestPrim() { + return "void eqtestPrim(int a) { if (0 == (@TA int)a); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = CAST, + genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String eqtestPrimArray() { + return "void eqtestPrimArray() { if (null == (@TB int @TA [])null); }"; + } + +} diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/TypeTests.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/TypeTests.java new file mode 100644 index 00000000000..5aa07b88db6 --- /dev/null +++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/TypeTests.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2009 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. + */ + +import static com.sun.tools.classfile.TypeAnnotation.TargetType.*; + +/* + * @test + * @summary Test population of reference info for class literals + * @compile -g Driver.java ReferenceInfoUtil.java TypeTests.java + * @run main Driver TypeTests + */ +public class TypeTests { + + @TADescription(annotation = "TA", type = INSTANCEOF, offset = ReferenceInfoUtil.IGNORE_VALUE) + public String returnObject() { + return "Object returnObject() { return null instanceof @TA String; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = INSTANCEOF, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = INSTANCEOF, + genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TC", type = INSTANCEOF, + genericLocation = { 0, 0, 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String returnObjectArray() { + return "Object returnObjectArray() { return null instanceof @TC String @TA [] @TB []; }"; + } + + // no type test for primitives + + @TADescriptions({ + @TADescription(annotation = "TA", type = INSTANCEOF, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = INSTANCEOF, + genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TC", type = INSTANCEOF, + genericLocation = { 0, 0, 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String returnPrimArray() { + return "Object returnPrimArray() { return null instanceof @TC int @TA [] @TB []; }"; + } + + // no void + // no void array + + @TADescription(annotation = "TA", type = INSTANCEOF, offset = ReferenceInfoUtil.IGNORE_VALUE) + public String initObject() { + return "void initObject() { Object a = null instanceof @TA String; }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = INSTANCEOF, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = INSTANCEOF, + genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TC", type = INSTANCEOF, + genericLocation = { 0, 0, 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String initObjectArray() { + return "void initObjectArray() { Object a = null instanceof @TC String @TA [] @TB []; }"; + } + + // no primitive instanceof + + @TADescriptions({ + @TADescription(annotation = "TA", type = INSTANCEOF, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = INSTANCEOF, + genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TC", type = INSTANCEOF, + genericLocation = { 0, 0, 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String initPrimArray() { + return "void initPrimArray() { Object a = null instanceof @TC int @TA [] @TB []; }"; + } + + // no void + // no void array + + @TADescription(annotation = "TA", type = INSTANCEOF, offset = ReferenceInfoUtil.IGNORE_VALUE) + public String eqtestObject() { + return "void eqtestObject() { if (true == (null instanceof @TA String)); }"; + } + + @TADescriptions({ + @TADescription(annotation = "TA", type = INSTANCEOF, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = INSTANCEOF, + genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TC", type = INSTANCEOF, + genericLocation = { 0, 0, 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String eqtestObjectArray() { + return "void eqtestObjectArray() { if (true == (null instanceof @TC String @TA [] @TB [])); }"; + } + + // no primitives + + @TADescriptions({ + @TADescription(annotation = "TA", type = INSTANCEOF, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TB", type = INSTANCEOF, + genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE), + @TADescription(annotation = "TC", type = INSTANCEOF, + genericLocation = { 0, 0, 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE) + }) + public String eqtestPrimArray() { + return "void eqtestPrimArray() { if (true == (null instanceof @TC int @TA [] @TB [])); }"; + } + + // no void + // no void array + +} diff --git a/langtools/test/tools/javac/api/EndPositions.java b/langtools/test/tools/javac/api/EndPositions.java index 1971a7dd5ac..f791cc7666b 100644 --- a/langtools/test/tools/javac/api/EndPositions.java +++ b/langtools/test/tools/javac/api/EndPositions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, 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 @@ -28,11 +28,7 @@ * an annotation processor is present */ -import com.sun.source.tree.ClassTree; -import com.sun.source.tree.CompilationUnitTree; -import com.sun.source.tree.Tree; import com.sun.source.util.JavacTask; -import com.sun.source.util.Trees; import java.io.IOException; import java.net.URI; import java.util.Arrays; @@ -72,16 +68,17 @@ public class EndPositions extends AbstractProcessor { JavacTask task = (JavacTask)javac.getTask(null, null, diagnostics, options, null, compilationUnits); boolean valid = task.call(); if (valid) - throw new AssertionError("Compilation succeeded unexpectedly"); + throw new AssertionError("Expected one error, but found none."); List> errors = diagnostics.getDiagnostics(); if (errors.size() != 1) - throw new AssertionError("Expected one error only, but found " + errors.size() + " errors"); + throw new AssertionError("Expected one error only, but found " + errors.size() + "; errors: " + errors); Diagnostic error = errors.get(0); if (error.getStartPosition() >= error.getEndPosition()) throw new AssertionError("Expected start to be less than end position: start [" + - error.getStartPosition() + "], end [" + error.getEndPosition() +"]"); + error.getStartPosition() + "], end [" + error.getEndPosition() +"]" + + "; diagnostics code: " + error.getCode()); System.out.println("All is good!"); } diff --git a/langtools/test/tools/javac/diags/CheckResourceKeys.java b/langtools/test/tools/javac/diags/CheckResourceKeys.java index 4c10b1a9878..bb9e10bd7cf 100644 --- a/langtools/test/tools/javac/diags/CheckResourceKeys.java +++ b/langtools/test/tools/javac/diags/CheckResourceKeys.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, 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 @@ -200,6 +200,7 @@ public class CheckResourceKeys { Set needToInvestigate = new TreeSet(Arrays.asList( + "compiler.misc.fatal.err.cant.close.loader", // Supressed by JSR308 "compiler.err.cant.read.file", // UNUSED "compiler.err.illegal.self.ref", // UNUSED "compiler.err.io.exception", // UNUSED diff --git a/langtools/test/tools/javac/diags/examples.not-yet.txt b/langtools/test/tools/javac/diags/examples.not-yet.txt index 3583063294e..437d61d2406 100644 --- a/langtools/test/tools/javac/diags/examples.not-yet.txt +++ b/langtools/test/tools/javac/diags/examples.not-yet.txt @@ -48,6 +48,7 @@ compiler.misc.bad.enclosing.class # bad class file compiler.misc.bad.enclosing.method # bad class file compiler.misc.bad.runtime.invisible.param.annotations # bad class file compiler.misc.bad.signature # bad class file +compiler.misc.bad.type.annotation.value compiler.misc.base.membership # UNUSED compiler.misc.ccf.found.later.version compiler.misc.ccf.unrecognized.attribute diff --git a/langtools/test/tools/javac/diags/examples/CantAnnotateNestedType.java b/langtools/test/tools/javac/diags/examples/CantAnnotateNestedType.java new file mode 100644 index 00000000000..30d4572e601 --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/CantAnnotateNestedType.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2012, 2013, 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. + */ + +// key: compiler.err.cant.annotate.nested.type + +import java.lang.annotation.*; + +class CantAnnotateStaticClass { + @Target(ElementType.TYPE_USE) + @interface A {} + + interface Outer { + interface Inner {} + } + + // Error: + @A Outer.Inner f; + + // OK: + @A Outer g; +} diff --git a/langtools/test/tools/javac/diags/examples/CantAnnotateStaticClass.java b/langtools/test/tools/javac/diags/examples/CantAnnotateStaticClass.java new file mode 100644 index 00000000000..d3505bbd461 --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/CantAnnotateStaticClass.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2012, 2013, 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. + */ + +// key: compiler.err.cant.annotate.static.class + +import java.lang.annotation.*; + +class CantAnnotateStaticClass { + @Target(ElementType.TYPE_USE) + @interface A {} + + static class Outer { + class Inner {} + } + + // Error: + @A Outer.Inner f; + + // OK: + @A Outer g; +} diff --git a/langtools/test/tools/javac/diags/examples/IncorrectReceiverType.java b/langtools/test/tools/javac/diags/examples/IncorrectReceiverType.java new file mode 100644 index 00000000000..548067b503b --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/IncorrectReceiverType.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2012, 2013, 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. + */ + +// key: compiler.err.incorrect.receiver.type + +class IncorrectReceiverType { + void m(Object this) {} +} diff --git a/langtools/test/tools/javac/diags/examples/NoAnnotationsOnDotClass.java b/langtools/test/tools/javac/diags/examples/NoAnnotationsOnDotClass.java new file mode 100644 index 00000000000..0ce65530e6f --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/NoAnnotationsOnDotClass.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2012, 2013, 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. + */ + +// key: compiler.err.no.annotations.on.dot.class + +class NoAnnotationsOnDotClass { + @Target(ElementType.TYPE_USE) + @interface A {} + + Object o = @A Object.class; +} diff --git a/langtools/test/tools/javac/diags/examples/ThisAsIdentifier.java b/langtools/test/tools/javac/diags/examples/ThisAsIdentifier.java new file mode 100644 index 00000000000..cb3be6172dc --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/ThisAsIdentifier.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2012, 2013, 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. + */ + +// key: compiler.err.this.as.identifier + +class ThisAsIdentifier { + Object this; +} diff --git a/langtools/test/tools/javac/diags/examples/TypeAnnotationsNotSupported.java b/langtools/test/tools/javac/diags/examples/TypeAnnotationsNotSupported.java new file mode 100644 index 00000000000..16e6b8b51d3 --- /dev/null +++ b/langtools/test/tools/javac/diags/examples/TypeAnnotationsNotSupported.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +// key: compiler.err.type.annotations.not.supported.in.source +// key: compiler.warn.source.no.bootclasspath +// options: -source 6 + +@interface Anno { } + +class TypeAnnotationsNotSupported { + void m() { + int i = (@Anno int) 3.14; + } +} diff --git a/langtools/test/tools/javac/failover/CheckAttributedTree.java b/langtools/test/tools/javac/failover/CheckAttributedTree.java index 14d1e40ca03..8f7fc379a18 100644 --- a/langtools/test/tools/javac/failover/CheckAttributedTree.java +++ b/langtools/test/tools/javac/failover/CheckAttributedTree.java @@ -362,11 +362,18 @@ public class CheckAttributedTree extends JavacTestingAbstractThreadedTest { } Info self = new Info(tree, endPosTable); - check(!mandatoryType(tree) || - (tree.type != null && - checkFields(tree)), - "'null' found in tree ", - self); + if (mandatoryType(tree)) { + check(tree.type != null, + "'null' field 'type' found in tree ", self); + if (tree.type==null) + new Throwable().printStackTrace(); + } + + Field errField = checkFields(tree); + if (errField!=null) { + check(false, + "'null' field '" + errField.getName() + "' found in tree ", self); + } Info prevEncl = encl; encl = self; @@ -395,7 +402,7 @@ public class CheckAttributedTree extends JavacTestingAbstractThreadedTest { } } - boolean checkFields(JCTree t) { + Field checkFields(JCTree t) { List fieldsToCheck = treeUtil.getFieldsOfType(t, excludedFields, Symbol.class, @@ -403,7 +410,7 @@ public class CheckAttributedTree extends JavacTestingAbstractThreadedTest { for (Field f : fieldsToCheck) { try { if (f.get(t) == null) { - return false; + return f; } } catch (IllegalAccessException e) { @@ -411,7 +418,7 @@ public class CheckAttributedTree extends JavacTestingAbstractThreadedTest { //swallow it } } - return true; + return null; } @Override diff --git a/langtools/test/tools/javac/processing/6994946/SemanticErrorTest.2.out b/langtools/test/tools/javac/processing/6994946/SemanticErrorTest.2.out index 37632783d8f..5e68e1d9c15 100644 --- a/langtools/test/tools/javac/processing/6994946/SemanticErrorTest.2.out +++ b/langtools/test/tools/javac/processing/6994946/SemanticErrorTest.2.out @@ -1,4 +1,3 @@ SemanticErrorTest.java:11:46: compiler.err.repeated.interface - compiler.err.proc.messager: Deliberate Error -SemanticErrorTest.java:11:46: compiler.err.repeated.interface -2 errors +2 errors \ No newline at end of file diff --git a/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java b/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java index 33466e65476..13fe97c18af 100644 --- a/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java +++ b/langtools/test/tools/javac/processing/model/element/TestAnonClassNames.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, 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 @@ -78,7 +78,7 @@ public class TestAnonClassNames { @Nesting(LOCAL) class LocalClass{}; - Object o = new /*@Nesting(ANONYMOUS)*/ Object() { // An anonymous annotated class + Object o = new @Nesting(ANONYMOUS) Object() { // An anonymous annotated class public String toString() { return "I have no name!"; } @@ -96,10 +96,9 @@ public class TestAnonClassNames { List names = new ArrayList(); for(Class clazz : classes) { String name = clazz.getName(); - Nesting anno = clazz.getAnnotation(Nesting.class); System.out.format("%s is %s%n", clazz.getName(), - anno == null ? "(unset/ANONYMOUS)" : anno.value()); + clazz.getAnnotation(Nesting.class).value()); testClassName(name); names.add(name); } @@ -158,6 +157,7 @@ public class TestAnonClassNames { } } +@Target({ElementType.TYPE, ElementType.TYPE_USE}) @Retention(RUNTIME) @interface Nesting { NestingKind value(); @@ -185,8 +185,8 @@ class ClassNameProber extends JavacTestingAbstractProcessor { typeElt.getQualifiedName().toString(), typeElt.getKind().toString(), nestingKind.toString()); - Nesting anno = typeElt.getAnnotation(Nesting.class); - if ((anno == null ? NestingKind.ANONYMOUS : anno.value()) != nestingKind) { + + if (typeElt.getAnnotation(Nesting.class).value() != nestingKind) { throw new RuntimeException("Mismatch of expected and reported nesting kind."); } } diff --git a/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.java b/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.java index 70666856a21..2ddcd10bd26 100644 --- a/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.java +++ b/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, 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 @@ -28,7 +28,7 @@ * @summary Modeling type implementing missing interfaces * @library /tools/javac/lib * @build JavacTestingAbstractProcessor TestMissingElement - * @compile -proc:only -XprintRounds -processor TestMissingElement InvalidSource.java + * @compile/fail/ref=TestMissingElement.ref -proc:only -XprintRounds -XDrawDiagnostics -processor TestMissingElement InvalidSource.java */ import java.util.*; diff --git a/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.ref b/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.ref new file mode 100644 index 00000000000..4c31a101dbb --- /dev/null +++ b/langtools/test/tools/javac/processing/model/element/TestMissingElement/TestMissingElement.ref @@ -0,0 +1,49 @@ +Round 1: + input files: {ExpectInterfaces, ExpectSupertype, OK, InvalidSource} + annotations: [ExpectSupertype, ExpectInterfaces] + last round: false +Round 2: + input files: {} + annotations: [] + last round: true +InvalidSource.java:55:42: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:58:44: compiler.err.doesnt.exist: A +InvalidSource.java:61:54: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.package, java.util, null) +InvalidSource.java:64:47: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:67:44: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:70:46: compiler.err.doesnt.exist: A +InvalidSource.java:73:55: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:76:59: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:79:46: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:79:49: compiler.err.cant.resolve.location: kindname.class, B, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:82:44: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:85:46: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:88:50: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:91:45: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:91:48: compiler.err.cant.resolve.location: kindname.class, B, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:94:49: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:97:51: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:97:57: compiler.err.cant.resolve.location: kindname.class, B, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:100:49: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:103:51: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:103:57: compiler.err.cant.resolve.location: kindname.class, B, , , (compiler.misc.location: kindname.class, InvalidSource, null) +InvalidSource.java:106:58: compiler.err.cant.resolve.location: kindname.class, X, , , (compiler.misc.location: kindname.class, InvalidSource, null) +22 errors +check supertype: InvalidSource.TestClassMissingClassA -- !:empty clss A! +check supertype: InvalidSource.TestClassMissingClassAB -- !:empty clss (pkg A).B! +check supertype: InvalidSource.TestClassMissingClass_juA -- !:empty clss (pkg java.util).A! +check supertype: InvalidSource.TestClassTMissingClassAT -- !:empty clss A! +check interfaces: InvalidSource.TestClassMissingIntfA -- !:empty intf A! +check interfaces: InvalidSource.TestClassMissingIntfAB -- !:empty intf (pkg A).B! +check interfaces: InvalidSource.TestClassMissingIntfAOK -- !:empty intf A!, intf OK +check interfaces: InvalidSource.TestClassOKMissingIntfA -- intf OK, !:empty intf A! +check interfaces: InvalidSource.TestClassMissingIntfA_B -- !:empty intf A!, !:empty intf B! +check interfaces: InvalidSource.TestIntfMissingIntfA -- !:empty intf A! +check interfaces: InvalidSource.TestIntfMissingIntfAOK -- !:empty intf A!, intf OK +check interfaces: InvalidSource.TestIntfOKMissingIntfA -- intf OK, !:empty intf A! +check interfaces: InvalidSource.TestIntfMissingIntfAB -- !:empty intf A!, !:empty intf B! +check interfaces: InvalidSource.TestClassTMissingIntfAT -- !:empty intf A! +check interfaces: InvalidSource.TestClassTMissingIntfAT_B -- !:empty intf A!, !:empty intf B! +check interfaces: InvalidSource.TestIntfTMissingIntfAT -- !:empty intf A! +check interfaces: InvalidSource.TestIntfTMissingIntfAT_B -- !:empty intf A!, !:empty intf B! +check interfaces: InvalidSource.TestClassListMissingX -- intf (pkg java.util).List \ No newline at end of file diff --git a/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.java b/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.java index 78808318ba3..ee0b9039737 100644 --- a/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.java +++ b/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2013, 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 @@ -28,7 +28,7 @@ * @author Scott Seligman * @library /tools/javac/lib * @build JavacTestingAbstractProcessor DirectSupersOfErr - * @compile -processor DirectSupersOfErr -proc:only C1.java + * @compile/fail/ref=DirectSupersOfErr.ref -processor DirectSupersOfErr -proc:only -XDrawDiagnostics C1.java */ import java.util.Set; diff --git a/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.ref b/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.ref new file mode 100644 index 00000000000..8fe9c7ed8be --- /dev/null +++ b/langtools/test/tools/javac/processing/model/util/directSupersOfErr/DirectSupersOfErr.ref @@ -0,0 +1,2 @@ +C1.java:24:18: compiler.err.cant.resolve: kindname.class, Bogus, , +1 error diff --git a/langtools/test/tools/javac/tree/TreeKindTest.java b/langtools/test/tools/javac/tree/TreeKindTest.java index 608c45a4df7..8497308afb6 100644 --- a/langtools/test/tools/javac/tree/TreeKindTest.java +++ b/langtools/test/tools/javac/tree/TreeKindTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2013, 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 @@ -29,7 +29,7 @@ import com.sun.source.tree.*; -public class TreeKindTest{ +public class TreeKindTest { public static void main(String... args) { boolean ok = true; @@ -108,6 +108,11 @@ public class TreeKindTest{ ok = ok & verify(k, i, i == ClassTree.class); break; + case ANNOTATION: + case TYPE_ANNOTATION: + ok = ok & verify(k, i, i == AnnotationTree.class); + break; + case OTHER: ok = ok & verify(k, i, i == null); break; diff --git a/langtools/test/tools/javac/tree/TreePosTest.java b/langtools/test/tools/javac/tree/TreePosTest.java index b8f8a36b1b0..8fed3e5c07f 100644 --- a/langtools/test/tools/javac/tree/TreePosTest.java +++ b/langtools/test/tools/javac/tree/TreePosTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, 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 @@ -75,6 +75,7 @@ import com.sun.tools.javac.api.JavacTool; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.tree.EndPosTable; import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.JCTree.JCAnnotatedType; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.tree.JCTree.JCNewClass; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; @@ -100,7 +101,8 @@ import static com.sun.tools.javac.util.Position.NOPOS; * @test * @bug 6919889 * @summary assorted position errors in compiler syntax trees - * @run main TreePosTest -q -r -ef ./tools/javac/typeAnnotations -ef ./tools/javap/typeAnnotations -et ANNOTATED_TYPE . + * OLD: -q -r -ef ./tools/javac/typeAnnotations -ef ./tools/javap/typeAnnotations -et ANNOTATED_TYPE . + * @run main TreePosTest -q -r . */ public class TreePosTest { /** @@ -367,15 +369,24 @@ public class TreePosTest { // e.g. int[][] a = new int[2][]; check("encl.start <= start", encl, self, encl.start <= self.start); check("start <= pos", encl, self, self.start <= self.pos); - if (!(self.tag == TYPEARRAY + if (!( (self.tag == TYPEARRAY || + isAnnotatedArray(self.tree)) && (encl.tag == VARDEF || encl.tag == METHODDEF || - encl.tag == TYPEARRAY))) { + encl.tag == TYPEARRAY || + isAnnotatedArray(encl.tree)) + || + encl.tag == ANNOTATED_TYPE && self.tag == SELECT + )) { check("encl.pos <= start || end <= encl.pos", encl, self, encl.pos <= self.start || self.end <= encl.pos); } check("pos <= end", encl, self, self.pos <= self.end); - if (!(self.tag == TYPEARRAY && encl.tag == TYPEARRAY)) { + if (!( (self.tag == TYPEARRAY || isAnnotatedArray(self.tree)) && + (encl.tag == TYPEARRAY || isAnnotatedArray(encl.tree)) + || + encl.tag == MODIFIERS && self.tag == ANNOTATION + ) ) { check("end <= encl.end", encl, self, self.end <= encl.end); } } @@ -387,6 +398,11 @@ public class TreePosTest { encl = prevEncl; } + private boolean isAnnotatedArray(JCTree tree) { + return tree.hasTag(ANNOTATED_TYPE) && + ((JCAnnotatedType)tree).underlyingType.hasTag(TYPEARRAY); + } + @Override public void visitVarDef(JCVariableDecl tree) { // enum member declarations are desugared in the parser and have @@ -427,7 +443,8 @@ public class TreePosTest { viewer.addEntry(sourcefile, label, encl, self); } - String s = self.tree.toString(); + String s = "encl: " + encl.tree.toString() + + " this: " + self.tree.toString(); String msg = sourcefile.getName() + ": " + label + ": " + "encl:" + encl + " this:" + self + "\n" + s.substring(0, Math.min(80, s.length())).replaceAll("[\r\n]+", " "); diff --git a/langtools/test/tools/javac/treeannotests/AnnoTreeTests.java b/langtools/test/tools/javac/treeannotests/AnnoTreeTests.java new file mode 100644 index 00000000000..0db46b5774b --- /dev/null +++ b/langtools/test/tools/javac/treeannotests/AnnoTreeTests.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2010, 2013, 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. + */ + +/* + * @test + * @build DA TA Test TestProcessor + * @compile -proc:only -processor TestProcessor AnnoTreeTests.java + */ + +@Test(4) +class AnnoTreeTests { + // primitive types + // @TA("int") int i1 = 0; // TODO: Only visible via ClassFile + long i2 = (@TA("long") long) 0; + + // simple array types + // @DA("short") short[] a1; // TODO: Only visible via ClassFile + byte @TA("byte[]") [] a2; + float[] a3 = (@TA("float") float[]) null; + double[] a4 = (double @TA("double[]") []) null; + + // multi-dimensional array types + // (still to come) +} diff --git a/langtools/test/tools/javac/treeannotests/TestProcessor.java b/langtools/test/tools/javac/treeannotests/TestProcessor.java index f74cd3c7cea..8b6c4adb265 100644 --- a/langtools/test/tools/javac/treeannotests/TestProcessor.java +++ b/langtools/test/tools/javac/treeannotests/TestProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, 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 @@ -203,13 +203,16 @@ public class TestProcessor extends AbstractProcessor { * expression name=value. */ String getStringValue(JCExpression e) { - if (e.getTag() == JCTree.ASSIGN) { + if (e.hasTag(JCTree.Tag.ASSIGN)) { JCAssign a = (JCAssign) e; JCExpression rhs = a.rhs; - if (rhs.getTag() == JCTree.LITERAL) { + if (rhs.hasTag(JCTree.Tag.LITERAL)) { JCLiteral l = (JCLiteral) rhs; return (String) l.value; } + } else if (e.hasTag(JCTree.Tag.LITERAL)) { + JCLiteral l = (JCLiteral) e; + return (String) l.value; } throw new IllegalArgumentException(e.toString()); } diff --git a/langtools/test/tools/javac/typeAnnotations/newlocations/BasicTest.out b/langtools/test/tools/javac/typeAnnotations/newlocations/BasicTest.out deleted file mode 100644 index eecd7f7e638..00000000000 --- a/langtools/test/tools/javac/typeAnnotations/newlocations/BasicTest.out +++ /dev/null @@ -1,61 +0,0 @@ -BasicTest.java:47:27: compiler.err.illegal.start.of.type -BasicTest.java:47:28: compiler.err.expected: '{' -BasicTest.java:47:36: compiler.err.expected: token.identifier -BasicTest.java:47:38: compiler.err.illegal.start.of.type -BasicTest.java:47:45: compiler.err.expected: token.identifier -BasicTest.java:47:47: compiler.err.expected: ';' -BasicTest.java:47:62: compiler.err.expected: token.identifier -BasicTest.java:47:84: compiler.err.expected: token.identifier -BasicTest.java:52:22: compiler.err.illegal.start.of.expr -BasicTest.java:52:31: compiler.err.expected: ';' -BasicTest.java:52:37: compiler.err.expected: token.identifier -BasicTest.java:53:30: compiler.err.expected: token.identifier -BasicTest.java:53:31: compiler.err.expected: -> -BasicTest.java:56:23: compiler.err.expected: token.identifier -BasicTest.java:56:24: compiler.err.expected2: '(', '[' -BasicTest.java:56:25: compiler.err.expected: ';' -BasicTest.java:56:27: compiler.err.invalid.meth.decl.ret.type.req -BasicTest.java:56:34: compiler.err.illegal.start.of.type -BasicTest.java:58:34: compiler.err.illegal.start.of.type -BasicTest.java:61:16: compiler.err.illegal.start.of.type -BasicTest.java:61:18: compiler.err.expected: ';' -BasicTest.java:61:24: compiler.err.illegal.start.of.type -BasicTest.java:61:26: compiler.err.expected: ';' -BasicTest.java:61:33: compiler.err.expected: token.identifier -BasicTest.java:61:34: compiler.err.illegal.start.of.type -BasicTest.java:61:35: compiler.err.expected: token.identifier -BasicTest.java:61:37: compiler.err.expected: ';' -BasicTest.java:61:45: compiler.err.expected: token.identifier -BasicTest.java:61:50: compiler.err.expected: token.identifier -BasicTest.java:62:16: compiler.err.expected: token.identifier -BasicTest.java:62:17: compiler.err.expected2: '(', '[' -BasicTest.java:62:18: compiler.err.expected: ';' -BasicTest.java:62:28: compiler.err.illegal.start.of.type -BasicTest.java:62:30: compiler.err.expected: ';' -BasicTest.java:62:36: compiler.err.illegal.start.of.type -BasicTest.java:62:38: compiler.err.expected: ';' -BasicTest.java:62:45: compiler.err.expected: token.identifier -BasicTest.java:62:46: compiler.err.illegal.start.of.type -BasicTest.java:62:47: compiler.err.expected: token.identifier -BasicTest.java:62:49: compiler.err.expected: ';' -BasicTest.java:62:57: compiler.err.expected: token.identifier -BasicTest.java:62:58: compiler.err.illegal.start.of.type -BasicTest.java:62:59: compiler.err.expected: token.identifier -BasicTest.java:64:25: compiler.err.illegal.start.of.type -BasicTest.java:64:27: compiler.err.expected: ';' -BasicTest.java:64:34: compiler.err.expected: token.identifier -BasicTest.java:64:38: compiler.err.expected: token.identifier -BasicTest.java:64:41: compiler.err.illegal.start.of.expr -BasicTest.java:64:50: compiler.err.expected: ';' -BasicTest.java:64:56: compiler.err.expected: token.identifier -BasicTest.java:69:17: compiler.err.expected: ';' -BasicTest.java:69:24: compiler.err.illegal.start.of.type -BasicTest.java:69:30: compiler.err.expected: ';' -BasicTest.java:69:59: compiler.err.expected: token.identifier -BasicTest.java:69:74: compiler.err.expected: ';' -BasicTest.java:74:22: compiler.err.expected: token.identifier -BasicTest.java:74:24: compiler.err.expected: ';' -BasicTest.java:74:25: compiler.err.illegal.start.of.type -BasicTest.java:74:33: compiler.err.expected: ';' -BasicTest.java:77:2: compiler.err.premature.eof -60 errors diff --git a/langtools/test/tools/javap/typeAnnotations/JSR175Annotations.java b/langtools/test/tools/javap/typeAnnotations/JSR175Annotations.java new file mode 100644 index 00000000000..3504cb520bb --- /dev/null +++ b/langtools/test/tools/javap/typeAnnotations/JSR175Annotations.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +import java.io.*; +import com.sun.tools.classfile.*; + +/* + * @test JSR175Annotations + * @bug 6843077 + * @summary test that only type annotations are recorded as such in classfile + */ + +public class JSR175Annotations { + public static void main(String[] args) throws Exception { + new JSR175Annotations().run(); + } + + public void run() throws Exception { + File javaFile = writeTestFile(); + File classFile = compileTestFile(javaFile); + + ClassFile cf = ClassFile.read(classFile); + for (Field f : cf.fields) { + test(cf, f); + } + for (Method m: cf.methods) { + test(cf, m); + } + + countAnnotations(); + + if (errors > 0) + throw new Exception(errors + " errors found"); + System.out.println("PASSED"); + } + + void test(ClassFile cf, Method m) { + test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); + test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); + } + + void test(ClassFile cf, Field m) { + test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); + test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void test(ClassFile cf, Method m, String name, boolean visible) { + int index = m.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = m.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + } + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void test(ClassFile cf, Field m, String name, boolean visible) { + int index = m.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = m.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + } + } + + File writeTestFile() throws IOException { + File f = new File("Test.java"); + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); + out.println("import java.lang.annotation.*;"); + out.println("abstract class Test { "); + out.println(" @Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})"); + out.println(" @Retention(RetentionPolicy.RUNTIME)"); + out.println(" @interface A { }"); + out.println(" @A String m;"); + out.println(" @A String method(@A String a) {"); + out.println(" return a;"); + out.println(" }"); + out.println("}"); + out.close(); + return f; + } + + File compileTestFile(File f) { + int rc = com.sun.tools.javac.Main.compile(new String[] { "-source", "1.8", "-g", f.getPath() }); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + String path = f.getPath(); + return new File(path.substring(0, path.length() - 5) + ".class"); + } + + void countAnnotations() { + int expected_visibles = 0, expected_invisibles = 0; + int expected_all = expected_visibles + expected_invisibles; + + if (expected_all != all) { + errors++; + System.err.println("expected " + expected_all + + " annotations but found " + all); + } + + if (expected_visibles != visibles) { + errors++; + System.err.println("expected " + expected_visibles + + " visibles annotations but found " + visibles); + } + + if (expected_invisibles != invisibles) { + errors++; + System.err.println("expected " + expected_invisibles + + " invisibles annotations but found " + invisibles); + } + + } + + int errors; + int all; + int visibles; + int invisibles; +} diff --git a/langtools/test/tools/javap/typeAnnotations/NewArray.java b/langtools/test/tools/javap/typeAnnotations/NewArray.java new file mode 100644 index 00000000000..bcb25efc047 --- /dev/null +++ b/langtools/test/tools/javap/typeAnnotations/NewArray.java @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +import java.io.*; +import com.sun.tools.classfile.*; + +/* + * @test NewArray + * @bug 6843077 + * @summary test that all type annotations are present in the classfile + */ + +public class NewArray { + public static void main(String[] args) throws Exception { + new NewArray().run(); + } + + public void run() throws Exception { + File javaFile = writeTestFile(); + File classFile = compileTestFile(javaFile); + + ClassFile cf = ClassFile.read(classFile); + test(cf); + for (Field f : cf.fields) { + test(cf, f); + } + for (Method m: cf.methods) { + test(cf, m); + } + + countAnnotations(); + + if (errors > 0) + throw new Exception(errors + " errors found"); + System.out.println("PASSED"); + } + + void test(ClassFile cf) { + test(cf, Attribute.RuntimeVisibleTypeAnnotations, true); + test(cf, Attribute.RuntimeInvisibleTypeAnnotations, false); + } + + void test(ClassFile cf, Method m) { + test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); + test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); + } + + void test(ClassFile cf, Field m) { + test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); + test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void test(ClassFile cf, String name, boolean visible) { + int index = cf.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = cf.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + } + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void test(ClassFile cf, Method m, String name, boolean visible) { + int index = m.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = m.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + } + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void test(ClassFile cf, Field m, String name, boolean visible) { + int index = m.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = m.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + } + } + + File writeTestFile() throws IOException { + File f = new File("Test.java"); + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); + out.println("import java.lang.annotation.*;"); + out.println("import java.util.*;"); + out.println("class Test { "); + out.println(" @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})"); + out.println(" @interface A { }"); + + out.println(" void test() {"); + out.println(" Object a = new @A String @A [5] @A [];"); + out.println(" Object b = new @A String @A [5] @A [3];"); + out.println(" Object c = new @A String @A [] @A [] {};"); + out.println(" }"); + out.println("}"); + + out.close(); + return f; + } + + File compileTestFile(File f) { + int rc = com.sun.tools.javac.Main.compile(new String[] { "-source", "1.8", "-g", f.getPath() }); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + String path = f.getPath(); + return new File(path.substring(0, path.length() - 5) + ".class"); + } + + void countAnnotations() { + int expected_visibles = 0, expected_invisibles = 9; + int expected_all = expected_visibles + expected_invisibles; + + if (expected_all != all) { + errors++; + System.err.println("expected " + expected_all + + " annotations but found " + all); + } + + if (expected_visibles != visibles) { + errors++; + System.err.println("expected " + expected_visibles + + " visibles annotations but found " + visibles); + } + + if (expected_invisibles != invisibles) { + errors++; + System.err.println("expected " + expected_invisibles + + " invisibles annotations but found " + invisibles); + } + + } + + int errors; + int all; + int visibles; + int invisibles; +} diff --git a/langtools/test/tools/javap/typeAnnotations/Presence.java b/langtools/test/tools/javap/typeAnnotations/Presence.java new file mode 100644 index 00000000000..6ed86083eb8 --- /dev/null +++ b/langtools/test/tools/javap/typeAnnotations/Presence.java @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +import java.io.*; +import java.lang.annotation.ElementType; + +import com.sun.tools.classfile.*; + +/* + * @test Presence + * @bug 6843077 + * @summary test that all type annotations are present in the classfile + */ + +public class Presence { + public static void main(String[] args) throws Exception { + new Presence().run(); + } + + public void run() throws Exception { + File javaFile = writeTestFile(); + File classFile = compileTestFile(javaFile); + + ClassFile cf = ClassFile.read(classFile); + test(cf); + for (Field f : cf.fields) { + test(cf, f); + } + for (Method m: cf.methods) { + test(cf, m); + } + + countAnnotations(); + + if (errors > 0) + throw new Exception(errors + " errors found"); + System.out.println("PASSED"); + } + + void test(ClassFile cf) { + test(cf, Attribute.RuntimeVisibleTypeAnnotations, true); + test(cf, Attribute.RuntimeInvisibleTypeAnnotations, false); + } + + void test(ClassFile cf, Method m) { + test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); + test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); + } + + void test(ClassFile cf, Field m) { + test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); + test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void test(ClassFile cf, String name, boolean visible) { + int index = cf.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = cf.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + } + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void test(ClassFile cf, Method m, String name, boolean visible) { + int index = m.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = m.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + } + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void test(ClassFile cf, Field m, String name, boolean visible) { + int index = m.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = m.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + } + } + + File writeTestFile() throws IOException { + File f = new File("Test.java"); + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); + out.println("import java.util.*;"); + out.println("import java.lang.annotation.*;"); + + out.println("class Test<@Test.A T extends @Test.A List<@Test.A String>> { "); + out.println(" @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})"); + out.println(" @interface A { }"); + + out.println(" Map<@A String, Map<@A String, @A String>> f1;"); + + out.println(" <@A TM extends @A List<@A String>>"); + out.println(" Map<@A String, @A List<@A String>>"); + out.println(" method(@A Test this, List<@A String> @A [] param1, String @A [] @A ... param2)"); + out.println(" throws @A Exception {"); + out.println(" @A String lc1 = null;"); + out.println(" @A List<@A String> lc2 = null;"); + out.println(" @A String @A [] [] @A[] lc3 = null;"); + out.println(" List> lc4 = null;"); + out.println(" Object lc5 = (@A List<@A String>) null;"); + out.println(" boolean lc6 = lc1 instanceof @A String;"); + out.println(" boolean lc7 = lc5 instanceof @A String @A [] @A [];"); + out.println(" new @A ArrayList<@A String>();"); + out.println(" Object lc8 = new @A String @A [4];"); + out.println(" try {"); + out.println(" Object lc10 = int.class;"); + out.println(" } catch (@A Exception e) { e.toString(); }"); + out.println(" return null;"); + out.println(" }"); + out.println(" void vararg1(String @A ... t) { } "); + out.println("}"); + out.close(); + return f; + } + + File compileTestFile(File f) { + int rc = com.sun.tools.javac.Main.compile(new String[] { "-source", "1.8", "-g", f.getPath() }); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + String path = f.getPath(); + return new File(path.substring(0, path.length() - 5) + ".class"); + } + + void countAnnotations() { + int expected_visibles = 0, expected_invisibles = 38; + int expected_all = expected_visibles + expected_invisibles; + + if (expected_all != all) { + errors++; + System.err.println("expected " + expected_all + + " annotations but found " + all); + } + + if (expected_visibles != visibles) { + errors++; + System.err.println("expected " + expected_visibles + + " visibles annotations but found " + visibles); + } + + if (expected_invisibles != invisibles) { + errors++; + System.err.println("expected " + expected_invisibles + + " invisibles annotations but found " + invisibles); + } + + } + + int errors; + int all; + int visibles; + int invisibles; +} diff --git a/langtools/test/tools/javap/typeAnnotations/PresenceInner.java b/langtools/test/tools/javap/typeAnnotations/PresenceInner.java new file mode 100644 index 00000000000..1b859206a3d --- /dev/null +++ b/langtools/test/tools/javap/typeAnnotations/PresenceInner.java @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2009, 2013, 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. + */ + +import java.io.*; +import com.sun.tools.classfile.*; + +/* + * @test PresenceInner + * @bug 6843077 + * @summary test that annotations in inner types count only once + */ + +public class PresenceInner { + public static void main(String[] args) throws Exception { + new PresenceInner().run(); + } + + public void run() throws Exception { + File javaFile = writeTestFile(); + File classFile = compileTestFile(javaFile); + + ClassFile cf = ClassFile.read(classFile); + test(cf); + for (Field f : cf.fields) { + test(cf, f); + } + for (Method m: cf.methods) { + test(cf, m); + } + + // counts are zero when vising outer class + countAnnotations(0); + + // visit inner class + File innerFile = new File("Test$1Inner.class"); + ClassFile icf = ClassFile.read(innerFile); + test(icf); + for (Field f : icf.fields) { + test(cf, f); + } + for (Method m: icf.methods) { + test(cf, m); + } + + countAnnotations(1); + if (errors > 0) + throw new Exception(errors + " errors found"); + System.out.println("PASSED"); + } + + void test(ClassFile cf) { + test(cf, Attribute.RuntimeVisibleTypeAnnotations, true); + test(cf, Attribute.RuntimeInvisibleTypeAnnotations, false); + } + + void test(ClassFile cf, Method m) { + test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); + test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); + } + + void test(ClassFile cf, Field m) { + test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); + test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void test(ClassFile cf, String name, boolean visible) { + int index = cf.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = cf.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + } + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void test(ClassFile cf, Method m, String name, boolean visible) { + int index = m.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = m.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + } + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void test(ClassFile cf, Field m, String name, boolean visible) { + int index = m.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = m.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + } + } + + File writeTestFile() throws IOException { + File f = new File("Test.java"); + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); + + out.println("import java.lang.annotation.*;"); + out.println("class Test {"); + out.println(" void method() {"); + out.println(" class Inner { }"); + out.println(" }"); + out.println("}"); + out.println("@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})"); + out.println("@interface A { }"); + out.close(); + System.out.println(f.getAbsolutePath()); + return f; + } + + File compileTestFile(File f) { + int rc = com.sun.tools.javac.Main.compile(new String[] { "-source", "1.8", "-g", f.getPath() }); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + String path = f.getPath(); + return new File(path.substring(0, path.length() - 5) + ".class"); + } + + void countAnnotations(int expected_invisibles) { + int expected_visibles = 0; + int expected_all = expected_visibles + expected_invisibles; + + if (expected_all != all) { + errors++; + System.err.println("expected " + expected_all + + " annotations but found " + all); + } + + if (expected_visibles != visibles) { + errors++; + System.err.println("expected " + expected_visibles + + " visibles annotations but found " + visibles); + } + + if (expected_invisibles != invisibles) { + errors++; + System.err.println("expected " + expected_invisibles + + " invisibles annotations but found " + invisibles); + } + + } + + int errors; + int all; + int visibles; + int invisibles; +} diff --git a/langtools/test/tools/javap/typeAnnotations/T6855990.java b/langtools/test/tools/javap/typeAnnotations/T6855990.java new file mode 100644 index 00000000000..bc24eda6f11 --- /dev/null +++ b/langtools/test/tools/javap/typeAnnotations/T6855990.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2009, 2013, 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. + */ + +import java.io.*; + +/* + * @test + * @bug 6855990 + * @summary InstructionDetailWriter should support new 308 annotations attribute + */ + +public class T6855990 { + public static void main(String[] args) throws Exception { + new T6855990().run(); + } + + public void run() throws Exception { + @Simple String[] args = { "-c", "-XDdetails:typeAnnotations", "T6855990" }; + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + int rc = com.sun.tools.javap.Main.run(args, pw); + pw.close(); + String out = sw.toString(); + System.out.println(out); + if (out.indexOf("@Simple: LOCAL_VARIABLE") == -1) + throw new Exception("expected output not found"); + } +} + +@interface Simple { } + diff --git a/langtools/test/tools/javap/typeAnnotations/TypeCasts.java b/langtools/test/tools/javap/typeAnnotations/TypeCasts.java new file mode 100644 index 00000000000..589b91fa13e --- /dev/null +++ b/langtools/test/tools/javap/typeAnnotations/TypeCasts.java @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2009, 2013, 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. + */ + +import java.io.*; +import com.sun.tools.classfile.*; + +/* + * @test + * @bug 6843077 + * @summary test that typecasts annotation are emitted if only the cast + * expression is optimized away + */ + +public class TypeCasts { + public static void main(String[] args) throws Exception { + new TypeCasts().run(); + } + + public void run() throws Exception { + File javaFile = writeTestFile(); + File classFile = compileTestFile(javaFile); + + ClassFile cf = ClassFile.read(classFile); + test(cf); + for (Field f : cf.fields) { + test(cf, f); + } + for (Method m: cf.methods) { + test(cf, m); + } + + countAnnotations(); + + if (errors > 0) + throw new Exception(errors + " errors found"); + System.out.println("PASSED"); + } + + void test(ClassFile cf) { + test(cf, Attribute.RuntimeVisibleTypeAnnotations, true); + test(cf, Attribute.RuntimeInvisibleTypeAnnotations, false); + } + + void test(ClassFile cf, Method m) { + test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); + test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); + } + + void test(ClassFile cf, Field m) { + test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); + test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void test(ClassFile cf, String name, boolean visible) { + int index = cf.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = cf.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + } + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void test(ClassFile cf, Method m, String name, boolean visible) { + int index = m.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = m.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + } + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void test(ClassFile cf, Field m, String name, boolean visible) { + int index = m.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = m.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + } + } + + + File writeTestFile() throws IOException { + File f = new File("Test.java"); + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); + out.println("import java.lang.annotation.*;"); + out.println("class Test { "); + out.println(" @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})"); + out.println(" @interface A { }"); + + out.println(" void emit() {"); + out.println(" Object o = null;"); + out.println(" String s = null;"); + + out.println(" String a0 = (@A String)o;"); + out.println(" Object a1 = (@A Object)o;"); + + out.println(" String b0 = (@A String)s;"); + out.println(" Object b1 = (@A Object)s;"); + out.println(" }"); + + out.println(" void alldeadcode() {"); + out.println(" Object o = null;"); + + out.println(" if (false) {"); + out.println(" String a0 = (@A String)o;"); + out.println(" }"); + out.println(" }"); + + out.println("}"); + out.close(); + return f; + } + + File compileTestFile(File f) { + int rc = com.sun.tools.javac.Main.compile(new String[] { "-source", "1.8", "-g", f.getPath() }); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + String path = f.getPath(); + return new File(path.substring(0, path.length() - 5) + ".class"); + } + + void countAnnotations() { + int expected_visibles = 0, expected_invisibles = 4; + int expected_all = expected_visibles + expected_invisibles; + + if (expected_all != all) { + errors++; + System.err.println("expected " + expected_all + + " annotations but found " + all); + } + + if (expected_visibles != visibles) { + errors++; + System.err.println("expected " + expected_visibles + + " visibles annotations but found " + visibles); + } + + if (expected_invisibles != invisibles) { + errors++; + System.err.println("expected " + expected_invisibles + + " invisibles annotations but found " + invisibles); + } + + } + + int errors; + int all; + int visibles; + int invisibles; +} diff --git a/langtools/test/tools/javap/typeAnnotations/Visibility.java b/langtools/test/tools/javap/typeAnnotations/Visibility.java new file mode 100644 index 00000000000..9fe348bad6c --- /dev/null +++ b/langtools/test/tools/javap/typeAnnotations/Visibility.java @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2008, 2013, 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. + */ + +import java.io.*; +import com.sun.tools.classfile.*; + +/* + * @test Visibility + * @bug 6843077 + * @summary test that type annotations are recorded in the classfile + */ + +public class Visibility { + public static void main(String[] args) throws Exception { + new Visibility().run(); + } + + public void run() throws Exception { + File javaFile = writeTestFile(); + File classFile = compileTestFile(javaFile); + + ClassFile cf = ClassFile.read(classFile); + for (Method m: cf.methods) { + test(cf, m); + } + + countAnnotations(); + + if (errors > 0) + throw new Exception(errors + " errors found"); + System.out.println("PASSED"); + } + + void test(ClassFile cf, Method m) { + test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); + test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void test(ClassFile cf, Method m, String name, boolean visible) { + int index = m.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = m.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + } + } + + File writeTestFile() throws IOException { + File f = new File("Test.java"); + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); + out.println("import java.lang.annotation.ElementType;"); + out.println("import java.lang.annotation.Retention;"); + out.println("import java.lang.annotation.RetentionPolicy;"); + out.println("import java.lang.annotation.Target;"); + out.println("abstract class Test { "); + // visible annotations: RUNTIME + out.println(" @Retention(RetentionPolicy.RUNTIME)"); + out.println(" @Target(ElementType.TYPE_USE)"); + out.println(" @interface A { }"); + out.println(" void visible(@A Test this) { }"); + + // invisible annotations: CLASS + out.println(" @Retention(RetentionPolicy.CLASS)"); + out.println(" @Target(ElementType.TYPE_USE)"); + out.println(" @interface B { }"); + out.println(" void invisible(@B Test this) { }"); + + // source annotations + out.println(" @Retention(RetentionPolicy.SOURCE)"); + out.println(" @Target(ElementType.TYPE_USE)"); + out.println(" @interface C { }"); + out.println(" void source(@C Test this) { }"); + + // default visibility: CLASS + out.println(" @Target(ElementType.TYPE_USE)"); + out.println(" @interface D { }"); + out.println(" void def(@D Test this) { }"); + out.println("}"); + out.close(); + return f; + } + + File compileTestFile(File f) { + int rc = com.sun.tools.javac.Main.compile(new String[] { "-source", "1.8", "-g", f.getPath() }); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + String path = f.getPath(); + return new File(path.substring(0, path.length() - 5) + ".class"); + } + + void countAnnotations() { + int expected_all = 3, expected_visibles = 1, expected_invisibles = 2; + + if (expected_all != all) { + errors++; + System.err.println("expected " + expected_all + + " annotations but found " + all); + } + + if (expected_visibles != visibles) { + errors++; + System.err.println("expected " + expected_visibles + + " visibles annotations but found " + visibles); + } + + if (expected_invisibles != invisibles) { + errors++; + System.err.println("expected " + expected_invisibles + + " invisibles annotations but found " + invisibles); + } + + } + + int errors; + int all; + int visibles; + int invisibles; +} diff --git a/langtools/test/tools/javap/typeAnnotations/Wildcards.java b/langtools/test/tools/javap/typeAnnotations/Wildcards.java new file mode 100644 index 00000000000..7e011b260d3 --- /dev/null +++ b/langtools/test/tools/javap/typeAnnotations/Wildcards.java @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2009, 2013, 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. + */ + +import java.io.*; +import com.sun.tools.classfile.*; + +/* + * @test Wildcards + * @bug 6843077 + * @summary test that annotations target wildcards get emitted to classfile + */ +public class Wildcards { + public static void main(String[] args) throws Exception { + new Wildcards().run(); + } + + public void run() throws Exception { + File javaFile = writeTestFile(); + File classFile = compileTestFile(javaFile); + + ClassFile cf = ClassFile.read(classFile); + test(cf); + for (Field f : cf.fields) { + test(cf, f); + } + for (Method m: cf.methods) { + test(cf, m); + } + + countAnnotations(); + + if (errors > 0) + throw new Exception(errors + " errors found"); + System.out.println("PASSED"); + } + + void test(ClassFile cf) { + test(cf, Attribute.RuntimeVisibleTypeAnnotations, true); + test(cf, Attribute.RuntimeInvisibleTypeAnnotations, false); + } + + void test(ClassFile cf, Method m) { + test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); + test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); + } + + void test(ClassFile cf, Field m) { + test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true); + test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false); + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void test(ClassFile cf, String name, boolean visible) { + int index = cf.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = cf.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + } + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void test(ClassFile cf, Method m, String name, boolean visible) { + int index = m.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = m.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + } + } + + // test the result of Attributes.getIndex according to expectations + // encoded in the method's name + void test(ClassFile cf, Field m, String name, boolean visible) { + int index = m.attributes.getIndex(cf.constant_pool, name); + if (index != -1) { + Attribute attr = m.attributes.get(index); + assert attr instanceof RuntimeTypeAnnotations_attribute; + RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; + all += tAttr.annotations.length; + if (visible) + visibles += tAttr.annotations.length; + else + invisibles += tAttr.annotations.length; + } + } + + File writeTestFile() throws IOException { + File f = new File("Test.java"); + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); + out.println("import java.lang.annotation.*;"); + out.println("import java.util.*;"); + out.println("class Test { "); + out.println(" @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})"); + out.println(" @interface A { }"); + + out.println(" List f;"); + + out.println(" List test(List p) {"); + out.println(" List l;"); // not counted... gets optimized away + out.println(" return null;"); + out.println(" }"); + out.println("}"); + + out.close(); + return f; + } + + File compileTestFile(File f) { + int rc = com.sun.tools.javac.Main.compile(new String[] { "-source", "1.8", "-g", f.getPath() }); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + String path = f.getPath(); + return new File(path.substring(0, path.length() - 5) + ".class"); + } + + void countAnnotations() { + int expected_visibles = 0, expected_invisibles = 3; + int expected_all = expected_visibles + expected_invisibles; + + if (expected_all != all) { + errors++; + System.err.println("expected " + expected_all + + " annotations but found " + all); + } + + if (expected_visibles != visibles) { + errors++; + System.err.println("expected " + expected_visibles + + " visibles annotations but found " + visibles); + } + + if (expected_invisibles != invisibles) { + errors++; + System.err.println("expected " + expected_invisibles + + " invisibles annotations but found " + invisibles); + } + + } + + int errors; + int all; + int visibles; + int invisibles; +} From 3fcddbbea2842ee62c0f26f0fae52435033545af Mon Sep 17 00:00:00 2001 From: Tim Bell Date: Wed, 23 Jan 2013 13:30:11 -0800 Subject: [PATCH 160/204] 8006797: build-infra JPRT builds need JPRT_ARCHIVE_INSTALL_BUNDLE in common/makefiles/Jprt.gmk Reviewed-by: ohair --- common/makefiles/Jprt.gmk | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/common/makefiles/Jprt.gmk b/common/makefiles/Jprt.gmk index 05a7c66d0d3..b8bc418fbae 100644 --- a/common/makefiles/Jprt.gmk +++ b/common/makefiles/Jprt.gmk @@ -150,6 +150,9 @@ PHONY_LIST += bridge2configure bridgeBuild ifndef JPRT_ARCHIVE_BUNDLE JPRT_ARCHIVE_BUNDLE=/tmp/jprt_bundles/j2sdk-image.zip endif +ifndef JPRT_ARCHIVE_INSTALL_BUNDLE + JPRT_ARCHIVE_INSTALL_BUNDLE=/tmp/jprt_bundles/product-install.zip +endif # These targets execute in a SPEC free context, before calling bridgeBuild # to generate the SPEC. @@ -188,6 +191,9 @@ ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_BITS),solaris-64) else $(CD) $(JDK_IMAGE_DIR) && $(ZIP) -q -r $(BUILD_OUTPUT)/bundles/j2sdk-image.zip . $(CD) $(JRE_IMAGE_DIR) && $(ZIP) -q -r $(BUILD_OUTPUT)/bundles/j2re-image.zip . + if [ -d $(BUILD_OUTPUT)/install/bundles ] ; then \ + $(CD) $(BUILD_OUTPUT)/install/bundles && $(ZIP) -q -r $(JPRT_ARCHIVE_INSTALL_BUNDLE) . ; \ + fi endif @$(call TargetExit) From 89152955605ad92d71d5ed48e89f2571417ea40b Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Wed, 23 Jan 2013 15:11:03 -0800 Subject: [PATCH 161/204] 8003878: compiler/7196199 test failed on OS X since 8b54, jdk7u12b01 Limit vectors size to 16 bytes on BSD until the problem is fixed Reviewed-by: twisti --- hotspot/src/cpu/x86/vm/vm_version_x86.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp index 01d99c37219..90066c1041a 100644 --- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp +++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp @@ -661,6 +661,14 @@ void VM_Version::get_processor_features() { } } } +#if defined(COMPILER2) && defined(_ALLBSD_SOURCE) + if (MaxVectorSize > 16) { + // Limit vectors size to 16 bytes on BSD until it fixes + // restoring upper 128bit of YMM registers on return + // from signal handler. + FLAG_SET_DEFAULT(MaxVectorSize, 16); + } +#endif // COMPILER2 // Use population count instruction if available. if (supports_popcnt()) { From 6b27e0670184ea24ab6761a04de4e5437d8a1c2f Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Wed, 23 Jan 2013 20:11:07 -0800 Subject: [PATCH 162/204] 8006264: Add explanation of why default methods cannot be used in JDK 8 javax.lang.model Reviewed-by: jjg --- .../lang/model/element/AnnotationValueVisitor.java | 14 +++++++++++++- .../javax/lang/model/element/ElementVisitor.java | 14 +++++++++++++- .../classes/javax/lang/model/type/TypeVisitor.java | 12 ++++++++++++ .../util/AbstractAnnotationValueVisitor6.java | 9 +++++++++ .../util/AbstractAnnotationValueVisitor7.java | 11 ++++++++++- .../util/AbstractAnnotationValueVisitor8.java | 11 ++++++++++- .../lang/model/util/AbstractElementVisitor6.java | 11 ++++++++++- .../lang/model/util/AbstractElementVisitor7.java | 11 ++++++++++- .../lang/model/util/AbstractElementVisitor8.java | 11 ++++++++++- .../lang/model/util/AbstractTypeVisitor6.java | 9 +++++++++ .../lang/model/util/AbstractTypeVisitor7.java | 11 ++++++++++- .../lang/model/util/AbstractTypeVisitor8.java | 11 ++++++++++- .../javax/lang/model/util/ElementKindVisitor6.java | 11 ++++++++++- .../javax/lang/model/util/ElementKindVisitor7.java | 11 ++++++++++- .../javax/lang/model/util/ElementKindVisitor8.java | 11 ++++++++++- .../model/util/SimpleAnnotationValueVisitor6.java | 11 ++++++++++- .../model/util/SimpleAnnotationValueVisitor7.java | 11 ++++++++++- .../model/util/SimpleAnnotationValueVisitor8.java | 11 ++++++++++- .../lang/model/util/SimpleElementVisitor6.java | 11 ++++++++++- .../lang/model/util/SimpleElementVisitor7.java | 11 ++++++++++- .../lang/model/util/SimpleElementVisitor8.java | 11 ++++++++++- .../javax/lang/model/util/SimpleTypeVisitor6.java | 11 ++++++++++- .../javax/lang/model/util/SimpleTypeVisitor7.java | 11 ++++++++++- .../javax/lang/model/util/SimpleTypeVisitor8.java | 11 ++++++++++- .../javax/lang/model/util/TypeKindVisitor6.java | 11 ++++++++++- .../javax/lang/model/util/TypeKindVisitor7.java | 11 ++++++++++- .../javax/lang/model/util/TypeKindVisitor8.java | 11 ++++++++++- 27 files changed, 276 insertions(+), 24 deletions(-) diff --git a/langtools/src/share/classes/javax/lang/model/element/AnnotationValueVisitor.java b/langtools/src/share/classes/javax/lang/model/element/AnnotationValueVisitor.java index 888ab35f397..6d01d0f1734 100644 --- a/langtools/src/share/classes/javax/lang/model/element/AnnotationValueVisitor.java +++ b/langtools/src/share/classes/javax/lang/model/element/AnnotationValueVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -61,6 +61,18 @@ import javax.lang.model.type.TypeMirror; * parameters, return type, etc. rather than one of the abstract * classes. * + *

Note that methods to accommodate new language constructs could + * be added in a source compatible way if they were added as + * default methods. However, default methods are only + * available on Java SE 8 and higher releases and the {@code + * javax.lang.model.*} packages bundled in Java SE 8 are required to + * also be runnable on Java SE 7. Therefore, default methods + * cannot be used when extending {@code javax.lang.model.*} + * to cover Java SE 8 language features. However, default methods may + * be used in subsequent revisions of the {@code javax.lang.model.*} + * packages that are only required to run on Java SE 8 and higher + * platform versions. + * * @param the return type of this visitor's methods * @param

the type of the additional parameter to this visitor's methods. * @author Joseph D. Darcy diff --git a/langtools/src/share/classes/javax/lang/model/element/ElementVisitor.java b/langtools/src/share/classes/javax/lang/model/element/ElementVisitor.java index 34fb9328c6c..56c07bde4b8 100644 --- a/langtools/src/share/classes/javax/lang/model/element/ElementVisitor.java +++ b/langtools/src/share/classes/javax/lang/model/element/ElementVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -52,6 +52,18 @@ import javax.lang.model.util.*; * parameters, return type, etc. rather than one of the abstract * classes. * + *

Note that methods to accommodate new language constructs could + * be added in a source compatible way if they were added as + * default methods. However, default methods are only + * available on Java SE 8 and higher releases and the {@code + * javax.lang.model.*} packages bundled in Java SE 8 are required to + * also be runnable on Java SE 7. Therefore, default methods + * cannot be used when extending {@code javax.lang.model.*} + * to cover Java SE 8 language features. However, default methods may + * be used in subsequent revisions of the {@code javax.lang.model.*} + * packages that are only required to run on Java SE 8 and higher + * platform versions. + * * @param the return type of this visitor's methods. Use {@link * Void} for visitors that do not need to return results. * @param

the type of the additional parameter to this visitor's diff --git a/langtools/src/share/classes/javax/lang/model/type/TypeVisitor.java b/langtools/src/share/classes/javax/lang/model/type/TypeVisitor.java index b59cce20b74..2d8674d6512 100644 --- a/langtools/src/share/classes/javax/lang/model/type/TypeVisitor.java +++ b/langtools/src/share/classes/javax/lang/model/type/TypeVisitor.java @@ -52,6 +52,18 @@ import javax.lang.model.element.*; * parameters, return type, etc. rather than one of the abstract * classes. * + *

Note that methods to accommodate new language constructs could + * be added in a source compatible way if they were added as + * default methods. However, default methods are only + * available on Java SE 8 and higher releases and the {@code + * javax.lang.model.*} packages bundled in Java SE 8 are required to + * also be runnable on Java SE 7. Therefore, default methods + * cannot be used when extending {@code javax.lang.model.*} + * to cover Java SE 8 language features. However, default methods may + * be used in subsequent revisions of the {@code javax.lang.model.*} + * packages that are only required to run on Java SE 8 and higher + * platform versions. + * * @param the return type of this visitor's methods. Use {@link * Void} for visitors that do not need to return results. * @param

the type of the additional parameter to this visitor's diff --git a/langtools/src/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor6.java b/langtools/src/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor6.java index 109349aa612..2d4d6b4e4b5 100644 --- a/langtools/src/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor6.java +++ b/langtools/src/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor6.java @@ -54,6 +54,15 @@ import javax.annotation.processing.SupportedSourceVersion; * behavior for the visit method in question. When the new visitor is * introduced, all or portions of this visitor may be deprecated. * + *

Note that adding a default implementation of a new visit method + * in a visitor class will occur instead of adding a default + * method directly in the visitor interface since a Java SE 8 + * language feature cannot be used to this version of the API since + * this version is required to be runnable on Java SE 7 + * implementations. Future versions of the API that are only required + * to run on Java SE 8 and later may take advantage of default methods + * in this situation. + * * @param the return type of this visitor's methods * @param

the type of the additional parameter to this visitor's methods. * diff --git a/langtools/src/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor7.java b/langtools/src/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor7.java index 35a93718615..ae2438e065e 100644 --- a/langtools/src/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor7.java +++ b/langtools/src/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor7.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, 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 @@ -51,6 +51,15 @@ import javax.annotation.processing.SupportedSourceVersion; * behavior for the visit method in question. When the new visitor is * introduced, all or portions of this visitor may be deprecated. * + *

Note that adding a default implementation of a new visit method + * in a visitor class will occur instead of adding a default + * method directly in the visitor interface since a Java SE 8 + * language feature cannot be used to this version of the API since + * this version is required to be runnable on Java SE 7 + * implementations. Future versions of the API that are only required + * to run on Java SE 8 and later may take advantage of default methods + * in this situation. + * * @param the return type of this visitor's methods * @param

the type of the additional parameter to this visitor's methods. * diff --git a/langtools/src/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor8.java b/langtools/src/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor8.java index c7a0f7be70f..47c25598d61 100644 --- a/langtools/src/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor8.java +++ b/langtools/src/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor8.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, 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 @@ -51,6 +51,15 @@ import javax.annotation.processing.SupportedSourceVersion; * behavior for the visit method in question. When the new visitor is * introduced, all or portions of this visitor may be deprecated. * + *

Note that adding a default implementation of a new visit method + * in a visitor class will occur instead of adding a default + * method directly in the visitor interface since a Java SE 8 + * language feature cannot be used to this version of the API since + * this version is required to be runnable on Java SE 7 + * implementations. Future versions of the API that are only required + * to run on Java SE 8 and later may take advantage of default methods + * in this situation. + * * @param the return type of this visitor's methods * @param

the type of the additional parameter to this visitor's methods. * diff --git a/langtools/src/share/classes/javax/lang/model/util/AbstractElementVisitor6.java b/langtools/src/share/classes/javax/lang/model/util/AbstractElementVisitor6.java index 8e1d65613d5..2ce7465d151 100644 --- a/langtools/src/share/classes/javax/lang/model/util/AbstractElementVisitor6.java +++ b/langtools/src/share/classes/javax/lang/model/util/AbstractElementVisitor6.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -53,6 +53,15 @@ import static javax.lang.model.SourceVersion.*; * visit method in question. When the new visitor is introduced, all * or portions of this visitor may be deprecated. * + *

Note that adding a default implementation of a new visit method + * in a visitor class will occur instead of adding a default + * method directly in the visitor interface since a Java SE 8 + * language feature cannot be used to this version of the API since + * this version is required to be runnable on Java SE 7 + * implementations. Future versions of the API that are only required + * to run on Java SE 8 and later may take advantage of default methods + * in this situation. + * * @param the return type of this visitor's methods. Use {@link * Void} for visitors that do not need to return results. * @param

the type of the additional parameter to this visitor's diff --git a/langtools/src/share/classes/javax/lang/model/util/AbstractElementVisitor7.java b/langtools/src/share/classes/javax/lang/model/util/AbstractElementVisitor7.java index 0e5d8daeebc..f5c87e46d0f 100644 --- a/langtools/src/share/classes/javax/lang/model/util/AbstractElementVisitor7.java +++ b/langtools/src/share/classes/javax/lang/model/util/AbstractElementVisitor7.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, 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 @@ -52,6 +52,15 @@ import static javax.lang.model.SourceVersion.*; * visit method in question. When the new visitor is introduced, all * or portions of this visitor may be deprecated. * + *

Note that adding a default implementation of a new visit method + * in a visitor class will occur instead of adding a default + * method directly in the visitor interface since a Java SE 8 + * language feature cannot be used to this version of the API since + * this version is required to be runnable on Java SE 7 + * implementations. Future versions of the API that are only required + * to run on Java SE 8 and later may take advantage of default methods + * in this situation. + * * @param the return type of this visitor's methods. Use {@link * Void} for visitors that do not need to return results. * @param

the type of the additional parameter to this visitor's diff --git a/langtools/src/share/classes/javax/lang/model/util/AbstractElementVisitor8.java b/langtools/src/share/classes/javax/lang/model/util/AbstractElementVisitor8.java index b4afe113fac..fb99d187f36 100644 --- a/langtools/src/share/classes/javax/lang/model/util/AbstractElementVisitor8.java +++ b/langtools/src/share/classes/javax/lang/model/util/AbstractElementVisitor8.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, 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 @@ -52,6 +52,15 @@ import static javax.lang.model.SourceVersion.*; * visit method in question. When the new visitor is introduced, all * or portions of this visitor may be deprecated. * + *

Note that adding a default implementation of a new visit method + * in a visitor class will occur instead of adding a default + * method directly in the visitor interface since a Java SE 8 + * language feature cannot be used to this version of the API since + * this version is required to be runnable on Java SE 7 + * implementations. Future versions of the API that are only required + * to run on Java SE 8 and later may take advantage of default methods + * in this situation. + * * @param the return type of this visitor's methods. Use {@link * Void} for visitors that do not need to return results. * @param

the type of the additional parameter to this visitor's diff --git a/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java b/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java index aa07280c91a..0ae91ef0977 100644 --- a/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java +++ b/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java @@ -49,6 +49,15 @@ import javax.lang.model.type.*; * visit method in question. When the new visitor is introduced, all * or portions of this visitor may be deprecated. * + *

Note that adding a default implementation of a new visit method + * in a visitor class will occur instead of adding a default + * method directly in the visitor interface since a Java SE 8 + * language feature cannot be used to this version of the API since + * this version is required to be runnable on Java SE 7 + * implementations. Future versions of the API that are only required + * to run on Java SE 8 and later may take advantage of default methods + * in this situation. + * * @param the return type of this visitor's methods. Use {@link * Void} for visitors that do not need to return results. * @param

the type of the additional parameter to this visitor's diff --git a/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor7.java b/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor7.java index 7deefe9bed7..3fe08dcc1db 100644 --- a/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor7.java +++ b/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor7.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, 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 @@ -49,6 +49,15 @@ import javax.lang.model.type.*; * visit method in question. When the new visitor is introduced, all * or portions of this visitor may be deprecated. * + *

Note that adding a default implementation of a new visit method + * in a visitor class will occur instead of adding a default + * method directly in the visitor interface since a Java SE 8 + * language feature cannot be used to this version of the API since + * this version is required to be runnable on Java SE 7 + * implementations. Future versions of the API that are only required + * to run on Java SE 8 and later may take advantage of default methods + * in this situation. + * * @param the return type of this visitor's methods. Use {@link * Void} for visitors that do not need to return results. * @param

the type of the additional parameter to this visitor's diff --git a/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor8.java b/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor8.java index 5713b24b82b..a23b6e7fc5b 100644 --- a/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor8.java +++ b/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor8.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, 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 @@ -49,6 +49,15 @@ import javax.lang.model.type.*; * visit method in question. When the new visitor is introduced, all * or portions of this visitor may be deprecated. * + *

Note that adding a default implementation of a new visit method + * in a visitor class will occur instead of adding a default + * method directly in the visitor interface since a Java SE 8 + * language feature cannot be used to this version of the API since + * this version is required to be runnable on Java SE 7 + * implementations. Future versions of the API that are only required + * to run on Java SE 8 and later may take advantage of default methods + * in this situation. + * * @param the return type of this visitor's methods. Use {@link * Void} for visitors that do not need to return results. * @param

the type of the additional parameter to this visitor's diff --git a/langtools/src/share/classes/javax/lang/model/util/ElementKindVisitor6.java b/langtools/src/share/classes/javax/lang/model/util/ElementKindVisitor6.java index f1ad3fed21f..9925955ed9a 100644 --- a/langtools/src/share/classes/javax/lang/model/util/ElementKindVisitor6.java +++ b/langtools/src/share/classes/javax/lang/model/util/ElementKindVisitor6.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -67,6 +67,15 @@ import javax.lang.model.SourceVersion; * for the visit method in question. When the new visitor is * introduced, all or portions of this visitor may be deprecated. * + *

Note that adding a default implementation of a new visit method + * in a visitor class will occur instead of adding a default + * method directly in the visitor interface since a Java SE 8 + * language feature cannot be used to this version of the API since + * this version is required to be runnable on Java SE 7 + * implementations. Future versions of the API that are only required + * to run on Java SE 8 and later may take advantage of default methods + * in this situation. + * * @param the return type of this visitor's methods. Use {@link * Void} for visitors that do not need to return results. * @param

the type of the additional parameter to this visitor's diff --git a/langtools/src/share/classes/javax/lang/model/util/ElementKindVisitor7.java b/langtools/src/share/classes/javax/lang/model/util/ElementKindVisitor7.java index 25a68a909f7..ebaeb6ba67b 100644 --- a/langtools/src/share/classes/javax/lang/model/util/ElementKindVisitor7.java +++ b/langtools/src/share/classes/javax/lang/model/util/ElementKindVisitor7.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, 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 @@ -65,6 +65,15 @@ import static javax.lang.model.SourceVersion.*; * for the visit method in question. When the new visitor is * introduced, all or portions of this visitor may be deprecated. * + *

Note that adding a default implementation of a new visit method + * in a visitor class will occur instead of adding a default + * method directly in the visitor interface since a Java SE 8 + * language feature cannot be used to this version of the API since + * this version is required to be runnable on Java SE 7 + * implementations. Future versions of the API that are only required + * to run on Java SE 8 and later may take advantage of default methods + * in this situation. + * * @param the return type of this visitor's methods. Use {@link * Void} for visitors that do not need to return results. * @param

the type of the additional parameter to this visitor's diff --git a/langtools/src/share/classes/javax/lang/model/util/ElementKindVisitor8.java b/langtools/src/share/classes/javax/lang/model/util/ElementKindVisitor8.java index d5ea0f6f960..61ccc789073 100644 --- a/langtools/src/share/classes/javax/lang/model/util/ElementKindVisitor8.java +++ b/langtools/src/share/classes/javax/lang/model/util/ElementKindVisitor8.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, 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 @@ -65,6 +65,15 @@ import javax.lang.model.SourceVersion; * for the visit method in question. When the new visitor is * introduced, all or portions of this visitor may be deprecated. * + *

Note that adding a default implementation of a new visit method + * in a visitor class will occur instead of adding a default + * method directly in the visitor interface since a Java SE 8 + * language feature cannot be used to this version of the API since + * this version is required to be runnable on Java SE 7 + * implementations. Future versions of the API that are only required + * to run on Java SE 8 and later may take advantage of default methods + * in this situation. + * * @param the return type of this visitor's methods. Use {@link * Void} for visitors that do not need to return results. * @param

the type of the additional parameter to this visitor's diff --git a/langtools/src/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor6.java b/langtools/src/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor6.java index b2995723564..1bb58b96376 100644 --- a/langtools/src/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor6.java +++ b/langtools/src/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor6.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -63,6 +63,15 @@ import javax.annotation.processing.SupportedSourceVersion; * behavior for the visit method in question. When the new visitor is * introduced, all or portions of this visitor may be deprecated. * + *

Note that adding a default implementation of a new visit method + * in a visitor class will occur instead of adding a default + * method directly in the visitor interface since a Java SE 8 + * language feature cannot be used to this version of the API since + * this version is required to be runnable on Java SE 7 + * implementations. Future versions of the API that are only required + * to run on Java SE 8 and later may take advantage of default methods + * in this situation. + * * @param the return type of this visitor's methods * @param

the type of the additional parameter to this visitor's methods. * diff --git a/langtools/src/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor7.java b/langtools/src/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor7.java index 2e3cfafcc70..0a442111cf7 100644 --- a/langtools/src/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor7.java +++ b/langtools/src/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor7.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, 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 @@ -58,6 +58,15 @@ import static javax.lang.model.SourceVersion.*; * behavior for the visit method in question. When the new visitor is * introduced, all or portions of this visitor may be deprecated. * + *

Note that adding a default implementation of a new visit method + * in a visitor class will occur instead of adding a default + * method directly in the visitor interface since a Java SE 8 + * language feature cannot be used to this version of the API since + * this version is required to be runnable on Java SE 7 + * implementations. Future versions of the API that are only required + * to run on Java SE 8 and later may take advantage of default methods + * in this situation. + * * @param the return type of this visitor's methods * @param

the type of the additional parameter to this visitor's methods. * diff --git a/langtools/src/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor8.java b/langtools/src/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor8.java index 30823cdd584..1b84d328ca8 100644 --- a/langtools/src/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor8.java +++ b/langtools/src/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor8.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, 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 @@ -58,6 +58,15 @@ import static javax.lang.model.SourceVersion.*; * behavior for the visit method in question. When the new visitor is * introduced, all or portions of this visitor may be deprecated. * + *

Note that adding a default implementation of a new visit method + * in a visitor class will occur instead of adding a default + * method directly in the visitor interface since a Java SE 8 + * language feature cannot be used to this version of the API since + * this version is required to be runnable on Java SE 7 + * implementations. Future versions of the API that are only required + * to run on Java SE 8 and later may take advantage of default methods + * in this situation. + * * @param the return type of this visitor's methods * @param

the type of the additional parameter to this visitor's methods. * diff --git a/langtools/src/share/classes/javax/lang/model/util/SimpleElementVisitor6.java b/langtools/src/share/classes/javax/lang/model/util/SimpleElementVisitor6.java index a0055f76cfe..8c7ff87fbd9 100644 --- a/langtools/src/share/classes/javax/lang/model/util/SimpleElementVisitor6.java +++ b/langtools/src/share/classes/javax/lang/model/util/SimpleElementVisitor6.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -65,6 +65,15 @@ import static javax.lang.model.SourceVersion.*; * visit method in question. When the new visitor is introduced, all * or portions of this visitor may be deprecated. * + *

Note that adding a default implementation of a new visit method + * in a visitor class will occur instead of adding a default + * method directly in the visitor interface since a Java SE 8 + * language feature cannot be used to this version of the API since + * this version is required to be runnable on Java SE 7 + * implementations. Future versions of the API that are only required + * to run on Java SE 8 and later may take advantage of default methods + * in this situation. + * * @param the return type of this visitor's methods. Use {@code Void} * for visitors that do not need to return results. * @param

the type of the additional parameter to this visitor's methods. Use {@code Void} diff --git a/langtools/src/share/classes/javax/lang/model/util/SimpleElementVisitor7.java b/langtools/src/share/classes/javax/lang/model/util/SimpleElementVisitor7.java index 5d54cff9333..b9df9c49e1c 100644 --- a/langtools/src/share/classes/javax/lang/model/util/SimpleElementVisitor7.java +++ b/langtools/src/share/classes/javax/lang/model/util/SimpleElementVisitor7.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, 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 @@ -62,6 +62,15 @@ import static javax.lang.model.SourceVersion.*; * visit method in question. When the new visitor is introduced, all * or portions of this visitor may be deprecated. * + *

Note that adding a default implementation of a new visit method + * in a visitor class will occur instead of adding a default + * method directly in the visitor interface since a Java SE 8 + * language feature cannot be used to this version of the API since + * this version is required to be runnable on Java SE 7 + * implementations. Future versions of the API that are only required + * to run on Java SE 8 and later may take advantage of default methods + * in this situation. + * * @param the return type of this visitor's methods. Use {@code Void} * for visitors that do not need to return results. * @param

the type of the additional parameter to this visitor's methods. Use {@code Void} diff --git a/langtools/src/share/classes/javax/lang/model/util/SimpleElementVisitor8.java b/langtools/src/share/classes/javax/lang/model/util/SimpleElementVisitor8.java index 63cacd00f3c..f0cb871c99c 100644 --- a/langtools/src/share/classes/javax/lang/model/util/SimpleElementVisitor8.java +++ b/langtools/src/share/classes/javax/lang/model/util/SimpleElementVisitor8.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, 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 @@ -61,6 +61,15 @@ import static javax.lang.model.SourceVersion.*; * visit method in question. When the new visitor is introduced, all * or portions of this visitor may be deprecated. * + *

Note that adding a default implementation of a new visit method + * in a visitor class will occur instead of adding a default + * method directly in the visitor interface since a Java SE 8 + * language feature cannot be used to this version of the API since + * this version is required to be runnable on Java SE 7 + * implementations. Future versions of the API that are only required + * to run on Java SE 8 and later may take advantage of default methods + * in this situation. + * * @param the return type of this visitor's methods. Use {@code Void} * for visitors that do not need to return results. * @param

the type of the additional parameter to this visitor's methods. Use {@code Void} diff --git a/langtools/src/share/classes/javax/lang/model/util/SimpleTypeVisitor6.java b/langtools/src/share/classes/javax/lang/model/util/SimpleTypeVisitor6.java index 7fadd6de08d..5d1b3d7a309 100644 --- a/langtools/src/share/classes/javax/lang/model/util/SimpleTypeVisitor6.java +++ b/langtools/src/share/classes/javax/lang/model/util/SimpleTypeVisitor6.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -64,6 +64,15 @@ import static javax.lang.model.SourceVersion.*; * visit method in question. When the new visitor is introduced, all * or portions of this visitor may be deprecated. * + *

Note that adding a default implementation of a new visit method + * in a visitor class will occur instead of adding a default + * method directly in the visitor interface since a Java SE 8 + * language feature cannot be used to this version of the API since + * this version is required to be runnable on Java SE 7 + * implementations. Future versions of the API that are only required + * to run on Java SE 8 and later may take advantage of default methods + * in this situation. + * * @param the return type of this visitor's methods. Use {@link * Void} for visitors that do not need to return results. * @param

the type of the additional parameter to this visitor's diff --git a/langtools/src/share/classes/javax/lang/model/util/SimpleTypeVisitor7.java b/langtools/src/share/classes/javax/lang/model/util/SimpleTypeVisitor7.java index dfb1f5d9187..66eb20aafa7 100644 --- a/langtools/src/share/classes/javax/lang/model/util/SimpleTypeVisitor7.java +++ b/langtools/src/share/classes/javax/lang/model/util/SimpleTypeVisitor7.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, 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 @@ -61,6 +61,15 @@ import static javax.lang.model.SourceVersion.*; * visit method in question. When the new visitor is introduced, all * or portions of this visitor may be deprecated. * + *

Note that adding a default implementation of a new visit method + * in a visitor class will occur instead of adding a default + * method directly in the visitor interface since a Java SE 8 + * language feature cannot be used to this version of the API since + * this version is required to be runnable on Java SE 7 + * implementations. Future versions of the API that are only required + * to run on Java SE 8 and later may take advantage of default methods + * in this situation. + * * @param the return type of this visitor's methods. Use {@link * Void} for visitors that do not need to return results. * @param

the type of the additional parameter to this visitor's diff --git a/langtools/src/share/classes/javax/lang/model/util/SimpleTypeVisitor8.java b/langtools/src/share/classes/javax/lang/model/util/SimpleTypeVisitor8.java index fc023d869c2..c4faae9f45e 100644 --- a/langtools/src/share/classes/javax/lang/model/util/SimpleTypeVisitor8.java +++ b/langtools/src/share/classes/javax/lang/model/util/SimpleTypeVisitor8.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, 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 @@ -60,6 +60,15 @@ import static javax.lang.model.SourceVersion.*; * visit method in question. When the new visitor is introduced, all * or portions of this visitor may be deprecated. * + *

Note that adding a default implementation of a new visit method + * in a visitor class will occur instead of adding a default + * method directly in the visitor interface since a Java SE 8 + * language feature cannot be used to this version of the API since + * this version is required to be runnable on Java SE 7 + * implementations. Future versions of the API that are only required + * to run on Java SE 8 and later may take advantage of default methods + * in this situation. + * * @param the return type of this visitor's methods. Use {@link * Void} for visitors that do not need to return results. * @param

the type of the additional parameter to this visitor's diff --git a/langtools/src/share/classes/javax/lang/model/util/TypeKindVisitor6.java b/langtools/src/share/classes/javax/lang/model/util/TypeKindVisitor6.java index 9e007fe54f3..3add039d49a 100644 --- a/langtools/src/share/classes/javax/lang/model/util/TypeKindVisitor6.java +++ b/langtools/src/share/classes/javax/lang/model/util/TypeKindVisitor6.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -63,6 +63,15 @@ import static javax.lang.model.SourceVersion.*; * method in question. When the new visitor is introduced, all or * portions of this visitor may be deprecated. * + *

Note that adding a default implementation of a new visit method + * in a visitor class will occur instead of adding a default + * method directly in the visitor interface since a Java SE 8 + * language feature cannot be used to this version of the API since + * this version is required to be runnable on Java SE 7 + * implementations. Future versions of the API that are only required + * to run on Java SE 8 and later may take advantage of default methods + * in this situation. + * * @param the return type of this visitor's methods. Use {@link * Void} for visitors that do not need to return results. * @param

the type of the additional parameter to this visitor's diff --git a/langtools/src/share/classes/javax/lang/model/util/TypeKindVisitor7.java b/langtools/src/share/classes/javax/lang/model/util/TypeKindVisitor7.java index 4bbe1d6635a..a0a0c1276a3 100644 --- a/langtools/src/share/classes/javax/lang/model/util/TypeKindVisitor7.java +++ b/langtools/src/share/classes/javax/lang/model/util/TypeKindVisitor7.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, 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 @@ -63,6 +63,15 @@ import javax.lang.model.SourceVersion; * method in question. When the new visitor is introduced, all or * portions of this visitor may be deprecated. * + *

Note that adding a default implementation of a new visit method + * in a visitor class will occur instead of adding a default + * method directly in the visitor interface since a Java SE 8 + * language feature cannot be used to this version of the API since + * this version is required to be runnable on Java SE 7 + * implementations. Future versions of the API that are only required + * to run on Java SE 8 and later may take advantage of default methods + * in this situation. + * * @param the return type of this visitor's methods. Use {@link * Void} for visitors that do not need to return results. * @param

the type of the additional parameter to this visitor's diff --git a/langtools/src/share/classes/javax/lang/model/util/TypeKindVisitor8.java b/langtools/src/share/classes/javax/lang/model/util/TypeKindVisitor8.java index 698364f791e..60b3b6125d1 100644 --- a/langtools/src/share/classes/javax/lang/model/util/TypeKindVisitor8.java +++ b/langtools/src/share/classes/javax/lang/model/util/TypeKindVisitor8.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, 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 @@ -63,6 +63,15 @@ import static javax.lang.model.SourceVersion.*; * method in question. When the new visitor is introduced, all or * portions of this visitor may be deprecated. * + *

Note that adding a default implementation of a new visit method + * in a visitor class will occur instead of adding a default + * method directly in the visitor interface since a Java SE 8 + * language feature cannot be used to this version of the API since + * this version is required to be runnable on Java SE 7 + * implementations. Future versions of the API that are only required + * to run on Java SE 8 and later may take advantage of default methods + * in this situation. + * * @param the return type of this visitor's methods. Use {@link * Void} for visitors that do not need to return results. * @param

the type of the additional parameter to this visitor's From ae1a2f5e3c8f92b39804dcba66b984bde4292880 Mon Sep 17 00:00:00 2001 From: Krystal Mo Date: Thu, 24 Jan 2013 02:03:38 -0800 Subject: [PATCH 163/204] 8006758: LinkResolver assertion (caused by @Contended changes) Treat anonymous classes as privileged code to restore the special handling for @Compiled during class file parsing Reviewed-by: jrose, coleenp, kvn, dholmes --- hotspot/src/share/vm/classfile/classFileParser.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index e0558af122b..557707ba432 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -1802,11 +1802,9 @@ ClassFileParser::AnnotationCollector::ID ClassFileParser::AnnotationCollector::annotation_index(ClassLoaderData* loader_data, Symbol* name) { vmSymbols::SID sid = vmSymbols::find_sid(name); - bool privileged = false; - if (loader_data->is_the_null_class_loader_data()) { - // Privileged code can use all annotations. Other code silently drops some. - privileged = true; - } + // Privileged code can use all annotations. Other code silently drops some. + bool privileged = loader_data->is_the_null_class_loader_data() || + loader_data->is_anonymous(); switch (sid) { case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_ForceInline_signature): if (_location != _in_method) break; // only allow for methods From 7782e252f16cbd8a426ad736ac43a197b4d93d8e Mon Sep 17 00:00:00 2001 From: Alexander Potochkin Date: Thu, 24 Jan 2013 15:26:40 +0400 Subject: [PATCH 164/204] 7147078: [macosx] Echo char set in TextField doesn't prevent word jumping Reviewed-by: art --- .../com/apple/laf/AquaKeyBindings.java | 15 ++++++++++++ .../com/apple/laf/AquaLookAndFeel.java | 2 +- .../classes/sun/lwawt/LWTextFieldPeer.java | 23 +++++++++++++------ 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/jdk/src/macosx/classes/com/apple/laf/AquaKeyBindings.java b/jdk/src/macosx/classes/com/apple/laf/AquaKeyBindings.java index bbb804ae3f1..88db59f0b9f 100644 --- a/jdk/src/macosx/classes/com/apple/laf/AquaKeyBindings.java +++ b/jdk/src/macosx/classes/com/apple/laf/AquaKeyBindings.java @@ -142,6 +142,21 @@ public class AquaKeyBindings { })); } + LateBoundInputMap getPasswordFieldInputMap() { + return new LateBoundInputMap(new SimpleBinding(getTextFieldInputMap().getBindings()), + // nullify all the bindings that may discover space characters in the text + new SimpleBinding(new String[] { + "alt LEFT", null, + "alt KP_LEFT", null, + "alt RIGHT", null, + "alt KP_RIGHT", null, + "shift alt LEFT", null, + "shift alt KP_LEFT", null, + "shift alt RIGHT", null, + "shift alt KP_RIGHT", null, + })); + } + LateBoundInputMap getMultiLineTextInputMap() { return new LateBoundInputMap(new SimpleBinding(commonTextEditorBindings), new SimpleBinding(new String[] { "ENTER", DefaultEditorKit.insertBreakAction, diff --git a/jdk/src/macosx/classes/com/apple/laf/AquaLookAndFeel.java b/jdk/src/macosx/classes/com/apple/laf/AquaLookAndFeel.java index 4f108da2df0..457b82d36a3 100644 --- a/jdk/src/macosx/classes/com/apple/laf/AquaLookAndFeel.java +++ b/jdk/src/macosx/classes/com/apple/laf/AquaLookAndFeel.java @@ -697,7 +697,7 @@ public class AquaLookAndFeel extends BasicLookAndFeel { "Panel.foreground", black, "Panel.opaque", useOpaqueComponents, - "PasswordField.focusInputMap", aquaKeyBindings.getTextFieldInputMap(), + "PasswordField.focusInputMap", aquaKeyBindings.getPasswordFieldInputMap(), "PasswordField.font", controlFont, "PasswordField.background", textBackground, "PasswordField.foreground", textForeground, diff --git a/jdk/src/macosx/classes/sun/lwawt/LWTextFieldPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWTextFieldPeer.java index 7532f620149..ef2b4d087e2 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWTextFieldPeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWTextFieldPeer.java @@ -34,7 +34,7 @@ import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.peer.TextFieldPeer; -import javax.swing.JPasswordField; +import javax.swing.*; import javax.swing.text.JTextComponent; final class LWTextFieldPeer @@ -48,7 +48,7 @@ final class LWTextFieldPeer @Override protected JPasswordField createDelegate() { - return new JTextAreaDelegate(); + return new JPasswordFieldDelegate(); } @Override @@ -69,9 +69,18 @@ final class LWTextFieldPeer public void setEchoChar(final char echoChar) { synchronized (getDelegateLock()) { getDelegate().setEchoChar(echoChar); - getDelegate().putClientProperty("JPasswordField.cutCopyAllowed", - getDelegate().echoCharIsSet() - ? Boolean.FALSE : Boolean.TRUE); + final boolean cutCopyAllowed; + final String focusInputMapKey; + if (echoChar != 0) { + cutCopyAllowed = false; + focusInputMapKey = "PasswordField.focusInputMap"; + } else { + cutCopyAllowed = true; + focusInputMapKey = "TextField.focusInputMap"; + } + getDelegate().putClientProperty("JPasswordField.cutCopyAllowed", cutCopyAllowed); + InputMap inputMap = (InputMap) UIManager.get(focusInputMapKey); + SwingUtilities.replaceUIInputMap(getDelegate(), JComponent.WHEN_FOCUSED, inputMap); } } @@ -106,11 +115,11 @@ final class LWTextFieldPeer super.handleJavaFocusEvent(e); } - private final class JTextAreaDelegate extends JPasswordField { + private final class JPasswordFieldDelegate extends JPasswordField { // Empty non private constructor was added because access to this // class shouldn't be emulated by a synthetic accessor method. - JTextAreaDelegate() { + JPasswordFieldDelegate() { super(); } From 6eb458d36453af70db7612168e05592078b935e1 Mon Sep 17 00:00:00 2001 From: Alexander Potochkin Date: Thu, 24 Jan 2013 15:52:25 +0400 Subject: [PATCH 165/204] 7132793: [macosx] setWheelScrollEnabled action reversed Reviewed-by: serb, art --- .../classes/sun/lwawt/LWComponentPeer.java | 2 +- .../classes/sun/lwawt/LWScrollPanePeer.java | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java index 55b4665a752..aa9b798c617 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java @@ -1226,7 +1226,7 @@ public abstract class LWComponentPeer sendEventToDelegate(e); } - private void sendEventToDelegate(final AWTEvent e) { + protected void sendEventToDelegate(final AWTEvent e) { synchronized (getDelegateLock()) { if (getDelegate() == null || !isShowing() || !isEnabled()) { return; diff --git a/jdk/src/macosx/classes/sun/lwawt/LWScrollPanePeer.java b/jdk/src/macosx/classes/sun/lwawt/LWScrollPanePeer.java index 1e386f25725..723a9dd8da7 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWScrollPanePeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWScrollPanePeer.java @@ -29,6 +29,7 @@ import javax.swing.*; import javax.swing.event.ChangeListener; import javax.swing.event.ChangeEvent; import java.awt.*; +import java.awt.event.MouseWheelEvent; import java.awt.peer.ScrollPanePeer; import java.util.List; @@ -51,6 +52,21 @@ final class LWScrollPanePeer extends LWContainerPeer return sp; } + @Override + public void handleEvent(AWTEvent e) { + if (e instanceof MouseWheelEvent) { + MouseWheelEvent wheelEvent = (MouseWheelEvent) e; + //java.awt.ScrollPane consumes the event + // in case isWheelScrollingEnabled() is true, + // forcibly send the consumed event to the delegate + if (getTarget().isWheelScrollingEnabled() && wheelEvent.isConsumed()) { + sendEventToDelegate(wheelEvent); + } + } else { + super.handleEvent(e); + } + } + @Override public void stateChanged(final ChangeEvent e) { SwingUtilities.invokeLater(new Runnable() { From 3f2ea7f894d876792aff7c243d700229331cabf1 Mon Sep 17 00:00:00 2001 From: Petr Pchelko Date: Thu, 24 Jan 2013 15:55:04 +0400 Subject: [PATCH 166/204] 8005997: [macosx] Printer Dialog opens an additional title bar Reviewed-by: anthony, art --- jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java index c20f0a97ec8..54f15f66c99 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java @@ -923,6 +923,10 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor return false; } + if (blocker instanceof CPrinterDialogPeer) { + return true; + } + CPlatformWindow pWindow = (CPlatformWindow)blocker.getPlatformWindow(); pWindow.orderAboveSiblings(); From c41878d46d98fa25a364cad74bb5359dfacc44ce Mon Sep 17 00:00:00 2001 From: Alexander Zuev Date: Thu, 24 Jan 2013 16:09:48 +0400 Subject: [PATCH 167/204] 7143768: [macosx] Unexpected NullPointerException and java.io.IOException during DnD Reviewed-by: alexp --- .../sun/lwawt/macosx/CDataTransferer.java | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CDataTransferer.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CDataTransferer.java index 459895523e2..5b56b19ac1c 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CDataTransferer.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CDataTransferer.java @@ -273,8 +273,31 @@ public class CDataTransferer extends DataTransferer { @Override protected ByteArrayOutputStream convertFileListToBytes(ArrayList fileList) throws IOException { - // TODO Auto-generated method stub - return null; + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + for (int i = 0; i < fileList.size(); i++) + { + byte[] bytes = fileList.get(i).getBytes(); + bos.write(bytes, 0, bytes.length); + bos.write(0); + } + return bos; + } + + @Override + protected boolean isURIListFormat(long format) { + String nat = getNativeForFormat(format); + if (nat == null) { + return false; + } + try { + DataFlavor df = new DataFlavor(nat); + if (df.getPrimaryType().equals("text") && df.getSubType().equals("uri-list")) { + return true; + } + } catch (Exception e) { + // Not a MIME format. + } + return false; } } From d22b9b71497108e67d65b5bd7b2ddb462bdc3eef Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Thu, 24 Jan 2013 17:26:32 +0400 Subject: [PATCH 168/204] 6817933: Setting the background of an HTML Widget changes the native Windows JFileChooser Reviewed-by: alexsch --- .../classes/sun/swing/WindowsPlacesBar.java | 5 +- .../JFileChooser/6817933/Test6817933.java | 121 ++++++++++++++++++ 2 files changed, 122 insertions(+), 4 deletions(-) create mode 100644 jdk/test/javax/swing/JFileChooser/6817933/Test6817933.java diff --git a/jdk/src/share/classes/sun/swing/WindowsPlacesBar.java b/jdk/src/share/classes/sun/swing/WindowsPlacesBar.java index a05259e5978..8b033ca3e7f 100644 --- a/jdk/src/share/classes/sun/swing/WindowsPlacesBar.java +++ b/jdk/src/share/classes/sun/swing/WindowsPlacesBar.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -116,9 +116,6 @@ public class WindowsPlacesBar extends JToolBar icon = fsv.getSystemIcon(files[i]); } buttons[i] = new JToggleButton(folderName, icon); - if (isXPPlatform) { - buttons[i].setText("

"+folderName+"
"); - } if (isXPStyle) { buttons[i].putClientProperty("XPStyle.subAppName", "placesbar"); } else { diff --git a/jdk/test/javax/swing/JFileChooser/6817933/Test6817933.java b/jdk/test/javax/swing/JFileChooser/6817933/Test6817933.java new file mode 100644 index 00000000000..2b65f173a18 --- /dev/null +++ b/jdk/test/javax/swing/JFileChooser/6817933/Test6817933.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013, 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. + */ + +/* + * @test + * @bug 6817933 + * @summary Tests that HTMLEditorKit does not affect JFileChooser + * @author Sergey Malenkov + */ + +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JToggleButton; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.text.html.HTMLEditorKit; +import javax.swing.text.html.StyleSheet; + +import sun.awt.SunToolkit; +import sun.swing.WindowsPlacesBar; + +public class Test6817933 { + + private static final String STYLE = "BODY {background:red}"; + private static final Color COLOR = Color.RED; + private static JFileChooser chooser; + + public static void main(String[] args) throws Exception { + try { + UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); + } + catch (Exception exception) { + exception.printStackTrace(); + return; // ignore test on non-Windows machines + } + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + StyleSheet css = new StyleSheet(); + css.addRule(STYLE); + + HTMLEditorKit kit = new HTMLEditorKit(); + kit.setStyleSheet(css); + + JFrame frame = new JFrame(STYLE); + frame.add(chooser = new JFileChooser()); + frame.setSize(640, 480); + frame.setVisible(true); + } + }); + + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + toolkit.realSync(500); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + try { + JToggleButton button = get(JToggleButton.class, + get(WindowsPlacesBar.class, chooser)); + + int width = button.getWidth(); + int height = button.getHeight() / 3; + Point point = new Point(0, height * 2); + SwingUtilities.convertPointToScreen(point, button); + width += point.x; + height += point.y; + + int count = 0; + Robot robot = new Robot(); + for (int x = point.x; x < width; x++) { + for (int y = point.y; y < height; y++) { + count += COLOR.equals(robot.getPixelColor(x, y)) ? -2 : 1; + } + } + if (count < 0) { + throw new Exception("TEST ERROR: a lot of red pixels"); + } + } + catch (Exception exception) { + throw new Error(exception); + } + finally { + SwingUtilities.getWindowAncestor(chooser).dispose(); + } + } + }); + } + + private static T get(Class type, Container container) { + Component component = container.getComponent(0); + if (!type.isAssignableFrom(component.getClass())) { + throw new IllegalStateException("expected " + type + "; expected " + component.getClass()); + } + return (T) component; + } +} From 2c1808e68da8f2372180005d14ce74af2f123f7c Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Thu, 24 Jan 2013 17:50:03 +0400 Subject: [PATCH 169/204] 8003173: [macosx] Fullscreen on Mac leaves an empty rectangle Reviewed-by: anthony, alexsch --- .../classes/sun/awt/CGraphicsDevice.java | 20 ++- .../classes/sun/lwawt/LWWindowPeer.java | 40 ++--- .../sun/lwawt/macosx/CPlatformView.java | 24 +-- .../sun/lwawt/macosx/CPlatformWindow.java | 55 +++--- .../FullScreenInsets/FullScreenInsets.java | 156 ++++++++++++++++++ 5 files changed, 219 insertions(+), 76 deletions(-) create mode 100644 jdk/test/java/awt/FullScreen/FullScreenInsets/FullScreenInsets.java diff --git a/jdk/src/macosx/classes/sun/awt/CGraphicsDevice.java b/jdk/src/macosx/classes/sun/awt/CGraphicsDevice.java index 2b884538839..bcb24ea46f7 100644 --- a/jdk/src/macosx/classes/sun/awt/CGraphicsDevice.java +++ b/jdk/src/macosx/classes/sun/awt/CGraphicsDevice.java @@ -30,6 +30,7 @@ import java.awt.GraphicsDevice; import java.awt.Window; import java.awt.AWTPermission; import java.awt.DisplayMode; +import java.util.Objects; import sun.java2d.opengl.CGLGraphicsConfig; @@ -122,12 +123,12 @@ public final class CGraphicsDevice extends GraphicsDevice { boolean fsSupported = isFullScreenSupported(); if (fsSupported && old != null) { - // enter windowed mode (and restore original display mode) - exitFullScreenExclusive(old); + // restore original display mode and enter windowed mode. if (originalMode != null) { setDisplayMode(originalMode); originalMode = null; } + exitFullScreenExclusive(old); } super.setFullScreenWindow(w); @@ -186,13 +187,20 @@ public final class CGraphicsDevice extends GraphicsDevice { } @Override - public void setDisplayMode(DisplayMode dm) { + public void setDisplayMode(final DisplayMode dm) { if (dm == null) { throw new IllegalArgumentException("Invalid display mode"); } - nativeSetDisplayMode(displayID, dm.getWidth(), dm.getHeight(), dm.getBitDepth(), dm.getRefreshRate()); - if (isFullScreenSupported() && getFullScreenWindow() != null) { - getFullScreenWindow().setSize(dm.getWidth(), dm.getHeight()); + if (!Objects.equals(dm, getDisplayMode())) { + final Window w = getFullScreenWindow(); + if (w != null) { + exitFullScreenExclusive(w); + } + nativeSetDisplayMode(displayID, dm.getWidth(), dm.getHeight(), + dm.getBitDepth(), dm.getRefreshRate()); + if (isFullScreenSupported() && w != null) { + enterFullScreenExclusive(w); + } } } diff --git a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java index c11b626a764..5b19788f244 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java @@ -53,7 +53,7 @@ public class LWWindowPeer private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.lwawt.focus.LWWindowPeer"); - private PlatformWindow platformWindow; + private final PlatformWindow platformWindow; // Window bounds reported by the native system (as opposed to // regular bounds inherited from LWComponentPeer which are @@ -554,12 +554,14 @@ public class LWWindowPeer /** * Called by the {@code PlatformWindow} when this window is moved/resized by - * user. There's no notifyReshape() in LWComponentPeer as the only - * components which could be resized by user are top-level windows. + * user or window insets are changed. There's no notifyReshape() in + * LWComponentPeer as the only components which could be resized by user are + * top-level windows. */ public final void notifyReshape(int x, int y, int w, int h) { final boolean moved; final boolean resized; + final boolean invalid = updateInsets(platformWindow.getInsets()); synchronized (getStateLock()) { moved = (x != sysX) || (y != sysY); resized = (w != sysW) || (h != sysH); @@ -570,7 +572,7 @@ public class LWWindowPeer } // Check if anything changed - if (!moved && !resized) { + if (!moved && !resized && !invalid) { return; } // First, update peer's bounds @@ -584,10 +586,10 @@ public class LWWindowPeer } // Third, COMPONENT_MOVED/COMPONENT_RESIZED/PAINT events - if (moved) { + if (moved || invalid) { handleMove(x, y, true); } - if (resized) { + if (resized || invalid) { handleResize(w, h, true); repaintPeer(); } @@ -999,27 +1001,21 @@ public class LWWindowPeer } } - /* - * Request the window insets from the delegate and compares it - * with the current one. This method is mostly called by the - * delegate, e.g. when the window state is changed and insets - * should be recalculated. - * + /** + * Request the window insets from the delegate and compares it with the + * current one. This method is mostly called by the delegate, e.g. when the + * window state is changed and insets should be recalculated. + *

* This method may be called on the toolkit thread. */ - public boolean updateInsets(Insets newInsets) { - boolean changed = false; + public final boolean updateInsets(final Insets newInsets) { synchronized (getStateLock()) { - changed = (insets.equals(newInsets)); + if (insets.equals(newInsets)) { + return false; + } insets = newInsets; } - - if (changed) { - replaceSurfaceData(); - repaintPeer(); - } - - return changed; + return true; } public static LWWindowPeer getWindowUnderCursor() { diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java index 4972301e780..495657963bd 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java @@ -27,7 +27,6 @@ package sun.lwawt.macosx; import java.awt.*; import java.awt.geom.Rectangle2D; -import java.awt.image.VolatileImage; import sun.awt.CGraphicsConfig; import sun.awt.CGraphicsEnvironment; @@ -89,29 +88,8 @@ public class CPlatformView extends CFRetainedResource { return peer; } - public void enterFullScreenMode(final long nsWindowPtr) { + public void enterFullScreenMode() { CWrapper.NSView.enterFullScreenMode(ptr); - - // REMIND: CGLSurfaceData expects top-level's size - // and therefore we need to account insets before - // recreating the surface data - Insets insets = peer.getInsets(); - - Rectangle screenBounds; - final long screenPtr = CWrapper.NSWindow.screen(nsWindowPtr); - try { - screenBounds = CWrapper.NSScreen.frame(screenPtr).getBounds(); - } finally { - CWrapper.NSObject.release(screenPtr); - } - - // the move/size notification from the underlying system comes - // but it contains a bounds smaller than the whole screen - // and therefore we need to create the synthetic notifications - peer.notifyReshape(screenBounds.x - insets.left, - screenBounds.y - insets.bottom, - screenBounds.width + insets.left + insets.right, - screenBounds.height + insets.top + insets.bottom); } public void exitFullScreenMode() { diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java index 54f15f66c99..8f83702a209 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java @@ -38,7 +38,6 @@ import sun.awt.*; import sun.java2d.SurfaceData; import sun.java2d.opengl.CGLSurfaceData; import sun.lwawt.*; -import sun.lwawt.LWWindowPeer.PeerType; import sun.util.logging.PlatformLogger; import com.apple.laf.*; @@ -196,7 +195,8 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor // 1) setting native bounds via nativeSetBounds() call // 2) getting notification from the native level via deliverMoveResizeEvent() private Rectangle nativeBounds = new Rectangle(0, 0, 0, 0); - private volatile boolean isFullScreenMode = false; + private volatile boolean isFullScreenMode; + private boolean isFullScreenAnimationOn; private Window target; private LWWindowPeer peer; @@ -414,8 +414,10 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor @Override // PlatformWindow public Insets getInsets() { - final Insets insets = nativeGetNSWindowInsets(getNSWindowPtr()); - return insets; + if (!isFullScreenMode) { + return nativeGetNSWindowInsets(getNSWindowPtr()); + } + return new Insets(0, 0, 0, 0); } @Override // PlatformWindow @@ -727,7 +729,19 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor @Override public void enterFullScreenMode() { isFullScreenMode = true; - contentView.enterFullScreenMode(getNSWindowPtr()); + contentView.enterFullScreenMode(); + // the move/size notification from the underlying system comes + // but it contains a bounds smaller than the whole screen + // and therefore we need to create the synthetic notifications + Rectangle screenBounds; + final long screenPtr = CWrapper.NSWindow.screen(getNSWindowPtr()); + try { + screenBounds = CWrapper.NSScreen.frame(screenPtr).getBounds(); + } finally { + CWrapper.NSObject.release(screenPtr); + } + peer.notifyReshape(screenBounds.x, screenBounds.y, screenBounds.width, + screenBounds.height); } @Override @@ -874,11 +888,10 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor final Rectangle oldB = nativeBounds; nativeBounds = new Rectangle(x, y, width, height); peer.notifyReshape(x, y, width, height); - if (byUser && !oldB.getSize().equals(nativeBounds.getSize())) { + if ((byUser && !oldB.getSize().equals(nativeBounds.getSize())) + || isFullScreenAnimationOn) { flushBuffers(); } - //TODO validateSurface already called from notifyReshape - validateSurface(); } private void deliverWindowClosingEvent() { @@ -978,27 +991,19 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor orderAboveSiblings(); } - private void updateDisplay() { - EventQueue.invokeLater(new Runnable() { - public void run() { - validateSurface(); - } - }); - } - - private void updateWindowContent() { - ComponentEvent resizeEvent = new ComponentEvent(target, ComponentEvent.COMPONENT_RESIZED); - SunToolkit.postEvent(SunToolkit.targetToAppContext(target), resizeEvent); - } - private void windowWillEnterFullScreen() { - updateWindowContent(); + isFullScreenAnimationOn = true; } + private void windowDidEnterFullScreen() { - updateDisplay(); + isFullScreenAnimationOn = false; } + private void windowWillExitFullScreen() { - updateWindowContent(); + isFullScreenAnimationOn = true; + } + + private void windowDidExitFullScreen() { + isFullScreenAnimationOn = false; } - private void windowDidExitFullScreen() {} } diff --git a/jdk/test/java/awt/FullScreen/FullScreenInsets/FullScreenInsets.java b/jdk/test/java/awt/FullScreen/FullScreenInsets/FullScreenInsets.java new file mode 100644 index 00000000000..d42137af303 --- /dev/null +++ b/jdk/test/java/awt/FullScreen/FullScreenInsets/FullScreenInsets.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2013, 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. + */ + +import java.awt.AWTException; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.DisplayMode; +import java.awt.Frame; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Insets; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.Window; +import java.awt.image.BufferedImage; + +import sun.awt.SunToolkit; + +/** + * @test + * @bug 8003173 7019055 + * @summary Full-screen windows should have the proper insets. + * @author Sergey Bylokhov + */ +public final class FullScreenInsets { + + private static boolean passed = true; + + public static void main(final String[] args) { + final GraphicsEnvironment ge = GraphicsEnvironment + .getLocalGraphicsEnvironment(); + final GraphicsDevice[] devices = ge.getScreenDevices(); + + final Window wGreen = new Frame(); + wGreen.setBackground(Color.GREEN); + wGreen.setSize(300, 300); + wGreen.setVisible(true); + sleep(); + final Insets iGreen = wGreen.getInsets(); + final Dimension sGreen = wGreen.getSize(); + + final Window wRed = new Frame(); + wRed.setBackground(Color.RED); + wRed.setSize(300, 300); + wRed.setVisible(true); + sleep(); + final Insets iRed = wGreen.getInsets(); + final Dimension sRed = wGreen.getSize(); + + for (final GraphicsDevice device : devices) { + if (!device.isFullScreenSupported()) { + continue; + } + device.setFullScreenWindow(wGreen); + sleep(); + testWindowBounds(device.getDisplayMode(), wGreen); + testColor(wGreen, Color.GREEN); + + device.setFullScreenWindow(wRed); + sleep(); + testWindowBounds(device.getDisplayMode(), wRed); + testColor(wRed, Color.RED); + + device.setFullScreenWindow(null); + sleep(); + testInsets(wGreen.getInsets(), iGreen); + testInsets(wRed.getInsets(), iRed); + testSize(wGreen.getSize(), sGreen); + testSize(wRed.getSize(), sRed); + } + wGreen.dispose(); + wRed.dispose(); + if (!passed) { + throw new RuntimeException("Test failed"); + } + } + + private static void testSize(final Dimension actual, final Dimension exp) { + if (!exp.equals(actual)) { + System.err.println(" Wrong window size:" + + " Expected: " + exp + " Actual: " + actual); + passed = false; + } + } + + private static void testInsets(final Insets actual, final Insets exp) { + if (!actual.equals(exp)) { + System.err.println(" Wrong window insets:" + + " Expected: " + exp + " Actual: " + actual); + passed = false; + } + } + + private static void testWindowBounds(final DisplayMode dm, final Window w) { + if (w.getWidth() != dm.getWidth() || w.getHeight() != dm.getHeight()) { + System.err.println(" Wrong window bounds:" + + " Expected: width = " + dm.getWidth() + + ", height = " + dm.getHeight() + " Actual: " + + w.getSize()); + passed = false; + } + } + + private static void testColor(final Window w, final Color color) { + final Robot r; + try { + r = new Robot(w.getGraphicsConfiguration().getDevice()); + } catch (AWTException e) { + e.printStackTrace(); + passed = false; + return; + } + final BufferedImage bi = r.createScreenCapture(w.getBounds()); + for (int y = 0; y < bi.getHeight(); y++) { + for (int x = 0; x < bi.getWidth(); x++) { + if (bi.getRGB(x, y) != color.getRGB()) { + System.err.println( + "Incorrect pixel at " + x + "x" + y + " : " + + Integer.toHexString(bi.getRGB(x, y)) + + " ,expected : " + Integer.toHexString( + color.getRGB())); + passed = false; + return; + } + } + } + } + + private static void sleep() { + ((SunToolkit) Toolkit.getDefaultToolkit()).realSync(); + try { + Thread.sleep(2000); + } catch (InterruptedException ignored) { + } + } +} From 6d5f0df029a95b5e39c278d7603a5e2467e8ba18 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Thu, 24 Jan 2013 17:57:02 +0400 Subject: [PATCH 170/204] 8005138: test/java/beans/Introspector/TestTypeResolver.java fails Reviewed-by: alexsch --- .../java/beans/Introspector/TestTypeResolver.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/jdk/test/java/beans/Introspector/TestTypeResolver.java b/jdk/test/java/beans/Introspector/TestTypeResolver.java index 6704d8f7e16..e6915192776 100644 --- a/jdk/test/java/beans/Introspector/TestTypeResolver.java +++ b/jdk/test/java/beans/Introspector/TestTypeResolver.java @@ -180,10 +180,22 @@ public class TestTypeResolver { return null; // not used } + public T[] getAnnotations(Class annotationClass) { + return null; // not used + } + public Annotation[] getAnnotations() { return null; // not used } + public T getDeclaredAnnotation(Class annotationClass) { + return null; // not used + } + + public T[] getDeclaredAnnotations(Class annotationClass) { + return null; // not used + } + public Annotation[] getDeclaredAnnotations() { return null; // not used } From 601fc96c2768b371b1d8975fa79475eef7f8a338 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Thu, 24 Jan 2013 18:06:24 +0400 Subject: [PATCH 171/204] 8003400: JTree scrolling problem when using large model in WindowsLookAndFeel Reviewed-by: alexsch --- .../javax/swing/plaf/basic/BasicTreeUI.java | 25 +++- .../swing/JTree/8003400/Test8003400.java | 109 ++++++++++++++++++ 2 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 jdk/test/javax/swing/JTree/8003400/Test8003400.java diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java index 497c0d6cac0..3d39cf6a876 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java @@ -1879,6 +1879,20 @@ public class BasicTreeUI extends TreeUI visRect.x -= i.left; visRect.y -= i.top; } + // we should consider a non-visible area above + Component component = SwingUtilities.getUnwrappedParent(tree); + if (component instanceof JViewport) { + component = component.getParent(); + if (component instanceof JScrollPane) { + JScrollPane pane = (JScrollPane) component; + JScrollBar bar = pane.getHorizontalScrollBar(); + if ((bar != null) && bar.isVisible()) { + int height = bar.getHeight(); + visRect.y -= height; + visRect.height += height; + } + } + } preferredSize.width = treeState.getPreferredWidth(visRect); } else { @@ -4504,7 +4518,7 @@ public class BasicTreeUI extends TreeUI } } - private void home(JTree tree, BasicTreeUI ui, int direction, + private void home(JTree tree, final BasicTreeUI ui, int direction, boolean addToSelection, boolean changeSelection) { // disable moving of lead unless in discontiguous mode @@ -4514,7 +4528,7 @@ public class BasicTreeUI extends TreeUI changeSelection = true; } - int rowCount = ui.getRowCount(tree); + final int rowCount = ui.getRowCount(tree); if (rowCount > 0) { if(direction == -1) { @@ -4566,6 +4580,13 @@ public class BasicTreeUI extends TreeUI ui.setLeadSelectionPath(ui.getPathForRow(tree, rowCount - 1), true); } + if (ui.isLargeModel()){ + SwingUtilities.invokeLater(new Runnable() { + public void run() { + ui.ensureRowsAreVisible(rowCount - 1, rowCount - 1); + } + }); + } } } } diff --git a/jdk/test/javax/swing/JTree/8003400/Test8003400.java b/jdk/test/javax/swing/JTree/8003400/Test8003400.java new file mode 100644 index 00000000000..f2102f8b1e4 --- /dev/null +++ b/jdk/test/javax/swing/JTree/8003400/Test8003400.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013, 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. + */ + +/* + * @test + * @bug 8003400 + * @summary Tests that JTree shows the last row + * @author Sergey Malenkov + * @run main/othervm Test8003400 + * @run main/othervm Test8003400 reverse + * @run main/othervm Test8003400 system + * @run main/othervm Test8003400 system reverse + */ + +import sun.awt.SunToolkit; + +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.KeyEvent; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.JTree; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.tree.DefaultMutableTreeNode; + +public class Test8003400 { + + private static final String TITLE = "Test JTree with a large model"; + private static List OBJECTS = Arrays.asList(TITLE, "x", "y", "z"); + private static JScrollPane pane; + + public static void main(String[] args) throws Exception { + for (String arg : args) { + if (arg.equals("reverse")) { + Collections.reverse(OBJECTS); + } + if (arg.equals("system")) { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } + } + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + DefaultMutableTreeNode root = new DefaultMutableTreeNode(); + + JTree tree = new JTree(root); + tree.setLargeModel(true); + tree.setRowHeight(16); + + JFrame frame = new JFrame(TITLE); + frame.add(pane = new JScrollPane(tree)); + frame.setSize(200, 100); + frame.setLocationRelativeTo(null); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame.setVisible(true); + + for (String object : OBJECTS) { + root.add(new DefaultMutableTreeNode(object)); + } + tree.expandRow(0); + } + }); + + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + toolkit.realSync(500); + new Robot().keyPress(KeyEvent.VK_END); + toolkit.realSync(500); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + JTree tree = (JTree) pane.getViewport().getView(); + Rectangle inner = tree.getRowBounds(tree.getRowCount() - 1); + Rectangle outer = SwingUtilities.convertRectangle(tree, inner, pane); + outer.y += tree.getRowHeight() - 1 - pane.getVerticalScrollBar().getHeight(); + // error reporting only for automatic testing + if (null != System.getProperty("test.src", null)) { + SwingUtilities.getWindowAncestor(pane).dispose(); + if (outer.y != 0) { + throw new Error("TEST FAILED: " + outer.y); + } + } + } + }); + } +} From 5288b84f0aeceba081a97e25314c92ece5322abd Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 24 Jan 2013 16:48:33 -0800 Subject: [PATCH 172/204] Added tag jdk8-b74 for changeset dde885cc8685 --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 8555b3366ec..53096d3923b 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -195,3 +195,4 @@ cdb401a60cea6ad5ef3f498725ed1decf8dda1ea jdk8-b68 51ad2a34342055333eb5f36e2fb514b027895708 jdk8-b71 c1be681d80a1f1c848dc671d664fccb19e046a12 jdk8-b72 93b9664f97eeb6f89397a8842318ebacaac9feb9 jdk8-b73 +b43aa5bd8ca5c8121336495382d35ecfa7a71536 jdk8-b74 From ad11d38f92225e708f8bbecd30706a5c7587e87c Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 24 Jan 2013 16:48:39 -0800 Subject: [PATCH 173/204] Added tag jdk8-b74 for changeset 5a4f1fb4c6ef --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index 1a3ee17d1bb..c01bb26f197 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -195,3 +195,4 @@ d54dc53e223ed9ce7d5f4d2cd02ad9d5def3c2db jdk8-b59 8171d23e914d758836527b80b06debcfdb718f2d jdk8-b71 cb40427f47145b01b7e53c3e02b38ff7625efbda jdk8-b72 191afde59e7be0e1a1d76d06f2a32ff17444f0ec jdk8-b73 +2132845cf5f717ff5c240a2431c0c0e03e66e3a5 jdk8-b74 From 86f89a0768cf6004a1a812b563f73aa7b14e24eb Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 24 Jan 2013 16:48:45 -0800 Subject: [PATCH 174/204] Added tag jdk8-b74 for changeset 8d54b69d4504 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 617e00e138a..ad0530d1939 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -308,3 +308,4 @@ e94068d4ff52849c8aa0786a53a59b63d1312a39 jdk8-b70 d5cb5830f570d1304ea4b196dde672a291b55f29 jdk8-b72 1e129851479e4f5df439109fca2c7be1f1613522 hs25-b15 11619f33cd683c2f1d6ef72f1c6ff3dacf5a9f1c jdk8-b73 +1a3e54283c54aaa8b3437813e8507fbdc966e5b6 jdk8-b74 From 23ff2911e336618477b224006fc09a3445b3c76e Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 24 Jan 2013 16:48:57 -0800 Subject: [PATCH 175/204] Added tag jdk8-b74 for changeset 6ab75b6a0432 --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index 4d8f24840a0..25b3727d9e6 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -195,3 +195,4 @@ b854e70084214e9dcf1b37373f6e4b1a68760e03 jdk8-b68 499be952a291cec1dc774a84a238941d6faf772d jdk8-b71 bdf2af722a6b54fca47d8c51d17a1b8f41dd7a3e jdk8-b72 84946404d1e1de003ed2bf218ef8d48906a90e37 jdk8-b73 +2087e24a4357eceb6432e94918e75fdc706a27d6 jdk8-b74 From bdd8df2f1b527287f39e0b2cea26fb909aa3276a Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 24 Jan 2013 16:49:01 -0800 Subject: [PATCH 176/204] Added tag jdk8-b74 for changeset f0f3e46c8780 --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index f4bf9b21b81..1ae97b3df38 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -195,3 +195,4 @@ d3fe408f3a9ad250bc9a4e9365bdfc3f28c1d3f4 jdk8-b68 f577a39c9fb3d5820248c13c2cc74a192a9313e0 jdk8-b71 d9707230294d54e695e745a90de6112909100f12 jdk8-b72 c606f644a5d9118c14b5822738bf23c300f14f24 jdk8-b73 +12db3c5a3393b03eeb09ff26f418c4420c21aaab jdk8-b74 From 686adf319b544c41debb75dc7fe27c2229323d38 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 24 Jan 2013 16:49:20 -0800 Subject: [PATCH 177/204] Added tag jdk8-b74 for changeset 64054e252871 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index e774b097c5e..dbc8d128f1f 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -195,3 +195,4 @@ a996b57e554198f4592a5f3c30f2f9f4075e545d jdk8-b70 2a5af0f766d0acd68a81fb08fe11fd66795f86af jdk8-b71 32a57e645e012a1f0665c075969ca598e0dbb948 jdk8-b72 733885f57e14cc27f5a5ff0dffe641d2fa3c704a jdk8-b73 +57d5d954462831ac353a1f40d3bb05ddb4620952 jdk8-b74 From 90c6fdd5060867be1f49e818b2f30822f983458c Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 24 Jan 2013 16:49:37 -0800 Subject: [PATCH 178/204] Added tag jdk8-b74 for changeset 2d74b1d7456b --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index cd611eef514..f4fbd85e67d 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -195,3 +195,4 @@ d7360bf35ee1f40ff78c2e83a22b5446ee464346 jdk8-b69 467e4d9281bcf119eaec42af1423c96bd401871c jdk8-b71 6f0986ed9b7e11d6eb06618f27e20b18f19fb797 jdk8-b72 8d0baee36c7184d55c80354b45704c37d6b7ac79 jdk8-b73 +56c97aff46bb577b8668874154c24115a7e8a3e8 jdk8-b74 From 6e9aeb35208ec7e95bafc1d75e2807c91024f6ef Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Fri, 25 Jan 2013 02:36:28 -0800 Subject: [PATCH 179/204] Added tag hs25-b17 for changeset f767fc368725 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 54ddc0b1e90..d46eb646def 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -310,3 +310,4 @@ d5cb5830f570d1304ea4b196dde672a291b55f29 jdk8-b72 11619f33cd683c2f1d6ef72f1c6ff3dacf5a9f1c jdk8-b73 70c89bd6b895a10d25ca70e08093c09ff2005fda hs25-b16 1a3e54283c54aaa8b3437813e8507fbdc966e5b6 jdk8-b74 +b4391649e91ea8d37f66317a03d6d2573a93d10d hs25-b17 From b29b4794613a2aca125c2a6e9f8ed1d0f01a4ce2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Borggr=C3=A9n-Franck?= Date: Tue, 29 Jan 2013 10:32:49 +0100 Subject: [PATCH 180/204] 8004698: Implement Core Reflection for Type Annotations Reviewed-by: darcy --- jdk/src/share/classes/java/lang/Class.java | 56 ++ jdk/src/share/classes/java/lang/System.java | 9 +- .../java/lang/reflect/AnnotatedArrayType.java | 43 ++ .../reflect/AnnotatedParameterizedType.java | 42 ++ .../java/lang/reflect/AnnotatedType.java | 44 ++ .../lang/reflect/AnnotatedTypeVariable.java | 43 ++ .../lang/reflect/AnnotatedWildcardType.java | 49 ++ .../java/lang/reflect/Constructor.java | 12 + .../classes/java/lang/reflect/Executable.java | 87 +++- .../classes/java/lang/reflect/Field.java | 21 +- .../classes/java/lang/reflect/Method.java | 12 + .../java/lang/reflect/ReflectAccess.java | 6 +- .../java/lang/reflect/TypeVariable.java | 14 +- .../classes/sun/misc/JavaLangAccess.java | 15 +- .../sun/reflect/LangReflectAccess.java | 5 +- .../sun/reflect/ReflectionFactory.java | 9 +- .../annotation/AnnotatedTypeFactory.java | 320 ++++++++++++ .../reflect/annotation/AnnotationParser.java | 4 +- .../reflect/annotation/TypeAnnotation.java | 227 ++++++++ .../annotation/TypeAnnotationParser.java | 491 ++++++++++++++++++ .../reflectiveObjects/TypeVariableImpl.java | 67 ++- jdk/src/share/javavm/export/jvm.h | 6 + jdk/src/share/native/java/lang/Class.c | 5 +- .../annotation/TypeAnnotationReflection.java | 428 +++++++++++++++ .../lang/annotation/TypeParamAnnotation.java | 120 +++++ 25 files changed, 2106 insertions(+), 29 deletions(-) create mode 100644 jdk/src/share/classes/java/lang/reflect/AnnotatedArrayType.java create mode 100644 jdk/src/share/classes/java/lang/reflect/AnnotatedParameterizedType.java create mode 100644 jdk/src/share/classes/java/lang/reflect/AnnotatedType.java create mode 100644 jdk/src/share/classes/java/lang/reflect/AnnotatedTypeVariable.java create mode 100644 jdk/src/share/classes/java/lang/reflect/AnnotatedWildcardType.java create mode 100644 jdk/src/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java create mode 100644 jdk/src/share/classes/sun/reflect/annotation/TypeAnnotation.java create mode 100644 jdk/src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java create mode 100644 jdk/test/java/lang/annotation/TypeAnnotationReflection.java create mode 100644 jdk/test/java/lang/annotation/TypeParamAnnotation.java diff --git a/jdk/src/share/classes/java/lang/Class.java b/jdk/src/share/classes/java/lang/Class.java index 094f0cf26d6..87f78530899 100644 --- a/jdk/src/share/classes/java/lang/Class.java +++ b/jdk/src/share/classes/java/lang/Class.java @@ -29,12 +29,14 @@ import java.lang.reflect.Array; import java.lang.reflect.GenericArrayType; import java.lang.reflect.Member; import java.lang.reflect.Field; +import java.lang.reflect.Executable; import java.lang.reflect.Method; import java.lang.reflect.Constructor; import java.lang.reflect.Modifier; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.AnnotatedType; import java.lang.ref.SoftReference; import java.io.InputStream; import java.io.ObjectStreamField; @@ -2325,6 +2327,11 @@ public final // Annotations handling private native byte[] getRawAnnotations(); + // Since 1.8 + native byte[] getRawTypeAnnotations(); + static byte[] getExecutableTypeAnnotationBytes(Executable ex) { + return getReflectionFactory().getExecutableTypeAnnotationBytes(ex); + } native ConstantPool getConstantPool(); @@ -3196,4 +3203,53 @@ public final * Maintained by the ClassValue class. */ transient ClassValue.ClassValueMap classValueMap; + + /** + * Returns an AnnotatedType object that represents the use of a type to specify + * the superclass of the entity represented by this Class. (The use of type + * Foo to specify the superclass in '... extends Foo' is distinct from the + * declaration of type Foo.) + * + * If this Class represents a class type whose declaration does not explicitly + * indicate an annotated superclass, the return value is null. + * + * If this Class represents either the Object class, an interface type, an + * array type, a primitive type, or void, the return value is null. + * + * @since 1.8 + */ + public AnnotatedType getAnnotatedSuperclass() { + return TypeAnnotationParser.buildAnnotatedSuperclass(getRawTypeAnnotations(), getConstantPool(), this); +} + + /** + * Returns an array of AnnotatedType objects that represent the use of types to + * specify superinterfaces of the entity represented by this Class. (The use + * of type Foo to specify a superinterface in '... implements Foo' is + * distinct from the declaration of type Foo.) + * + * If this Class represents a class, the return value is an array + * containing objects representing the uses of interface types to specify + * interfaces implemented by the class. The order of the objects in the + * array corresponds to the order of the interface types used in the + * 'implements' clause of the declaration of this Class. + * + * If this Class represents an interface, the return value is an array + * containing objects representing the uses of interface types to specify + * interfaces directly extended by the interface. The order of the objects in + * the array corresponds to the order of the interface types used in the + * 'extends' clause of the declaration of this Class. + * + * If this Class represents a class or interface whose declaration does not + * explicitly indicate any annotated superinterfaces, the return value is an + * array of length 0. + * + * If this Class represents either the Object class, an array type, a + * primitive type, or void, the return value is an array of length 0. + * + * @since 1.8 + */ + public AnnotatedType[] getAnnotatedInterfaces() { + return TypeAnnotationParser.buildAnnotatedInterfaces(getRawTypeAnnotations(), getConstantPool(), this); + } } diff --git a/jdk/src/share/classes/java/lang/System.java b/jdk/src/share/classes/java/lang/System.java index a6206e60391..d901e992b9a 100644 --- a/jdk/src/share/classes/java/lang/System.java +++ b/jdk/src/share/classes/java/lang/System.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2013, 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 @@ -26,6 +26,7 @@ package java.lang; import java.io.*; import java.lang.annotation.Annotation; +import java.lang.reflect.Executable; import java.util.Properties; import java.util.PropertyPermission; import java.util.StringTokenizer; @@ -1199,6 +1200,12 @@ public final class System { public A getDirectDeclaredAnnotation(Class klass, Class anno) { return klass.getDirectDeclaredAnnotation(anno); } + public byte[] getRawClassTypeAnnotations(Class klass) { + return klass.getRawTypeAnnotations(); + } + public byte[] getRawExecutableTypeAnnotations(Executable executable) { + return Class.getExecutableTypeAnnotationBytes(executable); + } public > E[] getEnumConstantsShared(Class klass) { return klass.getEnumConstantsShared(); diff --git a/jdk/src/share/classes/java/lang/reflect/AnnotatedArrayType.java b/jdk/src/share/classes/java/lang/reflect/AnnotatedArrayType.java new file mode 100644 index 00000000000..e84a3360fdd --- /dev/null +++ b/jdk/src/share/classes/java/lang/reflect/AnnotatedArrayType.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2012, 2013, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package java.lang.reflect; + + +/** + * AnnotatedArrayType represents the use of an array type, whose component + * type may itself represent the annotated use of a type. + * + * @since 1.8 + */ +public interface AnnotatedArrayType extends AnnotatedType { + + /** + * Returns the annotated generic component type of this array type. + * + * @return the annotated generic component type of this array type + */ + AnnotatedType getAnnotatedGenericComponentType(); +} diff --git a/jdk/src/share/classes/java/lang/reflect/AnnotatedParameterizedType.java b/jdk/src/share/classes/java/lang/reflect/AnnotatedParameterizedType.java new file mode 100644 index 00000000000..4fa089e318c --- /dev/null +++ b/jdk/src/share/classes/java/lang/reflect/AnnotatedParameterizedType.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012, 2013, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package java.lang.reflect; + +/** + * AnnotatedParameterizedType represents the use of a parameterized type, + * whose type arguments may themselves represent annotated uses of types. + * + * @since 1.8 + */ +public interface AnnotatedParameterizedType extends AnnotatedType { + + /** + * Returns the annotated actual type arguments of this parameterized type. + * + * @return the annotated actual type arguments of this parameterized type + */ + AnnotatedType[] getAnnotatedActualTypeArguments(); +} diff --git a/jdk/src/share/classes/java/lang/reflect/AnnotatedType.java b/jdk/src/share/classes/java/lang/reflect/AnnotatedType.java new file mode 100644 index 00000000000..d1ee79f14f4 --- /dev/null +++ b/jdk/src/share/classes/java/lang/reflect/AnnotatedType.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2012, 2013, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package java.lang.reflect; + +/** + * AnnotatedType represents the annotated use of a type in the program + * currently running in this VM. The use may be of any type in the Java + * programming language, including an array type, a parameterized type, a type + * variable, or a wildcard type. + * + * @since 1.8 + */ +public interface AnnotatedType extends AnnotatedElement { + + /** + * Returns the underlying type that this annotated type represents. + * + * @return the type this annotated type represents + */ + public Type getType(); +} diff --git a/jdk/src/share/classes/java/lang/reflect/AnnotatedTypeVariable.java b/jdk/src/share/classes/java/lang/reflect/AnnotatedTypeVariable.java new file mode 100644 index 00000000000..3580a14442f --- /dev/null +++ b/jdk/src/share/classes/java/lang/reflect/AnnotatedTypeVariable.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2012, 2013, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package java.lang.reflect; + +/** + * AnnotatedTypeVariable represents the use of a type variable, whose + * declaration may have bounds which themselves represent annotated uses of + * types. + * + * @since 1.8 + */ +public interface AnnotatedTypeVariable extends AnnotatedType { + + /** + * Returns the annotated bounds of this type variable. + * + * @return the annotated bounds of this type variable + */ + AnnotatedType[] getAnnotatedBounds(); +} diff --git a/jdk/src/share/classes/java/lang/reflect/AnnotatedWildcardType.java b/jdk/src/share/classes/java/lang/reflect/AnnotatedWildcardType.java new file mode 100644 index 00000000000..c357eb9d0bc --- /dev/null +++ b/jdk/src/share/classes/java/lang/reflect/AnnotatedWildcardType.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2012, 2013, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package java.lang.reflect; + +/** + * AnnotatedWildcardType represents the use of a wildcard type argument, whose + * upper or lower bounds may themselves represent annotated uses of types. + * + * @since 1.8 + */ +public interface AnnotatedWildcardType extends AnnotatedType { + + /** + * Returns the annotated lower bounds of this wildcard type. + * + * @return the annotated lower bounds of this wildcard type + */ + AnnotatedType[] getAnnotatedLowerBounds(); + + /** + * Returns the annotated upper bounds of this wildcard type. + * + * @return the annotated upper bounds of this wildcard type + */ + AnnotatedType[] getAnnotatedUpperBounds(); +} diff --git a/jdk/src/share/classes/java/lang/reflect/Constructor.java b/jdk/src/share/classes/java/lang/reflect/Constructor.java index 1973e820950..bbfd1d5ab9d 100644 --- a/jdk/src/share/classes/java/lang/reflect/Constructor.java +++ b/jdk/src/share/classes/java/lang/reflect/Constructor.java @@ -154,6 +154,10 @@ public final class Constructor extends Executable { byte[] getAnnotationBytes() { return annotations; } + @Override + byte[] getTypeAnnotationBytes() { + return typeAnnotations; + } /** * {@inheritDoc} @@ -523,4 +527,12 @@ public final class Constructor extends Executable { } } } + + /** + * {@inheritDoc} + * @since 1.8 + */ + public AnnotatedType getAnnotatedReturnType() { + return getAnnotatedReturnType0(getDeclaringClass()); + } } diff --git a/jdk/src/share/classes/java/lang/reflect/Executable.java b/jdk/src/share/classes/java/lang/reflect/Executable.java index f2befd2dcdd..b9ed7310a4d 100644 --- a/jdk/src/share/classes/java/lang/reflect/Executable.java +++ b/jdk/src/share/classes/java/lang/reflect/Executable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -31,6 +31,8 @@ import java.util.Map; import java.util.Objects; import sun.reflect.annotation.AnnotationParser; import sun.reflect.annotation.AnnotationSupport; +import sun.reflect.annotation.TypeAnnotationParser; +import sun.reflect.annotation.TypeAnnotation; import sun.reflect.generics.repository.ConstructorRepository; /** @@ -50,6 +52,7 @@ public abstract class Executable extends AccessibleObject * Accessor method to allow code sharing */ abstract byte[] getAnnotationBytes(); + abstract byte[] getTypeAnnotationBytes(); /** * Does the Executable have generic information. @@ -470,4 +473,86 @@ public abstract class Executable extends AccessibleObject return declaredAnnotations; } + + /* Helper for subclasses of Executable. + * + * Returns an AnnotatedType object that represents the use of a type to + * specify the return type of the method/constructor represented by this + * Executable. + * + * @since 1.8 + */ + AnnotatedType getAnnotatedReturnType0(Type returnType) { + return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes(), + sun.misc.SharedSecrets.getJavaLangAccess(). + getConstantPool(getDeclaringClass()), + this, + getDeclaringClass(), + returnType, + TypeAnnotation.TypeAnnotationTarget.METHOD_RETURN_TYPE); + } + + /** + * Returns an AnnotatedType object that represents the use of a type to + * specify the receiver type of the method/constructor represented by this + * Executable. The receiver type of a method/constructor is available only + * if the method/constructor declares a formal parameter called 'this'. + * + * Returns null if this Executable represents a constructor or instance + * method that either declares no formal parameter called 'this', or + * declares a formal parameter called 'this' with no annotations on its + * type. + * + * Returns null if this Executable represents a static method. + * + * @since 1.8 + */ + public AnnotatedType getAnnotatedReceiverType() { + return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes(), + sun.misc.SharedSecrets.getJavaLangAccess(). + getConstantPool(getDeclaringClass()), + this, + getDeclaringClass(), + getDeclaringClass(), + TypeAnnotation.TypeAnnotationTarget.METHOD_RECEIVER_TYPE); + } + + /** + * Returns an array of AnnotatedType objects that represent the use of + * types to specify formal parameter types of the method/constructor + * represented by this Executable. The order of the objects in the array + * corresponds to the order of the formal parameter types in the + * declaration of the method/constructor. + * + * Returns an array of length 0 if the method/constructor declares no + * parameters. + * + * @since 1.8 + */ + public AnnotatedType[] getAnnotatedParameterTypes() { + throw new UnsupportedOperationException("Not yet"); + } + + /** + * Returns an array of AnnotatedType objects that represent the use of + * types to specify the declared exceptions of the method/constructor + * represented by this Executable. The order of the objects in the array + * corresponds to the order of the exception types in the declaration of + * the method/constructor. + * + * Returns an array of length 0 if the method/constructor declares no + * exceptions. + * + * @since 1.8 + */ + public AnnotatedType[] getAnnotatedExceptionTypes() { + return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes(), + sun.misc.SharedSecrets.getJavaLangAccess(). + getConstantPool(getDeclaringClass()), + this, + getDeclaringClass(), + getGenericExceptionTypes(), + TypeAnnotation.TypeAnnotationTarget.THROWS); + } + } diff --git a/jdk/src/share/classes/java/lang/reflect/Field.java b/jdk/src/share/classes/java/lang/reflect/Field.java index e5471459586..d2502efb4dd 100644 --- a/jdk/src/share/classes/java/lang/reflect/Field.java +++ b/jdk/src/share/classes/java/lang/reflect/Field.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, 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 @@ -36,7 +36,8 @@ import java.util.Map; import java.util.Objects; import sun.reflect.annotation.AnnotationParser; import sun.reflect.annotation.AnnotationSupport; - +import sun.reflect.annotation.TypeAnnotation; +import sun.reflect.annotation.TypeAnnotationParser; /** * A {@code Field} provides information about, and dynamic access to, a @@ -1053,4 +1054,20 @@ class Field extends AccessibleObject implements Member { } return declaredAnnotations; } + + /** + * Returns an AnnotatedType object that represents the use of a type to specify + * the declared type of the field represented by this Field. + * + * @since 1.8 + */ + public AnnotatedType getAnnotatedType() { + return TypeAnnotationParser.buildAnnotatedType(typeAnnotations, + sun.misc.SharedSecrets.getJavaLangAccess(). + getConstantPool(getDeclaringClass()), + this, + getDeclaringClass(), + getGenericType(), + TypeAnnotation.TypeAnnotationTarget.FIELD_TYPE); +} } diff --git a/jdk/src/share/classes/java/lang/reflect/Method.java b/jdk/src/share/classes/java/lang/reflect/Method.java index a7beb011400..1507c77194a 100644 --- a/jdk/src/share/classes/java/lang/reflect/Method.java +++ b/jdk/src/share/classes/java/lang/reflect/Method.java @@ -165,6 +165,10 @@ public final class Method extends Executable { byte[] getAnnotationBytes() { return annotations; } + @Override + byte[] getTypeAnnotationBytes() { + return typeAnnotations; + } /** * {@inheritDoc} @@ -621,6 +625,14 @@ public final class Method extends Executable { return sharedGetParameterAnnotations(parameterTypes, parameterAnnotations); } + /** + * {@inheritDoc} + * @since 1.8 + */ + public AnnotatedType getAnnotatedReturnType() { + return getAnnotatedReturnType0(getGenericReturnType()); + } + @Override void handleParameterNumberMismatch(int resultLength, int numParameters) { throw new AnnotationFormatError("Parameter annotations don't match number of parameters"); diff --git a/jdk/src/share/classes/java/lang/reflect/ReflectAccess.java b/jdk/src/share/classes/java/lang/reflect/ReflectAccess.java index 80311d240e6..c3ac1557b85 100644 --- a/jdk/src/share/classes/java/lang/reflect/ReflectAccess.java +++ b/jdk/src/share/classes/java/lang/reflect/ReflectAccess.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -128,6 +128,10 @@ class ReflectAccess implements sun.reflect.LangReflectAccess { return c.getRawParameterAnnotations(); } + public byte[] getExecutableTypeAnnotationBytes(Executable ex) { + return ex.getTypeAnnotationBytes(); + } + // // Copying routines, needed to quickly fabricate new Field, // Method, and Constructor objects from templates diff --git a/jdk/src/share/classes/java/lang/reflect/TypeVariable.java b/jdk/src/share/classes/java/lang/reflect/TypeVariable.java index b0ff7880cda..42027e0041c 100644 --- a/jdk/src/share/classes/java/lang/reflect/TypeVariable.java +++ b/jdk/src/share/classes/java/lang/reflect/TypeVariable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -86,4 +86,16 @@ public interface TypeVariable extends Type, Annota * @return the name of this type variable, as it appears in the source code */ String getName(); + + /** + * Returns an array of AnnotatedType objects that represent the use of + * types to denote the upper bounds of the type parameter represented by + * this TypeVariable. The order of the objects in the array corresponds to + * the order of the bounds in the declaration of the type parameter. + * + * Returns an array of length 0 if the type parameter declares no bounds. + * + * @since 1.8 + */ + AnnotatedType[] getAnnotatedBounds(); } diff --git a/jdk/src/share/classes/sun/misc/JavaLangAccess.java b/jdk/src/share/classes/sun/misc/JavaLangAccess.java index 9506194c707..1624d67f4a9 100644 --- a/jdk/src/share/classes/sun/misc/JavaLangAccess.java +++ b/jdk/src/share/classes/sun/misc/JavaLangAccess.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -26,6 +26,7 @@ package sun.misc; import java.lang.annotation.Annotation; +import java.lang.reflect.Executable; import sun.reflect.ConstantPool; import sun.reflect.annotation.AnnotationType; import sun.nio.ch.Interruptible; @@ -46,6 +47,18 @@ public interface JavaLangAccess { */ AnnotationType getAnnotationType(Class klass); + /** + * Get the array of bytes that is the class-file representation + * of this Class' type annotations. + */ + byte[] getRawClassTypeAnnotations(Class klass); + + /** + * Get the array of bytes that is the class-file representation + * of this Executable's type annotations. + */ + byte[] getRawExecutableTypeAnnotations(Executable executable); + /** * Returns the elements of an enum class or null if the * Class object does not represent an enum type; diff --git a/jdk/src/share/classes/sun/reflect/LangReflectAccess.java b/jdk/src/share/classes/sun/reflect/LangReflectAccess.java index fba1d318086..3c3b2757410 100644 --- a/jdk/src/share/classes/sun/reflect/LangReflectAccess.java +++ b/jdk/src/share/classes/sun/reflect/LangReflectAccess.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -81,6 +81,9 @@ public interface LangReflectAccess { public void setConstructorAccessor(Constructor c, ConstructorAccessor accessor); + /** Gets the byte[] that encodes TypeAnnotations on an Executable. */ + public byte[] getExecutableTypeAnnotationBytes(Executable ex); + /** Gets the "slot" field from a Constructor (used for serialization) */ public int getConstructorSlot(Constructor c); diff --git a/jdk/src/share/classes/sun/reflect/ReflectionFactory.java b/jdk/src/share/classes/sun/reflect/ReflectionFactory.java index ea5323b8b9a..de97dfc7001 100644 --- a/jdk/src/share/classes/sun/reflect/ReflectionFactory.java +++ b/jdk/src/share/classes/sun/reflect/ReflectionFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -26,6 +26,7 @@ package sun.reflect; import java.lang.reflect.Field; +import java.lang.reflect.Executable; import java.lang.reflect.Method; import java.lang.reflect.Constructor; import java.lang.reflect.Modifier; @@ -314,6 +315,12 @@ public class ReflectionFactory { return langReflectAccess().copyConstructor(arg); } + /** Gets the byte[] that encodes TypeAnnotations on an executable. + */ + public byte[] getExecutableTypeAnnotationBytes(Executable ex) { + return langReflectAccess().getExecutableTypeAnnotationBytes(ex); + } + //-------------------------------------------------------------------------- // // Routines used by serialization diff --git a/jdk/src/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java b/jdk/src/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java new file mode 100644 index 00000000000..afb4c4865e7 --- /dev/null +++ b/jdk/src/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2013, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package sun.reflect.annotation; + +import java.lang.annotation.*; +import java.lang.reflect.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import static sun.reflect.annotation.TypeAnnotation.*; + +public class AnnotatedTypeFactory { + /** + * Create an AnnotatedType. + * + * @param type the type this AnnotatedType corresponds to + * @param currentLoc the location this AnnotatedType corresponds to + * @param actualTypeAnnos the type annotations this AnnotatedType has + * @param allOnSameTarget all type annotation on the same TypeAnnotationTarget + * as the AnnotatedType being built + * @param decl the declaration having the type use this AnnotatedType + * corresponds to + */ + public static AnnotatedType buildAnnotatedType(Type type, + LocationInfo currentLoc, + TypeAnnotation[] actualTypeAnnos, + TypeAnnotation[] allOnSameTarget, + AnnotatedElement decl) { + if (type == null) { + return EMPTY_ANNOTATED_TYPE; + } + if (isArray(type)) + return new AnnotatedArrayTypeImpl(type, + currentLoc, + actualTypeAnnos, + allOnSameTarget, + decl); + if (type instanceof Class) { + return new AnnotatedTypeBaseImpl(type, + addNesting(type, currentLoc), + actualTypeAnnos, + allOnSameTarget, + decl); + } else if (type instanceof TypeVariable) { + return new AnnotatedTypeVariableImpl((TypeVariable)type, + currentLoc, + actualTypeAnnos, + allOnSameTarget, + decl); + } else if (type instanceof ParameterizedType) { + return new AnnotatedParameterizedTypeImpl((ParameterizedType)type, + addNesting(type, currentLoc), + actualTypeAnnos, + allOnSameTarget, + decl); + } else if (type instanceof WildcardType) { + return new AnnotatedWildcardTypeImpl((WildcardType) type, + currentLoc, + actualTypeAnnos, + allOnSameTarget, + decl); + } + throw new AssertionError("Unknown instance of Type: " + type + "\nThis should not happen."); + } + + private static LocationInfo addNesting(Type type, LocationInfo addTo) { + if (isArray(type)) + return addTo; + if (type instanceof Class) { + Class clz = (Class)type; + if (clz.getEnclosingClass() == null) + return addTo; + return addNesting(clz.getEnclosingClass(), addTo.pushInner()); + } else if (type instanceof ParameterizedType) { + ParameterizedType t = (ParameterizedType)type; + if (t.getOwnerType() == null) + return addTo; + return addNesting(t.getOwnerType(), addTo.pushInner()); + } + return addTo; + } + + private static boolean isArray(Type t) { + if (t instanceof Class) { + Class c = (Class)t; + if (c.isArray()) + return true; + } else if (t instanceof GenericArrayType) { + return true; + } + return false; + } + + static final AnnotatedType EMPTY_ANNOTATED_TYPE = new AnnotatedTypeBaseImpl(null, LocationInfo.BASE_LOCATION, + new TypeAnnotation[0], new TypeAnnotation[0], null); + + private static class AnnotatedTypeBaseImpl implements AnnotatedType { + private final Type type; + private final AnnotatedElement decl; + private final LocationInfo location; + private final TypeAnnotation[] allOnSameTargetTypeAnnotations; + private final Map, Annotation> annotations; + + AnnotatedTypeBaseImpl(Type type, LocationInfo location, + TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations, + AnnotatedElement decl) { + this.type = type; + this.decl = decl; + this.location = location; + this.allOnSameTargetTypeAnnotations = allOnSameTargetTypeAnnotations; + this.annotations = TypeAnnotationParser.mapTypeAnnotations(location.filter(actualTypeAnnotations)); + } + + // AnnotatedElement + @Override + public final boolean isAnnotationPresent(Class annotation) { + return annotations.get(annotation) != null; + } + + @Override + public final Annotation[] getAnnotations() { + return getDeclaredAnnotations(); + } + + @Override + public final T getAnnotation(Class annotation) { + return getDeclaredAnnotation(annotation); + } + + @Override + public final T[] getAnnotations(Class annotation) { + return getDeclaredAnnotations(annotation); + } + + @Override + public Annotation[] getDeclaredAnnotations() { + return annotations.values().toArray(new Annotation[0]); + } + + @Override + @SuppressWarnings("unchecked") + public T getDeclaredAnnotation(Class annotation) { + return (T)annotations.get(annotation); + } + + @Override + public T[] getDeclaredAnnotations(Class annotation) { + return AnnotationSupport.getMultipleAnnotations(annotations, annotation); + } + + // AnnotatedType + @Override + public Type getType() { + return type; + } + + // Implementation details + LocationInfo getLocation() { + return location; + } + TypeAnnotation[] getTypeAnnotations() { + return allOnSameTargetTypeAnnotations; + } + AnnotatedElement getDecl() { + return decl; + } + } + + private static class AnnotatedArrayTypeImpl extends AnnotatedTypeBaseImpl implements AnnotatedArrayType { + AnnotatedArrayTypeImpl(Type type, LocationInfo location, + TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations, + AnnotatedElement decl) { + super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl); + } + + @Override + public AnnotatedType getAnnotatedGenericComponentType() { + return AnnotatedTypeFactory.buildAnnotatedType(getComponentType(), + getLocation().pushArray(), + getTypeAnnotations(), + getTypeAnnotations(), + getDecl()); + } + + private Type getComponentType() { + Type t = getType(); + if (t instanceof Class) { + Class c = (Class)t; + return c.getComponentType(); + } + return ((GenericArrayType)t).getGenericComponentType(); + } + } + + private static class AnnotatedTypeVariableImpl extends AnnotatedTypeBaseImpl implements AnnotatedTypeVariable { + AnnotatedTypeVariableImpl(TypeVariable type, LocationInfo location, + TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations, + AnnotatedElement decl) { + super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl); + } + + @Override + public AnnotatedType[] getAnnotatedBounds() { + return getTypeVariable().getAnnotatedBounds(); + } + + private TypeVariable getTypeVariable() { + return (TypeVariable)getType(); + } + } + + private static class AnnotatedParameterizedTypeImpl extends AnnotatedTypeBaseImpl implements AnnotatedParameterizedType { + AnnotatedParameterizedTypeImpl(ParameterizedType type, LocationInfo location, + TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations, + AnnotatedElement decl) { + super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl); + } + + @Override + public AnnotatedType[] getAnnotatedActualTypeArguments() { + Type[] arguments = getParameterizedType().getActualTypeArguments(); + AnnotatedType[] res = new AnnotatedType[arguments.length]; + Arrays.fill(res, EMPTY_ANNOTATED_TYPE); + int initialCapacity = getTypeAnnotations().length; + for (int i = 0; i < res.length; i++) { + List l = new ArrayList<>(initialCapacity); + LocationInfo newLoc = getLocation().pushTypeArg((byte)i); + for (TypeAnnotation t : getTypeAnnotations()) + if (t.getLocationInfo().isSameLocationInfo(newLoc)) + l.add(t); + res[i] = buildAnnotatedType(arguments[i], + newLoc, + l.toArray(new TypeAnnotation[0]), + getTypeAnnotations(), + getDecl()); + } + return res; + } + + private ParameterizedType getParameterizedType() { + return (ParameterizedType)getType(); + } + } + + private static class AnnotatedWildcardTypeImpl extends AnnotatedTypeBaseImpl implements AnnotatedWildcardType { + private final boolean hasUpperBounds; + AnnotatedWildcardTypeImpl(WildcardType type, LocationInfo location, + TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations, + AnnotatedElement decl) { + super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl); + hasUpperBounds = (type.getLowerBounds().length == 0); + } + + @Override + public AnnotatedType[] getAnnotatedUpperBounds() { + if (!hasUpperBounds()) + return new AnnotatedType[0]; + return getAnnotatedBounds(getWildcardType().getUpperBounds()); + } + + @Override + public AnnotatedType[] getAnnotatedLowerBounds() { + if (hasUpperBounds) + return new AnnotatedType[0]; + return getAnnotatedBounds(getWildcardType().getLowerBounds()); + } + + private AnnotatedType[] getAnnotatedBounds(Type[] bounds) { + AnnotatedType[] res = new AnnotatedType[bounds.length]; + Arrays.fill(res, EMPTY_ANNOTATED_TYPE); + LocationInfo newLoc = getLocation().pushWildcard(); + int initialCapacity = getTypeAnnotations().length; + for (int i = 0; i < res.length; i++) { + List l = new ArrayList<>(initialCapacity); + for (TypeAnnotation t : getTypeAnnotations()) + if (t.getLocationInfo().isSameLocationInfo(newLoc)) + l.add(t); + res[i] = buildAnnotatedType(bounds[i], + newLoc, + l.toArray(new TypeAnnotation[0]), + getTypeAnnotations(), + getDecl()); + } + return res; + } + + private WildcardType getWildcardType() { + return (WildcardType)getType(); + } + + private boolean hasUpperBounds() { + return hasUpperBounds; + } + } +} diff --git a/jdk/src/share/classes/sun/reflect/annotation/AnnotationParser.java b/jdk/src/share/classes/sun/reflect/annotation/AnnotationParser.java index 6f26ec368b7..a980a9126ef 100644 --- a/jdk/src/share/classes/sun/reflect/annotation/AnnotationParser.java +++ b/jdk/src/share/classes/sun/reflect/annotation/AnnotationParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -188,7 +188,7 @@ public class AnnotationParser { * available at runtime */ @SuppressWarnings("unchecked") - private static Annotation parseAnnotation(ByteBuffer buf, + static Annotation parseAnnotation(ByteBuffer buf, ConstantPool constPool, Class container, boolean exceptionOnMissingAnnotationClass) { diff --git a/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotation.java b/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotation.java new file mode 100644 index 00000000000..c5399725e8b --- /dev/null +++ b/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotation.java @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2013, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ +package sun.reflect.annotation; + +import java.lang.annotation.Annotation; +import java.lang.annotation.AnnotationFormatError; +import java.lang.reflect.AnnotatedElement; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; + +/** + * A TypeAnnotation contains all the information needed to transform type + * annotations on declarations in the class file to actual Annotations in + * AnnotatedType instances. + * + * TypeAnnotaions contain a base Annotation, location info (which lets you + * distinguish between '@A Inner.@B Outer' in for example nested types), + * target info and the declaration the TypeAnnotaiton was parsed from. + */ +public class TypeAnnotation { + private final TypeAnnotationTargetInfo targetInfo; + private final LocationInfo loc; + private final Annotation annotation; + private final AnnotatedElement baseDeclaration; + + public TypeAnnotation(TypeAnnotationTargetInfo targetInfo, + LocationInfo loc, + Annotation annotation, + AnnotatedElement baseDeclaration) { + this.targetInfo = targetInfo; + this.loc = loc; + this.annotation = annotation; + this.baseDeclaration = baseDeclaration; + } + + public TypeAnnotationTargetInfo getTargetInfo() { + return targetInfo; + } + public Annotation getAnnotation() { + return annotation; + } + public AnnotatedElement getBaseDeclaration() { + return baseDeclaration; + } + public LocationInfo getLocationInfo() { + return loc; + } + + public static List filter(TypeAnnotation[] typeAnnotations, + TypeAnnotationTarget predicate) { + ArrayList typeAnnos = new ArrayList<>(typeAnnotations.length); + for (TypeAnnotation t : typeAnnotations) + if (t.getTargetInfo().getTarget() == predicate) + typeAnnos.add(t); + typeAnnos.trimToSize(); + return typeAnnos; + } + + public static enum TypeAnnotationTarget { + CLASS_TYPE_PARAMETER, + METHOD_TYPE_PARAMETER, + CLASS_EXTENDS, + CLASS_IMPLEMENTS, + CLASS_PARAMETER_BOUND, + METHOD_PARAMETER_BOUND, + METHOD_RETURN_TYPE, + METHOD_RECEIVER_TYPE, + FIELD_TYPE, + THROWS; + } + public static class TypeAnnotationTargetInfo { + private final TypeAnnotationTarget target; + private final int count; + private final int secondaryIndex; + private static final int UNUSED_INDEX = -2; // this is not a valid index in the 308 spec + + public TypeAnnotationTargetInfo(TypeAnnotationTarget target) { + this(target, UNUSED_INDEX, UNUSED_INDEX); + } + + public TypeAnnotationTargetInfo(TypeAnnotationTarget target, + int count) { + this(target, count, UNUSED_INDEX); + } + + public TypeAnnotationTargetInfo(TypeAnnotationTarget target, + int count, + int secondaryIndex) { + this.target = target; + this.count = count; + this.secondaryIndex = secondaryIndex; + } + + public TypeAnnotationTarget getTarget() { + return target; + } + public int getCount() { + return count; + } + public int getSecondaryIndex() { + return secondaryIndex; + } + + @Override + public String toString() { + return "" + target + ": " + count + ", " + secondaryIndex; + } + } + + public static class LocationInfo { + private final int depth; + private final Location[] locations; + + private LocationInfo() { + this(0, new Location[0]); + } + private LocationInfo(int depth, Location[] locations) { + this.depth = depth; + this.locations = locations; + } + + public static final LocationInfo BASE_LOCATION = new LocationInfo(); + + public static LocationInfo parseLocationInfo(ByteBuffer buf) { + int depth = buf.get(); + if (depth == 0) + return BASE_LOCATION; + Location[] locations = new Location[depth]; + for (int i = 0; i < depth; i++) { + byte tag = buf.get(); + byte index = buf.get(); + if (!(tag == 0 || tag == 1 | tag == 2 || tag == 3)) + throw new AnnotationFormatError("Bad Location encoding in Type Annotation"); + if (tag != 3 && index != 0) + throw new AnnotationFormatError("Bad Location encoding in Type Annotation"); + locations[i] = new Location(tag, index); + } + return new LocationInfo(depth, locations); + } + + public LocationInfo pushArray() { + return pushLocation((byte)0, (byte)0); + } + + public LocationInfo pushInner() { + return pushLocation((byte)1, (byte)0); + } + + public LocationInfo pushWildcard() { + return pushLocation((byte) 2, (byte) 0); + } + + public LocationInfo pushTypeArg(byte index) { + return pushLocation((byte) 3, index); + } + + public LocationInfo pushLocation(byte tag, byte index) { + int newDepth = this.depth + 1; + Location[] res = new Location[newDepth]; + System.arraycopy(this.locations, 0, res, 0, depth); + res[newDepth - 1] = new Location(tag, index); + return new LocationInfo(newDepth, res); + } + + public TypeAnnotation[] filter(TypeAnnotation[] ta) { + ArrayList l = new ArrayList<>(ta.length); + for (TypeAnnotation t : ta) { + if (isSameLocationInfo(t.getLocationInfo())) + l.add(t); + } + return l.toArray(new TypeAnnotation[0]); + } + + boolean isSameLocationInfo(LocationInfo other) { + if (depth != other.depth) + return false; + for (int i = 0; i < depth; i++) + if (!locations[i].isSameLocation(other.locations[i])) + return false; + return true; + } + + public static class Location { + public final byte tag; + public final byte index; + + boolean isSameLocation(Location other) { + return tag == other.tag && index == other.index; + } + + public Location(byte tag, byte index) { + this.tag = tag; + this.index = index; + } + } + } + + @Override + public String toString() { + return annotation.toString() + " with Targetnfo: " + + targetInfo.toString() + " on base declaration: " + + baseDeclaration.toString(); + } +} diff --git a/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java b/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java new file mode 100644 index 00000000000..12abe28b4d5 --- /dev/null +++ b/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java @@ -0,0 +1,491 @@ +/* + * Copyright (c) 2013, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package sun.reflect.annotation; + +import java.lang.annotation.*; +import java.lang.reflect.*; +import java.nio.ByteBuffer; +import java.nio.BufferUnderflowException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import sun.misc.JavaLangAccess; +import sun.reflect.ConstantPool; +import static sun.reflect.annotation.TypeAnnotation.*; + +/** + * TypeAnnotationParser implements the logic needed to parse + * TypeAnnotations from an array of bytes. + */ +public class TypeAnnotationParser { + private static final TypeAnnotation[] EMPTY_TYPE_ANNOTATION_ARRAY = new TypeAnnotation[0]; + + /** + * Build an AnnotatedType from the parameters supplied. + * + * This method and {@code buildAnnotatedTypes} are probably + * the entry points you are looking for. + * + * @param rawAnnotations the byte[] encoding of all type annotations on this declaration + * @param cp the ConstantPool needed to parse the embedded Annotation + * @param decl the dclaration this type annotation is on + * @param container the Class this type annotation is on (may be the same as decl) + * @param type the type the AnnotatedType corresponds to + * @param filter the type annotation targets included in this AnnotatedType + */ + public static AnnotatedType buildAnnotatedType(byte[] rawAnnotations, + ConstantPool cp, + AnnotatedElement decl, + Class container, + Type type, + TypeAnnotationTarget filter) { + TypeAnnotation[] tas = parseTypeAnnotations(rawAnnotations, + cp, + decl, + container); + List l = new ArrayList<>(tas.length); + for (TypeAnnotation t : tas) { + TypeAnnotationTargetInfo ti = t.getTargetInfo(); + if (ti.getTarget() == filter) + l.add(t); + } + TypeAnnotation[] typeAnnotations = l.toArray(new TypeAnnotation[0]); + return AnnotatedTypeFactory.buildAnnotatedType(type, + LocationInfo.BASE_LOCATION, + typeAnnotations, + typeAnnotations, + decl); + } + + /** + * Build an array of AnnotatedTypes from the parameters supplied. + * + * This method and {@code buildAnnotatedType} are probably + * the entry points you are looking for. + * + * @param rawAnnotations the byte[] encoding of all type annotations on this declaration + * @param cp the ConstantPool needed to parse the embedded Annotation + * @param decl the declaration this type annotation is on + * @param container the Class this type annotation is on (may be the same as decl) + * @param types the Types the AnnotatedTypes corresponds to + * @param filter the type annotation targets that included in this AnnotatedType + */ + public static AnnotatedType[] buildAnnotatedTypes(byte[] rawAnnotations, + ConstantPool cp, + AnnotatedElement decl, + Class container, + Type[] types, + TypeAnnotationTarget filter) { + int size = types.length; + AnnotatedType[] result = new AnnotatedType[size]; + Arrays.fill(result, AnnotatedTypeFactory.EMPTY_ANNOTATED_TYPE); + @SuppressWarnings("rawtypes") + ArrayList[] l = new ArrayList[size]; // array of ArrayList + + TypeAnnotation[] tas = parseTypeAnnotations(rawAnnotations, + cp, + decl, + container); + for (TypeAnnotation t : tas) { + TypeAnnotationTargetInfo ti = t.getTargetInfo(); + if (ti.getTarget() == filter) { + int pos = ti.getCount(); + if (l[pos] == null) { + ArrayList tmp = new ArrayList<>(tas.length); + l[pos] = tmp; + } + @SuppressWarnings("unchecked") + ArrayList tmp = l[pos]; + tmp.add(t); + } + } + for (int i = 0; i < size; i++) { + @SuppressWarnings("unchecked") + ArrayList list = l[i]; + if (list != null) { + TypeAnnotation[] typeAnnotations = list.toArray(new TypeAnnotation[0]); + result[i] = AnnotatedTypeFactory.buildAnnotatedType(types[i], + LocationInfo.BASE_LOCATION, + typeAnnotations, + typeAnnotations, + decl); + } + } + return result; + } + + // Class helpers + + /** + * Build an AnnotatedType for the class decl's supertype. + * + * @param rawAnnotations the byte[] encoding of all type annotations on this declaration + * @param cp the ConstantPool needed to parse the embedded Annotation + * @param decl the Class which annotated supertype is being built + */ + public static AnnotatedType buildAnnotatedSuperclass(byte[] rawAnnotations, + ConstantPool cp, + Class decl) { + Type supertype = decl.getGenericSuperclass(); + if (supertype == null) + return AnnotatedTypeFactory.EMPTY_ANNOTATED_TYPE; + return buildAnnotatedType(rawAnnotations, + cp, + decl, + decl, + supertype, + TypeAnnotationTarget.CLASS_EXTENDS); + } + + /** + * Build an array of AnnotatedTypes for the class decl's implemented + * interfaces. + * + * @param rawAnnotations the byte[] encoding of all type annotations on this declaration + * @param cp the ConstantPool needed to parse the embedded Annotation + * @param decl the Class whose annotated implemented interfaces is being built + */ + public static AnnotatedType[] buildAnnotatedInterfaces(byte[] rawAnnotations, + ConstantPool cp, + Class decl) { + return buildAnnotatedTypes(rawAnnotations, + cp, + decl, + decl, + decl.getGenericInterfaces(), + TypeAnnotationTarget.CLASS_IMPLEMENTS); + } + + // TypeVariable helpers + + /** + * Parse regular annotations on a TypeVariable declared on genericDecl. + * + * Regular Annotations on TypeVariables are stored in the type + * annotation byte[] in the class file. + * + * @param genericsDecl the declaration declaring the type variable + * @param typeVarIndex the 0-based index of this type variable in the declaration + */ + public static Annotation[] parseTypeVariableAnnotations(D genericDecl, + int typeVarIndex) { + AnnotatedElement decl; + TypeAnnotationTarget predicate; + if (genericDecl instanceof Class) { + decl = (Class)genericDecl; + predicate = TypeAnnotationTarget.CLASS_TYPE_PARAMETER; + } else if (genericDecl instanceof Executable) { + decl = (Executable)genericDecl; + predicate = TypeAnnotationTarget.METHOD_TYPE_PARAMETER; + } else { + throw new AssertionError("Unknown GenericDeclaration " + genericDecl + "\nthis should not happen."); + } + List typeVarAnnos = TypeAnnotation.filter(parseAllTypeAnnotations(decl), + predicate); + List res = new ArrayList<>(typeVarAnnos.size()); + for (TypeAnnotation t : typeVarAnnos) + if (t.getTargetInfo().getCount() == typeVarIndex) + res.add(t.getAnnotation()); + return res.toArray(new Annotation[0]); + } + + /** + * Build an array of AnnotatedTypes for the declaration decl's bounds. + * + * @param bounds the bounds corresponding to the annotated bounds + * @param decl the declaration whose annotated bounds is being built + * @param typeVarIndex the index of this type variable on the decl + */ + public static AnnotatedType[] parseAnnotatedBounds(Type[] bounds, + D decl, + int typeVarIndex) { + return parseAnnotatedBounds(bounds, decl, typeVarIndex, LocationInfo.BASE_LOCATION); + } + //helper for above + static AnnotatedType[] parseAnnotatedBounds(Type[] bounds, + D decl, + int typeVarIndex, + LocationInfo loc) { + List candidates = fetchBounds(decl); + if (bounds != null) { + int startIndex = 0; + AnnotatedType[] res = new AnnotatedType[bounds.length]; + Arrays.fill(res, AnnotatedTypeFactory.EMPTY_ANNOTATED_TYPE); + + // Adjust bounds index + // + // Figure out if the type annotations for this bound starts with 0 + // or 1. The spec says within a bound the 0:th type annotation will + // always be on an bound of a Class type (not Interface type). So + // if the programmer starts with an Interface type for the first + // (and following) bound(s) the implicit Object bound is considered + // the first (that is 0:th) bound and type annotations start on + // index 1. + if (bounds.length > 0) { + Type b0 = bounds[0]; + if (!(b0 instanceof Class)) { + startIndex = 1; + } else { + Class c = (Class)b0; + if (c.isInterface()) { + startIndex = 1; + } + } + } + + for (int i = 0; i < bounds.length; i++) { + List l = new ArrayList<>(candidates.size()); + for (TypeAnnotation t : candidates) { + TypeAnnotationTargetInfo tInfo = t.getTargetInfo(); + if (tInfo.getSecondaryIndex() == i + startIndex && + tInfo.getCount() == typeVarIndex) { + l.add(t); + } + res[i] = AnnotatedTypeFactory.buildAnnotatedType(bounds[i], + loc, + l.toArray(new TypeAnnotation[0]), + candidates.toArray(new TypeAnnotation[0]), + (AnnotatedElement)decl); + } + } + return res; + } + return new AnnotatedType[0]; + } + private static List fetchBounds(D decl) { + AnnotatedElement boundsDecl; + TypeAnnotationTarget target; + if (decl instanceof Class) { + target = TypeAnnotationTarget.CLASS_PARAMETER_BOUND; + boundsDecl = (Class)decl; + } else { + target = TypeAnnotationTarget.METHOD_PARAMETER_BOUND; + boundsDecl = (Executable)decl; + } + return TypeAnnotation.filter(TypeAnnotationParser.parseAllTypeAnnotations(boundsDecl), target); + } + + /* + * Parse all type annotations on the declaration supplied. This is needed + * when you go from for example an annotated return type on a method that + * is a type variable declared on the class. In this case you need to + * 'jump' to the decl of the class and parse all type annotations there to + * find the ones that are applicable to the type variable. + */ + static TypeAnnotation[] parseAllTypeAnnotations(AnnotatedElement decl) { + Class container; + byte[] rawBytes; + JavaLangAccess javaLangAccess = sun.misc.SharedSecrets.getJavaLangAccess(); + if (decl instanceof Class) { + container = (Class)decl; + rawBytes = javaLangAccess.getRawClassTypeAnnotations(container); + } else if (decl instanceof Executable) { + container = ((Executable)decl).getDeclaringClass(); + rawBytes = javaLangAccess.getRawExecutableTypeAnnotations((Executable)decl); + } else { + // Should not reach here. Assert? + return EMPTY_TYPE_ANNOTATION_ARRAY; + } + return parseTypeAnnotations(rawBytes, javaLangAccess.getConstantPool(container), + decl, container); + } + + /* Parse type annotations encoded as an array of bytes */ + private static TypeAnnotation[] parseTypeAnnotations(byte[] rawAnnotations, + ConstantPool cp, + AnnotatedElement baseDecl, + Class container) { + if (rawAnnotations == null) + return EMPTY_TYPE_ANNOTATION_ARRAY; + + ByteBuffer buf = ByteBuffer.wrap(rawAnnotations); + int annotationCount = buf.getShort() & 0xFFFF; + List typeAnnotations = new ArrayList<>(annotationCount); + + // Parse each TypeAnnotation + for (int i = 0; i < annotationCount; i++) { + TypeAnnotation ta = parseTypeAnnotation(buf, cp, baseDecl, container); + if (ta != null) + typeAnnotations.add(ta); + } + + return typeAnnotations.toArray(EMPTY_TYPE_ANNOTATION_ARRAY); + } + + + // Helper + static Map, Annotation> mapTypeAnnotations(TypeAnnotation[] typeAnnos) { + Map, Annotation> result = + new LinkedHashMap<>(); + for (TypeAnnotation t : typeAnnos) { + Annotation a = t.getAnnotation(); + Class klass = a.annotationType(); + AnnotationType type = AnnotationType.getInstance(klass); + if (type.retention() == RetentionPolicy.RUNTIME) + if (result.put(klass, a) != null) + throw new AnnotationFormatError("Duplicate annotation for class: "+klass+": " + a); + } + return result; + } + + // Position codes + // Regular type parameter annotations + private static final byte CLASS_TYPE_PARAMETER = 0x00; + private static final byte METHOD_TYPE_PARAMETER = 0x01; + // Type Annotations outside method bodies + private static final byte CLASS_EXTENDS = 0x10; + private static final byte CLASS_TYPE_PARAMETER_BOUND = 0x11; + private static final byte METHOD_TYPE_PARAMETER_BOUND = 0x12; + private static final byte FIELD = 0x13; + private static final byte METHOD_RETURN = 0x14; + private static final byte METHOD_RECEIVER = 0x15; + private static final byte METHOD_FORMAL_PARAMETER = 0x16; + private static final byte THROWS = 0x17; + // Type Annotations inside method bodies + private static final byte LOCAL_VARIABLE = (byte)0x40; + private static final byte RESOURCE_VARIABLE = (byte)0x41; + private static final byte EXCEPTION_PARAMETER = (byte)0x42; + private static final byte CAST = (byte)0x43; + private static final byte INSTANCEOF = (byte)0x44; + private static final byte NEW = (byte)0x45; + private static final byte CONSTRUCTOR_REFERENCE_RECEIVER = (byte)0x46; + private static final byte METHOD_REFERENCE_RECEIVER = (byte)0x47; + private static final byte LAMBDA_FORMAL_PARAMETER = (byte)0x48; + private static final byte METHOD_REFERENCE = (byte)0x49; + private static final byte METHOD_REFERENCE_TYPE_ARGUMENT = (byte)0x50; + + private static TypeAnnotation parseTypeAnnotation(ByteBuffer buf, + ConstantPool cp, + AnnotatedElement baseDecl, + Class container) { + TypeAnnotationTargetInfo ti = parseTargetInfo(buf); + LocationInfo locationInfo = LocationInfo.parseLocationInfo(buf); + Annotation a = AnnotationParser.parseAnnotation(buf, cp, container, false); + if (ti == null) // Inside a method for example + return null; + return new TypeAnnotation(ti, locationInfo, a, baseDecl); + } + + private static TypeAnnotationTargetInfo parseTargetInfo(ByteBuffer buf) { + byte posCode = buf.get(); + switch(posCode) { + case CLASS_TYPE_PARAMETER: + case METHOD_TYPE_PARAMETER: { + byte index = buf.get(); + TypeAnnotationTargetInfo res; + if (posCode == CLASS_TYPE_PARAMETER) + res = new TypeAnnotationTargetInfo(TypeAnnotationTarget.CLASS_TYPE_PARAMETER, + index); + else + res = new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_TYPE_PARAMETER, + index); + return res; + } // unreachable break; + case CLASS_EXTENDS: { + short index = buf.getShort(); + if (index == -1) { + return new TypeAnnotationTargetInfo(TypeAnnotationTarget.CLASS_EXTENDS); + } else if (index >= 0) { + TypeAnnotationTargetInfo res = new TypeAnnotationTargetInfo(TypeAnnotationTarget.CLASS_IMPLEMENTS, + index); + return res; + }} break; + case CLASS_TYPE_PARAMETER_BOUND: + return parse2ByteTarget(TypeAnnotationTarget.CLASS_PARAMETER_BOUND, buf); + case METHOD_TYPE_PARAMETER_BOUND: + return parse2ByteTarget(TypeAnnotationTarget.METHOD_PARAMETER_BOUND, buf); + case FIELD: + return new TypeAnnotationTargetInfo(TypeAnnotationTarget.FIELD_TYPE); + case METHOD_RETURN: + return new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_RETURN_TYPE); + case METHOD_RECEIVER: + return new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_RECEIVER_TYPE); + case METHOD_FORMAL_PARAMETER: { + // Todo + byte index = buf.get(); + } break; + case THROWS: + return parseShortTarget(TypeAnnotationTarget.THROWS, buf); + + /* + * The ones below are inside method bodies, we don't care about them for core reflection + * other than adjusting for them in the byte stream. + */ + case LOCAL_VARIABLE: + case RESOURCE_VARIABLE: + short length = buf.getShort(); + for (int i = 0; i < length; ++i) { + short offset = buf.getShort(); + short varLength = buf.getShort(); + short index = buf.getShort(); + } + break; + case EXCEPTION_PARAMETER: { + byte index = buf.get(); + } break; + case CAST: + case INSTANCEOF: + case NEW: { + short offset = buf.getShort(); + } break; + case CONSTRUCTOR_REFERENCE_RECEIVER: + case METHOD_REFERENCE_RECEIVER: { + short offset = buf.getShort(); + byte index = buf.get(); + } break; + case LAMBDA_FORMAL_PARAMETER: { + byte index = buf.get(); + } break; + case METHOD_REFERENCE: + // This one isn't in the spec yet + break; + case METHOD_REFERENCE_TYPE_ARGUMENT: { + short offset = buf.getShort(); + byte index = buf.get(); + } break; + + default: + // will throw error below + break; + } + throw new AnnotationFormatError("Could not parse bytes for type annotations"); + } + + private static TypeAnnotationTargetInfo parseShortTarget(TypeAnnotationTarget target, ByteBuffer buf) { + short index = buf.getShort(); + return new TypeAnnotationTargetInfo(target, index); + } + private static TypeAnnotationTargetInfo parse2ByteTarget(TypeAnnotationTarget target, ByteBuffer buf) { + byte count = buf.get(); + byte secondaryIndex = buf.get(); + return new TypeAnnotationTargetInfo(target, + count, + secondaryIndex); + } +} diff --git a/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java b/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java index 021b84891f1..4bc3356278b 100644 --- a/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java +++ b/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -25,13 +25,18 @@ package sun.reflect.generics.reflectiveObjects; -import java.lang.annotation.Annotation; +import java.lang.annotation.*; +import java.lang.reflect.AnnotatedType; import java.lang.reflect.Array; import java.lang.reflect.GenericDeclaration; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; +import java.util.LinkedHashMap; +import java.util.Map; import java.util.Objects; - +import sun.reflect.annotation.AnnotationSupport; +import sun.reflect.annotation.TypeAnnotationParser; +import sun.reflect.annotation.AnnotationType; import sun.reflect.generics.factory.GenericsFactory; import sun.reflect.generics.tree.FieldTypeSignature; import sun.reflect.generics.visitor.Reifier; @@ -182,45 +187,75 @@ public class TypeVariableImpl return genericDeclaration.hashCode() ^ name.hashCode(); } - // Currently vacuous implementations of AnnotatedElement methods. + // Implementations of AnnotatedElement methods. public boolean isAnnotationPresent(Class annotationClass) { Objects.requireNonNull(annotationClass); return false; } + @SuppressWarnings("unchecked") public T getAnnotation(Class annotationClass) { Objects.requireNonNull(annotationClass); - return null; + // T is an Annotation type, the return value of get will be an annotation + return (T)mapAnnotations(getAnnotations()).get(annotationClass); } public T getDeclaredAnnotation(Class annotationClass) { Objects.requireNonNull(annotationClass); - return null; + return getAnnotation(annotationClass); } - @SuppressWarnings("unchecked") public T[] getAnnotations(Class annotationClass) { Objects.requireNonNull(annotationClass); - // safe because annotationClass is the class for T - return (T[])Array.newInstance(annotationClass, 0); + return AnnotationSupport.getMultipleAnnotations(mapAnnotations(getAnnotations()), annotationClass); } - @SuppressWarnings("unchecked") public T[] getDeclaredAnnotations(Class annotationClass) { Objects.requireNonNull(annotationClass); - // safe because annotationClass is the class for T - return (T[])Array.newInstance(annotationClass, 0); + return getAnnotations(annotationClass); } public Annotation[] getAnnotations() { - // Since zero-length, don't need defensive clone - return EMPTY_ANNOTATION_ARRAY; + int myIndex = typeVarIndex(); + if (myIndex < 0) + throw new AssertionError("Index must be non-negative."); + return TypeAnnotationParser.parseTypeVariableAnnotations(getGenericDeclaration(), myIndex); } public Annotation[] getDeclaredAnnotations() { - // Since zero-length, don't need defensive clone - return EMPTY_ANNOTATION_ARRAY; + return getAnnotations(); + } + + public AnnotatedType[] getAnnotatedBounds() { + return TypeAnnotationParser.parseAnnotatedBounds(getBounds(), + getGenericDeclaration(), + typeVarIndex()); } private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0]; + + // Helpers for annotation methods + private int typeVarIndex() { + TypeVariable[] tVars = getGenericDeclaration().getTypeParameters(); + int i = -1; + for (TypeVariable v : tVars) { + i++; + if (equals(v)) + return i; + } + return -1; + } + + private static Map, Annotation> mapAnnotations(Annotation[] annos) { + Map, Annotation> result = + new LinkedHashMap<>(); + for (Annotation a : annos) { + Class klass = a.annotationType(); + AnnotationType type = AnnotationType.getInstance(klass); + if (type.retention() == RetentionPolicy.RUNTIME) + if (result.put(klass, a) != null) + throw new AnnotationFormatError("Duplicate annotation for class: "+klass+": " + a); + } + return result; + } } diff --git a/jdk/src/share/javavm/export/jvm.h b/jdk/src/share/javavm/export/jvm.h index 28885cfb14d..56a8abb03cc 100644 --- a/jdk/src/share/javavm/export/jvm.h +++ b/jdk/src/share/javavm/export/jvm.h @@ -465,6 +465,12 @@ JVM_GetClassSignature(JNIEnv *env, jclass cls); JNIEXPORT jbyteArray JNICALL JVM_GetClassAnnotations(JNIEnv *env, jclass cls); +/* Type use annotations support (JDK 1.8) */ + +JNIEXPORT jbyteArray JNICALL +JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls); + + /* * New (JDK 1.4) reflection implementation */ diff --git a/jdk/src/share/native/java/lang/Class.c b/jdk/src/share/native/java/lang/Class.c index 3e595e726af..20d03060101 100644 --- a/jdk/src/share/native/java/lang/Class.c +++ b/jdk/src/share/native/java/lang/Class.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2013, 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 @@ -75,7 +75,8 @@ static JNINativeMethod methods[] = { {"getRawAnnotations", "()" BA, (void *)&JVM_GetClassAnnotations}, {"getConstantPool", "()" CPL, (void *)&JVM_GetClassConstantPool}, {"desiredAssertionStatus0","("CLS")Z",(void *)&JVM_DesiredAssertionStatus}, - {"getEnclosingMethod0", "()[" OBJ, (void *)&JVM_GetEnclosingMethodInfo} + {"getEnclosingMethod0", "()[" OBJ, (void *)&JVM_GetEnclosingMethodInfo}, + {"getRawTypeAnnotations", "()" BA, (void *)&JVM_GetClassTypeAnnotations}, }; #undef OBJ diff --git a/jdk/test/java/lang/annotation/TypeAnnotationReflection.java b/jdk/test/java/lang/annotation/TypeAnnotationReflection.java new file mode 100644 index 00000000000..b3aad9726a9 --- /dev/null +++ b/jdk/test/java/lang/annotation/TypeAnnotationReflection.java @@ -0,0 +1,428 @@ +/* + * Copyright (c) 2013, 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. + */ + +/* + * @test + * @bug 8004698 + * @summary Unit test for type annotations + */ + +import java.util.*; +import java.lang.annotation.*; +import java.lang.reflect.*; +import java.io.Serializable; + +public class TypeAnnotationReflection { + public static void main(String[] args) throws Exception { + testSuper(); + testInterfaces(); + testReturnType(); + testNested(); + testArray(); + testRunException(); + testClassTypeVarBounds(); + testMethodTypeVarBounds(); + testFields(); + testClassTypeVar(); + testMethodTypeVar(); + testParameterizedType(); + testNestedParameterizedType(); + testWildcardType(); + } + + private static void check(boolean b) { + if (!b) + throw new RuntimeException(); + } + + private static void testSuper() throws Exception { + check(Object.class.getAnnotatedSuperclass().getAnnotations().length == 0); + check(Class.class.getAnnotatedSuperclass().getAnnotations().length == 0); + + AnnotatedType a; + a = TestClassArray.class.getAnnotatedSuperclass(); + Annotation[] annos = a.getAnnotations(); + check(annos.length == 2); + check(annos[0].annotationType().equals(TypeAnno.class)); + check(annos[1].annotationType().equals(TypeAnno2.class)); + check(((TypeAnno)annos[0]).value().equals("extends")); + check(((TypeAnno2)annos[1]).value().equals("extends2")); + } + + private static void testInterfaces() throws Exception { + AnnotatedType[] as; + as = TestClassArray.class.getAnnotatedInterfaces(); + check(as.length == 3); + check(as[1].getAnnotations().length == 0); + + Annotation[] annos; + annos = as[0].getAnnotations(); + check(annos.length == 2); + check(annos[0].annotationType().equals(TypeAnno.class)); + check(annos[1].annotationType().equals(TypeAnno2.class)); + check(((TypeAnno)annos[0]).value().equals("implements serializable")); + check(((TypeAnno2)annos[1]).value().equals("implements2 serializable")); + + annos = as[2].getAnnotations(); + check(annos.length == 2); + check(annos[0].annotationType().equals(TypeAnno.class)); + check(annos[1].annotationType().equals(TypeAnno2.class)); + check(((TypeAnno)annos[0]).value().equals("implements cloneable")); + check(((TypeAnno2)annos[1]).value().equals("implements2 cloneable")); + } + + private static void testReturnType() throws Exception { + Method m = TestClassArray.class.getDeclaredMethod("foo", (Class[])null); + Annotation[] annos = m.getAnnotatedReturnType().getAnnotations(); + check(annos.length == 1); + check(annos[0].annotationType().equals(TypeAnno.class)); + check(((TypeAnno)annos[0]).value().equals("return1")); + } + + private static void testNested() throws Exception { + Method m = TestClassNested.class.getDeclaredMethod("foo", (Class[])null); + Annotation[] annos = m.getAnnotatedReturnType().getAnnotations(); + check(annos.length == 1); + check(annos[0].annotationType().equals(TypeAnno.class)); + check(((TypeAnno)annos[0]).value().equals("array")); + + AnnotatedType t = m.getAnnotatedReturnType(); + t = ((AnnotatedArrayType)t).getAnnotatedGenericComponentType(); + annos = t.getAnnotations(); + check(annos.length == 1); + check(annos[0].annotationType().equals(TypeAnno.class)); + check(((TypeAnno)annos[0]).value().equals("Inner")); + } + + private static void testArray() throws Exception { + Method m = TestClassArray.class.getDeclaredMethod("foo", (Class[])null); + AnnotatedArrayType t = (AnnotatedArrayType) m.getAnnotatedReturnType(); + Annotation[] annos = t.getAnnotations(); + check(annos.length == 1); + check(annos[0].annotationType().equals(TypeAnno.class)); + check(((TypeAnno)annos[0]).value().equals("return1")); + + t = (AnnotatedArrayType)t.getAnnotatedGenericComponentType(); + annos = t.getAnnotations(); + check(annos.length == 0); + + t = (AnnotatedArrayType)t.getAnnotatedGenericComponentType(); + annos = t.getAnnotations(); + check(annos.length == 1); + check(annos[0].annotationType().equals(TypeAnno.class)); + check(((TypeAnno)annos[0]).value().equals("return3")); + + AnnotatedType tt = t.getAnnotatedGenericComponentType(); + check(!(tt instanceof AnnotatedArrayType)); + annos = tt.getAnnotations(); + check(annos.length == 1); + check(annos[0].annotationType().equals(TypeAnno.class)); + check(((TypeAnno)annos[0]).value().equals("return4")); + } + + private static void testRunException() throws Exception { + Method m = TestClassException.class.getDeclaredMethod("foo", (Class[])null); + AnnotatedType[] ts = m.getAnnotatedExceptionTypes(); + check(ts.length == 3); + + AnnotatedType t; + Annotation[] annos; + t = ts[0]; + annos = t.getAnnotations(); + check(annos.length == 2); + check(annos[0].annotationType().equals(TypeAnno.class)); + check(annos[1].annotationType().equals(TypeAnno2.class)); + check(((TypeAnno)annos[0]).value().equals("RE")); + check(((TypeAnno2)annos[1]).value().equals("RE2")); + + t = ts[1]; + annos = t.getAnnotations(); + check(annos.length == 0); + + t = ts[2]; + annos = t.getAnnotations(); + check(annos.length == 1); + check(annos[0].annotationType().equals(TypeAnno.class)); + check(((TypeAnno)annos[0]).value().equals("AIOOBE")); + } + + private static void testClassTypeVarBounds() throws Exception { + Method m = TestClassTypeVarAndField.class.getDeclaredMethod("foo", (Class[])null); + AnnotatedType ret = m.getAnnotatedReturnType(); + Annotation[] annos = ret.getAnnotations(); + check(annos.length == 2); + + AnnotatedType[] annotatedBounds = ((AnnotatedTypeVariable)ret).getAnnotatedBounds(); + check(annotatedBounds.length == 2); + + annos = annotatedBounds[0].getAnnotations(); + check(annos.length == 1); + check(annos[0].annotationType().equals(TypeAnno.class)); + check(((TypeAnno)annos[0]).value().equals("Object1")); + + annos = annotatedBounds[1].getAnnotations(); + check(annos.length == 2); + check(annos[0].annotationType().equals(TypeAnno.class)); + check(annos[1].annotationType().equals(TypeAnno2.class)); + check(((TypeAnno)annos[0]).value().equals("Runnable1")); + check(((TypeAnno2)annos[1]).value().equals("Runnable2")); + } + + private static void testMethodTypeVarBounds() throws Exception { + Method m2 = TestClassTypeVarAndField.class.getDeclaredMethod("foo2", (Class[])null); + AnnotatedType ret2 = m2.getAnnotatedReturnType(); + AnnotatedType[] annotatedBounds2 = ((AnnotatedTypeVariable)ret2).getAnnotatedBounds(); + check(annotatedBounds2.length == 1); + + Annotation[] annos = annotatedBounds2[0].getAnnotations(); + check(annos.length == 1); + check(annos[0].annotationType().equals(TypeAnno.class)); + check(((TypeAnno)annos[0]).value().equals("M Runnable")); + } + + private static void testFields() throws Exception { + Field f1 = TestClassTypeVarAndField.class.getDeclaredField("field1"); + AnnotatedType at; + Annotation[] annos; + + at = f1.getAnnotatedType(); + annos = at.getAnnotations(); + check(annos.length == 2); + check(annos[0].annotationType().equals(TypeAnno.class)); + check(annos[1].annotationType().equals(TypeAnno2.class)); + check(((TypeAnno)annos[0]).value().equals("T1 field")); + check(((TypeAnno2)annos[1]).value().equals("T2 field")); + + Field f2 = TestClassTypeVarAndField.class.getDeclaredField("field2"); + at = f2.getAnnotatedType(); + annos = at.getAnnotations(); + check(annos.length == 0); + + Field f3 = TestClassTypeVarAndField.class.getDeclaredField("field3"); + at = f3.getAnnotatedType(); + annos = at.getAnnotations(); + check(annos.length == 1); + check(annos[0].annotationType().equals(TypeAnno.class)); + check(((TypeAnno)annos[0]).value().equals("Object field")); + } + + private static void testClassTypeVar() throws Exception { + TypeVariable[] typeVars = TestClassTypeVarAndField.class.getTypeParameters(); + Annotation[] annos; + check(typeVars.length == 2); + + // First TypeVar + AnnotatedType[] annotatedBounds = typeVars[0].getAnnotatedBounds(); + check(annotatedBounds.length == 2); + + annos = annotatedBounds[0].getAnnotations(); + check(annos.length == 1); + check(annos[0].annotationType().equals(TypeAnno.class)); + check(((TypeAnno)annos[0]).value().equals("Object1")); + + annos = annotatedBounds[1].getAnnotations(); + check(annos.length == 2); + check(annos[0].annotationType().equals(TypeAnno.class)); + check(annos[1].annotationType().equals(TypeAnno2.class)); + check(((TypeAnno)annos[0]).value().equals("Runnable1")); + check(((TypeAnno2)annos[1]).value().equals("Runnable2")); + + // second TypeVar regular anno + Annotation[] regularAnnos = typeVars[1].getAnnotations(); + check(regularAnnos.length == 1); + check(typeVars[1].getAnnotation(TypeAnno.class).value().equals("EE")); + + // second TypeVar + annotatedBounds = typeVars[1].getAnnotatedBounds(); + check(annotatedBounds.length == 1); + + annos = annotatedBounds[0].getAnnotations(); + check(annos.length == 1); + check(annos[0].annotationType().equals(TypeAnno2.class)); + check(((TypeAnno2)annos[0]).value().equals("EEBound")); + } + + private static void testMethodTypeVar() throws Exception { + Method m2 = TestClassTypeVarAndField.class.getDeclaredMethod("foo2", (Class[])null); + TypeVariable[] t = m2.getTypeParameters(); + check(t.length == 1); + Annotation[] annos = t[0].getAnnotations(); + check(annos.length == 0); + + AnnotatedType[] annotatedBounds2 = t[0].getAnnotatedBounds(); + check(annotatedBounds2.length == 1); + + annos = annotatedBounds2[0].getAnnotations(); + check(annos.length == 1); + check(annos[0].annotationType().equals(TypeAnno.class)); + check(((TypeAnno)annos[0]).value().equals("M Runnable")); + + // Second method + m2 = TestClassTypeVarAndField.class.getDeclaredMethod("foo3", (Class[])null); + t = m2.getTypeParameters(); + check(t.length == 1); + annos = t[0].getAnnotations(); + check(annos.length == 1); + check(annos[0].annotationType().equals(TypeAnno.class)); + check(((TypeAnno)annos[0]).value().equals("K")); + + annotatedBounds2 = t[0].getAnnotatedBounds(); + check(annotatedBounds2.length == 1); + + annos = annotatedBounds2[0].getAnnotations(); + check(annos.length == 0); + } + + private static void testParameterizedType() { + // Base + AnnotatedType[] as; + as = TestParameterizedType.class.getAnnotatedInterfaces(); + check(as.length == 1); + check(as[0].getAnnotations().length == 1); + check(as[0].getAnnotation(TypeAnno.class).value().equals("M")); + + Annotation[] annos; + as = ((AnnotatedParameterizedType)as[0]).getAnnotatedActualTypeArguments(); + check(as.length == 2); + annos = as[0].getAnnotations(); + check(annos.length == 1); + check(as[0].getAnnotation(TypeAnno.class).value().equals("S")); + check(as[0].getAnnotation(TypeAnno2.class) == null); + + annos = as[1].getAnnotations(); + check(annos.length == 2); + check(((TypeAnno)annos[0]).value().equals("I")); + check(as[1].getAnnotation(TypeAnno2.class).value().equals("I2")); + } + + private static void testNestedParameterizedType() throws Exception { + Method m = TestParameterizedType.class.getDeclaredMethod("foo2", (Class[])null); + AnnotatedType ret = m.getAnnotatedReturnType(); + Annotation[] annos; + annos = ret.getAnnotations(); + check(annos.length == 1); + check(((TypeAnno)annos[0]).value().equals("I")); + + AnnotatedType[] args = ((AnnotatedParameterizedType)ret).getAnnotatedActualTypeArguments(); + check(args.length == 1); + annos = args[0].getAnnotations(); + check(annos.length == 2); + check(((TypeAnno)annos[0]).value().equals("I1")); + check(args[0].getAnnotation(TypeAnno2.class).value().equals("I2")); + } + + private static void testWildcardType() throws Exception { + Method m = TestWildcardType.class.getDeclaredMethod("foo", (Class[])null); + AnnotatedType ret = m.getAnnotatedReturnType(); + AnnotatedType[] t; + t = ((AnnotatedParameterizedType)ret).getAnnotatedActualTypeArguments(); + check(t.length == 1); + ret = t[0]; + + Field f = TestWildcardType.class.getDeclaredField("f1"); + AnnotatedWildcardType w = (AnnotatedWildcardType)((AnnotatedParameterizedType)f + .getAnnotatedType()).getAnnotatedActualTypeArguments()[0]; + t = w.getAnnotatedLowerBounds(); + check(t.length == 0); + t = w.getAnnotatedUpperBounds(); + check(t.length == 1); + Annotation[] annos; + annos = t[0].getAnnotations(); + check(annos.length == 1); + check(((TypeAnno)annos[0]).value().equals("2")); + + f = TestWildcardType.class.getDeclaredField("f2"); + w = (AnnotatedWildcardType)((AnnotatedParameterizedType)f + .getAnnotatedType()).getAnnotatedActualTypeArguments()[0]; + t = w.getAnnotatedUpperBounds(); + check(t.length == 0); + t = w.getAnnotatedLowerBounds(); + check(t.length == 1); + } +} + +abstract class TestWildcardType { + public List foo() { return null;} + public Class<@TypeAnno("1") ? extends @TypeAnno("2") Annotation> f1; + public Class<@TypeAnno("3") ? super @TypeAnno("4") Annotation> f2; +} + +abstract class TestParameterizedType implements @TypeAnno("M") Map<@TypeAnno("S")String, @TypeAnno("I") @TypeAnno2("I2")Integer> { + public ParameterizedOuter.ParameterizedInner foo() {return null;} + public @TypeAnno("O") ParameterizedOuter<@TypeAnno("S1") @TypeAnno2("S2") String>. + @TypeAnno("I") ParameterizedInner<@TypeAnno("I1") @TypeAnno2("I2")Integer> foo2() { + return null; + } +} + +class ParameterizedOuter { + class ParameterizedInner {} +} + +abstract class TestClassArray extends @TypeAnno("extends") @TypeAnno2("extends2") Object + implements @TypeAnno("implements serializable") @TypeAnno2("implements2 serializable") Serializable, + Readable, + @TypeAnno("implements cloneable") @TypeAnno2("implements2 cloneable") Cloneable { + public @TypeAnno("return4") Object @TypeAnno("return1") [][] @TypeAnno("return3")[] foo() { return null; } +} + +abstract class TestClassNested { + public @TypeAnno("Outer") Outer.@TypeAnno("Inner")Inner @TypeAnno("array")[] foo() { return null; } +} + +class Outer { + class Inner { + } +} + +abstract class TestClassException { + public Object foo() throws @TypeAnno("RE") @TypeAnno2("RE2") RuntimeException, + NullPointerException, + @TypeAnno("AIOOBE") ArrayIndexOutOfBoundsException { + return null; + } +} + +abstract class TestClassTypeVarAndField { + @TypeAnno("T1 field") @TypeAnno2("T2 field") T field1; + T field2; + @TypeAnno("Object field") Object field3; + + public @TypeAnno("t1") @TypeAnno2("t2") T foo(){ return null; } + public M foo2() {return null;} + public <@TypeAnno("K") K extends Cloneable> K foo3() {return null;} +} + +@Target(ElementType.TYPE_USE) +@Retention(RetentionPolicy.RUNTIME) +@interface TypeAnno { + String value(); +} + +@Target(ElementType.TYPE_USE) +@Retention(RetentionPolicy.RUNTIME) +@interface TypeAnno2 { + String value(); +} diff --git a/jdk/test/java/lang/annotation/TypeParamAnnotation.java b/jdk/test/java/lang/annotation/TypeParamAnnotation.java new file mode 100644 index 00000000000..50457ec46b1 --- /dev/null +++ b/jdk/test/java/lang/annotation/TypeParamAnnotation.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2013, 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. + */ + +/* + * @test + * @bug 8004698 + * @summary Unit test for annotations on TypeVariables + */ + +import java.util.*; +import java.lang.annotation.*; +import java.lang.reflect.*; +import java.io.Serializable; + +public class TypeParamAnnotation { + public static void main(String[] args) throws Exception { + testOnClass(); + testOnMethod(); + testGetAnno(); + testGetAnnos(); + } + + private static void check(boolean b) { + if (!b) + throw new RuntimeException(); + } + + private static void testOnClass() { + TypeVariable[] ts = TypeParam.class.getTypeParameters(); + check(ts.length == 3); + + Annotation[] as; + + as = ts[0].getAnnotations(); + check(as.length == 2); + check(((ParamAnno)as[0]).value().equals("t")); + check(((ParamAnno2)as[1]).value() == 1); + + as = ts[1].getAnnotations(); + check(as.length == 0); + + as = ts[2].getAnnotations(); + check(as.length == 2); + check(((ParamAnno)as[0]).value().equals("v")); + check(((ParamAnno2)as[1]).value() == 2); + } + private static void testOnMethod() throws Exception { + TypeVariable[] ts = TypeParam.class.getDeclaredMethod("foo").getTypeParameters(); + check(ts.length == 3); + + Annotation[] as; + + as = ts[0].getAnnotations(); + check(as.length == 2); + check(((ParamAnno)as[0]).value().equals("x")); + check(((ParamAnno2)as[1]).value() == 3); + + as = ts[1].getAnnotations(); + check(as.length == 0); + + as = ts[2].getAnnotations(); + check(as.length == 2); + check(((ParamAnno)as[0]).value().equals("z")); + check(((ParamAnno2)as[1]).value() == 4); + } + + private static void testGetAnno() { + TypeVariable[] ts = TypeParam.class.getTypeParameters(); + ParamAnno a; + a = ts[0].getAnnotation(ParamAnno.class); + check(a.value().equals("t")); + } + private static void testGetAnnos() throws Exception { + TypeVariable[] ts = TypeParam.class.getDeclaredMethod("foo").getTypeParameters(); + ParamAnno2[] as; + as = ts[0].getAnnotations(ParamAnno2.class); + check(as.length == 1); + check(as[0].value() == 3); + } +} + +class TypeParam <@ParamAnno("t") @ParamAnno2(1) T, + U, + @ParamAnno("v") @ParamAnno2(2) V extends Runnable> { + public <@ParamAnno("x") @ParamAnno2(3) X, + Y, + @ParamAnno("z") @ParamAnno2(4) Z extends Cloneable> void foo() {} +} + +@Target(ElementType.TYPE_PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +@interface ParamAnno { + String value(); +} + +@Target(ElementType.TYPE_PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +@interface ParamAnno2 { + int value(); +} From a1d7653c193af77712492373eb05615afd084c30 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Tue, 29 Jan 2013 16:35:24 +0100 Subject: [PATCH 181/204] 8006873: SWAT-b74 msvcr100.dll does not have the permission for all Reviewed-by: alanb, tbell --- jdk/makefiles/CopyFiles.gmk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/jdk/makefiles/CopyFiles.gmk b/jdk/makefiles/CopyFiles.gmk index 8f99a113d3d..7de946c88e3 100644 --- a/jdk/makefiles/CopyFiles.gmk +++ b/jdk/makefiles/CopyFiles.gmk @@ -267,10 +267,12 @@ endif ifeq ($(OPENJDK_TARGET_OS),windows) MSVCR_TARGET := $(JDK_OUTPUTDIR)/bin/$(notdir $(MSVCR_DLL)) + # Chmod to avoid permission issues if bundles are unpacked on unix platforms. $(MSVCR_TARGET): $(MSVCR_DLL) $(MKDIR) -p $(@D) $(RM) $@ $(CP) $< $@ + $(CHMOD) a+rx $@ COPY_FILES += $(MSVCR_TARGET) endif From 34e17268605994c714d5e02c25da4d5b37df96f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Borggr=C3=A9n-Franck?= Date: Thu, 31 Jan 2013 10:10:34 +0100 Subject: [PATCH 182/204] 8005712: Simplify support for repeating annotations in j.l.r.AnnotatedElement 8004919: AnnotationSupport uses possibly half-constructed AnnotationType instances Implements the simplified semantics for repeating annotations and removes the incorrect obtaining of an AnnotationType Reviewed-by: darcy, abuckley --- jdk/src/share/classes/java/lang/Class.java | 20 +-- jdk/src/share/classes/java/lang/System.java | 4 - .../java/lang/reflect/AnnotatedElement.java | 54 +++++-- .../classes/java/lang/reflect/Executable.java | 6 +- .../classes/java/lang/reflect/Field.java | 5 +- .../classes/java/lang/reflect/Parameter.java | 3 +- .../classes/sun/misc/JavaLangAccess.java | 5 - .../reflect/annotation/AnnotationSupport.java | 143 ++++-------------- .../RepeatedUnitTest.java | 23 ++- .../subpackage/Containee.java | 3 +- .../subpackage/Container.java | 3 +- .../subpackage/InheritedContainee.java | 3 +- .../subpackage/InheritedContainer.java | 3 +- 13 files changed, 98 insertions(+), 177 deletions(-) diff --git a/jdk/src/share/classes/java/lang/Class.java b/jdk/src/share/classes/java/lang/Class.java index 87f78530899..31e2294ebf6 100644 --- a/jdk/src/share/classes/java/lang/Class.java +++ b/jdk/src/share/classes/java/lang/Class.java @@ -3075,11 +3075,12 @@ public final * @throws NullPointerException {@inheritDoc} * @since 1.5 */ + @SuppressWarnings("unchecked") public A getAnnotation(Class annotationClass) { Objects.requireNonNull(annotationClass); initAnnotationsIfNecessary(); - return AnnotationSupport.getOneAnnotation(annotations, annotationClass); + return (A) annotations.get(annotationClass); } /** @@ -3108,18 +3109,19 @@ public final */ public Annotation[] getAnnotations() { initAnnotationsIfNecessary(); - return AnnotationSupport.unpackToArray(annotations); + return AnnotationParser.toArray(annotations); } /** * @throws NullPointerException {@inheritDoc} * @since 1.8 */ + @SuppressWarnings("unchecked") public A getDeclaredAnnotation(Class annotationClass) { Objects.requireNonNull(annotationClass); initAnnotationsIfNecessary(); - return AnnotationSupport.getOneAnnotation(declaredAnnotations, annotationClass); + return (A) declaredAnnotations.get(annotationClass); } /** @@ -3138,17 +3140,7 @@ public final */ public Annotation[] getDeclaredAnnotations() { initAnnotationsIfNecessary(); - return AnnotationSupport.unpackToArray(declaredAnnotations); - } - - /** Returns one "directly" present annotation or null */ - A getDirectDeclaredAnnotation(Class annotationClass) { - Objects.requireNonNull(annotationClass); - - initAnnotationsIfNecessary(); - @SuppressWarnings("unchecked") // TODO check safe - A ret = (A)declaredAnnotations.get(annotationClass); - return ret; + return AnnotationParser.toArray(declaredAnnotations); } // Annotations cache diff --git a/jdk/src/share/classes/java/lang/System.java b/jdk/src/share/classes/java/lang/System.java index d901e992b9a..45ea7190ae8 100644 --- a/jdk/src/share/classes/java/lang/System.java +++ b/jdk/src/share/classes/java/lang/System.java @@ -25,7 +25,6 @@ package java.lang; import java.io.*; -import java.lang.annotation.Annotation; import java.lang.reflect.Executable; import java.util.Properties; import java.util.PropertyPermission; @@ -1197,9 +1196,6 @@ public final class System { public AnnotationType getAnnotationType(Class klass) { return klass.getAnnotationType(); } - public A getDirectDeclaredAnnotation(Class klass, Class anno) { - return klass.getDirectDeclaredAnnotation(anno); - } public byte[] getRawClassTypeAnnotations(Class klass) { return klass.getRawTypeAnnotations(); } diff --git a/jdk/src/share/classes/java/lang/reflect/AnnotatedElement.java b/jdk/src/share/classes/java/lang/reflect/AnnotatedElement.java index 58a07350f36..e7de9429b0c 100644 --- a/jdk/src/share/classes/java/lang/reflect/AnnotatedElement.java +++ b/jdk/src/share/classes/java/lang/reflect/AnnotatedElement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -35,6 +35,24 @@ import java.lang.annotation.Annotation; * arrays returned by accessors for array-valued enum members; it will * have no affect on the arrays returned to other callers. * + *

An annotation A is directly present on an element E if the + * RuntimeVisibleAnnotations or RuntimeVisibleParameterAnnotations attribute + * associated with E either: + *

+ * + *

An annotation A is present on an element E if either: + *

    + *
  • A is directly present on E; or + *
  • There are no annotations of A's type which are directly present + * on E, and E is a class, and A's type is inheritable (JLS 9.6.3.3), and A is + * present on the superclass of E + *
+ * *

If an annotation returned by a method in this interface contains * (directly or indirectly) a {@link Class}-valued member referring to * a class that is not accessible in this VM, attempting to read the class @@ -50,7 +68,7 @@ import java.lang.annotation.Annotation; * containing annotation type of T will result in an * InvalidContainerAnnotationError. * - *

Finally, Attempting to read a member whose definition has evolved + *

Finally, attempting to read a member whose definition has evolved * incompatibly will result in a {@link * java.lang.annotation.AnnotationTypeMismatchException} or an * {@link java.lang.annotation.IncompleteAnnotationException}. @@ -70,6 +88,9 @@ public interface AnnotatedElement { * is present on this element, else false. This method * is designed primarily for convenient access to marker annotations. * + *

The truth value returned by this method is equivalent to: + * {@code getAnnotation(annotationClass) != null} + * * @param annotationClass the Class object corresponding to the * annotation type * @return true if an annotation for the specified annotation @@ -110,12 +131,15 @@ public interface AnnotatedElement { T[] getAnnotations(Class annotationClass); /** - * Returns all annotations present on this element. (Returns an array - * of length zero if this element has no annotations.) The caller of - * this method is free to modify the returned array; it will have no - * effect on the arrays returned to other callers. + * Returns annotations that are present on this element. * - * @return all annotations present on this element + * If there are no annotations present on this element, the return + * value is an array of length 0. + * + * The caller of this method is free to modify the returned array; it will + * have no effect on the arrays returned to other callers. + * + * @return annotations present on this element * @since 1.5 */ Annotation[] getAnnotations(); @@ -157,14 +181,16 @@ public interface AnnotatedElement { T[] getDeclaredAnnotations(Class annotationClass); /** - * Returns all annotations that are directly present on this - * element. This method ignores inherited annotations. (Returns - * an array of length zero if no annotations are directly present - * on this element.) The caller of this method is free to modify - * the returned array; it will have no effect on the arrays - * returned to other callers. + * Returns annotations that are directly present on this element. + * This method ignores inherited annotations. * - * @return All annotations directly present on this element + * If there are no annotations directly present on this element, + * the return value is an array of length 0. + * + * The caller of this method is free to modify the returned array; it will + * have no effect on the arrays returned to other callers. + * + * @return annotations directly present on this element * @since 1.5 */ Annotation[] getDeclaredAnnotations(); diff --git a/jdk/src/share/classes/java/lang/reflect/Executable.java b/jdk/src/share/classes/java/lang/reflect/Executable.java index b9ed7310a4d..ad1a5808632 100644 --- a/jdk/src/share/classes/java/lang/reflect/Executable.java +++ b/jdk/src/share/classes/java/lang/reflect/Executable.java @@ -26,7 +26,6 @@ package java.lang.reflect; import java.lang.annotation.*; -import java.util.Collections; import java.util.Map; import java.util.Objects; import sun.reflect.annotation.AnnotationParser; @@ -438,8 +437,7 @@ public abstract class Executable extends AccessibleObject */ public T getAnnotation(Class annotationClass) { Objects.requireNonNull(annotationClass); - - return AnnotationSupport.getOneAnnotation(declaredAnnotations(), annotationClass); + return annotationClass.cast(declaredAnnotations().get(annotationClass)); } /** @@ -457,7 +455,7 @@ public abstract class Executable extends AccessibleObject * {@inheritDoc} */ public Annotation[] getDeclaredAnnotations() { - return AnnotationSupport.unpackToArray(declaredAnnotations()); + return AnnotationParser.toArray(declaredAnnotations()); } private transient Map, Annotation> declaredAnnotations; diff --git a/jdk/src/share/classes/java/lang/reflect/Field.java b/jdk/src/share/classes/java/lang/reflect/Field.java index d2502efb4dd..df38832eb15 100644 --- a/jdk/src/share/classes/java/lang/reflect/Field.java +++ b/jdk/src/share/classes/java/lang/reflect/Field.java @@ -1021,8 +1021,7 @@ class Field extends AccessibleObject implements Member { */ public T getAnnotation(Class annotationClass) { Objects.requireNonNull(annotationClass); - - return AnnotationSupport.getOneAnnotation(declaredAnnotations(), annotationClass); + return annotationClass.cast(declaredAnnotations().get(annotationClass)); } /** @@ -1040,7 +1039,7 @@ class Field extends AccessibleObject implements Member { * {@inheritDoc} */ public Annotation[] getDeclaredAnnotations() { - return AnnotationSupport.unpackToArray(declaredAnnotations()); + return AnnotationParser.toArray(declaredAnnotations()); } private transient Map, Annotation> declaredAnnotations; diff --git a/jdk/src/share/classes/java/lang/reflect/Parameter.java b/jdk/src/share/classes/java/lang/reflect/Parameter.java index 6eed6926be0..4fda579c5fc 100644 --- a/jdk/src/share/classes/java/lang/reflect/Parameter.java +++ b/jdk/src/share/classes/java/lang/reflect/Parameter.java @@ -233,8 +233,7 @@ public final class Parameter implements AnnotatedElement { */ public T getAnnotation(Class annotationClass) { Objects.requireNonNull(annotationClass); - - return AnnotationSupport.getOneAnnotation(declaredAnnotations(), annotationClass); + return annotationClass.cast(declaredAnnotations().get(annotationClass)); } /** diff --git a/jdk/src/share/classes/sun/misc/JavaLangAccess.java b/jdk/src/share/classes/sun/misc/JavaLangAccess.java index 1624d67f4a9..db8d8213179 100644 --- a/jdk/src/share/classes/sun/misc/JavaLangAccess.java +++ b/jdk/src/share/classes/sun/misc/JavaLangAccess.java @@ -97,9 +97,4 @@ public interface JavaLangAccess { * Returns the ith StackTraceElement for the given throwable. */ StackTraceElement getStackTraceElement(Throwable t, int i); - - /** - * Returns a directly present annotation. - */ - public A getDirectDeclaredAnnotation(Class klass, Class anno); } diff --git a/jdk/src/share/classes/sun/reflect/annotation/AnnotationSupport.java b/jdk/src/share/classes/sun/reflect/annotation/AnnotationSupport.java index 3046792b161..5ca88f90202 100644 --- a/jdk/src/share/classes/sun/reflect/annotation/AnnotationSupport.java +++ b/jdk/src/share/classes/sun/reflect/annotation/AnnotationSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -27,63 +27,29 @@ package sun.reflect.annotation; import java.lang.annotation.*; import java.lang.reflect.*; -import java.util.Arrays; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Objects; -import sun.reflect.Reflection; -import sun.misc.JavaLangAccess; public final class AnnotationSupport { - private static final JavaLangAccess javaLangAccess = sun.misc.SharedSecrets.getJavaLangAccess(); - - /** - * Finds and returns _one_ annotation of the type indicated by - * {@code annotationClass} from the {@code Map} {@code - * annotationMap}. Looks into containers of the {@code - * annotationClass} (as specified by an the {@code - * annotationClass} type being meta-annotated with an {@code - * ContainedBy} annotation). - * - * @param annotationMap the {@code Map} used to store annotations and indexed by their type - * @param annotationClass the type of annotation to search for - * - * @return in instance of {@code annotationClass} or {@code null} if none were found - */ - public static A getOneAnnotation(final Map, Annotation> annotationMap, - final Class annotationClass) { - @SuppressWarnings("unchecked") - final A candidate = (A)annotationMap.get(annotationClass); - if (candidate != null) { - return candidate; - } - - final Class containerClass = getContainer(annotationClass); - if (containerClass != null) { - return unpackOne(annotationMap.get(containerClass), annotationClass); - } - - return null; // found none - } - /** * Finds and returns all annotation of the type indicated by * {@code annotationClass} from the {@code Map} {@code * annotationMap}. Looks into containers of the {@code * annotationClass} (as specified by an the {@code * annotationClass} type being meta-annotated with an {@code - * ContainedBy} annotation). + * Repeatable} annotation). * * @param annotationMap the {@code Map} used to store annotations indexed by their type * @param annotationClass the type of annotation to search for * * @return an array of instances of {@code annotationClass} or an empty array if none were found */ - public static A[] getMultipleAnnotations(final Map, Annotation> annotationMap, - final Class annotationClass) { - final ArrayList res = new ArrayList(); + public static A[] getMultipleAnnotations( + final Map, Annotation> annotationMap, + final Class annotationClass) { + final List res = new ArrayList(); @SuppressWarnings("unchecked") final A candidate = (A)annotationMap.get(annotationClass); @@ -101,49 +67,10 @@ public final class AnnotationSupport { return res.isEmpty() ? emptyTemplateArray : res.toArray(emptyTemplateArray); } - /** - * Unpacks the {@code annotationMap} parameter into an array of - * {@code Annotation}s. This method will unpack all repeating - * annotations containers (once). An annotation type is marked as a - * container by meta-annotating it the with the {@code - * ContainerFor} annotation. - * - * @param annotationMap the {@code Map} from where the annotations are unpacked - * - * @return an array of Annotation - */ - public static Annotation[] unpackToArray(Map, Annotation> annotationMap) { - List res = new ArrayList<>(); - for (Map.Entry, Annotation> e : annotationMap.entrySet()) { - Class annotationClass = e.getKey(); - Annotation annotationInstance = e.getValue(); - Class containee = getContainee(e.getKey()); - boolean isContainer = javaLangAccess.getDirectDeclaredAnnotation(annotationClass, ContainerFor.class) != null; - - if (isContainer) { - res.addAll(unpackAll(annotationInstance, containee)); - } else { - res.add(annotationInstance); - } - } - - return res.isEmpty() - ? AnnotationParser.getEmptyAnnotationArray() - : res.toArray(AnnotationParser.getEmptyAnnotationArray()); - } - /** Helper to get the container, or null if none, of an annotation. */ private static Class getContainer(Class annotationClass) { - ContainedBy containerAnnotation = - javaLangAccess.getDirectDeclaredAnnotation(annotationClass, ContainedBy.class); - return (containerAnnotation == null) ? null : containerAnnotation.value(); - } - - /** Helper to get the containee, or null if this isn't a container, of a possible container annotation. */ - private static Class getContainee(Class annotationClass) { - ContainerFor containerAnnotation = - javaLangAccess.getDirectDeclaredAnnotation(annotationClass, ContainerFor.class); - return (containerAnnotation == null) ? null : containerAnnotation.value(); + Repeatable containingAnnotation = annotationClass.getDeclaredAnnotation(Repeatable.class); + return (containingAnnotation == null) ? null : containingAnnotation.value(); } /** Reflectively look up and get the returned array from the the @@ -156,14 +83,15 @@ public final class AnnotationSupport { // value element. Get the AnnotationType, get the "value" element // and invoke it to get the contents. - Class containerClass = containerInstance.annotationType(); - AnnotationType annoType = javaLangAccess.getAnnotationType(containerClass); + Class containerClass = containerInstance.annotationType(); + AnnotationType annoType = AnnotationType.getInstance(containerClass); if (annoType == null) throw new InvalidContainerAnnotationError(containerInstance + " is an invalid container for repeating annotations"); Method m = annoType.members().get("value"); if (m == null) - throw new InvalidContainerAnnotationError(containerInstance + " is an invalid container for repeating annotations"); + throw new InvalidContainerAnnotationError(containerInstance + + " is an invalid container for repeating annotations"); m.setAccessible(true); @SuppressWarnings("unchecked") // not provably safe, but we catch the ClassCastException @@ -175,32 +103,11 @@ public final class AnnotationSupport { IllegalArgumentException | // parameters doesn't match InvocationTargetException | // the value method threw an exception ClassCastException e) { // well, a cast failed ... - throw new InvalidContainerAnnotationError(containerInstance + " is an invalid container for repeating annotations", - e, - containerInstance, - null); - } - } - - /* Sanity check type of and return the first annotation instance - * of type {@code annotationClass} from {@code - * containerInstance}. - */ - private static A unpackOne(Annotation containerInstance, Class annotationClass) { - if (containerInstance == null) { - return null; - } - - try { - return annotationClass.cast(getValueArray(containerInstance)[0]); - } catch (ArrayIndexOutOfBoundsException | // empty array - ClassCastException | // well, a cast failed ... - NullPointerException e) { // can this NP? for good meassure - throw new InvalidContainerAnnotationError(String.format("%s is an invalid container for repeating annotations of type: %s", - containerInstance, annotationClass), - e, - containerInstance, - annotationClass); + throw new InvalidContainerAnnotationError( + containerInstance + " is an invalid container for repeating annotations", + e, + containerInstance, + null); } } @@ -208,24 +115,26 @@ public final class AnnotationSupport { * instances of type {@code annotationClass} from {@code * containerInstance}. */ - private static List unpackAll(Annotation containerInstance, Class annotationClass) { + private static List unpackAll(Annotation containerInstance, + Class annotationClass) { if (containerInstance == null) { return Collections.emptyList(); // container not present } try { A[] a = getValueArray(containerInstance); - ArrayList l = new ArrayList<>(a.length); + List l = new ArrayList<>(a.length); for (int i = 0; i < a.length; i++) l.add(annotationClass.cast(a[i])); return l; } catch (ClassCastException | NullPointerException e) { - throw new InvalidContainerAnnotationError(String.format("%s is an invalid container for repeating annotations of type: %s", - containerInstance, annotationClass), - e, - containerInstance, - annotationClass); + throw new InvalidContainerAnnotationError( + String.format("%s is an invalid container for repeating annotations of type: %s", + containerInstance, annotationClass), + e, + containerInstance, + annotationClass); } } } diff --git a/jdk/test/java/lang/annotation/repeatingAnnotations/RepeatedUnitTest.java b/jdk/test/java/lang/annotation/repeatingAnnotations/RepeatedUnitTest.java index 0d9cb59d1c4..10e3d746261 100644 --- a/jdk/test/java/lang/annotation/repeatingAnnotations/RepeatedUnitTest.java +++ b/jdk/test/java/lang/annotation/repeatingAnnotations/RepeatedUnitTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 7154390 + * @bug 7154390 8005712 * @summary Unit test for repeated annotation reflection * * @compile RepeatedUnitTest.java subpackage/package-info.java subpackage/Container.java subpackage/Containee.java subpackage/NonRepeated.java subpackage/InheritedContainee.java subpackage/InheritedContainer.java subpackage/InheritedNonRepeated.java @@ -58,7 +58,7 @@ public class RepeatedUnitTest { checkMultiplier(Me1.class.getField("foo"), 1); // METHOD - checkMultiplier(Me1.class.getDeclaredMethod("mee", null), 100); + checkMultiplier(Me1.class.getDeclaredMethod("mee", (Class[])null), 100); // INNER CLASS checkMultiplier(Me1.MiniMee.class, 1000); @@ -84,8 +84,7 @@ public class RepeatedUnitTest { static void packageRepeated(AnnotatedElement e) { Containee c = e.getAnnotation(Containee.class); - check(c.value() == 1); - + check(c == null); check(2 == countAnnotation(e, Containee.class)); c = e.getAnnotations(Containee.class)[0]; @@ -93,7 +92,7 @@ public class RepeatedUnitTest { c = e.getAnnotations(Containee.class)[1]; check(c.value() == 2); - check(2 == containsAnnotationOfType(e.getAnnotations(), Containee.class)); + check(0 == containsAnnotationOfType(e.getAnnotations(), Containee.class)); } static void packageContainer(AnnotatedElement e) { @@ -161,14 +160,26 @@ public class RepeatedUnitTest { } static void checkMultiplier(AnnotatedElement e, int m) { + // Basic sanity of non-repeating getAnnotation(Class) check(e.getAnnotation(NonRepeated.class).value() == 5 * m); + // Check count of annotations returned from getAnnotations(Class) check(4 == countAnnotation(e, Containee.class)); check(1 == countAnnotation(e, Container.class)); check(1 == countAnnotation(e, NonRepeated.class)); + // Check contents of array returned from getAnnotations(Class) check(e.getAnnotations(Containee.class)[2].value() == 3 * m); check(e.getAnnotations(NonRepeated.class)[0].value() == 5 * m); + + // Check getAnnotation(Class) + check(e.getAnnotation(Containee.class) == null); + check(e.getAnnotation(Container.class) != null); + + // Check count of annotations returned from getAnnotations() + check(0 == containsAnnotationOfType(e.getAnnotations(), Containee.class)); + check(1 == containsAnnotationOfType(e.getAnnotations(), Container.class)); + check(1 == containsAnnotationOfType(e.getAnnotations(), NonRepeated.class)); } static void check(Boolean b) { diff --git a/jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/Containee.java b/jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/Containee.java index c977b2e5c2d..cca790696d6 100644 --- a/jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/Containee.java +++ b/jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/Containee.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -26,7 +26,6 @@ package subpackage; import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) -@ContainedBy(Container.class) @Repeatable(Container.class) public @interface Containee { int value(); diff --git a/jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/Container.java b/jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/Container.java index e8e2f05ab55..f4d370b7add 100644 --- a/jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/Container.java +++ b/jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/Container.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -26,7 +26,6 @@ package subpackage; import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) -@ContainerFor(Containee.class) public @interface Container { Containee[] value(); } diff --git a/jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/InheritedContainee.java b/jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/InheritedContainee.java index 080d12ce3f5..37f44932a86 100644 --- a/jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/InheritedContainee.java +++ b/jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/InheritedContainee.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -27,7 +27,6 @@ import java.lang.annotation.*; @Inherited @Retention(RetentionPolicy.RUNTIME) -@ContainedBy(InheritedContainer.class) @Repeatable(InheritedContainer.class) public @interface InheritedContainee { int value(); diff --git a/jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/InheritedContainer.java b/jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/InheritedContainer.java index a66af4f6ed8..bff3082520e 100644 --- a/jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/InheritedContainer.java +++ b/jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/InheritedContainer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -27,7 +27,6 @@ import java.lang.annotation.*; @Inherited @Retention(RetentionPolicy.RUNTIME) -@ContainerFor(InheritedContainee.class) public @interface InheritedContainer { InheritedContainee[] value(); } From 7d55c3076545e613503a24f56570448601bda485 Mon Sep 17 00:00:00 2001 From: "J. Duke" Date: Wed, 5 Jul 2017 18:36:12 +0200 Subject: [PATCH 183/204] Added tag jdk8-b73 for changeset fe94b40ffd93 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 6accf5b6291..af2c1e3c0a5 100644 --- a/.hgtags +++ b/.hgtags @@ -194,3 +194,4 @@ adb5171c554e14cd86f618b5584f6e3d693d5889 jdk8-b69 0d625373c69e2ad6f546fd88ab50c6c9aad01271 jdk8-b70 a41ada2ed4ef735449531c6ebe6cec593d890a1c jdk8-b71 6725b3961f987cf40f446d1c11cd324a3bec545f jdk8-b72 +fe94b40ffd9390f6cffcdf51c0389b0e6dde0c13 jdk8-b73 From 8a530c580d0ca71a36cdadae666b19ca1e4ac998 Mon Sep 17 00:00:00 2001 From: "J. Duke" Date: Wed, 5 Jul 2017 18:37:14 +0200 Subject: [PATCH 184/204] Added tag jdk8-b74 for changeset f627eff81962 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index af2c1e3c0a5..261cb1ea200 100644 --- a/.hgtags +++ b/.hgtags @@ -195,3 +195,4 @@ adb5171c554e14cd86f618b5584f6e3d693d5889 jdk8-b69 a41ada2ed4ef735449531c6ebe6cec593d890a1c jdk8-b71 6725b3961f987cf40f446d1c11cd324a3bec545f jdk8-b72 fe94b40ffd9390f6cffcdf51c0389b0e6dde0c13 jdk8-b73 +f627eff819628822a0777af8062244352f2a29cf jdk8-b74 From b3fa7187ae4430440189921e23c59e849c56b93c Mon Sep 17 00:00:00 2001 From: David Buck Date: Thu, 31 Jan 2013 10:55:15 -0800 Subject: [PATCH 185/204] 7042126: (alt-rt) HashMap.clone implementation should be re-examined Test case for cr7042126. Issue only found in OracleJDK, but test case is valid for OpenJDK as well Reviewed-by: mduigou --- .../java/util/HashMap/HashMapCloneLeak.java | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 jdk/test/java/util/HashMap/HashMapCloneLeak.java diff --git a/jdk/test/java/util/HashMap/HashMapCloneLeak.java b/jdk/test/java/util/HashMap/HashMapCloneLeak.java new file mode 100644 index 00000000000..2a5fcaa4f1c --- /dev/null +++ b/jdk/test/java/util/HashMap/HashMapCloneLeak.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013, 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. + */ + +/** + * @test + * @bug 7042126 + * @summary Verify that we do not leak contents when we clone a HashMap + * @author david.buck@oracle.com + * @run main/othervm HashMapCloneLeak + * @run main/othervm -XX:+AggressiveOpts HashMapCloneLeak + */ + +import java.util.HashMap; +import java.lang.ref.WeakReference; + +public class HashMapCloneLeak { + + static WeakReference wr = null; + + // helper method to keep testObject and map out of main method's scope + private static HashMap makeMap() { + HashMap map = new HashMap(); + Object testObject = new Object(); + wr = new WeakReference(testObject); + map.put(42, testObject); + return map; + } + + public static void main(String[] args) throws Exception { + HashMap hm = makeMap(); + hm = (HashMap)hm.clone(); + hm.clear(); + // There should no longer be a strong reference to testObject + // the WeakReference should be nulled out by GC. If not, + // we will hang here until timed out by the test harness. + Object[] chain = null; + while (wr.get() != null) { + try { + Object[] allocate = new Object[1000000]; + allocate[0] = chain; + chain = allocate; + } catch (OutOfMemoryError oome) { + chain = null; + } + System.gc(); + Thread.sleep(100); + } + } + +} From 907f0724ce28cc7a6753f1f103b9e8d30f2d5893 Mon Sep 17 00:00:00 2001 From: Xueming Shen Date: Thu, 31 Jan 2013 11:09:36 -0800 Subject: [PATCH 186/204] 8005394: Base64.Decoder/Encoder.wrap(XStream) don't throw NPE for null args passed To check null for dec/enc.wrap methods Reviewed-by: alanb --- jdk/src/share/classes/java/util/Base64.java | 2 ++ jdk/test/java/util/Base64/TestBase64.java | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/util/Base64.java b/jdk/src/share/classes/java/util/Base64.java index f5ff211f8d4..7a01c05e653 100644 --- a/jdk/src/share/classes/java/util/Base64.java +++ b/jdk/src/share/classes/java/util/Base64.java @@ -413,6 +413,7 @@ public class Base64 { * specified Base64 encoded format */ public OutputStream wrap(OutputStream os) { + Objects.requireNonNull(os); return new EncOutputStream(os, isURL ? toBase64URL : toBase64, newline, linemax); } @@ -866,6 +867,7 @@ public class Base64 { * byte stream */ public InputStream wrap(InputStream is) { + Objects.requireNonNull(is); return new DecInputStream(is, isURL ? fromBase64URL : fromBase64, isMIME); } diff --git a/jdk/test/java/util/Base64/TestBase64.java b/jdk/test/java/util/Base64/TestBase64.java index 6b37772d7f6..645f570b0f3 100644 --- a/jdk/test/java/util/Base64/TestBase64.java +++ b/jdk/test/java/util/Base64/TestBase64.java @@ -22,7 +22,7 @@ */ /** - * @test 4235519 8004212 + * @test 4235519 8004212 8005394 * @summary tests java.util.Base64 */ @@ -295,6 +295,7 @@ public class TestBase64 { checkNull(new Runnable() { public void run() { enc.encode(bb_null); }}); checkNull(new Runnable() { public void run() { enc.encode(bb_null, ByteBuffer.allocate(10), 0); }}); checkNull(new Runnable() { public void run() { enc.encode(ByteBuffer.allocate(10), bb_null, 0); }}); + checkNull(new Runnable() { public void run() { enc.wrap(null); }}); } private static void testNull(final Base64.Decoder dec) { @@ -305,6 +306,7 @@ public class TestBase64 { checkNull(new Runnable() { public void run() { dec.decode(bb_null); }}); checkNull(new Runnable() { public void run() { dec.decode(bb_null, ByteBuffer.allocate(10)); }}); checkNull(new Runnable() { public void run() { dec.decode(ByteBuffer.allocate(10), bb_null); }}); + checkNull(new Runnable() { public void run() { dec.wrap(null); }}); } private static interface Testable { From 9101ca61f5fb2707a4caf94dec32bbb0c7f4728e Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Thu, 31 Jan 2013 12:13:21 -0800 Subject: [PATCH 187/204] 8005832: Remove java.lang.annotation.{ContainedBy, ContainerFor} annotation types Reviewed-by: mduigou --- .../java/lang/annotation/ContainedBy.java | 71 ------------------ .../java/lang/annotation/ContainerFor.java | 73 ------------------- .../InvalidContainerAnnotationError.java | 9 +-- 3 files changed, 4 insertions(+), 149 deletions(-) delete mode 100644 jdk/src/share/classes/java/lang/annotation/ContainedBy.java delete mode 100644 jdk/src/share/classes/java/lang/annotation/ContainerFor.java diff --git a/jdk/src/share/classes/java/lang/annotation/ContainedBy.java b/jdk/src/share/classes/java/lang/annotation/ContainedBy.java deleted file mode 100644 index 4f032863791..00000000000 --- a/jdk/src/share/classes/java/lang/annotation/ContainedBy.java +++ /dev/null @@ -1,71 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -package java.lang.annotation; - -/** - * The annotation type {@code java.lang.annotation.ContainedBy} is - * used to indicate that the annotation type whose declaration it - * (meta-)annotates is repeatable. The value of - * {@code @ContainedBy} indicates the containing annotation - * type for the repeatable annotation type. - * - *

The pair of annotation types {@code @ContainedBy} and - * {@link java.lang.annotation.ContainerFor @ContainerFor} are used to - * indicate that annotation types are repeatable. Specifically: - * - *

    - *
  • The annotation type {@code @ContainedBy} is used on the - * declaration of a repeatable annotation type (JLS 9.6) to indicate - * its containing annotation type. - * - *
  • The annotation type {@code @ContainerFor} is used on the - * declaration of a containing annotation type (JLS 9.6) to indicate - * the repeatable annotation type for which it serves as the - * containing annotation type. - *
- * - *

- * An inconsistent pair of {@code @ContainedBy} and - * {@code @ContainerFor} annotations on a repeatable annotation type - * and its containing annotation type (JLS 9.6) will lead to - * compile-time errors and runtime exceptions when using reflection to - * read annotations of a repeatable type. - * - * @see java.lang.annotation.ContainerFor - * @since 1.8 - * @jls 9.6 Annotation Types - * @jls 9.7 Annotations - */ -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.ANNOTATION_TYPE) -public @interface ContainedBy { - /** - * Indicates the containing annotation type for the - * repeatable annotation type. - */ - Class value(); -} diff --git a/jdk/src/share/classes/java/lang/annotation/ContainerFor.java b/jdk/src/share/classes/java/lang/annotation/ContainerFor.java deleted file mode 100644 index 62f3446e021..00000000000 --- a/jdk/src/share/classes/java/lang/annotation/ContainerFor.java +++ /dev/null @@ -1,73 +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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -package java.lang.annotation; - -/** - * The annotation type {@code java.lang.annotation.ContainerFor} is - * used to indicate that the annotation type whose declaration it - * (meta-)annotates is a containing annotation type. The - * value of {@code @ContainerFor} indicates the repeatable - * annotation type for the containing annotation type. - * - *

The pair of annotation types {@link - * java.lang.annotation.ContainedBy @ContainedBy} and - * {@code @ContainerFor} are used to indicate that annotation types - * are repeatable. Specifically: - * - *

    - *
  • The annotation type {@code @ContainedBy} is used on the - * declaration of a repeatable annotation type (JLS 9.6) to indicate - * its containing annotation type. - * - *
  • The annotation type {@code @ContainerFor} is used on the - * declaration of a containing annotation type (JLS 9.6) to indicate - * the repeatable annotation type for which it serves as the - * containing annotation type. - *
- * - *

- * An inconsistent pair of {@code @ContainedBy} and - * {@code @ContainerFor} annotations on a repeatable annotation type - * and its containing annotation type (JLS 9.6) will lead to - * compile-time errors and runtime exceptions when using reflection to - * read annotations of a repeatable type. - * - * @see java.lang.annotation.ContainedBy - * @since 1.8 - * @jls 9.6 Annotation Types - * @jls 9.7 Annotations - */ -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.ANNOTATION_TYPE) -public @interface ContainerFor { - - /** - * Indicates the repeatable annotation type for the containing - * annotation type. - */ - Class value(); -} diff --git a/jdk/src/share/classes/java/lang/annotation/InvalidContainerAnnotationError.java b/jdk/src/share/classes/java/lang/annotation/InvalidContainerAnnotationError.java index b24e3034179..37d00a98b40 100644 --- a/jdk/src/share/classes/java/lang/annotation/InvalidContainerAnnotationError.java +++ b/jdk/src/share/classes/java/lang/annotation/InvalidContainerAnnotationError.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -27,10 +27,9 @@ package java.lang.annotation; import java.util.Objects; /** - * Thrown to indicate that an annotation type whose declaration is - * (meta-)annotated with a {@link ContainerFor} annotation is not, in - * fact, the containing annotation type of the type named by {@link - * ContainerFor}. + * Thrown to indicate that an annotation type expected to act as a + * container for another annotation type by virture of an @Repeatable + * annotation, does not act as a container. * * @see java.lang.reflect.AnnotatedElement * @since 1.8 From 757d9cdeb9c5cac2cf99a8a29f53ef68448964c4 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Thu, 31 Jan 2013 12:23:04 -0800 Subject: [PATCH 188/204] 8007115: Refactor regression tests for java.lang.reflect.Parameter Reviewed-by: emc --- .../reflect/Parameter/WithoutParameters.java | 249 +++++++++--------- 1 file changed, 119 insertions(+), 130 deletions(-) diff --git a/jdk/test/java/lang/reflect/Parameter/WithoutParameters.java b/jdk/test/java/lang/reflect/Parameter/WithoutParameters.java index 39be21471aa..50254fd9d6b 100644 --- a/jdk/test/java/lang/reflect/Parameter/WithoutParameters.java +++ b/jdk/test/java/lang/reflect/Parameter/WithoutParameters.java @@ -23,163 +23,152 @@ /* * @test + * @bug 8004729 * @summary javac should generate method parameters correctly. */ import java.lang.*; import java.lang.reflect.*; +import java.lang.annotation.*; import java.util.List; +import java.util.Objects; + +import static java.lang.annotation.ElementType.*; public class WithoutParameters { + int errors = 0; - private static final Class[] qux_types = { - int.class, - Foo.class, - List.class, - List.class, - List.class, - String[].class - }; + private WithoutParameters() {} public static void main(String argv[]) throws Exception { - int error = 0; - Method[] methods = Foo.class.getMethods(); - for(Method m : methods) { - System.err.println("Inspecting method " + m); - Parameter[] parameters = m.getParameters(); - if(parameters == null) - throw new Exception("getParameters should never be null"); - for(int i = 0; i < parameters.length; i++) { - Parameter p = parameters[i]; - if(!p.getDeclaringExecutable().equals(m)) { - System.err.println(p + ".getDeclaringExecutable != " + m); - error++; - } - if(null == p.getType()) { - System.err.println(p + ".getType() == null"); - error++; - } - if(null == p.getParameterizedType()) { - System.err.println(p + ".getParameterizedType == null"); - error++; - } - } - if(m.getName().equals("qux")) { - if(6 != parameters.length) { - System.err.println("Wrong number of parameters for qux"); - error++; - } - for(int i = 0; i < parameters.length; i++) { - Parameter p = parameters[i]; - // The getType family work with or without - // parameter attributes compiled in. - if(!parameters[i].getType().equals(qux_types[i])) { - System.err.println("Wrong parameter type for " + parameters[0] + ": expected " + qux_types[i] + ", but got " + parameters[i].getType()); - error++; - } - } - if(!parameters[0].getParameterizedType().equals(int.class)) { - System.err.println("getParameterizedType for quux is wrong"); - error++; - } - if(!parameters[1].getParameterizedType().equals(Foo.class)) { - System.err.println("getParameterizedType for quux is wrong"); - error++; - } - if(!(parameters[2].getParameterizedType() instanceof - ParameterizedType)) { - System.err.println("getParameterizedType for l is wrong"); - error++; - } else { - ParameterizedType pt = - (ParameterizedType) parameters[2].getParameterizedType(); - if(!pt.getRawType().equals(List.class)) { - System.err.println("Raw type for l is wrong"); - error++; - } - if(1 != pt.getActualTypeArguments().length) { - System.err.println("Number of type parameters for l is wrong"); - error++; - } - if(!(pt.getActualTypeArguments()[0] instanceof WildcardType)) { - System.err.println("Type parameter for l is wrong"); - error++; - } - } - if(!(parameters[3].getParameterizedType() instanceof - ParameterizedType)) { - System.err.println("getParameterizedType for l2 is wrong"); - error++; - } else { - ParameterizedType pt = - (ParameterizedType) parameters[3].getParameterizedType(); - if(!pt.getRawType().equals(List.class)) { - System.err.println("Raw type for l2 is wrong"); - error++; - } - if(1 != pt.getActualTypeArguments().length) { - System.err.println("Number of type parameters for l2 is wrong"); - error++; - } - if(!(pt.getActualTypeArguments()[0].equals(Foo.class))) { - System.err.println("Type parameter for l2 is wrong"); - error++; - } - } - if(!(parameters[4].getParameterizedType() instanceof - ParameterizedType)) { - System.err.println("getParameterizedType for l3 is wrong"); - error++; - } else { - ParameterizedType pt = - (ParameterizedType) parameters[4].getParameterizedType(); - if(!pt.getRawType().equals(List.class)) { - System.err.println("Raw type for l3 is wrong"); - error++; - } - if(1 != pt.getActualTypeArguments().length) { - System.err.println("Number of type parameters for l3 is wrong"); - error++; - } - if(!(pt.getActualTypeArguments()[0] instanceof WildcardType)) { - System.err.println("Type parameter for l3 is wrong"); - error++; - } else { - WildcardType wt = (WildcardType) - pt.getActualTypeArguments()[0]; - if(!wt.getUpperBounds()[0].equals(Foo.class)) { - System.err.println("Upper bounds on type parameter fol l3 is wrong"); - error++; - } - } - } - if(!parameters[5].isVarArgs()) { - System.err.println("isVarArg for rest is wrong"); - error++; - } - if(!(parameters[5].getParameterizedType().equals(String[].class))) { - System.err.println("getParameterizedType for rest is wrong"); - error++; - } + WithoutParameters wp = new WithoutParameters(); + wp.runTests(Foo.class.getMethods()); + wp.runTests(Foo.Inner.class.getConstructors()); + wp.checkForErrors(); + } + void runTests(Method[] methods) throws Exception { + for(Method m : methods) {runTest(m);} + } + + void runTests(Constructor[] constructors) throws Exception { + for(Constructor c : constructors) {runTest(c);} + } + + void runTest(Executable e) throws Exception { + System.err.println("Inspecting executable " + e); + Parameter[] parameters = e.getParameters(); + Objects.requireNonNull(parameters, "getParameters should never be null"); + + ExpectedParameterInfo epi = e.getAnnotation(ExpectedParameterInfo.class); + if (epi != null) { + abortIfTrue(epi.parameterCount() != e.getParameterCount(), "Bad parameter count for "+ e); + abortIfTrue(epi.isVarArgs() != e.isVarArgs(),"Bad varargs value for "+ e); + } + abortIfTrue(e.getParameterCount() != parameters.length, "Mismatched of parameter counts."); + + for(int i = 0; i < parameters.length; i++) { + Parameter p = parameters[i]; + errorIfTrue(!p.getDeclaringExecutable().equals(e), p + ".getDeclaringExecutable != " + e); + Objects.requireNonNull(p.getType(), "getType() should not be null"); + Objects.requireNonNull(p.getParameterizedType(), "getParameterizedType() should not be null"); + + if (epi != null) { + Class expectedParameterType = epi.parameterTypes()[i]; + errorIfTrue(!p.getType().equals(expectedParameterType), + "Wrong parameter type for " + p + ": expected " + expectedParameterType + + ", but got " + p.getType()); + + ParameterizedInfo[] expectedParameterizedTypes = epi.parameterizedTypes(); + if (expectedParameterizedTypes.length > 0) { + Type parameterizedType = p.getParameterizedType(); + Class expectedParameterziedTypeType = expectedParameterizedTypes[i].value(); + errorIfTrue(!expectedParameterziedTypeType.isAssignableFrom(parameterizedType.getClass()), + "Wrong class of parameteried type of " + p + ": expected " + expectedParameterziedTypeType + + ", but got " + parameterizedType.getClass()); + + if (expectedParameterziedTypeType.equals(Class.class)) { + errorIfTrue(!parameterizedType.equals(expectedParameterType), + "Wrong parameteried type for " + p + ": expected " + expectedParameterType + + ", but got " + parameterizedType); + } else { + if (expectedParameterziedTypeType.equals(ParameterizedType.class)) { + ParameterizedType ptype = (ParameterizedType)parameterizedType; + errorIfTrue(!ptype.getRawType().equals(expectedParameterType), + "Wrong raw type for " + p + ": expected " + expectedParameterType + + ", but got " + ptype.getRawType()); + } + + // Check string representation + String expectedStringOfType = epi.parameterizedTypes()[i].string(); + errorIfTrue(!expectedStringOfType.equals(parameterizedType.toString()), + "Bad type string" + p + ": expected " + expectedStringOfType + + ", but got " + parameterizedType.toString()); + } + } } } - if(0 != error) - throw new Exception("Failed " + error + " tests"); + } + + private void checkForErrors() { + if (errors > 0) + throw new RuntimeException("Failed " + errors + " tests"); + } + + private void errorIfTrue(boolean predicate, String errMessage) { + if (predicate) { + errors++; + System.err.println(errMessage); + } + } + + private void abortIfTrue(boolean predicate, String errMessage) { + if (predicate) { + throw new RuntimeException(errMessage); + } + } + + @Retention(RetentionPolicy.RUNTIME) + @Target({METHOD, CONSTRUCTOR}) + @interface ExpectedParameterInfo { + int parameterCount() default 0; + Class[] parameterTypes() default {}; + ParameterizedInfo[] parameterizedTypes() default {}; + boolean isVarArgs() default false; + } + + @Target({}) + @interface ParameterizedInfo { + Class value() default Class.class; + String string() default ""; } public class Foo { int thing; + @ExpectedParameterInfo(parameterCount = 6, + parameterTypes = + {int.class, Foo.class, + List.class, List.class, + List.class, String[].class}, + parameterizedTypes = + {@ParameterizedInfo(Class.class), + @ParameterizedInfo(Class.class), + @ParameterizedInfo(value=ParameterizedType.class, string="java.util.List"), + @ParameterizedInfo(value=ParameterizedType.class, string="java.util.List"), + @ParameterizedInfo(value=ParameterizedType.class, string="java.util.List"), + @ParameterizedInfo(Class.class)}, + isVarArgs = true) public void qux(int quux, Foo quuux, List l, List l2, List l3, String... rest) {} public class Inner { int thang; + @ExpectedParameterInfo(parameterCount = 2, + parameterTypes = {Foo.class, int.class}) public Inner(int theng) { thang = theng + thing; } } } - } From 320ce960ce44832016963f7356269e3ae6b63677 Mon Sep 17 00:00:00 2001 From: Xueming Shen Date: Thu, 31 Jan 2013 13:13:14 -0800 Subject: [PATCH 189/204] 8007298: Base64.getMimeDecoder().decode() throws IAE for a single non-base64 character 8006526: Base64.Decoder.decode(String) spec contains a copy-paste mistake To ignore single non-base64 char in mime decoding Reviewed-by: alanb --- jdk/src/share/classes/java/util/Base64.java | 7 +++++-- jdk/test/java/util/Base64/TestBase64.java | 18 +++++++++++++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/classes/java/util/Base64.java b/jdk/src/share/classes/java/util/Base64.java index 7a01c05e653..471b4e28620 100644 --- a/jdk/src/share/classes/java/util/Base64.java +++ b/jdk/src/share/classes/java/util/Base64.java @@ -696,7 +696,7 @@ public class Base64 { * using the {@link Base64} encoding scheme. * *

An invocation of this method has exactly the same effect as invoking - * {@code return decode(src.getBytes(StandardCharsets.ISO_8859_1))} + * {@code decode(src.getBytes(StandardCharsets.ISO_8859_1))} * * @param src * the string to decode @@ -1014,9 +1014,12 @@ public class Base64 { int len = sl - sp; if (len == 0) return 0; - if (len < 2) + if (len < 2) { + if (isMIME && base64[0] == -1) + return 0; throw new IllegalArgumentException( "Input byte[] should at least have 2 bytes for base64 bytes"); + } if (src[sl - 1] == '=') { paddings++; if (src[sl - 2] == '=') diff --git a/jdk/test/java/util/Base64/TestBase64.java b/jdk/test/java/util/Base64/TestBase64.java index 645f570b0f3..0a8eea6e4aa 100644 --- a/jdk/test/java/util/Base64/TestBase64.java +++ b/jdk/test/java/util/Base64/TestBase64.java @@ -22,7 +22,7 @@ */ /** - * @test 4235519 8004212 8005394 + * @test 4235519 8004212 8005394 8007298 * @summary tests java.util.Base64 */ @@ -109,6 +109,9 @@ public class TestBase64 { // test return value from decode(ByteBuffer, ByteBuffer) testDecBufRet(); + + // test single-non-base64 character for mime decoding + testSingleNonBase64MimeDec(); } private static sun.misc.BASE64Encoder sunmisc = new sun.misc.BASE64Encoder(); @@ -356,6 +359,19 @@ public class TestBase64 { } catch (IllegalArgumentException iae) {} } + // single-non-base64-char should be ignored for mime decoding, but + // iae for basic decoding + private static void testSingleNonBase64MimeDec() throws Throwable { + for (String nonBase64 : new String[] {"#", "(", "!", "\\", "-", "_"}) { + if (Base64.getMimeDecoder().decode(nonBase64).length != 0) { + throw new RuntimeException("non-base64 char is not ignored"); + } + try { + Base64.getDecoder().decode(nonBase64); + throw new RuntimeException("No IAE for single non-base64 char"); + } catch (IllegalArgumentException iae) {} + } + } private static void testDecBufRet() throws Throwable { Random rnd = new java.util.Random(); From 665fca9d60704d2dad7b0611f4b73adabd0e659a Mon Sep 17 00:00:00 2001 From: Mike Duigou Date: Thu, 31 Jan 2013 13:27:04 -0800 Subject: [PATCH 190/204] 8006709: Add minimal support of MacOSX platform for NetBeans Projects Adds support for MacOSX platform and architecture detection. Other minor updates (-source/target 1.8) Reviewed-by: ohair --- .../architectures/arch-x86_64.properties | 32 +++++++++++++++++++ .../architectures/name-Macosx.properties | 32 +++++++++++++++++++ jdk/make/netbeans/common/java-data-native.ent | 4 +-- .../netbeans/common/java-data-no-native.ent | 4 +-- jdk/make/netbeans/common/make.xml | 7 +++- jdk/make/netbeans/common/shared.xml | 7 ++-- 6 files changed, 77 insertions(+), 9 deletions(-) create mode 100644 jdk/make/netbeans/common/architectures/arch-x86_64.properties create mode 100644 jdk/make/netbeans/common/architectures/name-Macosx.properties diff --git a/jdk/make/netbeans/common/architectures/arch-x86_64.properties b/jdk/make/netbeans/common/architectures/arch-x86_64.properties new file mode 100644 index 00000000000..eac11240e57 --- /dev/null +++ b/jdk/make/netbeans/common/architectures/arch-x86_64.properties @@ -0,0 +1,32 @@ +# +# Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# - Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# - Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# - Neither the name of Oracle nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +arch=x86_64 diff --git a/jdk/make/netbeans/common/architectures/name-Macosx.properties b/jdk/make/netbeans/common/architectures/name-Macosx.properties new file mode 100644 index 00000000000..05744c7f05c --- /dev/null +++ b/jdk/make/netbeans/common/architectures/name-Macosx.properties @@ -0,0 +1,32 @@ +# +# Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# - Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# - Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# - Neither the name of Oracle nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +platform=macosx diff --git a/jdk/make/netbeans/common/java-data-native.ent b/jdk/make/netbeans/common/java-data-native.ent index a801e821db6..8db2a86d618 100644 --- a/jdk/make/netbeans/common/java-data-native.ent +++ b/jdk/make/netbeans/common/java-data-native.ent @@ -39,11 +39,11 @@ ${bootstrap.jdk}/jre/lib/rt.jar ${root}/build/${platform}-${arch}/classes ${root}/build/${platform}-${arch}/docs/api - 1.7 + 1.8 ${root}/test - 1.7 + 1.8 diff --git a/jdk/make/netbeans/common/java-data-no-native.ent b/jdk/make/netbeans/common/java-data-no-native.ent index a204f3a6f17..240ec4aadc9 100644 --- a/jdk/make/netbeans/common/java-data-no-native.ent +++ b/jdk/make/netbeans/common/java-data-no-native.ent @@ -37,11 +37,11 @@ ${bootstrap.jdk}/jre/lib/rt.jar ${root}/build/${platform}-${arch}/classes ${root}/build/${platform}-${arch}/docs/api - 1.7 + 1.8 ${root}/test - 1.7 + 1.8 diff --git a/jdk/make/netbeans/common/make.xml b/jdk/make/netbeans/common/make.xml index a61f04f07db..ee1a47a4fe1 100644 --- a/jdk/make/netbeans/common/make.xml +++ b/jdk/make/netbeans/common/make.xml @@ -33,7 +33,7 @@ - + @@ -42,6 +42,11 @@ + + + + + diff --git a/jdk/make/netbeans/common/shared.xml b/jdk/make/netbeans/common/shared.xml index 7c2b8095f79..ba104445273 100644 --- a/jdk/make/netbeans/common/shared.xml +++ b/jdk/make/netbeans/common/shared.xml @@ -85,6 +85,9 @@ + + + @@ -126,10 +129,6 @@ - - - - From f7f0768c22be02b8e88f44c7b023bbe079f083a4 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Thu, 31 Jan 2013 14:29:19 -0800 Subject: [PATCH 191/204] 6355704: (fmt) %f formatting of BigDecimals is incorrect Reviewed-by: darcy --- jdk/test/java/util/Formatter/Basic-X.java.template | 9 +++++++++ jdk/test/java/util/Formatter/BasicBigDecimal.java | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/jdk/test/java/util/Formatter/Basic-X.java.template b/jdk/test/java/util/Formatter/Basic-X.java.template index 55b24097f6e..831c49212f0 100644 --- a/jdk/test/java/util/Formatter/Basic-X.java.template +++ b/jdk/test/java/util/Formatter/Basic-X.java.template @@ -1103,6 +1103,15 @@ public class Basic$Type$ extends Basic { test("%.5f", "1.99999", val); test("%.6f", "1.999990", val); + val = new BigDecimal(0.9996); + test("%.0f", "1", val); + test("%.1f", "1.0", val); + test("%.2f", "1.00", val); + test("%.3f", "1.000", val); + test("%.4f", "0.9996", val); + test("%.5f", "0.99960", val); + test("%.6f", "0.999600", val); + #end[BigDecimal] #if[float] diff --git a/jdk/test/java/util/Formatter/BasicBigDecimal.java b/jdk/test/java/util/Formatter/BasicBigDecimal.java index afc446ae4b0..6f36201aa34 100644 --- a/jdk/test/java/util/Formatter/BasicBigDecimal.java +++ b/jdk/test/java/util/Formatter/BasicBigDecimal.java @@ -1102,6 +1102,15 @@ public class BasicBigDecimal extends Basic { test("%.4f", "2.0000", val); test("%.5f", "1.99999", val); test("%.6f", "1.999990", val); + + val = new BigDecimal(0.9996); + test("%.0f", "1", val); + test("%.1f", "1.0", val); + test("%.2f", "1.00", val); + test("%.3f", "1.000", val); + test("%.4f", "0.9996", val); + test("%.5f", "0.99960", val); + test("%.6f", "0.999600", val); From 0c6cb9cdc2f088b887efdf3599213f39208f191c Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Fri, 1 Feb 2013 07:39:41 +0800 Subject: [PATCH 192/204] 8006564: Test sun/security/util/Oid/S11N.sh fails with timeout on Linux 32-bit Reviewed-by: alanb --- jdk/test/sun/security/util/Oid/S11N.java | 246 ++++++++++++++++++ jdk/test/sun/security/util/Oid/S11N.sh | 188 ------------- .../sun/security/util/Oid/SerialTest.java | 66 ----- 3 files changed, 246 insertions(+), 254 deletions(-) create mode 100644 jdk/test/sun/security/util/Oid/S11N.java delete mode 100644 jdk/test/sun/security/util/Oid/S11N.sh delete mode 100644 jdk/test/sun/security/util/Oid/SerialTest.java diff --git a/jdk/test/sun/security/util/Oid/S11N.java b/jdk/test/sun/security/util/Oid/S11N.java new file mode 100644 index 00000000000..a5595d10112 --- /dev/null +++ b/jdk/test/sun/security/util/Oid/S11N.java @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2013, 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. + */ + +/* + * @test + * @bug 4811968 6908628 8006564 + * @run main S11N check + * @summary Serialization compatibility with old versions (and fixes) + */ + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.HashMap; +import java.util.Map; +import sun.misc.BASE64Encoder; +import sun.security.util.ObjectIdentifier; + +public class S11N { + static String[] SMALL= { + "0.0", + "1.1", + "2.2", + "1.2.3456", + "1.2.2147483647.4", + "1.2.268435456.4", + }; + + static String[] HUGE = { + "2.16.764.1.3101555394.1.0.100.2.1", + "1.2.2147483648.4", + "2.3.4444444444444444444444", + "1.2.8888888888888888.33333333333333333.44444444444444", + }; + + // Do not use j.u.Base64, the test needs to run in jdk6 + static BASE64Encoder encoder = new BASE64Encoder() { + @Override + protected int bytesPerLine() { + return 48; + } + }; + + public static void main(String[] args) throws Exception { + if (args[0].equals("check")) { + int version = Integer.valueOf(System.getProperty("java.version") + .split("\\.")[1]); + System.out.println("version is " + version); + if (version >= 7) { + for (String oid: SMALL) { + // 7 -> 7 + check(out(oid), oid); + // 6 -> 7 + check(out6(oid), oid); + } + for (String oid: HUGE) { + // 7 -> 7 + check(out(oid), oid); + } + } else { + for (String oid: SMALL) { + // 6 -> 6 + check(out(oid), oid); + // 7 -> 6 + check(out7(oid), oid); + } + for (String oid: HUGE) { + // 7 -> 6 fails for HUGE oids + boolean ok = false; + try { + check(out7(oid), oid); + ok = true; + } catch (Exception e) { + System.out.println(e); + } + if (ok) { + throw new Exception(); + } + } + } + } else { + // Generates the JDK6 serialized string inside this test, call + // $JDK7/bin/java S11N dump7 + // $JDK6/bin/java S11N dump6 + // and paste the output at the end of this test. + dump(args[0], SMALL); + // For jdk6, the following line will throw an exception, ignore it + dump(args[0], HUGE); + } + } + + // Gets the serialized form for jdk6 + private static byte[] out6(String oid) throws Exception { + return new sun.misc.BASE64Decoder().decodeBuffer(dump6.get(oid)); + } + + // Gets the serialized form for jdk7 + private static byte[] out7(String oid) throws Exception { + return new sun.misc.BASE64Decoder().decodeBuffer(dump7.get(oid)); + } + + // Gets the serialized form for this java + private static byte[] out(String oid) throws Exception { + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + new ObjectOutputStream(bout).writeObject(new ObjectIdentifier(oid)); + return bout.toByteArray(); + } + + // Makes sure serialized form can be deserialized + private static void check(byte[] in, String oid) throws Exception { + ObjectIdentifier o = (ObjectIdentifier) ( + new ObjectInputStream(new ByteArrayInputStream(in)).readObject()); + if (!o.toString().equals(oid)) { + throw new Exception("Read Fail " + o + ", not " + oid); + } + } + + // dump serialized form to java code style text + private static void dump(String title, String[] oids) throws Exception { + for (String oid: oids) { + String[] base64 = encoder.encodeBuffer(out(oid)).split("\n"); + System.out.println(" " + title + ".put(\"" + oid + "\","); + for (int i = 0; i dump7 = new HashMap(); + private static Map dump6 = new HashMap(); + + static { + ////////////// PASTE BEGIN ////////////// + dump7.put("0.0", + "rO0ABXNyACJzdW4uc2VjdXJpdHkudXRpbC5PYmplY3RJZGVudGlmaWVyeLIO7GQX" + + "fy4DAANJAAxjb21wb25lbnRMZW5MAApjb21wb25lbnRzdAASTGphdmEvbGFuZy9P" + + "YmplY3Q7WwAIZW5jb2Rpbmd0AAJbQnhwAAAAAnVyAAJbSU26YCZ26rKlAgAAeHAA" + + "AAACAAAAAAAAAAB1cgACW0Ks8xf4BghU4AIAAHhwAAAAAQB4"); + dump7.put("1.1", + "rO0ABXNyACJzdW4uc2VjdXJpdHkudXRpbC5PYmplY3RJZGVudGlmaWVyeLIO7GQX" + + "fy4DAANJAAxjb21wb25lbnRMZW5MAApjb21wb25lbnRzdAASTGphdmEvbGFuZy9P" + + "YmplY3Q7WwAIZW5jb2Rpbmd0AAJbQnhwAAAAAnVyAAJbSU26YCZ26rKlAgAAeHAA" + + "AAACAAAAAQAAAAF1cgACW0Ks8xf4BghU4AIAAHhwAAAAASl4"); + dump7.put("2.2", + "rO0ABXNyACJzdW4uc2VjdXJpdHkudXRpbC5PYmplY3RJZGVudGlmaWVyeLIO7GQX" + + "fy4DAANJAAxjb21wb25lbnRMZW5MAApjb21wb25lbnRzdAASTGphdmEvbGFuZy9P" + + "YmplY3Q7WwAIZW5jb2Rpbmd0AAJbQnhwAAAAAnVyAAJbSU26YCZ26rKlAgAAeHAA" + + "AAACAAAAAgAAAAJ1cgACW0Ks8xf4BghU4AIAAHhwAAAAAVJ4"); + dump7.put("1.2.3456", + "rO0ABXNyACJzdW4uc2VjdXJpdHkudXRpbC5PYmplY3RJZGVudGlmaWVyeLIO7GQX" + + "fy4DAANJAAxjb21wb25lbnRMZW5MAApjb21wb25lbnRzdAASTGphdmEvbGFuZy9P" + + "YmplY3Q7WwAIZW5jb2Rpbmd0AAJbQnhwAAAAA3VyAAJbSU26YCZ26rKlAgAAeHAA" + + "AAADAAAAAQAAAAIAAA2AdXIAAltCrPMX+AYIVOACAAB4cAAAAAMqmwB4"); + dump7.put("1.2.2147483647.4", + "rO0ABXNyACJzdW4uc2VjdXJpdHkudXRpbC5PYmplY3RJZGVudGlmaWVyeLIO7GQX" + + "fy4DAANJAAxjb21wb25lbnRMZW5MAApjb21wb25lbnRzdAASTGphdmEvbGFuZy9P" + + "YmplY3Q7WwAIZW5jb2Rpbmd0AAJbQnhwAAAABHVyAAJbSU26YCZ26rKlAgAAeHAA" + + "AAAEAAAAAQAAAAJ/////AAAABHVyAAJbQqzzF/gGCFTgAgAAeHAAAAAHKof///9/" + + "BHg="); + dump7.put("1.2.268435456.4", + "rO0ABXNyACJzdW4uc2VjdXJpdHkudXRpbC5PYmplY3RJZGVudGlmaWVyeLIO7GQX" + + "fy4DAANJAAxjb21wb25lbnRMZW5MAApjb21wb25lbnRzdAASTGphdmEvbGFuZy9P" + + "YmplY3Q7WwAIZW5jb2Rpbmd0AAJbQnhwAAAABHVyAAJbSU26YCZ26rKlAgAAeHAA" + + "AAAEAAAAAQAAAAIQAAAAAAAABHVyAAJbQqzzF/gGCFTgAgAAeHAAAAAHKoGAgIAA" + + "BHg="); + dump7.put("2.16.764.1.3101555394.1.0.100.2.1", + "rO0ABXNyACJzdW4uc2VjdXJpdHkudXRpbC5PYmplY3RJZGVudGlmaWVyeLIO7GQX" + + "fy4DAANJAAxjb21wb25lbnRMZW5MAApjb21wb25lbnRzdAASTGphdmEvbGFuZy9P" + + "YmplY3Q7WwAIZW5jb2Rpbmd0AAJbQnhw/////3NyAD5zdW4uc2VjdXJpdHkudXRp" + + "bC5PYmplY3RJZGVudGlmaWVyJEh1Z2VPaWROb3RTdXBwb3J0ZWRCeU9sZEpESwAA" + + "AAAAAAABAgAAeHB1cgACW0Ks8xf4BghU4AIAAHhwAAAADmCFfAGLxvf1QgEAZAIB" + + "eA=="); + dump7.put("1.2.2147483648.4", + "rO0ABXNyACJzdW4uc2VjdXJpdHkudXRpbC5PYmplY3RJZGVudGlmaWVyeLIO7GQX" + + "fy4DAANJAAxjb21wb25lbnRMZW5MAApjb21wb25lbnRzdAASTGphdmEvbGFuZy9P" + + "YmplY3Q7WwAIZW5jb2Rpbmd0AAJbQnhw/////3NyAD5zdW4uc2VjdXJpdHkudXRp" + + "bC5PYmplY3RJZGVudGlmaWVyJEh1Z2VPaWROb3RTdXBwb3J0ZWRCeU9sZEpESwAA" + + "AAAAAAABAgAAeHB1cgACW0Ks8xf4BghU4AIAAHhwAAAAByqIgICAAAR4"); + dump7.put("2.3.4444444444444444444444", + "rO0ABXNyACJzdW4uc2VjdXJpdHkudXRpbC5PYmplY3RJZGVudGlmaWVyeLIO7GQX" + + "fy4DAANJAAxjb21wb25lbnRMZW5MAApjb21wb25lbnRzdAASTGphdmEvbGFuZy9P" + + "YmplY3Q7WwAIZW5jb2Rpbmd0AAJbQnhw/////3NyAD5zdW4uc2VjdXJpdHkudXRp" + + "bC5PYmplY3RJZGVudGlmaWVyJEh1Z2VPaWROb3RTdXBwb3J0ZWRCeU9sZEpESwAA" + + "AAAAAAABAgAAeHB1cgACW0Ks8xf4BghU4AIAAHhwAAAADFOD4e+HpNG968eOHHg="); + dump7.put("1.2.8888888888888888.33333333333333333.44444444444444", + "rO0ABXNyACJzdW4uc2VjdXJpdHkudXRpbC5PYmplY3RJZGVudGlmaWVyeLIO7GQX" + + "fy4DAANJAAxjb21wb25lbnRMZW5MAApjb21wb25lbnRzdAASTGphdmEvbGFuZy9P" + + "YmplY3Q7WwAIZW5jb2Rpbmd0AAJbQnhw/////3NyAD5zdW4uc2VjdXJpdHkudXRp" + + "bC5PYmplY3RJZGVudGlmaWVyJEh1Z2VPaWROb3RTdXBwb3J0ZWRCeU9sZEpESwAA" + + "AAAAAAABAgAAeHB1cgACW0Ks8xf4BghU4AIAAHhwAAAAGCqP5Yzbxa6cOLubj9ek" + + "japVio3AusuOHHg="); + + dump6.put("0.0", + "rO0ABXNyACJzdW4uc2VjdXJpdHkudXRpbC5PYmplY3RJZGVudGlmaWVyeLIO7GQX" + + "fy4CAAJJAAxjb21wb25lbnRMZW5bAApjb21wb25lbnRzdAACW0l4cAAAAAJ1cgAC" + + "W0lNumAmduqypQIAAHhwAAAAAgAAAAAAAAAA"); + dump6.put("1.1", + "rO0ABXNyACJzdW4uc2VjdXJpdHkudXRpbC5PYmplY3RJZGVudGlmaWVyeLIO7GQX" + + "fy4CAAJJAAxjb21wb25lbnRMZW5bAApjb21wb25lbnRzdAACW0l4cAAAAAJ1cgAC" + + "W0lNumAmduqypQIAAHhwAAAAAgAAAAEAAAAB"); + dump6.put("2.2", + "rO0ABXNyACJzdW4uc2VjdXJpdHkudXRpbC5PYmplY3RJZGVudGlmaWVyeLIO7GQX" + + "fy4CAAJJAAxjb21wb25lbnRMZW5bAApjb21wb25lbnRzdAACW0l4cAAAAAJ1cgAC" + + "W0lNumAmduqypQIAAHhwAAAAAgAAAAIAAAAC"); + dump6.put("1.2.3456", + "rO0ABXNyACJzdW4uc2VjdXJpdHkudXRpbC5PYmplY3RJZGVudGlmaWVyeLIO7GQX" + + "fy4CAAJJAAxjb21wb25lbnRMZW5bAApjb21wb25lbnRzdAACW0l4cAAAAAN1cgAC" + + "W0lNumAmduqypQIAAHhwAAAAAwAAAAEAAAACAAANgA=="); + dump6.put("1.2.2147483647.4", + "rO0ABXNyACJzdW4uc2VjdXJpdHkudXRpbC5PYmplY3RJZGVudGlmaWVyeLIO7GQX" + + "fy4CAAJJAAxjb21wb25lbnRMZW5bAApjb21wb25lbnRzdAACW0l4cAAAAAR1cgAC" + + "W0lNumAmduqypQIAAHhwAAAABAAAAAEAAAACf////wAAAAQ="); + dump6.put("1.2.268435456.4", + "rO0ABXNyACJzdW4uc2VjdXJpdHkudXRpbC5PYmplY3RJZGVudGlmaWVyeLIO7GQX" + + "fy4CAAJJAAxjb21wb25lbnRMZW5bAApjb21wb25lbnRzdAACW0l4cAAAAAR1cgAC" + + "W0lNumAmduqypQIAAHhwAAAABAAAAAEAAAACEAAAAAAAAAQ="); + ////////////// PASTE END ////////////// + } +} diff --git a/jdk/test/sun/security/util/Oid/S11N.sh b/jdk/test/sun/security/util/Oid/S11N.sh deleted file mode 100644 index a19af17be5f..00000000000 --- a/jdk/test/sun/security/util/Oid/S11N.sh +++ /dev/null @@ -1,188 +0,0 @@ -# -# Copyright (c) 2004, 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. -# -# @test -# @bug 4811968 6908628 -# @summary Serialization compatibility with old versions (and fix) -# @author Weijun Wang -# -# set a few environment variables so that the shell-script can run stand-alone -# in the source directory - -if [ "${TESTSRC}" = "" ] ; then - TESTSRC="." -fi -if [ "${TESTCLASSES}" = "" ] ; then - TESTCLASSES="." -fi -if [ "${TESTJAVA}" = "" ] ; then - echo "TESTJAVA not set. Test cannot execute." - echo "FAILED!!!" - exit 1 -fi -if [ "${COMPILEJAVA}" = "" ]; then - COMPILEJAVA="${TESTJAVA}" -fi - -# set platform-dependent variables -PF="" - -OS=`uname -s` -case "$OS" in - SunOS ) - FS="/" - ARCH=`isainfo` - case "$ARCH" in - sparc* ) - PF="solaris-sparc" - ;; - i[3-6]86 ) - PF="solaris-i586" - ;; - amd64* ) - PF="solaris-amd64" - ;; - * ) - echo "Unsupported System: Solaris ${ARCH}" - exit 0; - ;; - esac - ;; - Linux ) - ARCH=`uname -m` - FS="/" - case "$ARCH" in - i[3-6]86 ) - PF="linux-i586" - ;; - amd64* | x86_64 ) - PF="linux-amd64" - ;; - * ) - echo "Unsupported System: Linux ${ARCH}" - exit 0; - ;; - esac - ;; - Windows* ) - FS="\\" - PF="windows-i586" - - # 'uname -m' does not give us enough information - - # should rely on $PROCESSOR_IDENTIFIER (as is done in Defs-windows.gmk), - # but JTREG does not pass this env variable when executing a shell script. - # - # execute test program - rely on it to exit if platform unsupported - - ;; - * ) - echo "Unsupported System: ${OS}" - exit 0; - ;; -esac - -echo "===================================================" -echo "Try to set ALT_JAVA_RE_JDK if you see timeout error" -echo "===================================================" - -# the test code - -${COMPILEJAVA}${FS}bin${FS}javac -target 1.4 -source 1.4 \ - -d . ${TESTSRC}${FS}SerialTest.java || exit 10 - -# You can set ALT_JAVA_RE_JDK to another location that contains the -# binaries for older JDK releases. You can set it to a non-existent -# directory to skip the interop tests between different versions. - -if [ "$ALT_JAVA_RE_JDK" = "" ]; then - JAVA_RE_JDK=/java/re/j2se -else - JAVA_RE_JDK=$ALT_JAVA_RE_JDK -fi - -OLDJAVA=" - $JAVA_RE_JDK/1.6.0/latest/binaries/${PF} - $JAVA_RE_JDK/1.5.0/latest/binaries/${PF} - $JAVA_RE_JDK/1.4.2/latest/binaries/${PF} -" - -SMALL=" - 0.0 - 1.1 - 2.2 - 1.2.3456 - 1.2.2147483647.4 - 1.2.268435456.4 -" - -HUGE=" - 2.16.764.1.3101555394.1.0.100.2.1 - 1.2.2147483648.4 - 2.3.4444444444444444444444 - 1.2.888888888888888888.111111111111111.2222222222222.33333333333333333.44444444444444 -" - -for oid in ${SMALL}; do - echo ${oid} - # new -> - ${TESTJAVA}${FS}bin${FS}java SerialTest out ${oid} > tmp.oid.serial || exit 1 - # -> new - ${TESTJAVA}${FS}bin${FS}java SerialTest in ${oid} < tmp.oid.serial || exit 2 - for oldj in ${OLDJAVA}; do - if [ -d ${oldj} ]; then - echo ${oldj} - # -> old - ${oldj}${FS}bin${FS}java SerialTest in ${oid} < tmp.oid.serial || exit 3 - # old -> - ${oldj}${FS}bin${FS}java SerialTest out ${oid} > tmp.oid.serial.old || exit 4 - # -> new - ${TESTJAVA}${FS}bin${FS}java SerialTest in ${oid} < tmp.oid.serial.old || exit 5 - fi - done -done - -for oid in ${HUGE}; do - echo ${oid} - # new -> - ${TESTJAVA}${FS}bin${FS}java SerialTest out ${oid} > tmp.oid.serial || exit 1 - # -> new - ${TESTJAVA}${FS}bin${FS}java SerialTest in ${oid} < tmp.oid.serial || exit 2 - for oldj in ${OLDJAVA}; do - if [ -d ${oldj} ]; then - echo ${oldj} - # -> old - ${oldj}${FS}bin${FS}java SerialTest badin < tmp.oid.serial || exit 3 - fi - done -done - -rm -f tmp.oid.serial -rm -f tmp.oid.serial.old -rm -f SerialTest.class - -for oldj in ${OLDJAVA}; do - if [ ! -d ${oldj} ]; then - echo WARNING: ${oldj} is missing. Test incomplete! > /dev/stderr - fi -done - -exit 0 diff --git a/jdk/test/sun/security/util/Oid/SerialTest.java b/jdk/test/sun/security/util/Oid/SerialTest.java deleted file mode 100644 index ba127441cad..00000000000 --- a/jdk/test/sun/security/util/Oid/SerialTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2004, 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. - */ - -/* - * read S11.sh - */ -import java.io.*; -import sun.security.util.*; - -/** - * Test OID serialization between versions - * - * java SerialTest out oid // write a OID into System.out - * java SerialTest in oid // read from System.in and compare it with oid - * java SerialTest badin // make sure *cannot* read from System.in - */ -class SerialTest { - public static void main(String[] args) throws Exception { - if (args[0].equals("out")) - out(args[1]); - else if (args[0].equals("in")) - in(args[1]); - else - badin(); - } - - static void in(String oid) throws Exception { - ObjectIdentifier o = (ObjectIdentifier) (new ObjectInputStream(System.in).readObject()); - if (!o.toString().equals(oid)) - throw new Exception("Read Fail " + o + ", not " + oid); - } - - static void badin() throws Exception { - boolean pass = true; - try { - new ObjectInputStream(System.in).readObject(); - } catch (Exception e) { - pass = false; - } - if (pass) throw new Exception("Should fail but not"); - } - - static void out(String oid) throws Exception { - new ObjectOutputStream(System.out).writeObject(new ObjectIdentifier(oid)); - } -} From d0830009e80631e78a3a776954143194bab97530 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Fri, 1 Feb 2013 06:51:37 +0000 Subject: [PATCH 193/204] 8006395: Race in async socket close on Linux Reviewed-by: alanb, dsamersoff --- jdk/src/solaris/native/java/net/linux_close.c | 21 +++-- jdk/test/java/net/Socket/asyncClose/Race.java | 77 +++++++++++++++++++ 2 files changed, 87 insertions(+), 11 deletions(-) create mode 100644 jdk/test/java/net/Socket/asyncClose/Race.java diff --git a/jdk/src/solaris/native/java/net/linux_close.c b/jdk/src/solaris/native/java/net/linux_close.c index 5665e85e09c..51f9cb2ee70 100644 --- a/jdk/src/solaris/native/java/net/linux_close.c +++ b/jdk/src/solaris/native/java/net/linux_close.c @@ -191,17 +191,6 @@ static int closefd(int fd1, int fd2) { pthread_mutex_lock(&(fdEntry->lock)); { - /* - * Send a wakeup signal to all threads blocked on this - * file descriptor. - */ - threadEntry_t *curr = fdEntry->threads; - while (curr != NULL) { - curr->intr = 1; - pthread_kill( curr->thr, sigWakeup ); - curr = curr->next; - } - /* * And close/dup the file descriptor * (restart if interrupted by signal) @@ -214,6 +203,16 @@ static int closefd(int fd1, int fd2) { } } while (rv == -1 && errno == EINTR); + /* + * Send a wakeup signal to all threads blocked on this + * file descriptor. + */ + threadEntry_t *curr = fdEntry->threads; + while (curr != NULL) { + curr->intr = 1; + pthread_kill( curr->thr, sigWakeup ); + curr = curr->next; + } } /* diff --git a/jdk/test/java/net/Socket/asyncClose/Race.java b/jdk/test/java/net/Socket/asyncClose/Race.java new file mode 100644 index 00000000000..f8869394b3d --- /dev/null +++ b/jdk/test/java/net/Socket/asyncClose/Race.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013, 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. + */ + +/* + * @test + * @bug 8006395 + * @summary Race in async socket close on Linux + */ + +import java.io.InputStream; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketException; +import java.util.concurrent.Phaser; + +// Racey test, will not always fail, but if it does then we have a problem. + +public class Race { + final static int THREADS = 100; + + public static void main(String[] args) throws Exception { + try (ServerSocket ss = new ServerSocket(0)) { + final int port = ss.getLocalPort(); + final Phaser phaser = new Phaser(THREADS + 1); + for (int i=0; i<100; i++) { + final Socket s = new Socket("localhost", port); + s.setSoLinger(false, 0); + try (Socket sa = ss.accept()) { + sa.setSoLinger(false, 0); + final InputStream is = s.getInputStream(); + Thread[] threads = new Thread[THREADS]; + for (int j=0; j Date: Fri, 1 Feb 2013 07:25:51 -0800 Subject: [PATCH 194/204] 8006536: [launcher] removes trailing slashes on arguments Reviewed-by: ksrini, akhil --- jdk/src/windows/bin/cmdtoargs.c | 13 ++++++++++++- jdk/test/tools/launcher/Arrrghs.java | 3 ++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/jdk/src/windows/bin/cmdtoargs.c b/jdk/src/windows/bin/cmdtoargs.c index 4e92d18708c..669f3683bfe 100644 --- a/jdk/src/windows/bin/cmdtoargs.c +++ b/jdk/src/windows/bin/cmdtoargs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, 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 @@ -104,6 +104,11 @@ static char* next_arg(char* cmdline, char* arg, jboolean* wildcard) { case ' ': case '\t': + if (prev == '\\') { + for (i = 0 ; i < slashes; i++) { + *dest++ = prev; + } + } if (quotes % 2 == 1) { *dest++ = ch; } else { @@ -591,6 +596,12 @@ int main(int argc, char* argv[]) { // v->disable(); vectors[i++] = v; + v= new Vector(argv[0], "a b\\\\ d"); + v->add("a", FALSE); + v->add("b\\\\", FALSE); + v->add("d", FALSE); + vectors[i++] = v; + dotest(vectors); printf("All tests pass [%d]\n", i); doexit(0); diff --git a/jdk/test/tools/launcher/Arrrghs.java b/jdk/test/tools/launcher/Arrrghs.java index 9bf9f21b465..cf0dfbf7410 100644 --- a/jdk/test/tools/launcher/Arrrghs.java +++ b/jdk/test/tools/launcher/Arrrghs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2013, 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 @@ -309,6 +309,7 @@ public class Arrrghs extends TestHelper { checkArgumentParsing("../../*", "../../*"); checkArgumentParsing("..\\..\\", "..\\..\\"); checkArgumentParsing("../../", "../../"); + checkArgumentParsing("a b\\ c", "a", "b\\", "c"); } private void initEmptyDir(File emptyDir) throws IOException { From 854e269f2070cb04422933225eff9841837a553e Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Fri, 1 Feb 2013 21:01:44 +0000 Subject: [PATCH 195/204] 5035569: Formatter should document that %a conversion unsupported for BigDecimal args Reviewed-by: darcy --- jdk/src/share/classes/java/util/Formatter.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/util/Formatter.java b/jdk/src/share/classes/java/util/Formatter.java index f5f479588c1..03a58004918 100644 --- a/jdk/src/share/classes/java/util/Formatter.java +++ b/jdk/src/share/classes/java/util/Formatter.java @@ -351,7 +351,9 @@ import sun.misc.FormattedFloatingDecimal; * {@code 'a'}, {@code 'A'} * floating point * The result is formatted as a hexadecimal floating-point number with - * a significand and an exponent + * a significand and an exponent. This conversion is not supported + * for the {@code BigDecimal} type despite the latter's being in the + * floating point argument category. * * {@code 't'}, {@code 'T'} * date/time From 0050c5b4fbec24b46fb46c5d070a98a4e86c2174 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Fri, 1 Feb 2013 19:30:02 -0800 Subject: [PATCH 196/204] 6964528: Double.toHexString(double d) String manipulation with + in an append of StringBuilder Reviewed-by: shade --- jdk/src/share/classes/java/lang/Double.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/jdk/src/share/classes/java/lang/Double.java b/jdk/src/share/classes/java/lang/Double.java index f79980f4bb8..9bdb0ca4679 100644 --- a/jdk/src/share/classes/java/lang/Double.java +++ b/jdk/src/share/classes/java/lang/Double.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2013, 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 @@ -289,7 +289,7 @@ public final class Double extends Number implements Comparable { return Double.toString(d); else { // Initialized to maximum size of output. - StringBuffer answer = new StringBuffer(24); + StringBuilder answer = new StringBuilder(24); if (Math.copySign(1.0, d) == -1.0) // value is negative, answer.append("-"); // so append sign info @@ -300,8 +300,7 @@ public final class Double extends Number implements Comparable { if(d == 0.0) { answer.append("0.0p0"); - } - else { + } else { boolean subnormal = (d < DoubleConsts.MIN_NORMAL); // Isolate significand bits and OR in a high-order bit @@ -324,13 +323,14 @@ public final class Double extends Number implements Comparable { "0": signif.replaceFirst("0{1,12}$", "")); + answer.append('p'); // If the value is subnormal, use the E_min exponent // value for double; otherwise, extract and report d's // exponent (the representation of a subnormal uses // E_min -1). - answer.append("p" + (subnormal ? - DoubleConsts.MIN_EXPONENT: - Math.getExponent(d) )); + answer.append(subnormal ? + DoubleConsts.MIN_EXPONENT: + Math.getExponent(d)); } return answer.toString(); } From 81a6d7fb0112e56b07f00075f5602eac0595140e Mon Sep 17 00:00:00 2001 From: Kumar Srinivasan Date: Fri, 1 Feb 2013 22:12:52 -0800 Subject: [PATCH 197/204] 8003549: (pack200) assertion errors when processing lambda class files with IMethods Add more check for opcode, sketch provided by jrose Reviewed-by: jrose --- .../com/sun/java/util/jar/pack/Attribute.java | 23 +++-- .../sun/java/util/jar/pack/ClassReader.java | 53 +++++++--- .../sun/java/util/jar/pack/ConstantPool.java | 30 +++++- .../sun/java/util/jar/pack/Instruction.java | 14 ++- .../sun/java/util/jar/pack/PackageWriter.java | 10 ++ .../sun/java/util/jar/pack/PackerImpl.java | 14 ++- .../com/sun/java/util/jar/pack/PropMap.java | 7 +- .../com/sun/java/util/jar/pack/Utils.java | 8 +- jdk/test/ProblemList.txt | 3 - jdk/test/tools/pack200/InstructionTests.java | 99 +++++++++++++++++++ .../src/xmlkit/ClassReader.java | 17 ++++ 11 files changed, 241 insertions(+), 37 deletions(-) create mode 100644 jdk/test/tools/pack200/InstructionTests.java diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java index 9e891fc7c87..f6ff030263e 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Attribute.java @@ -1287,19 +1287,24 @@ class Attribute implements Comparable { if (localRef == 0) { globalRef = null; // N.B. global null reference is -1 } else { - globalRef = holder.getCPMap()[localRef]; - if (e.refKind == CONSTANT_Signature + Entry[] cpMap = holder.getCPMap(); + globalRef = (localRef >= 0 && localRef < cpMap.length + ? cpMap[localRef] + : null); + byte tag = e.refKind; + if (globalRef != null && tag == CONSTANT_Signature && globalRef.getTag() == CONSTANT_Utf8) { // Cf. ClassReader.readSignatureRef. String typeName = globalRef.stringValue(); globalRef = ConstantPool.getSignatureEntry(typeName); - } else if (e.refKind == CONSTANT_FieldSpecific) { - assert(globalRef.getTag() >= CONSTANT_Integer); - assert(globalRef.getTag() <= CONSTANT_String || - globalRef.getTag() >= CONSTANT_MethodHandle); - assert(globalRef.getTag() <= CONSTANT_MethodType); - } else if (e.refKind < CONSTANT_GroupFirst) { - assert(e.refKind == globalRef.getTag()); + } + String got = (globalRef == null + ? "invalid CP index" + : "type=" + ConstantPool.tagName(globalRef.tag)); + if (globalRef == null || !globalRef.tagMatches(tag)) { + throw new IllegalArgumentException( + "Bad constant, expected type=" + + ConstantPool.tagName(tag) + " got " + got); } } out.putRef(bandIndex, globalRef); diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java index 2ca2d0926c6..3df8706da37 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -54,6 +54,7 @@ class ClassReader { Package pkg; Class cls; long inPos; + long constantPoolLimit = -1; DataInputStream in; Map attrDefs; Map attrCommands; @@ -117,15 +118,33 @@ class ClassReader { private Entry readRef(byte tag) throws IOException { Entry e = readRef(); - assert(e != null); assert(!(e instanceof UnresolvedEntry)); - assert(e.tagMatches(tag)); + checkTag(e, tag); return e; } + /** Throw a ClassFormatException if the entry does not match the expected tag type. */ + private Entry checkTag(Entry e, byte tag) throws ClassFormatException { + if (e == null || !e.tagMatches(tag)) { + String where = (inPos == constantPoolLimit + ? " in constant pool" + : " at pos: " + inPos); + String got = (e == null + ? "null CP index" + : "type=" + ConstantPool.tagName(e.tag)); + throw new ClassFormatException("Bad constant, expected type=" + + ConstantPool.tagName(tag) + + " got "+ got + ", in File: " + cls.file.nameString + where); + } + return e; + } + private Entry checkTag(Entry e, byte tag, boolean nullOK) throws ClassFormatException { + return nullOK && e == null ? null : checkTag(e, tag); + } + private Entry readRefOrNull(byte tag) throws IOException { Entry e = readRef(); - assert(e == null || e.tagMatches(tag)); + checkTag(e, tag, true); return e; } @@ -143,8 +162,10 @@ class ClassReader { private SignatureEntry readSignatureRef() throws IOException { // The class file stores a Utf8, but we want a Signature. - Entry e = readRef(CONSTANT_Utf8); - return ConstantPool.getSignatureEntry(e.stringValue()); + Entry e = readRef(CONSTANT_Signature); + return (e != null && e.getTag() == CONSTANT_Utf8) + ? ConstantPool.getSignatureEntry(e.stringValue()) + : (SignatureEntry) e; } void read() throws IOException { @@ -279,6 +300,7 @@ class ClassReader { " at pos: " + inPos); } } + constantPoolLimit = inPos; // Fix up refs, which might be out of order. while (fptr > 0) { @@ -311,25 +333,25 @@ class ClassReader { case CONSTANT_Fieldref: case CONSTANT_Methodref: case CONSTANT_InterfaceMethodref: - ClassEntry mclass = (ClassEntry) cpMap[ref]; - DescriptorEntry mdescr = (DescriptorEntry) cpMap[ref2]; + ClassEntry mclass = (ClassEntry) checkTag(cpMap[ref], CONSTANT_Class); + DescriptorEntry mdescr = (DescriptorEntry) checkTag(cpMap[ref2], CONSTANT_NameandType); cpMap[cpi] = ConstantPool.getMemberEntry((byte)tag, mclass, mdescr); break; case CONSTANT_NameandType: - Utf8Entry mname = (Utf8Entry) cpMap[ref]; - Utf8Entry mtype = (Utf8Entry) cpMap[ref2]; + Utf8Entry mname = (Utf8Entry) checkTag(cpMap[ref], CONSTANT_Utf8); + Utf8Entry mtype = (Utf8Entry) checkTag(cpMap[ref2], CONSTANT_Signature); cpMap[cpi] = ConstantPool.getDescriptorEntry(mname, mtype); break; case CONSTANT_MethodType: - cpMap[cpi] = ConstantPool.getMethodTypeEntry((Utf8Entry) cpMap[ref]); + cpMap[cpi] = ConstantPool.getMethodTypeEntry((Utf8Entry) checkTag(cpMap[ref], CONSTANT_Signature)); break; case CONSTANT_MethodHandle: byte refKind = (byte)(-1 ^ ref); - MemberEntry memRef = (MemberEntry) cpMap[ref2]; + MemberEntry memRef = (MemberEntry) checkTag(cpMap[ref2], CONSTANT_AnyMember); cpMap[cpi] = ConstantPool.getMethodHandleEntry(refKind, memRef); break; case CONSTANT_InvokeDynamic: - DescriptorEntry idescr = (DescriptorEntry) cpMap[ref2]; + DescriptorEntry idescr = (DescriptorEntry) checkTag(cpMap[ref2], CONSTANT_NameandType); cpMap[cpi] = new UnresolvedEntry((byte)tag, (-1 ^ ref), idescr); // Note that ref must be resolved later, using the BootstrapMethods attribute. break; @@ -541,7 +563,8 @@ class ClassReader { code.max_locals = readUnsignedShort(); code.bytes = new byte[readInt()]; in.readFully(code.bytes); - Instruction.opcodeChecker(code.bytes); + Entry[] cpMap = cls.getCPMap(); + Instruction.opcodeChecker(code.bytes, cpMap); int nh = readUnsignedShort(); code.setHandlerCount(nh); for (int i = 0; i < nh; i++) { @@ -559,7 +582,7 @@ class ClassReader { MethodHandleEntry bsmRef = (MethodHandleEntry) readRef(CONSTANT_MethodHandle); Entry[] argRefs = new Entry[readUnsignedShort()]; for (int j = 0; j < argRefs.length; j++) { - argRefs[j] = readRef(); + argRefs[j] = readRef(CONSTANT_LoadableValue); } bsms[i] = ConstantPool.getBootstrapMethodEntry(bsmRef, argRefs); } diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java index be4da54d247..ad2175f9993 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -243,8 +243,32 @@ class ConstantPool { return tag == CONSTANT_Double || tag == CONSTANT_Long; } - public final boolean tagMatches(int tag) { - return (this.tag == tag); + public final boolean tagMatches(int matchTag) { + if (tag == matchTag) + return true; + byte[] allowedTags; + switch (matchTag) { + case CONSTANT_All: + return true; + case CONSTANT_Signature: + return tag == CONSTANT_Utf8; // format check also? + case CONSTANT_LoadableValue: + allowedTags = LOADABLE_VALUE_TAGS; + break; + case CONSTANT_AnyMember: + allowedTags = ANY_MEMBER_TAGS; + break; + case CONSTANT_FieldSpecific: + allowedTags = FIELD_SPECIFIC_TAGS; + break; + default: + return false; + } + for (byte b : allowedTags) { + if (b == tag) + return true; + } + return false; } public String toString() { diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/Instruction.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/Instruction.java index f488bede323..31ee22b059d 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Instruction.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Instruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, 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 @@ -647,7 +647,7 @@ class Instruction { } } - public static void opcodeChecker(byte[] code) throws FormatException { + public static void opcodeChecker(byte[] code, ConstantPool.Entry[] cpMap) throws FormatException { Instruction i = at(code, 0); while (i != null) { int opcode = i.getBC(); @@ -655,6 +655,16 @@ class Instruction { String message = "illegal opcode: " + opcode + " " + i; throw new FormatException(message); } + ConstantPool.Entry e = i.getCPRef(cpMap); + if (e != null) { + byte tag = i.getCPTag(); + if (!e.tagMatches(tag)) { + String message = "illegal reference, expected type=" + + ConstantPool.tagName(tag) + ": " + + i.toString(cpMap); + throw new FormatException(message); + } + } i = i.next(); } } diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageWriter.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageWriter.java index e6990451135..47959294fd2 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageWriter.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackageWriter.java @@ -1618,6 +1618,16 @@ class PackageWriter extends BandStructure { bc_which = null; assert(false); } + if (ref != null && bc_which.index != null && !bc_which.index.contains(ref)) { + // Crash and burn with a complaint if there are funny + // references for this bytecode instruction. + // Example: invokestatic of a CONSTANT_InterfaceMethodref. + String complaint = code.getMethod() + + " contains a bytecode " + i + + " with an unsupported constant reference; please use the pass-file option on this class."; + Utils.log.warning(complaint); + throw new IOException(complaint); + } bc_codes.putByte(vbc); bc_which.putRef(ref); // handle trailing junk diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java index c7ef4ee2013..0dc88a108c7 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -180,6 +180,15 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer { } unknownAttrCommand = uaMode.intern(); } + final String classFormatCommand; + { + String fmtMode = props.getProperty(Utils.CLASS_FORMAT_ERROR, Pack200.Packer.PASS); + if (!(Pack200.Packer.PASS.equals(fmtMode) || + Pack200.Packer.ERROR.equals(fmtMode))) { + throw new RuntimeException("Bad option: " + Utils.CLASS_FORMAT_ERROR + " = " + fmtMode); + } + classFormatCommand = fmtMode.intern(); + } final Map attrDefs; final Map attrCommands; @@ -505,8 +514,7 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer { } } else if (ioe instanceof ClassReader.ClassFormatException) { ClassReader.ClassFormatException ce = (ClassReader.ClassFormatException) ioe; - // %% TODO: Do we invent a new property for this or reuse %% - if (unknownAttrCommand.equals(Pack200.Packer.PASS)) { + if (classFormatCommand.equals(Pack200.Packer.PASS)) { Utils.log.info(ce.toString()); Utils.log.warning(message + " unknown class format: " + fname); diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/PropMap.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/PropMap.java index 6199c77b51d..24485040378 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PropMap.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PropMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -112,6 +112,11 @@ final class PropMap implements SortedMap { // Pass through files with unrecognized attributes by default. props.put(Pack200.Packer.UNKNOWN_ATTRIBUTE, Pack200.Packer.PASS); + // Pass through files with unrecognized format by default, also + // allow system property to be set + props.put(Utils.CLASS_FORMAT_ERROR, + System.getProperty(Utils.CLASS_FORMAT_ERROR, Pack200.Packer.PASS)); + // Default effort is 5, midway between 1 and 9. props.put(Pack200.Packer.EFFORT, "5"); diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/Utils.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/Utils.java index 5edd73e21cb..ebe0960dba0 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Utils.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Utils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, 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 @@ -122,6 +122,12 @@ class Utils { */ static final String PACK_ZIP_ARCHIVE_MARKER_COMMENT = "PACK200"; + /* + * behaviour when we hit a class format error, but not necessarily + * an unknown attribute, by default it is allowed to PASS. + */ + static final String CLASS_FORMAT_ERROR = COM_PREFIX+"class.format.error"; + // Keep a TLS point to the global data and environment. // This makes it simpler to supply environmental options // to the engine code, especially the native code. diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 5e181ac7e03..7b763477192 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -321,9 +321,6 @@ sun/jvmstat/monitor/MonitoredVm/CR6672135.java generic-all tools/pack200/CommandLineTests.java generic-all tools/pack200/Pack200Test.java generic-all -# 8001163 -tools/pack200/AttributeTests.java generic-all - # 7150569 tools/launcher/UnicodeTest.java macosx-all diff --git a/jdk/test/tools/pack200/InstructionTests.java b/jdk/test/tools/pack200/InstructionTests.java new file mode 100644 index 00000000000..ce92c0ed558 --- /dev/null +++ b/jdk/test/tools/pack200/InstructionTests.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2013, 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. + */ +import java.io.File; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; +import static java.nio.file.StandardOpenOption.*; +import java.util.regex.Pattern; + +/* + * @test + * @bug 8003549 + * @summary tests class files instruction formats introduced in JSR-335 + * @compile -XDignore.symbol.file Utils.java InstructionTests.java + * @run main InstructionTests + * @author ksrini + */ +public class InstructionTests { + public static void main(String... args) throws Exception { + testInvokeOpCodes(); + } + /* + * the following should produce invokestatic and invokespecial + * on InterfaceMethodRefs vs. MethodRefs, packer/unpacker should work + */ + static void testInvokeOpCodes() throws Exception { + List scratch = new ArrayList<>(); + final String fname = "A"; + String javaFileName = fname + Utils.JAVA_FILE_EXT; + scratch.add("interface IntIterator {"); + scratch.add(" default void forEach(){}"); + scratch.add(" static void next() {}"); + scratch.add("}"); + scratch.add("class A implements IntIterator {"); + scratch.add("public void forEach(Object o){"); + scratch.add("IntIterator.super.forEach();"); + scratch.add("IntIterator.next();"); + scratch.add("}"); + scratch.add("}"); + File cwd = new File("."); + File javaFile = new File(cwd, javaFileName); + Files.write(javaFile.toPath(), scratch, Charset.defaultCharset(), + CREATE, TRUNCATE_EXISTING); + + // make sure we have -g so that we compare LVT and LNT entries + Utils.compiler("-g", javaFile.getName()); + + // jar the file up + File testjarFile = new File(cwd, "test" + Utils.JAR_FILE_EXT); + Utils.jar("cvf", testjarFile.getName(), "."); + + // pack using --repack + File outjarFile = new File(cwd, "out" + Utils.JAR_FILE_EXT); + scratch.clear(); + scratch.add(Utils.getPack200Cmd()); + scratch.add("-J-ea"); + scratch.add("-J-esa"); + scratch.add("--repack"); + scratch.add(outjarFile.getName()); + scratch.add(testjarFile.getName()); + List output = Utils.runExec(scratch); + // TODO remove this when we get bc escapes working correctly + // this test anyhow would fail at that time + findString("WARNING: Passing.*" + fname + Utils.CLASS_FILE_EXT, + output); + + Utils.doCompareVerify(testjarFile, outjarFile); + } + + static boolean findString(String str, List list) { + Pattern p = Pattern.compile(str); + for (String x : list) { + if (p.matcher(x).matches()) + return true; + } + throw new RuntimeException("Error: " + str + " not found in output"); + } +} diff --git a/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassReader.java b/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassReader.java index 177849872a9..db7d0465777 100644 --- a/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassReader.java +++ b/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassReader.java @@ -57,8 +57,10 @@ import com.sun.tools.classfile.MethodParameters_attribute; import com.sun.tools.classfile.Opcode; import com.sun.tools.classfile.RuntimeInvisibleAnnotations_attribute; import com.sun.tools.classfile.RuntimeInvisibleParameterAnnotations_attribute; +import com.sun.tools.classfile.RuntimeInvisibleTypeAnnotations_attribute; import com.sun.tools.classfile.RuntimeVisibleAnnotations_attribute; import com.sun.tools.classfile.RuntimeVisibleParameterAnnotations_attribute; +import com.sun.tools.classfile.RuntimeVisibleTypeAnnotations_attribute; import com.sun.tools.classfile.Signature_attribute; import com.sun.tools.classfile.SourceDebugExtension_attribute; import com.sun.tools.classfile.SourceFile_attribute; @@ -1214,6 +1216,21 @@ class AttributeVisitor implements Attribute.Visitor { p.add(e); return null; } + + /* + * TODO + * add these two for now to keep the compiler happy, we will implement + * these along with the JSR-308 changes. + */ + @Override + public Element visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute rvta, Element p) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Element visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute rita, Element p) { + throw new UnsupportedOperationException("Not supported yet."); + } } class StackMapVisitor implements StackMapTable_attribute.stack_map_frame.Visitor { From 8da1d4a40c9b4827e2fdb3cbe7488c5cb991c9ae Mon Sep 17 00:00:00 2001 From: Kumar Srinivasan Date: Fri, 1 Feb 2013 22:18:18 -0800 Subject: [PATCH 198/204] 8007428: [launcher] add tools/launcher/FXLauncherTest.java to ProblemList.txt Reviewed-by: mchung --- jdk/test/ProblemList.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 7b763477192..1870b0b9219 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -324,6 +324,9 @@ tools/pack200/Pack200Test.java generic-all # 7150569 tools/launcher/UnicodeTest.java macosx-all +# 8007410 +tools/launcher/FXLauncherTest.java linux-all + ############################################################################ # jdk_jdi From b61bb15030d4c205949f3663bc6d60e41bce3c6c Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Sat, 2 Feb 2013 17:15:13 +0000 Subject: [PATCH 199/204] 8007322: untangle ftp protocol from general networking URL tests Reviewed-by: alanb --- jdk/test/java/net/URL/Constructor.java | 260 ++++++++++++++---- jdk/test/java/net/URL/HandlerLoop.java | 2 +- jdk/test/java/net/URL/Test.java | 19 +- jdk/test/java/net/URL/URIToURLTest.java | 31 ++- jdk/test/java/net/URL/abnormal_http_urls | 43 --- jdk/test/java/net/URL/ftp_urls | 27 -- jdk/test/java/net/URL/jar_urls | 75 ----- jdk/test/java/net/URL/normal_http_urls | 83 ------ jdk/test/java/net/URL/runconstructor.sh | 67 ----- jdk/test/java/net/URL/share_file_urls | 51 ---- jdk/test/java/net/URL/win32_file_urls | 15 - .../net/URLConnection/RequestProperties.java | 129 ++++----- .../URLConnection/RequestPropertyValues.java | 30 +- jdk/test/sun/net/{www => ftp}/EncDec.doc | Bin .../sun/net/{www => ftp}/MarkResetTest.java | 0 .../sun/net/{www => ftp}/MarkResetTest.sh | 0 .../net/www/http/HttpClient/ProxyTest.java | 12 +- 17 files changed, 327 insertions(+), 517 deletions(-) delete mode 100644 jdk/test/java/net/URL/abnormal_http_urls delete mode 100644 jdk/test/java/net/URL/ftp_urls delete mode 100644 jdk/test/java/net/URL/jar_urls delete mode 100644 jdk/test/java/net/URL/normal_http_urls delete mode 100644 jdk/test/java/net/URL/runconstructor.sh delete mode 100644 jdk/test/java/net/URL/share_file_urls delete mode 100644 jdk/test/java/net/URL/win32_file_urls rename jdk/test/sun/net/{www => ftp}/EncDec.doc (100%) rename jdk/test/sun/net/{www => ftp}/MarkResetTest.java (100%) rename jdk/test/sun/net/{www => ftp}/MarkResetTest.sh (100%) diff --git a/jdk/test/java/net/URL/Constructor.java b/jdk/test/java/net/URL/Constructor.java index 2930db2fa4c..13eae40d6d4 100644 --- a/jdk/test/java/net/URL/Constructor.java +++ b/jdk/test/java/net/URL/Constructor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, 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 @@ -21,71 +21,235 @@ * questions. */ -/* This is no longer run directly. See runconstructor.sh - * - * - * +/* + * @test + * @bug 4393671 + * @summary URL constructor URL(URL context, String spec) FAILED with specific input + */ + +/* * This program tests the URL parser in the URL constructor. It * tries to construct a variety of valid URLs with a given context * (which may be null) and a variety of specs. It then compares the * result with an expected value. - * - * It expects that a data file named "urls" be available in the - * current directory, from which it will get its testing data. The - * format of the file is: - * - * URL: null - * spec: jar:http://www.foo.com/dir1/jar.jar!/ - * expected: jar:http://www.foo.com/dir1/jar.jar!/ - * - * where URL is the context, spec is the spec and expected is the - * expected result. The first : must be followed by a space. Each test - * entry should be followed by a blank line. */ -import java.io.*; +import java.net.MalformedURLException; import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; public class Constructor { public static void main(String[] args) throws Exception { - URL url = null; - String urls = "jar_urls"; - if (args.length > 0 && args[0] != null) { - urls = args[0]; - } + List entries = new ArrayList<>(); + entries.addAll(Arrays.asList(fileURLs)); + entries.addAll(Arrays.asList(jarURLs)); + entries.addAll(Arrays.asList(normalHttpURLs)); + entries.addAll(Arrays.asList(abnormalHttpURLs)); + if (hasFtp()) + entries.addAll(Arrays.asList(ftpURLs)); + URL url; - File f = new File(urls); - InputStream file = new FileInputStream(f); - BufferedReader in = new BufferedReader(new InputStreamReader(file)); - while(true) { - String context = in.readLine(); - if (context == null) { - break; - } - context = getValue(context); - String spec = getValue(in.readLine()); - String expected = getValue(in.readLine()); + for (Entry e : entries) { + if (e.context == null) + url = new URL(e.spec); + else + url = new URL(new URL(e.context), e.spec); - if (context.equals("null")) { - url = new URL(spec); - } else { - url = new URL(new URL(context), spec); - } - if (!(url.toString().equals(expected))) { - throw new RuntimeException("error for: \n\tURL:" + context + - "\n\tspec: " + spec + - "\n\texpected: " + expected + + if (!(url.toString().equals(e.expected))) { + throw new RuntimeException("error for: \n\tURL:" + e.context + + "\n\tspec: " + e.spec + + "\n\texpected: " + e.expected + "\n\tactual: " + url.toString()); } else { - System.out.println("success for: " + url + "\n"); + //debug + //System.out.println("success for: " + url); } - in.readLine(); } - in.close(); } - private static String getValue(String value) { - return value.substring(value.indexOf(':') + 2); + private static boolean hasFtp() { + try { + return new java.net.URL("ftp://") != null; + } catch (java.net.MalformedURLException x) { + System.out.println("FTP not supported by this runtime."); + return false; + } } + + static class Entry { + final String context; + final String spec; + final String expected; + Entry(String context, String spec, String expected) { + this.context = context; + this.spec =spec; + this.expected = expected; + } + } + + static Entry[] fileURLs = new Entry[] { + new Entry(null, + "file://JavaSoft/Test", + "file://JavaSoft/Test"), + new Entry(null, + "file:///JavaSoft/Test", + "file:/JavaSoft/Test"), + new Entry(null, + "file:/JavaSoft/Test", + "file:/JavaSoft/Test"), + new Entry(null, + "file:/c:/JavaSoft/Test", + "file:/c:/JavaSoft/Test"), + new Entry(null, + "file:/c:/JavaSoft/Test:something", + "file:/c:/JavaSoft/Test:something"), + new Entry(null, + "file:/c:/JavaSoft/Test#anchor", + "file:/c:/JavaSoft/Test#anchor"), + new Entry("file://JavaSoft/Test", + "Test#bar", + "file://JavaSoft/Test#bar"), + new Entry("file://codrus/c:/jdk/eng/index.html", + "pulsar.html", + "file://codrus/c:/jdk/eng/pulsar.html"), + new Entry("file:///c:/jdk/eng/index.html", + "pulsar.html", + "file:/c:/jdk/eng/pulsar.html"), + new Entry("file:///jdk/eng/index.html", + "pulsar.html", + "file:/jdk/eng/pulsar.html"), + new Entry("file://JavaSoft/Test", + "file://radartoad.com/Test#bar", + "file://radartoad.com/Test#bar"), + new Entry("file://JavaSoft/Test", + "/c:/Test#bar", + "file://JavaSoft/c:/Test#bar"), + }; + + static Entry[] jarURLs = new Entry[] { + new Entry(null, + "jar:http://www.foo.com/dir1/jar.jar!/dir2/entry.txt", + "jar:http://www.foo.com/dir1/jar.jar!/dir2/entry.txt"), + new Entry(null, + "jar:http://www.foo.com/dir1/jar.jar!/", + "jar:http://www.foo.com/dir1/jar.jar!/"), + new Entry(null, + "jar:http://www.foo.com/dir1/jar.jar!/", + "jar:http://www.foo.com/dir1/jar.jar!/"), + new Entry("jar:http://www.foo.com/dir1/jar.jar!/", + "entry.txt", + "jar:http://www.foo.com/dir1/jar.jar!/entry.txt"), + new Entry("jar:http://www.foo.com/dir1/jar.jar!/", + "/entry.txt", + "jar:http://www.foo.com/dir1/jar.jar!/entry.txt"), + new Entry("jar:http://www.foo.com/dir1/jar.jar!/", + "dir1/entry.txt", + "jar:http://www.foo.com/dir1/jar.jar!/dir1/entry.txt"), + new Entry("jar:http://www.foo.com/dir1/jar.jar!/", + "/dir1/entry.txt", + "jar:http://www.foo.com/dir1/jar.jar!/dir1/entry.txt"), + new Entry("jar:http://www.foo.com/dir1/jar.jar!/", + "entry.txt", + "jar:http://www.foo.com/dir1/jar.jar!/entry.txt"), + new Entry("jar:http://www.foo.com/dir1/jar.jar!/", + "/entry.txt", + "jar:http://www.foo.com/dir1/jar.jar!/entry.txt"), + new Entry("jar:http://www.foo.com/dir1/jar.jar!/", + "/entry.txt", + "jar:http://www.foo.com/dir1/jar.jar!/entry.txt"), + new Entry("jar:http://www.foo.com/dir1/jar.jar!/dir1/", + "entry.txt", + "jar:http://www.foo.com/dir1/jar.jar!/dir1/entry.txt"), + new Entry("jar:http://www.foo.com/dir1/jar.jar!/dir2/dir3/entry2.txt", + "/dir1/entry.txt", + "jar:http://www.foo.com/dir1/jar.jar!/dir1/entry.txt"), + new Entry("jar:http://www.foo.com/dir1/jar.jar!/", + "/dir1/foo/entry.txt", + "jar:http://www.foo.com/dir1/jar.jar!/dir1/foo/entry.txt"), + new Entry("jar:http://www.foo.com/dir1/jar.jar!/dir1/dir2/dir3/", + "dir4/foo/entry.txt", + "jar:http://www.foo.com/dir1/jar.jar!/dir1/dir2/dir3/dir4/foo/entry.txt"), + new Entry("jar:http://www.foo.com/dir1/jar.jar!/", + "/dir1/foo/entry.txt", + "jar:http://www.foo.com/dir1/jar.jar!/dir1/foo/entry.txt"), + new Entry(null, + "jar:http://www.foo.com/dir1/jar.jar!/foo.txt#anchor", + "jar:http://www.foo.com/dir1/jar.jar!/foo.txt#anchor"), + new Entry("jar:http://www.foo.com/dir1/jar.jar!/foo.txt", + "#anchor", + "jar:http://www.foo.com/dir1/jar.jar!/foo.txt#anchor"), + new Entry("jar:http://www.foo.com/dir1/jar.jar!/foo/bar/", + "baz/quux#anchor", + "jar:http://www.foo.com/dir1/jar.jar!/foo/bar/baz/quux#anchor"), + new Entry("jar:http://balloo.com/olle.jar!/", + "p2", + "jar:http://balloo.com/olle.jar!/p2") + }; + + static Entry[] normalHttpURLs = new Entry[] { + new Entry("http://a/b/c/d;p?q", "g", "http://a/b/c/g"), + new Entry("http://a/b/c/d;p?q", "./g", "http://a/b/c/g"), + new Entry("http://a/b/c/d;p?q", "g/", "http://a/b/c/g/"), + new Entry("http://a/b/c/d;p?q", "/g", "http://a/g"), + new Entry("http://a/b/c/d;p?q", "//g", "http://g"), + new Entry("http://a/b/c/d;p?q", "?y", "http://a/b/c/?y"), + new Entry("http://a/b/c/d;p?q", "g?y", "http://a/b/c/g?y"), + new Entry("http://a/b/c/d;p?q", "g#s", "http://a/b/c/g#s"), + new Entry("http://a/b/c/d;p?q", "g?y#s", "http://a/b/c/g?y#s"), + new Entry("http://a/b/c/d;p?q", ";x", "http://a/b/c/;x"), + new Entry("http://a/b/c/d;p?q", "g;x", "http://a/b/c/g;x"), + new Entry("http://a/b/c/d;p?q", "g;x?y#s", "http://a/b/c/g;x?y#s"), + new Entry("http://a/b/c/d;p?q", ".", "http://a/b/c/"), + new Entry("http://a/b/c/d;p?q", "./", "http://a/b/c/"), + new Entry("http://a/b/c/d;p?q", "..", "http://a/b/"), + new Entry("http://a/b/c/d;p?q", "../", "http://a/b/"), + new Entry("http://a/b/c/d;p?q", "../g", "http://a/b/g"), + new Entry("http://a/b/c/d;p?q", "../..", "http://a/"), + new Entry("http://a/b/c/d;p?q", "../../", "http://a/"), + new Entry("http://a/b/c/d;p?q", "../../g", "http://a/g"), + new Entry(null, + "http://www.javasoft.com/jdc/community/chat/index.html#javalive?frontpage-jdc", + "http://www.javasoft.com/jdc/community/chat/index.html#javalive?frontpage-jdc") + }; + + static Entry[] abnormalHttpURLs = new Entry[] { + new Entry("http://a/b/c/d;p?q", "../../../g", "http://a/../g"), + new Entry("http://a/b/c/d;p?q", "../../../../g", "http://a/../../g"), + new Entry("http://a/b/c/d;p?q", "/./g", "http://a/./g"), + new Entry("http://a/b/c/d;p?q", "/../g", "http://a/../g"), + new Entry("http://a/b/c/d;p?q", ".g", "http://a/b/c/.g"), + new Entry("http://a/b/c/d;p?q", "g.", "http://a/b/c/g."), + new Entry("http://a/b/c/d;p?q", "./../g", "http://a/b/g"), + new Entry("http://a/b/c/d;p?q", "./g/.", "http://a/b/c/g/"), + new Entry("http://a/b/c/d;p?q", "g/./h", "http://a/b/c/g/h"), + new Entry("http://a/b/c/d;p?q", "g;x=1/./y", "http://a/b/c/g;x=1/y"), + new Entry("http://a/b/c/d;p?q", "g;x=1/../y", "http://a/b/c/y") + }; + + static Entry[] ftpURLs = new Entry[] { + new Entry(null, + "ftp://ftp.foo.com/dir1/entry.txt", + "ftp://ftp.foo.com/dir1/entry.txt"), + new Entry(null, + "ftp://br:pwd@ftp.foo.com/dir1/jar.jar", + "ftp://br:pwd@ftp.foo.com/dir1/jar.jar"), + new Entry("ftp://ftp.foo.com/dir1/foo.txt", + "bar.txt", + "ftp://ftp.foo.com/dir1/bar.txt"), + new Entry("ftp://ftp.foo.com/dir1/jar.jar", + "/entry.txt", + "ftp://ftp.foo.com/entry.txt"), + new Entry("ftp://ftp.foo.com/dir1/jar.jar", + "dir1/entry.txt", + "ftp://ftp.foo.com/dir1/dir1/entry.txt"), + new Entry("ftp://ftp.foo.com/dir1/jar.jar", + "/dir1/entry.txt", + "ftp://ftp.foo.com/dir1/entry.txt"), + new Entry("ftp://br:pwd@ftp.foo.com/dir1/jar.jar", + "/dir1/entry.txt", + "ftp://br:pwd@ftp.foo.com/dir1/entry.txt") + }; } diff --git a/jdk/test/java/net/URL/HandlerLoop.java b/jdk/test/java/net/URL/HandlerLoop.java index 69ca4e523b5..df02891b038 100644 --- a/jdk/test/java/net/URL/HandlerLoop.java +++ b/jdk/test/java/net/URL/HandlerLoop.java @@ -36,7 +36,7 @@ public class HandlerLoop { public static void main(String args[]) throws Exception { URL.setURLStreamHandlerFactory( new HandlerFactory("sun.net.www.protocol")); - URL url = new URL("file://bogus/index.html"); + URL url = new URL("file:///bogus/index.html"); System.out.println("url = " + url); url.openConnection(); } diff --git a/jdk/test/java/net/URL/Test.java b/jdk/test/java/net/URL/Test.java index 4ea4bd7c634..1e44ffe8b03 100644 --- a/jdk/test/java/net/URL/Test.java +++ b/jdk/test/java/net/URL/Test.java @@ -310,7 +310,14 @@ public class Test { throw new RuntimeException("Test failed"); } - + private static boolean hasFtp() { + try { + return new java.net.URL("ftp://") != null; + } catch (java.net.MalformedURLException x) { + System.out.println("FTP not supported by this runtime."); + return false; + } + } // -- Tests -- @@ -319,8 +326,9 @@ public class Test { header("RFC2396: Basic examples"); - test("ftp://ftp.is.co.za/rfc/rfc1808.txt") - .s("ftp").h("ftp.is.co.za").p("/rfc/rfc1808.txt").z(); + if (hasFtp()) + test("ftp://ftp.is.co.za/rfc/rfc1808.txt") + .s("ftp").h("ftp.is.co.za").p("/rfc/rfc1808.txt").z(); test("http://www.math.uio.no/faq/compression-faq/part1.html") .s("http").h("www.math.uio.no").p("/faq/compression-faq/part1.html").z(); @@ -328,8 +336,9 @@ public class Test { test("http://www.w3.org/Addressing/") .s("http").h("www.w3.org").p("/Addressing/").z(); - test("ftp://ds.internic.net/rfc/") - .s("ftp").h("ds.internic.net").p("/rfc/").z(); + if (hasFtp()) + test("ftp://ds.internic.net/rfc/") + .s("ftp").h("ds.internic.net").p("/rfc/").z(); test("http://www.ics.uci.edu/pub/ietf/url/historical.html#WARNING") .s("http").h("www.ics.uci.edu").p("/pub/ietf/url/historical.html") diff --git a/jdk/test/java/net/URL/URIToURLTest.java b/jdk/test/java/net/URL/URIToURLTest.java index 8ae07b36b12..79273b246c5 100644 --- a/jdk/test/java/net/URL/URIToURLTest.java +++ b/jdk/test/java/net/URL/URIToURLTest.java @@ -28,20 +28,22 @@ */ import java.net.*; +import java.util.ArrayList; +import java.util.List; public class URIToURLTest { public static void main(String args[]) throws Exception { - String[] uris = { - "http://jag:cafebabe@java.sun.com:94/b/c/d?q#g", - "http://[1080:0:0:0:8:800:200C:417A]/index.html", - "http://a/b/c/d;p?q", - "ftp://ftp.is.co.za/rfc/rfc1808.txt", - "mailto:mduerst@ifi.unizh.ch", // opaque url - "http:comp.infosystems.www.servers.unix" //opaque url - }; + List uris = new ArrayList<>(); + uris.add("http://jag:cafebabe@java.sun.com:94/b/c/d?q#g"); + uris.add("http://[1080:0:0:0:8:800:200C:417A]/index.html"); + uris.add("http://a/b/c/d;p?q"); + uris.add("mailto:mduerst@ifi.unizh.ch"); + uris.add("http:comp.infosystems.www.servers.unix"); + if (hasFtp()) + uris.add("ftp://ftp.is.co.za/rfc/rfc1808.txt"); - for (int i = 0; i < uris.length; i++) { - URI uri = new URI(uris[i]); + for (String uriStr : uris) { + URI uri = new URI(uriStr); URL url = uri.toURL(); String scheme = uri.getScheme(); boolean schemeCheck = scheme == null? url.getProtocol() == null : @@ -111,4 +113,13 @@ public class URIToURLTest { url.getRef()); } } + + private static boolean hasFtp() { + try { + return new java.net.URL("ftp://") != null; + } catch (java.net.MalformedURLException x) { + System.out.println("FTP not supported by this runtime."); + return false; + } + } } diff --git a/jdk/test/java/net/URL/abnormal_http_urls b/jdk/test/java/net/URL/abnormal_http_urls deleted file mode 100644 index 1fbf57d37a5..00000000000 --- a/jdk/test/java/net/URL/abnormal_http_urls +++ /dev/null @@ -1,43 +0,0 @@ -URL: http://a/b/c/d;p?q -spec: ../../../g -expected: http://a/../g - -URL: http://a/b/c/d;p?q -spec: ../../../../g -expected: http://a/../../g - -URL: http://a/b/c/d;p?q -spec: /./g -expected: http://a/./g - -URL: http://a/b/c/d;p?q -spec: /../g -expected: http://a/../g - -URL: http://a/b/c/d;p?q -spec: .g -expected: http://a/b/c/.g - -URL: http://a/b/c/d;p?q -spec: g. -expected: http://a/b/c/g. - -URL: http://a/b/c/d;p?q -spec: ./../g -expected: http://a/b/g - -URL: http://a/b/c/d;p?q -spec: ./g/. -expected: http://a/b/c/g/ - -URL: http://a/b/c/d;p?q -spec: g/./h -expected: http://a/b/c/g/h - -URL: http://a/b/c/d;p?q -spec: g;x=1/./y -expected: http://a/b/c/g;x=1/y - -URL: http://a/b/c/d;p?q -spec: g;x=1/../y -expected: http://a/b/c/y diff --git a/jdk/test/java/net/URL/ftp_urls b/jdk/test/java/net/URL/ftp_urls deleted file mode 100644 index 1f8d6fc6fa6..00000000000 --- a/jdk/test/java/net/URL/ftp_urls +++ /dev/null @@ -1,27 +0,0 @@ -URL: null -spec: ftp://ftp.foo.com/dir1/entry.txt -expected: ftp://ftp.foo.com/dir1/entry.txt - -URL: null -spec: ftp://br:pwd@ftp.foo.com/dir1/jar.jar -expected: ftp://br:pwd@ftp.foo.com/dir1/jar.jar - -URL: ftp://ftp.foo.com/dir1/foo.txt -spec: bar.txt -expected: ftp://ftp.foo.com/dir1/bar.txt - -URL: ftp://ftp.foo.com/dir1/jar.jar -spec: /entry.txt -expected: ftp://ftp.foo.com/entry.txt - -URL: ftp://ftp.foo.com/dir1/jar.jar -spec: dir1/entry.txt -expected: ftp://ftp.foo.com/dir1/dir1/entry.txt - -URL: ftp://ftp.foo.com/dir1/jar.jar -spec: /dir1/entry.txt -expected: ftp://ftp.foo.com/dir1/entry.txt - -URL: ftp://br:pwd@ftp.foo.com/dir1/jar.jar -spec: /dir1/entry.txt -expected: ftp://br:pwd@ftp.foo.com/dir1/entry.txt diff --git a/jdk/test/java/net/URL/jar_urls b/jdk/test/java/net/URL/jar_urls deleted file mode 100644 index ebd888450fa..00000000000 --- a/jdk/test/java/net/URL/jar_urls +++ /dev/null @@ -1,75 +0,0 @@ -URL: null -spec: jar:http://www.foo.com/dir1/jar.jar!/dir2/entry.txt -expected: jar:http://www.foo.com/dir1/jar.jar!/dir2/entry.txt - -URL: null -spec: jar:http://www.foo.com/dir1/jar.jar!/ -expected: jar:http://www.foo.com/dir1/jar.jar!/ - -URL: null -spec: jar:http://www.foo.com/dir1/jar.jar!/ -expected: jar:http://www.foo.com/dir1/jar.jar!/ - -URL: jar:http://www.foo.com/dir1/jar.jar!/ -spec: entry.txt -expected: jar:http://www.foo.com/dir1/jar.jar!/entry.txt - -URL: jar:http://www.foo.com/dir1/jar.jar!/ -spec: /entry.txt -expected: jar:http://www.foo.com/dir1/jar.jar!/entry.txt - -URL: jar:http://www.foo.com/dir1/jar.jar!/ -spec: dir1/entry.txt -expected: jar:http://www.foo.com/dir1/jar.jar!/dir1/entry.txt - -URL: jar:http://www.foo.com/dir1/jar.jar!/ -spec: /dir1/entry.txt -expected: jar:http://www.foo.com/dir1/jar.jar!/dir1/entry.txt - -URL: jar:http://www.foo.com/dir1/jar.jar!/ -spec: entry.txt -expected: jar:http://www.foo.com/dir1/jar.jar!/entry.txt - -URL: jar:http://www.foo.com/dir1/jar.jar!/ -spec: /entry.txt -expected: jar:http://www.foo.com/dir1/jar.jar!/entry.txt - -URL: jar:http://www.foo.com/dir1/jar.jar!/ -spec: /entry.txt -expected: jar:http://www.foo.com/dir1/jar.jar!/entry.txt - -URL: jar:http://www.foo.com/dir1/jar.jar!/dir1/ -spec: entry.txt -expected: jar:http://www.foo.com/dir1/jar.jar!/dir1/entry.txt - -URL: jar:http://www.foo.com/dir1/jar.jar!/dir2/dir3/entry2.txt -spec: /dir1/entry.txt -expected: jar:http://www.foo.com/dir1/jar.jar!/dir1/entry.txt - -URL: jar:http://www.foo.com/dir1/jar.jar!/ -spec: /dir1/foo/entry.txt -expected: jar:http://www.foo.com/dir1/jar.jar!/dir1/foo/entry.txt - -URL: jar:http://www.foo.com/dir1/jar.jar!/dir1/dir2/dir3/ -spec: dir4/foo/entry.txt -expected: jar:http://www.foo.com/dir1/jar.jar!/dir1/dir2/dir3/dir4/foo/entry.txt - -URL: jar:http://www.foo.com/dir1/jar.jar!/ -spec: /dir1/foo/entry.txt -expected: jar:http://www.foo.com/dir1/jar.jar!/dir1/foo/entry.txt - -URL: null -spec: jar:http://www.foo.com/dir1/jar.jar!/foo.txt#anchor -expected: jar:http://www.foo.com/dir1/jar.jar!/foo.txt#anchor - -URL: jar:http://www.foo.com/dir1/jar.jar!/foo.txt -spec: #anchor -expected: jar:http://www.foo.com/dir1/jar.jar!/foo.txt#anchor - -URL: jar:http://www.foo.com/dir1/jar.jar!/foo/bar/ -spec: baz/quux#anchor -expected: jar:http://www.foo.com/dir1/jar.jar!/foo/bar/baz/quux#anchor - -URL: jar:http://balloo.com/olle.jar!/ -spec: p2 -expected: jar:http://balloo.com/olle.jar!/p2 diff --git a/jdk/test/java/net/URL/normal_http_urls b/jdk/test/java/net/URL/normal_http_urls deleted file mode 100644 index 52d332057dd..00000000000 --- a/jdk/test/java/net/URL/normal_http_urls +++ /dev/null @@ -1,83 +0,0 @@ -URL: http://a/b/c/d;p?q -spec: g -expected: http://a/b/c/g - -URL: http://a/b/c/d;p?q -spec: ./g -expected: http://a/b/c/g - -URL: http://a/b/c/d;p?q -spec: g/ -expected: http://a/b/c/g/ - -URL: http://a/b/c/d;p?q -spec: /g -expected: http://a/g - -URL: http://a/b/c/d;p?q -spec: //g -expected: http://g - -URL: http://a/b/c/d;p?q -spec: ?y -expected: http://a/b/c/?y - -URL: http://a/b/c/d;p?q -spec: g?y -expected: http://a/b/c/g?y - -URL: http://a/b/c/d;p?q -spec: g#s -expected: http://a/b/c/g#s - -URL: http://a/b/c/d;p?q -spec: g?y#s -expected: http://a/b/c/g?y#s - -URL: http://a/b/c/d;p?q -spec: ;x -expected: http://a/b/c/;x - -URL: http://a/b/c/d;p?q -spec: g;x -expected: http://a/b/c/g;x - -URL: http://a/b/c/d;p?q -spec: g;x?y#s -expected: http://a/b/c/g;x?y#s - -URL: http://a/b/c/d;p?q -spec: . -expected: http://a/b/c/ - -URL: http://a/b/c/d;p?q -spec: ./ -expected: http://a/b/c/ - -URL: http://a/b/c/d;p?q -spec: .. -expected: http://a/b/ - -URL: http://a/b/c/d;p?q -spec: ../ -expected: http://a/b/ - -URL: http://a/b/c/d;p?q -spec: ../g -expected: http://a/b/g - -URL: http://a/b/c/d;p?q -spec: ../.. -expected: http://a/ - -URL: http://a/b/c/d;p?q -spec: ../../ -expected: http://a/ - -URL: http://a/b/c/d;p?q -spec: ../../g -expected: http://a/g - -URL: null -spec: http://www.javasoft.com/jdc/community/chat/index.html#javalive?frontpage-jdc -expected: http://www.javasoft.com/jdc/community/chat/index.html#javalive?frontpage-jdc diff --git a/jdk/test/java/net/URL/runconstructor.sh b/jdk/test/java/net/URL/runconstructor.sh deleted file mode 100644 index f64fd8509d1..00000000000 --- a/jdk/test/java/net/URL/runconstructor.sh +++ /dev/null @@ -1,67 +0,0 @@ -# -# Copyright (c) 2000, 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. -# - -# @test -# @bug 4393671 -# @summary URL constructor URL(URL context, String spec) FAILED with specific input in merlin -# -OS=`uname -s` -case "$OS" in - SunOS | Linux | Darwin ) - PS=":" - FS="/" - ;; - CYGWIN* ) - PS=";" - FS="/" - ;; - Windows* ) - PS=";" - FS="\\" - ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; -esac -${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . \ - ${TESTSRC}${FS}Constructor.java - -failures=0 - -go() { - echo '' - ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} Constructor $1 - if [ $? != 0 ]; then failures=`expr $failures + 1`; fi -} - -go ${TESTSRC}${FS}share_file_urls -go ${TESTSRC}${FS}jar_urls -go ${TESTSRC}${FS}normal_http_urls -go ${TESTSRC}${FS}ftp_urls -go ${TESTSRC}${FS}abnormal_http_urls - -if [ "$failures" != "0" ]; then - echo $failures tests failed - exit 1; -fi diff --git a/jdk/test/java/net/URL/share_file_urls b/jdk/test/java/net/URL/share_file_urls deleted file mode 100644 index 48451b45db4..00000000000 --- a/jdk/test/java/net/URL/share_file_urls +++ /dev/null @@ -1,51 +0,0 @@ -URL: null -spec: file://JavaSoft/Test -expected: file://JavaSoft/Test - -URL: null -spec: file:///JavaSoft/Test -expected: file:/JavaSoft/Test - -URL: null -spec: file:/JavaSoft/Test -expected: file:/JavaSoft/Test - -URL: null -spec: file:/c:/JavaSoft/Test -expected: file:/c:/JavaSoft/Test - -URL: null -spec: file:/c:/JavaSoft/Test:something -expected: file:/c:/JavaSoft/Test:something - -URL: null -spec: file:/c:/JavaSoft/Test#anchor -expected: file:/c:/JavaSoft/Test#anchor - -URL: null -spec: file:/JavaSoft/Test -expected: file:/JavaSoft/Test - -URL: file://JavaSoft/Test -spec: Test#bar -expected: file://JavaSoft/Test#bar - -URL: file://codrus/c:/jdk/eng/index.html -spec: pulsar.html -expected: file://codrus/c:/jdk/eng/pulsar.html - -URL: file:///c:/jdk/eng/index.html -spec: pulsar.html -expected: file:/c:/jdk/eng/pulsar.html - -URL: file:///jdk/eng/index.html -spec: pulsar.html -expected: file:/jdk/eng/pulsar.html - -URL: file://JavaSoft/Test -spec: file://radartoad.com/Test#bar -expected: file://radartoad.com/Test#bar - -URL: file://JavaSoft/Test -spec: /c:/Test#bar -expected: file://JavaSoft/c:/Test#bar \ No newline at end of file diff --git a/jdk/test/java/net/URL/win32_file_urls b/jdk/test/java/net/URL/win32_file_urls deleted file mode 100644 index 7e3981c1490..00000000000 --- a/jdk/test/java/net/URL/win32_file_urls +++ /dev/null @@ -1,15 +0,0 @@ -URL: null -spec: file://c:\JavaSoft\Test -expected: file://c:/JavaSoft/Test - -URL: null -spec: file:/c:\JavaSoft\Test -expected: file:/c:/JavaSoft/Test - -URL: null -spec: file:/c:\JavaSoft\Test:something#anchor -expected: file:/c:/JavaSoft/Test:something#anchor - -URL: file:///c:\jdk\eng\index.html -spec: pulsar.html -expected: file:/c:/jdk/eng/pulsar.html \ No newline at end of file diff --git a/jdk/test/java/net/URLConnection/RequestProperties.java b/jdk/test/java/net/URLConnection/RequestProperties.java index 74fd558ddbe..af549e22e54 100644 --- a/jdk/test/java/net/URLConnection/RequestProperties.java +++ b/jdk/test/java/net/URLConnection/RequestProperties.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013 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 @@ -28,90 +28,55 @@ */ import java.net.*; +import java.util.ArrayList; +import java.util.List; public class RequestProperties { - public static void main (String args[]) throws Exception { - URL url0 = new URL ("http://foo.com/bar/"); - URL url1 = new URL ("file:/etc/passwd"); - URL url2 = new URL ("ftp://foo:bar@foobar.com/etc/passwd"); - URL url3 = new URL ("jar:http://foo.com/bar.html!/foo/bar"); - URLConnection urlc0 = url0.openConnection (); - URLConnection urlc1 = url1.openConnection (); - URLConnection urlc2 = url2.openConnection (); - URLConnection urlc3 = url3.openConnection (); - int count = 0; - String s = null; - try { - urlc0.setRequestProperty (null, null); - System.out.println ("http: setRequestProperty (null,) did not throw NPE"); - } catch (NullPointerException e) { - count ++; - } - try { - urlc0.addRequestProperty (null, null); - System.out.println ("http: addRequestProperty (null,) did not throw NPE"); - } catch (NullPointerException e) { - count ++; - } - try { - urlc1.setRequestProperty (null, null); - System.out.println ("file: setRequestProperty (null,) did not throw NPE"); - } catch (NullPointerException e) { - count ++; - } - try { - urlc1.addRequestProperty (null, null); - System.out.println ("file: addRequestProperty (null,) did not throw NPE"); - } catch (NullPointerException e) { - count ++; - } - try { - urlc2.setRequestProperty (null, null); - System.out.println ("ftp: setRequestProperty (null,) did not throw NPE"); - } catch (NullPointerException e) { - count ++; - } - try { - urlc2.addRequestProperty (null, null); - System.out.println ("ftp: addRequestProperty (null,) did not throw NPE"); - } catch (NullPointerException e) { - count ++; - } - try { - urlc3.setRequestProperty (null, null); - System.out.println ("jar: setRequestProperty (null,) did not throw NPE"); - } catch (NullPointerException e) { - count ++; - } - try { - urlc3.addRequestProperty (null, null); - System.out.println ("jar: addRequestProperty (null,) did not throw NPE"); - } catch (NullPointerException e) { - count ++; - } - if (urlc0.getRequestProperty (null) != null) { - System.out.println ("http: getRequestProperty (null,) did not return null"); - } else { - count ++; - } - if (urlc1.getRequestProperty (null) != null) { - System.out.println ("file: getRequestProperty (null,) did not return null"); - } else { - count ++; - } - if (urlc2.getRequestProperty (null) != null) { - System.out.println ("ftp: getRequestProperty (null,) did not return null"); - } else { - count ++; - } - if (urlc2.getRequestProperty (null) != null) { - System.out.println ("jar: getRequestProperty (null,) did not return null"); - } else { - count ++; - } + static int failed; - if (count != 12) { - throw new RuntimeException ((12 -count) + " errors") ; + public static void main (String args[]) throws Exception { + List urls = new ArrayList<>(); + urls.add("http://foo.com/bar/"); + urls.add("jar:http://foo.com/bar.html!/foo/bar"); + urls.add("file:/etc/passwd"); + if (hasFtp()) + urls.add("ftp://foo:bar@foobar.com/etc/passwd"); + + for (String urlStr : urls) + test(new URL(urlStr)); + + if (failed != 0) + throw new RuntimeException(failed + " errors") ; + } + + static void test(URL url) throws Exception { + URLConnection urlc = url.openConnection(); + try { + urlc.setRequestProperty(null, null); + System.out.println(url.getProtocol() + + ": setRequestProperty(null,) did not throw NPE"); + failed++; + } catch (NullPointerException e) { /* Expected */ } + try { + urlc.addRequestProperty(null, null); + System.out.println(url.getProtocol() + + ": addRequestProperty(null,) did not throw NPE"); + failed++; + } catch (NullPointerException e) { /* Expected */ } + + if (urlc.getRequestProperty(null) != null) { + System.out.println(url.getProtocol() + + ": getRequestProperty(null,) did not return null"); + failed++; + } + } + + private static boolean hasFtp() { + try { + return new java.net.URL("ftp://") != null; + } catch (java.net.MalformedURLException x) { + System.out.println("FTP not supported by this runtime."); + return false; } } } diff --git a/jdk/test/java/net/URLConnection/RequestPropertyValues.java b/jdk/test/java/net/URLConnection/RequestPropertyValues.java index 77bb469e672..6874063ca1d 100644 --- a/jdk/test/java/net/URLConnection/RequestPropertyValues.java +++ b/jdk/test/java/net/URLConnection/RequestPropertyValues.java @@ -27,8 +27,11 @@ * @summary Test URLConnection Request Proterties */ +import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; +import java.util.ArrayList; +import java.util.List; /** * Part1: @@ -45,28 +48,29 @@ public class RequestPropertyValues { } public static void part1() throws Exception { - URL[] urls = { new URL("http://localhost:8088"), - new URL("file:/etc/passwd"), - new URL("ftp://foo:bar@foobar.com/etc/passwd"), - new URL("jar:http://foo.com/bar.html!/foo/bar") - }; + List urls = new ArrayList<>(); + urls.add(new URL("http://localhost:8088")); + urls.add(new URL("file:/etc/passwd")); + urls.add(new URL("jar:http://foo.com/bar.html!/foo/bar")); + if (hasFtp()) + urls.add(new URL("ftp://foo:bar@foobar.com/etc/passwd")); boolean failed = false; - for (int proto = 0; proto < urls.length; proto++) { - URLConnection uc = (URLConnection) urls[proto].openConnection(); + for (URL url : urls) { + URLConnection uc = url.openConnection(); try { uc.setRequestProperty("TestHeader", null); } catch (NullPointerException npe) { System.out.println("setRequestProperty is throwing NPE" + - " for url: " + urls[proto]); + " for url: " + url); failed = true; } try { uc.addRequestProperty("TestHeader", null); } catch (NullPointerException npe) { System.out.println("addRequestProperty is throwing NPE" + - " for url: " + urls[proto]); + " for url: " + url); failed = true; } } @@ -110,4 +114,12 @@ public class RequestPropertyValues { } } + private static boolean hasFtp() { + try { + return new java.net.URL("ftp://") != null; + } catch (java.net.MalformedURLException x) { + System.out.println("FTP not supported by this runtime."); + return false; + } + } } diff --git a/jdk/test/sun/net/www/EncDec.doc b/jdk/test/sun/net/ftp/EncDec.doc similarity index 100% rename from jdk/test/sun/net/www/EncDec.doc rename to jdk/test/sun/net/ftp/EncDec.doc diff --git a/jdk/test/sun/net/www/MarkResetTest.java b/jdk/test/sun/net/ftp/MarkResetTest.java similarity index 100% rename from jdk/test/sun/net/www/MarkResetTest.java rename to jdk/test/sun/net/ftp/MarkResetTest.java diff --git a/jdk/test/sun/net/www/MarkResetTest.sh b/jdk/test/sun/net/ftp/MarkResetTest.sh similarity index 100% rename from jdk/test/sun/net/www/MarkResetTest.sh rename to jdk/test/sun/net/ftp/MarkResetTest.sh diff --git a/jdk/test/sun/net/www/http/HttpClient/ProxyTest.java b/jdk/test/sun/net/www/http/HttpClient/ProxyTest.java index 18c2e1f0840..5d13a58d8cb 100644 --- a/jdk/test/sun/net/www/http/HttpClient/ProxyTest.java +++ b/jdk/test/sun/net/www/http/HttpClient/ProxyTest.java @@ -161,8 +161,18 @@ public class ProxyTest { } } + private static boolean hasFtp() { + try { + return new java.net.URL("ftp://") != null; + } catch (java.net.MalformedURLException x) { + System.out.println("FTP not supported by this runtime."); + return false; + } + } + public static void main(String[] args) throws Exception { - ProxyTest test = new ProxyTest(); + if (hasFtp()) + new ProxyTest(); } public ProxyTest() throws Exception { From e618b1556c93d5dec1c30b236a46f22f0e6f756e Mon Sep 17 00:00:00 2001 From: Ragini Prasad Date: Sat, 2 Feb 2013 12:08:43 -0800 Subject: [PATCH 200/204] 8007135: tools/launcher/VersionCheck.java failing with new tool jabswitch Reviewed-by: ksrini, mduigou --- jdk/test/tools/launcher/VersionCheck.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jdk/test/tools/launcher/VersionCheck.java b/jdk/test/tools/launcher/VersionCheck.java index c30ef424011..11f65cb2e9a 100644 --- a/jdk/test/tools/launcher/VersionCheck.java +++ b/jdk/test/tools/launcher/VersionCheck.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2013, 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 @@ -42,6 +42,7 @@ public class VersionCheck extends TestHelper { // tools that do not accept -J-option static final String[] BLACKLIST_JOPTION = { "controlpanel", + "jabswitch", "java-rmi", "java-rmi.cgi", "java", From 3f02516d3e67f8cd452bdd95cecb5667752abc81 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Sun, 3 Feb 2013 18:20:24 +0400 Subject: [PATCH 201/204] 6471906: java.lang.NegativeArraySizeException in tenToThe Reviewed-by: darcy --- .../share/classes/java/math/BigDecimal.java | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/jdk/src/share/classes/java/math/BigDecimal.java b/jdk/src/share/classes/java/math/BigDecimal.java index d95b1cb27b3..b7f6380948e 100644 --- a/jdk/src/share/classes/java/math/BigDecimal.java +++ b/jdk/src/share/classes/java/math/BigDecimal.java @@ -3537,13 +3537,25 @@ public class BigDecimal extends Number implements Comparable { else return expandBigIntegerTenPowers(n); } - // BigInteger.pow is slow, so make 10**n by constructing a - // BigInteger from a character string (still not very fast) - char tenpow[] = new char[n + 1]; - tenpow[0] = '1'; - for (int i = 1; i <= n; i++) - tenpow[i] = '0'; - return new BigInteger(tenpow,1, tenpow.length); + + if (n < 1024*524288) { + // BigInteger.pow is slow, so make 10**n by constructing a + // BigInteger from a character string (still not very fast) + // which occupies no more than 1GB (!) of memory. + char tenpow[] = new char[n + 1]; + tenpow[0] = '1'; + for (int i = 1; i <= n; i++) { + tenpow[i] = '0'; + } + return new BigInteger(tenpow, 1, tenpow.length); + } + + if ((n & 0x1) == 0x1) { + return BigInteger.TEN.multiply(bigTenToThe(n - 1)); + } else { + BigInteger tmp = bigTenToThe(n/2); + return tmp.multiply(tmp); + } } /** From eea117f3e5a46f6183ccf36fe87f5cfb3eb8fb0e Mon Sep 17 00:00:00 2001 From: Dmitry Samersoff Date: Sun, 3 Feb 2013 21:39:58 +0400 Subject: [PATCH 202/204] 8002048: Protocol to discovery of manageable Java processes on a network Introduce a protocol to discover manageble Java instances across a network subnet, JDP Reviewed-by: sla, dfuchs --- .../share/classes/sun/management/Agent.java | 218 ++++++++---- .../sun/management/jdp/JdpBroadcaster.java | 124 +++++++ .../sun/management/jdp/JdpController.java | 196 +++++++++++ .../sun/management/jdp/JdpException.java | 40 +++ .../sun/management/jdp/JdpGenericPacket.java | 95 ++++++ .../sun/management/jdp/JdpJmxPacket.java | 196 +++++++++++ .../classes/sun/management/jdp/JdpPacket.java | 63 ++++ .../sun/management/jdp/JdpPacketReader.java | 139 ++++++++ .../sun/management/jdp/JdpPacketWriter.java | 93 +++++ .../sun/management/jdp/package-info.java | 55 +++ jdk/test/sun/management/jdp/JdpClient.java | 160 +++++++++ .../sun/management/jdp/JdpDoSomething.java | 103 ++++++ jdk/test/sun/management/jdp/JdpTest.sh | 323 ++++++++++++++++++ jdk/test/sun/management/jdp/JdpUnitTest.java | 90 +++++ 14 files changed, 1824 insertions(+), 71 deletions(-) create mode 100644 jdk/src/share/classes/sun/management/jdp/JdpBroadcaster.java create mode 100644 jdk/src/share/classes/sun/management/jdp/JdpController.java create mode 100644 jdk/src/share/classes/sun/management/jdp/JdpException.java create mode 100644 jdk/src/share/classes/sun/management/jdp/JdpGenericPacket.java create mode 100644 jdk/src/share/classes/sun/management/jdp/JdpJmxPacket.java create mode 100644 jdk/src/share/classes/sun/management/jdp/JdpPacket.java create mode 100644 jdk/src/share/classes/sun/management/jdp/JdpPacketReader.java create mode 100644 jdk/src/share/classes/sun/management/jdp/JdpPacketWriter.java create mode 100644 jdk/src/share/classes/sun/management/jdp/package-info.java create mode 100644 jdk/test/sun/management/jdp/JdpClient.java create mode 100644 jdk/test/sun/management/jdp/JdpDoSomething.java create mode 100644 jdk/test/sun/management/jdp/JdpTest.sh create mode 100644 jdk/test/sun/management/jdp/JdpUnitTest.java diff --git a/jdk/src/share/classes/sun/management/Agent.java b/jdk/src/share/classes/sun/management/Agent.java index 19d2dedb5b4..feef02ad6be 100644 --- a/jdk/src/share/classes/sun/management/Agent.java +++ b/jdk/src/share/classes/sun/management/Agent.java @@ -22,7 +22,6 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ - package sun.management; import java.io.BufferedInputStream; @@ -31,49 +30,55 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; - +import java.lang.management.ManagementFactory; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.lang.management.ManagementFactory; - +import java.net.InetAddress; +import java.net.Socket; +import java.net.UnknownHostException; import java.text.MessageFormat; - import java.util.MissingResourceException; import java.util.Properties; import java.util.ResourceBundle; import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXServiceURL; import static sun.management.AgentConfigurationError.*; import sun.management.jmxremote.ConnectorBootstrap; +import sun.management.jdp.JdpController; +import sun.management.jdp.JdpException; import sun.misc.VMSupport; /** - * This Agent is started by the VM when -Dcom.sun.management.snmp - * or -Dcom.sun.management.jmxremote is set. This class will be - * loaded by the system class loader. Also jmx framework could - * be started by jcmd + * This Agent is started by the VM when -Dcom.sun.management.snmp or + * -Dcom.sun.management.jmxremote is set. This class will be loaded by the + * system class loader. Also jmx framework could be started by jcmd */ public class Agent { // management properties + private static Properties mgmtProps; private static ResourceBundle messageRB; - private static final String CONFIG_FILE = - "com.sun.management.config.file"; + "com.sun.management.config.file"; private static final String SNMP_PORT = - "com.sun.management.snmp.port"; + "com.sun.management.snmp.port"; private static final String JMXREMOTE = - "com.sun.management.jmxremote"; + "com.sun.management.jmxremote"; private static final String JMXREMOTE_PORT = - "com.sun.management.jmxremote.port"; + "com.sun.management.jmxremote.port"; + private static final String RMI_PORT = + "com.sun.management.jmxremote.rmi.port"; private static final String ENABLE_THREAD_CONTENTION_MONITORING = - "com.sun.management.enableThreadContentionMonitoring"; + "com.sun.management.enableThreadContentionMonitoring"; private static final String LOCAL_CONNECTOR_ADDRESS_PROP = - "com.sun.management.jmxremote.localConnectorAddress"; - + "com.sun.management.jmxremote.localConnectorAddress"; private static final String SNMP_ADAPTOR_BOOTSTRAP_CLASS_NAME = - "sun.management.snmp.AdaptorBootstrap"; + "sun.management.snmp.AdaptorBootstrap"; + + private static final String JDP_DEFAULT_ADDRESS = "239.255.255.225"; + private static final int JDP_DEFAULT_PORT = 7095; // The only active agent allowed private static JMXConnectorServer jmxServer = null; @@ -81,26 +86,25 @@ public class Agent { // Parse string com.sun.management.prop=xxx,com.sun.management.prop=yyyy // and return property set if args is null or empty // return empty property set - private static Properties parseString(String args){ + private static Properties parseString(String args) { Properties argProps = new Properties(); if (args != null) { - for (String option : args.split(",")) { - String s[] = option.split("=", 2); - String name = s[0].trim(); - String value = (s.length > 1) ? s[1].trim() : ""; + for (String option : args.split(",")) { + String s[] = option.split("=", 2); + String name = s[0].trim(); + String value = (s.length > 1) ? s[1].trim() : ""; - if (!name.startsWith("com.sun.management.")) { - error(INVALID_OPTION, name); - } + if (!name.startsWith("com.sun.management.")) { + error(INVALID_OPTION, name); + } - argProps.setProperty(name, value); - } + argProps.setProperty(name, value); + } } return argProps; } - // invoked by -javaagent or -Dcom.sun.management.agent.class public static void premain(String args) throws Exception { agentmain(args); @@ -115,18 +119,18 @@ public class Agent { Properties arg_props = parseString(args); // Read properties from the config file - Properties config_props = new Properties(); - String fname = arg_props.getProperty(CONFIG_FILE); - readConfiguration(fname, config_props); + Properties config_props = new Properties(); + String fname = arg_props.getProperty(CONFIG_FILE); + readConfiguration(fname, config_props); - // Arguments override config file - config_props.putAll(arg_props); - startAgent(config_props); + // Arguments override config file + config_props.putAll(arg_props); + startAgent(config_props); } // jcmd ManagementAgent.start_local entry point // Also called due to command-line via startAgent() - private static synchronized void startLocalManagementAgent(){ + private static synchronized void startLocalManagementAgent() { Properties agentProps = VMSupport.getAgentProperties(); // start local connector if not started @@ -156,7 +160,7 @@ public class Agent { throw new RuntimeException(getText(INVALID_STATE, "Agent already started")); } - Properties argProps = parseString(args); + Properties argProps = parseString(args); Properties configProps = new Properties(); // Load the management properties from the config file @@ -169,7 +173,7 @@ public class Agent { // management properties can be overridden by system properties // which take precedence Properties sysProps = System.getProperties(); - synchronized(sysProps){ + synchronized (sysProps) { configProps.putAll(sysProps); } @@ -190,21 +194,26 @@ public class Agent { // can specify this property inside config file, so enable optional // monitoring functionality if this property is set final String enableThreadContentionMonitoring = - configProps.getProperty(ENABLE_THREAD_CONTENTION_MONITORING); + configProps.getProperty(ENABLE_THREAD_CONTENTION_MONITORING); if (enableThreadContentionMonitoring != null) { ManagementFactory.getThreadMXBean(). - setThreadContentionMonitoringEnabled(true); + setThreadContentionMonitoringEnabled(true); } String jmxremotePort = configProps.getProperty(JMXREMOTE_PORT); if (jmxremotePort != null) { jmxServer = ConnectorBootstrap. - startRemoteConnectorServer(jmxremotePort, configProps); + startRemoteConnectorServer(jmxremotePort, configProps); + + startDiscoveryService(configProps); } } private static synchronized void stopRemoteManagementAgent() throws Exception { + + JdpController.stopDiscoveryService(); + if (jmxServer != null) { ConnectorBootstrap.unexportRegistry(); @@ -222,15 +231,15 @@ public class Agent { // Enable optional monitoring functionality if requested final String enableThreadContentionMonitoring = - props.getProperty(ENABLE_THREAD_CONTENTION_MONITORING); + props.getProperty(ENABLE_THREAD_CONTENTION_MONITORING); if (enableThreadContentionMonitoring != null) { ManagementFactory.getThreadMXBean(). - setThreadContentionMonitoringEnabled(true); + setThreadContentionMonitoringEnabled(true); } try { if (snmpPort != null) { - loadSnmpAgent(snmpPort, props); + loadSnmpAgent(snmpPort, props); } /* @@ -242,13 +251,14 @@ public class Agent { * of this "local" server is exported as a counter to the jstat * instrumentation buffer. */ - if (jmxremote != null || jmxremotePort != null) { + if (jmxremote != null || jmxremotePort != null) { if (jmxremotePort != null) { - jmxServer = ConnectorBootstrap. - startRemoteConnectorServer(jmxremotePort, props); + jmxServer = ConnectorBootstrap. + startRemoteConnectorServer(jmxremotePort, props); + startDiscoveryService(props); } startLocalManagementAgent(); - } + } } catch (AgentConfigurationError e) { error(e.getError(), e.getParams()); @@ -257,6 +267,73 @@ public class Agent { } } + private static void startDiscoveryService(Properties props) + throws IOException { + // Start discovery service if requested + String discoveryPort = props.getProperty("com.sun.management.jdp.port"); + String discoveryAddress = props.getProperty("com.sun.management.jdp.address"); + String discoveryShouldStart = props.getProperty("com.sun.management.jmxremote.autodiscovery"); + + // Decide whether we should start autodicovery service. + // To start autodiscovery following conditions should be met: + // autodiscovery==true OR (autodicovery==null AND jdp.port != NULL) + + boolean shouldStart = false; + if (discoveryShouldStart == null){ + shouldStart = (discoveryPort != null); + } + else{ + try{ + shouldStart = Boolean.parseBoolean(discoveryShouldStart); + } catch (NumberFormatException e) { + throw new AgentConfigurationError("Couldn't parse autodiscovery argument"); + } + } + + if (shouldStart) { + // port and address are required arguments and have no default values + InetAddress address; + try { + address = (discoveryAddress == null) ? + InetAddress.getByName(JDP_DEFAULT_ADDRESS) : InetAddress.getByName(discoveryAddress); + } catch (UnknownHostException e) { + throw new AgentConfigurationError("Unable to broadcast to requested address", e); + } + + int port = JDP_DEFAULT_PORT; + if (discoveryPort != null) { + try { + port = Integer.parseInt(discoveryPort); + } catch (NumberFormatException e) { + throw new AgentConfigurationError("Couldn't parse JDP port argument"); + } + } + + // Rebuilding service URL to broadcast it + String jmxremotePort = props.getProperty(JMXREMOTE_PORT); + String rmiPort = props.getProperty(RMI_PORT); + + JMXServiceURL url = jmxServer.getAddress(); + String hostname = url.getHost(); + + String jmxUrlStr = (rmiPort != null) + ? String.format( + "service:jmx:rmi://%s:%s/jndi/rmi://%s:%s/jmxrmi", + hostname, rmiPort, hostname, jmxremotePort) + : String.format( + "service:jmx:rmi:///jndi/rmi://%s:%s/jmxrmi", hostname, jmxremotePort); + + String instanceName = System.getProperty("com.sun.management.jdp.name"); + + try{ + JdpController.startDiscoveryService(address, port, instanceName, jmxUrlStr); + } + catch(JdpException e){ + throw new AgentConfigurationError("Couldn't start JDP service", e); + } + } + } + public static Properties loadManagementProperties() { Properties props = new Properties(); @@ -268,22 +345,22 @@ public class Agent { // management properties can be overridden by system properties // which take precedence Properties sysProps = System.getProperties(); - synchronized(sysProps){ + synchronized (sysProps) { props.putAll(sysProps); } return props; - } + } - public static synchronized Properties getManagementProperties() { + public static synchronized Properties getManagementProperties() { if (mgmtProps == null) { String configFile = System.getProperty(CONFIG_FILE); String snmpPort = System.getProperty(SNMP_PORT); String jmxremote = System.getProperty(JMXREMOTE); String jmxremotePort = System.getProperty(JMXREMOTE_PORT); - if (configFile == null && snmpPort == null && - jmxremote == null && jmxremotePort == null) { + if (configFile == null && snmpPort == null + && jmxremote == null && jmxremotePort == null) { // return if out-of-the-management option is not specified return null; } @@ -297,22 +374,23 @@ public class Agent { // invoke the following through reflection: // AdaptorBootstrap.initialize(snmpPort, props); final Class adaptorClass = - Class.forName(SNMP_ADAPTOR_BOOTSTRAP_CLASS_NAME,true,null); + Class.forName(SNMP_ADAPTOR_BOOTSTRAP_CLASS_NAME, true, null); final Method initializeMethod = adaptorClass.getMethod("initialize", - String.class, Properties.class); - initializeMethod.invoke(null,snmpPort,props); + String.class, Properties.class); + initializeMethod.invoke(null, snmpPort, props); } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException x) { // snmp runtime doesn't exist - initialization fails - throw new UnsupportedOperationException("Unsupported management property: " + SNMP_PORT,x); + throw new UnsupportedOperationException("Unsupported management property: " + SNMP_PORT, x); } catch (InvocationTargetException x) { final Throwable cause = x.getCause(); - if (cause instanceof RuntimeException) + if (cause instanceof RuntimeException) { throw (RuntimeException) cause; - else if (cause instanceof Error) + } else if (cause instanceof Error) { throw (Error) cause; + } // should not happen... - throw new UnsupportedOperationException("Unsupported management property: " + SNMP_PORT,cause); + throw new UnsupportedOperationException("Unsupported management property: " + SNMP_PORT, cause); } } @@ -353,8 +431,8 @@ public class Agent { } catch (IOException e) { error(CONFIG_FILE_CLOSE_FAILED, fname); } - } - } + } + } } public static void startAgent() throws Exception { @@ -389,9 +467,9 @@ public class Agent { // invoke the premain(String args) method Class clz = ClassLoader.getSystemClassLoader().loadClass(cname); Method premain = clz.getMethod("premain", - new Class[] { String.class }); + new Class[]{String.class}); premain.invoke(null, /* static */ - new Object[] { args }); + new Object[]{args}); } catch (ClassNotFoundException ex) { error(AGENT_CLASS_NOT_FOUND, "\"" + cname + "\""); } catch (NoSuchMethodException ex) { @@ -400,8 +478,8 @@ public class Agent { error(AGENT_CLASS_ACCESS_DENIED); } catch (Exception ex) { String msg = (ex.getCause() == null - ? ex.getMessage() - : ex.getCause().getMessage()); + ? ex.getMessage() + : ex.getCause().getMessage()); error(AGENT_CLASS_FAILED, msg); } } @@ -425,7 +503,6 @@ public class Agent { } } - public static void error(String key, String message) { String keyText = getText(key); System.err.print(getText("agent.err.error") + ": " + keyText); @@ -447,7 +524,7 @@ public class Agent { private static void initResource() { try { messageRB = - ResourceBundle.getBundle("sun.management.resources.agent"); + ResourceBundle.getBundle("sun.management.resources.agent"); } catch (MissingResourceException e) { throw new Error("Fatal: Resource for management agent is missing"); } @@ -470,10 +547,9 @@ public class Agent { } String format = messageRB.getString(key); if (format == null) { - format = "missing resource key: key = \"" + key + "\", " + - "arguments = \"{0}\", \"{1}\", \"{2}\""; + format = "missing resource key: key = \"" + key + "\", " + + "arguments = \"{0}\", \"{1}\", \"{2}\""; } return MessageFormat.format(format, (Object[]) args); } - } diff --git a/jdk/src/share/classes/sun/management/jdp/JdpBroadcaster.java b/jdk/src/share/classes/sun/management/jdp/JdpBroadcaster.java new file mode 100644 index 00000000000..df5f23458e5 --- /dev/null +++ b/jdk/src/share/classes/sun/management/jdp/JdpBroadcaster.java @@ -0,0 +1,124 @@ +/* + * 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. + */ +package sun.management.jdp; + +import java.io.IOException; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.NetworkInterface; +import java.net.ProtocolFamily; +import java.net.StandardProtocolFamily; +import java.net.StandardSocketOptions; +import java.nio.ByteBuffer; +import java.nio.channels.DatagramChannel; +import java.nio.channels.UnsupportedAddressTypeException; + +/** + * JdpBroadcaster is responsible for sending pre-built JDP packet across a Net + * + *

Multicast group address, port number and ttl have to be chosen on upper + * level and passed to broadcaster constructor. Also it's possible to specify + * source address to broadcast from.

+ * + *

JdpBradcaster doesn't perform any validation on a supplied {@code port} and {@code ttl} because + * the allowed values depend on an operating system setup

+ * + */ +public final class JdpBroadcaster { + + private final InetAddress addr; + private final int port; + private final DatagramChannel channel; + + /** + * Create a new broadcaster + * + * @param address - multicast group address + * @param srcAddress - address of interface we should use to broadcast. + * @param port - udp port to use + * @param ttl - packet ttl + * @throws IOException + */ + public JdpBroadcaster(InetAddress address, InetAddress srcAddress, int port, int ttl) + throws IOException, JdpException { + this.addr = address; + this.port = port; + + ProtocolFamily family = (address instanceof Inet6Address) + ? StandardProtocolFamily.INET6 : StandardProtocolFamily.INET; + + channel = DatagramChannel.open(family); + channel.setOption(StandardSocketOptions.SO_REUSEADDR, true); + channel.setOption(StandardSocketOptions.IP_MULTICAST_TTL, ttl); + + // with srcAddress equal to null, this constructor do exactly the same as + // if srcAddress is not passed + if (srcAddress != null) { + // User requests particular interface to bind to + NetworkInterface interf = NetworkInterface.getByInetAddress(srcAddress); + try { + channel.bind(new InetSocketAddress(srcAddress, 0)); + } catch (UnsupportedAddressTypeException ex) { + throw new JdpException("Unable to bind to source address"); + } + channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, interf); + } + } + + /** + * Create a new broadcaster + * + * @param address - multicast group address + * @param port - udp port to use + * @param ttl - packet ttl + * @throws IOException + */ + public JdpBroadcaster(InetAddress address, int port, int ttl) + throws IOException, JdpException { + this(address, null, port, ttl); + } + + /** + * Broadcast pre-built packet + * + * @param packet - instance of JdpPacket + * @throws IOException + */ + public void sendPacket(JdpPacket packet) + throws IOException { + byte[] data = packet.getPacketData(); + // Unlike allocate/put wrap don't need a flip afterward + ByteBuffer b = ByteBuffer.wrap(data); + channel.send(b, new InetSocketAddress(addr, port)); + } + + /** + * Shutdown broadcaster and close underlying socket channel + * + * @throws IOException + */ + public void shutdown() throws IOException { + channel.close(); + } +} diff --git a/jdk/src/share/classes/sun/management/jdp/JdpController.java b/jdk/src/share/classes/sun/management/jdp/JdpController.java new file mode 100644 index 00000000000..d8d0ed46930 --- /dev/null +++ b/jdk/src/share/classes/sun/management/jdp/JdpController.java @@ -0,0 +1,196 @@ +/* + * 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. + */ +package sun.management.jdp; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.UUID; + +/** + * JdpController is responsible to create and manage a broadcast loop + * + *

Other part of code has no access to broadcast loop and have to use + * provided static methods + * {@link #startDiscoveryService(InetAddress,int,String,String) startDiscoveryService} + * and {@link #stopDiscoveryService() stopDiscoveryService}

+ *

{@link #startDiscoveryService(InetAddress,int,String,String) startDiscoveryService} could be called multiple + * times as it stops the running service if it is necessary. Call to {@link #stopDiscoveryService() stopDiscoveryService} + * ignored if service isn't run

+ * + * + *

+ * + *

System properties below could be used to control broadcast loop behavior. + * Property below have to be set explicitly in command line. It's not possible to + * set it in management.config file. Careless changes of these properties could + * lead to security or network issues. + *

    + *
  • com.sun.management.jdp.ttl - set ttl for broadcast packet
  • + *
  • com.sun.management.jdp.pause - set broadcast interval in seconds
  • + *
  • com.sun.management.jdp.source_addr - an address of interface to use for broadcast
  • + *
+

+ *

null parameters values are filtered out on {@link JdpPacketWriter} level and + * corresponding keys are not placed to packet.

+ */ +public final class JdpController { + + private static class JDPControllerRunner implements Runnable { + + private final JdpJmxPacket packet; + private final JdpBroadcaster bcast; + private final int pause; + private volatile boolean shutdown = false; + + private JDPControllerRunner(JdpBroadcaster bcast, JdpJmxPacket packet, int pause) { + this.bcast = bcast; + this.packet = packet; + this.pause = pause; + } + + @Override + public void run() { + try { + while (!shutdown) { + bcast.sendPacket(packet); + try { + Thread.sleep(this.pause); + } catch (InterruptedException e) { + // pass + } + } + + } catch (IOException e) { + // pass; + } + + // It's not possible to re-use controller, + // nevertheless reset shutdown variable + try { + stop(); + bcast.shutdown(); + } catch (IOException ex) { + // pass - ignore IOException during shutdown + } + } + + public void stop() { + shutdown = true; + } + } + private static JDPControllerRunner controller = null; + + private JdpController(){ + // Don't allow to instantiate this class. + } + + // Utility to handle optional system properties + // Parse an integer from string or return default if provided string is null + private static int getInteger(String val, int dflt, String msg) throws JdpException { + try { + return (val == null) ? dflt : Integer.parseInt(val); + } catch (NumberFormatException ex) { + throw new JdpException(msg); + } + } + + // Parse an inet address from string or return default if provided string is null + private static InetAddress getInetAddress(String val, InetAddress dflt, String msg) throws JdpException { + try { + return (val == null) ? dflt : InetAddress.getByName(val); + } catch (UnknownHostException ex) { + throw new JdpException(msg); + } + } + + /** + * Starts discovery service + * + * @param address - multicast group address + * @param port - udp port to use + * @param instanceName - name of running JVM instance + * @param url - JMX service url + * @throws IOException + */ + public static synchronized void startDiscoveryService(InetAddress address, int port, String instanceName, String url) + throws IOException, JdpException { + + // Limit packet to local subnet by default + int ttl = getInteger( + System.getProperty("com.sun.management.jdp.ttl"), 1, + "Invalid jdp packet ttl"); + + // Broadcast once a 5 seconds by default + int pause = getInteger( + System.getProperty("com.sun.management.jdp.pause"), 5, + "Invalid jdp pause"); + + // Converting seconds to milliseconds + pause = pause * 1000; + + // Allow OS to choose broadcast source + InetAddress sourceAddress = getInetAddress( + System.getProperty("com.sun.management.jdp.source_addr"), null, + "Invalid source address provided"); + + // Generate session id + UUID id = UUID.randomUUID(); + + JdpJmxPacket packet = new JdpJmxPacket(id, url); + + // Don't broadcast whole command line for security reason. + // Strip everything after first space + String javaCommand = System.getProperty("sun.java.command"); + if (javaCommand != null) { + String[] arr = javaCommand.split(" ", 2); + packet.setMainClass(arr[0]); + } + + // Put optional explicit java instance name to packet, if user doesn't specify + // it the key is skipped. PacketWriter is responsible to skip keys having null value. + packet.setInstanceName(instanceName); + + JdpBroadcaster bcast = new JdpBroadcaster(address, sourceAddress, port, ttl); + + // Stop discovery service if it's already running + stopDiscoveryService(); + + controller = new JDPControllerRunner(bcast, packet, pause); + + Thread t = new Thread(controller, "JDP broadcaster"); + t.setDaemon(true); + t.start(); + } + + /** + * Stop running discovery service, + * it's safe to attempt to stop not started service + */ + public static synchronized void stopDiscoveryService() { + if ( controller != null ){ + controller.stop(); + controller = null; + } + } +} diff --git a/jdk/src/share/classes/sun/management/jdp/JdpException.java b/jdk/src/share/classes/sun/management/jdp/JdpException.java new file mode 100644 index 00000000000..03404223e94 --- /dev/null +++ b/jdk/src/share/classes/sun/management/jdp/JdpException.java @@ -0,0 +1,40 @@ +/* + * 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. + */ +package sun.management.jdp; + +/** + * An Exception thrown if a JDP implementation encounters a problem. + */ +public final class JdpException extends Exception { + + private static final long serialVersionUID = 1L; + + /** + * Construct a new JDP exception with a meaningful message + * + * @param msg - message + */ + public JdpException(String msg) { + super(msg); + } +} diff --git a/jdk/src/share/classes/sun/management/jdp/JdpGenericPacket.java b/jdk/src/share/classes/sun/management/jdp/JdpGenericPacket.java new file mode 100644 index 00000000000..8e88b148265 --- /dev/null +++ b/jdk/src/share/classes/sun/management/jdp/JdpGenericPacket.java @@ -0,0 +1,95 @@ +/* + * 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. + */ +package sun.management.jdp; + +/** + * JdpGenericPacket responsible to provide fields + * common for all Jdp packets + */ +public abstract class JdpGenericPacket implements JdpPacket { + + /** + * JDP protocol magic. Magic allows a reader to quickly select + * JDP packets from a bunch of broadcast packets addressed to the same port + * and broadcast group. Any packet intended to be parsed by JDP client + * has to start from this magic. + */ + private static final int MAGIC = 0xC0FFEE42; + + /** + * Current version of protocol. Any implementation of this protocol has to + * conform with the packet structure and the flow described in JEP-168 + */ + private static final short PROTOCOL_VERSION = 1; + + /** + * Default do-nothing constructor + */ + protected JdpGenericPacket(){ + // do nothing + } + + + /** + * Validate protocol header magic field + * + * @param magic - value to validate + * @throws JdpException + */ + public static void checkMagic(int magic) + throws JdpException { + if (magic != MAGIC) { + throw new JdpException("Invalid JDP magic header: " + magic); + } + } + + /** + * Validate protocol header version field + * + * @param version - value to validate + * @throws JdpException + */ + public static void checkVersion(short version) + throws JdpException { + + if (version > PROTOCOL_VERSION) { + throw new JdpException("Unsupported protocol version: " + version); + } + } + + /** + * + * @return protocol magic + */ + public static int getMagic() { + return MAGIC; + } + + /** + * + * @return current protocol version + */ + public static short getVersion() { + return PROTOCOL_VERSION; + } +} diff --git a/jdk/src/share/classes/sun/management/jdp/JdpJmxPacket.java b/jdk/src/share/classes/sun/management/jdp/JdpJmxPacket.java new file mode 100644 index 00000000000..7d5ccc2f892 --- /dev/null +++ b/jdk/src/share/classes/sun/management/jdp/JdpJmxPacket.java @@ -0,0 +1,196 @@ +/* + * 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. + */ +package sun.management.jdp; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; + +/** + * A packet to broadcasts JMX URL + * + * Fields: + * + *
    + *
  • UUID - broadcast session ID, changed every time when we start/stop + * discovery service
  • + *
  • JMX_URL - URL to connect to JMX service
  • + *
  • MAIN_CLASS - optional name of main class, filled from sun.java.command stripped for + * security reason to first space
  • + *
  • INSTANCE_NAME - optional custom name of particular instance as provided by customer
  • + *
+ */ +public final class JdpJmxPacket + extends JdpGenericPacket + implements JdpPacket { + + /** + * Session ID + */ + public final static String UUID_KEY = "DISCOVERABLE_SESSION_UUID"; + /** + * Name of main class + */ + public final static String MAIN_CLASS_KEY = "MAIN_CLASS"; + /** + * JMX service URL + */ + public final static String JMX_SERVICE_URL_KEY = "JMX_SERVICE_URL"; + /** + * Name of Java instance + */ + public final static String INSTANCE_NAME_KEY = "INSTANCE_NAME"; + + private UUID id; + private String mainClass; + private String jmxServiceUrl; + private String instanceName; + + /** + * Create new instance from user provided data. Set mandatory fields + * + * @param id - java instance id + * @param jmxServiceUrl - JMX service url + */ + public JdpJmxPacket(UUID id, String jmxServiceUrl) { + this.id = id; + this.jmxServiceUrl = jmxServiceUrl; + } + + /** + * Create new instance from network data Parse packet and set fields. + * + * @param data - raw packet data as it came from a Net + * @throws JdpException + */ + public JdpJmxPacket(byte[] data) + throws JdpException { + JdpPacketReader reader; + + reader = new JdpPacketReader(data); + Map p = reader.getDiscoveryDataAsMap(); + + String sId = p.get(UUID_KEY); + this.id = (sId == null) ? null : UUID.fromString(sId); + this.jmxServiceUrl = p.get(JMX_SERVICE_URL_KEY); + this.mainClass = p.get(MAIN_CLASS_KEY); + this.instanceName = p.get(INSTANCE_NAME_KEY); + } + + /** + * Set main class field + * + * @param mainClass - main class of running app + */ + public void setMainClass(String mainClass) { + this.mainClass = mainClass; + } + + /** + * Set instance name field + * + * @param instanceName - name of instance as provided by customer + */ + public void setInstanceName(String instanceName) { + this.instanceName = instanceName; + } + + /** + * @return id of discovery session + */ + public UUID getId() { + return id; + } + + /** + * + * @return main class field + */ + public String getMainClass() { + return mainClass; + } + + /** + * + * @return JMX service URL + */ + public String getJmxServiceUrl() { + return jmxServiceUrl; + } + + /** + * + * @return instance name + */ + public String getInstanceName() { + return instanceName; + } + + /** + * + * @return assembled packet ready to be sent across a Net + * @throws IOException + */ + @Override + public byte[] getPacketData() throws IOException { + // Assemble packet from fields to byte array + JdpPacketWriter writer; + writer = new JdpPacketWriter(); + writer.addEntry(UUID_KEY, (id == null) ? null : id.toString()); + writer.addEntry(MAIN_CLASS_KEY, mainClass); + writer.addEntry(JMX_SERVICE_URL_KEY, jmxServiceUrl); + writer.addEntry(INSTANCE_NAME_KEY, instanceName); + return writer.getPacketBytes(); + } + + /** + * + * @return packet hash code + */ + @Override + public int hashCode() { + int hash = 1; + hash = hash * 31 + id.hashCode(); + hash = hash * 31 + jmxServiceUrl.hashCode(); + return hash; + } + + /** + * Compare two packets + * + * @param o - packet to compare + * @return either packet equals or not + */ + @Override + public boolean equals(Object o) { + + if (o == null || ! (o instanceof JdpJmxPacket) ){ + return false; + } + + JdpJmxPacket p = (JdpJmxPacket) o; + return Objects.equals(id, p.getId()) && Objects.equals(jmxServiceUrl, p.getJmxServiceUrl()); + } +} diff --git a/jdk/src/share/classes/sun/management/jdp/JdpPacket.java b/jdk/src/share/classes/sun/management/jdp/JdpPacket.java new file mode 100644 index 00000000000..ba0ec4f97ac --- /dev/null +++ b/jdk/src/share/classes/sun/management/jdp/JdpPacket.java @@ -0,0 +1,63 @@ +/* + * 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. + */ + +package sun.management.jdp; + +import java.io.IOException; + +/** + * Packet to broadcast + * + *

Each packet have to contain MAGIC and PROTOCOL_VERSION in order to be + * recognized as a valid JDP packet.

+ * + *

Default implementation build packet as a set of UTF-8 encoded Key/Value pairs + * are stored as an ordered list of values, and are sent to the server + * in that order.

+ * + *

+ * Packet structure: + * + * 4 bytes JDP magic (0xC0FFE42) + * 2 bytes JDP protocol version (01) + * + * 2 bytes size of key + * x bytes key (UTF-8 encoded) + * 2 bytes size of value + * x bytes value (UTF-8 encoded) + * + * repeat as many times as necessary ... + *

+ */ +public interface JdpPacket { + + /** + * This method responsible to assemble packet and return a byte array + * ready to be sent across a Net. + * + * @return assembled packet as an array of bytes + * @throws IOException + */ + public byte[] getPacketData() throws IOException; + +} diff --git a/jdk/src/share/classes/sun/management/jdp/JdpPacketReader.java b/jdk/src/share/classes/sun/management/jdp/JdpPacketReader.java new file mode 100644 index 00000000000..9f3957ab5ce --- /dev/null +++ b/jdk/src/share/classes/sun/management/jdp/JdpPacketReader.java @@ -0,0 +1,139 @@ +/* + * 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. + */ +package sun.management.jdp; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.EOFException; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * JdpPacketReader responsible for reading a packet

This class gets a byte + * array as it came from a Net, validates it and breaks a part

+ */ +public final class JdpPacketReader { + + private final DataInputStream pkt; + private Map pmap = null; + + /** + * Create packet reader, extract and check magic and version + * + * @param packet - packet received from a Net + * @throws JdpException + */ + public JdpPacketReader(byte[] packet) + throws JdpException { + ByteArrayInputStream bais = new ByteArrayInputStream(packet); + pkt = new DataInputStream(bais); + + try { + int magic = pkt.readInt(); + JdpGenericPacket.checkMagic(magic); + } catch (IOException e) { + throw new JdpException("Invalid JDP packet received, bad magic"); + } + + try { + short version = pkt.readShort(); + JdpGenericPacket.checkVersion(version); + } catch (IOException e) { + throw new JdpException("Invalid JDP packet received, bad protocol version"); + } + } + + /** + * Get next entry from packet + * + * @return the entry + * @throws EOFException + * @throws JdpException + */ + public String getEntry() + throws EOFException, JdpException { + + try { + short len = pkt.readShort(); + // Artificial setting the "len" field to Short.MAX_VALUE may cause a reader to allocate + // to much memory. Prevent this possible DOS attack. + if (len < 1 && len > pkt.available()) { + throw new JdpException("Broken JDP packet. Invalid entry length field."); + } + + byte[] b = new byte[len]; + if (pkt.read(b) != len) { + throw new JdpException("Broken JDP packet. Unable to read entry."); + } + return new String(b, "UTF-8"); + + } catch (EOFException e) { + throw e; + } catch (UnsupportedEncodingException ex) { + throw new JdpException("Broken JDP packet. Unable to decode entry."); + } catch (IOException e) { + throw new JdpException("Broken JDP packet. Unable to read entry."); + } + + + } + + /** + * return packet content as a key/value map + * + * @return map containing packet entries pair of entries treated as + * key,value + * @throws IOException + * @throws JdpException + */ + public Map getDiscoveryDataAsMap() + throws JdpException { + // return cached map if possible + if (pmap != null) { + return pmap; + } + + String key = null, value = null; + + final Map tmpMap = new HashMap<>(); + try { + while (true) { + key = getEntry(); + value = getEntry(); + tmpMap.put(key, value); + } + } catch (EOFException e) { + // EOF reached on reading value, report broken packet + // otherwise ignore it. + if (value == null) { + throw new JdpException("Broken JDP packet. Key without value." + key); + } + } + + pmap = Collections.unmodifiableMap(tmpMap); + return pmap; + } +} diff --git a/jdk/src/share/classes/sun/management/jdp/JdpPacketWriter.java b/jdk/src/share/classes/sun/management/jdp/JdpPacketWriter.java new file mode 100644 index 00000000000..7ebd002608c --- /dev/null +++ b/jdk/src/share/classes/sun/management/jdp/JdpPacketWriter.java @@ -0,0 +1,93 @@ +/* + * 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. + */ +package sun.management.jdp; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * JdpPacketWriter responsible for writing a packet + *

This class assembles a set of key/value pairs to valid JDP packet, + * ready to be sent across a Net

+ */ +public final class JdpPacketWriter { + + private final ByteArrayOutputStream baos; + private final DataOutputStream pkt; + + /** + * Create a JDP packet, add mandatory magic and version headers + * + * @throws IOException + */ + public JdpPacketWriter() + throws IOException { + baos = new ByteArrayOutputStream(); + pkt = new DataOutputStream(baos); + + pkt.writeInt(JdpGenericPacket.getMagic()); + pkt.writeShort(JdpGenericPacket.getVersion()); + } + + /** + * Put string entry to packet + * + * @param entry - string to put (utf-8 encoded) + * @throws IOException + */ + public void addEntry(String entry) + throws IOException { + pkt.writeShort(entry.length()); + byte[] b = entry.getBytes("UTF-8"); + pkt.write(b); + } + + /** + * Put key/value pair to packet + * + * @param key - key to put (utf-8 encoded) + * @param val - value to put (utf-8 encoded) + * @throws IOException + */ + public void addEntry(String key, String val) + throws IOException { + /* Silently skip key if value is null. + * We don't need to distinguish between key missing + * and key has no value cases + */ + if (val != null) { + addEntry(key); + addEntry(val); + } + } + + /** + * Return assembled packet as a byte array + * + * @return packet bytes + */ + public byte[] getPacketBytes() { + return baos.toByteArray(); + } +} diff --git a/jdk/src/share/classes/sun/management/jdp/package-info.java b/jdk/src/share/classes/sun/management/jdp/package-info.java new file mode 100644 index 00000000000..e21e461214f --- /dev/null +++ b/jdk/src/share/classes/sun/management/jdp/package-info.java @@ -0,0 +1,55 @@ +/** + * Summary + * ------- + * + * Define a lightweight network protocol for discovering running and + * manageable Java processes within a network subnet. + * + * + * Description + * ----------- + * + * The protocol is lightweight multicast based, and works like a beacon, + * broadcasting the JMXService URL needed to connect to the external JMX + * agent if an application is started with appropriate parameters. + * + * The payload is structured like this: + * + * 4 bytes JDP magic (0xC0FFEE42) + * 2 bytes JDP protocol version (1) + * 2 bytes size of the next entry + * x bytes next entry (UTF-8 encoded) + * 2 bytes size of next entry + * ... Rinse and repeat... + * + * The payload will be parsed as even entries being keys, odd entries being + * values. + * + * The standard JDP packet contains four entries: + * + * - `DISCOVERABLE_SESSION_UUID` -- Unique id of the instance; this id changes every time + * the discovery protocol starts and stops + * + * - `MAIN_CLASS` -- The value of the `sun.java.command` property + * + * - `JMX_SERVICE_URL` -- The URL to connect to the JMX agent + * + * - `INSTANCE_NAME` -- The user-provided name of the running instance + * + * The protocol sends packets to 239.255.255.225:7095 by default. + * + * The protocol uses system properties to control it's behaviour: + * - `com.sun.management.jdp.port` -- override default port + * + * - `com.sun.management.jdp.address` -- override default address + * + * - `com.sun.management.jmxremote.autodiscovery` -- whether we should start autodiscovery or + * not. Autodiscovery starts if and only if following conditions are met: (autodiscovery is + * true OR (autodiscovery is not set AND jdp.port is set)) + * + * - `com.sun.management.jdp.ttl` -- set ttl for broadcast packet, default is 1 + * - `com.sun.management.jdp.pause` -- set broadcast interval in seconds default is 5 + * - `com.sun.management.jdp.source_addr` -- an address of interface to use for broadcast + */ + +package sun.management.jdp; diff --git a/jdk/test/sun/management/jdp/JdpClient.java b/jdk/test/sun/management/jdp/JdpClient.java new file mode 100644 index 00000000000..4a2348468b2 --- /dev/null +++ b/jdk/test/sun/management/jdp/JdpClient.java @@ -0,0 +1,160 @@ +/* + * 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. + */ + +import java.io.IOException; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.NetworkInterface; +import java.net.ProtocolFamily; +import java.net.StandardProtocolFamily; +import java.net.StandardSocketOptions; +import java.nio.ByteBuffer; +import java.nio.channels.DatagramChannel; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.util.Collections; +import java.util.Enumeration; +import sun.management.jdp.JdpException; +import sun.management.jdp.JdpJmxPacket; + +public class JdpClient { + + private static class PacketListener implements Runnable { + + private static final int BUFFER_LENGTH = 4096; + private final DatagramChannel channel; + private static int maxPacketCount = 1; + private static int maxEmptyPacketCount = 10; + + + PacketListener(DatagramChannel channel) { + this.channel = channel; + } + + @java.lang.Override + public void run() { + try { + Selector sel; + sel = Selector.open(); + channel.configureBlocking(false); + channel.register(sel, SelectionKey.OP_READ); + ByteBuffer buf = ByteBuffer.allocate(1024); + + int count = 1; + int emptyPacketsCount = 1; + + try { + while (true) { + + sel.selectedKeys().clear(); + buf.rewind(); + + sel.select(10 * 1000); + channel.receive(buf); + + if (buf.position() == 0 ){ + if (JdpDoSomething.getVerbose()){ + System.err.println("Empty packet received"); + } + if (++emptyPacketsCount > maxEmptyPacketCount){ + throw new RuntimeException("Test failed, maxEmptyPacketCount reached"); + } + + continue; + } + + buf.flip(); + byte[] dgramData = new byte[buf.remaining()]; + buf.get(dgramData); + + try { + JdpJmxPacket packet = new JdpJmxPacket(dgramData); + JdpDoSomething.printJdpPacket(packet); + if(++count > maxPacketCount){ + break; + } + } catch (JdpException e) { + e.printStackTrace(); + throw new RuntimeException("Test failed"); + } + + } + + System.out.println("OK: Test passed"); + + } finally { + sel.close(); + channel.close(); + } + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException("Test failed"); + } + } + } + + public static void main(String[] args) { + try { + String discoveryPort = System.getProperty("com.sun.management.jdp.port"); + String discoveryAddress = System.getProperty("com.sun.management.jdp.address"); + if (discoveryAddress == null || discoveryPort == null) { + System.out.println("Test failed. address and port must be specified"); + return; + } + + int port = Integer.parseInt(discoveryPort); + InetAddress address = InetAddress.getByName(discoveryAddress); + + + ProtocolFamily family = (address instanceof Inet6Address) + ? StandardProtocolFamily.INET6 : StandardProtocolFamily.INET; + + DatagramChannel channel; + + channel = DatagramChannel.open(family); + channel.setOption(StandardSocketOptions.SO_REUSEADDR, true); + channel.bind(new InetSocketAddress(port)); + + Enumeration nets = NetworkInterface.getNetworkInterfaces(); + for (NetworkInterface interf : Collections.list(nets)) { + if (interf.supportsMulticast()) { + try { + channel.join(address, interf); + } catch (IOException e) { + // Skip not configured interfaces + } + } + } + + PacketListener listener = new PacketListener(channel); + new Thread(listener, "Jdp Client").start(); + + } catch (RuntimeException e){ + System.out.println("Test failed."); + } catch (Exception e) { + e.printStackTrace(); + System.out.println("Test failed. unexpected error " + e); + } + } +} diff --git a/jdk/test/sun/management/jdp/JdpDoSomething.java b/jdk/test/sun/management/jdp/JdpDoSomething.java new file mode 100644 index 00000000000..ad9366cbaa4 --- /dev/null +++ b/jdk/test/sun/management/jdp/JdpDoSomething.java @@ -0,0 +1,103 @@ +/* + * 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. + */ + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.Objects; + +import sun.management.jdp.JdpJmxPacket; +import sun.management.jdp.JdpException; + +public class JdpDoSomething { + + private static final String lockFileName = "JdpDoSomething.lck"; + private static final boolean verbose=false; + + public static boolean getVerbose(){ + return verbose; + } + + public static void printJdpPacket(JdpJmxPacket p) { + if (getVerbose()) { + try { + RandomAccessFile f = new RandomAccessFile("out.dmp", "rw"); + f.write(p.getPacketData()); + f.close(); + } catch (IOException e) { + System.out.println("Can't write a dump file: " + e); + } + + System.out.println("Id: " + p.getId()); + System.out.println("Jmx: " + p.getJmxServiceUrl()); + System.out.println("Main: " + p.getMainClass()); + System.out.println("InstanceName: " + p.getInstanceName()); + + System.out.flush(); + } + } + + public static void compaireJdpPacketEx(JdpJmxPacket p1, JdpJmxPacket p2) + throws JdpException { + + if (!Objects.equals(p1, p1)) { + throw new JdpException("Packet mismatch error"); + } + + if (!Objects.equals(p1.getMainClass(), p2.getMainClass())) { + throw new JdpException("Packet mismatch error (main class)"); + } + + if (!Objects.equals(p1.getInstanceName(), p2.getInstanceName())) { + throw new JdpException("Packet mismatch error (instance name)"); + } + } + + public static void doSomething() { + try { + File lockFile = new File(lockFileName); + lockFile.createNewFile(); + + while (lockFile.exists()) { + long datetime = lockFile.lastModified(); + long epoch = System.currentTimeMillis() / 1000; + + // Don't allow test app to run more than an hour + if (epoch - datetime > 3600) { + System.err.println("Lock is too old. Aborting"); + return; + } + Thread.sleep(1); + } + + } catch (Throwable e) { + System.err.println("Something bad happens:" + e); + } + } + + public static void main(String args[]) throws Exception { + System.err.println("main enter"); + doSomething(); + System.err.println("main exit"); + } +} diff --git a/jdk/test/sun/management/jdp/JdpTest.sh b/jdk/test/sun/management/jdp/JdpTest.sh new file mode 100644 index 00000000000..2aded729953 --- /dev/null +++ b/jdk/test/sun/management/jdp/JdpTest.sh @@ -0,0 +1,323 @@ +#!/bin/sh + +# Copyright (c) 2011, 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. + +# @test +# @bug 7169888 +# @build JdpUnitTest JdpClient JdpDoSomething +# @run shell JdpTest.sh --jtreg --no-compile +# @summary No word Failed expected in the test output + +_verbose=no +_jtreg=no +_compile=yes + +# temporary disable jcmd related tests +# _testsuite="01,02,03,04,05" +_testsuite="01,02,04" + +_pwd=`pwd` + +_testclasses=".classes" +_testsrc="${_pwd}" +_lockFileName="JdpDoSomething.lck" + +_logname=".classes/output.txt" +_last_pid="" + + +_compile(){ + + if [ ! -e ${_testclasses} ] + then + mkdir -p ${_testclasses} + fi + + rm -f ${_testclasses}/*.class + + # Compile testcase + ${TESTJAVA}/bin/javac -d ${_testclasses} JdpUnitTest.java \ + JdpDoSomething.java \ + JdpClient.java + + + if [ ! -e ${_testclasses}/JdpDoSomething.class -o ! -e ${_testclasses}/JdpClient.class -o ! -e ${_testclasses}/JdpUnitTest.class ] + then + echo "ERROR: Can't compile" + exit -1 + fi +} + + +_app_start(){ + + testappname=$1 + shift + + ${TESTJAVA}/bin/java -server $* -cp ${_testclasses} ${testappname} >> ${_logname} 2>&1 & + _last_pid=$! + + npid=`_get_pid` + if [ "${npid}" = "" ] + then + echo "ERROR: Test app not started" + if [ "${_jtreg}" = "yes" ] + then + exit -1 + fi + fi +} + +_get_pid(){ + ${TESTJAVA}/bin/jps | sed -n "/Jdp/s/ .*//p" +} + +_app_stop(){ + rm ${_lockFileName} + +# wait until VM is actually shuts down + while true + do + npid=`_get_pid` + if [ "${npid}" = "" ] + then + break + fi + sleep 1 + done +} + +_testme(){ + ${TESTJAVA}/bin/java \ + -cp ${_testclasses} \ + $* \ + -Dcom.sun.management.jdp.port=7095 \ + -Dcom.sun.management.jdp.address=239.255.255.225 \ + JdpClient + +} + + +_jcmd(){ + ${TESTJAVA}/bin/jcmd JdpDoSomething $* > /dev/null 2>/dev/null +} + + +_echo(){ + echo "$*" + echo "$*" >> ${_logname} +} + +# ============= TESTS ====================================== + +test_01(){ + + _echo "**** Test one ****" + + _app_start JdpUnitTest \ + -Dcom.sun.management.jdp.port=7095 \ + -Dcom.sun.management.jdp.address=239.255.255.225 \ + -Dcom.sun.management.jdp.pause=5 + + res=`_testme` + + case "${res}" in + OK*) + _echo "Passed" + ;; + *) + _echo "Failed!" + ;; + esac + + _app_stop +} + +test_02(){ + + _echo "**** Test two ****" + + _app_start JdpDoSomething \ + -Dcom.sun.management.jdp.port=7095 \ + -Dcom.sun.management.jdp.address=239.255.255.225 \ + -Dcom.sun.management.jdp.pause=5 \ + -Dcom.sun.management.jmxremote.port=4545 \ + -Dcom.sun.management.jmxremote.authenticate=false \ + -Dcom.sun.management.jmxremote.ssl=false + + res=`_testme` + + case "${res}" in + OK*) + _echo "Passed" + ;; + *) + _echo "Failed!" + ;; + esac + + _app_stop +} + +test_03(){ + + _echo "**** Test three ****" + + _app_start JdpDoSomething + + _jcmd ManagementAgent.start\ + jdp.port=7095 \ + jdp.address=239.255.255.225 \ + jdp.pause=5 \ + jmxremote.port=4545 \ + jmxremote.authenticate=false \ + jmxremote.ssl=false + + res=`_testme` + + case "${res}" in + OK*) + _echo "Passed" + ;; + *) + _echo "Failed!" + ;; + esac + + _app_stop +} + +test_04(){ + + _echo "**** Test four ****" + + _app_start JdpDoSomething \ + -Dcom.sun.management.jmxremote.autodiscovery=true \ + -Dcom.sun.management.jmxremote.port=4545 \ + -Dcom.sun.management.jmxremote.authenticate=false \ + -Dcom.sun.management.jmxremote.ssl=false + + res=`_testme` + + case "${res}" in + OK*) + _echo "Passed" + ;; + *) + _echo "Failed!" + ;; + esac + + _app_stop +} + +test_05(){ + + _echo "**** Test five ****" + + _app_start JdpDoSomething + + _jcmd ManagementAgent.start\ + jmxremote.autodiscovery=true \ + jmxremote.port=4545 \ + jmxremote.authenticate=false \ + jmxremote.ssl=false + + + res=`_testme` + + case "${res}" in + OK*) + _echo "Passed" + ;; + *) + _echo "Failed!" + ;; + esac + + _app_stop +} + + +# ============= MAIN ======================================= + +if [ "x${TESTJAVA}" = "x" ] +then + echo "TESTJAVA env have to be set" + exit +fi + +#------------------------------------------------------------------------------ +# reading parameters + +for parm in "$@" +do + case $parm in + --verbose) _verbose=yes ;; + --jtreg) _jtreg=yes ;; + --no-compile) _compile=no ;; + --testsuite=*) _testsuite=`_echo $parm | sed "s,^--.*=\(.*\),\1,"` ;; + *) + echo "Undefined parameter $parm. Try --help for help" + exit + ;; + esac +done + +if [ ${_compile} = "yes" ] +then + _compile +fi + +if [ ${_jtreg} = "yes" ] +then + _testclasses=${TESTCLASSES} + _testsrc=${TESTSRC} + _logname="output.txt" +fi + +# Make sure _tesclasses is absolute path +tt=`echo ${_testclasses} | sed -e 's,/,,'` +if [ ${tt} = ${_testclasses} ] +then + _testclasses="${_pwd}/${_testclasses}" +fi + +_policyname="${_testclasses}/policy" + +rm -f ${_logname} +rm -f ${_policyname} + +if [ -e ${_testsrc}/policy.tpl ] +then + +cat ${_testsrc}/policy.tpl | \ + sed -e "s,@_TESTCLASSES@,${_testclasses},g" -e "s,@TESTJAVA@,${TESTJAVA},g" \ + > ${_policyname} + +fi + +# Local mode tests +for i in `echo ${_testsuite} | sed -e "s/,/ /g"` +do + test_${i} +done diff --git a/jdk/test/sun/management/jdp/JdpUnitTest.java b/jdk/test/sun/management/jdp/JdpUnitTest.java new file mode 100644 index 00000000000..fed4ae216c2 --- /dev/null +++ b/jdk/test/sun/management/jdp/JdpUnitTest.java @@ -0,0 +1,90 @@ +/* + * 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. + */ + +import java.io.IOException; +import java.net.InetAddress; +import java.util.UUID; + +import sun.management.jdp.JdpController; +import sun.management.jdp.JdpPacket; +import sun.management.jdp.JdpJmxPacket; +import sun.management.jdp.JdpException; + +public class JdpUnitTest { + + /** + * This test tests that complete packet is build correctly + */ + public static void PacketBuilderTest() + throws IOException, JdpException { + + /* Complete packet test */ + { + JdpJmxPacket p1 = new JdpJmxPacket(UUID.randomUUID(), "fake://unit-test"); + p1.setMainClass("FakeUnitTest"); + p1.setInstanceName("Fake"); + byte[] b = p1.getPacketData(); + + JdpJmxPacket p2 = new JdpJmxPacket(b); + JdpDoSomething.printJdpPacket(p1); + JdpDoSomething.compaireJdpPacketEx(p1, p2); + } + + /*Missed field packet test*/ + { + JdpJmxPacket p1 = new JdpJmxPacket(UUID.randomUUID(), "fake://unit-test"); + p1.setMainClass("FakeUnitTest"); + p1.setInstanceName(null); + byte[] b = p1.getPacketData(); + + JdpJmxPacket p2 = new JdpJmxPacket(b); + JdpDoSomething.printJdpPacket(p1); + JdpDoSomething.compaireJdpPacketEx(p1, p2); + } + + System.out.println("OK: Test passed"); + + } + + public static void startFakeDiscoveryService() + throws IOException, JdpException { + + String discoveryPort = System.getProperty("com.sun.management.jdp.port"); + String discoveryAddress = System.getProperty("com.sun.management.jdp.address"); + InetAddress address = InetAddress.getByName(discoveryAddress); + int port = Integer.parseInt(discoveryPort); + JdpController.startDiscoveryService(address, port, "FakeDiscovery", "fake://unit-test"); + } + + public static void main(String[] args) { + try { + PacketBuilderTest(); + startFakeDiscoveryService(); + JdpDoSomething.doSomething(); + + } catch (Throwable e) { + e.printStackTrace(); + System.out.println("Test failed. unexpected error " + e); + } + } +} From ddbfa5fe533275175c38fc7acedc124f1684df68 Mon Sep 17 00:00:00 2001 From: Vinnie Ryan Date: Mon, 4 Feb 2013 17:20:26 +0000 Subject: [PATCH 203/204] 8006994: Cleanup PKCS12 tests to ensure streams get closed Reviewed-by: mullan --- jdk/test/java/security/KeyStore/PBETest.java | 63 ++++++++------- .../security/pkcs12/StorePasswordTest.java | 50 ++++++------ .../security/pkcs12/StoreSecretKeyTest.java | 41 +++++----- .../security/pkcs12/StoreTrustedCertTest.java | 80 +++++++++---------- 4 files changed, 116 insertions(+), 118 deletions(-) diff --git a/jdk/test/java/security/KeyStore/PBETest.java b/jdk/test/java/security/KeyStore/PBETest.java index be437d03bbd..2186165ea68 100644 --- a/jdk/test/java/security/KeyStore/PBETest.java +++ b/jdk/test/java/security/KeyStore/PBETest.java @@ -58,45 +58,46 @@ public class PBETest { new File(NEW_KEYSTORE).delete(); - try { - KeyStore keystore = load(KEYSTORE_TYPE, KEYSTORE, PASSWORD); - KeyStore.Entry entry = - keystore.getEntry(ALIAS, - new KeyStore.PasswordProtection(PASSWORD)); - System.out.println("Retrieved entry named '" + ALIAS + "'"); - - // Set entry - KeyStore keystore2 = load(NEW_KEYSTORE_TYPE, null, null); - keystore2.setEntry(ALIAS, entry, - new KeyStore.PasswordProtection(PASSWORD, PBE_ALGO, - new PBEParameterSpec(SALT, ITERATION_COUNT, - new IvParameterSpec(IV)))); - System.out.println("Encrypted entry using: " + PBE_ALGO); - - System.out.println("Storing keystore to: " + NEW_KEYSTORE); - keystore2.store(new FileOutputStream(NEW_KEYSTORE), PASSWORD); - - keystore2 = load(NEW_KEYSTORE_TYPE, NEW_KEYSTORE, PASSWORD); - entry = keystore2.getEntry(ALIAS, + KeyStore keystore = load(KEYSTORE_TYPE, KEYSTORE, PASSWORD); + KeyStore.Entry entry = + keystore.getEntry(ALIAS, new KeyStore.PasswordProtection(PASSWORD)); - System.out.println("Retrieved entry named '" + ALIAS + "'"); + System.out.println("Retrieved entry named '" + ALIAS + "'"); - } finally { - new File(NEW_KEYSTORE).delete(); - System.out.println("Deleted keystore: " + NEW_KEYSTORE); + // Set entry + KeyStore keystore2 = load(NEW_KEYSTORE_TYPE, null, null); + keystore2.setEntry(ALIAS, entry, + new KeyStore.PasswordProtection(PASSWORD, PBE_ALGO, + new PBEParameterSpec(SALT, ITERATION_COUNT, + new IvParameterSpec(IV)))); + System.out.println("Encrypted entry using: " + PBE_ALGO); + + try (FileOutputStream outStream = new FileOutputStream(NEW_KEYSTORE)) { + System.out.println("Storing keystore to: " + NEW_KEYSTORE); + keystore2.store(outStream, PASSWORD); } + + keystore2 = load(NEW_KEYSTORE_TYPE, NEW_KEYSTORE, PASSWORD); + entry = keystore2.getEntry(ALIAS, + new KeyStore.PasswordProtection(PASSWORD)); + System.out.println("Retrieved entry named '" + ALIAS + "'"); } private static KeyStore load(String type, String path, char[] password) throws Exception { - - FileInputStream stream = null; - if (path != null) { - stream = new FileInputStream(path); - } KeyStore keystore = KeyStore.getInstance(type); - System.out.println("Loading keystore from: " + path); - keystore.load(stream, password); + + if (path != null) { + + try (FileInputStream inStream = new FileInputStream(path)) { + System.out.println("Loading keystore from: " + path); + keystore.load(inStream, password); + System.out.println("Loaded keystore with " + keystore.size() + + " entries"); + } + } else { + keystore.load(null, null); + } return keystore; } diff --git a/jdk/test/sun/security/pkcs12/StorePasswordTest.java b/jdk/test/sun/security/pkcs12/StorePasswordTest.java index fc2f77c51c1..d258aaa10a7 100644 --- a/jdk/test/sun/security/pkcs12/StorePasswordTest.java +++ b/jdk/test/sun/security/pkcs12/StorePasswordTest.java @@ -47,40 +47,40 @@ public class StorePasswordTest { new File(KEYSTORE).delete(); - try { + KeyStore keystore = KeyStore.getInstance("PKCS12"); + keystore.load(null, null); - KeyStore keystore = KeyStore.getInstance("PKCS12"); - keystore.load(null, null); - - // Set entry - keystore.setEntry(ALIAS, - new KeyStore.SecretKeyEntry(convertPassword(USER_PASSWORD)), - new KeyStore.PasswordProtection(PASSWORD)); + // Set entry + keystore.setEntry(ALIAS, + new KeyStore.SecretKeyEntry(convertPassword(USER_PASSWORD)), + new KeyStore.PasswordProtection(PASSWORD)); + try (FileOutputStream outStream = new FileOutputStream(KEYSTORE)) { System.out.println("Storing keystore to: " + KEYSTORE); - keystore.store(new FileOutputStream(KEYSTORE), PASSWORD); + keystore.store(outStream, PASSWORD); + } + try (FileInputStream inStream = new FileInputStream(KEYSTORE)) { System.out.println("Loading keystore from: " + KEYSTORE); - keystore.load(new FileInputStream(KEYSTORE), PASSWORD); + keystore.load(inStream, PASSWORD); System.out.println("Loaded keystore with " + keystore.size() + " entries"); - KeyStore.Entry entry = keystore.getEntry(ALIAS, - new KeyStore.PasswordProtection(PASSWORD)); - System.out.println("Retrieved entry: " + entry); + } - SecretKey key = (SecretKey) keystore.getKey(ALIAS, PASSWORD); - SecretKeyFactory factory = - SecretKeyFactory.getInstance(key.getAlgorithm()); - PBEKeySpec keySpec = - (PBEKeySpec) factory.getKeySpec(key, PBEKeySpec.class); - char[] pwd = keySpec.getPassword(); - System.out.println("Recovered credential: " + new String(pwd)); + KeyStore.Entry entry = keystore.getEntry(ALIAS, + new KeyStore.PasswordProtection(PASSWORD)); + System.out.println("Retrieved entry: " + entry); - if (!Arrays.equals(USER_PASSWORD.toCharArray(), pwd)) { - throw new Exception("Failed to recover the stored password"); - } - } finally { - new File(KEYSTORE).delete(); + SecretKey key = (SecretKey) keystore.getKey(ALIAS, PASSWORD); + SecretKeyFactory factory = + SecretKeyFactory.getInstance(key.getAlgorithm()); + PBEKeySpec keySpec = + (PBEKeySpec) factory.getKeySpec(key, PBEKeySpec.class); + char[] pwd = keySpec.getPassword(); + System.out.println("Recovered credential: " + new String(pwd)); + + if (!Arrays.equals(USER_PASSWORD.toCharArray(), pwd)) { + throw new Exception("Failed to recover the stored password"); } } diff --git a/jdk/test/sun/security/pkcs12/StoreSecretKeyTest.java b/jdk/test/sun/security/pkcs12/StoreSecretKeyTest.java index f002ef7506a..84c28899126 100644 --- a/jdk/test/sun/security/pkcs12/StoreSecretKeyTest.java +++ b/jdk/test/sun/security/pkcs12/StoreSecretKeyTest.java @@ -53,35 +53,34 @@ public class StoreSecretKeyTest { new File(KEYSTORE).delete(); - try { + KeyStore keystore = KeyStore.getInstance("PKCS12"); + keystore.load(null, null); - KeyStore keystore = KeyStore.getInstance("PKCS12"); - keystore.load(null, null); - - // Set entry - keystore.setEntry(ALIAS, - new KeyStore.SecretKeyEntry(generateSecretKey("AES", 128)), - new KeyStore.PasswordProtection(PASSWORD)); + // Set entry + keystore.setEntry(ALIAS, + new KeyStore.SecretKeyEntry(generateSecretKey("AES", 128)), + new KeyStore.PasswordProtection(PASSWORD)); + try (FileOutputStream outStream = new FileOutputStream(KEYSTORE)) { System.out.println("Storing keystore to: " + KEYSTORE); - keystore.store(new FileOutputStream(KEYSTORE), PASSWORD); + keystore.store(outStream, PASSWORD); + } + try (FileInputStream inStream = new FileInputStream(KEYSTORE)) { System.out.println("Loading keystore from: " + KEYSTORE); - keystore.load(new FileInputStream(KEYSTORE), PASSWORD); + keystore.load(inStream, PASSWORD); System.out.println("Loaded keystore with " + keystore.size() + " entries"); - KeyStore.Entry entry = keystore.getEntry(ALIAS, - new KeyStore.PasswordProtection(PASSWORD)); - System.out.println("Retrieved entry: " + entry); + } - if (entry instanceof KeyStore.SecretKeyEntry) { - System.out.println("Retrieved secret key entry: " + - entry); - } else { - throw new Exception("Not a secret key entry"); - } - } finally { - new File(KEYSTORE).delete(); + KeyStore.Entry entry = keystore.getEntry(ALIAS, + new KeyStore.PasswordProtection(PASSWORD)); + System.out.println("Retrieved entry: " + entry); + + if (entry instanceof KeyStore.SecretKeyEntry) { + System.out.println("Retrieved secret key entry: " + entry); + } else { + throw new Exception("Not a secret key entry"); } } diff --git a/jdk/test/sun/security/pkcs12/StoreTrustedCertTest.java b/jdk/test/sun/security/pkcs12/StoreTrustedCertTest.java index a1481749d7e..0cbca31e2d1 100644 --- a/jdk/test/sun/security/pkcs12/StoreTrustedCertTest.java +++ b/jdk/test/sun/security/pkcs12/StoreTrustedCertTest.java @@ -49,59 +49,57 @@ public class StoreTrustedCertTest { new File(KEYSTORE).delete(); - try { - KeyStore keystore = KeyStore.getInstance("PKCS12"); - keystore.load(null, null); + KeyStore keystore = KeyStore.getInstance("PKCS12"); + keystore.load(null, null); - Certificate cert = loadCertificate(CERT); - Set attributes = new HashSet<>(); - attributes.add(new PKCS12Attribute("1.3.5.7.9", "that's odd")); - attributes.add(new PKCS12Attribute("2.4.6.8.10", "that's even")); + Certificate cert = loadCertificate(CERT); + Set attributes = new HashSet<>(); + attributes.add(new PKCS12Attribute("1.3.5.7.9", "that's odd")); + attributes.add(new PKCS12Attribute("2.4.6.8.10", "that's even")); - // Set trusted certificate entry - keystore.setEntry(ALIAS, - new KeyStore.TrustedCertificateEntry(cert), null); + // Set trusted certificate entry + keystore.setEntry(ALIAS, + new KeyStore.TrustedCertificateEntry(cert), null); - // Set trusted certificate entry with attributes - keystore.setEntry(ALIAS2, - new KeyStore.TrustedCertificateEntry(cert, attributes), null); + // Set trusted certificate entry with attributes + keystore.setEntry(ALIAS2, + new KeyStore.TrustedCertificateEntry(cert, attributes), null); + try (FileOutputStream outStream = new FileOutputStream(KEYSTORE)) { System.out.println("Storing keystore to: " + KEYSTORE); - keystore.store(new FileOutputStream(KEYSTORE), PASSWORD); + keystore.store(outStream, PASSWORD); + } + try (FileInputStream inStream = new FileInputStream(KEYSTORE)) { System.out.println("Loading keystore from: " + KEYSTORE); - keystore.load(new FileInputStream(KEYSTORE), PASSWORD); + keystore.load(inStream, PASSWORD); System.out.println("Loaded keystore with " + keystore.size() + " entries"); + } - KeyStore.Entry entry = keystore.getEntry(ALIAS, null); - if (entry instanceof KeyStore.TrustedCertificateEntry) { - System.out.println("Retrieved trusted certificate entry: " + - entry); + KeyStore.Entry entry = keystore.getEntry(ALIAS, null); + if (entry instanceof KeyStore.TrustedCertificateEntry) { + System.out.println("Retrieved trusted certificate entry: " + entry); + } else { + throw new Exception("Not a trusted certificate entry"); + } + System.out.println(); + + entry = keystore.getEntry(ALIAS2, null); + if (entry instanceof KeyStore.TrustedCertificateEntry) { + KeyStore.TrustedCertificateEntry trustedEntry = + (KeyStore.TrustedCertificateEntry) entry; + Set entryAttributes = + trustedEntry.getAttributes(); + + if (entryAttributes.containsAll(attributes)) { + System.out.println("Retrieved trusted certificate entry " + + "with attributes: " + entry); } else { - throw new Exception("Not a trusted certificate entry"); + throw new Exception("Failed to retrieve entry attributes"); } - System.out.println(); - - entry = keystore.getEntry(ALIAS2, null); - if (entry instanceof KeyStore.TrustedCertificateEntry) { - KeyStore.TrustedCertificateEntry trustedEntry = - (KeyStore.TrustedCertificateEntry) entry; - Set entryAttributes = - trustedEntry.getAttributes(); - - if (entryAttributes.containsAll(attributes)) { - System.out.println("Retrieved trusted certificate entry " + - "with attributes: " + entry); - } else { - throw new Exception("Failed to retrieve entry attributes"); - } - } else { - throw new Exception("Not a trusted certificate entry"); - } - - } finally { - new File(KEYSTORE).delete(); + } else { + throw new Exception("Not a trusted certificate entry"); } } From db8ced219f196ccdbae9f1121dd5411412dbdf90 Mon Sep 17 00:00:00 2001 From: Xueming Shen Date: Mon, 4 Feb 2013 11:58:43 -0800 Subject: [PATCH 204/204] 8006295: Base64.Decoder.wrap(java.io.InputStream) returns InputStream which throws unspecified IOException on attempt to decode invalid Base64 byte stream 8006315: Base64.Decoder decoding methods are not consistent in treating non-padded data 8006530: Base64.getMimeDecoder().decode() throws exception for non-base64 character after adding = Updated the spec to describe the expected behave explicitly and the implementation to follow Reviewed-by: alanb, chegar, lancea --- jdk/src/share/classes/java/util/Base64.java | 121 +++++++++++++------- jdk/test/java/util/Base64/TestBase64.java | 83 +++++++++++++- 2 files changed, 161 insertions(+), 43 deletions(-) diff --git a/jdk/src/share/classes/java/util/Base64.java b/jdk/src/share/classes/java/util/Base64.java index 471b4e28620..88b17406799 100644 --- a/jdk/src/share/classes/java/util/Base64.java +++ b/jdk/src/share/classes/java/util/Base64.java @@ -64,7 +64,8 @@ import java.nio.charset.StandardCharsets; * RFC 2045 for encoding and decoding operation. The encoded output * must be represented in lines of no more than 76 characters each * and uses a carriage return {@code '\r'} followed immediately by - * a linefeed {@code '\n'} as the line separator. All line separators + * a linefeed {@code '\n'} as the line separator. No line separator + * is added to the end of the encoded output. All line separators * or other characters not found in the base64 alphabet table are * ignored in decoding operation.

* @@ -614,6 +615,13 @@ public class Base64 { * This class implements a decoder for decoding byte data using the * Base64 encoding scheme as specified in RFC 4648 and RFC 2045. * + *

The Base64 padding character {@code '='} is accepted and + * interpreted as the end of the encoded byte data, but is not + * required. So if the final unit of the encoded byte data only has + * two or three Base64 characters (without the corresponding padding + * character(s) padded), they are decoded as if followed by padding + * character(s). + * *

Instances of {@link Decoder} class are safe for use by * multiple concurrent threads. * @@ -857,6 +865,9 @@ public class Base64 { /** * Returns an input stream for decoding {@link Base64} encoded byte stream. * + *

The {@code read} methods of the returned {@code InputStream} will + * throw {@code IOException} when reading bytes that cannot be decoded. + * *

Closing the returned input stream will close the underlying * input stream. * @@ -883,13 +894,16 @@ public class Base64 { int dl = dst.arrayOffset() + dst.limit(); int dp0 = dp; int mark = sp; - boolean padding = false; try { while (sp < sl) { int b = sa[sp++] & 0xff; if ((b = base64[b]) < 0) { if (b == -2) { // padding byte - padding = true; + if (shiftto == 6 && (sp == sl || sa[sp++] != '=') || + shiftto == 18) { + throw new IllegalArgumentException( + "Input byte array has wrong 4-byte ending unit"); + } break; } if (isMIME) // skip if for rfc2045 @@ -915,24 +929,23 @@ public class Base64 { if (shiftto == 6) { if (dl - dp < 1) return dp - dp0; - if (padding && (sp + 1 != sl || sa[sp++] != '=')) - throw new IllegalArgumentException( - "Input buffer has wrong 4-byte ending unit"); da[dp++] = (byte)(bits >> 16); - mark = sp; } else if (shiftto == 0) { if (dl - dp < 2) return dp - dp0; - if (padding && sp != sl) - throw new IllegalArgumentException( - "Input buffer has wrong 4-byte ending unit"); da[dp++] = (byte)(bits >> 16); da[dp++] = (byte)(bits >> 8); - mark = sp; - } else if (padding || shiftto != 18) { + } else if (shiftto == 12) { throw new IllegalArgumentException( "Last unit does not have enough valid bits"); } + while (sp < sl) { + if (isMIME && base64[sa[sp++]] < 0) + continue; + throw new IllegalArgumentException( + "Input byte array has incorrect ending byte at " + sp); + } + mark = sp; return dp - dp0; } finally { src.position(mark); @@ -950,14 +963,16 @@ public class Base64 { int dl = dst.limit(); int dp0 = dp; int mark = sp; - boolean padding = false; - try { while (sp < sl) { int b = src.get(sp++) & 0xff; if ((b = base64[b]) < 0) { if (b == -2) { // padding byte - padding = true; + if (shiftto == 6 && (sp == sl || src.get(sp++) != '=') || + shiftto == 18) { + throw new IllegalArgumentException( + "Input byte array has wrong 4-byte ending unit"); + } break; } if (isMIME) // skip if for rfc2045 @@ -983,24 +998,23 @@ public class Base64 { if (shiftto == 6) { if (dl - dp < 1) return dp - dp0; - if (padding && (sp + 1 != sl || src.get(sp++) != '=')) - throw new IllegalArgumentException( - "Input buffer has wrong 4-byte ending unit"); dst.put(dp++, (byte)(bits >> 16)); - mark = sp; } else if (shiftto == 0) { if (dl - dp < 2) return dp - dp0; - if (padding && sp != sl) - throw new IllegalArgumentException( - "Input buffer has wrong 4-byte ending unit"); dst.put(dp++, (byte)(bits >> 16)); dst.put(dp++, (byte)(bits >> 8)); - mark = sp; - } else if (padding || shiftto != 18) { + } else if (shiftto == 12) { throw new IllegalArgumentException( "Last unit does not have enough valid bits"); } + while (sp < sl) { + if (isMIME && base64[src.get(sp++)] < 0) + continue; + throw new IllegalArgumentException( + "Input byte array has incorrect ending byte at " + sp); + } + mark = sp; return dp - dp0; } finally { src.position(mark); @@ -1048,12 +1062,20 @@ public class Base64 { int dp = 0; int bits = 0; int shiftto = 18; // pos of first byte of 4-byte atom - boolean padding = false; while (sp < sl) { int b = src[sp++] & 0xff; if ((b = base64[b]) < 0) { - if (b == -2) { // padding byte - padding = true; + if (b == -2) { // padding byte '=' + // xx= shiftto==6&&sp==sl missing last = + // xx=y shiftto==6 last is not = + // = shiftto==18 unnecessary padding + // x= shiftto==12 be taken care later + // together with single x, invalid anyway + if (shiftto == 6 && (sp == sl || src[sp++] != '=') || + shiftto == 18) { + throw new IllegalArgumentException( + "Input byte array has wrong 4-byte ending unit"); + } break; } if (isMIME) // skip if for rfc2045 @@ -1073,22 +1095,23 @@ public class Base64 { bits = 0; } } - // reach end of byte arry or hit padding '=' characters. - // if '=' presents, they must be the last one or two. - if (shiftto == 6) { // xx== - if (padding && (sp + 1 != sl || src[sp] != '=')) - throw new IllegalArgumentException( - "Input byte array has wrong 4-byte ending unit"); + // reached end of byte array or hit padding '=' characters. + if (shiftto == 6) { dst[dp++] = (byte)(bits >> 16); - } else if (shiftto == 0) { // xxx= - if (padding && sp != sl) - throw new IllegalArgumentException( - "Input byte array has wrong 4-byte ending unit"); + } else if (shiftto == 0) { dst[dp++] = (byte)(bits >> 16); dst[dp++] = (byte)(bits >> 8); - } else if (padding || shiftto != 18) { - throw new IllegalArgumentException( - "last unit does not have enough bytes"); + } else if (shiftto == 12) { + throw new IllegalArgumentException( + "Last unit does not have enough valid bits"); + } + // anything left is invalid, if is not MIME. + // if MIME, ignore all non-base64 character + while (sp < sl) { + if (isMIME && base64[src[sp++]] < 0) + continue; + throw new IllegalArgumentException( + "Input byte array has incorrect ending byte at " + sp); } return dp; } @@ -1252,8 +1275,22 @@ public class Base64 { int v = is.read(); if (v == -1) { eof = true; - if (nextin != 18) - throw new IOException("Base64 stream has un-decoded dangling byte(s)."); + if (nextin != 18) { + if (nextin == 12) + throw new IOException("Base64 stream has one un-decoded dangling byte."); + // treat ending xx/xxx without padding character legal. + // same logic as v == 'v' below + b[off++] = (byte)(bits >> (16)); + len--; + if (nextin == 0) { // only one padding byte + if (len == 0) { // no enough output space + bits >>= 8; // shift to lowest byte + nextout = 0; + } else { + b[off++] = (byte) (bits >> 8); + } + } + } if (off == oldOff) return -1; else diff --git a/jdk/test/java/util/Base64/TestBase64.java b/jdk/test/java/util/Base64/TestBase64.java index 0a8eea6e4aa..e0af4de23b7 100644 --- a/jdk/test/java/util/Base64/TestBase64.java +++ b/jdk/test/java/util/Base64/TestBase64.java @@ -22,7 +22,7 @@ */ /** - * @test 4235519 8004212 8005394 8007298 + * @test 4235519 8004212 8005394 8007298 8006295 8006315 8006530 * @summary tests java.util.Base64 */ @@ -112,6 +112,12 @@ public class TestBase64 { // test single-non-base64 character for mime decoding testSingleNonBase64MimeDec(); + + // test decoding of unpadded data + testDecodeUnpadded(); + + // test mime decoding with ignored character after padding + testDecodeIgnoredAfterPadding(); } private static sun.misc.BASE64Encoder sunmisc = new sun.misc.BASE64Encoder(); @@ -359,6 +365,81 @@ public class TestBase64 { } catch (IllegalArgumentException iae) {} } + private static void testDecodeIgnoredAfterPadding() throws Throwable { + for (byte nonBase64 : new byte[] {'#', '(', '!', '\\', '-', '_', '\n', '\r'}) { + byte[][] src = new byte[][] { + "A".getBytes("ascii"), + "AB".getBytes("ascii"), + "ABC".getBytes("ascii"), + "ABCD".getBytes("ascii"), + "ABCDE".getBytes("ascii") + }; + Base64.Encoder encM = Base64.getMimeEncoder(); + Base64.Decoder decM = Base64.getMimeDecoder(); + Base64.Encoder enc = Base64.getEncoder(); + Base64.Decoder dec = Base64.getDecoder(); + for (int i = 0; i < src.length; i++) { + // decode(byte[]) + byte[] encoded = encM.encode(src[i]); + encoded = Arrays.copyOf(encoded, encoded.length + 1); + encoded[encoded.length - 1] = nonBase64; + checkEqual(decM.decode(encoded), src[i], "Non-base64 char is not ignored"); + try { + dec.decode(encoded); + throw new RuntimeException("No IAE for non-base64 char"); + } catch (IllegalArgumentException iae) {} + + // decode(ByteBuffer[], ByteBuffer[]) + ByteBuffer encodedBB = ByteBuffer.wrap(encoded); + ByteBuffer decodedBB = ByteBuffer.allocate(100); + int ret = decM.decode(encodedBB, decodedBB); + byte[] buf = new byte[ret]; + decodedBB.flip(); + decodedBB.get(buf); + checkEqual(buf, src[i], "Non-base64 char is not ignored"); + try { + encodedBB.rewind(); + decodedBB.clear(); + dec.decode(encodedBB, decodedBB); + throw new RuntimeException("No IAE for non-base64 char"); + } catch (IllegalArgumentException iae) {} + // direct + encodedBB.rewind(); + decodedBB = ByteBuffer.allocateDirect(100); + ret = decM.decode(encodedBB, decodedBB); + buf = new byte[ret]; + decodedBB.flip(); + decodedBB.get(buf); + checkEqual(buf, src[i], "Non-base64 char is not ignored"); + try { + encodedBB.rewind(); + decodedBB.clear(); + dec.decode(encodedBB, decodedBB); + throw new RuntimeException("No IAE for non-base64 char"); + } catch (IllegalArgumentException iae) {} + } + } + } + + private static void testDecodeUnpadded() throws Throwable { + byte[] srcA = new byte[] { 'Q', 'Q' }; + byte[] srcAA = new byte[] { 'Q', 'Q', 'E'}; + Base64.Decoder dec = Base64.getDecoder(); + byte[] ret = dec.decode(srcA); + if (ret[0] != 'A') + throw new RuntimeException("Decoding unpadding input A failed"); + ret = dec.decode(srcAA); + if (ret[0] != 'A' && ret[1] != 'A') + throw new RuntimeException("Decoding unpadding input AA failed"); + ret = new byte[10]; + if (dec.wrap(new ByteArrayInputStream(srcA)).read(ret) != 1 && + ret[0] != 'A') + throw new RuntimeException("Decoding unpadding input A from stream failed"); + if (dec.wrap(new ByteArrayInputStream(srcA)).read(ret) != 2 && + ret[0] != 'A' && ret[1] != 'A') + throw new RuntimeException("Decoding unpadding input AA from stream failed"); + } + // single-non-base64-char should be ignored for mime decoding, but // iae for basic decoding private static void testSingleNonBase64MimeDec() throws Throwable {