Tue, 02 Aug 2011 12:13:13 -0700
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
Summary: Align the reserved size of the heap and perm to the heap region size to get a preferred heap base that is aligned to the region size, and call the correct heap reservation constructor. Also add a check in the heap reservation code that the reserved space starts at the requested address (if any).
Reviewed-by: kvn, ysr
src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp | file | annotate | diff | comparison | revisions | |
src/share/vm/runtime/virtualspace.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Mon Aug 01 10:04:28 2011 -0700 1.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Tue Aug 02 12:13:13 2011 -0700 1.3 @@ -1901,12 +1901,27 @@ 1.4 PermanentGenerationSpec* pgs = collector_policy()->permanent_generation(); 1.5 // Includes the perm-gen. 1.6 1.7 - const size_t total_reserved = max_byte_size + pgs->max_size(); 1.8 + // When compressed oops are enabled, the preferred heap base 1.9 + // is calculated by subtracting the requested size from the 1.10 + // 32Gb boundary and using the result as the base address for 1.11 + // heap reservation. If the requested size is not aligned to 1.12 + // HeapRegion::GrainBytes (i.e. the alignment that is passed 1.13 + // into the ReservedHeapSpace constructor) then the actual 1.14 + // base of the reserved heap may end up differing from the 1.15 + // address that was requested (i.e. the preferred heap base). 1.16 + // If this happens then we could end up using a non-optimal 1.17 + // compressed oops mode. 1.18 + 1.19 + // Since max_byte_size is aligned to the size of a heap region (checked 1.20 + // above), we also need to align the perm gen size as it might not be. 1.21 + const size_t total_reserved = max_byte_size + 1.22 + align_size_up(pgs->max_size(), HeapRegion::GrainBytes); 1.23 + Universe::check_alignment(total_reserved, HeapRegion::GrainBytes, "g1 heap and perm"); 1.24 + 1.25 char* addr = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop); 1.26 1.27 - ReservedSpace heap_rs(max_byte_size + pgs->max_size(), 1.28 - HeapRegion::GrainBytes, 1.29 - UseLargePages, addr); 1.30 + ReservedHeapSpace heap_rs(total_reserved, HeapRegion::GrainBytes, 1.31 + UseLargePages, addr); 1.32 1.33 if (UseCompressedOops) { 1.34 if (addr != NULL && !heap_rs.is_reserved()) { 1.35 @@ -1914,14 +1929,17 @@ 1.36 // region is taken already, for example, by 'java' launcher. 1.37 // Try again to reserver heap higher. 1.38 addr = Universe::preferred_heap_base(total_reserved, Universe::ZeroBasedNarrowOop); 1.39 - ReservedSpace heap_rs0(total_reserved, HeapRegion::GrainBytes, 1.40 - UseLargePages, addr); 1.41 + 1.42 + ReservedHeapSpace heap_rs0(total_reserved, HeapRegion::GrainBytes, 1.43 + UseLargePages, addr); 1.44 + 1.45 if (addr != NULL && !heap_rs0.is_reserved()) { 1.46 // Failed to reserve at specified address again - give up. 1.47 addr = Universe::preferred_heap_base(total_reserved, Universe::HeapBasedNarrowOop); 1.48 assert(addr == NULL, ""); 1.49 - ReservedSpace heap_rs1(total_reserved, HeapRegion::GrainBytes, 1.50 - UseLargePages, addr); 1.51 + 1.52 + ReservedHeapSpace heap_rs1(total_reserved, HeapRegion::GrainBytes, 1.53 + UseLargePages, addr); 1.54 heap_rs = heap_rs1; 1.55 } else { 1.56 heap_rs = heap_rs0;
2.1 --- a/src/share/vm/runtime/virtualspace.cpp Mon Aug 01 10:04:28 2011 -0700 2.2 +++ b/src/share/vm/runtime/virtualspace.cpp Tue Aug 02 12:13:13 2011 -0700 2.3 @@ -1,5 +1,5 @@ 2.4 /* 2.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 2.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 2.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.8 * 2.9 * This code is free software; you can redistribute it and/or modify it 2.10 @@ -68,7 +68,7 @@ 2.11 assert(len >= required_size, "len too small"); 2.12 2.13 const size_t s = size_t(addr); 2.14 - const size_t beg_ofs = s + prefix_size & suffix_align - 1; 2.15 + const size_t beg_ofs = (s + prefix_size) & (suffix_align - 1); 2.16 const size_t beg_delta = beg_ofs == 0 ? 0 : suffix_align - beg_ofs; 2.17 2.18 if (len < beg_delta + required_size) { 2.19 @@ -113,8 +113,8 @@ 2.20 assert(res >= raw, "alignment decreased start addr"); 2.21 assert(res + prefix_size + suffix_size <= raw + reserve_size, 2.22 "alignment increased end addr"); 2.23 - assert((res & prefix_align - 1) == 0, "bad alignment of prefix"); 2.24 - assert((res + prefix_size & suffix_align - 1) == 0, 2.25 + assert((res & (prefix_align - 1)) == 0, "bad alignment of prefix"); 2.26 + assert(((res + prefix_size) & (suffix_align - 1)) == 0, 2.27 "bad alignment of suffix"); 2.28 } 2.29 #endif 2.30 @@ -135,7 +135,7 @@ 2.31 assert(UseCompressedOops, "currently requested address used only for compressed oops"); 2.32 if (PrintCompressedOopsMode) { 2.33 tty->cr(); 2.34 - tty->print_cr("Reserved memory at not requested address: " PTR_FORMAT " vs " PTR_FORMAT, base, requested_address); 2.35 + tty->print_cr("Reserved memory not at requested address: " PTR_FORMAT " vs " PTR_FORMAT, base, requested_address); 2.36 } 2.37 // OS ignored requested address. Try different address. 2.38 if (special) { 2.39 @@ -162,11 +162,11 @@ 2.40 assert(prefix_align != 0, "sanity"); 2.41 assert(suffix_size != 0, "sanity"); 2.42 assert(suffix_align != 0, "sanity"); 2.43 - assert((prefix_size & prefix_align - 1) == 0, 2.44 + assert((prefix_size & (prefix_align - 1)) == 0, 2.45 "prefix_size not divisible by prefix_align"); 2.46 - assert((suffix_size & suffix_align - 1) == 0, 2.47 + assert((suffix_size & (suffix_align - 1)) == 0, 2.48 "suffix_size not divisible by suffix_align"); 2.49 - assert((suffix_align & prefix_align - 1) == 0, 2.50 + assert((suffix_align & (prefix_align - 1)) == 0, 2.51 "suffix_align not divisible by prefix_align"); 2.52 2.53 // Assert that if noaccess_prefix is used, it is the same as prefix_align. 2.54 @@ -210,8 +210,8 @@ 2.55 if (addr == NULL) return; 2.56 2.57 // Check whether the result has the needed alignment (unlikely unless 2.58 - // prefix_align == suffix_align). 2.59 - const size_t ofs = size_t(addr) + adjusted_prefix_size & suffix_align - 1; 2.60 + // prefix_align < suffix_align). 2.61 + const size_t ofs = (size_t(addr) + adjusted_prefix_size) & (suffix_align - 1); 2.62 if (ofs != 0) { 2.63 // Wrong alignment. Release, allocate more space and do manual alignment. 2.64 // 2.65 @@ -232,6 +232,15 @@ 2.66 addr = reserve_and_align(size + suffix_align, adjusted_prefix_size, 2.67 prefix_align, suffix_size, suffix_align); 2.68 } 2.69 + 2.70 + if (requested_address != 0 && 2.71 + failed_to_reserve_as_requested(addr, requested_address, size, false)) { 2.72 + // As a result of the alignment constraints, the allocated addr differs 2.73 + // from the requested address. Return back to the caller who can 2.74 + // take remedial action (like try again without a requested address). 2.75 + assert(_base == NULL, "should be"); 2.76 + return; 2.77 + } 2.78 } 2.79 2.80 _base = addr; 2.81 @@ -245,13 +254,19 @@ 2.82 const size_t noaccess_prefix, 2.83 bool executable) { 2.84 const size_t granularity = os::vm_allocation_granularity(); 2.85 - assert((size & granularity - 1) == 0, 2.86 + assert((size & (granularity - 1)) == 0, 2.87 "size not aligned to os::vm_allocation_granularity()"); 2.88 - assert((alignment & granularity - 1) == 0, 2.89 + assert((alignment & (granularity - 1)) == 0, 2.90 "alignment not aligned to os::vm_allocation_granularity()"); 2.91 assert(alignment == 0 || is_power_of_2((intptr_t)alignment), 2.92 "not a power of 2"); 2.93 2.94 + alignment = MAX2(alignment, (size_t)os::vm_page_size()); 2.95 + 2.96 + // Assert that if noaccess_prefix is used, it is the same as alignment. 2.97 + assert(noaccess_prefix == 0 || 2.98 + noaccess_prefix == alignment, "noaccess prefix wrong"); 2.99 + 2.100 _base = NULL; 2.101 _size = 0; 2.102 _special = false; 2.103 @@ -282,10 +297,8 @@ 2.104 return; 2.105 } 2.106 // Check alignment constraints 2.107 - if (alignment > 0) { 2.108 - assert((uintptr_t) base % alignment == 0, 2.109 - "Large pages returned a non-aligned address"); 2.110 - } 2.111 + assert((uintptr_t) base % alignment == 0, 2.112 + "Large pages returned a non-aligned address"); 2.113 _special = true; 2.114 } else { 2.115 // failed; try to reserve regular memory below 2.116 @@ -321,7 +334,7 @@ 2.117 if (base == NULL) return; 2.118 2.119 // Check alignment constraints 2.120 - if (alignment > 0 && ((size_t)base & alignment - 1) != 0) { 2.121 + if ((((size_t)base + noaccess_prefix) & (alignment - 1)) != 0) { 2.122 // Base not aligned, retry 2.123 if (!os::release_memory(base, size)) fatal("os::release_memory failed"); 2.124 // Reserve size large enough to do manual alignment and 2.125 @@ -338,12 +351,21 @@ 2.126 os::release_memory(extra_base, extra_size); 2.127 base = os::reserve_memory(size, base); 2.128 } while (base == NULL); 2.129 + 2.130 + if (requested_address != 0 && 2.131 + failed_to_reserve_as_requested(base, requested_address, size, false)) { 2.132 + // As a result of the alignment constraints, the allocated base differs 2.133 + // from the requested address. Return back to the caller who can 2.134 + // take remedial action (like try again without a requested address). 2.135 + assert(_base == NULL, "should be"); 2.136 + return; 2.137 + } 2.138 } 2.139 } 2.140 // Done 2.141 _base = base; 2.142 _size = size; 2.143 - _alignment = MAX2(alignment, (size_t) os::vm_page_size()); 2.144 + _alignment = alignment; 2.145 _noaccess_prefix = noaccess_prefix; 2.146 2.147 // Assert that if noaccess_prefix is used, it is the same as alignment.