From 62d7317f860477916a95537f8d82843981e9053b Mon Sep 17 00:00:00 2001 From: Sangheon Kim Date: Wed, 12 Jun 2019 10:34:29 +0200 Subject: [PATCH 01/19] 8225478: Make G1CMRootRegions independent of HeapRegions Remove dependency of HeapRegion from G1CMRootRegions class Reviewed-by: tschatzl, kbarrett --- src/hotspot/share/gc/g1/g1CollectedHeap.cpp | 2 +- src/hotspot/share/gc/g1/g1ConcurrentMark.cpp | 79 ++++++++++++-------- src/hotspot/share/gc/g1/g1ConcurrentMark.hpp | 34 +++++---- src/hotspot/share/memory/memRegion.hpp | 8 +- 4 files changed, 70 insertions(+), 53 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index e9c480ac8b3..800861f5f41 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -4640,7 +4640,7 @@ void G1CollectedHeap::retire_gc_alloc_region(HeapRegion* alloc_region, bool const during_im = collector_state()->in_initial_mark_gc(); if (during_im && allocated_bytes > 0) { - _cm->root_regions()->add(alloc_region); + _cm->root_regions()->add(alloc_region->next_top_at_mark_start(), alloc_region->top()); } _hr_printer.retire(alloc_region); } diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp index eb0824bb633..e7044a826eb 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp @@ -257,30 +257,38 @@ void G1CMMarkStack::set_empty() { _free_list = NULL; } -G1CMRootRegions::G1CMRootRegions(uint const max_regions) : - _root_regions(NEW_C_HEAP_ARRAY(HeapRegion*, max_regions, mtGC)), - _max_regions(max_regions), - _num_root_regions(0), - _claimed_root_regions(0), - _scan_in_progress(false), - _should_abort(false) { } - -G1CMRootRegions::~G1CMRootRegions() { - FREE_C_HEAP_ARRAY(HeapRegion*, _max_regions); +G1CMRootMemRegions::G1CMRootMemRegions(uint const max_regions) : + _root_regions(NULL), + _max_regions(max_regions), + _num_root_regions(0), + _claimed_root_regions(0), + _scan_in_progress(false), + _should_abort(false) { + _root_regions = new MemRegion[_max_regions]; + if (_root_regions == NULL) { + vm_exit_during_initialization("Could not allocate root MemRegion set."); + } } -void G1CMRootRegions::reset() { +G1CMRootMemRegions::~G1CMRootMemRegions() { + delete[] _root_regions; +} + +void G1CMRootMemRegions::reset() { _num_root_regions = 0; } -void G1CMRootRegions::add(HeapRegion* hr) { +void G1CMRootMemRegions::add(HeapWord* start, HeapWord* end) { assert_at_safepoint(); size_t idx = Atomic::add((size_t)1, &_num_root_regions) - 1; - assert(idx < _max_regions, "Trying to add more root regions than there is space " SIZE_FORMAT, _max_regions); - _root_regions[idx] = hr; + assert(idx < _max_regions, "Trying to add more root MemRegions than there is space " SIZE_FORMAT, _max_regions); + assert(start != NULL && end != NULL && start <= end, "Start (" PTR_FORMAT ") should be less or equal to " + "end (" PTR_FORMAT ")", p2i(start), p2i(end)); + _root_regions[idx].set_start(start); + _root_regions[idx].set_end(end); } -void G1CMRootRegions::prepare_for_scan() { +void G1CMRootMemRegions::prepare_for_scan() { assert(!scan_in_progress(), "pre-condition"); _scan_in_progress = _num_root_regions > 0; @@ -289,7 +297,7 @@ void G1CMRootRegions::prepare_for_scan() { _should_abort = false; } -HeapRegion* G1CMRootRegions::claim_next() { +const MemRegion* G1CMRootMemRegions::claim_next() { if (_should_abort) { // If someone has set the should_abort flag, we return NULL to // force the caller to bail out of their loop. @@ -302,26 +310,26 @@ HeapRegion* G1CMRootRegions::claim_next() { size_t claimed_index = Atomic::add((size_t)1, &_claimed_root_regions) - 1; if (claimed_index < _num_root_regions) { - return _root_regions[claimed_index]; + return &_root_regions[claimed_index]; } return NULL; } -uint G1CMRootRegions::num_root_regions() const { +uint G1CMRootMemRegions::num_root_regions() const { return (uint)_num_root_regions; } -void G1CMRootRegions::notify_scan_done() { +void G1CMRootMemRegions::notify_scan_done() { MutexLocker x(RootRegionScan_lock, Mutex::_no_safepoint_check_flag); _scan_in_progress = false; RootRegionScan_lock->notify_all(); } -void G1CMRootRegions::cancel_scan() { +void G1CMRootMemRegions::cancel_scan() { notify_scan_done(); } -void G1CMRootRegions::scan_finished() { +void G1CMRootMemRegions::scan_finished() { assert(scan_in_progress(), "pre-condition"); if (!_should_abort) { @@ -333,7 +341,7 @@ void G1CMRootRegions::scan_finished() { notify_scan_done(); } -bool G1CMRootRegions::wait_until_scan_finished() { +bool G1CMRootMemRegions::wait_until_scan_finished() { if (!scan_in_progress()) { return false; } @@ -875,14 +883,21 @@ uint G1ConcurrentMark::calc_active_marking_workers() { return result; } -void G1ConcurrentMark::scan_root_region(HeapRegion* hr, uint worker_id) { - assert(hr->is_old() || (hr->is_survivor() && hr->next_top_at_mark_start() == hr->bottom()), - "Root regions must be old or survivor but region %u is %s", hr->hrm_index(), hr->get_type_str()); +void G1ConcurrentMark::scan_root_region(const MemRegion* region, uint worker_id) { +#ifdef ASSERT + HeapWord* last = region->last(); + HeapRegion* hr = _g1h->heap_region_containing(last); + assert(hr->is_old() || hr->next_top_at_mark_start() == hr->bottom(), + "Root regions must be old or survivor/eden but region %u is %s", hr->hrm_index(), hr->get_type_str()); + assert(hr->next_top_at_mark_start() == region->start(), + "MemRegion start should be equal to nTAMS"); +#endif + G1RootRegionScanClosure cl(_g1h, this, worker_id); const uintx interval = PrefetchScanIntervalInBytes; - HeapWord* curr = hr->next_top_at_mark_start(); - const HeapWord* end = hr->top(); + HeapWord* curr = region->start(); + const HeapWord* end = region->end(); while (curr < end) { Prefetch::read(curr, interval); oop obj = oop(curr); @@ -902,11 +917,11 @@ public: assert(Thread::current()->is_ConcurrentGC_thread(), "this should only be done by a conc GC thread"); - G1CMRootRegions* root_regions = _cm->root_regions(); - HeapRegion* hr = root_regions->claim_next(); - while (hr != NULL) { - _cm->scan_root_region(hr, worker_id); - hr = root_regions->claim_next(); + G1CMRootMemRegions* root_regions = _cm->root_regions(); + const MemRegion* region = root_regions->claim_next(); + while (region != NULL) { + _cm->scan_root_region(region, worker_id); + region = root_regions->claim_next(); } } }; diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp index 62079af67df..8454622ae24 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp @@ -222,18 +222,20 @@ private: template void iterate(Fn fn) const PRODUCT_RETURN; }; -// Root Regions are regions that contain objects from nTAMS to top. These are roots -// for marking, i.e. their referenced objects must be kept alive to maintain the +// Root MemRegions are memory areas that contain objects which references are +// roots wrt to the marking. They must be scanned before marking to maintain the // SATB invariant. -// We could scan and mark them through during the initial-mark pause, but for +// Typically they contain the areas from nTAMS to top of the regions. +// We could scan and mark through these objects during the initial-mark pause, but for // pause time reasons we move this work to the concurrent phase. // We need to complete this procedure before the next GC because it might determine // that some of these "root objects" are dead, potentially dropping some required // references. -// Root regions comprise of the complete contents of survivor regions, and any -// objects copied into old gen during GC. -class G1CMRootRegions { - HeapRegion** _root_regions; +// Root MemRegions comprise of the contents of survivor regions at the end +// of the GC, and any objects copied into the old gen during GC. +class G1CMRootMemRegions { + // The set of root MemRegions. + MemRegion* _root_regions; size_t const _max_regions; volatile size_t _num_root_regions; // Actual number of root regions. @@ -246,13 +248,13 @@ class G1CMRootRegions { void notify_scan_done(); public: - G1CMRootRegions(uint const max_regions); - ~G1CMRootRegions(); + G1CMRootMemRegions(uint const max_regions); + ~G1CMRootMemRegions(); // Reset the data structure to allow addition of new root regions. void reset(); - void add(HeapRegion* hr); + void add(HeapWord* start, HeapWord* end); // Reset the claiming / scanning of the root regions. void prepare_for_scan(); @@ -264,9 +266,9 @@ public: // false otherwise. bool scan_in_progress() { return _scan_in_progress; } - // Claim the next root region to scan atomically, or return NULL if + // Claim the next root MemRegion to scan atomically, or return NULL if // all have been claimed. - HeapRegion* claim_next(); + const MemRegion* claim_next(); // The number of root regions to scan. uint num_root_regions() const; @@ -310,7 +312,7 @@ class G1ConcurrentMark : public CHeapObj { MemRegion const _heap; // Root region tracking and claiming - G1CMRootRegions _root_regions; + G1CMRootMemRegions _root_regions; // For grey objects G1CMMarkStack _global_mark_stack; // Grey objects behind global finger @@ -501,7 +503,7 @@ public: size_t partial_mark_stack_size_target() const { return _global_mark_stack.capacity() / 3; } bool mark_stack_empty() const { return _global_mark_stack.is_empty(); } - G1CMRootRegions* root_regions() { return &_root_regions; } + G1CMRootMemRegions* root_regions() { return &_root_regions; } void concurrent_cycle_start(); // Abandon current marking iteration due to a Full GC. @@ -554,8 +556,8 @@ public: // them. void scan_root_regions(); - // Scan a single root region from nTAMS to top and mark everything reachable from it. - void scan_root_region(HeapRegion* hr, uint worker_id); + // Scan a single root MemRegion to mark everything reachable from it. + void scan_root_region(const MemRegion* region, uint worker_id); // Do concurrent phase of marking, to a tentative transitive closure. void mark_from_roots(); diff --git a/src/hotspot/share/memory/memRegion.hpp b/src/hotspot/share/memory/memRegion.hpp index 1e79a545e4f..d1268caea0a 100644 --- a/src/hotspot/share/memory/memRegion.hpp +++ b/src/hotspot/share/memory/memRegion.hpp @@ -32,13 +32,13 @@ // A very simple data structure representing a contigous region // region of address space. -// Note that MemRegions are passed by value, not by reference. +// Note that MemRegions are typically passed by value, not by reference. // The intent is that they remain very small and contain no // objects. The copy constructor and destructor must be trivial, // to support optimization for pass-by-value. -// These should never be allocated in heap but we do -// create MemRegions (in CardTableBarrierSet) in heap so operator -// new and operator new [] added for this special case. +// These should almost never be allocated in heap but we do +// create MemRegions (in CardTable and G1CMRootMemRegions) on the heap so operator +// new and operator new [] were added for these special cases. class MemRegion { friend class VMStructs; From 0d8209a2b74dcc2ebbbf43ff0b85273f2aecedee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Wed, 12 Jun 2019 13:21:25 +0200 Subject: [PATCH 02/19] 8223364: Bad placement of anchor relative to header Reviewed-by: jjg --- .../html/AnnotationTypeFieldWriterImpl.java | 6 +- ...nnotationTypeRequiredMemberWriterImpl.java | 8 +-- .../formats/html/ConstructorWriterImpl.java | 10 ++-- .../formats/html/EnumConstantWriterImpl.java | 6 +- .../doclets/formats/html/FieldWriterImpl.java | 5 +- .../formats/html/MethodWriterImpl.java | 9 ++- .../formats/html/PropertyWriterImpl.java | 6 +- .../doclets/formats/html/markup/Links.java | 2 +- .../doclets/toolkit/resources/stylesheet.css | 3 +- .../TestAnnotationTypes.java | 12 +--- .../jdk/javadoc/doclet/testHref/TestHref.java | 8 +-- .../testHtmlVersion/TestHtmlVersion.java | 54 +++++++++--------- .../doclet/testInterface/TestInterface.java | 10 +--- .../javadoc/doclet/testJavaFX/TestJavaFX.java | 54 ++++-------------- .../testMemberSummary/TestMemberSummary.java | 4 +- .../doclet/testOptions/TestOptions.java | 10 +--- .../doclet/testOrdering/TestOrdering.java | 56 +++++++++---------- .../TestBadOverride.java | 5 +- .../doclet/testSummaryTag/TestSummaryTag.java | 5 +- .../testTypeParams/TestTypeParameters.java | 4 +- 20 files changed, 106 insertions(+), 171 deletions(-) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeFieldWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeFieldWriterImpl.java index f05d4ba5e6b..b61e11a2d3c 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeFieldWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeFieldWriterImpl.java @@ -33,6 +33,7 @@ import javax.lang.model.type.TypeMirror; import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; +import jdk.javadoc.internal.doclets.formats.html.markup.StringContent; import jdk.javadoc.internal.doclets.formats.html.markup.Table; import jdk.javadoc.internal.doclets.formats.html.markup.TableHeader; import jdk.javadoc.internal.doclets.toolkit.AnnotationTypeFieldWriter; @@ -104,9 +105,9 @@ public class AnnotationTypeFieldWriterImpl extends AbstractMemberWriter if (!writer.printedAnnotationFieldHeading) { Content heading = HtmlTree.HEADING(Headings.TypeDeclaration.DETAILS_HEADING, contents.fieldDetailsLabel); - memberDetailsTree.add(heading); memberDetailsTree.add(links.createAnchor( SectionName.ANNOTATION_TYPE_FIELD_DETAIL)); + memberDetailsTree.add(heading); writer.printedAnnotationFieldHeading = true; } return memberDetailsTree; @@ -119,9 +120,8 @@ public class AnnotationTypeFieldWriterImpl extends AbstractMemberWriter Content annotationDetailsTree) { Content annotationDocTree = new ContentBuilder(); Content heading = new HtmlTree(Headings.TypeDeclaration.MEMBER_HEADING); - heading.add(name(member)); + heading.add(links.createAnchor(name(member), new StringContent(name(member)))); annotationDocTree.add(heading); - annotationDocTree.add(links.createAnchor(name(member))); return HtmlTree.SECTION(HtmlStyle.detail, annotationDocTree); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java index 52067767b09..50d3f7f40ae 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java @@ -33,6 +33,7 @@ import javax.lang.model.type.TypeMirror; import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; +import jdk.javadoc.internal.doclets.formats.html.markup.StringContent; import jdk.javadoc.internal.doclets.formats.html.markup.Table; import jdk.javadoc.internal.doclets.formats.html.markup.TableHeader; import jdk.javadoc.internal.doclets.toolkit.AnnotationTypeRequiredMemberWriter; @@ -106,9 +107,9 @@ public class AnnotationTypeRequiredMemberWriterImpl extends AbstractMemberWriter if (!writer.printedAnnotationHeading) { Content heading = HtmlTree.HEADING(Headings.TypeDeclaration.DETAILS_HEADING, contents.annotationTypeDetailsLabel); - memberDetailsTree.add(heading); memberDetailsTree.add(links.createAnchor( SectionName.ANNOTATION_TYPE_ELEMENT_DETAIL)); + memberDetailsTree.add(heading); writer.printedAnnotationHeading = true; } return memberDetailsTree; @@ -122,10 +123,9 @@ public class AnnotationTypeRequiredMemberWriterImpl extends AbstractMemberWriter String simpleName = name(member); Content annotationDocTree = new ContentBuilder(); Content heading = new HtmlTree(Headings.TypeDeclaration.MEMBER_HEADING); - heading.add(simpleName); + heading.add(links.createAnchor( + simpleName + utils.signature((ExecutableElement) member), new StringContent(simpleName))); annotationDocTree.add(heading); - annotationDocTree.add(links.createAnchor( - simpleName + utils.signature((ExecutableElement) member))); return HtmlTree.SECTION(HtmlStyle.detail, annotationDocTree); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstructorWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstructorWriterImpl.java index f88962e924a..1e9a262f69a 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstructorWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstructorWriterImpl.java @@ -37,6 +37,7 @@ import jdk.javadoc.internal.doclets.formats.html.markup.Entity; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; +import jdk.javadoc.internal.doclets.formats.html.markup.StringContent; import jdk.javadoc.internal.doclets.formats.html.markup.Table; import jdk.javadoc.internal.doclets.formats.html.markup.TableHeader; import jdk.javadoc.internal.doclets.toolkit.ConstructorWriter; @@ -122,9 +123,9 @@ public class ConstructorWriterImpl extends AbstractExecutableMemberWriter Content constructorDetailsTree = new ContentBuilder(); Content heading = HtmlTree.HEADING(Headings.TypeDeclaration.DETAILS_HEADING, contents.constructorDetailsLabel); - constructorDetailsTree.add(heading); constructorDetailsTree.add(links.createAnchor( SectionName.CONSTRUCTOR_DETAIL)); + constructorDetailsTree.add(heading); return constructorDetailsTree; } @@ -137,12 +138,11 @@ public class ConstructorWriterImpl extends AbstractExecutableMemberWriter String erasureAnchor; Content constructorDocTree = new ContentBuilder(); Content heading = new HtmlTree(Headings.TypeDeclaration.MEMBER_HEADING); - heading.add(name(constructor)); - constructorDocTree.add(heading); if ((erasureAnchor = getErasureAnchor(constructor)) != null) { - constructorDocTree.add(links.createAnchor((erasureAnchor))); + heading.add(links.createAnchor((erasureAnchor))); } - constructorDocTree.add(links.createAnchor(writer.getAnchor(constructor))); + heading.add(links.createAnchor(writer.getAnchor(constructor), new StringContent(name(constructor)))); + constructorDocTree.add(heading); return HtmlTree.SECTION(HtmlStyle.detail, constructorDocTree); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/EnumConstantWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/EnumConstantWriterImpl.java index b9af9c62644..ce222bb9aa9 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/EnumConstantWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/EnumConstantWriterImpl.java @@ -33,6 +33,7 @@ import javax.lang.model.element.VariableElement; import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; +import jdk.javadoc.internal.doclets.formats.html.markup.StringContent; import jdk.javadoc.internal.doclets.formats.html.markup.Table; import jdk.javadoc.internal.doclets.formats.html.markup.TableHeader; import jdk.javadoc.internal.doclets.toolkit.Content; @@ -91,9 +92,9 @@ public class EnumConstantWriterImpl extends AbstractMemberWriter Content enumConstantsDetailsTree = new ContentBuilder(); Content heading = HtmlTree.HEADING(Headings.TypeDeclaration.DETAILS_HEADING, contents.enumConstantDetailLabel); - enumConstantsDetailsTree.add(heading); enumConstantsDetailsTree.add(links.createAnchor( SectionName.ENUM_CONSTANT_DETAIL)); + enumConstantsDetailsTree.add(heading); return enumConstantsDetailsTree; } @@ -105,9 +106,8 @@ public class EnumConstantWriterImpl extends AbstractMemberWriter Content enumConstantsDetailsTree) { Content enumConstantsTree = new ContentBuilder(); Content heading = new HtmlTree(Headings.TypeDeclaration.MEMBER_HEADING); - heading.add(name(enumConstant)); + heading.add(links.createAnchor(name(enumConstant), new StringContent(name(enumConstant)))); enumConstantsTree.add(heading); - enumConstantsTree.add(links.createAnchor(name(enumConstant))); return HtmlTree.SECTION(HtmlStyle.detail, enumConstantsTree); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FieldWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FieldWriterImpl.java index 0e1db2fb686..ad78c02a4d0 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FieldWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FieldWriterImpl.java @@ -96,9 +96,9 @@ public class FieldWriterImpl extends AbstractMemberWriter Content fieldDetailsTree = new ContentBuilder(); Content heading = HtmlTree.HEADING(Headings.TypeDeclaration.DETAILS_HEADING, contents.fieldDetailsLabel); - fieldDetailsTree.add(heading); fieldDetailsTree.add(links.createAnchor( SectionName.FIELD_DETAIL)); + fieldDetailsTree.add(heading); return fieldDetailsTree; } @@ -109,9 +109,8 @@ public class FieldWriterImpl extends AbstractMemberWriter public Content getFieldDocTreeHeader(VariableElement field, Content fieldDetailsTree) { Content fieldTree = new ContentBuilder(); Content heading = new HtmlTree(Headings.TypeDeclaration.MEMBER_HEADING); - heading.add(name(field)); + heading.add(links.createAnchor(name(field), new StringContent(name(field)))); fieldTree.add(heading); - fieldTree.add(links.createAnchor(name(field))); return HtmlTree.SECTION(HtmlStyle.detail, fieldTree); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MethodWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MethodWriterImpl.java index 6cbf6a37a3f..fe2b0f02439 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MethodWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MethodWriterImpl.java @@ -109,8 +109,8 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter Content methodDetailsTree = new ContentBuilder(); Content heading = HtmlTree.HEADING(Headings.TypeDeclaration.DETAILS_HEADING, contents.methodDetailLabel); - methodDetailsTree.add(heading); methodDetailsTree.add(links.createAnchor(SectionName.METHOD_DETAIL)); + methodDetailsTree.add(heading); return methodDetailsTree; } @@ -122,12 +122,11 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter String erasureAnchor; Content methodDocTree = new ContentBuilder(); Content heading = new HtmlTree(Headings.TypeDeclaration.MEMBER_HEADING); - heading.add(name(method)); - methodDocTree.add(heading); if ((erasureAnchor = getErasureAnchor(method)) != null) { - methodDocTree.add(links.createAnchor((erasureAnchor))); + heading.add(links.createAnchor((erasureAnchor))); } - methodDocTree.add(links.createAnchor(writer.getAnchor(method))); + heading.add(links.createAnchor(writer.getAnchor(method), new StringContent(name(method)))); + methodDocTree.add(heading); return HtmlTree.SECTION(HtmlStyle.detail, methodDocTree); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriterImpl.java index 2b66346f9a4..43547bfc00e 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriterImpl.java @@ -89,8 +89,8 @@ public class PropertyWriterImpl extends AbstractMemberWriter Content propertyDetailsTree = new ContentBuilder(); Content heading = HtmlTree.HEADING(Headings.TypeDeclaration.DETAILS_HEADING, contents.propertyDetailsLabel); - propertyDetailsTree.add(heading); propertyDetailsTree.add(links.createAnchor(SectionName.PROPERTY_DETAIL)); + propertyDetailsTree.add(heading); return propertyDetailsTree; } @@ -102,9 +102,9 @@ public class PropertyWriterImpl extends AbstractMemberWriter Content propertyDetailsTree) { Content propertyDocTree = new ContentBuilder(); Content heading = new HtmlTree(Headings.TypeDeclaration.MEMBER_HEADING); - heading.add(utils.getPropertyLabel(name(property))); + heading.add(links.createAnchor(name(property), + new StringContent(utils.getPropertyLabel(name(property))))); propertyDocTree.add(heading); - propertyDocTree.add(links.createAnchor(name(property))); return HtmlTree.SECTION(HtmlStyle.detail, propertyDocTree); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Links.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Links.java index cf2876e95c1..f9eb9ee749f 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Links.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Links.java @@ -100,7 +100,7 @@ public class Links { * @return a content tree for the marker anchor */ public Content createAnchor(String name, Content content) { - return HtmlTree.A_ID(name, (content == null ? EMPTY_COMMENT : content)); + return HtmlTree.A_ID(getName(name), (content == null ? EMPTY_COMMENT : content)); } private static final Content EMPTY_COMMENT = new Comment(" "); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css index 19d8acc3de4..9681235b9e5 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css @@ -574,8 +574,7 @@ td.colLast a { div.memberSignature { font-family:'DejaVu Sans Mono', monospace; font-size:14px; - margin-top:6px; - margin-bottom:14px; + margin:14px 0; white-space: pre-wrap; } div.memberSignature span.annotations { diff --git a/test/langtools/jdk/javadoc/doclet/testAnnotationTypes/TestAnnotationTypes.java b/test/langtools/jdk/javadoc/doclet/testAnnotationTypes/TestAnnotationTypes.java index 5c5ea97a115..15ea74d4aa2 100644 --- a/test/langtools/jdk/javadoc/doclet/testAnnotationTypes/TestAnnotationTypes.java +++ b/test/langtools/jdk/javadoc/doclet/testAnnotationTypes/TestAnnotationTypes.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4973609 8015249 8025633 8026567 6469561 8071982 8162363 8182765 + * @bug 4973609 8015249 8025633 8026567 6469561 8071982 8162363 8182765 8223364 * @summary Make sure that annotation types with 0 members does not have * extra HR tags. * @author jamieh @@ -61,10 +61,7 @@ public class TestAnnotationTypes extends JavadocTester { "DEFAULT_NAME" + "", "", - "

DEFAULT_NAME

\n" - + "\n" - + "\n" - + "\n" + "

DEFAULT_NAME

\n" + "
static final " + "java.lang.String " + "DEFAULT_NAME
\n"); @@ -87,10 +84,7 @@ public class TestAnnotationTypes extends JavadocTester { "
    ", "
  • ", "
    ", - "

    value

    ", - "", - "", - "", + "

    value

    ", "
    int" + " value
    "); diff --git a/test/langtools/jdk/javadoc/doclet/testHref/TestHref.java b/test/langtools/jdk/javadoc/doclet/testHref/TestHref.java index 506bf946773..4b8ba697327 100644 --- a/test/langtools/jdk/javadoc/doclet/testHref/TestHref.java +++ b/test/langtools/jdk/javadoc/doclet/testHref/TestHref.java @@ -57,13 +57,9 @@ public class TestHref extends JavadocTester { //Member summary table link. "href=\"#method(int,int,java.util.ArrayList)\"", //Anchor test. - "\n" - + "\n" - + "", + "", //Backward compatibility anchor test."pkg/C1.html", - "\n" - + "\n" - + ""); + ""); checkOutput("pkg/C2.html", true, //{@link} test. diff --git a/test/langtools/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java b/test/langtools/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java index 7aa832ae4d7..965375ab3a2 100644 --- a/test/langtools/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java +++ b/test/langtools/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java @@ -323,21 +323,21 @@ public class TestHtmlVersion extends JavadocTester { + "\n" + "\n" + "

    Method Summary

    ", - "
    \n" - + "

    Field Details

    \n" + "
    " + "\n" + "\n" - + "", - "
    \n" - + "

    Constructor Details

    \n" + + "\n" + + "

    Field Details

    \n", + "
    " + "\n" + "\n" - + "", - "
    \n" - + "

    Method Details

    \n" + + "\n" + + "

    Constructor Details

    \n", + "
    " + "\n" + "\n" - + "", + + "\n" + + "

    Method Details

    \n", "