7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking

Tue, 02 Aug 2011 12:13:13 -0700

author
johnc
date
Tue, 02 Aug 2011 12:13:13 -0700
changeset 3022
6aa4feb8a366
parent 3021
14a2fd14c0db
child 3023
a20e6e447d3d

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.

mercurial