src/share/vm/gc_implementation/g1/heapRegionSeq.cpp

changeset 2472
0fa27f37d4d4
parent 2453
2250ee17e258
child 2492
a672e43650cc
     1.1 --- a/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp	Wed Jan 19 13:04:37 2011 -0800
     1.2 +++ b/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp	Wed Jan 19 19:30:42 2011 -0500
     1.3 @@ -65,152 +65,6 @@
     1.4  
     1.5  // Private methods.
     1.6  
     1.7 -HeapWord*
     1.8 -HeapRegionSeq::alloc_obj_from_region_index(int ind, size_t word_size) {
     1.9 -  assert(G1CollectedHeap::isHumongous(word_size),
    1.10 -         "Allocation size should be humongous");
    1.11 -  int cur = ind;
    1.12 -  int first = cur;
    1.13 -  size_t sumSizes = 0;
    1.14 -  while (cur < _regions.length() && sumSizes < word_size) {
    1.15 -    // Loop invariant:
    1.16 -    //  For all i in [first, cur):
    1.17 -    //       _regions.at(i)->is_empty()
    1.18 -    //    && _regions.at(i) is contiguous with its predecessor, if any
    1.19 -    //  && sumSizes is the sum of the sizes of the regions in the interval
    1.20 -    //       [first, cur)
    1.21 -    HeapRegion* curhr = _regions.at(cur);
    1.22 -    if (curhr->is_empty()
    1.23 -        && (first == cur
    1.24 -            || (_regions.at(cur-1)->end() ==
    1.25 -                curhr->bottom()))) {
    1.26 -      sumSizes += curhr->capacity() / HeapWordSize;
    1.27 -    } else {
    1.28 -      first = cur + 1;
    1.29 -      sumSizes = 0;
    1.30 -    }
    1.31 -    cur++;
    1.32 -  }
    1.33 -  if (sumSizes >= word_size) {
    1.34 -    _alloc_search_start = cur;
    1.35 -
    1.36 -    // We need to initialize the region(s) we just discovered. This is
    1.37 -    // a bit tricky given that it can happen concurrently with
    1.38 -    // refinement threads refining cards on these regions and
    1.39 -    // potentially wanting to refine the BOT as they are scanning
    1.40 -    // those cards (this can happen shortly after a cleanup; see CR
    1.41 -    // 6991377). So we have to set up the region(s) carefully and in
    1.42 -    // a specific order.
    1.43 -
    1.44 -    // Currently, allocs_are_zero_filled() returns false. The zero
    1.45 -    // filling infrastructure will be going away soon (see CR 6977804).
    1.46 -    // So no need to do anything else here.
    1.47 -    bool zf = G1CollectedHeap::heap()->allocs_are_zero_filled();
    1.48 -    assert(!zf, "not supported");
    1.49 -
    1.50 -    // This will be the "starts humongous" region.
    1.51 -    HeapRegion* first_hr = _regions.at(first);
    1.52 -    {
    1.53 -      MutexLockerEx x(ZF_mon, Mutex::_no_safepoint_check_flag);
    1.54 -      first_hr->set_zero_fill_allocated();
    1.55 -    }
    1.56 -    // The header of the new object will be placed at the bottom of
    1.57 -    // the first region.
    1.58 -    HeapWord* new_obj = first_hr->bottom();
    1.59 -    // This will be the new end of the first region in the series that
    1.60 -    // should also match the end of the last region in the seriers.
    1.61 -    // (Note: sumSizes = "region size" x "number of regions we found").
    1.62 -    HeapWord* new_end = new_obj + sumSizes;
    1.63 -    // This will be the new top of the first region that will reflect
    1.64 -    // this allocation.
    1.65 -    HeapWord* new_top = new_obj + word_size;
    1.66 -
    1.67 -    // First, we need to zero the header of the space that we will be
    1.68 -    // allocating. When we update top further down, some refinement
    1.69 -    // threads might try to scan the region. By zeroing the header we
    1.70 -    // ensure that any thread that will try to scan the region will
    1.71 -    // come across the zero klass word and bail out.
    1.72 -    //
    1.73 -    // NOTE: It would not have been correct to have used
    1.74 -    // CollectedHeap::fill_with_object() and make the space look like
    1.75 -    // an int array. The thread that is doing the allocation will
    1.76 -    // later update the object header to a potentially different array
    1.77 -    // type and, for a very short period of time, the klass and length
    1.78 -    // fields will be inconsistent. This could cause a refinement
    1.79 -    // thread to calculate the object size incorrectly.
    1.80 -    Copy::fill_to_words(new_obj, oopDesc::header_size(), 0);
    1.81 -
    1.82 -    // We will set up the first region as "starts humongous". This
    1.83 -    // will also update the BOT covering all the regions to reflect
    1.84 -    // that there is a single object that starts at the bottom of the
    1.85 -    // first region.
    1.86 -    first_hr->set_startsHumongous(new_top, new_end);
    1.87 -
    1.88 -    // Then, if there are any, we will set up the "continues
    1.89 -    // humongous" regions.
    1.90 -    HeapRegion* hr = NULL;
    1.91 -    for (int i = first + 1; i < cur; ++i) {
    1.92 -      hr = _regions.at(i);
    1.93 -      {
    1.94 -        MutexLockerEx x(ZF_mon, Mutex::_no_safepoint_check_flag);
    1.95 -        hr->set_zero_fill_allocated();
    1.96 -      }
    1.97 -      hr->set_continuesHumongous(first_hr);
    1.98 -    }
    1.99 -    // If we have "continues humongous" regions (hr != NULL), then the
   1.100 -    // end of the last one should match new_end.
   1.101 -    assert(hr == NULL || hr->end() == new_end, "sanity");
   1.102 -
   1.103 -    // Up to this point no concurrent thread would have been able to
   1.104 -    // do any scanning on any region in this series. All the top
   1.105 -    // fields still point to bottom, so the intersection between
   1.106 -    // [bottom,top] and [card_start,card_end] will be empty. Before we
   1.107 -    // update the top fields, we'll do a storestore to make sure that
   1.108 -    // no thread sees the update to top before the zeroing of the
   1.109 -    // object header and the BOT initialization.
   1.110 -    OrderAccess::storestore();
   1.111 -
   1.112 -    // Now that the BOT and the object header have been initialized,
   1.113 -    // we can update top of the "starts humongous" region.
   1.114 -    assert(first_hr->bottom() < new_top && new_top <= first_hr->end(),
   1.115 -           "new_top should be in this region");
   1.116 -    first_hr->set_top(new_top);
   1.117 -
   1.118 -    // Now, we will update the top fields of the "continues humongous"
   1.119 -    // regions. The reason we need to do this is that, otherwise,
   1.120 -    // these regions would look empty and this will confuse parts of
   1.121 -    // G1. For example, the code that looks for a consecutive number
   1.122 -    // of empty regions will consider them empty and try to
   1.123 -    // re-allocate them. We can extend is_empty() to also include
   1.124 -    // !continuesHumongous(), but it is easier to just update the top
   1.125 -    // fields here.
   1.126 -    hr = NULL;
   1.127 -    for (int i = first + 1; i < cur; ++i) {
   1.128 -      hr = _regions.at(i);
   1.129 -      if ((i + 1) == cur) {
   1.130 -        // last continues humongous region
   1.131 -        assert(hr->bottom() < new_top && new_top <= hr->end(),
   1.132 -               "new_top should fall on this region");
   1.133 -        hr->set_top(new_top);
   1.134 -      } else {
   1.135 -        // not last one
   1.136 -        assert(new_top > hr->end(), "new_top should be above this region");
   1.137 -        hr->set_top(hr->end());
   1.138 -      }
   1.139 -    }
   1.140 -    // If we have continues humongous regions (hr != NULL), then the
   1.141 -    // end of the last one should match new_end and its top should
   1.142 -    // match new_top.
   1.143 -    assert(hr == NULL ||
   1.144 -           (hr->end() == new_end && hr->top() == new_top), "sanity");
   1.145 -
   1.146 -    return new_obj;
   1.147 -  } else {
   1.148 -    // If we started from the beginning, we want to know why we can't alloc.
   1.149 -    return NULL;
   1.150 -  }
   1.151 -}
   1.152 -
   1.153  void HeapRegionSeq::print_empty_runs() {
   1.154    int empty_run = 0;
   1.155    int n_empty = 0;
   1.156 @@ -284,13 +138,67 @@
   1.157    return res;
   1.158  }
   1.159  
   1.160 -HeapWord* HeapRegionSeq::obj_allocate(size_t word_size) {
   1.161 -  int cur = _alloc_search_start;
   1.162 -  // Make sure "cur" is a valid index.
   1.163 -  assert(cur >= 0, "Invariant.");
   1.164 -  HeapWord* res = alloc_obj_from_region_index(cur, word_size);
   1.165 -  if (res == NULL)
   1.166 -    res = alloc_obj_from_region_index(0, word_size);
   1.167 +int HeapRegionSeq::find_contiguous_from(int from, size_t num) {
   1.168 +  assert(num > 1, "pre-condition");
   1.169 +  assert(0 <= from && from <= _regions.length(),
   1.170 +         err_msg("from: %d should be valid and <= than %d",
   1.171 +                 from, _regions.length()));
   1.172 +
   1.173 +  int curr = from;
   1.174 +  int first = -1;
   1.175 +  size_t num_so_far = 0;
   1.176 +  while (curr < _regions.length() && num_so_far < num) {
   1.177 +    HeapRegion* curr_hr = _regions.at(curr);
   1.178 +    if (curr_hr->is_empty()) {
   1.179 +      if (first == -1) {
   1.180 +        first = curr;
   1.181 +        num_so_far = 1;
   1.182 +      } else {
   1.183 +        num_so_far += 1;
   1.184 +      }
   1.185 +    } else {
   1.186 +      first = -1;
   1.187 +      num_so_far = 0;
   1.188 +    }
   1.189 +    curr += 1;
   1.190 +  }
   1.191 +
   1.192 +  assert(num_so_far <= num, "post-condition");
   1.193 +  if (num_so_far == num) {
   1.194 +    // we find enough space for the humongous object
   1.195 +    assert(from <= first && first < _regions.length(), "post-condition");
   1.196 +    assert(first < curr && (curr - first) == (int) num, "post-condition");
   1.197 +    for (int i = first; i < first + (int) num; ++i) {
   1.198 +      assert(_regions.at(i)->is_empty(), "post-condition");
   1.199 +    }
   1.200 +    return first;
   1.201 +  } else {
   1.202 +    // we failed to find enough space for the humongous object
   1.203 +    return -1;
   1.204 +  }
   1.205 +}
   1.206 +
   1.207 +int HeapRegionSeq::find_contiguous(size_t num) {
   1.208 +  assert(num > 1, "otherwise we should not be calling this");
   1.209 +  assert(0 <= _alloc_search_start && _alloc_search_start <= _regions.length(),
   1.210 +         err_msg("_alloc_search_start: %d should be valid and <= than %d",
   1.211 +                 _alloc_search_start, _regions.length()));
   1.212 +
   1.213 +  int start = _alloc_search_start;
   1.214 +  int res = find_contiguous_from(start, num);
   1.215 +  if (res == -1 && start != 0) {
   1.216 +    // Try starting from the beginning. If _alloc_search_start was 0,
   1.217 +    // no point in doing this again.
   1.218 +    res = find_contiguous_from(0, num);
   1.219 +  }
   1.220 +  if (res != -1) {
   1.221 +    assert(0 <= res && res < _regions.length(),
   1.222 +           err_msg("res: %d should be valid", res));
   1.223 +    _alloc_search_start = res + (int) num;
   1.224 +  }
   1.225 +  assert(0 < _alloc_search_start && _alloc_search_start <= _regions.length(),
   1.226 +         err_msg("_alloc_search_start: %d should be valid",
   1.227 +                 _alloc_search_start));
   1.228    return res;
   1.229  }
   1.230  
   1.231 @@ -376,6 +284,10 @@
   1.232  
   1.233  MemRegion HeapRegionSeq::shrink_by(size_t shrink_bytes,
   1.234                                     size_t& num_regions_deleted) {
   1.235 +  // Reset this in case it's currently pointing into the regions that
   1.236 +  // we just removed.
   1.237 +  _alloc_search_start = 0;
   1.238 +
   1.239    assert(shrink_bytes % os::vm_page_size() == 0, "unaligned");
   1.240    assert(shrink_bytes % HeapRegion::GrainBytes == 0, "unaligned");
   1.241  
   1.242 @@ -395,7 +307,6 @@
   1.243      }
   1.244      assert(cur == _regions.top(), "Should be top");
   1.245      if (!cur->is_empty()) break;
   1.246 -    cur->reset_zero_fill();
   1.247      shrink_bytes -= cur->capacity();
   1.248      num_regions_deleted++;
   1.249      _regions.pop();
   1.250 @@ -410,7 +321,6 @@
   1.251    return MemRegion(last_start, end);
   1.252  }
   1.253  
   1.254 -
   1.255  class PrintHeapRegionClosure : public  HeapRegionClosure {
   1.256  public:
   1.257    bool doHeapRegion(HeapRegion* r) {

mercurial