Mon, 04 Aug 2014 10:48:10 -0700
8031323: Optionally align objects copied to survivor spaces
Reviewed-by: brutisso, tschatzl
1.1 --- a/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp Thu Aug 07 18:09:12 2014 -0700 1.2 +++ b/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp Mon Aug 04 10:48:10 2014 -0700 1.3 @@ -288,7 +288,12 @@ 1.4 } 1.5 1.6 HeapWord* G1ParScanThreadState::allocate(GCAllocPurpose purpose, size_t word_sz) { 1.7 - HeapWord* obj = alloc_buffer(purpose)->allocate(word_sz); 1.8 + HeapWord* obj = NULL; 1.9 + if (purpose == GCAllocForSurvived) { 1.10 + obj = alloc_buffer(GCAllocForSurvived)->allocate_aligned(word_sz, SurvivorAlignmentInBytes); 1.11 + } else { 1.12 + obj = alloc_buffer(GCAllocForTenured)->allocate(word_sz); 1.13 + } 1.14 if (obj != NULL) { 1.15 return obj; 1.16 }
2.1 --- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Thu Aug 07 18:09:12 2014 -0700 2.2 +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Mon Aug 04 10:48:10 2014 -0700 2.3 @@ -28,12 +28,12 @@ 2.4 #include "gc_implementation/parNew/parOopClosures.inline.hpp" 2.5 #include "gc_implementation/shared/adaptiveSizePolicy.hpp" 2.6 #include "gc_implementation/shared/ageTable.hpp" 2.7 -#include "gc_implementation/shared/parGCAllocBuffer.hpp" 2.8 +#include "gc_implementation/shared/copyFailedInfo.hpp" 2.9 #include "gc_implementation/shared/gcHeapSummary.hpp" 2.10 #include "gc_implementation/shared/gcTimer.hpp" 2.11 #include "gc_implementation/shared/gcTrace.hpp" 2.12 #include "gc_implementation/shared/gcTraceTime.hpp" 2.13 -#include "gc_implementation/shared/copyFailedInfo.hpp" 2.14 +#include "gc_implementation/shared/parGCAllocBuffer.inline.hpp" 2.15 #include "gc_implementation/shared/spaceDecorator.hpp" 2.16 #include "memory/defNewGeneration.inline.hpp" 2.17 #include "memory/genCollectedHeap.hpp" 2.18 @@ -251,7 +251,7 @@ 2.19 plab->set_word_size(buf_size); 2.20 plab->set_buf(buf_space); 2.21 record_survivor_plab(buf_space, buf_size); 2.22 - obj = plab->allocate(word_sz); 2.23 + obj = plab->allocate_aligned(word_sz, SurvivorAlignmentInBytes); 2.24 // Note that we cannot compare buf_size < word_sz below 2.25 // because of AlignmentReserve (see ParGCAllocBuffer::allocate()). 2.26 assert(obj != NULL || plab->words_remaining() < word_sz,
3.1 --- a/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Thu Aug 07 18:09:12 2014 -0700 3.2 +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Mon Aug 04 10:48:10 2014 -0700 3.3 @@ -168,7 +168,7 @@ 3.4 HeapWord* alloc_in_to_space_slow(size_t word_sz); 3.5 3.6 HeapWord* alloc_in_to_space(size_t word_sz) { 3.7 - HeapWord* obj = to_space_alloc_buffer()->allocate(word_sz); 3.8 + HeapWord* obj = to_space_alloc_buffer()->allocate_aligned(word_sz, SurvivorAlignmentInBytes); 3.9 if (obj != NULL) return obj; 3.10 else return alloc_in_to_space_slow(word_sz); 3.11 }
4.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.hpp Thu Aug 07 18:09:12 2014 -0700 4.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.hpp Mon Aug 04 10:48:10 2014 -0700 4.3 @@ -26,6 +26,7 @@ 4.4 #define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONLAB_HPP 4.5 4.6 #include "gc_implementation/parallelScavenge/objectStartArray.hpp" 4.7 +#include "gc_interface/collectedHeap.inline.hpp" 4.8 #include "memory/allocation.hpp" 4.9 4.10 // 4.11 @@ -94,23 +95,9 @@ 4.12 PSYoungPromotionLAB() { } 4.13 4.14 // Not MT safe 4.15 - HeapWord* allocate(size_t size) { 4.16 - // Can't assert this, when young fills, we keep the LAB around, but flushed. 4.17 - // assert(_state != flushed, "Sanity"); 4.18 - HeapWord* obj = top(); 4.19 - HeapWord* new_top = obj + size; 4.20 - // The 'new_top>obj' check is needed to detect overflow of obj+size. 4.21 - if (new_top > obj && new_top <= end()) { 4.22 - set_top(new_top); 4.23 - assert(is_object_aligned((intptr_t)obj) && is_object_aligned((intptr_t)new_top), 4.24 - "checking alignment"); 4.25 - return obj; 4.26 - } 4.27 + inline HeapWord* allocate(size_t size); 4.28 4.29 - return NULL; 4.30 - } 4.31 - 4.32 - debug_only(virtual bool lab_is_valid(MemRegion lab)); 4.33 + debug_only(virtual bool lab_is_valid(MemRegion lab);) 4.34 }; 4.35 4.36 class PSOldPromotionLAB : public PSPromotionLAB {
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.inline.hpp Mon Aug 04 10:48:10 2014 -0700 5.3 @@ -0,0 +1,52 @@ 5.4 +/* 5.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.7 + * 5.8 + * This code is free software; you can redistribute it and/or modify it 5.9 + * under the terms of the GNU General Public License version 2 only, as 5.10 + * published by the Free Software Foundation. 5.11 + * 5.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 5.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 5.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 5.15 + * version 2 for more details (a copy is included in the LICENSE file that 5.16 + * accompanied this code). 5.17 + * 5.18 + * You should have received a copy of the GNU General Public License version 5.19 + * 2 along with this work; if not, write to the Free Software Foundation, 5.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 5.21 + * 5.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 5.23 + * or visit www.oracle.com if you need additional information or have any 5.24 + * questions. 5.25 + * 5.26 + */ 5.27 + 5.28 +#ifndef SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONLAB_INLINE_HPP 5.29 +#define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONLAB_INLINE_HPP 5.30 + 5.31 +#include "gc_implementation/parallelScavenge/psPromotionLAB.hpp" 5.32 +#include "gc_interface/collectedHeap.inline.hpp" 5.33 + 5.34 +HeapWord* PSYoungPromotionLAB::allocate(size_t size) { 5.35 + // Can't assert this, when young fills, we keep the LAB around, but flushed. 5.36 + // assert(_state != flushed, "Sanity"); 5.37 + HeapWord* obj = CollectedHeap::align_allocation_or_fail(top(), end(), SurvivorAlignmentInBytes); 5.38 + if (obj == NULL) { 5.39 + return NULL; 5.40 + } 5.41 + 5.42 + HeapWord* new_top = obj + size; 5.43 + // The 'new_top>obj' check is needed to detect overflow of obj+size. 5.44 + if (new_top > obj && new_top <= end()) { 5.45 + set_top(new_top); 5.46 + assert(is_ptr_aligned(obj, SurvivorAlignmentInBytes) && is_object_aligned((intptr_t)new_top), 5.47 + "checking alignment"); 5.48 + return obj; 5.49 + } else { 5.50 + set_top(obj); 5.51 + return NULL; 5.52 + } 5.53 +} 5.54 + 5.55 +#endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONLAB_INLINE_HPP
6.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp Thu Aug 07 18:09:12 2014 -0700 6.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp Mon Aug 04 10:48:10 2014 -0700 6.3 @@ -27,6 +27,7 @@ 6.4 6.5 #include "gc_implementation/parallelScavenge/psOldGen.hpp" 6.6 #include "gc_implementation/parallelScavenge/psPromotionManager.hpp" 6.7 +#include "gc_implementation/parallelScavenge/psPromotionLAB.inline.hpp" 6.8 #include "gc_implementation/parallelScavenge/psScavenge.hpp" 6.9 #include "oops/oop.psgc.inline.hpp" 6.10
7.1 --- a/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp Thu Aug 07 18:09:12 2014 -0700 7.2 +++ b/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp Mon Aug 04 10:48:10 2014 -0700 7.3 @@ -24,7 +24,7 @@ 7.4 7.5 #ifndef SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARGCALLOCBUFFER_HPP 7.6 #define SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARGCALLOCBUFFER_HPP 7.7 - 7.8 +#include "gc_interface/collectedHeap.hpp" 7.9 #include "memory/allocation.hpp" 7.10 #include "memory/blockOffsetTable.hpp" 7.11 #include "memory/threadLocalAllocBuffer.hpp" 7.12 @@ -84,6 +84,9 @@ 7.13 } 7.14 } 7.15 7.16 + // Allocate the object aligned to "alignment_in_bytes". 7.17 + HeapWord* allocate_aligned(size_t word_sz, unsigned short alignment_in_bytes); 7.18 + 7.19 // Undo the last allocation in the buffer, which is required to be of the 7.20 // "obj" of the given "word_sz". 7.21 void undo_allocation(HeapWord* obj, size_t word_sz) {
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/src/share/vm/gc_implementation/shared/parGCAllocBuffer.inline.hpp Mon Aug 04 10:48:10 2014 -0700 8.3 @@ -0,0 +1,44 @@ 8.4 +/* 8.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.7 + * 8.8 + * This code is free software; you can redistribute it and/or modify it 8.9 + * under the terms of the GNU General Public License version 2 only, as 8.10 + * published by the Free Software Foundation. 8.11 + * 8.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 8.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 8.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 8.15 + * version 2 for more details (a copy is included in the LICENSE file that 8.16 + * accompanied this code). 8.17 + * 8.18 + * You should have received a copy of the GNU General Public License version 8.19 + * 2 along with this work; if not, write to the Free Software Foundation, 8.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 8.21 + * 8.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 8.23 + * or visit www.oracle.com if you need additional information or have any 8.24 + * questions. 8.25 + * 8.26 + */ 8.27 + 8.28 +#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_PARGCALLOCBUFFER_INLINE_HPP 8.29 +#define SHARE_VM_GC_IMPLEMENTATION_SHARED_PARGCALLOCBUFFER_INLINE_HPP 8.30 + 8.31 +#include "gc_implementation/shared/parGCAllocBuffer.hpp" 8.32 +#include "gc_interface/collectedHeap.inline.hpp" 8.33 + 8.34 +HeapWord* ParGCAllocBuffer::allocate_aligned(size_t word_sz, unsigned short alignment_in_bytes) { 8.35 + 8.36 + HeapWord* res = CollectedHeap::align_allocation_or_fail(_top, _end, alignment_in_bytes); 8.37 + if (res == NULL) { 8.38 + return NULL; 8.39 + } 8.40 + 8.41 + // Set _top so that allocate(), which expects _top to be correctly set, 8.42 + // can be used below. 8.43 + _top = res; 8.44 + return allocate(word_sz); 8.45 +} 8.46 + 8.47 +#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_PARGCALLOCBUFFER_INLINE_HPP
9.1 --- a/src/share/vm/gc_interface/collectedHeap.hpp Thu Aug 07 18:09:12 2014 -0700 9.2 +++ b/src/share/vm/gc_interface/collectedHeap.hpp Mon Aug 04 10:48:10 2014 -0700 9.3 @@ -351,6 +351,12 @@ 9.4 fill_with_object(start, pointer_delta(end, start), zap); 9.5 } 9.6 9.7 + // Return the address "addr" aligned by "alignment_in_bytes" if such 9.8 + // an address is below "end". Return NULL otherwise. 9.9 + inline static HeapWord* align_allocation_or_fail(HeapWord* addr, 9.10 + HeapWord* end, 9.11 + unsigned short alignment_in_bytes); 9.12 + 9.13 // Some heaps may offer a contiguous region for shared non-blocking 9.14 // allocation, via inlined code (by exporting the address of the top and 9.15 // end fields defining the extent of the contiguous allocation region.)
10.1 --- a/src/share/vm/gc_interface/collectedHeap.inline.hpp Thu Aug 07 18:09:12 2014 -0700 10.2 +++ b/src/share/vm/gc_interface/collectedHeap.inline.hpp Mon Aug 04 10:48:10 2014 -0700 10.3 @@ -241,6 +241,44 @@ 10.4 oop_iterate(&no_header_cl); 10.5 } 10.6 10.7 + 10.8 +inline HeapWord* CollectedHeap::align_allocation_or_fail(HeapWord* addr, 10.9 + HeapWord* end, 10.10 + unsigned short alignment_in_bytes) { 10.11 + if (alignment_in_bytes <= ObjectAlignmentInBytes) { 10.12 + return addr; 10.13 + } 10.14 + 10.15 + assert(is_ptr_aligned(addr, HeapWordSize), 10.16 + err_msg("Address " PTR_FORMAT " is not properly aligned.", p2i(addr))); 10.17 + assert(is_size_aligned(alignment_in_bytes, HeapWordSize), 10.18 + err_msg("Alignment size %u is incorrect.", alignment_in_bytes)); 10.19 + 10.20 + HeapWord* new_addr = (HeapWord*) align_pointer_up(addr, alignment_in_bytes); 10.21 + size_t padding = pointer_delta(new_addr, addr); 10.22 + 10.23 + if (padding == 0) { 10.24 + return addr; 10.25 + } 10.26 + 10.27 + if (padding < CollectedHeap::min_fill_size()) { 10.28 + padding += alignment_in_bytes / HeapWordSize; 10.29 + assert(padding >= CollectedHeap::min_fill_size(), 10.30 + err_msg("alignment_in_bytes %u is expect to be larger " 10.31 + "than the minimum object size", alignment_in_bytes)); 10.32 + new_addr = addr + padding; 10.33 + } 10.34 + 10.35 + assert(new_addr > addr, err_msg("Unexpected arithmetic overflow " 10.36 + PTR_FORMAT " not greater than " PTR_FORMAT, p2i(new_addr), p2i(addr))); 10.37 + if(new_addr < end) { 10.38 + CollectedHeap::fill_with_object(addr, padding); 10.39 + return new_addr; 10.40 + } else { 10.41 + return NULL; 10.42 + } 10.43 +} 10.44 + 10.45 #ifndef PRODUCT 10.46 10.47 inline bool
11.1 --- a/src/share/vm/memory/defNewGeneration.cpp Thu Aug 07 18:09:12 2014 -0700 11.2 +++ b/src/share/vm/memory/defNewGeneration.cpp Mon Aug 04 10:48:10 2014 -0700 11.3 @@ -789,7 +789,7 @@ 11.4 11.5 // Try allocating obj in to-space (unless too old) 11.6 if (old->age() < tenuring_threshold()) { 11.7 - obj = (oop) to()->allocate(s); 11.8 + obj = (oop) to()->allocate_aligned(s); 11.9 } 11.10 11.11 // Otherwise try allocating obj tenured
12.1 --- a/src/share/vm/memory/space.cpp Thu Aug 07 18:09:12 2014 -0700 12.2 +++ b/src/share/vm/memory/space.cpp Mon Aug 04 10:48:10 2014 -0700 12.3 @@ -28,6 +28,7 @@ 12.4 #include "gc_implementation/shared/liveRange.hpp" 12.5 #include "gc_implementation/shared/markSweep.hpp" 12.6 #include "gc_implementation/shared/spaceDecorator.hpp" 12.7 +#include "gc_interface/collectedHeap.inline.hpp" 12.8 #include "memory/blockOffsetTable.inline.hpp" 12.9 #include "memory/defNewGeneration.hpp" 12.10 #include "memory/genCollectedHeap.hpp" 12.11 @@ -719,6 +720,27 @@ 12.12 } while (true); 12.13 } 12.14 12.15 +HeapWord* ContiguousSpace::allocate_aligned(size_t size) { 12.16 + assert(Heap_lock->owned_by_self() || (SafepointSynchronize::is_at_safepoint() && Thread::current()->is_VM_thread()), "not locked"); 12.17 + HeapWord* end_value = end(); 12.18 + 12.19 + HeapWord* obj = CollectedHeap::align_allocation_or_fail(top(), end_value, SurvivorAlignmentInBytes); 12.20 + if (obj == NULL) { 12.21 + return NULL; 12.22 + } 12.23 + 12.24 + if (pointer_delta(end_value, obj) >= size) { 12.25 + HeapWord* new_top = obj + size; 12.26 + set_top(new_top); 12.27 + assert(is_ptr_aligned(obj, SurvivorAlignmentInBytes) && is_aligned(new_top), 12.28 + "checking alignment"); 12.29 + return obj; 12.30 + } else { 12.31 + set_top(obj); 12.32 + return NULL; 12.33 + } 12.34 +} 12.35 + 12.36 // Requires locking. 12.37 HeapWord* ContiguousSpace::allocate(size_t size) { 12.38 return allocate_impl(size, end());
13.1 --- a/src/share/vm/memory/space.hpp Thu Aug 07 18:09:12 2014 -0700 13.2 +++ b/src/share/vm/memory/space.hpp Mon Aug 04 10:48:10 2014 -0700 13.3 @@ -526,6 +526,7 @@ 13.4 // Allocation (return NULL if full) 13.5 virtual HeapWord* allocate(size_t word_size); 13.6 virtual HeapWord* par_allocate(size_t word_size); 13.7 + HeapWord* allocate_aligned(size_t word_size); 13.8 13.9 // Iteration 13.10 void oop_iterate(ExtendedOopClosure* cl);
14.1 --- a/src/share/vm/oops/oop.pcgc.inline.hpp Thu Aug 07 18:09:12 2014 -0700 14.2 +++ b/src/share/vm/oops/oop.pcgc.inline.hpp Mon Aug 04 10:48:10 2014 -0700 14.3 @@ -54,8 +54,6 @@ 14.4 klass()->oop_follow_contents(cm, this); 14.5 } 14.6 14.7 -// Used by parallel old GC. 14.8 - 14.9 inline oop oopDesc::forward_to_atomic(oop p) { 14.10 assert(ParNewGeneration::is_legal_forward_ptr(p), 14.11 "illegal forwarding pointer value.");
15.1 --- a/src/share/vm/runtime/arguments.cpp Thu Aug 07 18:09:12 2014 -0700 15.2 +++ b/src/share/vm/runtime/arguments.cpp Mon Aug 04 10:48:10 2014 -0700 15.3 @@ -1398,6 +1398,22 @@ 15.4 (int)ObjectAlignmentInBytes, os::vm_page_size()); 15.5 return false; 15.6 } 15.7 + if(SurvivorAlignmentInBytes == 0) { 15.8 + SurvivorAlignmentInBytes = ObjectAlignmentInBytes; 15.9 + } else { 15.10 + if (!is_power_of_2(SurvivorAlignmentInBytes)) { 15.11 + jio_fprintf(defaultStream::error_stream(), 15.12 + "error: SurvivorAlignmentInBytes=%d must be power of 2\n", 15.13 + (int)SurvivorAlignmentInBytes); 15.14 + return false; 15.15 + } 15.16 + if (SurvivorAlignmentInBytes < ObjectAlignmentInBytes) { 15.17 + jio_fprintf(defaultStream::error_stream(), 15.18 + "error: SurvivorAlignmentInBytes=%d must be greater than ObjectAlignmentInBytes=%d \n", 15.19 + (int)SurvivorAlignmentInBytes, (int)ObjectAlignmentInBytes); 15.20 + return false; 15.21 + } 15.22 + } 15.23 return true; 15.24 } 15.25
16.1 --- a/src/share/vm/runtime/globals.hpp Thu Aug 07 18:09:12 2014 -0700 16.2 +++ b/src/share/vm/runtime/globals.hpp Mon Aug 04 10:48:10 2014 -0700 16.3 @@ -3885,6 +3885,9 @@ 16.4 product(bool, PrintGCCause, true, \ 16.5 "Include GC cause in GC logging") \ 16.6 \ 16.7 + experimental(intx, SurvivorAlignmentInBytes, 0, \ 16.8 + "Default survivor space alignment in bytes") \ 16.9 + \ 16.10 product(bool , AllowNonVirtualCalls, false, \ 16.11 "Obey the ACC_SUPER flag and allow invokenonvirtual calls") \ 16.12 \